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

Reply via email to