This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Finding the end of the catch clauses
- To: gcc-patches at gcc dot gnu dot org
- Subject: Finding the end of the catch clauses
- From: "Martin v. Loewis" <martin at loewis dot home dot cs dot tu-berlin dot de>
- Date: Sun, 19 Mar 2000 15:41:10 +0100
When compiling large C++ programs, significant time is spent in
push_to_sequence, when switching to the catch_clauses insn
sequence. In particular, the time is spent in iterating over the
growing insn list, every time a handler is added to the list.
This patch adds a field to the function state which always carries the
end of this insn chain. It also adds the function pair
push_to_full_sequence/end_full_sequence which allow to save and
restore a pair of first/last insn pointers. There may be other
candidates for using this interface, but profiling shows that it pays
most for catch clauses. Together with the type hash patch, this
speeds-up one of my examples from 186s to 171s (approx 9%).
The full bootstrap and testsuite run was successfully performed on
i586-pc-linux-gnu. If approved, the cp and java Changelog entries will
go in their separate change logs, of course.
Regards,
Martin
2000-03-19 Martin v. Löwis <loewis@informatik.hu-berlin.de>
* emit-rtl.c (push_to_full_sequence, end_full_sequence): New functions.
* except.c (emit_cleanup_handler): Use them.
(expand_end_all_catch): Likewise.
* function.c (fixup_var_refs): Likewise.
(expand_function_end): Clear catch_clauses_last.
* rtl.h (push_to_full_sequence, end_full_sequence): Declare.
* except.h (struct eh_status): New field x_catch_clauses_last.
(catch_clauses_last): New define.
* cp/except.c (expand_exception_blocks): Clear catch_clauses_last.
* java/except.c (emit_handlers): Clear catch_clauses_last.
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/emit-rtl.c,v
retrieving revision 1.116
diff -u -p -r1.116 emit-rtl.c
--- emit-rtl.c 2000/03/07 20:39:04 1.116
+++ emit-rtl.c 2000/03/19 13:49:02
@@ -3415,6 +3415,20 @@ push_to_sequence (first)
last_insn = last;
}
+/* Set up the insn chain from a chain stort in FIRST to LAST. */
+
+void
+push_to_full_sequence (first, last)
+ rtx first, last;
+{
+ start_sequence ();
+ first_insn = first;
+ last_insn = last;
+ /* We really should have the end of the insn chain here. */
+ if (last && NEXT_INSN (last))
+ abort ();
+}
+
/* Set up the outer-level insn chain
as the current sequence, saving the previously current one. */
@@ -3475,6 +3489,18 @@ end_sequence ()
seq_stack = tem->next;
free (tem);
+}
+
+/* This works like end_sequence, but records the old sequence in FIRST
+ and LAST. */
+
+void
+end_full_sequence (first, last)
+ rtx *first, *last;
+{
+ *first = first_insn;
+ *last = last_insn;
+ end_sequence();
}
/* Return 1 if currently emitting into a sequence. */
Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/except.c,v
retrieving revision 1.124
diff -u -p -r1.124 except.c
--- except.c 2000/03/10 19:21:06 1.124
+++ except.c 2000/03/19 13:49:06
@@ -1865,10 +1865,9 @@ emit_cleanup_handler (entry)
end_sequence ();
/* And add it to the CATCH_CLAUSES. */
- push_to_sequence (catch_clauses);
+ push_to_full_sequence (catch_clauses, catch_clauses_last);
emit_insns (handler_insns);
- catch_clauses = get_insns ();
- end_sequence ();
+ end_full_sequence (&catch_clauses, &catch_clauses_last);
/* Now we've left the handler. */
pop_ehqueue ();
@@ -1990,10 +1989,9 @@ expand_end_all_catch ()
pop_label_entry (&outer_context_label_stack);
/* Add the new sequence of catches to the main one for this function. */
- push_to_sequence (catch_clauses);
+ push_to_full_sequence (catch_clauses, catch_clauses_last);
emit_insns (new_catch_clause);
- catch_clauses = get_insns ();
- end_sequence ();
+ end_full_sequence (&catch_clauses, &catch_clauses_last);
/* Here we fall through into the continuation code. */
}
Index: except.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/except.h,v
retrieving revision 1.38
diff -u -p -r1.38 except.h
--- except.h 2000/03/09 19:01:46 1.38
+++ except.h 2000/03/19 13:49:06
@@ -120,6 +120,8 @@ struct eh_status
/* Insns for all of the exception handlers for the current function.
They are currently emitted by the frontend code. */
rtx x_catch_clauses;
+ /* End of exception handler insn sequence. */
+ rtx x_catch_clauses_last;
/* A random data area for the front end's own use. */
struct label_node *x_false_label_stack;
/* Keeps track of the label to resume to should one want to resume
@@ -142,6 +144,7 @@ struct eh_status
#define catchstack (cfun->eh->x_catchstack)
#define ehqueue (cfun->eh->x_ehqueue)
#define catch_clauses (cfun->eh->x_catch_clauses)
+#define catch_clauses_last (cfun->eh->x_catch_clauses_last)
#define false_label_stack (cfun->eh->x_false_label_stack)
#define caught_return_label_stack (cfun->eh->x_caught_return_label_stack)
#define protect_list (cfun->eh->x_protect_list)
Index: function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.176
diff -u -p -r1.176 function.c
--- function.c 2000/03/17 22:40:44 1.176
+++ function.c 2000/03/19 13:49:14
@@ -1548,10 +1548,10 @@ fixup_var_refs (var, promoted_mode, unsi
}
/* Scan the catch clauses for exception handling too. */
- push_to_sequence (catch_clauses);
+ push_to_full_sequence (catch_clauses, catch_clauses_last);
fixup_var_refs_insns (var, promoted_mode, unsignedp, catch_clauses,
0, 0);
- end_sequence ();
+ end_full_sequence (&catch_clauses, &catch_clauses_last);
/* Scan sequences saved in CALL_PLACEHOLDERS too. */
for (insn = first_insn; insn; insn = NEXT_INSN (insn))
@@ -6559,7 +6559,7 @@ expand_function_end (filename, line, end
/* If there are any catch_clauses remaining, output them now. */
emit_insns (catch_clauses);
- catch_clauses = NULL_RTX;
+ catch_clauses = catch_clauses_last = NULL_RTX;
/* If the above emitted any code, may sure we jump around it. */
if (last != get_last_insn ())
{
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.179
diff -u -p -r1.179 rtl.h
--- rtl.h 2000/03/17 22:40:44 1.179
+++ rtl.h 2000/03/19 13:49:17
@@ -1012,6 +1012,8 @@ extern rtx get_last_insn_anywhere PARAMS
extern void start_sequence PARAMS ((void));
extern void push_to_sequence PARAMS ((rtx));
extern void end_sequence PARAMS ((void));
+extern void push_to_full_sequence PARAMS ((rtx, rtx));
+extern void end_full_sequence PARAMS ((rtx*, rtx*));
extern rtx gen_sequence PARAMS ((void));
extern rtx immed_double_const PARAMS ((HOST_WIDE_INT, HOST_WIDE_INT, enum machine_mode));
extern rtx force_const_mem PARAMS ((enum machine_mode, rtx));
Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/except.c,v
retrieving revision 1.105
diff -u -p -r1.105 except.c
--- except.c 2000/03/14 08:11:38 1.105
+++ except.c 2000/03/19 14:30:23
@@ -796,13 +796,13 @@ expand_exception_blocks ()
expand_eh_region_start ();
emit_insns (catch_clauses);
- catch_clauses = NULL_RTX;
+ catch_clauses = catch_clauses_last = NULL_RTX;
if (exceptions_via_longjmp == 0)
expand_eh_region_end (build_terminate_handler ());
emit_insns (catch_clauses);
- catch_clauses = NULL_RTX;
+ catch_clauses = catch_clauses_last = NULL_RTX;
emit_label (funcend);
}
}
Index: java/except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/except.c,v
retrieving revision 1.21
diff -u -p -r1.21 except.c
--- except.c 2000/02/26 19:56:23 1.21
+++ except.c 2000/03/19 13:49:52
@@ -433,7 +433,7 @@ emit_handlers ()
emit_jump (funcend);
emit_insns (catch_clauses);
- catch_clauses = NULL_RTX;
+ catch_clauses = catch_clauses_last = NULL_RTX;
expand_leftover_cleanups ();
emit_label (funcend);