llvm / circt

Circuit IR Compilers and Tools
https://circt.org
Other
1.67k stars 298 forks source link

[FIRRTL][Refs] Optimize through local send/resolve #4693

Closed dtzSiFive closed 1 year ago

dtzSiFive commented 1 year ago

Send and resolve pairs (read-only references) in same module can have the referent forwarded to the resolve. Consider:

firrtl.circuit "RefLocal" {
  firrtl.module @RefLocal(in %x : !firrtl.uint<2>, out %y : !firrtl.uint<2>) {
    %x_ref = firrtl.ref.send %x : !firrtl.uint<2>
    %x_by_another_name = firrtl.ref.resolve %x_ref: !firrtl.ref<uint<2>>
    firrtl.strictconnect %y, %x_by_another_name: !firrtl.uint<2>
  }
}

Current output:

// Generated by CIRCT 1.31.0g20230217_f4a1235
module RefLocal(    // ref-local.mlir:2:3
  input  [1:0] x,   // ref-local.mlir:2:30
  output [1:0] y    // ref-local.mlir:2:56
);

  assign y = RefLocal.x;    // ref-local.mlir:2:3, :4:26
endmodule

This could more simply be assign y = x;, and converting this earlier may open up for further optimizations/simplifications/DCE.

Should be able to emit simpler references when target is in same module, orthogonal to improvements that replace the dataflow with a direct use or connect operation.

dtzSiFive commented 1 year ago

Reverted that fix, that idea has legs but the approach was too simple to support where things are going. Tackle later.

dtzSiFive commented 1 year ago

Fixed in https://github.com/llvm/circt/commit/f39e8e788c5e3ea4cf7d2e7533bc4d26dcf0492d (thanks @seldridge ) and in follow-on commits support for Forceable added as well.

Original MLIR now generates the following output:

// Generated by CIRCT 1.42.0g20230517_0e0b40e
module RefLocal(    // issue-4693.mlir:2:3
  input  [1:0] x,   // issue-4693.mlir:2:30
  output [1:0] y    // issue-4693.mlir:2:56
);

  assign y = x; // issue-4693.mlir:2:3
endmodule