|
@@ -3,6 +3,7 @@
|
|
import modelverse_jit.cfg_ir as cfg_ir
|
|
import modelverse_jit.cfg_ir as cfg_ir
|
|
import modelverse_jit.cfg_optimization as cfg_optimization
|
|
import modelverse_jit.cfg_optimization as cfg_optimization
|
|
import modelverse_jit.tree_ir as tree_ir
|
|
import modelverse_jit.tree_ir as tree_ir
|
|
|
|
+import modelverse_jit.runtime as jit_runtime
|
|
|
|
|
|
# The CFG deconstruction code here is based on the relooper algorithm
|
|
# The CFG deconstruction code here is based on the relooper algorithm
|
|
# as detailed in https://github.com/kripken/Relooper/blob/master/paper.pdf
|
|
# as detailed in https://github.com/kripken/Relooper/blob/master/paper.pdf
|
|
@@ -82,7 +83,7 @@ class MultipleBlock(object):
|
|
tree_ir.BinaryInstruction(
|
|
tree_ir.BinaryInstruction(
|
|
state.label_variable,
|
|
state.label_variable,
|
|
'==',
|
|
'==',
|
|
- tree_ir.LiteralInstruction(state.get_label_value(entry))),
|
|
|
|
|
|
+ tree_ir.LiteralInstruction(entry.index)),
|
|
block.lower(state),
|
|
block.lower(state),
|
|
result)
|
|
result)
|
|
return result
|
|
return result
|
|
@@ -279,27 +280,26 @@ class LoweringState(object):
|
|
def __init__(self, jit):
|
|
def __init__(self, jit):
|
|
self.jit = jit
|
|
self.jit = jit
|
|
self.label_variable = tree_ir.VariableName('__label')
|
|
self.label_variable = tree_ir.VariableName('__label')
|
|
- self.label_map = {}
|
|
|
|
self.definition_loads = {}
|
|
self.definition_loads = {}
|
|
|
|
|
|
- def get_label_value(self, block):
|
|
|
|
- """Gets the label value for the given block."""
|
|
|
|
- if block in self.label_map:
|
|
|
|
- return self.label_map[block]
|
|
|
|
|
|
+ def __create_value_load(self, value):
|
|
|
|
+ """Creates a tree that loads the given value."""
|
|
|
|
+ if value.has_value():
|
|
|
|
+ if isinstance(value, cfg_ir.Literal):
|
|
|
|
+ return tree_ir.LiteralInstruction(value.literal)
|
|
|
|
+ else:
|
|
|
|
+ return tree_ir.LoadLocalInstruction(None)
|
|
else:
|
|
else:
|
|
- result = len(self.label_map)
|
|
|
|
- self.label_map[block] = result
|
|
|
|
- return result
|
|
|
|
|
|
+ return tree_ir.LiteralInstruction(None)
|
|
|
|
|
|
def load_definition(self, definition):
|
|
def load_definition(self, definition):
|
|
"""Loads the given definition's variable."""
|
|
"""Loads the given definition's variable."""
|
|
if definition in self.definition_loads:
|
|
if definition in self.definition_loads:
|
|
return self.definition_loads[definition]
|
|
return self.definition_loads[definition]
|
|
|
|
|
|
- if definition.instruction.has_value():
|
|
|
|
- raise NotImplementedError()
|
|
|
|
- else:
|
|
|
|
- raise NotImplementedError()
|
|
|
|
|
|
+ result = self.__create_value_load(definition.value)
|
|
|
|
+ self.definition_loads[definition] = result
|
|
|
|
+ return result
|
|
|
|
|
|
def lower_block(self, block):
|
|
def lower_block(self, block):
|
|
"""Lowers the given (relooped) block to a tree."""
|
|
"""Lowers the given (relooped) block to a tree."""
|
|
@@ -313,8 +313,9 @@ class LoweringState(object):
|
|
"""Lowers the given definition to a tree."""
|
|
"""Lowers the given definition to a tree."""
|
|
instruction = definition.value
|
|
instruction = definition.value
|
|
tree_instruction = self.lower_instruction(instruction)
|
|
tree_instruction = self.lower_instruction(instruction)
|
|
- if instruction.has_value():
|
|
|
|
- return self.load_definition(definition).create_store(tree_instruction)
|
|
|
|
|
|
+ def_load = self.load_definition(definition)
|
|
|
|
+ if isinstance(def_load, tree_ir.LocalInstruction):
|
|
|
|
+ return def_load.create_store(tree_instruction)
|
|
else:
|
|
else:
|
|
return tree_instruction
|
|
return tree_instruction
|
|
|
|
|
|
@@ -324,4 +325,54 @@ class LoweringState(object):
|
|
|
|
|
|
def lower_flow(self, flow):
|
|
def lower_flow(self, flow):
|
|
"""Lowers the given (relooped) flow instruction to a tree."""
|
|
"""Lowers the given (relooped) flow instruction to a tree."""
|
|
- raise NotImplementedError()
|
|
|
|
|
|
+ flow_type = type(flow)
|
|
|
|
+ if flow_type in LoweringState.flow_lowerings:
|
|
|
|
+ return LoweringState.flow_lowerings[flow_type](self, flow)
|
|
|
|
+ else:
|
|
|
|
+ raise jit_runtime.JitCompilationFailedException(
|
|
|
|
+ "Unknown CFG flow instruction: '%s'" % flow)
|
|
|
|
+
|
|
|
|
+ def lower_jump(self, flow):
|
|
|
|
+ """Lowers the given 'jump' flow instruction to a tree."""
|
|
|
|
+ return self.lower_branch(flow.branch)
|
|
|
|
+
|
|
|
|
+ def lower_select(self, flow):
|
|
|
|
+ """Lowers the given 'select' flow instruction to a tree."""
|
|
|
|
+ return tree_ir.SelectInstruction(
|
|
|
|
+ self.load_definition(flow.condition),
|
|
|
|
+ self.lower_branch(flow.if_branch),
|
|
|
|
+ self.lower_branch(flow.else_branch))
|
|
|
|
+
|
|
|
|
+ def lower_return(self, flow):
|
|
|
|
+ """Lowers the given 'return' flow instruction to a tree."""
|
|
|
|
+ return tree_ir.ReturnInstruction(self.load_definition(flow.value))
|
|
|
|
+
|
|
|
|
+ def lower_unreachable(self, _):
|
|
|
|
+ """Lowers the given 'unreachable' flow instruction to a tree."""
|
|
|
|
+ return tree_ir.EmptyInstruction()
|
|
|
|
+
|
|
|
|
+ def lower_break(self, _):
|
|
|
|
+ """Lowers the given 'break' flow instruction to a tree."""
|
|
|
|
+ return tree_ir.BreakInstruction()
|
|
|
|
+
|
|
|
|
+ def lower_continue(self, _):
|
|
|
|
+ """Lowers the given 'continue' flow instruction to a tree."""
|
|
|
|
+ return tree_ir.ContinueInstruction()
|
|
|
|
+
|
|
|
|
+ def lower_branch(self, branch):
|
|
|
|
+ """Lowers the given (relooped) branch to a tree."""
|
|
|
|
+ for param, arg in zip(branch.block.parameters, branch.arguments):
|
|
|
|
+ self.load_definition(param).create_store(self.load_definition(arg))
|
|
|
|
+
|
|
|
|
+ return tree_ir.StoreLocalInstruction(
|
|
|
|
+ self.label_variable,
|
|
|
|
+ tree_ir.LiteralInstruction(branch.block.index))
|
|
|
|
+
|
|
|
|
+ flow_lowerings = {
|
|
|
|
+ cfg_ir.JumpFlow : lower_jump,
|
|
|
|
+ cfg_ir.SelectFlow : lower_select,
|
|
|
|
+ cfg_ir.ReturnFlow : lower_return,
|
|
|
|
+ cfg_ir.UnreachableFlow : lower_unreachable,
|
|
|
|
+ BreakFlow : lower_break,
|
|
|
|
+ ContinueFlow : lower_continue
|
|
|
|
+ }
|