This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Problems with a patch to improve dependence analysis


 
I am working on a patch to make the dependence analysis slightly more
powerful to enable the vectorizer. I would be happy to get some input on
what could be wrong. The case I'm trying to get to work is the
following:

int foo (int A[N][N])
{
  int i,j;
  /* vectorizable */
  for (i = 1; i < N; i++)
    for (j = 0; j < N; j++)
      A[i][j] = A[i-1][j] + A[i][j];

  return 0;
}

Currently this does not get vectorized because internally A[i-1][j] is
represented as (A+k)[i][j]. The dependence analysis determines that A
and (A+k) are not the same base object and gives up. The function
split_constant_offset is doing some work to eliminate this problem but
it does not follow ssa edges, the constant in this case is in a
different statemt. Below is a fix for this:

Index: trunk/gcc/tree-data-ref.c
===================================================================
--- trunk/gcc/tree-data-ref.c	(revision 126419)
+++ trunk/gcc/tree-data-ref.c	(working copy)
@@ -566,6 +566,25 @@ split_constant_offset (tree exp, tree *v
 	return;
       }
 
+    case SSA_NAME:
+      {
+         tree def_stmt = SSA_NAME_DEF_STMT (exp);
+	    if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT)
+           {
+             tree def_stmt_rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
+             if (!TREE_SIDE_EFFECTS (def_stmt_rhs) 
+                 && EXPR_P (def_stmt_rhs))
+               {
+                 split_constant_offset (def_stmt_rhs, &var0, &off0);
+                 var0 = fold_convert (type, var0);
+                 *var = var0;
+                 *off = off0;
+                 return;
+               }
+           }
+        break;
+      }
+
     default:
       break;
     }

This worked for the most part (non-bootstrap, make check), but there are
errors during bootstrap:

-----------------------------------------------------------------------
 _r4.c: In function 'matmul_r4':
 /home/jsjodin/Work/Project/GCC/Latest/trunk/libgfortran/generated/matm
 ul
 _r4.c:87: error: expected an SSA_NAME object
/home/jsjodin/Work/Project/GCC/Latest/trunk/libgfortran/generated/matm
 ul
 _r4.c:87: error: in statement
 # VUSE <SMT.37> { SMT.37 }
 D.5431_402 = retarray_45(D)->data;
----------------------------------------------------------------------

Since split_constant_offset now can create large expressions any direct
uses of the result to generate code will not be valid (GIMPLE). The
result of split_constant_offset is used for computing three properties
in data_ref:

DR_BASE_OBJECT  -- only used internally by the dependence analysis 

DR_BASE_ADDRESS -- used in tree-vect-transform.c to generate code
(triggers the error)

DR_OFFSET       -- used in tree-vect-transform.c to generate code

There are no other uses to my knowledge.

The idea to fix this was to use force_gimple_operand, but doing that
does not change anything the same error still occurs. We have verified
that DR_BASE_ADDRESS is the problem (added a flag to enable/disable the
SSA_NAME case in split_constant_offset). Unless the fix below is buggy
(the temporaries "batmp" get generated and used in other examples) I
don't know what could be the cause of the errors. Does anyone have an
idea why? 


Below is the code change for tree-vect-transform.c
Index: trunk/gcc/tree-vect-transform.c
===================================================================
--- trunk/gcc/tree-vect-transform.c	(revision 126419)
+++ trunk/gcc/tree-vect-transform.c	(working copy)
@@ -651,21 +651,32 @@ vect_create_addr_base_for_vector_ref (tr  {
   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
-  tree data_ref_base = unshare_expr (DR_BASE_ADDRESS (dr));
-  tree base_name = build_fold_indirect_ref (data_ref_base);
+  tree data_ref_base_expr = unshare_expr (DR_BASE_ADDRESS (dr));  tree 
+ base_name = build_fold_indirect_ref (data_ref_base_expr);  tree 
+ data_ref_base_var;  tree data_ref_base;  tree new_base_stmt;
   tree vec_stmt;
   tree addr_base, addr_expr;
   tree dest, new_stmt;
   tree base_offset = unshare_expr (DR_OFFSET (dr));
   tree init = unshare_expr (DR_INIT (dr));
   tree vect_ptr_type, addr_expr2;
+  
+  
+  /* Create data_ref_base */
+  data_ref_base_var = create_tmp_var (TREE_TYPE (data_ref_base_expr), 
+                                      "batmp");
+  add_referenced_var (data_ref_base_var);
+  data_ref_base = force_gimple_operand (data_ref_base_expr,
&new_base_stmt,
+					true, data_ref_base_var);
+  append_to_statement_list_force(new_base_stmt, new_stmt_list);
 
   /* Create base_offset */
   base_offset = size_binop (PLUS_EXPR, base_offset, init);
   base_offset = fold_convert (sizetype, base_offset);
   dest = create_tmp_var (TREE_TYPE (base_offset), "base_off");
   add_referenced_var (dest);
-  base_offset = force_gimple_operand (base_offset, &new_stmt, false,
dest);  
+  base_offset = force_gimple_operand (base_offset, &new_stmt, true, 
+ dest);
   append_to_statement_list_force (new_stmt, new_stmt_list);
 
   if (offset)



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]