|
@@ -317,8 +317,75 @@ def find_inlinable_definitions(entry_point):
|
|
|
|
|
|
return eligible_defs
|
|
|
|
|
|
-class DefinitionScheduler(object):
|
|
|
- """Schedules definitions within a basic block."""
|
|
|
+class SimpleDefinitionScheduler(object):
|
|
|
+ """Schedules definitions within a basic block in the order they occur in."""
|
|
|
+ def __init__(self, lowering_state, definitions, flow):
|
|
|
+ self.lowering_state = lowering_state
|
|
|
+ self.definition_queue = definitions + [flow]
|
|
|
+ self.definition_set = set(self.definition_queue)
|
|
|
+
|
|
|
+ def use(self, definition):
|
|
|
+ """Creates a tree that produces the given definition's value."""
|
|
|
+ def_value = cfg_ir.get_def_value(definition)
|
|
|
+ if isinstance(def_value, LoweringState.inline_value_types):
|
|
|
+ return self.lowering_state.lower_value(def_value)
|
|
|
+ elif isinstance(def_value, cfg_ir.AllocateRootNode):
|
|
|
+ return tree_ir.LoadLocalInstruction(
|
|
|
+ self.lowering_state.get_root_node_name(def_value))
|
|
|
+ elif definition.has_value():
|
|
|
+ return self.lowering_state.create_definition_load(definition)
|
|
|
+ else:
|
|
|
+ return tree_ir.EmptyInstruction()
|
|
|
+
|
|
|
+ def get_schedulable_definition(self):
|
|
|
+ """Finds a schedulable definition. Returns None if there are no definitions left to
|
|
|
+ schedule."""
|
|
|
+ if len(self.definition_queue) == 0:
|
|
|
+ return None
|
|
|
+ else:
|
|
|
+ return self.definition_queue[-1]
|
|
|
+
|
|
|
+ def __schedule_single_def(self, definition, store_and_forget, statements):
|
|
|
+ if isinstance(definition, cfg_ir.FlowInstruction):
|
|
|
+ statements.append(self.lowering_state.lower_value(definition))
|
|
|
+ else:
|
|
|
+ # We're sure that we're dealing with a bona fide cfg_ir.Definition now.
|
|
|
+ definition_value = definition.value
|
|
|
+ if cfg_ir.is_value_def(definition_value, LoweringState.inline_value_types):
|
|
|
+ pass
|
|
|
+ else:
|
|
|
+ lowered_value = self.lowering_state.lower_value(definition_value)
|
|
|
+ if definition.has_value():
|
|
|
+ def_load = self.lowering_state.create_definition_load(definition)
|
|
|
+ statements.append(
|
|
|
+ tree_ir.IgnoreInstruction(def_load.create_store(lowered_value)))
|
|
|
+ if not store_and_forget:
|
|
|
+ statements.append(def_load)
|
|
|
+ else:
|
|
|
+ statements.append(lowered_value)
|
|
|
+
|
|
|
+ def has_scheduled(self, definition):
|
|
|
+ """Tests if the given definition has already been scheduled."""
|
|
|
+ return definition not in self.definition_set
|
|
|
+
|
|
|
+ def schedule(self, definition, store_and_forget=False):
|
|
|
+ """Schedules the given definition. The resulting tree is returned."""
|
|
|
+ assert definition in self.definition_set
|
|
|
+
|
|
|
+ index = self.definition_queue.index(definition)
|
|
|
+ defs_to_schedule = self.definition_queue[:index + 1]
|
|
|
+ del self.definition_queue[:index + 1]
|
|
|
+
|
|
|
+ statements = []
|
|
|
+ for schedule_def in defs_to_schedule:
|
|
|
+ self.definition_set.remove(schedule_def)
|
|
|
+ self.__schedule_single_def(schedule_def, store_and_forget, statements)
|
|
|
+
|
|
|
+ return tree_ir.create_block(*statements)
|
|
|
+
|
|
|
+class DependencyDefinitionScheduler(object):
|
|
|
+ """Schedules definitions within a basic block in an order that tries to maximize
|
|
|
+ the inlining of expressions."""
|
|
|
# We now have the opportunity to schedule definitions in a somewhat intelligent way.
|
|
|
# We ought to make sure that we don't reorder operations in an observable way, though.
|
|
|
# Specifically:
|
|
@@ -615,13 +682,13 @@ class LoweringState(object):
|
|
|
def lower_block(self, block):
|
|
|
"""Lowers the given (relooped) block to a tree."""
|
|
|
statements = []
|
|
|
- self.scheduler = DefinitionScheduler(self, block.definitions, block.flow)
|
|
|
+ self.scheduler = SimpleDefinitionScheduler(self, block.definitions, block.flow)
|
|
|
while 1:
|
|
|
schedulable_def = self.scheduler.get_schedulable_definition()
|
|
|
if schedulable_def is None:
|
|
|
break
|
|
|
|
|
|
- statements.append(self.scheduler.schedule(schedulable_def))
|
|
|
+ statements.append(self.scheduler.schedule(schedulable_def, True))
|
|
|
|
|
|
self.scheduler = None
|
|
|
|