|
OpenADFortTk (basic)
|
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 }