Author: mberg
Date: 2011-04-07 15:33:55 -0400 (Thu, 07 Apr 2011)
New Revision: 3539

Modified:
   trunk/osprey/be/cg/cg.cxx
   trunk/osprey/be/cg/cg_flags.cxx
   trunk/osprey/be/cg/ebo.cxx
   trunk/osprey/be/cg/x8664/cgtarget.cxx
   trunk/osprey/be/cg/x8664/ebo_special.cxx
   trunk/osprey/be/cg/x8664/exp_loadstore.cxx
   trunk/osprey/be/opt/opt_estr.cxx
   trunk/osprey/common/com/config_wopt.cxx
   trunk/osprey/common/com/config_wopt.h
Log:
Addition of -WOPT:SIB=<on|off> flag and its functionality to support
Scaled-Index-Base address mode generation.  Also extended pattern
matching for add sub instructions to generation inc and dec
instructions.



Modified: trunk/osprey/be/cg/cg.cxx
===================================================================
--- trunk/osprey/be/cg/cg.cxx   2011-04-07 17:28:58 UTC (rev 3538)
+++ trunk/osprey/be/cg/cg.cxx   2011-04-07 19:33:55 UTC (rev 3539)
@@ -748,6 +748,7 @@
   Set_Error_Phase( "Code Generation" );
   Start_Timer( T_CodeGen_CU );
 
+
 #ifdef TARG_X8664
 // Cannot enable emit_unwind_info if Force_Frame_Pointer is not set
 // Need this flag set for C++ exceptions and for -g

Modified: trunk/osprey/be/cg/cg_flags.cxx
===================================================================
--- trunk/osprey/be/cg/cg_flags.cxx     2011-04-07 17:28:58 UTC (rev 3538)
+++ trunk/osprey/be/cg/cg_flags.cxx     2011-04-07 19:33:55 UTC (rev 3539)
@@ -296,7 +296,7 @@
 UINT64 CG_p2align_freq = 10000;
 UINT32 CG_p2align_max_skip_bytes = 3;
 UINT32 CG_movnti = 1000;
-BOOL CG_use_incdec = FALSE;
+BOOL CG_use_incdec = TRUE;
 BOOL CG_use_xortozero = TRUE; // bug 8592
 BOOL CG_use_xortozero_Set = FALSE;
 BOOL CG_use_test = FALSE;

Modified: trunk/osprey/be/cg/ebo.cxx
===================================================================
--- trunk/osprey/be/cg/ebo.cxx  2011-04-07 17:28:58 UTC (rev 3538)
+++ trunk/osprey/be/cg/ebo.cxx  2011-04-07 19:33:55 UTC (rev 3539)
@@ -2970,6 +2970,12 @@
                 op_replaced = Constant_Operand1 (op, opnd_tn, opnd_tninfo);
               }
             }
+#ifdef TARG_X8664
+           if (!op_replaced && (OP_code(op) == TOP_inc32 || OP_code(op) == 
TOP_dec32 
+                               || OP_code(op) == TOP_inc64 || OP_code(op) == 
TOP_dec64 )
+              )
+              op_replaced = Constant_Operand1 (op, opnd_tn, opnd_tninfo);
+#endif
             if (o1_idx >= 0) {
               tn = opnd_tn[o1_idx];
               if (!op_replaced &&

Modified: trunk/osprey/be/cg/x8664/cgtarget.cxx
===================================================================
--- trunk/osprey/be/cg/x8664/cgtarget.cxx       2011-04-07 17:28:58 UTC (rev 
3538)
+++ trunk/osprey/be/cg/x8664/cgtarget.cxx       2011-04-07 19:33:55 UTC (rev 
3539)
@@ -166,6 +166,11 @@
       case TOP_ldhpdx:
       case TOP_ldhpdxx:
       case TOP_ldhpd_n32:
+      // only source operand of cvtps2pd can be memory, so the ref is 8 bytes.
+      case TOP_cvtps2pd:
+      case TOP_cvtps2pd_x:
+      case TOP_cvtps2pd_xx:
+      case TOP_cvtps2pd_xxx:
         return 8;
       default:
         return 16;

Modified: trunk/osprey/be/cg/x8664/ebo_special.cxx
===================================================================
--- trunk/osprey/be/cg/x8664/ebo_special.cxx    2011-04-07 17:28:58 UTC (rev 
3538)
+++ trunk/osprey/be/cg/x8664/ebo_special.cxx    2011-04-07 19:33:55 UTC (rev 
3539)
@@ -148,7 +148,7 @@
 static BOOL Convert_Imm_And( OP* op, TN *tnr, TN *tn, INT64 imm_val, 
EBO_TN_INFO *tninfo );
 static BOOL Convert_Imm_Mul( OP* op, TN *tnr, TN *tn, INT64 imm_val, 
EBO_TN_INFO *tninfo );
 static BOOL Convert_Imm_Or( OP* op, TN *tnr, TN *tn, INT64 imm_val, 
EBO_TN_INFO *tninfo );
-static BOOL Convert_Imm_Add( OP* op, TN *tnr, TN *tn, INT64 imm_val, 
EBO_TN_INFO *tninfo );
+static BOOL Convert_Imm_Add( OP* op, TN *tnr, TN *tn, INT64 imm_val, 
EBO_TN_INFO *tninfo, BOOL simplify_iadd );
 static BOOL Convert_Imm_Xor( OP* op, TN *tnr, TN *tn, INT64 imm_val, 
EBO_TN_INFO *tninfo );
 static BOOL Convert_Imm_Cmp( OP* op, TN *tnr, TN *tn, INT64 imm_val, 
EBO_TN_INFO *tninfo );
 
@@ -1477,7 +1477,8 @@
 /* Attempt to convert an add of 'tn' + 'imm_val' into an addi. Return
    TRUE if we succeed, FALSE otherwise. */
 static BOOL
-Convert_Imm_Add (OP *op, TN *tnr, TN *tn, INT64 imm_val, EBO_TN_INFO *tninfo)
+Convert_Imm_Add (OP *op, TN *tnr, TN *tn, INT64 imm_val, 
+                 EBO_TN_INFO *tninfo, BOOL simplify_iadd)
 {
 #if Is_True_On
   if (!(EBO_Opt_Mask & EBO_CONVERT_IMM_ADD)) return FALSE;
@@ -1501,11 +1502,26 @@
     new_op = Mk_OP(new_opcode, tnr, tn);
 
   } else if (ISA_LC_Value_In_Class ( imm_val, LC_simm32)) {
-    if ( OP_code(op) == TOP_addi32 || OP_code(op) == TOP_addi64 ||
-        OP_code(op) == TOP_lea32 || OP_code(op) == TOP_lea64 )
+    // Use simplify_iadd to guard against inc/dec forms which
+    // come from addi-addi combinations.
+    if ( simplify_iadd ) {
+      if ( OP_code(op) == TOP_lea32 || OP_code(op) == TOP_lea64 ) {
+        return FALSE;
+      } else if ( OP_code(op) == TOP_addi32 || OP_code(op) == TOP_addi64 ) {
+        if ( ( imm_val != 1 ) && ( imm_val != -1 ) )
+          return FALSE;
+        else if ( Is_Target_32bit() ) 
+          return FALSE;
+      }
+    } else if ( OP_code(op) == TOP_addi32 || OP_code(op) == TOP_addi64 ||
+                OP_code(op) == TOP_lea32  || OP_code(op) == TOP_lea64 ) {
       return FALSE;
+    }
     new_opcode = is_64bit ? TOP_addi64 : TOP_addi32;
     BOOL rflags_read = FALSE;
+    if ( simplify_iadd )
+      new_opcode = OP_code(op);
+
     // If there is an instruction that is awaiting a rflags update then, 
     // do not convert the current op.
     for( OP* next_op = OP_next(op); next_op != NULL;
@@ -1535,6 +1551,17 @@
           TOP_is_change_rflags( OP_code(op) )))))
       return FALSE;
 
+    if ( simplify_iadd ) {
+      bool valid_inc_dec = true;
+      if ( is_64bit && (OP_code(op) != TOP_addi64))
+        valid_inc_dec = false;
+      else if (!is_64bit && (OP_code(op) != TOP_addi32))
+        valid_inc_dec = false;
+
+      if (valid_inc_dec == false)
+        return FALSE;
+    }
+
     if (new_opcode != TOP_inc32 && new_opcode != TOP_inc64 &&
        new_opcode != TOP_dec32 && new_opcode != TOP_dec64)
       new_op = Mk_OP(new_opcode, tnr, tn, Gen_Literal_TN(imm_val, 4));
@@ -1617,7 +1644,8 @@
       opcode == TOP_add64 ||
       opcode == TOP_lea32 ||
       opcode == TOP_lea64)
-    return Convert_Imm_Add(op, tnr, tn1, TN_value(tn0), opnd_tninfo[o1_idx]);
+    return Convert_Imm_Add(op, tnr, tn1, TN_value(tn0), 
+                           opnd_tninfo[o1_idx], false);
 
   return FALSE;
 }
@@ -1850,7 +1878,18 @@
   return TRUE;
 }
 
+BOOL OP_iadd_inc(OP* op)
+{
+  if (OP_iadd(op)) return TRUE;
+  TOP top = OP_code(op);
+  if (top == TOP_inc32 || top == TOP_inc64 ||
+      top == TOP_dec32 || top == TOP_dec64)
+        return TRUE;
+  return FALSE; 
 
+}
+
+
 /*
  * Look at an exression that has a constant second operand and attempt to
  * simplify the computations.
@@ -1886,6 +1925,11 @@
 
   TN *tn0 = opnd_tn[o0_idx];
   TN *tn1 = opnd_tn[o1_idx];
+  if (OP_code(op) == TOP_inc32 || OP_code(op) == TOP_inc64)
+    tn1 = Gen_Literal_TN(1, 4);
+  else if (OP_code(op) == TOP_dec32 || OP_code(op) == TOP_dec64)
+    tn1 = Gen_Literal_TN(-1, 4);
+
   TN *tnr = OP_has_result(op) ? OP_result(op,0) : NULL;
 
   /* Don't mess with symbols. */
@@ -1921,8 +1965,10 @@
       opcode == TOP_add64 ||
       opcode == TOP_lea32 || 
       opcode == TOP_lea64 )
-    return Convert_Imm_Add(op, tnr, tn0, imm_val, opnd_tninfo[o0_idx]);
+    return Convert_Imm_Add( op, tnr, tn0, imm_val, 
+                            opnd_tninfo[o0_idx], false );
 
+
   if( OP_imul( op ) )
     return Convert_Imm_Mul( op, tnr, tn0, imm_val, opnd_tninfo[o0_idx] );
 
@@ -1943,12 +1989,16 @@
   TOP pred_opcode = OP_code(pred_op);
 
   /* Look for a sequence of two addi that can be combined. */
-  if (OP_iadd(op) && OP_iadd(pred_op))
+  if (OP_iadd_inc(op) && OP_iadd_inc(pred_op))
   {
     INT ptn0_idx = 0;
     INT ptn1_idx = 1;
     TN *ptn0 = OP_opnd(pred_op, ptn0_idx);
     TN *ptn1 = OP_opnd(pred_op, ptn1_idx);
+    if (OP_code(pred_op) == TOP_inc32 || OP_code(pred_op) == TOP_inc64)
+      ptn1 = Gen_Literal_TN(1, 4);
+    else if (OP_code(pred_op) == TOP_dec32 || OP_code(pred_op) == TOP_dec64)
+      ptn1 = Gen_Literal_TN(-1, 4);
 
     if (TN_is_constant(ptn1) && !TN_is_symbol(ptn1))
     {
@@ -1958,7 +2008,7 @@
       if (EBO_tn_available(bb, ptn0_tninfo))
       {
        const INT64 new_val = imm_val + TN_value(ptn1);
-       if (Convert_Imm_Add(op, tnr, ptn0, new_val, ptn0_tninfo))
+       if (Convert_Imm_Add(op, tnr, ptn0, new_val, ptn0_tninfo, false))
        {
          if (EBO_Trace_Optimization)
            fprintf(TFile,"\tcombine immediate adds\n");
@@ -1969,6 +2019,14 @@
     }
   }
 
+  if ( opcode == TOP_addi32 ||
+       opcode == TOP_addi64 ) {
+    if ( ( imm_val == 1 ) || ( imm_val == -1 ) ) {
+      return Convert_Imm_Add( op, tnr, tn0, imm_val, 
+                              opnd_tninfo[o0_idx], true );
+    }
+  }
+
   return FALSE;
 }
 
@@ -2691,6 +2749,7 @@
 
   return TRUE;
 }
+static inline TN* OP_opnd_use( OP* op, ISA_OPERAND_USE use );
 
 BOOL Delete_Unwanted_Prefetches ( OP* op )
 {
@@ -2703,7 +2762,9 @@
   OP *incr = NULL;
   OP *as_opnd = NULL;
   OP *as_result = NULL;
+  OP *leaxx = NULL;
   OP *load_store = NULL;
+  BOOL sib = FALSE;
   BB* bb = OP_bb( op );
   OP *next = BB_first_op( bb );
 
@@ -2714,7 +2775,9 @@
   if(PF_GET_KEEP_ANYWAY(WN_prefetch_flag(mem_wn)))
    return FALSE;
 #endif  
-  if (OP_find_opnd_use( op, OU_base ) >= 0)
+  if (OP_find_opnd_use( op, OU_base ) >= 0 && 
+      // the prefetch instruction has passed a call of this function, so pass 
it.
+      Get_Top_For_Addr_Mode(OP_code(op), BASE_MODE) == OP_code(op))
     base = OP_opnd( op, OP_find_opnd_use( op, OU_base ));
   else
     return FALSE; // Can not analyze further; make safe assumption.
@@ -2729,21 +2792,43 @@
        as_result = next;
       else if (OP_opnd(next, 0) == base)
        as_opnd = next;
-    }
+    } else if ((OP_code(next) == TOP_leax32 || OP_code(next) == TOP_leax64) 
+                   && OP_result(next, 0) == base)
+           leaxx = next;
     
     next = OP_next(next);
   }
   
+  INT delta_base;
   if (!incr) {
-    if (!as_result && !as_opnd)
+    if (!as_result && !as_opnd && !leaxx)
       return TRUE;
-    else if (as_result)
-      incr = as_result;
+    else if (leaxx)
+    {  // further analyze the two terms for RPR
+      TN* term;
+      term = OP_opnd_use(leaxx, OU_index);
+
+      OP *w_incr;
+        for (w_incr = BB_first_op(bb); w_incr != NULL; w_incr = 
OP_next(w_incr))
+       {
+          if (((OP_code(w_incr) == TOP_addi32 || OP_code(w_incr) == 
TOP_addi64)) &&
+            (OP_results(w_incr) != 0 && OP_result(w_incr, 0) == term && 
+             OP_opnd(w_incr, 0) == term))
+         break;
+       }
+      if (w_incr != NULL){
+       sib = TRUE;
+        delta_base = TN_value(OP_opnd(w_incr,1)) * 
(TN_value(OP_opnd_use(leaxx,OU_scale)));
+      } else
+        return TRUE;
+    } else if (as_result)
+           incr = as_result;
     else 
       incr = as_opnd;
   }
   
-  INT delta_base = TN_value(OP_opnd(incr, 1));
+  if (!sib) 
+    delta_base = TN_value(OP_opnd(incr, 1));
 
   next = BB_first_op( bb );
   while (next && !load_store) {
@@ -4110,12 +4195,21 @@
     break;
 
   case TOP_addi32:
+  case TOP_inc32:
+  case TOP_dec32:
     if( Is_Target_64bit() )
       return FALSE;
     // fall thru
   case TOP_addi64:
+  case TOP_inc64:
+  case TOP_dec64:
     a.base = OP_opnd( addr_op, 0 );
-    a.offset = OP_opnd( addr_op, 1 );
+    if (top == TOP_inc32 || top == TOP_inc64)
+      a.offset = Gen_Literal_TN(1, 4);
+    else if (top == TOP_dec32 || top == TOP_dec64)
+      a.offset = Gen_Literal_TN(-1, 4);
+    else
+      a.offset = OP_opnd( addr_op, 1 );
     break;
 
   case TOP_mov32:

Modified: trunk/osprey/be/cg/x8664/exp_loadstore.cxx
===================================================================
--- trunk/osprey/be/cg/x8664/exp_loadstore.cxx  2011-04-07 17:28:58 UTC (rev 
3538)
+++ trunk/osprey/be/cg/x8664/exp_loadstore.cxx  2011-04-07 19:33:55 UTC (rev 
3539)
@@ -192,7 +192,7 @@
     if ( rclass == ISA_REGISTER_CLASS_mmx )
       return base != NULL ? TOP_ld64_2m : TOP_ld64_2m_n32;
     else if ( rclass == ISA_REGISTER_CLASS_float )
-      return base != NULL ? TOP_ld64_2sse : TOP_ld64_2sse_n32;
+      return base != NULL ? TOP_ldlps : TOP_ldlps_n32;
     else
       return base != NULL ? TOP_ld64 : TOP_ld64_off;
   case MTYPE_M8I1:

Modified: trunk/osprey/be/opt/opt_estr.cxx
===================================================================
--- trunk/osprey/be/opt/opt_estr.cxx    2011-04-07 17:28:58 UTC (rev 3538)
+++ trunk/osprey/be/opt/opt_estr.cxx    2011-04-07 19:33:55 UTC (rev 3539)
@@ -1002,7 +1002,19 @@
   return FALSE;
 }
 
+static
+BOOL Is_address_const(OPERATOR opr, const CODEREP *expr, 
+                      const CODEREP *expr_sib, const CODEREP *expr_parent)
+{
+    if (!WOPT_Enable_SIB) return FALSE;
+    if (opr == OPR_MPY && expr->Kind() == CK_CONST &&
+        (expr->Const_val() == 2 || 
+         expr->Const_val() == 4 ||
+         expr->Const_val() == 8 )) 
+        return TRUE;
 
+    return FALSE;
+}
 
 //======================================================================
 // Determine if this occurrence is a strength-reduction candidate
@@ -1102,7 +1114,8 @@
                                opr == OPR_ADD || opr == OPR_SUB))
       {
        if (Is_cvt_linear(use_opnd0) &&
-           Is_implicit_cvt_linear(cr->Dtyp(), use_opnd0)) {
+           Is_implicit_cvt_linear(cr->Dtyp(), use_opnd0) &&
+        !Is_address_const(opr, use_opnd1, use_opnd0, cr)) {
          return TRUE;
         }
       }
@@ -1115,7 +1128,8 @@
                                opr == OPR_ADD || opr == OPR_SUB))
       {
         if (Is_cvt_linear(use_opnd1) &&
-           Is_implicit_cvt_linear(cr->Dtyp(), use_opnd1)) {
+           Is_implicit_cvt_linear(cr->Dtyp(), use_opnd1) &&
+        !Is_address_const(opr, use_opnd0, use_opnd1, cr)) {
          return TRUE;
         }
       }
@@ -1187,7 +1201,8 @@
                                       opr == OPR_ADD || opr == OPR_SUB))
       {
        if (Is_cvt_linear(use_opnd0) &&
-           Is_implicit_cvt_linear(cr->Dtyp(), use_opnd0)) {
+           Is_implicit_cvt_linear(cr->Dtyp(), use_opnd0) &&
+        !Is_address_const(opr, use_opnd1, use_opnd0, cr)) {
          return TRUE;
        }
       }
@@ -1200,7 +1215,8 @@
                                       opr == OPR_ADD || opr == OPR_SUB))
       {
        if (Is_cvt_linear(use_opnd1) &&
-           Is_implicit_cvt_linear(cr->Dtyp(), use_opnd1)) {
+           Is_implicit_cvt_linear(cr->Dtyp(), use_opnd1) &&
+        !Is_address_const(opr, use_opnd0, use_opnd1, cr)) {
          return TRUE;
        }
       }

Modified: trunk/osprey/common/com/config_wopt.cxx
===================================================================
--- trunk/osprey/common/com/config_wopt.cxx     2011-04-07 17:28:58 UTC (rev 
3538)
+++ trunk/osprey/common/com/config_wopt.cxx     2011-04-07 19:33:55 UTC (rev 
3539)
@@ -207,6 +207,7 @@
 BOOL  WOPT_Enable_MP_varref = TRUE;
 const BOOL  WOPT_Enable_MP_Const_Prop = TRUE;
 BOOL  WOPT_Enable_New_SR = TRUE;
+BOOL  WOPT_Enable_SIB = FALSE;
 INT32 WOPT_Enable_New_SR_Limit = 0;
 BOOL  WOPT_Enable_Output_Copy = TRUE;
 INT32 WOPT_Enable_Ocopy_Lookupstmt = 2;
@@ -587,6 +588,8 @@
 #endif
   { OVK_BOOL,  OV_VISIBLE,     TRUE, "new_sr",         "",
     0, 0, 0,   &WOPT_Enable_New_SR, NULL },
+  { OVK_BOOL,  OV_VISIBLE,     FALSE, "sib",           "sib",
+    0, 0, 0,   &WOPT_Enable_SIB, NULL },
   { OVK_INT32, OV_VISIBLE,     TRUE, "new_sr_limit",           "new_sr_limit",
     INT32_MAX, 0, INT32_MAX,   &WOPT_Enable_New_SR_Limit, NULL },
   { OVK_BOOL,  OV_VISIBLE,     TRUE, "ocopy",          "ocopy",

Modified: trunk/osprey/common/com/config_wopt.h
===================================================================
--- trunk/osprey/common/com/config_wopt.h       2011-04-07 17:28:58 UTC (rev 
3538)
+++ trunk/osprey/common/com/config_wopt.h       2011-04-07 19:33:55 UTC (rev 
3539)
@@ -214,6 +214,7 @@
 extern const BOOL WOPT_Enable_MP_Const_Prop;  /* perform const prop into MP 
region */
 extern BOOL WOPT_Enable_New_SR;                /* new strength-reduction */
 extern BOOL WOPT_Enable_New_SR_Limit;
+extern BOOL WOPT_Enable_SIB;           /* abandon some SR candidate for x86 
SIB */
 extern BOOL WOPT_Enable_Output_Copy;    /* output copy propagation */
 extern BOOL WOPT_Enable_Ocopy_Lookupstmt;
 extern BOOL WOPT_Enable_Parm;          /* insert OPTPARM over parms */


------------------------------------------------------------------------------
Xperia(TM) PLAY
It's a major breakthrough. An authentic gaming
smartphone on the nation's most reliable network.
And it wants your games.
http://p.sf.net/sfu/verizon-sfdev
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to