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]

[tree-ssa] source_location re-write


This is a port to the tree-ssa branch of the patch in:
http://gcc.gnu.org/ml/gcc-patches/2003-10/msg01200.html

It needs a litle more fine-tuning. For example some of the variable
names need updating. There are still a small number of testsuite regressions that need to be investigated. Someone with more knowledge
of the the rtl code could probably do a better job. Most critically,
this is a C-only patch so far.


One advantage of this change is simplification and making the
main parts of the compiler more consistent with cpplib.  It should
also be a performance improvement.  It reduces the space needed by
a decl by 32 bits (128 bits on a 64-bit system due to alignment),
and avoids the need to ggc-allocate a location_t for each expression.
Column numbers can be accomodated without increasing the space
needed for source_location.  Plus it has some advantages for the compile
server (which otherwise has to add a cpp_fragment pointer into
each decl).

The rather coarse tools I have for measuring compile-time makes it
difficult to determine the compile-speed difference. I.e. the
difference due to this change is less than the variability between
runs. The numbers below show the times for 3 runs each re-compiling
15 gcc source files with CFLAGS='-g -O2' using respectively the system compiler, the unmodified tree-ssa branch, and tree-ssa with this patch.
It suggests a small small but significant improvement in user time.


gcc is hashed (/usr/bin/gcc)
3.3.2 20031022 (Red Hat Linux 3.3.2-1)
real    0m16.862s  user    0m16.170s  sys     0m0.580s
real    0m16.832s  user    0m16.120s  sys     0m0.680s
real    0m17.115s  user    0m16.270s  sys     0m0.530s

/home/bothner/GNU/gcc.ssa/configure  --enable-languages=c \
  --disable-checking --prefix=/home/bothner/GNU/install-gcc.ssa
gcc is /home/bothner/GNU/install-gcc.ssa/bin/gcc
3.5-tree-ssa 20031113 (merged 20031111)
real    0m19.929s  user    0m19.090s  sys     0m0.670s
real    0m21.443s  user    0m18.990s  sys     0m0.800s
real    0m19.917s  user    0m18.990s  sys     0m0.740s

/home/bothner/GNU/gcc.ssa-loc/configure  --enable-languages=c \
  --disable-checking --prefix=/home/bothner/GNU/install-gcc.ssa-loc
gcc is /home/bothner/GNU/install-gcc.ssa-loc/bin/gcc
3.5-tree-ssa 20031113 (merged 20031111)
real    0m20.771s  user    0m18.920s  sys     0m0.710s
real    0m19.761s  user    0m18.820s  sys     0m0.820s
real    0m19.707s  user    0m18.940s  sys     0m0.690s
--
	--Per Bothner
per@bothner.com   http://per.bothner.com/


Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.344.2.50
diff -u -p -r1.344.2.50 c-common.c
--- c-common.c	13 Nov 2003 02:37:34 -0000	1.344.2.50
+++ c-common.c	15 Nov 2003 20:18:30 -0000
@@ -752,7 +752,7 @@ static int constant_fits_type_p (tree, t
 typedef struct
 {
   int compstmt_count;
-  location_t locus;
+  source_location locus;
   int needs_warning;
   tree if_stmt;
 } if_elt;
@@ -1148,8 +1148,8 @@ fname_decl (unsigned int rid, tree id)
 	 beginning of the function and this line number will be wrong.
 	 To avoid this problem set the lineno to 0 here; that prevents
 	 it from appearing in the RTL.  */
-      int saved_lineno = input_line;
-      input_line = 0;
+      source_location saved_lineno = input_location;
+      input_location = 0;
 
       decl = (*make_fname_decl) (id, fname_vars[ix].pretty);
       if (last_tree != saved_last_tree)
@@ -1165,7 +1165,7 @@ fname_decl (unsigned int rid, tree id)
 						 saved_function_name_decls);
 	}
       *fname_vars[ix].decl = decl;
-      input_line = saved_lineno;
+      input_location = saved_lineno;
     }
   if (!ix && !current_function_decl)
     pedwarn ("%J'%D' is not defined outside of function scope", decl, decl);
@@ -4110,8 +4110,7 @@ c_do_switch_warnings (splay_tree cases, 
   if (!warn_switch && !warn_switch_enum && !warn_switch_default)
     return;
 
-  switch_locus.file = input_filename;
-  switch_locus.line = STMT_LINENO (switch_stmt);
+  switch_locus = STMT_SOURCE_LOCATION (switch_stmt);
   type = SWITCH_TYPE (switch_stmt);
 
   default_node = splay_tree_lookup (cases, (splay_tree_key) NULL);
@@ -5832,7 +5831,7 @@ c_walk_subtrees (tree *tp, int *walk_sub
   /* Set input_line here so we get the right instantiation context
      if we call instantiate_decl from inlinable_function_p.  */
   if (STATEMENT_CODE_P (code) && !STMT_LINENO_FOR_FN_P (*tp))
-    input_line = STMT_LINENO (*tp);
+    input_location = STMT_SOURCE_LOCATION (*tp);
 
   if (code == DECL_STMT)
     {
@@ -6014,14 +6013,15 @@ c_warn_unused_result (tree *top_p)
 
       if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
 	{
+	  source_location loc = EXPR_LOCATION (t);
 	  if (fdecl)
 	    warning ("%Hignoring return value of `%D', "
 		     "declared with attribute warn_unused_result",
-		     EXPR_LOCUS (t), fdecl);
+		     &loc, fdecl);
 	  else
 	    warning ("%Hignoring return value of function "
 		     "declared with attribute warn_unused_result",
-		     EXPR_LOCUS (t));
+		     &loc);
 	}
       break;
 
Index: c-common.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.def,v
retrieving revision 1.11.2.4
diff -u -p -r1.11.2.4 c-common.def
--- c-common.def	7 May 2003 13:27:31 -0000	1.11.2.4
+++ c-common.def	15 Nov 2003 20:18:30 -0000
@@ -89,10 +89,6 @@ DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 
    variables declared in this scope.  */
 DEFTREECODE (SCOPE_STMT, "scope_stmt", 'e', 1)
 
-/* A FILE_STMT marks the spot where a function changes files.  It has no
-   other semantics.  FILE_STMT_FILENAME gives the name.  */
-DEFTREECODE (FILE_STMT, "file_stmt", 'e', 1)
-
 /* Used to represent a CASE_LABEL. The operands are CASE_LOW and
    CASE_HIGH, respectively. If CASE_LOW is NULL_TREE, the label is a
    'default' label. If CASE_HIGH is NULL_TREE, the label is a normal case
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.141.2.38
diff -u -p -r1.141.2.38 c-common.h
--- c-common.h	12 Nov 2003 02:51:23 -0000	1.141.2.38
+++ c-common.h	15 Nov 2003 20:18:30 -0000
@@ -1109,20 +1109,14 @@ extern void finish_file	(void);
 #define CLEANUP_EXPR(NODE) \
   TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 1)
 
-/* The filename we are changing to as of this FILE_STMT.  */
-#define FILE_STMT_FILENAME_NODE(NODE) \
-  (TREE_OPERAND (FILE_STMT_CHECK (NODE), 0))
-#define FILE_STMT_FILENAME(NODE) \
-  (IDENTIFIER_POINTER (FILE_STMT_FILENAME_NODE (NODE)))
-
 /* The line-number at which a statement began.  But if
    STMT_LINENO_FOR_FN_P does holds, then this macro gives the
    line number for the end of the current function instead.  */
-#define STMT_LINENO(NODE)			\
+#define STMT_SOURCE_LOCATION(NODE)			\
   (TREE_COMPLEXITY ((NODE)))
 
-/* If nonzero, the STMT_LINENO for NODE is the line at which the
-   function ended.  */
+/* If nonzero, the STMT_SOURCE_LOCATION for NODE is the line
+   at which the function ended.  */
 #define STMT_LINENO_FOR_FN_P(NODE)		\
   (TREE_LANG_FLAG_2 ((NODE)))
 
@@ -1146,7 +1140,7 @@ enum c_tree_code {
    WHILE_STMT,		DO_STMT,	RETURN_STMT,	\
    BREAK_STMT,		CONTINUE_STMT,	SCOPE_STMT,	\
    SWITCH_STMT,		GOTO_STMT,	LABEL_STMT,	\
-   ASM_STMT,		FILE_STMT,	CASE_LABEL
+   ASM_STMT,		CASE_LABEL
 
 /* TRUE if a code represents a statement.  The front end init
    langhook should take care of initialization of this array.  */
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.334.2.70
diff -u -p -r1.334.2.70 c-decl.c
--- c-decl.c	13 Nov 2003 02:37:35 -0000	1.334.2.70
+++ c-decl.c	15 Nov 2003 20:18:33 -0000
@@ -43,6 +43,8 @@ Software Foundation, 59 Temple Place - S
 #include "ggc.h"
 #include "tm_p.h"
 #include "cpplib.h"
+/* FIXME */
+#include "cpphash.h"
 #include "target.h"
 #include "debug.h"
 #include "opts.h"
@@ -1631,7 +1633,7 @@ warn_if_shadowing (tree x, tree old)
 static void
 clone_underlying_type (tree x)
 {
-  if (DECL_SOURCE_LINE (x) == 0)
+  if (DECL_SOURCE_LOCATION (x) <= 1)
     {
       if (TYPE_NAME (TREE_TYPE (x)) == 0)
 	TYPE_NAME (TREE_TYPE (x)) = x;
@@ -2267,8 +2269,8 @@ c_init_decl_processing (void)
   /* Declarations from c_common_nodes_and_builtins must not be associated
      with this input file, lest we get differences between using and not
      using preprocessed headers.  */
-  input_location.file = "<internal>";
-  input_location.line = 0;
+  linemap_add (&line_table, LC_ENTER, 0, parse_in->line, "<internal>", 0);
+  input_location = parse_in->line++;
 
   /* Make the DECL for the toplevel file scope.  */
   current_file_decl = build_decl (TRANSLATION_UNIT_DECL, NULL, NULL);
@@ -2301,6 +2303,7 @@ c_init_decl_processing (void)
 
   first_builtin_decl = global_scope->names;
   last_builtin_decl = global_scope->names_last;
+  linemap_add (&line_table, LC_LEAVE, 0, parse_in->line, NULL, 0);
 }
 
 /* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
Index: c-dump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-dump.c,v
retrieving revision 1.13.2.5
diff -u -p -r1.13.2.5 c-dump.c
--- c-dump.c	21 Jul 2003 13:50:25 -0000	1.13.2.5
+++ c-dump.c	15 Nov 2003 20:18:33 -0000
@@ -32,7 +32,7 @@ Software Foundation, 59 Temple Place - S
 void
 dump_stmt (dump_info_p di, tree t)
 {
-  dump_int (di, "line", STMT_LINENO (t));
+  dump_int (di, "line", LOCATION_LINE (STMT_SOURCE_LOCATION (t)));
 }
 
 /* Dump the next statement after STMT.  */
Index: c-lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lex.c,v
retrieving revision 1.182.2.16
diff -u -p -r1.182.2.16 c-lex.c
--- c-lex.c	6 Oct 2003 17:36:12 -0000	1.182.2.16
+++ c-lex.c	15 Nov 2003 20:18:33 -0000
@@ -199,7 +199,7 @@ cb_line_change (cpp_reader *pfile ATTRIB
   if (token->type == CPP_EOF || parsing_args)
     return;
 
-  input_line = SOURCE_LINE (map, token->line);
+  input_location = token->line;
 }
 
 static void
@@ -226,11 +226,9 @@ fe_file_change (const struct line_map *n
 	main_input_filename = new_map->to_file;
       else
 	{
-          int included_at = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
-
-	  input_line = included_at;
-	  push_srcloc (new_map->to_file, 1);
-	  (*debug_hooks->start_source_file) (included_at, new_map->to_file);
+	  input_location = new_map->from_line - 1;
+	  push_srcloc (input_location);
+	  (*debug_hooks->start_source_file) (input_line, new_map->to_file);
 #ifndef NO_IMPLICIT_EXTERN_C
 	  if (c_header_level)
 	    ++c_header_level;
@@ -259,8 +257,8 @@ fe_file_change (const struct line_map *n
 
   update_header_times (new_map->to_file);
   in_system_header = new_map->sysp != 0;
-  input_filename = new_map->to_file;
-  input_line = new_map->to_line;
+  input_location = new_map->from_line;
+
   map = new_map;
 
   /* Hook for C++.  */
@@ -288,7 +286,7 @@ cb_def_pragma (cpp_reader *pfile, unsign
 	    name = cpp_token_as_text (pfile, s);
 	}
 
-      input_line = SOURCE_LINE (map, line);
+      input_location = line;
       warning ("ignoring #pragma %s %s", space, name);
     }
 }
Index: c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.7.2.23
diff -u -p -r1.7.2.23 c-opts.c
--- c-opts.c	13 Nov 2003 02:37:36 -0000	1.7.2.23
+++ c-opts.c	15 Nov 2003 20:18:33 -0000
@@ -46,7 +46,7 @@ Software Foundation, 59 Temple Place - S
 # define TARGET_SYSTEM_ROOT NULL
 #endif
 
-static int saved_lineno;
+static source_location saved_location;
 
 /* CPP's options.  */
 static cpp_options *cpp_opts;
@@ -203,7 +203,7 @@ c_common_init_options (unsigned int argc
     }
 
   parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89,
-				ident_hash);
+				ident_hash, &line_table);
 
   cpp_opts = cpp_get_options (parse_in);
   cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
@@ -1141,14 +1141,14 @@ c_common_post_options (const char **pfil
       init_c_lex ();
 
       /* Yuk.  WTF is this?  I do know ObjC relies on it somewhere.  */
-      input_line = 0;
+      input_location = 0;
     }
 
   cpp_get_callbacks (parse_in)->file_change = cb_file_change;
   cpp_post_options (parse_in);
 
-  saved_lineno = input_line;
-  input_line = 0;
+  saved_location = input_location;
+  input_location = 0;
 
   /* If an error has occurred in cpplib, note it so we fail
      immediately.  */
@@ -1161,7 +1161,7 @@ c_common_post_options (const char **pfil
 bool
 c_common_init (void)
 {
-  input_line = saved_lineno;
+  input_location = saved_location;
 
   /* Set up preprocessor arithmetic.  Must be done after call to
      c_common_nodes_and_builtins for type nodes to be good.  */
Index: c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.144.2.23
diff -u -p -r1.144.2.23 c-parse.in
--- c-parse.in	28 Oct 2003 14:56:10 -0000	1.144.2.23
+++ c-parse.in	15 Nov 2003 20:18:34 -0000
@@ -2179,7 +2179,7 @@ simple_if:
 
 if_prefix:
 	  /* We must build the IF_STMT node before parsing its
-	     condition so that STMT_LINENO refers to the line
+	     condition so that STMT_SOURCE_LOCATION refers to the line
 	     containing the "if", and not the line containing
 	     the close-parenthesis.
 
@@ -2241,7 +2241,7 @@ lineno_stmt:
 	  save_location stmt
 		{ if ($2)
 		    {
-		      STMT_LINENO ($2) = $1.line;
+		      STMT_SOURCE_LOCATION ($2) = $1;
 		      /* ??? We currently have no way of recording
 			 the filename for a statement.  This probably
 			 matters little in practice at the moment,
@@ -2255,7 +2255,7 @@ lineno_label:
 	  save_location label
 		{ if ($2)
 		    {
-		      STMT_LINENO ($2) = $1.line;
+		      STMT_SOURCE_LOCATION ($2) = $1;
 		    }
 		}
 	;
@@ -2284,7 +2284,7 @@ select_or_iter_stmt:
 	| simple_if ELSE error
 		{ c_expand_end_cond (); }
        /* We must build the WHILE_STMT node before parsing its
-	  condition so that STMT_LINENO refers to the line
+	  condition so that STMT_SOURCE_LOCATION refers to the line
 	  containing the "while", and not the line containing
 	  the close-parenthesis.
 
Index: c-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pretty-print.c,v
retrieving revision 1.1.4.37
diff -u -p -r1.1.4.37 c-pretty-print.c
--- c-pretty-print.c	18 Oct 2003 23:59:36 -0000	1.1.4.37
+++ c-pretty-print.c	15 Nov 2003 20:18:35 -0000
@@ -2126,6 +2126,7 @@ pp_c_statement (c_pretty_printer *pp, tr
       }
       break;
 
+#if 0
     case FILE_STMT:
       pp_c_identifier (pp, "__FILE__");
       pp_space (pp);
@@ -2135,6 +2136,7 @@ pp_c_statement (c_pretty_printer *pp, tr
       pp_c_semicolon (pp);
       pp_needs_newline (pp) = true;
       break;
+#endif
 
     default:
       pp_unsupported_tree (pp, stmt);
Index: c-semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-semantics.c,v
retrieving revision 1.43.2.26
diff -u -p -r1.43.2.26 c-semantics.c
--- c-semantics.c	12 Nov 2003 02:51:23 -0000	1.43.2.26
+++ c-semantics.c	15 Nov 2003 20:18:35 -0000
@@ -73,7 +73,6 @@ begin_stmt_tree (tree *t)
   *t = build_nt (EXPR_STMT, void_zero_node);
   last_tree = *t;
   last_expr_type = NULL_TREE;
-  last_expr_filename = input_filename;
 }
 
 /* T is a statement.  Add it to the statement-tree.  */
@@ -81,19 +80,6 @@ begin_stmt_tree (tree *t)
 tree
 add_stmt (tree t)
 {
-  if (input_filename != last_expr_filename)
-    {
-      /* If the filename has changed, also add in a FILE_STMT.  Do a string
-	 compare first, though, as it might be an equivalent string.  */
-      int add = (strcmp (input_filename, last_expr_filename) != 0);
-      last_expr_filename = input_filename;
-      if (add)
-	{
-	  tree pos = build_nt (FILE_STMT, get_identifier (input_filename));
-	  add_stmt (pos);
-	}
-    }
-
   /* Add T to the statement-tree.  */
   TREE_CHAIN (last_tree) = t;
   last_tree = t;
@@ -176,14 +162,14 @@ finish_stmt_tree (tree *t)
     {
       /* The line-number recorded in the outermost statement in a function
 	 is the line number of the end of the function.  */
-      STMT_LINENO (stmt) = input_line;
+      STMT_SOURCE_LOCATION (stmt) = input_location;
       STMT_LINENO_FOR_FN_P (stmt) = 1;
     }
 }
 
 /* Build a generic statement based on the given type of node and
    arguments. Similar to `build_nt', except that we set
-   STMT_LINENO to be the current line number.  */
+   STMT_SOURCE_LOCATION to the current line number.  */
 /* ??? This should be obsolete with the lineno_stmt productions
    in the grammar.  */
 
@@ -199,7 +185,7 @@ build_stmt (enum tree_code code, ...)
 
   ret = make_node (code);
   length = TREE_CODE_LENGTH (code);
-  STMT_LINENO (ret) = input_line;
+  STMT_SOURCE_LOCATION (ret) = input_location;
 
   /* Most statements have implicit side effects all on their own, 
      such as control transfer.  For those that do, we'll compute
@@ -781,7 +767,7 @@ void
 prep_stmt (tree t)
 {
   if (!STMT_LINENO_FOR_FN_P (t))
-    input_line = STMT_LINENO (t);
+    input_location = STMT_SOURCE_LOCATION (t);
   current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
 }
 
@@ -801,10 +787,6 @@ expand_stmt (tree t)
 
       switch (TREE_CODE (t))
 	{
-	case FILE_STMT:
-	  input_filename = FILE_STMT_FILENAME (t);
-	  break;
-
 	case RETURN_STMT:
 	  genrtl_return_stmt (t);
 	  t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
@@ -1013,7 +995,7 @@ expand_unreachable_stmt (tree t, int war
 	  case IF_STMT:
 	  case RETURN_STMT:
 	    if (!STMT_LINENO_FOR_FN_P (t))
-	      input_line = STMT_LINENO (t);
+	      input_location = STMT_SOURCE_LOCATION (t);
 	    warning("will never be executed");
 	    warn = false;
 	    break;
@@ -1027,10 +1009,6 @@ expand_unreachable_stmt (tree t, int war
 	case GOTO_STMT:
 	case CONTINUE_STMT:
 	case BREAK_STMT:
-	  break;
-
-	case FILE_STMT:
-	  input_filename = FILE_STMT_FILENAME (t);
 	  break;
 
 	case RETURN_STMT:
Index: c-simplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/c-simplify.c,v
retrieving revision 1.1.4.83
diff -u -p -r1.1.4.83 c-simplify.c
--- c-simplify.c	12 Nov 2003 22:06:24 -0000	1.1.4.83
+++ c-simplify.c	15 Nov 2003 20:18:35 -0000
@@ -289,10 +289,6 @@ c_gimplify_stmt (tree *stmt_p)
 	  }
 	  break;
 
-	case FILE_STMT:
-	  input_filename = FILE_STMT_FILENAME (stmt);
-	  goto cont;
-
 	default:
 	  if (lang_gimplify_stmt && (*lang_gimplify_stmt) (&stmt, &next))
 	    {
@@ -402,7 +398,7 @@ gimplify_block (tree *stmt_p, tree *next
   tree block;
   tree bind;
   int depth;
-  int stmt_lineno;
+  source_location stmt_location;
 
   if (!SCOPE_BEGIN_P (*stmt_p))
     {
@@ -434,7 +430,7 @@ gimplify_block (tree *stmt_p, tree *next
       if (SCOPE_STMT_BLOCK (*p) != block)
 	abort ();
 
-      stmt_lineno = STMT_LINENO (*p);
+      stmt_location = STMT_SOURCE_LOCATION (*p);
       *next_p = TREE_CHAIN (*p);
       *p = NULL_TREE;
     }
@@ -443,12 +439,12 @@ gimplify_block (tree *stmt_p, tree *next
       /* Can wind up mismatched with syntax errors.  */
       if (!errorcount && !sorrycount)
 	abort ();
-      stmt_lineno = input_line;
+      stmt_location = input_location;
     }
 
   bind = c_build_bind_expr (block, TREE_CHAIN (*stmt_p));
   *stmt_p = bind;
-  input_line = stmt_lineno;
+  input_location = stmt_location;
 
   return GS_OK;
 }
@@ -777,7 +773,7 @@ gimplify_switch_stmt (tree *stmt_p)
 
   *stmt_p = build (SWITCH_EXPR, SWITCH_TYPE (stmt), SWITCH_COND (stmt),
 		   body, NULL_TREE);
-  annotate_with_locus (*stmt_p, stmt_locus);
+  SET_EXPR_LOCATION (*stmt_p, stmt_locus);
   gimplify_stmt (stmt_p);
 
   *stmt_p = finish_bc_block (break_block, *stmt_p);
@@ -966,9 +962,7 @@ gimplify_stmt_expr (tree *expr_p)
 	  || (TREE_TYPE (last_stmt)
 	      && VOID_TYPE_P (TREE_TYPE (last_stmt))))
 	{
-	  location_t loc;
-	  loc.file = input_filename;
-	  loc.line = STMT_LINENO (last_stmt);
+	  source_location loc = STMT_SOURCE_LOCATION (last_stmt);
 	  warning ("%Hstatement-expressions should end with a "
 		   "non-void expression", &loc);
 	  last_expr = NULL_TREE;
Index: cfglayout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfglayout.c,v
retrieving revision 1.19.2.14
diff -u -p -r1.19.2.14 cfglayout.c
--- cfglayout.c	26 Oct 2003 18:16:53 -0000	1.19.2.14
+++ cfglayout.c	15 Nov 2003 20:18:36 -0000
@@ -325,10 +325,7 @@ insn_locators_initialize (void)
 	      break;
 	    default:
 	      if (NOTE_LINE_NUMBER (insn) > 0)
-		{
-		  line_number = NOTE_LINE_NUMBER (insn);
-		  file_name = (char *)NOTE_SOURCE_FILE (insn);
-		}
+		input_location = NOTE_SOURCE_LOCATION (insn);
 	      break;
 	    }
 	}
Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgrtl.c,v
retrieving revision 1.57.2.18
diff -u -p -r1.57.2.18 cfgrtl.c
--- cfgrtl.c	13 Nov 2003 02:37:37 -0000	1.57.2.18
+++ cfgrtl.c	15 Nov 2003 20:18:36 -0000
@@ -135,7 +135,7 @@ delete_insn (rtx insn)
 	  really_delete = false;
 	  PUT_CODE (insn, NOTE);
 	  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED_LABEL;
-	  NOTE_SOURCE_FILE (insn) = name;
+	  NOTE_DELETED_LABEL_NAME (insn) = name;
 	}
 
       remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.299.2.29
diff -u -p -r1.299.2.29 combine.c
--- combine.c	18 Oct 2003 23:59:37 -0000	1.299.2.29
+++ combine.c	15 Nov 2003 20:18:41 -0000
@@ -2619,7 +2619,6 @@ try_combine (rtx i3, rtx i2, rtx i1, int
       {
 	PUT_CODE (i2, NOTE);
 	NOTE_LINE_NUMBER (i2) = NOTE_INSN_DELETED;
-	NOTE_SOURCE_FILE (i2) = 0;
       }
 
     if (i1)
@@ -2628,7 +2627,6 @@ try_combine (rtx i3, rtx i2, rtx i1, int
 	REG_NOTES (i1) = 0;
 	PUT_CODE (i1, NOTE);
 	NOTE_LINE_NUMBER (i1) = NOTE_INSN_DELETED;
-	NOTE_SOURCE_FILE (i1) = 0;
       }
 
     /* Get death notes for everything that is now used in either I3 or
@@ -12711,7 +12709,6 @@ distribute_notes (rtx notes, rtx from_in
 
 			  PUT_CODE (tem, NOTE);
 			  NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED;
-			  NOTE_SOURCE_FILE (tem) = 0;
 
 #ifdef HAVE_cc0
 			  /* Delete the setter too.  */
@@ -12727,7 +12724,6 @@ distribute_notes (rtx notes, rtx from_in
 			      PUT_CODE (cc0_setter, NOTE);
 			      NOTE_LINE_NUMBER (cc0_setter)
 				= NOTE_INSN_DELETED;
-			      NOTE_SOURCE_FILE (cc0_setter) = 0;
 			    }
 #endif
 			}
Index: cpperror.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpperror.c,v
retrieving revision 1.60.2.9
diff -u -p -r1.60.2.9 cpperror.c
--- cpperror.c	13 Nov 2003 02:37:47 -0000	1.60.2.9
+++ cpperror.c	15 Nov 2003 20:18:41 -0000
@@ -45,8 +45,8 @@ print_location (cpp_reader *pfile, filel
       const struct line_map *map;
       unsigned int lin;
 
-      map = linemap_lookup (&pfile->line_maps, line);
-      linemap_print_containing_files (&pfile->line_maps, map);
+      map = linemap_lookup (pfile->line_table, line);
+      linemap_print_containing_files (pfile->line_table, map);
 
       lin = SOURCE_LINE (map, line);
       if (col == 0)
Index: cppfiles.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppfiles.c,v
retrieving revision 1.150.2.18
diff -u -p -r1.150.2.18 cppfiles.c
--- cppfiles.c	13 Nov 2003 02:37:49 -0000	1.150.2.18
+++ cppfiles.c	15 Nov 2003 20:18:41 -0000
@@ -1216,7 +1216,7 @@ validate_pch (cpp_reader *pfile, _cpp_fi
       if (CPP_OPTION (pfile, print_include_names))
 	{
 	  unsigned int i;
-	  for (i = 1; i < pfile->line_maps.depth; i++)
+	  for (i = 1; i < pfile->line_table->depth; i++)
 	    putc ('.', stderr);
 	  fprintf (stderr, "%c %s\n",
 		   valid ? '!' : 'x', pchname);
Index: cpphash.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpphash.h,v
retrieving revision 1.166.2.17
diff -u -p -r1.166.2.17 cpphash.h
--- cpphash.h	6 Oct 2003 17:36:24 -0000	1.166.2.17
+++ cpphash.h	15 Nov 2003 20:18:41 -0000
@@ -330,7 +330,7 @@ struct cpp_reader
   struct lexer_state state;
 
   /* Source line tracking.  */
-  struct line_maps line_maps;
+  struct line_maps *line_table;
   const struct line_map *map;
   fileline line;
 
Index: cppinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppinit.c,v
retrieving revision 1.242.2.26
diff -u -p -r1.242.2.26 cppinit.c
--- cppinit.c	13 Nov 2003 02:37:49 -0000	1.242.2.26
+++ cppinit.c	15 Nov 2003 20:18:42 -0000
@@ -124,7 +124,8 @@ init_library (void)
 
 /* Initialize a cpp_reader structure.  */
 cpp_reader *
-cpp_create_reader (enum c_lang lang, hash_table *table)
+cpp_create_reader (enum c_lang lang, hash_table *table,
+		   struct line_maps *line_table)
 {
   cpp_reader *pfile;
 
@@ -169,7 +170,7 @@ cpp_create_reader (enum c_lang lang, has
 
   /* Initialize the line map.  Start at logical line 1, so we can use
      a line number of zero for special states.  */
-  linemap_init (&pfile->line_maps);
+  pfile->line_table = line_table;
   pfile->line = 1;
 
   /* Initialize lexer state.  */
@@ -259,7 +260,6 @@ cpp_destroy (cpp_reader *pfile)
       free (context);
     }
 
-  linemap_free (&pfile->line_maps);
   free (pfile);
 }
 
@@ -498,7 +498,7 @@ cpp_push_main_file (cpp_reader *pfile)
   /* Set this here so the client can change the option if it wishes,
      and after stacking the main file so we don't trace the main
      file.  */
-  pfile->line_maps.trace_includes = CPP_OPTION (pfile, print_include_names);
+  pfile->line_table->trace_includes = CPP_OPTION (pfile, print_include_names);
 }
 
 /* For preprocessed files, if the first tokens are of the form # NUM.
Index: cpplib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.c,v
retrieving revision 1.311.2.21
diff -u -p -r1.311.2.21 cpplib.c
--- cpplib.c	13 Nov 2003 02:37:49 -0000	1.311.2.21
+++ cpplib.c	15 Nov 2003 20:18:42 -0000
@@ -674,7 +674,7 @@ do_include_common (cpp_reader *pfile, en
     return;
 
   /* Prevent #include recursion.  */
-  if (pfile->line_maps.depth >= CPP_STACK_MAX)
+  if (pfile->line_table->depth >= CPP_STACK_MAX)
     cpp_error (pfile, CPP_DL_ERROR, "#include nested too deeply");
   else
     {
@@ -893,7 +893,7 @@ _cpp_do_file_change (cpp_reader *pfile, 
 		     const char *to_file, unsigned int file_line,
 		     unsigned int sysp)
 {
-  pfile->map = linemap_add (&pfile->line_maps, reason, sysp,
+  pfile->map = linemap_add (pfile->line_table, reason, sysp,
 			    pfile->line, to_file, file_line);
 
   if (pfile->cb.file_change)
@@ -1900,7 +1900,7 @@ cpp_get_callbacks (cpp_reader *pfile)
 const struct line_maps *
 cpp_get_line_maps (cpp_reader *pfile)
 {
-  return &pfile->line_maps;
+  return pfile->line_table;
 }
 
 /* Copy the given callbacks structure to our own.  */
Index: cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.h,v
retrieving revision 1.224.2.20
diff -u -p -r1.224.2.20 cpplib.h
--- cpplib.h	13 Nov 2003 02:37:50 -0000	1.224.2.20
+++ cpplib.h	15 Nov 2003 20:18:42 -0000
@@ -507,7 +507,8 @@ struct cpp_hashnode GTY(())
    pointer.  Otherwise you should pass in an initialized hash table
    that cpplib will share; this technique is used by the C front
    ends.  */
-extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *);
+extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *,
+				      struct line_maps *);
 
 /* Call this to change the selected language standard (e.g. because of
    command line options).  */
Index: cppmacro.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppmacro.c,v
retrieving revision 1.115.2.17
diff -u -p -r1.115.2.17 cppmacro.c
--- cppmacro.c	13 Nov 2003 02:37:50 -0000	1.115.2.17
+++ cppmacro.c	15 Nov 2003 20:18:43 -0000
@@ -80,7 +80,7 @@ _cpp_warn_if_unused_macro (cpp_reader *p
       cpp_macro *macro = node->value.macro;
 
       if (!macro->used
-	  && MAIN_FILE_P (linemap_lookup (&pfile->line_maps, macro->line)))
+	  && MAIN_FILE_P (linemap_lookup (pfile->line_table, macro->line)))
 	cpp_error_with_line (pfile, CPP_DL_WARNING, macro->line, 0,
 			     "macro \"%s\" is not used", NODE_NAME (node));
     }
@@ -136,7 +136,7 @@ _cpp_builtin_macro_text (cpp_reader *pfi
 
 	if (node->value.builtin == BT_BASE_FILE)
 	  while (! MAIN_FILE_P (map))
-	    map = INCLUDED_FROM (&pfile->line_maps, map);
+	    map = INCLUDED_FROM (pfile->line_table, map);
 
 	name = map->to_file;
 	len = strlen (name);
@@ -153,7 +153,7 @@ _cpp_builtin_macro_text (cpp_reader *pfi
       /* The line map depth counts the primary source as level 1, but
 	 historically __INCLUDE_DEPTH__ has called the primary source
 	 level 0.  */
-      number = pfile->line_maps.depth - 1;
+      number = pfile->line_table->depth - 1;
       break;
 
     case BT_SPECLINE:
Index: diagnostic.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/diagnostic.c,v
retrieving revision 1.91.2.25
diff -u -p -r1.91.2.25 diagnostic.c
--- diagnostic.c	28 Sep 2003 06:06:17 -0000	1.91.2.25
+++ diagnostic.c	15 Nov 2003 20:18:43 -0000
@@ -173,13 +173,13 @@ diagnostic_build_prefix (diagnostic_info
 #undef DEFINE_DIAGNOSTIC_KIND
     "must-not-happen"
   };
-   if (diagnostic->kind >= DK_LAST_DIAGNOSTIC_KIND)
-     abort();
+  struct location_s s = get_location_s (diagnostic->location);
+  if (diagnostic->kind >= DK_LAST_DIAGNOSTIC_KIND)
+    abort();
 
-  return diagnostic->location.file
+  return s.file
     ? build_message_string ("%s:%d: %s",
-                            diagnostic->location.file,
-                            diagnostic->location.line,
+                            s.file, s.line,
                             _(diagnostic_kind_text[diagnostic->kind]))
     : build_message_string ("%s: %s", progname,
                             _(diagnostic_kind_text[diagnostic->kind]));
@@ -206,8 +206,9 @@ diagnostic_count_diagnostic (diagnostic_
 	   || diagnostic_kind_count (context, DK_SORRY) > 0)
 	  && !context->abort_on_error)
 	{
+	  struct location_s s = get_location_s (diagnostic->location);
 	  fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
-		   diagnostic->location.file, diagnostic->location.line);
+		   s.file, s.line);
 	  exit (FATAL_EXIT_CODE);
 	}
 #endif
@@ -300,8 +301,6 @@ diagnostic_report_current_function (diag
 void
 diagnostic_report_current_module (diagnostic_context *context)
 {
-  struct file_stack *p;
-
   if (pp_needs_newline (context->printer))
     {
       pp_newline (context->printer);
@@ -310,14 +309,18 @@ diagnostic_report_current_module (diagno
 
   if (input_file_stack && diagnostic_last_module_changed (context))
     {
-      p = input_file_stack;
+      struct file_stack *p = input_file_stack;
+      const struct line_map *map = linemap_lookup (&line_table, p->location);
       pp_verbatim (context->printer,
                    "In file included from %s:%d",
-                   p->location.file, p->location.line);
+                   map->to_file, SOURCE_LINE (map, p->location));
       while ((p = p->next) != NULL)
-	pp_verbatim (context->printer,
-                     ",\n                 from %s:%d",
-                     p->location.file, p->location.line);
+	{
+	  map = linemap_lookup (&line_table, p->location);
+	  pp_verbatim (context->printer,
+		       ",\n                 from %s:%d",
+		       map->to_file, SOURCE_LINE (map, p->location));
+	}
       pp_verbatim (context->printer, ":\n");
       diagnostic_set_last_module (context);
     }
Index: diagnostic.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/diagnostic.h,v
retrieving revision 1.44.2.24
diff -u -p -r1.44.2.24 diagnostic.h
--- diagnostic.h	11 Nov 2003 18:04:46 -0000	1.44.2.24
+++ diagnostic.h	15 Nov 2003 20:18:43 -0000
@@ -39,7 +39,7 @@ typedef enum
 typedef struct
 {
   text_info message;
-  location_t location;
+  source_location location;
   /* The kind of diagnostic it is about.  */
   diagnostic_t kind;
 } diagnostic_info;
@@ -175,7 +175,7 @@ extern void diagnostic_report_current_fu
 extern void diagnostic_report_diagnostic (diagnostic_context *,
 					  diagnostic_info *);
 extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *,
-				 location_t, diagnostic_t);
+				 source_location, diagnostic_t);
 extern char *diagnostic_build_prefix (diagnostic_info *);
 
 /* Pure text formatting support functions.  */
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.379.2.30
diff -u -p -r1.379.2.30 dwarf2out.c
--- dwarf2out.c	10 Nov 2003 23:47:46 -0000	1.379.2.30
+++ dwarf2out.c	15 Nov 2003 20:18:47 -0000
@@ -9902,10 +9902,11 @@ add_pure_or_virtual_attribute (dw_die_re
 static void
 add_src_coords_attributes (dw_die_ref die, tree decl)
 {
-  unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl));
+  struct location_s s = get_location_s (DECL_SOURCE_LOCATION (decl));
+  unsigned file_index = lookup_filename (s.file);
 
   add_AT_unsigned (die, DW_AT_decl_file, file_index);
-  add_AT_unsigned (die, DW_AT_decl_line, DECL_SOURCE_LINE (decl));
+  add_AT_unsigned (die, DW_AT_decl_line, s.line);
 }
 
 /* Add a DW_AT_name attribute and source coordinate attribute for the
Index: dwarfout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarfout.c,v
retrieving revision 1.111.2.19
diff -u -p -r1.111.2.19 dwarfout.c
--- dwarfout.c	18 Oct 2003 23:59:44 -0000	1.111.2.19
+++ dwarfout.c	15 Nov 2003 20:18:49 -0000
@@ -3392,7 +3392,8 @@ name_and_src_coords_attributes (tree dec
       name_attribute (IDENTIFIER_POINTER (decl_name));
 #ifdef DWARF_DECL_COORDINATES
       {
-	register unsigned file_index;
+	struct location_s s = get_location_s (DECL_SOURCE_LOCATION (decl));
+	unsigned file_index = lookup_filename (s.file);
 
 	/* This is annoying, but we have to pop out of the .debug section
 	   for a moment while we call `lookup_filename' because calling it
@@ -3405,10 +3406,9 @@ name_and_src_coords_attributes (tree dec
 	   Fred Fish sez that m68k/svr4 assemblers botch those.  */
 
 	ASM_OUTPUT_POP_SECTION (asm_out_file);
-	file_index = lookup_filename (DECL_SOURCE_FILE (decl));
 	ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SECTION);
 
-	src_coords_attribute (file_index, DECL_SOURCE_LINE (decl));
+	src_coords_attribute (file_index, s.line);
       }
 #endif /* defined(DWARF_DECL_COORDINATES) */
     }
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v
retrieving revision 1.280.2.24
diff -u -p -r1.280.2.24 emit-rtl.c
--- emit-rtl.c	13 Nov 2003 02:37:51 -0000	1.280.2.24
+++ emit-rtl.c	15 Nov 2003 20:18:50 -0000
@@ -4179,7 +4179,6 @@ emit_note_before (int subtype, rtx befor
 {
   rtx note = rtx_alloc (NOTE);
   INSN_UID (note) = cur_insn_uid++;
-  NOTE_SOURCE_FILE (note) = 0;
   NOTE_LINE_NUMBER (note) = subtype;
   BLOCK_FOR_INSN (note) = NULL;
 
@@ -4402,7 +4401,6 @@ emit_note_after (int subtype, rtx after)
 {
   rtx note = rtx_alloc (NOTE);
   INSN_UID (note) = cur_insn_uid++;
-  NOTE_SOURCE_FILE (note) = 0;
   NOTE_LINE_NUMBER (note) = subtype;
   BLOCK_FOR_INSN (note) = NULL;
   add_insn_after (note, after);
@@ -4665,11 +4663,21 @@ emit_line_note (location_t location)
   
   set_file_and_line_for_stmt (location);
   
-  if (location.file && last_location.file
-      && !strcmp (location.file, last_location.file)
-      && location.line == last_location.line)
+#if 1
+  if (location == last_location)
     return NULL_RTX;
   last_location = location;
+#else
+  const struct line_map *map = linemap_lookup (&line_table, location);
+  int line = SOURCE_LINE (map, p->location);
+  if (map && map->to_file && last_location_file
+      && !strcmp (map->to_file, last_location_file)
+      && line == last_location_line)
+    return NULL_RTX;
+  last_location = location;
+  last_location_file = map->to_file;
+  last_location_line = line;
+#endif
   
   if (no_line_numbers)
     {
@@ -4677,8 +4685,7 @@ emit_line_note (location_t location)
       return NULL_RTX;
     }
 
-  note = emit_note (location.line);
-  NOTE_SOURCE_FILE (note) = location.file;
+  note = emit_note ((int) location);
   
   return note;
 }
@@ -4730,7 +4737,7 @@ emit_note (int note_no)
 void
 force_next_line_note (void)
 {
-  last_location.line = -1;
+  last_location = -1;
 }
 
 /* Place a note of KIND on insn INSN with DATUM as the datum. If a
@@ -5197,8 +5204,7 @@ init_emit (void)
   seq_rtl_expr = NULL;
   cur_insn_uid = 1;
   reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
-  last_location.line = 0;
-  last_location.file = 0;
+  last_location = 0;
   first_label_num = label_num;
   last_label_num = 0;
   seq_stack = NULL;
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.63
diff -u -p -r1.467.2.63 expr.c
--- expr.c	13 Nov 2003 02:37:51 -0000	1.467.2.63
+++ expr.c	15 Nov 2003 20:18:54 -0000
@@ -242,9 +242,6 @@ enum insn_code clrstr_optab[NUM_MACHINE_
 enum insn_code cmpstr_optab[NUM_MACHINE_MODES];
 enum insn_code cmpmem_optab[NUM_MACHINE_MODES];
 
-/* Stack of EXPR_WITH_FILE_LOCATION nested expressions.  */
-struct file_stack *expr_wfl_stack;
-
 /* SLOW_UNALIGNED_ACCESS is nonzero if unaligned accesses are very slow.  */
 
 #ifndef SLOW_UNALIGNED_ACCESS
@@ -6277,13 +6274,13 @@ expand_expr (tree exp, rtx target, enum 
      information.  It would be better of the diagnostic routines 
      used the file/line information embedded in the tree nodes rather
      than globals.  */
-  if (cfun && EXPR_LOCUS (exp))
+  if (cfun && EXPR_LOCATION (exp))
     {
       location_t saved_location;
       rtx ret;
 
       saved_location = input_location;
-      input_location = *EXPR_LOCUS (exp);
+      input_location = EXPR_LOCATION (exp);
       emit_line_note (input_location);
 
       /* Record where the insns produced belong.  */
@@ -8433,9 +8430,9 @@ expand_expr_1 (tree exp, rtx target, enu
 	  for (; TREE_CODE (exp) == COND_EXPR; exp = TREE_OPERAND (exp, 2))
 	    {
 	      expand_start_else ();
-	      if (EXPR_LOCUS (exp))
+	      if (EXPR_LOCATION (exp))
 		{
-		  emit_line_note (*(EXPR_LOCUS (exp)));
+		  emit_line_note (EXPR_LOCATION (exp));
 		  if (cfun->dont_emit_block_notes)
 		    record_block_change (TREE_BLOCK (exp));
 		}
Index: final.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/final.c,v
retrieving revision 1.262.2.19
diff -u -p -r1.262.2.19 final.c
--- final.c	13 Nov 2003 02:37:53 -0000	1.262.2.19
+++ final.c	15 Nov 2003 20:18:55 -0000
@@ -1529,26 +1529,32 @@ final (rtx first, FILE *file, int optimi
       for (insn = first; insn; insn = NEXT_INSN (insn))
 	if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
 	  {
+	    int line;
+
 	    if ((RTX_INTEGRATED_P (insn)
 		 && strcmp (NOTE_SOURCE_FILE (insn), main_input_filename) != 0)
-		 || (last != 0
-		     && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
-		     && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last)))
+		|| (last != 0 /* FIXME */
+		    && NOTE_SOURCE_LOCATION (insn) == NOTE_SOURCE_LOCATION (last)))
 	      {
 		delete_insn (insn);	/* Use delete_note.  */
 		continue;
 	      }
 	    last = insn;
-	    if (NOTE_LINE_NUMBER (insn) > max_line)
-	      max_line = NOTE_LINE_NUMBER (insn);
+	    line = NOTE_SOURCE_LINE (insn);
+	    if (line > max_line)
+	      max_line = line;
 	  }
     }
   else
 #endif
     {
       for (insn = first; insn; insn = NEXT_INSN (insn))
-	if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > max_line)
-	  max_line = NOTE_LINE_NUMBER (insn);
+	if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
+	  {
+	    int line = NOTE_SOURCE_LINE (insn);
+	    if (line > max_line)
+	      max_line = line;
+	  }
     }
 
   line_note_exists = xcalloc (max_line + 1, sizeof (char));
@@ -1558,7 +1564,7 @@ final (rtx first, FILE *file, int optimi
       if (INSN_UID (insn) > max_uid)       /* Find largest UID.  */
 	max_uid = INSN_UID (insn);
       if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
-	line_note_exists[NOTE_LINE_NUMBER (insn)] = 1;
+	line_note_exists[NOTE_SOURCE_LINE (insn)] = 1;
 #ifdef HAVE_cc0
       /* If CC tracking across branches is enabled, record the insn which
 	 jumps to each branch only reached from one place.  */
Index: fix-header.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fix-header.c,v
retrieving revision 1.82.2.12
diff -u -p -r1.82.2.12 fix-header.c
--- fix-header.c	13 Nov 2003 02:37:53 -0000	1.82.2.12
+++ fix-header.c	15 Nov 2003 20:18:55 -0000
@@ -590,10 +590,12 @@ read_scan_file (char *in_fname, int argc
   struct fn_decl *fn;
   int i, strings_processed;
   struct symbol_list *cur_symbols;
+  struct line_maps line_table;
 
   obstack_init (&scan_file_obstack);
 
-  scan_in = cpp_create_reader (CLK_GNUC89, NULL);
+  linemap_init (&line_table);
+  scan_in = cpp_create_reader (CLK_GNUC89, NULL, &line_table);
   cb = cpp_get_callbacks (scan_in);
   cb->file_change = cb_file_change;
 
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.534.2.18
diff -u -p -r1.534.2.18 flow.c
--- flow.c	18 Oct 2003 23:59:45 -0000	1.534.2.18
+++ flow.c	15 Nov 2003 20:18:56 -0000
@@ -3374,7 +3374,6 @@ attempt_auto_inc (struct propagate_block
 
       PUT_CODE (incr, NOTE);
       NOTE_LINE_NUMBER (incr) = NOTE_INSN_DELETED;
-      NOTE_SOURCE_FILE (incr) = 0;
     }
 
   if (regno >= FIRST_PSEUDO_REGISTER)
Index: function.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.h,v
retrieving revision 1.83.2.17
diff -u -p -r1.83.2.17 function.h
--- function.h	4 Nov 2003 00:13:36 -0000	1.83.2.17
+++ function.h	15 Nov 2003 20:18:57 -0000
@@ -88,7 +88,7 @@ struct emit_status GTY(())
 
   /* Location the last line-number NOTE emitted.
      This is used to avoid generating duplicates.  */
-  location_t x_last_location;
+  source_location x_last_location;
 
   /* The length of the regno_pointer_align, regno_decl, and x_regno_reg_rtx
      vectors.  Since these vectors are needed during the expansion phase when
@@ -414,7 +414,7 @@ struct function GTY(())
   int max_jumptable_ents;
 
   /* Line number of the end of the function.  */
-  location_t function_end_locus;
+  source_location function_end_locus;
 
   /* Array mapping insn uids to blocks.  */
   struct varray_head_tag *ib_boundaries_block;
Index: gengtype.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gengtype.c,v
retrieving revision 1.7.4.23
diff -u -p -r1.7.4.23 gengtype.c
--- gengtype.c	28 Oct 2003 14:56:18 -0000	1.7.4.23
+++ gengtype.c	15 Nov 2003 20:18:57 -0000
@@ -2915,6 +2915,8 @@ main(int argc ATTRIBUTE_UNUSED, char **a
   do_scalar_typedef ("uint8", &pos);
   do_scalar_typedef ("jword", &pos);
   do_scalar_typedef ("JCF_u2", &pos);
+  do_scalar_typedef ("fileline", &pos);
+  do_scalar_typedef ("source_location", &pos);
 
   do_typedef ("PTR", create_pointer (create_scalar_type ("void",
 							 strlen ("void"))),
Index: gimple-low.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimple-low.c,v
retrieving revision 1.1.4.11
diff -u -p -r1.1.4.11 gimple-low.c
--- gimple-low.c	12 Nov 2003 22:06:25 -0000	1.1.4.11
+++ gimple-low.c	15 Nov 2003 20:18:58 -0000
@@ -95,7 +95,7 @@ lower_stmt (tree_stmt_iterator *tsi, str
 {
   tree stmt = tsi_stmt (*tsi);
 
-  if (EXPR_LOCUS (stmt))
+  if (EXPR_LOCATION (stmt))
     TREE_BLOCK (stmt) = data->block;
 
   switch (TREE_CODE (stmt))
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v
retrieving revision 1.1.2.112
diff -u -p -r1.1.2.112 gimplify.c
--- gimplify.c	13 Nov 2003 02:47:41 -0000	1.1.2.112
+++ gimplify.c	15 Nov 2003 20:18:59 -0000
@@ -453,10 +453,7 @@ internal_get_tmp_var (tree val, tree *pr
   mod = build (MODIFY_EXPR, TREE_TYPE (t), t, val);
 
   class = TREE_CODE_CLASS (TREE_CODE (val));
-  if (EXPR_LOCUS (val))
-    SET_EXPR_LOCUS (mod, EXPR_LOCUS (val));
-  else
-    annotate_with_locus (mod, input_location);
+  SET_EXPR_LOCATION (mod, EXPR_LOCATION (val));
   /* gimplify_modify_expr might want to reduce this further.  */
   gimplify_stmt (&mod);
   append_to_statement_list (mod, pre_p);
@@ -576,9 +573,9 @@ annotate_all_with_locus (tree *stmt_p, l
 #endif
 
       if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (t)))
-	  && ! EXPR_LOCUS (t)
+	  && ! EXPR_LOCATION (t)
 	  && should_carry_locus_p (t))
-	annotate_with_locus (t, locus);
+	SET_EXPR_LOCATION (t, locus);
     }
 }
 
@@ -1658,8 +1655,7 @@ gimplify_call_expr (tree *expr_p, tree *
 
   /* For reliable diagnostics during inlining, it is necessary that 
      every call_expr be annotated with file and line.  */
-  if (!EXPR_LOCUS (*expr_p))
-    annotate_with_locus (*expr_p, input_location);
+  SET_EXPR_LOCATION (*expr_p, input_location);
 
   /* This may be a call to a builtin function.
 
@@ -2764,7 +2760,6 @@ gimplify_expr (tree *expr_p, tree *pre_p
   tree internal_post = NULL_TREE;
   tree save_expr;
   int is_statement = (pre_p == NULL);
-  location_t *locus;
   location_t saved_location;
   enum gimplify_status ret;
 
@@ -2787,9 +2782,7 @@ gimplify_expr (tree *expr_p, tree *pre_p
     post_p = &internal_post;
 
   saved_location = input_location;
-  locus = EXPR_LOCUS (*expr_p);
-  if (locus)
-    input_location = *locus;
+  input_location = EXPR_LOCATION (*expr_p);
 
   /* Loop over the specific gimplifiers until the toplevel node remains the
      same.  */
Index: haifa-sched.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/haifa-sched.c,v
retrieving revision 1.210.2.16
diff -u -p -r1.210.2.16 haifa-sched.c
--- haifa-sched.c	21 Oct 2003 14:35:48 -0000	1.210.2.16
+++ haifa-sched.c	15 Nov 2003 20:18:59 -0000
@@ -1563,8 +1563,7 @@ restore_line_notes (rtx head, rtx tail)
 	     && (note = LINE_NOTE (insn)) != 0
 	     && note != line
 	     && (line == 0
-		 || NOTE_LINE_NUMBER (note) != NOTE_LINE_NUMBER (line)
-		 || NOTE_SOURCE_FILE (note) != NOTE_SOURCE_FILE (line)))
+		 || NOTE_SOURCE_LOCATION (note) != NOTE_SOURCE_LOCATION (line)))
       {
 	line = note;
 	prev = PREV_INSN (insn);
@@ -1581,7 +1580,6 @@ restore_line_notes (rtx head, rtx tail)
 	  {
 	    added_notes++;
 	    new = emit_note_after (NOTE_LINE_NUMBER (note), prev);
-	    NOTE_SOURCE_FILE (new) = NOTE_SOURCE_FILE (note);
 	    RTX_INTEGRATED_P (new) = RTX_INTEGRATED_P (note);
 	  }
       }
@@ -1610,16 +1608,13 @@ rm_redundant_line_notes (void)
 	if (active_insn == 0)
 	  {
 	    notes++;
-	    NOTE_SOURCE_FILE (insn) = 0;
 	    NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
 	  }
 	/* If the line number is unchanged, LINE is redundant.  */
 	else if (line
-		 && NOTE_LINE_NUMBER (line) == NOTE_LINE_NUMBER (insn)
-		 && NOTE_SOURCE_FILE (line) == NOTE_SOURCE_FILE (insn))
+		 && NOTE_SOURCE_LOCATION (line) == NOTE_SOURCE_LOCATION (insn))
 	  {
 	    notes++;
-	    NOTE_SOURCE_FILE (line) = 0;
 	    NOTE_LINE_NUMBER (line) = NOTE_INSN_DELETED;
 	    line = insn;
 	  }
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.95.2.20
diff -u -p -r1.95.2.20 ifcvt.c
--- ifcvt.c	13 Nov 2003 02:37:55 -0000	1.95.2.20
+++ ifcvt.c	15 Nov 2003 20:19:00 -0000
@@ -280,7 +280,6 @@ cond_exec_process_insns (ce_if_block_t *
 	     given what we'd have to coordinate with our callers.  */
 	  PUT_CODE (insn, NOTE);
 	  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
-	  NOTE_SOURCE_FILE (insn) = 0;
 	  goto insn_done;
 	}
 
Index: input.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/input.h,v
retrieving revision 1.8.2.4
diff -u -p -r1.8.2.4 input.h
--- input.h	28 Sep 2003 06:06:28 -0000	1.8.2.4
+++ input.h	15 Nov 2003 20:19:00 -0000
@@ -22,9 +22,11 @@ Software Foundation, 59 Temple Place - S
 #ifndef GCC_INPUT_H
 #define GCC_INPUT_H
 
-/* The data structure used to record a location in a translation unit.  */
-/* Long-term, we want to get rid of this and typedef fileline location_t.  */
-struct location_s GTY (())
+#include "line-map.h"
+typedef source_location location_t;
+extern struct line_maps line_table;
+
+struct location_s
 {
   /* The name of the source file involved.  */
   const char *file;
@@ -32,20 +34,82 @@ struct location_s GTY (())
   /* The line-location in the source file.  */
   int line;
 };
-typedef struct location_s location_t;
+
+#ifdef __GNUC__
+#define get_location_s(FILELINE) __extension__ ({ \
+  struct location_s __t; \
+  fileline __line = (FILELINE); \
+  if (__line == 0) { __t.file = NULL; __t.line = 0; } \
+  else { \
+    const struct line_map *__map = linemap_lookup (&line_table,__line);	\
+    __t.file = __map->to_file; \
+    __t.line = SOURCE_LINE (__map, __line); \
+  };\
+  __t; })
+#else
+static struct location_s
+get_location_s (fileline fline)
+{
+  struct location_s s;
+  if (__line == 0) { __t.file = NULL; __t.line = 0; }
+  else
+    {
+      const struct line_map *map = linemap_lookup (&line_table, fline);
+      s.file = map->to_file;
+      s.line = SOURCE_LINE (map, fline);
+    }
+  return s;
+}
+#endif
 
 struct file_stack
 {
   struct file_stack *next;
-  location_t location;
+  source_location location;
 };
 
 /* Top-level source file.  */
 extern const char *main_input_filename;
 
-extern location_t input_location;
-#define input_line (input_location.line)
-#define input_filename (input_location.file)
+extern source_location input_location;
+#ifdef __GNUC__
+#define LOCATION_FILE(FILELINE) __extension__ \
+ ({ fileline __line = (FILELINE); \
+    __line == 0 ? NULL \
+   : __extension__ ({ \
+       const struct line_map *__map = linemap_lookup (&line_table, __line); \
+      __map->to_file; }); })
+#define LOCATION_LINE(FILELINE) __extension__ \
+ ({ fileline __line = (FILELINE); \
+    __line == 0 ? 0 \
+   : __extension__ ({ \
+      const struct line_map *__map = linemap_lookup (&line_table, __line); \
+      SOURCE_LINE (__map, __line); }); })
+#else
+static const char *
+LOCATION_FILE(fileline fline)
+{
+  if (fline == 0) return NULL;
+  else
+    {
+      const struct line_map *map = linemap_lookup (&line_table, fline);
+      return map->to_file;
+    }
+}
+static int
+LOCATION_LINE(fileline fline)
+{
+  if (fline == 0) return 0;
+  else
+    {
+      const struct line_map *map = linemap_lookup (&line_table, fline);
+      return SOURCE_LINE (map, fline);
+    }
+}
+#endif
+
+#define input_line LOCATION_LINE(input_location)
+#define input_filename LOCATION_FILE(input_location)
 
 /* Stack of currently pending input files.
    The line member is not accurate for the innermost file on the stack.  */
@@ -54,7 +118,7 @@ extern struct file_stack *input_file_sta
 /* Incremented on each change to input_file_stack.  */
 extern int input_file_stack_tick;
 
-extern void push_srcloc (const char *name, int line);
+extern void push_srcloc (fileline);
 extern void pop_srcloc (void);
 
 #endif
Index: integrate.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/integrate.c,v
retrieving revision 1.197.2.28
diff -u -p -r1.197.2.28 integrate.c
--- integrate.c	28 Oct 2003 14:56:18 -0000	1.197.2.28
+++ integrate.c	15 Nov 2003 20:19:02 -0000
@@ -1641,7 +1641,8 @@ copy_insn_list (rtx insns, struct inline
 	    {
 	      copy = emit_label (get_label_from_map (map,
 						    CODE_LABEL_NUMBER (insn)));
-	      LABEL_NAME (copy) = NOTE_SOURCE_FILE (insn);
+	      /* FIXME - see delete_insn */
+	      LABEL_NAME (copy) = NOTE_DELETED_LABEL_NAME (insn);
 	      map->const_age++;
 	      break;
 	    }
@@ -2212,8 +2213,8 @@ copy_rtx_and_substitute (rtx orig, struc
 	  ASM_OPERANDS_INPUT_VEC (copy) = map->copy_asm_operands_vector;
 	  ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy)
 	    = map->copy_asm_constraints_vector;
-	  ASM_OPERANDS_SOURCE_FILE (copy) = ASM_OPERANDS_SOURCE_FILE (orig);
-	  ASM_OPERANDS_SOURCE_LINE (copy) = ASM_OPERANDS_SOURCE_LINE (orig);
+	  ASM_OPERANDS_SOURCE_LOCATION (copy)
+	    = ASM_OPERANDS_SOURCE_LOCATION (orig);
 	  return copy;
 	}
       break;
Index: jump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/jump.c,v
retrieving revision 1.210.2.16
diff -u -p -r1.210.2.16 jump.c
--- jump.c	20 Aug 2003 20:44:24 -0000	1.210.2.16
+++ jump.c	15 Nov 2003 20:19:02 -0000
@@ -193,8 +193,7 @@ purge_line_number_notes (rtx f)
 	  {
 	    /* Delete this note if it is identical to previous note.  */
 	    if (last_note
-		&& NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last_note)
-		&& NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last_note))
+		&& NOTE_SOURCE_LOCATION (insn) == NOTE_SOURCE_LOCATION (last_note))
 	      {
 		delete_related_insns (insn);
 		continue;
@@ -406,10 +405,7 @@ duplicate_loop_exit_test (rtx loop_start
 	case NOTE:
 	  /* Only copy line-number notes.  */
 	  if (NOTE_LINE_NUMBER (insn) >= 0)
-	    {
-	      copy = emit_note_before (NOTE_LINE_NUMBER (insn), loop_start);
-	      NOTE_SOURCE_FILE (copy) = NOTE_SOURCE_FILE (insn);
-	    }
+	    copy = emit_note_before (NOTE_LINE_NUMBER (insn), loop_start);
 	  break;
 
 	case INSN:
@@ -1890,9 +1886,7 @@ never_reached_warning (rtx avoided_insn,
     }
   if (two_avoided_lines && contains_insn)
     {
-      location_t locus;
-      locus.file = NOTE_SOURCE_FILE (a_line_note);
-      locus.line = NOTE_LINE_NUMBER (a_line_note);
+      location_t locus = NOTE_SOURCE_LOCATION (a_line_note);
       warning ("%Hwill never be executed", &locus);
     }
 }
Index: line-map.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/line-map.c,v
retrieving revision 1.6.18.5
diff -u -p -r1.6.18.5 line-map.c
--- line-map.c	20 Aug 2003 20:44:25 -0000	1.6.18.5
+++ line-map.c	15 Nov 2003 20:19:02 -0000
@@ -32,12 +32,13 @@ static void trace_include (const struct 
 void
 linemap_init (struct line_maps *set)
 {
-  set->maps = 0;
+  set->maps = NULL;
   set->allocated = 0;
   set->used = 0;
   set->last_listed = -1;
   set->trace_includes = false;
   set->depth = 0;
+  set->cache = NULL;
 }
 
 /* Free a line map set.  */
@@ -85,8 +86,10 @@ linemap_add (struct line_maps *set, enum
 
   if (set->used == set->allocated)
     {
+      int cache_offset = set->maps == NULL ? 0 : set->cache - set->maps;
       set->allocated = 2 * set->allocated + 256;
       set->maps = xrealloc (set->maps, set->allocated * sizeof (struct line_map));
+      set->cache = set->maps + cache_offset;
     }
 
   map = &set->maps[set->used++];
@@ -141,6 +144,10 @@ linemap_add (struct line_maps *set, enum
   map->from_line = from_line;
   map->to_file = to_file;
   map->to_line = to_line;
+  map->last = 1;
+  if (set->used > 1)
+    map[-1].last = 0;
+  set->cache = map;
 
   if (reason == LC_ENTER)
     {
@@ -168,7 +175,15 @@ linemap_add (struct line_maps *set, enum
 const struct line_map *
 linemap_lookup (struct line_maps *set, unsigned int line)
 {
-  unsigned int md, mn = 0, mx = set->used;
+  unsigned int md, mn, mx;
+
+  const struct line_map *saved = set->cache;
+  if (line >= saved->from_line
+      && (saved->last || line < saved[1].from_line))
+    return saved;
+
+  mn = 0;
+  mx = set->used;
 
   if (mx == 0)
     abort ();
@@ -182,7 +197,9 @@ linemap_lookup (struct line_maps *set, u
 	mn = md;
     }
 
-  return &set->maps[mn];
+  saved = &set->maps[mn];
+  set->cache = saved;
+  return saved;
 }
 
 /* Print the file names and line numbers of the #include commands
Index: line-map.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/line-map.h,v
retrieving revision 1.9.18.4
diff -u -p -r1.9.18.4 line-map.h
--- line-map.h	28 Sep 2003 06:06:29 -0000	1.9.18.4
+++ line-map.h	15 Nov 2003 20:19:02 -0000
@@ -31,8 +31,7 @@ Foundation, 59 Temple Place - Suite 330,
 enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
 
 /* A logical line number, i,e, an "index" into a line_map.  */
-/* Long-term, we want to use this to replace struct location_s (in input.h),
-   and effectively typedef fileline location_t.  */
+typedef unsigned int source_location;
 typedef unsigned int fileline;
 
 /* The logical line FROM_LINE maps to physical source file TO_FILE at
@@ -47,10 +46,11 @@ struct line_map
 {
   const char *to_file;
   unsigned int to_line;
-  fileline from_line;
+  source_location from_line;
   int included_from;
   ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
   unsigned char sysp;
+  unsigned char last;
 };
 
 /* A set of chronological line_map structures.  */
@@ -70,6 +70,7 @@ struct line_maps
 
   /* If true, prints an include trace a la -H.  */
   bool trace_includes;
+  const struct line_map *cache;
 };
 
 /* Initialize a line map set.  */
@@ -92,11 +93,12 @@ extern void linemap_free (struct line_ma
    maps, so any stored line_map pointers should not be used.  */
 extern const struct line_map *linemap_add
   (struct line_maps *, enum lc_reason, unsigned int sysp,
-   fileline from_line, const char *to_file, unsigned int to_line);
+   source_location from_line, const char *to_file, unsigned int to_line);
 
 /* Given a logical line, returns the map from which the corresponding
    (source file, line) pair can be deduced.  */
-extern const struct line_map *linemap_lookup (struct line_maps *, fileline);
+extern const struct line_map *linemap_lookup (struct line_maps *,
+					      source_location);
 
 /* Print the file names and line numbers of the #include commands
    which led to the map MAP, if any, to stderr.  Nothing is output if
Index: pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/pretty-print.c,v
retrieving revision 2.5.2.3
diff -u -p -r2.5.2.3 pretty-print.c
--- pretty-print.c	28 Sep 2003 06:06:32 -0000	2.5.2.3
+++ pretty-print.c	15 Nov 2003 20:19:02 -0000
@@ -281,11 +281,12 @@ pp_base_format_text (pretty_printer *pp,
 
         case 'H':
           {
-            const location_t *locus = va_arg (*text->args_ptr, location_t *);
+            location_t *locus = va_arg (*text->args_ptr, location_t *);
+	    struct location_s s = get_location_s (*locus);
             pp_string (pp, "file '");
-            pp_string (pp, locus->file);
+            pp_string (pp, s.file);
             pp_string (pp, "', line ");
-            pp_decimal_int (pp, locus->line);
+            pp_decimal_int (pp, s.line);
           }
           break;
 
Index: print-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/print-rtl.c,v
retrieving revision 1.84.2.13
diff -u -p -r1.84.2.13 print-rtl.c
--- print-rtl.c	13 Nov 2003 02:37:56 -0000	1.84.2.13
+++ print-rtl.c	15 Nov 2003 20:19:03 -0000
@@ -276,10 +276,13 @@ print_rtx (rtx in_rtx)
 		break;
 
 	      case NOTE_INSN_DELETED_LABEL:
-		if (NOTE_SOURCE_FILE (in_rtx))
-		  fprintf (outfile, " (\"%s\")", NOTE_SOURCE_FILE (in_rtx));
-		else
-		  fprintf (outfile, " \"\"");
+		{
+		  const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
+		  if (label)
+		    fprintf (outfile, " (\"%s\")", label);
+		  else
+		    fprintf (outfile, " \"\"");
+		}
 		break;
 
 	      case NOTE_INSN_PREDICTION:
@@ -293,7 +296,7 @@ print_rtx (rtx in_rtx)
 
 	      default:
 		{
-		  const char * const str = X0STR (in_rtx, i);
+		  const char * const str = X0STR (in_rtx, i); /* ??? */
 
 		  if (NOTE_LINE_NUMBER (in_rtx) < 0)
 		    ;
Index: print-tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/print-tree.c,v
retrieving revision 1.59.2.17
diff -u -p -r1.59.2.17 print-tree.c
--- print-tree.c	12 Oct 2003 19:43:32 -0000	1.59.2.17
+++ print-tree.c	15 Nov 2003 20:19:03 -0000
@@ -734,7 +734,7 @@ print_node (FILE *file, const char *pref
       break;
     }
 
-  if (EXPR_LOCUS (node))
+  if (EXPR_LOCATION (node))
     {
       indent_to (file, indent+4);
       fprintf (file, "%s:%d",
Index: profile.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/profile.c,v
retrieving revision 1.93.2.23
diff -u -p -r1.93.2.23 profile.c
--- profile.c	9 Nov 2003 09:51:14 -0000	1.93.2.23
+++ profile.c	15 Nov 2003 20:19:03 -0000
@@ -922,23 +922,26 @@ branch_prob (void)
 		    ignore_next_note = 0;
 		  else
 		    {
+		      struct location_s s;
+
 		      if (!offset)
 			{
 			  offset = gcov_write_tag (GCOV_TAG_LINES);
 			  gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
 			}
 
+		      s = get_location_s (NOTE_SOURCE_LOCATION (insn));
+
 		      /* If this is a new source file, then output the
 			 file's name to the .bb file.  */
 		      if (!prev_file_name
-			  || strcmp (NOTE_SOURCE_FILE (insn),
-				     prev_file_name))
+			  || strcmp (s.file, prev_file_name))
 			{
-			  prev_file_name = NOTE_SOURCE_FILE (insn);
+			  prev_file_name = s.file;
 			  gcov_write_unsigned (0);
 			  gcov_write_string (prev_file_name);
 			}
-		      gcov_write_unsigned (NOTE_LINE_NUMBER (insn));
+		      gcov_write_unsigned (s.line);
 		    }
 		}
 	      insn = NEXT_INSN (insn);
Index: ra-debug.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ra-debug.c,v
retrieving revision 1.5.2.9
diff -u -p -r1.5.2.9 ra-debug.c
--- ra-debug.c	28 Sep 2003 06:06:32 -0000	1.5.2.9
+++ ra-debug.c	15 Nov 2003 20:19:03 -0000
@@ -388,9 +388,11 @@ ra_print_rtx (FILE *file, rtx x, int wit
 	    fprintf (file, " %s", GET_NOTE_INSN_NAME (ln));
 	  else
 	    {
-	      fprintf (file, " line %d", ln);
-	      if (NOTE_SOURCE_FILE (x))
-		fprintf (file, ":%s", NOTE_SOURCE_FILE (x));
+	      struct location_s s
+		= get_location_s (NOTE_SOURCE_LOCATION (x));
+	      fprintf (file, " line %d", s.line);
+	      if (s.file != NULL)
+		fprintf (file, ":%s", s.file);
 	    }
 	}
       else
Index: recog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/recog.c,v
retrieving revision 1.159.2.17
diff -u -p -r1.159.2.17 recog.c
--- recog.c	13 Nov 2003 02:37:57 -0000	1.159.2.17
+++ recog.c	15 Nov 2003 20:19:04 -0000
@@ -2671,7 +2671,6 @@ split_insn (rtx insn)
 	{
 	  /* try_split returns the NOTE that INSN became.  */
 	  PUT_CODE (insn, NOTE);
-	  NOTE_SOURCE_FILE (insn) = 0;
 	  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
 
 	  /* ??? Coddle to md files that generate subregs in post-
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.346.2.24
diff -u -p -r1.346.2.24 reload1.c
--- reload1.c	13 Nov 2003 02:37:59 -0000	1.346.2.24
+++ reload1.c	15 Nov 2003 20:19:07 -0000
@@ -1038,7 +1038,6 @@ reload (rtx first, int global)
 	      else
 		{
 		  PUT_CODE (equiv_insn, NOTE);
-		  NOTE_SOURCE_FILE (equiv_insn) = 0;
 		  NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED;
 		}
 	    }
@@ -1883,7 +1882,6 @@ delete_dead_insn (rtx insn)
 
   PUT_CODE (insn, NOTE);
   NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
-  NOTE_SOURCE_FILE (insn) = 0;
 }
 
 /* Modify the home of pseudo-reg I.
Index: rtl-error.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl-error.c,v
retrieving revision 1.6.2.5
diff -u -p -r1.6.2.5 rtl-error.c
--- rtl-error.c	23 Jul 2003 16:59:56 -0000	1.6.2.5
+++ rtl-error.c	15 Nov 2003 20:19:07 -0000
@@ -59,10 +59,7 @@ location_for_asm (rtx insn)
     asmop = NULL;
 
   if (asmop)
-    {
-      loc.file = ASM_OPERANDS_SOURCE_FILE (asmop);
-      loc.line = ASM_OPERANDS_SOURCE_LINE (asmop);
-    }
+    loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
   else
     loc = input_location;
   return loc;
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.def,v
retrieving revision 1.57.2.11
diff -u -p -r1.57.2.11 rtl.def
--- rtl.def	28 Oct 2003 14:56:20 -0000	1.57.2.11
+++ rtl.def	15 Nov 2003 20:19:08 -0000
@@ -668,9 +668,8 @@ DEF_RTL_EXPR(ASM_INPUT, "asm_input", "s"
    5th is a vector of modes and constraints for the input operands.
      Each element is an ASM_INPUT containing a constraint string
      and whose mode indicates the mode of the input operand.
-   6th is the name of the containing source file.
-   7th is the source line number.  */
-DEF_RTL_EXPR(ASM_OPERANDS, "asm_operands", "ssiEEsi", 'x')
+   6th is the source line number.  */
+DEF_RTL_EXPR(ASM_OPERANDS, "asm_operands", "ssiEEi", 'x')
 
 /* A machine-specific operation.
    1st operand is a vector of operands being used by the operation so that
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.362.2.27
diff -u -p -r1.362.2.27 rtl.h
--- rtl.h	28 Oct 2003 14:56:20 -0000	1.362.2.27
+++ rtl.h	15 Nov 2003 20:19:09 -0000
@@ -812,7 +812,10 @@ extern const char * const reg_note_name[
 
 /* Opaque data.  */
 #define NOTE_DATA(INSN)	        RTL_CHECKC1 (INSN, 4, NOTE)
-#define NOTE_SOURCE_FILE(INSN)	XCSTR (INSN, 4, NOTE)
+#define NOTE_DELETED_LABEL_NAME(INSN) XCSTR (INSN, 4, NOTE)
+#define NOTE_SOURCE_LOCATION(INSN) XCUINT (INSN, 5, NOTE)
+#define NOTE_SOURCE_LINE(INSN)	LOCATION_LINE (NOTE_SOURCE_LOCATION (INSN))
+#define NOTE_SOURCE_FILE(INSN)	LOCATION_FILE (NOTE_SOURCE_LOCATION (INSN))
 #define NOTE_BLOCK(INSN)	XCTREE (INSN, 4, NOTE)
 #define NOTE_EH_HANDLER(INSN)	XCINT (INSN, 4, NOTE)
 #define NOTE_BASIC_BLOCK(INSN)	XCBBDEF (INSN, 4, NOTE)
@@ -1111,8 +1114,7 @@ do {									\
   XSTR (XCVECEXP (RTX, 4, N, ASM_OPERANDS), 0)
 #define ASM_OPERANDS_INPUT_MODE(RTX, N)  \
   GET_MODE (XCVECEXP (RTX, 4, N, ASM_OPERANDS))
-#define ASM_OPERANDS_SOURCE_FILE(RTX) XCSTR (RTX, 5, ASM_OPERANDS)
-#define ASM_OPERANDS_SOURCE_LINE(RTX) XCINT (RTX, 6, ASM_OPERANDS)
+#define ASM_OPERANDS_SOURCE_LOCATION(RTX) XCUINT (RTX, 5, ASM_OPERANDS)
 
 /* 1 if RTX is a mem and we should keep the alias set for this mem
    unchanged when we access a component.  Set to 1, or example, when we
Index: sched-rgn.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-rgn.c,v
retrieving revision 1.46.2.13
diff -u -p -r1.46.2.13 sched-rgn.c
--- sched-rgn.c	18 Oct 2003 23:59:51 -0000	1.46.2.13
+++ sched-rgn.c	15 Nov 2003 20:19:10 -0000
@@ -2324,8 +2324,13 @@ debug_dependencies (void)
 		      if (n < 0)
 			fprintf (sched_dump, "%s\n", GET_NOTE_INSN_NAME (n));
 		      else
-			fprintf (sched_dump, "line %d, file %s\n", n,
-				 NOTE_SOURCE_FILE (insn));
+			{
+			  const struct line_map *map
+			    = linemap_lookup (&line_table, (fileline) n);
+			  fprintf (sched_dump, "line %d, file %s\n",
+				   SOURCE_LINE (map, (fileline) n),
+				   map->to_file);
+			}
 		    }
 		  else
 		    fprintf (sched_dump, " {%s}\n", GET_RTX_NAME (GET_CODE (insn)));
Index: sched-vis.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-vis.c,v
retrieving revision 1.22.2.5
diff -u -p -r1.22.2.5 sched-vis.c
--- sched-vis.c	23 Jul 2003 16:59:57 -0000	1.22.2.5
+++ sched-vis.c	15 Nov 2003 20:19:10 -0000
@@ -787,8 +787,11 @@ print_insn (char *buf, rtx x, int verbos
       break;
     case NOTE:
       if (NOTE_LINE_NUMBER (x) > 0)
-	sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
-		 NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
+	{
+	  struct location_s s = get_location_s (NOTE_SOURCE_LOCATION (x));
+	  sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
+		   s.file, s.line);
+	}
       else
 	sprintf (buf, "%4d %s", INSN_UID (x),
 		 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.267.2.40
diff -u -p -r1.267.2.40 stmt.c
--- stmt.c	13 Nov 2003 02:37:59 -0000	1.267.2.40
+++ stmt.c	15 Nov 2003 20:19:12 -0000
@@ -368,7 +368,7 @@ struct stmt_status GTY(())
 
   /* Location of last line-number note, whether we actually
      emitted it or not.  */
-  location_t x_emit_locus;
+  source_location x_emit_locus;
 
   struct goto_fixup *x_goto_fixup_chain;
 };
@@ -438,7 +438,7 @@ init_stmt_for_function (void)
 /* Record the current file and line.  Called from emit_line_note.  */
 
 void
-set_file_and_line_for_stmt (location_t location)
+set_file_and_line_for_stmt (source_location location)
 {
   /* If we're outputting an inline function, and we add a line note,
      there may be no CFUN->STMT information.  So, there's no need to
@@ -1460,7 +1460,7 @@ decl_conflicts_with_clobbers_p (tree dec
 
 void
 expand_asm_operands (tree string, tree outputs, tree inputs,
-		     tree clobbers, int vol, location_t locus)
+		     tree clobbers, int vol, source_location locus)
 {
   rtvec argvec, constraintvec;
   rtx body;
@@ -1678,7 +1678,7 @@ expand_asm_operands (tree string, tree o
 				: GET_MODE (output_rtx[0])),
 			       TREE_STRING_POINTER (string),
 			       empty_string, 0, argvec, constraintvec,
-			       locus.file, locus.line);
+			       locus);
 
   MEM_VOLATILE_P (body) = vol;
 
@@ -1825,7 +1825,7 @@ expand_asm_operands (tree string, tree o
 			   (GET_MODE (output_rtx[i]),
 			    TREE_STRING_POINTER (string),
 			    constraints[i], i, argvec, constraintvec,
-			    locus.file, locus.line));
+			    locus));
 
 	  MEM_VOLATILE_P (SET_SRC (XVECEXP (body, 0, i))) = vol;
 	}
@@ -4545,9 +4545,8 @@ check_seenlabel (void)
 	      /* If insn is zero, then there must have been a syntax error.  */
 	      if (insn)
                 {
-                  location_t locus;
-                  locus.file = NOTE_SOURCE_FILE (insn);
-                  locus.line = NOTE_LINE_NUMBER (insn);
+                  source_location locus;
+                  locus = NOTE_SOURCE_LOCATION (insn);
                   warning ("%Hunreachable code at beginning of %s", &locus,
                            case_stack->data.case_stmt.printname);
                 }
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.654.2.74
diff -u -p -r1.654.2.74 toplev.c
--- toplev.c	13 Nov 2003 02:38:00 -0000	1.654.2.74
+++ toplev.c	15 Nov 2003 20:19:13 -0000
@@ -188,6 +188,8 @@ const char *main_input_filename;
 
 location_t input_location;
 
+struct line_maps line_table;
+
 /* Nonzero if it is unsafe to create any new pseudo registers.  */
 int no_new_pseudos;
 
@@ -1829,15 +1831,14 @@ warn_deprecated_use (tree node)
    INPUT_LOCATION accordingly.  */
 
 void
-push_srcloc (const char *file, int line)
+push_srcloc (fileline fline)
 {
   struct file_stack *fs;
 
   fs = xmalloc (sizeof (struct file_stack));
   fs->location = input_location;
   fs->next = input_file_stack;
-  input_filename = file;
-  input_line = line;
+  input_location = fline;
   input_file_stack = fs;
   input_file_stack_tick++;
 }
@@ -4348,6 +4349,7 @@ general_init (const char *argv0)
      table.  */
   init_ggc ();
   init_stringpool ();
+  linemap_init (&line_table);
   init_ttree ();
 
   /* Initialize register usage now so switches may override.  */
@@ -4369,7 +4371,6 @@ process_options (void)
      sets the original filename if appropriate (e.g. foo.i -> foo.c)
      so we can correctly initialize debug output.  */
   no_backend = (*lang_hooks.post_options) (&main_input_filename);
-  input_filename = main_input_filename;
 
 #ifdef OVERRIDE_OPTIONS
   /* Some machines may reject certain combinations of options.  */
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.211
diff -u -p -r1.1.4.211 tree-cfg.c
--- tree-cfg.c	13 Nov 2003 02:47:41 -0000	1.1.4.211
+++ tree-cfg.c	15 Nov 2003 20:19:14 -0000
@@ -800,9 +800,10 @@ static void remove_useless_stmts_1 (tree
 static bool
 remove_useless_stmts_warn_notreached (tree stmt)
 {
-  if (EXPR_LOCUS (stmt))
+  if (EXPR_LOCATION (stmt))
     {
-      warning ("%Hwill never be executed", EXPR_LOCUS (stmt));
+      source_location loc = EXPR_LOCATION (stmt);
+      warning ("%Hwill never be executed", &loc);
       return true;
     }
 
@@ -1495,7 +1496,7 @@ static void
 remove_bb (basic_block bb)
 {
   block_stmt_iterator i;
-  location_t *loc = NULL;
+  source_location loc = 0;
 
   dump_file = dump_begin (TDI_cfg, &dump_flags);
   if (dump_file)
@@ -1521,8 +1522,8 @@ remove_bb (basic_block bb)
 	 jump threading, thus resulting into bogus warnings.  Not great,
 	 since this way we lose warnings for gotos in the original program
 	 that are indeed unreachable.  */
-      if (TREE_CODE (stmt) != GOTO_EXPR && EXPR_LOCUS (stmt) && !loc)
-	loc = EXPR_LOCUS (stmt);
+      if (TREE_CODE (stmt) != GOTO_EXPR && EXPR_LOCATION (stmt) && !loc)
+	loc = EXPR_LOCATION (stmt);
     }
 
   /* If requested, give a warning that the first statement in the
@@ -1530,7 +1531,7 @@ remove_bb (basic_block bb)
      loop above, so the last statement we process is the first statement
      in the block.  */
   if (warn_notreached && loc)
-    warning ("%Hwill never be executed", loc);
+    warning ("%Hwill never be executed", &loc);
 
   remove_phi_nodes_and_edges_for_unreachable_block (bb);
 
Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
retrieving revision 1.1.2.57
diff -u -p -r1.1.2.57 tree-flow-inline.h
--- tree-flow-inline.h	12 Nov 2003 22:06:26 -0000	1.1.2.57
+++ tree-flow-inline.h	15 Nov 2003 20:19:14 -0000
@@ -139,6 +139,21 @@ set_has_hidden_use (tree var)
   ann->has_hidden_use = 1;
 }
 
+static inline source_location
+get_location (tree expr)
+{
+  if (expr == NULL_TREE)
+    return -1;
+
+  if (TREE_CODE (expr) == COMPOUND_EXPR)
+    expr = TREE_OPERAND (expr, 0);
+
+  if (! EXPR_LOCATION (expr))
+    return -1;
+
+  return EXPR_LOCATION (expr);
+}
+
 static inline int
 get_lineno (tree expr)
 {
@@ -148,7 +163,7 @@ get_lineno (tree expr)
   if (TREE_CODE (expr) == COMPOUND_EXPR)
     expr = TREE_OPERAND (expr, 0);
 
-  if (! EXPR_LOCUS (expr))
+  if (! EXPR_LOCATION (expr))
     return -1;
 
   return EXPR_LINENO (expr);
@@ -163,7 +178,7 @@ get_filename (tree expr)
   if (TREE_CODE (expr) == COMPOUND_EXPR)
     expr = TREE_OPERAND (expr, 0);
 
-  if (EXPR_LOCUS (expr) && EXPR_FILENAME (expr))
+  if (EXPR_LOCATION (expr) && EXPR_FILENAME (expr))
     return EXPR_FILENAME (expr);
   else
     return "???";
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.148
diff -u -p -r1.1.4.148 tree-flow.h
--- tree-flow.h	13 Nov 2003 02:47:41 -0000	1.1.4.148
+++ tree-flow.h	15 Nov 2003 20:19:14 -0000
@@ -288,6 +288,7 @@ static inline void set_may_alias_global_
 static inline bool may_alias_global_mem_p (tree);
 static inline bool may_point_to_global_mem_p (tree);
 static inline void set_may_point_to_global_mem (tree);
+static inline source_location get_location (tree);
 static inline int get_lineno (tree);
 static inline const char *get_filename (tree);
 static inline bool is_exec_stmt (tree);
Index: tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.26.2.60
diff -u -p -r1.26.2.60 tree-inline.c
--- tree-inline.c	13 Nov 2003 02:38:01 -0000	1.26.2.60
+++ tree-inline.c	15 Nov 2003 20:19:15 -0000
@@ -1330,8 +1330,8 @@ expand_call_inline (tree *tp, int *walk_
   /* Set input_location here so we get the right instantiation context
      if we call instantiate_decl from inlinable_function_p.  */
   saved_location = input_location;
-  if (EXPR_LOCUS (t))
-    input_location = *EXPR_LOCUS (t);
+  if (EXPR_LOCATION (t))
+    input_location = EXPR_LOCATION (t);
 
   /* Recurse, but letting recursive invocations know that we are
      inside the body of a TARGET_EXPR.  */
Index: tree-mudflap.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-mudflap.c,v
retrieving revision 1.1.2.57
diff -u -p -r1.1.2.57 tree-mudflap.c
--- tree-mudflap.c	12 Nov 2003 22:06:26 -0000	1.1.2.57
+++ tree-mudflap.c	15 Nov 2003 20:19:16 -0000
@@ -53,14 +53,14 @@ static void mf_init_extern_trees (void);
 static void mf_decl_cache_locals (tree *);
 static void mf_decl_clear_locals (void);
 static tree mf_varname_tree (tree);
-static tree mf_file_function_line_tree (const char *, int);
+static tree mf_file_function_line_tree (source_location);
 static tree mf_mostly_copy_tree_r (tree *, int *, void *);
 static tree mx_xfn_indirect_ref (tree *, int *, void *);
 static tree mx_xfn_xform_decls (tree *, int *, void *);
 
 static tree mf_offset_expr_of_array_ref (tree, tree *, tree *, tree *);
 static tree mf_build_check_statement_for (tree, tree, tree, tree, tree,
-					  const char *, int);
+					  source_location);
 static void mx_register_decls (tree, tree *);
 
 
@@ -373,8 +373,9 @@ mf_varname_tree (tree decl)
 
 /* And another friend, for producing a simpler message.  */
 static tree
-mf_file_function_line_tree (const char * file, int line)
+mf_file_function_line_tree (source_location location)
 {
+  struct location_s loc_s = get_location_s (location);
   static pretty_printer buf_rec;
   static int initialized = 0;
   pretty_printer *buf = & buf_rec;
@@ -389,16 +390,16 @@ mf_file_function_line_tree (const char *
   pp_clear_output_area (buf);
 
   /* Add FILENAME[:LINENUMBER]. */
-  if (file == NULL && current_function_decl != NULL_TREE)
-    file = DECL_SOURCE_FILE (current_function_decl);
-  if (file == NULL)
-    file = "<unknown file>";
-  pp_string (buf, file);
+  if (loc_s.file == NULL && current_function_decl != NULL_TREE)
+    loc_s.file = DECL_SOURCE_FILE (current_function_decl);
+  if (loc_s.file == NULL)
+    loc_s.file = "<unknown file>";
+  pp_string (buf, loc_s.file);
 
-  if (line > 0)
+  if (loc_s.line > 0)
     {
       pp_string (buf, ":");
-      pp_decimal_int (buf, line);
+      pp_decimal_int (buf, loc_s.line);
     }
 
   /* Add (FUNCTION) */
@@ -516,11 +517,11 @@ mf_offset_expr_of_array_ref (tree t, tre
 static tree
 mf_build_check_statement_for (tree ptrvalue, tree chkbase, tree chksize,
 			      tree acctype, tree chkdecls,
-			      const char *filename, int lineno)
+			      source_location location)
 {
   tree ptrtype = TREE_TYPE (ptrvalue);
   tree myptrtype = build_qualified_type (ptrtype, TYPE_QUAL_CONST);
-  tree location_string = mf_file_function_line_tree (filename, lineno);
+  tree location_string = mf_file_function_line_tree (location);
 
   tree bind_decls = NULL_TREE;  /* A chain of VAR_DECL nodes. */
   tree bind_exprs = NULL_TREE;  /* Eventually a COMPOUND_EXPR. */
@@ -772,8 +773,7 @@ static int tree_roles_init;
 static tree
 mx_xfn_indirect_ref (tree *t, int *continue_p, void *data)
 {
-  static const char *last_filename = NULL;
-  static int last_lineno = -1;
+  source_location last_location = 0;
   htab_t verboten = (htab_t) data;
   tree tree_role;
 
@@ -792,16 +792,11 @@ mx_xfn_indirect_ref (tree *t, int *conti
   *continue_p = 1;
 
   /* Track file-name/line-numbers.  */
-  if (STATEMENT_CODE_P (TREE_CODE (*t)))
-    last_lineno = (STMT_LINENO (*t) > 0 ? STMT_LINENO (*t) : last_lineno);
-  if (TREE_CODE (*t) == FILE_STMT)
-    last_filename = FILE_STMT_FILENAME (*t);
+  if (STATEMENT_CODE_P (TREE_CODE (*t))  && STMT_SOURCE_LOCATION (*t))
+    last_location = STMT_SOURCE_LOCATION (*t);
   /* Try also the LOCUS, but ignore a simply referenced decl.  */
-  if (! DECL_P (*t) && EXPR_LOCUS (*t)) 
-    {
-      last_filename = EXPR_FILENAME (*t);
-      last_lineno = (EXPR_LINENO (*t) > 0 ? EXPR_LINENO (*t) : last_lineno);
-    }
+  if (! DECL_P (*t) && EXPR_LOCATION (*t)) 
+    last_location = EXPR_LOCATION (*t);
 
   /* Avoid traversal into subtrees specifically listed as
      do-not-traverse.  This occurs for certain nested operator/array
@@ -953,7 +948,7 @@ mx_xfn_indirect_ref (tree *t, int *conti
 
 	    tmp = mf_build_check_statement_for (value_ptr, check_ptr, check_size,
 						tree_role, check_decls,
-						last_filename, last_lineno);
+						last_location);
 	    *t = mf_mark (build1 (INDIRECT_REF, base_obj_type, tmp));
 	  }
       }
@@ -972,8 +967,7 @@ mx_xfn_indirect_ref (tree *t, int *conti
 				      TYPE_SIZE_UNIT (TREE_TYPE
 						      (TREE_TYPE
 						       (TREE_OPERAND (*t, 0)))),
-				      tree_role, NULL_TREE,
-				      last_filename, last_lineno);
+				      tree_role, NULL_TREE, last_location);
 	/* Prevent this transform's reapplication to this tree node.
 	   Note that we do not prevent recursion in walk_tree toward
 	   subtrees of this node, in case of nested pointer expressions.  */
@@ -1001,8 +995,7 @@ mx_xfn_indirect_ref (tree *t, int *conti
 
 	  *pointer =
 	    mf_build_check_statement_for (*pointer, *pointer, check_size,
-					  tree_role, NULL_TREE,
-					  last_filename, last_lineno);
+					  tree_role, NULL_TREE, last_location);
 
 	  /* Don't instrument the nested INDIRECT_REF. */
 	  mf_mark (TREE_OPERAND (*t, 0));
@@ -1028,8 +1021,7 @@ mx_xfn_indirect_ref (tree *t, int *conti
 
 	  *pointer =
 	    mf_build_check_statement_for (*pointer, *pointer, check_size,
-					  tree_role, NULL_TREE,
-					  last_filename, last_lineno);
+					  tree_role, NULL_TREE, last_location);
 
 	  /* Don't instrument the nested INDIRECT_REF. */
 	  mf_mark (TREE_OPERAND (*t, 0));
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 1.1.4.71
diff -u -p -r1.1.4.71 tree-optimize.c
--- tree-optimize.c	12 Nov 2003 22:06:26 -0000	1.1.4.71
+++ tree-optimize.c	15 Nov 2003 20:19:16 -0000
@@ -358,7 +358,7 @@ tree_rest_of_compilation (tree fndecl, b
 
   /* Make sure the locus is set to the end of the function, so that 
      epilogue line numbers and warnings are set properly.  */
-  if (cfun->function_end_locus.file)
+  if (cfun->function_end_locus)
     input_location = cfun->function_end_locus;
 
   /* The following insns belong to the top scope.  */
Index: tree-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-pretty-print.c,v
retrieving revision 1.1.2.58
diff -u -p -r1.1.2.58 tree-pretty-print.c
--- tree-pretty-print.c	12 Nov 2003 22:06:26 -0000	1.1.2.58
+++ tree-pretty-print.c	15 Nov 2003 20:19:16 -0000
@@ -177,7 +177,7 @@ dump_generic_node (pretty_printer *buffe
 
   if (dumping_stmts
       && (flags & TDF_LINENO)
-      && EXPR_LOCUS (node))
+      && EXPR_LOCATION (node))
     {
       pp_character (buffer, '[');
       if (EXPR_FILENAME (node))
Index: tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-pre.c,v
retrieving revision 1.1.4.102
diff -u -p -r1.1.4.102 tree-ssa-pre.c
--- tree-ssa-pre.c	12 Nov 2003 22:06:26 -0000	1.1.4.102
+++ tree-ssa-pre.c	15 Nov 2003 20:19:17 -0000
@@ -2671,7 +2671,7 @@ code_motion (struct expr_info *ei)
 	      fprintf (dump_file, " before statement ");
 	      print_generic_expr (dump_file, use_stmt, 0);
 	      fprintf (dump_file, "\n");
-	      if (EXPR_LOCUS (use_stmt))
+	      if (EXPR_LOCATION (use_stmt))
 		fprintf (dump_file, " on line %d\n",
 			 EXPR_LINENO (use_stmt));
 	    }
@@ -2702,7 +2702,7 @@ code_motion (struct expr_info *ei)
 	      fprintf (dump_file, " in statement ");
 	      print_generic_stmt (dump_file, use_stmt, 0);
 	      fprintf (dump_file, "\n");
-	      if (EXPR_LOCUS (use_stmt))
+	      if (EXPR_LOCATION (use_stmt))
 		fprintf (dump_file, " on line %d\n",
 			 EXPR_LINENO (use_stmt));
 	    }
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.263.2.67
diff -u -p -r1.263.2.67 tree.c
--- tree.c	13 Nov 2003 02:38:01 -0000	1.263.2.67
+++ tree.c	15 Nov 2003 20:19:19 -0000
@@ -2414,8 +2414,7 @@ build1 (enum tree_code code, tree type, 
   TREE_SET_CODE (t, code);
 
   TREE_TYPE (t) = type;
-  /* FIXME maybe give expr a locus here?  */
-  SET_EXPR_LOCUS (t, NULL);
+  SET_EXPR_LOCATION (t, (source_location) 0);
   TREE_COMPLEXITY (t) = 0;
   TREE_OPERAND (t, 0) = node;
   TREE_BLOCK (t) = NULL_TREE;
@@ -2576,51 +2575,6 @@ build_block (tree vars, tree tags ATTRIB
   BLOCK_SUPERCONTEXT (block) = supercontext;
   BLOCK_CHAIN (block) = chain;
   return block;
-}
-
-static GTY(()) tree last_annotated_node;
-
-/* Record the exact location where an expression or an identifier were
-   encountered.  */
-
-void
-annotate_with_file_line (tree node, const char *file, int line)
-{
-  /* Roughly one percent of the calls to this function are to annotate
-     a node with the same information already attached to that node!
-     Just return instead of wasting memory.  */
-  if (EXPR_LOCUS (node)
-      && (EXPR_FILENAME (node) == file
-	  || ! strcmp (EXPR_FILENAME (node), file))
-      && EXPR_LINENO (node) == line)
-    {
-      last_annotated_node = node;
-      return;
-    }
-
-  /* In heavily macroized code (such as GCC itself) this single
-     entry cache can reduce the number of allocations by more
-     than half.  */
-  if (last_annotated_node
-      && EXPR_LOCUS (last_annotated_node)
-      && (EXPR_FILENAME (last_annotated_node) == file
-	  || ! strcmp (EXPR_FILENAME (last_annotated_node), file))
-      && EXPR_LINENO (last_annotated_node) == line)
-    {
-      SET_EXPR_LOCUS (node, EXPR_LOCUS (last_annotated_node));
-      return;
-    }
-
-  SET_EXPR_LOCUS (node, ggc_alloc (sizeof (location_t)));
-  EXPR_LINENO (node) = line;
-  EXPR_FILENAME (node) = file;
-  last_annotated_node = node;
-}
-
-void
-annotate_with_locus (tree node, location_t locus)
-{
-  annotate_with_file_line (node, locus.file, locus.line);
 }
 
 /* Return a declaration like DDECL except that its DECL_ATTRIBUTES
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.124
diff -u -p -r1.342.2.124 tree.h
--- tree.h	13 Nov 2003 02:38:02 -0000	1.342.2.124
+++ tree.h	15 Nov 2003 20:19:20 -0000
@@ -916,16 +916,16 @@ struct tree_vec GTY(())
 /* The source location of this expression.  Non-tree_exp nodes such as
    decls and constants can be shared among multiple locations, so
    return nothing.  */
-#define EXPR_LOCUS(NODE)					\
+#define EXPR_LOCATION(NODE)					\
   (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (NODE)))	\
    ? (NODE)->exp.locus						\
-   : (location_t *)NULL)
-#define SET_EXPR_LOCUS(NODE, FROM) \
+   : (source_location) 0)
+#define SET_EXPR_LOCATION(NODE, FROM) \
   (EXPR_CHECK (NODE)->exp.locus = (FROM))
 #define EXPR_FILENAME(NODE) \
-  (EXPR_CHECK (NODE)->exp.locus->file)
+  LOCATION_FILE (EXPR_CHECK (NODE)->exp.locus)
 #define EXPR_LINENO(NODE) \
-  (EXPR_CHECK (NODE)->exp.locus->line)
+  LOCATION_LINE (EXPR_CHECK (NODE)->exp.locus)
 
 /* In a TARGET_EXPR node.  */
 #define TARGET_EXPR_SLOT(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 0)
@@ -996,7 +996,7 @@ struct tree_vec GTY(())
 struct tree_exp GTY(())
 {
   struct tree_common common;
-  location_t *locus;
+  source_location locus;
   int complexity;
   tree block;
   tree GTY ((special ("tree_exp"),
@@ -1701,8 +1701,8 @@ struct tree_type GTY(())
    function that is declared first and then defined later), this
    information should refer to the definition.  */
 #define DECL_SOURCE_LOCATION(NODE) (DECL_CHECK (NODE)->decl.locus)
-#define DECL_SOURCE_FILE(NODE) (DECL_SOURCE_LOCATION (NODE).file)
-#define DECL_SOURCE_LINE(NODE) (DECL_SOURCE_LOCATION (NODE).line)
+#define DECL_SOURCE_FILE(NODE) LOCATION_FILE (DECL_SOURCE_LOCATION (NODE))
+#define DECL_SOURCE_LINE(NODE) LOCATION_LINE (DECL_SOURCE_LOCATION (NODE))
 /* Holds the size of the datum, in bits, as a tree expression.
    Need not be constant.  */
 #define DECL_SIZE(NODE) (DECL_CHECK (NODE)->decl.size)
@@ -2053,7 +2053,7 @@ union alias_typevar_def;
 struct tree_decl GTY(())
 {
   struct tree_common common;
-  location_t locus;
+  source_location locus;
   unsigned int uid;
   tree size;
   ENUM_BITFIELD(machine_mode) mode : 8;
@@ -2570,8 +2570,6 @@ extern tree build1 (enum tree_code, tree
 extern tree build_tree_list (tree, tree);
 extern tree build_decl (enum tree_code, tree, tree);
 extern tree build_block (tree, tree, tree, tree, tree);
-extern void annotate_with_file_line (tree, const char *, int);
-extern void annotate_with_locus (tree, location_t);
 extern tree build_empty_stmt (void);
 
 /* Construct various nodes representing data types.  */
@@ -3374,7 +3372,7 @@ extern void check_max_integer_computatio
 
 /* In emit-rtl.c */
 extern void start_sequence_for_rtl_expr (tree);
-extern rtx emit_line_note (location_t);
+extern rtx emit_line_note (source_location);
 
 /* In calls.c */
 
@@ -3452,7 +3450,7 @@ extern bool parse_output_constraint (con
 				     bool *, bool *, bool *);
 extern bool parse_input_constraint (const char **, int, int, int, int,
 				    const char * const *, bool *, bool *);
-extern void expand_asm_operands (tree, tree, tree, tree, int, location_t);
+extern void expand_asm_operands (tree, tree, tree, tree, int, source_location);
 extern void expand_asm_expr (tree);
 extern bool asm_op_is_mem_input (tree, tree);
 extern tree resolve_asm_operand_names (tree, tree, tree);

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