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