diff --git a/include/NeuraDialect/NeuraOps.td b/include/NeuraDialect/NeuraOps.td index ed1a1157..e83771cf 100644 --- a/include/NeuraDialect/NeuraOps.td +++ b/include/NeuraDialect/NeuraOps.td @@ -108,7 +108,7 @@ def Neura_FDivOp : Op { Example: %result = neura.fdiv %a, %b : f32 }]; - let arguments = (ins AnyType:$lhs, AnyType:$rhs); + let arguments = (ins AnyType:$lhs, Optional:$rhs); let results = (outs AnyType:$result); let traits = [SameOperandsAndResultElementType]; } diff --git a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp index a5d3fb29..bd6a5eb9 100644 --- a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp +++ b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp @@ -37,6 +37,12 @@ bool HeuristicMapping::mapWithBacktrack( << sorted_ops_with_levels.size() - materialized_ops.size() << " non-materialized operations, " << materialized_ops.size() << " operations require physical mapping." << "\n"; + + llvm::outs() << "[HeuristicMapping] Materialized operations list:\n"; + for (size_t i = 0; i < materialized_ops.size(); ++i) { + llvm::outs() << i << " " << *materialized_ops[i].first + << " (level: " << materialized_ops[i].second << ")\n"; + } // Stores the mapping state snapshots for backtracking. std::vector snapshots; diff --git a/lib/NeuraDialect/Mapping/MappingState.cpp b/lib/NeuraDialect/Mapping/MappingState.cpp index cfb946da..bd0d1aad 100644 --- a/lib/NeuraDialect/Mapping/MappingState.cpp +++ b/lib/NeuraDialect/Mapping/MappingState.cpp @@ -5,6 +5,24 @@ using namespace mlir; using namespace mlir::neura; +// Constants for table formatting in dumpOpToLocs. +// Total column width including separators. +constexpr int kKeyMaxLen = 36; +// Actual cell content width (35). +constexpr int kCellWidth = kKeyMaxLen - 1; +// Threshold to distinguish single-digit from double-digit numbers. +constexpr int kTwoDigitThreshold = 10; +// Threshold to distinguish double-digit from triple-digit numbers. +constexpr int kThreeDigitThreshold = 100; +// Length of time slot header prefix "t%N=" for single-digit II (e.g., "t%3="). +constexpr int kHeaderPrefixLenSingleDigit = 5; +// Length of time slot header prefix "t%N=" for double-digit II (e.g., "t%10="). +constexpr int kHeaderPrefixLenDoubleDigit = 6; +// Number of digits for single-digit slot numbers. +constexpr int kSingleDigitLen = 1; +// Number of digits for double-digit slot numbers. +constexpr int kDoubleDigitLen = 2; + MappingState::MappingState(const Architecture &arch, int II, bool is_spatial_only) : II(II), is_spatial_only(is_spatial_only) {} @@ -200,21 +218,129 @@ void MappingState::releaseRoute(Operation *op) { } void MappingState::dumpOpToLocs(llvm::raw_ostream &os) const { - os << "=== MappingState: op_to_locs ===\n"; + os << "=== MappingState: Resource Allocation Table ===\n"; + // Collects all tiles and time steps (modulo II). + std::set tile_ids; + // Time slots range from 0 to II-1. + std::set time_slots; + // Maps (tile_id, time_slot) to list of (operation, actual_time_step). + std::map, std::vector>> tile_slot_to_ops; + for (const auto &[op, locs] : op_to_locs) { - os << " - " << op->getName(); - if (auto name_attr = op->getAttrOfType("sym_name")) { - os << " @" << name_attr; - } - os << "\n"; - for (const MappingLoc &loc : locs) { auto *res = loc.resource; - os << " -> " << res->getType() << "#" << res->getId() - << " @t=" << loc.time_step << "\n"; + // Only shows tiles in the table. + if (res->getType() == "tile") { + tile_ids.insert(res->getId()); + // Computes modulo II. + int time_slot = loc.time_step % II; + time_slots.insert(time_slot); + tile_slot_to_ops[{res->getId(), time_slot}].push_back({op, loc.time_step}); + } + } + } + + if (tile_ids.empty() || time_slots.empty()) { + os << "No tile operations mapped.\n"; + os << "=== End ===\n"; + return; + } + + os << "II = " << II << "\n"; + + // Prints header - time slots (0 to II-1) as columns. + os << "\nTile | "; + for (int slot : time_slots) { + os << "t%" << II << "=" << slot; + int padding = kKeyMaxLen - (II < kTwoDigitThreshold ? kHeaderPrefixLenSingleDigit : kHeaderPrefixLenDoubleDigit) + - (slot < kTwoDigitThreshold ? kSingleDigitLen : kDoubleDigitLen); + for (int i = 0; i < padding; ++i) os << " "; + os << " | "; + } + os << "\n"; + + // Prints separator line. + os << "---------+"; + for (size_t i = 0; i < time_slots.size(); ++i) { + for (int j = 0; j < kKeyMaxLen + 1; ++j) os << "-"; + os << "+"; + } + os << "\n"; + + // Prints each tile as a row. + for (int tile_id : tile_ids) { + os << "Tile#" << tile_id; + if (tile_id < kTwoDigitThreshold) os << " "; + else if (tile_id < kThreeDigitThreshold) os << " "; + os << " | "; + + for (int slot : time_slots) { + auto it = tile_slot_to_ops.find({tile_id, slot}); + if (it != tile_slot_to_ops.end() && !it->second.empty()) { + // Multiple operations may exist in the same slot (from different iterations). + // Shows the first one. + Operation *op = it->second[0].first; + int actual_time = it->second[0].second; + + // Builds operation string: %result = op_name(%operand1, %operand2, ...). + std::string op_str; + llvm::raw_string_ostream op_stream(op_str); + mlir::OpPrintingFlags flags; + + // Prints result (if exists). + if (op->getNumResults() > 0) { + op->getResult(0).printAsOperand(op_stream, flags); + op_stream << " = "; + } + + // Prints operation name (removes "neura." prefix). + std::string op_name = op->getName().getStringRef().str(); + if (op_name.rfind("neura.", 0) == 0) { + op_name = op_name.substr(6); + } + op_stream << op_name; + + // Prints operands. + if (op->getNumOperands() > 0) { + op_stream << "("; + for (unsigned i = 0; i < op->getNumOperands(); ++i) { + if (i > 0) op_stream << ", "; + op->getOperand(i).printAsOperand(op_stream, flags); + } + op_stream << ")"; + } + + // Adds time annotation if not in [0, II). + if (actual_time >= II) { + op_stream << " (t=" << actual_time << ")"; + } + + op_stream.flush(); + + // Truncates string if too long to fit in the cell. + if (op_str.length() > kCellWidth) { + op_str = op_str.substr(0, kCellWidth - 3) + "..."; + } + + // Pads to fixed width (kCellWidth chars). + os << op_str; + int padding = kCellWidth - op_str.length(); + for (int i = 0; i < padding; ++i) os << " "; + } else { + // Renders empty cell. + for (int i = 0; i < kCellWidth; ++i) os << " "; + } + os << " | "; } + os << "\n"; } + + os << "\n=== Legend ===\n"; + os << "- Table shows operations mapped to tiles (modulo II scheduling)\n"; + os << "- Column headers: t%II=X means time slot X (t=X, X+II, X+2*II, ...)\n"; + os << "- Operations with (t=Y) annotation are scheduled at actual time step Y\n"; + os << "- Operations without annotation are scheduled at t=0 to t=" << (II-1) << "\n"; os << "=== End ===\n"; } diff --git a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp index cd9284ab..97fb67ec 100644 --- a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp +++ b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp @@ -358,6 +358,11 @@ struct MapToAcceleratorPass "customized=max_loc,max_depth (default " "max_loc=5, max_depth=3)"), llvm::cl::init("customized")}; + Option dumpMappingTable{ + *this, "dump-mapping-table", + llvm::cl::desc( + "Dump the resource allocation table after mapping (default: true)"), + llvm::cl::init(true)}; void runOnOperation() override { ModuleOp module = getOperation(); @@ -609,7 +614,10 @@ struct MapToAcceleratorPass if (mapping_strategy->map(sorted_ops_with_alap_levels, critical_ops, architecture, mapping_state)) { // success - mapping_state.dumpOpToLocs(); // logs to stderr + if (dumpMappingTable) { + // logs to stderr + mapping_state.dumpOpToLocs(); + } mapping_state.encodeMappingState(); // Sets the mapping_info attribute on the function. diff --git a/lib/NeuraDialect/Transforms/Optimizations/HwAgnosticOpt/FoldConstantPass.cpp b/lib/NeuraDialect/Transforms/Optimizations/HwAgnosticOpt/FoldConstantPass.cpp index 1a6cdcc7..0e8a940c 100644 --- a/lib/NeuraDialect/Transforms/Optimizations/HwAgnosticOpt/FoldConstantPass.cpp +++ b/lib/NeuraDialect/Transforms/Optimizations/HwAgnosticOpt/FoldConstantPass.cpp @@ -282,6 +282,8 @@ DEFINE_BINARY_OP_PATTERN(FAdd, FAddOp) DEFINE_BINARY_OP_PATTERN(FSub, FSubOp) // Generates: FuseFMulConstantPattern. DEFINE_BINARY_OP_PATTERN(FMul, FMulOp) +// Generates: FuseFDivConstantPattern. +DEFINE_BINARY_OP_PATTERN(FDiv, FDivOp) // Generates: FuseICmpConstantPattern. // Note: ICmpOp has a cmp_type attribute that is automatically preserved. DEFINE_BINARY_OP_PATTERN(ICmp, ICmpOp) @@ -587,6 +589,7 @@ struct FoldConstantPass patterns.add(&getContext()); patterns.add(&getContext()); patterns.add(&getContext()); + patterns.add(&getContext()); patterns.add(&getContext()); patterns.add(&getContext()); diff --git a/test/c2llvm2mlir/simple_loop/test.mlir b/test/c2llvm2mlir/simple_loop/test.mlir index 908ff439..6d4e813e 100644 --- a/test/c2llvm2mlir/simple_loop/test.mlir +++ b/test/c2llvm2mlir/simple_loop/test.mlir @@ -32,6 +32,7 @@ // RUN: --insert-data-mov %t-kernel.mlir -o %t-kernel-neura.mlir // RUN: FileCheck %s --check-prefix=CHECK-LLVM2NEURA < %t-kernel-neura.mlir +// Test with mapping table dump enabled // RUN: mlir-neura-opt --assign-accelerator \ // RUN: --lower-llvm-to-neura \ // RUN: --promote-func-arg-to-const \ @@ -42,9 +43,17 @@ // RUN: --view-op-graph \ // RUN: --architecture-spec=../../arch_spec/architecture.yaml \ // RUN: --insert-data-mov \ -// RUN: --map-to-accelerator="mapping-strategy=heuristic backtrack-config=customized=5,3" %t-kernel.mlir -o %t-kernel-mapped.mlir +// RUN: --map-to-accelerator="mapping-strategy=heuristic backtrack-config=customized=5,3 dump-mapping-table=true" %t-kernel.mlir -o %t-kernel-mapped.mlir 2>&1 | tee %t-kernel-mapping-output.txt +// RUN: FileCheck %s --check-prefix=CHECK-MAPPING-TABLE < %t-kernel-mapping-output.txt // RUN: FileCheck %s --check-prefix=CHECK-LLVM2NEURA-MAP < %t-kernel-mapped.mlir +// Checks the resource allocation table output +// CHECK-MAPPING-TABLE: === MappingState: Resource Allocation Table === +// CHECK-MAPPING-TABLE: II = 5 +// CHECK-MAPPING-TABLE: Tile | t%{{[0-9]+}}={{[0-9]+}} +// CHECK-MAPPING-TABLE: ---------+ +// CHECK-MAPPING-TABLE: Tile#{{[0-9]+}} | + // CHECK-LLVM2NEURA: accelerator = "neura" // CHECK-LLVM2NEURA: dataflow_mode = "predicate" // CHECK-LLVM2NEURA: neura.phi diff --git a/test/e2e/histogram/histogram_kernel.mlir b/test/e2e/histogram/histogram_kernel.mlir index 47900057..3e5e0b19 100644 --- a/test/e2e/histogram/histogram_kernel.mlir +++ b/test/e2e/histogram/histogram_kernel.mlir @@ -25,7 +25,7 @@ // MAPPING: module // MAPPING: func.func -// MAPPING-SAME: compiled_ii = 8 +// MAPPING-SAME: compiled_ii = 5 // MAPPING-SAME: mapping_mode = "spatial-temporal" // MAPPING-SAME: mapping_strategy = "heuristic" // MAPPING-SAME: rec_mii = 5 @@ -33,60 +33,51 @@ // MAPPING-SAME: x_tiles = 4 // MAPPING-SAME: y_tiles = 4 // -// MAPPING-NEXT: %0 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 0 : i32, x = 2 : i32, y = 2 : i32}]} : () -> !neura.data -// MAPPING-NEXT: %1 = "neura.grant_once"() <{constant_value = 1.800000e+01 : f32}> {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 4 : i32, x = 3 : i32, y = 2 : i32}]} : () -> !neura.data -// MAPPING-NEXT: %2 = neura.reserve : !neura.data -// MAPPING-NEXT: %3 = "neura.data_mov"(%1) {mapping_locs = [{id = 35 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %4 = "neura.phi"(%2, %3) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 5 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// MAPPING-NEXT: %5 = neura.reserve : !neura.data -// MAPPING-NEXT: %6 = "neura.data_mov"(%0) {mapping_locs = [{id = 320 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 0 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %7 = "neura.phi"(%5, %6) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 1 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// MAPPING-NEXT: %8 = "neura.data_mov"(%7) {mapping_locs = [{id = 34 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %9 = "neura.gep"(%8) <{operandSegmentSizes = array}> {lhs_value = "%arg0", mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 2 : i32, x = 2 : i32, y = 3 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %10 = "neura.data_mov"(%9) {mapping_locs = [{id = 448 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %11 = "neura.load"(%10) {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 3 : i32, x = 2 : i32, y = 3 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %12 = "neura.data_mov"(%11) {mapping_locs = [{id = 448 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %13 = "neura.fadd"(%12) {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 4 : i32, x = 2 : i32, y = 3 : i32}], rhs_value = -1.000000e+00 : f32} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %14 = "neura.data_mov"(%13) {mapping_locs = [{id = 448 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %15 = "neura.fmul"(%14) {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 5 : i32, x = 2 : i32, y = 3 : i32}], rhs_value = 5.000000e+00 : f32} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %16 = "neura.data_mov"(%15) {mapping_locs = [{id = 448 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %17 = "neura.data_mov"(%4) {mapping_locs = [{id = 34 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %18 = "neura.fdiv"(%16, %17) {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 6 : i32, x = 2 : i32, y = 3 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// MAPPING-NEXT: %19 = "neura.data_mov"(%18) {mapping_locs = [{id = 448 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %20 = "neura.cast"(%19) <{cast_type = "fptosi"}> {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 7 : i32, x = 2 : i32, y = 3 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %21 = "neura.data_mov"(%20) {mapping_locs = [{id = 43 : i32, resource = "link", time_step = 7 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %22 = neura.sext %21 {mapping_locs = [{id = 13 : i32, resource = "tile", time_step = 8 : i32, x = 1 : i32, y = 3 : i32}]} : !neura.data -> !neura.data -// MAPPING-NEXT: %23 = "neura.data_mov"(%22) {mapping_locs = [{id = 40 : i32, resource = "link", time_step = 8 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %24 = "neura.gep"(%23) <{operandSegmentSizes = array}> {lhs_value = "%arg1", mapping_locs = [{id = 12 : i32, resource = "tile", time_step = 9 : i32, x = 0 : i32, y = 3 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %25 = "neura.data_mov"(%24) {mapping_locs = [{id = 39 : i32, resource = "link", time_step = 9 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %26 = "neura.load"(%25) {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 10 : i32, x = 0 : i32, y = 2 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %27 = "neura.data_mov"(%26) {mapping_locs = [{id = 24 : i32, resource = "link", time_step = 10 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %28 = "neura.add"(%27) {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 11 : i32, x = 1 : i32, y = 2 : i32}], rhs_value = 1 : i32} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %29 = "neura.data_mov"(%28) {mapping_locs = [{id = 288 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 11 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %30 = "neura.data_mov"(%24) {mapping_locs = [{id = 38 : i32, resource = "link", time_step = 9 : i32}, {id = 42 : i32, resource = "link", time_step = 10 : i32}, {id = 289 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 11 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: "neura.store"(%29, %30) {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 12 : i32, x = 1 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> () -// MAPPING-NEXT: %31 = "neura.data_mov"(%7) {mapping_locs = [{id = 320 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %32 = "neura.add"(%31) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 2 : i32, x = 2 : i32, y = 2 : i32}], rhs_value = 1 : i64} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %33 = "neura.data_mov"(%32) {mapping_locs = [{id = 320 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %34 = "neura.icmp"(%33) <{cmpType = "eq"}> {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 3 : i32, x = 2 : i32, y = 2 : i32}], rhs_value = 20 : i64} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %35 = "neura.data_mov"(%34) {mapping_locs = [{id = 320 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %36 = "neura.not"(%35) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 4 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %37 = "neura.data_mov"(%32) {mapping_locs = [{id = 321 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 2 : i32}, {id = 321 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 3 : i32}, {id = 321 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 4 : i32}, {id = 321 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %38 = "neura.data_mov"(%36) {mapping_locs = [{id = 320 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 4 : i32}, {id = 320 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %39 = neura.grant_predicate %37, %38 {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 6 : i32, x = 2 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %39 -> %5 {mapping_locs = [{id = 321 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 6 : i32}, {id = 321 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 7 : i32}, {id = 321 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 8 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %40 = "neura.data_mov"(%4) {mapping_locs = [{id = 33 : i32, resource = "link", time_step = 5 : i32}, {id = 192 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 6 : i32}, {id = 192 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 7 : i32}, {id = 192 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 8 : i32}, {id = 192 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 9 : i32}, {id = 192 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 10 : i32}, {id = 192 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 11 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %41 = "neura.data_mov"(%36) {mapping_locs = [{id = 33 : i32, resource = "link", time_step = 4 : i32}, {id = 193 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 5 : i32}, {id = 193 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 6 : i32}, {id = 193 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 7 : i32}, {id = 193 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 8 : i32}, {id = 193 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 9 : i32}, {id = 193 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 10 : i32}, {id = 193 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 11 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %42 = neura.grant_predicate %40, %41 {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 12 : i32, x = 2 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %42 -> %2 {mapping_locs = [{id = 20 : i32, resource = "link", time_step = 12 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: "neura.return"() {mapping_locs = [{id = 15 : i32, resource = "tile", time_step = 12 : i32, x = 3 : i32, y = 3 : i32}]} : () -> () +// MAPPING-NEXT: %0 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 0 : i32, x = 3 : i32, y = 2 : i32}]} : () -> !neura.data +// MAPPING-NEXT: %1 = neura.reserve : !neura.data +// MAPPING-NEXT: %2 = "neura.data_mov"(%0) {mapping_locs = [{id = 352 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 0 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %3 = "neura.phi"(%1, %2) {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 1 : i32, x = 3 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %4 = "neura.data_mov"(%3) {mapping_locs = [{id = 36 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %5 = "neura.gep"(%4) <{operandSegmentSizes = array}> {lhs_value = "%arg0", mapping_locs = [{id = 7 : i32, resource = "tile", time_step = 2 : i32, x = 3 : i32, y = 1 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %6 = "neura.data_mov"(%5) {mapping_locs = [{id = 23 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %7 = "neura.load"(%6) {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 3 : i32, x = 3 : i32, y = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %8 = "neura.data_mov"(%7) {mapping_locs = [{id = 37 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %9 = "neura.fadd"(%8) {mapping_locs = [{id = 15 : i32, resource = "tile", time_step = 4 : i32, x = 3 : i32, y = 3 : i32}], rhs_value = -1.000000e+00 : f32} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %10 = "neura.data_mov"(%9) {mapping_locs = [{id = 46 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %11 = "neura.fmul"(%10) {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 5 : i32, x = 2 : i32, y = 3 : i32}], rhs_value = 5.000000e+00 : f32} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %12 = "neura.data_mov"(%11) {mapping_locs = [{id = 45 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %13 = "neura.fdiv"(%12) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 6 : i32, x = 2 : i32, y = 2 : i32}], rhs_value = 1.800000e+01 : f32} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %14 = "neura.data_mov"(%13) {mapping_locs = [{id = 31 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %15 = "neura.cast"(%14) <{cast_type = "fptosi"}> {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 7 : i32, x = 1 : i32, y = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %16 = "neura.data_mov"(%15) {mapping_locs = [{id = 29 : i32, resource = "link", time_step = 7 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %17 = neura.sext %16 {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 8 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data -> !neura.data +// MAPPING-NEXT: %18 = "neura.data_mov"(%17) {mapping_locs = [{id = 160 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 8 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %19 = "neura.gep"(%18) <{operandSegmentSizes = array}> {lhs_value = "%arg1", mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 9 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %20 = "neura.data_mov"(%19) {mapping_locs = [{id = 160 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 9 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %21 = "neura.load"(%20) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 10 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %22 = "neura.data_mov"(%21) {mapping_locs = [{id = 16 : i32, resource = "link", time_step = 10 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %23 = "neura.add"(%22) {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 11 : i32, x = 1 : i32, y = 2 : i32}], rhs_value = 1 : i32} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %24 = "neura.data_mov"(%23) {mapping_locs = [{id = 30 : i32, resource = "link", time_step = 11 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %25 = "neura.data_mov"(%19) {mapping_locs = [{id = 16 : i32, resource = "link", time_step = 9 : i32}, {id = 30 : i32, resource = "link", time_step = 10 : i32}, {id = 416 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 11 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: "neura.store"(%24, %25) {mapping_locs = [{id = 13 : i32, resource = "tile", time_step = 12 : i32, x = 1 : i32, y = 3 : i32}]} : (!neura.data, !neura.data) -> () +// MAPPING-NEXT: %26 = "neura.data_mov"(%3) {mapping_locs = [{id = 352 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %27 = "neura.add"(%26) {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 2 : i32, x = 3 : i32, y = 2 : i32}], rhs_value = 1 : i64} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %28 = "neura.data_mov"(%27) {mapping_locs = [{id = 35 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %29 = "neura.icmp"(%28) <{cmpType = "eq"}> {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 3 : i32, x = 2 : i32, y = 2 : i32}], rhs_value = 20 : i64} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %30 = "neura.data_mov"(%29) {mapping_locs = [{id = 320 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %31 = "neura.not"(%30) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 4 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %32 = "neura.data_mov"(%27) {mapping_locs = [{id = 352 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 2 : i32}, {id = 35 : i32, resource = "link", time_step = 3 : i32}, {id = 320 : i32, per_tile_register_id = 0 : i32, resource = "register", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %33 = "neura.data_mov"(%31) {mapping_locs = [{id = 321 : i32, per_tile_register_id = 1 : i32, resource = "register", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %34 = neura.grant_predicate %32, %33 {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 5 : i32, x = 2 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: neura.ctrl_mov %34 -> %1 {mapping_locs = [{id = 32 : i32, resource = "link", time_step = 5 : i32}]} : !neura.data !neura.data +// MAPPING-NEXT: "neura.return"() {mapping_locs = [{id = 12 : i32, resource = "tile", time_step = 12 : i32, x = 0 : i32, y = 3 : i32}]} : () -> () // YAML: instructions: -// YAML: - opcode: "GRANT_ONCE" -// YAML: - opcode: "FDIV" // YAML: - opcode: "CAST_FPTOSI" +// YAML: - opcode: "FDIV" +// YAML: - opcode: "GRANT_ONCE" -// ASM: PE(2,2): +// ASM: PE(3,2): // ASM-NEXT: { // ASM-NEXT: GRANT_ONCE, [#0] -> [$0] // ASM-NEXT: } (t=0)