Author: meiye Date: 2011-05-23 20:25:51 -0400 (Mon, 23 May 2011) New Revision: 3624
Modified: trunk/osprey/be/lno/outer.cxx trunk/osprey/be/lno/sclrze.cxx Log: Add a heuristic to turn off level 2 loop fusion if there exists a write to formal paramters. This is a workaround for a program bug in CPU2006 gameness. Flag pass-by-reference parameters in scalarization to avoid deleting stores that appear dead but actually not since the variable is passed by reference. CR: Sun Chan Modified: trunk/osprey/be/lno/outer.cxx =================================================================== --- trunk/osprey/be/lno/outer.cxx 2011-05-24 00:24:38 UTC (rev 3623) +++ trunk/osprey/be/lno/outer.cxx 2011-05-24 00:25:51 UTC (rev 3624) @@ -345,8 +345,44 @@ } return FALSE; } - +// Check whether there exists write to formal parameters in 'writes'. +static BOOL Has_parm_ref(REF_LIST_STACK * writes) +{ + for (int i = 0; i < writes->Elements(); i++) { + REFERENCE_ITER w_iter(writes->Bottom_nth(i)); + for (REFERENCE_NODE * node1 = w_iter.First(); !w_iter.Is_Empty(); + node1 = w_iter.Next()) { + WN * wn_node = node1->Wn; + if (wn_node) { + OPERATOR opr = WN_operator(wn_node); + if (OPERATOR_is_store(opr)) { + if (OPERATOR_is_scalar_store(opr)) { + if (WN_has_sym(wn_node)) { + ST *st = WN_st(wn_node); + if ((ST_sclass(st) == SCLASS_FORMAL) + || (ST_sclass(st) == SCLASS_FORMAL_REF)) { + return TRUE; + } + } + } + else { + WN * base = WN_array_base(WN_kid(wn_node,1)); + if (base && WN_has_sym(base)) { + ST * st = WN_st(base); + if ((ST_sclass(st) == SCLASS_FORMAL) + || (ST_sclass(st) == SCLASS_FORMAL_REF)) { + return TRUE; + } + } + } + } + } + } + } + return FALSE; +} + static FISSION_FUSION_STATUS Fuse_Outer_Loops(WN** loop1_p, WN** loop2_p, FIZ_FUSE_INFO* ffi, WN2UINT *wn2ffi, UINT* fusion_level_io) { @@ -627,13 +663,34 @@ if (array_ref_count2 == -1) return Failed; + // This is a workaround for Fortran program error that is exposed by + // more aggressive loop fusions. + if (LNO_Fusion >= 2) { + if (Has_parm_ref(writes1)) + dli1->No_Fusion = 1; + else if (Has_parm_ref(writes2)) + dli2->No_Fusion = 1; + + if (dli1->No_Fusion || dli2->No_Fusion) { + if (LNO_Verbose) + outer_fusion_verbose_info(srcpos1,srcpos2, + "Loops with writes to reference parameter cannot be outer fused."); + if (LNO_Analysis) + outer_fusion_analysis_info(FAIL,srcpos1,srcpos2,0,0, + "Loops with writes to reference paramater cannot be outer fused."); + if (LNO_Tlog) + outer_fusion_tlog_info(FAIL,srcpos1,srcpos2,0,0, + "Loops with writes to reference parameter cannot be outer fused."); + return Failed; + } + } + BOOL prefer_fuse = FALSE; - if (Do_Aggressive_Fuse) { // If two loops have many array data dependencies, fusion can enable scalarization // to reduce memory bandwith. if ((dli1->Prefer_Fuse != 1) - && (Array_Data_Dependence_Count(writes1, reads2) >= LNO_Fusion_Ddep_Limit)) + && (Array_Data_Dependence_Count(writes1, reads2) >= LNO_Fusion_Ddep_Limit)) dli1->Prefer_Fuse = 1; prefer_fuse = (dli1->Prefer_Fuse == 1) ? TRUE : FALSE; } Modified: trunk/osprey/be/lno/sclrze.cxx =================================================================== --- trunk/osprey/be/lno/sclrze.cxx 2011-05-24 00:24:38 UTC (rev 3623) +++ trunk/osprey/be/lno/sclrze.cxx 2011-05-24 00:25:51 UTC (rev 3624) @@ -344,6 +344,18 @@ else Check_use(st, wn, dep_graph, FALSE); } + // Flag ADDR_TAKEN bit for parameters passed by reference. + WN * wn_p = LWN_Get_Parent(wn); + if (wn_p && (WN_operator(wn_p) == OPR_PARM)) { + INT flag = WN_flag(wn_p); + if (flag & WN_PARM_BY_REFERENCE) { + int val = Array_Use_Hash->Find(st); + val |= ADDR_TAKEN; + if (val) { + Array_Use_Hash->Find_And_Set(st, val); + } + } + } } break; @@ -716,6 +728,7 @@ } } } + } // Given that there is a must dependence between store and load, ------------------------------------------------------------------------------ vRanger cuts backup time in half-while increasing security. With the market-leading solution for virtual backup and recovery, you get blazing-fast, flexible, and affordable data protection. Download your free trial now. http://p.sf.net/sfu/quest-d2dcopy1 _______________________________________________ Open64-devel mailing list Open64-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/open64-devel