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
[email protected]
https://lists.sourceforge.net/lists/listinfo/open64-devel