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