OSDN Git Service

enable SH libgloss build
[pf3gnuchains/gcc-fork.git] / gcc / matrix-reorg.c
index 8a2734d..d2687b8 100644 (file)
@@ -1,5 +1,5 @@
 /* Matrix layout transformations.
-   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
    Contributed by Razya Ladelsky <razya@il.ibm.com>
    Originally written by Revital Eres and Mustafa Hagog.
    
@@ -107,9 +107,7 @@ along with GCC; see the file COPYING3.  If not see
 
   Both optimizations are described in the paper "Matrix flattening and 
   transposing in GCC" which was presented in GCC summit 2006. 
-  http://www.gccsummit.org/2006/2006-GCC-Summit-Proceedings.pdf
-
- */
+  http://www.gccsummit.org/2006/2006-GCC-Summit-Proceedings.pdf.  */
 
 #include "config.h"
 #include "system.h"
@@ -117,7 +115,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "rtl.h"
-#include "c-tree.h"
 #include "tree-inline.h"
 #include "tree-flow.h"
 #include "tree-flow-inline.h"
@@ -133,7 +130,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "timevar.h"
 #include "params.h"
 #include "fibheap.h"
-#include "c-common.h"
 #include "intl.h"
 #include "function.h"
 #include "basic-block.h"
@@ -144,9 +140,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-data-ref.h"
 #include "tree-chrec.h"
 #include "tree-scalar-evolution.h"
+#include "tree-ssa-sccvn.h"
 
-/*
-   We need to collect a lot of data from the original malloc,
+/* We need to collect a lot of data from the original malloc,
    particularly as the gimplifier has converted:
 
    orig_var = (struct_type *) malloc (x * sizeof (struct_type *));
@@ -164,11 +160,14 @@ along with GCC; see the file COPYING3.  If not see
 
 struct malloc_call_data
 {
-  tree call_stmt;              /* Tree for "T4 = malloc (T3);"                     */
+  gimple call_stmt;            /* Tree for "T4 = malloc (T3);"                     */
   tree size_var;               /* Var decl for T3.                                 */
   tree malloc_size;            /* Tree for "<constant>", the rhs assigned to T3.   */
 };
 
+static tree can_calculate_expr_before_stmt (tree, sbitmap);
+static tree can_calculate_stmt_before_stmt (gimple, sbitmap);
+
 /* The front end of the compiler, when parsing statements of the form:
 
    var = (type_cast) malloc (sizeof (type));
@@ -188,24 +187,20 @@ struct malloc_call_data
    need to find the rest of the variables/statements on our own.  That
    is what the following function does.  */
 static void
-collect_data_for_malloc_call (tree stmt, struct malloc_call_data *m_data)
+collect_data_for_malloc_call (gimple stmt, struct malloc_call_data *m_data)
 {
   tree size_var = NULL;
   tree malloc_fn_decl;
-  tree tmp;
   tree arg1;
 
-  gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
+  gcc_assert (is_gimple_call (stmt));
 
-  tmp = get_call_expr_in (stmt);
-  malloc_fn_decl = CALL_EXPR_FN (tmp);
-  if (TREE_CODE (malloc_fn_decl) != ADDR_EXPR
-      || TREE_CODE (TREE_OPERAND (malloc_fn_decl, 0)) != FUNCTION_DECL
-      || DECL_FUNCTION_CODE (TREE_OPERAND (malloc_fn_decl, 0)) !=
-      BUILT_IN_MALLOC)
+  malloc_fn_decl = gimple_call_fndecl (stmt);
+  if (malloc_fn_decl == NULL
+      || DECL_FUNCTION_CODE (malloc_fn_decl) != BUILT_IN_MALLOC)
     return;
 
-  arg1 = CALL_EXPR_ARG (tmp, 0);
+  arg1 = gimple_call_arg (stmt, 0);
   size_var = arg1;
 
   m_data->call_stmt = stmt;
@@ -224,7 +219,7 @@ collect_data_for_malloc_call (tree stmt, struct malloc_call_data *m_data)
 struct access_site_info
 {
   /* The statement (INDIRECT_REF or POINTER_PLUS_EXPR).  */
-  tree stmt;
+  gimple stmt;
 
   /* In case of POINTER_PLUS_EXPR, what is the offset.  */
   tree offset;
@@ -249,6 +244,14 @@ typedef struct access_site_info *access_site_info_p;
 DEF_VEC_P (access_site_info_p);
 DEF_VEC_ALLOC_P (access_site_info_p, heap);
 
+/* Calls to free when flattening a matrix.  */
+
+struct free_info
+{
+  gimple stmt;
+  tree func;
+};
+
 /* Information about matrix to flatten.  */
 struct matrix_info
 {
@@ -263,29 +266,25 @@ struct matrix_info
      0 to ACTUAL_DIM - k escapes.  */
   int min_indirect_level_escape;
 
-  tree min_indirect_level_escape_stmt;
-
-  /* Is the matrix transposed.  */
-  bool is_transposed_p;
+  gimple min_indirect_level_escape_stmt;
 
   /* Hold the allocation site for each level (dimension).
      We can use NUM_DIMS as the upper bound and allocate the array
      once with this number of elements and no need to use realloc and
      MAX_MALLOCED_LEVEL.  */
-  tree *malloc_for_level;
+  gimple *malloc_for_level;
 
   int max_malloced_level;
 
+  /* Is the matrix transposed.  */
+  bool is_transposed_p;
+
   /* The location of the allocation sites (they must be in one
      function).  */
   tree allocation_function_decl;
 
   /* The calls to free for each level of indirection.  */
-  struct free_info
-  {
-    tree stmt;
-    tree func;
-  } *free_stmts;
+  struct free_info *free_stmts;
 
   /* An array which holds for each dimension its size. where
      dimension 0 is the outer most (one that contains all the others).
@@ -307,7 +306,7 @@ struct matrix_info
 
   /* An array of the accesses to be flattened.
      elements are of type "struct access_site_info *".  */
-    VEC (access_site_info_p, heap) * access_l;
+  VEC (access_site_info_p, heap) * access_l;
 
   /* A map of how the dimensions will be organized at the end of 
      the analyses.  */
@@ -323,7 +322,7 @@ struct matrix_info
 
 struct matrix_access_phi_node
 {
-  tree phi;
+  gimple phi;
   int indirection_level;
 };
 
@@ -358,7 +357,8 @@ static bool check_transpose_p;
 static hashval_t
 mat_acc_phi_hash (const void *p)
 {
-  const struct matrix_access_phi_node *ma_phi = p;
+  const struct matrix_access_phi_node *const ma_phi =
+    (const struct matrix_access_phi_node *) p;
 
   return htab_hash_pointer (ma_phi->phi);
 }
@@ -368,8 +368,10 @@ mat_acc_phi_hash (const void *p)
 static int
 mat_acc_phi_eq (const void *p1, const void *p2)
 {
-  const struct matrix_access_phi_node *phi1 = p1;
-  const struct matrix_access_phi_node *phi2 = p2;
+  const struct matrix_access_phi_node *const phi1 =
+    (const struct matrix_access_phi_node *) p1;
+  const struct matrix_access_phi_node *const phi2 =
+    (const struct matrix_access_phi_node *) p2;
 
   if (phi1->phi == phi2->phi)
     return 1;
@@ -397,8 +399,8 @@ mtt_info_hash (const void *mtt)
 static int
 mtt_info_eq (const void *mtt1, const void *mtt2)
 {
-  const struct matrix_info *i1 = mtt1;
-  const struct matrix_info *i2 = mtt2;
+  const struct matrix_info *const i1 = (const struct matrix_info *) mtt1;
+  const struct matrix_info *const i2 = (const struct matrix_info *) mtt2;
 
   if (i1->decl == i2->decl)
     return true;
@@ -406,29 +408,21 @@ mtt_info_eq (const void *mtt1, const void *mtt2)
   return false;
 }
 
-/* Return the inner most tree that is not a cast.  */
-static tree
-get_inner_of_cast_expr (tree t)
-{
-  while (TREE_CODE (t) == CONVERT_EXPR || TREE_CODE (t) == NOP_EXPR
-        || TREE_CODE (t) == VIEW_CONVERT_EXPR)
-    t = TREE_OPERAND (t, 0);
-
-  return t;
-}
-
 /* Return false if STMT may contain a vector expression.  
    In this situation, all matrices should not be flattened.  */
 static bool
-may_flatten_matrices_1 (tree stmt)
+may_flatten_matrices_1 (gimple stmt)
 {
   tree t;
 
-  switch (TREE_CODE (stmt))
+  switch (gimple_code (stmt))
     {
-    case GIMPLE_MODIFY_STMT:
-      t = GIMPLE_STMT_OPERAND (stmt, 1);
-      while (TREE_CODE (t) == CONVERT_EXPR || TREE_CODE (t) == NOP_EXPR)
+    case GIMPLE_ASSIGN:
+      if (!gimple_assign_cast_p (stmt))
+       return true;
+
+      t = gimple_assign_rhs1 (stmt);
+      while (CONVERT_EXPR_P (t))
        {
          if (TREE_TYPE (t) && POINTER_TYPE_P (TREE_TYPE (t)))
            {
@@ -448,7 +442,7 @@ may_flatten_matrices_1 (tree stmt)
          t = TREE_OPERAND (t, 0);
        }
       break;
-    case ASM_EXPR:
+    case GIMPLE_ASM:
       /* Asm code could contain vector operations.  */
       return false;
       break;
@@ -466,15 +460,15 @@ may_flatten_matrices (struct cgraph_node *node)
   tree decl;
   struct function *func;
   basic_block bb;
-  block_stmt_iterator bsi;
+  gimple_stmt_iterator gsi;
 
   decl = node->decl;
   if (node->analyzed)
     {
       func = DECL_STRUCT_FUNCTION (decl);
       FOR_EACH_BB_FN (bb, func)
-       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
-       if (!may_flatten_matrices_1 (bsi_stmt (bsi)))
+       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+       if (!may_flatten_matrices_1 (gsi_stmt (gsi)))
          return false;
     }
   return true;
@@ -521,7 +515,7 @@ analyze_matrix_decl (tree var_decl)
 
   /* Check to see if this pointer is already in there.  */
   tmpmi.decl = var_decl;
-  mi = htab_find (matrices_to_reorg, &tmpmi);
+  mi = (struct matrix_info *) htab_find (matrices_to_reorg, &tmpmi);
 
   if (mi)
     return NULL;
@@ -595,7 +589,7 @@ find_matrices_decl (void)
 
 /* Mark that the matrix MI escapes at level L.  */
 static void
-mark_min_matrix_escape_level (struct matrix_info *mi, int l, tree s)
+mark_min_matrix_escape_level (struct matrix_info *mi, int l, gimple s)
 {
   if (mi->min_indirect_level_escape == -1
       || (mi->min_indirect_level_escape > l))
@@ -608,19 +602,13 @@ mark_min_matrix_escape_level (struct matrix_info *mi, int l, tree s)
 /* Find if the SSA variable is accessed inside the
    tree and record the tree containing it.
    The only relevant uses are the case of SSA_NAME, or SSA inside
-   INDIRECT_REF, CALL_EXPR, PLUS_EXPR, POINTER_PLUS_EXPR, MULT_EXPR.  */
+   INDIRECT_REF, PLUS_EXPR, POINTER_PLUS_EXPR, MULT_EXPR.  */
 static void
 ssa_accessed_in_tree (tree t, struct ssa_acc_in_tree *a)
 {
-  tree call, decl;
-  tree arg;
-  call_expr_arg_iterator iter;
-
   a->t_code = TREE_CODE (t);
   switch (a->t_code)
     {
-      tree op1, op2;
-
     case SSA_NAME:
       if (t == a->ssa_var)
        a->var_found = true;
@@ -630,24 +618,58 @@ ssa_accessed_in_tree (tree t, struct ssa_acc_in_tree *a)
          && TREE_OPERAND (t, 0) == a->ssa_var)
        a->var_found = true;
       break;
-    case CALL_EXPR:
-      FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
-      {
-       if (arg == a->ssa_var)
-         {
-           a->var_found = true;
-           call = get_call_expr_in (t);
-           if (call && (decl = get_callee_fndecl (call)))
-             a->t_tree = decl;
-           break;
-         }
-      }
+    default:
+      break;
+    }
+}
+
+/* Find if the SSA variable is accessed on the right hand side of
+   gimple call STMT. */
+
+static void
+ssa_accessed_in_call_rhs (gimple stmt, struct ssa_acc_in_tree *a)
+{
+  tree decl;
+  tree arg;
+  size_t i;
+
+  a->t_code = CALL_EXPR;
+  for (i = 0; i < gimple_call_num_args (stmt); i++)
+    {
+      arg = gimple_call_arg (stmt, i);
+      if (arg == a->ssa_var)
+       {
+         a->var_found = true;
+         decl = gimple_call_fndecl (stmt);
+         a->t_tree = decl;
+         break;
+       }
+    }
+}
+
+/* Find if the SSA variable is accessed on the right hand side of
+   gimple assign STMT. */
+
+static void
+ssa_accessed_in_assign_rhs (gimple stmt, struct ssa_acc_in_tree *a)
+{
+
+  a->t_code = gimple_assign_rhs_code (stmt);
+  switch (a->t_code)
+    {
+      tree op1, op2;
+
+    case SSA_NAME:
+    case INDIRECT_REF:
+    CASE_CONVERT:
+    case VIEW_CONVERT_EXPR:
+      ssa_accessed_in_tree (gimple_assign_rhs1 (stmt), a);
       break;
     case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MULT_EXPR:
-      op1 = TREE_OPERAND (t, 0);
-      op2 = TREE_OPERAND (t, 1);
+      op1 = gimple_assign_rhs1 (stmt);
+      op2 = gimple_assign_rhs2 (stmt);
 
       if (op1 == a->ssa_var)
        {
@@ -668,7 +690,7 @@ ssa_accessed_in_tree (tree t, struct ssa_acc_in_tree *a)
 /* Record the access/allocation site information for matrix MI so we can 
    handle it later in transformation.  */
 static void
-record_access_alloc_site_info (struct matrix_info *mi, tree stmt, tree offset,
+record_access_alloc_site_info (struct matrix_info *mi, gimple stmt, tree offset,
                               tree index, int level, bool is_alloc)
 {
   struct access_site_info *acc_info;
@@ -695,7 +717,7 @@ record_access_alloc_site_info (struct matrix_info *mi, tree stmt, tree offset,
    all the allocation sites could be pre-calculated before the call to
    the malloc of level 0 (the main malloc call).  */
 static void
-add_allocation_site (struct matrix_info *mi, tree stmt, int level)
+add_allocation_site (struct matrix_info *mi, gimple stmt, int level)
 {
   struct malloc_call_data mcd;
 
@@ -738,13 +760,13 @@ add_allocation_site (struct matrix_info *mi, tree stmt, int level)
      calls like calloc and realloc.  */
   if (!mi->malloc_for_level)
     {
-      mi->malloc_for_level = xcalloc (level + 1, sizeof (tree));
+      mi->malloc_for_level = XCNEWVEC (gimple, level + 1);
       mi->max_malloced_level = level + 1;
     }
   else if (mi->max_malloced_level <= level)
     {
       mi->malloc_for_level
-       = xrealloc (mi->malloc_for_level, (level + 1) * sizeof (tree));
+       = XRESIZEVEC (gimple, mi->malloc_for_level, level + 1);
 
       /* Zero the newly allocated items.  */
       memset (&(mi->malloc_for_level[mi->max_malloced_level + 1]),
@@ -767,79 +789,74 @@ add_allocation_site (struct matrix_info *mi, tree stmt, int level)
    Return if STMT is related to an allocation site.  */
 
 static void
-analyze_matrix_allocation_site (struct matrix_info *mi, tree stmt,
+analyze_matrix_allocation_site (struct matrix_info *mi, gimple stmt,
                                int level, sbitmap visited)
 {
-  if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+  if (gimple_assign_copy_p (stmt) || gimple_assign_cast_p (stmt))
     {
-      tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+      tree rhs = gimple_assign_rhs1 (stmt);
 
-      rhs = get_inner_of_cast_expr (rhs);
       if (TREE_CODE (rhs) == SSA_NAME)
        {
-         tree def = SSA_NAME_DEF_STMT (rhs);
+         gimple def = SSA_NAME_DEF_STMT (rhs);
 
          analyze_matrix_allocation_site (mi, def, level, visited);
          return;
        }
+      /* If we are back to the original matrix variable then we
+         are sure that this is analyzed as an access site.  */
+      else if (rhs == mi->decl)
+       return;
+    }
+  /* A result of call to malloc.  */
+  else if (is_gimple_call (stmt))
+    {
+      int call_flags = gimple_call_flags (stmt);
 
-      /* A result of call to malloc.  */
-      else if (TREE_CODE (rhs) == CALL_EXPR)
+      if (!(call_flags & ECF_MALLOC))
+       {
+         mark_min_matrix_escape_level (mi, level, stmt);
+         return;
+       }
+      else
        {
-         int call_flags = call_expr_flags (rhs);
+         tree malloc_fn_decl;
+         const char *malloc_fname;
 
-         if (!(call_flags & ECF_MALLOC))
+         malloc_fn_decl = gimple_call_fndecl (stmt);
+         if (malloc_fn_decl == NULL_TREE)
            {
              mark_min_matrix_escape_level (mi, level, stmt);
              return;
            }
-         else
-           {
-             tree malloc_fn_decl;
-             const char *malloc_fname;
-
-             malloc_fn_decl = CALL_EXPR_FN (rhs);
-             if (TREE_CODE (malloc_fn_decl) != ADDR_EXPR
-                 || TREE_CODE (TREE_OPERAND (malloc_fn_decl, 0)) !=
-                 FUNCTION_DECL)
-               {
-                 mark_min_matrix_escape_level (mi, level, stmt);
-                 return;
-               }
-             malloc_fn_decl = TREE_OPERAND (malloc_fn_decl, 0);
-             malloc_fname = IDENTIFIER_POINTER (DECL_NAME (malloc_fn_decl));
-             if (DECL_FUNCTION_CODE (malloc_fn_decl) != BUILT_IN_MALLOC)
-               {
-                 if (dump_file)
-                   fprintf (dump_file,
-                            "Matrix %s is an argument to function %s\n",
-                            get_name (mi->decl), get_name (malloc_fn_decl));
-                 mark_min_matrix_escape_level (mi, level, stmt);
-                 return;
-               }
-           }
-         /* This is a call to malloc of level 'level'.  
-            mi->max_malloced_level-1 == level  means that we've 
-            seen a malloc statement of level 'level' before.  
-            If the statement is not the same one that we've 
-            seen before, then there's another malloc statement 
-            for the same level, which means that we need to mark 
-            it escaping.  */
-         if (mi->malloc_for_level
-             && mi->max_malloced_level-1 == level
-             && mi->malloc_for_level[level] != stmt)
+         malloc_fname = IDENTIFIER_POINTER (DECL_NAME (malloc_fn_decl));
+         if (DECL_FUNCTION_CODE (malloc_fn_decl) != BUILT_IN_MALLOC)
            {
+             if (dump_file)
+               fprintf (dump_file,
+                        "Matrix %s is an argument to function %s\n",
+                        get_name (mi->decl), get_name (malloc_fn_decl));
              mark_min_matrix_escape_level (mi, level, stmt);
              return;
            }
-         else
-           add_allocation_site (mi, stmt, level);
+       }
+      /* This is a call to malloc of level 'level'.  
+        mi->max_malloced_level-1 == level  means that we've 
+        seen a malloc statement of level 'level' before.  
+        If the statement is not the same one that we've 
+        seen before, then there's another malloc statement 
+        for the same level, which means that we need to mark 
+        it escaping.  */
+      if (mi->malloc_for_level
+         && mi->max_malloced_level-1 == level
+         && mi->malloc_for_level[level] != stmt)
+       {
+         mark_min_matrix_escape_level (mi, level, stmt);
          return;
        }
-      /* If we are back to the original matrix variable then we
-         are sure that this is analyzed as an access site.  */
-      else if (rhs == mi->decl)
-       return;
+      else
+       add_allocation_site (mi, stmt, level);
+      return;
     }
   /* Looks like we don't know what is happening in this
      statement so be in the safe side and mark it as escaping.  */
@@ -879,7 +896,7 @@ analyze_matrix_allocation_site (struct matrix_info *mi, tree stmt,
 static int
 analyze_transpose (void **slot, void *data ATTRIBUTE_UNUSED)
 {
-  struct matrix_info *mi = *slot;
+  struct matrix_info *mi = (struct matrix_info *) *slot;
   int min_escape_l = mi->min_indirect_level_escape;
   struct loop *loop;
   affine_iv iv;
@@ -907,7 +924,7 @@ analyze_transpose (void **slot, void *data ATTRIBUTE_UNUSED)
   for (i = 0; VEC_iterate (access_site_info_p, mi->access_l, i, acc_info);
        i++)
     {
-      if (TREE_CODE (GIMPLE_STMT_OPERAND (acc_info->stmt, 1)) == POINTER_PLUS_EXPR
+      if (gimple_assign_rhs_code (acc_info->stmt) == POINTER_PLUS_EXPR
          && acc_info->level < min_escape_l)
        {
          loop = loop_containing_stmt (acc_info->stmt);
@@ -916,7 +933,7 @@ analyze_transpose (void **slot, void *data ATTRIBUTE_UNUSED)
              free (acc_info);
              continue;
            }
-         if (simple_iv (loop, acc_info->stmt, acc_info->offset, &iv, true))
+         if (simple_iv (loop, loop, acc_info->offset, &iv, true))
            {
              if (iv.step != NULL)
                {
@@ -927,7 +944,7 @@ analyze_transpose (void **slot, void *data ATTRIBUTE_UNUSED)
                    {
                      acc_info->iterated_by_inner_most_loop_p = 1;
                      mi->dim_hot_level[acc_info->level] +=
-                       bb_for_stmt (acc_info->stmt)->count;
+                       gimple_bb (acc_info->stmt)->count;
                    }
 
                }
@@ -943,19 +960,21 @@ analyze_transpose (void **slot, void *data ATTRIBUTE_UNUSED)
 /* Find the index which defines the OFFSET from base.  
    We walk from use to def until we find how the offset was defined.  */
 static tree
-get_index_from_offset (tree offset, tree def_stmt)
+get_index_from_offset (tree offset, gimple def_stmt)
 {
-  tree op1, op2, expr, index;
+  tree op1, op2, index;
 
-  if (TREE_CODE (def_stmt) == PHI_NODE)
+  if (gimple_code (def_stmt) == GIMPLE_PHI)
     return NULL;
-  expr = get_inner_of_cast_expr (GIMPLE_STMT_OPERAND (def_stmt, 1));
-  if (TREE_CODE (expr) == SSA_NAME)
-    return get_index_from_offset (offset, SSA_NAME_DEF_STMT (expr));
-  else if (TREE_CODE (expr) == MULT_EXPR)
+  if ((gimple_assign_copy_p (def_stmt) || gimple_assign_cast_p (def_stmt))
+      && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
+    return get_index_from_offset (offset,
+                                 SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt)));
+  else if (is_gimple_assign (def_stmt)
+          && gimple_assign_rhs_code (def_stmt) == MULT_EXPR)
     {
-      op1 = TREE_OPERAND (expr, 0);
-      op2 = TREE_OPERAND (expr, 1);
+      op1 = gimple_assign_rhs1 (def_stmt);
+      op2 = gimple_assign_rhs2 (def_stmt);
       if (TREE_CODE (op1) != INTEGER_CST && TREE_CODE (op2) != INTEGER_CST)
        return NULL;
       index = (TREE_CODE (op1) == INTEGER_CST) ? op2 : op1;
@@ -969,17 +988,17 @@ get_index_from_offset (tree offset, tree def_stmt)
    of the type related to the SSA_VAR, or the type related to the
    lhs of STMT, in the case that it is an INDIRECT_REF.  */
 static void
-update_type_size (struct matrix_info *mi, tree stmt, tree ssa_var,
+update_type_size (struct matrix_info *mi, gimple stmt, tree ssa_var,
                  int current_indirect_level)
 {
   tree lhs;
   HOST_WIDE_INT type_size;
 
   /* Update type according to the type of the INDIRECT_REF expr.   */
-  if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
-      && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == INDIRECT_REF)
+  if (is_gimple_assign (stmt)
+      && TREE_CODE (gimple_assign_lhs (stmt)) == INDIRECT_REF)
     {
-      lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+      lhs = gimple_assign_lhs (stmt);
       gcc_assert (POINTER_TYPE_P
                  (TREE_TYPE (SSA_NAME_VAR (TREE_OPERAND (lhs, 0)))));
       type_size =
@@ -1024,24 +1043,66 @@ update_type_size (struct matrix_info *mi, tree stmt, tree ssa_var,
     }
 }
 
-/* USE_STMT represents a call_expr ,where one of the arguments is the 
+/* USE_STMT represents a GIMPLE_CALL, where one of the arguments is the 
    ssa var that we want to check because it came from some use of matrix 
    MI.  CURRENT_INDIRECT_LEVEL is the indirection level we reached so 
    far.  */
 
-static void
-analyze_accesses_for_call_expr (struct matrix_info *mi, tree use_stmt,
-                               int current_indirect_level)
+static int
+analyze_accesses_for_call_stmt (struct matrix_info *mi, tree ssa_var,
+                               gimple use_stmt, int current_indirect_level)
 {
-  tree call = get_call_expr_in (use_stmt);
-  if (call && get_callee_fndecl (call))
+  tree fndecl = gimple_call_fndecl (use_stmt);
+
+  if (gimple_call_lhs (use_stmt))
     {
-      if (DECL_FUNCTION_CODE (get_callee_fndecl (call)) != BUILT_IN_FREE)
+      tree lhs = gimple_call_lhs (use_stmt);
+      struct ssa_acc_in_tree lhs_acc, rhs_acc;
+
+      memset (&lhs_acc, 0, sizeof (lhs_acc));
+      memset (&rhs_acc, 0, sizeof (rhs_acc));
+
+      lhs_acc.ssa_var = ssa_var;
+      lhs_acc.t_code = ERROR_MARK;
+      ssa_accessed_in_tree (lhs, &lhs_acc);
+      rhs_acc.ssa_var = ssa_var;
+      rhs_acc.t_code = ERROR_MARK;
+      ssa_accessed_in_call_rhs (use_stmt, &rhs_acc);
+
+      /* The SSA must be either in the left side or in the right side,
+        to understand what is happening.
+        In case the SSA_NAME is found in both sides we should be escaping
+        at this level because in this case we cannot calculate the
+        address correctly.  */
+      if ((lhs_acc.var_found && rhs_acc.var_found
+          && lhs_acc.t_code == INDIRECT_REF)
+         || (!rhs_acc.var_found && !lhs_acc.var_found))
+       {
+         mark_min_matrix_escape_level (mi, current_indirect_level, use_stmt);
+         return current_indirect_level;
+       }
+      gcc_assert (!rhs_acc.var_found || !lhs_acc.var_found);
+
+      /* If we are storing to the matrix at some level, then mark it as
+        escaping at that level.  */
+      if (lhs_acc.var_found)
+       {
+         int l = current_indirect_level + 1;
+
+         gcc_assert (lhs_acc.t_code == INDIRECT_REF);
+         mark_min_matrix_escape_level (mi, l, use_stmt);
+         return current_indirect_level;
+       }
+    }
+
+  if (fndecl)
+    {
+      if (DECL_FUNCTION_CODE (fndecl) != BUILT_IN_FREE)
        {
          if (dump_file)
            fprintf (dump_file,
                     "Matrix %s: Function call %s, level %d escapes.\n",
-                    get_name (mi->decl), get_name (get_callee_fndecl (call)),
+                    get_name (mi->decl), get_name (fndecl),
                     current_indirect_level);
          mark_min_matrix_escape_level (mi, current_indirect_level, use_stmt);
        }
@@ -1058,6 +1119,7 @@ analyze_accesses_for_call_expr (struct matrix_info *mi, tree use_stmt,
          mi->free_stmts[l].func = current_function_decl;
        }
     }
+  return current_indirect_level;
 }
 
 /* USE_STMT represents a phi node of the ssa var that we want to 
@@ -1071,7 +1133,7 @@ analyze_accesses_for_call_expr (struct matrix_info *mi, tree use_stmt,
    CURRENT_INDIRECT_LEVEL is the indirection level we reached so far.  */
 
 static void
-analyze_accesses_for_phi_node (struct matrix_info *mi, tree use_stmt,
+analyze_accesses_for_phi_node (struct matrix_info *mi, gimple use_stmt,
                               int current_indirect_level, sbitmap visited,
                               bool record_accesses)
 {
@@ -1079,7 +1141,8 @@ analyze_accesses_for_phi_node (struct matrix_info *mi, tree use_stmt,
   struct matrix_access_phi_node tmp_maphi, *maphi, **pmaphi;
 
   tmp_maphi.phi = use_stmt;
-  if ((maphi = htab_find (htab_mat_acc_phi_nodes, &tmp_maphi)))
+  if ((maphi = (struct matrix_access_phi_node *)
+       htab_find (htab_mat_acc_phi_nodes, &tmp_maphi)))
     {
       if (maphi->indirection_level == current_indirect_level)
        return;
@@ -1087,18 +1150,18 @@ analyze_accesses_for_phi_node (struct matrix_info *mi, tree use_stmt,
        {
          int level = MIN (maphi->indirection_level,
                           current_indirect_level);
-         int j;
-         tree t = NULL_TREE;
+         size_t j;
+         gimple stmt = NULL;
 
          maphi->indirection_level = level;
-         for (j = 0; j < PHI_NUM_ARGS (use_stmt); j++)
+         for (j = 0; j < gimple_phi_num_args (use_stmt); j++)
            {
              tree def = PHI_ARG_DEF (use_stmt, j);
 
-             if (TREE_CODE (SSA_NAME_DEF_STMT (def)) != PHI_NODE)
-               t = SSA_NAME_DEF_STMT (def);
+             if (gimple_code (SSA_NAME_DEF_STMT (def)) != GIMPLE_PHI)
+               stmt = SSA_NAME_DEF_STMT (def);
            }
-         mark_min_matrix_escape_level (mi, level, t);
+         mark_min_matrix_escape_level (mi, level, stmt);
        }
       return;
     }
@@ -1123,20 +1186,17 @@ analyze_accesses_for_phi_node (struct matrix_info *mi, tree use_stmt,
     }
 }
 
-/* USE_STMT represents a modify statement (the rhs or lhs include 
+/* USE_STMT represents an assign statement (the rhs or lhs include 
    the ssa var that we want to check  because it came from some use of matrix 
-   MI.
-   CURRENT_INDIRECT_LEVEL is the indirection level we reached so far.  */
+   MI.  CURRENT_INDIRECT_LEVEL is the indirection level we reached so far.  */
 
 static int
-analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
-                                 tree use_stmt, int current_indirect_level,
+analyze_accesses_for_assign_stmt (struct matrix_info *mi, tree ssa_var,
+                                 gimple use_stmt, int current_indirect_level,
                                  bool last_op, sbitmap visited,
                                  bool record_accesses)
 {
-
-  tree lhs = GIMPLE_STMT_OPERAND (use_stmt, 0);
-  tree rhs = GIMPLE_STMT_OPERAND (use_stmt, 1);
+  tree lhs = gimple_get_lhs (use_stmt);
   struct ssa_acc_in_tree lhs_acc, rhs_acc;
 
   memset (&lhs_acc, 0, sizeof (lhs_acc));
@@ -1147,7 +1207,7 @@ analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
   ssa_accessed_in_tree (lhs, &lhs_acc);
   rhs_acc.ssa_var = ssa_var;
   rhs_acc.t_code = ERROR_MARK;
-  ssa_accessed_in_tree (get_inner_of_cast_expr (rhs), &rhs_acc);
+  ssa_accessed_in_assign_rhs (use_stmt, &rhs_acc);
 
   /* The SSA must be either in the left side or in the right side,
      to understand what is happening.
@@ -1167,17 +1227,18 @@ analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
      escaping at that level.  */
   if (lhs_acc.var_found)
     {
-      tree def;
       int l = current_indirect_level + 1;
 
       gcc_assert (lhs_acc.t_code == INDIRECT_REF);
-      def = get_inner_of_cast_expr (rhs);
-      if (TREE_CODE (def) != SSA_NAME)
+
+      if (!(gimple_assign_copy_p (use_stmt)
+           || gimple_assign_cast_p (use_stmt))
+         || (TREE_CODE (gimple_assign_rhs1 (use_stmt)) != SSA_NAME))
        mark_min_matrix_escape_level (mi, l, use_stmt);
       else
        {
-         def = SSA_NAME_DEF_STMT (def);
-         analyze_matrix_allocation_site (mi, def, l, visited);
+         gimple def_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (use_stmt));
+         analyze_matrix_allocation_site (mi, def_stmt, l, visited);
          if (record_accesses)
            record_access_alloc_site_info (mi, use_stmt, NULL_TREE,
                                           NULL_TREE, l, true);
@@ -1189,17 +1250,6 @@ analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
      is used.  */
   if (rhs_acc.var_found)
     {
-      /* If we are passing the ssa name to a function call and
-         the pointer escapes when passed to the function 
-         (not the case of free), then we mark the matrix as 
-         escaping at this level.  */
-      if (rhs_acc.t_code == CALL_EXPR)
-       {
-         analyze_accesses_for_call_expr (mi, use_stmt,
-                                         current_indirect_level);
-
-         return current_indirect_level;
-       }
       if (rhs_acc.t_code != INDIRECT_REF
          && rhs_acc.t_code != POINTER_PLUS_EXPR && rhs_acc.t_code != SSA_NAME)
        {
@@ -1232,8 +1282,8 @@ analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
              tree index;
              tree op1, op2;
 
-             op1 = TREE_OPERAND (rhs, 0);
-             op2 = TREE_OPERAND (rhs, 1);
+             op1 = gimple_assign_rhs1 (use_stmt);
+             op2 = gimple_assign_rhs2 (use_stmt);
 
              op2 = (op1 == ssa_var) ? op2 : op1;
              if (TREE_CODE (op2) == INTEGER_CST)
@@ -1328,8 +1378,8 @@ analyze_matrix_accesses (struct matrix_info *mi, tree ssa_var,
 
   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, ssa_var)
   {
-    tree use_stmt = USE_STMT (use_p);
-    if (TREE_CODE (use_stmt) == PHI_NODE)
+    gimple use_stmt = USE_STMT (use_p);
+    if (gimple_code (use_stmt) == GIMPLE_PHI)
       /* We check all the escaping levels that get to the PHI node
          and make sure they are all the same escaping;
          if not (which is rare) we let the escaping level be the
@@ -1339,16 +1389,22 @@ analyze_matrix_accesses (struct matrix_info *mi, tree ssa_var,
       analyze_accesses_for_phi_node (mi, use_stmt, current_indirect_level,
                                     visited, record_accesses);
 
-    else if (TREE_CODE (use_stmt) == CALL_EXPR)
-      analyze_accesses_for_call_expr (mi, use_stmt, current_indirect_level);
-    else if (TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT)
+    else if (is_gimple_call (use_stmt))
+      analyze_accesses_for_call_stmt (mi, ssa_var, use_stmt,
+                                     current_indirect_level);
+    else if (is_gimple_assign (use_stmt))
       current_indirect_level =
-       analyze_accesses_for_modify_stmt (mi, ssa_var, use_stmt,
+       analyze_accesses_for_assign_stmt (mi, ssa_var, use_stmt,
                                          current_indirect_level, last_op,
                                          visited, record_accesses);
   }
 }
 
+typedef struct 
+{
+  tree fn;
+  gimple stmt;
+} check_var_data;
 
 /* A walk_tree function to go over the VAR_DECL, PARM_DECL nodes of
    the malloc size expression and check that those aren't changed
@@ -1358,22 +1414,26 @@ check_var_notmodified_p (tree * tp, int *walk_subtrees, void *data)
 {
   basic_block bb;
   tree t = *tp;
-  tree fn = data;
-  block_stmt_iterator bsi;
-  tree stmt;
+  check_var_data *callback_data = (check_var_data*) data;
+  tree fn = callback_data->fn;
+  gimple_stmt_iterator gsi;
+  gimple stmt;
 
   if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
     return NULL_TREE;
 
   FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (fn))
   {
-    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+    for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
       {
-       stmt = bsi_stmt (bsi);
-       if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+       stmt = gsi_stmt (gsi);
+       if (!is_gimple_assign (stmt) && !is_gimple_call (stmt))
          continue;
-       if (GIMPLE_STMT_OPERAND (stmt, 0) == t)
-         return stmt;
+       if (gimple_get_lhs (stmt) == t)
+         {
+           callback_data->stmt = stmt;
+           return t;
+         }
       }
   }
   *walk_subtrees = 1;
@@ -1381,58 +1441,63 @@ check_var_notmodified_p (tree * tp, int *walk_subtrees, void *data)
 }
 
 /* Go backwards in the use-def chains and find out the expression
-   represented by the possible SSA name in EXPR, until it is composed
+   represented by the possible SSA name in STMT, until it is composed
    of only VAR_DECL, PARM_DECL and INT_CST.  In case of phi nodes
    we make sure that all the arguments represent the same subexpression,
    otherwise we fail.  */
+
 static tree
-can_calculate_expr_before_stmt (tree expr, sbitmap visited)
+can_calculate_stmt_before_stmt (gimple stmt, sbitmap visited)
 {
-  tree def_stmt, op1, op2, res;
+  tree op1, op2, res;
+  enum tree_code code;
 
-  switch (TREE_CODE (expr))
+  switch (gimple_code (stmt))
     {
-    case SSA_NAME:
-      /* Case of loop, we don't know to represent this expression.  */
-      if (TEST_BIT (visited, SSA_NAME_VERSION (expr)))
-       return NULL_TREE;
+    case GIMPLE_ASSIGN:
+      code = gimple_assign_rhs_code (stmt);
+      op1 = gimple_assign_rhs1 (stmt);
+       
+      switch (code)
+       {
+       case POINTER_PLUS_EXPR:
+       case PLUS_EXPR:
+       case MINUS_EXPR:
+       case MULT_EXPR:
+
+         op2 = gimple_assign_rhs2 (stmt);
+         op1 = can_calculate_expr_before_stmt (op1, visited);
+         if (!op1)
+           return NULL_TREE;
+         op2 = can_calculate_expr_before_stmt (op2, visited);
+         if (op2)
+           return fold_build2 (code, gimple_expr_type (stmt), op1, op2);
+         return NULL_TREE;
+
+       CASE_CONVERT:
+         res = can_calculate_expr_before_stmt (op1, visited);
+         if (res != NULL_TREE)
+           return build1 (code, gimple_expr_type (stmt), res);
+         else
+           return NULL_TREE;
 
-      SET_BIT (visited, SSA_NAME_VERSION (expr));
-      def_stmt = SSA_NAME_DEF_STMT (expr);
-      res = can_calculate_expr_before_stmt (def_stmt, visited);
-      RESET_BIT (visited, SSA_NAME_VERSION (expr));
-      return res;
-    case VAR_DECL:
-    case PARM_DECL:
-    case INTEGER_CST:
-      return expr;
-    case POINTER_PLUS_EXPR:
-    case PLUS_EXPR:
-    case MINUS_EXPR:
-    case MULT_EXPR:
-      op1 = TREE_OPERAND (expr, 0);
-      op2 = TREE_OPERAND (expr, 1);
+       default:
+         if (gimple_assign_single_p (stmt))
+           return can_calculate_expr_before_stmt (op1, visited);
+         else
+           return NULL_TREE;
+       }
 
-      op1 = can_calculate_expr_before_stmt (op1, visited);
-      if (!op1)
-       return NULL_TREE;
-      op2 = can_calculate_expr_before_stmt (op2, visited);
-      if (op2)
-       return fold_build2 (TREE_CODE (expr), TREE_TYPE (expr), op1, op2);
-      return NULL_TREE;
-    case GIMPLE_MODIFY_STMT:
-      return can_calculate_expr_before_stmt (GIMPLE_STMT_OPERAND (expr, 1),
-                                            visited);
-    case PHI_NODE:
+    case GIMPLE_PHI:
       {
-       int j;
+       size_t j;
 
        res = NULL_TREE;
        /* Make sure all the arguments represent the same value.  */
-       for (j = 0; j < PHI_NUM_ARGS (expr); j++)
+       for (j = 0; j < gimple_phi_num_args (stmt); j++)
          {
            tree new_res;
-           tree def = PHI_ARG_DEF (expr, j);
+           tree def = PHI_ARG_DEF (stmt, j);
 
            new_res = can_calculate_expr_before_stmt (def, visited);
            if (res == NULL_TREE)
@@ -1442,14 +1507,40 @@ can_calculate_expr_before_stmt (tree expr, sbitmap visited)
          }
        return res;
       }
-    case NOP_EXPR:
-    case CONVERT_EXPR:
-      res = can_calculate_expr_before_stmt (TREE_OPERAND (expr, 0), visited);
-      if (res != NULL_TREE)
-       return build1 (TREE_CODE (expr), TREE_TYPE (expr), res);
-      else
+
+    default:
+      return NULL_TREE;
+    }
+}
+
+/* Go backwards in the use-def chains and find out the expression
+   represented by the possible SSA name in EXPR, until it is composed
+   of only VAR_DECL, PARM_DECL and INT_CST.  In case of phi nodes
+   we make sure that all the arguments represent the same subexpression,
+   otherwise we fail.  */
+static tree
+can_calculate_expr_before_stmt (tree expr, sbitmap visited)
+{
+  gimple def_stmt;
+  tree res;
+
+  switch (TREE_CODE (expr))
+    {
+    case SSA_NAME:
+      /* Case of loop, we don't know to represent this expression.  */
+      if (TEST_BIT (visited, SSA_NAME_VERSION (expr)))
        return NULL_TREE;
 
+      SET_BIT (visited, SSA_NAME_VERSION (expr));
+      def_stmt = SSA_NAME_DEF_STMT (expr);
+      res = can_calculate_stmt_before_stmt (def_stmt, visited);
+      RESET_BIT (visited, SSA_NAME_VERSION (expr));
+      return res;
+    case VAR_DECL:
+    case PARM_DECL:
+    case INTEGER_CST:
+      return expr;
+
     default:
       return NULL_TREE;
     }
@@ -1481,9 +1572,9 @@ static int
 check_allocation_function (void **slot, void *data ATTRIBUTE_UNUSED)
 {
   int level;
-  block_stmt_iterator bsi;
+  gimple_stmt_iterator gsi;
   basic_block bb_level_0;
-  struct matrix_info *mi = *slot;
+  struct matrix_info *mi = (struct matrix_info *) *slot;
   sbitmap visited;
 
   if (!mi->malloc_for_level)
@@ -1502,17 +1593,18 @@ check_allocation_function (void **slot, void *data ATTRIBUTE_UNUSED)
     if (!mi->malloc_for_level[level])
       break;
 
-  mark_min_matrix_escape_level (mi, level, NULL_TREE);
+  mark_min_matrix_escape_level (mi, level, NULL);
 
-  bsi = bsi_for_stmt (mi->malloc_for_level[0]);
-  bb_level_0 = bsi.bb;
+  gsi = gsi_for_stmt (mi->malloc_for_level[0]);
+  bb_level_0 = gsi.bb;
 
   /* Check if the expression of the size passed to malloc could be
      pre-calculated before the malloc of level 0.  */
   for (level = 1; level < mi->min_indirect_level_escape; level++)
     {
-      tree call_stmt, size;
-      struct malloc_call_data mcd;
+      gimple call_stmt;
+      tree size;
+      struct malloc_call_data mcd = {NULL, NULL_TREE, NULL_TREE};
 
       call_stmt = mi->malloc_for_level[level];
 
@@ -1544,7 +1636,7 @@ check_allocation_function (void **slot, void *data ATTRIBUTE_UNUSED)
          mark_min_matrix_escape_level (mi, level, call_stmt);
          if (dump_file)
            fprintf (dump_file,
-                    "Matrix %s: Cannot calculate the size of allocation. escaping at level %d\n",
+                    "Matrix %s: Cannot calculate the size of allocation, escaping at level %d\n",
                     get_name (mi->decl), level);
          break;
        }
@@ -1572,8 +1664,8 @@ find_sites_in_func (bool record)
 {
   sbitmap visited_stmts_1;
 
-  block_stmt_iterator bsi;
-  tree stmt;
+  gimple_stmt_iterator gsi;
+  gimple stmt;
   basic_block bb;
   struct matrix_info tmpmi, *mi;
 
@@ -1581,29 +1673,34 @@ find_sites_in_func (bool record)
 
   FOR_EACH_BB (bb)
   {
-    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+    for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
       {
-       stmt = bsi_stmt (bsi);
-       if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
-           && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == VAR_DECL)
+       tree lhs;
+
+       stmt = gsi_stmt (gsi);
+       lhs = gimple_get_lhs (stmt);
+       if (lhs != NULL_TREE
+           && TREE_CODE (lhs) == VAR_DECL)
          {
-           tmpmi.decl = GIMPLE_STMT_OPERAND (stmt, 0);
-           if ((mi = htab_find (matrices_to_reorg, &tmpmi)))
+           tmpmi.decl = lhs;
+           if ((mi = (struct matrix_info *) htab_find (matrices_to_reorg,
+                                                       &tmpmi)))
              {
                sbitmap_zero (visited_stmts_1);
                analyze_matrix_allocation_site (mi, stmt, 0, visited_stmts_1);
              }
          }
-       if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
-           && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
-           && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == VAR_DECL)
+       if (is_gimple_assign (stmt)
+           && gimple_assign_single_p (stmt)
+           && TREE_CODE (lhs) == SSA_NAME
+           && TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL)
          {
-           tmpmi.decl = GIMPLE_STMT_OPERAND (stmt, 1);
-           if ((mi = htab_find (matrices_to_reorg, &tmpmi)))
+           tmpmi.decl = gimple_assign_rhs1 (stmt);
+           if ((mi = (struct matrix_info *) htab_find (matrices_to_reorg,
+                                                       &tmpmi)))
              {
                sbitmap_zero (visited_stmts_1);
-               analyze_matrix_accesses (mi,
-                                        GIMPLE_STMT_OPERAND (stmt, 0), 0,
+               analyze_matrix_accesses (mi, lhs, 0,
                                         false, visited_stmts_1, record);
              }
          }
@@ -1635,10 +1732,11 @@ record_all_accesses_in_func (void)
       tree rhs, lhs;
 
       if (!ssa_var
-         || TREE_CODE (SSA_NAME_DEF_STMT (ssa_var)) != GIMPLE_MODIFY_STMT)
+         || !is_gimple_assign (SSA_NAME_DEF_STMT (ssa_var))
+         || !gimple_assign_single_p (SSA_NAME_DEF_STMT (ssa_var)))
        continue;
-      rhs = GIMPLE_STMT_OPERAND (SSA_NAME_DEF_STMT (ssa_var), 1);
-      lhs = GIMPLE_STMT_OPERAND (SSA_NAME_DEF_STMT (ssa_var), 0);
+      rhs = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (ssa_var));
+      lhs = gimple_assign_lhs (SSA_NAME_DEF_STMT (ssa_var));
       if (TREE_CODE (rhs) != VAR_DECL && TREE_CODE (lhs) != VAR_DECL)
        continue;
 
@@ -1646,7 +1744,7 @@ record_all_accesses_in_func (void)
          chain for this SSA_VAR and check for escapes or apply the
          flattening.  */
       tmpmi.decl = rhs;
-      if ((mi = htab_find (matrices_to_reorg, &tmpmi)))
+      if ((mi = (struct matrix_info *) htab_find (matrices_to_reorg, &tmpmi)))
        {
          /* This variable will track the visited PHI nodes, so we can limit
             its size to the maximum number of SSA names.  */
@@ -1659,16 +1757,20 @@ record_all_accesses_in_func (void)
   sbitmap_free (visited_stmts_1);
 }
 
-/* Used when we want to convert the expression: RESULT =  something * ORIG to RESULT = something * NEW. If ORIG and NEW are power of 2, shift operations can be done, else division and multiplication.  */
+/* Used when we want to convert the expression: RESULT = something *
+   ORIG to RESULT = something * NEW_VAL. If ORIG and NEW_VAL are power
+   of 2, shift operations can be done, else division and
+   multiplication.  */
+
 static tree
-compute_offset (HOST_WIDE_INT orig, HOST_WIDE_INT new, tree result)
+compute_offset (HOST_WIDE_INT orig, HOST_WIDE_INT new_val, tree result)
 {
 
   int x, y;
   tree result1, ratio, log, orig_tree, new_tree;
 
   x = exact_log2 (orig);
-  y = exact_log2 (new);
+  y = exact_log2 (new_val);
 
   if (x != -1 && y != -1)
     {
@@ -1687,7 +1789,7 @@ compute_offset (HOST_WIDE_INT orig, HOST_WIDE_INT new, tree result)
       return result1;
     }
   orig_tree = build_int_cst (TREE_TYPE (result), orig);
-  new_tree = build_int_cst (TREE_TYPE (result), new);
+  new_tree = build_int_cst (TREE_TYPE (result), new_val);
   ratio = fold_build2 (TRUNC_DIV_EXPR, TREE_TYPE (result), result, orig_tree);
   result1 = fold_build2 (MULT_EXPR, TREE_TYPE (result), ratio, new_tree);
 
@@ -1714,10 +1816,11 @@ compute_offset (HOST_WIDE_INT orig, HOST_WIDE_INT new, tree result)
 static int
 transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 {
-  block_stmt_iterator bsi;
-  struct matrix_info *mi = *slot;
+  gimple_stmt_iterator gsi;
+  struct matrix_info *mi = (struct matrix_info *) *slot;
   int min_escape_l = mi->min_indirect_level_escape;
   struct access_site_info *acc_info;
+  enum tree_code code;
   int i;
 
   if (min_escape_l < 2 || !mi->access_l)
@@ -1725,8 +1828,6 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
   for (i = 0; VEC_iterate (access_site_info_p, mi->access_l, i, acc_info);
        i++)
     {
-      tree orig, type;
-
       /* This is possible because we collect the access sites before
          we determine the final minimum indirection level.  */
       if (acc_info->level >= min_escape_l)
@@ -1736,73 +1837,66 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
        }
       if (acc_info->is_alloc)
        {
-         if (acc_info->level >= 0 && bb_for_stmt (acc_info->stmt))
+         if (acc_info->level >= 0 && gimple_bb (acc_info->stmt))
            {
              ssa_op_iter iter;
              tree def;
-             tree stmt = acc_info->stmt;
+             gimple stmt = acc_info->stmt;
+             tree lhs;
 
              FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
                mark_sym_for_renaming (SSA_NAME_VAR (def));
-             bsi = bsi_for_stmt (stmt);
-             gcc_assert (TREE_CODE (acc_info->stmt) == GIMPLE_MODIFY_STMT);
-             if (TREE_CODE (GIMPLE_STMT_OPERAND (acc_info->stmt, 0)) ==
-                 SSA_NAME && acc_info->level < min_escape_l - 1)
+             gsi = gsi_for_stmt (stmt);
+             gcc_assert (is_gimple_assign (acc_info->stmt));
+             lhs = gimple_assign_lhs (acc_info->stmt);
+             if (TREE_CODE (lhs) == SSA_NAME
+                 && acc_info->level < min_escape_l - 1)
                {
                  imm_use_iterator imm_iter;
                  use_operand_p use_p;
-                 tree use_stmt;
+                 gimple use_stmt;
 
-                 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter,
-                                        GIMPLE_STMT_OPERAND (acc_info->stmt,
-                                                             0))
+                 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs)
                    FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
                  {
-                   tree conv, tmp, stmts;
+                   tree rhs, tmp;
+                   gimple new_stmt;
 
+                   gcc_assert (gimple_assign_rhs_code (acc_info->stmt)
+                               == INDIRECT_REF);
                    /* Emit convert statement to convert to type of use.  */
-                   conv =
-                     fold_build1 (CONVERT_EXPR,
-                                  TREE_TYPE (GIMPLE_STMT_OPERAND
-                                             (acc_info->stmt, 0)),
-                                  TREE_OPERAND (GIMPLE_STMT_OPERAND
-                                                (acc_info->stmt, 1), 0));
-                   tmp =
-                     create_tmp_var (TREE_TYPE
-                                     (GIMPLE_STMT_OPERAND
-                                      (acc_info->stmt, 0)), "new");
+                   tmp = create_tmp_var (TREE_TYPE (lhs), "new");
                    add_referenced_var (tmp);
-                   stmts =
-                     fold_build2 (GIMPLE_MODIFY_STMT,
-                                  TREE_TYPE (GIMPLE_STMT_OPERAND
-                                             (acc_info->stmt, 0)), tmp,
-                                  conv);
-                   tmp = make_ssa_name (tmp, stmts);
-                   GIMPLE_STMT_OPERAND (stmts, 0) = tmp;
-                   bsi = bsi_for_stmt (acc_info->stmt);
-                   bsi_insert_after (&bsi, stmts, BSI_SAME_STMT);
+                   rhs = gimple_assign_rhs1 (acc_info->stmt);
+                   rhs = fold_convert (TREE_TYPE (tmp),
+                                       TREE_OPERAND (rhs, 0));
+                   new_stmt = gimple_build_assign (tmp, rhs);
+                   tmp = make_ssa_name (tmp, new_stmt);
+                   gimple_assign_set_lhs (new_stmt, tmp);
+                   gsi = gsi_for_stmt (acc_info->stmt);
+                   gsi_insert_after (&gsi, new_stmt, GSI_SAME_STMT);
                    SET_USE (use_p, tmp);
                  }
                }
              if (acc_info->level < min_escape_l - 1)
-               bsi_remove (&bsi, true);
+               gsi_remove (&gsi, true);
            }
          free (acc_info);
          continue;
        }
-      orig = GIMPLE_STMT_OPERAND (acc_info->stmt, 1);
-      type = TREE_TYPE (orig);
-      if (TREE_CODE (orig) == INDIRECT_REF
+      code = gimple_assign_rhs_code (acc_info->stmt);
+      if (code == INDIRECT_REF
          && acc_info->level < min_escape_l - 1)
        {
          /* Replace the INDIRECT_REF with NOP (cast) usually we are casting
             from "pointer to type" to "type".  */
-         orig =
-           build1 (NOP_EXPR, TREE_TYPE (orig),
-                   GIMPLE_STMT_OPERAND (orig, 0));
-         GIMPLE_STMT_OPERAND (acc_info->stmt, 1) = orig;
+         tree t =
+           build1 (NOP_EXPR, TREE_TYPE (gimple_assign_rhs1 (acc_info->stmt)),
+                   TREE_OPERAND (gimple_assign_rhs1 (acc_info->stmt), 0));
+         gimple_assign_set_rhs_code (acc_info->stmt, NOP_EXPR);
+         gimple_assign_set_rhs1 (acc_info->stmt, t);
        }
-      else if (TREE_CODE (orig) == POINTER_PLUS_EXPR
+      else if (code == POINTER_PLUS_EXPR
               && acc_info->level < (min_escape_l))
        {
          imm_use_iterator imm_iter;
@@ -1836,10 +1930,10 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
                  total_elements = new_offset;
                  if (new_offset != offset)
                    {
-                     bsi = bsi_for_stmt (acc_info->stmt);
-                     tmp1 = force_gimple_operand_bsi (&bsi, total_elements,
+                     gsi = gsi_for_stmt (acc_info->stmt);
+                     tmp1 = force_gimple_operand_gsi (&gsi, total_elements,
                                                       true, NULL,
-                                                      true, BSI_SAME_STMT);
+                                                      true, GSI_SAME_STMT);
                    }
                  else
                    tmp1 = offset;
@@ -1852,16 +1946,16 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
                fold_build2 (MULT_EXPR, sizetype, fold_convert (sizetype, acc_info->index),
                            fold_convert (sizetype, d_size));
              add_referenced_var (d_size);
-             bsi = bsi_for_stmt (acc_info->stmt);
-             tmp1 = force_gimple_operand_bsi (&bsi, num_elements, true,
-                                              NULL, true, BSI_SAME_STMT);
+             gsi = gsi_for_stmt (acc_info->stmt);
+             tmp1 = force_gimple_operand_gsi (&gsi, num_elements, true,
+                                              NULL, true, GSI_SAME_STMT);
            }
          /* Replace the offset if needed.  */
          if (tmp1 != offset)
            {
              if (TREE_CODE (offset) == SSA_NAME)
                {
-                 tree use_stmt;
+                 gimple use_stmt;
 
                  FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, offset)
                    FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
@@ -1871,7 +1965,8 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
              else
                {
                  gcc_assert (TREE_CODE (offset) == INTEGER_CST);
-                 TREE_OPERAND (orig, 1) = tmp1;
+                 gimple_assign_set_rhs2 (acc_info->stmt, tmp1);
+                 update_stmt (acc_info->stmt);
                }
            }
        }
@@ -1930,11 +2025,12 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 {
   int i;
   struct matrix_info *mi;
-  tree type, call_stmt_0, malloc_stmt, oldfn, prev_dim_size, use_stmt;
+  tree type, oldfn, prev_dim_size;
+  gimple call_stmt_0, use_stmt;
   struct cgraph_node *c_node;
   struct cgraph_edge *e;
-  block_stmt_iterator bsi;
-  struct malloc_call_data mcd;
+  gimple_stmt_iterator gsi;
+  struct malloc_call_data mcd = {NULL, NULL_TREE, NULL_TREE};
   HOST_WIDE_INT element_size;
 
   imm_use_iterator imm_iter;
@@ -1943,7 +2039,7 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
   int min_escape_l;
   int id;
 
-  mi = *slot;
+  mi = (struct matrix_info *) *slot;
 
   min_escape_l = mi->min_indirect_level_escape;
 
@@ -2016,17 +2112,20 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
   for (i = 1; i < mi->min_indirect_level_escape; i++)
     {
       tree t;
+      check_var_data data;
 
       /* mi->dimension_size must contain the expression of the size calculated
          in check_allocation_function.  */
       gcc_assert (mi->dimension_size[i]);
 
+      data.fn = mi->allocation_function_decl;
+      data.stmt = NULL;
       t = walk_tree_without_duplicates (&(mi->dimension_size[i]),
                                        check_var_notmodified_p,
-                                       mi->allocation_function_decl);
+                                       &data);
       if (t != NULL_TREE)
        {
-         mark_min_matrix_escape_level (mi, i, t);
+         mark_min_matrix_escape_level (mi, i, data.stmt);
          break;
        }
     }
@@ -2036,7 +2135,7 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 
   /* Since we should make sure that the size expression is available
      before the call to malloc of level 0.  */
-  bsi = bsi_for_stmt (call_stmt_0);
+  gsi = gsi_for_stmt (call_stmt_0);
 
   /* Find out the size of each dimension by looking at the malloc
      sites and create a global variable to hold it.
@@ -2055,7 +2154,8 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 
   for (i = mi->min_indirect_level_escape - 1; i >= 0; i--)
     {
-      tree dim_size, dim_var, tmp;
+      tree dim_size, dim_var;
+      gimple stmt;
       tree d_type_size;
 
       /* Now put the size expression in a global variable and initialize it to
@@ -2086,24 +2186,22 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 
          dim_size = fold_build2 (MULT_EXPR, type, dim_size, prev_dim_size);
        }
-      dim_size = force_gimple_operand_bsi (&bsi, dim_size, true, NULL,
-                                          true, BSI_SAME_STMT);
+      dim_size = force_gimple_operand_gsi (&gsi, dim_size, true, NULL,
+                                          true, GSI_SAME_STMT);
       /* GLOBAL_HOLDING_THE_SIZE = DIM_SIZE.  */
-      tmp = fold_build2 (GIMPLE_MODIFY_STMT, type, dim_var, dim_size);
-      GIMPLE_STMT_OPERAND (tmp, 0) = dim_var;
-      mark_symbols_for_renaming (tmp);
-      bsi_insert_before (&bsi, tmp, BSI_SAME_STMT);
+      stmt = gimple_build_assign (dim_var, dim_size);
+      mark_symbols_for_renaming (stmt);
+      gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
 
       prev_dim_size = mi->dimension_size[i] = dim_var;
     }
   update_ssa (TODO_update_ssa);
   /* Replace the malloc size argument in the malloc of level 0 to be
      the size of all the dimensions.  */
-  malloc_stmt = GIMPLE_STMT_OPERAND (call_stmt_0, 1);
   c_node = cgraph_node (mi->allocation_function_decl);
-  old_size_0 = CALL_EXPR_ARG (malloc_stmt, 0);
-  tmp = force_gimple_operand_bsi (&bsi, mi->dimension_size[0], true,
-                                 NULL, true, BSI_SAME_STMT);
+  old_size_0 = gimple_call_arg (call_stmt_0, 0);
+  tmp = force_gimple_operand_gsi (&gsi, mi->dimension_size[0], true,
+                                 NULL, true, GSI_SAME_STMT);
   if (TREE_CODE (old_size_0) == SSA_NAME)
     {
       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, old_size_0)
@@ -2118,33 +2216,31 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
      check this outside of "cgraph.c".  */
   for (i = 1; i < mi->min_indirect_level_escape; i++)
     {
-      block_stmt_iterator bsi;
-      tree use_stmt1 = NULL;
-      tree call;
+      gimple_stmt_iterator gsi;
+      gimple use_stmt1 = NULL;
 
-      tree call_stmt = mi->malloc_for_level[i];
-      call = GIMPLE_STMT_OPERAND (call_stmt, 1);
-      gcc_assert (TREE_CODE (call) == CALL_EXPR);
+      gimple call_stmt = mi->malloc_for_level[i];
+      gcc_assert (is_gimple_call (call_stmt));
       e = cgraph_edge (c_node, call_stmt);
       gcc_assert (e);
       cgraph_remove_edge (e);
-      bsi = bsi_for_stmt (call_stmt);
+      gsi = gsi_for_stmt (call_stmt);
       /* Remove the call stmt.  */
-      bsi_remove (&bsi, true);
+      gsi_remove (&gsi, true);
       /* remove the type cast stmt.  */
       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter,
-                            GIMPLE_STMT_OPERAND (call_stmt, 0))
+                            gimple_call_lhs (call_stmt))
       {
        use_stmt1 = use_stmt;
-       bsi = bsi_for_stmt (use_stmt);
-       bsi_remove (&bsi, true);
+       gsi = gsi_for_stmt (use_stmt);
+       gsi_remove (&gsi, true);
       }
       /* Remove the assignment of the allocated area.  */
       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter,
-                            GIMPLE_STMT_OPERAND (use_stmt1, 0))
+                            gimple_get_lhs (use_stmt1))
       {
-       bsi = bsi_for_stmt (use_stmt);
-       bsi_remove (&bsi, true);
+       gsi = gsi_for_stmt (use_stmt);
+       gsi_remove (&gsi, true);
       }
     }
   update_ssa (TODO_update_ssa);
@@ -2154,24 +2250,21 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
   /* Delete the calls to free.  */
   for (i = 1; i < mi->min_indirect_level_escape; i++)
     {
-      block_stmt_iterator bsi;
-      tree call;
+      gimple_stmt_iterator gsi;
 
       /* ??? wonder why this case is possible but we failed on it once.  */
       if (!mi->free_stmts[i].stmt)
        continue;
 
-      call = TREE_OPERAND (mi->free_stmts[i].stmt, 1);
       c_node = cgraph_node (mi->free_stmts[i].func);
-
-      gcc_assert (TREE_CODE (mi->free_stmts[i].stmt) == CALL_EXPR);
+      gcc_assert (is_gimple_call (mi->free_stmts[i].stmt));
       e = cgraph_edge (c_node, mi->free_stmts[i].stmt);
       gcc_assert (e);
       cgraph_remove_edge (e);
       current_function_decl = mi->free_stmts[i].func;
       set_cfun (DECL_STRUCT_FUNCTION (mi->free_stmts[i].func));
-      bsi = bsi_for_stmt (mi->free_stmts[i].stmt);
-      bsi_remove (&bsi, true);
+      gsi = gsi_for_stmt (mi->free_stmts[i].stmt);
+      gsi_remove (&gsi, true);
     }
   /* Return to the previous situation.  */
   current_function_decl = oldfn;
@@ -2185,7 +2278,7 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 static int
 dump_matrix_reorg_analysis (void **slot, void *data ATTRIBUTE_UNUSED)
 {
-  struct matrix_info *mi = *slot;
+  struct matrix_info *mi = (struct matrix_info *) *slot;
 
   if (!dump_file)
     return 1;
@@ -2199,7 +2292,6 @@ dump_matrix_reorg_analysis (void **slot, void *data ATTRIBUTE_UNUSED)
   return 1;
 }
 
-
 /* Perform matrix flattening.  */
 
 static unsigned int
@@ -2228,7 +2320,7 @@ matrix_reorg (void)
        current_function_decl = node->decl;
        push_cfun (DECL_STRUCT_FUNCTION (node->decl));
        bitmap_obstack_initialize (NULL);
-       tree_register_cfg_hooks ();
+       gimple_register_cfg_hooks ();
 
        if (!gimple_in_ssa_p (cfun))
          {
@@ -2236,6 +2328,7 @@ matrix_reorg (void)
            free_dominance_info (CDI_POST_DOMINATORS);
            pop_cfun ();
            current_function_decl = temp_fn;
+           bitmap_obstack_release (NULL);
 
            return 0;
          }
@@ -2250,6 +2343,7 @@ matrix_reorg (void)
            free_dominance_info (CDI_POST_DOMINATORS);
            pop_cfun ();
            current_function_decl = temp_fn;
+           bitmap_obstack_release (NULL);
 
            return 0;
          }
@@ -2280,6 +2374,7 @@ matrix_reorg (void)
        free_dominance_info (CDI_POST_DOMINATORS);
        pop_cfun ();
        current_function_decl = temp_fn;
+       bitmap_obstack_release (NULL);
       }
   htab_traverse (matrices_to_reorg, transform_allocation_sites, NULL);
   /* Now transform the accesses.  */
@@ -2293,13 +2388,14 @@ matrix_reorg (void)
        current_function_decl = node->decl;
        push_cfun (DECL_STRUCT_FUNCTION (node->decl));
        bitmap_obstack_initialize (NULL);
-       tree_register_cfg_hooks ();
+       gimple_register_cfg_hooks ();
        record_all_accesses_in_func ();
        htab_traverse (matrices_to_reorg, transform_access_sites, NULL);
        free_dominance_info (CDI_DOMINATORS);
        free_dominance_info (CDI_POST_DOMINATORS);
        pop_cfun ();
        current_function_decl = temp_fn;
+       bitmap_obstack_release (NULL);
       }
   htab_traverse (matrices_to_reorg, dump_matrix_reorg_analysis, NULL);
 
@@ -2327,9 +2423,9 @@ struct simple_ipa_opt_pass pass_ipa_matrix_reorg =
   NULL,                                /* sub */
   NULL,                                /* next */
   0,                           /* static_pass_number */
-  0,                           /* tv_id */
+  TV_NONE,                     /* tv_id */
   0,                           /* properties_required */
-  PROP_trees,                  /* properties_provided */
+  0,                           /* properties_provided */
   0,                           /* properties_destroyed */
   0,                           /* todo_flags_start */
   TODO_dump_cgraph | TODO_dump_func    /* todo_flags_finish */