|
@@ -175,11 +175,50 @@ def eliminate_unused_definitions(entry_point):
|
|
|
for dead_def in dead_defs:
|
|
|
dead_def.block.remove_definition(dead_def)
|
|
|
|
|
|
-def optimize(entry_point):
|
|
|
+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
|
|
|
+ if not isinstance(call, cfg_ir.IndirectFunctionCall):
|
|
|
+ return
|
|
|
+
|
|
|
+ target = cfg_ir.get_def_value(call.target)
|
|
|
+ if isinstance(target, cfg_ir.LoadPointer):
|
|
|
+ loaded_ptr = cfg_ir.get_def_value(target.pointer)
|
|
|
+ if isinstance(loaded_ptr, cfg_ir.ResolveGlobal):
|
|
|
+ resolved_var_name = loaded_ptr.variable.name
|
|
|
+
|
|
|
+ # # Try to resolve the callee as an intrinsic.
|
|
|
+ # intrinsic = jit.get_intrinsic(resolved_var_name)
|
|
|
+ # if intrinsic is not None:
|
|
|
+ # return redefine_as_intrinsic(definition, intrinsic, call.argument_list)
|
|
|
+
|
|
|
+ # Otherwise, build a thunk.
|
|
|
+ thunk_name = jit.jit_thunk_global(resolved_var_name)
|
|
|
+ definition.redefine(
|
|
|
+ cfg_ir.DirectFunctionCall(
|
|
|
+ thunk_name, call.argument_list, cfg_ir.JIT_CALLING_CONVENTION))
|
|
|
+ called_globals.add(loaded_ptr)
|
|
|
+ elif isinstance(target, cfg_ir.Literal):
|
|
|
+ node_id = target.literal
|
|
|
+ thunk_name = jit.jit_thunk_constant(node_id)
|
|
|
+ definition.redefine(
|
|
|
+ cfg_ir.DirectFunctionCall(
|
|
|
+ thunk_name, call.argument_list, cfg_ir.JIT_CALLING_CONVENTION))
|
|
|
+
|
|
|
+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):
|
|
|
+ for definition in block.definitions:
|
|
|
+ try_redefine_as_direct_call(definition, jit, called_globals)
|
|
|
+
|
|
|
+def optimize(entry_point, jit):
|
|
|
"""Optimizes the control-flow graph defined by the given entry point."""
|
|
|
optimize_graph_flow(entry_point)
|
|
|
elide_local_checks(entry_point)
|
|
|
optimize_graph_flow(entry_point)
|
|
|
+ optimize_calls(entry_point, jit)
|
|
|
eliminate_unused_definitions(entry_point)
|
|
|
optimize_graph_flow(entry_point)
|
|
|
merge_blocks(entry_point)
|