Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 }