Skip to content

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

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

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

@hedgar2017 hedgar2017 commented May 28, 2026

Copy link
Copy Markdown
Contributor

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.

@hedgar2017 hedgar2017 added the ci:slang Trigger slang unit tests on PR label May 28, 2026
@hedgar2017 hedgar2017 force-pushed the feat-slang-multi-contract branch from 7fe873f to f579275 Compare June 1, 2026 05:30
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 force-pushed the feat-slang-mlir-cross-contract-deps branch from 4d54a1d to 1ce6f24 Compare June 1, 2026 05:32
@hedgar2017 hedgar2017 requested a review from Copilot June 1, 2026 05:33
@hedgar2017 hedgar2017 self-assigned this Jun 1, 2026
@hedgar2017 hedgar2017 marked this pull request as ready for review June 1, 2026 05:33

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 to solx-mlir::MlirOutput and to solx-core’s MLIR IR representation so it can be serialized/deserialized and propagated.
  • Add dependency collection to solx_mlir::Context via interior mutability (add_dependency) and drain it into MlirOutput at finalize_module.
  • Thread MLIR dependencies into solx_codegen_evm::Dependencies construction in the MLIR compilation path in solx-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 abinavpp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

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.

3 participants