|
OpenADFortTk (basic)
|
00001 #include <iostream> 00002 #include <sstream> 00003 00004 #include "ScalarizedRef.h" 00005 #include "Diagnostics.h" 00006 00007 #include "Open64IRInterface/stab_attr.h" 00008 #include "Open64IRInterface/wn_attr.h" 00009 00010 namespace fortTkSupport { 00011 00012 unsigned int ScalarizedRef::ourNextId = 0; 00013 const std::string ScalarizedRef::ourPrefix("oaScalRef"); 00014 00015 ScalarizedRef::ScalarizedRef(WN* const aWNp) : 00016 myId(ourNextId++), 00017 myWNp(aWNp) { 00018 std::ostringstream theName; 00019 theName << ourPrefix.c_str() << myId << std::ends; 00020 myName=theName.str(); 00021 } 00022 00023 ScalarizedRef::ScalarizedRef(WN* const aWNp, 00024 const std::string& aPostFix) : 00025 myId(ourNextId++), 00026 myWNp(aWNp) { 00027 std::ostringstream theName; 00028 theName << ourPrefix.c_str() << myId << aPostFix.c_str() << std::ends; 00029 myName=theName.str(); 00030 } 00031 00032 ScalarizedRef::~ScalarizedRef() { 00033 } 00034 00035 const std::string& ScalarizedRef::getName()const { 00036 return myName; 00037 } 00038 00039 WN* ScalarizedRef::getWN() const { 00040 return myWNp; 00041 } 00042 00043 unsigned int ScalarizedRef::getId() const { 00044 return myId; 00045 } 00046 00047 void ScalarizedRef::dump(std::ostream& o) const { 00048 o << myName; 00049 } 00050 00051 void ScalarizedRef::ddump() const { 00052 dump(std::cerr); 00053 } 00054 00055 bool ScalarizedRef::isRefTranslatableToXAIF(const WN* aWNp) { 00056 return (isRefSimple(aWNp) || isRefScalarizable(aWNp)); 00057 } 00058 00059 bool ScalarizedRef::isRefSimple(const WN* aWNp) { 00060 return (isRefSimpleScalar(aWNp) 00061 || 00062 isRefSimpleArrayElem(aWNp) 00063 || 00064 isRefSimpleArray(aWNp)); 00065 } 00066 00067 bool ScalarizedRef::isRefSimpleScalar(const WN* aWNp) { 00068 OPERATOR opr = WN_operator(aWNp); 00069 switch (opr) { 00070 case OPR_LDA: 00071 case OPR_LDMA: 00072 case OPR_LDID: 00073 case OPR_LDBITS: 00074 case OPR_STID: 00075 case OPR_STBITS: 00076 case OPR_ILOAD: 00077 case OPR_ILDBITS: { 00078 // (for stores, only check LHS (kid1)) 00079 TY_IDX baseobj_ty = WN_GetBaseObjType(aWNp); 00080 TY_IDX refobj_ty = WN_GetRefObjType(aWNp); 00081 if (opr == OPR_LDA || opr == OPR_LDMA) { 00082 // dereference the pointer (assume Fortran) 00083 refobj_ty = TY_pointed(refobj_ty); 00084 } 00085 return (isRefScalar(baseobj_ty, refobj_ty)); 00086 } 00087 default: 00088 break; // fall through 00089 } // switch 00090 return false; 00091 } 00092 00093 bool ScalarizedRef::isRefSimpleArrayElem(const WN* aWNp) { 00094 OPERATOR opr = WN_operator(aWNp); 00095 switch (opr) { 00096 case OPR_LDA: 00097 case OPR_LDMA: 00098 case OPR_LDID: // probably never used for this 00099 case OPR_STID: // probably never used for this 00100 case OPR_ILOAD: 00101 case OPR_ISTORE: { 00102 // yes if baseobj_ty is of type array and reference is non-scalar 00103 // (for stores, only check LHS (kid1)) 00104 TY_IDX baseobj_ty = WN_GetBaseObjType(aWNp); 00105 TY_IDX refobj_ty = WN_GetRefObjType(aWNp); 00106 return (TY_Is_Array(baseobj_ty) && !isRefScalar(baseobj_ty, refobj_ty)); 00107 } 00108 case OPR_ARRAY: 00109 return true; 00110 default: 00111 break; // fall through 00112 } // switch 00113 return false; 00114 } 00115 00116 bool ScalarizedRef::isRefSimpleArray(const WN* aWNp) { 00117 OPERATOR opr = WN_operator(aWNp); 00118 switch (opr) { 00119 case OPR_LDA: 00120 case OPR_LDMA: 00121 case OPR_LDID: { 00122 // yes if refobj_ty is of type array 00123 TY_IDX baseobj_ty = WN_GetBaseObjType(aWNp); 00124 TY_IDX refobj_ty = WN_GetRefObjType(aWNp); 00125 return (TY_Is_Array(refobj_ty)); 00126 } 00127 case OPR_ARRSECTION: // FIXME: can we do arrsection? 00128 case OPR_ARRAYEXP: 00129 return true; 00130 default: 00131 break; // fall through 00132 } // switch 00133 return false; 00134 } 00135 00136 bool ScalarizedRef::isRefScalarizable(const WN* aWNp) { 00137 OPERATOR opr = WN_operator(aWNp); 00138 switch (opr) { 00139 case OPR_LDA: 00140 case OPR_LDMA: 00141 case OPR_LDID: 00142 case OPR_LDBITS: 00143 case OPR_STID: 00144 case OPR_STBITS: 00145 case OPR_ILOAD: 00146 case OPR_ISTORE: { 00147 FORTTK_MSG(1, "ScalarizedRef::isRefScalarizable(" << OPERATOR_name(opr) << ":" << aWNp << ")"); 00148 // yes if refobj_ty is scalar and reference is non-scalar 00149 // (for stores, only check LHS (kid1)) 00150 TY_IDX baseobj_ty = WN_GetBaseObjType(aWNp); 00151 TY_IDX refobj_ty = WN_GetRefObjType(aWNp); 00152 // Special cases: 00153 // 1) passing a whole array looks like a scalarizable reference: 00154 // call foo(x) ! where x is an array 00155 // (ILOAD F8 F8 (0 0 (ty ".predef_F8" 11 8) (ty pointer-to-F8)) 00156 // (LDID U8 U8 ((st "X" 2 1) 0 (ty pointer-to-array) 0)))) 00157 // call foo(px) ! where px is an array 00158 // (ILOAD F8 F8 (0 0 (ty ".predef_F8" 11 8) (ty pointer-to-F8)) 00159 // (LDA U8 V ((st "PX" 2 4) 0 (ty pointer-to-array) 0)))) 00160 if (opr == OPR_ILOAD && 00161 (WN_operator(WN_kid0(aWNp)) == OPR_LDID || 00162 WN_operator(WN_kid0(aWNp)) == OPR_LDA)) { 00163 TY_IDX ty = WN_ty(WN_kid0(aWNp)); 00164 if (TY_Is_Pointer(ty) && TY_Is_Array(TY_pointed(ty))) { 00165 FORTTK_MSG(1, "ScalarizedRef::isRefScalarizable returns false"); 00166 return false; 00167 } 00168 } 00169 FORTTK_MSG(1, "ScalarizedRef::isRefScalarizable returns " << (TY_Is_Scalar(refobj_ty) && !isRefScalar(baseobj_ty, refobj_ty))); 00170 return (TY_Is_Scalar(refobj_ty) && !isRefScalar(baseobj_ty, refobj_ty)); 00171 } 00172 case OPR_STRCTFLD: { 00173 FORTTK_MSG(1, "ScalarizedRef::isRefScalarizable(" << OPERATOR_name(opr) << ":" << aWNp << ")"); 00174 // yes if refobj_ty is scalar and reference is non-scalar 00175 // (for stores, only check LHS (kid1)) 00176 TY_IDX baseobj_ty = WN_GetBaseObjType(aWNp); 00177 TY_IDX refobj_ty = WN_GetRefObjType(aWNp); 00178 FORTTK_MSG(1, "ScalarizedRef::isRefScalarizable returns TY_Is_Scalar(" << TY_IDX_index(refobj_ty) << ")=" << TY_Is_Scalar(refobj_ty) << " && " << (!isRefScalar(baseobj_ty, refobj_ty)) ); 00179 return true; 00180 } 00181 // FIXME: ILOADX, ISTOREX / ILDBITS, ISTBITS 00182 default: 00183 break; // fall through 00184 } // switch 00185 return false; 00186 } 00187 00188 bool ScalarizedRef::isRefScalar(TY_IDX baseobj_ty, 00189 TY_IDX refobj_ty) { 00190 if (TY_IsNonScalar(refobj_ty)) { 00191 // This is a reference to a non-scalar or a non-scalar within a 00192 // non-scalar (e.g. a record or a record within a record) 00193 return false; 00194 } 00195 else if (TY_Is_Scalar(refobj_ty)) { 00196 // Test whether 'baseobj_ty' is assignable to 'refobj_ty'. If 00197 // not, we have a non-scalar reference (e.g. a field within a 00198 // structure; an element within an array). 00199 return (WN2F_Can_Assign_Types(baseobj_ty, refobj_ty)); 00200 } 00201 else { 00202 return false; 00203 } 00204 } 00205 00206 }