Skip to content

feat(mlir): plumb cross-contract dependencies through the MLIR pipeline#461

Draft
hedgar2017 wants to merge 1 commit into
feat-slang-multi-contractfrom
feat-slang-mlir-cross-contract-deps
Draft

feat(mlir): plumb cross-contract dependencies through the MLIR pipeline#461
hedgar2017 wants to merge 1 commit into
feat-slang-multi-contractfrom
feat-slang-mlir-cross-contract-deps

Conversation

@hedgar2017
Copy link
Copy Markdown
Contributor

@hedgar2017 hedgar2017 commented May 28, 2026

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 could not resolve B's deploy bytecode at link time — the LLD pass produced non-ref undefined symbol: __datasize__$<hash>$__.

The Yul pipeline solves the same problem by walking each Yul object's body for datasize/dataoffset literal-string arguments and pushing them into a solx_codegen_evm::Dependencies struct 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: MlirOutput carries a Vec<String> of cross-contract references, solx_mlir::Context accumulates names via add_dependency (interior mut, since emitters hold &Context), and solx-core's ContractMLIR propagates them into the Dependencies struct fed to the assembler.

Dormant in this PR — no emitter calls Context::add_dependency yet, so the list is always empty and the link behavior is unchanged. tests/solidity/simple -O M3B3 produces 1896 passed / 3 failed / 307 invalid both with and without this change. The follow-up PR that lowers new B() to sol.new will 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.

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.
@hedgar2017 hedgar2017 added the ci:slang Trigger slang unit tests on PR label May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:slang Trigger slang unit tests on PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant