-
-
Notifications
You must be signed in to change notification settings - Fork 804
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat[codegen]: deallocate variables after last use #4219
base: master
Are you sure you want to change the base?
Changes from 6 commits
38759d2
99c04ae
51aa936
7d8b64f
e0261dc
7ce131e
5d82615
c9fbfac
128de31
3ad92a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,7 @@ class VariableRecord: | |
defined_at: Any = None | ||
is_internal: bool = False | ||
alloca: Optional[Alloca] = None | ||
system: bool = False | ||
|
||
# the following members are probably dead | ||
is_immutable: bool = False | ||
|
@@ -121,6 +122,8 @@ def __init__( | |
|
||
self.settings = get_global_settings() | ||
|
||
self._to_deallocate = set() | ||
|
||
def is_constant(self): | ||
return self.constancy is Constancy.Constant or self.in_range_expr | ||
|
||
|
@@ -201,7 +204,7 @@ def deallocate_variable(self, varname, var): | |
|
||
# sanity check the type's size hasn't changed since allocation. | ||
n = var.typ.memory_bytes_required | ||
assert n == var.size | ||
assert n == var.size, var | ||
|
||
if self.settings.experimental_codegen: | ||
# do not deallocate at this stage because this will break | ||
|
@@ -212,6 +215,29 @@ def deallocate_variable(self, varname, var): | |
|
||
del self.vars[var.name] | ||
|
||
def mark_for_deallocation(self, varname): | ||
# for variables get deallocated anyway | ||
if varname in self.forvars: | ||
return | ||
if self.vars[varname].system: | ||
return | ||
self._to_deallocate.add(varname) | ||
|
||
# "mark-and-sweep", haha | ||
def sweep(self): | ||
tmp = set() | ||
for varname in self._to_deallocate: | ||
var = self.vars[varname] | ||
for s in self._scopes: | ||
if s not in var.blockscopes: | ||
# defer deallocation until we hit the end of its scope | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this accurate? we defer the dealoc until we hit its scope again (not necessarily its end) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. or if "it" refers to the scope then still we might have to wait until multiple scopes finish There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "it" refers to the scope of the variable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but we sweep after statements, right? a: uint256 = 0
for i: uint256 in range(1, 3):
a += i # <- can't dealoc, defer
b: uint256 = 0 # a already deallocated, swept after the for
b += 1
return b # actual scope end but a is already deallocated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yea, this is the idea here |
||
tmp.add(varname) | ||
break | ||
else: | ||
self.deallocate_variable(varname, self.vars[varname]) | ||
|
||
self._to_deallocate = tmp | ||
|
||
def _new_variable( | ||
self, | ||
name: str, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't we rather modify the analysis than create a new type of variable given it's used only at one place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea, it's a bit of a kludge, until we refactor
sqrt
to be either pure IR or a library function