Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e0fdc3f
Support spatial-temporal loop control, and parsing perfect nested loo…
Oct 23, 2025
5637cad
Merge origin/main and remove allow-steering-spatial-temporal option
Oct 27, 2025
fc3792a
Fix test: check if there exists neura.load_indexed/store_indexed, and…
Oct 27, 2025
85a8a28
Fix compilation errors in AffineToNeuraPass
Oct 27, 2025
e09519c
Completely rewrite AffineToNeura pass with dataflow-style loop lowering
Oct 27, 2025
e57c3e0
Add comprehensive test suite and fix code style
Oct 28, 2025
bb4816a
feat(AffineToNeura): Add loop nest analysis and valid signal reuse op…
Oct 28, 2025
cb6f657
refactor: Reorganize AffineToNeura tests - split into focused test files
Oct 28, 2025
56a16ba
Fixed know error
Oct 28, 2025
5a2e111
fix: Pass empty ValueRange to inlineBlockBefore
Oct 29, 2025
bb86bdd
fix: Correctly pass loop_index to inlineBlockBefore
Oct 29, 2025
53cd897
style: rename LoopInfo fields to snake_case
Oct 30, 2025
ce811c0
refactor: remove unused fused operations (CarryInvariantOp, Condition…
Oct 30, 2025
c9950fc
refactor: improve test readability
Oct 30, 2025
07f83da
test: add example of unsupported case (affine.if)
Oct 30, 2025
0357b5c
refactor: remove hard 3D dimension constraint
Oct 30, 2025
f83f8ad
docs: add comment explaining AffineApplyOp single-result check
Oct 30, 2025
1571c5a
docs: add comprehensive examples for all conversions
Oct 30, 2025
f063aec
fix: remove ConstantOp from steering unwrapped operations.
Oct 31, 2025
ed2795d
Fix grant_once semantic conflict in loop control
Oct 31, 2025
154d3b2
1. Remove indentation in imperfect-ops-after.mlir CHECK lines
Oct 31, 2025
7331bf4
fix: update test files to expect constant instead of grant_once
Oct 31, 2025
698121c
fix: address reviewer comments on test files
Nov 2, 2025
e5d2243
remove: delete unsupported-dynamic-bounds.mlir test file
Nov 2, 2025
49cc61a
Remove confusing comments in mapping_util.cpp
Nov 2, 2025
bc0695c
Align is_steering_unwrapped_op with InsertDataMovPass behavior
Nov 2, 2025
9a59352
fix: correct FileCheck pattern in unsupported-affine-if test
Nov 2, 2025
00d6d55
fix: remove is_steering_unwrapped_op per reviewer feedback and fix test
Nov 3, 2025
0e22a58
feat: add complete multi-stage lowering demonstration for affine.if
Nov 3, 2025
7544c23
test: use deterministic patterns and move CHECK after code
Nov 3, 2025
17f512f
test: add visual separators in CHECK patterns
Nov 3, 2025
fadb2f0
fix: correct operation names in complex-affine-expressions test
Nov 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/Conversion/ConversionPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ std::unique_ptr<mlir::Pass> createLowerArithToNeuraPass();
std::unique_ptr<mlir::Pass> createLowerLlvmToNeuraPass();
std::unique_ptr<mlir::Pass> createLowerMemRefToNeuraPass();
std::unique_ptr<mlir::Pass> createLowerBuiltinToNeuraPass();
std::unique_ptr<mlir::Pass> createLowerAffineToNeuraPass();

#define GEN_PASS_REGISTRATION
#include "Conversion/ConversionPasses.h.inc"
Expand Down
12 changes: 12 additions & 0 deletions include/Conversion/ConversionPasses.td
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,16 @@ def LowerBuiltinToNeura : Pass<"lower-builtin-to-neura", "ModuleOp">{
let constructor = "mlir::createLowerBuiltinToNeuraPass()";
}

def LowerAffineToNeura : Pass<"lower-affine-to-neura", "func::FuncOp">{
let summary = "Lower Affine perfect nested loops to Neura loop_control operations";
let description = [{
Converts perfectly nested affine.for loops directly to Neura dialect using
loop_control operations, avoiding the need to flatten to LLVM IR first.
This preserves loop structure information for better optimization on
dataflow architectures.
}];
let constructor = "mlir::createLowerAffineToNeuraPass()";
let dependentDialects = ["mlir::neura::NeuraDialect", "mlir::affine::AffineDialect"];
}

#endif // CONVERSION_PASSES_TD
4 changes: 3 additions & 1 deletion include/NeuraDialect/Architecture/Architecture.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ enum OperationKind {
// Loop control operations.
ILoopControl = 34,
// Constant operations.
IConstant = 35
IConstant = 35,
// Steering control fused operations.
ICarryInvariant = 36, IConditionalSelect = 37, IInvariantGroup = 38
};

//===----------------------------------------------------------------------===//
Expand Down
129 changes: 129 additions & 0 deletions include/NeuraDialect/NeuraOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -575,4 +575,133 @@ def Neura_InvariantOp : Op<NeuraDialect, "invariant">{
let arguments = (ins AnyType:$initial, AnyType:$condition);
let results = (outs AnyType:$result);
let assemblyFormat = "$initial `,` $condition attr-dict `:` type($initial) `,` type($condition) `->` type($result)";
}

// ============================================================================
// FUSED OPERATIONS FOR RECMII OPTIMIZATION
// ============================================================================

// Defines the carry_invariant fused operation.
def Neura_CarryInvariantOp : Op<NeuraDialect, "carry_invariant">{
let summary = "Fused carry and invariant operation for nested loops.";
let description = [{
Combines carry and invariant operations into a single operation to reduce RecMII.
This is optimized for nested loop patterns where an inner loop's carry result
is used as an invariant in the outer loop.

Semantics:
- If inner_condition is false (first inner iteration): return initial value
- Else if outer_condition is false (outer loop active, inner loop invariant):
return initial value from inner carry
- Else: return carried value

Replaces the pattern:
%carry_result = neura.carry %init, %inner_cond, %carried
%inv_result = neura.invariant %carry_result, %outer_cond

With:
%result = neura.carry_invariant %init, %inner_cond, %outer_cond, %carried

RecMII Impact: Reduces 2 operations to 1 operation (-50% on critical path)

Example:
%out = neura.carry_invariant %init, %inner_cond, %outer_cond, %carried
: i64, i1, i1, i64 -> i64
}];

let arguments = (ins
AnyType:$initial,
AnyType:$inner_condition,
AnyType:$outer_condition,
AnyType:$carried
);
let results = (outs AnyType:$result);

let assemblyFormat = [{
$initial `,` $inner_condition `,` $outer_condition `,` $carried attr-dict
`:` type($initial) `,` type($inner_condition) `,` type($outer_condition) `,`
type($carried) `->` type($result)
}];
}

// Defines the conditional_select fused operation.
def Neura_ConditionalSelectOp : Op<NeuraDialect, "cond_select">{
let summary = "Fused comparison and conditional selection operation.";
let description = [{
Combines comparison (icmp) and conditional selection (false_steer) into a
single atomic operation to reduce RecMII.

Semantics:
- Performs comparison: result = (lhs <predicate> rhs)
- If result is false: return value
- If result is true: return default value (typically from hardware)

Replaces the pattern:
%cond = neura.icmp %lhs, %rhs <{cmpType = "slt"}>
%result = neura.false_steer %value, %cond

With:
%result = neura.cond_select %lhs, %rhs, %value <{predicate = "slt"}>

RecMII Impact: Reduces 2 operations to 1 operation (-50% on critical path)

Supported predicates: "eq", "ne", "slt", "sle", "sgt", "sge", "ult", "ule", "ugt", "uge"

Example:
%out = neura.cond_select %a, %b, %val <{predicate = "slt"}>
: i64, i64, i64 -> i64
}];

let arguments = (ins
AnyType:$lhs,
AnyType:$rhs,
AnyType:$value,
StrAttr:$predicate
);
let results = (outs AnyType:$result);

let assemblyFormat = [{
$lhs `,` $rhs `,` $value attr-dict `:` type($lhs) `,` type($rhs) `,`
type($value) `->` type($result)
}];
}

// Defines the invariant_group batch operation.
def Neura_InvariantGroupOp : Op<NeuraDialect, "invariant_group">{
let summary = "Batch invariant extraction for multiple values.";
let description = [{
Extracts multiple invariants with the same condition in a single operation.
This is optimized for nested loops where many values need to be marked as
invariant with respect to the outer loop.

Hardware can optimize this by:
- Sharing condition checking logic
- Parallel invariant extraction
- Reduced control overhead

Replaces multiple individual invariant operations:
%inv1 = neura.invariant %val1, %cond
%inv2 = neura.invariant %val2, %cond
%inv3 = neura.invariant %val3, %cond

With a single batch operation:
%inv1, %inv2, %inv3 = neura.invariant_group %val1, %val2, %val3, %cond

ResMII Impact: Reduces N operations to 1 operation (improves resource utilization)

Example:
%out1, %out2, %out3 = neura.invariant_group %in1, %in2, %in3, %cond
: i64, i64, i64, i1 -> i64, i64, i64
}];

let arguments = (ins
Variadic<AnyType>:$inputs,
AnyType:$condition
);
let results = (outs Variadic<AnyType>:$outputs);

let assemblyFormat = [{
$inputs `,` $condition attr-dict `:` type($inputs) `,` type($condition)
`->` type($outputs)
}];
}
1 change: 1 addition & 0 deletions include/NeuraDialect/NeuraPasses.td
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,5 @@ def RemovePredicatedType : Pass<"remove-predicated-type", "ModuleOp"> {
}];
let constructor = "neura::createRemovePredicatedTypePass()";
}

#endif // NEURA_PASSES_TD
Loading