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]

[PATCH] Make treelang work with TreeSSA and cgraph.


 Hi,

  The attached patch fixes some minor bugs in Treelang as well as updating it
to be function/unit at a time.  I've bootstraped and used make treelang.check
to test this patch.  All tests including the new ones pass.

-- 
Thanks,
Jim

http://www.student.cs.uwaterloo.ca/~ja2morri/
http://phython.blogspot.com
http://open.nit.ca/wiki/?page=jim

Attachment: badreturn.tree
Description: testcase

Attachment: var_defs.tree
Description: testcase

Attachment: full_unit.tree
Description: unit at a time test

Index: treelang/ChangeLog

2004-08-01  James A. Morrison  <phython@gcc.gnu.org>

	* Make-lang.in (TREE_BE_LIBS): Remove.
	(tree1): Depend on BACKEND and LIBDEPS.  Use BACKEND and LIBS instead
	of TREE_BE_LIBS.
	* parse.y: Add variable_defs_opt before statements_opt.
	Use tree_code_get_type instead of get_type_for_numeric_type.
	Reformat long lines.
	(parameters_opt): New rule.
	(function_prototype): Use parameters_opt.
	(return): Remove calls to print_token in error cases.  Use VOID_TYPE.
	(check_type_match): Use VOID_TYPE.
	* lex.l (update_lineno_charno): Ensure INPUT_LINE starts at 1.
	* tree1.c: Include version.h and cgraph.h
	(treelang_parse_file): Call cgraph_finalize_compilation_unit and
	cgraph_optimize.
	* treelang.h (item): Remove extraneous GTY.
	* treetree.h (get_type_for_numeric_type): Remove.
	* treetree.c: Include tree-dump.h, tree-iterator.h, tree-gimple.h,
	function.h, and cgraph.h.  Don't include rtl.h
	(keep_level_p): Remove.
	(tree_push_atomic_type_decl): Remove.
	(get_type_for_numeric_type): Remove.
	(tree_code_get_numeric_type): Remove.
	(global_bindings_p): Make static.
	(getdecls): Likewise.
	(insert_block): Likewise.
	(tree_code_if_start): Create a COND_EXPR and add it to the tree
	instead of creating rtl.
	(tree_code_if_else): Create a BIND_EXPR if any variables were created
	in the if statement.
	(tree_code_end_if): Likewise.
	(tree_code_create_function_prototype): Use tree_code_get_type.
	Don't use SET_DECL_ASSEMBLER_NAME.
	(tree_code_create_function_initial): Set DECL_ARTIFICIAL and
	DECL_IGNORING_P on RESULT_DECL.  Use tree_code_get_type.  Don't call
	layout_decl on RESULT_DECL.  Don't call rtl expand functions.
	(tree_code_create_function_wrapup): Don't call rtl expand functions.
	Create a BIND_EXPR for each function.  Dump original and gimplified
	copies of the function tree.  Gimplify function.
	(tree_code_create_variable): Use tree_code_get_type.  Don't call
	layout_decl or expand_decl.  Fold CONVERT_EXPRs.
	(tree_code_generate_return): Fold CONVERT_EXPRs and MODIFY_EXPRs.
	Add RETURN_EXPR to the current statement list.  Don't call rtl expand
	functions.
	(tree_code_output_expression_statement): Append CODE to current
	statement list.
	(tree_code_get_expression): Fold expressions.  Build a pointer to
	a FUNCTION_TYPE intead of the called functions return type.
	(struct binding_level): Add statement list STMTS.
	(getstmtlist): New Function.
	(pushlevel): Make static.  Allocate an empty statement list.
	(poplevel): Make static.  Don't clear BLOCK_NODE's BLOCK_VARS.
	Don't use DECL_ASSEMBLER_NAME.
	(tree_push_type_decl): Set TYPE_NAME of TYPE_NODE to ID.
	(treelang_init_decl_processing): Define basic types after unused types.
	Don't call tree_push_atomic_type_decl.
	(builtin_function): Don't call make_decl_rtl.
	(treelang_expand_function). New Function.

testsuite/treelang/ChangeLog

2004-07-31  James A. Morrison  <phython@gcc.gnu.org>

	* compile/vars_def.tree: New file.
	* compile/badreturn.tree: New file.
        * compile/full_unit.tree: New file.

Index: treelang/Make-lang.in
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/treelang/Make-lang.in,v
retrieving revision 1.46
diff -u -u -r1.46 Make-lang.in
--- treelang/Make-lang.in	20 Feb 2004 08:08:57 -0000	1.46
+++ treelang/Make-lang.in	1 Aug 2004 21:05:12 -0000
@@ -45,10 +45,6 @@
 TREELANGSED = sed
 TREELANGSEDFLAGS = -n
 
-# back end compiler libraries etc
-TREE_BE_LIBS = $(BACKEND) $(LIBIBERTY) $(INTLIBS) $(LIBS) $(LIBDEPS)
-
-
 GCC_EXTRAS = -B./ -B$(build_tooldir)/bin/ -isystem $(build_tooldir)/include
 
 # ./xgcc is the just built compiler. See GCC_FOR_TARGET in the GCC Makefile.in.
@@ -83,11 +79,11 @@
 # core compiler
 tree1$(exeext): treelang/tree1.o treelang/treetree.o treelang/tree-convert.o \
 	treelang/lex.o treelang/parse.o \
-	$(TREE_BE_LIBS) attribs.o
+	$(BACKEND) $(LIBSDEPS) attribs.o
 	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
 	treelang/tree1.o treelang/treetree.o treelang/tree-convert.o \
 	treelang/lex.o treelang/parse.o \
-	$(TREE_BE_LIBS) attribs.o
+	$(BACKEND) $(LIBS) attribs.o
 
 #
 # Compiling object files from source files.
Index: treelang/lex.l
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/treelang/lex.l,v
retrieving revision 1.8
diff -u -u -r1.8 lex.l
--- treelang/lex.l	5 Dec 2003 06:43:30 -0000	1.8
+++ treelang/lex.l	1 Aug 2004 21:05:12 -0000
@@ -4,7 +4,7 @@
 
    ---------------------------------------------------------------------
 
-   Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003
+   Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
    
    This program is free software; you can redistribute it and/or modify it 
@@ -233,6 +233,9 @@
    int yyl;
    ((struct prod_token_parm_item *)yylval)->tp.tok.location = input_location;
    ((struct prod_token_parm_item *)yylval)->tp.tok.charno = next_tree_charno;
+   if (input_line == 0)
+     input_line = 1;
+
    for ( yyl = 0; yyl < yyleng; ++yyl ) 
       {
          if ( yytext[yyl] == '\n' ) 
Index: treelang/parse.y
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/treelang/parse.y,v
retrieving revision 1.11
diff -u -u -r1.11 parse.y
--- treelang/parse.y	8 Jan 2004 07:50:46 -0000	1.11
+++ treelang/parse.y	1 Aug 2004 21:05:12 -0000
@@ -5,7 +5,8 @@
 
      ---------------------------------------------------------------------
 
-     Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+     Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+     Free Software Foundation, Inc.
 
      This program is free software; you can redistribute it and/or modify it
      under the terms of the GNU General Public License as published by the
@@ -254,7 +255,7 @@
 ;
 
 function_prototype:
-storage typename NAME LEFT_PARENTHESIS parameters RIGHT_PARENTHESIS SEMICOLON {
+storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLON {
   struct prod_token_parm_item* tok;
   struct prod_token_parm_item *prod;
   struct prod_token_parm_item *type;
@@ -450,6 +451,14 @@
 }
 ;
 
+parameters_opt:
+/* Nothing to do.  */ {
+ $$ = 0;
+}
+| parameters {
+ $$ = $1;
+}
+
 parameters:
 parameter {
   /* Nothing to do.  */
@@ -496,7 +505,7 @@
   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
   tree_code_if_start (exp->tp.pro.code, tok->tp.tok.location);
 }
-LEFT_BRACE statements_opt RIGHT_BRACE {
+LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
   /* Just let the statements flow.  */
 }
 ELSE {
@@ -504,7 +513,7 @@
   tok = $1;
   tree_code_if_else (tok->tp.tok.location);
 }
-LEFT_BRACE statements_opt RIGHT_BRACE {
+LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
   struct prod_token_parm_item* tok;
   tok = $12;
   tree_code_if_end (tok->tp.tok.location);
@@ -518,25 +527,23 @@
   struct prod_token_parm_item* ret_tok;
   ret_tok = $1;
   type_prod = EXPRESSION_TYPE (current_function);
-  if (NUMERIC_TYPE (type_prod) == VOID)
+  if (NUMERIC_TYPE (type_prod) == VOID_TYPE)
     if ($2 == NULL)
       tree_code_generate_return (type_prod->tp.pro.code, NULL);
     else
       {
         fprintf (stderr, "%s:%i:%i: Redundant expression in return\n",
-		 ret_tok->tp.tok.location.file,
-		 ret_tok->tp.tok.location.line, ret_tok->tp.tok.charno);
-        print_token (stderr, 0, ret_tok);
+                ret_tok->tp.tok.location.file,
+                ret_tok->tp.tok.location.line, ret_tok->tp.tok.charno);
         errorcount++;
         tree_code_generate_return (type_prod->tp.pro.code, NULL);
-      }
+       }
   else
     if ($2 == NULL)
       {
         fprintf (stderr, "%s:%i:%i: Expression missing in return\n",
-		 ret_tok->tp.tok.location.file,
-		 ret_tok->tp.tok.location.line, ret_tok->tp.tok.charno); 
-        print_token (stderr, 0, ret_tok);
+                ret_tok->tp.tok.location.file,
+                ret_tok->tp.tok.location.line, ret_tok->tp.tok.charno);
         errorcount++;
       }
     else
@@ -687,7 +694,7 @@
       abort ();
     parms = tree_code_add_parameter (parms, var->tp.pro.code, exp->tp.pro.code);
   }
-  type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+  type = tree_code_get_type (NUMERIC_TYPE (prod));
   prod->tp.pro.code = tree_code_get_expression
     (EXP_FUNCTION_INVOCATION, type, proto->tp.pro.code, parms, NULL);
   $$ = prod;
@@ -734,7 +741,7 @@
 
   prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
   NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
-  type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+  type = tree_code_get_type (NUMERIC_TYPE (prod));
   if (!NUMERIC_TYPE (prod))
     YYERROR;
   OP1 (prod) = $1;
@@ -832,7 +839,7 @@
 static void
 ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
 {
-  if (type == VOID)
+  if (type == VOID_TYPE)
     {
       fprintf (stderr, "%s:%i:%i: Type must not be void in this context\n",
 	       name->tp.tok.location.file,
@@ -877,7 +884,7 @@
         case UNSIGNED_CHAR:
           return 1;
           
-        case VOID:
+        case VOID_TYPE:
           abort ();
       
         default: 
@@ -885,7 +892,7 @@
         }
       break;
       
-    case VOID:
+    case VOID_TYPE:
       abort ();
       
     default:
@@ -903,7 +910,8 @@
   struct prod_token_parm_item *prod;
   tok = value;
   prod = make_production (PROD_INTEGER_CONSTANT, tok);
-  if ((tok->tp.tok.chars[0] == (unsigned char)'-')|| (tok->tp.tok.chars[0] == (unsigned char)'+'))
+  if ((tok->tp.tok.chars[0] == (unsigned char)'-')
+      || (tok->tp.tok.chars[0] == (unsigned char)'+'))
     NUMERIC_TYPE (prod) = SIGNED_INT;
   else
     NUMERIC_TYPE (prod) = UNSIGNED_INT;
@@ -930,7 +938,7 @@
   prod = make_production (PROD_PLUS_EXPRESSION, tok);
 
   NUMERIC_TYPE (prod) = type_code;
-  type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+  type = tree_code_get_type (type_code);
   if (!type)
     abort ();
   OP1 (prod) = op1;
Index: treelang/tree1.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/treelang/tree1.c,v
retrieving revision 1.16
diff -u -u -r1.16 tree1.c
--- treelang/tree1.c	28 Jul 2003 04:39:29 -0000	1.16
+++ treelang/tree1.c	1 Aug 2004 21:05:13 -0000
@@ -3,7 +3,8 @@
     TREELANG Compiler almost main (tree1)
     Called by GCC's toplev.c
 
-    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004
+    Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
@@ -37,9 +38,11 @@
 #include "tm.h"
 #include "flags.h"
 #include "toplev.h"
+#include "version.h"
 
 #include "ggc.h"
 #include "tree.h"
+#include "cgraph.h"
 #include "diagnostic.h"
 
 #include "treelang.h"
@@ -141,7 +144,7 @@
 treelang_init (void)
 {
   input_filename = main_input_filename;
-  input_line = 0;
+  input_line = 1;
 
   /* Init decls etc.  */
 
@@ -185,6 +188,8 @@
 {
   treelang_debug ();
   yyparse ();
+  cgraph_finalize_compilation_unit ();
+  cgraph_optimize ();
 }
 
 /* Allocate SIZE bytes and clear them.  Not to be used for strings
Index: treelang/treelang.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/treelang/treelang.h,v
retrieving revision 1.6
diff -u -u -r1.6 treelang.h
--- treelang/treelang.h	9 May 2003 21:43:54 -0000	1.6
+++ treelang/treelang.h	1 Aug 2004 21:05:13 -0000
@@ -2,7 +2,8 @@
 
     TREELANG Compiler common definitions (treelang.h)
 
-    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004
+    Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
@@ -48,7 +49,7 @@
 struct token_part;
 struct production_part;
 struct prod_token_parm_item;
-typedef struct GTY(()) prod_token_parm_item item;
+typedef struct prod_token_parm_item item;
 
 /* A token from the input file.  */
 
Index: treelang/treetree.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/treelang/treetree.c,v
retrieving revision 1.39
diff -u -u -r1.39 treetree.c
--- treelang/treetree.c	11 Jul 2004 09:53:06 -0000	1.39
+++ treelang/treetree.c	1 Aug 2004 21:05:13 -0000
@@ -1,13 +1,13 @@
 /*
 
-    TREELANG Compiler back end interface (treetree.c)
+    TREELANG Compiler interface to GCC's middle end (treetree.c)
     Called by the parser.
 
     If you want a working example of how to write a front end to GCC,
     you are in the right place.
 
     Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-    1999, 2000, 2001, 2002, 2003, Free Software Foundation, Inc.
+    1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
     This code is based on toy.c written by Richard Kenner.
 
@@ -19,6 +19,8 @@
 
     It was adapted to TREELANG by Tim Josling 2001.
 
+    Updated to function-at-a-time by James A. Morrison, 2004.
+
     ---------------------------------------------------------------------------
 
     This program is free software; you can redistribute it and/or modify it
@@ -51,8 +53,8 @@
   need for a *lot* of bother to ensure everything is in the mark trees
   at all times.  */
 
-  /* Note it is OK to use GCC extensions such as long long in a compiler front end.
-     This is because the GCC front ends are built using GCC. */
+/* Note, it is OK to use GCC extensions such as long long in a compiler front
+   end.  This is because the GCC front ends are built using GCC.   */
 
 /* GCC headers.  */
 
@@ -61,9 +63,12 @@
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
+#include "tree-dump.h"
+#include "tree-iterator.h"
+#include "tree-gimple.h"
+#include "function.h"
 #include "flags.h"
 #include "output.h"
-#include "rtl.h"
 #include "ggc.h"
 #include "toplev.h"
 #include "varray.h"
@@ -71,6 +76,8 @@
 #include "langhooks.h"
 #include "target.h"
 
+#include "cgraph.h"
+
 #include "treelang.h"
 #include "treetree.h"
 #include "opts.h"
@@ -130,17 +137,22 @@
 static tree tree_lang_signed_type (tree type_node);
 static tree tree_lang_signed_or_unsigned_type (int unsignedp, tree type);
 
-/* XXX these should be static */
-void pushlevel (int ignore);
-tree poplevel (int keep, int reverse, int functionbody);
-int global_bindings_p (void);
-void insert_block (tree block);
-tree pushdecl (tree decl);
-tree getdecls (void);
-int kept_level_p (void);
+/* Functions to keep track of the current scope.  */
+static void pushlevel (int ignore);
+static tree poplevel (int keep, int reverse, int functionbody);
+static tree pushdecl (tree decl);
+static tree* getstmtlist (void);
+
+/* Langhooks.  */
+static tree builtin_function (const char *name, tree type, int function_code,
+		  enum built_in_class class, const char *library_name,
+		  tree attrs);
+static tree getdecls (void);
+static int global_bindings_p (void);
+static void insert_block (tree);
 
 static void tree_push_type_decl (tree id, tree type_node);
-static void tree_push_atomic_type_decl (tree id, tree type_node);
+static void treelang_expand_function (tree fndecl);
 
 /* The front end language hooks (addresses of code for this front
    end).  These are not really very language-dependent, i.e.
@@ -163,6 +175,12 @@
 #undef LANG_HOOKS_PARSE_FILE
 #define LANG_HOOKS_PARSE_FILE treelang_parse_file
 
+#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
+#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION treelang_expand_function
+
+/* #undef LANG_HOOKS_TYPES_COMPATIBLE_P
+#define LANG_HOOKS_TYPES_COMPATIBLE_P hook_bool_tree_tree_true
+*/
 /* Hook routines and data unique to treelang.  */
 
 #undef LANG_HOOKS_INIT
@@ -243,33 +261,54 @@
 void
 tree_code_if_start (tree exp, location_t loc)
 {
-  tree cond_exp;
-  cond_exp = build (NE_EXPR,
-                 TREE_TYPE (exp),
-                 exp,
-                 build1 (CONVERT_EXPR, TREE_TYPE (exp), integer_zero_node));
-  emit_line_note (loc); /* Output the line number information.  */
-  expand_start_cond (cond_exp, /* Exit-able if nonzero.  */ 0);
+  tree cond_exp, cond;
+  cond_exp = fold (build2 (NE_EXPR, boolean_type_node, exp,
+                     fold (build1 (CONVERT_EXPR, TREE_TYPE (exp), integer_zero_node))));
+  SET_EXPR_LOCATION (cond_exp, loc);
+  cond = build3 (COND_EXPR, void_type_node, cond_exp, NULL_TREE,
+                 NULL_TREE);
+  SET_EXPR_LOCATION (cond, loc);
+  append_to_statement_list_force (cond, getstmtlist ());
+  pushlevel (0);
 }
 
 /* Output the code for the else of an if statement.  The else occurred
    at line LINENO in file FILENAME.  */
 
 void
-tree_code_if_else (location_t loc)
+tree_code_if_else (location_t loc ATTRIBUTE_UNUSED)
 {
-  emit_line_note (loc); /* Output the line number information.  */
-  expand_start_else ();
+  tree stmts = *getstmtlist ();
+  tree block = poplevel (1, 0, 0);
+  if (BLOCK_VARS (block))
+    {
+      tree bindexpr = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
+                              stmts, block);
+      stmts = alloc_stmt_list ();
+      append_to_statement_list (bindexpr, &stmts);
+    }
+
+  TREE_OPERAND (STATEMENT_LIST_TAIL (*getstmtlist ())->stmt, 1) = stmts;
+  pushlevel (0);
 }
 
-/* Output the code for the end_if an if statement.  The end_if (final brace) occurred
-   at line LINENO in file FILENAME.  */
+/* Output the code for the end_if an if statement.  The end_if (final brace)
+   occurred at line LINENO in file FILENAME.  */
 
 void
-tree_code_if_end (location_t loc)
+tree_code_if_end (location_t loc ATTRIBUTE_UNUSED)
 {
-  emit_line_note (loc); /* Output the line number information.  */
-  expand_end_cond ();
+  tree stmts = *getstmtlist ();
+  tree block = poplevel (1, 0, 0);
+  if (BLOCK_VARS (block))
+    {
+       tree bindexpr = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
+                               stmts, block);
+       stmts = alloc_stmt_list ();
+       append_to_statement_list (bindexpr, &stmts);
+    }
+
+  TREE_OPERAND (STATEMENT_LIST_TAIL (*getstmtlist ())->stmt, 2) = stmts;
 }
 
 /* Create a function.  The prototype name is NAME, storage class is
@@ -297,7 +336,7 @@
     {
       if (parm->category != parameter_category)
         abort ();
-      type_node = get_type_for_numeric_type (parm->type);
+      type_node = tree_code_get_type (parm->type);
       type_list = tree_cons (NULL_TREE, type_node, type_list);
     }
   /* Last parm if void indicates fixed length list (as opposed to
@@ -306,20 +345,18 @@
   /* The back end needs them in reverse order.  */
   type_list = nreverse (type_list);
 
-  type_node = get_type_for_numeric_type (ret_type);
+  type_node = tree_code_get_type (ret_type);
   fn_type = build_function_type (type_node, type_list);
 
   id = get_identifier ((const char*)chars);
   fn_decl = build_decl (FUNCTION_DECL, id, fn_type);
 
-  DECL_CONTEXT (fn_decl) = NULL_TREE; /* Nested functions not supported here.  */
+  /* Nested functions not supported here.  */
+  DECL_CONTEXT (fn_decl) = NULL_TREE;
   DECL_SOURCE_LOCATION (fn_decl) = loc;
 
   TREE_USED (fn_decl) = 1;
 
-  /* Real name (optional).  */
-  SET_DECL_ASSEMBLER_NAME (fn_decl, DECL_NAME (fn_decl));
-
   TREE_PUBLIC (fn_decl) = 0;
   DECL_EXTERNAL (fn_decl) = 0;
   TREE_STATIC (fn_decl) = 0;
@@ -340,7 +377,6 @@
       DECL_EXTERNAL (fn_decl) = 1;
       break;
 
-
     case AUTOMATIC_STORAGE:
     default:
       abort ();
@@ -364,8 +400,6 @@
 {
   tree fn_decl;
   tree param_decl;
-  tree next_param;
-  tree first_param;
   tree parm_decl;
   tree parm_list;
   tree resultdecl;
@@ -388,15 +422,14 @@
 
   DECL_SOURCE_LOCATION (fn_decl) = loc;
 
-  /* Prepare creation of rtl for a new function.  */
-
-  resultdecl = DECL_RESULT (fn_decl) 
-    = build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (TREE_TYPE (fn_decl)));
-  DECL_CONTEXT (DECL_RESULT (fn_decl)) = fn_decl;
+  /* Create a DECL for the functions result.  */
+  resultdecl =
+    build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (TREE_TYPE (fn_decl)));
+  DECL_CONTEXT (resultdecl) = fn_decl;
+  DECL_ARTIFICIAL (resultdecl) = 1;
+  DECL_IGNORED_P (resultdecl) = 1;
   DECL_SOURCE_LOCATION (resultdecl) = loc;
-
-  /* Work out the size. ??? is this needed.  */
-  layout_decl (DECL_RESULT (fn_decl), 0);
+  DECL_RESULT (fn_decl) = resultdecl;
 
   /* Make the argument variable decls.  */
   parm_list = NULL_TREE;
@@ -404,7 +437,7 @@
     {
       parm_decl = build_decl (PARM_DECL, get_identifier
                               ((const char*) (parm->tp.par.variable_name)),
-                              get_type_for_numeric_type (parm->type));
+                              tree_code_get_type (parm->type));
 
       /* Some languages have different nominal and real types.  */
       DECL_ARG_TYPE (parm_decl) = TREE_TYPE (parm_decl);
@@ -436,58 +469,15 @@
   if (this_parm)
     abort (); /* Too many.  */
 
-  /* Output the decl rtl (not the rtl for the function code).  ???.
-     If the function is not defined in this file, when should you
-     execute this?  */
-  make_decl_rtl (fn_decl, NULL);
-
-  init_function_start (fn_decl);
-
-  /* Create rtl for startup code of function, such as saving registers.  */
-
-  expand_function_start (fn_decl, 0);
-
-  /* Function.c requires a push at the start of the function. that
-     looks like a bug to me but let's make it happy.  */
+  /* Create a new level at the start of the function.  */
 
   pushlevel (0);
 
-  /* Create rtl for the start of a new scope.  */
-
-  expand_start_bindings (2);
-
-  /* Put the parameters into the symbol table.  */
-
-  for (first_param = param_decl = nreverse (DECL_ARGUMENTS (fn_decl));
-       param_decl;
-       param_decl = next_param)
-    {
-      next_param = TREE_CHAIN (param_decl);
-      TREE_CHAIN (param_decl) = NULL;
-      /* layout_decl (param_decl, 0);  Already done in build_decl tej 13/4/2002.  */
-      pushdecl (param_decl);
-      if (DECL_CONTEXT (param_decl) != current_function_decl)
-        abort ();
-    }
-
-  /* Store back the PARM_DECL nodes.  They appear in the right order.  */
-  DECL_ARGUMENTS (fn_decl) = getdecls ();
-
   /* Force it to be output, else may be solely inlined.  */
   TREE_ADDRESSABLE (fn_decl) = 1;
 
   /* Stop -O3 from deleting it.  */
   TREE_USED (fn_decl) = 1;
-
-  /* Add a new level to the debugger symbol table.  */
-
-  pushlevel (0);
-
-  /* Create rtl for the start of a new scope.  */
-
-  expand_start_bindings (0);
-
-  emit_line_note (loc); /* Output the line number information.  */
 }
 
 /* Wrapup a function contained in file FILENAME, ending at line LINENO.  */
@@ -496,42 +486,38 @@
 {
   tree block;
   tree fn_decl;
+  tree stmts = *getstmtlist ();
 
   fn_decl = current_function_decl;
 
-  emit_line_note (loc); /* Output the line number information.  */
-
-  /* Get completely built level from debugger symbol table.  */
-
-  block = poplevel (1, 0, 0);
-
-  /* Emit rtl for end of scope.  */
-
-  expand_end_bindings (block, 0, 1);
-
-  /* Emit rtl for end of function.  */
-
-  expand_function_end ();
-
   /* Pop the level.  */
 
   block = poplevel (1, 0, 1);
 
   /* And attach it to the function.  */
 
-  DECL_INITIAL (fn_decl) = block;
+  DECL_SAVED_TREE (fn_decl) = build3 (BIND_EXPR, void_type_node,
+                                      BLOCK_VARS (block),
+			              stmts, block);
 
-  /* Emit rtl for end of scope.  */
+  allocate_struct_function (fn_decl);
+  cfun->function_end_locus = loc;
 
-  expand_end_bindings (block, 0, 1);
 
-  /* Call optimization and convert optimized rtl to assembly code.  */
+  /* Dump the original tree to a file.  */
+  dump_function (TDI_original, fn_decl);
 
-  rest_of_compilation (fn_decl);
+  /* Convert current function to GIMPLE for the middle end.  */
+  gimplify_function_tree (fn_decl);
+  dump_function (TDI_generic, fn_decl);
 
   /* We are not inside of any scope now.  */
-
   current_function_decl = NULL_TREE;
+  cfun = NULL;
+
+  /* Pass the current function off to the middle end.  */
+  (void)cgraph_node (fn_decl);
+  cgraph_finalize_function (fn_decl, false);
 }
 
 /*
@@ -556,7 +542,7 @@
   tree var_decl;
 
   /* 1. Build the type.  */
-  var_type = get_type_for_numeric_type (expression_type);
+  var_type = tree_code_get_type (expression_type);
 
   /* 2. Build the name.  */
   if (chars[length] != 0)
@@ -569,13 +555,10 @@
 
   /* 3a. Initialization.  */
   if (init)
-    DECL_INITIAL (var_decl) = build1 (CONVERT_EXPR, var_type, init);
+    DECL_INITIAL (var_decl) = fold (build1 (CONVERT_EXPR, var_type, init));
   else
     DECL_INITIAL (var_decl) = NULL_TREE;
 
-  /* 4. Compute size etc.  */
-  layout_decl (var_decl, 0);
-
   if (TYPE_SIZE (var_type) == 0)
     abort (); /* Did not calculate size.  */
 
@@ -617,13 +600,8 @@
 
   if (TREE_STATIC (var_decl))
     rest_of_decl_compilation (var_decl, 0, 0, 0);
-  else
-    {
-      expand_decl (var_decl);
-      if (DECL_INITIAL (var_decl))
-        expand_decl_init (var_decl);
-    }
 
+  TYPE_NAME (TREE_TYPE (var_decl)) = TYPE_NAME (var_type);
   return pushdecl (copy_node (var_decl));
 
 }
@@ -646,28 +624,33 @@
         abort ();
     }
 
-  if (exp)
+  if (exp && TREE_TYPE (TREE_TYPE (current_function_decl)) != void_type_node)
     {
-      setret = build (MODIFY_EXPR, type, DECL_RESULT (current_function_decl),
-                     build1 (CONVERT_EXPR, type, exp));
+      setret = fold (build2 (MODIFY_EXPR, type, 
+                             DECL_RESULT (current_function_decl),
+                             fold (build1 (CONVERT_EXPR, type, exp))));
       TREE_SIDE_EFFECTS (setret) = 1;
       TREE_USED (setret) = 1;
-      expand_expr_stmt (setret);
+      setret = build1 (RETURN_EXPR, type, setret);
     }
-  expand_return (DECL_RESULT (current_function_decl));
+   else
+     setret = build1 (RETURN_EXPR, type, NULL_TREE);
+
+   append_to_statement_list_force (setret, getstmtlist ());
 }
 
-/* Output the code for this expression statement CODE.  */
 
+/* Output the code for this expression statement CODE.  */
 
 void
 tree_code_output_expression_statement (tree code, location_t loc)
 {
   /* Output the line number information.  */
-  emit_line_note (loc);
+  SET_EXPR_LOCATION (code, loc);
   TREE_USED (code) = 1;
   TREE_SIDE_EFFECTS (code) = 1;
-  expand_expr_stmt (code);
+  /* put CODE into the code list.  */
+  append_to_statement_list_force (code, getstmtlist ());
 }
 
 /* Return a tree for a constant integer value in the token TOK.  No
@@ -716,9 +699,8 @@
       if (!op1 || !op2)
         abort ();
       operator = MODIFY_EXPR;
-      ret1 = build (operator, type,
-                 op1,
-                 build1 (CONVERT_EXPR, type, op2));
+      ret1 = fold (build2 (operator, void_type_node, op1,
+                           fold (build1 (CONVERT_EXPR, TREE_TYPE (op1), op2))));
 
       break;
 
@@ -734,13 +716,13 @@
       operator = EQ_EXPR;
       goto binary_expression;
 
-      /* Expand a binary expression.  Ensure the operands are the right type.  */
+    /* Expand a binary expression.  Ensure the operands are the right type.  */
     binary_expression:
       if (!op1 || !op2)
         abort ();
-      ret1  =  build (operator, type,
-                   build1 (CONVERT_EXPR, type, op1),
-                   build1 (CONVERT_EXPR, type, op2));
+      ret1  =  fold (build2 (operator, type,
+                       fold (build1 (CONVERT_EXPR, type, op1)),
+                       fold (build1 (CONVERT_EXPR, type, op2))));
       break;
 
       /* Reference to a variable.  This is dead easy, just return the
@@ -752,16 +734,18 @@
       if (type == TREE_TYPE (op1))
         ret1 = op1;
       else
-        ret1 = build1 (CONVERT_EXPR, type, op1);
+        ret1 = fold (build1 (CONVERT_EXPR, type, op1));
       break;
 
     case EXP_FUNCTION_INVOCATION:
       if (!op1 || !op2)
         abort ();
+
       {
         tree fun_ptr;
-        fun_ptr = build1 (ADDR_EXPR, build_pointer_type (type), op1);
-        ret1 = build (CALL_EXPR, type, fun_ptr, nreverse (op2));
+        fun_ptr = fold (build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (op1)),
+                                op1));
+        ret1 = build3 (CALL_EXPR, type, fun_ptr, nreverse (op2), NULL_TREE);
       }
       break;
 
@@ -788,83 +772,13 @@
 {
   tree new_exp;
   new_exp = tree_cons (NULL_TREE,
-                    build1 (CONVERT_EXPR, TREE_TYPE (proto_exp), exp),
-                    NULL_TREE);
+                       fold (build1 (CONVERT_EXPR, TREE_TYPE (proto_exp), exp)),
+                       NULL_TREE);
   if (!list)
     return new_exp;
   return chainon (new_exp, list);
 }
 
-/* Get the tree type for this type whose number is NUMERIC_TYPE.  */
-
-tree
-get_type_for_numeric_type (unsigned int numeric_type)
-{
-
-  int size1;
-  int sign1;
-  switch (numeric_type)
-    {
-    case VOID_TYPE:
-      return void_type_node;
-
-    case SIGNED_INT:
-      size1 = tree_code_int_size;
-      sign1 = 1;
-      break;
-
-    case UNSIGNED_INT:
-      size1 = tree_code_int_size;
-      sign1 = 0;
-      break;
-
-    case SIGNED_CHAR:
-      size1 = tree_code_char_size;
-      sign1 = 1;
-      break;
-
-    case UNSIGNED_CHAR:
-      size1 = tree_code_char_size;
-      sign1 = 0;
-      break;
-
-    default:
-      abort ();
-    }
-
-  return tree_code_get_numeric_type (size1, sign1);
-
-}
-
-/* Return tree representing a numeric type of size SIZE1 bits and
-   signed if SIGN1 !=  0.  */
-tree
-tree_code_get_numeric_type (unsigned int size1, unsigned int sign1)
-{
-  tree ret1;
-  if (!size1)
-    abort ();
-  if (size1 == tree_code_int_size)
-    {
-      if (sign1)
-        ret1 = integer_type_node;
-      else
-        ret1 = unsigned_type_node;
-    }
-  else
-    if (size1 == tree_code_char_size)
-      {
-        if (sign1)
-          ret1 = signed_char_type_node;
-        else
-          ret1 = unsigned_char_type_node;
-      }
-    else
-      abort ();
-
-  return ret1;
-}
-
 /* Get a stringpool entry for a string S of length L.  This is needed
    because the GTY routines don't mark strings, forcing you to put
    them into stringpool, which is never freed.  */
@@ -1056,6 +970,8 @@
   /* For each level (except the global one), a chain of BLOCK nodes for all
      the levels that were entered and exited one level down from this one.  */
   tree blocks;
+
+  tree stmts;
   /* The binding level containing this one (the enclosing binding level). */
   struct binding_level *level_chain;
 };
@@ -1068,37 +984,38 @@
 static struct binding_level *global_binding_level;
 
 /* Binding level structures are initialized by copying this one.  */
-static struct binding_level clear_binding_level = {NULL, NULL, NULL };
+static struct binding_level clear_binding_level = {NULL, NULL, NULL, NULL };
 
 /* Return non-zero if we are currently in the global binding level.  */
 
-int
+static int
 global_bindings_p (void)
 {
   return current_binding_level == global_binding_level ? -1 : 0;
 }
 
+
 /* Return the list of declarations in the current level. Note that this list
    is in reverse order (it has to be so for back-end compatibility).  */
 
-tree
+static tree
 getdecls (void)
 {
   return current_binding_level->names;
 }
 
-/* Nonzero if the current level needs to have a BLOCK made.  */
+/* Return a STATMENT_LIST for the current block.  */
 
-int
-kept_level_p (void)
+static tree*
+getstmtlist (void)
 {
-  return (current_binding_level->names != 0);
+  return &current_binding_level->stmts;
 }
 
 /* Enter a new binding level. The input parameter is ignored, but has to be
    specified for back-end compatibility.  */
 
-void
+static void
 pushlevel (int ignore ATTRIBUTE_UNUSED)
 {
   struct binding_level *newlevel = xmalloc (sizeof (struct binding_level));
@@ -1109,6 +1026,7 @@
      active.  */
   newlevel->level_chain = current_binding_level;
   current_binding_level = newlevel;
+  current_binding_level->stmts = alloc_stmt_list ();
 }
 
 /* Exit a binding level.
@@ -1126,7 +1044,7 @@
    If REVERSE is nonzero, reverse the order of decls before putting
    them into the BLOCK.  */
 
-tree
+static tree
 poplevel (int keep, int reverse, int functionbody)
 {
   /* Points to a BLOCK tree node. This is the BLOCK node construted for the
@@ -1166,8 +1084,6 @@
 	{
 	  if (TREE_USED (subblock_node))
 	    TREE_USED (DECL_NAME (subblock_node)) = 1;
-	  if (TREE_ADDRESSABLE (subblock_node))
-	    TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (subblock_node)) = 1;
 	}
 
   /* Pop the current level.  */
@@ -1175,12 +1091,8 @@
 
   if (functionbody)
     {
-      /* This is the top level block of a function. The ..._DECL chain stored
-	 in BLOCK_VARS are the function's parameters (PARM_DECL nodes). Don't
-	 leave them in the BLOCK because they are found in the FUNCTION_DECL
-	 instead.  */
+      /* This is the top level block of a function.  */
       DECL_INITIAL (current_function_decl) = block_node;
-      BLOCK_VARS (block_node) = 0;
     }
   else if (block_node)
     {
@@ -1205,7 +1117,7 @@
    current binding level.  This is used when a BIND_EXPR is expanded,
    to handle the BLOCK node inside the BIND_EXPR.  */
 
-void
+static void
 insert_block (tree block)
 {
   TREE_USED (block) = 1;
@@ -1213,6 +1125,7 @@
     = chainon (current_binding_level->blocks, block);
 }
 
+
 /* Records a ..._DECL node DECL as belonging to the current lexical scope.
    Returns the ..._DECL node. */
 
@@ -1247,22 +1160,10 @@
 tree_push_type_decl(tree id, tree type_node)
 {
   tree decl = build_decl (TYPE_DECL, id, type_node);
-  TYPE_NAME (type_node) = decl;
-  TYPE_STUB_DECL (type_node) = decl;
+  TYPE_NAME (type_node) = id;
   pushdecl (decl);
 }
 
-/* push_atomic_type_decl() ensures that the type's type is itself. 
-   Needed for DBX.  Must only be used for atomic types,
-   not for e.g. pointer or array types.  */
-
-static void
-tree_push_atomic_type_decl(tree id, tree type_node)
-{
-  TREE_TYPE (type_node) = type_node;
-  tree_push_type_decl (id, type_node);
-}
-
 #define NULL_BINDING_LEVEL (struct binding_level *) NULL                        
 
 /* Create the predefined scalar types of C,
@@ -1282,53 +1183,52 @@
 
   /* set standard type names */
 
-  /* Define `int' and `char' first so that dbx will output them first.  */
+  /* Define `int' and `char' last so that they are not overwritten.  */
+  tree_push_type_decl (NULL_TREE, intQI_type_node);
+  tree_push_type_decl (NULL_TREE, intHI_type_node);
+  tree_push_type_decl (NULL_TREE, intSI_type_node);
+  tree_push_type_decl (NULL_TREE, intDI_type_node);
+#if HOST_BITS_PER_WIDE_INT >= 64
+  tree_push_type_decl (NULL_TREE, intTI_type_node);
+#endif
+  tree_push_type_decl (NULL_TREE, unsigned_intQI_type_node);
+  tree_push_type_decl (NULL_TREE, unsigned_intHI_type_node);
+  tree_push_type_decl (NULL_TREE, unsigned_intSI_type_node);
+  tree_push_type_decl (NULL_TREE, unsigned_intDI_type_node);
+#if HOST_BITS_PER_WIDE_INT >= 64
+  tree_push_type_decl (NULL_TREE, unsigned_intTI_type_node);
+#endif
 
-  tree_push_atomic_type_decl (get_identifier ("int"), integer_type_node);
-  tree_push_atomic_type_decl (get_identifier ("char"), char_type_node);
-  tree_push_atomic_type_decl (get_identifier ("long int"),
+  tree_push_type_decl (get_identifier ("int"), integer_type_node);
+  tree_push_type_decl (get_identifier ("char"), char_type_node);
+  tree_push_type_decl (get_identifier ("long int"),
 			      long_integer_type_node);
-  tree_push_atomic_type_decl (get_identifier ("unsigned int"),
+  tree_push_type_decl (get_identifier ("unsigned int"),
 			      unsigned_type_node);
-  tree_push_atomic_type_decl (get_identifier ("long unsigned int"),
+  tree_push_type_decl (get_identifier ("long unsigned int"),
 			      long_unsigned_type_node);
-  tree_push_atomic_type_decl (get_identifier ("long long int"),
+  tree_push_type_decl (get_identifier ("long long int"),
 			      long_long_integer_type_node);
-  tree_push_atomic_type_decl (get_identifier ("long long unsigned int"),
+  tree_push_type_decl (get_identifier ("long long unsigned int"),
 			      long_long_unsigned_type_node);
-  tree_push_atomic_type_decl (get_identifier ("short int"),
+  tree_push_type_decl (get_identifier ("short int"),
 			      short_integer_type_node);
-  tree_push_atomic_type_decl (get_identifier ("short unsigned int"),
+  tree_push_type_decl (get_identifier ("short unsigned int"),
 			      short_unsigned_type_node);
-  tree_push_atomic_type_decl (get_identifier ("signed char"),
+  tree_push_type_decl (get_identifier ("signed char"),
 			      signed_char_type_node);
-  tree_push_atomic_type_decl (get_identifier ("unsigned char"),
+  tree_push_type_decl (get_identifier ("unsigned char"),
 			      unsigned_char_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, intQI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, intHI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, intSI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, intDI_type_node);
-#if HOST_BITS_PER_WIDE_INT >= 64
-  tree_push_atomic_type_decl (NULL_TREE, intTI_type_node);
-#endif
-  tree_push_atomic_type_decl (NULL_TREE, unsigned_intQI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, unsigned_intHI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, unsigned_intSI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, unsigned_intDI_type_node);
-#if HOST_BITS_PER_WIDE_INT >= 64
-  tree_push_atomic_type_decl (NULL_TREE, unsigned_intTI_type_node);
-#endif
-  
   size_type_node = make_unsigned_type (POINTER_SIZE);
-  tree_push_atomic_type_decl (get_identifier ("size_t"), size_type_node);
+  tree_push_type_decl (get_identifier ("size_t"), size_type_node);
   set_sizetype (size_type_node);
 
   build_common_tree_nodes_2 (/* short_double= */ 0);
 
-  tree_push_atomic_type_decl (get_identifier ("float"), float_type_node);
-  tree_push_atomic_type_decl (get_identifier ("double"), double_type_node);
-  tree_push_atomic_type_decl (get_identifier ("long double"), long_double_type_node);
-  tree_push_atomic_type_decl (get_identifier ("void"), void_type_node);
+  tree_push_type_decl (get_identifier ("float"), float_type_node);
+  tree_push_type_decl (get_identifier ("double"), double_type_node);
+  tree_push_type_decl (get_identifier ("long double"), long_double_type_node);
+  tree_push_type_decl (get_identifier ("void"), void_type_node);
 
   /* Add any target-specific builtin functions.  */
   (*targetm.init_builtins) ();
@@ -1348,7 +1248,7 @@
    copied from gcc/c-decl.c
 */
 
-tree
+static tree
 builtin_function (const char *name, tree type, int function_code,
 		  enum built_in_class class, const char *library_name,
 		  tree attrs)
@@ -1358,7 +1258,6 @@
   TREE_PUBLIC (decl) = 1;
   if (library_name)
     SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
-  make_decl_rtl (decl, NULL);
   pushdecl (decl);
   DECL_BUILT_IN_CLASS (decl) = class;
   DECL_FUNCTION_CODE (decl) = function_code;
@@ -1372,5 +1271,14 @@
   return decl;
 }
 
+/* Treelang expand function langhook.  */
+
+static void
+treelang_expand_function (tree fndecl)
+{
+  /* We have nothing special to do while expanding functions for treelang.  */
+  tree_rest_of_compilation (fndecl, 0);
+}
+
 #include "debug.h" /* for debug_hooks, needed by gt-treelang-treetree.h */
 #include "gt-treelang-treetree.h"
Index: treelang/treetree.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/treelang/treetree.h,v
retrieving revision 1.8
diff -u -u -r1.8 treetree.h
--- treelang/treetree.h	2 Jul 2003 20:15:46 -0000	1.8
+++ treelang/treetree.h	1 Aug 2004 21:05:13 -0000
@@ -3,7 +3,8 @@
     TREELANG Compiler definitions for interfacing to treetree.c
     (compiler back end interface).
 
-    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004
+    Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
@@ -55,7 +56,6 @@
 				location_t loc);
 void tree_code_output_expression_statement (tree code,
 					    location_t loc);
-tree get_type_for_numeric_type (unsigned int numeric_type);
 void tree_code_if_start (tree exp, location_t loc);
 void tree_code_if_else (location_t loc);
 void tree_code_if_end (location_t loc);

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