OpenADFortTk (basic)
src/whirl2xaif/wn2xaif_mem.cxx
Go to the documentation of this file.
00001 // -*-Mode: C++;-*-
00002 // $Header: /Volumes/cvsrep/developer/OpenADFortTk/src/whirl2xaif/wn2xaif_mem.cxx,v 1.39 2006/05/12 16:12:23 utke Exp $
00003 
00004 
00005 #include <sstream> //FIXME
00006 #include <cassert> //FIXME
00007 #include <strings.h>
00008 
00009 
00010 #include "Open64IRInterface/Open64BasicTypes.h"
00011 #include "pf_cg.h"
00012 
00013 
00014 #include "wn2xaif.h"
00015 #include "wn2xaif_mem.h"
00016 #include "st2xaif.h"
00017 #include "ty2xaif.h"
00018 
00019 namespace whirl2xaif { 
00020 
00021 
00022   // ************************** Forward Declarations ***************************
00023 
00024   static void
00025   DumpVarRefEdge(xml::ostream& xos, UINT eid, UINT srcid, UINT targid);
00026 
00027   static void 
00028   WN2F_Block(xml::ostream& xos, ST * st, STAB_OFFSET off, PUXlationContext& ctxt);
00029 
00030   static WN *WN2F_ZeroInt_Ptr = NULL;
00031   static WN *WN2F_OneInt_Ptr = NULL;
00032 
00033 #define WN2F_INTCONST_ZERO                                              \
00034   (WN2F_ZeroInt_Ptr == NULL? WN2F_ZeroInt_Ptr = WN2F_Initiate_ZeroInt() \
00035    : WN2F_ZeroInt_Ptr)
00036 #define WN2F_INTCONST_ONE                                               \
00037   (WN2F_OneInt_Ptr == NULL? WN2F_OneInt_Ptr = WN2F_Initiate_OneInt()    \
00038    : WN2F_OneInt_Ptr)
00039 
00040   static void 
00041   WN2F_Arrsection_Slots(xml::ostream& xos, WN* wn, PUXlationContext& ctxt);
00042 
00043   static void 
00044   xlate_ArrayIndices(xml::ostream& xos, WN* wn, PUXlationContext& ctxt);
00045 
00046   // ***************************************************************************
00047 
00048   /*------------------------- Utility Functions ------------------------*/
00049   /*--------------------------------------------------------------------*/
00050 
00051   static WN *
00052   WN2F_Initiate_ZeroInt(void)
00053   {
00054     static char ZeroInt [sizeof (WN)];
00055     WN       *wn = (WN*) &ZeroInt;
00056     OPCODE    opcode = OPCODE_make_op(OPR_INTCONST, MTYPE_I4, MTYPE_V);
00057   
00058     bzero(wn, sizeof(WN));
00059     WN_set_opcode(wn, opcode);
00060     WN_set_kid_count(wn, 0);
00061     WN_map_id(wn) =  WN_MAP_UNDEFINED;
00062     WN_const_val(wn) = 0LL;
00063     return wn;
00064   } /* WN2F_Initiate_ZeroInt */
00065 
00066   static WN *
00067   WN2F_Initiate_OneInt(void)
00068   {
00069     static char OneInt [sizeof (WN)];
00070     WN       *wn = (WN*) &OneInt;
00071     OPCODE    opcode = OPCODE_make_op(OPR_INTCONST, MTYPE_I4, MTYPE_V);
00072   
00073     bzero(wn, sizeof(WN));
00074     WN_set_opcode(wn, opcode);
00075     WN_set_kid_count(wn, 0);
00076     WN_map_id(wn) =  WN_MAP_UNDEFINED;
00077     WN_const_val(wn) = 1LL;
00078     return wn;
00079   } /* WN2F_Initiate_ZeroInt */
00080 
00081 
00095   static void
00096   WN2F_Substring(xml::ostream& xos, 
00097                  INT64        string_size,
00098                  WN          *lower_bnd,
00099                  WN          *substring_size,
00100                  PUXlationContext& ctxt) {
00101     if (WN_operator(lower_bnd) == OPR_INTCONST   
00102         &&
00103         WN_const_val(lower_bnd) == 0                    
00104         &&
00105         WN_operator(substring_size) == OPR_INTCONST 
00106         &&
00107         WN_const_val(substring_size) == string_size) {
00108         FORTTK_DIE("should not invoke this");
00109     }
00110     xos << xml::BegElem(XAIFStrings.elem_ArrayElemRef())
00111         << xml::Attr("vertex_id", ctxt.currentXlationContext().getNewVertexId());
00112     xos << xml::BegElem(XAIFStrings.elem_IndexTriplet());
00113     xos << xml::BegElem(XAIFStrings.elem_Index());
00114     ctxt.createXlationContext(); 
00115     ctxt.currentXlationContext().unsetFlag(XlationContext::VARREF); // elem_Index() contains ExpressionType
00116     TranslateWN(xos, lower_bnd, ctxt);
00117     ctxt.deleteXlationContext();
00118     xos << xml::EndElem;
00119     xos << xml::BegElem(XAIFStrings.elem_Bound());
00120     ctxt.createXlationContext(); 
00121     ctxt.currentXlationContext().unsetFlag(XlationContext::VARREF); // elem_Index() contains ExpressionType
00122     TranslateWN(xos, substring_size, ctxt);
00123     ctxt.deleteXlationContext();
00124     xos << xml::EndElem;
00125     xos << xml::EndElem;
00126     xos << xml::EndElem;
00127   }
00128 
00129 
00130   static void
00131   WN2F_Get_Substring_Info(WN **base,        /* Possibly OPR_ARRAY node (in/out)*/
00132                           TY_IDX *string_ty,/* The string type (out) */
00133                           WN **lower_bnd,   /* The lower bound index (out) */
00134                           WN **length )
00135   {
00136     /* There are two possibilities concerning the array base expressions.
00137      * It can be a pointer to a complete character-string (array) or it
00138      * can be a pointer to a character within a character-string (single
00139      * character).  In the first instance, the offset off the base of 
00140      * string is zero.  In the latter case, the offset is given by the
00141      * array indexing operation.
00142      */
00143     TY_IDX ptr_ty = WN_Tree_Type(*base);
00144 
00145     // the WN_Tree_Type logic has been changed to 
00146     // return the actual result type rather than a 
00147     // low level compiler internal "void pointer" 
00148     // therefore this may not actually be a pointer type. 
00149     if ((TY_kind(ptr_ty) == KIND_POINTER) &&
00150         (TY_kind(TY_pointed(ptr_ty)) != KIND_FUNCTION))
00151       *string_ty = TY_pointed(ptr_ty);
00152     else
00153       *string_ty=ptr_ty;
00154 
00155     if (TY_size(*string_ty) == 1 && !TY_Is_Array(*string_ty)
00156         && WN_operator(*base) == OPR_ARRAY) {
00157       /* Let the base of the string be denoted as the base of the array
00158        * expression.
00159        */
00160       *string_ty = TY_pointed(WN_Tree_Type(WN_kid0(*base)));
00161       *lower_bnd = WN_array_index(*base, 0);
00162       *length    = WN_kid1(*base);
00163       *base = WN_kid0(*base);
00164     }
00165     else if (WN_operator(*base) == OPR_ARRAY &&
00166              TY_Is_Array(*string_ty)             &&
00167              TY_AR_ndims(*string_ty) == 1        &&
00168              TY_Is_Character_String(*string_ty)  &&
00169              !TY_ptr_as_array(Ty_Table[ptr_ty])) {
00170       /* Presumably, the lower bound is given by the array operator */
00171       *lower_bnd = WN_array_index(*base, 0);
00172       *length    = WN_kid1(*base);
00173       *base = WN_kid0(*base);
00174     }
00175     else {
00176       *lower_bnd = WN2F_INTCONST_ZERO;
00177       *length    = WN2F_INTCONST_ZERO;
00178     }
00179   } /* WN2F_Get_Substring_Info */
00180 
00181   static WN *
00182   WN2F_Find_Base(WN *addr)
00183   {
00184     /* utility to find base of address tree */
00185     WN *res = addr;
00186 
00187     switch (WN_operator(addr)) {
00188     case OPR_ARRAY: 
00189     case OPR_ILOAD:
00190       res=WN_kid0(addr);
00191       break;
00192 
00193     case OPR_ADD:
00194       if (WN_operator(WN_kid0(addr)) == OPR_INTCONST)
00195         res = WN2F_Find_Base(WN_kid1(addr));
00196       else
00197         res = WN2F_Find_Base(WN_kid0(addr));
00198       break;
00199 
00200     default:
00201       res = addr;
00202       break;
00203     }
00204     return res;
00205   }
00206 
00207   BOOL
00208   WN2F_Is_Address_Preg(WN * ad ,TY_IDX ptr_ty)
00209   {
00210     /* Does this look like a preg or variable being used as an address ? */
00211     /* These are propagated by opt/pfa                                   */
00212 
00213     BOOL is_somewhat_address_like = TY_kind(ptr_ty) == KIND_POINTER;
00214   
00215     if (TY_kind(ptr_ty) == KIND_SCALAR) {
00216       TYPE_ID tid = TY_mtype(ptr_ty);
00217       is_somewhat_address_like |= (MTYPE_is_pointer(tid)) || (tid == MTYPE_I8) || (tid == MTYPE_I4) ;
00218     }
00219 
00220     if (is_somewhat_address_like) {
00221       WN * wn = WN2F_Find_Base(ad);
00222       if (WN_operator(wn) == OPR_LDID) {
00223         ST * st = WN_st(wn) ;
00224         if (ST_class(st) == CLASS_PREG)
00225           return TRUE ;
00226       
00227         if (ST_class(st) == CLASS_VAR) {
00228           if (TY_kind(ptr_ty) == KIND_SCALAR)
00229             return TRUE;
00230         
00231           if (TY_kind(WN_ty(wn)) == KIND_SCALAR) {
00232             TYPE_ID wtid = TY_mtype(WN_ty(wn));
00233           
00234             /* Looks like a Cray pointer (I4/I8) ? */
00235             if ((wtid == MTYPE_I8)|| (wtid == MTYPE_I4))
00236               if (ad != wn)
00237                 return TRUE ;
00238           
00239             /* Looks like a VAR with a U4/U8? used  */
00240             /* only with offsets, or FORMALs would  */
00241             /* qualify, if intrinsic mtype          */
00242             if (MTYPE_is_pointer(wtid))
00243               if (TY_kind(ST_type(st)) != KIND_SCALAR)
00244                 return TRUE;
00245           }
00246         }
00247       }
00248     }
00249     return FALSE;
00250   }
00251 
00252 
00253   // ***************************************************************************
00254   // Loads (In WHIRL, loads are expressions.)
00255   // ***************************************************************************
00256 
00257   void 
00258   xlate_LDA(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00259   {
00260     FORTTK_ASSERT(WN_operator(wn) == OPR_LDA, fortTkSupport::Diagnostics::UnexpectedInput);
00261     FORTTK_ASSERT(ST_class(WN_st(wn)) != CLASS_PREG, "Cannot LDA a PREG");
00262   
00263     // Base and referenced (some offset, possibly 0, from base) objects
00264     ST* base_st = WN_st(wn); // symbol for base object
00265     TY_IDX base_ty = WN_GetBaseObjType(wn);
00266     TY_IDX baseptr_ty = Stab_Pointer_To(base_ty);
00267     TY_IDX ref_ty = WN_GetRefObjType(wn); // a pointer type
00268   
00269     // Implicit dereference (Note: sometimes we need to deal with buggy
00270     // WHIRL code, where ref_ty is not a pointer type.  In this case we
00271     // guess a type.
00272     ref_ty = (TY_Is_Pointer(ref_ty)) ? TY_pointed(ref_ty) : base_ty;
00273   
00274     ctxt.currentXlationContext().setWN(wn);
00275     ctxt.currentXlationContext().unsetFlag(XlationContext::DEREF_ADDR);
00276     ctxt.currentXlationContext().setFlag(XlationContext::HAS_NO_ARR_ELMT);
00277     xlate_SymRef(xos, base_st, baseptr_ty, ref_ty, WN_lda_offset(wn), ctxt);
00278     ctxt.currentXlationContext().unsetFlag(XlationContext::HAS_NO_ARR_ELMT);
00279   
00280     
00281   }
00282 
00283 
00284   void 
00285   xlate_LDID(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00286   {
00287     FORTTK_ASSERT(WN_operator(wn) == OPR_LDID, fortTkSupport::Diagnostics::UnexpectedInput);
00288 
00289     // Base and referenced (some offset, possibly 0, from base) objects
00290     TY_IDX base_ty = WN_GetBaseObjType(wn);
00291     TY_IDX baseptr_ty;
00292     TY_IDX ref_ty = WN_GetRefObjType(wn);
00293   
00294     if (ST_class(WN_st(wn)) == CLASS_PREG) {
00295       // Note: WN_load_offset() is the PREG_IDX
00296       ctxt.currentXlationContext().setWN(wn);
00297       xlate_PregRef(xos, WN_st(wn), base_ty, WN_load_offset(wn), ctxt);
00298     } 
00299     else {
00300 
00301       // FIXME: Stab_Pointer_To, et. al. create types!!!
00302       if (ctxt.currentXlationContext().isFlag(XlationContext::DEREF_ADDR) && TY_Is_Pointer(base_ty)) {
00303         // Expect the loaded type to be a pointer to the type of object
00304         // to be dereferenced.  The only place (besides declaration sites)
00305         // where we expect to specially handle ptr_as_array objects.
00306         if (TY_ptr_as_array(Ty_Table[ref_ty])) {
00307           ref_ty = Stab_Array_Of(TY_pointed(ref_ty), 0/*size*/);
00308         } else {
00309           ref_ty = TY_pointed(ref_ty);
00310         }
00311       
00312         // There are two possibilities for the base type: A regular 
00313         // pointer or a pointer to be treated as a pointer to an array.
00314         // In either case, 'baseptr_ty' is a pointer to the 
00315         // derefenced base type. 
00316         //
00317         // Note that this does not handle a pointer to a struct to be
00318         // treated as an array of structs, where the object type and
00319         // offset denote a member of the struct, since xlate_SymRef() 
00320         // cannot access a struct member through an array access.
00321         if (TY_ptr_as_array(Ty_Table[base_ty])) {
00322           base_ty = Stab_Array_Of(TY_pointed(base_ty), 0/*size*/);
00323         } else {
00324           base_ty = TY_pointed(base_ty); // baseptr_ty = base_ty;
00325         }
00326       } 
00327       baseptr_ty = Stab_Pointer_To(base_ty);
00328     
00329       ctxt.currentXlationContext().setWN(wn);
00330       ctxt.currentXlationContext().setFlag(XlationContext::HAS_NO_ARR_ELMT); // FIXME why?
00331       xlate_SymRef(xos, WN_st(wn), baseptr_ty, ref_ty, WN_load_offset(wn), ctxt);
00332       ctxt.currentXlationContext().unsetFlag(XlationContext::HAS_NO_ARR_ELMT);
00333     }
00334 
00335     
00336   } 
00337 
00338 
00339   void 
00340   xlate_ILOAD(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00341   {
00342     // Note that we handle this just like we do the lhs of an ISTORE.
00343     FORTTK_ASSERT(WN_operator(wn) == OPR_ILOAD, fortTkSupport::Diagnostics::UnexpectedInput);
00344   
00345     // Base and referenced (some offset, possibly 0, from base) objects
00346     WN* baseptr = WN_kid0(wn); // address expression as WN
00347     TY_IDX base_ty = WN_GetBaseObjType(wn);
00348     TY_IDX baseptr_ty = Stab_Pointer_To(base_ty);
00349     TY_IDX ref_ty = WN_GetRefObjType(wn);
00350   
00351     // Translate into a reference
00352     ctxt.currentXlationContext().setWN(wn);
00353     if (WN_operator(baseptr) == OPR_LDA || WN_operator(baseptr) == OPR_LDID) {
00354       ctxt.currentXlationContext().setFlag(XlationContext::HAS_NO_ARR_ELMT); // FIXME
00355     }
00356   
00357     xlate_MemRef(xos, baseptr, baseptr_ty, ref_ty, WN_load_offset(wn), ctxt);
00358   
00359     ctxt.currentXlationContext().unsetFlag(XlationContext::HAS_NO_ARR_ELMT);
00360 
00361     
00362   }
00363 
00364   void 
00365   xlate_ILOADX(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00366   {
00367     FORTTK_DIE(fortTkSupport::Diagnostics::Unimplemented);
00368     xos << OPCODE_name(WN_opcode(wn));
00369     
00370   }
00371 
00372 
00373   void 
00374   WN2F_mload(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00375   {
00376     // This should only appear the as the rhs of an ISTORE.  Treat
00377     // it just like an ILOAD.
00378     FORTTK_ASSERT(WN_operator(wn) == OPR_MLOAD, fortTkSupport::Diagnostics::UnexpectedInput);
00379 
00380     // FIXME:
00381     
00382     /* Get the type of the base from which we are loading */
00383     TY_IDX base_ty = WN_Tree_Type(WN_kid0(wn));
00384     if (!TY_Is_Pointer(base_ty))
00385       base_ty = WN_ty(wn);
00386   
00387     /* Get the object to be loaded */
00388     xlate_MemRef(xos, WN_kid0(wn), /* base-symbol */
00389                  base_ty, /* base-type */
00390                  TY_pointed(WN_ty(wn)), /* object-type */
00391                  WN_load_offset(wn), /* object-ofst */ ctxt);
00392 
00393     
00394   }
00395 
00396 
00397   // ***************************************************************************
00398   // Stores (In WHIRL, stores are statements.)
00399   // ***************************************************************************
00400 
00401   // xlate_STID: Translate a WHIRL STID node to an XAIF assignment
00402   void 
00403   xlate_STID(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00404   {
00405     FORTTK_ASSERT(WN_operator(wn) == OPR_STID, fortTkSupport::Diagnostics::UnexpectedInput);
00406 
00407     // LHS base and referenced (some offset, possibly 0, from base) objects
00408     ST* base_st = WN_st(wn); // symbol for base object
00409     TY_IDX base_ty = WN_GetBaseObjType(wn);
00410     TY_IDX baseptr_ty = Stab_Pointer_To(base_ty);
00411     TY_IDX ref_ty = WN_GetRefObjType(wn);
00412   
00413     // Assignment
00414     if (!ctxt.currentXlationContext().isFlag(XlationContext::ASSIGN)) {
00415       USRCPOS srcpos;
00416       USRCPOS_srcpos(srcpos) = WN_Get_Linenum(wn);
00417       xos << xml::BegElem(XAIFStrings.elem_Assign())
00418           << xml::Attr("statement_id", ctxt.findWNId(wn))
00419           << xml::Attr("lineNumber",USRCPOS_linenum(srcpos))    
00420           << xml::Attr("do_chain", ctxt.findDoChainId(wn));
00421     }
00422   
00423     // LHS of assignment
00424     WN* lhs = wn; // OPR_STID represents the LHS of the assignment
00425     xos << xml::BegElem(XAIFStrings.elem_AssignLHS()) 
00426         << xml::Attr("du_ud", ctxt.findUDDUChainId(lhs))
00427         << xml::Attr("alias", ctxt.getAliasMapKey(lhs))
00428         << xml::EndAttrs;
00429     ctxt.createXlationContext(XlationContext::VARREF, wn); // implicit for LHS
00430   
00431     if (ST_class(base_st) == CLASS_PREG) { // FIXME
00432       // Note: WN_load_offset() is the PREG_IDX
00433       xlate_PregRef(xos, base_st, base_ty, WN_store_offset(wn), ctxt);
00434     } 
00435     else {
00436       xlate_SymRef(xos, base_st, baseptr_ty, ref_ty, WN_store_offset(wn), ctxt);
00437     }
00438   
00439     ctxt.deleteXlationContext();
00440     xos << xml::EndElem;
00441   
00442     // RHS of assignment
00443     BOOL logical = TY_is_logical(Ty_Table[ref_ty]); // FIXME
00444     xos << xml::BegElem(XAIFStrings.elem_AssignRHS()) << xml::EndAttrs;
00445     ctxt.createXlationContext(XlationContext::NOFLAG, wn);
00446     if (logical) { 
00447       ctxt.currentXlationContext().setFlag(XlationContext::HAS_LOGICAL_ARG); 
00448     } // FIXME
00449     TranslateWN(xos, WN_kid0(wn), ctxt);
00450     if (logical) { 
00451       ctxt.currentXlationContext().unsetFlag(XlationContext::HAS_LOGICAL_ARG); 
00452     } // FIXME
00453     ctxt.deleteXlationContext();
00454     xos << xml::EndElem;
00455 
00456     if (!ctxt.currentXlationContext().isFlag(XlationContext::ASSIGN)) {
00457       xos << xml::EndElem /* elem_Assign() */;
00458     }
00459   
00460     
00461   }
00462 
00463   void 
00464   xlate_ISTORE(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00465   {
00466     FORTTK_ASSERT(WN_operator(wn) == OPR_ISTORE, fortTkSupport::Diagnostics::UnexpectedInput);
00467 
00468     // LHS base and referenced (some offset, possibly 0, from base) objects
00469     WN* baseptr = WN_kid1(wn); // address expression as WN
00470     TY_IDX base_ty = WN_GetBaseObjType(wn);
00471     TY_IDX baseptr_ty = Stab_Pointer_To(base_ty);
00472     TY_IDX ref_ty = WN_GetRefObjType(wn);
00473   
00474     // Assignment
00475     if (!ctxt.currentXlationContext().isFlag(XlationContext::ASSIGN)) {
00476       USRCPOS srcpos;
00477       USRCPOS_srcpos(srcpos) = WN_Get_Linenum(wn);
00478       xos << xml::BegElem(XAIFStrings.elem_Assign())
00479           << xml::Attr("statement_id", ctxt.findWNId(wn))
00480           << xml::Attr("lineNumber",USRCPOS_linenum(srcpos))    
00481           << xml::Attr("do_chain", ctxt.findDoChainId(wn));
00482     }
00483   
00484     // LHS of assignment (dereference address)
00485     WN* lhs = baseptr;
00486     xos << xml::BegElem(XAIFStrings.elem_AssignLHS()) 
00487         << xml::Attr("du_ud", ctxt.findUDDUChainId(lhs))
00488         << xml::Attr("alias", ctxt.getAliasMapKey(lhs))
00489         << xml::EndAttrs;
00490     ctxt.createXlationContext(XlationContext::VARREF, wn); // implicit for LHS
00491   
00492     if (WN_operator(baseptr) == OPR_LDA || WN_operator(baseptr) == OPR_LDID) {
00493       ctxt.currentXlationContext().setFlag(XlationContext::HAS_NO_ARR_ELMT);
00494     }
00495     xlate_MemRef(xos, baseptr, baseptr_ty, ref_ty, WN_store_offset(wn), ctxt);
00496     ctxt.currentXlationContext().unsetFlag(XlationContext::HAS_NO_ARR_ELMT); 
00497 
00498     ctxt.deleteXlationContext();
00499     xos << xml::EndElem;
00500 
00501     // RHS of assignment
00502     xos << xml::BegElem(XAIFStrings.elem_AssignRHS()) << xml::EndAttrs;
00503     ctxt.createXlationContext(XlationContext::NOFLAG, wn);
00504     TranslateWN(xos, WN_kid0(wn), ctxt);
00505     ctxt.deleteXlationContext();
00506     xos << xml::EndElem;
00507 
00508     if (!ctxt.currentXlationContext().isFlag(XlationContext::ASSIGN)) {
00509       xos << xml::EndElem /* elem_Assign() */;
00510     }
00511   
00512     
00513   }
00514 
00515   void 
00516   xlate_ISTOREX(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00517   {
00518     FORTTK_DIE(fortTkSupport::Diagnostics::Unimplemented);
00519     xos << std::endl << OPCODE_name(WN_opcode(wn));
00520     
00521   }
00522 
00523 
00524   void 
00525   WN2F_mstore(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00526   {
00527     /* Note that we make the assumption that this is just like an 
00528      * ISTORE, and handle it as though it were.  We do not handle
00529      * specially assignment-forms where the lhs is incompatible with
00530      * the rhs, since we assume this will never happen for Fortran
00531      * and we cannot easily get around this like we do in C (i.e.
00532      * with cast expressions. (FIXME)
00533      */
00534     FORTTK_ASSERT(WN_operator(wn) == OPR_MSTORE, fortTkSupport::Diagnostics::UnexpectedInput);
00535 #if 0
00536     FORTTK_ASSERT_WARN(WN_operator(WN_kid0(wn)) == OPR_MLOAD,
00537                        fortTkSupport::Diagnostics::UnexpectedOpr << "rhs of WN2F_mstore");
00538   
00539     //TODO: scalar expression allowed, but array/structure assignment assumed
00540     // with constant ie: should put out doloop?... call OFFSET_Memref?
00541 #endif
00542 
00543     /* Get the base address into which we are storing a value */
00544     TY_IDX base_ty = WN_Tree_Type(WN_kid1(wn));
00545     if (!TY_Is_Pointer(base_ty))
00546       base_ty = WN_ty(wn);
00547   
00548     /* Get the lhs of the assignment (dereference address) */
00549     xos << std::endl; 
00550     xlate_MemRef(xos, WN_kid1(wn),      /* base-symbol */
00551                  base_ty,               /* base-type */ 
00552                  TY_pointed(WN_ty(wn)), /* object-type */
00553                  WN_store_offset(wn),   /* object-ofst */ 
00554                  ctxt);
00555   
00556     // Assign the rhs to the lhs.
00557     xos << "mstore=" << std::endl;
00558   
00559     /* The rhs */
00560     TranslateWN(xos, WN_kid0(wn), ctxt);
00561 
00562     
00563   }
00564 
00565 
00566   void
00567   WN2F_pstid(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00568   {
00569     FORTTK_ASSERT(WN_operator(wn) == OPR_PSTID, fortTkSupport::Diagnostics::UnexpectedInput);
00570   
00571     /* Get the lhs of the assignment */
00572     xos << std::endl;
00573     if (ST_class(WN_st(wn)) == CLASS_PREG) {
00574       xlate_PregRef(xos, WN_st(wn), ST_type(WN_st(wn)), WN_store_offset(wn), 
00575                     ctxt);
00576     } 
00577     else {
00578       xlate_SymRef(xos, WN_st(wn),                      /* base-symbol */
00579                    Stab_Pointer_To(ST_type(WN_st(wn))), /* base-type */
00580                    WN_ty(wn),                           /* object-type */
00581                    WN_store_offset(wn),                 /* object-ofst */
00582                    ctxt);
00583     }
00584   
00585     // Assign the rhs to the lhs.
00586     xos << "pstid=>";
00587   
00588     /* The rhs */
00589     if (TY_is_logical(Ty_Table[WN_ty(wn)])) {
00590       ctxt.currentXlationContext().setFlag(XlationContext::HAS_LOGICAL_ARG);
00591       TranslateWN(xos, WN_kid0(wn), ctxt);
00592       ctxt.currentXlationContext().unsetFlag(XlationContext::HAS_LOGICAL_ARG);
00593     } else
00594       TranslateWN(xos, WN_kid0(wn), ctxt);
00595   
00596     
00597   } /* WN2F_pstid */
00598 
00599 
00600   void
00601   WN2F_pstore(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00602   {
00603     TY_IDX        base_ty;
00604     FORTTK_ASSERT(WN_operator(wn) == OPR_PSTORE, fortTkSupport::Diagnostics::UnexpectedInput);
00605   
00606     /* Get the base address into which we are storing a value */
00607     base_ty = WN_Tree_Type(WN_kid1(wn));
00608     if (!TY_Is_Pointer(base_ty))
00609       base_ty = WN_ty(wn);
00610   
00611     /* Get the lhs of the assignment (dereference address) */
00612     xos << std::endl;
00613     ctxt.currentXlationContext().setFlag(XlationContext::HAS_NO_ARR_ELMT);
00614   
00615     xlate_MemRef(xos,
00616                  WN_kid1(wn),           /* base-symbol */
00617                  base_ty,               /* base-type */
00618                  TY_pointed(WN_ty(wn)), /* object-type */
00619                  WN_store_offset(wn),   /* object-ofst */
00620                  ctxt);
00621     ctxt.currentXlationContext().unsetFlag(XlationContext::HAS_NO_ARR_ELMT);
00622   
00623     // Assign the rhs to the lhs.
00624     xos << "pstore=>";
00625   
00626     /* The rhs */
00627     if (TY_is_logical(Ty_Table[TY_pointed(WN_ty(wn))])) {
00628       ctxt.currentXlationContext().setFlag(XlationContext::HAS_LOGICAL_ARG);
00629       TranslateWN(xos, WN_kid0(wn), ctxt);
00630       ctxt.currentXlationContext().unsetFlag(XlationContext::HAS_LOGICAL_ARG);
00631     } 
00632     else {
00633       TranslateWN(xos, WN_kid0(wn), ctxt);
00634     }
00635   
00636     
00637   } /* WN2F_pstore */
00638 
00639   // ***************************************************************************
00640   // Array Operators (N-ary Operations)
00641   // ***************************************************************************
00642 
00643   void
00644   xlate_ARRAY(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00645   {
00646     // N.B.: WHIRL indices are 0-based and memory layout is row-major
00647     // (right-most index represents contiguous elements).  
00648     // In contrast, Fortran indices are 1-based and memory layout is
00649     // column-major (left-most index represents contiguous elements).
00650     // To convert WHIRL indices into a Fortran index expression, reverse
00651     // their order and denormalize to base 1.
00652   
00653     /* Note that array indices have been normalized to assume the
00654      * array is based at index zero.  Since a base at index 1 is
00655      * the default for Fortran, we denormalize to base 1 here. */
00656     FORTTK_ASSERT(WN_operator(wn) == OPR_ARRAY, fortTkSupport::Diagnostics::UnexpectedInput);
00657 
00658     BOOL deref = ctxt.currentXlationContext().isFlag(XlationContext::DEREF_ADDR);
00659   
00660     // Only allow taking the address of an array element for F90!
00661 #if 0
00662     FORTK_ASSERT_WARN(deref, "taking the address of an array element");
00663 #endif
00664 
00665     bool newContext = false; // FIXME: abstract (symref, memref)
00666     if (!ctxt.currentXlationContext().isFlag(XlationContext::VARREF)) {
00667       xos << xml::BegElem(XAIFStrings.elem_VarRef())
00668           << xml::Attr("vertex_id", ctxt.currentXlationContext().getNewVertexId())
00669           << xml::Attr("du_ud", ctxt.findUDDUChainId(wn))
00670           << xml::Attr("alias", ctxt.getAliasMapKey(wn));
00671       ctxt.createXlationContext(XlationContext::VARREF, wn); // FIXME: do we need wn?
00672       newContext = true; 
00673     }
00674 
00675     /* Get the array or, for ptr-as-array types, the element type */  
00676     WN* kid = WN_kid0(wn);
00677     TY_IDX ptr_ty = WN_Tree_Type(kid);
00678   
00679     if (WN2F_Is_Address_Preg(kid, ptr_ty)) {
00680       /* a preg or sym has been used as an address, usually after
00681          optimization don't know base type, or anything else so use
00682          OPR_ARRAY to generate bounds */
00683       TranslateWN(xos, kid, ctxt);
00684       xlate_ArrayIndices(xos, wn, ctxt);
00685       // FIXME
00686     } else {
00687       TY_IDX array_ty = TY_pointed(ptr_ty); // base of OPR_ARRAY
00688     
00689       if (WN_operator(kid) == OPR_LDID 
00690           && ST_sclass(WN_st(kid)) == SCLASS_FORMAL 
00691           && !ST_is_value_parm(WN_st(kid))
00692           && WN_element_size(wn) == (INT64)TY_size(array_ty)
00693           && WN_num_dim(wn) == 1
00694           && WN_operator(WN_array_index(wn, 0)) == OPR_INTCONST 
00695           && WN_const_val(WN_array_index(wn, 0)) == 0 
00696           && !TY_ptr_as_array(Ty_Table[WN_ty(kid)])
00697           && (!TY_Is_Array(array_ty) 
00698               || TY_size(TY_AR_etype(array_ty)) < TY_size(array_ty))) {
00699         // This array access is just a weird representation for an implicit
00700         // reference parameter dereference.  Ignore the array indexing.
00701         TranslateWN(xos, kid, ctxt);
00702 
00703       } else if (!TY_ptr_as_array(Ty_Table[ptr_ty]) 
00704                  && TY_Is_Character_String(array_ty) ) {
00705         /* We assume that substring accesses are treated in the handling
00706          * of intrinsic functions, except when the substrings are to be
00707          * handled as integral types and thus are encountered here. */
00708         WN2F_String_Argument(xos, wn, WN2F_INTCONST_ONE, ctxt);
00709       } else { 
00710         // A regular array access
00711 
00712         // Array base
00713         UINT srcid = ctxt.currentXlationContext().peekVertexId();
00714         TranslateWN(xos, kid, ctxt); // still use ctxt.currentXlationContext().isFlag(XlationContext::DEREF_ADDR)
00715         ctxt.currentXlationContext().unsetFlag(XlationContext::DEREF_ADDR);
00716 
00717         // Array indexing
00718         UINT targid = ctxt.currentXlationContext().peekVertexId();
00719         WN2F_array_bounds(xos, wn, array_ty, ctxt);
00720       
00721         DumpVarRefEdge(xos, ctxt.currentXlationContext().getNewEdgeId(), srcid, targid);
00722       }
00723     }
00724   
00725     if (newContext) {
00726       ctxt.deleteXlationContext();
00727       xos << xml::EndElem /* elem_VarRef() */;
00728     }
00729   
00730     
00731   } /* xlate_ARRAY */
00732 
00733 
00734   /*
00735     |*                                                                           *|
00736     |* for array section triplet node,kid0 is lower bound,it should plus 1LL for *|
00737     |* adjusted bound,upper bound=kid0+k1*k2                                     *|
00738     |* kid0 evaluates to the starting integer value of the progression.      *|
00739     |* kid1 evaluates to an integer value that gives the stride in the           *|
00740     |*   progression                                                             *|
00741     |* kid2 evaluates to the number of values in the progression             *|
00742     |*                                                                           *|
00743   */
00744   void
00745   WN2F_triplet(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00746   {
00747     WN      *kid0;
00748     WN      *kid1;
00749     WN      *kid2;
00750     kid0=WN_kid0(wn);
00751     kid1=WN_kid1(wn);
00752     kid2=WN_kid2(wn);
00753     TranslateWN(xos, kid0, ctxt);
00754     if ((WN_operator(kid2) == OPR_INTCONST) &&
00755         (WN_const_val(kid2)==INT_MIN) )
00756       xos << ":";
00757     else  {
00758       xos << ":";
00759       if (WN_operator(kid0) == OPR_INTCONST &&
00760           WN_operator(kid1) == OPR_INTCONST &&
00761           WN_operator(kid2) == OPR_INTCONST) {
00762         std::string val;
00763         if ((WN_const_val(kid0)+WN_const_val(kid2)*WN_const_val(kid1))>=INT_MAX)
00764           val = TCON2F_translate(Host_To_Targ(MTYPE_I8, WN_const_val(kid0)+
00765                                               WN_const_val(kid2)*
00766                                               WN_const_val(kid1)),
00767                                  FALSE);
00768         else    
00769           val = TCON2F_translate(Host_To_Targ(MTYPE_I4, WN_const_val(kid0)+
00770                                               WN_const_val(kid2)*
00771                                               WN_const_val(kid1)),
00772                                  FALSE);
00773         xos << val;
00774       
00775       } 
00776       else 
00777         if (WN_operator(kid0) == OPR_INTCONST &&
00778             WN_operator(kid1) == OPR_INTCONST ) {
00779           if (WN_const_val(kid1)==1) {
00780             if (WN_const_val(kid0)== 0) {
00781               TranslateWN(xos, kid2, ctxt);
00782             }
00783             else {
00784               TranslateWN(xos, kid1, ctxt);
00785               xos << "+";
00786               TranslateWN(xos, kid2, ctxt); }
00787           }
00788           else {
00789             if (WN_const_val(kid0)== 0){
00790               TranslateWN(xos, kid1, ctxt);
00791               xos << "*";
00792               TranslateWN(xos, kid2, ctxt); }
00793             else {
00794               TranslateWN(xos, kid0, ctxt);
00795               xos << "+";
00796               TranslateWN(xos, kid1, ctxt);
00797               xos << "*";
00798               TranslateWN(xos, kid2, ctxt); }
00799           }
00800         }
00801         else 
00802           if (WN_operator(kid1) == OPR_INTCONST &&
00803               WN_operator(kid2) == OPR_INTCONST) {
00804             TranslateWN(xos, kid0, ctxt);
00805             xos << "+";
00806           
00807             std::string val;
00808             if ((WN_const_val(kid1)*WN_const_val(kid2))>=INT_MAX)
00809               val = TCON2F_translate(Host_To_Targ(MTYPE_I8,   
00810                                                   WN_const_val(kid1)*
00811                                                   WN_const_val(kid2)),
00812                                      FALSE);
00813             else 
00814               val = TCON2F_translate(Host_To_Targ(MTYPE_I4,   
00815                                                   WN_const_val(kid1)*
00816                                                   WN_const_val(kid2)),
00817                                      FALSE);
00818           }
00819           else 
00820             if (WN_operator(kid0) == OPR_INTCONST &&
00821                 WN_operator(kid2) == OPR_INTCONST) {
00822               if (WN_const_val(kid2)==1) {
00823                 if (WN_const_val(kid0)== 0) {
00824                   TranslateWN(xos, kid1, ctxt);
00825                 }
00826                 else {
00827                   TranslateWN(xos, kid0, ctxt);
00828                   xos << "+";
00829                   TranslateWN(xos, kid1, ctxt); 
00830                 }
00831               }
00832               else {
00833                 if (WN_const_val(kid0)== 0){
00834                   TranslateWN(xos, kid2, ctxt);
00835                   xos << "*";
00836                   TranslateWN(xos, kid1, ctxt); }
00837                 else {
00838                   TranslateWN(xos, kid0, ctxt);
00839                   xos << "+";
00840                   TranslateWN(xos, kid1, ctxt);
00841                   xos << "*";
00842                   TranslateWN(xos, kid2, ctxt); }
00843               }
00844             }
00845             else 
00846               if (WN_operator(kid0) == OPR_INTCONST){ 
00847                 if (WN_const_val(kid0)==0) {
00848                   TranslateWN(xos, kid1, ctxt);
00849                   xos << "*";
00850                   TranslateWN(xos, kid2, ctxt);}
00851                 else {
00852                   TranslateWN(xos, kid0, ctxt);
00853                   xos << "+";
00854                   TranslateWN(xos, kid1, ctxt);
00855                   xos << "*";
00856                   TranslateWN(xos, kid2, ctxt);
00857                 }
00858               }
00859               else 
00860                 if (WN_operator(kid1) == OPR_INTCONST){
00861                   TranslateWN(xos, kid0, ctxt);
00862                   xos << "+";
00863                   if (WN_const_val(kid1)==1){
00864                     TranslateWN(xos, kid2, ctxt);}
00865                   else {
00866                     TranslateWN(xos, kid1, ctxt);
00867                     xos << "*";
00868                     TranslateWN(xos, kid2, ctxt);
00869                   }
00870                 }
00871                 else
00872                   if (WN_operator(kid2) == OPR_INTCONST) {
00873                     TranslateWN(xos, kid0, ctxt);
00874                     xos << "+";
00875                     if (WN_const_val(kid2)==1)
00876                       TranslateWN(xos, kid1, ctxt);
00877                     else
00878                       {
00879                         TranslateWN(xos, kid2, ctxt);
00880                         xos << "*";
00881                         TranslateWN(xos, kid1, ctxt);
00882                       }
00883                   }
00884       if ((WN_operator(kid1) == OPR_INTCONST) && 
00885           (WN_const_val(kid1)==1))  {
00886       } else {
00887         xos << ":";
00888         TranslateWN(xos, kid1, ctxt);
00889       } 
00890     }  
00891     
00892   
00893   }
00894 
00895   void
00896   WN2F_src_triplet(xml::ostream& xos, WN* wn, PUXlationContext& ctxt) {
00897     if (WN_operator(WN_kid0(wn))!= OPR_IMPLICIT_BND) {
00898       xos << xml::BegElem(XAIFStrings.elem_Index());
00899       ctxt.createXlationContext(); 
00900       ctxt.currentXlationContext().unsetFlag(XlationContext::VARREF); // elem_Index() contains ExpressionType
00901       TranslateWN(xos, WN_kid0(wn), ctxt);
00902       ctxt.deleteXlationContext();
00903       xos << xml::EndElem;
00904     }
00905     if (WN_operator(WN_kid1(wn))!= OPR_IMPLICIT_BND) { 
00906       xos << xml::BegElem(XAIFStrings.elem_Bound());
00907       ctxt.createXlationContext(); 
00908       ctxt.currentXlationContext().unsetFlag(XlationContext::VARREF); // elem_Bound() contains ExpressionType
00909       TranslateWN(xos, WN_kid1(wn), ctxt); 
00910       ctxt.deleteXlationContext();
00911       xos << xml::EndElem;
00912     }
00913     xos << xml::BegElem(XAIFStrings.elem_Stride());
00914     ctxt.createXlationContext(); 
00915     ctxt.currentXlationContext().unsetFlag(XlationContext::VARREF); // elem_Stride() contains ExpressionType
00916     TranslateWN(xos, WN_kid2(wn), ctxt); 
00917     ctxt.deleteXlationContext();
00918     xos << xml::EndElem;
00919   }
00920 
00921   void
00922   WN2F_arrayexp(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00923   {
00924     TranslateWN(xos, WN_kid0(wn), ctxt);
00925     
00926   }
00927   
00928 
00929   void
00930   WN2F_arrsection(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
00931   {
00932     /* Note that array indices have been normalized to assume the
00933      * array is based at index zero.  Since a base at index 1 is
00934      * the default for Fortran, we denormalize to base 1 here.
00935      */
00936     FORTTK_ASSERT(WN_operator(wn) == OPR_ARRSECTION, fortTkSupport::Diagnostics::UnexpectedInput);
00937 
00938     BOOL  deref = ctxt.currentXlationContext().isFlag(XlationContext::DEREF_ADDR);
00939     WN    * kid;
00940     TY_IDX ptr_ty;
00941     TY_IDX array_ty;
00942 
00943     /* Only allow taking the address of an array element for F90!
00944      *
00945      */
00946 #if 0
00947     FORTTK_ASSERT_WARN(deref, "taking the address of an array element");
00948 #endif
00949 
00950     /* Get the array or, for ptr-as-array types, the element type */
00951     kid    = WN_kid0(wn);
00952     ptr_ty = WN_Tree_Type(kid);
00953 
00954     if (WN2F_Is_Address_Preg(kid,ptr_ty) or !TY_Is_Pointer(ptr_ty)) {
00955       /* a preg or sym has been used as an address, usually after
00956          optimization don't know base type, or anything else so use
00957          OPR_ARRAY to generate bounds */
00958 
00959       UINT srcid = ctxt.currentXlationContext().peekVertexId();
00960       TranslateWN(xos, kid, ctxt);
00961       // Array indexing
00962       UINT targid = ctxt.currentXlationContext().peekVertexId();
00963       WN2F_Arrsection_Slots(xos,wn,ctxt);
00964       DumpVarRefEdge(xos, ctxt.currentXlationContext().getNewEdgeId(), srcid, targid);
00965     }
00966     else {
00967       array_ty = TY_pointed(ptr_ty); // base of OPR_ARRAY
00968     
00969       if (WN_operator(kid) == OPR_LDID       &&
00970 
00971           ST_sclass(WN_st(kid)) == SCLASS_FORMAL &&
00972           !ST_is_value_parm(WN_st(kid))          &&
00973           WN_element_size(wn) == (INT64)TY_size(array_ty)       &&
00974           WN_num_dim(wn) == 1                            &&
00975           WN_operator(WN_array_index(wn, 0)) == OPR_INTCONST &&
00976           WN_const_val(WN_array_index(wn, 0)) == 0       &&
00977           !TY_ptr_as_array(Ty_Table[WN_ty(kid)])           &&
00978           (!TY_Is_Array(array_ty) ||
00979            TY_size(TY_AR_etype(array_ty)) < TY_size(array_ty))) {
00980         /* This array access is just a weird representation for an implicit
00981          * reference parameter dereference.  Ignore the array indexing.
00982          */
00983 
00984         TranslateWN(xos, kid, ctxt);
00985       }
00986       else if (!TY_ptr_as_array(Ty_Table[ptr_ty]) 
00987                && TY_Is_Character_String(array_ty)) {
00988         /* We assume that substring accesses are treated in the handling
00989          * of intrinsic functions, except when the substrings are to be
00990          * handled as integral types and thus are encountered here.
00991          */
00992         WN2F_String_Argument(xos, wn, WN2F_INTCONST_ONE, ctxt);
00993       }
00994       else { /* A regular array access */
00995         /* Get the base of the object to be indexed into, still using
00996          * ctxt.currentXlationContext().isFlag(XlationContext::DEREF_ADDR).
00997          */
00998         bool newContext=false;
00999         if (!ctxt.currentXlationContext().isFlag(XlationContext::VARREF)) {
01000           xos << xml::BegElem(XAIFStrings.elem_VarRef())
01001               << xml::Attr("vertex_id", ctxt.currentXlationContext().getNewVertexId())
01002               << xml::Attr("du_ud", ctxt.findUDDUChainId(wn))
01003               << xml::Attr("alias", ctxt.getAliasMapKey(wn));
01004           ctxt.createXlationContext(XlationContext::VARREF, wn);
01005           newContext=true;
01006         }
01007         UINT srcid = ctxt.currentXlationContext().peekVertexId();
01008         TranslateWN(xos, kid, ctxt);
01009         ctxt.currentXlationContext().unsetFlag(XlationContext::DEREF_ADDR);
01010        
01011         if ( ctxt.currentXlationContext().isFlag(XlationContext::HAS_NO_ARR_ELMT))
01012           ;
01013         else { 
01014           UINT targid = ctxt.currentXlationContext().peekVertexId();
01015           WN2F_arrsection_bounds(xos,wn,array_ty,ctxt);
01016           DumpVarRefEdge(xos, ctxt.currentXlationContext().getNewEdgeId(), srcid, targid);
01017         }
01018         if (newContext) {
01019           ctxt.deleteXlationContext();
01020           xos << xml::EndElem /* elem_VarRef() */;
01021         }
01022       }
01023     }
01024     
01025   } /* WN2F_arrsection */
01026 
01027 
01028   void 
01029   WN2F_where(xml::ostream& xos, 
01030              WN* wn, 
01031              PUXlationContext& ctxt) {
01032     xos << "WHERE(";
01033     TranslateWN(xos, WN_kid0(wn), ctxt);
01034     xos << ")";
01035     TranslateWN(xos, WN_kid1(wn), ctxt);
01036     xos << "END WHERE";
01037     TranslateWN(xos, WN_kid2(wn), ctxt);
01038   }
01039 
01040 
01041   void
01042   WN2F_Arrsection_Slots(xml::ostream& xos, WN* wn, PUXlationContext& ctxt) {
01043     INT32 dim;
01044     INT32 array_dim;
01045     TY_IDX ttyy;
01046     ARB_HANDLE arb_base;
01047     WN* kid;
01048     /* Gets bounds from the slots of an OPC_ARRSECTION node  */
01049     /* Append the "denormalized" indexing expressions in reverse order
01050      * of the way they occur in the indexing expression, since Fortran
01051      * employs column-major array layout, meaning the leftmost indexing
01052      * expression represents array elements laid out in contiguous
01053      * memory locations.
01054      */
01055     WN* kid0 = WN_kid0(wn);
01056     if (WN_operator(kid0)==OPR_ILOAD && WN_operator(WN_kid0(kid0)) == OPR_STRCTFLD) { 
01057       kid0 = WN_kid0(kid0);
01058     }
01059     if (WN_operator(kid0)==OPR_STRCTFLD) { 
01060       ttyy=WN_GetRefObjType(kid0);
01061     }
01062     else { 
01063       ttyy = ST_type(WN_st(kid0));
01064     }
01065     if (TY_Is_Pointer(ttyy))  //Sept temp use
01066       ttyy=TY_pointed(ttyy);
01067     if (TY_is_f90_pointer(ttyy))
01068       ttyy = TY_pointed(ttyy);
01069     arb_base = TY_arb(ttyy);
01070     array_dim =  ARB_dimension(arb_base);
01071     if (array_dim>0) {
01072       xos << xml::BegElem(XAIFStrings.elem_ArrayElemRef())
01073           << xml::Attr("vertex_id", ctxt.currentXlationContext().getNewVertexId());
01074       for (dim = WN_num_dim(wn)-1; dim >= 0; --dim) {
01075         xos << xml::BegElem(XAIFStrings.elem_IndexTriplet());
01076         if (WN_operator(WN_array_index(wn, dim))==OPR_SRCTRIPLET) {
01077           TranslateWN(xos, WN_array_index(wn, dim), ctxt);
01078         } else {
01079           xos << xml::BegElem(XAIFStrings.elem_Index());
01080           ctxt.createXlationContext(); 
01081           ctxt.currentXlationContext().unsetFlag(XlationContext::VARREF); // elem_Index() contains ExpressionType
01082           TranslateWN(xos, WN_array_index(wn, dim), ctxt);
01083           ctxt.deleteXlationContext();
01084           xos << xml::EndElem;
01085         }
01086         xos << xml::EndElem;
01087       }
01088       xos << xml::EndElem;
01089     }
01090   }
01091 
01092   void
01093   xlate_ArrayIndices(xml::ostream& xos, WN* wn, PUXlationContext& ctxt)
01094   {
01095     // FIXME: do not handle co dimentions
01096   
01097     /* get array's rank and co_rank information from kid0 of wn
01098      * kid0 should be OPR_LDA */
01099     INT32 array_dim;
01100     WN* kid = WN_kid0(wn);
01101     if (WN_operator(kid) == OPR_LDA) {
01102       ST* st = WN_st(kid);
01103       TY_IDX ty = ST_type(st);
01104     
01105       if (TY_Is_Pointer(ty))
01106         ty = TY_pointed(ty);
01107       if (TY_is_f90_pointer(ty))
01108         ty = TY_pointed(ty);
01109     
01110       ARB_HANDLE arb_base = TY_arb(ty);
01111       array_dim = ARB_dimension(arb_base);
01112     } else {
01113       array_dim = WN_num_dim(wn);
01114     }
01115   
01116     /* Append indexing expressions in reverse order of the way they
01117      * occur in the indexing expression, since Fortran employs
01118      * column-major array layout, meaning the leftmost indexing
01119      * expression represents array elements laid out in contiguous
01120      * memory locations. */
01121     xos << xml::BegElem(XAIFStrings.elem_ArrayElemRef()) 
01122         << xml::Attr("vertex_id", ctxt.currentXlationContext().getNewVertexId());
01123     for (INT32 dim = array_dim - 1; dim >= 0; --dim) {
01124       xos << xml::BegElem(XAIFStrings.elem_IndexTriplet());
01125       xos << xml::BegElem(XAIFStrings.elem_Index());
01126       ctxt.createXlationContext(); 
01127       ctxt.currentXlationContext().unsetFlag(XlationContext::VARREF); // elem_Index() contains ExpressionType
01128       TranslateWN(xos, WN_array_index(wn, dim), ctxt);
01129       ctxt.deleteXlationContext();
01130       xos << xml::EndElem;
01131       xos << xml::EndElem;
01132     }
01133     xos << xml::EndElem;
01134   }
01135 
01136   void
01137   WN2F_array_bounds(xml::ostream& xos, WN* wn, TY_IDX array_ty,
01138                     PUXlationContext& ctxt)
01139   {
01140     // FIXME: referenced in ty2xaif.cxx
01141 
01142     if (TY_is_f90_pointer(array_ty)) // FIXME (should this be moved up?)
01143       array_ty = TY_pointed(array_ty); //Sept
01144   
01145     // (TY_Is_Array(array_ty) && TY_AR_ndims(array_ty) >= WN_num_dim(wn)) 
01146     FORTTK_ASSERT_WARN((TY_AR_ndims(array_ty) == WN_num_dim(wn)),
01147                        "array dimension mismatch");
01148     FORTTK_ASSERT_WARN(((INT64)TY_size(TY_AR_etype(array_ty)) 
01149                         == WN_element_size(wn)) 
01150                        || WN_element_size(wn) < 0 
01151                        || TY_size(TY_AR_etype(array_ty)) == 0,
01152                        "access/declaration mismatch in array element size");
01153   
01154     xlate_ArrayIndices(xos, wn, ctxt);
01155   }
01156 
01157   void
01158   WN2F_arrsection_bounds(xml::ostream& xos, WN* wn, TY_IDX array_ty,
01159                          PUXlationContext& ctxt)
01160   {
01161     /* This prints the array subscript expression. It was part of
01162      * xlate_ARRAY, but was split so it could be used for bounds
01163      * of structure components.
01164      */
01165     if (TY_is_f90_pointer(array_ty))
01166       array_ty = TY_pointed(array_ty);//Sept
01167   
01168     if (TY_Is_Array(array_ty) && TY_AR_ndims(array_ty) >= WN_num_dim(wn)) {
01169       /* Cannot currently handle differing element sizes at place of
01170        * array declaration versus place of array access (TODO?). */
01171       FORTTK_ASSERT_WARN(((INT64)TY_size(TY_AR_etype(array_ty)) 
01172                           == WN_element_size(wn))
01173                          || WN_element_size(wn) < 0 
01174                          || TY_size(TY_AR_etype(array_ty)) == 0,
01175                          "access/declaration mismatch in array element size");
01176     
01177       WN2F_Arrsection_Slots(xos,wn,ctxt);
01178     
01179     } else { /* Normalize array access to assume a single dimension */
01180       FORTTK_DIE(fortTkSupport::Diagnostics::Unimplemented);
01181       FORTTK_ASSERT_WARN(!TY_Is_Array(array_ty) || TY_AR_ndims(array_ty) == 1,
01182                          "access/declaration mismatch in array dimensions");
01183       //FIXME: WN2F_Normalize_Idx_To_Onedim(xos, wn, ctxt);
01184     }
01185   
01186   }
01187 
01188   void
01189   WN2F_String_Argument(xml::ostream& xos, WN* base_parm, WN* length,
01190                        PUXlationContext& ctxt)
01191   {
01192     /* Append the xos denoting the substring expression represented
01193      * by the base-expression.
01194      *
01195      * There are two possibilities concerning the array base 
01196      * expressions.  It can be a pointer to a complete character-
01197      * string (array) or it can be a pointer to a character within 
01198      * a character-string (single character).  In the first instance,
01199      * the offset off the base of string is zero.  In the latter 
01200      * case, the offset is given by the array indexing operation.
01201      *
01202      * NOTE: In some cases (notably for IO_ITEMs), we may try to 
01203      * derive a substring off an OPC_VINTRINSIC_CALL node or a
01204      * VCALL node.  This should only happend when the returned value
01205      * is the first argument and the length is the second argument.
01206      */
01207     WN   *base = WN_Skip_Parm(base_parm);
01208     WN   *base1 = WN_Skip_Parm(base_parm);
01209     WN   *lower_bnd;
01210     WN   *length_new;
01211     WN   *arg_expr;
01212     TY_IDX str_ty;
01213     INT64 str_length;
01214   
01215     /* Skip any INTR_ADRTMP and INTR_VALTMP nodes */
01216     if (WN_operator(base) == OPR_INTRINSIC_OP &&
01217         (INTR_is_adrtmp(WN_intrinsic(base)) || 
01218          INTR_is_valtmp(WN_intrinsic(base)))) {
01219       base = WN_kid0(base);
01220     }
01221   
01222     if (WN_operator(base) == OPR_CVTL) {
01223       /* probably CHAR(INT) within IO stmt. convert via CHAR & process
01224          rest elsewhere */
01225       xos << "(char";
01226       TranslateWN(xos,WN_kid0(base),ctxt);
01227       xos << ')';
01228       return;
01229     }
01230   
01231   
01232     /* Handle VCALLs specially, since the string information is given
01233      * by the first two arguments to the call.  Note that we can 
01234      * always assume a lower bound of zero for these, as we never 
01235      * generate code for the return-address.  This should only occur
01236      * within an IO stmt.  Note that the type of VCALLs must be 
01237      * accessed in the ctxt of an ADRTMP or VALTMP.
01238      */
01239     if (WN_opcode(base) == OPC_VCALL ||
01240         WN_opcode(base) == OPC_VINTRINSIC_CALL) {
01241       arg_expr  = WN_Skip_Parm(WN_kid1(base));
01242       lower_bnd = WN2F_INTCONST_ZERO;
01243     
01244       /* fixed size string? */
01245       if (WN_operator(arg_expr) == OPR_INTCONST)
01246         str_length = WN_const_val(arg_expr);
01247       else
01248         str_length = -1 ;  
01249     
01250       ctxt.currentXlationContext().setFlag(XlationContext::DEREF_ADDR);
01251       TranslateWN(xos, base, ctxt);
01252       ctxt.currentXlationContext().unsetFlag(XlationContext::DEREF_ADDR);
01253     
01254     } else {
01255       /* A regular address expression as base */    
01256       WN2F_Get_Substring_Info(&base, &str_ty, &lower_bnd, &length_new);
01257     
01258       /* Was this a character component of an array of derived type? */
01259       /* eg: vvv(2)%ccc(:)(1:5) - offset to ccc is added above base, */
01260       /* ADD(8,ARRAY(2,LDA VVV)) with array section for CCC on top   */
01261       /* of the ADD, and the substring above the array section. Take */
01262       /* the substring off the top, and process the rest             */    
01263       if (TY_kind(str_ty) == KIND_STRUCT) {
01264         FLD_PATH_INFO *fld_path ;
01265         FLD_HANDLE fld;
01266         TY_IDX  ty_idx ; 
01267       
01268         TY & ty = New_TY(ty_idx);
01269       
01270         TY_Init (ty, 1, KIND_SCALAR, MTYPE_U1, Save_Str(".w2fch."));
01271         Set_TY_is_character(ty);
01272       
01273         fld_path = TY2F_Get_Fld_Path(str_ty, 
01274                                      ty_idx,
01275                                      WN2F_Sum_Offsets(base));
01276       
01277         fld = TY2F_Last_Fld(fld_path);
01278         TY2F_Free_Fld_Path(fld_path);
01279       
01280         /* call memref for FLD offset, otherwise the ADD is */
01281         /* just another binary op                           */
01282         xlate_MemRef(xos, WN_kid0(base), WN_Tree_Type(base),
01283                      FLD_type(fld), 0, ctxt);
01284       } else {
01285         str_length = TY_size(str_ty);
01286       
01287         /* with optimization, may not have useful address TY 
01288          * when TreeType will return array of U1 from SubstringInfo */
01289       
01290         FORTTK_ASSERT(TY_Is_Character_String(str_ty) 
01291                       || TY_Is_Array_Of_UChars(str_ty),
01292                       "Unexpected conversion from pointer to character string");
01293 
01294         /* Get the string base and substring notation for the argument.  */
01295         if ((WN_operator(lower_bnd) != OPR_INTCONST   
01296              ||
01297              WN_const_val(lower_bnd) != 0                    
01298              ||
01299              WN_operator(length_new) != OPR_INTCONST 
01300              ||
01301              WN_const_val(length_new) != str_length )
01302             && 
01303             !ctxt.currentXlationContext().isFlag(XlationContext::HAS_NO_ARR_ELMT)
01304             && 
01305             WN_class(base)!=CLASS_CONST
01306             && 
01307             WN_class(base)!=CLASS_FUNC) { 
01308           xos << xml::BegElem(XAIFStrings.elem_VarRef())
01309               << xml::Attr("vertex_id", ctxt.currentXlationContext().getNewVertexId())
01310               << xml::Attr("du_ud", ctxt.findUDDUChainId(base))
01311               << xml::Attr("alias", ctxt.getAliasMapKey(base));
01312           ctxt.createXlationContext(XlationContext::VARREF, base); 
01313           UINT srcid = ctxt.currentXlationContext().peekVertexId();
01314           TranslateWN(xos, base, ctxt);
01315           UINT targid = ctxt.currentXlationContext().peekVertexId();
01316           WN2F_Substring(xos, 
01317                          str_length, 
01318                          lower_bnd,
01319                          length_new, 
01320                          ctxt);
01321           DumpVarRefEdge(xos, ctxt.currentXlationContext().getNewEdgeId(), srcid, targid);
01322           xos << xml::EndElem /* elem_VarRef() */;
01323           ctxt.deleteXlationContext();
01324         }
01325         else {
01326           ctxt.currentXlationContext().setFlag(XlationContext::DEREF_ADDR);
01327           TranslateWN(xos, base, ctxt);
01328           ctxt.currentXlationContext().unsetFlag(XlationContext::DEREF_ADDR);
01329         }
01330         return;
01331       }
01332     } /* WN2F_String_Argument */
01333   }
01334 
01335   static void
01336   DumpVarRefEdge(xml::ostream& xos, UINT eid, UINT srcid, UINT targid)
01337   {
01338     xos << xml::BegElem(XAIFStrings.elem_VarRefEdge()) << xml::Attr("edge_id", eid)
01339         << xml::Attr("source", srcid) << xml::Attr("target", targid)
01340         << xml::EndElem;
01341   }
01342 
01343 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines