OSDN Git Service

2008-03-23 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / ipa-type-escape.c
index 0a4464d..9cd9caa 100644 (file)
@@ -1,12 +1,12 @@
 /* Type based alias analysis.
 /* Type based alias analysis.
-   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,9 +15,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /* This pass determines which types in the program contain only
    instances that are completely encapsulated by the compilation unit.
 
 /* This pass determines which types in the program contain only
    instances that are completely encapsulated by the compilation unit.
@@ -275,6 +274,7 @@ type_to_consider (tree type)
     case INTEGER_TYPE:
     case QUAL_UNION_TYPE:
     case REAL_TYPE:
     case INTEGER_TYPE:
     case QUAL_UNION_TYPE:
     case REAL_TYPE:
+    case FIXED_POINT_TYPE:
     case RECORD_TYPE:
     case UNION_TYPE:
     case VECTOR_TYPE:
     case RECORD_TYPE:
     case UNION_TYPE:
     case VECTOR_TYPE:
@@ -926,56 +926,89 @@ is_cast_from_non_pointer (tree var, tree def_stmt, void *data)
 
 */
 
 
 */
 
-static bool
-is_array_access_through_pointer_and_index (tree op0, tree op1)
+bool
+is_array_access_through_pointer_and_index (enum tree_code code, tree op0, 
+                                          tree op1, tree *base, tree *offset,
+                                          tree *offset_cast_stmt)
 {
 {
-  tree base, offset, offset_cast_stmt;
   tree before_cast, before_cast_def_stmt;
   cast_t op0_cast, op1_cast;
 
   tree before_cast, before_cast_def_stmt;
   cast_t op0_cast, op1_cast;
 
+  *base = NULL;
+  *offset = NULL;
+  *offset_cast_stmt = NULL;
+
   /* Check 1.  */
   /* Check 1.  */
+  if (code == POINTER_PLUS_EXPR)
+    {
+      tree op0type = TYPE_MAIN_VARIANT (TREE_TYPE (op0));
+      tree op1type = TYPE_MAIN_VARIANT (TREE_TYPE (op1));
 
 
-  /* Init data for walk_use_def_chains function.  */
-  op0_cast.type = op1_cast.type = 0;
-  op0_cast.stmt = op1_cast.stmt = NULL;
+      /* One of op0 and op1 is of pointer type and the other is numerical.  */
+      if (POINTER_TYPE_P (op0type) && NUMERICAL_TYPE_CHECK (op1type))
+       {
+         *base = op0;
+         *offset = op1;
+       }
+      else if (POINTER_TYPE_P (op1type) && NUMERICAL_TYPE_CHECK (op0type))
+       {
+         *base = op1;
+         *offset = op0;
+       }
+      else
+       return false;
+    }
+  else
+    {
+      /* Init data for walk_use_def_chains function.  */
+      op0_cast.type = op1_cast.type = 0;
+      op0_cast.stmt = op1_cast.stmt = NULL;
 
 
-  visited_stmts = pointer_set_create ();
-  walk_use_def_chains (op0, is_cast_from_non_pointer,(void *)(&op0_cast), false);
-  pointer_set_destroy (visited_stmts);
+      visited_stmts = pointer_set_create ();
+      walk_use_def_chains (op0, is_cast_from_non_pointer,(void *)(&op0_cast),
+                          false);
+      pointer_set_destroy (visited_stmts);
 
 
-  visited_stmts = pointer_set_create ();  
-  walk_use_def_chains (op1, is_cast_from_non_pointer,(void *)(&op1_cast), false);
-  pointer_set_destroy (visited_stmts);
+      visited_stmts = pointer_set_create ();  
+      walk_use_def_chains (op1, is_cast_from_non_pointer,(void *)(&op1_cast),
+                          false);
+      pointer_set_destroy (visited_stmts);
 
 
-  if (op0_cast.type == 1 && op1_cast.type == 0)
-    {
-      base = op1;
-      offset = op0;
-      offset_cast_stmt = op0_cast.stmt;
-    }
-  else if (op0_cast.type == 0 && op1_cast.type == 1)
-    {
-      base = op0;
-      offset = op1;      
-      offset_cast_stmt = op1_cast.stmt;
+      if (op0_cast.type == 1 && op1_cast.type == 0)
+       {
+         *base = op1;
+         *offset = op0;
+         *offset_cast_stmt = op0_cast.stmt;
+       }
+      else if (op0_cast.type == 0 && op1_cast.type == 1)
+       {
+         *base = op0;
+         *offset = op1;      
+         *offset_cast_stmt = op1_cast.stmt;
+       }
+      else
+       return false;
     }
     }
-  else
-    return false;
-
+  
   /* Check 2.  
      offset_cast_stmt is of the form: 
      D.1606_7 = (struct str_t *) D.1605_6;  */
 
   /* Check 2.  
      offset_cast_stmt is of the form: 
      D.1606_7 = (struct str_t *) D.1605_6;  */
 
-  before_cast = SINGLE_SSA_TREE_OPERAND (offset_cast_stmt, SSA_OP_USE);
-  if (!before_cast)
-    return false;
+  if (*offset_cast_stmt)
+    {
+      before_cast = SINGLE_SSA_TREE_OPERAND (*offset_cast_stmt, SSA_OP_USE);
+      if (!before_cast)
+       return false;
   
   
-  if (SSA_NAME_IS_DEFAULT_DEF(before_cast))
-    return false;
+      if (SSA_NAME_IS_DEFAULT_DEF (before_cast))
+       return false;
   
   
-  before_cast_def_stmt = SSA_NAME_DEF_STMT (before_cast);
-  if (!before_cast_def_stmt)
-    return false;
+      before_cast_def_stmt = SSA_NAME_DEF_STMT (before_cast);
+      if (!before_cast_def_stmt)
+       return false;
+    }
+  else
+    before_cast_def_stmt = SSA_NAME_DEF_STMT (*offset);
 
   /* before_cast_def_stmt should be of the form:
      D.1605_6 = i.1_5 * 16; */
 
   /* before_cast_def_stmt should be of the form:
      D.1605_6 = i.1_5 * 16; */
@@ -1449,7 +1482,6 @@ static bool
 okay_pointer_operation (enum tree_code code, tree op0, tree op1)
 {
   tree op0type = TYPE_MAIN_VARIANT (TREE_TYPE (op0));
 okay_pointer_operation (enum tree_code code, tree op0, tree op1)
 {
   tree op0type = TYPE_MAIN_VARIANT (TREE_TYPE (op0));
-  tree op1type = TYPE_MAIN_VARIANT (TREE_TYPE (op1));
 
   switch (code)
     {
 
   switch (code)
     {
@@ -1459,11 +1491,17 @@ okay_pointer_operation (enum tree_code code, tree op0, tree op1)
       break;
     case MINUS_EXPR:
     case PLUS_EXPR:
       break;
     case MINUS_EXPR:
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
       {
       {
-       if (POINTER_TYPE_P (op1type)
+       tree base, offset, offset_cast_stmt;
+
+       if (POINTER_TYPE_P (op0type)
            && TREE_CODE (op0) == SSA_NAME 
            && TREE_CODE (op1) == SSA_NAME 
            && TREE_CODE (op0) == SSA_NAME 
            && TREE_CODE (op1) == SSA_NAME 
-           && is_array_access_through_pointer_and_index (op0, op1))
+           && is_array_access_through_pointer_and_index (code, op0, op1, 
+                                                         &base, 
+                                                         &offset, 
+                                                         &offset_cast_stmt))
          return true;
        else
          {
          return true;
        else
          {
@@ -2158,8 +2196,10 @@ gate_type_escape_vars (void)
          && !(errorcount || sorrycount));
 }
 
          && !(errorcount || sorrycount));
 }
 
-struct tree_opt_pass pass_ipa_type_escape =
+struct simple_ipa_opt_pass pass_ipa_type_escape =
 {
 {
+ {
+  SIMPLE_IPA_PASS,
   "type-escape-var",                   /* name */
   gate_type_escape_vars,               /* gate */
   type_escape_execute,                 /* execute */
   "type-escape-var",                   /* name */
   gate_type_escape_vars,               /* gate */
   type_escape_execute,                 /* execute */
@@ -2171,7 +2211,7 @@ struct tree_opt_pass pass_ipa_type_escape =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  0,                                    /* todo_flags_finish */
-  0                                    /* letter */
+  0                                     /* todo_flags_finish */
+ }
 };
 
 };