Skip to content

Commit

Permalink
feat[venom]: cleanup variable version handling (vyperlang#4404)
Browse files Browse the repository at this point in the history
refactor `IRVariable` so that parsing cannot result in a nonzero
`.version` (it should only be modified by internal passes).

---------

Co-authored-by: Charles Cooper <[email protected]>
  • Loading branch information
harkal and charles-cooper authored Dec 18, 2024
1 parent f31ff46 commit 296a071
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 28 deletions.
48 changes: 27 additions & 21 deletions vyper/venom/basicblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,20 @@ class IROperand:
"""

value: Any
_hash: Optional[int]

def __init__(self, value: Any) -> None:
self.value = value
self._hash = None

@property
def name(self) -> str:
return self.value

def __hash__(self) -> int:
return hash(self.value)
if self._hash is None:
self._hash = hash(self.value)
return self._hash

def __eq__(self, other) -> bool:
if not isinstance(other, type(self)):
Expand All @@ -140,6 +147,7 @@ class IRLiteral(IROperand):
value: int

def __init__(self, value: int) -> None:
super().__init__(value)
assert isinstance(value, int), "value must be an int"
self.value = value

Expand All @@ -149,27 +157,25 @@ class IRVariable(IROperand):
IRVariable represents a variable in IR. A variable is a string that starts with a %.
"""

value: str

def __init__(self, value: str, version: Optional[str | int] = None) -> None:
assert isinstance(value, str)
assert ":" not in value, "Variable name cannot contain ':'"
if version:
assert isinstance(value, str) or isinstance(value, int), "value must be an str or int"
value = f"{value}:{version}"
if value[0] != "%":
value = f"%{value}"
self.value = value
_name: str
version: Optional[int]

def __init__(self, name: str, version: int = 0) -> None:
super().__init__(name)
assert isinstance(name, str)
assert isinstance(version, int | None)
if not name.startswith("%"):
name = f"%{name}"
self._name = name
self.version = version
if version > 0:
self.value = f"{name}:{version}"
else:
self.value = name

@property
def name(self) -> str:
return self.value.split(":")[0]

@property
def version(self) -> int:
if ":" not in self.value:
return 0
return int(self.value.split(":")[1])
return self._name


class IRLabel(IROperand):
Expand All @@ -184,7 +190,7 @@ class IRLabel(IROperand):

def __init__(self, value: str, is_symbol: bool = False) -> None:
assert isinstance(value, str), "value must be an str"
self.value = value
super().__init__(value)
self.is_symbol = is_symbol


Expand Down Expand Up @@ -464,7 +470,7 @@ def remove_cfg_out(self, bb: "IRBasicBlock") -> None:
self.cfg_out.remove(bb)

def append_instruction(
self, opcode: str, *args: Union[IROperand, int], ret: IRVariable = None
self, opcode: str, *args: Union[IROperand, int], ret: Optional[IRVariable] = None
) -> Optional[IRVariable]:
"""
Append an instruction to the basic block
Expand Down
8 changes: 1 addition & 7 deletions vyper/venom/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,7 @@ def LABEL(self, label) -> IRLabel:
return IRLabel(label[1:])

def VAR_IDENT(self, var_ident) -> IRVariable:
parts = var_ident[1:].split(":", maxsplit=1)
assert 1 <= len(parts) <= 2
varname = parts[0]
version = None
if len(parts) > 1:
version = int(parts[1])
return IRVariable(varname, version=version)
return IRVariable(var_ident[1:])

def CONST(self, val) -> IRLiteral:
return IRLiteral(int(val))
Expand Down

0 comments on commit 296a071

Please sign in to comment.