Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
opt_addr_flags.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 #include "opt_alias_interface.h"  
00037 #include "opt_points_to.h"        
00038 #include "config_opt.h"           
00039 #include "symtab_access.h"
00040 #include "wn.h"
00041 #include "be_symtab.h"
00042 
00043 // Adjust address flags
00044 
00045 static BOOL suppress_all_warnings;
00046 static void Set_addr_saved_stmt(WN *wn, BOOL use_passed_not_saved);
00047 
00048 // wn is an actual parameter.  Search for LDAs under the expr that 
00049 // are not consumed by an ILOAD, and set their addr_saved flag.
00050 // warn is TRUE iff we should issue a DevWarn for each ST whose addr_saved
00051 // flag we set.
00052 static void
00053 Set_addr_saved_expr(WN *wn, BOOL warn)
00054 {
00055   OPCODE opc = WN_opcode(wn);
00056   Is_True(OPCODE_is_expression(opc),
00057           ("Update_addr_saved: opcode must be expression"));
00058 
00059   if (OPCODE_is_load(opc))
00060     return;
00061 
00062   if (OPCODE_operator(opc) == OPR_LDA) {
00063     ST *st = WN_st(wn);
00064     if (ST_class(st) == CLASS_VAR &&
00065         !ST_addr_saved(st)) {
00066       Set_ST_addr_saved(st);
00067       if (warn && !suppress_all_warnings)
00068         DevWarn("Set_addr_saved_expr: addr_saved flag of ST (%s) should be set.", 
00069                 ST_name(st));
00070     }
00071   }
00072   if (OPCODE_operator(opc) == OPR_COMMA) {
00073         Set_addr_saved_stmt(WN_kid(wn,0), warn);
00074         Set_addr_saved_expr(WN_kid(wn,1), warn);
00075         return;
00076   }
00077   if (OPCODE_operator(opc) == OPR_RCOMMA) {
00078         Set_addr_saved_expr(WN_kid(wn,0), warn);
00079         Set_addr_saved_stmt(WN_kid(wn,1), warn);
00080         return;
00081   }
00082   for (INT i = 0; i < WN_kid_count(wn); i++) 
00083     Set_addr_saved_expr(WN_kid(wn,i), warn);
00084 }
00085 
00086 
00087 static void 
00088 Set_addr_saved_stmt(WN *wn, BOOL use_passed_not_saved)
00089 {
00090   if (wn == NULL) return;       
00091   OPCODE opc = WN_opcode(wn);
00092 
00093   if (OPCODE_is_call(opc)) {
00094     for (INT32 i = 0; i < WN_kid_count(wn); i++) {
00095       WN *actual = WN_actual(wn,i);
00096       // Question: What justification could there be for the
00097       // following line? Answer: It is a dangerous but cheap hack to
00098       // avoid processing the function address kid of ICALL as if it
00099       // were a parameter, which would otherwise happen because
00100       // WN_actual is naively implemented as WN_kid, with no check
00101       // for ICALL or other kinds of calls. We count on alias
00102       // classification or some other relatively conservative phase
00103       // to assert that the parameters are all PARM nodes.
00104 
00105       // Answer2:  WN_actual() does not guarantee returning a PARM node.
00106       // In this analysis, we don't care about the function address 
00107       // because it will not affect setting of addr saved.
00108       // Consider a direct call to FUNC and indiret call to FUNC should
00109       // be equivalent, although there is an extra function addr kid to
00110       // the indirect call.
00111 
00112       if (WN_operator(actual) != OPR_PARM) continue;
00113       if (!use_passed_not_saved ||
00114           !WN_Parm_Passed_Not_Saved(actual))
00115         Set_addr_saved_expr(WN_kid0(actual), FALSE);
00116     }
00117     return;
00118   }
00119 
00120   switch (OPCODE_operator(opc)) {
00121   case OPR_FORWARD_BARRIER:
00122   case OPR_BACKWARD_BARRIER:
00123   case OPR_ALLOCA:
00124   case OPR_DEALLOCA:
00125     return;
00126   }
00127 
00128   if (OPCODE_is_black_box(opc)) 
00129     return;
00130   
00131   if (opc == OPC_BLOCK) {
00132     for (WN *stmt = WN_first(wn); stmt != NULL; stmt = WN_next(stmt))  
00133       Set_addr_saved_stmt(stmt, use_passed_not_saved);
00134   } else {
00135     for (INT i = 0; i < WN_kid_count(wn); i++) {
00136       Set_addr_saved_stmt(WN_kid(wn,i), use_passed_not_saved);
00137     }
00138   }
00139 }
00140 
00141 
00142 // For debugging only!
00143 static void 
00144 Recompute_addr_saved_stmt(WN *wn)
00145 {
00146   if (wn == NULL) return;       
00147   OPCODE opc = WN_opcode(wn);
00148 
00149   if (OPCODE_is_store(opc)) {
00150     // the RHS expr of any store is kid0
00151     // Any idea on how to assert?
00152     Set_addr_saved_expr(WN_kid0(wn), TRUE);
00153   }
00154 
00155   if (OPCODE_is_black_box(opc)) 
00156     return;
00157   
00158   if (opc == OPC_BLOCK) {
00159     for (WN *stmt = WN_first(wn); stmt != NULL; stmt = WN_next(stmt))  
00160       Recompute_addr_saved_stmt(stmt);
00161   } else {
00162     for (INT i = 0; i < WN_kid_count(wn); i++) {
00163       Recompute_addr_saved_stmt(WN_kid(wn,i));
00164     }
00165   }
00166 }
00167 
00168 
00169 #ifdef Is_True_On
00170 
00171 static void Verify_addr_flags_stmt(WN *wn);
00172 
00173 static void
00174 Verify_addr_saved_expr(WN *wn)
00175 {
00176   OPCODE opc = WN_opcode(wn);
00177   Is_True(OPCODE_is_expression(opc),
00178           ("Update_addr_saved: opcode must be expression"));
00179 
00180   if (OPCODE_is_load(opc))
00181     return;
00182 
00183   if (OPCODE_operator(opc) == OPR_LDA) {
00184     ST *st = WN_st(wn);
00185     if (ST_class(st) == CLASS_VAR &&
00186         !ST_addr_saved(st)) {
00187       FmtAssert(TRUE, ("PU_adjust_addr_flags:  ST %s should be addr_saved.\n",
00188                        ST_name(st)));
00189     }
00190   }
00191   if (OPCODE_operator(opc) == OPR_COMMA) {
00192         Verify_addr_flags_stmt(WN_kid(wn,0));
00193         Verify_addr_saved_expr(WN_kid(wn,1));
00194         return;
00195   }
00196   if (OPCODE_operator(opc) == OPR_RCOMMA) {
00197         Verify_addr_saved_expr(WN_kid(wn,0));
00198         Verify_addr_flags_stmt(WN_kid(wn,1));
00199         return;
00200   }
00201   for (INT i = 0; i < WN_kid_count(wn); i++) 
00202     Verify_addr_saved_expr(WN_kid(wn,i));
00203 }
00204 
00205 static void 
00206 Verify_addr_flags_stmt(WN *wn)
00207 {
00208   if (wn == NULL) return;       
00209   OPCODE opc = WN_opcode(wn);
00210 
00211   if (OPCODE_is_store(opc)) {
00212     // the RHS expr of any store is kid0
00213     // Any idea on how to assert?
00214     Verify_addr_saved_expr(WN_kid0(wn));
00215   }
00216 
00217   switch (OPCODE_operator(opc)) {
00218   case OPR_FORWARD_BARRIER:
00219   case OPR_BACKWARD_BARRIER:
00220   case OPR_ALLOCA:
00221   case OPR_DEALLOCA:
00222     return;
00223   }
00224 
00225   if (OPCODE_is_black_box(opc)) 
00226     return;
00227   
00228   if (opc == OPC_BLOCK) {
00229     for (WN *stmt = WN_first(wn); stmt != NULL; stmt = WN_next(stmt))  
00230       Verify_addr_flags_stmt(stmt);
00231   } else {
00232     for (INT i = 0; i < WN_kid_count(wn); i++) {
00233       Verify_addr_flags_stmt(WN_kid(wn,i));
00234     }
00235   }
00236 }
00237 #endif
00238 
00239 
00240 void
00241 PU_adjust_addr_flags(ST* pu_st, WN *wn)
00242 {
00243   suppress_all_warnings = FALSE;
00244 
00245           // PV 682222: the MP lowerer may introduce LDA's on privatized
00246           // ST's which require setting their addr_saved flag before WOPT.
00247           // So the MP lowerer sets the PU_needs_addr_flag_adjust bit.
00248   BOOL has_privatization_LDAs = BE_ST_pu_needs_addr_flag_adjust(pu_st);
00249 
00250   if (OPT_recompute_addr_flags || has_privatization_LDAs) {
00251     if (!OPT_recompute_addr_flags)
00252       suppress_all_warnings = TRUE; // LDAs from privatization are OK
00253     Recompute_addr_saved_stmt(wn);
00254   }
00255 
00256   if (BE_ST_pu_needs_addr_flag_adjust(pu_st))
00257     Clear_BE_ST_pu_needs_addr_flag_adjust(pu_st);
00258 
00259 #ifdef Is_True_On
00260   if (!PU_smart_addr_analysis(Pu_Table[ST_pu(pu_st)]))
00261     Verify_addr_flags_stmt(wn);
00262 #endif
00263 
00264   // Adjust addr_saved from actual parameters for non-Fortran programs.
00265   if (!Is_FORTRAN()) {
00266     PU& pu = Pu_Table[ST_pu(pu_st)];
00267     Set_addr_saved_stmt(wn,
00268                         CXX_Alias_Const || 
00269                         (OPT_IPA_addr_analysis && PU_ipa_addr_analysis(pu)));
00270   }
00271 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines