Skip to content

Problem: function copy don't work#4940

Open
yihuang wants to merge 2 commits intovyperlang:masterfrom
yihuang:master
Open

Problem: function copy don't work#4940
yihuang wants to merge 2 commits intovyperlang:masterfrom
yihuang:master

Conversation

@yihuang
Copy link
Copy Markdown

@yihuang yihuang commented Apr 25, 2026

What I did

Fix IRFunction copy method to preserve necessary fields.

How I did it

How to verify it

Commit message

Commit message for the final, squashed PR. (Optional, but reviewers will appreciate it! Please see our commit message style guide for what we would ideally like to see in a commit message.)

Description for the changelog

Cute Animal Picture

Put a link to a cute animal picture inside the parenthesis-->

Copilot AI review requested due to automatic review settings April 25, 2026 17:33
Copy link
Copy Markdown

Copilot AI left a comment

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 updates Venom IR function cloning to make IRFunction.copy() produce a more usable duplicate of a function’s basic blocks, addressing the reported issue that “function copy don’t work”.

Changes:

  • Clear the auto-created entry block when cloning, then rebuild the function from copied basic blocks.
  • Preserve last_variable across copies to keep variable numbering consistent.
  • Fix basic-block parent linkage (new_bb.parent = new) in the cloned function.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread vyper/venom/function.py
def copy(self):
new = IRFunction(self.name)
new.clear_basic_blocks()
new.last_variable = self.last_variable
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

IRFunction.copy() currently copies last_variable and basic blocks, but it doesn't copy other function-level metadata like _invoke_param_count / _has_memory_return_buffer_param. These fields influence invoke-related optimizations/analyses; dropping them on copy can change behavior compared to the original function. If the intent is a faithful clone, copy these fields as well (or document/reset them explicitly if not).

Suggested change
new.last_variable = self.last_variable
new.last_variable = self.last_variable
new._invoke_param_count = self._invoke_param_count
new._has_memory_return_buffer_param = self._has_memory_return_buffer_param

Copilot uses AI. Check for mistakes.
Comment thread vyper/venom/function.py
Comment on lines 130 to +132
new = IRFunction(self.name)
new.clear_basic_blocks()
new.last_variable = self.last_variable
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

Creating an IRFunction and immediately calling clear_basic_blocks() works, but it relies on the constructor always auto-inserting an entry block (which then becomes an unused orphan). Consider a dedicated constructor arg / classmethod for creating an empty IRFunction (used here and in FunctionInlinerPass._clone_function) to make cloning less error-prone and avoid creating throwaway blocks.

Copilot uses AI. Check for mistakes.
Comment thread vyper/venom/function.py
Comment on lines +132 to 137
new.last_variable = self.last_variable
for bb in self.get_basic_blocks():
new_bb = bb.copy()
new_bb.parent = new
new.append_basic_block(new_bb)

Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

This change is fixing core cloning behavior (variable counter + basic-block/function parent linkage). There are many Venom unit tests, but none appear to cover IRFunction.copy() specifically; adding a regression test that exercises copy() (and then runs at least one analysis/pass on the copy, or appends an instruction and checks variable naming) would help prevent this from breaking again.

Suggested change
new.last_variable = self.last_variable
for bb in self.get_basic_blocks():
new_bb = bb.copy()
new_bb.parent = new
new.append_basic_block(new_bb)
new.last_variable = self.last_variable
bb_map = {}
copied_bbs = []
for bb in self.get_basic_blocks():
new_bb = bb.copy()
new_bb.parent = new
new.append_basic_block(new_bb)
bb_map[bb] = new_bb
copied_bbs.append((bb, new_bb))
for old_bb, new_bb in copied_bbs:
if hasattr(new_bb, "out_bbs") and hasattr(old_bb, "out_bbs"):
new_bb.out_bbs = type(new_bb.out_bbs)(
bb_map.get(out_bb, out_bb) for out_bb in old_bb.out_bbs
)
if hasattr(new_bb, "in_bbs") and hasattr(old_bb, "in_bbs"):
new_bb.in_bbs = type(new_bb.in_bbs)(
bb_map.get(in_bb, in_bb) for in_bb in old_bb.in_bbs
)
new_bb.parent = new

Copilot uses AI. Check for mistakes.
Comment thread vyper/venom/function.py
@@ -128,8 +128,11 @@ def error_msg(self) -> Optional[str]:

def copy(self):
new = IRFunction(self.name)
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

IRFunction.copy() creates new = IRFunction(self.name) with no ctx, so new.ctx is None. Many analyses/passes assume fn.ctx exists (e.g. IRAnalysesCache._ensure_global_analyses_cache() dereferences self.function.ctx), so a copied function will crash if analyzed unless the caller manually reattaches a context. Consider constructing the copy with ctx=self.ctx (or explicitly setting new.ctx = self.ctx) so the copy is usable with the existing analysis/pass infrastructure.

Suggested change
new = IRFunction(self.name)
new = IRFunction(self.name, ctx=self.ctx)

Copilot uses AI. Check for mistakes.
@charles-cooper charles-cooper requested a review from harkal April 25, 2026 18:24
Copy link
Copy Markdown
Collaborator

@harkal harkal left a comment

Choose a reason for hiding this comment

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

This method is essentially dead code. We should probably remove it all-together.

@yihuang
Copy link
Copy Markdown
Author

yihuang commented Apr 26, 2026

This method is essentially dead code. We should probably remove it all-together.

we are experimenting with the API to build EVM bytecodes programmatically, we are not sure if it's the right approach yet, so no strong opinions on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants