00001
00002
00003
00004
00005
00006
00007
00008 #ifndef CFG_H_
00009 #define CFG_H_
00010
00011 #include <string>
00012 #include <vector>
00013 #include <map>
00014 #include <set>
00015 #include <deque>
00016 #include "Loop.h"
00017 #include "Identifier.h"
00018 using namespace std;
00019
00020 namespace sail {
00021 class BasicBlock;
00022 class Instruction;
00023 class Label;
00024 class CfgEdge;
00025 class Symbol;
00026 class Loop;
00027 class Block;
00028 class SuperBlock;
00029 class Function;
00030
00031
00032
00033
00034
00035
00036
00037 class CompareEdge:public binary_function<CfgEdge*, CfgEdge*, bool> {
00038
00039 public:
00040 bool operator()(const CfgEdge* e1, const CfgEdge* e2) const;
00041 };
00042
00043 class CompareBlock:public binary_function<BasicBlock*, BasicBlock*, bool> {
00044
00045 public:
00046 bool operator()(const Block* b1, const Block* b2) const;
00047 };
00048
00058 class Cfg {
00059 friend class boost::serialization::access;
00060
00061 template<class Archive>
00062 void serialize(Archive & ar, const unsigned int version)
00063 {
00064 ar & entry_block;
00065 ar & exit_block;
00066 ar & exception_block;
00067 ar & basic_blocks;
00068 ar & blocks;
00069 ar & super_blocks_ordered;
00070 ar & id_to_superblock;
00071 }
00072
00073 private:
00074 BasicBlock* entry_block;
00075 BasicBlock* exit_block;
00076
00077 BasicBlock* exception_block;
00078 set<BasicBlock*> basic_blocks;
00079 set<Block*> blocks;
00080
00081
00082 set<BasicBlock*> embedded_basic_blocks;
00083 set<CfgEdge*> edges;
00084 set<Loop*, LoopCompare> loops;
00085 map<BasicBlock*, Loop*> loopheaders;
00086 map<BasicBlock*, SuperBlock*> headers_to_superblocks;
00087 map<Label*, BasicBlock*> resolved_blocks;
00088 map<Label*, set<CfgEdge*> > unresolved_blocks;
00089
00090
00091
00092
00093
00094 map<string, SuperBlock*> id_to_superblock;
00095
00096
00097
00098
00099
00100 vector<SuperBlock*> super_blocks_ordered;
00101
00102 Function* f;
00103
00104 bool exit_fn_as_exception;
00105
00106
00107 public:
00115 Cfg(Function* f, bool exit_fn_modifies_control = false);
00116 Cfg();
00117 virtual ~Cfg();
00118
00126 string to_dotty(bool pretty_print = true);
00127
00131 set<Block*>& get_blocks();
00132
00137 set<BasicBlock*>& get_basic_blocks();
00138
00142 BasicBlock* get_entry_block();
00143
00148 BasicBlock* get_exit_block();
00149
00154 BasicBlock* get_exception_block();
00155
00161 SuperBlock* get_superblock(const Identifier & id);
00162
00167 const vector<SuperBlock*>& get_ordered_superblocks();
00168
00169 bool is_header_of_superblock(BasicBlock* b);
00170 SuperBlock* get_superblock_of_entry_block(BasicBlock* b);
00171
00172
00173 private:
00174 void build_cfg(vector<Instruction*>* body);
00175 int fill_basic_block(BasicBlock* cur, vector<Instruction*>* body,
00176 int start_index);
00177 bool is_control_instruction(Instruction* inst);
00178 BasicBlock* get_new_block(Instruction* inst);
00179 CfgEdge* connect_blocks(BasicBlock* pred, BasicBlock* succ, Symbol* cond);
00180 void add_unresolved_edge(Label* l, CfgEdge* e);
00181 void process_next_block(BasicBlock*& cur_block, int& cur_index,
00182 vector<Instruction*>* function_body);
00183 void process_jump_label(BasicBlock* cur_block, Label* l, Symbol* cond);
00184 void assign_block_ids();
00185 void print_cfg();
00186
00187 string blocks_to_dotty();
00188 bool check_cycle(bool edge);
00189 void optimize_cfg();
00190 void remove_unreachable_blocks();
00191 void remove_empty_blocks();
00192 void merge_redundant_blocks();
00193 void merge_blocks(BasicBlock* b1, BasicBlock* b2, CfgEdge* e);
00194 void make_reducible();
00195 void traverse_postorder(BasicBlock* cur, int& counter,
00196 set<BasicBlock*>& visited);
00197 void compute_dominators();
00198 void compute_post_dominators();
00199 void check_cfg();
00200 void identify_loops();
00201 void find_backedges();
00202 void get_edges(set<CfgEdge*>& edges);
00203 void finalize_cfg();
00204 void make_superblocks();
00205
00206 };
00207
00208 }
00209
00210 #endif