Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
opt_cvtl_rule.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 //-*-c++-*-
00037 // ====================================================================
00038 // ====================================================================
00039 //
00040 //
00041 // Description: Conversion rules
00042 //
00043 // ====================================================================
00044 // ====================================================================
00045 
00046 #include "opt_cvtl_rule.h"
00047 #include "wn.h"
00048 
00049 #define  nop {NOT_AT_ALL,OPCODE_LAST+1}
00050 #define I8I4 {NEED_CVT,  OPC_I8I4CVT}
00051 #define U8I4 {NEED_CVT,  OPC_U8I4CVT}
00052 #define I4I8 {NEED_CVT,  OPC_I4I8CVT}
00053 #define U4I8 {NEED_CVT,  OPC_U4I8CVT}
00054 #define I8U4 {NEED_CVT,  OPC_I8U4CVT}
00055 #define U8U4 {NEED_CVT,  OPC_U8U4CVT}
00056 #define I4U8 {NEED_CVT,  OPC_I4U8CVT}
00057 #define U4U8 {NEED_CVT,  OPC_U4U8CVT}
00058 
00059 #define I4I2 {NEED_CVTL, OPC_I4CVTL}
00060 #define I4I1 {NEED_CVTL, OPC_I4CVTL}
00061 #define U4U2 {NEED_CVTL, OPC_U4CVTL}
00062 #define U4U1 {NEED_CVTL, OPC_U4CVTL}
00063 #define I4U4 {NEED_CVTL, OPC_U4CVTL}
00064 #define U4I4 {NEED_CVTL, OPC_I4CVTL}
00065 #define I8I2 {NEED_CVTL, OPC_I8CVTL}
00066 #define I8I1 {NEED_CVTL, OPC_I8CVTL}
00067 #define U8U2 {NEED_CVTL, OPC_U8CVTL}
00068 #define U8U1 {NEED_CVTL, OPC_U8CVTL}
00069 
00070 #define I1I4 {NEED_CVTL, OPC_I4CVTL}
00071 #define I2I4 {NEED_CVTL, OPC_I4CVTL}
00072 #define I1I8 {NEED_CVTL, OPC_I8CVTL}
00073 #define I2I8 {NEED_CVTL, OPC_I8CVTL}
00074 #define U1U4 {NEED_CVTL, OPC_U4CVTL}
00075 #define U2U4 {NEED_CVTL, OPC_U4CVTL}
00076 #define U1U8 {NEED_CVTL, OPC_U8CVTL}
00077 #define U2U8 {NEED_CVTL, OPC_U8CVTL}
00078 
00079 #define I4B  {NEED_CVT, OPC_I4BCVT}
00080 #define I8B  {NEED_CVT, OPC_I8BCVT}
00081 #define U4B  {NEED_CVT, OPC_U4BCVT}
00082 #define U8B  {NEED_CVT, OPC_U8BCVT}
00083 
00084 // This table reflexs the table 3 in whirl definition document.  There
00085 // is minor differences, the convert in the original table is removed
00086 // if it does not require an instruction in MIPS architecture.  all
00087 // macros for conversion is ToFrom sequence.
00088 static struct cvt_rule {
00089   char   _cvt_kind;
00090   mINT32 _cvt_opcode;
00091 } cvt_rule[MTYPE_U8+1][MTYPE_U8+1] = {
00092   //UNK, B,   I1,  I2,  I4,  I8,  U1,  U2,  U4,  U8   From
00093   { nop, nop, nop, nop, nop, nop, nop, nop, nop, nop},//to UNK
00094   { nop, nop, nop, nop, nop, nop, nop, nop, nop, nop},//to B
00095   { nop, nop, nop, nop,I1I4,I1I8, nop, nop,I1I4,I1I8},//to I1
00096   { nop, nop, nop, nop,I2I4,I2I8, nop, nop,I2I4,I1I8},//to I2
00097   { nop, I4B,I4I1,I4I2, nop,I4I8, nop, nop, nop,I4U8},//to I4
00098 #ifdef TARG_MIPS
00099   { nop, nop,I8I1,I8I2, nop, nop, nop, nop,I8U4, nop},//to I8
00100 #elif defined(TARG_IA32)
00101   { nop, nop,I8I1,I8I2,I8I4, nop, nop, nop,I8U4, nop},//to I8
00102 #else
00103   { nop, I8B,I8I1,I8I2,I8I4, nop, nop, nop, nop, nop},//to I8
00104 #endif
00105   { nop, nop, nop, nop,U1U4,U1U8, nop, nop,U1U4,U1U8},//to U1
00106   { nop, nop, nop, nop,U2U4,U2U8, nop, nop,U2U4,U2U8},//to U2
00107   { nop, U4B, nop, nop, nop,U4I8,U4U1,U4U2, nop,U4U8},//to U4
00108 #ifdef TARG_MIPS
00109   { nop, nop, nop, nop, nop, nop,U8U1,U8U2,U8U4, nop} //to U8
00110 #elif defined(TARG_IA32)
00111   { nop, nop, nop, nop,U8I4, nop,U8U1,U8U2,U8U4, nop} //to U8
00112 #else
00113   { nop, U8B, nop, nop,U8I4, nop,U8U1,U8U2, nop, nop} //to U8
00114 #endif
00115 };
00116 
00117 // return NOT_AT_ALL, NEED_CVT, or NEED_CVTL.  The reference parameter
00118 // opc returns the opcode for the conversion, if it is either NEED_CVT
00119 // or NEED_CVTL.
00120 INT Need_type_conversion(TYPE_ID from_ty, TYPE_ID to_ty, OPCODE *opc)
00121 {
00122   if (!(MTYPE_is_integral(from_ty) && MTYPE_is_integral(to_ty))) {
00123     if (from_ty == to_ty) return NOT_AT_ALL;
00124     if (opc != NULL) 
00125       *opc = OPCODE_make_op(OPR_CVT, to_ty, from_ty);
00126     return NEED_CVT;
00127   }
00128 
00129   if (opc != NULL)
00130     *opc = (OPCODE)cvt_rule[to_ty][from_ty]._cvt_opcode;
00131   return (INT)cvt_rule[to_ty][from_ty]._cvt_kind;
00132 }
00133 
00134 
00135 // ==========================================================
00136 // Load/Iload convertion rule for desc type if size 4
00137 //            hi32 sign extended
00138 // U8U4ILOAD        0
00139 // I8I4ILOAD        1
00140 // U4U4ILOAD        1
00141 // I4I4ILOAD        1
00142 // need conversion between {U8U4ILOAD} and {I8I4ILOAD,U4U4ILOAD,I4I4ILOAD}
00143 // ==========================================================
00144 // static struct load_convert_rule_4 {
00145 //   char   _cvt_kind;
00146 //   mINT32 _cvt_opcode;
00147 // } load_convert_rule_4[2][2] = {
00148 //   // 0      1  From
00149 //   {  nop, U8U4},//to 0
00150 //   { U4U8,  nop} //to 1
00151 // };
00152 //
00153 // ==========================================================
00154 // Load/Iload convertion rule for desc type if size < 4
00155 //            lo32 sign extended
00156 // U8U{1,2}ILOAD        0
00157 // I8I{1,2}ILOAD        1
00158 // U4U{1,2}ILOAD        0
00159 // I4I{1,2}ILOAD        1
00160 // need conversion between {U{8,4}U{1,2}ILOAD} and {I{8,4}I{1,2}ILOAD}
00161 // ==========================================================
00162 // static struct load_convert_rule_1_2 {
00163 //   char   _cvt_kind;
00164 //   mINT32 _cvt_opcode;
00165 // } load_convert_rule_1_2[2][2] = {
00166 //   // 0      1 From
00167 //   { nop, U4U1 },// to 0
00168 //   {I4I1,  nop } // to 1
00169 // };
00170 //
00171 // ===================================================================
00172 // Implementing Load/Iload conversion rule as scratched above.
00173 // return NOT_AT_ALL, NEED_CVT, or NEED_CVTL.  The reference parameter
00174 // opc returns the opcode for the conversion, if it is either NEED_CVT
00175 // or NEED_CVTL.
00176 // ===================================================================
00177 INT Need_load_type_conversion(BOOL source_sign_extd, BOOL target_sign_extd, 
00178                               TYPE_ID to_ty, TYPE_ID dsc_ty, OPCODE *opc)
00179 {
00180 
00181   Is_True(MTYPE_is_integral(to_ty),("Need_load_type_conversion: non integral type"));
00182   Is_True(to_ty != MTYPE_BS,("Need_load_type_conversion: illegal MTYPE_BS"));
00183   Is_True(MTYPE_size_min(to_ty)>=MTYPE_size_min(MTYPE_I4), 
00184           ("Need_load_type_conversion: data type size less than I4"));
00185 
00186   if (source_sign_extd == target_sign_extd || 
00187       MTYPE_size_min(dsc_ty) > MTYPE_size_min(MTYPE_I4) && dsc_ty != MTYPE_BS) 
00188     return NOT_AT_ALL;
00189   
00190   if (MTYPE_size_min(dsc_ty) == MTYPE_size_min(MTYPE_I4) && 
00191       dsc_ty != MTYPE_BS) {
00192     if (source_sign_extd) {            // !targ_sign_extd
00193       *opc = (OPCODE) OPC_U8U4CVT;
00194     } else {                           // targ_sign_extd && !source_sign_extd
00195       *opc = (OPCODE) OPC_U4U8CVT;
00196     }
00197     return NEED_CVT;
00198   }
00199   else {
00200     if (source_sign_extd) {            // !targ_sign_extd
00201       *opc = (OPCODE) (MTYPE_size_min(to_ty) == MTYPE_size_min(MTYPE_I4)) ? 
00202         OPC_U4CVTL : OPC_U8CVTL;
00203     } else {                           // targ_sign_extd && !source_sign_extd
00204       *opc = (OPCODE) (MTYPE_size_min(to_ty) == MTYPE_size_min(MTYPE_I4)) ? 
00205         OPC_I4CVTL : OPC_I8CVTL;
00206     }
00207     return NEED_CVTL;
00208   }
00209 
00210 }
00211 
00212 // Check if TYPE_ID lhs_type is compatible with the RHS of assignment stmt
00213 BOOL
00214 Types_are_compatible(TYPE_ID lhs_type, TYPE_ID rhs_type)
00215 {
00216   BOOL   compatible;
00217   OPCODE opc;
00218 
00219   if ((MTYPE_type_class(rhs_type)&MTYPE_CLASS_UNSIGNED_INTEGER) == 0 ||
00220       (MTYPE_type_class(lhs_type)&MTYPE_CLASS_UNSIGNED_INTEGER) == 0) {
00221         if (rhs_type == lhs_type) return FALSE;
00222         else
00223           return TRUE;
00224       }
00225   compatible = Need_type_conversion(rhs_type, lhs_type, &opc) != NEED_CVT;
00226   return compatible;
00227 }
00228 
00229 // Check if TYPE_ID lhs_type is compatible with the RHS of assignment stmt
00230 BOOL
00231 Types_are_compatible(TYPE_ID lhs_type, WN *rhs_wn)
00232 {
00233   TYPE_ID  rhs_type = Actual_result_type(rhs_wn);
00234 
00235   return Types_are_compatible(lhs_type, rhs_type);
00236 }
00237   
00238   
00239 
00240 TYPE_ID Rebuild_rtype(TYPE_ID rtype, INT bits)
00241 {
00242   if ( rtype == MTYPE_I4 || rtype == MTYPE_I8 ) {
00243     if ( bits <= 8 )
00244       rtype = MTYPE_I1;
00245     else if ( bits <= 16 )
00246       rtype = MTYPE_I2;
00247     else if ( bits <= 32 )
00248       rtype = MTYPE_I4;
00249     else
00250       rtype = MTYPE_I8;
00251   }
00252   else  {
00253     if ( bits <= 8 )
00254       rtype = MTYPE_U1;
00255     else if ( bits <= 16 )
00256       rtype = MTYPE_U2;
00257     else if ( bits <= 32 )
00258       rtype = MTYPE_U4;
00259     else
00260       rtype = MTYPE_U8;
00261   }
00262   return rtype;
00263 }  
00264 
00265 // Actual_data_size calculates the number of bits for the data
00266 // carried by the tree, ie do not count those bits contains 0 in the
00267 // lsb.  This function is ENDIAN dependent!
00268 INT Actual_data_size(WN *wn)
00269 {
00270   OPERATOR opr = WN_operator(wn);
00271   TYPE_ID rtype = WN_rtype(wn);
00272   INT    actual_size;
00273 
00274   if ((MTYPE_type_class(rtype) & MTYPE_CLASS_INTEGER) == 0)
00275     return MTYPE_size_min(rtype);
00276 
00277   switch ( opr ) {
00278   case OPR_INTCONST:
00279     {
00280       INT64 val;
00281       for (val = WN_const_val(wn), actual_size = 0;
00282            actual_size < 64 && val != 0; actual_size++)
00283         val = val >> 1;
00284       if (MTYPE_is_integral(rtype) && !MTYPE_is_unsigned(rtype) && MTYPE_size_min(rtype) == actual_size) {
00285         // must assume sign extended
00286         actual_size = MTYPE_size_min(Pointer_type);
00287       }
00288       return actual_size;
00289     }
00290 
00291   case OPR_CVTL:
00292     if (MTYPE_is_signed(rtype)) {
00293       actual_size = Actual_data_size(WN_kid0(wn));
00294       if (MTYPE_size_min(rtype) == actual_size)
00295         return actual_size;
00296       else
00297         return WN_cvtl_bits(wn);
00298     }
00299     else
00300       return WN_cvtl_bits(wn);
00301 
00302   case OPR_LDBITS:
00303   case OPR_ILDBITS:
00304       if (MTYPE_is_signed(rtype))
00305         return MTYPE_size_min(rtype);
00306       else
00307         return WN_bit_size (wn);
00308 
00309   case OPR_LDID:
00310   case OPR_ILOAD:
00311     if (MTYPE_is_signed(rtype))  // pv 361929
00312       return MTYPE_size_min(rtype);
00313     else
00314       return MTYPE_size_min(WN_desc(wn));
00315 
00316   case OPR_BAND:
00317   case OPR_BIOR:
00318     {
00319       INT kid0_size = Actual_data_size(WN_kid0(wn));
00320       INT kid1_size = Actual_data_size(WN_kid1(wn));
00321       if (MTYPE_is_unsigned(rtype)) {
00322         if (opr == OPR_BIOR)
00323           return (kid0_size > kid1_size)? kid0_size : kid1_size;
00324         else return (kid0_size > kid1_size)? kid1_size : kid0_size;
00325       }
00326       else return MTYPE_size_min(rtype);
00327     }
00328 
00329   case OPR_SHL:
00330   case OPR_ASHR:
00331   case OPR_LSHR:
00332     {
00333       // The kid1 contains the number of bits.  
00334       WN *bits = WN_kid1(wn);
00335 
00336       // skip if kid 1 is not a constant.
00337       if ( WN_operator(bits) == OPR_INTCONST ) {
00338         UINT bit_cnt = WN_const_val(bits);
00339         if (MTYPE_size_min(rtype) == 32)
00340           bit_cnt &= 0x1F;  // use the low 5 bits
00341         else
00342           bit_cnt &= 0x3F;
00343 
00344         actual_size = Actual_data_size(WN_kid0(wn));
00345         if (opr == OPR_SHL) {
00346           if (MTYPE_is_unsigned(rtype)) {
00347             actual_size += bit_cnt;
00348             if (actual_size > MTYPE_size_min(rtype)) // pv 364274
00349               actual_size = MTYPE_size_min(rtype);
00350           }
00351           else actual_size = MTYPE_size_min(rtype);
00352         }
00353         else if (MTYPE_is_unsigned(rtype)) {
00354           actual_size -= bit_cnt;
00355           if (actual_size < 0) actual_size = 0;
00356         }
00357         else actual_size = MTYPE_size_min(rtype);
00358         return actual_size;
00359       }
00360     }
00361     break;
00362   default:
00363     ;
00364   }
00365   return MTYPE_size_min(rtype);
00366 }
00367 
00368 
00369 // given a OPR_CVTL opcode and the number of bits it converting to,
00370 // return the actual type.
00371 TYPE_ID Actual_cvtl_type(OPCODE opc, INT bits)
00372 {
00373   return Rebuild_rtype(OPCODE_rtype(opc), bits);
00374 }
00375 
00376 // Actual_result_type returns the data type of the tree with the
00377 // actual number of bytes that we can determine at this point.  This
00378 // function helps to determine a CVTL node is required or can be
00379 // deleted by the optimizer emitter.
00380 TYPE_ID Actual_result_type(WN *wn)
00381 {
00382   OPCODE opc = WN_opcode(wn);
00383   TYPE_ID  rtype = OPCODE_rtype(opc);
00384   INT    bits;
00385 
00386   // only do it for an integer type
00387   if ((MTYPE_type_class(rtype) & MTYPE_CLASS_INTEGER) == 0)
00388     return rtype;
00389 
00390   switch ( OPCODE_operator(opc) ) {
00391   case OPR_CVTL:
00392   case OPR_LDID:
00393   case OPR_LDBITS:
00394   case OPR_ILOAD:
00395   case OPR_ILDBITS:
00396   case OPR_BIOR:
00397   case OPR_BAND:
00398   case OPR_SHL:
00399   case OPR_ASHR:
00400   case OPR_LSHR:
00401   case OPR_INTCONST:
00402     bits = Actual_data_size(wn);
00403     rtype = Rebuild_rtype(rtype, bits);
00404   }
00405 
00406   return rtype;
00407 }
00408 
00409 TYPE_ID Adjust_signed_type(TYPE_ID rtype, INT size, WN *wn)
00410 {
00411   INT bits = Actual_data_size(wn);
00412 
00413   if (MTYPE_is_integral(rtype) && !MTYPE_is_unsigned(rtype) && size == bits) {
00414     // need sign extension
00415     // 32 is the largest size CVTL would convert to
00416     return Rebuild_rtype(rtype, 32);
00417   }
00418   return MTYPE_UNKNOWN;
00419 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines