|
@@ -230,7 +230,7 @@ def erase_parameters(entry_point, parameters_to_erase):
|
|
|
|
|
|
def try_redefine_as_direct_call(definition, jit, called_globals):
|
|
|
"""Tries to redefine the given indirect call definition as a direct call."""
|
|
|
- call = definition.value
|
|
|
+ call = cfg_ir.get_def_value(definition)
|
|
|
if not isinstance(call, cfg_ir.IndirectFunctionCall):
|
|
|
return
|
|
|
|
|
@@ -258,13 +258,49 @@ def try_redefine_as_direct_call(definition, jit, called_globals):
|
|
|
cfg_ir.DirectFunctionCall(
|
|
|
thunk_name, call.argument_list, cfg_ir.JIT_CALLING_CONVENTION))
|
|
|
|
|
|
+def get_checked_global(definition):
|
|
|
+ """If the definition is a check that tests if a global does not exist, then
|
|
|
+ the instruction that resolves the global is returned; otherwise None."""
|
|
|
+ def_value = cfg_ir.get_def_value(definition)
|
|
|
+ if not isinstance(def_value, cfg_ir.Binary):
|
|
|
+ return None
|
|
|
+
|
|
|
+ if def_value.operator != 'is':
|
|
|
+ return None
|
|
|
+
|
|
|
+ def __get_checked_global_single_dir(lhs, rhs):
|
|
|
+ if (isinstance(lhs, cfg_ir.ResolveGlobal)
|
|
|
+ and isinstance(rhs, cfg_ir.Literal)
|
|
|
+ and rhs.literal is None):
|
|
|
+ return lhs
|
|
|
+ else:
|
|
|
+ return None
|
|
|
+
|
|
|
+ bin_lhs = cfg_ir.get_def_value(def_value.lhs)
|
|
|
+ bin_rhs = cfg_ir.get_def_value(def_value.rhs)
|
|
|
+ result = __get_checked_global_single_dir(bin_lhs, bin_rhs)
|
|
|
+ if result is None:
|
|
|
+ result = __get_checked_global_single_dir(bin_rhs, bin_lhs)
|
|
|
+
|
|
|
+ return result
|
|
|
+
|
|
|
def optimize_calls(entry_point, jit):
|
|
|
"""Converts indirect calls to direct calls in the control-flow graph defined by the
|
|
|
given entry point."""
|
|
|
called_globals = set()
|
|
|
- for block in get_all_blocks(entry_point):
|
|
|
+ global_exists_defs = defaultdict(list)
|
|
|
+ all_blocks = list(get_all_blocks(entry_point))
|
|
|
+ for block in all_blocks:
|
|
|
for definition in block.definitions:
|
|
|
- try_redefine_as_direct_call(definition, jit, called_globals)
|
|
|
+ checked_global = get_checked_global(definition)
|
|
|
+ if checked_global is not None:
|
|
|
+ global_exists_defs[checked_global].append(definition)
|
|
|
+ else:
|
|
|
+ try_redefine_as_direct_call(definition, jit, called_globals)
|
|
|
+
|
|
|
+ for resolve_global in called_globals:
|
|
|
+ for exists_def in global_exists_defs[resolve_global]:
|
|
|
+ exists_def.redefine(cfg_ir.Literal(False))
|
|
|
|
|
|
def optimize(entry_point, jit):
|
|
|
"""Optimizes the control-flow graph defined by the given entry point."""
|
|
@@ -276,3 +312,4 @@ def optimize(entry_point, jit):
|
|
|
eliminate_unused_definitions(entry_point)
|
|
|
optimize_graph_flow(entry_point)
|
|
|
merge_blocks(entry_point)
|
|
|
+ eliminate_unused_definitions(entry_point)
|