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