Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
wn_simp.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 /* ====================================================================
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines