|
@@ -21,18 +21,22 @@ class BasicBlock(object):
|
|
self.definitions = []
|
|
self.definitions = []
|
|
self.counter = counter
|
|
self.counter = counter
|
|
self.index = counter.next_value()
|
|
self.index = counter.next_value()
|
|
|
|
+ self.definition_counter = SharedCounter()
|
|
self.flow = UnreachableFlow()
|
|
self.flow = UnreachableFlow()
|
|
|
|
|
|
def append_parameter(self, parameter):
|
|
def append_parameter(self, parameter):
|
|
"""Appends a parameter to this basic block."""
|
|
"""Appends a parameter to this basic block."""
|
|
result = self.create_definition(parameter)
|
|
result = self.create_definition(parameter)
|
|
self.parameters.append(result)
|
|
self.parameters.append(result)
|
|
|
|
+ if len(self.definitions) > 0:
|
|
|
|
+ self.renumber_definitions()
|
|
return result
|
|
return result
|
|
|
|
|
|
def prepend_definition(self, value):
|
|
def prepend_definition(self, value):
|
|
"""Defines the given value in this basic block."""
|
|
"""Defines the given value in this basic block."""
|
|
result = self.create_definition(value)
|
|
result = self.create_definition(value)
|
|
self.definitions.insert(0, result)
|
|
self.definitions.insert(0, result)
|
|
|
|
+ self.renumber_definitions()
|
|
return result
|
|
return result
|
|
|
|
|
|
def append_definition(self, value):
|
|
def append_definition(self, value):
|
|
@@ -47,12 +51,23 @@ class BasicBlock(object):
|
|
return value
|
|
return value
|
|
else:
|
|
else:
|
|
assert isinstance(value, Value) or value is None
|
|
assert isinstance(value, Value) or value is None
|
|
- return Definition(self.counter.next_value(), value)
|
|
|
|
|
|
+ return Definition(
|
|
|
|
+ self.counter.next_value(),
|
|
|
|
+ self.definition_counter.next_value(),
|
|
|
|
+ value)
|
|
|
|
|
|
def remove_definition(self, definition):
|
|
def remove_definition(self, definition):
|
|
"""Removes the given definition from this basic block."""
|
|
"""Removes the given definition from this basic block."""
|
|
return self.definitions.remove(definition)
|
|
return self.definitions.remove(definition)
|
|
|
|
|
|
|
|
+ def renumber_definitions(self):
|
|
|
|
+ """Re-numbers all definitions in this basic block."""
|
|
|
|
+ self.definition_counter = SharedCounter()
|
|
|
|
+ for definition in self.parameters:
|
|
|
|
+ definition.renumber(self.definition_counter.next_value())
|
|
|
|
+ for definition in self.definitions:
|
|
|
|
+ definition.renumber(self.definition_counter.next_value())
|
|
|
|
+
|
|
def __str__(self):
|
|
def __str__(self):
|
|
prefix = '!%d(%s):' % (self.index, ', '.join(map(str, self.parameters)))
|
|
prefix = '!%d(%s):' % (self.index, ', '.join(map(str, self.parameters)))
|
|
return '\n'.join(
|
|
return '\n'.join(
|
|
@@ -61,8 +76,9 @@ class BasicBlock(object):
|
|
|
|
|
|
class Definition(object):
|
|
class Definition(object):
|
|
"""Maps a value to a variable."""
|
|
"""Maps a value to a variable."""
|
|
- def __init__(self, index, value):
|
|
|
|
|
|
+ def __init__(self, index, definition_index, value):
|
|
self.index = index
|
|
self.index = index
|
|
|
|
+ self.definition_index = definition_index
|
|
self.value = value
|
|
self.value = value
|
|
if value is not None:
|
|
if value is not None:
|
|
assert isinstance(value, Value)
|
|
assert isinstance(value, Value)
|
|
@@ -73,6 +89,10 @@ class Definition(object):
|
|
if new_value is not None:
|
|
if new_value is not None:
|
|
assert isinstance(new_value, Value)
|
|
assert isinstance(new_value, Value)
|
|
|
|
|
|
|
|
+ def renumber(self, new_definition_index):
|
|
|
|
+ """Updates this definition's index in the block that defines it."""
|
|
|
|
+ self.definition_index = new_definition_index
|
|
|
|
+
|
|
def ref_str(self):
|
|
def ref_str(self):
|
|
"""Gets a string that represents a reference to this definition."""
|
|
"""Gets a string that represents a reference to this definition."""
|
|
return '$%d' % self.index
|
|
return '$%d' % self.index
|