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]

[ast-optimizer-branch] Simplification of arrays and structures [patch]


This patch fixes the simplification of arrays and structures and
makes a couple of changes in the SIMPLE grammar.  The original
grammar allows

a.b[2][3].c = 3;

to be simplified as

t1 = &a.b
t2 = &t1[2][3]
*t2.c = 3

Which is invalid, of course.  I don't quite know how they got
around it.  In any case, what I've done is modify the grammar so
that we never split array references like that and relax the
rules for structure reference chains to include arrays.

Committed to the branch.


Diego.



	* Makefile.in (c-simplify.o): Add dependency on varray.h.
	* c-simplify.c: Include varray.h.
	Remove comments with SIMPLE grammar.
	(simplify_array_ref): New.
	(simplify_self_mod_expr): New.
	(simplify_component_ref): New.
	(add_assignment_tree): New.
	(simplify_expr): Call simplify_array_ref to simplify array
	references.
	Call simplify_self_mod_expr to simplify ++, --, += and -=
	expressions.
	Call simplify_component_ref to simplify references to structures.
	(simplify_binary_expr): Do not check whether the expression is
	already in SIMPLE form.
	* tree-simple.c: Document changes from original SIMPLE grammar.
	(is_simple_unary_expr): Add check for *ID.
	(is_simple_call_expr): Update comments.
	(is_simple_const): Ditto.
	(is_simple_id): Do not accept *ID expressions.
	(is_simple_val): Update comments.
	(is_simple_arrayref): Accept any variable name as the base address.
	(is_simple_compref_lhs): New.
	(is_simple_compref): Call it.
	* tree-simple.h (is_simple_compref_lhs): Declare.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.701.2.17
diff -d -p -d -u -p -r1.701.2.17 Makefile.in
--- Makefile.in	2002/03/18 23:52:18	1.701.2.17
+++ Makefile.in	2002/03/21 05:10:55
@@ -1353,7 +1353,7 @@ tree-optimize.o : tree-optimize.c tree-o
    $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) $(EXPR_H) \
    $(GGC_H) output.h diagnostic.h ssa.h errors.h flags.h
 c-simplify.o : c-simplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
-   $(C_TREE_H) $(C_COMMON_H) diagnostic.h tree-simple.h
+   $(C_TREE_H) $(C_COMMON_H) diagnostic.h tree-simple.h varray.h
 tree-simple.o : tree-simple.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) tree-simple.h
 c-pretty-print.o : c-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
    $(RTL_H) $(TREE_H) $(EXPR_H) $(C_COMMON_H) errors.h diagnostic.h
Index: c-simplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/c-simplify.c,v
retrieving revision 1.1.2.6
diff -d -p -d -u -p -r1.1.2.6 c-simplify.c
--- c-simplify.c	2002/03/18 23:52:19	1.1.2.6
+++ c-simplify.c	2002/03/21 05:10:55
@@ -28,13 +28,12 @@ Software Foundation, 59 Temple Place - S
 #include "system.h"
 #include "tree.h"
 #include "errors.h"
+#include "varray.h"
 #include "c-tree.h"
 #include "c-common.h"
 #include "tree-simple.h"
 #include "diagnostic.h"
 
-/* {{{ Grammar for SIMPLE trees.  */
-
 /** The simplification pass converts the language-dependent trees
     (ld-trees) emitted by the parser into language-independent trees
     (li-trees) that are the target of SSA analysis and transformations.  
@@ -49,158 +48,8 @@ Software Foundation, 59 Temple Place - S
     Compilers for Parallel Computing, no. 757 in Lecture Notes in
     Computer Science, New Haven, Connecticut, pp. 406-420,
     Springer-Verlag, August 3-5, 1992.
-
-    http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
-
-                                SIMPLE C Grammar
-
-    ----------------------------------------------------------------------
-
-    The BNF rules for SIMPLE C
-
-      Statements
-
-      all_stmts
-	      : stmtlist stop_stmt
-	      | stmtlist
-
-      stmtlist
-	      : stmtlist stmt
-	      | stmt
-
-      stmt
-	      : compstmt
-	      | expr ';'
-	      | IF '(' condexpr ')' stmt
-	      | IF '(' condexpr ')' stmt ELSE stmt
-	      | WHILE '(' condexpr ')' stmt
-	      | DO stmt WHILE '(' condexpr ')'
-	      | FOR '('exprseq ';' condexpr ';'exprseq ')' stmt
-	      | SWITCH '(' val ')' casestmts
-	      | ';'
-
-      compsmt
-	      : '{' all_stmts '}'
-	      | '{' '}'
-	      | '{' decls all_stmts '}'
-	      | '{' decls '}'
-
-      Declarations
-
-      All the possible C declarations. The only difference is that in
-      SIMPLE the declarations are not allowed to have initializations in
-      them.
-
-      Expressions
-
-      exprseq
-	      : exprseq ',' expr
-	      | expr
-
-      stop_stmt
-	      : BREAK ';'
-	      | CONTINUE ';'
-	      | RETURN ';'
-	      | RETURN val ';'
-	      | RETURN '(' val ')' ';'
-
-      casestmts
-	      : '{' cases default'}'
-	      | ';'
-	      | '{' '}'
-
-      cases
-	      : cases case
-	      | case
-
-      case
-	      : CASE CONST':' stmtlist stop_stmt
-
-      default
-	      : DEFAULT ':' stmtlist stop_stmt
-
-      expr
-	      : rhs
-	      | modify_expr
-
-      call_expr
-	      : ID '(' arglist ')'
-
-      arglist
-	      : arglist ',' val
-	      | val
-
-      modify_expr
-	      : varname '=' rhs
-	      | '*' ID '=' rhs
-
-      rhs
-	      : binary_expr
-	      | unary_expr
-
-      unary_expr
-	      : simp_expr
-	      | '*' ID
-	      | '&' varname
-	      | call_expr
-	      | unop val
-	      | '(' cast ')' varname
-
-	      (cast here stands for all valid C typecasts)
-
-      binary_expr
-	      : val binop val
-
-      unop
-	      : '+'
-	      | '-'
-
-      binop
-	      : relop
-	      | '-'
-	      | '+'
-	      ....
-
-      relop
-	      : '<'
-	      | '<='
-	      ...
-
-      condexpr
-	      : val
-	      | val relop val
-
-      simp_expr
-	      : varname
-	      | CONST
-
-      val
-	      : ID
-	      | CONST
-
-      varname
-	      : arrayref
-	      | compref
-	      | ID
-
-      arrayref
-	      : ID reflist
-
-      reflist
-	      : '[' val ']'
-	      | reflist '[' val ']'
-
-      idlist
-	      : idlist '.' ID
-	      | ID
-
-      compref
-	      : '(' '*' ID ')' '.' idlist
-	      | idlist
-
-     ----------------------------------------------------------------------  */
 
-/* }}} */
+    http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html   */
 
 /* {{{ Local declarations.  */
 
@@ -212,8 +61,12 @@ static tree simplify_decl_stmt       PAR
 static tree new_simplified_if        PARAMS ((tree, tree, tree, tree *, tree *, int));
 static tree simplify_expr            PARAMS ((tree, tree *, tree *, tree *));
 static tree simplify_binary_expr     PARAMS ((tree, tree *, tree *, tree *));
+static tree simplify_array_ref       PARAMS ((tree, tree *, tree *, tree *));
+static tree simplify_self_mod_expr   PARAMS ((tree, tree *, tree *, tree *));
+static tree simplify_component_ref   PARAMS ((tree, tree *, tree *, tree *));
 static void make_type_writable       PARAMS ((tree));
 static void add_tree                 PARAMS ((tree, tree *));
+static void add_assignment_tree      PARAMS ((tree, tree, tree *));
 static int  keep_stmt_p              PARAMS ((tree));
 static void insert_after_case_labels PARAMS ((tree, tree, int));
 static tree insert_before_continue   PARAMS ((tree, tree));
@@ -862,17 +715,17 @@ simplify_decl_stmt (t, after_p)
 
 /** {{{ simplify_expr()
 
-    Simplifies the expression tree rooted at T.  Returns the simplified
-    version of T.
+    Simplifies the expression tree rooted at EXPR.  Returns the simplified
+    version of EXPR.
 
     BEFORE_P points to the list where side effects that must happen before
-	T should be stored.
+	EXPR should be stored.
 
-    AFTER_P points to the list where side effects that must happen after T
-	should be stored.
+    AFTER_P points to the list where side effects that must happen after
+	EXPR should be stored.
 
     NEW_VARS_P points to the list where any temporary VAR_DECLs needed to
-	model T's side effects should be stored.  */
+	model EXPR's side effects should be stored.  */
 
 static tree
 simplify_expr (expr, before_p, after_p, new_vars_p)
@@ -900,95 +753,15 @@ simplify_expr (expr, before_p, after_p, 
 	 the AFTER list.  */
     case POSTINCREMENT_EXPR:
     case POSTDECREMENT_EXPR:
-      lhs = simplify_expr (TREE_OPERAND (expr, 0), before_p, after_p,
-	                   new_vars_p);
-      rhs = simplify_expr (TREE_OPERAND (expr, 1), before_p, after_p,
-	                   new_vars_p);
-      t1 = build ((code == POSTINCREMENT_EXPR) ? PLUS_EXPR : MINUS_EXPR,
-	          TREE_TYPE (expr), lhs, rhs);
-      t2 = build_modify_expr (lhs, NOP_EXPR, t1);
-      add_tree (build_stmt (EXPR_STMT, t2), after_p);
-      return lhs;
-
-
-      /* Pre-decrement and increment expressions.  Queue the operation in
-	 the BEFORE list.  */
-    case PREDECREMENT_EXPR:
     case PREINCREMENT_EXPR:
-      lhs = simplify_expr (TREE_OPERAND (expr, 0), before_p, after_p,
-	                   new_vars_p);
-      rhs = simplify_expr (TREE_OPERAND (expr, 1), before_p, after_p,
-	                   new_vars_p);
-      t1 = build ((code == PREINCREMENT_EXPR) ? PLUS_EXPR : MINUS_EXPR,
-	          TREE_TYPE (expr), lhs, rhs);
-      t2 = build_modify_expr (lhs, NOP_EXPR, t1);
-      add_tree (build_stmt (EXPR_STMT, t2), before_p);
-      return lhs;
+    case PREDECREMENT_EXPR:
+      return simplify_self_mod_expr (expr, before_p, after_p, new_vars_p);
 
-      /* Array references.  Simplify each side of the reference and
-	 re-write the expression.  */
     case ARRAY_REF:
-      {
-	tree type_p;
-
-	lhs = simplify_expr (TREE_OPERAND (expr, 0), before_p, after_p,
-	                     new_vars_p);
-	rhs = simplify_expr (TREE_OPERAND (expr, 1), before_p, after_p,
-			     new_vars_p);
-
-        TREE_OPERAND (expr, 0) = lhs;
-        TREE_OPERAND (expr, 1) = rhs;
-
-	if (!is_simple_id (lhs) && !is_simple_arrayref (lhs))
-	  {
-	    type_p = build_pointer_type (TREE_TYPE (expr));
-
-	    /* Create a pointer to the base address of the array.  */
-	    t1 = create_tmp_var (type_p, new_vars_p);
-	    t2 = build_modify_expr (t1, NOP_EXPR, 
-		                    build1 (ADDR_EXPR, type_p, lhs));
-	    add_tree (build_stmt (EXPR_STMT, t2), before_p);
-
-	    /* Now create a reference to the original location.  */
-	    t1 = create_tmp_var (type_p, new_vars_p);
-	    t2 = build_modify_expr (t1, NOP_EXPR,
-		                    build1 (ADDR_EXPR, type_p, expr));
-	    add_tree (build_stmt (EXPR_STMT, t2), before_p);
-
-	    return build1 (INDIRECT_REF, TREE_TYPE (expr), t1);
-	  }
-	else
-	  return expr;
-      }
+      return simplify_array_ref (expr, before_p, after_p, new_vars_p);
 
     case COMPONENT_REF:
-      {
-	lhs = TREE_OPERAND (expr, 0);
-	rhs = TREE_OPERAND (expr, 1);
-
-	if (!is_simple_id (lhs))
-	  {
-	    lhs = simplify_expr (lhs, before_p, after_p, new_vars_p);
-	    t1 = create_tmp_var (TREE_TYPE (lhs), new_vars_p);
-	    t2 = build_modify_expr (t1, NOP_EXPR, lhs);
-	    add_tree (build_stmt (EXPR_STMT, t2), before_p);
-	    lhs = t1;
-	  }
-
-	if (!is_simple_id (rhs))
-	  {
-	    rhs = simplify_expr (rhs, before_p, after_p, new_vars_p);
-	    t1 = create_tmp_var (TREE_TYPE (rhs), new_vars_p);
-	    t2 = build_modify_expr (t1, NOP_EXPR, rhs);
-	    add_tree (build_stmt (EXPR_STMT, t2), before_p);
-	    rhs = t1;
-	  }
-
-	TREE_OPERAND (expr, 0) = lhs;
-	TREE_OPERAND (expr, 1) = rhs;
-
-	return expr;
-        }
+      return simplify_component_ref (expr, before_p, after_p, new_vars_p);
       
     case COND_EXPR:
       {
@@ -1028,9 +801,9 @@ simplify_expr (expr, before_p, after_p, 
 	return tmp;
       }
 
-      /* Transform this expression into T, 
+      /* Transform this expression into EXPR, 
 	 insert in before_p its definition : the simplified version of 
-	 'if (cond) T = 1; else T = 0;'  */
+	 'if (cond) EXPR = 1; else EXPR = 0;'  */
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
       {
@@ -1151,10 +924,16 @@ simplify_expr (expr, before_p, after_p, 
     }
   else
     {
+#if 0
       error ("unhandled expression in simplify_expr():");
+#endif
+      warning ("unhandled expression in simplify_expr():");
       debug_tree (expr);
       fputs ("\n", stderr);
+#if 0
       abort ();
+#endif
+      return expr;
     }
 }
 
@@ -1165,13 +944,13 @@ simplify_expr (expr, before_p, after_p, 
     Return the simplified version of EXPR.
 
     BEFORE_P points to the list where side effects that must happen before
-	T should be stored.
+	EXPR should be stored.
 
-    AFTER_P points to the list where side effects that must happen after T
-	should be stored.
+    AFTER_P points to the list where side effects that must happen after
+	EXPR should be stored.
 
     NEW_VARS_P points to the list where any temporary VAR_DECLs needed to
-	model T's side effects should be stored.  */
+	model EXPR's side effects should be stored.  */
 
 static tree
 simplify_binary_expr (expr, before_p, after_p, new_vars_p)
@@ -1182,9 +961,6 @@ simplify_binary_expr (expr, before_p, af
 {
   tree t1, t2, lhs, rhs;
 
-  if (is_simple_expr (expr))
-    return expr;
-
   lhs = TREE_OPERAND (expr, 0);
   rhs = TREE_OPERAND (expr, 1);
 
@@ -1218,6 +994,221 @@ simplify_binary_expr (expr, before_p, af
 
 /* }}} */
 
+/** {{{ simplify_array_ref ()
+
+    Re-write EXPR (assumed to be an ARRAY_REF) so that it conforms to the
+    SIMPLE grammar:
+
+     arrayref
+	    : varname reflist
+
+     reflist
+	    : '[' val ']'
+	    | reflist '[' val ']'		*/
+
+static tree
+simplify_array_ref (expr, before_p, after_p, new_vars_p)
+     tree expr;
+     tree *before_p;
+     tree *after_p;
+     tree *new_vars_p;
+{
+  tree base, ret, varname, type_p, t1;
+  varray_type dim_stack;
+
+  if (TREE_CODE (expr) != ARRAY_REF)
+    abort ();
+
+  VARRAY_GENERIC_PTR_INIT (dim_stack, 10, "dim_stack");
+
+  /* First find and simplify the base of the array.  While looking
+     for the base of the array, push all the dimensions along the
+     way, so that they can be simplified from left to right after the
+     base.  */
+  base = expr;
+  VARRAY_PUSH_GENERIC_PTR (dim_stack, (PTR)&(TREE_OPERAND (expr, 1)));
+  while (TREE_CODE (TREE_OPERAND (base, 0)) == ARRAY_REF)
+    {
+      base = TREE_OPERAND (base, 0);
+      VARRAY_PUSH_GENERIC_PTR (dim_stack, (PTR)&(TREE_OPERAND (base, 1)));
+    }
+
+  /* After the loop above, 'base' contains the leftmost ARRAY_REF,
+     and 'dim_stack' contains pointers to all the dimensions in left
+     to right order (the leftmost dimension is at the top of the
+     stack).
+
+     We now convert the array reference so that it complies with the
+     grammar production for arrays.  */
+  varname = TREE_OPERAND (base, 0);
+  if (!is_simple_varname (varname))
+    {
+      /* Simplify varname and create the assignment t1 = &expr.  */
+      TREE_OPERAND (base, 0) = simplify_expr (varname, before_p, after_p,
+	                                      new_vars_p);
+      type_p = build_pointer_type (TREE_TYPE (expr));
+      t1 = create_tmp_var (type_p, new_vars_p);
+      add_assignment_tree (t1, build1 (ADDR_EXPR, type_p, expr), before_p);
+
+      /* Since the base has been simplified into t1, we need to
+	 return a reference to *t1.  */
+      ret = build1 (INDIRECT_REF, TREE_TYPE (expr), t1);
+    }
+  else
+    {
+      /* The base array is in SIMPLE form already, we only need to
+	 simplify its dimensions.  Return the original expression
+	 with all the dimensions simplified.  */
+      ret = expr;
+    }
+
+  /* Now simplify each of the dimensions from left to right.  */
+  while (VARRAY_ACTIVE_SIZE (dim_stack) > 0)
+    {
+      tree *dim_p = (tree *)VARRAY_TOP_GENERIC_PTR (dim_stack);
+      VARRAY_POP (dim_stack);
+
+      if (!is_simple_val (*dim_p))
+	{
+	  t1 = create_tmp_var (TREE_TYPE (*dim_p), new_vars_p);
+	  add_assignment_tree (t1, simplify_expr (*dim_p, before_p, after_p,
+		               new_vars_p),
+	      before_p);
+	  *dim_p = t1;
+	}
+    }
+
+  VARRAY_FREE (dim_stack);
+
+  /* Return the simplified array expression.  */
+  return ret;
+}
+
+/* }}} */
+
+/** {{{ simplify_self_mod_expr ()
+
+    Simplify self modifying expression EXPR (++, --, +=, -=).
+
+    BEFORE_P points to the list where side effects that must happen before
+	EXPR should be stored.
+
+    AFTER_P points to the list where side effects that must happen after
+	EXPR should be stored.
+
+    NEW_VARS_P points to the list where any temporary VAR_DECLs needed to
+	model EXPR's side effects should be stored.  */
+
+static tree
+simplify_self_mod_expr (expr, before_p, after_p, new_vars_p)
+     tree expr;
+     tree *before_p;
+     tree *after_p;
+     tree *new_vars_p;
+{
+  enum tree_code code;
+  tree lhs, rhs, t1, t2;
+
+  code = TREE_CODE (expr);
+
+  if (code != POSTINCREMENT_EXPR
+      && code != POSTDECREMENT_EXPR
+      && code != PREINCREMENT_EXPR
+      && code != PREDECREMENT_EXPR)
+    abort ();
+
+  lhs = simplify_expr (TREE_OPERAND (expr, 0), before_p, after_p, new_vars_p);
+  rhs = simplify_expr (TREE_OPERAND (expr, 1), before_p, after_p, new_vars_p);
+
+  /* Determine whether we need to create a PLUS or a MINUS operation.  */
+  if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
+    t1 = build (PLUS_EXPR, TREE_TYPE (expr), lhs, rhs);
+  else
+    t1 = build (MINUS_EXPR, TREE_TYPE (expr), lhs, rhs);
+
+  /* Create the statement LHS = LHS OP RHS.  */
+  t2 = build_modify_expr (lhs, NOP_EXPR, t1);
+
+  /* Determine whether the new assignment goes should go before or after
+     the simplified statement.  */
+  if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
+    add_tree (build_stmt (EXPR_STMT, t2), before_p);
+  else
+    add_tree (build_stmt (EXPR_STMT, t2), after_p);
+
+  /* Return the result of the simplified expression.  */
+  return lhs;
+}
+
+/* }}} */
+
+/** {{{ simplify_component_ref()
+    
+    Simplify the structure reference given by EXPR to comply with:
+
+      compref
+	      : '(' '*' ID ')' '.' idlist
+	      | idlist
+
+      idlist
+	      : idlist '.' ID
+	      | ID
+
+
+    BEFORE_P points to the list where side effects that must happen before
+	EXPR should be stored.
+
+    AFTER_P points to the list where side effects that must happen after
+    	EXPR should be stored.
+
+    NEW_VARS_P points to the list where any temporary VAR_DECLs needed to
+	model EXPR's side effects should be stored.  */
+
+static tree
+simplify_component_ref (expr, before_p, after_p, new_vars_p)
+     tree expr;
+     tree *before_p;
+     tree *after_p;
+     tree *new_vars_p;
+{
+  tree t1, lhs, rhs, type_p;
+
+  if (TREE_CODE (expr) != COMPONENT_REF)
+    abort ();
+
+  lhs = TREE_OPERAND (expr, 0);
+  rhs = TREE_OPERAND (expr, 1);
+
+  /* Re-write the LHS if it's not an ID, *ID or a SIMPLE component ref.  */
+  if (!is_simple_compref_lhs (lhs))
+    {
+      /* Simplify the LHS and create the assignment t1 = &lhs.  */
+      lhs = simplify_expr (lhs, before_p, after_p, new_vars_p);
+      type_p = build_pointer_type (TREE_TYPE (lhs));
+      t1 = create_tmp_var (type_p, new_vars_p);
+      add_assignment_tree (t1, build1 (ADDR_EXPR, type_p, lhs), before_p);
+
+      /* Rewrite the LHS with *t1.  */
+      TREE_OPERAND (expr, 0) = build1 (INDIRECT_REF, TREE_TYPE (lhs), t1);
+    }
+
+  if (!is_simple_id (rhs))
+    {
+      /* Simplify the RHS and create the assignment t1 = &rhs.  */
+      rhs = simplify_expr (rhs, before_p, after_p, new_vars_p);
+      type_p = build_pointer_type (TREE_TYPE (rhs));
+      t1 = create_tmp_var (type_p, new_vars_p);
+      add_assignment_tree (t1, build1 (ADDR_EXPR, type_p, rhs), before_p);
+
+      /* Rewrite the RHS with *t1.  */
+      TREE_OPERAND (expr, 1) = build1 (INDIRECT_REF, TREE_TYPE (rhs), t1);
+    }
+
+  return expr;
+}
+
+/* }}} */
+
 /** {{{ create_tmp_var()
 
    Create a new temporary variable declaration of type TYPE.  Returns the
@@ -1446,6 +1437,23 @@ add_tree (t, list_p)
     chainon (*list_p, t);
   else
     *list_p = t;
+}
+
+/* }}} */
+
+/** {{{ add_assignment_tree ()
+
+   Add the expression statement 'LHS = RHS;' to the list of statements
+   given by LIST_P.  */
+
+static void
+add_assignment_tree (lhs, rhs, list_p)
+     tree lhs;
+     tree rhs;
+     tree *list_p;
+{
+  tree t = build_modify_expr (lhs, NOP_EXPR, rhs);
+  add_tree (build_stmt (EXPR_STMT, t), list_p);
 }
 
 /* }}} */
Index: tree-simple.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.c,v
retrieving revision 1.1.2.1
diff -d -p -d -u -p -r1.1.2.1 tree-simple.c
--- tree-simple.c	2002/03/18 23:52:20	1.1.2.1
+++ tree-simple.c	2002/03/21 05:10:55
@@ -26,22 +26,9 @@ Boston, MA 02111-1307, USA.  */
 
 /* {{{ Grammar for SIMPLE trees.  */
 
-/** The simplification pass converts the language-dependent trees
-    (ld-trees) emitted by the parser into language-independent trees
-    (li-trees) that are the target of SSA analysis and transformations.  
-
-    Language-independent trees are based on the SIMPLE intermediate
-    representation used in the McCAT compiler framework:
-
-    "Designing the McCAT Compiler Based on a Family of Structured
-    Intermediate Representations,"
-    L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
-    Proceedings of the 5th International Workshop on Languages and
-    Compilers for Parallel Computing, no. 757 in Lecture Notes in
-    Computer Science, New Haven, Connecticut, pp. 406-420,
-    Springer-Verlag, August 3-5, 1992.
+/** Original grammar available at:
 
-    http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
+	      http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
 
                                 SIMPLE C Grammar
 
@@ -175,7 +162,12 @@ Boston, MA 02111-1307, USA.  */
 	      | ID
 
       arrayref
-	      : ID reflist
+	      : varname reflist		=> Original grammar only allowed
+	                                   'ID reflist'.  This causes weird
+					   splits like k.d[2][3] into
+					   
+					   	t1 = &(k.d[2])
+  						t2 = *(&t1[3])
 
       reflist
 	      : '[' val ']'
@@ -187,6 +179,8 @@ Boston, MA 02111-1307, USA.  */
 
       compref
 	      : '(' '*' ID ')' '.' idlist
+	      : '&' ID '.' idlist	=> Original grammar does not allow
+					   this.
 	      | idlist
 
      ----------------------------------------------------------------------  */
@@ -325,17 +319,16 @@ int
 is_simple_unary_expr (t)
      tree t;
 {
-  enum tree_code code;
-
   if (t == NULL_TREE)
     abort ();
 
-  code = TREE_CODE (t);
-
-  /* NOTE: is_simple_varname() will also return true for '*' ID.  */
   if (is_simple_varname (t) || is_simple_const (t))
     return 1;
 
+  if (TREE_CODE (t) == INDIRECT_REF
+      && is_simple_id (TREE_OPERAND (t, 0)))
+    return 1;
+
   if (TREE_CODE (t) == ADDR_EXPR
       && is_simple_varname (TREE_OPERAND (t, 0)))
     return 1;
@@ -395,22 +388,8 @@ is_simple_call_expr (t)
       varname
 	      : arrayref
 	      | compref
-	      | ID
-
-      arrayref
-	      : ID reflist
-
-      reflist
-	      : '[' val ']'
-	      | reflist '[' val ']'
-
-      idlist
-	      : idlist '.' ID
-	      | ID
+	      | ID     */
 
-      compref
-	      : '(' '*' ID ')' '.' idlist
-	      | idlist  */
 int
 is_simple_varname (t)
      tree t;
@@ -442,8 +421,7 @@ is_simple_const (t)
 
 /** {{{ is_simple_id ()
 
-    Return non-zero if T is an identifier or an indirect reference to an
-    identifier.  */
+    Return non-zero if T is a SIMPLE identifier.  */
 
 int
 is_simple_id (t)
@@ -452,9 +430,7 @@ is_simple_id (t)
   return (TREE_CODE (t) == VAR_DECL
 	  || TREE_CODE (t) == FUNCTION_DECL
 	  || TREE_CODE (t) == PARM_DECL
-	  || TREE_CODE (t) == FIELD_DECL
-	  || (TREE_CODE (t) == INDIRECT_REF
-	      && is_simple_id (TREE_OPERAND (t, 0))));
+	  || TREE_CODE (t) == FIELD_DECL);
 }
 
 /* }}} */
@@ -477,7 +453,7 @@ is_simple_val (t)
     Return non-zero if T is an array reference of the form:
 
       arrayref
-	      : ID reflist
+	      : varname reflist
 
       reflist
 	      : '[' val ']'
@@ -488,8 +464,7 @@ is_simple_arrayref (t)
      tree t;
 {
   return (TREE_CODE (t) == ARRAY_REF
-	  && (is_simple_id (TREE_OPERAND (t, 0))
-	      || is_simple_arrayref (TREE_OPERAND (t, 0)))
+	  && is_simple_varname (TREE_OPERAND (t, 0))
           && is_simple_val (TREE_OPERAND (t, 1)));
 }
 
@@ -497,10 +472,11 @@ is_simple_arrayref (t)
 
 /** {{{ is_simple_compref ()
 
-    Return non-zero if T is a reference of the form:
+    Return non-zero if T is a component reference of the form:
 
       compref
 	      : '(' '*' ID ')' '.' idlist
+	      : '&' ID '.' idlist
 	      | idlist
 
       idlist
@@ -512,8 +488,28 @@ is_simple_compref (t)
      tree t;
 {
   return (TREE_CODE (t) == COMPONENT_REF
-          && is_simple_id (TREE_OPERAND (t, 0))
+	  && is_simple_compref_lhs (TREE_OPERAND (t, 0))
 	  && is_simple_id (TREE_OPERAND (t, 1)));
+}
+
+/* }}} */
+
+/** {{{ is_simple_compref_lhs ()
+
+    Return non-zero if T is allowed on the left side of a component
+    reference.  */
+
+int
+is_simple_compref_lhs (t)
+     tree t;
+{
+  /* Allow ID, *ID or an idlist on the left side.  */
+  return (is_simple_id (t)
+	  || (TREE_CODE (t) == INDIRECT_REF
+	      && is_simple_id (TREE_OPERAND (t, 0)))
+	  || (TREE_CODE (t) == ADDR_EXPR
+	      && is_simple_id (TREE_OPERAND (t, 0)))
+	  || is_simple_compref (t));
 }
 
 /* }}} */
Index: tree-simple.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.h,v
retrieving revision 1.1.2.2
diff -d -p -d -u -p -r1.1.2.2 tree-simple.h
--- tree-simple.h	2002/03/18 23:52:20	1.1.2.2
+++ tree-simple.h	2002/03/21 05:10:55
@@ -46,6 +46,7 @@ int  is_simple_varname                 P
 int  is_simple_val                     PARAMS ((tree));
 int  is_simple_arrayref                PARAMS ((tree));
 int  is_simple_compref                 PARAMS ((tree));
+int  is_simple_compref_lhs             PARAMS ((tree));
 int  is_simple_cast                    PARAMS ((tree));
 
 #endif /* _TREE_SIMPLE_H */


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