Optimize dominator computation and SSA.is_used_later

pull/87/head
Josselin 6 years ago
parent d601645c52
commit 9355e8a4b1
  1. 20
      slither/core/dominators/utils.py
  2. 44
      slither/slithir/utils/ssa.py

@ -31,16 +31,18 @@ def compute_dominators(nodes):
# compute immediate dominator
for node in nodes:
all_dom = []
idom_candidates = set(node.dominators)
idom_candidates.remove(node)
for dominator in node.dominators:
doms = list(dominator.dominators)
doms.remove(dominator)
all_dom = all_dom + doms
idom = [d for d in all_dom if all_dom.count(d) == 1]
assert len(idom)<=1
if idom:
node.immediate_dominator = idom[0]
idom[0].dominator_successors.add(node)
if dominator != node:
[idom_candidates.remove(d) for d in dominator.dominators if d in idom_candidates and d!=dominator]
assert len(idom_candidates)<=1
if idom_candidates:
idom = idom_candidates.pop()
node.immediate_dominator = idom
idom.dominator_successors.add(node)

@ -62,7 +62,7 @@ def add_ssa_ir(function, all_state_variables_instances):
# The state variable is used
# And if the state variables is written in another function (otherwise its stay at index 0)
for (_, variable_instance) in all_state_variables_instances.items():
if is_used_later(function.entry_point, variable_instance, []):
if is_used_later(function.entry_point, variable_instance):
# rvalues are fixed in solc_parsing.declaration.function
function.entry_point.add_ssa_ir(Phi(StateIRVariable(variable_instance), set()))
@ -73,7 +73,7 @@ def add_ssa_ir(function, all_state_variables_instances):
for (variable, nodes) in node.phi_origins_local_variables.values():
if len(nodes)<2:
continue
if not is_used_later(node, variable, []):
if not is_used_later(node, variable):
continue
node.add_ssa_ir(Phi(LocalIRVariable(variable), nodes))
for (variable, nodes) in node.phi_origins_state_variables.values():
@ -163,7 +163,7 @@ def update_lvalue(new_ir, node, local_variables_instances, all_local_variables_i
to_update = to_update.points_to
to_update.points_to = new_var
def is_used_later(node, variable, visited):
def is_used_later(initial_node, variable):
# TODO: does not handle the case where its read and written in the declaration node
# It can be problematic if this happens in a loop/if structure
# Ex:
@ -172,21 +172,27 @@ def is_used_later(node, variable, visited):
# uint a = a;
# }
# ..
if node in visited:
return False
# shared visited
visited.append(node)
if isinstance(variable, LocalVariable):
if any(v.name == variable.name for v in node.local_variables_read):
return True
if any(v.name == variable.name for v in node.local_variables_written):
return False
if isinstance(variable, StateVariable):
if any(v.name == variable.name and v.contract == variable.contract for v in node.state_variables_read):
return True
if any(v.name == variable.name and v.contract == variable.contract for v in node.state_variables_written):
return False
return any(is_used_later(son, variable, visited) for son in node.sons)
to_explore = {initial_node}
explored = set()
while to_explore:
node = to_explore.pop()
explored.add(node)
if isinstance(variable, LocalVariable):
if any(v.name == variable.name for v in node.local_variables_read):
return True
if any(v.name == variable.name for v in node.local_variables_written):
return False
if isinstance(variable, StateVariable):
if any(v.name == variable.name and v.contract == variable.contract for v in node.state_variables_read):
return True
if any(v.name == variable.name and v.contract == variable.contract for v in node.state_variables_written):
return False
for son in node.sons:
if not son in explored:
to_explore.add(son)
return False
def generate_ssa_irs(node, local_variables_instances, all_local_variables_instances, state_variables_instances, all_state_variables_instances, init_local_variables_instances, visited):
@ -225,7 +231,7 @@ def generate_ssa_irs(node, local_variables_instances, all_local_variables_instan
if isinstance(ir, LibraryCall):
continue
for variable in all_state_variables_instances.values():
if not is_used_later(node, variable, []):
if not is_used_later(node, variable):
continue
new_var = StateIRVariable(variable)
new_var.index = all_state_variables_instances[variable.canonical_name].index + 1

Loading…
Cancel
Save