Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
w2op.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 /* Conversion from WHIRL opcode to CG opcode. */
00037 
00038 #ifdef USE_PCH
00039 #include "be_com_pch.h"
00040 #endif /* USE_PCH */
00041 #pragma hdrstop
00042 #include "defs.h"
00043 #include "errors.h"
00044 #include "util.h"
00045 #include "topcode.h"
00046 #include "targ_isa_properties.h"
00047 #include "wn.h"
00048 #include "opcode.h"
00049 #include "config_targ.h"
00050 #include "config.h"
00051 #include "config_debug.h"
00052 #include "tracing.h"
00053 #include "opt_alias_interface.h"
00054 #include "opt_alias_mgr.h"
00055 #include "betarget.h"
00056 #include "w2op.h"
00057 
00058 
00059 /* only return machine_ops, TOP_UNDEFINED if not an exact correspondence */
00060 TOP
00061 WHIRL_To_TOP (WN *wn)
00062 {
00063   OPCODE opcode = WN_opcode(wn);
00064   TOP top;
00065 
00066   top = OPCODE_To_TOP (opcode);
00067 
00068   /* For TAS WHIRL operators there is no direct translation. We 
00069    * have to look at the kids to determine the corresponding TOP.
00070    */
00071   if (top == TOP_UNDEFINED && OPCODE_operator(opcode) == OPR_TAS) {
00072       top = TAS_To_TOP (wn);
00073   }
00074   return top;
00075 }
00076 
00077 
00078 /* determines if the TOP can be speculatively executed taking into account
00079  * eagerness level
00080  */
00081 BOOL TOP_Can_Be_Speculative (TOP opcode)
00082 {
00083   switch (Eager_Level) {
00084   case EAGER_NONE:
00085 
00086     /* not allowed to speculate anything
00087      */
00088     break;
00089 
00090   case EAGER_SAFE:
00091 
00092     /* Only exception-safe speculative ops are allowed
00093      */
00094     if (TOP_is_ftrap(opcode) || TOP_is_itrap(opcode)) break;
00095     /*FALLTHROUGH*/
00096 
00097   case EAGER_ARITH:
00098 
00099     /* Arithmetic exceptions allowed
00100      */
00101     if (TOP_is_fdiv(opcode)) break;
00102     /*FALLTHROUGH*/
00103 
00104   case EAGER_DIVIDE:
00105 
00106     /* Divide by zero exceptions allowed 
00107      */
00108     if (TOP_is_memtrap(opcode)) break;
00109     /*FALLTHROUGH*/
00110 
00111   case EAGER_MEMORY:
00112 
00113     /* Memory exceptions allowed / All speculative ops allowed
00114      */
00115     if (TOP_is_unsafe(opcode)) break;
00116     return TRUE;
00117 
00118   default:
00119     DevWarn("unhandled eagerness level: %d", Eager_Level);
00120     break;
00121   }
00122 
00123    return FALSE;
00124 }
00125 
00126 
00127 /* ====================================================================
00128  *
00129  * BOOL OPCODE_Can_Be_Speculative(OPCODE opcode)
00130  *
00131  * Determine is the opcode can be executed speculatively, given that
00132  * its children are speculative
00133  *
00134  * Note:
00135  * TOP div (integer) does NOT trap, although -DEBUG:div_check (default)
00136  * inserts a trap to check divide by zero. So we have the strange case
00137  * that OPC_{I,U}{4,8}DIV does trap but the TOP div does not.
00138  *
00139  * ====================================================================
00140  */
00141 
00142 BOOL OPCODE_Can_Be_Speculative(OPCODE opcode)
00143 {
00144   if (Eager_Level == EAGER_NONE)
00145     return FALSE;
00146 
00147   switch(OPCODE_operator(opcode))
00148   {
00149   case OPR_LDA:
00150   case OPR_CONST:
00151   case OPR_INTCONST:
00152   case OPR_IDNAME:
00153   case OPR_PREFETCH:
00154   case OPR_PREFETCHX:
00155   case OPR_ARRAY:
00156     return EAGER_SAFE <= Eager_Level;
00157 
00158   case OPR_ILOAD:
00159   case OPR_ILOADX:
00160   case OPR_MLOAD:
00161   case OPR_LDID:
00162     return EAGER_MEMORY <= Eager_Level;
00163 
00164   case OPR_CVT:
00165   case OPR_NEG:
00166   case OPR_ABS:
00167   case OPR_RND:
00168   case OPR_TRUNC:
00169   case OPR_CEIL:
00170   case OPR_FLOOR:
00171   case OPR_MADD:
00172   case OPR_MSUB:
00173   case OPR_NMADD:
00174   case OPR_NMSUB:
00175     if (MTYPE_is_float(OPCODE_rtype(opcode)))
00176       return EAGER_ARITH <= Eager_Level;
00177     return EAGER_SAFE <= Eager_Level;
00178 
00179   case OPR_SQRT:
00180   case OPR_DIV:
00181   case OPR_RECIP:
00182   case OPR_RSQRT:
00183   case OPR_REM:
00184   case OPR_DIVREM:
00185     if (MTYPE_is_float(OPCODE_rtype(opcode)) ||
00186         DEBUG_Div_Zero_Check)
00187       return EAGER_DIVIDE <= Eager_Level;
00188     return EAGER_SAFE <= Eager_Level;
00189 
00190   case OPR_REALPART:
00191   case OPR_IMAGPART:
00192   case OPR_PAREN:
00193   case OPR_LOWPART:
00194   case OPR_HIGHPART:
00195   case OPR_MINMAX:
00196   case OPR_MINPART:
00197   case OPR_MAXPART:
00198   case OPR_COMPLEX:
00199     return EAGER_SAFE <= Eager_Level;
00200 
00201   case OPR_BNOT:
00202   case OPR_LNOT:
00203   case OPR_ADD:
00204   case OPR_SUB:
00205   case OPR_MPY:
00206   case OPR_MOD:
00207   case OPR_MAX:
00208   case OPR_MIN:
00209   case OPR_TAS:
00210   case OPR_CVTL:
00211   case OPR_BAND:
00212   case OPR_BIOR:
00213   case OPR_BNOR:
00214   case OPR_BXOR:
00215   case OPR_LAND:
00216   case OPR_LIOR:
00217   case OPR_SHL:
00218   case OPR_ASHR:
00219   case OPR_LSHR:
00220     if (MTYPE_is_float(OPCODE_rtype(opcode)))
00221       return EAGER_DIVIDE <= Eager_Level;
00222     return EAGER_SAFE <= Eager_Level;
00223 
00224   case OPR_CAND:
00225   case OPR_CIOR:
00226   case OPR_SELECT:
00227   case OPR_CSELECT:
00228     return EAGER_SAFE <= Eager_Level;
00229 
00230   case OPR_EQ:
00231   case OPR_NE:
00232   case OPR_GT:
00233   case OPR_GE:
00234   case OPR_LT:
00235   case OPR_LE:
00236     return EAGER_SAFE <= Eager_Level;
00237 
00238   case OPR_INTRINSIC_OP:
00239     return FALSE;
00240   }
00241   return FALSE;
00242 }
00243 
00244 
00245 /* ====================================================================
00246  *
00247  * BOOL WN_Can_Be_Speculative (WN *wn, struct ALIAS_MANAGER *alias)
00248  *
00249  * Determine is the wn can be executed speculatively
00250  * This is a close approximation to be/cg/cgtarget.c: CGTAG_Can_Be_Speculative()
00251  *
00252  *
00253  * TODO:
00254  *      handle classes of ILOADs
00255  *
00256  * ====================================================================
00257  */
00258 BOOL WN_Can_Be_Speculative (WN *wn, struct ALIAS_MANAGER *alias)
00259 {
00260   switch(WN_operator(wn))
00261   {
00262   case OPR_CONST:
00263   case OPR_INTCONST:
00264   case OPR_LDA:
00265     return TRUE;
00266 
00267   case OPR_LDID:
00268     if (WN_class(wn) == CLASS_PREG)
00269       return TRUE;
00270 
00271     if (ST_is_constant(WN_st(wn)))
00272       return TRUE;
00273     
00274     // fall thru
00275 
00276   case OPR_ILOAD:
00277   case OPR_ILOADX:
00278     if (WN_Is_Volatile_Mem(wn))
00279       return FALSE;
00280 
00281     return FALSE;
00282 
00283   case OPR_DIV:
00284     TYPE_ID rtype = WN_rtype(wn); 
00285     if ((rtype == MTYPE_I4 || rtype == MTYPE_I8 || rtype == MTYPE_U4
00286         || rtype == MTYPE_U8) && WN_operator(WN_kid1(wn)) 
00287         == OPR_INTCONST && WN_const_val(wn) != 0)
00288       return TRUE; 
00289 
00290   } 
00291   return OPCODE_Can_Be_Speculative(WN_opcode(wn));
00292 }
00293 
00294 /* ====================================================================
00295  *
00296  * BOOL WN_Expr_Can_Be_Speculative (WN *wn, struct ALIAS_MANAGER *alias)
00297  *
00298  * Determine if the whirl expression can be executed speculatively
00299  * It can only be speculative if the expression and all its children are speculative
00300  *
00301  * ====================================================================
00302  */
00303 BOOL WN_Expr_Can_Be_Speculative (WN *wn, struct ALIAS_MANAGER *alias)
00304 {
00305   INT16 i;
00306 
00307   for(i=0; i<WN_kid_count(wn); i++)
00308   {
00309     if (WN_Expr_Can_Be_Speculative(WN_kid(wn,i), alias) == FALSE)
00310       return FALSE;
00311   }
00312 
00313   return WN_Can_Be_Speculative(wn, alias);
00314 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines