OpenADFortTk (basic)
src/lib/support/Open64IRInterface/CleanUpWhirl.cpp
Go to the documentation of this file.
00001 #include <set>
00002 #include "CleanUpWhirl.h"
00003 #include "IFDiagnostics.h"
00004 #include "WhirlGlobalStateUtils.h"
00005 
00006 PU_Info* CleanUpWhirl::findModulePU(PU_Info* aPUInfoForest_p,
00007                                     ST* moduleName_ST_p) { 
00008   PU_Info* aPUInfoTree_p;
00009   for (aPUInfoTree_p=aPUInfoForest_p; aPUInfoTree_p!= NULL; aPUInfoTree_p=PU_Info_next(aPUInfoTree_p)) {
00010     if (aPUInfoTree_p->proc_sym==ST_st_idx(*moduleName_ST_p))
00011       return aPUInfoTree_p;
00012   }
00013   DIE("findModulePU: no module %s\n",ST_name(moduleName_ST_p));
00014 }
00015                 
00016 
00017 void CleanUpWhirl::forPUInfoForest(PU_Info* aPUInfoForest_p) { 
00018   if (!aPUInfoForest_p) { return; }
00019   /* Loop through all the PU_Infos */
00020   PU_Info* aPUInfoTree_p;
00021   for (aPUInfoTree_p=aPUInfoForest_p; aPUInfoTree_p!= NULL; aPUInfoTree_p=PU_Info_next(aPUInfoTree_p)) {
00022     forPUInfoTree(aPUInfoTree_p,
00023                   aPUInfoForest_p);
00024   }
00025 } 
00026 
00027 void CleanUpWhirl::forPUInfoTree(PU_Info* aPUInfoTree_p,
00028                                  PU_Info* aTopPUInfo_p) { 
00029   if (!aPUInfoTree_p) { return; }
00030   forPUInfo(aPUInfoTree_p,
00031             aTopPUInfo_p);
00032   for (PU_Info *aPUInfosubtree_p = PU_Info_child(aPUInfoTree_p); 
00033        aPUInfosubtree_p != NULL; 
00034        aPUInfosubtree_p = PU_Info_next(aPUInfosubtree_p)) {
00035     forPUInfoTree(aPUInfosubtree_p,
00036                   aTopPUInfo_p);
00037   }
00038 }
00039 
00040 ST* CleanUpWhirl::findModuleSymbol(ST* moduleName_ST_p,
00041                                    ST* dummyLocal_ST_p,
00042                                    PU_Info* aTopPUInfo_p) { 
00043   INT level=ST_level(moduleName_ST_p); 
00044   // level should be the same as the module name symbol, i.e. 1 
00045   for (INT i = 1; 
00046        i < ST_Table_Size(level) ; 
00047        ++i) { 
00048     // get the symbol from the table
00049     ST* an_ST_p=&(St_Table(level,i));
00050     if ((ST_sclass(an_ST_p)==SCLASS_MODULE) // must be module storage class 
00051         && 
00052         (moduleName_ST_p== ST_base(an_ST_p)) // must be the same module symbol
00053         && 
00054         (strcmp(ST_name(an_ST_p),ST_name(dummyLocal_ST_p))==0)) // must match the name
00055       return an_ST_p;
00056   }
00057   // haven't found it yet.  This can be the case if the module variable is actually 
00058   // a fortran "PARAMETER" i.e. a constant for which the name won't match
00059   // because its name in the global symbol table is the constant value. 
00060   // we can't do anything here because the symbol table entry in the 
00061   // actual module isn't visible in this context (because whirl 
00062   // only distinguishes things by symbol table level (both would be level 2) 
00063   // and within that given level by "index"
00064   // so we don't do anything here under the assumption that the 
00065   // parameter in all references is being replaced by the actual value anyway
00066   PU_Info* theModulePU=findModulePU(aTopPUInfo_p,moduleName_ST_p);
00067   const char* dummyLocalName=ST_name(dummyLocal_ST_p);
00068   DBGMSG(2,"findModuleSymbol: not replacing presumed parameter with local name %s",dummyLocalName); 
00069   return dummyLocal_ST_p;       
00070 } 
00071 
00072 // in use statements the front-end generates
00073 // references to bogus local symbol table 
00074 // entries instead of the proper entries in the 
00075 // global symbol table. We replace these references.
00076 void CleanUpWhirl::forPUInfo(PU_Info* aPUInfo_p,
00077                              PU_Info* aTopPUInfo_p) {
00078   PU_SetGlobalState(aPUInfo_p);
00079   WN *pragmaWN_p=0, *parentBlockWN_p=0;
00080   WN* thePU_WN_p = PU_Info_tree_ptr(aPUInfo_p);
00081   WN_TREE_CONTAINER<PRE_ORDER> aWNPtree(thePU_WN_p);
00082   WN_TREE_CONTAINER<PRE_ORDER>::iterator aWNPtreeIterator=aWNPtree.begin();
00083   typedef std::pair<WN*, WN*> NodeBlockWNPPair;
00084   typedef std::set<NodeBlockWNPPair> NodeBlockWNPPairSet;
00085   NodeBlockWNPPairSet interfaceTreesToBeDeleted;
00086   std::set<WN*> useVarsToBeDeleted;
00087   bool skipKids=false;
00088   while (aWNPtreeIterator != aWNPtree.end()) { 
00089     WN* curWN_p = aWNPtreeIterator.Wn();
00090     OPERATOR opr = WN_operator(curWN_p);
00091     if (opr==OPR_USE) {  // use statements
00092       skipKids=true;
00093       ST* moduleName_ST_p=WN_st(curWN_p); 
00094       for (INT kidIdx = 0; kidIdx < WN_kid_count(curWN_p); kidIdx+=2) {
00095         // for each symbol listed in the code after the use
00096         // the symbol is repeated identical if it is not renamed
00097         // or else the first in the pair is the new name
00098         // with which we reference the module name listed as the second one.
00099         const char* renameName=ST_name(WN_st(WN_kid(curWN_p,kidIdx)));
00100         const char* moduleName=ST_name(WN_st(WN_kid(curWN_p,kidIdx+1)));
00101         if (!strcmp(renameName,moduleName)) {
00102           // is not a rename, fix up the first kid as well to be consistent
00103           WN* useOldKid_WN_p = WN_kid(curWN_p, kidIdx);
00104           ST* dummyLocal_ST_p=WN_st(useOldKid_WN_p);
00105           ST* properModule_ST_p=findModuleSymbol(moduleName_ST_p,
00106                                                  dummyLocal_ST_p,
00107                                                  aTopPUInfo_p);
00108           if (properModule_ST_p && properModule_ST_p!=dummyLocal_ST_p) { 
00109             WN_kid(curWN_p,kidIdx)=WN_CreateIdname(WN_idname_offset(useOldKid_WN_p),properModule_ST_p);
00110             useVarsToBeDeleted.insert(useOldKid_WN_p);
00111           }
00112         }
00113         // always fix up the second kid
00114         WN* useOldKid_WN_p = WN_kid(curWN_p, kidIdx+1);
00115         ST* dummyLocal_ST_p=WN_st(useOldKid_WN_p);
00116         ST* properModule_ST_p=findModuleSymbol(moduleName_ST_p,
00117                                                dummyLocal_ST_p,
00118                                                aTopPUInfo_p);
00119         if (properModule_ST_p && properModule_ST_p!=dummyLocal_ST_p) { 
00120           WN_kid(curWN_p,kidIdx+1)=WN_CreateIdname(WN_idname_offset(useOldKid_WN_p),properModule_ST_p);
00121           useVarsToBeDeleted.insert(useOldKid_WN_p);
00122         }
00123       }
00124     }
00125     else if ( opr == OPR_INTERFACE ) {
00126       if (parentBlockWN_p==0 || pragmaWN_p==0) { 
00127         DIE("forPUInfo: need parentBlockWN_p(%h)!=0 and pragmaWN_p(%h)!=0\n",parentBlockWN_p,pragmaWN_p);
00128       }
00129       skipKids=true;
00130       if (parentBlockWN_p!=pragmaWN_p) { // don't repeat things if we already cleaned up once ...
00131         // make a copy of curWN_p 
00132         // attach it to pragma_WN_p
00133         WN* newInterfaceWN_p=WN_COPY_Tree(curWN_p);
00134         WN_INSERT_BlockLast(pragmaWN_p,newInterfaceWN_p);
00135         interfaceTreesToBeDeleted.insert(NodeBlockWNPPair(curWN_p,parentBlockWN_p));
00136       }
00137     }
00138     else if ( opr == OPR_BLOCK ) {
00139       parentBlockWN_p=curWN_p;
00140     }
00141     else if ( opr == OPR_FUNC_ENTRY ) {
00142       pragmaWN_p=WN_kid(curWN_p,WN_kid_count(curWN_p)-3);
00143     }
00144     // advance the iterator
00145     if (skipKids){
00146       aWNPtreeIterator.WN_TREE_next_skip();
00147       skipKids=false;
00148     }
00149     else
00150       ++aWNPtreeIterator;
00151   }
00152   // postpone the deletion to avoid possibly upsetting the iterator
00153   for (std::set<WN*>::iterator i = useVarsToBeDeleted.begin();
00154        i!=useVarsToBeDeleted.end();
00155        ++i) 
00156     WN_Delete(*i);
00157   for (NodeBlockWNPPairSet::iterator i = interfaceTreesToBeDeleted.begin();
00158        i!=interfaceTreesToBeDeleted.end();
00159        ++i) {
00160     WN_DELETE_FromBlock((*i).second,(*i).first);
00161   }
00162 } 
00163 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines