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
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
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
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
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
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
00064
00065
00066
00067
00068
00069
00070
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
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
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
00107 ourIntrinsicInfoMap[Key( OPR_MAX, NULL) ]=Info(false,2,FLOAT_INTR);
00108 ourIntrinsicInfoMap[Key( OPR_MIN, NULL) ]=Info(false,2,FLOAT_INTR);
00109
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
00121 ourIntrinsicInfoMap[Key( OPR_SHL, NULL) ]=Info(false,2,INTEGER_INTR);
00122 ourIntrinsicInfoMap[Key( OPR_ASHR, NULL) ]=Info(false,2,INTEGER_INTR);
00123
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
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
00162 ST* st = WN_st(aWN_p);
00163 const char* funcNm = ST_name(st);
00164
00165
00166 finder=getMap().find(Key(opr,funcNm));
00167 }
00168 else {
00169
00170
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
00203 const char* opc_str = WN_intrinsic_name(intrn);
00204 const char* opc_str_base = opc_str;
00205 const int prefixLength(2);
00206
00207 char buf[prefixLength+1];
00208 for (int i = 0; i < 2; ++i) {
00209
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;
00217 }
00218 }
00219
00220 strncpy(buf, opc_str_base, 1);
00221 buf[1] = '\0';
00222 bool pfix = lookupIntrinsicPrefix(buf);
00223 if (pfix) {
00224
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",
00241 "I1", "I2", "I4", "I8",
00242 "U1", "U2", "U4", "U8",
00243 "F4", "F8", "FQ",
00244 "C4", "C8", "CQ"
00245
00246
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
00252 if (!prefixTableSorted) {
00253 qsort(prefixTable,
00254 prefixTableSz,
00255 prefixTableElemSz,
00256 (compare_fn_t)prefixTableCmp);
00257 prefixTableSorted = true;
00258 }
00259
00260 void* e = bsearch(&str,
00261 prefixTable,
00262 prefixTableSz,
00263 prefixTableElemSz,
00264 (compare_fn_t)prefixTableCmp);
00265 return (e != NULL);
00266 }