From 9efc2e757210c6e5828883f4374aa827f3a50442 Mon Sep 17 00:00:00 2001 From: Martin Erhart Date: Mon, 19 Aug 2024 17:36:10 +0100 Subject: [PATCH] [LLHD] Let WaitOp observe plain values instead of signals (#7528) This is necessary to lower the moore dialect's always_comb and always_latch without introducing helper signals. It also allows for more mem2reg at the LLHD level. --- .../circt/Dialect/LLHD/IR/LLHDStructureOps.td | 4 +- lib/Conversion/MooreToCore/MooreToCore.cpp | 21 ++++++- .../LLHD/Transforms/ProcessLoweringPass.cpp | 55 ++++++------------- test/Conversion/MooreToCore/basic.mlir | 25 ++++++--- .../LLHD/Canonicalization/probeCSE.mlir | 5 +- test/Dialect/LLHD/IR/basic.mlir | 16 ++++-- .../LLHD/Transforms/earlyCodeMotion.mlir | 14 +++-- .../Transforms/memoryToBlockArgument.mlir | 6 +- .../LLHD/Transforms/processLowering.mlir | 36 ++++++++---- .../Transforms/processLoweringErrors.mlir | 13 +++-- .../LLHD/Transforms/temporal-code-motion.mlir | 10 +++- 11 files changed, 125 insertions(+), 80 deletions(-) diff --git a/include/circt/Dialect/LLHD/IR/LLHDStructureOps.td b/include/circt/Dialect/LLHD/IR/LLHDStructureOps.td index 58afcb53bd..c288c68e55 100644 --- a/include/circt/Dialect/LLHD/IR/LLHDStructureOps.td +++ b/include/circt/Dialect/LLHD/IR/LLHDStructureOps.td @@ -130,14 +130,14 @@ def WaitOp : LLHDOp<"wait", [ ``` }]; - let arguments = (ins Variadic:$obs, + let arguments = (ins Variadic:$observed, Optional:$time, Variadic:$destOps); let successors = (successor AnySuccessor:$dest); let assemblyFormat = [{ - (`for` $time^ `,`)? (`(`$obs^ `:` qualified(type($obs))`)` `,`)? + (`for` $time^ `,`)? (`(`$observed^ `:` qualified(type($observed))`)` `,`)? $dest (`(` $destOps^ `:` qualified(type($destOps)) `)`)? attr-dict }]; } diff --git a/lib/Conversion/MooreToCore/MooreToCore.cpp b/lib/Conversion/MooreToCore/MooreToCore.cpp index 6a3470049d..a5e1840511 100644 --- a/lib/Conversion/MooreToCore/MooreToCore.cpp +++ b/lib/Conversion/MooreToCore/MooreToCore.cpp @@ -322,6 +322,19 @@ struct WaitEventOpConversion : public OpConversionPattern { rewriter.eraseOp(detectOp); } + auto setInsertionPointAfterDef = [&](Value value) { + if (auto *op = value.getDefiningOp()) + rewriter.setInsertionPointAfter(op); + if (auto arg = dyn_cast(value)) + rewriter.setInsertionPointToStart(value.getParentBlock()); + }; + + auto probeIfSignal = [&](Value value) -> Value { + if (!isa(value.getType())) + return value; + return rewriter.create(loc, value); + }; + // Determine the values used during event detection that are defined outside // the `wait_event`'s body region. We want to wait for a change on these // signals before we check if any interesting event happened. @@ -334,12 +347,16 @@ struct WaitEventOpConversion : public OpConversionPattern { if (!alreadyObserved.insert(value).second) continue; if (auto remapped = rewriter.getRemappedValue(value)) { - observeValues.push_back(remapped); + OpBuilder::InsertionGuard g(rewriter); + setInsertionPointAfterDef(remapped); + observeValues.push_back(probeIfSignal(remapped)); } else { + OpBuilder::InsertionGuard g(rewriter); + setInsertionPointAfterDef(value); auto type = typeConverter->convertType(value.getType()); auto converted = typeConverter->materializeTargetConversion( rewriter, loc, type, value); - observeValues.push_back(converted); + observeValues.push_back(probeIfSignal(converted)); } } }); diff --git a/lib/Dialect/LLHD/Transforms/ProcessLoweringPass.cpp b/lib/Dialect/LLHD/Transforms/ProcessLoweringPass.cpp index d20a5f437e..2ec645d6ae 100644 --- a/lib/Dialect/LLHD/Transforms/ProcessLoweringPass.cpp +++ b/lib/Dialect/LLHD/Transforms/ProcessLoweringPass.cpp @@ -34,40 +34,6 @@ struct ProcessLoweringPass void runOnOperation() override; }; -/// Backtrack a signal value and make sure that every part of it is in the -/// observer list at some point. Assumes that there is no operation that adds -/// parts to a signal that it does not take as input (e.g. something like -/// llhd.sig.zext %sig : !hw.inout -> !hw.inout). -static LogicalResult checkSignalsAreObserved(OperandRange obs, Value value) { - // If the value in the observer list, we don't need to backtrack further. - if (llvm::is_contained(obs, value)) - return success(); - - if (Operation *op = value.getDefiningOp()) { - // If no input is a signal, this operation creates one and thus this is the - // last point where it could have been observed. As we've already checked - // that, we can fail here. This includes for example llhd.sig - if (llvm::none_of(op->getOperands(), [](Value arg) { - return isa(arg.getType()); - })) - return failure(); - - // Only recusively backtrack signal values. Other values cannot be changed - // from outside or with a delay. If they come from probes at some point, - // they are covered by that probe. As soon as we find a signal that is not - // observed no matter how far we backtrack, we fail. - return success(llvm::all_of(op->getOperands(), [&](Value arg) { - return !isa(arg.getType()) || - succeeded(checkSignalsAreObserved(obs, arg)); - })); - } - - // If the value is a module argument (no block arguments except for the entry - // block are allowed here) and was not observed, we cannot backtrack further - // and thus fail. - return failure(); -} - static LogicalResult isProcValidToLower(llhd::ProcessOp op) { size_t numBlocks = op.getBody().getBlocks().size(); @@ -98,13 +64,24 @@ static LogicalResult isProcValidToLower(llhd::ProcessOp op) { "during process-lowering: llhd.wait terminators with optional time " "argument cannot be lowered to structural LLHD"); + SmallVector observedSignals; + for (Value obs : wait.getObserved()) + if (auto prb = obs.getDefiningOp()) + if (!op.getBody().isAncestor(prb->getParentRegion())) + observedSignals.push_back(prb.getSignal()); + // Every probed signal has to occur in the observed signals list in // the wait instruction - WalkResult result = op.walk([&wait](llhd::PrbOp prbOp) -> WalkResult { - if (failed(checkSignalsAreObserved(wait.getObs(), prbOp.getSignal()))) - return wait.emitOpError( - "during process-lowering: the wait terminator is required to " - "have all probed signals as arguments"); + WalkResult result = op.walk([&](Operation *operation) -> WalkResult { + // TODO: value does not need to be observed if all values this value is + // a combinatorial result of are observed. + for (Value operand : operation->getOperands()) + if (!op.getBody().isAncestor(operand.getParentRegion()) && + !llvm::is_contained(wait.getObserved(), operand) && + !llvm::is_contained(observedSignals, operand)) + return wait.emitOpError( + "during process-lowering: the wait terminator is required to " + "have values used in the process as arguments"); return WalkResult::advance(); }); diff --git a/test/Conversion/MooreToCore/basic.mlir b/test/Conversion/MooreToCore/basic.mlir index f3d89bf635..3a0c872131 100644 --- a/test/Conversion/MooreToCore/basic.mlir +++ b/test/Conversion/MooreToCore/basic.mlir @@ -536,8 +536,19 @@ func.func private @dummyC() -> () // CHECK-LABEL: hw.module @WaitEvent moore.module @WaitEvent() { // CHECK: %a = llhd.sig + // CHECK: [[PRB_A6:%.+]] = llhd.prb %a + // CHECK: [[PRB_A5:%.+]] = llhd.prb %a + // CHECK: [[PRB_A4:%.+]] = llhd.prb %a + // CHECK: [[PRB_A3:%.+]] = llhd.prb %a + // CHECK: [[PRB_A2:%.+]] = llhd.prb %a + // CHECK: [[PRB_A1:%.+]] = llhd.prb %a + // CHECK: [[PRB_A0:%.+]] = llhd.prb %a // CHECK: %b = llhd.sig + // CHECK: [[PRB_B2:%.+]] = llhd.prb %b + // CHECK: [[PRB_B1:%.+]] = llhd.prb %b + // CHECK: [[PRB_B0:%.+]] = llhd.prb %b // CHECK: %c = llhd.sig + // CHECK: [[PRB_C:%.+]] = llhd.prb %c %a = moore.variable : %b = moore.variable : %c = moore.variable : @@ -569,7 +580,7 @@ moore.module @WaitEvent() { // CHECK: llhd.process { moore.procedure initial { // CHECK: [[BEFORE:%.+]] = llhd.prb %a - // CHECK: llhd.wait (%a : {{.+}}), ^[[CHECK:.+]] + // CHECK: llhd.wait ([[PRB_A0]] : {{.+}}), ^[[CHECK:.+]] // CHECK: ^[[CHECK]]: // CHECK: [[AFTER:%.+]] = llhd.prb %a // CHECK: [[TMP:%.+]] = comb.icmp bin ne [[BEFORE]], [[AFTER]] @@ -585,7 +596,7 @@ moore.module @WaitEvent() { moore.procedure initial { // CHECK: [[BEFORE_A:%.+]] = llhd.prb %a // CHECK: [[BEFORE_B:%.+]] = llhd.prb %b - // CHECK: llhd.wait (%a, %b : {{.+}}), ^[[CHECK:.+]] + // CHECK: llhd.wait ([[PRB_A1]], [[PRB_B0]] : {{.+}}), ^[[CHECK:.+]] // CHECK: ^[[CHECK]]: // CHECK: [[AFTER_A:%.+]] = llhd.prb %a // CHECK: [[AFTER_B:%.+]] = llhd.prb %b @@ -605,7 +616,7 @@ moore.module @WaitEvent() { // CHECK: [[BEFORE_A:%.+]] = llhd.prb %a // CHECK: [[BEFORE_B:%.+]] = llhd.prb %b // CHECK: [[BEFORE_C:%.+]] = llhd.prb %c - // CHECK: llhd.wait (%a, %b, %c : {{.+}}), ^[[CHECK:.+]] + // CHECK: llhd.wait ([[PRB_A2]], [[PRB_B1]], [[PRB_C]] : {{.+}}), ^[[CHECK:.+]] // CHECK: ^[[CHECK]]: // CHECK: [[AFTER_A:%.+]] = llhd.prb %a // CHECK: [[AFTER_B:%.+]] = llhd.prb %b @@ -629,7 +640,7 @@ moore.module @WaitEvent() { // CHECK: llhd.process { moore.procedure initial { // CHECK: [[BEFORE:%.+]] = llhd.prb %a - // CHECK: llhd.wait (%a : {{.+}}), ^[[CHECK:.+]] + // CHECK: llhd.wait ([[PRB_A3]] : {{.+}}), ^[[CHECK:.+]] // CHECK: ^[[CHECK]]: // CHECK: [[AFTER:%.+]] = llhd.prb %a // CHECK: [[TRUE:%.+]] = hw.constant true @@ -646,7 +657,7 @@ moore.module @WaitEvent() { // CHECK: llhd.process { moore.procedure initial { // CHECK: [[BEFORE:%.+]] = llhd.prb %a - // CHECK: llhd.wait (%a : {{.+}}), ^[[CHECK:.+]] + // CHECK: llhd.wait ([[PRB_A4]] : {{.+}}), ^[[CHECK:.+]] // CHECK: ^[[CHECK]]: // CHECK: [[AFTER:%.+]] = llhd.prb %a // CHECK: [[TRUE:%.+]] = hw.constant true @@ -663,7 +674,7 @@ moore.module @WaitEvent() { // CHECK: llhd.process { moore.procedure initial { // CHECK: [[BEFORE:%.+]] = llhd.prb %a - // CHECK: llhd.wait (%a : {{.+}}), ^[[CHECK:.+]] + // CHECK: llhd.wait ([[PRB_A5]] : {{.+}}), ^[[CHECK:.+]] // CHECK: ^[[CHECK]]: // CHECK: [[AFTER:%.+]] = llhd.prb %a // CHECK: [[TRUE:%.+]] = hw.constant true @@ -682,7 +693,7 @@ moore.module @WaitEvent() { // CHECK: llhd.process { moore.procedure initial { - // CHECK: llhd.wait (%a, %b : + // CHECK: llhd.wait ([[PRB_A6]], [[PRB_B2]] : moore.wait_event { %0 = moore.constant 0 : i1 %1 = moore.conditional %0 : i1 -> i1 { diff --git a/test/Dialect/LLHD/Canonicalization/probeCSE.mlir b/test/Dialect/LLHD/Canonicalization/probeCSE.mlir index c1b968830c..8568ec6ddf 100644 --- a/test/Dialect/LLHD/Canonicalization/probeCSE.mlir +++ b/test/Dialect/LLHD/Canonicalization/probeCSE.mlir @@ -18,7 +18,8 @@ hw.module @checkPrbDceAndCseIn(inout %arg0 : i32, inout %arg1 : i32, inout %arg2 // CHECK-LABEL: @checkPrbDceButNotCse hw.module @checkPrbDceButNotCse(inout %arg0 : i32, inout %arg1 : i32, inout %arg2 : i32) { - // CHECK-NEXT: llhd.process + %prb = llhd.prb %arg0 : !hw.inout + // CHECK: llhd.process llhd.process { // CHECK-NEXT: llhd.constant_time %time = llhd.constant_time <0ns, 1d, 0e> @@ -26,7 +27,7 @@ hw.module @checkPrbDceButNotCse(inout %arg0 : i32, inout %arg1 : i32, inout %arg // CHECK-NEXT: [[P1:%.*]] = llhd.prb %1 = llhd.prb %arg0 : !hw.inout // CHECK-NEXT: llhd.wait - llhd.wait (%arg0: !hw.inout), ^bb1 + llhd.wait (%prb: i32), ^bb1 // CHECK-NEXT: ^bb1: ^bb1: // CHECK-NEXT: [[P2:%.*]] = llhd.prb diff --git a/test/Dialect/LLHD/IR/basic.mlir b/test/Dialect/LLHD/IR/basic.mlir index fb27f3f064..618d1a05b0 100644 --- a/test/Dialect/LLHD/IR/basic.mlir +++ b/test/Dialect/LLHD/IR/basic.mlir @@ -176,10 +176,14 @@ hw.module @check_wait_1 () { // CHECK: @check_wait_2(inout %[[ARG0:.*]] : i64, inout %[[ARG1:.*]] : i1) { hw.module @check_wait_2 (inout %arg0 : i64, inout %arg1 : i1) { + // CHECK: [[PRB0:%.+]] = llhd.prb %arg0 + %prb0 = llhd.prb %arg0 : !hw.inout + // CHECK: [[PRB1:%.+]] = llhd.prb %arg1 + %prb1 = llhd.prb %arg1 : !hw.inout // CHECK-NEXT: llhd.process llhd.process { - // CHECK-NEXT: llhd.wait (%[[ARG0]], %[[ARG1]] : !hw.inout, !hw.inout), ^[[BB:.*]](%[[ARG1]] : !hw.inout) - llhd.wait (%arg0, %arg1 : !hw.inout, !hw.inout), ^bb1(%arg1 : !hw.inout) + // CHECK-NEXT: llhd.wait ([[PRB0]], [[PRB1]] : i64, i1), ^[[BB:.*]](%[[ARG1]] : !hw.inout) + llhd.wait (%prb0, %prb1 : i64, i1), ^bb1(%arg1 : !hw.inout) // CHECK: ^[[BB]](%[[A:.*]]: !hw.inout): ^bb1(%a: !hw.inout): llhd.halt @@ -188,12 +192,16 @@ hw.module @check_wait_2 (inout %arg0 : i64, inout %arg1 : i1) { // CHECK: hw.module @check_wait_3(inout %[[ARG0:.*]] : i64, inout %[[ARG1:.*]] : i1) { hw.module @check_wait_3 (inout %arg0 : i64, inout %arg1 : i1) { + // CHECK: [[PRB0:%.+]] = llhd.prb %arg0 + %prb0 = llhd.prb %arg0 : !hw.inout + // CHECK: [[PRB1:%.+]] = llhd.prb %arg1 + %prb1 = llhd.prb %arg1 : !hw.inout // CHECK-NEXT: llhd.process llhd.process { // CHECK-NEXT: %[[TIME:.*]] = llhd.constant_time %time = llhd.constant_time #llhd.time<0ns, 0d, 0e> - // CHECK-NEXT: llhd.wait for %[[TIME]], (%[[ARG0]], %[[ARG1]] : !hw.inout, !hw.inout), ^[[BB:.*]](%[[ARG1]], %[[ARG0]] : !hw.inout, !hw.inout) - llhd.wait for %time, (%arg0, %arg1 : !hw.inout, !hw.inout), ^bb1(%arg1, %arg0 : !hw.inout, !hw.inout) + // CHECK-NEXT: llhd.wait for %[[TIME]], ([[PRB0]], [[PRB1]] : i64, i1), ^[[BB:.*]](%[[ARG1]], %[[ARG0]] : !hw.inout, !hw.inout) + llhd.wait for %time, (%prb0, %prb1 : i64, i1), ^bb1(%arg1, %arg0 : !hw.inout, !hw.inout) // CHECK: ^[[BB]](%[[A:.*]]: !hw.inout, %[[B:.*]]: !hw.inout): ^bb1(%a: !hw.inout, %b: !hw.inout): llhd.halt diff --git a/test/Dialect/LLHD/Transforms/earlyCodeMotion.mlir b/test/Dialect/LLHD/Transforms/earlyCodeMotion.mlir index 9cdf16d1f0..3ab23494b8 100644 --- a/test/Dialect/LLHD/Transforms/earlyCodeMotion.mlir +++ b/test/Dialect/LLHD/Transforms/earlyCodeMotion.mlir @@ -123,6 +123,7 @@ hw.module @check_blockarg(inout %sig : i32) { // CHECK-LABEL: @loop // CHECK-SAME: (inout %[[VAL_0:.*]] : i2) +// CHECK: [[PRB:%.+]] = llhd.prb %in_i // CHECK: llhd.process // CHECK: %[[VAL_1:.*]] = hw.constant 0 : i32 // CHECK: %[[VAL_2:.*]] = hw.constant 2 : i32 @@ -138,7 +139,7 @@ hw.module @check_blockarg(inout %sig : i32) { // CHECK: %[[VAL_8:.*]] = llhd.prb %[[VAL_0]] : !hw.inout // CHECK: cf.cond_br %[[VAL_7]], ^[[BB4:.+]], ^[[BB3:.+]] // CHECK: ^[[BB3]]: -// CHECK: llhd.wait (%[[VAL_0]] : !hw.inout), ^[[BB1]] +// CHECK: llhd.wait ([[PRB]] : i2), ^[[BB1]] // CHECK: ^[[BB4]]: // CHECK: %[[VAL_9:.*]] = llhd.load %[[VAL_5]] : !llhd.ptr // CHECK: %[[VAL_10:.*]] = comb.add %[[VAL_9]], %[[VAL_4]] : i32 @@ -146,6 +147,7 @@ hw.module @check_blockarg(inout %sig : i32) { // CHECK: cf.br ^[[BB2]] // CHECK: } hw.module @loop(inout %in_i : i2) { + %prb0 = llhd.prb %in_i : !hw.inout llhd.process { // TR: -1 cf.br ^body @@ -162,7 +164,7 @@ hw.module @loop(inout %in_i : i2) { cf.cond_br %2, ^loop_continue, ^check ^check: // TR: 1 - llhd.wait (%in_i : !hw.inout), ^body + llhd.wait (%prb0 : i2), ^body ^loop_continue: // TR: 1 %3 = hw.constant 0 : i2 @@ -177,6 +179,8 @@ hw.module @loop(inout %in_i : i2) { // CHECK-LABEL: @complicated // CHECK-SAME: (inout %[[VAL_0:.*]] : i1, inout %[[VAL_1:.*]] : i1, inout %[[VAL_2:.*]] : i1, inout %[[VAL_3:.*]] : i1, inout %[[VAL_4:.*]] : i1) +// CHECK: [[PRB_CLK:%.+]] = llhd.prb %[[VAL_1]] +// CHECK: [[PRB_RST:%.+]] = llhd.prb %[[VAL_0]] // CHECK: llhd.process // CHECK: %[[ALLSET:.*]] = hw.constant true // CHECK: %[[VAL_5:.*]] = hw.constant false @@ -191,7 +195,7 @@ hw.module @loop(inout %in_i : i2) { // CHECK: %[[VAL_10:.*]] = llhd.prb %[[VAL_0]] : !hw.inout // CHECK: %[[VAL_11:.*]] = comb.icmp eq %[[VAL_9]], %[[VAL_5]] : i1 // CHECK: %[[VAL_12:.*]] = comb.icmp ne %[[VAL_10]], %[[VAL_5]] : i1 -// CHECK: llhd.wait (%[[VAL_1]], %[[VAL_0]] : !hw.inout, !hw.inout), ^[[BB3:.+]] +// CHECK: llhd.wait ([[PRB_CLK]], [[PRB_RST]] : i1, i1), ^[[BB3:.+]] // CHECK: ^[[BB3]]: // CHECK: %[[VAL_13:.*]] = llhd.prb %[[VAL_3]] : !hw.inout // CHECK: llhd.store %[[VAL_8]], %[[VAL_13]] : !llhd.ptr @@ -221,6 +225,8 @@ hw.module @loop(inout %in_i : i2) { // CHECK: cf.br ^[[BB1]] // CHECK: } hw.module @complicated(inout %rst_ni: i1, inout %clk_i: i1, inout %async_ack_i: i1, inout %ack_src_q: i1, inout %ack_q: i1) { + %prb_clk = llhd.prb %clk_i : !hw.inout + %prb_rst = llhd.prb %rst_ni : !hw.inout llhd.process { %allset = hw.constant 1 : i1 // TR: -1 @@ -234,7 +240,7 @@ hw.module @complicated(inout %rst_ni: i1, inout %clk_i: i1, inout %async_ack_i: // TR: 2 %clk_i_prb = llhd.prb %clk_i : !hw.inout %rst_ni_prb = llhd.prb %rst_ni : !hw.inout - llhd.wait (%clk_i, %rst_ni : !hw.inout, !hw.inout), ^check + llhd.wait (%prb_clk, %prb_rst : i1, i1), ^check ^check: // TR: 0 %2 = llhd.prb %ack_src_q : !hw.inout diff --git a/test/Dialect/LLHD/Transforms/memoryToBlockArgument.mlir b/test/Dialect/LLHD/Transforms/memoryToBlockArgument.mlir index 50cc527fce..2c259e61e3 100644 --- a/test/Dialect/LLHD/Transforms/memoryToBlockArgument.mlir +++ b/test/Dialect/LLHD/Transforms/memoryToBlockArgument.mlir @@ -262,6 +262,7 @@ hw.module @multiple_store_one_block() { // CHECK-LABEL: @loop // CHECK-SAME: (inout %[[VAL_0:.*]] : i2) +// CHECK: [[PRB:%.+]] = llhd.prb %[[VAL_0]] // CHECK: cf.br ^bb1 // CHECK: ^bb1: // CHECK: %[[VAL_1:.*]] = hw.constant 0 : i32 @@ -271,7 +272,7 @@ hw.module @multiple_store_one_block() { // CHECK: %[[VAL_4:.*]] = comb.icmp ult %[[VAL_2]], %[[VAL_3]] : i32 // CHECK: cf.cond_br %[[VAL_4]], ^bb4, ^bb3 // CHECK: ^bb3: -// CHECK: llhd.wait (%[[VAL_0]] : !hw.inout), ^bb1 +// CHECK: llhd.wait ([[PRB]] : i2), ^bb1 // CHECK: ^bb4: // CHECK: %[[VAL_5:.*]] = hw.constant 0 : i2 // CHECK: %[[VAL_6:.*]] = hw.constant 1 : i32 @@ -279,6 +280,7 @@ hw.module @multiple_store_one_block() { // CHECK: cf.br ^bb2(%[[VAL_7]] : i32) // CHECK: } hw.module @loop(inout %in_i : i2) { + %prb = llhd.prb %in_i : !hw.inout llhd.process { cf.br ^body ^body: @@ -291,7 +293,7 @@ hw.module @loop(inout %in_i : i2) { %2 = comb.icmp ult %i_ld, %1 : i32 cf.cond_br %2, ^loop_continue, ^check ^check: - llhd.wait (%in_i : !hw.inout), ^body + llhd.wait (%prb : i2), ^body ^loop_continue: %3 = hw.constant 0 : i2 %5 = hw.constant 1 : i32 diff --git a/test/Dialect/LLHD/Transforms/processLowering.mlir b/test/Dialect/LLHD/Transforms/processLowering.mlir index c293354198..8420c3cb80 100644 --- a/test/Dialect/LLHD/Transforms/processLowering.mlir +++ b/test/Dialect/LLHD/Transforms/processLowering.mlir @@ -23,31 +23,41 @@ hw.module @simpleWait() { // Check wait with observing probed signals // CHECK-LABEL: hw.module @prbAndWait hw.module @prbAndWait(inout %arg0 : i64) { + // CHECK-NEXT: %{{.*}} = llhd.prb + %1 = llhd.prb %arg0 : !hw.inout llhd.process { // CHECK-NEXT: %{{.*}} = llhd.prb // CHECK-NEXT: hw.output cf.br ^bb1 ^bb1: %0 = llhd.prb %arg0 : !hw.inout - llhd.wait (%arg0 : !hw.inout), ^bb1 + llhd.wait (%1 : i64), ^bb1 } } // Check wait with observing probed signals // CHECK-LABEL: hw.module @prbAndWaitMoreObserved hw.module @prbAndWaitMoreObserved(inout %arg0 : i64, inout %arg1 : i64) { + // CHECK-NEXT: %{{.*}} = llhd.prb + %1 = llhd.prb %arg0 : !hw.inout + // CHECK-NEXT: %{{.*}} = llhd.prb + %2 = llhd.prb %arg1 : !hw.inout llhd.process { // CHECK-NEXT: %{{.*}} = llhd.prb // CHECK-NEXT: hw.output cf.br ^bb1 ^bb1: %0 = llhd.prb %arg0 : !hw.inout - llhd.wait (%arg0, %arg1 : !hw.inout, !hw.inout), ^bb1 + llhd.wait (%1, %2 : i64, i64), ^bb1 } } // CHECK-LABEL: hw.module @muxedSignal hw.module @muxedSignal(inout %arg0 : i64, inout %arg1 : i64) { + // CHECK-NEXT: %{{.*}} = llhd.prb + %1 = llhd.prb %arg0 : !hw.inout + // CHECK-NEXT: %{{.*}} = llhd.prb + %2 = llhd.prb %arg1 : !hw.inout llhd.process { cf.br ^bb1 ^bb1: @@ -58,28 +68,32 @@ hw.module @muxedSignal(inout %arg0 : i64, inout %arg1 : i64) { %cond = hw.constant true %sig = comb.mux %cond, %arg0, %arg1 : !hw.inout %0 = llhd.prb %sig : !hw.inout - llhd.wait (%arg0, %arg1 : !hw.inout, !hw.inout), ^bb1 + llhd.wait (%1, %2 : i64, i64), ^bb1 } } // CHECK-LABEL: hw.module @muxedSignal2 hw.module @muxedSignal2(inout %arg0 : i64, inout %arg1 : i64) { + // CHECK-NEXT: %{{.*}} = hw.constant + // CHECK-NEXT: %{{.*}} = comb.mux + // CHECK-NEXT: %{{.*}} = llhd.prb + %cond = hw.constant true + %sig = comb.mux %cond, %arg0, %arg1 : !hw.inout + %0 = llhd.prb %sig : !hw.inout llhd.process { cf.br ^bb1 ^bb1: - // CHECK-NEXT: %{{.*}} = hw.constant - // CHECK-NEXT: %{{.*}} = comb.mux - // CHECK-NEXT: %{{.*}} = llhd.prb + // CHECK-NEXT: comb.and + %1 = comb.and %0, %0 : i64 // CHECK-NEXT: hw.output - %cond = hw.constant true - %sig = comb.mux %cond, %arg0, %arg1 : !hw.inout - %0 = llhd.prb %sig : !hw.inout - llhd.wait (%sig : !hw.inout), ^bb1 + llhd.wait (%0 : i64), ^bb1 } } // CHECK-LABEL: hw.module @partialSignal hw.module @partialSignal(inout %arg0 : i64) { + // CHECK-NEXT: %{{.*}} = llhd.prb + %1 = llhd.prb %arg0 : !hw.inout llhd.process { cf.br ^bb1 ^bb1: @@ -90,6 +104,6 @@ hw.module @partialSignal(inout %arg0 : i64) { %c = hw.constant 16 : i6 %sig = llhd.sig.extract %arg0 from %c : (!hw.inout) -> !hw.inout %0 = llhd.prb %sig : !hw.inout - llhd.wait (%arg0 : !hw.inout), ^bb1 + llhd.wait (%1 : i64), ^bb1 } } diff --git a/test/Dialect/LLHD/Transforms/processLoweringErrors.mlir b/test/Dialect/LLHD/Transforms/processLoweringErrors.mlir index 7e2a6dfe6d..0ecf436263 100644 --- a/test/Dialect/LLHD/Transforms/processLoweringErrors.mlir +++ b/test/Dialect/LLHD/Transforms/processLoweringErrors.mlir @@ -6,7 +6,7 @@ hw.module @prbAndWaitNotObserved(inout %arg0 : i64) { cf.br ^bb1 ^bb1: %0 = llhd.prb %arg0 : !hw.inout - // expected-error @+1 {{during process-lowering: the wait terminator is required to have all probed signals as arguments}} + // expected-error @+1 {{during process-lowering: the wait terminator is required to have values used in the process as arguments}} llhd.wait ^bb1 } } @@ -17,9 +17,10 @@ hw.module @prbAndWaitNotObserved(inout %arg0 : i64) { hw.module @blockArgumentsNotAllowed(inout %arg0 : i64) { // expected-error @+1 {{during process-lowering: the second block (containing the llhd.wait) is not allowed to have arguments}} llhd.process { - cf.br ^bb1(%arg0 : !hw.inout) - ^bb1(%a : !hw.inout): - llhd.wait ^bb1(%a : !hw.inout) + %prb = llhd.prb %arg0 : !hw.inout + cf.br ^bb1(%prb : i64) + ^bb1(%a : i64): + llhd.wait ^bb1(%a: i64) } } @@ -83,7 +84,7 @@ hw.module @muxedSignal(inout %arg0 : i64, inout %arg1 : i64, inout %arg2 : i1) { %cond = llhd.prb %arg2 : !hw.inout %sig = comb.mux %cond, %arg0, %arg1 : !hw.inout %0 = llhd.prb %sig : !hw.inout - // expected-error @+1 {{during process-lowering: the wait terminator is required to have all probed signals as arguments}} - llhd.wait (%arg0, %arg2 : !hw.inout, !hw.inout), ^bb1 + // expected-error @+1 {{during process-lowering: the wait terminator is required to have values used in the process as arguments}} + llhd.wait (%cond : i1), ^bb1 } } diff --git a/test/Dialect/LLHD/Transforms/temporal-code-motion.mlir b/test/Dialect/LLHD/Transforms/temporal-code-motion.mlir index 00889d6d12..fb5c8d0394 100644 --- a/test/Dialect/LLHD/Transforms/temporal-code-motion.mlir +++ b/test/Dialect/LLHD/Transforms/temporal-code-motion.mlir @@ -32,6 +32,14 @@ hw.module @basic(in %cond: i1) { %n = llhd.sig %c0_i5 : i5 %o = llhd.sig %c0_i5 : i5 + %prb_k = llhd.prb %k : !hw.inout + %prb_c = llhd.prb %c : !hw.inout + %prb_e = llhd.prb %e : !hw.inout + %prb_h = llhd.prb %h : !hw.inout + %prb_d = llhd.prb %d : !hw.inout + %prb_f = llhd.prb %f : !hw.inout + %prb_g = llhd.prb %g : !hw.inout + // COM: Check that an auxillary block is created and all drives are moved to // COM: the exit block with the correct enable condition // CHECK: llhd.process @@ -41,7 +49,7 @@ hw.module @basic(in %cond: i1) { // CHECK: ^[[BB1]]: ^bb1: // CHECK: llhd.wait ({{.*}}), ^[[BB2:.+]] - llhd.wait (%k, %c, %e, %h, %d, %f, %g : !hw.inout, !hw.inout, !hw.inout, !hw.inout, !hw.inout, !hw.inout, !hw.inout), ^bb2 + llhd.wait (%prb_k, %prb_c, %prb_e, %prb_h, %prb_d, %prb_f, %prb_g : i5, i1, i1, i4, i1, i1, i4), ^bb2 // CHECK: ^[[BB2]]: ^bb2: // CHECK: [[V14:%.+]] = llhd.prb %k