IntrinsicInfo.cpp

Go to the documentation of this file.
00001 #include "IntrinsicInfo.h"
00002 #include "diagnostics.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,          "LEN")        ]=Info(false,1,STRING_INTR);
00060     ourIntrinsicInfoMap[Key( OPR_CALL,          "TRIM")       ]=Info(false,1,STRING_INTR);
00061     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_CALL,"CONCATEXPR") ]=Info(true, 2,STRING_INTR);
00062     
00063     // string assignment
00064     // String Assigment is Treated as a special case of Intrinsic functions.
00065     // We assume that Intrinsic Functions has no side Effects whereas 
00066     // CASSIGNSTMT has side effects. Therefore, we expect its behaviuor to be similar
00067     // to the AssignPair sattement. Therefore, Removed from list of Intrinsics.
00068     //ourIntrinsicInfoMap[Key( OPR_INTRINSIC_CALL,"CASSIGNSTMT")]=Info(false,1,STRING_INTR);
00069    
00070     // rounding and conversion
00071     ourIntrinsicInfoMap[Key( OPR_ABS,           NULL)         ]=Info(false,1,FLOAT_INTR);
00072     ourIntrinsicInfoMap[Key( OPR_CALL,          "ABS")        ]=Info(false,1,FLOAT_INTR);
00073     ourIntrinsicInfoMap[Key( OPR_CALL,          "DABS")       ]=Info(false,1,FLOAT_INTR);
00074     ourIntrinsicInfoMap[Key( OPR_CALL,          "IABS")       ]=Info(false,1,INTEGER_INTR); 
00075     ourIntrinsicInfoMap[Key( OPR_CALL,          "SIGN")       ]=Info(false,2,FLOAT_INTR); 
00076     ourIntrinsicInfoMap[Key( OPR_CALL,          "DSIGN")      ]=Info(false,2,FLOAT_INTR); 
00077     ourIntrinsicInfoMap[Key( OPR_RND,           NULL)         ]=Info(false,1,FLOAT_INTR);
00078     ourIntrinsicInfoMap[Key( OPR_TRUNC,         NULL)         ]=Info(false,1,FLOAT_INTR);
00079     ourIntrinsicInfoMap[Key( OPR_CALL,          "INT")        ]=Info(false,1,FLOAT_INTR);
00080     ourIntrinsicInfoMap[Key( OPR_CALL,          "NINT")       ]=Info(false,1,FLOAT_INTR);
00081     ourIntrinsicInfoMap[Key( OPR_CEIL,          NULL)         ]=Info(false,1,FLOAT_INTR);
00082     ourIntrinsicInfoMap[Key( OPR_FLOOR,         NULL)         ]=Info(false,1,FLOAT_INTR); 
00083     ourIntrinsicInfoMap[Key( OPR_CALL,          "REAL")       ]=Info(false,1,FLOAT_INTR);
00084     ourIntrinsicInfoMap[Key( OPR_CALL,          "FLOAT")      ]=Info(false,1,FLOAT_INTR);
00085     ourIntrinsicInfoMap[Key( OPR_CALL,          "DBLE")       ]=Info(false,1,FLOAT_INTR); 
00086     ourIntrinsicInfoMap[Key( OPR_CALL,          "AIMAG")      ]=Info(false,1,FLOAT_INTR); 
00087     ourIntrinsicInfoMap[Key( OPR_CALL,          "TRANS")      ]=Info(false,1,ARRAY_INTR); 
00088     ourIntrinsicInfoMap[Key( OPR_COMPLEX,       NULL)         ]=Info(false,2,FLOAT_INTR); 
00089     // logical (and bitwise logical) operations 
00090     ourIntrinsicInfoMap[Key( OPR_BNOT,          NULL)         ]=Info(false,1,BOOL_INTR);
00091     ourIntrinsicInfoMap[Key( OPR_BAND,          NULL)         ]=Info(false,2,BOOL_INTR);
00092     ourIntrinsicInfoMap[Key( OPR_BIOR,          NULL)         ]=Info(false,2,BOOL_INTR);
00093     ourIntrinsicInfoMap[Key( OPR_BXOR,          NULL)         ]=Info(false,2,BOOL_INTR); 
00094     ourIntrinsicInfoMap[Key( OPR_LNOT,          NULL)         ]=Info(false,1,BOOL_INTR);
00095     ourIntrinsicInfoMap[Key( OPR_LAND,          NULL)         ]=Info(false,2,BOOL_INTR);
00096     ourIntrinsicInfoMap[Key( OPR_LIOR,          NULL)         ]=Info(false,2,BOOL_INTR);
00097     ourIntrinsicInfoMap[Key( OPR_CAND,          NULL)         ]=Info(false,2,BOOL_INTR);
00098     ourIntrinsicInfoMap[Key( OPR_CIOR,          NULL)         ]=Info(false,2,BOOL_INTR); 
00099     // comparison operations
00100     ourIntrinsicInfoMap[Key( OPR_EQ,            NULL)         ]=Info(false,2,FLOAT_INTR);
00101     ourIntrinsicInfoMap[Key( OPR_NE,            NULL)         ]=Info(false,2,FLOAT_INTR);
00102     ourIntrinsicInfoMap[Key( OPR_GT,            NULL)         ]=Info(false,2,FLOAT_INTR);
00103     ourIntrinsicInfoMap[Key( OPR_GE,            NULL)         ]=Info(false,2,FLOAT_INTR);
00104     ourIntrinsicInfoMap[Key( OPR_LT,            NULL)         ]=Info(false,2,FLOAT_INTR);
00105     ourIntrinsicInfoMap[Key( OPR_LE,            NULL)         ]=Info(false,2,FLOAT_INTR); 
00106     // max/min
00107     ourIntrinsicInfoMap[Key( OPR_MAX,            NULL)        ]=Info(false,2,FLOAT_INTR); 
00108     ourIntrinsicInfoMap[Key( OPR_MIN,            NULL)        ]=Info(false,2,FLOAT_INTR); 
00109     // array operations
00110     ourIntrinsicInfoMap[Key( OPR_CALL,          "MAXVAL")     ]=Info(false,1,ARRAY_INTR);
00111     ourIntrinsicInfoMap[Key( OPR_CALL,          "LBOUND")     ]=Info(false,2,ARRAY_INTR);
00112     ourIntrinsicInfoMap[Key( OPR_CALL,          "UBOUND")     ]=Info(false,2,ARRAY_INTR);
00113     ourIntrinsicInfoMap[Key( OPR_CALL,          "SIZE")       ]=Info(false,2,ARRAY_INTR);
00114     ourIntrinsicInfoMap[Key( OPR_INTRINSIC_OP,  "F90INDEX")   ]=Info(false,2,ARRAY_INTR);
00115     ourIntrinsicInfoMap[Key( OPR_CALL,          "PRESENT")    ]=Info(false,1,COMPILER_INTERNAL_INTR);
00116     ourIntrinsicInfoMap[Key( OPR_CALL,          "ASSOCIATED") ]=Info(false,1,COMPILER_INTERNAL_INTR);
00117     ourIntrinsicInfoMap[Key( OPR_CALL,          "ALLOCATED")  ]=Info(false,1,COMPILER_INTERNAL_INTR);
00118     ourIntrinsicInfoMap[Key( OPR_CALL,          "MAXVAL")     ]=Info(false,2,ARRAY_INTR);
00119     ourIntrinsicInfoMap[Key( OPR_CALL,          "MINVAL")     ]=Info(false,2,ARRAY_INTR);
00120     // shifting operations
00121     ourIntrinsicInfoMap[Key( OPR_SHL,            NULL)        ]=Info(false,2,INTEGER_INTR);
00122     ourIntrinsicInfoMap[Key( OPR_ASHR,           NULL)        ]=Info(false,2,INTEGER_INTR); 
00123     // compiler internal routine for cleanup at the end of PROGRAM
00124     ourIntrinsicInfoMap[Key( OPR_CALL,          "_END")       ]=Info(false,0,COMPILER_INTERNAL_INTR);
00125     ourInitFlag = true;
00126   } 
00127   return ourIntrinsicInfoMap;
00128 } 
00129 
00130 bool IntrinsicInfo::lookupIntrinsicInfo(WN* aWN_p, const IntrinsicInfo::Info* anInfo) { 
00131   OPERATOR opr = WN_operator(aWN_p);
00132   IntrinsicMap::const_iterator finder;
00133 
00152   if (opr==OPR_INTRINSIC_OP) { 
00153     // get the name and strip machine type information
00154     const char* inm = intrinsicBaseName(WN_intrinsic(aWN_p));
00155     finder=getMap().find(Key(opr,inm));
00156     if (finder==getMap().end()) {
00157       DIE("IntrinsicInfo::isIntrinsic: no entry for OPR_INTRINSIC_OP %s ",inm);
00158     }
00159   }
00160   else if (opr==OPR_CALL) { 
00161     // get the name
00162     ST* st = WN_st(aWN_p);
00163     const char* funcNm = ST_name(st);
00164     // if we don't find it in the table we either forgot to add an entry
00165     // or the call is not to an intrinsic
00166     finder=getMap().find(Key(opr,funcNm));
00167   }
00168   else { 
00169     // the rest is for the OPERATORs without discriminating name which we 
00170     // hopefully have complete
00171     finder=getMap().find(Key(opr,NULL));
00172   }
00173   if (finder!=getMap().end())
00174     anInfo=&((*finder).second);
00175   return finder!=getMap().end();
00176 } 
00177 
00178 bool IntrinsicInfo::isIntrinsic(WN* aWN_p) { 
00179   const Info* anInfo_p;
00180   return lookupIntrinsicInfo(aWN_p,anInfo_p);
00181 }
00182 
00183 const IntrinsicInfo::Info& IntrinsicInfo::getIntrinsicInfo(WN* aWN_p) { 
00184   const Info* anInfo_p;
00185   if(!lookupIntrinsicInfo(aWN_p,anInfo_p))
00186     DIE("IntrinsicInfo::getIntrinsicInfo: not a known intrinsic");
00187   return *anInfo_p;
00188 }
00189 
00190 bool IntrinsicInfo::KeyLT::operator()(const IntrinsicInfo::Key& k1, const IntrinsicInfo::Key& k2) const {
00191   if (k1.myWNopr<k2.myWNopr)
00192     return true;
00193   else if (k1.myWNopr>k2.myWNopr)
00194     return false;
00195   else if (k1.myWNopr==OPR_CALL)
00196     return strcmp(k1.myName, k2.myName) < 0;
00197   else
00198     return false;
00199 }
00200 
00201 const char* IntrinsicInfo::intrinsicBaseName(INTRINSIC intrn) {
00202   // almost none of the Open64 code uses std::string
00203   const char* opc_str = WN_intrinsic_name(intrn); // INTRINSIC_name(intrn);
00204   const char* opc_str_base = opc_str;
00205   const int prefixLength(2);
00206   // Test for two-character prefixes (up to two)
00207   char buf[prefixLength+1];
00208   for (int i = 0; i < 2; ++i) {
00209     // If a prefix begins 'opc_str_base', shift pointer
00210     strncpy(buf, opc_str_base, prefixLength); 
00211     buf[prefixLength] = '\0';
00212     bool pfix = lookupIntrinsicPrefix(buf);
00213     if (pfix) { 
00214       opc_str_base += prefixLength; 
00215     } else {
00216       break; // no need to continue
00217     }
00218   }
00219   // Special case: test for one-character prefix
00220   strncpy(buf, opc_str_base, 1); 
00221   buf[1] = '\0';
00222   bool pfix = lookupIntrinsicPrefix(buf);
00223   if (pfix) {
00224     // an exception
00225     if ( !(strcmp(opc_str_base, "VALTMP") == 0) ) {
00226       opc_str_base++;
00227     }
00228   }
00229   return opc_str_base;
00230 }
00231 
00232 extern "C" int prefixTableCmp(const char** e1, const char** e2) {
00233   return strcmp(*e1, *e2);
00234 }
00235 
00236 extern "C" typedef int (*compare_fn_t)(const void *, const void *);
00237 
00238 bool IntrinsicInfo::lookupIntrinsicPrefix(const char* str){ 
00239   static const char* prefixTable[] = {
00240     "V",                    // void
00241     "I1", "I2", "I4", "I8", // integer
00242     "U1", "U2", "U4", "U8", // unsigned integer
00243     "F4", "F8", "FQ",       // floating point
00244     "C4", "C8", "CQ"        // complex
00245     // "C_" - C intrinsics
00246     // "S_" - UPC intrinsics
00247   }; 
00248   static unsigned int prefixTableElemSz = sizeof(const char*);
00249   static unsigned int prefixTableSz = (sizeof(prefixTable) / sizeof(const char*));
00250   static bool prefixTableSorted = false;
00251   // first sort it 
00252   if (!prefixTableSorted) {
00253     qsort(prefixTable, 
00254           prefixTableSz, 
00255           prefixTableElemSz, 
00256           (compare_fn_t)prefixTableCmp);
00257     prefixTableSorted = true;
00258   }
00259   // Search for entry str
00260   void* e = bsearch(&str, 
00261                     prefixTable, 
00262                     prefixTableSz, 
00263                     prefixTableElemSz,
00264                     (compare_fn_t)prefixTableCmp);
00265   return (e != NULL);
00266 }

Generated on Fri Jul 24 04:29:04 2009 for OpenADFortTk (extended to Open64) by  doxygen 1.5.7.1