00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #ifdef USE_PCH
00045 #include "common_com_pch.h"
00046 #endif
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
00076 WN_MAP WN_SimpParentMap = WN_MAP_UNDEFINED;
00077
00078 #define TRACEFILE TFile
00079
00080
00081
00082 #define WN_SIMP_WORKING_ON_WHIRL
00083
00084
00085
00086
00087 typedef WN * simpnode;
00088
00089
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
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
00139
00140
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
00171
00172
00173
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
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
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
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
00317
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 {
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
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
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
00422
00423 #include "wn_simp_code.h"
00424
00425
00426
00427
00428
00429
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
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
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
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 }