This patch is approved by Sun Chan and Fred Chow.
Gang

On Wed, Oct 20, 2010 at 8:00 PM, <s...@open64.net> wrote:

> 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
>
------------------------------------------------------------------------------
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