Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 /* ==================================================================== 00037 * ==================================================================== 00038 * 00039 * 00040 * ==================================================================== 00041 * ==================================================================== 00042 */ 00043 00044 #ifdef USE_PCH 00045 #include "common_com_pch.h" 00046 #endif /* USE_PCH */ 00047 #pragma hdrstop 00048 #include "defs.h" 00049 #include "errors.h" 00050 #include "erglob.h" 00051 #include "tracing.h" 00052 #include "wn.h" 00053 #include "stab.h" 00054 #include "wn_util.h" 00055 #include "ir_reader.h" 00056 00057 #include "config.h" 00058 #include "config_opt.h" 00059 #include "config_targ.h" 00060 00061 #include "const.h" 00062 #include "targ_const.h" 00063 00064 #ifdef BACK_END 00065 #include "opt_alias_interface.h" 00066 #endif 00067 00068 #include "wn_simp.h" 00069 #include "upc_symtab_utils.h" 00070 00071 BOOL WN_Simp_Fold_ILOAD = FALSE; 00072 00073 BOOL WN_Simp_Fold_LDA = FALSE; 00074 00075 /* Parent maps from LNO and anyone else who wants it */ 00076 WN_MAP WN_SimpParentMap = WN_MAP_UNDEFINED; 00077 00078 #define TRACEFILE TFile 00079 00080 00081 /* To tell wn_simp_code.h that it's working on WHIRL */ 00082 #define WN_SIMP_WORKING_ON_WHIRL 00083 00084 /* Definitions for wn_simp_code.h */ 00085 /* Type definition */ 00086 00087 typedef WN * simpnode; 00088 00089 /* Accessors */ 00090 #define SIMPNODE_operator(x) WN_operator(x) 00091 #define SIMPNODE_rtype(x) WN_rtype(x) 00092 #define SIMPNODE_desc(x) WN_desc(x) 00093 #define SIMPNODE_opcode WN_opcode 00094 #define SIMPNODE_load_offset WN_load_offset 00095 #define SIMPNODE_cvtl_bits WN_cvtl_bits 00096 #define SIMPNODE_st WN_st 00097 #define SIMPNODE_st_idx WN_st_idx 00098 #define SIMPNODE_ty WN_ty 00099 #define SIMPNODE_kid0 WN_kid0 00100 #define SIMPNODE_kid1 WN_kid1 00101 #define SIMPNODE_kid WN_kid 00102 #define SIMPNODE_element_size WN_element_size 00103 #define SIMPNODE_idname_offset WN_idname_offset 00104 #define SIMPNODE_lda_offset WN_lda_offset 00105 #define SIMPNODE_num_dim WN_num_dim 00106 #define SIMPNODE_array_base WN_array_base 00107 #define SIMPNODE_array_index WN_array_index 00108 #define SIMPNODE_array_dim WN_array_dim 00109 #define SIMPNODE_intrinsic WN_intrinsic 00110 #define SIMPNODE_kid_count WN_kid_count 00111 #define SIMPNODE_kid WN_kid 00112 #define SIMPNODE_const_val WN_const_val 00113 #define SIMPNODE_fconst_val Const_Val 00114 #define SIMPNODE_field_id WN_field_id // get the field id 00115 #define SIMPNODE_i_field_id WN_field_id // get the field id 00116 #define SIMPNODE_bit_offset WN_bit_offset // get the bit offset 00117 #define SIMPNODE_i_bit_offset WN_bit_offset // get the bit offset 00118 #define SIMPNODE_enable Enable_WN_Simp 00119 #define SIMPNODE_op_bit_offset WN_bit_offset 00120 #define SIMPNODE_op_bit_size WN_bit_size 00121 00122 /* Functions */ 00123 00124 #define SIMPNODE_SimpCreateExp1 WN_SimpCreateExp1 00125 #define SIMPNODE_SimpCreateExp2 WN_SimpCreateExp2 00126 #define SIMPNODE_SimpCreateExp3 WN_SimpCreateExp3 00127 #define SIMPNODE_SimpCreateCvtl WN_SimpCreateCvtl 00128 #define SIMPNODE_SimpCreateExtract WN_SimpCreateExtract 00129 #define SIMPNODE_SimpCreateDeposit WN_SimpCreateDeposit 00130 #define SIMPNODE_TREE_DELETE WN_DELETE_Tree 00131 #define SIMPNODE_DELETE WN_Delete 00132 #define SIMPNODE_CopyNode WN_CopyNode 00133 #define SIMPNODE_CreateIntconst WN_CreateIntconst 00134 #define SIMPNODE_CreateFloatconstFromTcon Make_Const 00135 #define SIMPNODE_Simplify_Initialize WN_Simplify_Initialize 00136 #define SIMPNODE_Compare_Symbols WN_Compare_Symbols 00137 00138 /* externally visible routines. These three are defined in wn_simp_code.h. 00139 * They need a name defined here and in whatever external interface file 00140 * exists for the routine 00141 */ 00142 #define SIMPNODE_SimplifyExp1 WN_SimplifyExp1 00143 #define SIMPNODE_SimplifyExp2 WN_SimplifyExp2 00144 #define SIMPNODE_SimplifyExp3 WN_SimplifyExp3 00145 #define SIMPNODE_SimplifyCvtl WN_SimplifyCvtl 00146 #define SIMPNODE_SimplifyIntrinsic WN_SimplifyIntrinsic 00147 #define SIMPNODE_SimplifyIload WN_SimplifyIload 00148 #define SIMPNODE_SimplifyIstore WN_SimplifyIstore 00149 #define SIMPNODE_SimplifyPstore WN_SimplifyPstore 00150 00151 #define SIMPNODE_Simp_Compare_Trees WN_Simp_Compare_Trees 00152 00153 static void show_tree(OPCODE opc, WN *k0, WN *k1, WN *r) 00154 { 00155 fprintf(TRACEFILE,"\nBefore:\n"); 00156 fdump_tree(TRACEFILE,k0); 00157 if (OPCODE_operator(opc) != OPR_CVTL) { 00158 if (k1) 00159 fdump_tree(TRACEFILE,k1); 00160 fprintf(TRACEFILE,"%s\n",OPCODE_name(opc)); 00161 } else 00162 fprintf(TRACEFILE,"%s %d\n",OPCODE_name(opc),(INT) (INTPS) k1); 00163 fprintf(TRACEFILE,"=====\nAfter:\n"); 00164 fdump_tree(TRACEFILE,r); 00165 fprintf(TRACEFILE, 00166 "-----------------------------------------------------\n"); 00167 } 00168 00169 00170 /* Walk a tree, simplifying from the bottom up. For operators 00171 * that the simplifier doesn't know how to deal with, simplify and replace the 00172 * children. For those that it does, simplify the children, then try and 00173 * simplify the argument with new children. 00174 */ 00175 WN *WN_Simplify_Tree(WN *t, ALIAS_MANAGER *alias_manager) 00176 { 00177 OPCODE op; 00178 OPERATOR opr; 00179 WN *k0, *k1, *k2, *r=NULL, *temp, *result, *next, *prev; 00180 INT16 numkids; 00181 INT32 i; 00182 00183 numkids = WN_kid_count(t); 00184 op = WN_opcode(t); 00185 opr = OPCODE_operator(op); 00186 result = t; 00187 00188 if (op == OPC_BLOCK) { 00189 result = t; 00190 r = WN_first(t); 00191 while (r) { 00192 prev = WN_prev(r); 00193 next = WN_next(r); 00194 temp = WN_Simplify_Tree(r); 00195 if (temp != r) { 00196 /* a simplification happened */ 00197 WN_next(temp) = next; 00198 WN_prev(temp) = prev; 00199 if (next) WN_prev(next) = temp; 00200 if (prev) WN_next(prev) = temp; 00201 if (WN_first(t) == r) WN_first(t) = temp; 00202 if (WN_last(t) == r) WN_last(t) = temp; 00203 } 00204 r = next; 00205 } 00206 } else if (opr == OPR_ILOAD) { 00207 k0 = WN_Simplify_Tree(WN_kid0(t)); 00208 r = WN_SimplifyIload(op,WN_load_offset(t),WN_ty(t),WN_field_id(t),WN_load_addr_ty(t),k0); 00209 if (r) { 00210 WN_Delete(t); 00211 result = r; 00212 } else { 00213 WN_kid0(t) = k0; 00214 result = t; 00215 } 00216 } else if (opr == OPR_ISTORE) { 00217 k0 = WN_Simplify_Tree(WN_kid0(t)); 00218 k1 = WN_Simplify_Tree(WN_kid1(t)); 00219 r = WN_SimplifyIstore(op,WN_load_offset(t),WN_ty(t),WN_field_id(t),k0,k1); 00220 if (r) { 00221 WN_Delete(t); 00222 result = r; 00223 } else { 00224 WN_kid0(t) = k0; 00225 WN_kid1(t) = k1; 00226 result = t; 00227 } 00228 } else if (opr == OPR_PSTORE) { 00229 k0 = WN_Simplify_Tree(WN_kid0(t)); 00230 k1 = WN_Simplify_Tree(WN_kid1(t)); 00231 r = WN_SimplifyPstore(op,WN_load_offset(t),WN_ty(t),WN_field_id(t),k0,k1); 00232 if (r) { 00233 WN_Delete(t); 00234 result = r; 00235 } else { 00236 WN_kid0(t) = k0; 00237 WN_kid1(t) = k1; 00238 result = t; 00239 } 00240 } else if (opr == OPR_INTRINSIC_OP) { 00241 for (i=0; i < numkids; i++) { 00242 WN_kid(t,i) = WN_Simplify_Tree(WN_kid(t,i)); 00243 } 00244 r = WN_SimplifyIntrinsic(op, WN_intrinsic(t), numkids, &WN_kid0(t)); 00245 if (r) { 00246 WN_Delete(t); 00247 result = r; 00248 } else { 00249 result = t; 00250 } 00251 } else if (opr == OPR_IO_ITEM) { 00252 // For IO_ITEM, just simplify the kids 00253 for (i=0; i < numkids; i++) { 00254 WN_kid(t,i) = WN_Simplify_Tree(WN_kid(t,i)); 00255 } 00256 result = t; 00257 } else if (numkids == 1) { 00258 k0 = WN_Simplify_Tree(WN_kid0(t)); 00259 00260 if (WN_operator(t) != OPR_CVTL) { 00261 r = WN_SimplifyExp1(op, k0); 00262 } else { 00263 r = WN_SimplifyCvtl(op, WN_cvtl_bits(t),k0); 00264 } 00265 if (r) { 00266 WN_Delete(t); 00267 result = r; 00268 } else { 00269 WN_kid0(t) = k0; 00270 result = t; 00271 } 00272 } else if (numkids == 2) { 00273 k0 = WN_Simplify_Tree(WN_kid0(t)); 00274 k1 = WN_Simplify_Tree(WN_kid1(t)); 00275 r = WN_SimplifyExp2(op, k0, k1); 00276 if (r) { 00277 WN_Delete(t); 00278 result = r; 00279 } else { 00280 WN_kid0(t) = k0; 00281 WN_kid1(t) = k1; 00282 result = t; 00283 } 00284 } else if (numkids == 3) { 00285 k0 = WN_Simplify_Tree(WN_kid0(t)); 00286 k1 = WN_Simplify_Tree(WN_kid1(t)); 00287 k2 = WN_Simplify_Tree(WN_kid(t,2)); 00288 r = WN_SimplifyExp3(op, k0, k1, k2); 00289 if (r) { 00290 WN_Delete(t); 00291 result = r; 00292 } else { 00293 WN_kid0(t) = k0; 00294 WN_kid1(t) = k1; 00295 WN_kid(t,2) = k2; 00296 result = t; 00297 } 00298 } else { 00299 for (i=0; i < numkids; i++) { 00300 WN_kid(t,i) = WN_Simplify_Tree(WN_kid(t,i)); 00301 } 00302 result = t; 00303 } 00304 00305 /* Update parent pointers */ 00306 if (WN_SimpParentMap != WN_MAP_UNDEFINED) { 00307 numkids = WN_kid_count(result); 00308 for (i=0; i < numkids; i++) { 00309 WN_MAP_Set(WN_SimpParentMap, WN_kid(result,i), (void *) result); 00310 } 00311 } 00312 00313 return (result); 00314 } 00315 00316 /* Assume that all children are already simplified, rebuild a tree using the new children. 00317 * This only applies itself to a subset of expression nodes. 00318 */ 00319 WN *WN_Simplify_Rebuild_Expr_Tree(WN *t,ALIAS_MANAGER *alias_manager) 00320 { 00321 OPCODE op; 00322 OPERATOR opr; 00323 WN *k0, *k1, *k2, *r=NULL, *result; 00324 INT16 numkids; 00325 00326 op = WN_opcode(t); 00327 if (!OPCODE_is_expression(op)) return (t); 00328 00329 numkids = WN_kid_count(t); 00330 opr = OPCODE_operator(op); 00331 result = t; 00332 00333 if (opr == OPR_ILOAD) { 00334 k0 = WN_kid0(t); 00335 r = WN_SimplifyIload(op,WN_load_offset(t),WN_ty(t),WN_field_id(t),WN_load_addr_ty(t),k0); 00336 if (r) { 00337 WN_Delete(t); 00338 result = r; 00339 } else { 00340 result = t; 00341 } 00342 } else if (opr == OPR_INTRINSIC_OP) { 00343 r = WN_SimplifyIntrinsic(op, WN_intrinsic(t), numkids, &WN_kid0(t)); 00344 if (r) { 00345 WN_Delete(t); 00346 result = r; 00347 } else { 00348 result = t; 00349 } 00350 } else if (numkids == 1) { 00351 k0 = WN_kid0(t); 00352 00353 if (WN_operator(t) != OPR_CVTL && WN_operator(t) != OPR_TAS) { 00354 r = WN_SimplifyExp1(op, k0); 00355 } else { 00356 if(WN_operator(t) == OPR_CVTL) 00357 r = WN_SimplifyCvtl(op, WN_cvtl_bits(t),k0); 00358 else { //TAS 00359 if(!Type_Is_Shared_Ptr(WN_ty(t))) 00360 r = WN_SimplifyExp1(op, k0); 00361 } 00362 } 00363 if (r) { 00364 WN_Delete(t); 00365 result = r; 00366 } else { 00367 WN_kid0(t) = k0; 00368 result = t; 00369 } 00370 } else if (numkids == 2) { 00371 k0 = WN_kid0(t); 00372 k1 = WN_kid1(t); 00373 r = WN_SimplifyExp2(op, k0, k1); 00374 if (r) { 00375 WN_Delete(t); 00376 result = r; 00377 } else { 00378 result = t; 00379 } 00380 } else if (numkids == 3) { 00381 k0 = WN_kid0(t); 00382 k1 = WN_kid1(t); 00383 k2 = WN_kid(t,2); 00384 r = WN_SimplifyExp3(op, k0, k1, k2); 00385 if (r) { 00386 WN_Delete(t); 00387 result = r; 00388 } else { 00389 result = t; 00390 } 00391 } else { 00392 result = t; 00393 } 00394 00395 return (result); 00396 } 00397 00398 /* Allow the simplifier to be turned on and off */ 00399 00400 BOOL WN_Simplifier_Enable(BOOL enable) 00401 { 00402 BOOL r = Enable_WN_Simp; 00403 Enable_WN_Simp = enable; 00404 return (r); 00405 } 00406 00407 /* Utility procedure which does a comparison on two symbols */ 00408 static INT32 WN_Compare_Symbols(simpnode t1, simpnode t2) 00409 { 00410 ST_IDX s1 = SIMPNODE_st_idx(t1); 00411 ST_IDX s2 = SIMPNODE_st_idx(t2); 00412 00413 if (s1 < s2) 00414 return -1; 00415 else if (s1 > s2) 00416 return 1; 00417 else 00418 return 0; 00419 } 00420 00421 /************ The code is here *******************/ 00422 00423 #include "wn_simp_code.h" 00424 00425 /**************************************************/ 00426 00427 /* Things which need to be written by the user */ 00428 00429 /* Interface to WN_CreateExp3, checking for parent updates */ 00430 static simpnode WN_SimpCreateExp3(OPCODE opc, 00431 simpnode k0, simpnode k1, simpnode k2) 00432 { 00433 simpnode wn; 00434 wn = WN_SimplifyExp3(opc, k0, k1, k2); 00435 if (!wn) { 00436 wn = WN_Create(opc,3); 00437 WN_kid0(wn) = k0; 00438 WN_kid1(wn) = k1; 00439 WN_kid(wn,2) = k2; 00440 if (WN_SimpParentMap != WN_MAP_UNDEFINED) { 00441 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn); 00442 WN_MAP_Set(WN_SimpParentMap, k1, (void *) wn); 00443 WN_MAP_Set(WN_SimpParentMap, k2, (void *) wn); 00444 } 00445 } 00446 00447 return(wn); 00448 } 00449 00450 /* Interface to WN_CreateExp2, checking for parent updates */ 00451 static simpnode WN_SimpCreateExp2(OPCODE opc, simpnode k0, simpnode k1) 00452 { 00453 simpnode wn; 00454 wn = WN_SimplifyExp2(opc, k0, k1); 00455 if (!wn) { 00456 wn = WN_Create(opc,2); 00457 WN_kid0(wn) = k0; 00458 WN_kid1(wn) = k1; 00459 if (WN_SimpParentMap != WN_MAP_UNDEFINED) { 00460 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn); 00461 WN_MAP_Set(WN_SimpParentMap, k1, (void *) wn); 00462 } 00463 } 00464 00465 return(wn); 00466 } 00467 00468 /* Interface to WN_CreateExp1, checking for parent updates */ 00469 static simpnode WN_SimpCreateExp1(OPCODE opc, simpnode k0) 00470 { 00471 simpnode wn; 00472 wn = WN_SimplifyExp1(opc, k0); 00473 if (!wn) { 00474 wn = WN_Create(opc,1); 00475 WN_kid0(wn) = k0; 00476 if (WN_SimpParentMap != WN_MAP_UNDEFINED) { 00477 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn); 00478 } 00479 } 00480 00481 return(wn); 00482 } 00483 00484 /* Interface to WN_CreateCvtl, checking for parent updates */ 00485 static simpnode WN_SimpCreateCvtl(OPCODE opc, INT16 bits, simpnode k0) 00486 { 00487 simpnode wn; 00488 wn = WN_SimplifyCvtl(opc, bits, k0); 00489 if (!wn) { 00490 wn = WN_Create(opc,1); 00491 WN_kid0(wn) = k0; 00492 WN_cvtl_bits(wn) = bits; 00493 if (WN_SimpParentMap != WN_MAP_UNDEFINED) { 00494 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn); 00495 } 00496 } 00497 00498 return(wn); 00499 } 00500 00501 static simpnode WN_SimpCreateExtract(OPCODE opc, INT16 boffset, INT16 bsize, simpnode k0) 00502 { 00503 simpnode wn; 00504 wn = WN_Create(opc,1); 00505 WN_kid0(wn) = k0; 00506 WN_set_bit_offset_size(wn,boffset,bsize); 00507 if (WN_SimpParentMap != WN_MAP_UNDEFINED) { 00508 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn); 00509 } 00510 00511 return(wn); 00512 } 00513 00514 static simpnode WN_SimpCreateDeposit(OPCODE opc, INT16 boffset, INT16 bsize, simpnode k0, simpnode k1) 00515 { 00516 simpnode wn; 00517 wn = WN_Create(opc,2); 00518 WN_kid0(wn) = k0; 00519 WN_kid1(wn) = k1; 00520 WN_set_bit_offset_size(wn,boffset,bsize); 00521 if (WN_SimpParentMap != WN_MAP_UNDEFINED) { 00522 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn); 00523 WN_MAP_Set(WN_SimpParentMap, k1, (void *) wn); 00524 } 00525 00526 return(wn); 00527 } 00528 00529 00530 static void SIMPNODE_Simplify_Initialize( void ) 00531 { 00532 trace_rules = (Get_Trace(TP_WHIRLSIMP, 1) != 0); 00533 trace_trees = (Get_Trace(TP_WHIRLSIMP, 2) != 0); 00534 SIMPNODE_simp_initialized = TRUE; 00535 }