cdg.ccGo to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "utilities/switches_util.h"
00018 #include "cdg_types.h"
00019 #include "cdg.h"
00020
00021 #include <strings.h>
00022
00023 #include "normalize_cfg.h"
00024 #include "ProgramUnit.h"
00025 #include "utilities/dominator_util.h"
00026 #include "domtree/polaris_domtree.h"
00027 #include "p-assert.h"
00028
00029 #include "Timer.h"
00030
00031
00032
00033
00034
00035
00036 static int _cdg_pass;
00037
00038 inline static bool equal(Statement& s1, Statement& s2){
00039 if (&s1!=&s2) return False;
00040 return True;
00041 }
00042
00043 inline static Statement* pdt_parent(Statement* stmt){
00044 pDominatorWorkSpace& ws=*(pDominatorWorkSpace *) stmt->work_stack().top_ref(_cdg_pass);
00045 p_assert(&ws, "Statement without pDominatorWorkSpace.");
00046 return ws.idom;
00047 }
00048
00049 CDGNode* pdt_parent(CDGNode* child){
00050 Statement* parent=pdt_parent(child->cfgnode());
00051 if (parent){
00052 return parent->cdgnode();
00053 } else {
00054 return 0;
00055 }
00056 }
00057
00058 static bool postdominates(Statement& s1, Statement& s2){
00059 Statement* stmt=&s2;
00060 while (stmt){
00061 if (equal(*stmt,s1)) return True;
00062 stmt=pdt_parent(stmt);
00063 }
00064 return False;
00065 }
00066
00067
00068
00069
00070 inline CDSet& cd(CDGNode* cdgnode){
00071 return cdgnode->ins();
00072 }
00073
00074
00075
00076
00077
00078 int _cdg_report_cycles;
00079
00080
00081 bool postdominates(CDGNode* n1, CDGNode* n2){
00082 if (n1==0 || n2==0) return false;
00083 return postdominates(*(n1->cfgnode()), *(n2->cfgnode()));
00084 }
00085
00086
00087
00088
00089 int cdg(ProgramUnit& pgm) {
00090
00091 switch(pgm.pu_class()){
00092 case PROGRAM_PU_TYPE:
00093 case SUBROUTINE_PU_TYPE:
00094 case FUNCTION_PU_TYPE:
00095 break;
00096 default:
00097 p_warning("Input to cdg is not a program, subroutine, or function: skipping.");
00098 return 0;
00099 }
00100
00101
00102
00103
00104 _cdg_report_cycles=0;
00105 StmtList& stmts=pgm.stmts();
00106
00107
00108 _cdg_pass = create_pass_tag();
00109
00110 Array<Statement *> vertex(stmts.entries());
00111 pDominator(pgm, vertex, new pDominatorWorkSpace(_cdg_pass));
00112
00113
00114 for (int i=0; i<vertex.entries(); i++){
00115 Statement* stmt=vertex[i];
00116 stmt->cdgnode(new CDGNode(stmt));
00117
00118
00119 if (stmt->stmt_class()==FLOW_ENTRY_STMT){
00120 pDominatorWorkSpace& ws=*(pDominatorWorkSpace *) stmt->work_stack().top_ref(_cdg_pass);
00121 p_assert(&ws, "Statement without pDominatorWorkSpace.");
00122 ws.idom=vertex[0];
00123 }
00124 }
00125
00126
00127 for (int i=0; i<vertex.entries(); i++){
00128 Statement& A=*vertex[i];
00129 int which_branch=0;
00130 for (Iterator<Statement> stit=A.succ(); stit.valid(); ++stit, which_branch++){
00131 Statement& B=stit.current();
00132 if (postdominates(B,A)) continue;
00133
00134 bool branch;
00135 switch (which_branch){
00136 case 0:
00137 branch=False;
00138 break;
00139 case 1:
00140 branch=True;
00141 break;
00142 default:
00143 p_abort("Reduce the number of branches to 2 before building CDG!");
00144 }
00145 Statement* PA=&A;
00146 Statement* parent=pdt_parent(&A);
00147 if (parent) PA=parent;
00148 CDGNode* cdgA=A.cdgnode();
00149
00150 Statement* N=&B;
00151 while (!equal(*N,*PA)){
00152 CDGNode* cdgN=N->cdgnode();
00153 CDElement in(cdgA,branch);
00154 CDElement out(cdgN,branch);
00155
00156 cdgN->ins().ins(in);
00157 cdgA->outs().ins(out);
00158
00159 N=pdt_parent(N);
00160 p_assert(N,"Just missed PA, so it does not postdominate N.");
00161 }
00162 }
00163 }
00164
00165
00166
00167 for (int i=0; i<vertex.entries(); i++){
00168 CDGNode* child=vertex[i]->cdgnode();
00169 Statement* sparent=pdt_parent(vertex[i]);
00170 if (sparent==0) continue;
00171 CDGNode* parent=sparent->cdgnode();
00172 child->ipdom_parent(parent);
00173 parent->ipdom_children().push_back(child);
00174 }
00175
00176 return _cdg_pass;
00177 }
00178
00179
00180
00181
00182 void clear_cdg_visited(ProgramUnit& pgm, int reset_value){
00183 for(Iterator<Statement> stit=pgm.stmts().iterator(); stit.valid();++stit){
00184 CDGNode* cdgnode=stit.current().cdgnode();
00185 if (!cdgnode) {
00186 String msg="\nCDG node does not exist for statement ";
00187 msg+=stit.current().tag();
00188 msg+=".\n";
00189 p_warning(msg);
00190 }
00191 cdgnode->visited(reset_value);
00192 }
00193 }
00194
00195
00196
00197 void uncdg(ProgramUnit& pgm){
00198 for(Iterator<Statement> stit=pgm.stmts().iterator(); stit.valid();++stit){
00199 CDGNode* cdgnode=stit.current().cdgnode();
00200 if (cdgnode) {
00201 delete cdgnode;
00202 stit.current().cdgnode(0);
00203 }
00204 }
00205 }
|