diff options
| author | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2015-02-25 12:49:06 +0100 |
|---|---|---|
| committer | serpilliere <fabrice.desclaux@cea.fr> | 2015-03-12 21:15:06 +0100 |
| commit | 0d7ddae798c44b327a5d9ef563b7c0bd201334bf (patch) | |
| tree | 9f4a30bf29c06b168897aaed6a6f919148b0afcc /miasm2/core/graph.py | |
| parent | 07c41ae8ee2b8fb8aaa117eb27af2d8a91a18e5d (diff) | |
| download | miasm-0d7ddae798c44b327a5d9ef563b7c0bd201334bf.tar.gz miasm-0d7ddae798c44b327a5d9ef563b7c0bd201334bf.zip | |
Graph: add postdominators computation
Diffstat (limited to 'miasm2/core/graph.py')
| -rw-r--r-- | miasm2/core/graph.py | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/miasm2/core/graph.py b/miasm2/core/graph.py index 5fed8d78..643c602b 100644 --- a/miasm2/core/graph.py +++ b/miasm2/core/graph.py @@ -216,3 +216,45 @@ shape = "box" for succ in self.successors_iter(node): todo.add(succ) return dict(dominators) + + + def compute_postdominators(self, leaf): + """Compute postdominators of the graph""" + nodes = set(self.reachable_parents(leaf)) + postdominators = defaultdict(set) + for node in nodes: + postdominators[node].update(nodes) + + postdominators[leaf] = set([leaf]) + modified = True + todo = set(nodes) + + while todo: + node = todo.pop() + + # Leaf state must not be changed + if node == leaf: + continue + + # Compute intersection of all successors'postdominators + new_post_dom = None + for succ in self.successors_iter(node): + if not succ in nodes: + continue + if new_post_dom is None: + new_post_dom = set(postdominators[succ]) + new_post_dom.intersection_update(postdominators[succ]) + + # We are not a leaf to we have at least one post dominator + assert(new_post_dom is not None) + + new_post_dom.update(set([node])) + + # If intersection has changed, add sons to the todo list + if new_post_dom == postdominators[node]: + continue + + postdominators[node] = new_post_dom + for succ in self.predecessors_iter(node): + todo.add(succ) + return dict(postdominators) |