Author: yug
Date: 2010-10-20 08:00:35 -0400 (Wed, 20 Oct 2010)
New Revision: 3379

Modified:
   trunk/osprey/be/opt/opt_cfg.cxx
   trunk/osprey/be/opt/opt_cfg.h
   trunk/osprey/be/opt/opt_dce.cxx
   trunk/osprey/common/com/config_wopt.cxx
   trunk/osprey/common/com/config_wopt.h
Log:
Open64's always bottom-test loop form (inversioned) are not code-size saving 
for those while-dos and do-loops with big condition and small body. So, we 
design a heuristic to filter out those cases and do normal condition headed 
loop lowering

Modified: trunk/osprey/be/opt/opt_cfg.cxx
===================================================================
--- trunk/osprey/be/opt/opt_cfg.cxx     2010-10-20 03:46:11 UTC (rev 3378)
+++ trunk/osprey/be/opt/opt_cfg.cxx     2010-10-20 12:00:35 UTC (rev 3379)
@@ -99,6 +99,7 @@
 #include "opt_ssa.h"
 #include "opt_tail.h"
 #include "w2op.h"
+#include "wn_tree_util.h"
 
 CFG::CFG(MEM_POOL *pool, MEM_POOL *lpool)
      : _bb_vec(pool),
@@ -2815,6 +2816,93 @@
 //   it's added to.
 // ====================================================================
 
+
+
+BOOL CFG::bottom_test_loop(WN* scf_loop){
+  
+  Is_True(scf_loop != NULL,("NULL passed to bottom_test_loop\n"));
+
+  const OPCODE   opc = WN_opcode(scf_loop);
+  const OPERATOR opr = OPCODE_operator(opc);
+  
+  Is_True(opr == OPR_WHILE_DO || opr == OPR_DO_LOOP,
+          ("%s not supported, only handle OPR_WHILE_DO or 
OPR_DO_LOOP\n",OPCODE_name(opc)));
+
+  WN *do_loopinfo = NULL;
+  WN *do_tripcount = NULL;
+
+  // for const tripcount(>0) do_loop , we always do bottom_test_loop
+  if ( (opr == OPR_DO_LOOP) && 
+       (do_loopinfo = WN_do_loop_info(scf_loop)) &&
+       (do_tripcount = WN_loop_trip(do_loopinfo)) &&
+       (WN_operator(do_tripcount) == OPR_INTCONST) &&
+       (WN_const_val(do_tripcount) > 0)) {
+    if (Trace()) {
+      fprintf(TFile,"bottom_test_loop:\n");
+      fdump_tree_no_st(TFile,scf_loop);
+    }
+    return TRUE;
+  }
+
+
+  WN* loop_condition = (opr == OPR_WHILE_DO) ? WN_while_test(scf_loop) : 
WN_end(scf_loop);
+  WN* loop_body = (opr == OPR_WHILE_DO) ? WN_while_body(scf_loop) : 
WN_do_body(scf_loop) ;
+
+  const OPCODE cond_op = WN_opcode(loop_condition);
+  const OPCODE body_op = WN_opcode(loop_body);
+  const OPERATOR opr_body = OPCODE_operator(body_op);
+
+  Is_True(OPCODE_is_expression(cond_op), 
+         ("Bad condition opcode %s\n", 
+          OPCODE_name(cond_op)));
+  Is_True(opr_body == OPR_BLOCK, 
+         ("Bad Body block opcode %s\n",
+          OPCODE_name(body_op)));
+
+  WN_TREE_CONTAINER<PRE_ORDER>  wcpre(loop_condition);
+  WN_TREE_CONTAINER<PRE_ORDER> ::iterator wipre;
+  WN_count wc;
+  INT32 stmt_count=0;
+
+  for (wipre = wcpre.begin(); wipre != wcpre.end(); ++wipre)
+    wc(wipre.Wn());
+  if (wc.num_nodes >= WOPT_Bottom_Test_Loop_Cond_Limit) {
+    for ( WN *stmt = WN_first(loop_body); stmt != NULL; stmt = WN_next(stmt) ) 
{
+      const OPCODE op_in_body = WN_opcode(stmt);
+      if( ! OPCODE_is_stmt(op_in_body) ) {
+       if (Trace()) {
+         fprintf(TFile,"bottom_test_loop:\n");
+         fdump_tree_no_st(TFile,scf_loop);
+       }
+       return TRUE;
+      }
+      if ( ! OPCODE_has_label(op_in_body)) {
+       stmt_count++;
+       if (stmt_count >= WOPT_Bottom_Test_Loop_Body_Limit) {
+         if (Trace()) {
+           fprintf(TFile,"bottom_test_loop:\n");
+           fdump_tree_no_st(TFile,scf_loop);
+         }
+         return TRUE;
+       }
+      }
+    }
+    if (Trace()) {
+         fprintf(TFile,"non bottom_test_loop:\n");
+         fdump_tree_no_st(TFile,scf_loop);
+    }
+    return FALSE;
+  }
+  else {
+    if (Trace()) {
+      fprintf(TFile,"bottom_test_loop:\n");
+      fdump_tree_no_st(TFile,scf_loop);
+    }
+    return TRUE;
+  }
+}
+
+
 void
 CFG::Add_one_stmt( WN *wn, END_BLOCK *ends_bb )
 {
@@ -2930,8 +3018,19 @@
 
   case OPR_DO_LOOP:
     Create_empty_preheader (wn);
-    if (Lower_fully())
-      Lower_do_loop( wn, ends_bb );
+    if (Lower_fully()) {
+      if ( OPT_Space && WOPT_Bottom_Test_Loop_Check ) {
+        if ( ! bottom_test_loop(wn) ) {
+          Add_one_do_loop_stmt( wn, ends_bb );
+        }
+        else {
+          Lower_do_loop( wn, ends_bb );
+        }
+      }
+      else {
+        Lower_do_loop( wn, ends_bb );
+      }
+    }
     else
       Add_one_do_loop_stmt( wn, ends_bb );
     break;
@@ -2939,7 +3038,17 @@
   case OPR_WHILE_DO:
     Create_empty_preheader (wn);
     if (Lower_fully()) {
-      Lower_while_do( wn, ends_bb );
+      if (OPT_Space && WOPT_Bottom_Test_Loop_Check) {
+        if ( ! bottom_test_loop(wn)) {
+          Add_one_while_do_stmt(wn, ends_bb);
+       }
+       else {
+         Lower_while_do( wn, ends_bb );
+       }
+      }
+      else {
+       Lower_while_do( wn, ends_bb );
+      }
     }
     else {
       Add_one_while_do_stmt( wn, ends_bb );
@@ -5327,7 +5436,11 @@
     BB_LOOP *loop = bb->Loop();
     if (loop != NULL && loop->Header() == bb) {
       if (loop->End() != NULL) {
-       loop->Start()->Set_loop(loop);
+       if(loop->Start())
+         loop->Start()->Set_loop(loop);
+       else {
+         Is_True(loop->Is_flag_set(LOOP_PRE_WHILE),("wrong non bottom test 
loop lowering\n"));
+       }
        loop->End()->Set_loop(loop);
        loop->Body()->Set_loop(loop);
        if (loop->Step())
@@ -5454,12 +5567,15 @@
         loop->Loopback()->Kind() == BB_REGIONEXIT,
                ("found inconsistent BB_LOOP -- loopback is not BB_GOTO"));
       } else {
-       Is_True(loop->Start()->Loop() == loop &&
+       Is_True((loop->Start() == NULL || loop->Start()->Loop() == loop) &&
                loop->End()->Loop() == loop &&
                loop->Body()->Loop() == loop &&
                (loop->Step() == NULL || loop->Step()->Loop() == loop),
                // loop->Merge()->Loop() == loop,
                ("found inconsistent BB_LOOP and CFG."));
+       if (loop->Start() == NULL) {
+          Is_True(loop->Is_flag_set(LOOP_PRE_WHILE),("wrong non bottom test 
loop lowering!\n"));
+        }
       }
     }
     // verify innermost loop

Modified: trunk/osprey/be/opt/opt_cfg.h
===================================================================
--- trunk/osprey/be/opt/opt_cfg.h       2010-10-20 03:46:11 UTC (rev 3378)
+++ trunk/osprey/be/opt/opt_cfg.h       2010-10-20 12:00:35 UTC (rev 3379)
@@ -445,6 +445,8 @@
   void         LMV_clone_BB_IFINFO (LMV_CFG_ADAPTOR* );
   void         LMV_clone_frequency (LMV_CFG_ADAPTOR*);
 
+  //bottom test loop check
+  BOOL bottom_test_loop(WN* while_do);
 
   // From here on, all are public access functions
 public:

Modified: trunk/osprey/be/opt/opt_dce.cxx
===================================================================
--- trunk/osprey/be/opt/opt_dce.cxx     2010-10-20 03:46:11 UTC (rev 3378)
+++ trunk/osprey/be/opt/opt_dce.cxx     2010-10-20 12:00:35 UTC (rev 3379)
@@ -2806,7 +2806,8 @@
          // back out during PRE
          // NOTE: this also picks up the Trip_count_stmt().
          BB_NODE *dohead = loop->Start();
-         if ( dohead && dohead->Kind() == BB_DOHEAD ) {
+         if ( (dohead && loop->Is_flag_set(LOOP_DO) && dohead->Kind() == 
BB_DOHEAD) ||
+           (dohead && loop->Is_flag_set(LOOP_PRE_DO) && dohead->Kind() == 
BB_DOSTART) ) {
            STMTREP_ITER stmt_iter(dohead->Stmtlist());
            STMTREP *dohead_stmt;
            FOR_ALL_NODE( dohead_stmt, stmt_iter, Init() ) {
@@ -3775,7 +3776,11 @@
     // having a live branch is all that's necessary for a valid loop,
     // but make sure we keep around interesting blocks
     if ( _cfg->Lower_fully() ) {
-      Keep_unreached_bb(bb->Loopstart());
+      if (bb->Loopstart())
+        Keep_unreached_bb(bb->Loopstart());
+      else { 
+        Is_True(bb->Loop()->Is_flag_set(LOOP_PRE_WHILE),("wrong non bottom 
test loop lowering!\n"));
+      }
       Keep_unreached_bb(bb->Loopbody());
       Keep_unreached_bb(bb->Loopmerge());
 

Modified: trunk/osprey/common/com/config_wopt.cxx
===================================================================
--- trunk/osprey/common/com/config_wopt.cxx     2010-10-20 03:46:11 UTC (rev 
3378)
+++ trunk/osprey/common/com/config_wopt.cxx     2010-10-20 12:00:35 UTC (rev 
3379)
@@ -377,6 +377,9 @@
 BOOL WOPT_Enable_Aggressive_Iload_CSE = TRUE; // ignore potential iload vsym 
aliasing
 #endif
 
+BOOL WOPT_Bottom_Test_Loop_Check=FALSE;
+INT32 WOPT_Bottom_Test_Loop_Cond_Limit=3;
+INT32 WOPT_Bottom_Test_Loop_Body_Limit=5;
 /* ====================================================================
  *
  * Descriptor for the -WOPT option group.
@@ -854,5 +857,11 @@
   { OVK_BOOL,   OV_VISIBLE,     TRUE, "aggr_iload_cse",        "",
     0, 0, 0,    &WOPT_Enable_Aggressive_Iload_CSE, NULL },
 #endif
+  { OVK_BOOL,   OV_INTERNAL,    TRUE, "bottom_test_loop_check",    "",
+      0, 0, 0,  &WOPT_Bottom_Test_Loop_Check, NULL},
+  { OVK_INT32,  OV_VISIBLE,    FALSE, "bottom_test_loop_cond",              "",
+    INT32_MAX, 0, INT32_MAX,    &WOPT_Bottom_Test_Loop_Cond_Limit, NULL },
+  { OVK_INT32,  OV_VISIBLE,    FALSE, "bottom_test_loop_body",              "",
+    INT32_MAX, 0, INT32_MAX,    &WOPT_Bottom_Test_Loop_Body_Limit, NULL },
   { OVK_COUNT }                /* List terminator -- must be last */
 };

Modified: trunk/osprey/common/com/config_wopt.h
===================================================================
--- trunk/osprey/common/com/config_wopt.h       2010-10-20 03:46:11 UTC (rev 
3378)
+++ trunk/osprey/common/com/config_wopt.h       2010-10-20 12:00:35 UTC (rev 
3379)
@@ -358,5 +358,9 @@
 
 extern BOOL WOPT_Enable_STR_Short;  // whether to assume 16bit IV can cross 16
 
+extern BOOL WOPT_Bottom_Test_Loop_Check;
+extern INT32 WOPT_Bottom_Test_Loop_Cond_Limit;
+extern INT32 WOPT_Bottom_Test_Loop_Body_Limit;
+
 #endif /* config_wopt_INCLUDED */
 


------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly 
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to