Author: pallavimathew
Date: 2011-07-05 18:08:23 -0400 (Tue, 05 Jul 2011)
New Revision: 3679

Modified:
   trunk/osprey/be/com/cxx_template.h
   trunk/osprey/be/com/dep_graph.cxx
   trunk/osprey/be/com/dep_graph.h
   trunk/osprey/be/lno/lnopt_main.cxx
   trunk/osprey/be/lno/lwn_util.cxx
   trunk/osprey/be/lno/lwn_util.h
Log:
Testcase:
extern double sqrt(double);

int global_arr[4];
void SetPoints()
{
  int i, r0;
  for (i=0; i<10; i++) {
    r0 = global_arr[3];
    sqrt(r0 * r0);
  }
}

Compiling with 'opencc -O3 -apo' gives:

### Assertion failure at line 710 of .../../../osprey/be/lno/access_vector.h:
### Compiler Error in file sample.c during Loop Nest Optimizer phase:
### SYMBOL::Init(WN*) called with opcode 66612
opencc INTERNAL ERROR: .../x86_64-open64-linux/4.2/be returned non-zero status 1

Problem/Fix Description:

The error is caused due to a dangling pointer leftover from an incomplete 
cleanup after array substitution removes a whirl node. The error shows up 
only for calls to builtin math function 'sqrt' (not sure if there are more 
such functions) where the original call is replaced by a builtin and a new 
call is placed depending on the accuracy of the result. The problem will not 
show with '-fno-math-errno'.
The fix adds a cleanup function to remove scalar references to WHIRL nodes 
marked for deletion.

The loop in sample.c:
  for (i=0; i<10; i++) {
    r0 = global_arr[3]; //L1
    sqrt(r0 * r0); //L2
  }

The CALL_INFO corresponding to L2 has 'r0' as a scalar_use.
Array substitution replaces 'r0' with 'global_arr[3] and deletes whirl node for 
'r0'. 
But the reference to 'r0' still exists within call_info of 'sqrt', which
results in an inconsistency (assertion failure) in array_loop_info that is 
detected 
when merging a call's scalar uses as part auto parallelization.

Note that had the call to 'sqrt' been a a VCALL it would not go through array 
substitution.
'sqrt' being a builtin, the VCALL is replaced (in the absence of 
-fno-math-errno) by
F8SQRT, result saved in temp_var and depending on whether or not the result is 
a NAN,
a call is placed to F8CALL_SQRT. (See trace file with -Wb,-tra).
-apo is needed to expose error because Annotations of Call 
(NSE_Annotate_Scalar_Call called by IPA_LNO_Map_Calls) only occurs under 
autopar.

The patch to function 'DeleteElement' in  osprey/be/com/cxx_template.h is to 
avoid 
a compile error (during compiler build) caused by absence of a suitable 
assignment 
operator for SCALAR_NODE and SCALAR_REF. This is issue was not exposed earlier 
because 
existing calls to 'DeleteTop' are only on a stack of pointers. 

C.R by Sun Chan.


Modified: trunk/osprey/be/com/cxx_template.h
===================================================================
--- trunk/osprey/be/com/cxx_template.h  2011-07-04 03:02:06 UTC (rev 3678)
+++ trunk/osprey/be/com/cxx_template.h  2011-07-05 22:08:23 UTC (rev 3679)
@@ -229,11 +229,9 @@
        for (int iter = idx; iter < _lastidx; iter++) {
           _array[idx] = _array[idx+1];
        }
-       _array[_lastidx] = NULL;
        Decidx();
     }
     else if (idx == _lastidx) {
-        _array[idx] = NULL;
         Decidx();
     }
   }

Modified: trunk/osprey/be/com/dep_graph.cxx
===================================================================
--- trunk/osprey/be/com/dep_graph.cxx   2011-07-04 03:02:06 UTC (rev 3678)
+++ trunk/osprey/be/com/dep_graph.cxx   2011-07-05 22:08:23 UTC (rev 3679)
@@ -3435,6 +3435,28 @@
   _stack->Top_nth(0)._scalar_ref_stack->Push(sref);
 }
 
+void SCALAR_STACK::Remove_Scalar(WN *wn)
+{
+  Is_True((WN_operator(wn) == OPR_LDID) ||
+          (WN_operator(wn) == OPR_STID), 
+         ("Non scalar passed to SCALAR_STACK::Remove_Scalar"));
+
+  SYMBOL symbol(wn);
+
+  for (INT i=0; i<_stack->Elements(); i++) {
+    if (symbol == _stack->Top_nth(i)._scalar) {
+      //remove all scalar_references to this symbol
+      for (INT j = 0; j < _stack->Top_nth(i)._scalar_ref_stack->Elements(); 
j++)
+       _stack->Top_nth(i)._scalar_ref_stack->DeleteTop(j);
+
+      //remove the SCALAR_NODE since its _scalar_ref_stack is now empty.
+      if (_stack->Top_nth(i)._scalar_ref_stack->Elements() == 0)
+       _stack->DeleteTop(i);
+      return;
+    }
+  }
+}
+
 void SCALAR_STACK::Print(FILE *fp)
 {
   for (INT i=0; i<_stack->Elements(); i++) {

Modified: trunk/osprey/be/com/dep_graph.h
===================================================================
--- trunk/osprey/be/com/dep_graph.h     2011-07-04 03:02:06 UTC (rev 3678)
+++ trunk/osprey/be/com/dep_graph.h     2011-07-05 22:08:23 UTC (rev 3679)
@@ -852,6 +852,7 @@
   }
   void Add_Scalar(WN *wn, UINT snumber);
   void Add_Scalar(WN *wn_call, SYMBOL* symbol, UINT snumber);
+  void Remove_Scalar(WN *wn);
   void Print(FILE *fp);
   void Clear() { _stack->Clear(); };
   INT Elements() const { return _stack->Elements(); };

Modified: trunk/osprey/be/lno/lnopt_main.cxx
===================================================================
--- trunk/osprey/be/lno/lnopt_main.cxx  2011-07-04 03:02:06 UTC (rev 3678)
+++ trunk/osprey/be/lno/lnopt_main.cxx  2011-07-05 22:08:23 UTC (rev 3679)
@@ -1192,6 +1192,8 @@
   ROUNDOFF Roundoff_Level_Save = Roundoff_Level;
 
   Du_Mgr = du_mgr;
+  if(Run_autopar)
+    WN_Register_Delete_Cleanup_Function(LWN_Delete_SR);
   WN_Register_Delete_Cleanup_Function(LWN_Delete_DU);
   VINDEX16 save_graph_capacity = GRAPH16_CAPACITY; 
   GRAPH16_CAPACITY = LNO_Graph_Capacity;
@@ -1759,6 +1761,8 @@
   MEM_POOL_Pop(&SNL_local_pool);
   MEM_POOL_Pop_Unfreeze(&LNO_default_pool);
 
+  if(Run_autopar)
+    WN_Remove_Delete_Cleanup_Function(LWN_Delete_SR);
   WN_Remove_Delete_Cleanup_Function(LWN_Delete_DU);
   GRAPH16_CAPACITY = save_graph_capacity; 
 

Modified: trunk/osprey/be/lno/lwn_util.cxx
===================================================================
--- trunk/osprey/be/lno/lwn_util.cxx    2011-07-04 03:02:06 UTC (rev 3678)
+++ trunk/osprey/be/lno/lwn_util.cxx    2011-07-05 22:08:23 UTC (rev 3679)
@@ -79,6 +79,7 @@
 #include "region_util.h"
 #include "lego_opts.h"
 #include "prompf.h"
+#include "call_info.h"
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -1062,6 +1063,45 @@
 
 #ifdef LNO
 
+// Look recursively inside wn_tree for OPR_CALL nodes and
+// remove any references therein to scalar_node
+void Remove_scalar_ref(WN* wn_tree, WN* scalar_node) {
+  if (WN_operator(wn_tree) == OPERATOR_UNKNOWN) 
+    // wn_tree has already been deleted.
+    return;
+
+  if (WN_operator(wn_tree) == OPR_CALL && Has_Call_Info(wn_tree)) {
+    ARA_LOOP_INFO* ali = Get_Call_Info(wn_tree)->Call_Ara_Info();
+    SCALAR_STACK scalar_uses = ali->SCALAR_USE();
+    scalar_uses.Remove_Scalar(scalar_node);
+  }
+
+  if (WN_operator(wn_tree) == OPR_BLOCK) { 
+    for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
+      Remove_scalar_ref(wn, scalar_node);
+  } else { 
+    for (INT i = 0; i < WN_kid_count(wn_tree); i++)
+      Remove_scalar_ref((WN_kid(wn_tree, i)), scalar_node);
+  } 
+  return;
+}
+
+//Eliminate scalar references to a node
+void LWN_Delete_SR(WN *scalar_node) {
+  if (!scalar_node)
+    return;
+
+  if(!((WN_operator(scalar_node) == OPR_LDID) ||
+       (WN_operator(scalar_node) == OPR_STID)))
+    // Not a scalar.
+    return;
+
+  // Inspect the eclosing function for calls that
+  // reference the scalar_node.
+  Remove_scalar_ref(Current_Func_Node, scalar_node);
+  return;
+}
+
 // Eliminate the du chains connected to a node
 void LWN_Delete_DU(WN *wn)
 {

Modified: trunk/osprey/be/lno/lwn_util.h
===================================================================
--- trunk/osprey/be/lno/lwn_util.h      2011-07-04 03:02:06 UTC (rev 3678)
+++ trunk/osprey/be/lno/lwn_util.h      2011-07-05 22:08:23 UTC (rev 3679)
@@ -217,6 +217,9 @@
  * extern void LWN_Delete_Tree(WN *wn);
  *   Delete the node and all its descendants.
  *
+ * extern void LWN_Delete_SR(WN *wn);
+ *  Delete CALL_INFO nodes' scalar references associated with wn
+ *
  * extern void LWN_Delete_DU(WN *wn)
  *  Delete the DU chain associated with wn
  *
@@ -455,6 +458,7 @@
 extern void LWN_Copy_Def_Use_Node(WN*, WN*, DU_MANAGER*);
 extern void LWN_Copy_Def_Use(WN*, WN*, DU_MANAGER*);
 extern void LWN_Delete_DU(WN *wn);
+extern void LWN_Delete_SR(WN *wn);
 extern void LWN_Delete_LNO_dep_graph(WN *wn);
 extern void LWN_Delete_CG_dep_graph(WN *wn);
 extern void LWN_Delete_Name_Manager(WN *wn);


------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to