OpenADFortTk (basic)
src/lib/support/ScalarizedRef.cxx
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines