• Main Page
  • Modules
  • Data Types
  • Files

osprey/be/opt/opt_htable.cxx

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2006. QLogic Corporation. All Rights Reserved.
00003  */
00004 
00005 //-*-c++-*-
00006 
00007 /*
00008  * Copyright 2002, 2003, 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
00009  */
00010 
00011 // ====================================================================
00012 // ====================================================================
00013 //
00014 // Module: opt_htable.cxx
00015 // $Revision: 1.1.1.1 $
00016 // $Date: 2005/10/21 19:00:00 $
00017 // $Author: marcel $
00018 // $Source: /proj/osprey/CVS/open64/osprey1.0/be/opt/opt_htable.cxx,v $
00019 //
00020 // ====================================================================
00021 //
00022 // Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00023 //
00024 // This program is free software; you can redistribute it and/or modify
00025 // it under the terms of version 2 of the GNU General Public License as
00026 // published by the Free Software Foundation.
00027 //
00028 // This program is distributed in the hope that it would be useful, but
00029 // WITHOUT ANY WARRANTY; without even the implied warranty of
00030 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00031 //
00032 // Further, this software is distributed without any warranty that it
00033 // is free of the rightful claim of any third person regarding
00034 // infringement  or the like.  Any license provided herein, whether
00035 // implied or otherwise, applies only to this software file.  Patent
00036 // licenses, if any, provided herein do not apply to combinations of
00037 // this program with other software, or any other product whatsoever.
00038 //
00039 // You should have received a copy of the GNU General Public License
00040 // along with this program; if not, write the Free Software Foundation,
00041 // Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
00042 //
00043 // Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00044 // Mountain View, CA 94043, or:
00045 //
00046 // http://www.sgi.com
00047 //
00048 // For further information regarding this notice, see:
00049 //
00050 // http://oss.sgi.com/projects/GenInfo/NoticeExplan
00051 //
00052 // ====================================================================
00053 //
00054 // Description: PLEASE fill me in.
00055 //
00056 // ====================================================================
00057 // ====================================================================
00058 
00059 
00060 #ifdef USE_PCH
00061 #include "opt_pch.h"
00062 #endif // USE_PCH
00063 #pragma hdrstop
00064 
00065 
00066 #include <math.h>     // for sqrt() used in htable stats
00067 
00068 #include "defs.h"
00069 #include "erglob.h"
00070 #include "opcode.h"
00071 #include "errors.h"
00072 #include "mtypes.h"
00073 #include "cxx_memory.h"
00074 #include "wn_util.h"
00075 #include "wn_tree_util.h"               // for TREE_ITER
00076 #include "targ_const.h"     // for TCON-related stuff
00077 #include "const.h"      // for symbol/TCON-related
00078 #include "pf_cg.h"
00079 #include "stblock.h"
00080 #include "w2op.h"
00081 #include "config_opt.h"         // for Delay_U64_Lowering
00082 
00083 #include "opt_sys.h"            // BZERO definition
00084 #include "opt_config.h"
00085 #include "opt_wn.h"
00086 #include "opt_util.h"
00087 #include "opt_cfg.h"
00088 #include "opt_sym.h"
00089 #include "opt_htable.h"
00090 #include "opt_ssa.h"
00091 #include "opt_combine.h"
00092 #include "opt_main.h"
00093 #include "opt_mu_chi.h"
00094 #include "opt_exc.h"
00095 #include "opt_fold.h"
00096 #include "config_targ.h"    // ISA info
00097 #include "opt_prop.h"
00098 #include "bb_node_set.h"
00099 #include "opt_bb.h"
00100 #include "opt_cvtl_rule.h"
00101 #include "opt_alias_mgr.h"
00102 
00103 #include <strings.h>   // bcopy
00104 #include "opt_sys.h"
00105 
00106 EXP_KIDS_ITER::EXP_KIDS_ITER(mUINT32 cnt, CODEREP **kp)
00107 {
00108   kid_count = cnt;
00109   cur_idx = (mUINT32)NIL;
00110   kids = kp;
00111   FmtAssert(kids != NULL, ("EXPREP_KIDS_ITER(EXPREP): NULL operand list"));
00112 }
00113 
00114 // ====================================================================
00115 // Check if a ivar is a volatile reference (or any part is volatile)
00116 // ====================================================================
00117 
00118 BOOL
00119 CODEREP::Is_ivar_volatile( void ) const
00120 {
00121   const OPERATOR  opr = Opr();
00122   const CODEREP  *ivar_vsym = Get_ivar_vsym();
00123 
00124   // Consider an Mload/Mstore/Iload/Istore associated with a volatile vsym
00125   // a volatile memory operation.
00126   //
00127   if (ivar_vsym != NULL && ivar_vsym->Is_var_volatile())
00128      return TRUE;
00129 
00130   switch ( opr ) {
00131   case OPR_MLOAD:
00132     {
00133       Is_True( TY_kind(Ilod_ty()) == KIND_POINTER,
00134          ("Is_ivar_volatile: Ilod_ty() of MLOAD not pointer") );
00135       if (Ilod_TY_is_volatile(Ilod_ty()))
00136   return TRUE;
00137     }
00138     break;
00139 
00140   case OPR_ILOAD:
00141   case OPR_ILDBITS:
00142   case OPR_ILOADX:
00143     {
00144       if ( TY_is_volatile(Ilod_ty()) )
00145   return TRUE;
00146   
00147       if ( TY_is_volatile(Ilod_base_ty()) )
00148   return TRUE;
00149 
00150       if ( TY_kind(Ilod_base_ty()) == KIND_POINTER ) 
00151   if (Ilod_TY_is_volatile(Ilod_base_ty()))
00152     return TRUE;
00153     }
00154     break;
00155 
00156   case OPR_PARM:
00157     {
00158       if ( TY_is_volatile(Ilod_ty()) )
00159   return TRUE;
00160     }
00161     break;
00162   }
00163 
00164   return FALSE;
00165 }
00166 
00167 #ifdef KEY
00168 // ====================================================================
00169 // Check if the region node BB contains a WN_PRAGMA_LOCAL pragma for the symbol
00170 // ====================================================================
00171 static BOOL Symbol_mp_local_in_region(BB_NODE *bb, 
00172               OPT_STAB *opt_stab, 
00173               AUX_ID aux_id) {
00174   Is_True(bb->Kind() == BB_REGIONSTART,
00175       ("Symbol_mp_local_in_region: bad bb argument"));
00176   WN *wn;
00177   ST *st;
00178   // try whirl
00179   STMT_ITER stmt_iter;
00180   FOR_ALL_ELEM(wn, stmt_iter, Init(bb->Firststmt(), bb->Laststmt())) {
00181     if (WN_opcode(wn) == OPC_PRAGMA && 
00182   ((WN_PRAGMA_ID)WN_pragma(wn) == WN_PRAGMA_LOCAL ||
00183    (WN_PRAGMA_ID)WN_pragma(wn) == WN_PRAGMA_FIRSTPRIVATE ||
00184    (WN_PRAGMA_ID)WN_pragma(wn) == WN_PRAGMA_LASTLOCAL)) {
00185       st = WN_st(wn);
00186       if (ST_sclass(st) == SCLASS_FORMAL && !ST_is_value_parm(st)) {
00187         if (aux_id == opt_stab->Find_vsym_with_base(st))
00188     return TRUE;
00189       }
00190       else {
00191   if (aux_id == opt_stab->Find_sym_with_st_and_ofst(st, WN_pragma_arg1(wn)))
00192     return TRUE;
00193       }
00194     }
00195   }
00196   // try stmtrep
00197   STMTREP     *stmt;
00198   STMTREP_ITER srep_iter(bb->Stmtlist());
00199   FOR_ALL_NODE(stmt, srep_iter, Init()) {
00200     if ( stmt->Op() == OPC_PRAGMA ) {
00201       wn = stmt->Orig_wn();
00202       if ((WN_PRAGMA_ID)WN_pragma(wn) == WN_PRAGMA_LOCAL ||
00203     (WN_PRAGMA_ID)WN_pragma(wn) == WN_PRAGMA_FIRSTPRIVATE ||
00204     (WN_PRAGMA_ID)WN_pragma(wn) == WN_PRAGMA_LASTLOCAL) {
00205         st = WN_st(wn);
00206         if (ST_sclass(st) == SCLASS_FORMAL && !ST_is_value_parm(st)) {
00207           if (aux_id == opt_stab->Find_vsym_with_base(st))
00208       return TRUE;
00209         }
00210         else {
00211     if (aux_id == opt_stab->Find_sym_with_st_and_ofst(st, WN_pragma_arg1(wn)))
00212       return TRUE;
00213   }
00214       }
00215     }
00216   }
00217   return FALSE;
00218 }
00219 #endif
00220 
00221 /* CVTL-RELATED start (correctness) */
00222 static BOOL Sign_extended(MTYPE dtyp, MTYPE dsctyp)
00223 {
00224   if (dsctyp == MTYPE_BS)
00225     return MTYPE_signed(dtyp);
00226   if (MTYPE_is_integral(dtyp) && MTYPE_is_integral(dsctyp) &&
00227       MTYPE_size_min(dsctyp) <= MTYPE_size_min(MTYPE_I4)) {
00228     if (MTYPE_size_min(dsctyp) == MTYPE_size_min(MTYPE_I4))
00229       return Is_hi_sign_extended(dtyp, dsctyp);
00230     else
00231       return Is_lo_sign_extended(dtyp, dsctyp);
00232   }
00233   return FALSE;
00234 }
00235 
00236 // ========================================================================
00237 // Set the sign extension flag for LOAD/ILOAD
00238 // ========================================================================
00239 void
00240 CODEREP::Set_sign_extension_flag(void)
00241 {
00242   Is_True(inCODEKIND(Kind(), CK_VAR|CK_IVAR), 
00243     ("CODEREP::Set_sign_extension_flag: illegal kind"));
00244   Assign_sign_extd(Sign_extended(Dtyp(), Dsctyp()));
00245 }
00246 /* CVTL-RELATED finish */
00247       
00248 // NOTE: CK_OP CODEREPs are bigger than the others so don't copy an operator
00249 //  node into another type of node.
00250 void
00251 CODEREP::Copy(const CODEREP &cr)
00252 {
00253   Set_kind(cr.Kind());
00254   Set_dtyp_strictly(cr.Dtyp());
00255   Set_dsctyp(cr.Dsctyp());
00256   Set_usecnt(cr.Usecnt());
00257   Assign_flags(cr.flags);
00258   Assign_is_lcse(cr.Is_lcse());
00259   Assign_is_saved(cr.Is_saved());
00260   Assign_is_volatile(cr.Is_volatile());
00261   Assign_sign_extd(cr.Is_sign_extd());
00262   Set_emit_bb(cr.Emit_bb());
00263   
00264   _coderep_id = 0;
00265   Set_Bitpos(cr.Bitpos());
00266 
00267   if (kind == CK_VAR) {
00268     Set_aux_id( cr.Aux_id() );
00269     Set_version( cr.Version() );
00270     Set_lod_ty( cr.Lod_ty() );
00271     Set_defstmt( cr.Defstmt() );
00272     Set_offset( cr.Offset() );
00273     Set_defchi( cr.Defchi() );
00274     Set_isvar_flags( cr.Isvar_flags() );
00275     Set_field_id( cr.Field_id() );
00276   }
00277   else if (kind == CK_LDA) {
00278     Set_lda_aux_id( cr.Lda_aux_id() );
00279     Set_lda_base_st( cr.Lda_base_st() );
00280     Set_lda_ty( cr.Lda_ty() );
00281     Set_offset(cr.Offset());
00282     Set_afield_id(cr.Afield_id());
00283   }
00284   else if (kind == CK_OP) {
00285     Set_opr(cr.Opr());
00286     Set_kid_count(cr.Kid_count());
00287     for (INT i = 0; i < Kid_count(); i++) {
00288       Set_opnd(i, cr.Get_opnd(i));
00289     }
00290     Reset_isop_flags();
00291     Set_temp_id(0);
00292 
00293     switch (Opr()) {
00294     case OPR_ARRAY:
00295       Set_elm_siz(cr.Elm_siz());
00296       break;
00297     case OPR_CVTL:
00298       Set_offset(cr.Offset());
00299       break;
00300     case OPR_EXTRACT_BITS:
00301     case OPR_COMPOSE_BITS:
00302       Set_op_bit_size(cr.Op_bit_size());
00303       Set_op_bit_offset(cr.Op_bit_offset());
00304       break;
00305     case OPR_INTRINSIC_CALL:
00306     case OPR_INTRINSIC_OP:
00307       Set_intrinsic(cr.Intrinsic());
00308       break;
00309     case OPR_TAS:
00310       Set_ty_index(cr.Ty_index());
00311       break;
00312     case OPR_ASM_INPUT:
00313       Set_asm_constraint(cr.Asm_constraint());
00314 #ifdef KEY
00315       Set_asm_input_rtype(cr.Asm_input_rtype());
00316       Set_asm_input_dsctype(cr.Asm_input_dsctype());
00317 #endif
00318       break;
00319 #ifdef KEY
00320     case OPR_PURE_CALL_OP:
00321       Set_call_op_aux_id (cr.Call_op_aux_id());
00322       break;
00323 #endif
00324     }
00325   }
00326   else if (kind == CK_IVAR) {
00327     Set_opr(cr.Opr());
00328     Set_ivar_occ(cr.Ivar_occ());
00329     Set_ilod_base(cr.Ilod_base());
00330     Set_istr_base(cr.Istr_base());
00331     Set_ilod_ty(cr.Ilod_ty());
00332     Set_offset(cr.Offset());
00333     Set_i_field_id(cr.I_field_id());
00334     Set_ivar_defstmt(cr.Ivar_defstmt());
00335     Set_ivar_mu_node(cr.Ivar_mu_node());
00336     Set_mload_size(cr.Mload_size());
00337   }
00338   else if (kind == CK_CONST) {
00339     Set_const_val( cr.Const_val() );
00340   }
00341   else if (kind == CK_RCONST) {
00342     Set_const_id( cr.Const_id() );
00343   }
00344   else {
00345     Is_True( kind == CK_DELETED,
00346        ("CODEREP::Copy: Invalid kind: %d", (INT)kind) );
00347   }
00348 }
00349 
00350 // Returns whether cr is among the top nth (starting from 0) elements of the 
00351 // code stack at aux_id aux.
00352 static BOOL Among_top_nth_coderep(CODEREP *cr, AUX_ID aux, INT32 n, 
00353           OPT_STAB *sym)
00354 {
00355   INT32 i;
00356   for (i = 0; i != n+1; i++) {
00357     if (cr == sym->Top_nth_coderep(aux, i))
00358       return TRUE;
00359   }
00360   return FALSE;
00361 }
00362 
00363 // Returns TRUE if all the opnds of the mu-list are defined by defstmt
00364 //  If mu_vsym_depth is not zero, matching succeeds if defstmt's version is 
00365 //  among the versions in the coderep stack from top up to that depth.
00366 BOOL
00367 CODEREP::Match_mu_and_def(STMTREP *defstmt, INT32 mu_vsym_depth, OPT_STAB *sym)
00368 const
00369 {
00370 #ifdef Is_True_On
00371   if (! WOPT_Enable_Ivar_Common) return FALSE;
00372 #endif
00373   MU_NODE *mnode = Ivar_mu_node();
00374   CODEREP *cr = mnode->OPND();
00375   if (cr && cr->Is_flag_set(CF_IS_ZERO_VERSION))
00376     return FALSE;
00377   if (mu_vsym_depth == 0) {
00378     if (cr != NULL && cr->Defstmt() != defstmt)
00379       return FALSE;
00380   }
00381   else {
00382     // find the chi node corresponding to this mu node
00383     CHI_NODE *cnode;
00384     CHI_LIST_ITER chi_iter;
00385     FOR_ALL_NODE(cnode, chi_iter, Init(defstmt->Chi_list()))
00386       if (cnode->Live() && cnode->Aux_id() == mnode->Aux_id())
00387   break;
00388     if (cnode == NULL || cnode->Aux_id() != mnode->Aux_id())
00389       return FALSE;
00390     // top of stack must be mnode->OPND()
00391     if (! Among_top_nth_coderep(cnode->RESULT(), mnode->Aux_id(), 
00392         mu_vsym_depth, sym))
00393       return FALSE;
00394   }
00395   return TRUE;
00396 }
00397 
00398 
00399 //  Returns TRUE the MU-lists are identical.
00400 //  If mu_vsym_depth is not zero, matching succeeds if "this" is among the
00401 //  versions in the coderep stack from top up to that depth.
00402 //  **** ASSUMPTION: ****
00403 //   the mu nodes are presented in the same order.
00404 //  The assumption is guaranteed by Compute_FFA() which
00405 //  inserts the MU and CHI lists.
00406 //
00407 inline BOOL
00408 CODEREP::Match_mu_and_mu(MU_NODE *mu_node, INT32 mu_vsym_depth, OPT_STAB *sym)
00409 const
00410 {
00411 #ifdef Is_True_On
00412   if (! WOPT_Enable_Ivar_Common) return FALSE;
00413 #endif
00414   MU_NODE *mnode1 = Ivar_mu_node();
00415   MU_NODE *mnode2 = mu_node;
00416   if (mnode2 == NULL ||
00417       mnode1 == NULL ||
00418       (mnode1 && mnode1->OPND()->Is_flag_set(CF_IS_ZERO_VERSION)) ||
00419       (mnode2 && mnode2->OPND()->Is_flag_set(CF_IS_ZERO_VERSION)))
00420     return FALSE;
00421   if (mu_vsym_depth == 0) {
00422     if (mnode1->OPND() != mnode2->OPND())
00423       return FALSE;
00424   }
00425   else {
00426     // top of stack must be mnode2->OPND()
00427     if (! Among_top_nth_coderep(mnode1->OPND(), mnode2->Aux_id(), 
00428         mu_vsym_depth, sym))
00429       return FALSE;
00430   }
00431   return TRUE;
00432 }
00433    
00434 BOOL
00435 CODEREP::Match(CODEREP* cr, INT32 mu_vsym_depth, OPT_STAB *sym)
00436 {
00437   // compare this with cr, return TRUE if identical
00438   Is_True(cr->Kind() != CK_VAR, 
00439     ("CODEREP::Match: should not need to call with a VAR node"));
00440   if (Kind() != cr->Kind()) return FALSE;
00441   if (Dtyp() != cr->Dtyp() && 
00443       !(Kind() == CK_IVAR && OPCODE_is_load(Op())))
00444     return FALSE;
00445 
00446   // in SSAPRE, this allows us to create a new node for the expr whose
00447   // CF_OWNED_BY_TEMP flag is set
00448   if (Is_flag_set(CF_OWNED_BY_TEMP))
00449     return FALSE;
00450 
00451   // UNDID THIS SINCE EPRE CANNOT HANDLE IT CORRECTLY!
00452   //
00453   // We turn off any redundancy elimination by means of online
00454   // value numbering when we test our new off-line value numbering
00455   // scheme.  However, due to side-effects we cannot do so for rconsts
00456   // and ivars (rdahl):
00457   //
00458   // if ((WOPT_Enable_Value_Numbering == VNFRE_BEFORE_AND_AFTER_EPRE ||
00459   //   WOPT_Enable_Value_Numbering == 
00460   //                            VNFRE_SINGLE_PASS_BEFORE_AND_AFTER_EPRE) &&
00461   //   !inCODEKIND(Kind(), CK_IVAR|CK_RCONST))
00462   //    return FALSE;
00463 
00464   switch (Kind()) {
00465 
00466   case CK_LDA:
00467     if (Lda_base_st() == cr->Lda_base_st() && Offset() == cr->Offset() &&
00468   Is_flag_set(CF_LDA_LABEL) == cr->Is_flag_set(CF_LDA_LABEL) &&
00469 #ifdef TARG_SL2
00470        Is_flag_set(CF_INTERNAL_MEM_OFFSET) == cr->Is_flag_set(CF_INTERNAL_MEM_OFFSET) &&
00471 #endif 
00472   Afield_id() == cr->Afield_id()) 
00473       return TRUE;
00474     else
00475       return FALSE;
00476 
00477 #if 0 // CK_VAR nodes never need to be matched
00478   case CK_VAR:
00479     if (Aux_id() == cr->Aux_id() &&  Version() == cr->Version() &&
00480   ! Is_var_volatile())
00481       return TRUE;
00482     else
00483       return FALSE;
00484 #endif
00485 
00486   case CK_OP:
00487 #if 0
00488     if (OPCODE_commutative_op(Op()) == Op()) {
00489       // commutative ops must have only 2 kids
00490       // TODO: handle opcodes that are commutative with different opcode
00491       //       e.g. a <= b becoming b >= a
00492       return Get_opnd(0) == cr->Get_opnd(0) && Get_opnd(1) == cr->Get_opnd(1)
00493         || Get_opnd(1) == cr->Get_opnd(0) && Get_opnd(0) == cr->Get_opnd(1);
00494     }
00495     else
00496 #endif
00497     if (Op() == cr->Op() && Kid_count() == cr->Kid_count()) {
00498       for (INT i = 0; i < Kid_count(); i++)
00499   if (Get_opnd(i) != cr->Get_opnd(i))
00500     return FALSE;
00501       switch (Opr()) {
00502       case OPR_CVTL:
00503   if (Offset() != cr->Offset())
00504     return FALSE;
00505   break;
00506       case OPR_EXTRACT_BITS:
00507       case OPR_COMPOSE_BITS:
00508   if (Op_bit_offset() != cr->Op_bit_offset() ||
00509       Op_bit_size() != cr->Op_bit_size())
00510     return FALSE;
00511   break;
00512       case OPR_ARRAY:
00513   if (Kid_count() != cr->Kid_count() || Elm_siz() != cr->Elm_siz())
00514     return FALSE;
00515   break;
00516 
00517       case OPR_CALL:
00518       case OPR_ICALL:
00519         return FALSE;
00520 
00521       case OPR_INTRINSIC_CALL:
00522   // never match intrinsic calls (yet)  (some problem with
00523   // mu lists being null)
00524   return FALSE;
00525 
00526       case OPR_INTRINSIC_OP:
00527   if (Intrinsic() != cr->Intrinsic())
00528     return FALSE;
00529   break;
00530 #ifdef KEY
00531       case OPR_PURE_CALL_OP:
00532         if (Call_op_aux_id() != cr->Call_op_aux_id())
00533     return FALSE;
00534   break;
00535 #endif
00536       }
00537       return TRUE;
00538     } else
00539       return FALSE;
00540 
00541   case CK_IVAR:
00542     {
00543       const OPCODE ivar_opc = Op();
00544       const OPERATOR ivar_opr = Opr();
00545       const OPCODE cr_opc = cr->Op();
00546       const OPERATOR cr_opr = cr->Opr();
00547 
00548       // e.g. do not match MLOAD and ILOAD.
00549       if (cr_opr != ivar_opr) return FALSE;
00550 
00551       if ( Get_mtype_class(OPCODE_rtype(ivar_opc)) != 
00552      Get_mtype_class(OPCODE_rtype(cr_opc)) )
00553   return FALSE;
00554       if (ivar_opr == OPR_PREFETCH)   // no CSE for PREFETCH op
00555   return FALSE;
00556       else if ( ivar_opr == OPR_PARM && cr_opr == OPR_PARM)
00557       {
00558   // types must match
00559   if ( ivar_opc != cr_opc )
00560     return FALSE;
00561         // flag must match
00562         if (Offset() != cr->Offset())
00563           return FALSE;
00564 
00565   // the actual parameter is stored in the base
00566   if ( Ilod_base() != cr->Ilod_base() )
00567     return FALSE;
00568 
00569         // the TY_IDX has to be different
00570         if (Ilod_ty() != cr->Ilod_ty())
00571           return FALSE;
00572 
00573 #if defined(TARG_SL)
00574   // for intrinsics with memory indirection, we don't want to cse them
00575   // since they don't point to the same place
00576         if ((cr->Offset() & WN_PARM_DEREFERENCE) || 
00577       (Offset() & WN_PARM_DEREFERENCE))
00578           return FALSE;
00579 #endif
00580   // must have matching mu lists as well
00581         if (cr->Ivar_mu_node() && Ivar_mu_node()) 
00582           return Match_mu_and_mu(cr->Ivar_mu_node(), 0, NULL);
00583         else if (cr->Ivar_mu_node() || Ivar_mu_node())
00584           return FALSE;
00585         else
00586           return TRUE;
00587       }
00588 
00589       if (cr->Is_ivar_volatile())
00590   return FALSE;
00591 
00592       if (ivar_opr == OPR_MLOAD) {
00593   if (cr->Mload_size() != Mload_size())
00594     return FALSE;
00595       }
00596       else { // for ILOADs check that they have identical alignments
00597   TY_IDX ivar_addr_ty = Ilod_base_ty();
00598   TY_IDX cr_addr_ty = cr->Ilod_base_ty();
00599   if (ivar_addr_ty != cr_addr_ty) {
00600 #ifdef KEY // bug 3621
00601     if (Dsctyp() == MTYPE_BS || cr->Dsctyp() == MTYPE_BS)
00602       return FALSE;
00603 #endif
00604     if (! ivar_addr_ty || ! cr_addr_ty)
00605       return FALSE;
00606     if (TY_kind(ivar_addr_ty) != KIND_POINTER)
00607       return FALSE;
00608     if (TY_kind(cr_addr_ty) != KIND_POINTER)
00609       return FALSE;
00610 #if 0
00611     // These code below cause some problems in some Fortran Cases and 416.gamess
00612     //   at -O3 with SIMD Opt. Some SIMD tys have the same type but diff align
00613     // With these code, the two cr will be different, which may cayse problems
00614     //   in EPRE or CG
00615     if (Ilod_ty() != cr->Ilod_ty())
00616       return FALSE;
00617 #endif
00618     if (TY_align_exp(TY_pointed(ivar_addr_ty)) !=
00619         TY_align_exp(TY_pointed(cr_addr_ty)))
00620       return FALSE;
00621   }
00622         Is_True(ivar_opr == cr_opr, 
00623     ("CODEREP::Match: ILOAD operator is inconsistent with bitfield"));
00624   if (ivar_opr == OPR_ILDBITS) {
00625     if (I_bit_offset() != cr->I_bit_offset() ||
00626         I_bit_size() != cr->I_bit_size())
00627       return FALSE;
00628   }
00629 
00630   if (ivar_opr == OPR_ILOADX) {
00631     if (cr->Index() != Index())
00632       return FALSE;
00633   }
00634       }
00635 
00636       if (Ilod_base() == NULL) {  // *this is a definition
00637   if (cr->Ilod_base() == Istr_base() &&
00638     cr->Match_mu_and_def( Ivar_defstmt(), mu_vsym_depth, sym)) {
00639     if (Offset() != cr->Offset())
00640       return FALSE;
00641     if (Dsctyp() == MTYPE_BS)
00642       if (I_field_id() != cr->I_field_id())
00643         return FALSE;
00644     Set_ilod_base(Istr_base());
00645     // SIDE EFFECT: Set the mu of the existing coderep to match
00646     // the LHS of the chi node.
00647     if (Ivar_mu_node() == NULL) {
00648       CODEREP *vsym = Get_ivar_vsym();
00649       if (vsym == NULL) {
00650         MU_NODE *mnode = CXX_NEW(MU_NODE, sym->Occ_pool());
00651         mnode->Set_aux_id( cr->Ivar_mu_node()->Aux_id());
00652         mnode->Set_OPND( cr->Ivar_mu_node()->OPND());
00653         Set_ivar_mu_node(mnode);
00654         Ivar_occ()->Set_aux_id( mnode->Aux_id());
00655       } else {
00656         // Is this the right MEM_POOL to use?
00657         MU_NODE *mnode = CXX_NEW(MU_NODE, sym->Occ_pool());
00658         mnode->Set_aux_id(vsym->Aux_id());
00659         mnode->Set_OPND(vsym);
00660         Set_ivar_mu_node(mnode);
00661       } 
00662     }
00663     if (Ivar_occ()->Lno_dep_vertex_load() == 0)
00664       Ivar_occ()->Set_lno_dep_vertex_load(cr->Ivar_occ()->Lno_dep_vertex_load());  // preserve LNO info
00665     return TRUE; 
00666   } 
00667   else return FALSE;
00668       } 
00669 
00670       if (cr->Ilod_base() == NULL) {   // *cr is a definition
00671   if (Ilod_base() == cr->Istr_base() &&
00672       Match_mu_and_def( cr->Ivar_defstmt(), 0, NULL)) {
00673     if (Offset() != cr->Offset())
00674        return FALSE;
00675     if (Dsctyp() == MTYPE_BS)
00676       if (I_field_id() != cr->I_field_id())
00677         return FALSE;
00678     Set_istr_base (Ilod_base());
00679     Ivar_occ()->Set_lno_dep_vertex_store(cr->Ivar_occ()->Lno_dep_vertex_store()); // preserve LNO info
00680     return TRUE;
00681   } else
00682     return FALSE;
00683       }
00684 
00685       // both *this and *cr are uses.
00686       if (Ilod_base() == cr->Ilod_base() && 
00687     Match_mu_and_mu(cr->Ivar_mu_node(), mu_vsym_depth, sym)){
00688   if (Offset() != cr->Offset()) 
00689     return FALSE;
00690         if (Dsctyp() == MTYPE_BS)
00691     if (I_field_id() != cr->I_field_id())
00692       return FALSE;
00693   if (Ivar_occ()->Lno_dep_vertex_load() == 0)
00694     Ivar_occ()->Set_lno_dep_vertex_load(cr->Ivar_occ()->Lno_dep_vertex_load());  // preserve LNO info
00695   return TRUE;
00696       }
00697       else
00698   return FALSE;
00699     }
00700 
00701   case CK_CONST:
00702     if (Const_val() == cr->Const_val()) 
00703       return TRUE;
00704     else return FALSE;
00705 
00706   case CK_RCONST:
00707     if (Const_id() == cr->Const_id()) {
00708       Set_dtyp(cr->Dtyp());
00709       Set_dsctyp(cr->Dsctyp());
00710       return TRUE;
00711     }
00712     else return FALSE;
00713   }
00714   Is_True(FALSE,("CODEREP::Match, should never reach this point"));
00715   return FALSE;
00716 }
00717 
00718 
00719 BOOL
00720 CODEREP::Match_constval(const CODEREP *cr) 
00721 {
00722   Is_True(Kind() == CK_CONST && cr->Kind() == CK_CONST,
00723     ("CR not CONST kind."));
00724   // ignore the Dtyp()
00725   return Const_val() == cr->Const_val();
00726 }
00727 
00728 BOOL
00729 CODEREP::Contains( const CODEREP *cr ) const
00730 {
00731   // returns TRUE if this tree contains the node 'cr'
00732   if (this == cr) return TRUE;
00733   INT i;
00734   switch (kind) {
00735   case CK_OP:
00736     for (i = 0; i < Kid_count(); i++)
00737       if (Get_opnd(i)->Contains(cr)) return TRUE;
00738     return FALSE;
00739   case CK_IVAR:
00740     Is_True(Ilod_base() != NULL,
00741       ("CODEREP::Contains: CK_IVAR must be rvalue"));
00742     if (Ilod_base()->Contains(cr)) return TRUE;
00743     if (Opr() == OPR_MLOAD) {
00744       CODEREP *num_byte = Mload_size();
00745       if (num_byte->Contains(cr)) return TRUE;
00746     }
00747     else if (Opr() == OPR_ILOADX) {
00748       CODEREP *index = Index();
00749       if (index->Contains(cr)) return TRUE;
00750     }
00751     return FALSE;
00752   case CK_LDA:
00753   case CK_VAR:
00754   case CK_CONST:
00755   case CK_RCONST:
00756     return FALSE;
00757   }
00758   return FALSE;
00759 }
00760 
00761 BOOL
00762 CODEREP::Contains_image( const CODEREP *cr ) const
00763 {
00764   // returns TRUE if this tree contains the same image(bitpos) as node 'cr'
00765   if (Bitpos() == cr->Bitpos()) return TRUE;
00766   INT i;
00767   switch (kind) {
00768   case CK_OP:
00769     for (i = 0; i < Kid_count(); i++)
00770       if (Get_opnd(i)->Contains_image(cr)) return TRUE;
00771     return FALSE;
00772   case CK_IVAR:
00773     if (Ilod_base()->Contains_image(cr)) return TRUE;
00774     if (Opr() == OPR_MLOAD) {
00775       CODEREP *num_byte = Mload_size();
00776       if (num_byte->Contains_image(cr)) return TRUE;
00777     }
00778     else if (Opr() == OPR_ILOADX) {
00779       CODEREP *index = Index();
00780       if (index->Contains_image(cr)) return TRUE;
00781     }
00782     return FALSE;
00783   case CK_LDA:
00784   case CK_VAR:
00785   case CK_CONST:
00786   case CK_RCONST:
00787     return FALSE;
00788   }
00789   return FALSE;
00790 }
00791 
00792 void
00793 CODEREP::Print(INT indent, FILE *fp) const
00794 {
00795   INT i;
00796   if (Kind() == CK_OP) {
00797     for (i = 0; i < Kid_count(); i++)
00798       Get_opnd(i)->Print(indent+1, fp);
00799   } else if (Kind() == CK_IVAR) {
00800     if (Ilod_base() != NULL)
00801       Ilod_base()->Print(indent+1, fp);
00802     else
00803       Istr_base()->Print(indent+1, fp);
00804   }
00805   Print_node(indent, fp);
00806   fprintf(fp, " b=%s",Print_bit());
00807   if (Kind() == CK_IVAR) {
00808     fprintf(fp, " mu<");
00809     if (Ivar_mu_node() && Ivar_mu_node()->OPND())  // Check if the MU has been deleted.
00810       fprintf(fp, "%d/cr%d", Ivar_mu_node()->OPND()->Aux_id(), 
00811         Ivar_mu_node()->OPND()->Coderep_id());
00812     fprintf(fp, ">\n"); 
00813   } else {
00814 #ifdef Is_True_On
00815     extern COMP_UNIT* g_comp_unit;
00816     if (Kind () == CK_VAR) {
00817       ST* st = g_comp_unit->Opt_stab()->St (Aux_id());
00818       if (st && ST_class(st) != CLASS_PREG) {
00819         fprintf (fp, " #%s", ST_name(st));
00820       }
00821     } else if (Kind() == CK_LDA) {
00822       fprintf (fp, " #%s", g_comp_unit->Opt_stab()->St_name(Lda_aux_id()));
00823     }
00824 #endif
00825     fprintf(fp, "\n");
00826   }
00827 }
00828 
00829 
00830 // this is to make it easier to print codereps in the debugger
00831 void
00832 dump_coderep (CODEREP *cr)
00833 {
00834   cr->Print(0,stdout);
00835 }
00836 
00837 void
00838 CODEREP::Print_node(INT32 indent, FILE *fp) const
00839 {
00840   INT i;
00841   switch (Kind()) {
00842   case CK_OP:
00843     fprintf(fp, ">"); // mark line visually as htable dump
00844     for (i = 0; i < indent; i++) fprintf(fp, " ");
00845     char buf[32];
00846     sprintf(buf, "%s", OPCODE_name(Op()));
00847     fprintf(fp, "%s", buf+4);
00848     switch (Opr()) {
00849     case OPR_CVTL:
00850       fprintf(fp, " %d", Offset());
00851       break;
00852     case OPR_EXTRACT_BITS:
00853     case OPR_COMPOSE_BITS:
00854       fprintf(fp," o:%d s:%d",Op_bit_offset(),Op_bit_size());
00855       break;
00856     case OPR_ARRAY:
00857       fprintf(fp, " %d %lld", Num_dim(), Elm_siz());
00858       break;
00859     case OPR_INTRINSIC_CALL:
00860     case OPR_INTRINSIC_OP:
00861       fprintf(fp, " %d", Intrinsic());
00862       break;
00863     case OPR_ASM_INPUT:
00864       fprintf(fp, " opnd:%d", Asm_opnd_num());
00865       break;
00866 #ifdef KEY
00867     case OPR_PURE_CALL_OP:
00868       fprintf(fp, " %d", Call_op_aux_id());
00869       break;
00870 #endif
00871     }
00872     break;
00873   case CK_IVAR:
00874     if (Opr() == OPR_MLOAD) {
00875       CODEREP *num_byte = Mload_size();
00876       num_byte->Print(indent+1, fp);
00877     }
00878     if (Opr() == OPR_ILOADX)
00879       Index()->Print(indent+1, fp);
00880     fprintf(fp, ">"); // mark line visually as htable dump
00881     for (i = 0; i < indent; i++) fprintf(fp, " ");
00882     if (Opr() == OPR_ILOADX ||
00883         Opr() == OPR_MLOAD ||
00884         Opr() == OPR_PARM)
00885       sprintf(buf, "%s ty=%x ", OPCODE_name(Op()), Ilod_ty());
00886     else
00887       sprintf(buf,"    %s%s%s %d ty=%x ",
00888               MTYPE_name(Dtyp()),MTYPE_name(Dsctyp()),
00889         Opr() == OPR_ILOAD ? "ILOAD" : "ILDBITS",
00890               Offset(), Ilod_ty());
00891     fprintf(fp, "%s", buf+4);
00892     break;
00893   case CK_LDA:
00894     fprintf(fp, ">"); // mark line visually as htable dump
00895     for (i = 0; i < indent; i++) fprintf(fp, " ");
00896     fprintf(fp, "LDA %s sym%d %d", MTYPE_name(Dtyp()),Lda_aux_id(),Offset());
00897     break;
00898   case CK_VAR:
00899 #ifdef TARG_NVISA
00900     // maybe it is just me, but I find it confusing that loads were printed
00901     // as dsctyp dtyp when whirl has them ordered as dtyp dsctyp.
00902     // So switch the order.
00903     fprintf(fp, " %s%s", MTYPE_name(Dtyp()), MTYPE_name(Dsctyp()));
00904     if (! Bit_field_valid())
00905       fprintf(fp, "LDID");
00906     else fprintf(fp, "LDBITS");
00907     fprintf(fp, " sym%dv%d %d ty=%x ", Aux_id(), Version(), Offset(), Lod_ty());
00908 #else
00909     fprintf(fp, ">"); // mark line visually as htable dump
00910     for (i = 0; i < indent; i++) fprintf(fp, " ");
00911     if (! Bit_field_valid())
00912       fprintf(fp, "LDID");
00913     else fprintf(fp, "LDBITS");
00914     fprintf(fp, " %s %s sym%dv%d %d ty=%x ", MTYPE_name(Dsctyp()),
00915       MTYPE_name(Dtyp()), Aux_id(), Version(), Offset(), Lod_ty());
00916 #endif
00917     break;
00918   case CK_CONST:
00919     fprintf(fp, ">"); // mark line visually as htable dump
00920     for (i = 0; i < indent; i++) fprintf(fp, " ");
00921     fprintf(fp, "LDC %s %lld", MTYPE_name(Dtyp()), Const_val());
00922     break;
00923   case CK_RCONST:
00924     fprintf(fp, ">"); // mark line visually as htable dump
00925     for (i = 0; i < indent; i++) fprintf(fp, " ");
00926     fprintf(fp, "LDRC %s 0x%p", MTYPE_name(Dtyp()), Const_id());
00927     break;
00928   case CK_DELETED:
00929   default:
00930     Is_True(FALSE,("CODEREP::Print_node: illegal kind: %s",Print_kind()));
00931     break;
00932   }
00933   fprintf(fp, " <u=%d cr%d>", Usecnt(), Coderep_id());
00934   switch (kind) {
00935   case CK_VAR:
00936     if (Is_var_nodef()) 
00937       fprintf(fp, " (no-def)");
00938     if (Is_var_volatile()) 
00939       fprintf(fp, " (vol)");
00940     break;
00941   case CK_IVAR:
00942 #if 0 //TODO: put in after ilod is recognized CSE
00943     if (Op_defstmt() == NULL) fprintf(fp, " (no-def)");
00944 #endif
00945     if (Is_ivar_volatile()) 
00946       fprintf(fp, " (vol)");
00947     break;
00948   case CK_OP:
00949     fprintf(fp, " isop_flags:0x%x", u2.isop.isop_flags);
00950     break;
00951   }
00952 
00953   fprintf( fp, " flags:0x%x", flags&0x1ff );
00954 }
00955 
00956 // Print a CODEREP to a string
00957 // the string is padded with spaces to be N chars long
00958 // if name_format is TRUE, print the opcode name
00959 // if name_format is FALSE, print the bit positions of the children
00960 #define Nchars 20
00961 char *
00962 CODEREP::Print_str(BOOL name_format) const
00963 {
00964   static char buf[100];
00965 
00966   buf[0] = '\0';
00967 
00968   switch (Kind()) {
00969   case CK_OP:
00970     if (name_format)
00971       sprintf(buf,"%s",OPCODE_name(Op())+4);
00972     else {
00973       sprintf(buf,"<");
00974       for (INT i=0; i<Kid_count(); i++) {
00975   strcat(buf,Opnd(i)->Print_bit());
00976   if (i+1 < Kid_count())
00977     strcat(buf,", ");
00978       }
00979       strcat(buf,">");
00980     }
00981     break;
00982   case CK_IVAR:
00983     if (name_format) {
00984       if (Opr() == OPR_MLOAD ||
00985     Opr() == OPR_PARM) {
00986   sprintf(buf,"%s %d ty=%x ", OPCODE_name(Op()),
00987                 Offset(), Ilod_ty());
00988       }
00989       else if (Opr() == OPR_ILOADX) {
00990   sprintf(buf,"%s%s%s ty=%x ",
00991     MTYPE_name(Dtyp()), MTYPE_name(Dsctyp()), "ILOADX", Ilod_ty());
00992       }
00993       else
00994   sprintf(buf,"%s%s%s %d ty=%x ",
00995     MTYPE_name(Dtyp()),MTYPE_name(Dsctyp()),
00996     Opr() == OPR_ILOAD ? "ILOAD" : "ILDBITS",
00997     Offset(), Ilod_ty());
00998     }
00999     else {
01000       if (Opr() == OPR_MLOAD)
01001   sprintf(buf,"<%s>",Mload_size()->Print_bit());
01002     }
01003     break;
01004   case CK_LDA:
01005     if (name_format)
01006       sprintf(buf,"LDA sym%d %d",Lda_aux_id(),Offset());
01007     break;
01008   case CK_VAR:
01009     if (name_format) {
01010       if (! Bit_field_valid())
01011         sprintf(buf,"LDID ");
01012       else sprintf(buf,"LDBITS ");
01013       sprintf(buf,"sym%dv%d %d ty=%x ",Aux_id(),Version(),Offset(), Lod_ty());
01014     }
01015     break;
01016   case CK_CONST:
01017     if (name_format)
01018       sprintf(buf,"LDC %lld",Const_val());
01019     break;
01020   case CK_RCONST:
01021     if (name_format)
01022       sprintf(buf,"LDRC 0x%p",Const_id());
01023     break;
01024   default:
01025     Warn_todo("CODEREP::Print: CODEKIND is not implemented yet");
01026     break;
01027   }
01028   if (name_format && strlen(buf) < Nchars) {    // pad with spaces to Nchars
01029     INT i;
01030     for (i=strlen(buf); i<Nchars; i++)
01031       buf[i] = ' ';
01032     buf[i] = '\0';
01033   }
01034   return buf;
01035 }
01036 
01037 // print the kind field to a string
01038 char *
01039 CODEREP::Print_kind(void) const
01040 {
01041   static char str[20];
01042   switch (Kind()) {
01043   case CK_LDA:          strcpy(str,"CK_LDA");   break;
01044   case CK_CONST:  strcpy(str,"CK_CONST");   break;
01045   case CK_RCONST: strcpy(str,"CK_RCONST");  break;
01046   case CK_VAR:          strcpy(str,"CK_VAR");   break;
01047   case CK_IVAR:   strcpy(str,"CK_IVAR");    break;
01048   case CK_OP:   strcpy(str,"CK_OP");    break;
01049   case CK_DELETED:  strcpy(str,"CK_DELETED"); break;
01050   default:    strcpy(str,"UNKNOWN");    break;
01051   }
01052   return str;
01053 }
01054 
01055 // given the opcode of the operator and some info about which kid we
01056 // are dealing with, come up with the type for the kid 
01057 MTYPE
01058 Operand_type( OPCODE op, INT which_kid, INT num_kids )
01059 {
01060   switch (OPCODE_operator(op)) {
01061   case OPR_CALL:
01062   case OPR_INTRINSIC_CALL:
01063   case OPR_INTRINSIC_OP:
01064   case OPR_TAS:
01065 #ifdef KEY
01066   case OPR_PURE_CALL_OP:
01067 #endif
01068     return MTYPE_UNKNOWN;
01069 
01070   case OPR_CEIL:
01071   case OPR_CVT:
01072   case OPR_FLOOR:
01073   case OPR_RND:
01074   case OPR_TRUNC:
01075   case OPR_LT:
01076   case OPR_LE:
01077   case OPR_EQ:
01078   case OPR_NE:
01079   case OPR_GE:
01080   case OPR_GT:
01081     return OPCODE_desc(op);
01082 
01083   case OPR_ICALL:
01084     if ( which_kid == num_kids-1 )
01085       // last kid is the address of function being called
01086       return Pointer_type;
01087     else
01088       return MTYPE_UNKNOWN;
01089 
01090   case OPR_ILDBITS:
01091   case OPR_ILOAD:   // only 1 kid
01092   case OPR_ILOADX:    // 2 kids, but both pointer types
01093   case OPR_MLOAD:   // 2 kids, but both pointer types
01094     return Pointer_type;
01095 
01096   case OPR_ISTORE:
01097   case OPR_ISTBITS:
01098   case OPR_ISTOREX:
01099     if ( which_kid == 0 )
01100       return OPCODE_desc(op); // value being stored
01101     else
01102       return Pointer_type;  // address(es) being stored to
01103 
01104   case OPR_ARRAY:
01105     if ( which_kid == 0 )
01106       return Pointer_type;  // base of the array
01107     else
01108       return MTYPE_UNKNOWN;
01109 
01110   case OPR_MSTORE:
01111     if ( which_kid == 0 )
01112       return MTYPE_UNKNOWN; // chunk being stored
01113     else
01114       return Pointer_type;  // address being stored to
01115 
01116   case OPR_COMPLEX:
01117     {
01118       MTYPE rtype = OPCODE_rtype(op);
01119       if ( rtype == MTYPE_C4 )
01120   return MTYPE_F4;
01121       else if ( rtype == MTYPE_C8 )
01122   return MTYPE_F8;
01123 #if defined(TARG_IA64)
01124       else if ( rtype == MTYPE_C10 )
01125   return MTYPE_F10;
01126 #endif
01127       else if ( rtype == MTYPE_CQ )
01128   return MTYPE_FQ;
01129       else {
01130   FmtAssert( FALSE, 
01131        ("CODEREP::Operand_type: unknown type %d", rtype) );
01132   return MTYPE_UNKNOWN;
01133       }
01134     }
01135       
01136   case OPR_REALPART:
01137   case OPR_IMAGPART:
01138     {
01139       MTYPE rtype = OPCODE_rtype(op);
01140       if ( rtype == MTYPE_F4 )
01141   return MTYPE_C4;
01142       else if ( rtype == MTYPE_F8 )
01143   return MTYPE_C8;
01144 #if defined(TARG_IA64)
01145       else if ( rtype == MTYPE_F10 )
01146   return MTYPE_C10;
01147 #endif
01148       else if ( rtype == MTYPE_FQ )
01149   return MTYPE_CQ;
01150       else {
01151   FmtAssert( FALSE, 
01152        ("CODEREP::Operand_type: unknown type %d", rtype) );
01153   return MTYPE_UNKNOWN;
01154       }
01155     }
01156 
01157   case OPR_SELECT:
01158     if ( which_kid == 0 )
01159       return MTYPE_UNKNOWN;
01160     else
01161       return OPCODE_rtype(op);
01162 
01163   case OPR_SHL:
01164   case OPR_ASHR:
01165   case OPR_LSHR:
01166     if ( which_kid == 1 )
01167       return MTYPE_UNKNOWN;
01168     else
01169       return OPCODE_rtype(op);
01170 
01171   case OPR_CVTL:
01172   default:
01173     return OPCODE_rtype(op);
01174   }
01175 }
01176 
01177 /* CVTL-RELATED start (correctness) */
01178 // Insert correct type conversion
01179 CODEREP*
01180 CODEREP::Fixup_type(MTYPE opr_type, CODEMAP *htable)
01181 {
01182   INT           cvt_kind;
01183   OPCODE        opc;
01184   CODEREP      *cr = Alloc_stack_cr(0);
01185 
01186   FmtAssert(this != NULL,
01187       ("CODEREP::Fixup_type: called with null CR "));
01188 
01189   // check if there is missing convert from this node to its parent
01190   cvt_kind = Need_type_conversion(Dtyp(), opr_type, &opc);
01191 
01192   switch (cvt_kind) {
01193   case NOT_AT_ALL:
01194     return this;
01195   case NEED_CVT:
01196     IncUsecnt();
01197     cr->Init_expr(opc, this);
01198     return htable->Rehash(cr);
01199   case NEED_CVTL:
01200     IncUsecnt();
01201     cr->Init_expr(opc, this);
01202     cr->Set_offset(MTYPE_bit_size(opr_type));
01203     return htable->Rehash(cr);
01204   }
01205 
01206   return this;
01207 }
01208 /* CVTL-RELATED finish */
01209 
01210 void
01211 CODEREP::DecUsecnt_rec(void)
01212 {
01213   //FmtAssert(usecnt != 0, 
01214   //   ("CODEREP::DecUsecnt_rec: trying to decrement usecnt when value is 0"));
01215   // convert to Warn_todo tempoary ...
01216   if (this == NULL) {
01217     Warn_todo(
01218       "CODEREP::DecUsecnt_rec: trying to decrement usecnt when this is null.");
01219     return;
01220   }
01221 
01222   if (usecnt == 0) 
01223     Warn_todo(
01224       "CODEREP::DecUsecnt_rec: trying to decrement usecnt when value is 0.");
01225   DecUsecnt();
01226   switch (kind) {
01227   case CK_LDA: 
01228   case CK_CONST: 
01229   case CK_RCONST:
01230   case CK_VAR:
01231     return;
01232   case CK_IVAR:
01233     if (Usecnt()) return;
01234     // usecnt becomes 0, so need just do the same for all kids
01235     Ilod_base()->DecUsecnt_rec();
01236     if (Opr() == OPR_MLOAD) {
01237       CODEREP *num_byte = Mload_size();
01238       num_byte->DecUsecnt_rec();
01239     }
01240     else if (Opr() == OPR_ILOADX) {
01241       CODEREP *index = Index();
01242       index->DecUsecnt_rec();
01243     }
01244     return;
01245   case CK_OP:
01246     if (Usecnt()) return;
01247     // usecnt becomes 0, so need just do the same for all kids
01248     for (INT32 i = 0; i < Kid_count(); i++) 
01249       Opnd(i)->DecUsecnt_rec();
01250     return;
01251   }
01252 }
01253 
01254 // Same as DecUsecnt_rec, except that the given node's usecnt is not
01255 // decremented.  Only its kids' usecnt are decremented.
01256 // NOTE:  This function may only be useful when eliminating some
01257 // statement and we need to deal with its lvalue (Lhs).
01258 void
01259 CODEREP::DecKidsUsecnt_rec( void )
01260 {
01261   // increment just this node's usecnt
01262   IncUsecnt();
01263   // then decrement it and all of its kids' usecnt
01264   DecUsecnt_rec();
01265 }
01266 
01267 void
01268 CODEREP::IncUsecnt_rec(void)
01269 {
01270   IncUsecnt();
01271   switch (kind) {
01272   case CK_LDA: 
01273   case CK_CONST: 
01274   case CK_RCONST:
01275   case CK_VAR:
01276     return;
01277   case CK_IVAR:
01278     if (Usecnt() <= 1) return;
01279     // it is a CSE, so need to decrease usecnt of all kids
01280     Ilod_base()->DecUsecnt_rec();
01281     if (Opr() == OPR_MLOAD)
01282       Mload_size()->DecUsecnt_rec(); // the kid for the size
01283     else if (Opr() == OPR_ILOADX)
01284       Index()->DecUsecnt_rec(); // the kid for the size
01285     return;
01286   case CK_OP:
01287     if (Usecnt() <= 1) return;
01288     // it is a CSE, so need to decrease usecnt of all kids
01289     for (INT32 i = 0; i < Kid_count(); i++) 
01290       Opnd(i)->DecUsecnt_rec();
01291     return;
01292   }
01293 }
01294 
01295 
01296 STMTREP*
01297 CODEREP::Create_cpstmt(CODEREP *a, MEM_POOL*p)
01298 {
01299   // create copy from 'this' to 'a'. Return the created stmtrep.
01300   STMTREP *cpstmt = CXX_NEW(STMTREP,p);
01301   IncUsecnt();
01302 
01303 #if 1
01304   // The dsctyp is wrong.
01305   Is_True(a->Dsctyp() != MTYPE_UNKNOWN || Dsctyp() != MTYPE_UNKNOWN
01306     || Kind() == CK_CONST || Kind() == CK_RCONST || Kind() == CK_LDA,
01307           ("CODEREP::Create_cpstmt: both assigner and assignee has no type.  This problem is likely due to the SSA form is incorrectly setup in the earlier phase."));
01308   if (a->Dsctyp() == MTYPE_UNKNOWN) {
01309     if (Kind() == CK_CONST) {
01310       a->Set_dtyp_strictly(Dtyp());
01311       a->Set_dsctyp(Dtyp());
01312       a->Set_lod_ty(MTYPE_To_TY(Dtyp()));
01313     }
01314     else {
01315       a->Set_dtyp(Dtyp());
01316       a->Set_dsctyp(Dtyp()); // in case 'this' is an expression
01317       a->Set_lod_ty(MTYPE_To_TY(Dtyp()));
01318     }
01319     a->Set_sign_extension_flag();
01320   }
01321   else if (Kind() == CK_VAR && Dsctyp() == MTYPE_UNKNOWN) {
01322     Copy_type(a);
01323     Set_sign_extension_flag();
01324   }
01325 
01326   cpstmt->Init(a, this, OPCODE_make_op(a->Bit_field_valid() ? 
01327         OPR_STBITS : OPR_STID, MTYPE_V, a->Dsctyp()));
01328 
01329 #else
01330 
01331   // for testing
01332   Warn_todo("Create_cpstmt has the wrong dsctype.");
01333   cpstmt->Init(a, this, OPCODE_make_op(a->Bit_field_valid() ?
01334         OPR_STBITS : OPR_STID, MTYPE_V, MTYPE_U8));
01335 
01336 #endif
01337 
01338   // NOTE:  we can set the mu/chi lists to null here because this store
01339   // is guaranteed not to have side-effects.  If there other stores
01340   // that could side-effect the location we're storing to, we would
01341   // not have gotten into the situation where we can be inserting this
01342   // store.
01343   cpstmt->Set_chi_list(NULL);
01344 //  cpstmt->Set_rhs_type(Dtyp());
01345   if (a->Kind() == CK_VAR) 
01346     a->Set_defstmt(cpstmt);
01347   else if (a->Kind() == CK_IVAR) 
01348     a->Set_ivar_defstmt(cpstmt);
01349   return cpstmt;
01350 }
01351 
01352 STMTREP*
01353 CODEREP::Create_istr_stmt(CODEREP *a, MEM_POOL*p)
01354 {
01355   // create copy from 'this' to 'a'. Return the created stmtrep.
01356   STMTREP *cpstmt = CXX_NEW(STMTREP,p);
01357   IncUsecnt();
01358 
01359   // The dsctyp is wrong.
01360   Is_True(a->Dsctyp() != MTYPE_UNKNOWN || Dsctyp() != MTYPE_UNKNOWN,
01361           ("CODEREP::Create_istr_stmt: both assigner and assignee has no type"));
01362   if (a->Dsctyp() == MTYPE_UNKNOWN) {
01363     a->Set_dtyp(Dtyp());
01364     a->Set_dsctyp(Dsctyp());
01365     a->Set_lod_ty(Lod_ty());
01366     a->Set_sign_extension_flag();
01367   }
01368   else if (Dsctyp() == MTYPE_UNKNOWN) {
01369     Set_dtyp(a->Dtyp());
01370     Set_dsctyp(a->Dsctyp());
01371     Set_lod_ty(a->Ilod_ty());
01372     Set_sign_extension_flag();
01373   }
01374 
01375   if (a->Istr_base() == NULL)
01376     a->Set_istr_base(a->Ilod_base());
01377 
01378   cpstmt->Init(a, this, OPCODE_make_op(a->Opr() == OPR_ILOAD ? OPR_ISTORE : OPR_ISTBITS, MTYPE_V, a->Dsctyp()));
01379 
01380 //  cpstmt->Set_rhs_type(Dtyp());
01381   a->Set_ivar_defstmt(cpstmt);
01382   return cpstmt;
01383 }
01384 
01385 // optimization has invalidate the has_zver flag; recompute this flag from
01386 // scratch
01387 void
01388 STMTREP::Recompute_has_zver(void)
01389 {
01390   CHI_LIST_ITER chi_iter;
01391   CHI_NODE *chi;
01392   Reset_has_zver();
01393   FOR_ALL_NODE(chi, chi_iter, Init(Chi_list())) {
01394     if (! chi->Live())
01395       continue;
01396     CODEREP *res = chi->RESULT();
01397     if (res->Kind() == CK_VAR && res->Is_flag_set(CF_IS_ZERO_VERSION)) {
01398       Set_has_zver();
01399       return;
01400     }
01401   }
01402 }
01403 
01404 BB_NODE*
01405 CODEREP::Defbb(void) const
01406 {
01407   // the BB that defines this coderep
01408   Is_True(Kind() == CK_VAR || Kind() == CK_IVAR,
01409     ("CODEREP::Defbb: handles CK_VAR and CK_IVAR only"));
01410   if (Is_flag_set(CF_DEF_BY_PHI))
01411     return Defphi()->Bb();
01412   if (Get_defstmt() == NULL) return NULL;
01413   return Get_defstmt()->Bb();
01414 }
01415 
01416 
01417 // Returns TRUE if the statment is defined at by the entry chi list.
01418 //
01419 BOOL
01420 CODEREP::Def_at_entry(void) const
01421 {
01422   STMTREP *defstmt = Get_defstmt();
01423   if (defstmt != NULL && defstmt->Opr() == OPR_OPT_CHI)
01424     return TRUE;
01425   return FALSE;
01426 }
01427 
01428 
01429 IDX_32 
01430 CODEMAP::Hash_op_and_canon(CODEREP *cr, BOOL canonicalize)
01431 {
01432 
01433   if (canonicalize &&
01434       (cr->Kid_count() == 2 && OPCODE_commutative_op(cr->Op()) == cr->Op() &&
01435        !OPCODE_is_compare(cr->Op()) &&
01436        inCODEKIND(cr->Get_opnd(0)->Kind(), CK_VAR | CK_LDA | CK_RCONST) &&
01437        inCODEKIND(cr->Get_opnd(1)->Kind(), CK_VAR | CK_LDA | CK_RCONST))) {
01438     if (CR_Compare_Trees(cr->Get_opnd(0), cr->Get_opnd(1)) == 1) {
01439       if (cr->Coderep_id() != 0)
01440         Warn_todo("CODEMAP::Hash_op_and_canon, hashed cr not in canonical form");
01441       CODEREP *tmp = cr->Get_opnd(0);
01442       cr->Set_opnd(0, cr->Get_opnd(1));
01443       cr->Set_opnd(1, tmp);
01444     }
01445   }
01446 
01447   INT val = cr->Op();
01448 
01449   for (INT i = 0; i < cr->Kid_count(); i++) {
01450     CODEREP *opnd = cr->Get_opnd(i);
01451     val += (opnd->Coderep_id() << 4);
01452   }
01453   return val % size;
01454 }
01455 
01456 IDX_32 
01457 CODEMAP::Hash_ivar(CODEREP *cr, CODEREP *base)
01458 {
01459   INT val;
01460   OPERATOR opr = cr->Opr();
01461   if (OPERATOR_is_load(opr))    // only use size for memory ops
01462     val = opr + MTYPE_size_min(cr->Dsctyp());
01463   else
01464     val = cr->Op();
01465   val += (base->Coderep_id() << 4);
01466   return val % size;
01467 }
01468 
01469 IDX_32
01470 CODEMAP::Hash(CODEREP *cr)
01471 {
01472   switch (cr->Kind()) {
01473   case CK_IVAR: 
01474     return Hash_ivar(cr, cr->Ilod_base() ? cr->Ilod_base() : cr->Istr_base());
01475   case CK_OP: 
01476     return Hash_op_and_canon(cr); 
01477   case CK_LDA: 
01478     return Hash_lda(cr->Lda_base_st(), (IDTYPE)cr->Offset());
01479   case CK_CONST: 
01480     return Hash_const(cr->Const_val());
01481   case CK_RCONST:
01482     return Hash_rconst(cr->Const_id(), (IDTYPE)0); 
01483   default:
01484     FmtAssert(FALSE, ("CODEMAP::Hash: called with bad node"));
01485   }
01486   return 0; // to satisfy compiler
01487 }
01488 
01489 void
01490 CODEREP_CONTAINER::Add_it(CODEREP *cr, const mUINT16 idx, CODEMAP *htable)
01491 {
01492   // Replicate cr and append it to the tail
01493   SLIST::Prepend(cr);
01494   cr->Set_coderep_id(htable->Next_coderep_id());
01495   htable->Set_hash_bucket(idx, Head());
01496 }
01497 
01498 void
01499 CODEREP_CONTAINER::Delete_it(CODEREP *cr, const mUINT16 idx, CODEMAP *htable)
01500 {
01501   // remove cr from the bucket; must succeed (cr must be in list)
01502   if (Head() == cr) {
01503     SLIST::Remove_Headnode();
01504     htable->Set_hash_bucket(idx, Head());
01505   }
01506   else {
01507     CODEREP *prev;
01508     CODEREP_ITER cr_iter;
01509     FOR_ALL_NODE(prev, cr_iter, Init(this->Head())) {
01510       if (prev->Next() == cr) {
01511         cr->Remove(prev);
01512       }
01513     }
01514   }
01515 }
01516 
01517 BOOL
01518 CODEREP_CONTAINER::Contains(CODEREP *cr)
01519 {
01520   // test coderep_container contains cr
01521   CODEREP *tmp;
01522   CODEREP_ITER cr_iter;
01523   FOR_ALL_NODE(tmp, cr_iter, Init(this->Head())) {
01524     if (tmp->Match(cr))
01525       return TRUE;
01526   }
01527   return FALSE;
01528 }
01529 
01530 CODEREP*
01531 CODEREP_CONTAINER::Find_cr(CODEREP *cr, INT32 mu_vsym_depth, OPT_STAB *sym)
01532 {
01533   // return the coderep it exists in MAP, return NULL otherwise
01534   // it also establish the len field and the tail field.
01535   CODEREP *tmp;
01536   CODEREP_ITER cr_iter;
01537   INT32 counter = 0;
01538   FOR_ALL_NODE(tmp, cr_iter, Init(this)) {
01539     Set_Tail(tmp);
01540     if (tmp->Match(cr, mu_vsym_depth, sym)) 
01541       return tmp;
01542     counter++;
01543   }
01544 
01545   // note: this is just a warning to us for now, and should be removed
01546   // and we can then remove the counter variable all together
01547   if ( counter >= 1000 ) {
01548     Warn_todo( "CODEREP_CONTAINER::Find_cr has 1000 hash entries" );
01549   }
01550 
01551   len = cr_iter.Len();
01552   return NULL;
01553 }
01554 
01555 CODEREP_LIST*
01556 CODEREP_LIST::Prepend(CODEREP *cr, MEM_POOL *pool)
01557 {
01558   CODEREP_LIST_CONTAINER coderep_list_container(this);
01559   CODEREP_LIST *new_crlst = (CODEREP_LIST*)CXX_NEW( CODEREP_LIST(cr), pool );
01560   if ( new_crlst == NULL ) ErrMsg ( EC_No_Mem, "CODEREP_LIST::Prepend" );
01561   coderep_list_container.Prepend(new_crlst);
01562   return (CODEREP_LIST*)coderep_list_container.Head();
01563 }
01564 
01565 BOOL 
01566 CODEREP_LIST::Contains(CODEREP *cr) 
01567 {
01568   // check if cr is already in the list
01569   CODEREP *tmp;
01570   CODEREP_LIST_ITER cr_iter;
01571   FOR_ALL_ELEM(tmp, cr_iter, Init(this)) 
01572     if (tmp == cr)
01573       return TRUE;
01574   return FALSE;
01575 }
01576 
01577 BOOL 
01578 CODEREP_LIST_CONTAINER::Contains(CODEREP *cr) 
01579 {
01580   // check if cr is already in the container
01581   CODEREP *tmp;
01582   CODEREP_LIST_ITER cr_iter;
01583   FOR_ALL_ELEM(tmp, cr_iter, Init(this)) 
01584     if (tmp == cr)
01585       return TRUE;
01586   return FALSE;
01587 }
01588 
01589 void
01590 CODEREP_LIST_CONTAINER::Prepend(CODEREP *cr, MEM_POOL *pool)
01591 {
01592   CODEREP_LIST *new_crlst = (CODEREP_LIST*)CXX_NEW( CODEREP_LIST(cr), pool );
01593   if ( new_crlst == NULL )
01594     ErrMsg ( EC_No_Mem, "CODEREP_LIST_CONTAINER::Prepend" );
01595   Prepend(new_crlst);
01596 }
01597 
01598 CR_PAIR_LIST*
01599 CR_PAIR_LIST::Prepend(CODEREP *nd1,  // insert in front, return head
01600           CODEREP *nd2,
01601           MEM_POOL *pool)
01602 {
01603   CR_PAIR_LIST_CONTAINER cr_pair_list_container(this);
01604   CR_PAIR_LIST *new_crlst = (CR_PAIR_LIST*)CXX_NEW( CR_PAIR_LIST(nd1,nd2), pool );
01605   if ( new_crlst == NULL ) ErrMsg ( EC_No_Mem, "CR_PAIR_LIST::Prepend" );
01606   cr_pair_list_container.Prepend(new_crlst);
01607   return (CR_PAIR_LIST*)cr_pair_list_container.Head();
01608 }
01609 
01610 BOOL 
01611 CR_PAIR_LIST::Contains(CODEREP *nd1,
01612            CODEREP *nd2)
01613 {
01614   if (nd2 > nd1) { // sort to make nd1 > nd2
01615     CODEREP *tmp = nd1; nd1 = nd2; nd2 = tmp;
01616   }
01617   // check if cr is already in the list
01618   CR_PAIR_LIST_ITER cr_iter;
01619   CR_PAIR_LIST     *tmp;
01620   FOR_ALL_NODE(tmp, cr_iter, Init(this))
01621     if (tmp->Nd1() == nd1 && tmp->Nd2())
01622       return TRUE;
01623   return FALSE;
01624 }
01625 
01626 BOOL 
01627 CR_PAIR_LIST_CONTAINER::Contains(CODEREP *nd1,
01628          CODEREP *nd2) 
01629 {
01630   // check if cr is already in the container
01631   if (nd2 > nd1) { // sort to make nd1 > nd2
01632     CODEREP *tmp = nd1; nd1 = nd2; nd2 = tmp;
01633   }
01634   CR_PAIR_LIST_ITER cr_iter;
01635   CR_PAIR_LIST     *tmp;
01636   FOR_ALL_NODE(tmp, cr_iter, Init(this))
01637     if (tmp->Nd1() == nd1 && tmp->Nd2())
01638       return TRUE;
01639   return FALSE;
01640 }
01641 
01642 void
01643 CR_PAIR_LIST_CONTAINER::Prepend(CODEREP *nd1,
01644         CODEREP *nd2,
01645         MEM_POOL *pool)
01646 {
01647   CR_PAIR_LIST *new_crlst = (CR_PAIR_LIST*)CXX_NEW( CR_PAIR_LIST(nd1,nd2), pool );
01648   if ( new_crlst == NULL )
01649     ErrMsg ( EC_No_Mem, "CR_PAIR_LIST_CONTAINER::Prepend" );
01650   Prepend(new_crlst);
01651 }
01652 
01653 void
01654 CODEMAP::Alloc_hash_vec(void)
01655 {
01656   // called by the constructor
01657   hash_vec = CXX_NEW_ARRAY(CODEREP*, size+1, mem_pool);
01658   if (hash_vec == NULL) ErrMsg ( EC_No_Mem, "CODEREP::Alloc_hash_vec" );
01659   BZERO(hash_vec, sizeof(CODEREP*) * (size+1));
01660 }
01661 
01662 void
01663 CODEMAP::Free_hash_vec(void)
01664 {
01665   // called by the destructor
01666   // do nothing since we want to pop the Opt_default_pool at the end
01667   // of optimization phase.
01668 }
01669 
01670 CODEMAP::CODEMAP(mUINT32   hash_size,
01671                  CFG      *cfg,
01672                  OPT_STAB *asym,
01673                  SSA      *ssa, 
01674                  IDX_32    phi_hash_size,
01675      OPT_PHASE phase,
01676                  MEM_POOL *pool):
01677   _phi_id_map(phi_hash_size, NULL, pool, 0)
01678 {
01679   mem_pool = pool;
01680   sym = asym;
01681   _cfg = cfg;
01682   _ssa = ssa;
01683   size = hash_size;
01684   _phase = phase;
01685   Alloc_hash_vec();
01686   _prefetch_map  = WN_MAP_Create(pool);
01687   _coderep_id_cnt = 1;        // ID of 0 is unused
01688   _num_iloadfolds = _num_istorefolds = _num_inputprops = _num_mainprops = _num_shrinks = 0;
01689   _tracing = Get_Trace( TP_GLOBOPT, CR_DUMP_FLAG );
01690   _phi_hash_valid = FALSE;
01691   _pre_temp_id = 0;
01692 }
01693 
01694 CODEMAP::~CODEMAP(void)
01695 {
01696   size = 0;
01697   Free_hash_vec();
01698   WN_MAP_Delete(_prefetch_map);
01699 }
01700 
01701 // search bucket, create CR if not found; increment usecnt
01702 CODEREP *
01703 CODEMAP::Find_or_append_CR(IDX_32 hash_idx, CODEREP *cr,
01704          INT32 mu_vsym_depth)
01705 { CODEREP_CONTAINER cr_list;
01706   cr_list.Init_Head(Hash_bucket(hash_idx));
01707   CODEREP *retv = cr_list.Find_cr(cr, mu_vsym_depth, Sym());
01708   if (retv) {
01709     retv->IncUsecnt_rec();
01710     return retv;
01711   } else {
01712     retv = CXX_NEW_VARIANT(CODEREP(*cr),
01713          cr->Extra_space_used(),
01714          mem_pool);
01715     cr_list.Add_it(retv, hash_idx, this);
01716     retv->Set_usecnt(1);
01717     return retv;
01718   }
01719 }
01720 
01721 // Create CR and append to bucket; does not increment usecnt
01722 CODEREP *
01723 CODEMAP::Append_CR(IDX_32 hash_idx, CODEREP *cr)
01724 { CODEREP_CONTAINER cr_list;
01725   CODEREP *retv = CXX_NEW_VARIANT(CODEREP(*cr),
01726           cr->Extra_space_used(),
01727           mem_pool);
01728   cr_list.Init_Head(Hash_bucket(hash_idx));
01729   retv->Set_usecnt(0);
01730   retv->Reset_flag((CR_FLAG)(CF_DEF_BY_PHI | CF_DEF_BY_CHI));
01731   cr_list.Add_it(retv, hash_idx, this);
01732   return retv;
01733 }
01734 
01735 // search bucket, error if not found
01736 CODEREP *
01737 CODEMAP::Find_CR(IDX_32 hash_idx, CODEREP *cr, INT32 mu_vsym_depth, BOOL ok_to_fail)
01738 { CODEREP_CONTAINER cr_list;
01739   cr_list.Init_Head(Hash_bucket(hash_idx));
01740   CODEREP *retv = cr_list.Find_cr(cr, mu_vsym_depth, Sym());
01741   if (retv) {
01742     if (!ok_to_fail) retv->IncUsecnt_rec();
01743     return retv;
01744   }
01745   if (!ok_to_fail)
01746     FmtAssert(FALSE,("CODEREP::Find_CR, CR was not found"));
01747   return NULL; // to satisfy compiler
01748 }
01749 
01750 // remove this node from htable; node must not be CK_VAR
01751 void        
01752 CODEMAP::Remove(CODEREP *cr)
01753 {
01754   IDX_32 hash_idx = Hash(cr);
01755   CODEREP_CONTAINER cr_list;
01756   cr_list.Init_Head(Hash_bucket(hash_idx));
01757   cr_list.Delete_it(cr, hash_idx, this);
01758 }
01759 
01760 // ======================================================================
01761 // For ILOAD
01762 // ======================================================================
01763 CODEREP *
01764 CODEMAP::Hash_Ivar(CODEREP *cr, INT32 mu_vsym_depth)
01765 { 
01766   Is_True(cr->Kind() == CK_IVAR,("CODEMAP::Hash_Ivar, wrong kind"));
01767   Is_True(cr->Ilod_base() || cr->Istr_base(),("CODEMAP::Hash_Ivar, no base"));
01768 
01769   CODEREP *new_cr = Alloc_stack_cr(0);
01770   OPCODE   opc;
01771   INT      need_cvt;
01772   CODEREP *exist_cr;
01773   IDX_32   hash_idx;
01774 
01775   /* CVTL-RELATED start (correctness) */
01776   // change {I,U}4{I,U}8ILOD to {I,U}4{I,U}8CVT({I,U}8{I,U}8ILOD) (truncation)
01777   if (cr->Dsctyp() != MTYPE_BS &&
01778       MTYPE_is_integral(cr->Dtyp()) && MTYPE_is_integral(cr->Dsctyp()) &&
01779       MTYPE_size_min(cr->Dsctyp()) > MTYPE_size_min(cr->Dtyp())) {
01780     need_cvt = Need_type_conversion(cr->Dsctyp(), cr->Dtyp(), &opc);
01781     Is_True(need_cvt == NEED_CVT, ("CODEMAP::Hash_Ivar: type err"));
01782 
01783     cr->IncUsecnt();
01784     cr->Set_dtyp(cr->Dsctyp());
01785     hash_idx = Hash_ivar(cr, cr->Ilod_base()?cr->Ilod_base():cr->Istr_base());
01786     exist_cr = Find_CR(hash_idx,cr,mu_vsym_depth,TRUE);
01787     if (exist_cr == NULL) {
01788       exist_cr = Append_CR(hash_idx,cr);
01789     }
01790     else { // pick stronger alignment
01791       TY_IDX exist_addr_ty = exist_cr->Ilod_base_ty();
01792       TY_IDX cr_addr_ty = cr->Ilod_base_ty();
01793       if (cr->Opr() == OPR_ILOAD && exist_addr_ty && cr_addr_ty &&
01794     TY_kind(exist_addr_ty) == KIND_POINTER &&
01795     TY_kind(cr_addr_ty) == KIND_POINTER &&
01796     TY_align_exp(TY_pointed(cr_addr_ty)) <
01797         TY_align_exp(TY_pointed(exist_addr_ty)))
01798   exist_cr->Set_ilod_base_ty(cr_addr_ty);
01799     }
01800     new_cr->Init_expr(opc, exist_cr);
01801     return Hash_Op(new_cr);
01802   }
01803 
01804   // Set the sign_extd flag for ILOAD of integral variable
01805   cr->Set_sign_extension_flag();
01806   hash_idx = Hash_ivar(cr, cr->Ilod_base()?cr->Ilod_base():cr->Istr_base());
01807   exist_cr = Find_CR(hash_idx,cr,mu_vsym_depth,TRUE);
01808   if (exist_cr == NULL) {
01809     return Append_CR(hash_idx,cr);
01810   } else {
01811      // pick stronger alignment
01812      TY_IDX exist_addr_ty = exist_cr->Ilod_base_ty();
01813      TY_IDX cr_addr_ty = cr->Ilod_base_ty();
01814      if (cr->Opr() == OPR_ILOAD && exist_addr_ty && cr_addr_ty &&
01815    TY_kind(exist_addr_ty) == KIND_POINTER &&
01816    TY_kind(cr_addr_ty) == KIND_POINTER &&
01817    TY_align_exp(TY_pointed(cr_addr_ty)) <
01818        TY_align_exp(TY_pointed(exist_addr_ty)))
01819        exist_cr->Set_ilod_base_ty(cr_addr_ty);
01820 
01821 #ifdef Is_True_On
01822     BOOL is_sign_extd = exist_cr->Is_sign_extd();
01823     exist_cr->Set_sign_extension_flag();
01824     Is_True(is_sign_extd==exist_cr->Is_sign_extd(),("CODEMAP::Hash_Ivar: existing cr's sign extension flag is not consistent"));
01825 #endif
01826 
01827     if (exist_cr->Is_sign_extd()==cr->Is_sign_extd()) { // no type conversion
01828 #ifdef KEY
01829       return exist_cr->Fixup_type(cr->Dtyp(), this);
01830 #else
01831       return exist_cr;
01832 #endif
01833     }
01834 
01835     need_cvt =
01836       Need_load_type_conversion(exist_cr->Is_sign_extd(), cr->Is_sign_extd(),
01837                                 cr->Dtyp(), cr->Dsctyp(), &opc);
01838     Is_True(need_cvt != NOT_AT_ALL, ("CODEMAP::Hash_Ivar: type err"));
01839 
01840     cr->IncUsecnt();
01841     new_cr->Init_expr(opc, exist_cr);
01842     if (need_cvt == NEED_CVTL) {
01843       if (cr->Dsctyp() != MTYPE_BS)
01844   new_cr->Set_offset(MTYPE_size_min(cr->Dsctyp()));
01845       else {
01846   UINT cur_field_id = 0;
01847   UINT64 field_offset = 0;
01848   FLD_HANDLE fld = FLD_And_Offset_From_Field_Id(cr->Ilod_ty(),
01849        cr->I_field_id(), cur_field_id, field_offset);
01850   new_cr->Set_offset(FLD_bsize(fld));
01851       }                                                                                            
01852     }
01853     return Hash_Op(new_cr);
01854   }
01855   /* CVTL-RELATED finish */
01856 }
01857 
01858 //----------------------------------------------------------------------------
01859 
01860 CODEREP *
01861 CODEMAP::Add_lda_node(CODEREP *lda, INT64 new_offset)
01862 {
01863   CODEREP *cr = Alloc_stack_cr(0);
01864   cr->Copy(*lda);
01865   cr->Set_offset(new_offset);
01866   return Hash_Lda(cr);
01867 }
01868 
01869 
01870 CODEREP *
01871 CODEMAP::Add_unary_node(OPCODE op, CODEREP *kid)
01872 {
01873   CODEREP *cr = Alloc_stack_cr(0);
01874   cr->Init_op( op, 1 );
01875   cr->Set_opnd( 0, kid);
01876   if (cr->Opr() == OPR_EXTRACT_BITS) printf("This is a disaster\n");
01877   return Hash_Op(cr);
01878 }
01879 
01880 
01881 CODEREP*
01882 CODEMAP::Add_bin_node(OPCODE op, CODEREP *kid0, CODEREP *kid1)
01883 {
01884   CODEREP *cr = Alloc_stack_cr(1);
01885   cr->Init_op( op, 2 );
01886   cr->Set_opnd( 0, kid0);
01887   cr->Set_opnd( 1, kid1);
01888   return Hash_Op(cr);
01889 }
01890 
01891 
01892 CODEREP*
01893 CODEMAP::Add_tertiary_node(OPCODE op, CODEREP *kid0, CODEREP *kid1, CODEREP *kid2)
01894 {
01895   CODEREP *cr = Alloc_stack_cr(2);
01896   cr->Init_op( op, 3 );
01897   cr->Set_opnd( 0, kid0);
01898   cr->Set_opnd( 1, kid1);
01899   cr->Set_opnd( 2, kid2);
01900   return Hash_Op(cr);
01901 }
01902 
01903 CODEREP *
01904 CODEMAP::Add_nary_node(OPCODE op, CODEREP **kids, mUINT32 n)
01905 {
01906   CODEREP *cr = Alloc_stack_cr(n - 1);
01907 
01908   mUINT32       i;
01909 
01910   cr->Init_op( op, n );
01911   for (i = 0; i < n; i++) {
01912     cr->Set_opnd( i, kids[i] );
01913   }
01914   return Hash_Op(cr);
01915 }
01916 
01917 CODEREP*
01918 CODEMAP::Add_unary_node_and_fold(OPCODE op, CODEREP *kid)
01919 {
01920   FOLD         ftmp;
01921   CODEREP      *crtmp;
01922   CODEREP      *cr;
01923 
01924   cr = Add_unary_node(op, kid);
01925   if ((crtmp = ftmp.Fold_Expr(cr)) != NULL)
01926     cr = crtmp;
01927   return cr;
01928 }
01929 
01930 BOOL WOPT_Enable_Canon_Compare=TRUE;
01931 
01932 CODEREP*
01933 CODEMAP::Add_bin_node_and_fold(OPCODE op,
01934                                CODEREP *kid0,
01935                                CODEREP *kid1,
01936                                BB_NODE *bb)
01937 {
01938   FOLD         ftmp;
01939   CODEREP      *crtmp;
01940   CODEREP      *cr;
01941 
01942   cr = Alloc_stack_cr(1);
01943   cr->Init_op( op, 2 );
01944   cr->Set_opnd( 0, kid0);
01945   cr->Set_opnd( 1, kid1);
01946 
01947   BOOL do_canonicalization = TRUE;
01948   BOOL modified;
01949   if ((crtmp = ftmp.Fold_Expr(cr)) != NULL) {
01950     if (crtmp->Kind() == CK_OP && OPCODE_is_compare(crtmp->Op()) &&
01951         WOPT_Enable_Canon_Compare && _phase == MAINOPT_PHASE && bb) {
01952       cr = Alloc_stack_cr(1);
01953       cr->Init_op( crtmp->Op(), 2 );
01954       cr->Set_opnd(0, crtmp->Get_opnd(0));
01955       cr->Set_opnd(1, crtmp->Get_opnd(1));
01956 
01957       do_canonicalization = !Canonicalize_compare(cr, bb, &modified);
01958       return Hash_Op(cr, do_canonicalization);
01959     }
01960     else {
01961       // here NOT select #ifdef KEY from pathscale, cause I'm afraid that osprey 
01962       // had modified #ifdef KEY to #ifdef TARG_X8664 in last merge.
01963 #ifdef KEY // bug 4518
01964       if (crtmp->Kind() == CK_CONST && crtmp->Dtyp() == MTYPE_U4 && 
01965     (MTYPE_signed(kid0->Dtyp()) || MTYPE_signed(kid1->Dtyp()))) 
01966   return Add_const(MTYPE_I4, crtmp->Const_val());
01967 #endif
01968       return crtmp;
01969     }
01970   }
01971   if (WOPT_Enable_Canon_Compare && _phase == MAINOPT_PHASE && bb)
01972     do_canonicalization = !Canonicalize_compare(cr, bb, &modified);
01973 
01974   return Hash_Op(cr, do_canonicalization);
01975 }
01976 
01977 
01978 CODEREP *
01979 CODEMAP::Add_expr_and_fold(CODEREP *cr) 
01980 {
01981   switch (cr->Kind()) {
01982   case CK_VAR:  
01983     return NULL;
01984   case CK_LDA:   
01985   case CK_CONST: 
01986   case CK_RCONST:
01987   case CK_IVAR:  
01988     return Rehash(cr);
01989   case CK_OP:
01990     {
01991       FOLD ftmp;
01992       CODEREP *newcr = ftmp.Fold_Expr(cr);
01993       return (newcr != NULL) ? newcr : Rehash(cr);
01994     }
01995   default:
01996     Fail_FmtAssertion("CODEMAP::Add_expr_and_fold: unhandled CK_KIND");
01997     // To satisfy the compiler:
01998     return NULL;
01999   }
02000 }
02001 
02002 
02003 CODEREP*
02004 CODEMAP::Add_const(MTYPE typ, INT64 val)
02005 {
02006   CODEREP *cr = Alloc_stack_cr(0);
02007   cr->Init_const(typ, val);
02008   cr = Hash_Const(cr);
02009 #ifndef KEY // this is bad for performance
02010   if (Split_64_Bit_Int_Ops && MTYPE_size_min(cr->Dtyp()) < MTYPE_size_min(typ))
02011     cr = Add_unary_node(OPCODE_make_op(OPR_CVT, typ, cr->Dtyp()), cr);
02012 #endif
02013   return cr;
02014 }
02015 
02016 // This function is exported to other classes
02017 // It creates a CANON_CR object on stack and use it to call the private
02018 // member function CODEMAP::Add_expr.  After the function return, it
02019 // then pull out the content from the CANON_CR to create the returning
02020 // CODEREP.
02021 CODEREP*
02022 CODEMAP::Add_expr(WN       *wn,
02023       OPT_STAB *opt_stab,
02024       STMTREP  *stmt,
02025       BOOL     *proped,
02026       COPYPROP *copyprop,
02027       BOOL no_complex_preg)
02028 {
02029   CANON_CR ccr;
02030   *proped |= Add_expr(wn, opt_stab, stmt, &ccr, copyprop, no_complex_preg);
02031   CODEREP *cr = ccr.Convert2cr(wn, this, *proped);
02032   return cr;
02033 }
02034 
02035 BOOL
02036 CODEMAP::Canon_add_sub(WN       *wn,
02037                       OPT_STAB *opt_stab,
02038                       STMTREP  *stmt,
02039                       CANON_CR *ccr,
02040                       CODEREP  *cr,
02041           COPYPROP *copyprop)
02042 {
02043   CANON_CR kid1;
02044   CODEREP *retv;
02045   const OPERATOR opr = WN_operator(wn);
02046   const OPCODE op = WN_opcode(wn);
02047   BOOL  propagated = FALSE;
02048 
02049   propagated |= Add_expr(WN_kid(wn, 0), opt_stab, stmt, ccr, copyprop);
02050   propagated |= Add_expr(WN_kid(wn, 1), opt_stab, stmt, &kid1, copyprop);
02051   if (opr == OPR_ADD)
02052     ccr->Set_scale(ccr->Scale() + kid1.Scale());
02053   else ccr->Set_scale(ccr->Scale() - kid1.Scale());
02054 #ifdef KEY // bug 5557
02055   if (MTYPE_byte_size(WN_rtype(wn)) == 4 &&
02056       (INT32)ccr->Scale() < 0x80000 /* bug8517 */)
02057     ccr->Set_scale(ccr->Scale() << 32 >> 32);
02058 #endif
02059   if (kid1.Tree() == NULL) 
02060     return propagated;
02061   if (ccr->Tree() == NULL) {
02062     if (opr == OPR_ADD)
02063       ccr->Set_tree(kid1.Tree());
02064     else
02065 #ifdef KEY // bug 14605: force to signed because generating negate
02066       ccr->Set_tree(Add_unary_node(
02067                       OPCODE_make_op(OPR_NEG,
02068                         Mtype_TransferSign(MTYPE_I4, OPCODE_rtype(op)),
02069                         MTYPE_V),
02070                       kid1.Tree()));
02071 #else
02072       ccr->Set_tree(Add_unary_node(
02073                         OPCODE_make_op(OPR_NEG, OPCODE_rtype(op), MTYPE_V), 
02074                         kid1.Tree()));
02075 #endif
02076     return propagated;
02077   }
02078   if (kid1.Tree() == NULL) {
02079     return propagated;
02080   }
02081   // both ccr and kid1 has tree
02082   cr->Set_opnd(0, ccr->Tree());
02083   cr->Set_opnd(1, kid1.Tree());
02084   if (propagated) {
02085     FOLD ftmp;
02086     retv = ftmp.Fold_Expr(cr);
02087     if (retv == NULL) { // either not folded or Fold_Expr has not rehashed
02088       retv = Hash_Op(cr);
02089     }
02090   }
02091   else {
02092     retv = Hash_Op(cr);
02093   }
02094   ccr->Set_tree(retv);
02095   return propagated;
02096 }
02097 
02098 BOOL
02099 CODEMAP::Canon_neg(WN       *wn,
02100                    OPT_STAB *opt_stab,
02101                    STMTREP  *stmt,
02102                    CANON_CR *ccr,
02103                    CODEREP  *cr,
02104        COPYPROP *copyprop)
02105 {
02106   CODEREP *retv;
02107   BOOL propagated = Add_expr(WN_kid(wn, 0), opt_stab, stmt, ccr, copyprop);
02108   ccr->Set_scale(- ccr->Scale());
02109   if (ccr->Tree() == NULL) 
02110     return propagated;
02111   cr->Set_opnd(0, ccr->Tree());
02112   retv = Hash_Op(cr);
02113   ccr->Set_tree(retv);
02114   return propagated;
02115 }
02116 
02117 BOOL
02118 CODEMAP::Canon_mpy(WN       *wn,
02119                    OPT_STAB *opt_stab,
02120                    STMTREP  *stmt,
02121                    CANON_CR *ccr,
02122                    CODEREP  *cr,
02123        COPYPROP *copyprop)
02124 {
02125   CANON_CR kid1;
02126   CODEREP *retv;
02127   BOOL  propagated = FALSE;
02128   BOOL  propagated1 = FALSE;
02129 
02130   propagated = Add_expr(WN_kid(wn, 0), opt_stab, stmt, ccr, copyprop);
02131   propagated1 = Add_expr(WN_kid(wn, 1), opt_stab, stmt, &kid1, copyprop);
02132   if (ccr->Tree() == NULL && kid1.Tree() == NULL) {
02133     ccr->Set_scale(ccr->Scale() * kid1.Scale());
02134 #ifdef KEY // bug 2846: check for need to truncate the folded result
02135     if (WN_rtype(wn) == MTYPE_I4)
02136       ccr->Set_scale((INT32) ccr->Scale());
02137     else if (WN_rtype(wn) == MTYPE_U4)
02138       ccr->Set_scale((UINT32) ccr->Scale());
02139 #endif
02140     return propagated+propagated1;
02141   }
02142   if (kid1.Tree() == NULL) {
02143     if (kid1.Scale() == 0 && !ccr->Tree()->Has_volatile_content()) {  // mult by 0: fold to 0
02144       ccr->Tree()->DecUsecnt_rec();
02145       ccr->Set_tree(NULL);
02146       ccr->Set_scale(0);
02147       return propagated+propagated1;
02148       }
02149     // materialize the constant part of ccr into tree
02150     cr->Set_opnd(0, ccr->Tree());
02151     cr->Set_opnd(1, Add_const(WN_rtype(wn), kid1.Scale()));
02152     ccr->Set_scale(ccr->Scale() * kid1.Scale());
02153     }
02154   else if (ccr->Tree() == NULL && !kid1.Tree()->Has_volatile_content()) {
02155     if (ccr->Scale() == 0) {  // mult by 0; fold to 0
02156       kid1.Tree()->DecUsecnt_rec();
02157       ccr->Set_tree(NULL);
02158       ccr->Set_scale(0);
02159       return propagated+propagated1;
02160       }
02161     // materialize the constant part of ccr into tree
02162     cr->Set_opnd(0, Add_const(WN_rtype(wn), ccr->Scale()));
02163     cr->Set_opnd(1, kid1.Tree());
02164     ccr->Set_scale(ccr->Scale() * kid1.Scale());
02165   }
02166   else {
02167     // both ccr and kid1 has tree
02168     cr->Set_opnd(0, ccr->Convert2cr(wn, this, propagated));
02169     cr->Set_opnd(1, kid1.Convert2cr(wn, this, propagated1));
02170     ccr->Set_scale(0);
02171   }
02172   if (propagated) {
02173     FOLD ftmp;
02174     retv = ftmp.Fold_Expr(cr);
02175     if (retv == NULL) { // either not folded or Fold_Expr has not rehashed
02176       retv = Hash_Op(cr);
02177     }
02178 #if defined(TARG_NVISA)
02179     else if (retv->Kind() == CK_CONST) { 
02180       // If after Folding we got a simple integer constant, this is same
02181       // as if (ccr->Tree() == NULL && kid1.Tree() == NULL) above
02182       // both trees are essentially null and the constant can be 
02183       // represented as just the additive part
02184       // Looks like there is no hashing implication
02185       // const_val has to be less than 32 bits to do this
02186       INT64 val = retv->Const_val();
02187       if (val == (INT32) val) {
02188         ccr->Set_scale((INT32) val);
02189         retv = NULL;
02190       }
02191     }
02192 #endif
02193   }
02194   else {
02195     retv = Hash_Op(cr);
02196   }
02197   ccr->Set_tree(retv);
02198   return propagated+propagated1;
02199 }
02200 
02201 /* CVTL-RELATED start (performance) */
02202 BOOL
02203 CODEMAP::Canon_cvt(WN       *wn,
02204                    OPT_STAB *opt_stab,
02205                    STMTREP  *stmt,
02206                    CANON_CR *ccr,
02207                    CODEREP  *cr,
02208        COPYPROP *copyprop)
02209 {
02210   const OPCODE op = WN_opcode(wn);
02211   WN   *kid = WN_kid(wn, 0);
02212   BOOL  propagated = Add_expr(kid, opt_stab, stmt, ccr, copyprop);
02213 #if defined(TARG_NVISA)
02214   if (ccr->Tree() == NULL) {
02215     // There is only a constant value in ccr
02216     return propagated;
02217   }
02218 #endif
02219 
02220 #if defined (TARG_MIPS) && !defined (TARG_SL)
02221   // U8I4CVT and I8I4CVT are nops so return kid, MIPS III and above
02222   // since U8I4CVT is required to preserve the type of its type for
02223   // Fix_var_type at emitter time, we do not delete U8I4CVT #329096
02224   if (Is_Target_ISA_M3Plus() && (op == OPC_I8I4CVT || op == OPC_U8I4CVT))
02225     return propagated;
02226 #elif defined(TARG_X8664)
02227   if (! Is_Target_32bit() && op == OPC_U8U4CVT)
02228     return propagated;
02229 #endif
02230   if ((Get_mtype_class(OPCODE_rtype(op)) & 
02231        Get_mtype_class(OPCODE_desc(op))) != 0 &&
02232       MTYPE_size_min(OPCODE_rtype(op)) == MTYPE_size_min(OPCODE_desc(op))) 
02233     return propagated;
02234 
02235 #ifdef TARG_SL
02236   extern BOOL Is_Target_32bit();
02237 #endif
02238 
02239   if ( WOPT_Enable_Cvt_Folding && 
02240 #if defined(TARG_X8664) || defined(TARG_NVISA) || defined (TARG_SL) // bug 5851
02241        ! Is_Target_32bit() &&
02242 #endif
02243       (op == OPC_I8U4CVT || op == OPC_U8U4CVT) && 
02244       WN_operator(kid) == OPR_LSHR ) {
02245     WN *bits = WN_kid1(kid);
02246     if ( WN_operator(bits) == OPR_INTCONST ) {
02247       INT bits_cnt = WN_const_val(bits);
02248       INT result_size = Actual_data_size(kid);
02249       if ( ( result_size <= MTYPE_size_min(MTYPE_I4) ) && 
02250     ( ( bits_cnt & 0x1F ) != 0 ) )
02251   {
02252     return propagated;
02253   }
02254     }
02255   }
02256   
02257   CODEREP *retv;
02258   CODEREP *expr;
02259 #if defined(TARG_X8664) || defined(TARG_NVISA)
02260   if (!Is_Target_32bit() && ccr->Tree() != NULL && Allow_wrap_around_opt) {
02261     if (ccr->Tree()->Kind() == CK_OP && ccr->Tree()->Op() == OPC_I8I4CVT && 
02262         op == OPC_I4I8CVT) { // bug 10707
02263       retv = ccr->Tree()->Opnd(0);
02264       ccr->Set_tree(retv);
02265     }
02266     else {
02267       cr->Set_opnd(0, ccr->Tree());
02268       retv = Hash_Op(cr);
02269       ccr->Set_tree(retv); // move the CVT to the operand
02270     }
02271   }
02272   else {
02273 #endif
02274   expr = ccr->Convert2cr(WN_kid0(wn), this, propagated);
02275   cr->Set_opnd(0, expr);
02276   retv = Hash_Op(cr);
02277   ccr->Set_tree(retv);
02278   ccr->Set_scale(0);
02279 #if defined(TARG_X8664) || defined(TARG_NVISA)
02280   }
02281 #endif
02282   return propagated;
02283 }
02284 /* CVTL-RELATED finish */
02285 
02286 // Create a new coderep node for this new variable version in the htable
02287 CODEREP *
02288 CODEMAP::Add_def(IDTYPE st, mINT16 version, STMTREP *stmt,
02289      MTYPE dtyp, MTYPE dsctyp, mINT32 ofst, TY_IDX ty,
02290      UINT field_id, BOOL is_store)
02291 {
02292   CODEREP         *cr = Alloc_stack_cr(0);
02293   CODEREP         *retv;
02294   INT              need_cvt = NOT_AT_ALL;
02295   OPCODE           opc;
02296 
02297   if (is_store && dtyp!=dsctyp && dsctyp != MTYPE_BS) {
02298     dtyp = Mtype_TransferSign(dsctyp,dtyp);
02299     if (MTYPE_size_min(dtyp)<=MTYPE_size_min(dsctyp))
02300       dtyp = dsctyp;  // necessary canonicalization
02301   }
02302   
02303 #ifdef TARG_SL
02304   if (dtyp == MTYPE_I2 && dsctyp == MTYPE_I2) {
02305     dtyp = MTYPE_I4;
02306   }
02307 #endif  
02308 #ifdef Is_True_On
02309   // check dtyp and dsctyp consistency
02310   if (MTYPE_is_float(dtyp)) {
02311     FmtAssert(MTYPE_is_float(dsctyp) && MTYPE_size_min(dtyp) == MTYPE_size_min(dsctyp),
02312         ("CODEMAP::Add_def: dtyp and dsctyp mismatch."));
02313   }
02314   if (MTYPE_is_complex(dtyp)) {
02315     FmtAssert(MTYPE_is_float(dsctyp) && MTYPE_size_min(dtyp) == MTYPE_size_min(dsctyp),
02316         ("CODEMAP::Add_def: dtyp and dsctyp mismatch."));
02317   }
02318 #endif
02319 
02320   const AUX_STAB_ENTRY* aux = sym->Aux_stab_entry(st);
02321   if (ty == 0 && aux->Is_dedicated_preg()) {
02322     ST *s = aux->St();
02323     ty = ST_type(s);
02324   }
02325 
02326   /* CVTL-RELATED start (correctness) */
02327   if (_phase != MAINOPT_PHASE || 
02328       ! Only_Unsigned_64_Bit_Ops || 
02329       Delay_U64_Lowering) {
02330 
02331     // Fix 777333.   Also add CVT for I8I4LDID.
02332     if ( dtyp == MTYPE_U8 && dsctyp == MTYPE_U4 ) {
02333       // make U8U4LDID into U8U4CVT(U4U4LDID)
02334       if ( ! is_store ) 
02335         need_cvt = Need_type_conversion(dsctyp, dtyp, &opc);
02336       dtyp = MTYPE_U4;
02337     }
02338     if ( dtyp == MTYPE_I8 && dsctyp == MTYPE_I4 ) {
02339       // make I8I4LDID into I8I4CVT(I4I4LDID)
02340       if ( ! is_store ) 
02341         need_cvt = Need_type_conversion(dsctyp, dtyp, &opc);
02342       dtyp = MTYPE_I4;
02343     }
02344   }
02345 
02346   cr->Init_var(dtyp, st, version, dsctyp, ofst, ty, field_id);
02347   if (aux->Bit_size() > 0) {
02348     if (aux->Field_id() != 0) {
02349       dsctyp = MTYPE_BS;    // we're in preopt with H WHIRL
02350       cr->Set_dsctyp(MTYPE_BS);
02351     }
02352     else if (dsctyp != MTYPE_BS) {
02353       cr->Set_bit_field_valid();
02354       cr->Set_bit_offset_size (aux->Bit_ofst(), aux->Bit_size());
02355     }
02356   }
02357   // change {I,U}4{I,U}8LDID to {I,U}4{I,U}8CVT({I,U}8{I,U}8LDID) (truncation)
02358   if (MTYPE_is_integral(dtyp) && MTYPE_is_integral(dsctyp) &&
02359       MTYPE_size_min(dsctyp) > MTYPE_size_min(dtyp)) {
02360     need_cvt = Need_type_conversion(cr->Dsctyp(), cr->Dtyp(), &opc);
02361     Is_True(need_cvt == NEED_CVT, ("CODEMAP::Add_def: type err"));
02362     cr->Set_dtyp(dsctyp);
02363   }
02364   cr->Set_sign_extension_flag();
02365   /* CVTL-RELATED finish */
02366 
02367   retv = CXX_NEW_VARIANT(CODEREP(*cr), cr->Extra_space_used(), mem_pool);
02368   retv->Set_coderep_id(Next_coderep_id());
02369   retv->Set_usecnt(0);
02370   retv->Reset_flag((CR_FLAG)(CF_DEF_BY_PHI | CF_DEF_BY_CHI));
02371   if (stmt) retv->Set_defstmt(stmt);
02372 
02373   // link up coderep nodes of the same variable
02374   AUX_STAB_ENTRY *aux_entry = sym->Aux_stab_entry(st);
02375   aux_entry->Set_cr_list(aux_entry->Cr_list()->Prepend(retv));
02376 
02377   /* CVTL-RELATED start (correctness) */
02378   if (need_cvt == NEED_CVT) {
02379     CODEREP *new_cr = Alloc_stack_cr(0);
02380     new_cr->Init_expr(opc, retv);
02381     retv = Hash_Op(new_cr);
02382   }
02383   /* CVTL-RELATED finish */
02384 
02385   return retv;
02386 }
02387 
02388 // Determine if two array subscript expressions only MAY yield the same value.
02389 // If they MUST or MUST NOT yield the same value, return FALSE.
02390 // Algorithm only matches expression patterns in canonicalized form.
02391 static BOOL
02392 Indices_only_may_overlap(CODEREP *x, CODEREP *y)
02393 {
02394   if (x == y) return FALSE; 
02395   if (inCODEKIND(x->Kind(), CK_LDA | CK_RCONST)) return TRUE;
02396   if (inCODEKIND(y->Kind(), CK_LDA | CK_RCONST)) return TRUE;
02397   if (x->Kind() == CK_CONST && y->Kind() == CK_CONST) {
02398     // both are integer constants
02399     return FALSE;
02400   }
02401   if (x->Kind() == CK_CONST || y->Kind() == CK_CONST) return TRUE;
02402   if (x->Kind() != CK_OP && y->Kind() != CK_OP) return TRUE;
02403   // now, one or both is CK_OP; if not CK_OP, can only be CK_VAR/CK_IVAR
02404   if (x->Kind() == CK_OP && y->Kind() == CK_OP) {
02405     if (x->Opr() != OPR_ADD && x->Opr() != OPR_SUB) 
02406       return TRUE;
02407     if (y->Opr() != OPR_ADD && y->Opr() != OPR_SUB) 
02408       return TRUE;
02409     if (x->Opr() != x->Opr())
02410       return TRUE;
02411     CODEREP *x0 = x->Opnd(0);
02412     CODEREP *x1 = x->Opnd(1);
02413     CODEREP *y0 = y->Opnd(0);
02414     CODEREP *y1 = y->Opnd(1);
02415     if (x0 == y0 && x1->Kind() == CK_CONST && y1->Kind() == CK_CONST)
02416       return FALSE;
02417     return TRUE;
02418   }
02419   if (x->Kind() != CK_OP) { // switch x and y
02420     CODEREP *t = y;
02421     y = x;
02422     x = t;
02423   }
02424   if (x->Opnd(0) != y) return TRUE;
02425   if (x->Kid_count() > 1 && 
02426       x->Opnd(1)->Kind() == CK_CONST && x->Opnd(1)->Const_val() != 0) 
02427     return FALSE;
02428   return TRUE;
02429 }
02430 
02431 // determine if two ivar nodes, in which one is a store and one is a load,
02432 // may be referencing the same location; lval is the store side; when not
02433 // sure, return TRUE
02434 static BOOL
02435 Ivars_may_overlap(CODEREP *lval, CODEREP *rval)
02436 {
02437  if (lval->Is_ivar_volatile()) return TRUE;
02438  if (lval->Dsctyp() == MTYPE_M || rval->Dsctyp() == MTYPE_M) {
02439    return TRUE;
02440  }
02441   if (lval->Istr_base() == rval->Ilod_base()) {
02442     INT32 lsize = MTYPE_size_min(lval->Dsctyp()) >> 3; // in bytes
02443     INT32 rsize = MTYPE_size_min(rval->Dsctyp()) >> 3; // in bytes
02444     INT32 loffset = lval->Offset();
02445     INT32 roffset = rval->Offset();
02446     return (loffset >= roffset) && (loffset - roffset < rsize) ||
02447      (roffset >= loffset) && (roffset - loffset < lsize);
02448   }
02449   else if (lval->Istr_base()->Kind() == CK_OP && 
02450      lval->Istr_base()->Opr() == OPR_ADD &&
02451      lval->Istr_base()->Opnd(1)->Kind() == CK_CONST &&
02452      lval->Istr_base()->Opnd(0) == rval->Ilod_base()) {
02453     INT64 lsize = MTYPE_size_min(lval->Dsctyp()) >> 3; // in bytes
02454     INT64 rsize = MTYPE_size_min(rval->Dsctyp()) >> 3; // in bytes
02455     INT64 loffset = lval->Offset() + lval->Istr_base()->Opnd(1)->Const_val();
02456     INT64 roffset = rval->Offset();
02457     return (loffset >= roffset) && (loffset - roffset < rsize) ||
02458      (roffset >= loffset) && (roffset - loffset < lsize);
02459   }
02460   else if (rval->Ilod_base()->Kind() == CK_OP && 
02461      rval->Ilod_base()->Opr() == OPR_ADD &&
02462      rval->Ilod_base()->Opnd(1)->Kind() == CK_CONST &&
02463      rval->Ilod_base()->Opnd(0) == lval->Istr_base()) {
02464     INT64 lsize = MTYPE_size_min(lval->Dsctyp()) >> 3; // in bytes
02465     INT64 rsize = MTYPE_size_min(rval->Dsctyp()) >> 3; // in bytes
02466     INT64 loffset = lval->Offset();
02467     INT64 roffset = rval->Offset() + rval->Ilod_base()->Opnd(1)->Const_val();
02468     return (loffset >= roffset) && (loffset - roffset < rsize) ||
02469      (roffset >= loffset) && (roffset - loffset < lsize);
02470   }
02471   else if (lval->Offset() == rval->Offset()) { // analyze array nodes
02472     CODEREP *lbase = lval->Istr_base();
02473     CODEREP *rbase = rval->Ilod_base();
02474     if (lbase->Kind() != CK_OP || lbase->Opr() != OPR_ARRAY ||
02475         rbase->Kind() != CK_OP || rbase->Opr() != OPR_ARRAY) 
02476       return TRUE;
02477     INT32 kid_count = lbase->Kid_count();
02478     if (kid_count != rbase->Kid_count())
02479       return TRUE;
02480     if (lbase->Opnd(0) != rbase->Opnd(0))
02481       return TRUE;
02482     INT32 dim = kid_count >> 1;
02483     INT32 i;
02484     for (i = 1; i <= dim; i++)
02485       if (lbase->Opnd(i) != rbase->Opnd(i))
02486   return TRUE;
02487     // analyze the subscripts
02488     BOOL subscripts_same = TRUE;
02489     for (i = 1; i <= dim; i++) {
02490       if (Indices_only_may_overlap(lbase->Opnd(dim+i), rbase->Opnd(dim+i)))
02491   return TRUE;
02492       if (lbase->Opnd(dim+i) != rbase->Opnd(dim+i)) 
02493   subscripts_same = FALSE;
02494     }
02495     return subscripts_same;
02496   }
02497   else return TRUE;
02498 }
02499 
02500 CODEREP *
02501 CODEMAP::Add_idef(OPCODE opc, OCC_TAB_ENTRY *occ, STMTREP *stmt,
02502       MU_NODE *mnode, MTYPE dtyp, MTYPE dsctyp, TY_IDX lodty,
02503       UINT field_id, mINT32 ofst, CODEREP *size, CODEREP *lbase,
02504       CODEREP *sbase, OPT_STAB* optstab)
02505 {
02506   CODEREP          *cr = Alloc_stack_cr(IVAR_EXTRA_NODE_CNT);
02507   CODEREP          *retv;
02508   OPERATOR         oper = OPCODE_operator(opc);
02509 
02510   cr->Init_ivar(opc, dtyp, occ, dsctyp, lodty, lbase, sbase,
02511     ofst, size, field_id);
02512   // all IVAR codereps have a mu_node
02513   cr->Set_ivar_mu_node(mnode);
02514   if (stmt) {
02515     cr->Set_ivar_defstmt(stmt);
02516     retv = Hash_New_ivar(cr);
02517   } 
02518   else {
02519     INT32 depth = 0;
02520     if (WOPT_Enable_VN_Full && 
02521   mnode != NULL &&
02522   OPERATOR_is_scalar_iload (cr->Opr()) &&
02523         cr->Dtyp() != MTYPE_M &&
02524   ! cr->Is_ivar_volatile()) {
02525       // find search distance in the use-def chain of the virtual variable in
02526       // terms of depth down its coderep stack 
02527       AUX_ID aux = mnode->OPND()->Aux_id();
02528       BOOL alias_with_cr = FALSE;
02529       CODEREP *vsym;
02530       if (Sym()->NULL_coderep(aux))
02531   alias_with_cr = TRUE;
02532       while (! alias_with_cr && Sym()->Elements_coderep(aux) > depth) {
02533   vsym = Sym()->Top_nth_coderep(aux, depth);
02534   STMTREP *dstmt = (vsym ? vsym->Defstmt() : NULL);
02535   alias_with_cr = (dstmt == NULL || 
02536        vsym->Is_flag_set(CF_IS_ZERO_VERSION) ||
02537        ! OPERATOR_is_scalar_istore (dstmt->Opr()) ||
02538        Ivars_may_overlap(dstmt->Lhs(), cr));
02539   if (! alias_with_cr) depth++;
02540       }
02541       // if zero version, need to back down by 1 because zero version 
02542       // cannot be used in finding match
02543       if (depth > 0 && 
02544     (vsym == NULL || vsym->Is_flag_set(CF_IS_ZERO_VERSION)))
02545   depth--;
02546     }
02547     OPERATOR oper = OPCODE_operator(opc);
02548     if ((OPERATOR_is_scalar_iload (oper) ||
02549   oper == OPR_ILOADX ||
02550   oper == OPR_PARM) && cr->Dtyp() != MTYPE_M)
02551       retv = Hash_Ivar(cr, depth);
02552     else {
02553       // OPR_MLOAD OPR_PREFETCH
02554       retv = Hash_New_ivar(cr);
02555     }
02556   }
02557 
02558   if (WOPT_Enable_Aggr_Pt_Keep_Track_Ptr) {
02559     POINTS_TO* pt = retv->Points_to(optstab);
02560 
02561     // If the "base is fixed", we don't want to set up the offset 
02562     // and CODEREP as indirectly access pointer. The reason is
02563     // twofolds: firstly, fixed base + offset is enough for memory 
02564     // disambiguation; secondly, the offset field of POINTS_TO
02565     // have different meaning when the base-is-fixed and when 
02566     // CODEREP is set as a indirect base for the POINTS_TO. 
02567     // For fortran cases, Add_idef() may be called upon some WNs 
02568     // whose POINTS_TO has fixed base. That is why we need 
02569     // condition "!pt->Base_is_fixed() to exclude this case. 
02570 
02571     if (pt && !pt->Base_is_fixed() && !pt->Pointer_is_coderep_id () 
02572         && !pt->Pointer_info_does_help()) {
02573       CODEREP* ptr = retv->Ilod_base() ? retv->Ilod_base() : retv->Istr_base();
02574       INT32 ofst = retv->Offset();   
02575       INT32 sz   = (MTYPE_size_min(retv->Dsctyp()) >> 3); // in bytes
02576       if (ptr->Kind() == CK_OP && ptr->Opr () == OPR_ADD) {
02577         if (ptr->Opnd(1)->Kind() == CK_CONST) {
02578           ofst += ptr->Opnd(1)->Const_val();
02579           ptr = ptr->Opnd(0);
02580         } else if (ptr->Opnd(0)->Kind() == CK_CONST) {
02581           ofst += ptr->Opnd(0)->Const_val();
02582           ptr = ptr->Opnd(1);
02583         }
02584       }
02585       pt->Set_pointer_as_coderep_id (ptr->Coderep_id());
02586       pt->Set_iofst_kind (OFST_IS_FIXED);
02587       pt->Set_byte_size (sz);
02588       pt->Set_byte_ofst (ofst);
02589     }
02590   }
02591 
02592   return retv;
02593 }
02594 
02595 /* CVTL-RELATED start (correctness) */
02596 // ====================================================================
02597 // Return a CODEREP with right sign extension
02598 // ====================================================================
02599 CODEREP *
02600 CODEREP::Var_type_conversion(CODEMAP *htable, MTYPE to_dtyp,
02601            MTYPE to_dsctyp, TY_IDX to_ty, UINT field_id)
02602 {
02603   Is_True(Kind() == CK_VAR, ("CODEREP::Var_type_conversion: not CK_VAR"));
02604   Is_True(to_dtyp != MTYPE_BS, ("CODEREP::Var_type_conversion: dtyp cannot be MTYPE_BS"));
02605 
02606   CODEREP * retval = this;
02607   if ( Is_flag_set(CF_MADEUP_TYPE) || Dsctyp() == MTYPE_UNKNOWN ) {
02608     // the type was made up by SSA, so change it
02609     Set_dtyp( to_dtyp );
02610     Set_dsctyp( to_dsctyp );
02611     Set_sign_extension_flag();
02612     Set_lod_ty( to_ty );
02613     Set_field_id (field_id);
02614     Reset_flag( CF_MADEUP_TYPE );
02615   } else {
02616 
02617     if (to_dsctyp != MTYPE_BS && Dsctyp() != MTYPE_BS) {
02618       if (MTYPE_size_min( Dsctyp() ) != MTYPE_size_min( to_dsctyp )) {
02619         Is_True(ST_class(htable->Opt_stab()->St(Aux_id())) == CLASS_PREG,
02620           ("CODEREP::Var_type_conversion: load from different dsc sizes"));
02621         DevWarn("CODEREP::Var_type_conversion: (fixed) loads of different size share aux_id %d",Aux_id());
02622   
02623         if ( MTYPE_size_min(to_dsctyp) > MTYPE_size_min(Dsctyp()) ) {
02624     Set_dsctyp( Mtype_TransferSign(Dsctyp(), to_dsctyp ) );
02625     Set_sign_extension_flag();
02626         } else {
02627     to_dsctyp = Mtype_TransferSign(to_dsctyp, Dsctyp());
02628         }
02629       }
02630     }
02631     else Is_True(to_dsctyp == Dsctyp(),
02632      ("CODEREP::Var_type_conversion: MTYPE_BS does not match"));
02633 
02634     BOOL is_sign_extd = Is_sign_extd();
02635     BOOL to_sign_extd = Sign_extended( to_dtyp, to_dsctyp );
02636 
02637 #ifdef Is_True_On
02638     Set_sign_extension_flag();
02639     Is_True(is_sign_extd == Is_sign_extd(),
02640       ("CODEREP::Var_type_conversion: inconsistent sign_extd flag"));
02641 #endif
02642 
02643 #if defined(TARG_X8664) || defined(TARG_NVISA) // bug 1561
02644     if (MTYPE_byte_size(to_dtyp) == 4 && MTYPE_byte_size(to_dsctyp) == 4) {
02645     } 
02646     else
02647 #endif
02648     if ( is_sign_extd != to_sign_extd ) {
02649       OPCODE opc;
02650       INT need_cvt =
02651   Need_load_type_conversion( is_sign_extd, to_sign_extd, 
02652           to_dtyp, to_dsctyp, &opc );
02653       Is_True(need_cvt != NOT_AT_ALL, 
02654         ("CODEREP::Var_type_conversion: type err"));
02655       CODEREP *new_cr = Alloc_stack_cr(0);
02656       IncUsecnt();
02657       new_cr->Init_expr( opc, this );
02658       if (need_cvt == NEED_CVTL) {
02659   if (to_dsctyp != MTYPE_BS)
02660     new_cr->Set_offset( MTYPE_size_min( to_dsctyp ) );
02661   else {
02662     UINT cur_field_id = 0;
02663     UINT64 field_offset = 0;
02664     FLD_HANDLE fld = FLD_And_Offset_From_Field_Id(to_ty, field_id,
02665             cur_field_id, field_offset);
02666     new_cr->Set_offset(FLD_bsize(fld));
02667         }
02668       }
02669       retval = htable->Hash_Op( new_cr );
02670     }
02671   }
02672   
02673 #ifdef KEY
02674   retval = retval->Fixup_type(to_dtyp, htable);
02675 #endif
02676 
02677   return retval;
02678 }
02679 /* CVTL-RELATED finish */
02680 
02681 CODEREP *
02682 CODEMAP::Cur_def(WN *wn, OPT_STAB *opt_stab)
02683 {
02684   IDTYPE du     = WN_ver(wn);
02685   FmtAssert(du != 0,
02686       ("CODEMAP::Cur_def: WN_st wasn't set correctly"));
02687 
02688   MTYPE  dtyp   = WN_rtype( wn );
02689   MTYPE  dsctyp = WN_desc( wn );
02690   TY_IDX ty     = WN_ty( wn );
02691 
02692   CODEREP *retv = opt_stab->Du_coderep( du );
02693   if ( retv == NULL ) {
02694     retv = Add_def(opt_stab->Du_aux_id( du ),
02695        opt_stab->Du_version( du ),
02696        NULL/*stmtrep*/,
02697        dtyp,
02698        dsctyp,
02699        WN_offset(wn),
02700        ty,
02701        WN_field_id(wn),
02702        FALSE);
02703     CODEREP *retv_var = ( retv->Kind() == CK_VAR ) ? retv : retv->Opnd(0);
02704     retv_var->Set_lod_ty( ty ) ;
02705     if ( opt_stab->Du_is_volatile( du ) ) { 
02706       // set the volatile attribute for this var, even if this
02707       // particular reference is not cast as volatile
02708       retv_var->Set_var_volatile();
02709     }
02710     else {
02711       // only cache non-volatile codereps
02712       opt_stab->Du_set_coderep( du, retv_var );
02713     }
02714   }
02715   else { 
02716     // cached value should not be a volatile
02717     Is_True( ! retv->Is_var_volatile() &&
02718              ! opt_stab->Du_is_volatile( du ),
02719       ("CODEMAP::Cur_def: Cached volatile reference [%3d]", retv->Aux_id()) );
02720 
02721 #ifdef KEY // bug 9656 Comment 2
02722     if (retv->Field_id() == 0 && WN_field_id(wn) != 0) {
02723       retv->Set_field_id(WN_field_id(wn));
02724       retv->Set_lod_ty(WN_ty(wn));
02725     }
02726 #endif
02727 
02728     /* CVTL-RELATED start (correctness) */
02729     // change {I,U}4{I,U}8LDID to {I,U}4{I,U}8CVT({I,U}8{I,U}8LDID)
02730     // (truncation)
02731     if (dsctyp != MTYPE_BS &&
02732   MTYPE_is_integral(dtyp) && MTYPE_is_integral(dsctyp) &&
02733   MTYPE_size_min(dsctyp) > MTYPE_size_min(dtyp)) {
02734       Is_True(MTYPE_size_min(dtyp) == MTYPE_size_min(MTYPE_I4),
02735         ("CODEMAP::Add_def: unexpected type"));
02736       retv = retv->Var_type_conversion(this, dsctyp, dsctyp, ty, WN_field_id(wn));
02737 
02738       CODEREP *new_cr = Alloc_stack_cr(0);
02739       OPCODE   opc; 
02740       INT      need_cvt = Need_type_conversion(dsctyp, dtyp, &opc);
02741 
02742       Is_True(need_cvt == NEED_CVT,("CODEMAP::Cur_def: type err"));
02743 
02744       retv->IncUsecnt();
02745       new_cr->Init_expr( opc, retv );
02746       retv = Hash_Op( new_cr );
02747 
02748     } else {
02749       retv = retv->Var_type_conversion(this, dtyp, dsctyp, ty, WN_field_id(wn));
02750       if (dsctyp == MTYPE_BS) {
02751   CODEREP *v = retv;
02752   if (v->Kind() == CK_OP) 
02753     v = v->Opnd(0);  // skip the CVTL inserted earlier
02754   // these fields could be wrong because there was no real node to look
02755   // at earlier, so fix them here
02756   v->Set_lod_ty(ty);
02757   v->Set_field_id(WN_field_id(wn));
02758   v->Set_offset(WN_offset(wn));
02759       }
02760     }
02761     /* CVTL-RELATED finish */
02762 
02763   }
02764 
02765   return retv;
02766 }
02767 
02768 // ====================================================================
02769 // Convert a TCON value into a coderep
02770 // ====================================================================
02771 
02772 CODEREP *
02773 CODEMAP::Add_tcon(TCON_IDX tc)
02774 {
02775   CODEREP *cr = Alloc_stack_cr(0);
02776   MTYPE mtype = TCON_ty(Tcon_Table[tc]);
02777 
02778   switch ( mtype ) {
02779     case MTYPE_B:
02780     case MTYPE_I1:
02781     case MTYPE_I2:
02782     case MTYPE_I4:
02783     case MTYPE_I8:
02784     case MTYPE_U1:
02785     case MTYPE_U2:
02786     case MTYPE_U4:
02787     case MTYPE_U8:
02788       cr->Init_const(mtype, Targ_To_Host(Tcon_Table[tc]));
02789       return Hash_Const(cr);
02790 
02791     case MTYPE_F4:
02792     case MTYPE_F8:
02793 #if defined(TARG_IA64)
02794     case MTYPE_F10:
02795     case MTYPE_C10:
02796 #endif
02797     case MTYPE_FQ:
02798     case MTYPE_C4:
02799     case MTYPE_C8:
02800     case MTYPE_CQ:
02801       {
02802         ST *new_sym = New_Const_Sym(tc, MTYPE_To_TY(mtype));
02803   cr->Init_rconst(mtype, new_sym);
02804       }
02805       return Hash_Rconst(cr);
02806     
02807     default:
02808       FmtAssert( FALSE,
02809   ("CODEMAP::Add_tcon: unexpected tcon type: %s",
02810    Mtype_Name(mtype)) );
02811       return NULL;
02812   }
02813 }
02814 
02815 // ====================================================================
02816 // wn is an ILOAD node whose base is an LDA; if it can be folded to an
02817 // LDID, do the folding and return the CK_VAR node; otherwise, return NULL
02818 // ====================================================================
02819 CODEREP *
02820 CODEMAP::Iload_folded(WN *wn,       // the iload node
02821           CANON_CR *base_ccr) // gives the LDA info
02822 {
02823   const OPCODE op = WN_opcode(wn);
02824   const OPERATOR opr = OPCODE_operator(op);
02825   CODEREP *retv;
02826   MU_NODE *mnode = Sym()->Get_mem_mu_node(wn);
02827   Is_True(mnode != NULL && mnode->Opnd() != 0, ("empty mu list at ILOAD"));
02828   // mu list only has its own virtual var; use virtual var to get to 
02829   // defstmt to look at the chi list
02830   AUX_ID vaux = Sym()->Du_aux_id(mnode->Opnd());
02831   
02832   CODEREP *vsymcr = Sym()->Du_coderep(mnode->Opnd());
02833   if ( vsymcr == NULL )
02834     return NULL;
02835 
02836   STMTREP *dstmt = vsymcr->Defstmt();
02837   if (dstmt != NULL) {
02838     // go thru chi list to find the scalar var version
02839     CHI_NODE *cnode;
02840     CHI_LIST_ITER chi_iter;
02841     FOR_ALL_NODE(cnode, chi_iter, Init(dstmt->Chi_list())) {
02842       vaux = cnode->Aux_id();
02843       if (!Sym()->Is_real_var(vaux))
02844         continue;
02845       INT64 v_ofst;
02846       ST *v_st;
02847       Expand_ST_into_base_and_ofst(Sym()->St(vaux), 
02848            Sym()->St_ofst(vaux), &v_st, &v_ofst);
02849       if (v_st == base_ccr->Tree()->Lda_base_st() &&
02850     v_ofst == base_ccr->Scale() && 
02851     0 == base_ccr->Tree()->Offset() && // TODO: not needed if canonicalize in preopt
02852     Sym()->Aux_stab_entry(vaux)->Mclass() == 
02853       Get_mtype_class(OPCODE_rtype(op)) &&
02854     Sym()->Aux_stab_entry(vaux)->Byte_size() * 8 == 
02855       MTYPE_size_min(OPCODE_desc(op)) &&
02856     (opr == OPR_ILOAD && Sym()->Aux_stab_entry(vaux)->Bit_size() == 0 ||
02857      OPCODE_desc(op) == MTYPE_BS && 
02858      WN_field_id(wn) == Sym()->Field_id(vaux) ||
02859      opr == OPR_ILDBITS && 
02860      Sym()->Aux_stab_entry(vaux)->Bit_ofst() == WN_bit_offset(wn) &&
02861      Sym()->Aux_stab_entry(vaux)->Bit_size() == WN_bit_size(wn))) {
02862         base_ccr->Tree()->DecUsecnt();  // for the LDA coderep
02863   _ssa->Value_number_mu_node(Sym()->Get_mem_mu_node(wn));
02864   if (! cnode->Live()) {
02865     _ssa->Resurrect_chi(cnode);
02866           cnode->RESULT()->Set_defstmt(dstmt);
02867   }
02868         retv = cnode->RESULT();
02869 
02870   if (retv->Is_flag_set(CF_IS_ZERO_VERSION)) {
02871     // create new coderep when it's the zero version
02872     retv = Add_def(vaux,
02873        0/*dummy*/,
02874        dstmt, // use the defstmt of this chi 
02875        OPCODE_rtype(op),
02876        OPCODE_desc(op),
02877        Sym()->St_ofst(vaux)/*base_ccr->Scale()*/,
02878        TY_pointed(WN_load_addr_ty(wn)), WN_field_id(wn),TRUE);
02879     retv->Set_flag(CF_DEF_BY_CHI);
02880     retv->Set_flag(CF_INCOMPLETE_USES);
02881     retv->Set_defchi(cnode);
02882     cnode->Set_RESULT(retv);  // change the chi to point to this
02883     dstmt->Recompute_has_zver();
02884     // make new node the current version 
02885     Sym()->Pop_coderep(vaux);
02886     Sym()->Push_coderep(vaux, retv);
02887   }
02888   goto return_pt;
02889       }
02890     }
02891 
02892     // check if dstmt is actually the matching STID 
02893     retv = dstmt->Lhs();
02894     if (retv != NULL && retv->Kind() == CK_VAR) {
02895       INT64 v_ofst;
02896       ST *v_st;
02897       Expand_ST_into_base_and_ofst(Sym()->St(retv->Aux_id()),
02898            Sym()->St_ofst(retv->Aux_id()), &v_st, &v_ofst);
02899 
02900       if (v_st == base_ccr->Tree()->Lda_base_st() &&
02901     v_ofst == base_ccr->Scale() &&
02902     0 == base_ccr->Tree()->Offset() && // TODO: not needed if canonicalize in preopt
02903     Get_mtype_class(retv->Dtyp()) == Get_mtype_class(OPCODE_rtype(op)) &&
02904     MTYPE_size_min(retv->Dsctyp()) == MTYPE_size_min(OPCODE_desc(op)) &&
02905 #ifdef KEY
02906     (OPCODE_rtype(op) != MTYPE_M || TY_size(WN_ty(wn)) == TY_size(retv->Lod_ty())) &&
02907 #endif
02908     (opr == OPR_ILOAD && ! retv->Bit_field_valid() &&
02909      (WN_desc(wn) != MTYPE_BS && retv->Dsctyp() != MTYPE_BS ||
02910       WN_desc(wn) == MTYPE_BS && WN_field_id(wn) == retv->Field_id()) ||
02911      opr == OPR_ILDBITS && retv->Bit_field_valid() &&
02912      retv->Bit_offset() == WN_bit_offset(wn) &&
02913      retv->Bit_size() == WN_bit_size(wn))) {
02914   base_ccr->Tree()->DecUsecnt();  // for the LDA coderep
02915   _ssa->Value_number_mu_node(Sym()->Get_mem_mu_node(wn));
02916   goto return_pt;
02917       }
02918     }
02919   }
02920   else if (vsymcr->Is_flag_set(CF_DEF_BY_PHI)) {
02921     // go thru phi list to find the scalar var version
02922     PHI_LIST_ITER phi_iter;
02923     PHI_NODE *phi;
02924     FOR_ALL_ELEM(phi, phi_iter, Init(vsymcr->Defphi()->Bb()->Phi_list())) {
02925       vaux = phi->Aux_id();
02926       if (!Sym()->Is_real_var(vaux))
02927   continue;
02928       INT64 v_ofst;
02929       ST *v_st;
02930       Expand_ST_into_base_and_ofst(Sym()->St(vaux), 
02931            Sym()->St_ofst(vaux), &v_st, &v_ofst);
02932       if (v_st == base_ccr->Tree()->Lda_base_st() &&
02933     v_ofst == base_ccr->Scale() && 
02934     0 == base_ccr->Tree()->Offset() && // TODO: not needed if canonicalize in preopt
02935     Sym()->Aux_stab_entry(vaux)->Mclass() == 
02936       Get_mtype_class(OPCODE_rtype(op)) &&
02937     Sym()->Aux_stab_entry(vaux)->Byte_size() * 8 ==
02938       MTYPE_size_min(OPCODE_desc(op)) &&
02939     (opr == OPR_ILOAD && Sym()->Aux_stab_entry(vaux)->Bit_size() == 0 ||
02940      OPCODE_desc(op) == MTYPE_BS && 
02941      WN_field_id(wn) == Sym()->Field_id(vaux) ||
02942      opr == OPR_ILDBITS && 
02943      Sym()->Aux_stab_entry(vaux)->Bit_ofst() == WN_bit_offset(wn) &&
02944      Sym()->Aux_stab_entry(vaux)->Bit_size() == WN_bit_size(wn))) {
02945         base_ccr->Tree()->DecUsecnt();  // for the LDA coderep
02946   _ssa->Value_number_mu_node(Sym()->Get_mem_mu_node(wn));
02947   if (! phi->Live()) 
02948     _ssa->Resurrect_phi(phi);
02949         retv = phi->RESULT();
02950   
02951   if (retv->Is_flag_set(CF_IS_ZERO_VERSION)) {
02952     // create new coderep when it's the zero version
02953     retv = Add_def(vaux,
02954        0/*dummy*/,
02955        dstmt, // use the defstmt of this chi 
02956        OPCODE_rtype(op),
02957        OPCODE_desc(op),
02958        Sym()->St_ofst(vaux)/*base_ccr->Scale()*/,
02959        TY_pointed(WN_load_addr_ty(wn)), WN_field_id(wn),TRUE);
02960     retv->Set_flag(CF_DEF_BY_PHI);
02961     retv->Set_defphi(phi);
02962     retv->Set_flag(CF_INCOMPLETE_USES);
02963     // make new node the current version 
02964     Sym()->Pop_coderep(vaux);
02965     Sym()->Push_coderep(vaux, retv);
02966     phi->Set_result(retv);  // change the phi to point to this
02967   }
02968   goto return_pt;
02969       }
02970     }
02971   }
02972   return NULL;
02973 
02974  return_pt:
02975   // insert necessary type conversion
02976   {
02977     /* CVTL-RELATED start (correctness) */
02978     retv = retv->Var_type_conversion(this, OPCODE_rtype(op),
02979              OPCODE_desc(op), WN_ty(wn),
02980              WN_field_id(wn));
02981     /* CVTL-RELATED finish */
02982     retv->Set_flag(CF_FOLDED_LDID); // hint for coloring
02983     retv->IncUsecnt();
02984     _num_iloadfolds++;
02985     return retv;
02986   }
02987 
02988 }
02989 
02990 // update the prefetch record
02991 void
02992 CODEMAP::Update_pref(CODEREP *ivar) const
02993 {
02994   PF_POINTER *pf = ivar->Ivar_occ()->Pf_pointer();
02995   if (pf != NULL) {
02996     if (VISITED_CM(pf)) return;
02997     WN      *pref_wn;
02998     STMTREP *pref_stmt;
02999     if ((pref_wn = PF_PTR_wn_pref_1L(pf)) != NULL) {
03000       pref_stmt = (STMTREP*) WN_MAP_Get(_prefetch_map, pref_wn);
03001       // Once LNO starts processing pragma and olimit regions, the else
03002       // part is all that is required here. (put in an Is_True(!pref_stmt))
03003       if (pref_stmt == NULL) {
03004   DevWarn("532176, 457243, LNO is introducing cross-region prefetches");
03005   PF_PTR_wn_pref_1L(pf) = (WN *) NULL;
03006       } else
03007   PF_PTR_wn_pref_1L(pf) = (WN *) pref_stmt;
03008     }
03009     if ((pref_wn = PF_PTR_wn_pref_2L(pf)) != NULL) {
03010       pref_stmt = (STMTREP*) WN_MAP_Get(_prefetch_map, pref_wn);
03011       // Once LNO starts processing pragma and olimit regions, the else
03012       // part is all that is required here. (put in an Is_True(!pref_stmt))
03013       if (pref_stmt == NULL) {
03014   DevWarn("532176, 457243, LNO is introducing cross-region prefetches");
03015   PF_PTR_wn_pref_2L(pf) = (WN *) NULL;
03016       } else
03017   PF_PTR_wn_pref_2L(pf) = (WN *) pref_stmt;
03018     }
03019     SET_VISITED_CM(pf);
03020   }
03021 }
03022 
03023 // ====================================================================
03024 // This overloaded member function recursively traverse the WN tree
03025 // and build the CODEREP bottom up in the canonical form.  During this
03026 // process, the constant part of the tree and the rest of the tree are
03027 // kept in the CANON_CR object.  The return value tells if something 
03028 // within the tree has been replaced due to copy propagation, so that
03029 // the parent would call the simplifier for the entire tree.
03030 // 
03031 // For no_complex_preg, see opt_prop.cxx's bug 10577 fixes.
03032 // ====================================================================
03033 BOOL
03034 CODEMAP::Add_expr(WN *wn, OPT_STAB *opt_stab, STMTREP *stmt, CANON_CR *ccr,
03035       COPYPROP *copyprop, BOOL no_complex_preg)
03036 {
03037   // given a WN node, add it to the coderep hash and return the
03038   // coderep for it.
03039   CODEREP          *cr = Alloc_stack_cr(WN_kid_count(wn)+IVAR_EXTRA_NODE_CNT);
03040   CODEREP          *retv;
03041   const OPCODE      op = WN_opcode(wn);
03042   const OPERATOR    oper = WN_operator(wn);
03043   BOOL  propagated = FALSE;
03044 
03045   FmtAssert (OPCODE_is_expression(op) || OPCODE_is_fake(op),
03046        ("CODEMAP::Hash: opcode %s is not an expression",OPCODE_name(op)));
03047 
03048   if (OPCODE_is_leaf(op)) {
03049     if (OPERATOR_is_scalar_load (oper)) {
03050       retv = Cur_def(wn, opt_stab);
03051       Is_True(retv->Kind()==CK_VAR || (retv->Kind()==CK_OP
03052                && (retv->Opr()==OPR_CVT ||
03053              retv->Opr()==OPR_CVTL)),
03054         ("CODEMAP::Add_expr: return illegal cr from Cur_def"));
03055       CODEREP * retv_var = retv;
03056       while (retv_var->Kind() != CK_VAR) 
03057   retv_var = retv_var->Opnd(0);
03058       if (retv_var->Is_var_volatile())
03059   stmt->Set_volatile_stmt();
03060       if (opt_stab->NULL_coderep(retv_var->Aux_id()))
03061         opt_stab->Push_coderep(retv_var->Aux_id(), retv_var);
03062 
03063       retv->IncUsecnt();
03064       if (WOPT_Enable_Input_Prop && !copyprop->Disabled()) {
03065         CODEREP *newtree = copyprop->Prop_var(retv_var, stmt->Bb(), TRUE, TRUE,TRUE/*in_array*/, no_complex_preg);
03066         if (newtree) {
03067     if (retv->Kind() == CK_VAR) 
03068       retv = newtree;
03069     else {
03070       CODEREP *cr = Alloc_stack_cr(0);
03071       newtree->IncUsecnt();
03072       cr->Init_expr(retv->Op(), newtree);
03073       if (retv->Opr() == OPR_CVTL) cr->Set_offset(retv->Offset());
03074 
03075             if (newtree->Kind() == CK_CONST) {
03076         FOLD ftmp;
03077         CODEREP *crtmp = ftmp.Fold_Expr(cr);
03078         if (crtmp != NULL) 
03079     retv = Hash_Const(crtmp);
03080         else
03081     retv = Hash_Op(cr);
03082       }
03083             else
03084               retv = Hash_Op(cr);
03085           }
03086           if (retv->Kind() == CK_CONST) {
03087       retv->DecUsecnt();
03088             ccr->Set_tree(NULL);
03089             ccr->Set_scale(retv->Const_val());
03090             return TRUE;
03091           }
03092 
03093           if (retv->Kind() == CK_OP) {
03094             // if CRSIMP flag is turned on, the opr is +,-,
03095             // and the kid1 is a constant, pull the constant out.
03096             OPERATOR opr = retv->Opr();
03097             CODEREP *retv_op = retv;
03098 #ifdef TARG_NVISA
03099             // may have CVT of ADD/SUB, so look under the CVT;
03100             // but then need to move cvt to non-const operand.
03101             // but only do this if integer cvt and op under cvt
03102             if (opr == OPR_CVT
03103               && MTYPE_is_integral(retv->Dtyp())
03104               && MTYPE_is_integral(retv->Dsctyp())
03105               && retv->Opnd(0)->Kind() == CK_OP)
03106             {
03107               retv_op = retv->Opnd(0);
03108               opr = retv_op->Opr();
03109             }
03110 #endif
03111             if (WOPT_Enable_CRSIMP &&
03112                 (opr == OPR_ADD || opr == OPR_SUB) &&
03113                 retv_op->Get_opnd(1)->Kind() == CK_CONST) {
03114                   CODEREP *cr = retv_op->Get_opnd(0);
03115 #ifdef TARG_NVISA
03116                   if (retv->Opr() == OPR_CVT) {
03117                     // need to preserve cvt
03118                     // changing CVT(ADD(x,c)) to scale(CVT(x),c)
03119                     DevWarn("pull out constant when cvt(add)");
03120                     cr = retv;
03121                     cr->Set_opnd(0, retv_op->Get_opnd(0));
03122                     cr = Hash_Op(cr); // need to rehash when changing node
03123                   }
03124 #endif
03125                   cr->DecUsecnt();
03126                   ccr->Set_tree(cr);
03127                   cr = retv_op->Get_opnd(1);
03128                   cr->DecUsecnt();
03129                   if (opr == OPR_SUB)
03130                     ccr->Set_scale(0 - cr->Const_val());
03131                   else
03132                     ccr->Set_scale(cr->Const_val());
03133                   return TRUE;
03134                 }
03135     } // if (retv->Kind() == CK_OP)
03136   }
03137       }
03138       if ((Split_64_Bit_Int_Ops || Only_Unsigned_64_Bit_Ops) &&
03139     MTYPE_is_integral(retv->Dtyp()) &&
03140     MTYPE_size_min(retv->Dtyp()) < MTYPE_size_min(WN_rtype(wn))) {
03141   retv = Add_unary_node(OPCODE_make_op(OPR_CVT, WN_rtype(wn), 
03142        Mtype_TransferSize(retv->Dtyp(), WN_rtype(wn))), retv);
03143       }
03144       ccr->Set_tree(retv);
03145       ccr->Set_scale(0);
03146       if (WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()) {
03147         MEMOP_ANNOT* annot = WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()->Get_annot (wn);
03148         if (annot) { opt_stab->Cr_sr_annot_mgr()->Import_annot (retv, annot); }
03149       }
03150       return TRUE;
03151     }
03152     else if (oper == OPR_LDA) {
03153       INT64 ofst;
03154       ST *lda_st;
03155       ST *wn_st = opt_stab->St(WN_aux(wn));
03156       if (_phase == MAINOPT_PHASE &&
03157           (! opt_stab->Is_up_level_var(wn_st) || WOPT_Enable_Canon_Uplevel)) {
03158   Expand_ST_into_base_and_ofst(wn_st,
03159              opt_stab->St_ofst(WN_aux(wn)), &lda_st, &ofst);
03160         ccr->Set_scale(ofst);
03161         ofst = 0;
03162       } else {
03163   lda_st = opt_stab->St(WN_aux(wn));
03164   ofst = opt_stab->St_ofst(WN_aux(wn));
03165         ccr->Set_scale(0);
03166       }
03167   
03168       Is_True(opt_stab->Base(WN_aux(wn)) != NULL, ("base st is null."));
03169       cr->Init_lda(OPCODE_rtype(op), WN_aux(wn), 
03170        (INT32)ofst, (TY_IDX) WN_ty(wn), lda_st, WN_field_id(wn));
03171 #ifdef TARG_SL2
03172       if(WN_is_internal_mem_ofst(wn)) {
03173         cr->Set_flag(CF_INTERNAL_MEM_OFFSET);
03174       }
03175 #endif 
03176       retv = Hash_Lda(cr);
03177       ccr->Set_tree(retv);
03178       return FALSE;
03179     }
03180     else if (oper == OPR_LDA_LABEL) {
03181       cr->Init_lda(WN_rtype(wn), (IDTYPE) 0, WN_label_number(wn), 
03182        (TY_IDX) WN_ty(wn), NULL);
03183       cr->Set_flag(CF_LDA_LABEL);
03184       retv = Hash_Lda(cr);
03185       ccr->Set_tree(retv);
03186       ccr->Set_scale(0);
03187       return FALSE;
03188     }
03189     else if (oper == OPR_INTCONST) {
03190       ccr->Set_tree(NULL);
03191       ccr->Set_scale(WN_get_const_val(wn));
03192       return FALSE;
03193     }
03194     else if (oper == OPR_CONST) {
03195       cr->Init_rconst(OPCODE_rtype(op), WN_sym(wn));
03196       retv = Hash_Rconst(cr);
03197       ccr->Set_tree(retv);
03198       ccr->Set_scale(0);
03199       return FALSE;
03200     }
03201     else {
03202       FmtAssert(FALSE,("CODEMAP::Add_expr: leaf opcode %s is not handled",
03203            OPCODE_name(op)));
03204       return FALSE;
03205     }
03206   }
03207   else if (OPERATOR_is_scalar_iload (oper) && oper != OPR_ILOADX) {
03208     CANON_CR base_ccr;
03209     Add_expr(WN_kid(wn, 0), opt_stab, stmt, &base_ccr, copyprop);
03210     base_ccr.Set_scale(base_ccr.Scale() + WN_offset(wn));
03211     base_ccr.Trim_to_16bits(WN_kid(wn, 0), this);
03212     if (base_ccr.Tree() != NULL &&
03213   base_ccr.Tree()->Kind() == CK_LDA )
03214     {
03215       {
03216   // is the result of the load volatile?
03217   if (Lod_TY_is_volatile(WN_ty(wn))) 
03218     goto no_fold_iload;
03219 
03220       // see if we point at a volatile object
03221   TY_IDX load_addr_ty = WN_load_addr_ty(wn);
03222   if (TY_is_volatile(load_addr_ty))
03223     goto no_fold_iload;
03224 
03225       // may point to a volatile object
03226   TY_IDX pointed = TY_pointed(load_addr_ty);
03227   if (TY_is_volatile(pointed))
03228     goto no_fold_iload;
03229 
03230       // fold to LDID
03231   if (retv = Iload_folded(wn, &base_ccr)) {
03232     if ((Split_64_Bit_Int_Ops || Only_Unsigned_64_Bit_Ops) &&
03233         MTYPE_is_integral(retv->Dtyp()) &&
03234         MTYPE_size_min(retv->Dtyp()) < MTYPE_size_min(WN_rtype(wn))) {
03235       retv = Add_unary_node(OPCODE_make_op(OPR_CVT, WN_rtype(wn), 
03236            Mtype_TransferSize(retv->Dtyp(), WN_rtype(wn))), retv);
03237     }
03238     ccr->Set_tree(retv);
03239     ccr->Set_scale(0);
03240     return FALSE;
03241   }
03242       }
03243 
03244       // jump here if we're not going to fold
03245       no_fold_iload: ;
03246     }
03247 
03248     // In IA-64, ILOAD should have zero offset
03249     if (! Use_Load_Store_Offset && base_ccr.Scale() != 0) {
03250       MTYPE typ = WN_rtype(WN_kid(wn, 0));
03251       CODEREP *retv = Add_const(typ, base_ccr.Scale());
03252       if (base_ccr.Tree() != NULL)
03253   retv = Add_bin_node(OPCODE_make_op(OPR_ADD, typ, MTYPE_V),
03254           base_ccr.Tree(), retv);
03255       base_ccr.Set_tree(retv);
03256       base_ccr.Set_scale(0);
03257     }
03258 
03259     _ssa->Value_number_mu_node(opt_stab->Get_mem_mu_node(wn));
03260     CODEREP *lbase = base_ccr.Tree() ? base_ccr.Tree() : Add_const(Pointer_type,(INT64)0);
03261     retv = Add_idef(op, opt_stab->Get_occ(wn), NULL,
03262         opt_stab->Get_mem_mu_node(wn), WN_rtype(wn),
03263         WN_desc(wn), WN_ty(wn), WN_field_id(wn),
03264         base_ccr.Scale(), (CODEREP *)(INTPTR) WN_load_addr_ty(wn),
03265         lbase, NULL, opt_stab);
03266 #if defined(TARG_SL)
03267     // vbuf stuff, it is really a relative offset from vbuf base
03268     if (WN_is_internal_mem_ofst(wn))
03269       retv->Set_flag(CF_INTERNAL_MEM_OFFSET);
03270 #endif 
03271     Is_True(retv->Kind()==CK_IVAR || (retv->Kind()==CK_OP
03272               && (retv->Opr()==OPR_CVT ||
03273             retv->Opr()==OPR_CVTL)),
03274       ("CODEMAP::Add_expr: return illegal cr from Add_idef"));
03275     CODEREP *retv_ivar = (retv->Kind()==CK_IVAR) ? retv : retv->Opnd(0);
03276     if (retv_ivar->Is_ivar_volatile()) 
03277       stmt->Set_volatile_stmt();
03278     Update_pref(retv_ivar);
03279     if (WOPT_Enable_Input_Prop) {
03280       CODEREP *newtree = copyprop->Prop_ivar(retv_ivar, stmt->Bb(), TRUE, TRUE,TRUE/*in_array*/, no_complex_preg);
03281       if (newtree) {
03282   if (retv->Kind()==CK_IVAR)
03283     retv = newtree;
03284   else {
03285     CODEREP *cr = Alloc_stack_cr(0);
03286     newtree->IncUsecnt();
03287     cr->Init_expr(retv->Op(), newtree);
03288     if (retv->Opr() == OPR_CVTL) cr->Set_offset(retv->Offset());
03289     retv = Hash_Op(cr);
03290   }
03291     
03292         if (newtree->Kind() == CK_CONST) {
03293     if (retv->Kind() != CK_IVAR) {
03294       FOLD ftmp;
03295       CODEREP *crtmp = ftmp.Fold_Expr(retv);
03296       if (crtmp != NULL) retv = Hash_Const(crtmp);
03297     }
03298 #ifdef KEY // bug 3054
03299     if (retv->Kind() == CK_CONST) {
03300 #endif
03301     retv->DecUsecnt();
03302     ccr->Set_tree(NULL);
03303     ccr->Set_scale(retv->Const_val());
03304     return TRUE;
03305 #ifdef KEY // bug 3054
03306     }
03307 #endif
03308         }
03309   if (retv->Kind() == CK_OP) {
03310     // if CRSIMP flag is turned on, the opr is +,-,
03311     // and the kid1 is a constant, pull the constant out.
03312     const OPERATOR opr = retv->Opr();
03313     if (WOPT_Enable_CRSIMP &&
03314         (opr == OPR_ADD || opr == OPR_SUB) &&
03315         retv->Get_opnd(1)->Kind() == CK_CONST) {
03316     CODEREP *cr = retv->Get_opnd(0);
03317     cr->DecUsecnt();
03318     ccr->Set_tree(cr);
03319     cr = retv->Get_opnd(1);
03320     cr->DecUsecnt();
03321     if (opr == OPR_SUB)
03322       ccr->Set_scale(0 - cr->Const_val());
03323     else
03324       ccr->Set_scale(cr->Const_val());
03325     return TRUE;
03326         }
03327   } // if (retv->Kind() == CK_OP)
03328       }
03329       if ((Split_64_Bit_Int_Ops || Only_Unsigned_64_Bit_Ops) &&
03330     MTYPE_is_integral(retv->Dtyp()) &&
03331     MTYPE_size_min(retv->Dtyp()) < MTYPE_size_min(WN_rtype(wn))) {
03332         retv = Add_unary_node(OPCODE_make_op(OPR_CVT, WN_rtype(wn), 
03333              Mtype_TransferSize(retv->Dtyp(), WN_rtype(wn))), retv);
03334       }
03335       ccr->Set_tree(retv);
03336       ccr->Set_scale(0);
03337       return TRUE;
03338     }
03339     if ((Split_64_Bit_Int_Ops || Only_Unsigned_64_Bit_Ops) &&
03340         MTYPE_is_integral(retv->Dtyp()) &&
03341         MTYPE_size_min(retv->Dtyp()) < MTYPE_size_min(WN_rtype(wn))) {
03342       retv = Add_unary_node(OPCODE_make_op(OPR_CVT, WN_rtype(wn), 
03343            Mtype_TransferSize(retv->Dtyp(), WN_rtype(wn))), retv);
03344     }
03345     ccr->Set_tree(retv);
03346     ccr->Set_scale(0);
03347 
03348     if (WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()) {
03349       MEMOP_ANNOT* annot = WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()->Get_annot (wn);
03350       if (annot) { opt_stab->Cr_sr_annot_mgr()->Import_annot (retv, annot); }
03351     }
03352 
03353     return FALSE;
03354   }
03355   else if (oper == OPR_ILOADX) {
03356     Is_True(FALSE, ("CODEMAP::Add_expr: should never see OPR_ILOADX"));
03357     CODEREP *base = Add_expr(WN_kid(wn, 0), opt_stab, stmt, &propagated, 
03358         copyprop);
03359     CODEREP *index = Add_expr(WN_kid(wn, 1), opt_stab, stmt, &propagated,
03360         copyprop);
03361     _ssa->Value_number_mu_node(opt_stab->Get_mem_mu_node(wn));
03362     retv = Add_idef(op, opt_stab->Get_occ(wn), NULL,
03363         opt_stab->Get_mem_mu_node(wn), WN_rtype(wn),
03364         WN_desc(wn), WN_ty(wn), WN_field_id(wn),
03365         (mINT32)(INTPTR)index, (CODEREP *)(INTPTR) WN_load_addr_ty(wn), 
03366                base, NULL, opt_stab);
03367     Is_True(retv->Kind()==CK_IVAR||(retv->Kind()==CK_OP
03368             && (retv->Opr()==OPR_CVT ||
03369           retv->Opr()==OPR_CVTL)),
03370       ("CODEMAP::Add_expr: return illegal cr from Add_idef"));
03371     CODEREP *retv_ivar = (retv->Kind()==CK_IVAR) ? retv : retv->Opnd(0);
03372     if (retv_ivar->Is_ivar_volatile())
03373       stmt->Set_volatile_stmt();
03374     ccr->Set_tree(retv);
03375     ccr->Set_scale(0);
03376 
03377     if (WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()) {
03378       MEMOP_ANNOT* annot = WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()->Get_annot (wn);
03379       if (annot) { opt_stab->Cr_sr_annot_mgr()->Import_annot (retv, annot); }
03380     }
03381     return FALSE;
03382   }
03383   else if (oper == OPR_MLOAD) {
03384     CANON_CR base_ccr;
03385     Add_expr(WN_kid(wn, 0), opt_stab, stmt, &base_ccr, copyprop);
03386     CODEREP *num_byte = Add_expr(WN_kid(wn, 1), opt_stab, stmt,
03387          &propagated, copyprop);
03388     _ssa->Value_number_mu_node(opt_stab->Get_mem_mu_node(wn));
03389     base_ccr.Set_scale(base_ccr.Scale() + WN_offset(wn));
03390     base_ccr.Trim_to_16bits(WN_kid(wn, 0), this);
03391 
03392     // In IA-64, MLOAD should have zero offset
03393     if (! Use_Load_Store_Offset && base_ccr.Scale() != 0) {
03394       MTYPE typ = WN_rtype(WN_kid(wn, 0));
03395       CODEREP *retv = Add_const(typ, base_ccr.Scale());
03396       if (base_ccr.Tree() != NULL)
03397   retv = Add_bin_node(OPCODE_make_op(OPR_ADD, typ, MTYPE_V),
03398           base_ccr.Tree(), retv);
03399       base_ccr.Set_tree(retv);
03400       base_ccr.Set_scale(0);
03401     }
03402 
03403     CODEREP *lbase = base_ccr.Tree() ? base_ccr.Tree() :
03404                    Add_const(Pointer_type, (INT64) 0);
03405 #if !(defined(linux) || defined(BUILD_OS_DARWIN))
03406     FmtAssert(sizeof(num_byte) == sizeof(TY_IDX),
03407         ("CODEMAP::Add_expr: Cannot union MLOAD size with "
03408          "Ilod_base_ty"));
03409 #endif /* linux */
03410     retv = Add_idef(op, opt_stab->Get_occ(wn), NULL,
03411         opt_stab->Get_mem_mu_node(wn),
03412         WN_rtype(wn),
03413         WN_desc(wn),
03414         WN_ty(wn), WN_field_id(wn), base_ccr.Scale(),
03415         // num_byte in the following line is correct. See
03416         // opt_htable.h, where the MLOAD/MSTORE size is
03417         // unioned with the Ilod_base_ty. The only thing
03418         // we need to check here is that we don't lose
03419         // information (see the assertion preceding this
03420         // Add_idef call).
03421         // -- RK 971104
03422         num_byte, lbase, NULL, opt_stab);
03423     Is_True(retv->Kind() == CK_IVAR ||
03424       (retv->Kind()==CK_OP &&
03425        (retv->Opr()==OPR_CVT || retv->Opr()==OPR_CVTL)),
03426       ("CODEMAP::Add_expr: return illegal cr from Add_idef"));
03427     CODEREP *retv_ivar = (retv->Kind()==CK_IVAR) ? retv : retv->Opnd(0);
03428     if (retv_ivar->Is_ivar_volatile())
03429       stmt->Set_volatile_stmt();
03430     ccr->Set_tree(retv);
03431     ccr->Set_scale(0);
03432 
03433     if (WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()) {
03434       MEMOP_ANNOT* annot = WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()->Get_annot (wn);
03435       if (annot) { opt_stab->Cr_sr_annot_mgr()->Import_annot (retv, annot); }
03436     }
03437     return FALSE;
03438   }
03439   else if ( oper == OPR_PARM ) {
03440     CODEREP *kid = Add_expr(WN_kid0(wn), opt_stab, stmt, &propagated, copyprop
03441 #ifdef KEY // bug 10577
03442               , TRUE
03443 #endif
03444           );
03445     /* CVTL-RELATED start (correctness) */
03446 #if 1
03447     // Attempt of fix 370390.  However, this breaks testn32/test_overall/longs.c
03448     // Because no CVT was inserted between the PARM node and LDID.
03449     cr->Init_ivar( op, WN_rtype(wn),
03450                    opt_stab->Get_occ(wn)/*occ*/, 
03451                    MTYPE_V/*dsctyp*/, WN_ty(wn)/*ldty*/,
03452                    kid/*lbase*/,
03453                    NULL/*sbase*/, WN_flag(wn)/*ofst*/, 0/*base_ty*/,
03454        0/*field_id*/ );
03455 #else
03456     cr->Init_ivar( op, kid->Dtyp(),
03457                    opt_stab->Get_occ(wn)/*occ*/, 
03458                    MTYPE_V/*dsctyp*/, WN_ty(wn)/*ldty*/,
03459                    kid/*lbase*/,
03460                    NULL/*sbase*/, WN_flag(wn)/*ofst*/, NULL/*base_ty*/,
03461        0/*field_id*/);
03462 #endif
03463     /* CVTL-RELATED finish */
03464 
03465     MU_NODE *mnode = opt_stab->Get_mem_mu_node(wn);
03466     if (mnode) {
03467       _ssa->Value_number_mu_node(mnode);
03468       cr->Set_ivar_mu_node(mnode);
03469     }
03470     retv = Hash_Ivar(cr);
03471     ccr->Set_tree(retv);
03472     ccr->Set_scale(0);
03473     return propagated; // return propagated instead of FALSE - transparent PARM
03474   }
03475   else if ( oper == OPR_CALL  ||
03476       oper == OPR_ICALL ||
03477       oper == OPR_INTRINSIC_CALL ||
03478       oper == OPR_INTRINSIC_OP ||
03479 #ifdef KEY
03480       oper == OPR_PURE_CALL_OP ||
03481 #endif
03482       oper == OPR_FORWARD_BARRIER ||
03483       oper == OPR_BACKWARD_BARRIER) {
03484     if ( WOPT_Enable_Combine_Operations ) {
03485       WN *combined_operation;
03486       if ( Combine_Operations( wn, &combined_operation ) ) {
03487         return Add_expr( combined_operation, opt_stab, stmt, ccr,
03488              copyprop );
03489       }
03490     }
03491 
03492     INT      kcnt = WN_kid_count(wn);
03493     cr->Init_op(WN_opcode(wn), kcnt);
03494 
03495     // In particular for CALLs and the like, the OPR_CALL itself
03496     // is entered as the first kid of the stmtrep, followed by
03497     // kids of OPR_CALL as the operands of the first cr.
03498     for (INT i = 0; i < kcnt; i++) {
03499       CODEREP *kid = Add_expr(WN_kid(wn, i), opt_stab, stmt, &propagated, copyprop);
03500       cr->Set_opnd(i, kid);
03501     }
03502 
03503     if (oper == OPR_INTRINSIC_CALL ) {
03504       cr->Set_intrinsic(WN_intrinsic(wn));
03505     }
03506     else if ( oper == OPR_INTRINSIC_OP
03507 #ifdef KEY
03508         || oper == OPR_PURE_CALL_OP
03509 #endif
03510             ) {
03511 
03512 #ifdef KEY
03513       if (oper == OPR_PURE_CALL_OP)
03514         cr->Set_call_op_aux_id (WN_st_idx(wn));
03515       else
03516 #endif
03517       cr->Set_intrinsic(WN_intrinsic(wn));
03518       // pv324295
03519       if (propagated) { // may have propagated all constants to the INTR_OP
03520   FOLD ftmp;
03521   retv = ftmp.Fold_Expr(cr);
03522   if (retv == NULL) { // either not folded or Fold_Expr has not rehashed
03523     retv = Hash_Op(cr);
03524   }
03525   if (retv->Kind() == CK_CONST) { // folded to constant
03526     ccr->Set_tree(NULL);
03527     ccr->Set_scale(retv->Const_val());
03528     retv->DecUsecnt();
03529     return FALSE;
03530   }
03531   if (retv->Kind() == CK_RCONST) {
03532     ccr->Set_tree(retv);
03533     ccr->Set_scale(0);
03534     return FALSE;
03535   }
03536   cr = retv;
03537       }
03538     }
03539     retv = Hash_Op(cr);
03540     ccr->Set_tree(retv);
03541     ccr->Set_scale(0);
03542     return FALSE;
03543   }
03544   else if (oper == OPR_ASM_STMT) {
03545     // The statement level has saved aside the information from the
03546     // constraint and clobber pragmas so we can reconstruct them at
03547     // emit time. We can ignore that information here.
03548 
03549     INT      kcnt = WN_kid_count(wn) - 2;
03550     cr->Init_op(WN_opcode(wn), kcnt);
03551 
03552     // In particular for ASMs, like CALLs, the OPR_ASM_STMT itself
03553     // is entered as the first kid of the stmtrep, followed by the
03554     // OPR_ASM_INPUT kids of OPR_ASM_STMT as the operands of the first
03555     // cr.
03556     for (INT i = 0; i < kcnt; i++) {
03557       CODEREP *kid = Add_expr(WN_kid(wn, i + 2),
03558             opt_stab,
03559             stmt,
03560             &propagated,
03561             copyprop);
03562       cr->Set_opnd(i, kid);
03563     }
03564 
03565     retv = Hash_Op(cr);
03566     ccr->Set_tree(retv);
03567     ccr->Set_scale(0);
03568     return FALSE;
03569   }
03570   else if (oper == OPR_ASM_INPUT) {
03571     INT kcnt = WN_kid_count(wn);
03572     cr->Init_op(WN_opcode(wn), kcnt);
03573     for (INT i = 0; i < kcnt; ++i) {
03574 // Bug 1573
03575 #if defined(KEY) && !defined(TARG_NVISA)
03576       BOOL save_flag = WOPT_Enable_Input_Prop;
03577       if (OPERATOR_is_scalar_load (WN_operator(WN_kid(wn, i))) || OPERATOR_is_scalar_iload (WN_operator(WN_kid(wn, i))))
03578         WOPT_Enable_Input_Prop = FALSE;
03579 #endif
03580       FmtAssert(i == 0, ("Asm_Input should have only one kid")); 
03581 #ifdef KEY
03582 // Bug 1575
03583       cr->Set_asm_input_rtype(WN_rtype(WN_kid(wn, i)));
03584       cr->Set_asm_input_dsctype(WN_desc(WN_kid(wn, i)));
03585       if (cr->Asm_input_dsctype() == MTYPE_V)
03586   cr->Set_asm_input_dsctype(cr->Asm_input_rtype());
03587 #endif
03588       CODEREP *kid = Add_expr(WN_kid(wn, i),
03589             opt_stab,
03590             stmt,
03591             &propagated,
03592             copyprop);
03593 #if defined(KEY) && !defined(TARG_NVISA)
03594       if (OPERATOR_is_scalar_load (WN_operator(WN_kid(wn, i))) || OPERATOR_is_scalar_iload (WN_operator(WN_kid(wn, i))))
03595         WOPT_Enable_Input_Prop = save_flag;
03596 #endif
03597       cr->Set_opnd(i, kid);
03598     }
03599     cr->Set_asm_opnd_num(WN_asm_opnd_num(wn));
03600     cr->Set_asm_constraint(WN_st_idx(wn));
03601     retv = Hash_Op(cr);
03602     ccr->Set_tree(retv);
03603     ccr->Set_scale(0);
03604     return FALSE;
03605   }
03606   else {
03607     if ( WOPT_Enable_Combine_Operations ) {
03608       WN *combined_operation;
03609       if ( Combine_Operations( wn, &combined_operation ) ) {
03610         return Add_expr( combined_operation, opt_stab, stmt, ccr,
03611              copyprop );
03612       }
03613     }
03614     
03615     INT      kcnt = WN_kid_count(wn);
03616     cr->Init_op(WN_opcode(wn), kcnt);
03617 
03618     if (WOPT_Enable_CRSIMP) {
03619       // process linear operator with canonicalization
03620       switch (oper) {
03621       case OPR_ADD: case OPR_SUB:
03622   if ((MTYPE_type_class(OPCODE_rtype(op)) & MTYPE_CLASS_INTEGER) != 0)
03623     return Canon_add_sub(wn, opt_stab, stmt, ccr, cr, copyprop);
03624   break;
03625       case OPR_NEG:
03626   if ((MTYPE_type_class(OPCODE_rtype(op)) & MTYPE_CLASS_INTEGER) != 0)
03627     return Canon_neg(wn, opt_stab, stmt, ccr, cr, copyprop);
03628   break;
03629       case OPR_MPY:
03630   if ((MTYPE_type_class(OPCODE_rtype(op)) & MTYPE_CLASS_INTEGER) != 0)
03631     return Canon_mpy(wn, opt_stab, stmt, ccr, cr, copyprop);
03632   break;
03633       case OPR_CVT:
03634   if ((MTYPE_type_class(OPCODE_rtype(op)) & MTYPE_CLASS_INTEGER) != 0
03635 #ifdef TARG_X8664 // bug 7733
03636       && ! MTYPE_is_vector(OPCODE_rtype(op)) 
03637       && ! MTYPE_is_vector(OPCODE_desc(op)) 
03638 #endif
03639      )
03640     return Canon_cvt(wn, opt_stab, stmt, ccr, cr, copyprop);
03641   break;
03642       default:
03643         break;
03644       }
03645     }
03646 
03647     // In particular for CALLs and the like, the OPR_CALL itself
03648     // is entered as the first kid of the stmtrep, followed by
03649     // kids of OPR_CALL as the operands of the first cr.
03650 
03651     BOOL prop_disabled = copyprop->Disabled();
03652     for (INT i = 0; i < kcnt; i++) {
03653       BOOL proped = FALSE;
03654       CODEREP *opnd =
03655         Add_expr(WN_kid(wn,i), opt_stab, stmt, &proped, copyprop);
03656       cr->Set_opnd(i, opnd);
03657       propagated |= proped;
03658     }
03659 
03660     switch (oper) {
03661       case OPR_ARRAY:
03662         cr->Set_elm_siz(WN_element_size(wn));
03663   break;
03664       case OPR_CVTL:
03665   cr->Set_offset((mINT32)WN_cvtl_bits(wn));
03666   break;
03667       case OPR_INTRINSIC_CALL:
03668       cr->Set_intrinsic(WN_intrinsic(wn));
03669   break;
03670       case OPR_INTRINSIC_OP:
03671   cr->Set_intrinsic(WN_intrinsic(wn));
03672   break;
03673       case OPR_TAS:
03674   cr->Set_ty_index(WN_ty(wn));
03675   break;
03676       case OPR_EXTRACT_BITS:
03677       case OPR_COMPOSE_BITS:
03678   cr->Set_op_bit_offset(WN_bit_offset(wn));
03679   cr->Set_op_bit_size(WN_bit_size(wn));
03680   break;
03681 #ifdef KEY
03682       case OPR_PURE_CALL_OP:
03683   cr->Set_call_op_aux_id (WN_st_idx(wn));
03684         break;
03685 #endif
03686     }
03687 
03688     BOOL do_canonicalization = TRUE;
03689     if (WOPT_Enable_Canon_Compare && _phase == MAINOPT_PHASE) {
03690       BOOL modified;
03691       do_canonicalization = !Canonicalize_compare(cr, stmt->Bb(), &modified);
03692     }
03693 
03694     // Fix 325467:  always try to simplify SELECT because some
03695     //  SELECT are generated in the opt_cfg.cxx pass with WHIRL simplification.
03696     if ( (propagated && do_canonicalization && kcnt < 3) ||
03697    oper==OPR_SELECT)  
03698     {
03699       FOLD ftmp;
03700       retv = ftmp.Fold_Expr(cr);
03701       if (retv == NULL) { // either not folded or Fold_Expr has not rehashed
03702         retv = Hash_Op(cr, do_canonicalization);
03703       }
03704     }
03705     else {
03706       retv = Hash_Op(cr, do_canonicalization);
03707     }
03708 
03709     if (retv->Kind() == CK_CONST) {
03710       // for cse of upper 16 bits of const addr
03711       retv->DecUsecnt();
03712       ccr->Set_tree(NULL);
03713       ccr->Set_scale(retv->Const_val());
03714       return TRUE;
03715     }
03716 
03717     ccr->Set_tree(retv);
03718     ccr->Set_scale(0);
03719     return propagated;
03720   }
03721 }
03722 
03723 BOOL
03724 STMTREP::Has_mu(void) const
03725 {
03726   if (_opr == OPR_REGION) { // need to check what kind of region
03727     if (Bb()->Kind() == BB_REGIONSTART || Bb()->Kind() == BB_REGIONEXIT) {
03728       RID *rid = Bb()->Regioninfo()->Rid();
03729       Is_True(rid != NULL, ("STMTREP::Has_mu, NULL RID"));
03730       if (RID_TYPE_mp(rid) || RID_TYPE_eh(rid))
03731   return FALSE;
03732     }
03733   }
03734   return OPERATOR_has_mu(_opr); 
03735 }
03736 
03737 BOOL
03738 STMTREP::Has_chi(void) const
03739 {
03740   if (_opr == OPR_REGION) { // need to check what kind of region
03741     if (Bb()->Kind() == BB_REGIONSTART || Bb()->Kind() == BB_REGIONEXIT) {
03742       RID *rid = Bb()->Regioninfo()->Rid();
03743       Is_True(rid != NULL, ("STMTREP::Has_chi, NULL RID"));
03744       if (RID_TYPE_mp(rid) || RID_TYPE_eh(rid))
03745   return FALSE;
03746     }
03747   }
03748   return OPERATOR_has_chi(_opr); 
03749 }
03750 
03751 void
03752 STMTREP::Enter_rhs(CODEMAP *htable, OPT_STAB *opt_stab, COPYPROP *copyprop, EXC *exc)
03753 {
03754   // Create the internal representation for the rhs of this statement.
03755   OPCODE op = WN_opcode(Wn());
03756   OPERATOR opr = WN_operator(Wn());
03757   BOOL   proped = FALSE;
03758 
03759   switch (opr) {
03760 
03761   case OPR_FUNC_ENTRY:
03762   case OPR_ALTENTRY:
03763     FmtAssert( FALSE, ("ENTRY not expected") );
03764     break;
03765 
03766   case OPR_BLOCK:
03767   case OPR_DO_LOOP:
03768   case OPR_WHILE_DO:
03769   case OPR_DO_WHILE:
03770   case OPR_IF:
03771   case OPR_RETURN:
03772 #ifdef KEY
03773   case OPR_GOTO_OUTER_BLOCK:
03774 #endif
03775     // skip these cases
03776     break;
03777 
03778   case OPR_GOTO:
03779   case OPR_REGION_EXIT:
03780     Set_label_number(WN_label_number(Wn()));
03781     break;
03782 
03783   case OPR_LABEL:
03784     // WN_st is not touched by opt_sym at all
03785     Set_label_number(WN_label_number(Wn()));
03786     Set_label_flags(WN_label_flag(Wn()));
03787     // note that we do *not* do anything about loop_info nodes that
03788     // may be attached because we dealt with them when building the
03789     // cfg, and they are no longer associated with the label.
03790     break;
03791 
03792   case OPR_FALSEBR:
03793   case OPR_TRUEBR:
03794     // WN_st is not converted to ver_stab index!
03795     Set_rhs(htable->Add_expr(WN_kid0(Wn()),
03796            opt_stab, this, &proped, copyprop));
03797 #if 0 // not needed because same call done in Add_expr, and if calling
03798       // Fold_Expr again, will undo the canonicalization of compare (492340)
03799     // simplifies 1 < 10 type expressions
03800     if (WOPT_Enable_Input_Prop && proped) {
03801       FOLD ftmp;
03802       CODEREP *retv;
03803       if (WOPT_Enable_Fast_Simp)
03804   retv = ftmp.Fold_Expr(Rhs()); // look at top stmt
03805       else
03806   retv = ftmp.Fold_Tree(Rhs()); // look at whole RHS
03807       if (retv != NULL)
03808   Set_rhs(retv);
03809     }
03810 #endif
03811     Set_label_number(WN_label_number(Wn()));
03812     break;
03813 
03814   case OPR_XPRAGMA:
03815     // pragma is IS_AFFINITY_XPRAGMA(wn)
03816     if (WN_pragma(Wn()) == WN_PRAGMA_COPYIN_BOUND) {
03817       copyprop->Set_disabled();
03818       CODEREP *cr = htable->Add_expr(WN_kid0(Wn()),
03819                                      opt_stab, this,  &proped, copyprop);
03820       Set_rhs(cr);
03821 #ifdef KEY // since its value may consist of MAX, prevent its copy propagation
03822       if (htable->Phase() == MAINOPT_PHASE && cr->Kind() == CK_VAR)
03823         cr->Set_flag(CF_DONT_PROP);
03824 #endif
03825 #if 0
03826       STMTREP *defstmt = cr->Defstmt();
03827       defstmt->Set_volatile_stmt();
03828 #endif
03829       copyprop->Reset_disabled();
03830     }
03831     else
03832       Set_rhs(htable->Add_expr(WN_kid0(Wn()),
03833                                opt_stab, this, &proped, copyprop));
03834     break;
03835 
03836   case OPR_AGOTO:
03837   case OPR_ASSERT:
03838   case OPR_EVAL:
03839   case OPR_COMPGOTO:
03840   case OPR_RETURN_VAL:
03841     Set_rhs(htable->Add_expr(WN_kid0(Wn()),
03842                              opt_stab, this, &proped, copyprop));
03843     break;
03844 
03845   case OPR_CALL:
03846   case OPR_ICALL:
03847   case OPR_INTRINSIC_CALL:
03848   case OPR_FORWARD_BARRIER:
03849   case OPR_BACKWARD_BARRIER:
03850   case OPR_DEALLOCA:
03851   case OPR_ALLOCA:
03852     // WN_st, if present, is not converted to ver_stab index!
03853     Set_rhs(htable->Add_expr(Wn(), opt_stab, this, &proped, copyprop));
03854     break;
03855 
03856   case OPR_COMMENT:
03857   case OPR_PRAGMA:
03858     // don't do anything
03859     break;
03860   
03861   case OPR_IO:
03862   case OPR_REGION:
03863     {
03864       // any region nodes not taken out during construction of CFG are black
03865       // boxes.
03866       Set_black_box();
03867       WN *new_wn = WN_COPY_Tree_With_Map(Wn()); // copy the tree in case we delete WHIRL
03868       Set_black_box_wn( new_wn );
03869     }
03870     break;
03871 
03872   case OPR_STID:
03873   case OPR_STBITS:
03874   case OPR_ISTORE:
03875   case OPR_ISTBITS:
03876   case OPR_ISTOREX:
03877   case OPR_MSTORE:
03878     Set_rhs(htable->Add_expr(WN_kid0(Wn()), opt_stab, this, &proped, copyprop));
03879     if (WOPT_Enable_Input_Prop && proped) {
03880       FOLD ftmp;
03881       CODEREP *retv;
03882       if (WOPT_Enable_Fast_Simp)
03883   retv = ftmp.Fold_Expr(Rhs()); // look at top stmt
03884       else
03885   retv = ftmp.Fold_Tree(Rhs()); // look at whole RHS
03886       if (retv != NULL)
03887   Set_rhs(retv);
03888     }
03889     return;
03890 
03891   case OPR_PREFETCH:
03892     {
03893       CANON_CR base_ccr;
03894       htable->Add_expr(WN_kid0(Wn()), opt_stab, this, &base_ccr, copyprop);
03895       base_ccr.Set_scale(base_ccr.Scale() + WN_offset(Wn()));
03896       base_ccr.Trim_to_16bits(WN_kid0(Wn()), htable);
03897 
03898       // In IA-64, PREFETCH should have zero offset
03899       if (! Use_Load_Store_Offset && base_ccr.Scale() != 0) {
03900   MTYPE typ = WN_rtype(WN_kid(Wn(), 0));
03901   CODEREP *retv = htable->Add_const(typ, base_ccr.Scale());
03902   if (base_ccr.Tree() != NULL)
03903     retv = htable->Add_bin_node
03904       (OPCODE_make_op(OPR_ADD, typ, MTYPE_V), base_ccr.Tree(), retv);
03905   base_ccr.Set_tree(retv);
03906   base_ccr.Set_scale(0);
03907       }
03908 
03909       CODEREP *lbase = base_ccr.Tree() ? base_ccr.Tree() :
03910           htable->Add_const(Pointer_type, (INT64) 0);
03911       Set_rhs(htable->Add_idef(op,
03912                                NULL,  // no occ_tab entry
03913                                NULL,  // no defining stmt
03914                                NULL,  // no mu-list
03915                                MTYPE_V, // no dtyp
03916                                MTYPE_V, // no desc
03917                                0,    // no TY
03918              0,    // no field id
03919                                base_ccr.Scale(),
03920                                (CODEREP *) 0,    // no load_addr_ty
03921                                lbase,
03922                                NULL, opt_stab));
03923       WN_MAP_Set(htable->Prefetch_map(), Wn(), this);
03924       return;
03925     }
03926 
03927   case OPR_OPT_CHI:
03928     break;
03929 
03930   case OPR_ASM_STMT:
03931     {
03932       // Save away the information from the constraint and clobber
03933       // pragmas so we can reconstruct those pragmas at emit time.
03934       Set_asm_pragma(CXX_NEW(ASM_PRAGMA_INFO(htable->Mem_pool()),
03935            htable->Mem_pool()));
03936       WN *prag = WN_first(WN_asm_clobbers(Wn()));
03937       while (prag != NULL) {
03938   FmtAssert(WN_pragma(prag) == WN_PRAGMA_ASM_CLOBBER,
03939       ("Unknown pragma type for ASM clobber"));
03940   CLOBBER_PRAGMA_INFO info;
03941   // bug fix for OSP_87 & OSP_90
03942   if (WN_opcode(prag) == OPC_XPRAGMA) {
03943     WN *kid = WN_kid0(prag);
03944     FmtAssert(WN_operator(kid) == OPR_IDNAME,
03945         ("Unknown kid operator for PREG ASM clobber"));
03946     info.preg_st_idx = WN_st_idx(kid);
03947     info.preg_number = WN_offset(kid);
03948     info.clobber_string_idx = WN_st_idx(prag);
03949         }
03950   else {
03951     info.preg_st_idx = 0;
03952     info.preg_number = 0;
03953     info.clobber_string_idx = WN_pragma_arg1(prag);
03954   }
03955   Asm_pragma()->clobber_info.push_back(info);
03956   prag = WN_next(prag);
03957       }
03958       prag = WN_first(WN_asm_constraints(Wn()));
03959       while (prag != NULL) {
03960   FmtAssert(WN_pragma(prag) == WN_PRAGMA_ASM_CONSTRAINT,
03961       ("Unknown pragma type for ASM output constraint"));
03962   CONSTRAINT_PRAGMA_INFO info;
03963   info.preg_st_idx = WN_st_idx(prag);
03964   info.constraint_st_idx = (ST_IDX) WN_pragma_arg1(prag);
03965   info.asm_neg_preg = WN_pragma_asm_copyout_preg(prag);
03966   info.asm_opnd_num = WN_pragma_asm_opnd_num(prag);
03967   Asm_pragma()->constraint_info.push_back(info);
03968   prag = WN_next(prag);
03969       }
03970       Set_rhs(htable->Add_expr(Wn(), opt_stab, this, &proped, copyprop));
03971       break;
03972     }
03973 
03974   case OPR_PREFETCHX:
03975   default:
03976     FmtAssert (FALSE,
03977          ("STMTREP::Enter_rhs: opcode %s is not implemented yet",
03978     OPCODE_name(op)));
03979   }
03980 }
03981 
03982 // return TRUE if two STMTREPs have same LHS
03983 BOOL
03984 STMTREP::Same_lhs(const STMTREP *stmt) const
03985 {
03986   if (this == NULL || stmt == NULL)
03987     return FALSE;
03988   if (Lhs() == NULL || stmt->Lhs() == NULL)
03989     return FALSE;
03990   if (Lhs()->Kind() != stmt->Lhs()->Kind())
03991     return FALSE;
03992   switch (Lhs()->Kind()) {
03993     case CK_VAR:
03994       return Lhs()->Aux_id() == stmt->Lhs()->Aux_id();
03995     case CK_IVAR:
03996       if (MTYPE_size_min(Lhs()->Dtyp())==MTYPE_size_min(stmt->Lhs()->Dtyp()) &&
03997     (Lhs()->Istr_base() == stmt->Lhs()->Istr_base()) &&
03998     (Lhs()->Offset() == stmt->Lhs()->Offset())) {
03999   if (Opr() == OPR_MLOAD) 
04000     return Lhs()->Mload_size() == stmt->Lhs()->Mload_size();
04001   else if (Opr() == OPR_ILOADX) 
04002     return Lhs()->Index() == stmt->Lhs()->Index();
04003   else
04004     return TRUE;
04005       }
04006       return FALSE;
04007     default:
04008       return FALSE;
04009   }
04010 }
04011   
04012 void
04013 STMTREP::Enter_lhs(CODEMAP *htable, OPT_STAB *opt_stab, COPYPROP *copyprop)
04014 {
04015   IDTYPE du;
04016   OPCODE opc;
04017   OPERATOR opr = WN_operator(Wn());
04018   MTYPE  dtyp, dsctyp;
04019   WN    *copy_wn;
04020   CANON_CR base_ccr;
04021   TY_IDX ilod_base_ty;
04022   BOOL   proped = FALSE;
04023 
04024   Set_linenum(WN_Get_Linenum(Wn()));
04025 
04026   // No need to do anything for "black-box" statements
04027   if ( WN_is_black_box( Wn() ) )
04028     return;
04029 
04030   if (OPERATOR_is_store (opr)) {
04031     if (WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()) {
04032       MEMOP_ANNOT* annot = WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()->Get_annot (Wn());
04033       if (annot) opt_stab->Cr_sr_annot_mgr()->Import_annot (this, annot);
04034     }
04035   }
04036 
04037   // Create the internal representation for the lhs of this statement.
04038   switch (opr) {
04039   case OPR_STID:
04040   case OPR_STBITS:
04041     du = WN_ver(Wn());
04042     FmtAssert(du != 0,
04043         ("STMTMAP::Enter_lhs: WN_st wasn't set correctly"));
04044     dsctyp = _desc;
04045     // under U64 ISA, STID can still be signed; the following makes sure
04046     // first-touch is always unsigned
04047     if (htable->Phase() == MAINOPT_PHASE && 
04048   (Only_Unsigned_64_Bit_Ops && ! Delay_U64_Lowering)) 
04049       dsctyp = Mtype_TransferSign(MTYPE_U8, dsctyp);
04050     Set_lhs( htable->Add_def(opt_stab->Du_aux_id(du), opt_stab->Du_version(du),
04051            this, WN_rtype(WN_kid0(Wn())), dsctyp,
04052            WN_offset(Wn()), WN_ty(Wn()),
04053            WN_field_id(Wn()), TRUE ) ); 
04054 
04055     if (opt_stab->Du_is_volatile(du)) { 
04056       // set the volatile attribute for this var, even if this
04057       // particular reference is not cast as volatile
04058       Lhs()->Set_var_volatile();
04059     }
04060     else {
04061       // only cache non-volatile codereps
04062       opt_stab->Du_set_coderep(du, Lhs());
04063     }
04064 
04065 #ifdef KEY // bug 5131: mark mp-shared variables defined in MP region 
04066     if (htable->Phase() != MAINOPT_PHASE && PU_has_mp(Get_Current_PU())) {
04067       BOOL is_mp_local = FALSE;
04068       if (Bb()->MP_region()) {
04069   BB_NODE *regionbb = Bb();
04070   if (regionbb->Kind() == BB_REGIONSTART) 
04071     is_mp_local = Symbol_mp_local_in_region(regionbb, opt_stab, Lhs()->Aux_id());
04072   while (! is_mp_local && 
04073          (regionbb = htable->Cfg()->Find_enclosing_parallel_region_bb(regionbb)) != NULL)
04074     is_mp_local = Symbol_mp_local_in_region(regionbb, opt_stab, Lhs()->Aux_id());
04075       }
04076       if (! is_mp_local)
04077   Lhs()->Set_mp_shared();
04078     }
04079 #endif
04080 
04081     opt_stab->Push_coderep(Lhs()->Aux_id(), Lhs());
04082 
04083     if (Rhs()->Kind() == CK_VAR &&
04084   Rhs()->Aux_id() == Lhs()->Aux_id() &&
04085   !Rhs()->Is_var_volatile() &&
04086   !Lhs()->Is_var_volatile())
04087       Set_identity_asgn();
04088 
04089     return;
04090 
04091   case OPR_ISTORE:
04092   case OPR_ISTBITS:
04093     {
04094       // ISTORE has no dtyp, we manufacture one from the rhs of its tree
04095       htable->Add_expr(WN_kid(Wn(), 1), opt_stab, this, &base_ccr, copyprop);
04096       CODEREP *baseexp = base_ccr.Tree();
04097 
04098       dtyp = WN_rtype(WN_kid0(Wn()));
04099       dsctyp = _desc;
04100       if (dsctyp != MTYPE_BS) {
04101         if (MTYPE_size_min(dsctyp) > MTYPE_size_min(dtyp)) {
04102     // ISTORE does not like dtyp < dsctyp, make sure 
04103     // they are of compatible size
04104     dtyp = Mtype_from_class_size(dtyp, dsctyp);
04105         }
04106         dtyp = Mtype_from_class_size(dsctyp, dtyp);
04107       }
04108 #ifdef TARG_SL
04109         if (dtyp == MTYPE_I2 && dsctyp == MTYPE_I2) {
04110           dtyp = MTYPE_I4;
04111         }
04112 #endif
04113       opc = OPCODE_make_op(opr == OPR_ISTORE ? OPR_ILOAD : OPR_ILDBITS, dtyp, dsctyp);
04114       base_ccr.Set_scale(base_ccr.Scale() + WN_offset(Wn()));
04115       base_ccr.Trim_to_16bits(WN_kid(Wn(), 1), htable);
04116       if (base_ccr.Tree() != NULL && 
04117     base_ccr.Tree()->Kind() == CK_LDA )
04118       {
04119   // is the result of the load volatile?
04120   if (TY_is_volatile(WN_ty(Wn()))) 
04121     goto no_fold_istore;
04122 
04123   // may point to a volatile object
04124   if (TY_kind(WN_ty(Wn())) == KIND_POINTER) {
04125     TY_IDX pointed = TY_pointed(WN_ty(Wn()));
04126     if (TY_is_volatile(pointed))
04127       goto no_fold_istore;
04128   }
04129       
04130   // fold to STID
04131   // go thru chi list to find the scalar var version
04132   CHI_NODE *cnode, *prev_cnode;
04133   CHI_LIST *chi_list = opt_stab->Get_generic_chi_list(Wn());
04134   CHI_LIST_ITER chi_iter;
04135 
04136   chi_iter.Init(chi_list);
04137   for (prev_cnode = NULL, cnode = chi_iter.First(); 
04138        ! chi_iter.Is_Empty(); 
04139        prev_cnode = cnode, cnode = chi_iter.Next()) {
04140     if (! cnode->Live())
04141       continue;
04142     AUX_ID vaux = cnode->Aux_id();
04143     if (!opt_stab->Is_real_var(vaux))
04144       continue;
04145     INT64 v_ofst;
04146     ST *v_st;
04147     Expand_ST_into_base_and_ofst(opt_stab->St(vaux), 
04148                opt_stab->St_ofst(vaux), &v_st, &v_ofst);
04149     if (v_st == base_ccr.Tree()->Lda_base_st() &&
04150         v_ofst == base_ccr.Scale() && 
04151         0 == base_ccr.Tree()->Offset() && // TODO: not needed if canonicalize in preopt
04152         opt_stab->Aux_stab_entry(vaux)->Mclass() == 
04153               Get_mtype_class(_desc) &&
04154         opt_stab->Aux_stab_entry(vaux)->Byte_size() * 8 ==
04155               MTYPE_size_min(_desc) &&
04156         (opr == OPR_ISTORE && 
04157          (opt_stab->Aux_stab_entry(vaux)->Bit_size() == 0 ||
04158     opt_stab->Aux_stab_entry(vaux)->Field_id() == WN_field_id(Wn())) ||
04159          opr == OPR_ISTBITS &&
04160          opt_stab->Aux_stab_entry(vaux)->Bit_ofst() == WN_bit_offset(Wn()) &&
04161          opt_stab->Aux_stab_entry(vaux)->Bit_size() == WN_bit_size(Wn()))) {
04162       VER_STAB_ENTRY *vse = opt_stab->Ver_stab_entry(cnode->Result());
04163       base_ccr.Tree()->DecUsecnt();   // for the LDA coderep
04164       Is_True(! vse->Real_use() ||
04165         vse->Coderep() == NULL && vse->Type() == CHI_STMT, 
04166         ("Error in ISTORE to STID folding in htable"));
04167 
04168       Set_lhs( htable->Add_def(vaux, vse->Version(), this,
04169              dtyp, dsctyp,
04170              opt_stab->St_ofst(vaux)/*base_ccr.Scale()*/,
04171              TY_pointed(WN_ty(Wn())),
04172              WN_field_id(Wn()), TRUE) );
04173       Lhs()->Set_flag(CF_FOLDED_LDID);
04174 
04175       if (opt_stab->Du_is_volatile(cnode->Result())) { 
04176         // set the volatile attribute for this var, even if this
04177         // particular reference is not cast as volatile
04178         Lhs()->Set_var_volatile();
04179       }
04180       else {
04181         // only cache non-volatile codereps
04182          opt_stab->Du_set_coderep(cnode->Result(), Lhs());
04183       }
04184 
04185       // if not zero version originally, set coderep that correspond to vers
04186       if (! vse->Zero_vers()) {
04187         vse->Set_Real_use();
04188         vse->Set_type(WHIRL_STMT);
04189       }
04190       chi_list->Remove(prev_cnode, cnode); // remove cnode from chi list
04191       // cnode must not be purged from memory because it will be
04192       // used by ILOAD-folding (refererened thru VSE and DU).
04193       cnode->Set_RESULT(Lhs()); 
04194 
04195       // TODO: need to remove extra chi nodes
04196       Set_op(OPCODE_make_op(opr == OPR_ISTORE ? OPR_STID : OPR_STBITS, MTYPE_V, dsctyp));
04197       opt_stab->Push_coderep(vaux, Lhs());
04198       htable->Inc_istorefolds();
04199       return;
04200     }
04201   }
04202       }
04203 
04204       // jump to here if not folding the istore
04205       no_fold_istore:;
04206 
04207       // In IA-64, ISTORE should have zero offset
04208       if (! Use_Load_Store_Offset && base_ccr.Scale() != 0) {
04209   MTYPE typ = WN_rtype(WN_kid(Wn(), 1));
04210   CODEREP *retv = htable->Add_const(typ, (INT64) base_ccr.Scale());
04211   if (base_ccr.Tree() != NULL)
04212     retv = htable->Add_bin_node
04213       (OPCODE_make_op(OPR_ADD, typ, MTYPE_V), base_ccr.Tree(), retv);
04214   base_ccr.Set_tree(retv);
04215   base_ccr.Set_scale(0);
04216       }
04217 
04218       ilod_base_ty = WN_ty(Wn());
04219       {
04220   CODEREP *lbase = ( base_ccr.Tree() ? base_ccr.Tree() :
04221          htable->Add_const(Pointer_type, (INT64) 0) );
04222   Set_lhs( htable->Add_idef(opc, opt_stab->Get_occ(Wn()), 
04223           this, NULL, dtyp, dsctyp, 
04224           TY_pointed(ilod_base_ty),
04225           WN_field_id(Wn()),
04226           base_ccr.Scale(),
04227           (CODEREP *)(INTPTR) ilod_base_ty, NULL, 
04228           lbase, opt_stab) );
04229       }
04230       if (Lhs()->Is_ivar_volatile())
04231   Set_volatile_stmt();
04232       htable->Update_pref(Lhs());
04233     }
04234     return;
04235 
04236   case OPR_ISTOREX:
04237     {
04238       Is_True(FALSE, ("STMTREP::Enter_lhs: should never see OPR_ISTOREX"));
04239       CODEREP *base = 
04240   htable->Add_expr(WN_kid(Wn(), 1), opt_stab, this, &proped, copyprop);
04241       CODEREP *index = htable->Add_expr(WN_kid(Wn(), 2), opt_stab, this,
04242   &proped, copyprop);
04243       
04244       dtyp = WN_rtype(WN_kid0(Wn()));
04245       dsctyp = _desc;
04246       //opc = OPCODE_make_op(OPR_ILOADX, dtyp, dsctyp);
04247       opc = OPCODE_make_op(OPR_ILOADX, dtyp, MTYPE_V);
04248       ilod_base_ty = WN_ty(Wn());
04249       CODEREP *lbase = base_ccr.Tree() ? base_ccr.Tree() :
04250         htable->Add_const(Pointer_type,(INT64)0);
04251       Set_lhs( htable->Add_idef(opc, opt_stab->Get_occ(Wn()), 
04252         this, NULL,
04253         WN_rtype(WN_kid0(Wn())),
04254         _desc,
04255         TY_pointed(ilod_base_ty),
04256         WN_field_id(Wn()),
04257         (mINT32)(INTPTR)index,
04258         (CODEREP *)(INTPTR) ilod_base_ty, NULL, lbase, 
04259                                 opt_stab));
04260       if (Lhs()->Is_ivar_volatile())
04261   Set_volatile_stmt();
04262     }
04263     return;
04264 
04265   case OPR_MSTORE:
04266     {
04267       htable->Add_expr(WN_kid(Wn(), 1), opt_stab, this, &base_ccr, copyprop);
04268       CODEREP *num_byte = htable->Add_expr(WN_kid(Wn(), 2), opt_stab, this,
04269              &proped, copyprop);
04270       // rtype and type of MLOAD is indepedent of its operands type
04271       opc = OPC_MLOAD;
04272       base_ccr.Set_scale(base_ccr.Scale() + WN_offset(Wn()));
04273       base_ccr.Trim_to_16bits(WN_kid(Wn(), 1), htable);
04274 
04275       // In IA-64, MLOAD should have zero offset
04276       if (! Use_Load_Store_Offset && base_ccr.Scale() != 0) {
04277   MTYPE typ = WN_rtype(WN_kid(Wn(), 1));
04278   CODEREP *retv = htable->Add_const(typ, (INT64) base_ccr.Scale());
04279   if (base_ccr.Tree() != NULL)
04280     retv = htable->Add_bin_node
04281       (OPCODE_make_op(OPR_ADD, typ, MTYPE_V), base_ccr.Tree(), retv);
04282   base_ccr.Set_tree(retv);
04283   base_ccr.Set_scale(0);
04284       }
04285 
04286       CODEREP *lbase = ( base_ccr.Tree() ? base_ccr.Tree() :
04287        htable->Add_const(Pointer_type, (INT64) 0) );
04288 #if !(defined(linux) || defined(BUILD_OS_DARWIN))
04289       FmtAssert(sizeof(num_byte) == sizeof(TY_IDX),
04290     ("CODEMAP::Add_expr: Cannot union MSTORE size with "
04291      "Ilod_base_ty"));
04292 #endif /* linux */
04293       Set_lhs(htable->Add_idef(opc, opt_stab->Get_occ(Wn()), 
04294              this, NULL,
04295              MTYPE_M,
04296              MTYPE_M,
04297              WN_ty(Wn()),
04298              WN_field_id(Wn()),
04299              base_ccr.Scale(),
04300              // num_byte in the following line is
04301              // correct. See opt_htable.h, where the
04302              // MLOAD/MSTORE size is unioned with the
04303              // Ilod_base_ty. The only thing we need
04304              // to check here is that we don't lose
04305              // information (see the assertion
04306              // preceding this Set_lhs call).
04307              // -- RK 971104
04308              num_byte, NULL, lbase,
04309                                opt_stab));
04310       if (Lhs()->Is_ivar_volatile())
04311   Set_volatile_stmt();
04312     }
04313     return;
04314 
04315   case OPR_COMPGOTO:
04316   case OPR_EVAL:
04317     // don't have to do anything with these (all handled by rhs)
04318     return;
04319 
04320   case OPR_BLOCK:
04321   case OPR_DO_LOOP:
04322   case OPR_WHILE_DO:
04323   case OPR_DO_WHILE:
04324   case OPR_IF:
04325     // should not ever get here
04326     FmtAssert(FALSE, ("CODEMAP::Enter_lhs: Don't know how to handle"));
04327     return;
04328 
04329   case OPR_FALSEBR:
04330   case OPR_TRUEBR:
04331     Set_label_number(WN_label_number(Wn()));
04332     return;
04333 
04334   case OPR_FORWARD_BARRIER:
04335   case OPR_BACKWARD_BARRIER:
04336   case OPR_DEALLOCA:
04337     Set_pt_list(opt_stab->Get_occ(Wn())->Pt_list());
04338     return;
04339 
04340   case OPR_INTRINSIC_CALL:
04341     Set_call_flags(WN_call_flag(Wn()));
04342     return;
04343 
04344   case OPR_ICALL:
04345     Set_call_flags(WN_call_flag(Wn()));
04346     Set_ty(WN_ty(Wn()));
04347     return;
04348 
04349   case OPR_CALL:
04350     Set_call_flags(WN_call_flag(Wn()));
04351     if (OPCODE_has_aux(WN_opcode(Wn())))
04352       Set_st(opt_stab->St((IDTYPE)(INTPTR)WN_st(Wn())));
04353     else
04354       Set_st(WN_st(Wn()));
04355     return;
04356 
04357   case OPR_ASM_STMT:
04358     Set_asm_string_idx(WN_st_idx(Wn()));
04359 #ifndef KEY
04360     _u4._asm_stmt_flags = _u3._wn->u1u2.uu.ua.asm_flag;
04361 #else
04362     Set_asm_stmt_flags(WN_asm_flag(Wn()));
04363 #endif
04364     return;
04365 
04366   case OPR_ASSERT:
04367   case OPR_RETURN:
04368   case OPR_RETURN_VAL:
04369   case OPR_PRAGMA:
04370   case OPR_XPRAGMA:
04371 #ifdef KEY
04372   case OPR_GOTO_OUTER_BLOCK:
04373 #endif
04374     copy_wn = WN_CopyNode(Wn());
04375     WN_set_map_id(copy_wn, WN_map_id(Wn()));
04376     Set_orig_wn(copy_wn);
04377     return;
04378 
04379   case OPR_REGION:
04380     copy_wn = WN_COPY_Tree_With_Map(Wn());
04381     Set_orig_wn(copy_wn);
04382     return;
04383 
04384   case OPR_PREFETCH:
04385     // pre-allocate the Prefetch wn
04386     copy_wn = WN_CopyNode(Wn());
04387     WN_set_map_id(copy_wn, WN_map_id(Wn()));
04388     Set_prefetch_wn(copy_wn);
04389     // update the pf_pointer to point to the STMTREP
04390     // opt_stab->Update_pf_list(Wn(), this);
04391     return;
04392 
04393   case OPR_GOTO:
04394   case OPR_AGOTO:
04395   case OPR_LABEL:
04396   case OPR_REGION_EXIT:
04397   case OPR_OPT_CHI:
04398   case OPR_EXC_SCOPE_BEGIN:
04399   case OPR_EXC_SCOPE_END:
04400     return;
04401 
04402   case OPR_PREFETCHX:
04403   default:
04404     Warn_todo("STMTREP::Enter_lhs: %s is not implemented yet",
04405         OPCODE_name(WN_opcode(Wn())));
04406     return;
04407   }
04408 }
04409 
04410 
04411 void
04412 CODEMAP::Init_var_phi_hash(void)
04413 {
04414   INT32 hash_tbl_capacity = 10; // Cfg()->Last_bb_id() * Opt_stab()->
04415   _phi_id_map.Init(hash_tbl_capacity);
04416   Set_phi_hash_valid();
04417 
04418   CFG_ITER cfg_iter;
04419   BB_NODE *bb;
04420   // It is cheaper to loop through all the phi's twice than to enlarge
04421   // the table a bunch of times! If we are going to do SSAPRE (which
04422   // creates a bunch of new variables to hold expression temporaries),
04423   // we will ask for an initial table capacity of 3/2 the number of
04424   // phi's currently in the program. Otherwise we ask for a table just
04425   // big enough to hold the current number of phi's in the program.
04426   if (WOPT_Enable_Exp_PRE ||
04427       WOPT_Enable_Load_PRE ||
04428       WOPT_Enable_Store_PRE) {
04429     FOR_ALL_NODE( bb, cfg_iter, Init(Cfg()) ) {
04430       PHI_NODE *phi;
04431       PHI_LIST_ITER phi_iter;
04432       FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
04433   hash_tbl_capacity += 3;
04434       }
04435     }
04436     hash_tbl_capacity = hash_tbl_capacity / 2;
04437   }
04438   else {
04439     FOR_ALL_NODE( bb, cfg_iter, Init(Cfg()) ) {
04440       PHI_NODE *phi;
04441       PHI_LIST_ITER phi_iter;
04442       FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
04443   ++hash_tbl_capacity;
04444       }
04445     }
04446   }
04447   _phi_id_map.Init(hash_tbl_capacity);
04448   Set_phi_hash_valid();
04449   FOR_ALL_NODE( bb, cfg_iter, Init(Cfg()) ) {
04450     PHI_NODE *phi;
04451     PHI_LIST_ITER phi_iter;
04452     FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
04453       Enter_var_phi_hash(phi);
04454     }
04455   }
04456 }
04457 
04458 
04459 void
04460 CODEMAP::Verify_var_phi_hash(void)
04461 {
04462 #ifdef Is_True_On
04463   CFG_ITER cfg_iter(Cfg());
04464   BB_NODE *bb;
04465   FOR_ALL_NODE( bb, cfg_iter, Init() ) {
04466     PHI_NODE *phi;
04467     PHI_LIST_ITER phi_iter;
04468     FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
04469       FmtAssert(phi == Lookup_var_phi(phi->Bb(), phi->Aux_id()),
04470     ("CODEMAP::Verify_var_phi_hash: phi %d at BB%d not found.", 
04471      phi->Aux_id(), phi->Bb()->Id()));
04472     
04473     }
04474   }
04475 #endif
04476 }
04477 
04478 
04479 void
04480 CODEMAP::Enter_var_phi_hash(PHI_NODE *phi)
04481 {
04482   Is_True(Phi_hash_valid(),
04483     ("CODEMAP::Enter_var_phi_hash:  hash not valid."));
04484   Is_True(_phi_id_map.Lookup(phi->Key()) == NULL,
04485     ("CODEMAP::Enter_var_phi_hash:  already entered."));
04486   _phi_id_map.Insert(phi->Key(), phi);
04487 }
04488 
04489 PHI_NODE*
04490 CODEMAP::Lookup_var_phi(const BB_NODE *bb, const AUX_ID id) const
04491 {
04492   Is_True(Phi_hash_valid(), ("CODEMAP::Lookup_var_phi:  hash not valid."));
04493   PHI_KEY key;  key.Init(bb->Id(),id);
04494   return _phi_id_map.Lookup(key);
04495 }
04496 
04497 void
04498 CODEMAP::Remove_var_phi_hash(PHI_NODE *phi)
04499 {
04500   Is_True(Phi_hash_valid(), ("CODEMAP::Lookup_var_phi:  hash not valid."));
04501   _phi_id_map.Delete(phi->Key());
04502 }
04503 
04504 void
04505 STMT_LIST::Print(FILE *fp) const
04506 {
04507   STMTREP_CONST_ITER  stmt_iter(this);
04508   const    STMTREP   *tmp;
04509   INT32               last_line = 0;
04510   FOR_ALL_NODE(tmp, stmt_iter, Init()) {
04511     if (Srcpos_To_Line(tmp->Linenum()) != last_line &&
04512   Srcpos_To_Line(tmp->Linenum()) != 0) {
04513       last_line = Srcpos_To_Line(tmp->Linenum());
04514       fprintf(fp, ">LINE %d___\n", last_line);
04515       }
04516     tmp->Print(fp);
04517     }
04518 }
04519 
04520 // Get the pointer information from opt_stab
04521 //
04522 POINTS_TO *
04523 CODEREP::Points_to(OPT_STAB *opt_stab) const  
04524 { 
04525   if (Kind() == CK_VAR) {
04526     return opt_stab->Points_to(Aux_id());
04527   }
04528   else if (Kind() == CK_LDA) {
04529     return opt_stab->Points_to(Lda_aux_id());
04530   }
04531   else if (Kind() == CK_IVAR) {
04532     // return opt_stab->Points_to(Ivar_aux_id());
04533     OCC_TAB_ENTRY *occ = Ivar_occ();
04534     if (occ)
04535       return Ivar_occ()->Points_to();
04536     return NULL;
04537   }
04538   else
04539     return NULL;
04540 }
04541 
04542 CODEREP *
04543 CODEREP::Get_ivar_vsym(void) const
04544 {
04545   if (Ivar_mu_node() != NULL) {
04546     return Ivar_mu_node()->OPND();
04547   } else {
04548     // PARM node has no chi list to search
04549     if (! OPERATOR_is_scalar_iload (Opr()) && Opr() != OPR_MLOAD)
04550       return NULL;
04551 
04552     // search the chi list
04553     Is_True(OPERATOR_is_scalar_istore (Ivar_defstmt()->Opr()) ||
04554             OPERATOR_is_scalar_store (Ivar_defstmt()->Opr()) ||
04555       Ivar_defstmt()->Opr() == OPR_MSTORE, 
04556       ("IVAR not defined by ISTORE/MSTORE/STID."));
04557     CHI_LIST_ITER chi_iter;
04558     CHI_NODE *cnode;
04559     CHI_LIST *chi_list = Ivar_defstmt()->Chi_list();
04560     FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
04561       if (cnode->Aux_id() == Ivar_occ()->Aux_id()) {
04562         // Is_True(cnode->Live(), ("CODEREP::Get_iver_vsym: cnode not live"));
04563   // Fix 510377!  vsym could be dead!  
04564   if (cnode->Live())
04565     return cnode->RESULT();
04566   else
04567     return NULL;
04568       }
04569     }
04570   }
04571   return NULL;
04572 }
04573 
04574 // Get the pointer information from opt_stab
04575 //
04576 POINTS_TO *
04577 STMTREP::Points_to(OPT_STAB *opt_stab) const  
04578 { 
04579   const OPERATOR opr = Opr();
04580 
04581   if (OPERATOR_is_scalar_load (opr) ||
04582       OPERATOR_is_scalar_store (opr) ||
04583       OPERATOR_is_scalar_iload (opr) ||
04584       OPERATOR_is_scalar_istore (opr) ||
04585       opr == OPR_ILOADX  || opr == OPR_ISTOREX)
04586     return Lhs()->Points_to(opt_stab);
04587   else if ( opr == OPR_RETURN || opr == OPR_RETURN_VAL
04588 #ifdef KEY
04589         || opr == OPR_GOTO_OUTER_BLOCK
04590 #endif
04591         )
04592     return opt_stab->Points_to_globals();
04593   else
04594     return NULL;
04595 }
04596 
04597 
04598 // ====================================================================
04599 // Determine if the statement redefines the variable (either directly,
04600 // or through a chi)
04601 // ====================================================================
04602 
04603 BOOL
04604 STMTREP::Redefines_var( AUX_ID var )
04605 {
04606   if (OPERATOR_is_scalar_store (Opr())) {
04607     CODEREP *lhs = Lhs();
04608     if ( Lhs()->Aux_id() == var ) {
04609       return TRUE;
04610     }
04611   }
04612 
04613   // check for indirect definitions
04614   if ( Has_chi() ) {
04615     CHI_LIST_ITER chi_iter;
04616     CHI_NODE *cnode;
04617     CHI_LIST *chi_list = Chi_list();
04618     FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
04619       if ( cnode->Aux_id() == var ) {
04620   return TRUE;
04621       }
04622     }
04623   }
04624 
04625   // must not redefine the variable
04626   return FALSE;
04627 }
04628 
04629 // ====================================================================
04630 // Determine if 'this' references the variable (either directly, or 
04631 // through a mu)
04632 // ====================================================================
04633 
04634 BOOL
04635 CODEREP::References_var( AUX_ID var )
04636 {
04637   switch ( Kind() ) {
04638     case CK_VAR:
04639       if ( Aux_id() == var )
04640   return TRUE;
04641       else
04642   return FALSE;
04643 
04644     case CK_IVAR:
04645       if ( Ilod_base()->References_var(var) )
04646   return TRUE;
04647       if (Opr() == OPR_MLOAD) {
04648   if ( Mload_size()->References_var(var) )
04649     return TRUE;
04650       }
04651       else if (Opr() == OPR_ILOADX) {
04652   if ( Index()->References_var(var) )
04653     return TRUE;
04654       }
04655       if (Ivar_mu_node() != NULL && Ivar_mu_node()->Aux_id() == var)
04656   return TRUE;
04657       return FALSE;
04658 
04659     case CK_OP:
04660       {
04661   for ( INT i = 0; i < Kid_count(); i++)
04662     if ( Get_opnd(i)->References_var(var) ) 
04663       return TRUE;
04664       }
04665       return FALSE;
04666 
04667     case CK_LDA:
04668     case CK_CONST:
04669     case CK_RCONST:
04670       return FALSE;
04671 
04672     default:
04673       FmtAssert( FALSE, ("CODEREP::References_var: invalid kind") );
04674   }
04675 
04676   // must not reference the variable
04677   return FALSE; // probably should not get to this statement
04678 }
04679 
04680 // ====================================================================
04681 // Determine if 'this' references the variable (either directly, or 
04682 // through a mu/chi)
04683 // ====================================================================
04684 
04685 BOOL
04686 STMTREP::References_var( AUX_ID var )
04687 {
04688   // check rhs
04689   if ( Rhs() != NULL ) {
04690     if ( Rhs()->References_var( var ) )
04691       return TRUE;
04692   }
04693     
04694   // check lhs
04695   if ( Lhs() != NULL ) {
04696     if ( Lhs()->References_var( var ) )
04697       return TRUE;
04698   }
04699     
04700   // check for indirect references through chi's
04701   if ( Has_chi() ) {
04702     CHI_LIST_ITER chi_iter;
04703     CHI_NODE *cnode;
04704     CHI_LIST *chi_list = Chi_list();
04705     FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
04706       if ( cnode->Aux_id() == var ) {
04707   return TRUE;
04708       }
04709     }
04710   }
04711 
04712   // check for indirect references through mu's
04713   if ( Has_mu() ) {
04714     MU_LIST_ITER mu_iter;
04715     MU_NODE *mnode;
04716     FOR_ALL_NODE( mnode, mu_iter, Init(Mu_list()) ) {
04717       if ( mnode->Aux_id() == var )
04718   return TRUE;
04719     }
04720   }
04721 
04722   // must not reference the variable
04723   return FALSE;
04724 }
04725 
04726 // ====================================================================
04727 // Print a bit position (formatted nicely)
04728 // ====================================================================
04729 
04730 char *
04731 CODEREP::Print_bit(void) const
04732 {
04733   static char buf[100];
04734   if (Bitpos() != ILLEGAL_BP)
04735     sprintf(buf,"%c%d",(Kind() == CK_VAR)?'V':'E',Bitpos());
04736   else
04737     sprintf(buf,"%d",Bitpos());
04738   return buf;
04739 }
04740 
04741 // Print a bit position (formatted nicely)
04742 //
04743 char *
04744 STMTREP::Print_bit(void) const
04745 {
04746   static char buf[100];
04747   if (Bitpos() != ILLEGAL_BP)
04748     sprintf(buf,"E%d",Bitpos());
04749   else
04750     sprintf(buf,"%d",Bitpos());
04751   return buf;
04752 }
04753 
04754 // ====================================================================
04755 // Can_be_speculated - tell whether the expression tree can be safely
04756 // moved to a point where it might be evaluated under circumstances
04757 // that didn't entail its evaluation in the original program. There
04758 // are several reasons why speculation might be unsafe:
04759 // 1) The expression might contain an opcode that can cause an
04760 //    exception;
04761 // 2) Under scalar_formal_ref, the expression might contain an f90
04762 //    formal parameter access to which might cause an exception; this
04763 //    contingency is allowed for in OPT_STAB::Safe_to_speculate.
04764 //
04765 // Restriction: Valid only for rvalues.
04766 // ====================================================================
04767 BOOL
04768 CODEREP::Can_be_speculated(OPT_STAB *opt_stab) const
04769 {
04770   switch (Kind()) {
04771   case CK_VAR:
04772     return opt_stab->Safe_to_speculate(Aux_id());
04773   case CK_IVAR: {
04774     CODEREP *base = Ilod_base() ? Ilod_base() : Istr_base();
04775     if (! base->Can_be_speculated(opt_stab))
04776       return FALSE;
04777     if (OPCODE_Can_Be_Speculative(Op()))
04778       return TRUE;
04779     // special case fortran array parameters declared constant bound and with
04780     // constant subscript that is within bounds (see 669621)
04781     if (! IS_FORTRAN)
04782       return FALSE;
04783     if (! OPERATOR_is_scalar_iload (Opr()))
04784       return FALSE;
04785     if (base->Kind() != CK_VAR)
04786       return FALSE;
04787     AUX_STAB_ENTRY *psym = opt_stab->Aux_stab_entry(base->Aux_id());
04788     if (ST_sclass(psym->St()) != SCLASS_FORMAL)
04789       return FALSE;
04790     if (ST_is_optional_argument(psym->St()))
04791       return FALSE;
04792     TY_IDX ty_idx = ST_type(psym->St());
04793     if (TY_kind(ty_idx) != KIND_POINTER)
04794       return FALSE;
04795     ty_idx = TY_pointed(ty_idx);
04796     if (TY_kind(ty_idx) != KIND_ARRAY)
04797       return FALSE;
04798     if (TY_size(ty_idx) == 0) // constant bounds
04799       return FALSE;
04800     if (Offset() < 0)
04801       return FALSE;   // will be out of bounds
04802     return (Offset() + MTYPE_byte_size(Dsctyp())) <= TY_size(ty_idx);
04803     }
04804   case CK_OP:
04805     if (!OPCODE_Can_Be_Speculative(Op())) {
04806       return FALSE;
04807     }
04808     else {
04809       for (INT i = 0; i < Kid_count(); i++) {
04810   if (!Opnd(i)->Can_be_speculated(opt_stab)) {
04811     return FALSE;
04812   }
04813       }
04814       return TRUE;
04815     }
04816   case CK_LDA:
04817   case CK_CONST:
04818   case CK_RCONST:
04819     return TRUE;
04820   default:
04821     FmtAssert(FALSE, ("CODEREP::Can_be_speculated: unknown kind"));
04822     return FALSE;
04823   }
04824 }
04825 
04826 // ====================================================================
04827 // Reset_isop_visited - reset a specific ISOP_VISITED bit in
04828 // all the CK_OP nodes in the tree; can assume that if this flag is not 
04829 // set, it is not set in the entire subtree rooted at that node.
04830 // It passes through the CK_IVAR nodes to get to the CK_OPs underneath.
04831 // Used by:
04832 //  Contains_only_the_var()   ISOP_CONTAIN_VISITED
04833 //  CODEREP::Antloc()   ISOP_ANTLOC_VISITED
04834 //  CODEREP::Antloc_rec()   ISOP_ANTLOC_VISITED
04835 //  BB_LOOP::Invariant_cr()   ISOP_INVARIANT_VISITED
04836 //  BB_LOOP::Invariant_cr_rec() ISOP_INVARIANT_VISITED
04837 //  MAIN_EMITTER::Check_expr_resolves_to_const() ISOP_EMIT_CONST_VISITED
04838 // ====================================================================
04839 void
04840 CODEREP::Reset_isop_visited(ISOP_FLAG flag)
04841 {
04842   if (Kind() == CK_OP) {
04843     if (!Is_isop_flag_set(flag))
04844       return;
04845     for  (INT32 i = 0; i < Kid_count(); i++) 
04846       Opnd(i)->Reset_isop_visited(flag);
04847     Reset_isop_flag(flag);
04848   } else if (Kind() == CK_IVAR) {
04849     CODEREP *base1, *base2;
04850     if (base1 = Ilod_base())  // if load base exists, follow it
04851       base1->Reset_isop_visited(flag);
04852     if ((base2 = Istr_base()) && base1 != base2) // if store base != load
04853       base2->Reset_isop_visited(flag);    //    then follow it
04854     if (Opr() == OPR_MLOAD)
04855       Mload_size()->Reset_isop_visited(flag);
04856     if (Opr() == OPR_ILOADX)
04857       Index()->Reset_isop_visited(flag);
04858   }
04859 }
04860 
04861 // Antloc (public) - non-recursive wrapper for Antloc_rec (private)
04862 // resets ISOP_ANTLOC_VISITED bit if Antloc_rec returns TRUE
04863 BOOL
04864 CODEREP::Antloc(BB_NODE *bb)
04865 {
04866   BOOL ret = Antloc_rec(bb);
04867   if (ret && WOPT_Enable_Prune)
04868     Reset_isop_visited(ISOP_ANTLOC_VISITED);
04869   return ret;
04870 }
04871 
04872 // Antloc_rec (private):
04873 // Test if the coderep is antloc by traversing the tree and test all
04874 // terminal nodes are defined locally.
04875 // NOTE: the setting an resetting of ISOP_ANTLOC_VISITED to control
04876 //   the exponential behavior of this routine is modelled after
04877 //   Contains_only_the_var in opt_prop.cxx.
04878 BOOL
04879 CODEREP::Antloc_rec(BB_NODE *bb)
04880 {
04881   MU_LIST_ITER mu_iter;
04882   switch (Kind()) {
04883   case CK_VAR:
04884     if (Is_flag_set(CF_IS_ZERO_VERSION))
04885       Warn_todo("CODEREP::Antloc_rec: Testing Antloc for CR of zero version");
04886     if (Defstmt() == NULL)
04887       return TRUE;
04888     else if (Is_flag_set(CF_DEF_BY_PHI))
04889       return TRUE;
04890     else
04891       return Defstmt()->Bb() != bb;
04892   case CK_IVAR:
04893     {
04894       CODEREP *base = Ilod_base() ? Ilod_base() : Istr_base();
04895       if (!base->Antloc_rec(bb))
04896   return FALSE;
04897       MU_NODE *mnode = Ivar_mu_node();
04898       if (mnode && mnode->Is_Valid()) {
04899   if (!mnode->OPND()->Antloc_rec(bb))
04900     return FALSE;
04901   // pv 385408, iload inserted by IRM has zero version vsym in mu
04902   // assume the worst case
04903   if (mnode->OPND()->Is_flag_set(CF_IS_ZERO_VERSION))
04904     return FALSE;
04905       }
04906     }
04907     // Ivar_defstmt is NULL all the time!
04908     if (Ivar_defstmt() == NULL)
04909        return TRUE;
04910     else if (Is_flag_set(CF_DEF_BY_PHI))
04911        return TRUE;
04912     else
04913        return Ivar_defstmt()->Bb() != bb;
04914     
04915   case CK_OP:
04916     {
04917       if (Is_isop_flag_set(ISOP_ANTLOC_VISITED) && WOPT_Enable_Prune)
04918   return TRUE;
04919       for (INT32 i = 0; i < Kid_count(); i++) {
04920   if (! Opnd(i)->Antloc_rec(bb)) {
04921     if (WOPT_Enable_Prune) {
04922       for (INT32 j = 0; j < i; j++) // reset ones visited so far
04923         Opnd(j)->Reset_isop_visited(ISOP_ANTLOC_VISITED);
04924     }
04925     return FALSE;
04926   }
04927       }
04928       if (WOPT_Enable_Prune)
04929   Set_isop_flag(ISOP_ANTLOC_VISITED);
04930     }
04931     return TRUE;
04932   case CK_LDA:
04933   case CK_CONST:
04934   case CK_RCONST:
04935     return TRUE;
04936   }
04937   return FALSE;
04938 }
04939 
04940 
04941 // Returns TRUE if this is divisable by cr
04942 BOOL
04943 CODEREP::Divisable(const CODEREP *cr, OPT_STAB *opt_stab) const
04944 {
04945   // only handle constants
04946   if (cr->Kind() != CK_CONST || cr->Const_val() == 0)
04947     return FALSE;
04948   
04949   // Always divisable by +1 or -1.
04950   if (cr->Const_val() == 1)
04951     return TRUE;
04952   else if (cr->Const_val() == -1)
04953     return TRUE;
04954 
04955   switch (Kind()) {
04956   case CK_CONST:
04957     if ((Const_val() % cr->Const_val()) == 0)
04958       return TRUE;
04959     return FALSE;
04960   
04961   case CK_VAR: 
04962     {
04963       TY_IDX ty = Lod_ty();
04964       if (ty != 0 && TY_kind(ty) == KIND_POINTER) {
04965   TY_IDX ty_pointed = TY_pointed(ty);
04966   if (ty_pointed != ((TY_IDX) 0) &&
04967       (TY_align(ty_pointed) % cr->Const_val()) == 0)
04968     return TRUE;
04969       } 
04970       if (Defstmt() != NULL && !Is_flag_set((CR_FLAG) (CF_DEF_BY_PHI|CF_DEF_BY_CHI))) {
04971   return Defstmt()->Rhs()->Divisable(cr, opt_stab);
04972       }
04973     }
04974     return FALSE;
04975     
04976   case CK_LDA:
04977     {
04978       if ((Offset() % cr->Const_val()) != 0)
04979   return FALSE;
04980       ST *st = opt_stab->Aux_stab_entry(Lda_aux_id())->St();
04981       if (st) {
04982   INT32 align = Adjusted_Alignment(st);
04983   if ((align % cr->Const_val()) == 0)
04984     return TRUE;
04985       }
04986     }
04987     return FALSE;     
04988     
04989   case CK_OP:
04990     {
04991       OPERATOR opr = Opr();
04992       switch (opr) {
04993       case OPR_ADD:
04994       case OPR_SUB:
04995   return Opnd(0)->Divisable(cr, opt_stab) && Opnd(1)->Divisable(cr, opt_stab);
04996       case OPR_ARRAY:
04997   return Opnd(0)->Divisable(cr, opt_stab) && (Elm_siz() % cr->Const_val()) == 0;
04998       }
04999     }
05000     return FALSE;
05001   } 
05002   return FALSE;
05003 }
05004 
05005 // Given an expression tree, infer if the result computed is a system address;
05006 // used by LFTR.  Potentially it is useful for strength reduction as well.
05007 ADDRESSABILITY
05008 CODEREP::Check_if_result_is_address(OPT_STAB *opt_stab) const
05009 {
05010   ADDRESSABILITY res0, res1;
05011 
05012   if (! MTYPE_is_integral(Dtyp()))
05013     return ADDRESSABILITY_NOT_ADDRESS;
05014 
05015   switch (Kind()) {
05016   case CK_LDA: 
05017     return ADDRESSABILITY_IS_ADDRESS;
05018   case CK_CONST:
05019   case CK_RCONST:
05020     return ADDRESSABILITY_NOT_ADDRESS;
05021   case CK_VAR: {
05022     AUX_STAB_ENTRY *aux = opt_stab->Aux_stab_entry(Aux_id());
05023     // check if info cached in aux_stab_entry by EPRE
05024     if (aux->Is_address())
05025       return ADDRESSABILITY_IS_ADDRESS;
05026     if (aux->Not_address())
05027       return ADDRESSABILITY_NOT_ADDRESS;
05028     // determine according to Lod_ty()
05029     if (TY_kind(Lod_ty()) == KIND_POINTER) 
05030       return ADDRESSABILITY_IS_ADDRESS;
05031     return ADDRESSABILITY_UNKNOWN;
05032     }
05033   case CK_IVAR:
05034     // determine according to Ilod_ty()
05035     if (OPERATOR_is_scalar_iload (Opr()) &&
05036   TY_kind(Ilod_ty()) ==KIND_POINTER)
05037       return ADDRESSABILITY_IS_ADDRESS;
05038     return ADDRESSABILITY_UNKNOWN;
05039   case CK_OP: {
05040     OPERATOR opr = Opr();
05041     switch (opr) {
05042     // n-ary operators
05043     case OPR_ARRAY: return ADDRESSABILITY_IS_ADDRESS;
05044     // ternary operators
05045     case OPR_SELECT: 
05046       res1 = Opnd(1)->Check_if_result_is_address(opt_stab); 
05047       return (res1 == ADDRESSABILITY_UNKNOWN) ? 
05048       Opnd(2)->Check_if_result_is_address(opt_stab) : res1;
05049     // binary operators
05050     case OPR_SHL: case OPR_LSHR: case OPR_ASHR: 
05051     case OPR_LAND: case OPR_LIOR:
05052     case OPR_BAND: case OPR_BIOR: case OPR_BNOR: case OPR_BXOR: 
05053     case OPR_EQ: case OPR_NE: 
05054     case OPR_GE: case OPR_GT: case OPR_LE: case OPR_LT:
05055     case OPR_DIV: case OPR_MOD: case OPR_REM: case OPR_DIVREM:
05056     case OPR_MPY: case OPR_HIGHMPY: case OPR_XMPY:
05057       return ADDRESSABILITY_NOT_ADDRESS;
05058     case OPR_MAX: case OPR_MIN: case OPR_MINMAX:
05059       res0 = Opnd(0)->Check_if_result_is_address(opt_stab); 
05060       if (res0 == ADDRESSABILITY_UNKNOWN)
05061   return ADDRESSABILITY_UNKNOWN;
05062       return Opnd(1)->Check_if_result_is_address(opt_stab); 
05063     case OPR_ADD: case OPR_SUB:
05064       res0 = Opnd(0)->Check_if_result_is_address(opt_stab); 
05065       if (res0 == ADDRESSABILITY_UNKNOWN)
05066   return ADDRESSABILITY_UNKNOWN;
05067       res1 = Opnd(1)->Check_if_result_is_address(opt_stab); 
05068       if (res1 == ADDRESSABILITY_UNKNOWN)
05069   return ADDRESSABILITY_UNKNOWN;
05070       if (res0 == res1) {
05071         if (res0 == ADDRESSABILITY_IS_ADDRESS)
05072           return ADDRESSABILITY_NOT_ADDRESS;
05073   return res0;
05074       }
05075       else return ADDRESSABILITY_IS_ADDRESS;
05076     // unary operators
05077     case OPR_CVT: case OPR_TAS:
05078     case OPR_NEG: case OPR_PAREN: case OPR_MINPART: case OPR_MAXPART: 
05079     case OPR_PARM:
05080       return Opnd(0)->Check_if_result_is_address(opt_stab); 
05081     case OPR_CVTL:
05082     case OPR_ABS: case OPR_SQRT: case OPR_RSQRT: case OPR_RECIP: 
05083     case OPR_RND: case OPR_TRUNC: case OPR_CEIL: case OPR_FLOOR: 
05084     case OPR_BNOT: case OPR_LNOT: case OPR_LOWPART: case OPR_HIGHPART:
05085       return ADDRESSABILITY_NOT_ADDRESS;
05086     default: ;
05087     }
05088     return ADDRESSABILITY_UNKNOWN;
05089     }
05090   default: ;
05091   }
05092   return ADDRESSABILITY_UNKNOWN;
05093 }
05094 
05095 // Print STMTREP tree
05096 //
05097 void
05098 STMTREP::Print(FILE *fp) const
05099 {
05100   if (_opr == OPR_PRAGMA) {
05101     fprintf(fp, ">"); // mark line visually as htable dump
05102     fdump_tree( fp, Orig_wn() );
05103     return;
05104   }
05105 
05106   if (Has_mu()) {
05107     MU_NODE *mnode;
05108     MU_LIST_ITER mu_iter;
05109     fprintf(fp, " mu<");
05110     if (Mu_list()) {
05111       FOR_ALL_NODE(mnode, mu_iter, Init(Mu_list())) 
05112   if (mnode->OPND())  // Check if the MU has been deleted.
05113     fprintf(fp, "%d/cr%d ", mnode->Aux_id(), mnode->OPND()->Coderep_id());
05114     }
05115     fprintf(fp, ">\n"); 
05116   }
05117 
05118   if (Rhs()) Rhs()->Print(1, fp);
05119   if (OPERATOR_is_scalar_istore (_opr) || _opr == OPR_ISTOREX ||
05120       _opr == OPR_MSTORE)
05121     Lhs()->Istr_base()->Print(1, fp);
05122   if (_opr == OPR_MSTORE)
05123     Lhs()->Mstore_size()->Print(1, fp);
05124   if (_opr == OPR_ISTOREX)
05125     Lhs()->Index()->Print(1, fp);
05126   Print_node(fp);
05127   if (OPERATOR_is_call(_opr)) 
05128     fprintf(fp, " call-flag:0x%x", Call_flags());
05129   fprintf(fp, " b=%s",Print_bit());
05130   fprintf(fp, " flags:0x%x", _flags&0x1f );
05131   fprintf(fp, " pj%d", Proj_op_uses());
05132   fprintf(fp, " Sid%d\n", Stmt_id());
05133 
05134   if (Has_chi()) {
05135     CHI_NODE *cnode;
05136     CHI_LIST_ITER chi_iter; 
05137     fprintf(fp,"chi <");
05138     FOR_ALL_NODE(cnode, chi_iter, Init(Chi_list())) {
05139       fprintf(fp, "%d", cnode->Aux_id());
05140       if (cnode->Live())  // Check if the MU has been deleted.
05141   fprintf(fp, "/cr%d/cr%d",
05142     cnode->RESULT()->Coderep_id(), cnode->OPND()->Coderep_id()); 
05143       fprintf(fp, " ");
05144     }
05145     fprintf(fp, "> 0x%p\n", this);
05146   }
05147 }
05148 
05149 void
05150 dump_stmtrep (STMTREP *sr)
05151 {
05152   sr->Print(stdout);
05153 }
05154 
05155 // Print the STMTREP node
05156 //
05157 void
05158 STMTREP::Print_node(FILE *fp) const
05159 {
05160   switch (_opr) {
05161   case OPR_STBITS:
05162   case OPR_STID:
05163     fprintf(fp, ">"); // mark line visually as htable dump
05164 #if defined(TARG_NVISA)
05165     fprintf(fp, "%s %s", OPERATOR_name(_opr), MTYPE_name(Lhs()->Dsctyp()));
05166     fprintf(fp, " sym%dv%d", Lhs()->Aux_id(), Lhs()->Version());
05167 #else
05168     fprintf(fp, "%s %s %s sym%dv%d", OPERATOR_name(_opr),
05169       MTYPE_name(Lhs()->Dtyp()), MTYPE_name(Lhs()->Dsctyp()),
05170       Lhs()->Aux_id(), Lhs()->Version());
05171 #endif
05172     fprintf(fp, " %d", Lhs()->Offset());
05173     fprintf(fp, " <u=%d cr%d>", Lhs()->Usecnt(), Lhs()->Coderep_id());
05174     break;
05175   case OPR_ISTORE:
05176   case OPR_ISTBITS:
05177     fprintf(fp, ">"); // mark line visually as htable dump
05178     fprintf(fp, "%s %s", OPERATOR_name(_opr), MTYPE_name(Lhs()->Dsctyp()));
05179     fprintf(fp, " %d", Lhs()->Offset());
05180     fprintf(fp, " <u=%d cr%d>", Lhs()->Usecnt(), Lhs()->Coderep_id());
05181     break;
05182   case OPR_ISTOREX:
05183     fprintf(fp, ">"); // mark line visually as htable dump
05184     fprintf(fp, "%s", OPERATOR_name(_opr));
05185     fprintf(fp, " <u=%d cr%d>",Lhs()->Usecnt(), Lhs()->Coderep_id());
05186     break;
05187   case OPR_MSTORE:
05188     fprintf(fp, ">"); // mark line visually as htable dump
05189     fprintf(fp, "%s", OPERATOR_name(_opr));
05190     fprintf(fp, " <u=%d cr%d>",Lhs()->Usecnt(), Lhs()->Coderep_id());
05191     break;
05192   case OPR_TRUEBR:
05193   case OPR_FALSEBR:
05194   case OPR_LABEL:
05195   case OPR_GOTO:
05196   case OPR_REGION_EXIT:
05197     fprintf(fp, ">"); // mark line visually as htable dump
05198     fprintf(fp, "%s %d", OPERATOR_name(_opr), Label_number());
05199     break;
05200   default:
05201     fprintf(fp, ">"); // mark line visually as htable dump
05202     fprintf(fp, "%s", OPERATOR_name(_opr));
05203   }
05204 
05205   if ( Black_box() ) {
05206     fprintf(fp, " (black-box)");
05207   }
05208 }
05209 
05210 // print the STMTREP to a string
05211 char *
05212 STMTREP::Print_str(BOOL name_format)
05213 {
05214   static char buf[100];
05215 
05216   buf[0] = '\0';
05217 
05218   if (!name_format) {
05219     if (Lhs())
05220       strcat(buf,Lhs()->Print_str(name_format));
05221     if (Rhs())
05222       strcat(buf,Rhs()->Print_str(name_format));
05223     return buf;
05224   }
05225 
05226   switch (_opr) {
05227     case OPR_STID:
05228     case OPR_STBITS:
05229       sprintf(buf,"%s sym%dv%d",
05230         OPERATOR_name(_opr)+4,Lhs()->Aux_id(),Lhs()->Version());
05231       break;
05232     case OPR_ISTORE:
05233     case OPR_ISTBITS:
05234     case OPR_ISTOREX:
05235     case OPR_MSTORE:
05236       sprintf(buf,"%s",OPERATOR_name(_opr)+4);
05237       break;
05238     default:
05239       sprintf(buf,"%s",OPERATOR_name(_opr)+4);
05240   }
05241   if (strlen(buf) < Nchars) { // pad with spaces to Nchars
05242     INT i;
05243     for (i = strlen(buf); i < Nchars; ++i)
05244       buf[i] = ' ';
05245     buf[i] = '\0';
05246   }
05247   return buf;
05248 }
05249 
05250 // Print out the CR
05251 void
05252 CODEMAP::Print_CR(CODEREP *cr, FILE *fp) const
05253 {
05254   INT32 i;
05255   fprintf(fp, "%ccr%d b=%s ",(cr->Usecnt() <= 0) ? '*' : ' ',
05256           cr->Coderep_id(),cr->Print_bit());
05257   cr->Print_node(0, fp);
05258   if (cr->Kind() == CK_OP) {
05259     fprintf(fp, " kids<");
05260     for (i = 0; i < cr->Kid_count(); i++)
05261       fprintf(fp, "cr%d ", cr->Get_opnd(i)->Coderep_id());
05262     fprintf(fp, ">");
05263   } else if (cr->Kind() == CK_IVAR) {
05264     if (cr->Ilod_base()) {
05265       fprintf(fp, " ilod<cr%d>", cr->Ilod_base()->Coderep_id());
05266     }
05267     if (cr->Istr_base()) {
05268       fprintf(fp, " istr<cr%d>", cr->Istr_base()->Coderep_id());
05269     }
05270     MU_NODE *mnode = cr->Ivar_mu_node();
05271     if (mnode && mnode->OPND()) { // Check if the MU has been deleted.
05272       fprintf(fp, " mu<");
05273       fprintf(fp, "%d/cr%d", mnode->Aux_id(), mnode->OPND()->Coderep_id());
05274       fprintf(fp, ">");
05275     }
05276   }
05277   fprintf(fp, " 0x%p",cr);
05278   fprintf(fp, "\n");
05279 }
05280 
05281 //  Print out the statement rep
05282 void
05283 CODEMAP::Print_SR(STMTREP *stmt, FILE *fp) const
05284 {
05285   fprintf(fp, " SR %p b=%s ", stmt, stmt->Print_bit());
05286   stmt->Print_node(fp);
05287   fprintf(fp, " kids<");
05288   if ((stmt->Opr() == OPR_CALL) ||
05289       (stmt->Opr() == OPR_ICALL) ||
05290       (stmt->Opr() == OPR_INTRINSIC_CALL)) {
05291     CODEREP *cr = stmt->Rhs();
05292     INT kcount = cr->Kid_count();
05293     for (INT i = 0; i < kcount; i++) {
05294       fprintf(fp, "cr%d ", cr->Get_opnd(i)->Coderep_id());
05295     }
05296   }
05297   if (OPERATOR_is_scalar_istore (stmt->Opr()) || stmt->Opr() == OPR_ISTOREX)
05298     fprintf(fp, "cr%d ", stmt->Lhs()->Coderep_id());
05299   if (stmt->Rhs())
05300     fprintf(fp, "cr%d ", stmt->Rhs()->Coderep_id());
05301   fprintf(fp, ">");
05302   if (stmt->Has_mu()) {
05303     MU_NODE *mnode;
05304     MU_LIST_ITER mu_iter;
05305     fprintf(fp, " mu<");
05306     if (stmt->Mu_list()) {
05307       FOR_ALL_NODE(mnode, mu_iter, Init(stmt->Mu_list())) 
05308   if (mnode->OPND())  // Check if the MU has been deleted.
05309     fprintf(fp, "%d/cr%d ", mnode->Aux_id(), mnode->OPND()->Coderep_id());
05310     }
05311     fprintf(fp, ">\n");
05312   }
05313   if (stmt->Has_chi()) {
05314     CHI_NODE *cnode;
05315     CHI_LIST_ITER chi_iter;
05316     fprintf(fp, " chi<");
05317     if (stmt->Chi_list()) {
05318       FOR_ALL_NODE(cnode, chi_iter, Init(stmt->Chi_list())) {
05319   fprintf(fp, "%d", cnode->Aux_id());
05320   if (cnode->Live())  // Check if the MU has been deleted.
05321     fprintf(fp, "/cr%d/cr%d", 
05322     cnode->RESULT()->Coderep_id(), cnode->OPND()->Coderep_id());
05323   fprintf(fp, " ");
05324       }
05325     }
05326     fprintf(fp, ">");
05327   }
05328   fprintf(fp," 0x%p" ,stmt);
05329   fprintf(fp, "\n");
05330 }
05331 
05332 
05333 // Print out the whole CODEMAP table.
05334 //
05335 void
05336 CODEMAP::Print(FILE *fp) const
05337 {
05338   CODEREP_ITER cr_iter;
05339   CODEREP *cr,*bucket;
05340   CODEMAP_ITER codemap_iter;
05341   INT32 count;
05342   INT32 scalar_var_count = 0;
05343   INT32 unique_vsym_count = 0;
05344   INT32 lda_vsym_count = 0;
05345   INT32 ivar_count = 0;
05346   
05347   UINT32 sum_bucket_len = 0;
05348   UINT32 ssq_bucket_len = 0;
05349   UINT32 max_bucket_len = 0;
05350   UINT32 num_nonempty_buckets = 0;
05351 
05352   fprintf(fp, "- - - Default vsym is sym%1d\n", Sym()->Default_vsym());
05353   fprintf(fp, "- - - Return vsym is sym%1d\n", Sym()->Return_vsym());
05354 
05355 #ifndef KEY
05356   // print coderep nodes in htable:
05357   count = 0;
05358   FOR_ALL_ELEM(bucket, codemap_iter, Init(this)) {
05359     UINT32 bucket_len = 0;
05360     if (bucket)
05361       fprintf(fp, "----bucket %d\n", codemap_iter.Cur());
05362     FOR_ALL_NODE(cr, cr_iter, Init(bucket)) {
05363       Print_CR(cr, fp);
05364       count++;
05365       if (cr->Kind() == CK_IVAR && cr->Opr() != OPR_PREFETCH) 
05366         ivar_count++;
05367       bucket_len++;
05368     }
05369     if (bucket_len != 0) {
05370       ++num_nonempty_buckets;
05371     }
05372     sum_bucket_len += bucket_len;
05373     ssq_bucket_len += bucket_len * bucket_len;
05374     max_bucket_len = MAX(max_bucket_len, bucket_len);
05375   }
05376   fprintf(fp, "%d of %d buckets are nonempty.\n",
05377     num_nonempty_buckets, size);
05378   fprintf(fp, "Average nonempty bucket (chain) length: %g\n",
05379     ((double) sum_bucket_len) / num_nonempty_buckets);
05380   fprintf(fp, "Average          bucket (chain) length: %g\n",
05381     ((double) sum_bucket_len) / size);
05382   fprintf(fp, "Bucket len  (nonempty)  std. deviation: %g\n",
05383     (double) sqrt(((double) num_nonempty_buckets * ssq_bucket_len -
05384        sum_bucket_len * sum_bucket_len) /
05385       (num_nonempty_buckets * num_nonempty_buckets)));
05386   fprintf(fp, "Bucket length           std. deviation: %g\n",
05387     (double) sqrt(((double) size * ssq_bucket_len -
05388        sum_bucket_len * sum_bucket_len) /
05389       (size * size)));
05390   fprintf(fp, "Maximum         bucket          length: %u\n\n",
05391     max_bucket_len);
05392 #endif
05393 
05394   CFG_ITER cfg_iter;
05395   STMTREP *stmt;
05396   BB_NODE *bb;
05397 
05398   // print coderep nodes in aux_stab:
05399   AUX_ID i;
05400   AUX_STAB_ITER aux_stab_iter(Sym());
05401   FOR_ALL_NODE(i, aux_stab_iter, Init()) {
05402     AUX_STAB_ENTRY *aux = Sym()->Aux_stab_entry(i);
05403     fprintf(fp, "----aux_id %d\n", i);
05404     FOR_ALL_NODE(cr, cr_iter, Init(aux->Cr_list())) {
05405       Print_CR(cr, fp);
05406       count++;
05407       Is_True(cr->Kind() == CK_VAR, ("CODEMAP::Print: coderep in aux_stab not CK_VAR"));
05408       if (aux->Is_real_var())
05409         scalar_var_count++;
05410       else if (Sym()->Unique_vsym(cr->Aux_id()))
05411         unique_vsym_count++;
05412       else if (Sym()->Lda_vsym(cr->Aux_id()))
05413         lda_vsym_count++;
05414     }
05415   }
05416 
05417   fprintf(fp, "\nNumber of CODEREP nodes = %d (%d scalar vars, "
05418     "%d unique vsyms, %d lda vsyms, %d ivars)\n", count,
05419     scalar_var_count, unique_vsym_count, lda_vsym_count,
05420     ivar_count);
05421 
05422   count = 0;
05423   FOR_ALL_NODE(bb, cfg_iter, Init(_cfg)) {
05424     // stupid way of doing a constructor only because Init() doesn't
05425     // take any argument.
05426     STMTREP_ITER stmt_iter(bb->Stmtlist());
05427     FOR_ALL_NODE(stmt, stmt_iter, Init()) {
05428       Print_SR(stmt, fp);
05429       count++;
05430     }
05431   }
05432   fprintf(fp, "\nNumber of STMTREP nodes = %d\n\n", count);
05433 }
05434 
05435 // Reset the ISOP_DCE_VISITED and ISOP_RETVSYM_VISITED flag
05436 // in the CODEREP
05437 //
05438 void
05439 CODEMAP::Reset_DCE_visited_flags()
05440 {
05441   CODEREP_ITER cr_iter;
05442   CODEREP *cr,*bucket;
05443   CODEMAP_ITER codemap_iter;
05444 
05445   FOR_ALL_ELEM(bucket, codemap_iter, Init(this)) {
05446     FOR_ALL_NODE(cr, cr_iter, Init(bucket)) {
05447       if (cr->Kind() == CK_OP) {
05448   cr->Reset_isop_flag(ISOP_DCE_VISITED);
05449   cr->Reset_isop_flag(ISOP_RETVSYM_VISITED);
05450       }
05451     }
05452   }
05453 }
05454 
05455 
05456 
05457 // ====================================================================
05458 // Determine if the assignment is " i = i " that can be deleted by 
05459 //   by the joint effort of COPYPROP and DCE.
05460 // ====================================================================
05461 BOOL
05462 STMTREP::Is_identity_assignment_removable() const
05463 {
05464   if (! OPERATOR_is_scalar_store (Opr()))
05465     return FALSE;
05466 
05467   const CODEREP *lhs = Lhs();
05468   const CODEREP *rhs = Rhs();
05469 
05470   // store to a volatile location?
05471   if ( lhs->Is_var_volatile() )
05472     return FALSE;
05473 
05474   if (Has_zver())
05475     return FALSE;
05476 
05477   // statements of form i = i are not required (unless volatile)
05478   //  (even it stores a dedicated register)
05479   if (rhs->Kind()==CK_VAR && rhs->Aux_id()==lhs->Aux_id() &&
05480       !rhs->Is_var_volatile()) 
05481     return TRUE;
05482 
05483   return FALSE;
05484 }
05485 
05486 // ====================================================================
05487 // Determine if statement has a reference to a volatile memory location
05488 // ====================================================================
05489 
05490 BOOL 
05491 STMTREP::Contains_volatile_ref(const BVECTOR &cr_vol_map) const
05492 {
05493    BOOL            pred = FALSE;
05494    CODEREP * const rhs = Rhs();
05495    CODEREP * const lhs = Lhs();
05496    
05497    if (OPCODE_is_fake(Op()))
05498    {
05499       for (INT32 i = 0; !pred && i < rhs->Kid_count(); i++)
05500    if (cr_vol_map[rhs->Opnd(i)->Coderep_id()])
05501       pred = TRUE;
05502    }
05503    else if ((rhs != NULL && cr_vol_map[rhs->Coderep_id()]))
05504    {
05505       pred = TRUE;
05506    }
05507    if (lhs != NULL && cr_vol_map[lhs->Coderep_id()])
05508    {
05509       pred = TRUE;
05510    }
05511    return pred;
05512 } //STMTREP::Contains_volatile_ref
05513 
05514 
05515 // ====================================================================
05516 // Determine if statement has a chi whose result is zero version
05517 // ====================================================================
05518 BOOL
05519 STMTREP::Has_zero_version_chi(void) const
05520 {
05521   if (! Has_chi())
05522     return FALSE;
05523   CHI_LIST_ITER chi_iter;
05524   CHI_NODE *cnode;
05525   CHI_LIST *chi_list = Chi_list();
05526   FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
05527     if (cnode->Live() && 
05528         (cnode->RESULT()->Is_flag_set(CF_IS_ZERO_VERSION) ||
05529          cnode->RESULT()->Is_flag_set(CF_INCOMPLETE_USES)))
05530       return TRUE;
05531   }
05532   return FALSE;
05533 }
05534 
05535 
05536 void
05537 CODEMAP::Insert_var_phi(CODEREP *new_lhs, BB_NODE *bb)
05538 {
05539   BB_NODE_SET_ITER    df_iter;
05540   BB_NODE *bb_phi;
05541   AUX_ID aux = new_lhs->Aux_id();
05542 
05543   FOR_ALL_ELEM (bb_phi, df_iter, Init(bb->Dom_frontier())) {
05544     PHI_NODE *phi = Lookup_var_phi(bb_phi, aux);
05545 
05546     // Fix 471645:  phis inserted by EPRE/LPRE are annotated with the INCOMPLETE flag.
05547     // The flag means a phi might not be found on this definition's dominance frontier.
05548     // For this reason, Insert_var_phi should recursively visit all DF+ to check
05549     // if phi should be inserted.
05550 
05551     if (phi == NULL || !phi->Live()) {
05552       // Insert a new phi node at the dominator frontiers.
05553       if (phi == NULL) {
05554   phi = bb_phi->Phi_list()->New_phi_node(aux, Ssa()->Mem_pool(), bb_phi);
05555 
05556   // Enter into the var phi hash table.
05557   Enter_var_phi_hash(phi);
05558 
05559       } else {
05560   phi->Reset_dse_dead();
05561   phi->Reset_dce_dead();
05562   phi->Set_res_is_cr();
05563   phi->Set_live();
05564       }
05565 
05566       CODEREP *phi_res = Add_def(aux, -1, 
05567          NULL, new_lhs->Dtyp(), new_lhs->Dsctyp(),
05568          new_lhs->Offset(), new_lhs->Lod_ty(),
05569          new_lhs->Field_id(), TRUE);
05570       phi_res->Set_flag(CF_DEF_BY_PHI);
05571       phi_res->Set_defphi(phi);
05572       phi->Set_live();
05573       phi->Set_result(phi_res);
05574 
05575       Is_Trace(Tracing(),
05576      (TFile, "CODEMAP: insert var phi at BB%d for sym%d\n", bb->Id(),
05577       aux));
05578 
05579       // Put zero versions at the phi opnds.
05580       CODEREP *zcr = Ssa()->Get_zero_version_CR(aux, Opt_stab(), 0);
05581       BB_NODE *pred;
05582       BB_LIST_ITER bb_iter;
05583       INT opnd = 0;
05584       FOR_ALL_ELEM (pred, bb_iter, Init(bb_phi->Pred())) {
05585   phi->Set_opnd(opnd, zcr);
05586   opnd++;
05587       }
05588 
05589       // Recursively introduce phi nodes
05590       Insert_var_phi(new_lhs, bb_phi);
05591 
05592     } else if (phi->Incomplete()) {
05593 
05594       phi->Reset_incomplete();  // phi will be inserted at each of its DF+
05595 
05596       // Recursively introduce phi nodes
05597       Insert_var_phi(new_lhs, bb_phi);
05598     }
05599   }
05600 }
05601 
05602 void STMTREP::Clone(STMTREP *sr, CODEMAP *htable, MEM_POOL *pool)
05603 {
05604   BCOPY(sr,this,sizeof(STMTREP));
05605   
05606   Set_Next(NULL); Set_Prev(NULL);
05607 
05608   switch (sr->Opr()) {
05609   case OPR_STID:
05610   case OPR_STBITS:
05611     {
05612       CODEREP *cr = sr->Lhs();
05613       Set_lhs(htable->Add_def(cr->Aux_id(), -1,
05614             this, cr->Dtyp(), cr->Dsctyp(),
05615             cr->Offset(), cr->Lod_ty(), cr->Field_id(),
05616             true));
05617       if (sr->Has_mu()) {
05618   Set_mu_list( CXX_NEW(MU_LIST, pool));
05619   Mu_list()->Clone_mu_list(sr->Mu_list(), pool);
05620       } else
05621   Set_mu_list(NULL);
05622 
05623       if (sr->Has_chi()) {
05624   Set_chi_list( CXX_NEW(CHI_LIST, pool));
05625   Chi_list()->Clone_chi_list(sr->Chi_list(), pool);
05626       } else 
05627   Set_chi_list(NULL);
05628     }
05629     break;
05630 
05631   case OPR_ISTORE:
05632   case OPR_ISTBITS:
05633   case OPR_MSTORE:
05634     {
05635       CODEREP *cr = sr->Lhs();
05636       OCC_TAB_ENTRY *occ = (OCC_TAB_ENTRY*) CXX_NEW(OCC_TAB_ENTRY, pool);
05637       occ->Clone(cr->Ivar_occ(), pool);
05638       MU_NODE *mnode = NULL;
05639       Set_lhs(htable->Add_idef(cr->Op(), occ,
05640              this,
05641              NULL, cr->Dtyp(), cr->Dsctyp(), cr->Ilod_ty(),
05642              cr->I_field_id(), cr->Offset(),
05643              cr->Mload_size(), NULL, cr->Istr_base(),
05644                                htable->Opt_stab()));
05645       Set_chi_list( CXX_NEW(CHI_LIST, pool));
05646       Chi_list()->Clone_chi_list(sr->Chi_list(), pool);
05647     }
05648     break;
05649 
05650   case OPR_ISTOREX:
05651     Is_True(FALSE, ("OPR_ISTOREX not expected."));
05652 
05653   default:
05654     if (sr->Has_mu()) {
05655       Set_mu_list( CXX_NEW(MU_LIST, pool));
05656       Mu_list()->Clone_mu_list(sr->Mu_list(), pool);
05657     } else
05658       Set_mu_list(NULL);
05659 
05660     if (sr->Has_chi()) {
05661       Set_chi_list( CXX_NEW(CHI_LIST, pool));
05662       Chi_list()->Clone_chi_list(sr->Chi_list(), pool);
05663     } else 
05664       Set_chi_list(NULL);
05665   }
05666 
05667   if (sr->Has_chi()) {
05668     CHI_LIST_ITER chi_iter;
05669     CHI_NODE *cnode;
05670     FOR_ALL_NODE( cnode, chi_iter, Init(Chi_list())) {
05671       if (!cnode->Dse_dead()) {
05672   CODEREP *cr = cnode->RESULT();
05673   CODEREP *newdef = htable->Add_def(cr->Aux_id(), -1,
05674             this, cr->Dtyp(), cr->Dsctyp(),
05675             cr->Offset(), cr->Lod_ty(),
05676             cr->Field_id(), TRUE);
05677   newdef->Set_flag(CF_DEF_BY_CHI);
05678   newdef->Set_defchi(cnode);
05679   cnode->Set_RESULT(newdef);
05680       }
05681     }
05682     Reset_has_zver();
05683   }
05684 }
05685 
05686 BOOL CODEREP::Has_volatile_content(void) const
05687 {
05688   switch(Kind()) {
05689   case CK_CONST:
05690   case CK_RCONST:
05691   case CK_LDA:
05692     return FALSE;
05693   case CK_VAR:
05694     return Is_var_volatile();
05695   case CK_IVAR:
05696     if (Opr() == OPR_MLOAD && Mload_size()->Has_volatile_content())
05697       return TRUE;
05698     if (Opr() == OPR_ILOADX && Index()->Has_volatile_content())
05699       return TRUE;
05700     if (Ilod_base()->Has_volatile_content())
05701       return TRUE;
05702     return Is_ivar_volatile();
05703   case CK_OP: {
05704       for (INT32 i=0; i < Kid_count(); i++)
05705   if (Opnd(i)->Has_volatile_content())
05706     return TRUE;
05707     }
05708   }
05709   return FALSE;
05710 }
05711 
05713 //
05714 //   Implementation of MEMOP_ANNOT_CR_SR_MGR 
05715 //
05717 //
05718 MEMOP_ANNOT_CR_SR_MGR::MEMOP_ANNOT_CR_SR_MGR (MEM_POOL* mp, BOOL trace):
05719   MEMOP_ANNOT_MGR(mp) {
05720 
05721   _imported = BS_Create_Empty (128, _mp);
05722   _exported = BS_Create_Empty (128, _mp);
05723 
05724   _trace = trace;
05725 }
05726  
05727 // Lookup the corresponding annotation 
05728 MEMOP_ANNOT*
05729 MEMOP_ANNOT_CR_SR_MGR::Get_annot (CODEREP* cr) {
05730   Is_True (cr != NULL, ("CODEREP is NULL"));
05731   CR_2_MEM_ANNOT_MAP::const_iterator iter = _cr_map.find ((const CODEREP*)cr);
05732   return iter != _cr_map.end () ? (*iter).second : NULL;
05733 }
05734   
05735 MEMOP_ANNOT_ITEM*
05736 MEMOP_ANNOT_CR_SR_MGR::Get_annot (CODEREP* cr, MEM_ANNOT_KIND kind) {
05737   Is_True (cr != NULL, ("CODEREP is NULL"));
05738 
05739   MEMOP_ANNOT* annot = Get_annot (cr);
05740   MEMOP_ANNOT_ITEM_VECT& v = annot->All_items ();
05741   for (MEMOP_ANNOT_ITEM_ITER iter = v.begin (); iter != v.end (); iter++) {
05742     if ((*iter).Kind () == kind) 
05743       return &(*iter);
05744   }
05745   return NULL;
05746 }
05747 
05748 MEMOP_ANNOT*
05749 MEMOP_ANNOT_CR_SR_MGR::Get_annot (STMTREP* sr) {
05750   Is_True (sr != NULL, ("STMTREP is NULL"));
05751 
05752   SR_2_MEM_ANNOT_MAP::const_iterator iter = _sr_map.find (sr);
05753   return iter != _sr_map.end () ? (*iter).second : NULL;
05754 }
05755 
05756 MEMOP_ANNOT_ITEM*
05757 MEMOP_ANNOT_CR_SR_MGR::Get_annot (STMTREP* sr, MEM_ANNOT_KIND kind) {
05758   Is_True (sr != NULL, ("STMTREP is NULL"));
05759 
05760   MEMOP_ANNOT* annot = Get_annot (sr);
05761   MEMOP_ANNOT_ITEM_VECT& v = annot->All_items ();
05762   for (MEMOP_ANNOT_ITEM_ITER iter = v.begin (); iter != v.end (); iter++) {
05763     if ((*iter).Kind () == kind) 
05764       return &(*iter);
05765   }
05766 }
05767 
05768 // Associate a MEMOP_ANNOT with given WN/CODEREP/STMTREP
05769 //
05770 void
05771 MEMOP_ANNOT_CR_SR_MGR::Add_annot (CODEREP* cr, const MEMOP_ANNOT_ITEM& annot_item) {
05772   Is_True (cr != NULL, ("CODEREP is NULL"));
05773 
05774   Is_True (cr->Kind() == CK_VAR || cr->Kind() == CK_IVAR, 
05775            ("Expression should be load"));
05776   MEMOP_ANNOT* annot = Get_annot (cr);  
05777   if (annot) 
05778     annot->Replace_or_add (annot_item); 
05779   else {
05780     annot = Alloc_annot ();
05781     annot->Replace_or_add (annot_item);
05782     _cr_map[cr] = annot; 
05783   }
05784 }
05785  
05786 void
05787 MEMOP_ANNOT_CR_SR_MGR::Add_annot 
05788   (STMTREP* stmt, const MEMOP_ANNOT_ITEM& annot_item) {
05789 
05790   Is_True (stmt != NULL, ("STMTREP is NULL"));
05791   Is_True (OPCODE_is_store (stmt->Op()), ("statement should be store"));
05792   
05793   MEMOP_ANNOT* annot = Get_annot (stmt);
05794   if (annot) 
05795     annot->Replace_or_add (annot_item); 
05796   else {
05797     annot = Alloc_annot ();
05798     annot->Replace_or_add (annot_item);
05799     _sr_map[stmt] = annot; 
05800   }
05801 }
05802 
05803 void
05804 MEMOP_ANNOT_CR_SR_MGR::Set_annot (CODEREP* cr, MEMOP_ANNOT* annot) {
05805 
05806   Is_True (cr != NULL, ("CODEREP is NULL"));
05807   Is_True (Alloc_by_this_class (annot), 
05808            ("annotation is not allocated by this class"));
05809   _cr_map[cr] = annot; 
05810 }
05811 
05812 void
05813 MEMOP_ANNOT_CR_SR_MGR::Set_annot (STMTREP* sr, MEMOP_ANNOT* annot) {
05814   Is_True (sr != NULL, ("STMTREP is NULL"));
05815   Is_True (Alloc_by_this_class (annot), 
05816            ("annotation is not allocated by this class"));
05817   _sr_map[sr] = annot;
05818 }
05819 
05820 // Transfer annotation from WN=>MEMOP_ANNOT map.
05821 //
05822 MEMOP_ANNOT*
05823 MEMOP_ANNOT_CR_SR_MGR::Import_annot (CODEREP* cr, MEMOP_ANNOT* annot) {
05824   MEMOP_ANNOT* t = Alloc_annot ();
05825   *t = *annot;
05826   Set_imported (t);
05827   Set_annot (cr,t);  
05828   Set_imported (t);
05829   return t;
05830 }
05831 
05832 MEMOP_ANNOT*
05833 MEMOP_ANNOT_CR_SR_MGR::Import_annot (STMTREP* sr,