feat(mlir): plumb cross-contract dependencies through the MLIR pipeline#461
feat(mlir): plumb cross-contract dependencies through the MLIR pipeline#461hedgar2017 wants to merge 1 commit into
Conversation
7fe873f to
f579275
Compare
With per-contract MLIR emission, the linker assembles bytecodes across contracts but only sees the dependencies declared on each `EVMContractObject`. The MLIR branch in `solx-core/src/project/contract/mod.rs` was constructing those with only the contract's own runtime identifier, so `new B()` from contract A had no way to resolve B's deploy bytecode at link time. Mirroring how the Yul pipeline walks `datasize`/`dataoffset` calls to populate `Dependencies`, this change adds a `Vec<String>` of cross-contract references to `MlirOutput` and threads it through `solx_mlir::Context` (interior mut, since emitters hold `&Context`), through `solx-core`'s `ContractMLIR`, and into the `Dependencies` struct fed to the assembler. Dormant until an emitter calls `Context::add_dependency` — no test delta today. The follow-up wiring `new B()` to `sol.new` will populate the list and make cross-contract creation linkable.
4d54a1d to
1ce6f24
Compare
There was a problem hiding this comment.
Pull request overview
This PR extends the MLIR (Slang→MLIR) pipeline to carry cross-contract dependency information through to the solx-codegen-evm assembler/linker dependency mechanism, matching the existing behavior/pattern used by the Yul pipeline. Although the dependency list is currently not populated by any emitter, the plumbing is added end-to-end so future emitters can record cross-contract references (e.g., sol.new) for correct link-time resolution.
Changes:
- Add a
dependencies: Vec<String>field tosolx-mlir::MlirOutputand tosolx-core’s MLIR IR representation so it can be serialized/deserialized and propagated. - Add dependency collection to
solx_mlir::Contextvia interior mutability (add_dependency) and drain it intoMlirOutputatfinalize_module. - Thread MLIR dependencies into
solx_codegen_evm::Dependenciesconstruction in the MLIR compilation path insolx-core.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
solx-mlir/src/output.rs |
Adds serialized dependencies field to MLIR pipeline output. |
solx-mlir/src/context/mod.rs |
Introduces dependency accumulation (RefCell<Vec<String>>), add_dependency, and drains into MlirOutput in finalize_module. |
solx-core/src/project/mod.rs |
Propagates MlirOutput.dependencies into ContractMLIR for deploy/runtime segments. |
solx-core/src/project/contract/mod.rs |
Pushes MLIR cross-contract dependencies into solx_codegen_evm::Dependencies for MLIR objects during object construction. |
solx-core/src/project/contract/ir/mlir.rs |
Adds dependencies field to the internal MLIR IR struct used by solx-core. |
abinavpp
left a comment
There was a problem hiding this comment.
how exactly will we track the dependencies? every time we visit the new, creationCode, runtimeCode? I think it'll be better to combine supports for them here so that we can review how this change will enable those lowering.
With per-contract MLIR emission, the linker assembles bytecodes across contracts but only sees the dependencies declared on each
EVMContractObject. The MLIR branch insolx-core/src/project/contract/mod.rswas constructing those with only the contract's own runtime identifier, sonew B()from contract A could not resolve B's deploy bytecode at link time — the LLD pass producednon-ref undefined symbol: __datasize__$<hash>$__.The Yul pipeline solves the same problem by walking each Yul object's body for
datasize/dataoffsetliteral-string arguments and pushing them into asolx_codegen_evm::Dependenciesstruct that the assembler later consumes (solx-yul/src/parser/statement/expression/function_call/mod.rs:112-135). This change mirrors that pattern for the MLIR side:MlirOutputcarries aVec<String>of cross-contract references,solx_mlir::Contextaccumulates names viaadd_dependency(interior mut, since emitters hold&Context), andsolx-core'sContractMLIRpropagates them into theDependenciesstruct fed to the assembler.Dormant in this PR — no emitter calls
Context::add_dependencyyet, so the list is always empty and the link behavior is unchanged.tests/solidity/simple -O M3B3produces 1896 passed / 3 failed / 307 invalid both with and without this change. The follow-up PR that lowersnew B()tosol.newwill start populating the list; from that point the assembler will resolve cross-contract deploy-code references the same way it already does for the Yul pipeline.