OpenADFortTk (basic)
src/lib/support/Open64IRInterface/IntrinsicInfo.cpp
Go to the documentation of this file.
00001 #include "IntrinsicInfo.h"
00002 #include "IFDiagnostics.h"
00003 #include "wn_attr.h"
00004 
00005 IntrinsicInfo::IntrinsicMap IntrinsicInfo::ourIntrinsicInfoMap;
00006 bool IntrinsicInfo::ourInitFlag=false;
00007 
00008 const IntrinsicInfo::IntrinsicMap& IntrinsicInfo::getMap() { 
00009   if (!ourInitFlag) { 
00010     // Common mathematical functions
00011     ourIntrinsicInfoMap[Key( OPR_NEG,           NULL)         ]=Info(false,1,FLOAT_INTR);
00012     ourIntrinsicInfoMap[Key( OPR_ADD,           NULL)         ]=Info(false,2,FLOAT_INTR);
00013     ourIntrinsicInfoMap[Key( OPR_SUB,           NULL)         ]=Info(false,2,FLOAT_INTR);
00014     ourIntrinsicInfoMap[Key( OPR_MPY,           NULL)         ]=Info(false,2,FLOAT_INTR);
00015     ourIntrinsicInfoMap[Key( OPR_DIV,           NULL)         ]=Info(false,2,FLOAT_INTR); 
00016     ourIntrinsicInfoMap[Key( OPR_CALL,          "SQRT")       ]=Info(false,1,FLOAT_INTR);
00017     ourIntrinsicInfoMap[Key( OPR_CALL,          "DSQRT")      ]=Info(false,1,FLOAT_INTR);
00018     ourIntrinsicInfoMap[Key( OPR_SQRT,          NULL)         ]=Info(false,1,FLOAT_INTR); 
00019     ourIntrinsicInfoMap[Key( OPR_CALL,          "SUM")        ]=Info(false,1,ARRAY_INTR); 
00020     // modulo/remainder
00021     ourIntrinsicInfoMap[Key( OPR_MOD,           NULL)         ]=Info(false,2,FLOAT_INTR); 
00022     ourIntrinsicInfoMap[Key( OPR_CALL,          "MODULO")     ]=Info(false,2,FLOAT_INTR); 
00023     ourIntrinsicInfoMap[Key( OPR_REM,           NULL)         ]=Info(false,2,FLOAT_INTR);
00024     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "AMOD")       ]=Info(false,2,FLOAT_INTR);
00025     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "DMOD")       ]=Info(false,2,FLOAT_INTR); 
00026     ourIntrinsicInfoMap[Key( OPR_CALL,          "MOD")        ]=Info(false,2,FLOAT_INTR); 
00027     // trigonometric
00028     ourIntrinsicInfoMap[Key( OPR_CALL,          "SIN")        ]=Info(false,1,FLOAT_INTR);
00029     ourIntrinsicInfoMap[Key( OPR_CALL,          "DSIN")       ]=Info(false,1,FLOAT_INTR);
00030     ourIntrinsicInfoMap[Key( OPR_CALL,          "COS")        ]=Info(false,1,FLOAT_INTR);
00031     ourIntrinsicInfoMap[Key( OPR_CALL,          "DCOS")       ]=Info(false,1,FLOAT_INTR);
00032     ourIntrinsicInfoMap[Key( OPR_CALL,          "TAN")        ]=Info(false,1,FLOAT_INTR);
00033     ourIntrinsicInfoMap[Key( OPR_CALL,          "DTAN")       ]=Info(false,1,FLOAT_INTR); 
00034     ourIntrinsicInfoMap[Key( OPR_CALL,          "ASIN")       ]=Info(false,1,FLOAT_INTR);
00035     ourIntrinsicInfoMap[Key( OPR_CALL,          "ACOS")       ]=Info(false,1,FLOAT_INTR);
00036     ourIntrinsicInfoMap[Key( OPR_CALL,          "ATAN")       ]=Info(false,1,FLOAT_INTR); 
00037     ourIntrinsicInfoMap[Key( OPR_CALL,          "SINH")       ]=Info(false,1,FLOAT_INTR);
00038     ourIntrinsicInfoMap[Key( OPR_CALL,          "DSINH")      ]=Info(false,1,FLOAT_INTR);
00039     ourIntrinsicInfoMap[Key( OPR_CALL,          "COSH")       ]=Info(false,1,FLOAT_INTR);
00040     ourIntrinsicInfoMap[Key( OPR_CALL,          "DCOSH")      ]=Info(false,1,FLOAT_INTR);
00041     ourIntrinsicInfoMap[Key( OPR_CALL,          "TANH")       ]=Info(false,1,FLOAT_INTR);
00042     ourIntrinsicInfoMap[Key( OPR_CALL,          "DTANH")      ]=Info(false,1,FLOAT_INTR);
00043     // exp/log
00044     ourIntrinsicInfoMap[Key( OPR_CALL,          "EXP")        ]=Info(false,1,FLOAT_INTR);
00045     ourIntrinsicInfoMap[Key( OPR_CALL,          "DEXP")       ]=Info(false,1,FLOAT_INTR);
00046     ourIntrinsicInfoMap[Key( OPR_CALL,          "LOG")        ]=Info(false,1,FLOAT_INTR);
00047     ourIntrinsicInfoMap[Key( OPR_CALL,          "DLOG")       ]=Info(false,1,FLOAT_INTR); 
00048     ourIntrinsicInfoMap[Key( OPR_CALL,          "ALOG")       ]=Info(false,1,FLOAT_INTR); 
00049     ourIntrinsicInfoMap[Key( OPR_CALL,          "LOG10")      ]=Info(false,1,FLOAT_INTR); 
00050     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "EXPEXPR")    ]=Info(false,2,FLOAT_INTR);
00051     // string ops
00052     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "CEQEXPR")    ]=Info(false,2,STRING_INTR);
00053     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "CNEEXPR")    ]=Info(false,2,STRING_INTR);
00054     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "CGEEXPR")    ]=Info(false,2,STRING_INTR);
00055     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "CGTEXPR")    ]=Info(false,2,STRING_INTR);
00056     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "CLEEXPR")    ]=Info(false,2,STRING_INTR);
00057     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "CLTEXPR")    ]=Info(false,2,STRING_INTR);
00058     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "LEN")        ]=Info(false,1,STRING_INTR);
00059     ourIntrinsicInfoMap[Key( OPR_CALL,          "INDEX")      ]=Info(true, 3,STRING_INTR);
00060     ourIntrinsicInfoMap[Key( OPR_CALL,          "LEN")        ]=Info(false,1,STRING_INTR);
00061     ourIntrinsicInfoMap[Key( OPR_CALL,          "LEN_TRIM")   ]=Info(false,1,STRING_INTR);
00062     ourIntrinsicInfoMap[Key( OPR_CALL,          "TRIM")       ]=Info(false,1,STRING_INTR);
00063     ourIntrinsicInfoMap[Key( OPR_CALL,          "SCAN")       ]=Info(false,2,STRING_INTR);
00064     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_CALL,"CONCATEXPR") ]=Info(true, 2,STRING_INTR);
00065     ourIntrinsicInfoMap[Key( OPR_CALL,          "ICHAR")      ]=Info(false,1,STRING_INTR);
00066     
00067     // string assignment
00068     // String Assigment is Treated as a special case of Intrinsic functions.
00069     // We assume that Intrinsic Functions has no side Effects whereas 
00070     // CASSIGNSTMT has side effects. Therefore, we expect its behaviuor to be similar
00071     // to the AssignPair sattement. Therefore, Removed from list of Intrinsics.
00072     //ourIntrinsicInfoMap[Key( OPR_INTRINSIC_CALL,"CASSIGNSTMT")]=Info(false,1,STRING_INTR);
00073    
00074     // rounding and conversion
00075     ourIntrinsicInfoMap[Key( OPR_ABS,           NULL)         ]=Info(false,1,FLOAT_INTR);
00076     ourIntrinsicInfoMap[Key( OPR_CALL,          "ABS")        ]=Info(false,1,FLOAT_INTR);
00077     ourIntrinsicInfoMap[Key( OPR_CALL,          "DABS")       ]=Info(false,1,FLOAT_INTR);
00078     ourIntrinsicInfoMap[Key( OPR_CALL,          "IABS")       ]=Info(false,1,INTEGER_INTR); 
00079     ourIntrinsicInfoMap[Key( OPR_CALL,          "SIGN")       ]=Info(false,2,FLOAT_INTR); 
00080     ourIntrinsicInfoMap[Key( OPR_CALL,          "DSIGN")      ]=Info(false,2,FLOAT_INTR); 
00081     ourIntrinsicInfoMap[Key( OPR_RND,           NULL)         ]=Info(false,1,FLOAT_INTR);
00082     ourIntrinsicInfoMap[Key( OPR_TRUNC,         NULL)         ]=Info(false,1,FLOAT_INTR);
00083     ourIntrinsicInfoMap[Key( OPR_CALL,          "INT")        ]=Info(false,1,FLOAT_INTR);
00084     ourIntrinsicInfoMap[Key( OPR_CALL,          "NINT")       ]=Info(false,1,FLOAT_INTR);
00085     ourIntrinsicInfoMap[Key( OPR_CALL,          "TRANSFER")   ]=Info(false,2,FLOAT_INTR);
00086     ourIntrinsicInfoMap[Key( OPR_CEIL,          NULL)         ]=Info(false,1,FLOAT_INTR);
00087     ourIntrinsicInfoMap[Key( OPR_FLOOR,         NULL)         ]=Info(false,1,FLOAT_INTR); 
00088     ourIntrinsicInfoMap[Key( OPR_CALL,          "REAL")       ]=Info(false,1,FLOAT_INTR);
00089     ourIntrinsicInfoMap[Key( OPR_CALL,          "FLOAT")      ]=Info(false,1,FLOAT_INTR);
00090     ourIntrinsicInfoMap[Key( OPR_CALL,          "DBLE")       ]=Info(false,1,FLOAT_INTR); 
00091     ourIntrinsicInfoMap[Key( OPR_CALL,          "AIMAG")      ]=Info(false,1,FLOAT_INTR); 
00092     ourIntrinsicInfoMap[Key( OPR_CALL,          "TRANSPOSE")  ]=Info(false,1,ARRAY_INTR); 
00093     ourIntrinsicInfoMap[Key( OPR_CALL,          "RESHAPE")    ]=Info(false,2,ARRAY_INTR); 
00094     ourIntrinsicInfoMap[Key( OPR_COMPLEX,       NULL)         ]=Info(false,2,FLOAT_INTR); 
00095     // logical (and bitwise logical) operations 
00096     ourIntrinsicInfoMap[Key( OPR_BNOT,          NULL)         ]=Info(false,1,BOOL_INTR);
00097     ourIntrinsicInfoMap[Key( OPR_BAND,          NULL)         ]=Info(false,2,BOOL_INTR);
00098     ourIntrinsicInfoMap[Key( OPR_BIOR,          NULL)         ]=Info(false,2,BOOL_INTR);
00099     ourIntrinsicInfoMap[Key( OPR_BXOR,          NULL)         ]=Info(false,2,BOOL_INTR); 
00100     ourIntrinsicInfoMap[Key( OPR_LNOT,          NULL)         ]=Info(false,1,BOOL_INTR);
00101     ourIntrinsicInfoMap[Key( OPR_LAND,          NULL)         ]=Info(false,2,BOOL_INTR);
00102     ourIntrinsicInfoMap[Key( OPR_LIOR,          NULL)         ]=Info(false,2,BOOL_INTR);
00103     ourIntrinsicInfoMap[Key( OPR_CAND,          NULL)         ]=Info(false,2,BOOL_INTR);
00104     ourIntrinsicInfoMap[Key( OPR_CIOR,          NULL)         ]=Info(false,2,BOOL_INTR); 
00105     // comparison operations
00106     ourIntrinsicInfoMap[Key( OPR_EQ,            NULL)         ]=Info(false,2,FLOAT_INTR);
00107     ourIntrinsicInfoMap[Key( OPR_NE,            NULL)         ]=Info(false,2,FLOAT_INTR);
00108     ourIntrinsicInfoMap[Key( OPR_GT,            NULL)         ]=Info(false,2,FLOAT_INTR);
00109     ourIntrinsicInfoMap[Key( OPR_GE,            NULL)         ]=Info(false,2,FLOAT_INTR);
00110     ourIntrinsicInfoMap[Key( OPR_LT,            NULL)         ]=Info(false,2,FLOAT_INTR);
00111     ourIntrinsicInfoMap[Key( OPR_LE,            NULL)         ]=Info(false,2,FLOAT_INTR); 
00112     ourIntrinsicInfoMap[Key( OPR_CALL,          "ANY")        ]=Info(false,1,ARRAY_INTR);
00113     // max/min
00114     ourIntrinsicInfoMap[Key( OPR_MAX,            NULL)        ]=Info(false,2,FLOAT_INTR); 
00115     ourIntrinsicInfoMap[Key( OPR_MIN,            NULL)        ]=Info(false,2,FLOAT_INTR); 
00116     // array operations
00117     ourIntrinsicInfoMap[Key( OPR_CALL,          "MAXVAL")     ]=Info(false,1,ARRAY_INTR);
00118     ourIntrinsicInfoMap[Key( OPR_CALL,          "MAXLOC")     ]=Info(false,1,ARRAY_INTR);
00119     ourIntrinsicInfoMap[Key( OPR_CALL,          "MINVAL")     ]=Info(false,1,ARRAY_INTR);
00120     ourIntrinsicInfoMap[Key( OPR_CALL,          "MINLOC")     ]=Info(false,1,ARRAY_INTR);
00121     ourIntrinsicInfoMap[Key( OPR_CALL,          "LBOUND")     ]=Info(false,2,ARRAY_INTR);
00122     ourIntrinsicInfoMap[Key( OPR_CALL,          "UBOUND")     ]=Info(false,2,ARRAY_INTR);
00123     ourIntrinsicInfoMap[Key( OPR_CALL,          "SIZE")       ]=Info(false,2,ARRAY_INTR);
00124     ourIntrinsicInfoMap[Key( OPR_CALL,          "SHAPE")      ]=Info(false,1,ARRAY_INTR);
00125     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "F90INDEX")   ]=Info(false,2,ARRAY_INTR);
00126     ourIntrinsicInfoMap[Key( OPR_CALL,          "PRESENT")    ]=Info(false,1,COMPILER_INTERNAL_INTR);
00127     ourIntrinsicInfoMap[Key( OPR_CALL,          "ASSOCIATED") ]=Info(false,1,COMPILER_INTERNAL_INTR);
00128     ourIntrinsicInfoMap[Key( OPR_CALL,          "ALLOCATED")  ]=Info(false,1,COMPILER_INTERNAL_INTR);
00129     ourIntrinsicInfoMap[Key( OPR_NULLIFY,       NULL)         ]=Info(false,1,COMPILER_INTERNAL_INTR);
00130     ourIntrinsicInfoMap[Key( OPR_CALL,          "_ALLOCATE")  ]=Info(false,1,COMPILER_INTERNAL_INTR);
00131     ourIntrinsicInfoMap[Key( OPR_CALL,          "_DEALLOCATE")]=Info(false,1,COMPILER_INTERNAL_INTR);
00132     ourIntrinsicInfoMap[Key( OPR_CALL,          "MAXVAL")     ]=Info(false,2,ARRAY_INTR);
00133     ourIntrinsicInfoMap[Key( OPR_CALL,          "MINVAL")     ]=Info(false,2,ARRAY_INTR);
00134     // shifting operations
00135     ourIntrinsicInfoMap[Key( OPR_SHL,            NULL)        ]=Info(false,2,INTEGER_INTR);
00136     ourIntrinsicInfoMap[Key( OPR_ASHR,           NULL)        ]=Info(false,2,INTEGER_INTR); 
00137     // compiler internal routine for cleanup at the end of PROGRAM
00138     ourIntrinsicInfoMap[Key( OPR_CALL,          "_END")       ]=Info(false,0,COMPILER_INTERNAL_INTR);
00139     ourInitFlag = true;
00140   } 
00141   return ourIntrinsicInfoMap;
00142 } 
00143 
00144 bool IntrinsicInfo::lookupIntrinsicInfo(const WN* aWN_p, const IntrinsicInfo::Info* anInfo) { 
00145   OPERATOR opr = WN_operator(aWN_p);
00146   IntrinsicMap::const_iterator finder;
00147 
00166   if (opr==OPR_INTRINSIC_OP) { 
00167     // get the name and strip machine type information
00168     const char* inm = intrinsicBaseName(WN_intrinsic(aWN_p));
00169     finder=getMap().find(Key(opr,inm));
00170     if (finder==getMap().end()) {
00171       DIE("IntrinsicInfo::isIntrinsic: no entry for OPR_INTRINSIC_OP %s ",inm);
00172     }
00173   }
00174   else if (opr==OPR_CALL) { 
00175     // get the name
00176     ST* st = WN_st(aWN_p);
00177     const char* funcNm = ST_name(st);
00178     // if we don't find it in the table we either forgot to add an entry
00179     // or the call is not to an intrinsic
00180     finder=getMap().find(Key(opr,funcNm));
00181   }
00182   else { 
00183     // the rest is for the OPERATORs without discriminating name which we 
00184     // hopefully have complete
00185     finder=getMap().find(Key(opr,NULL));
00186   }
00187   if (finder!=getMap().end())
00188     anInfo=&((*finder).second);
00189   return finder!=getMap().end();
00190 } 
00191 
00192 bool IntrinsicInfo::isIntrinsic(const WN* aWN_p) { 
00193   const Info* anInfo_p;
00194   return lookupIntrinsicInfo(aWN_p,anInfo_p);
00195 }
00196 
00197 const IntrinsicInfo::Info& IntrinsicInfo::getIntrinsicInfo(WN* aWN_p) { 
00198   const Info* anInfo_p;
00199   if(!lookupIntrinsicInfo(aWN_p,anInfo_p))
00200     DIE("IntrinsicInfo::getIntrinsicInfo: not a known intrinsic");
00201   return *anInfo_p;
00202 }
00203 
00204 bool IntrinsicInfo::KeyLT::operator()(const IntrinsicInfo::Key& k1, const IntrinsicInfo::Key& k2) const {
00205   if (k1.myWNopr<k2.myWNopr)
00206     return true;
00207   else if (k1.myWNopr>k2.myWNopr)
00208     return false;
00209   else if (k1.myWNopr==OPR_CALL)
00210     return strcmp(k1.myName, k2.myName) < 0;
00211   else
00212     return false;
00213 }
00214 
00215 const char* IntrinsicInfo::intrinsicBaseName(INTRINSIC intrn) {
00216   // almost none of the Open64 code uses std::string
00217   const char* opc_str = WN_intrinsic_name(intrn); // INTRINSIC_name(intrn);
00218   const char* opc_str_base = opc_str;
00219   const int prefixLength(2);
00220   // Test for two-character prefixes (up to two)
00221   char buf[prefixLength+1];
00222   for (int i = 0; i < 2; ++i) {
00223     // If a prefix begins 'opc_str_base', shift pointer
00224     strncpy(buf, opc_str_base, prefixLength); 
00225     buf[prefixLength] = '\0';
00226     bool pfix = lookupIntrinsicPrefix(buf);
00227     if (pfix) { 
00228       opc_str_base += prefixLength; 
00229     } else {
00230       break; // no need to continue
00231     }
00232   }
00233   // Special case: test for one-character prefix
00234   strncpy(buf, opc_str_base, 1); 
00235   buf[1] = '\0';
00236   bool pfix = lookupIntrinsicPrefix(buf);
00237   if (pfix) {
00238     // an exception
00239     if ( !(strcmp(opc_str_base, "VALTMP") == 0) ) {
00240       opc_str_base++;
00241     }
00242   }
00243   return opc_str_base;
00244 }
00245 
00246 extern "C" int prefixTableCmp(const char** e1, const char** e2) {
00247   return strcmp(*e1, *e2);
00248 }
00249 
00250 extern "C" typedef int (*compare_fn_t)(const void *, const void *);
00251 
00252 bool IntrinsicInfo::lookupIntrinsicPrefix(const char* str){ 
00253   static const char* prefixTable[] = {
00254     "V",                    // void
00255     "I1", "I2", "I4", "I8", // integer
00256     "U1", "U2", "U4", "U8", // unsigned integer
00257     "F4", "F8", "FQ",       // floating point
00258     "C4", "C8", "CQ"        // complex
00259     // "C_" - C intrinsics
00260     // "S_" - UPC intrinsics
00261   }; 
00262   static unsigned int prefixTableElemSz = sizeof(const char*);
00263   static unsigned int prefixTableSz = (sizeof(prefixTable) / sizeof(const char*));
00264   static bool prefixTableSorted = false;
00265   // first sort it 
00266   if (!prefixTableSorted) {
00267     qsort(prefixTable, 
00268           prefixTableSz, 
00269           prefixTableElemSz, 
00270           (compare_fn_t)prefixTableCmp);
00271     prefixTableSorted = true;
00272   }
00273   // Search for entry str
00274   void* e = bsearch(&str, 
00275                     prefixTable, 
00276                     prefixTableSz, 
00277                     prefixTableElemSz,
00278                     (compare_fn_t)prefixTableCmp);
00279   return (e != NULL);
00280 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines