Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
cleanUpWhirl.cxx
Go to the documentation of this file.
00001 #include <map>
00002 #include <set>
00003 #include "cleanUpWhirl.h"
00004 #include "wn_tree_util.h"
00005 #include "wn_util.h"
00006 #include "symtab.h"
00007 
00008 #define xDEBUG(flag,code) { if (flag) {code; fflush(stdout);} }
00009 #define DEB_CleanUpWhirl 0
00010 
00011 // the front-end introduces temporary variables 
00012 // for all kinds of expressions, in particular 
00013 // control flow related and in indices, already before the 
00014 // conversion to whirl.  These temporaries obfuscate 
00015 // the data dependencies by introducing an extra 
00016 // level of indirection. Replacing the temporary 
00017 // references with the respective right-hand-side 
00018 // expressions of their assignments is possible everywhere with 
00019 // the one exception of dimension computations within 
00020 // variable declarations. In the latter case there is no
00021 // location to represent these computations in whirl other than 
00022 // an explicit  assignment statement to a temporary. 
00023 // Therefore we currently do not remove any temporary assignments or 
00024 // the respective entries in the  symbol table. 
00025 void cleanUpPUInfo(PU_Info* aPUInfo_p) { 
00026   typedef std::map<ST*,std::pair<WN*,int> > STPtoWNPmap;
00027   STPtoWNPmap tempMap; 
00028   bool skipKids=false;
00029   WN* thePU_WN_p = PU_Info_tree_ptr(aPUInfo_p);
00030   xDEBUG(DEB_CleanUpWhirl, printf("cleanUpWhirl: doing %s\n",ST_name(WN_st(thePU_WN_p))););
00031   WN* parentWN_p=0;
00032   WN_TREE_CONTAINER<PRE_ORDER> aWNPtree(thePU_WN_p);
00033   WN_TREE_CONTAINER<PRE_ORDER>::iterator aWNPtreeIterator=aWNPtree.begin();
00034   while (aWNPtreeIterator != aWNPtree.end()) { 
00035     WN* curWN_p = aWNPtreeIterator.Wn();
00036     OPERATOR opr = WN_operator(curWN_p);
00037     if (opr==OPR_STID) {  // definitions
00038       if (ST_is_temp_var(WN_st(curWN_p))) {
00039         ST* tempST_p=WN_st(curWN_p);
00040         // is it not in the set?
00041         STPtoWNPmap::iterator mapIter=tempMap.find(tempST_p);
00042         if (mapIter == tempMap.end()) { //not found
00043           // add it
00044           tempMap.insert(std::pair<ST*,std::pair<WN*,int> >(tempST_p, std::pair<WN*,int>(WN_kid0(curWN_p),1)));
00045           const char* tmpName = ST_name(tempST_p); 
00046           ST* puST_p = ST_ptr(PU_Info_proc_sym(aPUInfo_p));
00047           const char* puName = ST_name(puST_p);
00048           xDEBUG(DEB_CleanUpWhirl, printf("cleanUpWhirl: recorded temporary %s defined in %s\n",tmpName, puName););
00049         }
00050         else { 
00051           // in many cases these are single assignment but in some cases 
00052           // there reassignments for instance when used in conjunction 
00053           // with PRESENT for optional parameters
00054           // where a different const value is assigned. 
00055           WN* defWN_p=(*mapIter).second.first;
00056           if (WN_operator(defWN_p)==OPR_INTCONST 
00057               && 
00058               WN_operator(WN_kid0(curWN_p))== OPR_INTCONST
00059               && WN_const_val(defWN_p)!=WN_const_val(WN_kid0(curWN_p))) {
00060             // assigning different values, i.e. can't replace
00061             Set_ST_keep_in_openad(tempST_p);
00062             ++((*mapIter).second.second);
00063           }
00064           else { 
00065             const char* tmpName = ST_name(tempST_p); 
00066             ST* puST_p = ST_ptr(PU_Info_proc_sym(aPUInfo_p));
00067             const char* puName = ST_name(puST_p);
00068             DevWarn("cleanUpWhirl: recorded temporary %s is redefined in %s\n",tmpName, puName);
00069           }
00070         }
00071       }
00072     }
00073     if (opr==OPR_LDID){ // uses
00074       // if we refer to a temp variable
00075       if (ST_is_temp_var(WN_st(curWN_p))) { 
00076         // that variable should have been added to the set
00077         // so find it: 
00078         ST* tempST_p=WN_st(curWN_p);
00079         STPtoWNPmap::iterator mapIter=tempMap.find(tempST_p);
00080         if (mapIter==tempMap.end()) { //not found
00081           // This shouldn't happen with local temporaries 
00082           // but some temporaries are  not local. For instance 
00083           // if we are in contained PU using an array from a containing PU 
00084           // then the array size comes down in a temporary defined in the 
00085           // containing PU
00086           const char* tmpName = ST_name(tempST_p); 
00087           ST* puST_p = ST_ptr(PU_Info_proc_sym(aPUInfo_p));
00088           const char* puName = ST_name(puST_p);
00089           xDEBUG(DEB_CleanUpWhirl, printf("cleanUpWhirl: no (local) definition for temporary %s in %s, probably defined in enclosing PU\n",tmpName,puName););
00090         }
00091         else { 
00092           // make sure the parent is set by now
00093           if (!aWNPtreeIterator.Get_parent_wn())
00094           Fatal_Error("cleanUpWhirl: no parent set");
00095           skipKids=true;
00096           // there was some very hackish logic implemented in whirl2f 
00097           // that sets an ST entry in all CASEGOTO nodes (even though they 
00098           // are not supposed to have symbols at all) that are  the children 
00099           // of a block following the LDID that is the first child of a 
00100           // SWITCH. If the switch condition is an expression we need to 
00101           // retain the temporary so here we inject the condtion that we will not 
00102           // to the replacement for an LDID directly under a SWITCH
00103           // and also not replace if we detected more than one definition
00104           if (WN_operator(aWNPtreeIterator.Get_parent_wn())!=OPR_SWITCH && (*mapIter).second.second==1) { 
00105             // replace the current node within the parent
00106             WN_kid(aWNPtreeIterator.Get_parent_wn(),aWNPtreeIterator.Get_kid_index()) = WN_COPY_Tree((*mapIter).second.first);
00107             const char* tmpName = ST_name(tempST_p); 
00108             ST* puST_p = ST_ptr(PU_Info_proc_sym(aPUInfo_p));
00109             const char* puName = ST_name(puST_p);
00110             xDEBUG(DEB_CleanUpWhirl, printf("cleanUpWhirl: subsituted temporary %s in %s\n",tmpName, puName););
00111           }
00112         }
00113       }
00114     } 
00115     // advance the iterator
00116     if (skipKids || opr==OPR_XPRAGMA){
00117       // XPRAGMAs may refer to temporaries before they are assigned
00118       aWNPtreeIterator.WN_TREE_next_skip();
00119       skipKids=false;
00120     }
00121     else
00122       ++aWNPtreeIterator;
00123   } // end while
00124 }
00125 
00126 // the C wrapper 
00127 extern "C" void cleanUpPUInfoTree(PU_Info* aPUInfoTree_p) { 
00128   if (!aPUInfoTree_p) { return; }
00129   cleanUpPUInfo(aPUInfoTree_p);
00130   // we cannot recur on the children because 
00131   // they are written *before* the parents and their 
00132   // Whirl rep is deallocated
00133 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines