Polaris: cdg.cc Source File

cdg.cc

Go to the documentation of this file.
00001 ///
00002 ///
00003 ///
00004 ///
00005 ///
00006 /// $Documentation Manager$ = "Doxygen"
00007 ///
00008 /*!
00009   \file cdg.cc
00010   \author Silvius Rus
00011   \date 9/19/00
00012   \brief Implementation for cdg.h
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 /// Static global objects.
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 /// Exported objects
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 /// It assumes the CFG has nodes with outdegree at most 2.
00087 /// normalize_cfg should be called before this function to fix the CFG.
00088 /// Returns its pass tag.
00089 int cdg(ProgramUnit& pgm) {
00090   //Sanity check.
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 /// Let the fun begin.
00102 ///   _cdg_report_cycles=switch_value("cdg_report_cycles");
00103 ///   if (_cdg_report_cycles<1) 
00104   _cdg_report_cycles=0;
00105   StmtList& stmts=pgm.stmts();
00106 
00107 /// Start to build post-dominator tree.
00108   _cdg_pass = create_pass_tag();
00109 /// Build post-dominator tree.
00110   Array<Statement *> vertex(stmts.entries());
00111   pDominator(pgm, vertex, new pDominatorWorkSpace(_cdg_pass));
00112 
00113 /// Create CDG nodes for every statement.
00114   for (int i=0; i<vertex.entries(); i++){
00115     Statement* stmt=vertex[i];
00116     stmt->cdgnode(new CDGNode(stmt));
00117 
00118     /// ...  Fix the PDT so that it looks like the edge start->end had existed in CFG when the PDT was built.
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 /// Create the CDG.
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     /// ...  Set links in CDG:
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 /// Copy ipdom info to cdg nodes.
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 /// Clears "visited" field to all nodes in the program unit cdg.
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 /// Removes cdg nodes associated with all statements.
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 }
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:41 2005