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
00045
00046
00047
00048
00049 #define __STDC_LIMIT_MACROS
00050 #include <stdint.h>
00051 #ifdef USE_PCH
00052 #include "common_com_pch.h"
00053 #endif
00054 #pragma hdrstop
00055 #include "defs.h"
00056 #include "errors.h"
00057 #include "erglob.h"
00058 #include "tracing.h"
00059 #include "wn.h"
00060 #include "stab.h"
00061 #include "wn_util.h"
00062 #include "ir_reader.h"
00063
00064 #include "config.h"
00065 #include "config_opt.h"
00066 #include "config_targ.h"
00067
00068 #include "const.h"
00069 #include "targ_const.h"
00070
00071 #ifdef BACK_END
00072 #include "opt_alias_interface.h"
00073 #endif
00074
00075 #include "wn_simp.h"
00076
00077 # if defined(KEY) && defined(Is_True_On)
00078 # include "config_opt.h"
00079 # endif
00080
00081 #ifdef BACK_END
00082 BOOL WN_Simp_Fold_ILOAD = TRUE;
00083 #else
00084 BOOL WN_Simp_Fold_ILOAD = FALSE;
00085 #endif
00086
00087 BOOL WN_Simp_Fold_LDA = FALSE;
00088
00089 #ifdef KEY
00090 BOOL WN_Simp_Rsqrt_Newton_Raphson = TRUE;
00091 #endif
00092
00093
00094 WN_MAP WN_SimpParentMap = WN_MAP_UNDEFINED;
00095
00096 #define TRACEFILE TFile
00097
00098
00099
00100 #define WN_SIMP_WORKING_ON_WHIRL
00101
00102
00103
00104
00105 typedef WN * simpnode;
00106
00107
00108 #define SIMPNODE_operator(x) WN_operator(x)
00109 #define SIMPNODE_rtype(x) WN_rtype(x)
00110 #define SIMPNODE_desc(x) WN_desc(x)
00111 #define SIMPNODE_opcode WN_opcode
00112 #define SIMPNODE_load_offset WN_load_offset
00113 #define SIMPNODE_cvtl_bits WN_cvtl_bits
00114 #define SIMPNODE_st WN_st
00115 #define SIMPNODE_st_idx WN_st_idx
00116 #define SIMPNODE_ty WN_ty
00117 #define SIMPNODE_kid0 WN_kid0
00118 #define SIMPNODE_kid1 WN_kid1
00119 #define SIMPNODE_kid WN_kid
00120 #define SIMPNODE_element_size WN_element_size
00121 #define SIMPNODE_idname_offset WN_idname_offset
00122 #define SIMPNODE_lda_offset WN_lda_offset
00123 #define SIMPNODE_label_number WN_label_number
00124 #define SIMPNODE_num_dim WN_num_dim
00125 #define SIMPNODE_array_base WN_array_base
00126 #define SIMPNODE_array_index WN_array_index
00127 #define SIMPNODE_array_dim WN_array_dim
00128 #define SIMPNODE_intrinsic WN_intrinsic
00129 #define SIMPNODE_kid_count WN_kid_count
00130 #define SIMPNODE_kid WN_kid
00131 #define SIMPNODE_const_val WN_const_val
00132 #define SIMPNODE_fconst_val Const_Val
00133 #define SIMPNODE_field_id WN_field_id // get the field id
00134 #define SIMPNODE_i_field_id WN_field_id // get the field id
00135 #define SIMPNODE_bit_offset WN_bit_offset // get the bit offset
00136 #define SIMPNODE_i_bit_offset WN_bit_offset // get the bit offset
00137 #define SIMPNODE_enable Enable_WN_Simp
00138 #define SIMPNODE_op_bit_offset WN_bit_offset
00139 #define SIMPNODE_op_bit_size WN_bit_size
00140
00141
00142
00143 #define SIMPNODE_SimpCreateExp1 WN_SimpCreateExp1
00144 #define SIMPNODE_SimpCreateExp2 WN_SimpCreateExp2
00145 #define SIMPNODE_SimpCreateExp3 WN_SimpCreateExp3
00146 #define SIMPNODE_SimpCreateCvtl WN_SimpCreateCvtl
00147 #define SIMPNODE_SimpCreateExtract WN_SimpCreateExtract
00148 #define SIMPNODE_SimpCreateDeposit WN_SimpCreateDeposit
00149 #define SIMPNODE_TREE_DELETE WN_DELETE_Tree
00150 #define SIMPNODE_DELETE WN_Delete
00151 #define SIMPNODE_CopyNode WN_CopyNode
00152 #define SIMPNODE_CreateIntconst WN_CreateIntconst
00153 #define SIMPNODE_CreateFloatconstFromTcon Make_Const
00154 #ifdef TARG_X8664
00155 #define SIMPNODE_CreateSIMDconstFromTcon Make_Const
00156 #endif
00157 #define SIMPNODE_Simplify_Initialize WN_Simplify_Initialize
00158 #define SIMPNODE_Compare_Symbols WN_Compare_Symbols
00159
00160
00161
00162
00163
00164 #define SIMPNODE_SimplifyExp1 WN_SimplifyExp1
00165 #define SIMPNODE_SimplifyExp2 WN_SimplifyExp2
00166 #define SIMPNODE_SimplifyExp3 WN_SimplifyExp3
00167 #define SIMPNODE_SimplifyCvtl WN_SimplifyCvtl
00168 #define SIMPNODE_SimplifyIntrinsic WN_SimplifyIntrinsic
00169 #define SIMPNODE_SimplifyIload WN_SimplifyIload
00170 #define SIMPNODE_SimplifyIstore WN_SimplifyIstore
00171 #define SIMPNODE_Simp_Compare_Trees WN_Simp_Compare_Trees
00172
00173 static void show_tree(OPCODE opc, WN *k0, WN *k1, WN *r)
00174 {
00175 fprintf(TRACEFILE,"\nBefore:\n");
00176 fdump_tree(TRACEFILE,k0);
00177 if (OPCODE_operator(opc) != OPR_CVTL) {
00178 if (k1)
00179 fdump_tree(TRACEFILE,k1);
00180 fprintf(TRACEFILE,"%s\n",OPCODE_name(opc));
00181 } else
00182 fprintf(TRACEFILE,"%s %d\n",OPCODE_name(opc),(INT) (INTPS) k1);
00183 fprintf(TRACEFILE,"=====\nAfter:\n");
00184 fdump_tree(TRACEFILE,r);
00185 fprintf(TRACEFILE,
00186 "-----------------------------------------------------\n");
00187 }
00188
00189
00190
00191
00192
00193
00194
00195 WN *WN_Simplify_Tree(WN *t, ALIAS_MANAGER *alias_manager)
00196 {
00197 OPCODE op;
00198 OPERATOR opr;
00199 WN *k0, *k1, *k2, *r=NULL, *temp, *result, *next, *prev;
00200 INT16 numkids;
00201 INT32 i;
00202
00203 numkids = WN_kid_count(t);
00204 op = WN_opcode(t);
00205 opr = OPCODE_operator(op);
00206 result = t;
00207
00208 if (op == OPC_BLOCK) {
00209 result = t;
00210 r = WN_first(t);
00211 while (r) {
00212 prev = WN_prev(r);
00213 next = WN_next(r);
00214 temp = WN_Simplify_Tree(r);
00215 if (temp != r) {
00216
00217 WN_next(temp) = next;
00218 WN_prev(temp) = prev;
00219 if (next) WN_prev(next) = temp;
00220 if (prev) WN_next(prev) = temp;
00221 if (WN_first(t) == r) WN_first(t) = temp;
00222 if (WN_last(t) == r) WN_last(t) = temp;
00223 }
00224 r = next;
00225 }
00226 } else if (opr == OPR_ILOAD) {
00227 k0 = WN_Simplify_Tree(WN_kid0(t));
00228 r = WN_SimplifyIload(op,WN_load_offset(t),WN_ty(t),WN_field_id(t),WN_load_addr_ty(t),k0);
00229 if (r) {
00230 #ifdef BACK_END
00231 if (alias_manager) {
00232 Copy_alias_info(alias_manager,t,r);
00233 }
00234 #endif
00235 WN_Delete(t);
00236 result = r;
00237 } else {
00238 WN_kid0(t) = k0;
00239 result = t;
00240 }
00241 } else if (opr == OPR_ISTORE) {
00242 k0 = WN_Simplify_Tree(WN_kid0(t));
00243 k1 = WN_Simplify_Tree(WN_kid1(t));
00244 r = WN_SimplifyIstore(op,WN_load_offset(t),WN_ty(t),WN_field_id(t),k0,k1);
00245 if (r) {
00246 #ifdef BACK_END
00247 if (alias_manager) {
00248 Copy_alias_info(alias_manager,t,r);
00249 }
00250 #endif
00251 WN_Delete(t);
00252 result = r;
00253 } else {
00254 WN_kid0(t) = k0;
00255 WN_kid1(t) = k1;
00256 result = t;
00257 }
00258 } else if (opr == OPR_INTRINSIC_OP) {
00259 for (i=0; i < numkids; i++) {
00260 WN_kid(t,i) = WN_Simplify_Tree(WN_kid(t,i));
00261 }
00262 r = WN_SimplifyIntrinsic(op, WN_intrinsic(t), numkids, &WN_kid0(t));
00263 if (r) {
00264 WN_Delete(t);
00265 result = r;
00266 } else {
00267 result = t;
00268 }
00269 } else if (opr == OPR_IO_ITEM) {
00270
00271 for (i=0; i < numkids; i++) {
00272 WN_kid(t,i) = WN_Simplify_Tree(WN_kid(t,i));
00273 }
00274 result = t;
00275 } else if (numkids == 1) {
00276 k0 = WN_Simplify_Tree(WN_kid0(t));
00277
00278 if (WN_operator(t) != OPR_CVTL) {
00279 r = WN_SimplifyExp1(op, k0);
00280 } else {
00281 r = WN_SimplifyCvtl(op, WN_cvtl_bits(t),k0);
00282 }
00283 if (r) {
00284 WN_Delete(t);
00285 result = r;
00286 } else {
00287 WN_kid0(t) = k0;
00288 result = t;
00289 }
00290 } else if (numkids == 2) {
00291 k0 = WN_Simplify_Tree(WN_kid0(t));
00292 k1 = WN_Simplify_Tree(WN_kid1(t));
00293 r = WN_SimplifyExp2(op, k0, k1);
00294 if (r) {
00295 WN_Delete(t);
00296 result = r;
00297 } else {
00298 WN_kid0(t) = k0;
00299 WN_kid1(t) = k1;
00300 result = t;
00301 }
00302 } else if (numkids == 3) {
00303 k0 = WN_Simplify_Tree(WN_kid0(t));
00304 k1 = WN_Simplify_Tree(WN_kid1(t));
00305 k2 = WN_Simplify_Tree(WN_kid(t,2));
00306 r = WN_SimplifyExp3(op, k0, k1, k2);
00307 if (r) {
00308 WN_Delete(t);
00309 result = r;
00310 } else {
00311 WN_kid0(t) = k0;
00312 WN_kid1(t) = k1;
00313 WN_kid(t,2) = k2;
00314 result = t;
00315 }
00316 } else {
00317 for (i=0; i < numkids; i++) {
00318 WN_kid(t,i) = WN_Simplify_Tree(WN_kid(t,i));
00319 }
00320 result = t;
00321 }
00322
00323
00324 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
00325 numkids = WN_kid_count(result);
00326 for (i=0; i < numkids; i++) {
00327 WN_MAP_Set(WN_SimpParentMap, WN_kid(result,i), (void *) result);
00328 }
00329 }
00330
00331 return (result);
00332 }
00333
00334
00335
00336
00337 WN *WN_Simplify_Rebuild_Expr_Tree(WN *t,ALIAS_MANAGER *alias_manager)
00338 {
00339 OPCODE op;
00340 OPERATOR opr;
00341 WN *k0, *k1, *k2, *r=NULL, *result;
00342 INT16 numkids;
00343 # if defined(KEY) && defined(Is_True_On)
00344 static INT cur_idx = 0;
00345 # endif
00346
00347 op = WN_opcode(t);
00348 if (!OPCODE_is_expression(op)) return (t);
00349
00350 numkids = WN_kid_count(t);
00351 opr = OPCODE_operator(op);
00352 result = t;
00353
00354 if (opr == OPR_ILOAD) {
00355 k0 = WN_kid0(t);
00356 # if defined (KEY) && defined (Is_True_On)
00357 if (Enable_WN_Simp_Expr_Limit == -1 || (Enable_WN_Simp_Expr_Limit != -1 && cur_idx < Enable_WN_Simp_Expr_Limit))
00358 # endif
00359 r = WN_SimplifyIload(op,WN_load_offset(t),WN_ty(t),WN_field_id(t),WN_load_addr_ty(t),k0);
00360 if (r) {
00361 # ifdef BACK_END
00362 if (alias_manager) {
00363 Copy_alias_info(alias_manager,t,r);
00364 }
00365 # endif
00366 WN_Delete(t);
00367 result = r;
00368 # if defined (KEY) && defined (Is_True_On)
00369 cur_idx ++;
00370 # endif
00371 } else {
00372 result = t;
00373 }
00374 } else if (opr == OPR_INTRINSIC_OP) {
00375 # if defined (KEY) && defined (Is_True_On)
00376 if (Enable_WN_Simp_Expr_Limit == -1 || (Enable_WN_Simp_Expr_Limit != -1 && cur_idx < Enable_WN_Simp_Expr_Limit))
00377 # endif
00378 r = WN_SimplifyIntrinsic(op, WN_intrinsic(t), numkids, &WN_kid0(t));
00379 if (r) {
00380 WN_Delete(t);
00381 result = r;
00382 # if defined (KEY) && defined (Is_True_On)
00383 cur_idx ++;
00384 # endif
00385 } else {
00386 result = t;
00387 }
00388 } else if (numkids == 1) {
00389 k0 = WN_kid0(t);
00390
00391 if (WN_operator(t) != OPR_CVTL) {
00392 # if defined (KEY) && defined (Is_True_On)
00393 if (Enable_WN_Simp_Expr_Limit == -1 || (Enable_WN_Simp_Expr_Limit != -1 && cur_idx < Enable_WN_Simp_Expr_Limit))
00394 # endif
00395 r = WN_SimplifyExp1(op, k0);
00396 } else {
00397 # if defined (KEY) && defined (Is_True_On)
00398 if (Enable_WN_Simp_Expr_Limit == -1 || (Enable_WN_Simp_Expr_Limit != -1 && cur_idx < Enable_WN_Simp_Expr_Limit))
00399 # endif
00400 r = WN_SimplifyCvtl(op, WN_cvtl_bits(t),k0);
00401 }
00402 if (r) {
00403 WN_Delete(t);
00404 result = r;
00405 # if defined (KEY) && defined (Is_True_On)
00406 cur_idx ++;
00407 # endif
00408 } else {
00409 WN_kid0(t) = k0;
00410 result = t;
00411 }
00412 } else if (numkids == 2) {
00413 k0 = WN_kid0(t);
00414 k1 = WN_kid1(t);
00415 # if defined (KEY) && defined (Is_True_On)
00416 if (Enable_WN_Simp_Expr_Limit == -1 || (Enable_WN_Simp_Expr_Limit != -1 && cur_idx < Enable_WN_Simp_Expr_Limit))
00417 # endif
00418 #ifdef KEY // bug 13507
00419 if (opr != OPR_PAIR)
00420 #endif
00421 r = WN_SimplifyExp2(op, k0, k1);
00422 if (r) {
00423 WN_Delete(t);
00424 result = r;
00425 # if defined (KEY) && defined (Is_True_On)
00426 cur_idx ++;
00427 # endif
00428 } else {
00429 result = t;
00430 }
00431 } else if (numkids == 3) {
00432 k0 = WN_kid0(t);
00433 k1 = WN_kid1(t);
00434 k2 = WN_kid(t,2);
00435 # if defined (KEY) && defined (Is_True_On)
00436 if (Enable_WN_Simp_Expr_Limit == -1 || (Enable_WN_Simp_Expr_Limit != -1 && cur_idx < Enable_WN_Simp_Expr_Limit))
00437 # endif
00438 r = WN_SimplifyExp3(op, k0, k1, k2);
00439 if (r) {
00440 WN_Delete(t);
00441 result = r;
00442 # if defined (KEY) && defined (Is_True_On)
00443 cur_idx ++;
00444 # endif
00445 } else {
00446 result = t;
00447 }
00448 } else {
00449 result = t;
00450 }
00451
00452 return (result);
00453 }
00454
00455
00456
00457 BOOL WN_Simplifier_Enable(BOOL enable)
00458 {
00459 BOOL r = Enable_WN_Simp;
00460 Enable_WN_Simp = enable;
00461 return (r);
00462 }
00463
00464
00465 static INT32 WN_Compare_Symbols(simpnode t1, simpnode t2)
00466 {
00467 ST_IDX s1 = SIMPNODE_st_idx(t1);
00468 ST_IDX s2 = SIMPNODE_st_idx(t2);
00469
00470 if (s1 < s2)
00471 return -1;
00472 else if (s1 > s2)
00473 return 1;
00474 else
00475 return 0;
00476 }
00477
00478
00479
00480 #include "wn_simp_code.h"
00481
00482
00483
00484
00485
00486
00487 static simpnode WN_SimpCreateExp3(OPCODE opc,
00488 simpnode k0, simpnode k1, simpnode k2)
00489 {
00490 simpnode wn;
00491 wn = WN_SimplifyExp3(opc, k0, k1, k2);
00492 if (!wn) {
00493 wn = WN_Create(opc,3);
00494 WN_kid0(wn) = k0;
00495 WN_kid1(wn) = k1;
00496 WN_kid(wn,2) = k2;
00497 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
00498 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn);
00499 WN_MAP_Set(WN_SimpParentMap, k1, (void *) wn);
00500 WN_MAP_Set(WN_SimpParentMap, k2, (void *) wn);
00501 }
00502 }
00503
00504 return(wn);
00505 }
00506
00507
00508 static simpnode WN_SimpCreateExp2(OPCODE opc, simpnode k0, simpnode k1)
00509 {
00510 simpnode wn;
00511 wn = WN_SimplifyExp2(opc, k0, k1);
00512 if (!wn) {
00513 wn = WN_Create(opc,2);
00514 WN_kid0(wn) = k0;
00515 WN_kid1(wn) = k1;
00516 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
00517 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn);
00518 WN_MAP_Set(WN_SimpParentMap, k1, (void *) wn);
00519 }
00520 }
00521
00522 return(wn);
00523 }
00524
00525
00526 static simpnode WN_SimpCreateExp1(OPCODE opc, simpnode k0)
00527 {
00528 simpnode wn;
00529 wn = WN_SimplifyExp1(opc, k0);
00530 if (!wn) {
00531 wn = WN_Create(opc,1);
00532 WN_kid0(wn) = k0;
00533 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
00534 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn);
00535 }
00536 }
00537
00538 return(wn);
00539 }
00540
00541
00542 static simpnode WN_SimpCreateCvtl(OPCODE opc, INT16 bits, simpnode k0)
00543 {
00544 simpnode wn;
00545 wn = WN_SimplifyCvtl(opc, bits, k0);
00546 if (!wn) {
00547 wn = WN_Create(opc,1);
00548 WN_kid0(wn) = k0;
00549 WN_cvtl_bits(wn) = bits;
00550 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
00551 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn);
00552 }
00553 }
00554
00555 return(wn);
00556 }
00557
00558 static simpnode WN_SimpCreateExtract(OPCODE opc, INT16 boffset, INT16 bsize, simpnode k0)
00559 {
00560 simpnode wn;
00561 wn = WN_Create(opc,1);
00562 WN_kid0(wn) = k0;
00563 WN_set_bit_offset_size(wn,boffset,bsize);
00564 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
00565 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn);
00566 }
00567
00568 return(wn);
00569 }
00570
00571 static simpnode WN_SimpCreateDeposit(OPCODE opc, INT16 boffset, INT16 bsize, simpnode k0, simpnode k1)
00572 {
00573 simpnode wn;
00574 wn = WN_Create(opc,2);
00575 WN_kid0(wn) = k0;
00576 WN_kid1(wn) = k1;
00577 WN_set_bit_offset_size(wn,boffset,bsize);
00578 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
00579 WN_MAP_Set(WN_SimpParentMap, k0, (void *) wn);
00580 WN_MAP_Set(WN_SimpParentMap, k1, (void *) wn);
00581 }
00582
00583 return(wn);
00584 }
00585
00586
00587 static void SIMPNODE_Simplify_Initialize( void )
00588 {
00589 trace_rules = (Get_Trace(TP_WHIRLSIMP, 1) != 0);
00590 trace_trees = (Get_Trace(TP_WHIRLSIMP, 2) != 0);
00591 SIMPNODE_simp_initialized = TRUE;
00592 }