Skip to content

Commit

Permalink
[blocks] Add dominance analysis over CFGs
Browse files Browse the repository at this point in the history
Dominance is important for correctly identifying loops and their
properties. This patch implements a dominator analysis that finds out
immediate dominators for all the blocks of the CFG, it also builds a
dominator tree using the idoms.

The dominator analysis also support building postdominator tree for the
CFG, and it can also build postdominator tree for loops without exits or
infinite loops.

This patch also implements several other important utilities like
postorder DFS and preorder DFS traversal of the CFG.

This patch implements the dominance algorithm from the paper
"A Simple, Fast Dominance Algorithm" [1] as it is easiest to implement
and is practically faster than the Lengauer-Tarjan dominance algorithm.

[1] http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
  • Loading branch information
VedantParanjape committed Feb 26, 2024
1 parent c37ad9a commit 30c6edd
Show file tree
Hide file tree
Showing 4 changed files with 531 additions and 0 deletions.
55 changes: 55 additions & 0 deletions include/blocks/dominance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef DOMINANCE_H
#define DOMINANCE_H
#include "blocks/block_visitor.h"
#include "blocks/basic_blocks.h"
#include "blocks/stmt.h"
#include <map>
#include <vector>
#include <stack>
#include <string>
#include <bitset>
#include <algorithm>

namespace block {
class dominator_analysis {
public:
dominator_analysis(basic_block::cfg_block cfg, bool is_postdom = false);
basic_block::cfg_block cfg_;
bool is_postdom_;
int max_depth;
unsigned int max_depth_bb_id;
std::vector<int> &get_postorder_bb_map();
std::vector<int> &get_postorder();
std::vector<int> &get_preorder_bb_map();
std::vector<int> &get_preorder();
std::vector<int> &get_idom();
std::map<int, std::vector<int>> &get_idom_map();
std::vector<int> &get_postorder_idom_map();
int get_idom(int bb_id);
std::vector<int> get_idom_map(int bb_id);
int get_postorder_idom_map(int idom_id);
bool dominates(int bb1_id, int bb2_id);
bool is_reachable_from_entry(int bb_id);
void analyze();

private:
std::vector<int> idom;
std::map<int, std::vector<int>> idom_map;
std::vector<int> postorder_idom;
std::vector<int> postorder;
std::vector<int> postorder_bb_map;
std::vector<int> preorder;
std::vector<int> preorder_bb_map;
void reverse_cfg();
void postorder_idom_helper(std::vector<bool> &visited, int id);
void postorder_dfs_helper(std::vector<bool> &visited_bbs, int id, int depth);
void postorder_dfs(bool reverse_cfg);
void preorder_dfs_helper(std::vector<bool> &visited_bbs, int id);
void preorder_dfs(bool reverse_cfg);
int intersect(int bb1_id, int bb2_id);
};

void dump(dominator_analysis &dom);
} // namespace block

#endif
1 change: 1 addition & 0 deletions include/builder/builder_context.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef BUILDER_CONTEXT
#define BUILDER_CONTEXT
#include "blocks/basic_blocks.h"
#include "blocks/dominance.h"
#include "blocks/expr.h"
#include "blocks/stmt.h"
#include "builder/forward_declarations.h"
Expand Down
Loading

0 comments on commit 30c6edd

Please sign in to comment.