circt icon indicating copy to clipboard operation
circt copied to clipboard

[SV] Why does `IfDefOp::thenRegion` enforce SSA dominance?

Open rsetaluri opened this issue 3 years ago • 3 comments

Issue

The following code

hw.module @m(%a: i8, %b: i8, %clk: i1) ->  () {
    %0 = sv.reg {name = "reg0"} : !hw.inout<i8>
    sv.alwaysff(posedge %clk) {
        sv.passign %0, %1 : i8
    }
    %1 = comb.or %a, %b : i8
}

works and produces fine Verilog even though %1 is used before it is defined.

However, this code does not:

hw.module @m(%a: i8, %b: i8, %clk: i1) ->  () {
    sv.ifdef "C" {
    %0 = sv.reg {name = "reg0"} : !hw.inout<i8>
    sv.alwaysff(posedge %clk) {
        sv.passign %0, %1 : i8
    }
    %1 = comb.or %a, %b : i8
    }
}

resulting in:

<stdin>:5:9: error: operand #1 does not dominate this use
        sv.passign %0, %1 : i8
        ^
<stdin>:5:9: note: see current operation: "sv.passign"(%0, %1) : (!hw.inout<i8>, i8) -> ()
<stdin>:7:10: note: operand defined here (op in a parent region)
    %1 = comb.or %a, %b : i8
         ^

Note the only difference is that the IR is now wrapped in an sv.ifdef.

Proposal

I'm not extremely familiar with the semantics of regions, but my understanding is that in GraphRegions SSA dominance is not enforced, and hw::ModuleOp is such a type of region. From my understanding of Verilog ifdef semantics, there are no restrictions as to what can be inside such directives. So I would presume that we could allow the same inside sv::IfDefOp?

Happy to discuss the requirement/use-case further.

rsetaluri avatar Sep 23 '22 00:09 rsetaluri

I think it makes sense to make IfDefOp to have graph regions. It's inconsistent that there is difference between HWModule and IfDefOp.

uenoku avatar Sep 23 '22 07:09 uenoku

Thanks @uenoku. What would be the code change required to make that happen?

rsetaluri avatar Sep 23 '22 16:09 rsetaluri

You can modify the region kind by defining RegionKindInterface for the operation. For example, HWModule: https://github.com/llvm/circt/blob/2966699d0ef01baba92ab7b43436d24df587b8ff/include/circt/Dialect/HW/HWStructure.td#L41-L78

Adding RegionKindInterface to the operation (Line 41) and defining getRegionKind (Line 78) are necessary.
You might have to include "mlir/IR/RegionKindInterface.td" into tablegen.

uenoku avatar Sep 23 '22 16:09 uenoku

@uenoku - great I will try that code change. Should we also consider removing the NonProceduralOp attribute? It seems similarly overly restrictive.

rsetaluri avatar Sep 30 '22 05:09 rsetaluri

Should we also consider removing the NonProceduralOp attribute?

I don't think so. There are IfDefProceduralOp and IfDefOp operations, and this distinction makes sense to me.

uenoku avatar Sep 30 '22 11:09 uenoku