1996-09-14 20:47:01 -04:00
|
|
|
|
/* Implements exception handling.
|
2001-12-12 09:27:29 +01:00
|
|
|
|
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
2002-01-03 00:53:36 +00:00
|
|
|
|
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
1996-07-23 20:20:04 +00:00
|
|
|
|
Contributed by Mike Stump <mrs@cygnus.com>.
|
|
|
|
|
|
Makefile.in, [...]: replace "GNU CC" with "GCC".
* Makefile.in, alias.c, basic-block.h, bb-reorder.c, bitmap.c,
bitmap.h, builtin-types.def, builtins.c, builtins.def,
c-aux-info.c, c-common.c, c-common.def, c-common.h,
c-convert.c, c-decl.c, c-dump.c, c-dump.h, c-errors.c,
c-format.c, c-lang.c, c-lex.c, c-lex.h, c-parse.in,
c-pragma.c, c-pragma.h, c-semantics.c, c-tree.h, c-typeck.c,
caller-save.c, calls.c, collect2.c, collect2.h, combine.c,
conditions.h, config.gcc, configure.frag, configure.in,
conflict.c, convert.c, convert.h, cppspec.c, crtstuff.c,
cse.c, cselib.c, cselib.h, dbxout.c, dbxout.h, defaults.h,
dependence.c, df.c, df.h, diagnostic.c, diagnostic.h,
doloop.c, dominance.c, dwarf.h, dwarf2.h, dwarf2asm.c,
dwarf2asm.h, dwarf2out.c, dwarf2out.h, dwarfout.c,
emit-rtl.c, errors.c, errors.h, except.c, except.h,
exgettext, explow.c, expmed.c, expr.c, expr.h, final.c,
fixproto, flags.h, flow.c, fold-const.c, fp-test.c,
function.c, function.h, gbl-ctors.h, gcc.c, gcc.h, gcc.hlp,
gccspec.c, gcov-io.h, gcse.c, genattr.c, genattrtab.c,
gencheck.c, gencodes.c, genconfig.c, genemit.c,
genextract.c, genflags.c, gengenrtl.c, genmultilib,
genopinit.c, genoutput.c, genpeep.c, genrecog.c,
gensupport.c, gensupport.h, ggc-callbacks.c, ggc-common.c,
ggc-none.c, ggc-page.c, ggc-simple.c, ggc.h, global.c,
graph.c, graph.h, gthr-aix.h, gthr-dce.h, gthr-posix.h,
gthr-rtems.h, gthr-single.h, gthr-solaris.h, gthr-vxworks.h,
gthr-win32.h, gthr.h, haifa-sched.c, halfpic.c, halfpic.h,
hard-reg-set.h, hwint.h, ifcvt.c, input.h, insn-addr.h,
integrate.c, integrate.h, jump.c, lcm.c, libgcc2.c,
libgcc2.h, lists.c, local-alloc.c, loop.c, loop.h,
machmode.def, machmode.h, main.c, mbchar.c, mbchar.h,
mips-tdump.c, mips-tfile.c, mklibgcc.in, mkmap-flat.awk,
mkmap-symver.awk, optabs.c, output.h, params.c, params.def,
params.h, predict.c, predict.def, predict.h, prefix.c,
prefix.h, print-rtl.c, print-tree.c, profile.c, protoize.c,
read-rtl.c, real.c, real.h, recog.c, recog.h, reg-stack.c,
regclass.c, regmove.c, regrename.c, regs.h, reload.c,
reload.h, reload1.c, reorg.c, resource.c, resource.h, rtl.c,
rtl.def, rtl.h, rtlanal.c, sbitmap.c, sbitmap.h,
sched-deps.c, sched-ebb.c, sched-int.h, sched-rgn.c,
sched-vis.c, sdbout.c, sdbout.h, sibcall.c, simplify-rtx.c,
ssa-ccp.c, ssa-dce.c, ssa.c, ssa.h, stmt.c, stor-layout.c,
stringpool.c, system.h, timevar.c, timevar.def, timevar.h,
tlink.c, toplev.c, toplev.h, tree.c, tree.def, tree.h,
tsystem.h, unroll.c, unwind-dw2-fde.c, unwind-dw2-fde.h,
unwind-dw2.c, unwind-pe.h, unwind-sjlj.c, unwind.h,
unwind.inc, varasm.c, varray.c, varray.h, xcoffout.c,
xcoffout.h: replace "GNU CC" with "GCC".
From-SVN: r45105
2001-08-22 14:35:51 +00:00
|
|
|
|
This file is part of GCC.
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
Makefile.in, [...]: replace "GNU CC" with "GCC".
* Makefile.in, alias.c, basic-block.h, bb-reorder.c, bitmap.c,
bitmap.h, builtin-types.def, builtins.c, builtins.def,
c-aux-info.c, c-common.c, c-common.def, c-common.h,
c-convert.c, c-decl.c, c-dump.c, c-dump.h, c-errors.c,
c-format.c, c-lang.c, c-lex.c, c-lex.h, c-parse.in,
c-pragma.c, c-pragma.h, c-semantics.c, c-tree.h, c-typeck.c,
caller-save.c, calls.c, collect2.c, collect2.h, combine.c,
conditions.h, config.gcc, configure.frag, configure.in,
conflict.c, convert.c, convert.h, cppspec.c, crtstuff.c,
cse.c, cselib.c, cselib.h, dbxout.c, dbxout.h, defaults.h,
dependence.c, df.c, df.h, diagnostic.c, diagnostic.h,
doloop.c, dominance.c, dwarf.h, dwarf2.h, dwarf2asm.c,
dwarf2asm.h, dwarf2out.c, dwarf2out.h, dwarfout.c,
emit-rtl.c, errors.c, errors.h, except.c, except.h,
exgettext, explow.c, expmed.c, expr.c, expr.h, final.c,
fixproto, flags.h, flow.c, fold-const.c, fp-test.c,
function.c, function.h, gbl-ctors.h, gcc.c, gcc.h, gcc.hlp,
gccspec.c, gcov-io.h, gcse.c, genattr.c, genattrtab.c,
gencheck.c, gencodes.c, genconfig.c, genemit.c,
genextract.c, genflags.c, gengenrtl.c, genmultilib,
genopinit.c, genoutput.c, genpeep.c, genrecog.c,
gensupport.c, gensupport.h, ggc-callbacks.c, ggc-common.c,
ggc-none.c, ggc-page.c, ggc-simple.c, ggc.h, global.c,
graph.c, graph.h, gthr-aix.h, gthr-dce.h, gthr-posix.h,
gthr-rtems.h, gthr-single.h, gthr-solaris.h, gthr-vxworks.h,
gthr-win32.h, gthr.h, haifa-sched.c, halfpic.c, halfpic.h,
hard-reg-set.h, hwint.h, ifcvt.c, input.h, insn-addr.h,
integrate.c, integrate.h, jump.c, lcm.c, libgcc2.c,
libgcc2.h, lists.c, local-alloc.c, loop.c, loop.h,
machmode.def, machmode.h, main.c, mbchar.c, mbchar.h,
mips-tdump.c, mips-tfile.c, mklibgcc.in, mkmap-flat.awk,
mkmap-symver.awk, optabs.c, output.h, params.c, params.def,
params.h, predict.c, predict.def, predict.h, prefix.c,
prefix.h, print-rtl.c, print-tree.c, profile.c, protoize.c,
read-rtl.c, real.c, real.h, recog.c, recog.h, reg-stack.c,
regclass.c, regmove.c, regrename.c, regs.h, reload.c,
reload.h, reload1.c, reorg.c, resource.c, resource.h, rtl.c,
rtl.def, rtl.h, rtlanal.c, sbitmap.c, sbitmap.h,
sched-deps.c, sched-ebb.c, sched-int.h, sched-rgn.c,
sched-vis.c, sdbout.c, sdbout.h, sibcall.c, simplify-rtx.c,
ssa-ccp.c, ssa-dce.c, ssa.c, ssa.h, stmt.c, stor-layout.c,
stringpool.c, system.h, timevar.c, timevar.def, timevar.h,
tlink.c, toplev.c, toplev.h, tree.c, tree.def, tree.h,
tsystem.h, unroll.c, unwind-dw2-fde.c, unwind-dw2-fde.h,
unwind-dw2.c, unwind-pe.h, unwind-sjlj.c, unwind.h,
unwind.inc, varasm.c, varray.c, varray.h, xcoffout.c,
xcoffout.h: replace "GNU CC" with "GCC".
From-SVN: r45105
2001-08-22 14:35:51 +00:00
|
|
|
|
GCC is free software; you can redistribute it and/or modify it under
|
|
|
|
|
the terms of the GNU General Public License as published by the Free
|
|
|
|
|
Software Foundation; either version 2, or (at your option) any later
|
|
|
|
|
version.
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
Makefile.in, [...]: replace "GNU CC" with "GCC".
* Makefile.in, alias.c, basic-block.h, bb-reorder.c, bitmap.c,
bitmap.h, builtin-types.def, builtins.c, builtins.def,
c-aux-info.c, c-common.c, c-common.def, c-common.h,
c-convert.c, c-decl.c, c-dump.c, c-dump.h, c-errors.c,
c-format.c, c-lang.c, c-lex.c, c-lex.h, c-parse.in,
c-pragma.c, c-pragma.h, c-semantics.c, c-tree.h, c-typeck.c,
caller-save.c, calls.c, collect2.c, collect2.h, combine.c,
conditions.h, config.gcc, configure.frag, configure.in,
conflict.c, convert.c, convert.h, cppspec.c, crtstuff.c,
cse.c, cselib.c, cselib.h, dbxout.c, dbxout.h, defaults.h,
dependence.c, df.c, df.h, diagnostic.c, diagnostic.h,
doloop.c, dominance.c, dwarf.h, dwarf2.h, dwarf2asm.c,
dwarf2asm.h, dwarf2out.c, dwarf2out.h, dwarfout.c,
emit-rtl.c, errors.c, errors.h, except.c, except.h,
exgettext, explow.c, expmed.c, expr.c, expr.h, final.c,
fixproto, flags.h, flow.c, fold-const.c, fp-test.c,
function.c, function.h, gbl-ctors.h, gcc.c, gcc.h, gcc.hlp,
gccspec.c, gcov-io.h, gcse.c, genattr.c, genattrtab.c,
gencheck.c, gencodes.c, genconfig.c, genemit.c,
genextract.c, genflags.c, gengenrtl.c, genmultilib,
genopinit.c, genoutput.c, genpeep.c, genrecog.c,
gensupport.c, gensupport.h, ggc-callbacks.c, ggc-common.c,
ggc-none.c, ggc-page.c, ggc-simple.c, ggc.h, global.c,
graph.c, graph.h, gthr-aix.h, gthr-dce.h, gthr-posix.h,
gthr-rtems.h, gthr-single.h, gthr-solaris.h, gthr-vxworks.h,
gthr-win32.h, gthr.h, haifa-sched.c, halfpic.c, halfpic.h,
hard-reg-set.h, hwint.h, ifcvt.c, input.h, insn-addr.h,
integrate.c, integrate.h, jump.c, lcm.c, libgcc2.c,
libgcc2.h, lists.c, local-alloc.c, loop.c, loop.h,
machmode.def, machmode.h, main.c, mbchar.c, mbchar.h,
mips-tdump.c, mips-tfile.c, mklibgcc.in, mkmap-flat.awk,
mkmap-symver.awk, optabs.c, output.h, params.c, params.def,
params.h, predict.c, predict.def, predict.h, prefix.c,
prefix.h, print-rtl.c, print-tree.c, profile.c, protoize.c,
read-rtl.c, real.c, real.h, recog.c, recog.h, reg-stack.c,
regclass.c, regmove.c, regrename.c, regs.h, reload.c,
reload.h, reload1.c, reorg.c, resource.c, resource.h, rtl.c,
rtl.def, rtl.h, rtlanal.c, sbitmap.c, sbitmap.h,
sched-deps.c, sched-ebb.c, sched-int.h, sched-rgn.c,
sched-vis.c, sdbout.c, sdbout.h, sibcall.c, simplify-rtx.c,
ssa-ccp.c, ssa-dce.c, ssa.c, ssa.h, stmt.c, stor-layout.c,
stringpool.c, system.h, timevar.c, timevar.def, timevar.h,
tlink.c, toplev.c, toplev.h, tree.c, tree.def, tree.h,
tsystem.h, unroll.c, unwind-dw2-fde.c, unwind-dw2-fde.h,
unwind-dw2.c, unwind-pe.h, unwind-sjlj.c, unwind.h,
unwind.inc, varasm.c, varray.c, varray.h, xcoffout.c,
xcoffout.h: replace "GNU CC" with "GCC".
From-SVN: r45105
2001-08-22 14:35:51 +00:00
|
|
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
|
for more details.
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
Makefile.in, [...]: replace "GNU CC" with "GCC".
* Makefile.in, alias.c, basic-block.h, bb-reorder.c, bitmap.c,
bitmap.h, builtin-types.def, builtins.c, builtins.def,
c-aux-info.c, c-common.c, c-common.def, c-common.h,
c-convert.c, c-decl.c, c-dump.c, c-dump.h, c-errors.c,
c-format.c, c-lang.c, c-lex.c, c-lex.h, c-parse.in,
c-pragma.c, c-pragma.h, c-semantics.c, c-tree.h, c-typeck.c,
caller-save.c, calls.c, collect2.c, collect2.h, combine.c,
conditions.h, config.gcc, configure.frag, configure.in,
conflict.c, convert.c, convert.h, cppspec.c, crtstuff.c,
cse.c, cselib.c, cselib.h, dbxout.c, dbxout.h, defaults.h,
dependence.c, df.c, df.h, diagnostic.c, diagnostic.h,
doloop.c, dominance.c, dwarf.h, dwarf2.h, dwarf2asm.c,
dwarf2asm.h, dwarf2out.c, dwarf2out.h, dwarfout.c,
emit-rtl.c, errors.c, errors.h, except.c, except.h,
exgettext, explow.c, expmed.c, expr.c, expr.h, final.c,
fixproto, flags.h, flow.c, fold-const.c, fp-test.c,
function.c, function.h, gbl-ctors.h, gcc.c, gcc.h, gcc.hlp,
gccspec.c, gcov-io.h, gcse.c, genattr.c, genattrtab.c,
gencheck.c, gencodes.c, genconfig.c, genemit.c,
genextract.c, genflags.c, gengenrtl.c, genmultilib,
genopinit.c, genoutput.c, genpeep.c, genrecog.c,
gensupport.c, gensupport.h, ggc-callbacks.c, ggc-common.c,
ggc-none.c, ggc-page.c, ggc-simple.c, ggc.h, global.c,
graph.c, graph.h, gthr-aix.h, gthr-dce.h, gthr-posix.h,
gthr-rtems.h, gthr-single.h, gthr-solaris.h, gthr-vxworks.h,
gthr-win32.h, gthr.h, haifa-sched.c, halfpic.c, halfpic.h,
hard-reg-set.h, hwint.h, ifcvt.c, input.h, insn-addr.h,
integrate.c, integrate.h, jump.c, lcm.c, libgcc2.c,
libgcc2.h, lists.c, local-alloc.c, loop.c, loop.h,
machmode.def, machmode.h, main.c, mbchar.c, mbchar.h,
mips-tdump.c, mips-tfile.c, mklibgcc.in, mkmap-flat.awk,
mkmap-symver.awk, optabs.c, output.h, params.c, params.def,
params.h, predict.c, predict.def, predict.h, prefix.c,
prefix.h, print-rtl.c, print-tree.c, profile.c, protoize.c,
read-rtl.c, real.c, real.h, recog.c, recog.h, reg-stack.c,
regclass.c, regmove.c, regrename.c, regs.h, reload.c,
reload.h, reload1.c, reorg.c, resource.c, resource.h, rtl.c,
rtl.def, rtl.h, rtlanal.c, sbitmap.c, sbitmap.h,
sched-deps.c, sched-ebb.c, sched-int.h, sched-rgn.c,
sched-vis.c, sdbout.c, sdbout.h, sibcall.c, simplify-rtx.c,
ssa-ccp.c, ssa-dce.c, ssa.c, ssa.h, stmt.c, stor-layout.c,
stringpool.c, system.h, timevar.c, timevar.def, timevar.h,
tlink.c, toplev.c, toplev.h, tree.c, tree.def, tree.h,
tsystem.h, unroll.c, unwind-dw2-fde.c, unwind-dw2-fde.h,
unwind-dw2.c, unwind-pe.h, unwind-sjlj.c, unwind.h,
unwind.inc, varasm.c, varray.c, varray.h, xcoffout.c,
xcoffout.h: replace "GNU CC" with "GCC".
From-SVN: r45105
2001-08-22 14:35:51 +00:00
|
|
|
|
along with GCC; see the file COPYING. If not, write to the Free
|
|
|
|
|
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
|
02111-1307, USA. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
|
|
|
|
|
1996-09-14 20:47:01 -04:00
|
|
|
|
/* An exception is an event that can be signaled from within a
|
|
|
|
|
function. This event can then be "caught" or "trapped" by the
|
|
|
|
|
callers of this function. This potentially allows program flow to
|
1997-12-06 17:31:01 -07:00
|
|
|
|
be transferred to any arbitrary code associated with a function call
|
1996-09-14 20:47:01 -04:00
|
|
|
|
several levels up the stack.
|
|
|
|
|
|
|
|
|
|
The intended use for this mechanism is for signaling "exceptional
|
|
|
|
|
events" in an out-of-band fashion, hence its name. The C++ language
|
|
|
|
|
(and many other OO-styled or functional languages) practically
|
|
|
|
|
requires such a mechanism, as otherwise it becomes very difficult
|
|
|
|
|
or even impossible to signal failure conditions in complex
|
|
|
|
|
situations. The traditional C++ example is when an error occurs in
|
|
|
|
|
the process of constructing an object; without such a mechanism, it
|
|
|
|
|
is impossible to signal that the error occurs without adding global
|
|
|
|
|
state variables and error checks around every object construction.
|
|
|
|
|
|
|
|
|
|
The act of causing this event to occur is referred to as "throwing
|
|
|
|
|
an exception". (Alternate terms include "raising an exception" or
|
|
|
|
|
"signaling an exception".) The term "throw" is used because control
|
|
|
|
|
is returned to the callers of the function that is signaling the
|
|
|
|
|
exception, and thus there is the concept of "throwing" the
|
|
|
|
|
exception up the call stack.
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
[ Add updated documentation on how to use this. ] */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "config.h"
|
Major cutover to using system.h:
* Makefile.in (alias.o, bitmap.o, c-aux-info.o, c-common.o,
c-decl.o, c-iterate.o, c-lang.o, c-lex.o, c-pragma.o, c-typeck.o,
caller-save.o, calls.o, collect2.o, combine.o, cse.o, dbxout.o,
dwarf2out.o, dwarfout.o, emit-rtl.o, except.o, explow.o, expmed.o,
expr.o, final.o, flow.o, function.o, getpwd.o, global.o,
integrate.o, jump.o, local-alloc.o, loop.o, optabs.o, pexecute.o,
prefix.o, print-rtl.o, print-tree.o, profile.o, real.o, recog.o,
reg-stack.o, regclass.o, regmove.o, reload.o, reload1.o, reorg.o,
rtl.o, rtlanal.o, sdbout.o, stmt.o, stor-layout.o, stupid.o,
tlink.o, toplev.o, tree.o, unroll.o, varasm.o, xcoffout.o): Depend
on system.h.
* alias.c, bitmap.c, c-aux-info.c, c-common.c, c-decl.c,
c-iterate.c, c-lang.c, c-lex.c, c-pragma.c, c-typeck.c,
caller-save.c, calls.c, collect2.c, combine.c, cse.c, dbxout.c,
dwarf2out.c, dwarfout.c, emit-rtl.c, except.c, explow.c, expmed.c,
expr.c, final.c, flow.c, function.c, gcc.c, getpwd.c, global.c,
integrate.c, jump.c, local-alloc.c, loop.c, optabs.c, pexecute.c,
prefix.c, print-rtl.c, print-tree.c, profile.c, real.c, recog.c,
reg-stack.c, regclass.c, regmove.c, reload.c, reload1.c, reorg.c,
rtl.c, rtlanal.c, sched.c, sdbout.c, stmt.c, stor-layout.c,
stupid.c, tlink.c, toplev.c, tree.c, unroll.c, varasm.c,
xcoffout.c: Include system.h. Organize include ordering so
that stdarg/varargs comes before other system headers. Remove
spurious casts of functions assured of a prototype in system.h.
From-SVN: r18726
1998-03-20 14:58:42 +00:00
|
|
|
|
#include "system.h"
|
2002-12-16 18:23:00 +00:00
|
|
|
|
#include "coretypes.h"
|
|
|
|
|
#include "tm.h"
|
1996-07-23 20:20:04 +00:00
|
|
|
|
#include "rtl.h"
|
|
|
|
|
#include "tree.h"
|
|
|
|
|
#include "flags.h"
|
|
|
|
|
#include "function.h"
|
|
|
|
|
#include "expr.h"
|
expr.h: Split out optab- and libfunc-related code to...
* expr.h: Split out optab- and libfunc-related code to...
* optabs.h, libfuncs.h: ... these new headers.
* Makefile.in (CONFIG_H, EXPR_H): Take out insn-codes.h.
(OPTABS_H): New.
(various .o rules): Add $(OPTABS_H) and/or libfuncs.h to
dependencies.
* mkconfig.sh: Don't include insn-codes.h from config.h.
* reload.h: Use #ifdef GCC_INSN_CODES_H to decide whether
enum insn_code is available. Move reload_in_optab and
reload_out_optab array declarations to optabs.h.
* regmove.c (gen_add3_insn): Move to optabs.c, export from
there, prototype in expr.h.
* gencodes.c: Cleanup: zap global variables, don't use
printf where puts will do, don't bother defining MAX_INSN_CODE
which nothing uses, let CODE_FOR_nothing get its value implicitly.
* genemit.c, genopinit.c: Include optabs.h in generated file.
* genoutput.c: Include insn-codes.h in generated file.
* builtins.c, caller-save.c, combine.c, doloop.c, explow.c,
expmed.c, expr.c, function.c, ifcvt.c, loop.c, optabs.c, profile.c,
reload1.c, simplify-rtx.c, stmt.c, unroll.c, config/alpha/alpha.c,
config/arm/arm.c, config/c4x/c4x.c, config/clipper/clipper.c,
config/i386/i386.c, config/ia64/ia64.c, config/mn10300/mn10300.c,
config/pj/pj.c, config/sh/sh.c, config/sparc/sparc.c:
Include optabs.h.
* builtins.c, calls.c, dwarf2out.c, except.c, expr.c, function.c,
optabs.c, stmt.c, config/c4x/c4x.c, config/clipper/clipper.c,
config/m88k/m88k.c, config/sparc/sparc.c:
Include libfuncs.h.
* reload.c: Include expr.h and optabs.h before reload.h.
* config/alpha/alpha.c: Include tree.h before reload.h.
* config/pa/pa.c: Include expr.h, optabs.h, libfuncs.h,
and reload.h in that order.
* config/sparc/sparc.c: Include debug.h.
* recog.c: Include insn-codes.h.
cp:
* Make-lang.in (cp/except.o): Add libfuncs.h to dependencies.
* except.c: Include libfuncs.h.
java:
* Make-lang.in (java/decl.o): Update dependencies.
* decl.c: Include libfuncs.h, don't include toplev.h.
From-SVN: r44858
2001-08-13 15:56:51 +00:00
|
|
|
|
#include "libfuncs.h"
|
1996-07-23 20:20:04 +00:00
|
|
|
|
#include "insn-config.h"
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#include "except.h"
|
|
|
|
|
#include "integrate.h"
|
|
|
|
|
#include "hard-reg-set.h"
|
|
|
|
|
#include "basic-block.h"
|
1996-07-23 20:20:04 +00:00
|
|
|
|
#include "output.h"
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#include "dwarf2asm.h"
|
|
|
|
|
#include "dwarf2out.h"
|
2001-05-11 23:03:20 -07:00
|
|
|
|
#include "dwarf2.h"
|
toplev.h: New file.
Wed May 6 06:35:38 1998 Robert Lipe <robertl@dgii.com>
* toplev.h: New file. Protypes for functions in toplev.c.
* tree.h, rtl.h: Deleted protos for functions in toplev.c.
* c-common.c, c-convert.c, c-decl.c, c-iterate.c, c-lex.c,
c-parse.in, c-parse.y, c-pragma.c, c-typeck.c, calls.c,
convert.c, dwarf2out.c, except.c, expr.c, final.c, fold-const.c,
function.c, hash.c, profile.c, real.c, reg-stack.c, regclass.c,
reload.c, reload1.c, stmt.c, stor-layout.c, tlink.c, tree.c,
varasm.c: include it.
From-SVN: r19564
1998-05-06 04:54:01 +00:00
|
|
|
|
#include "toplev.h"
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#include "hashtab.h"
|
1999-07-01 17:52:55 -06:00
|
|
|
|
#include "intl.h"
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
#include "ggc.h"
|
calls.c: Include tm_p.h later, so everything we need is defined.
* calls.c: Include tm_p.h later, so everything we need is defined.
* expr.c: Likewise.
* function.c: Likewise.
* except.c: Include tm_p.h.
* sparc.c: Likewise.
(dwarf2out_cfi_label): Don't prototype.
(check_return_regs, epilogue_renumber,
ultra_cmove_results_ready_p, ultra_fpmode_conflict_exists,
ultra_find_type, ultra_build_types_avail, ultra_flush_pipeline,
ultra_rescan_pipeline_state, set_extends, ultra_code_from_mask,
ultra_schedule_insn): Add static prototype.
(data_segment_operand, text_segment_operand): Call itself with the
proper number of arguments.
(sparc_flat_save_restore, sparc_v8plus_shift): Constify a char*.
* sparc.h: Move all declarations to sparc-protos.h.
(SELECT_RTX_SECTION): Pass a missing MODE argument to
symbolic_operand.
* sparc/sysv4.h (SELECT_RTX_SECTION): Likewise.
* config/svr4.h (text_section, ctors_section, dtors_section): Add
Prototypes.
(ASM_OUTPUT_SECTION_NAME, UNIQUE_SECTION,
ASM_FINISH_DECLARE_OBJECT, ASM_OUTPUT_LIMITED_STRING,
ASM_OUTPUT_ASCII): Constify a char*.
* sparc-protos.h: New file for sparc prototypes.
cp:
* expr.c: Include tm_p.h.
From-SVN: r30122
1999-10-21 16:58:33 +00:00
|
|
|
|
#include "tm_p.h"
|
2001-10-22 14:43:31 +00:00
|
|
|
|
#include "target.h"
|
2002-03-29 08:43:22 +00:00
|
|
|
|
#include "langhooks.h"
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* Provide defaults for stuff that may not be defined when using
|
|
|
|
|
sjlj exceptions. */
|
|
|
|
|
#ifndef EH_RETURN_DATA_REGNO
|
|
|
|
|
#define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM
|
2001-03-27 22:11:49 -08:00
|
|
|
|
#endif
|
|
|
|
|
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Nonzero means enable synchronous exceptions for non-call instructions. */
|
|
|
|
|
int flag_non_call_exceptions;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Protect cleanup actions with must-not-throw regions, with a call
|
|
|
|
|
to the given failure handler. */
|
2001-05-17 18:12:27 +00:00
|
|
|
|
tree (*lang_protect_cleanup_actions) PARAMS ((void));
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Return true if type A catches type B. */
|
|
|
|
|
int (*lang_eh_type_covers) PARAMS ((tree a, tree b));
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Map a type to a runtime object to match type. */
|
|
|
|
|
tree (*lang_eh_runtime_type) PARAMS ((tree));
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2002-04-09 17:15:58 -07:00
|
|
|
|
/* A hash table of label to region number. */
|
|
|
|
|
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct ehl_map_entry GTY(())
|
2002-04-09 17:15:58 -07:00
|
|
|
|
{
|
|
|
|
|
rtx label;
|
|
|
|
|
struct eh_region *region;
|
|
|
|
|
};
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static int call_site_base;
|
2002-06-04 07:11:05 +00:00
|
|
|
|
static GTY ((param_is (union tree_node)))
|
|
|
|
|
htab_t type_to_runtime_map;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* Describe the SjLj_Function_Context structure. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
static GTY(()) tree sjlj_fc_type_node;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static int sjlj_fc_call_site_ofs;
|
|
|
|
|
static int sjlj_fc_data_ofs;
|
|
|
|
|
static int sjlj_fc_personality_ofs;
|
|
|
|
|
static int sjlj_fc_lsda_ofs;
|
|
|
|
|
static int sjlj_fc_jbuf_ofs;
|
|
|
|
|
|
|
|
|
|
/* Describes one exception region. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct eh_region GTY(())
|
2001-03-28 03:04:51 -08:00
|
|
|
|
{
|
|
|
|
|
/* The immediately surrounding region. */
|
|
|
|
|
struct eh_region *outer;
|
1997-12-06 17:31:01 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* The list of immediately contained regions. */
|
|
|
|
|
struct eh_region *inner;
|
|
|
|
|
struct eh_region *next_peer;
|
1997-12-06 17:31:01 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* An identifier for this region. */
|
|
|
|
|
int region_number;
|
tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused.
* tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused. Kill.
(BUILT_IN_FP, BUILT_IN_SP, BUILT_IN_SET_RETURN_ADDR_REG): Kill.
(BUILT_IN_EH_STUB_OLD, BUILT_IN_EH_STUB, BUILT_IN_SET_EH_REGS): Kill.
(BUILT_IN_EH_RETURN, BUILT_IN_DWARF_CFA): New.
* c-decl.c (init_decl_processing): Update accordingly.
* expr.c (expand_builtin): Likewise.
* cp/decl.c (init_decl_processing): Likewise.
* rtl.h (global_rtl): Add cfa entry.
(virtual_cfa_rtx, VIRTUAL_CFA_REGNUM): New.
(LAST_VIRTUAL_REGISTER): Update.
* emit-rtl.c (global_rtl): Add cfa entry.
(init_emit): Initialize it.
* function.c (cfa_offset): New.
(instantiate_virtual_regs): Initialize it.
(instantiate_virtual_regs_1): Instantiate virtual_cfa_rtx.
(expand_function_end): Call expand_eh_return.
* tm.texi (ARG_POINTER_CFA_OFFSET): New.
* except.c (current_function_eh_stub_label): Kill.
(current_function_eh_old_stub_label): Likwise; update all references.
(expand_builtin_set_return_addr_reg): Kill.
(expand_builtin_eh_stub_old, expand_builtin_eh_stub): Kill.
(expand_builtin_set_eh_regs): Kill.
(eh_regs): Produce a third reg for the actual handler address.
(eh_return_context, eh_return_stack_adjust): New.
(eh_return_handler, eh_return_stub_label): New.
(init_eh_for_function): Initialize them.
(expand_builtin_eh_return, expand_eh_return): New.
* except.h: Update prototypes.
* flow.c (find_basic_blocks_1): Update references to the stub label.
* function.h (struct function): Kill stub label elements.
* libgcc2.c (in_reg_window): For REG_SAVED_REG, check that the
register number is one that would be in the previous window.
Provide a dummy definition for non-windowed targets.
(get_reg_addr): New function.
(get_reg, put_reg, copy_reg): Use it.
(__throw): Rely on in_reg_window, not INCOMING_REGNO. Kill stub
generating code and use __builtin_eh_return. Use __builtin_dwarf_cfa.
* alpha.c (alpha_eh_epilogue_sp_ofs): New.
(alpha_init_expanders): Initialize it.
(alpha_expand_epilogue): Use it.
* alpha.h: Declare it.
* alpha.md (eh_epilogue): New.
* m68h.h (ARG_POINTER_CFA_OFFSET): New.
* sparc.h (ARG_POINTER_CFA_OFFSET): New.
From-SVN: r22436
1998-09-15 12:19:12 -07:00
|
|
|
|
|
2002-04-09 17:15:58 -07:00
|
|
|
|
/* When a region is deleted, its parents inherit the REG_EH_REGION
|
|
|
|
|
numbers already assigned. */
|
|
|
|
|
bitmap aka;
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Each region does exactly one thing. */
|
|
|
|
|
enum eh_region_type
|
|
|
|
|
{
|
2001-11-17 17:33:57 +00:00
|
|
|
|
ERT_UNKNOWN = 0,
|
|
|
|
|
ERT_CLEANUP,
|
2001-03-28 03:04:51 -08:00
|
|
|
|
ERT_TRY,
|
|
|
|
|
ERT_CATCH,
|
|
|
|
|
ERT_ALLOWED_EXCEPTIONS,
|
|
|
|
|
ERT_MUST_NOT_THROW,
|
|
|
|
|
ERT_THROW,
|
|
|
|
|
ERT_FIXUP
|
|
|
|
|
} type;
|
|
|
|
|
|
ChangeLog.2, [...]: Fix spelling errors.
* ChangeLog.2, ChangeLog.3, ChangeLog.4, ChangeLog.5, ChangeLog,
cfg.c, cfganal.c, cfgcleanup.c, cfglayout.c, cfgloop.c, cfgrtl.c,
collect2.c, combine.c, config.in, configure, configure.in,
conflict.c, dwarf2out.c, dwarfout.c, except.c, final.c, flow.c,
genattrtab.c, ggc-page.c, jump.c, lcm.c, predict.c, reg-stack.c,
reload1.c, rtlanal.c, sched-rgn.c, toplev.c, unwind-dw2-fde.h: Fix
spelling errors.
From-SVN: r46928
2001-11-11 11:25:28 +00:00
|
|
|
|
/* Holds the action to perform based on the preceding type. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
union eh_region_u {
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* A list of catch blocks, a surrounding try block,
|
|
|
|
|
and the label for continuing after a catch. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct eh_region_u_try {
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *catch;
|
|
|
|
|
struct eh_region *last_catch;
|
|
|
|
|
struct eh_region *prev_try;
|
|
|
|
|
rtx continue_label;
|
2002-06-04 07:11:05 +00:00
|
|
|
|
} GTY ((tag ("ERT_TRY"))) try;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
/* The list through the catch handlers, the list of type objects
|
|
|
|
|
matched, and the list of associated filters. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct eh_region_u_catch {
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *next_catch;
|
|
|
|
|
struct eh_region *prev_catch;
|
2001-11-16 13:48:18 +01:00
|
|
|
|
tree type_list;
|
|
|
|
|
tree filter_list;
|
2002-06-04 07:11:05 +00:00
|
|
|
|
} GTY ((tag ("ERT_CATCH"))) catch;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* A tree_list of allowed types. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct eh_region_u_allowed {
|
2001-03-28 03:04:51 -08:00
|
|
|
|
tree type_list;
|
|
|
|
|
int filter;
|
2002-06-04 07:11:05 +00:00
|
|
|
|
} GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
2001-12-12 09:27:29 +01:00
|
|
|
|
/* The type given by a call to "throw foo();", or discovered
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for a throw. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct eh_region_u_throw {
|
2001-03-28 03:04:51 -08:00
|
|
|
|
tree type;
|
2002-06-04 07:11:05 +00:00
|
|
|
|
} GTY ((tag ("ERT_THROW"))) throw;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* Retain the cleanup expression even after expansion so that
|
|
|
|
|
we can match up fixup regions. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct eh_region_u_cleanup {
|
2001-03-28 03:04:51 -08:00
|
|
|
|
tree exp;
|
2003-03-17 06:09:30 +00:00
|
|
|
|
struct eh_region *prev_try;
|
2002-06-04 07:11:05 +00:00
|
|
|
|
} GTY ((tag ("ERT_CLEANUP"))) cleanup;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* The real region (by expression and by pointer) that fixup code
|
|
|
|
|
should live in. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct eh_region_u_fixup {
|
2001-03-28 03:04:51 -08:00
|
|
|
|
tree cleanup_exp;
|
|
|
|
|
struct eh_region *real_region;
|
2002-06-04 07:11:05 +00:00
|
|
|
|
} GTY ((tag ("ERT_FIXUP"))) fixup;
|
|
|
|
|
} GTY ((desc ("%0.type"))) u;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
2001-04-24 20:23:10 -04:00
|
|
|
|
/* Entry point for this region's handler before landing pads are built. */
|
|
|
|
|
rtx label;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
2001-04-24 20:23:10 -04:00
|
|
|
|
/* Entry point for this region's handler from the runtime eh library. */
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx landing_pad;
|
|
|
|
|
|
2001-04-24 20:23:10 -04:00
|
|
|
|
/* Entry point for this region's handler from an inner region. */
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx post_landing_pad;
|
2001-04-24 20:23:10 -04:00
|
|
|
|
|
|
|
|
|
/* The RESX insn for handing off control to the next outermost handler,
|
|
|
|
|
if appropriate. */
|
|
|
|
|
rtx resume;
|
2003-04-22 05:44:12 +00:00
|
|
|
|
|
|
|
|
|
/* True if something in this region may throw. */
|
|
|
|
|
unsigned may_contain_throw : 1;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
};
|
tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused.
* tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused. Kill.
(BUILT_IN_FP, BUILT_IN_SP, BUILT_IN_SET_RETURN_ADDR_REG): Kill.
(BUILT_IN_EH_STUB_OLD, BUILT_IN_EH_STUB, BUILT_IN_SET_EH_REGS): Kill.
(BUILT_IN_EH_RETURN, BUILT_IN_DWARF_CFA): New.
* c-decl.c (init_decl_processing): Update accordingly.
* expr.c (expand_builtin): Likewise.
* cp/decl.c (init_decl_processing): Likewise.
* rtl.h (global_rtl): Add cfa entry.
(virtual_cfa_rtx, VIRTUAL_CFA_REGNUM): New.
(LAST_VIRTUAL_REGISTER): Update.
* emit-rtl.c (global_rtl): Add cfa entry.
(init_emit): Initialize it.
* function.c (cfa_offset): New.
(instantiate_virtual_regs): Initialize it.
(instantiate_virtual_regs_1): Instantiate virtual_cfa_rtx.
(expand_function_end): Call expand_eh_return.
* tm.texi (ARG_POINTER_CFA_OFFSET): New.
* except.c (current_function_eh_stub_label): Kill.
(current_function_eh_old_stub_label): Likwise; update all references.
(expand_builtin_set_return_addr_reg): Kill.
(expand_builtin_eh_stub_old, expand_builtin_eh_stub): Kill.
(expand_builtin_set_eh_regs): Kill.
(eh_regs): Produce a third reg for the actual handler address.
(eh_return_context, eh_return_stack_adjust): New.
(eh_return_handler, eh_return_stub_label): New.
(init_eh_for_function): Initialize them.
(expand_builtin_eh_return, expand_eh_return): New.
* except.h: Update prototypes.
* flow.c (find_basic_blocks_1): Update references to the stub label.
* function.h (struct function): Kill stub label elements.
* libgcc2.c (in_reg_window): For REG_SAVED_REG, check that the
register number is one that would be in the previous window.
Provide a dummy definition for non-windowed targets.
(get_reg_addr): New function.
(get_reg, put_reg, copy_reg): Use it.
(__throw): Rely on in_reg_window, not INCOMING_REGNO. Kill stub
generating code and use __builtin_eh_return. Use __builtin_dwarf_cfa.
* alpha.c (alpha_eh_epilogue_sp_ofs): New.
(alpha_init_expanders): Initialize it.
(alpha_expand_epilogue): Use it.
* alpha.h: Declare it.
* alpha.md (eh_epilogue): New.
* m68h.h (ARG_POINTER_CFA_OFFSET): New.
* sparc.h (ARG_POINTER_CFA_OFFSET): New.
From-SVN: r22436
1998-09-15 12:19:12 -07:00
|
|
|
|
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct call_site_record GTY(())
|
|
|
|
|
{
|
|
|
|
|
rtx landing_pad;
|
|
|
|
|
int action;
|
|
|
|
|
};
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Used to save exception status for each function. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct eh_status GTY(())
|
2001-03-28 03:04:51 -08:00
|
|
|
|
{
|
|
|
|
|
/* The tree of all regions for this function. */
|
|
|
|
|
struct eh_region *region_tree;
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* The same information as an indexable array. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct eh_region ** GTY ((length ("%h.last_region_number"))) region_array;
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* The most recently open region. */
|
|
|
|
|
struct eh_region *cur_region;
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* This is the region for which we are processing catch blocks. */
|
|
|
|
|
struct eh_region *try_region;
|
tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused.
* tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused. Kill.
(BUILT_IN_FP, BUILT_IN_SP, BUILT_IN_SET_RETURN_ADDR_REG): Kill.
(BUILT_IN_EH_STUB_OLD, BUILT_IN_EH_STUB, BUILT_IN_SET_EH_REGS): Kill.
(BUILT_IN_EH_RETURN, BUILT_IN_DWARF_CFA): New.
* c-decl.c (init_decl_processing): Update accordingly.
* expr.c (expand_builtin): Likewise.
* cp/decl.c (init_decl_processing): Likewise.
* rtl.h (global_rtl): Add cfa entry.
(virtual_cfa_rtx, VIRTUAL_CFA_REGNUM): New.
(LAST_VIRTUAL_REGISTER): Update.
* emit-rtl.c (global_rtl): Add cfa entry.
(init_emit): Initialize it.
* function.c (cfa_offset): New.
(instantiate_virtual_regs): Initialize it.
(instantiate_virtual_regs_1): Instantiate virtual_cfa_rtx.
(expand_function_end): Call expand_eh_return.
* tm.texi (ARG_POINTER_CFA_OFFSET): New.
* except.c (current_function_eh_stub_label): Kill.
(current_function_eh_old_stub_label): Likwise; update all references.
(expand_builtin_set_return_addr_reg): Kill.
(expand_builtin_eh_stub_old, expand_builtin_eh_stub): Kill.
(expand_builtin_set_eh_regs): Kill.
(eh_regs): Produce a third reg for the actual handler address.
(eh_return_context, eh_return_stack_adjust): New.
(eh_return_handler, eh_return_stub_label): New.
(init_eh_for_function): Initialize them.
(expand_builtin_eh_return, expand_eh_return): New.
* except.h: Update prototypes.
* flow.c (find_basic_blocks_1): Update references to the stub label.
* function.h (struct function): Kill stub label elements.
* libgcc2.c (in_reg_window): For REG_SAVED_REG, check that the
register number is one that would be in the previous window.
Provide a dummy definition for non-windowed targets.
(get_reg_addr): New function.
(get_reg, put_reg, copy_reg): Use it.
(__throw): Rely on in_reg_window, not INCOMING_REGNO. Kill stub
generating code and use __builtin_eh_return. Use __builtin_dwarf_cfa.
* alpha.c (alpha_eh_epilogue_sp_ofs): New.
(alpha_init_expanders): Initialize it.
(alpha_expand_epilogue): Use it.
* alpha.h: Declare it.
* alpha.md (eh_epilogue): New.
* m68h.h (ARG_POINTER_CFA_OFFSET): New.
* sparc.h (ARG_POINTER_CFA_OFFSET): New.
From-SVN: r22436
1998-09-15 12:19:12 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx filter;
|
|
|
|
|
rtx exc_ptr;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int built_landing_pads;
|
|
|
|
|
int last_region_number;
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
varray_type ttype_data;
|
|
|
|
|
varray_type ehspec_data;
|
|
|
|
|
varray_type action_record_data;
|
2000-03-08 16:30:17 -05:00
|
|
|
|
|
2002-06-04 07:11:05 +00:00
|
|
|
|
htab_t GTY ((param_is (struct ehl_map_entry))) exception_handler_label_map;
|
|
|
|
|
|
|
|
|
|
struct call_site_record * GTY ((length ("%h.call_site_data_used")))
|
|
|
|
|
call_site_data;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int call_site_data_used;
|
|
|
|
|
int call_site_data_size;
|
|
|
|
|
|
|
|
|
|
rtx ehr_stackadj;
|
|
|
|
|
rtx ehr_handler;
|
|
|
|
|
rtx ehr_label;
|
|
|
|
|
|
|
|
|
|
rtx sjlj_fc;
|
|
|
|
|
rtx sjlj_exit_after;
|
|
|
|
|
};
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
static int t2r_eq PARAMS ((const PTR,
|
|
|
|
|
const PTR));
|
|
|
|
|
static hashval_t t2r_hash PARAMS ((const PTR));
|
|
|
|
|
static void add_type_for_runtime PARAMS ((tree));
|
|
|
|
|
static tree lookup_type_for_runtime PARAMS ((tree));
|
|
|
|
|
|
|
|
|
|
static struct eh_region *expand_eh_region_end PARAMS ((void));
|
|
|
|
|
|
2001-06-08 15:57:23 -07:00
|
|
|
|
static rtx get_exception_filter PARAMS ((struct function *));
|
2001-04-24 20:23:10 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void collect_eh_region_array PARAMS ((void));
|
|
|
|
|
static void resolve_fixup_regions PARAMS ((void));
|
|
|
|
|
static void remove_fixup_regions PARAMS ((void));
|
2002-01-14 22:06:26 +01:00
|
|
|
|
static void remove_unreachable_regions PARAMS ((rtx));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void convert_from_eh_region_ranges_1 PARAMS ((rtx *, int *, int));
|
|
|
|
|
|
|
|
|
|
static struct eh_region *duplicate_eh_region_1 PARAMS ((struct eh_region *,
|
|
|
|
|
struct inline_remap *));
|
|
|
|
|
static void duplicate_eh_region_2 PARAMS ((struct eh_region *,
|
|
|
|
|
struct eh_region **));
|
|
|
|
|
static int ttypes_filter_eq PARAMS ((const PTR,
|
|
|
|
|
const PTR));
|
|
|
|
|
static hashval_t ttypes_filter_hash PARAMS ((const PTR));
|
|
|
|
|
static int ehspec_filter_eq PARAMS ((const PTR,
|
|
|
|
|
const PTR));
|
|
|
|
|
static hashval_t ehspec_filter_hash PARAMS ((const PTR));
|
|
|
|
|
static int add_ttypes_entry PARAMS ((htab_t, tree));
|
|
|
|
|
static int add_ehspec_entry PARAMS ((htab_t, htab_t,
|
|
|
|
|
tree));
|
|
|
|
|
static void assign_filter_values PARAMS ((void));
|
|
|
|
|
static void build_post_landing_pads PARAMS ((void));
|
|
|
|
|
static void connect_post_landing_pads PARAMS ((void));
|
|
|
|
|
static void dw2_build_landing_pads PARAMS ((void));
|
|
|
|
|
|
|
|
|
|
struct sjlj_lp_info;
|
|
|
|
|
static bool sjlj_find_directly_reachable_regions
|
|
|
|
|
PARAMS ((struct sjlj_lp_info *));
|
|
|
|
|
static void sjlj_assign_call_site_values
|
|
|
|
|
PARAMS ((rtx, struct sjlj_lp_info *));
|
|
|
|
|
static void sjlj_mark_call_sites
|
|
|
|
|
PARAMS ((struct sjlj_lp_info *));
|
|
|
|
|
static void sjlj_emit_function_enter PARAMS ((rtx));
|
|
|
|
|
static void sjlj_emit_function_exit PARAMS ((void));
|
|
|
|
|
static void sjlj_emit_dispatch_table
|
|
|
|
|
PARAMS ((rtx, struct sjlj_lp_info *));
|
|
|
|
|
static void sjlj_build_landing_pads PARAMS ((void));
|
|
|
|
|
|
2002-04-09 17:15:58 -07:00
|
|
|
|
static hashval_t ehl_hash PARAMS ((const PTR));
|
|
|
|
|
static int ehl_eq PARAMS ((const PTR,
|
|
|
|
|
const PTR));
|
|
|
|
|
static void add_ehl_entry PARAMS ((rtx,
|
|
|
|
|
struct eh_region *));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void remove_exception_handler_label PARAMS ((rtx));
|
|
|
|
|
static void remove_eh_handler PARAMS ((struct eh_region *));
|
2002-04-09 17:15:58 -07:00
|
|
|
|
static int for_each_eh_label_1 PARAMS ((PTR *, PTR));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
struct reachable_info;
|
|
|
|
|
|
|
|
|
|
/* The return value of reachable_next_level. */
|
|
|
|
|
enum reachable_code
|
|
|
|
|
{
|
|
|
|
|
/* The given exception is not processed by the given region. */
|
|
|
|
|
RNL_NOT_CAUGHT,
|
|
|
|
|
/* The given exception may need processing by the given region. */
|
|
|
|
|
RNL_MAYBE_CAUGHT,
|
|
|
|
|
/* The given exception is completely processed by the given region. */
|
|
|
|
|
RNL_CAUGHT,
|
|
|
|
|
/* The given exception is completely processed by the runtime. */
|
|
|
|
|
RNL_BLOCKED
|
|
|
|
|
};
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static int check_handled PARAMS ((tree, tree));
|
|
|
|
|
static void add_reachable_handler
|
|
|
|
|
PARAMS ((struct reachable_info *, struct eh_region *,
|
|
|
|
|
struct eh_region *));
|
|
|
|
|
static enum reachable_code reachable_next_level
|
|
|
|
|
PARAMS ((struct eh_region *, tree, struct reachable_info *));
|
|
|
|
|
|
|
|
|
|
static int action_record_eq PARAMS ((const PTR,
|
|
|
|
|
const PTR));
|
|
|
|
|
static hashval_t action_record_hash PARAMS ((const PTR));
|
|
|
|
|
static int add_action_record PARAMS ((htab_t, int, int));
|
|
|
|
|
static int collect_one_action_chain PARAMS ((htab_t,
|
|
|
|
|
struct eh_region *));
|
|
|
|
|
static int add_call_site PARAMS ((rtx, int));
|
|
|
|
|
|
|
|
|
|
static void push_uleb128 PARAMS ((varray_type *,
|
|
|
|
|
unsigned int));
|
|
|
|
|
static void push_sleb128 PARAMS ((varray_type *, int));
|
|
|
|
|
#ifndef HAVE_AS_LEB128
|
|
|
|
|
static int dw2_size_of_call_site_table PARAMS ((void));
|
|
|
|
|
static int sjlj_size_of_call_site_table PARAMS ((void));
|
|
|
|
|
#endif
|
|
|
|
|
static void dw2_output_call_site_table PARAMS ((void));
|
|
|
|
|
static void sjlj_output_call_site_table PARAMS ((void));
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* Routine to see if exception handling is turned on.
|
2002-09-22 14:09:34 +00:00
|
|
|
|
DO_WARN is nonzero if we want to inform the user that exception
|
2001-12-12 09:27:29 +01:00
|
|
|
|
handling is turned off.
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
This is used to ensure that -fexceptions has been specified if the
|
|
|
|
|
compiler tries to use any exception-specific functions. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int
|
|
|
|
|
doing_eh (do_warn)
|
|
|
|
|
int do_warn;
|
|
|
|
|
{
|
|
|
|
|
if (! flag_exceptions)
|
|
|
|
|
{
|
|
|
|
|
static int warned = 0;
|
|
|
|
|
if (! warned && do_warn)
|
|
|
|
|
{
|
|
|
|
|
error ("exception handling disabled, use -fexceptions to enable");
|
|
|
|
|
warned = 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
init_eh ()
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! flag_exceptions)
|
|
|
|
|
return;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2002-06-04 07:11:05 +00:00
|
|
|
|
type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Create the SjLj_Function_Context structure. This should match
|
|
|
|
|
the definition in unwind-sjlj.c. */
|
|
|
|
|
if (USING_SJLJ_EXCEPTIONS)
|
|
|
|
|
{
|
|
|
|
|
tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2002-03-29 08:43:22 +00:00
|
|
|
|
sjlj_fc_type_node = (*lang_hooks.types.make_type) (RECORD_TYPE);
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
f_prev = build_decl (FIELD_DECL, get_identifier ("__prev"),
|
|
|
|
|
build_pointer_type (sjlj_fc_type_node));
|
|
|
|
|
DECL_FIELD_CONTEXT (f_prev) = sjlj_fc_type_node;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
f_cs = build_decl (FIELD_DECL, get_identifier ("__call_site"),
|
|
|
|
|
integer_type_node);
|
|
|
|
|
DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
tmp = build_index_type (build_int_2 (4 - 1, 0));
|
Makefile.in (convert.o, [...]): Update.
* Makefile.in (convert.o, calls.o, expmed.o): Update.
* attribs.c (handle_mode_attribute, handle_vector_size_attribute):
Use new hooks.
* builtin-types.def (BT_PTRMODE): Update.
* c-common.c (type_for_size): Rename c_common_type_for_size.
(type_for_mode): Similarly.
(shorten_compare, pointer_int_sum, c_common_nodes_and_builtins):
Use new hook.
* c-bommon.h (c_common_type_for_size, c_common_type_for_mode): New.
* c-decl.c (finish_enum, build_enumerator): Use new hooks.
* c-lang.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIZE):
Redefine.
* c-typeck.c (common_type, comptypes, default_conversion):
Use new hooks.
* calls.c: Include langhooks.h.
(emit_library_call_value_1): Use new hooks. Avoid redundant
calls.
* convert.c: Include langhooks.h
(convert_to_pointer, convert_to_integer): Use new hooks.
* except.c (init_eh): Similarly.
* expmed.c: Include langhooks.h.
(expand_mult_add): Use new hooks.
* expr.c (store_expr, store_constructor, expand_expr, do_jump,
try_casesi): Similarly.
* fold-const.c (optimize_bit_field_compare, make_range,
decode_field_reference, fold_truthop, fold): Similarly.
* function.c (assign_stack_local_1, assign_stack_temp_for_type,
put_var_into_stack): Similarly.
* langhooks-def.h (LANG_HOOKS_TYPE_FOR_MODE,
LANG_HOOKS_TYPE_FOR_SIZE): New.
(LANG_HOOKS_TYPES_INITIALIZER): Update.
* langhooks.h (lang_hooks_for_types): New hooks.
* stmt.c (expand_decl_cleanup, emit_case_nodes): Use new hooks.
* tree.c (get_unwidened, get_narrower): Similarly.
* tree.h (type_for_mode, type_for_size): Remove.
* varasm.c (force_const_mem): Use new hooks.
ada:
* gigi.h (type_for_size, type_for_mode): Rename.
* misc.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIZE):
Redefine.
* trans.c (tree_transform): Update.
* utils.c (gnat_init_decl_processing, init_gigi_decls,
builtin_function, float_type_for_size, signed_or_unsigned_type,
build_vms_descriptor, unchecked_convert): Update.
(type_for_mode, type_for_size): Rename.
* utils2.c (nonbinary_modular_operation): Update.
cp:
* cp-lang.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIZE):
Redefine.
* cvt.c (cp_convert_to_pointer, type_promotes_to): Use new hooks.
* decl.c (finish_enum): Similarly.
* error.c (dump_type): Similarly.
* lex.c (cxx_init): Similarly.
* mangle.c (write_builtin_type): Similarly.
* typeck.c (comptypes): Similarly.
f:
* com.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIZE):
Redefine.
(type_for_mode, type_for_size): Rename.
(signed_or_unsigned_type, signed_type, truthvalue_conversion,
unsigned_type): Use new hooks.
java:
* Make-lang.in (builtins.o): Update.
* boehm.c (get_boehm_type_descriptor): Update.
* builtins.c: Include langhooks.h.
* decl.c (java_init_decl_processing): Update.
* java-tree.h (java_type_for_mode, java_type_for_size): New.
* lang.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIaZE):
Redefine.
* typeck.c (type_for_mode, type_for_size): Update.
objc:
* objc-act.c (handle_impent): Update.
* objc-lang.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIaZE):
Redefine.
From-SVN: r51571
2002-03-29 21:46:27 +00:00
|
|
|
|
tmp = build_array_type ((*lang_hooks.types.type_for_mode) (word_mode, 1),
|
|
|
|
|
tmp);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp);
|
|
|
|
|
DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
f_per = build_decl (FIELD_DECL, get_identifier ("__personality"),
|
|
|
|
|
ptr_type_node);
|
|
|
|
|
DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
f_lsda = build_decl (FIELD_DECL, get_identifier ("__lsda"),
|
|
|
|
|
ptr_type_node);
|
|
|
|
|
DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node;
|
2000-03-08 16:30:17 -05:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#ifdef DONT_USE_BUILTIN_SETJMP
|
|
|
|
|
#ifdef JMP_BUF_SIZE
|
|
|
|
|
tmp = build_int_2 (JMP_BUF_SIZE - 1, 0);
|
|
|
|
|
#else
|
|
|
|
|
/* Should be large enough for most systems, if it is not,
|
|
|
|
|
JMP_BUF_SIZE should be defined with the proper value. It will
|
|
|
|
|
also tend to be larger than necessary for most systems, a more
|
|
|
|
|
optimal port will define JMP_BUF_SIZE. */
|
|
|
|
|
tmp = build_int_2 (FIRST_PSEUDO_REGISTER + 2 - 1, 0);
|
|
|
|
|
#endif
|
|
|
|
|
#else
|
|
|
|
|
/* This is 2 for builtin_setjmp, plus whatever the target requires
|
|
|
|
|
via STACK_SAVEAREA_MODE (SAVE_NONLOCAL). */
|
|
|
|
|
tmp = build_int_2 ((GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL))
|
|
|
|
|
/ GET_MODE_SIZE (Pmode)) + 2 - 1, 0);
|
|
|
|
|
#endif
|
|
|
|
|
tmp = build_index_type (tmp);
|
|
|
|
|
tmp = build_array_type (ptr_type_node, tmp);
|
|
|
|
|
f_jbuf = build_decl (FIELD_DECL, get_identifier ("__jbuf"), tmp);
|
|
|
|
|
#ifdef DONT_USE_BUILTIN_SETJMP
|
|
|
|
|
/* We don't know what the alignment requirements of the
|
|
|
|
|
runtime's jmp_buf has. Overestimate. */
|
|
|
|
|
DECL_ALIGN (f_jbuf) = BIGGEST_ALIGNMENT;
|
|
|
|
|
DECL_USER_ALIGN (f_jbuf) = 1;
|
|
|
|
|
#endif
|
|
|
|
|
DECL_FIELD_CONTEXT (f_jbuf) = sjlj_fc_type_node;
|
|
|
|
|
|
|
|
|
|
TYPE_FIELDS (sjlj_fc_type_node) = f_prev;
|
|
|
|
|
TREE_CHAIN (f_prev) = f_cs;
|
|
|
|
|
TREE_CHAIN (f_cs) = f_data;
|
|
|
|
|
TREE_CHAIN (f_data) = f_per;
|
|
|
|
|
TREE_CHAIN (f_per) = f_lsda;
|
|
|
|
|
TREE_CHAIN (f_lsda) = f_jbuf;
|
|
|
|
|
|
|
|
|
|
layout_type (sjlj_fc_type_node);
|
|
|
|
|
|
|
|
|
|
/* Cache the interesting field offsets so that we have
|
|
|
|
|
easy access from rtl. */
|
|
|
|
|
sjlj_fc_call_site_ofs
|
|
|
|
|
= (tree_low_cst (DECL_FIELD_OFFSET (f_cs), 1)
|
|
|
|
|
+ tree_low_cst (DECL_FIELD_BIT_OFFSET (f_cs), 1) / BITS_PER_UNIT);
|
|
|
|
|
sjlj_fc_data_ofs
|
|
|
|
|
= (tree_low_cst (DECL_FIELD_OFFSET (f_data), 1)
|
|
|
|
|
+ tree_low_cst (DECL_FIELD_BIT_OFFSET (f_data), 1) / BITS_PER_UNIT);
|
|
|
|
|
sjlj_fc_personality_ofs
|
|
|
|
|
= (tree_low_cst (DECL_FIELD_OFFSET (f_per), 1)
|
|
|
|
|
+ tree_low_cst (DECL_FIELD_BIT_OFFSET (f_per), 1) / BITS_PER_UNIT);
|
|
|
|
|
sjlj_fc_lsda_ofs
|
|
|
|
|
= (tree_low_cst (DECL_FIELD_OFFSET (f_lsda), 1)
|
|
|
|
|
+ tree_low_cst (DECL_FIELD_BIT_OFFSET (f_lsda), 1) / BITS_PER_UNIT);
|
|
|
|
|
sjlj_fc_jbuf_ofs
|
|
|
|
|
= (tree_low_cst (DECL_FIELD_OFFSET (f_jbuf), 1)
|
|
|
|
|
+ tree_low_cst (DECL_FIELD_BIT_OFFSET (f_jbuf), 1) / BITS_PER_UNIT);
|
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
init_eh_for_function ()
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2002-06-04 07:11:05 +00:00
|
|
|
|
cfun->eh = (struct eh_status *)
|
|
|
|
|
ggc_alloc_cleared (sizeof (struct eh_status));
|
2002-04-09 17:15:58 -07:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* Start an exception handling region. All instructions emitted
|
|
|
|
|
after this point are considered to be part of the region until
|
|
|
|
|
expand_eh_region_end is invoked. */
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
expand_eh_region_start ()
|
1998-05-14 13:39:15 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *new_region;
|
|
|
|
|
struct eh_region *cur_region;
|
|
|
|
|
rtx note;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! doing_eh (0))
|
|
|
|
|
return;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Insert a new blank region as a leaf in the tree. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
new_region = (struct eh_region *) ggc_alloc_cleared (sizeof (*new_region));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
cur_region = cfun->eh->cur_region;
|
|
|
|
|
new_region->outer = cur_region;
|
|
|
|
|
if (cur_region)
|
1998-05-14 13:39:15 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
new_region->next_peer = cur_region->inner;
|
|
|
|
|
cur_region->inner = new_region;
|
|
|
|
|
}
|
1998-12-08 14:04:03 +00:00
|
|
|
|
else
|
1998-05-14 13:39:15 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
new_region->next_peer = cfun->eh->region_tree;
|
|
|
|
|
cfun->eh->region_tree = new_region;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
cfun->eh->cur_region = new_region;
|
|
|
|
|
|
|
|
|
|
/* Create a note marking the start of this region. */
|
|
|
|
|
new_region->region_number = ++cfun->eh->last_region_number;
|
2001-05-01 12:11:35 +00:00
|
|
|
|
note = emit_note (NULL, NOTE_INSN_EH_REGION_BEG);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
NOTE_EH_HANDLER (note) = new_region->region_number;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Common code to end a region. Returns the region just ended. */
|
1998-05-28 07:32:33 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static struct eh_region *
|
|
|
|
|
expand_eh_region_end ()
|
1998-05-28 07:32:33 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *cur_region = cfun->eh->cur_region;
|
|
|
|
|
rtx note;
|
|
|
|
|
|
ChangeLog.0, [...]: Fix spelling errors.
* ChangeLog.0, ChangeLog.2, ChangeLog.3, ChangeLog.4, ChangeLog,
FSFChangeLog.10, c-decl.c, cppfiles.c, cppinit.c, cpplex.c,
cpplib.c, cppmain.c, cse.c, df.c, diagnostic.c, dominance.c,
dwarf2out.c, dwarfout.c, emit-rtl.c, errors.c, except.c, except.h,
explow.c, function.c, gcse.c, genrecog.c, predict.c, regmove.c,
sched-rgn.c, ssa-ccp.c, stmt.c, toplev.c: Fix spelling errors.
From-SVN: r47279
2001-11-23 02:05:19 +00:00
|
|
|
|
/* Create a note marking the end of this region. */
|
2001-05-01 12:11:35 +00:00
|
|
|
|
note = emit_note (NULL, NOTE_INSN_EH_REGION_END);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
NOTE_EH_HANDLER (note) = cur_region->region_number;
|
|
|
|
|
|
|
|
|
|
/* Pop. */
|
|
|
|
|
cfun->eh->cur_region = cur_region->outer;
|
|
|
|
|
|
|
|
|
|
return cur_region;
|
1998-05-28 07:32:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* End an exception handling region for a cleanup. HANDLER is an
|
|
|
|
|
expression to expand for the cleanup. */
|
1998-06-25 14:11:54 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
expand_eh_region_end_cleanup (handler)
|
|
|
|
|
tree handler;
|
1998-06-25 14:11:54 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *region;
|
2001-05-17 18:12:27 +00:00
|
|
|
|
tree protect_cleanup_actions;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx around_label;
|
2001-04-24 20:23:10 -04:00
|
|
|
|
rtx data_save[2];
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
if (! doing_eh (0))
|
|
|
|
|
return;
|
1998-06-25 14:11:54 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
region = expand_eh_region_end ();
|
|
|
|
|
region->type = ERT_CLEANUP;
|
|
|
|
|
region->label = gen_label_rtx ();
|
|
|
|
|
region->u.cleanup.exp = handler;
|
2003-03-17 06:09:30 +00:00
|
|
|
|
region->u.cleanup.prev_try = cfun->eh->try_region;
|
1998-06-25 14:11:54 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
around_label = gen_label_rtx ();
|
|
|
|
|
emit_jump (around_label);
|
1998-06-25 14:11:54 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_label (region->label);
|
1998-06-25 14:11:54 +00:00
|
|
|
|
|
2003-05-07 15:11:38 -07:00
|
|
|
|
if (flag_non_call_exceptions || region->may_contain_throw)
|
2003-04-22 05:44:12 +00:00
|
|
|
|
{
|
|
|
|
|
/* Give the language a chance to specify an action to be taken if an
|
|
|
|
|
exception is thrown that would propagate out of the HANDLER. */
|
|
|
|
|
protect_cleanup_actions
|
|
|
|
|
= (lang_protect_cleanup_actions
|
|
|
|
|
? (*lang_protect_cleanup_actions) ()
|
|
|
|
|
: NULL_TREE);
|
2001-05-17 18:12:27 +00:00
|
|
|
|
|
2003-04-22 05:44:12 +00:00
|
|
|
|
if (protect_cleanup_actions)
|
|
|
|
|
expand_eh_region_start ();
|
1998-06-25 14:11:54 +00:00
|
|
|
|
|
2003-04-22 05:44:12 +00:00
|
|
|
|
/* In case this cleanup involves an inline destructor with a try block in
|
|
|
|
|
it, we need to save the EH return data registers around it. */
|
|
|
|
|
data_save[0] = gen_reg_rtx (ptr_mode);
|
|
|
|
|
emit_move_insn (data_save[0], get_exception_pointer (cfun));
|
|
|
|
|
data_save[1] = gen_reg_rtx (word_mode);
|
|
|
|
|
emit_move_insn (data_save[1], get_exception_filter (cfun));
|
2001-04-24 20:23:10 -04:00
|
|
|
|
|
2003-04-22 05:44:12 +00:00
|
|
|
|
expand_expr (handler, const0_rtx, VOIDmode, 0);
|
1998-06-25 14:11:54 +00:00
|
|
|
|
|
2003-04-22 05:44:12 +00:00
|
|
|
|
emit_move_insn (cfun->eh->exc_ptr, data_save[0]);
|
|
|
|
|
emit_move_insn (cfun->eh->filter, data_save[1]);
|
2001-04-24 20:23:10 -04:00
|
|
|
|
|
2003-04-22 05:44:12 +00:00
|
|
|
|
if (protect_cleanup_actions)
|
|
|
|
|
expand_eh_region_end_must_not_throw (protect_cleanup_actions);
|
1999-09-09 00:17:20 -07:00
|
|
|
|
|
2003-04-22 05:44:12 +00:00
|
|
|
|
/* We need any stack adjustment complete before the around_label. */
|
|
|
|
|
do_pending_stack_adjust ();
|
|
|
|
|
}
|
2001-04-26 17:49:01 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* We delay the generation of the _Unwind_Resume until we generate
|
|
|
|
|
landing pads. We emit a marker here so as to get good control
|
|
|
|
|
flow data in the meantime. */
|
2001-04-24 20:23:10 -04:00
|
|
|
|
region->resume
|
|
|
|
|
= emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_barrier ();
|
|
|
|
|
|
|
|
|
|
emit_label (around_label);
|
1998-06-25 14:11:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* End an exception handling region for a try block, and prepares
|
|
|
|
|
for subsequent calls to expand_start_catch. */
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
expand_start_all_catch ()
|
1998-05-14 13:39:15 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *region;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! doing_eh (1))
|
|
|
|
|
return;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
region = expand_eh_region_end ();
|
|
|
|
|
region->type = ERT_TRY;
|
|
|
|
|
region->u.try.prev_try = cfun->eh->try_region;
|
|
|
|
|
region->u.try.continue_label = gen_label_rtx ();
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
cfun->eh->try_region = region;
|
|
|
|
|
|
|
|
|
|
emit_jump (region->u.try.continue_label);
|
|
|
|
|
}
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
/* Begin a catch clause. TYPE is the type caught, a list of such types, or
|
|
|
|
|
null if this is a catch-all clause. Providing a type list enables to
|
|
|
|
|
associate the catch region with potentially several exception types, which
|
2001-12-28 18:17:54 +00:00
|
|
|
|
is useful e.g. for Ada. */
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
2001-11-16 13:48:18 +01:00
|
|
|
|
expand_start_catch (type_or_list)
|
|
|
|
|
tree type_or_list;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *t, *c, *l;
|
2001-11-16 13:48:18 +01:00
|
|
|
|
tree type_list;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
if (! doing_eh (0))
|
|
|
|
|
return;
|
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
type_list = type_or_list;
|
|
|
|
|
|
|
|
|
|
if (type_or_list)
|
|
|
|
|
{
|
|
|
|
|
/* Ensure to always end up with a type list to normalize further
|
|
|
|
|
processing, then register each type against the runtime types
|
|
|
|
|
map. */
|
|
|
|
|
tree type_node;
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (type_or_list) != TREE_LIST)
|
2002-06-03 01:13:17 +00:00
|
|
|
|
type_list = tree_cons (NULL_TREE, type_or_list, NULL_TREE);
|
2001-11-16 13:48:18 +01:00
|
|
|
|
|
|
|
|
|
type_node = type_list;
|
|
|
|
|
for (; type_node; type_node = TREE_CHAIN (type_node))
|
2002-06-03 01:13:17 +00:00
|
|
|
|
add_type_for_runtime (TREE_VALUE (type_node));
|
2001-11-16 13:48:18 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
expand_eh_region_start ();
|
|
|
|
|
|
|
|
|
|
t = cfun->eh->try_region;
|
|
|
|
|
c = cfun->eh->cur_region;
|
|
|
|
|
c->type = ERT_CATCH;
|
2001-11-16 13:48:18 +01:00
|
|
|
|
c->u.catch.type_list = type_list;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
c->label = gen_label_rtx ();
|
|
|
|
|
|
|
|
|
|
l = t->u.try.last_catch;
|
|
|
|
|
c->u.catch.prev_catch = l;
|
|
|
|
|
if (l)
|
|
|
|
|
l->u.catch.next_catch = c;
|
|
|
|
|
else
|
|
|
|
|
t->u.try.catch = c;
|
|
|
|
|
t->u.try.last_catch = c;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_label (c->label);
|
1998-05-14 13:39:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* End a catch clause. Control will resume after the try/catch block. */
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
expand_end_catch ()
|
1998-05-14 13:39:15 +00:00
|
|
|
|
{
|
2002-12-16 18:23:00 +00:00
|
|
|
|
struct eh_region *try_region;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
if (! doing_eh (0))
|
|
|
|
|
return;
|
|
|
|
|
|
2002-12-16 18:23:00 +00:00
|
|
|
|
expand_eh_region_end ();
|
2001-03-28 03:04:51 -08:00
|
|
|
|
try_region = cfun->eh->try_region;
|
|
|
|
|
|
|
|
|
|
emit_jump (try_region->u.try.continue_label);
|
1998-05-14 13:39:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* End a sequence of catch handlers for a try block. */
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
expand_end_all_catch ()
|
1998-05-14 13:39:15 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *try_region;
|
|
|
|
|
|
|
|
|
|
if (! doing_eh (0))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
try_region = cfun->eh->try_region;
|
|
|
|
|
cfun->eh->try_region = try_region->u.try.prev_try;
|
|
|
|
|
|
|
|
|
|
emit_label (try_region->u.try.continue_label);
|
1998-05-14 13:39:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* End an exception region for an exception type filter. ALLOWED is a
|
|
|
|
|
TREE_LIST of types to be matched by the runtime. FAILURE is an
|
ChangeLog.0, [...]: Fix spelling errors.
* ChangeLog.0, ChangeLog.1, ChangeLog.2, ChangeLog.3, ChangeLog.4,
ChangeLog.5, ChangeLog, FSFChangeLog.10, FSFChangeLog.11,
c-common.c, c-common.h, c-parse.in, c-typeck.c, cfg.c, config.gcc,
configure, configure.in, except.c, except.h, flow.c, function.c,
gcc.c, gcse.c, genrecog.c, libgcc2.c, loop.c, loop.h, params.def,
predict.def, predict.h, reg-stack.c, regmove.c, sched-deps.c,
sched-int.h, sibcall.c, ssa.c, stringpool.c, toplev.c, tree.c,
unroll.c: Fix spelling errors.
From-SVN: r46595
2001-10-28 20:09:17 +00:00
|
|
|
|
expression to invoke if a mismatch occurs.
|
2001-08-16 12:24:46 -04:00
|
|
|
|
|
|
|
|
|
??? We could use these semantics for calls to rethrow, too; if we can
|
|
|
|
|
see the surrounding catch clause, we know that the exception we're
|
|
|
|
|
rethrowing satisfies the "filter" of the catch type. */
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
expand_eh_region_end_allowed (allowed, failure)
|
|
|
|
|
tree allowed, failure;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *region;
|
|
|
|
|
rtx around_label;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! doing_eh (0))
|
|
|
|
|
return;
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
region = expand_eh_region_end ();
|
|
|
|
|
region->type = ERT_ALLOWED_EXCEPTIONS;
|
|
|
|
|
region->u.allowed.type_list = allowed;
|
|
|
|
|
region->label = gen_label_rtx ();
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (; allowed ; allowed = TREE_CHAIN (allowed))
|
|
|
|
|
add_type_for_runtime (TREE_VALUE (allowed));
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* We must emit the call to FAILURE here, so that if this function
|
|
|
|
|
throws a different exception, that it will be processed by the
|
|
|
|
|
correct region. */
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
around_label = gen_label_rtx ();
|
|
|
|
|
emit_jump (around_label);
|
|
|
|
|
|
|
|
|
|
emit_label (region->label);
|
|
|
|
|
expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
2001-06-08 16:19:45 +00:00
|
|
|
|
/* We must adjust the stack before we reach the AROUND_LABEL because
|
|
|
|
|
the call to FAILURE does not occur on all paths to the
|
|
|
|
|
AROUND_LABEL. */
|
|
|
|
|
do_pending_stack_adjust ();
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_label (around_label);
|
1998-05-14 13:39:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* End an exception region for a must-not-throw filter. FAILURE is an
|
|
|
|
|
expression invoke if an uncaught exception propagates this far.
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
This is conceptually identical to expand_eh_region_end_allowed with
|
|
|
|
|
an empty allowed list (if you passed "std::terminate" instead of
|
|
|
|
|
"__cxa_call_unexpected"), but they are represented differently in
|
|
|
|
|
the C++ LSDA. */
|
2000-03-08 16:30:17 -05:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
expand_eh_region_end_must_not_throw (failure)
|
|
|
|
|
tree failure;
|
1998-12-08 14:04:03 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *region;
|
|
|
|
|
rtx around_label;
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! doing_eh (0))
|
|
|
|
|
return;
|
2000-03-08 16:30:17 -05:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
region = expand_eh_region_end ();
|
|
|
|
|
region->type = ERT_MUST_NOT_THROW;
|
|
|
|
|
region->label = gen_label_rtx ();
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* We must emit the call to FAILURE here, so that if this function
|
|
|
|
|
throws a different exception, that it will be processed by the
|
|
|
|
|
correct region. */
|
2000-03-08 16:30:17 -05:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
around_label = gen_label_rtx ();
|
|
|
|
|
emit_jump (around_label);
|
2000-03-08 16:30:17 -05:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_label (region->label);
|
|
|
|
|
expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
2000-03-08 16:30:17 -05:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_label (around_label);
|
1998-12-08 14:04:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* End an exception region for a throw. No handling goes on here,
|
|
|
|
|
but it's the easiest way for the front-end to indicate what type
|
|
|
|
|
is being thrown. */
|
2000-03-08 16:30:17 -05:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
expand_eh_region_end_throw (type)
|
|
|
|
|
tree type;
|
1998-12-08 14:04:03 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *region;
|
|
|
|
|
|
|
|
|
|
if (! doing_eh (0))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
region = expand_eh_region_end ();
|
|
|
|
|
region->type = ERT_THROW;
|
|
|
|
|
region->u.throw.type = type;
|
1998-12-08 14:04:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* End a fixup region. Within this region the cleanups for the immediately
|
|
|
|
|
enclosing region are _not_ run. This is used for goto cleanup to avoid
|
|
|
|
|
destroying an object twice.
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
This would be an extraordinarily simple prospect, were it not for the
|
|
|
|
|
fact that we don't actually know what the immediately enclosing region
|
|
|
|
|
is. This surprising fact is because expand_cleanups is currently
|
|
|
|
|
generating a sequence that it will insert somewhere else. We collect
|
|
|
|
|
the proper notion of "enclosing" in convert_from_eh_region_ranges. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
expand_eh_region_end_fixup (handler)
|
|
|
|
|
tree handler;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *fixup;
|
|
|
|
|
|
|
|
|
|
if (! doing_eh (0))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
fixup = expand_eh_region_end ();
|
|
|
|
|
fixup->type = ERT_FIXUP;
|
|
|
|
|
fixup->u.fixup.cleanup_exp = handler;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-04-22 05:44:12 +00:00
|
|
|
|
/* Note that the current EH region (if any) may contain a throw, or a
|
|
|
|
|
call to a function which itself may contain a throw. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
note_eh_region_may_contain_throw ()
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *region;
|
|
|
|
|
|
|
|
|
|
region = cfun->eh->cur_region;
|
|
|
|
|
while (region && !region->may_contain_throw)
|
|
|
|
|
{
|
|
|
|
|
region->may_contain_throw = 1;
|
|
|
|
|
region = region->outer;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-24 20:23:10 -04:00
|
|
|
|
/* Return an rtl expression for a pointer to the exception object
|
2001-03-28 03:04:51 -08:00
|
|
|
|
within a handler. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
|
|
|
|
rtx
|
2001-06-08 15:57:23 -07:00
|
|
|
|
get_exception_pointer (fun)
|
|
|
|
|
struct function *fun;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-06-08 15:57:23 -07:00
|
|
|
|
rtx exc_ptr = fun->eh->exc_ptr;
|
|
|
|
|
if (fun == cfun && ! exc_ptr)
|
2001-03-28 03:04:51 -08:00
|
|
|
|
{
|
2002-07-09 15:28:22 +00:00
|
|
|
|
exc_ptr = gen_reg_rtx (ptr_mode);
|
2001-06-08 15:57:23 -07:00
|
|
|
|
fun->eh->exc_ptr = exc_ptr;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
|
|
|
|
return exc_ptr;
|
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-04-24 20:23:10 -04:00
|
|
|
|
/* Return an rtl expression for the exception dispatch filter
|
|
|
|
|
within a handler. */
|
|
|
|
|
|
|
|
|
|
static rtx
|
2001-06-08 15:57:23 -07:00
|
|
|
|
get_exception_filter (fun)
|
|
|
|
|
struct function *fun;
|
2001-04-24 20:23:10 -04:00
|
|
|
|
{
|
2001-06-08 15:57:23 -07:00
|
|
|
|
rtx filter = fun->eh->filter;
|
|
|
|
|
if (fun == cfun && ! filter)
|
2001-04-24 20:23:10 -04:00
|
|
|
|
{
|
2001-04-26 19:32:49 -04:00
|
|
|
|
filter = gen_reg_rtx (word_mode);
|
2001-06-08 15:57:23 -07:00
|
|
|
|
fun->eh->filter = filter;
|
2001-04-24 20:23:10 -04:00
|
|
|
|
}
|
|
|
|
|
return filter;
|
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* This section is for the exception handling specific optimization pass. */
|
[multiple changes]
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.
* integrate.c (expand_inline_function): If the inline fn uses eh
context, make sure that the current fn has one.
* toplev.c (rest_of_compilation): Call emit_eh_context.
* except.c (use_eh_context): New fn.
(get_eh_context_once): New fn.
(call_get_eh_context): New fn.
(emit_eh_context): New fn.
(get_eh_context): Call either get_eh_context_once or
call_get_eh_context, depending on what we have.
(get_dynamic_handler_chain): Call get_eh_context_once.
* except.h: Prototypes for fns above.
* optabs.c (get_eh_context_libfunc): Removed.
(init_optabs): Don't initialize it.
* expr.h (get_eh_context_libfunc): Removed.
* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.
* config/pa/pa.h (CPP_SPEC): Support for -threads.
* config/pa/pa-hpux10.h (LIB_SPEC): Ditto.
* config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
New multilib for -threads.
* config/sparc/t-sol2: Added multilibs for -threads and
made -pthreads alias to it.
* config/sparc/sol2.h (CPP_SPEC, LIB_SPEC):
Added -threads and -pthreads options.
* libgcc-thr.h: New file.
* libgcc2.c: (__get_cpp_eh_context): Removed.
(struct cpp_eh_context): Removed.
(struct eh_context): Replaced cpp_eh_context with generic language
specific pointer.
(__get_eh_info): New function.
(__throw): Check eh_context::info.
(__sjthrow): Ditto.
* libgcc2.c: Include libgcc-thr.h.
(new_eh_context, __get_eh_context,
eh_pthread_initialize, eh_context_initialize, eh_context_static,
eh_context_specific, eh_context_free): New functions.
(get_eh_context, eh_context_key): New variables.
(__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use
get_eh_context to get the context.
(longjmp): Move the declaration inside
#ifdef DONT_USE_BUILTIN_SETJMP.
* frame.c: Include libgcc-thr.h.
(object_mutex): Mutex to protect the object list.
(find_fde, __register_frame, __register_frame_table,
__deregister_frame): Hold the lock while accessing objects.
* except.h (get_eh_context): Declare.
* except.c (current_function_ehc): Define.
(current_function_dhc, current_function_dcc): Removed.
(get_eh_context): New function.
(get_dynamic_handler_chain): Use get_eh_context.
(get_saved_pc_ref): Ditto.
(get_dynamic_cleanup_chain): Removed references to
current_function_dcc.
(save_eh_status, restore_eh_status): Save and restore
current_function_ehc instead.
* optabs.c (get_eh_context_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_eh_context_libfunc.
* function.h (struct function): Replaced dhc and dcc with ehc.
* except.c (get_saved_pc_ref): New functions.
(eh_saved_pc_rtx, eh_saved_pc): Deleted.
(expand_internal_throw_indirect): Use get_saved_pc_ref() instead
of eh_saved_pc.
(end_eh_unwinder): Likewise.
(init_eh): Remove initialization of eh_saved_pc.
* optabs.c (get_saved_pc_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_saved_pc_libfunc.
* except.h (eh_saved_pc_rtx): Deleted.
(get_saved_pc_ref): Declared.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* libgcc2.c (__get_saved_pc): New.
(__eh_type, __eh_pc): Deleted.
(__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc.
(__get_dynamic_handler_chain): Move __dynamic_handler_chain inside
this fcn.
cp/:
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.
(init_decl_processing): Initialize it.
* cp-tree.h: Declare it.
* exception.cc (__cp_exception_info): Use __get_eh_info.
(__cp_push_exception): Ditto.
(__cp_pop_exception): Ditto.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
saved_pc.
(init_exception_processing): Removed saved_pc initialization.
From-SVN: r17052
1997-12-12 04:53:20 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Random access the exception region tree. It's just as simple to
|
|
|
|
|
collect the regions this way as in expand_eh_region_start, but
|
|
|
|
|
without having to realloc memory. */
|
[multiple changes]
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.
* integrate.c (expand_inline_function): If the inline fn uses eh
context, make sure that the current fn has one.
* toplev.c (rest_of_compilation): Call emit_eh_context.
* except.c (use_eh_context): New fn.
(get_eh_context_once): New fn.
(call_get_eh_context): New fn.
(emit_eh_context): New fn.
(get_eh_context): Call either get_eh_context_once or
call_get_eh_context, depending on what we have.
(get_dynamic_handler_chain): Call get_eh_context_once.
* except.h: Prototypes for fns above.
* optabs.c (get_eh_context_libfunc): Removed.
(init_optabs): Don't initialize it.
* expr.h (get_eh_context_libfunc): Removed.
* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.
* config/pa/pa.h (CPP_SPEC): Support for -threads.
* config/pa/pa-hpux10.h (LIB_SPEC): Ditto.
* config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
New multilib for -threads.
* config/sparc/t-sol2: Added multilibs for -threads and
made -pthreads alias to it.
* config/sparc/sol2.h (CPP_SPEC, LIB_SPEC):
Added -threads and -pthreads options.
* libgcc-thr.h: New file.
* libgcc2.c: (__get_cpp_eh_context): Removed.
(struct cpp_eh_context): Removed.
(struct eh_context): Replaced cpp_eh_context with generic language
specific pointer.
(__get_eh_info): New function.
(__throw): Check eh_context::info.
(__sjthrow): Ditto.
* libgcc2.c: Include libgcc-thr.h.
(new_eh_context, __get_eh_context,
eh_pthread_initialize, eh_context_initialize, eh_context_static,
eh_context_specific, eh_context_free): New functions.
(get_eh_context, eh_context_key): New variables.
(__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use
get_eh_context to get the context.
(longjmp): Move the declaration inside
#ifdef DONT_USE_BUILTIN_SETJMP.
* frame.c: Include libgcc-thr.h.
(object_mutex): Mutex to protect the object list.
(find_fde, __register_frame, __register_frame_table,
__deregister_frame): Hold the lock while accessing objects.
* except.h (get_eh_context): Declare.
* except.c (current_function_ehc): Define.
(current_function_dhc, current_function_dcc): Removed.
(get_eh_context): New function.
(get_dynamic_handler_chain): Use get_eh_context.
(get_saved_pc_ref): Ditto.
(get_dynamic_cleanup_chain): Removed references to
current_function_dcc.
(save_eh_status, restore_eh_status): Save and restore
current_function_ehc instead.
* optabs.c (get_eh_context_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_eh_context_libfunc.
* function.h (struct function): Replaced dhc and dcc with ehc.
* except.c (get_saved_pc_ref): New functions.
(eh_saved_pc_rtx, eh_saved_pc): Deleted.
(expand_internal_throw_indirect): Use get_saved_pc_ref() instead
of eh_saved_pc.
(end_eh_unwinder): Likewise.
(init_eh): Remove initialization of eh_saved_pc.
* optabs.c (get_saved_pc_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_saved_pc_libfunc.
* except.h (eh_saved_pc_rtx): Deleted.
(get_saved_pc_ref): Declared.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* libgcc2.c (__get_saved_pc): New.
(__eh_type, __eh_pc): Deleted.
(__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc.
(__get_dynamic_handler_chain): Move __dynamic_handler_chain inside
this fcn.
cp/:
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.
(init_decl_processing): Initialize it.
* cp-tree.h: Declare it.
* exception.cc (__cp_exception_info): Use __get_eh_info.
(__cp_push_exception): Ditto.
(__cp_pop_exception): Ditto.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
saved_pc.
(init_exception_processing): Removed saved_pc initialization.
From-SVN: r17052
1997-12-12 04:53:20 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void
|
|
|
|
|
collect_eh_region_array ()
|
[multiple changes]
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.
* integrate.c (expand_inline_function): If the inline fn uses eh
context, make sure that the current fn has one.
* toplev.c (rest_of_compilation): Call emit_eh_context.
* except.c (use_eh_context): New fn.
(get_eh_context_once): New fn.
(call_get_eh_context): New fn.
(emit_eh_context): New fn.
(get_eh_context): Call either get_eh_context_once or
call_get_eh_context, depending on what we have.
(get_dynamic_handler_chain): Call get_eh_context_once.
* except.h: Prototypes for fns above.
* optabs.c (get_eh_context_libfunc): Removed.
(init_optabs): Don't initialize it.
* expr.h (get_eh_context_libfunc): Removed.
* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.
* config/pa/pa.h (CPP_SPEC): Support for -threads.
* config/pa/pa-hpux10.h (LIB_SPEC): Ditto.
* config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
New multilib for -threads.
* config/sparc/t-sol2: Added multilibs for -threads and
made -pthreads alias to it.
* config/sparc/sol2.h (CPP_SPEC, LIB_SPEC):
Added -threads and -pthreads options.
* libgcc-thr.h: New file.
* libgcc2.c: (__get_cpp_eh_context): Removed.
(struct cpp_eh_context): Removed.
(struct eh_context): Replaced cpp_eh_context with generic language
specific pointer.
(__get_eh_info): New function.
(__throw): Check eh_context::info.
(__sjthrow): Ditto.
* libgcc2.c: Include libgcc-thr.h.
(new_eh_context, __get_eh_context,
eh_pthread_initialize, eh_context_initialize, eh_context_static,
eh_context_specific, eh_context_free): New functions.
(get_eh_context, eh_context_key): New variables.
(__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use
get_eh_context to get the context.
(longjmp): Move the declaration inside
#ifdef DONT_USE_BUILTIN_SETJMP.
* frame.c: Include libgcc-thr.h.
(object_mutex): Mutex to protect the object list.
(find_fde, __register_frame, __register_frame_table,
__deregister_frame): Hold the lock while accessing objects.
* except.h (get_eh_context): Declare.
* except.c (current_function_ehc): Define.
(current_function_dhc, current_function_dcc): Removed.
(get_eh_context): New function.
(get_dynamic_handler_chain): Use get_eh_context.
(get_saved_pc_ref): Ditto.
(get_dynamic_cleanup_chain): Removed references to
current_function_dcc.
(save_eh_status, restore_eh_status): Save and restore
current_function_ehc instead.
* optabs.c (get_eh_context_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_eh_context_libfunc.
* function.h (struct function): Replaced dhc and dcc with ehc.
* except.c (get_saved_pc_ref): New functions.
(eh_saved_pc_rtx, eh_saved_pc): Deleted.
(expand_internal_throw_indirect): Use get_saved_pc_ref() instead
of eh_saved_pc.
(end_eh_unwinder): Likewise.
(init_eh): Remove initialization of eh_saved_pc.
* optabs.c (get_saved_pc_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_saved_pc_libfunc.
* except.h (eh_saved_pc_rtx): Deleted.
(get_saved_pc_ref): Declared.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* libgcc2.c (__get_saved_pc): New.
(__eh_type, __eh_pc): Deleted.
(__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc.
(__get_dynamic_handler_chain): Move __dynamic_handler_chain inside
this fcn.
cp/:
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.
(init_decl_processing): Initialize it.
* cp-tree.h: Declare it.
* exception.cc (__cp_exception_info): Use __get_eh_info.
(__cp_push_exception): Ditto.
(__cp_pop_exception): Ditto.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
saved_pc.
(init_exception_processing): Removed saved_pc initialization.
From-SVN: r17052
1997-12-12 04:53:20 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region **array, *i;
|
[multiple changes]
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.
* integrate.c (expand_inline_function): If the inline fn uses eh
context, make sure that the current fn has one.
* toplev.c (rest_of_compilation): Call emit_eh_context.
* except.c (use_eh_context): New fn.
(get_eh_context_once): New fn.
(call_get_eh_context): New fn.
(emit_eh_context): New fn.
(get_eh_context): Call either get_eh_context_once or
call_get_eh_context, depending on what we have.
(get_dynamic_handler_chain): Call get_eh_context_once.
* except.h: Prototypes for fns above.
* optabs.c (get_eh_context_libfunc): Removed.
(init_optabs): Don't initialize it.
* expr.h (get_eh_context_libfunc): Removed.
* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.
* config/pa/pa.h (CPP_SPEC): Support for -threads.
* config/pa/pa-hpux10.h (LIB_SPEC): Ditto.
* config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
New multilib for -threads.
* config/sparc/t-sol2: Added multilibs for -threads and
made -pthreads alias to it.
* config/sparc/sol2.h (CPP_SPEC, LIB_SPEC):
Added -threads and -pthreads options.
* libgcc-thr.h: New file.
* libgcc2.c: (__get_cpp_eh_context): Removed.
(struct cpp_eh_context): Removed.
(struct eh_context): Replaced cpp_eh_context with generic language
specific pointer.
(__get_eh_info): New function.
(__throw): Check eh_context::info.
(__sjthrow): Ditto.
* libgcc2.c: Include libgcc-thr.h.
(new_eh_context, __get_eh_context,
eh_pthread_initialize, eh_context_initialize, eh_context_static,
eh_context_specific, eh_context_free): New functions.
(get_eh_context, eh_context_key): New variables.
(__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use
get_eh_context to get the context.
(longjmp): Move the declaration inside
#ifdef DONT_USE_BUILTIN_SETJMP.
* frame.c: Include libgcc-thr.h.
(object_mutex): Mutex to protect the object list.
(find_fde, __register_frame, __register_frame_table,
__deregister_frame): Hold the lock while accessing objects.
* except.h (get_eh_context): Declare.
* except.c (current_function_ehc): Define.
(current_function_dhc, current_function_dcc): Removed.
(get_eh_context): New function.
(get_dynamic_handler_chain): Use get_eh_context.
(get_saved_pc_ref): Ditto.
(get_dynamic_cleanup_chain): Removed references to
current_function_dcc.
(save_eh_status, restore_eh_status): Save and restore
current_function_ehc instead.
* optabs.c (get_eh_context_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_eh_context_libfunc.
* function.h (struct function): Replaced dhc and dcc with ehc.
* except.c (get_saved_pc_ref): New functions.
(eh_saved_pc_rtx, eh_saved_pc): Deleted.
(expand_internal_throw_indirect): Use get_saved_pc_ref() instead
of eh_saved_pc.
(end_eh_unwinder): Likewise.
(init_eh): Remove initialization of eh_saved_pc.
* optabs.c (get_saved_pc_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_saved_pc_libfunc.
* except.h (eh_saved_pc_rtx): Deleted.
(get_saved_pc_ref): Declared.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* libgcc2.c (__get_saved_pc): New.
(__eh_type, __eh_pc): Deleted.
(__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc.
(__get_dynamic_handler_chain): Move __dynamic_handler_chain inside
this fcn.
cp/:
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.
(init_decl_processing): Initialize it.
* cp-tree.h: Declare it.
* exception.cc (__cp_exception_info): Use __get_eh_info.
(__cp_push_exception): Ditto.
(__cp_pop_exception): Ditto.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
saved_pc.
(init_exception_processing): Removed saved_pc initialization.
From-SVN: r17052
1997-12-12 04:53:20 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
i = cfun->eh->region_tree;
|
|
|
|
|
if (! i)
|
|
|
|
|
return;
|
[multiple changes]
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.
* integrate.c (expand_inline_function): If the inline fn uses eh
context, make sure that the current fn has one.
* toplev.c (rest_of_compilation): Call emit_eh_context.
* except.c (use_eh_context): New fn.
(get_eh_context_once): New fn.
(call_get_eh_context): New fn.
(emit_eh_context): New fn.
(get_eh_context): Call either get_eh_context_once or
call_get_eh_context, depending on what we have.
(get_dynamic_handler_chain): Call get_eh_context_once.
* except.h: Prototypes for fns above.
* optabs.c (get_eh_context_libfunc): Removed.
(init_optabs): Don't initialize it.
* expr.h (get_eh_context_libfunc): Removed.
* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.
* config/pa/pa.h (CPP_SPEC): Support for -threads.
* config/pa/pa-hpux10.h (LIB_SPEC): Ditto.
* config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
New multilib for -threads.
* config/sparc/t-sol2: Added multilibs for -threads and
made -pthreads alias to it.
* config/sparc/sol2.h (CPP_SPEC, LIB_SPEC):
Added -threads and -pthreads options.
* libgcc-thr.h: New file.
* libgcc2.c: (__get_cpp_eh_context): Removed.
(struct cpp_eh_context): Removed.
(struct eh_context): Replaced cpp_eh_context with generic language
specific pointer.
(__get_eh_info): New function.
(__throw): Check eh_context::info.
(__sjthrow): Ditto.
* libgcc2.c: Include libgcc-thr.h.
(new_eh_context, __get_eh_context,
eh_pthread_initialize, eh_context_initialize, eh_context_static,
eh_context_specific, eh_context_free): New functions.
(get_eh_context, eh_context_key): New variables.
(__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use
get_eh_context to get the context.
(longjmp): Move the declaration inside
#ifdef DONT_USE_BUILTIN_SETJMP.
* frame.c: Include libgcc-thr.h.
(object_mutex): Mutex to protect the object list.
(find_fde, __register_frame, __register_frame_table,
__deregister_frame): Hold the lock while accessing objects.
* except.h (get_eh_context): Declare.
* except.c (current_function_ehc): Define.
(current_function_dhc, current_function_dcc): Removed.
(get_eh_context): New function.
(get_dynamic_handler_chain): Use get_eh_context.
(get_saved_pc_ref): Ditto.
(get_dynamic_cleanup_chain): Removed references to
current_function_dcc.
(save_eh_status, restore_eh_status): Save and restore
current_function_ehc instead.
* optabs.c (get_eh_context_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_eh_context_libfunc.
* function.h (struct function): Replaced dhc and dcc with ehc.
* except.c (get_saved_pc_ref): New functions.
(eh_saved_pc_rtx, eh_saved_pc): Deleted.
(expand_internal_throw_indirect): Use get_saved_pc_ref() instead
of eh_saved_pc.
(end_eh_unwinder): Likewise.
(init_eh): Remove initialization of eh_saved_pc.
* optabs.c (get_saved_pc_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_saved_pc_libfunc.
* except.h (eh_saved_pc_rtx): Deleted.
(get_saved_pc_ref): Declared.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* libgcc2.c (__get_saved_pc): New.
(__eh_type, __eh_pc): Deleted.
(__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc.
(__get_dynamic_handler_chain): Move __dynamic_handler_chain inside
this fcn.
cp/:
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.
(init_decl_processing): Initialize it.
* cp-tree.h: Declare it.
* exception.cc (__cp_exception_info): Use __get_eh_info.
(__cp_push_exception): Ditto.
(__cp_pop_exception): Ditto.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
saved_pc.
(init_exception_processing): Removed saved_pc initialization.
From-SVN: r17052
1997-12-12 04:53:20 +00:00
|
|
|
|
|
2002-06-04 07:11:05 +00:00
|
|
|
|
array = ggc_alloc_cleared ((cfun->eh->last_region_number + 1)
|
|
|
|
|
* sizeof (*array));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
cfun->eh->region_array = array;
|
[multiple changes]
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.
* integrate.c (expand_inline_function): If the inline fn uses eh
context, make sure that the current fn has one.
* toplev.c (rest_of_compilation): Call emit_eh_context.
* except.c (use_eh_context): New fn.
(get_eh_context_once): New fn.
(call_get_eh_context): New fn.
(emit_eh_context): New fn.
(get_eh_context): Call either get_eh_context_once or
call_get_eh_context, depending on what we have.
(get_dynamic_handler_chain): Call get_eh_context_once.
* except.h: Prototypes for fns above.
* optabs.c (get_eh_context_libfunc): Removed.
(init_optabs): Don't initialize it.
* expr.h (get_eh_context_libfunc): Removed.
* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.
* config/pa/pa.h (CPP_SPEC): Support for -threads.
* config/pa/pa-hpux10.h (LIB_SPEC): Ditto.
* config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
New multilib for -threads.
* config/sparc/t-sol2: Added multilibs for -threads and
made -pthreads alias to it.
* config/sparc/sol2.h (CPP_SPEC, LIB_SPEC):
Added -threads and -pthreads options.
* libgcc-thr.h: New file.
* libgcc2.c: (__get_cpp_eh_context): Removed.
(struct cpp_eh_context): Removed.
(struct eh_context): Replaced cpp_eh_context with generic language
specific pointer.
(__get_eh_info): New function.
(__throw): Check eh_context::info.
(__sjthrow): Ditto.
* libgcc2.c: Include libgcc-thr.h.
(new_eh_context, __get_eh_context,
eh_pthread_initialize, eh_context_initialize, eh_context_static,
eh_context_specific, eh_context_free): New functions.
(get_eh_context, eh_context_key): New variables.
(__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use
get_eh_context to get the context.
(longjmp): Move the declaration inside
#ifdef DONT_USE_BUILTIN_SETJMP.
* frame.c: Include libgcc-thr.h.
(object_mutex): Mutex to protect the object list.
(find_fde, __register_frame, __register_frame_table,
__deregister_frame): Hold the lock while accessing objects.
* except.h (get_eh_context): Declare.
* except.c (current_function_ehc): Define.
(current_function_dhc, current_function_dcc): Removed.
(get_eh_context): New function.
(get_dynamic_handler_chain): Use get_eh_context.
(get_saved_pc_ref): Ditto.
(get_dynamic_cleanup_chain): Removed references to
current_function_dcc.
(save_eh_status, restore_eh_status): Save and restore
current_function_ehc instead.
* optabs.c (get_eh_context_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_eh_context_libfunc.
* function.h (struct function): Replaced dhc and dcc with ehc.
* except.c (get_saved_pc_ref): New functions.
(eh_saved_pc_rtx, eh_saved_pc): Deleted.
(expand_internal_throw_indirect): Use get_saved_pc_ref() instead
of eh_saved_pc.
(end_eh_unwinder): Likewise.
(init_eh): Remove initialization of eh_saved_pc.
* optabs.c (get_saved_pc_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_saved_pc_libfunc.
* except.h (eh_saved_pc_rtx): Deleted.
(get_saved_pc_ref): Declared.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* libgcc2.c (__get_saved_pc): New.
(__eh_type, __eh_pc): Deleted.
(__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc.
(__get_dynamic_handler_chain): Move __dynamic_handler_chain inside
this fcn.
cp/:
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.
(init_decl_processing): Initialize it.
* cp-tree.h: Declare it.
* exception.cc (__cp_exception_info): Use __get_eh_info.
(__cp_push_exception): Ditto.
(__cp_pop_exception): Ditto.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
saved_pc.
(init_exception_processing): Removed saved_pc initialization.
From-SVN: r17052
1997-12-12 04:53:20 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
array[i->region_number] = i;
|
|
|
|
|
|
|
|
|
|
/* If there are sub-regions, process them. */
|
|
|
|
|
if (i->inner)
|
|
|
|
|
i = i->inner;
|
|
|
|
|
/* If there are peers, process them. */
|
|
|
|
|
else if (i->next_peer)
|
|
|
|
|
i = i->next_peer;
|
|
|
|
|
/* Otherwise, step back up the tree to the next peer. */
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
do {
|
|
|
|
|
i = i->outer;
|
|
|
|
|
if (i == NULL)
|
|
|
|
|
return;
|
|
|
|
|
} while (i->next_peer == NULL);
|
|
|
|
|
i = i->next_peer;
|
|
|
|
|
}
|
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void
|
|
|
|
|
resolve_fixup_regions ()
|
1997-04-23 20:11:52 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int i, j, n = cfun->eh->last_region_number;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = 1; i <= n; ++i)
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *fixup = cfun->eh->region_array[i];
|
2001-06-18 06:43:51 +00:00
|
|
|
|
struct eh_region *cleanup = 0;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! fixup || fixup->type != ERT_FIXUP)
|
|
|
|
|
continue;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (j = 1; j <= n; ++j)
|
|
|
|
|
{
|
|
|
|
|
cleanup = cfun->eh->region_array[j];
|
2003-04-15 14:37:58 +02:00
|
|
|
|
if (cleanup && cleanup->type == ERT_CLEANUP
|
2001-03-28 03:04:51 -08:00
|
|
|
|
&& cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (j > n)
|
|
|
|
|
abort ();
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
fixup->u.fixup.real_region = cleanup->outer;
|
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Now that we've discovered what region actually encloses a fixup,
|
|
|
|
|
we can shuffle pointers and remove them from the tree. */
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
|
|
|
|
static void
|
2001-03-28 03:04:51 -08:00
|
|
|
|
remove_fixup_regions ()
|
1997-04-23 20:11:52 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int i;
|
2001-05-05 09:38:25 -07:00
|
|
|
|
rtx insn, note;
|
|
|
|
|
struct eh_region *fixup;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-05-05 09:38:25 -07:00
|
|
|
|
/* Walk the insn chain and adjust the REG_EH_REGION numbers
|
|
|
|
|
for instructions referencing fixup regions. This is only
|
|
|
|
|
strictly necessary for fixup regions with no parent, but
|
|
|
|
|
doesn't hurt to do it for all regions. */
|
|
|
|
|
for (insn = get_insns(); insn ; insn = NEXT_INSN (insn))
|
|
|
|
|
if (INSN_P (insn)
|
|
|
|
|
&& (note = find_reg_note (insn, REG_EH_REGION, NULL))
|
|
|
|
|
&& INTVAL (XEXP (note, 0)) > 0
|
|
|
|
|
&& (fixup = cfun->eh->region_array[INTVAL (XEXP (note, 0))])
|
|
|
|
|
&& fixup->type == ERT_FIXUP)
|
|
|
|
|
{
|
|
|
|
|
if (fixup->u.fixup.real_region)
|
2001-08-08 21:22:30 +00:00
|
|
|
|
XEXP (note, 0) = GEN_INT (fixup->u.fixup.real_region->region_number);
|
2001-05-05 09:38:25 -07:00
|
|
|
|
else
|
|
|
|
|
remove_note (insn, note);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Remove the fixup regions from the tree. */
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
|
|
|
|
{
|
2001-05-05 09:38:25 -07:00
|
|
|
|
fixup = cfun->eh->region_array[i];
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! fixup)
|
|
|
|
|
continue;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Allow GC to maybe free some memory. */
|
|
|
|
|
if (fixup->type == ERT_CLEANUP)
|
2002-06-03 01:13:17 +00:00
|
|
|
|
fixup->u.cleanup.exp = NULL_TREE;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (fixup->type != ERT_FIXUP)
|
|
|
|
|
continue;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (fixup->inner)
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *parent, *p, **pp;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
parent = fixup->u.fixup.real_region;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Fix up the children's parent pointers; find the end of
|
|
|
|
|
the list. */
|
|
|
|
|
for (p = fixup->inner; ; p = p->next_peer)
|
|
|
|
|
{
|
|
|
|
|
p->outer = parent;
|
|
|
|
|
if (! p->next_peer)
|
|
|
|
|
break;
|
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* In the tree of cleanups, only outer-inner ordering matters.
|
|
|
|
|
So link the children back in anywhere at the correct level. */
|
|
|
|
|
if (parent)
|
|
|
|
|
pp = &parent->inner;
|
|
|
|
|
else
|
|
|
|
|
pp = &cfun->eh->region_tree;
|
|
|
|
|
p->next_peer = *pp;
|
|
|
|
|
*pp = fixup->inner;
|
|
|
|
|
fixup->inner = NULL;
|
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
remove_eh_handler (fixup);
|
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-01-14 22:06:26 +01:00
|
|
|
|
/* Remove all regions whose labels are not reachable from insns. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
remove_unreachable_regions (insns)
|
|
|
|
|
rtx insns;
|
|
|
|
|
{
|
|
|
|
|
int i, *uid_region_num;
|
|
|
|
|
bool *reachable;
|
|
|
|
|
struct eh_region *r;
|
|
|
|
|
rtx insn;
|
|
|
|
|
|
|
|
|
|
uid_region_num = xcalloc (get_max_uid (), sizeof(int));
|
|
|
|
|
reachable = xcalloc (cfun->eh->last_region_number + 1, sizeof(bool));
|
|
|
|
|
|
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
|
|
|
|
{
|
|
|
|
|
r = cfun->eh->region_array[i];
|
|
|
|
|
if (!r || r->region_number != i)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (r->resume)
|
2002-06-03 01:13:17 +00:00
|
|
|
|
{
|
2002-01-14 22:06:26 +01:00
|
|
|
|
if (uid_region_num[INSN_UID (r->resume)])
|
|
|
|
|
abort ();
|
|
|
|
|
uid_region_num[INSN_UID (r->resume)] = i;
|
2002-06-03 01:13:17 +00:00
|
|
|
|
}
|
2002-01-14 22:06:26 +01:00
|
|
|
|
if (r->label)
|
2002-06-03 01:13:17 +00:00
|
|
|
|
{
|
2002-01-14 22:06:26 +01:00
|
|
|
|
if (uid_region_num[INSN_UID (r->label)])
|
|
|
|
|
abort ();
|
|
|
|
|
uid_region_num[INSN_UID (r->label)] = i;
|
2002-06-03 01:13:17 +00:00
|
|
|
|
}
|
2002-01-14 22:06:26 +01:00
|
|
|
|
if (r->type == ERT_TRY && r->u.try.continue_label)
|
2002-06-03 01:13:17 +00:00
|
|
|
|
{
|
2002-01-14 22:06:26 +01:00
|
|
|
|
if (uid_region_num[INSN_UID (r->u.try.continue_label)])
|
|
|
|
|
abort ();
|
|
|
|
|
uid_region_num[INSN_UID (r->u.try.continue_label)] = i;
|
2002-06-03 01:13:17 +00:00
|
|
|
|
}
|
2002-01-14 22:06:26 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (insn = insns; insn; insn = NEXT_INSN (insn))
|
|
|
|
|
reachable[uid_region_num[INSN_UID (insn)]] = true;
|
|
|
|
|
|
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
|
|
|
|
{
|
|
|
|
|
r = cfun->eh->region_array[i];
|
|
|
|
|
if (r && r->region_number == i && !reachable[i])
|
|
|
|
|
{
|
|
|
|
|
/* Don't remove ERT_THROW regions if their outer region
|
|
|
|
|
is reachable. */
|
|
|
|
|
if (r->type == ERT_THROW
|
|
|
|
|
&& r->outer
|
|
|
|
|
&& reachable[r->outer->region_number])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
remove_eh_handler (r);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free (reachable);
|
|
|
|
|
free (uid_region_num);
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Turn NOTE_INSN_EH_REGION notes into REG_EH_REGION notes for each
|
|
|
|
|
can_throw instruction in the region. */
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
|
|
|
|
static void
|
2001-03-28 03:04:51 -08:00
|
|
|
|
convert_from_eh_region_ranges_1 (pinsns, orig_sp, cur)
|
|
|
|
|
rtx *pinsns;
|
|
|
|
|
int *orig_sp;
|
|
|
|
|
int cur;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int *sp = orig_sp;
|
|
|
|
|
rtx insn, next;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (insn = *pinsns; insn ; insn = next)
|
|
|
|
|
{
|
|
|
|
|
next = NEXT_INSN (insn);
|
|
|
|
|
if (GET_CODE (insn) == NOTE)
|
|
|
|
|
{
|
|
|
|
|
int kind = NOTE_LINE_NUMBER (insn);
|
|
|
|
|
if (kind == NOTE_INSN_EH_REGION_BEG
|
|
|
|
|
|| kind == NOTE_INSN_EH_REGION_END)
|
|
|
|
|
{
|
|
|
|
|
if (kind == NOTE_INSN_EH_REGION_BEG)
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *r;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
*sp++ = cur;
|
|
|
|
|
cur = NOTE_EH_HANDLER (insn);
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
r = cfun->eh->region_array[cur];
|
|
|
|
|
if (r->type == ERT_FIXUP)
|
|
|
|
|
{
|
|
|
|
|
r = r->u.fixup.real_region;
|
|
|
|
|
cur = r ? r->region_number : 0;
|
|
|
|
|
}
|
|
|
|
|
else if (r->type == ERT_CATCH)
|
|
|
|
|
{
|
|
|
|
|
r = r->outer;
|
|
|
|
|
cur = r ? r->region_number : 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
cur = *--sp;
|
|
|
|
|
|
|
|
|
|
/* Removing the first insn of a CALL_PLACEHOLDER sequence
|
|
|
|
|
requires extra care to adjust sequence start. */
|
|
|
|
|
if (insn == *pinsns)
|
|
|
|
|
*pinsns = next;
|
|
|
|
|
remove_insn (insn);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (INSN_P (insn))
|
|
|
|
|
{
|
2003-05-07 15:11:38 -07:00
|
|
|
|
if (cur > 0
|
|
|
|
|
&& ! find_reg_note (insn, REG_EH_REGION, NULL_RTX)
|
|
|
|
|
/* Calls can always potentially throw exceptions, unless
|
|
|
|
|
they have a REG_EH_REGION note with a value of 0 or less.
|
|
|
|
|
Which should be the only possible kind so far. */
|
|
|
|
|
&& (GET_CODE (insn) == CALL_INSN
|
|
|
|
|
/* If we wanted exceptions for non-call insns, then
|
|
|
|
|
any may_trap_p instruction could throw. */
|
|
|
|
|
|| (flag_non_call_exceptions
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) != CLOBBER
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) != USE
|
|
|
|
|
&& may_trap_p (PATTERN (insn)))))
|
2001-03-28 03:04:51 -08:00
|
|
|
|
{
|
2003-05-07 15:11:38 -07:00
|
|
|
|
REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (cur),
|
2001-03-28 03:04:51 -08:00
|
|
|
|
REG_NOTES (insn));
|
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (GET_CODE (insn) == CALL_INSN
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
|
|
|
|
|
{
|
|
|
|
|
convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 0),
|
|
|
|
|
sp, cur);
|
|
|
|
|
convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 1),
|
|
|
|
|
sp, cur);
|
|
|
|
|
convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 2),
|
|
|
|
|
sp, cur);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (sp != orig_sp)
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
convert_from_eh_region_ranges ()
|
|
|
|
|
{
|
|
|
|
|
int *stack;
|
|
|
|
|
rtx insns;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
collect_eh_region_array ();
|
|
|
|
|
resolve_fixup_regions ();
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
stack = xmalloc (sizeof (int) * (cfun->eh->last_region_number + 1));
|
|
|
|
|
insns = get_insns ();
|
|
|
|
|
convert_from_eh_region_ranges_1 (&insns, stack, 0);
|
|
|
|
|
free (stack);
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
remove_fixup_regions ();
|
2002-01-14 22:06:26 +01:00
|
|
|
|
remove_unreachable_regions (insns);
|
1997-04-23 20:11:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-04-09 17:15:58 -07:00
|
|
|
|
static void
|
|
|
|
|
add_ehl_entry (label, region)
|
|
|
|
|
rtx label;
|
|
|
|
|
struct eh_region *region;
|
|
|
|
|
{
|
|
|
|
|
struct ehl_map_entry **slot, *entry;
|
|
|
|
|
|
|
|
|
|
LABEL_PRESERVE_P (label) = 1;
|
|
|
|
|
|
2002-06-04 07:11:05 +00:00
|
|
|
|
entry = (struct ehl_map_entry *) ggc_alloc (sizeof (*entry));
|
2002-04-09 17:15:58 -07:00
|
|
|
|
entry->label = label;
|
|
|
|
|
entry->region = region;
|
|
|
|
|
|
|
|
|
|
slot = (struct ehl_map_entry **)
|
2002-06-04 07:11:05 +00:00
|
|
|
|
htab_find_slot (cfun->eh->exception_handler_label_map, entry, INSERT);
|
2002-04-10 18:06:33 -07:00
|
|
|
|
|
|
|
|
|
/* Before landing pad creation, each exception handler has its own
|
|
|
|
|
label. After landing pad creation, the exception handlers may
|
|
|
|
|
share landing pads. This is ok, since maybe_remove_eh_handler
|
|
|
|
|
only requires the 1-1 mapping before landing pad creation. */
|
|
|
|
|
if (*slot && !cfun->eh->built_landing_pads)
|
2002-04-09 17:15:58 -07:00
|
|
|
|
abort ();
|
2002-04-10 18:06:33 -07:00
|
|
|
|
|
2002-04-09 17:15:58 -07:00
|
|
|
|
*slot = entry;
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
find_exception_handler_labels ()
|
1997-04-23 20:11:52 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int i;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2002-06-04 07:11:05 +00:00
|
|
|
|
if (cfun->eh->exception_handler_label_map)
|
|
|
|
|
htab_empty (cfun->eh->exception_handler_label_map);
|
2002-04-09 17:15:58 -07:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* ??? The expansion factor here (3/2) must be greater than the htab
|
|
|
|
|
occupancy factor (4/3) to avoid unnecessary resizing. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
cfun->eh->exception_handler_label_map
|
|
|
|
|
= htab_create_ggc (cfun->eh->last_region_number * 3 / 2,
|
|
|
|
|
ehl_hash, ehl_eq, NULL);
|
2002-04-09 17:15:58 -07:00
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (cfun->eh->region_tree == NULL)
|
|
|
|
|
return;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *region = cfun->eh->region_array[i];
|
|
|
|
|
rtx lab;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2002-01-14 22:06:26 +01:00
|
|
|
|
if (! region || region->region_number != i)
|
2001-03-28 03:04:51 -08:00
|
|
|
|
continue;
|
|
|
|
|
if (cfun->eh->built_landing_pads)
|
|
|
|
|
lab = region->landing_pad;
|
|
|
|
|
else
|
|
|
|
|
lab = region->label;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (lab)
|
2002-04-09 17:15:58 -07:00
|
|
|
|
add_ehl_entry (lab, region);
|
1997-04-23 20:11:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* For sjlj exceptions, need the return label to remain live until
|
|
|
|
|
after landing pad generation. */
|
|
|
|
|
if (USING_SJLJ_EXCEPTIONS && ! cfun->eh->built_landing_pads)
|
2002-04-09 17:15:58 -07:00
|
|
|
|
add_ehl_entry (return_label, NULL);
|
1997-04-23 20:11:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-19 16:49:13 -08:00
|
|
|
|
bool
|
|
|
|
|
current_function_has_exception_handlers ()
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *region = cfun->eh->region_array[i];
|
|
|
|
|
|
|
|
|
|
if (! region || region->region_number != i)
|
|
|
|
|
continue;
|
|
|
|
|
if (region->type != ERT_THROW)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
static struct eh_region *
|
|
|
|
|
duplicate_eh_region_1 (o, map)
|
|
|
|
|
struct eh_region *o;
|
|
|
|
|
struct inline_remap *map;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *n
|
2002-06-04 07:11:05 +00:00
|
|
|
|
= (struct eh_region *) ggc_alloc_cleared (sizeof (struct eh_region));
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
n->region_number = o->region_number + cfun->eh->last_region_number;
|
|
|
|
|
n->type = o->type;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
switch (n->type)
|
|
|
|
|
{
|
|
|
|
|
case ERT_CLEANUP:
|
|
|
|
|
case ERT_MUST_NOT_THROW:
|
|
|
|
|
break;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_TRY:
|
|
|
|
|
if (o->u.try.continue_label)
|
|
|
|
|
n->u.try.continue_label
|
|
|
|
|
= get_label_from_map (map,
|
|
|
|
|
CODE_LABEL_NUMBER (o->u.try.continue_label));
|
|
|
|
|
break;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_CATCH:
|
2001-11-16 13:48:18 +01:00
|
|
|
|
n->u.catch.type_list = o->u.catch.type_list;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
break;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_ALLOWED_EXCEPTIONS:
|
|
|
|
|
n->u.allowed.type_list = o->u.allowed.type_list;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ERT_THROW:
|
|
|
|
|
n->u.throw.type = o->u.throw.type;
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
default:
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (o->label)
|
|
|
|
|
n->label = get_label_from_map (map, CODE_LABEL_NUMBER (o->label));
|
2001-04-24 20:23:10 -04:00
|
|
|
|
if (o->resume)
|
1999-08-09 08:52:48 +00:00
|
|
|
|
{
|
2001-04-24 20:23:10 -04:00
|
|
|
|
n->resume = map->insn_map[INSN_UID (o->resume)];
|
|
|
|
|
if (n->resume == NULL)
|
2001-03-28 03:04:51 -08:00
|
|
|
|
abort ();
|
1997-04-23 20:11:52 +00:00
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return n;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void
|
|
|
|
|
duplicate_eh_region_2 (o, n_array)
|
|
|
|
|
struct eh_region *o;
|
|
|
|
|
struct eh_region **n_array;
|
1997-04-29 20:03:15 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *n = n_array[o->region_number];
|
1997-04-29 20:03:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
switch (n->type)
|
|
|
|
|
{
|
|
|
|
|
case ERT_TRY:
|
|
|
|
|
n->u.try.catch = n_array[o->u.try.catch->region_number];
|
|
|
|
|
n->u.try.last_catch = n_array[o->u.try.last_catch->region_number];
|
|
|
|
|
break;
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_CATCH:
|
|
|
|
|
if (o->u.catch.next_catch)
|
2002-06-03 01:13:17 +00:00
|
|
|
|
n->u.catch.next_catch = n_array[o->u.catch.next_catch->region_number];
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (o->u.catch.prev_catch)
|
2002-06-03 01:13:17 +00:00
|
|
|
|
n->u.catch.prev_catch = n_array[o->u.catch.prev_catch->region_number];
|
2001-03-28 03:04:51 -08:00
|
|
|
|
break;
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (o->outer)
|
|
|
|
|
n->outer = n_array[o->outer->region_number];
|
|
|
|
|
if (o->inner)
|
|
|
|
|
n->inner = n_array[o->inner->region_number];
|
|
|
|
|
if (o->next_peer)
|
|
|
|
|
n->next_peer = n_array[o->next_peer->region_number];
|
2001-12-12 09:27:29 +01:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
duplicate_eh_regions (ifun, map)
|
|
|
|
|
struct function *ifun;
|
|
|
|
|
struct inline_remap *map;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int ifun_last_region_number = ifun->eh->last_region_number;
|
|
|
|
|
struct eh_region **n_array, *root, *cur;
|
|
|
|
|
int i;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (ifun_last_region_number == 0)
|
|
|
|
|
return 0;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = 1; i <= ifun_last_region_number; ++i)
|
1997-04-23 20:11:52 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
cur = ifun->eh->region_array[i];
|
|
|
|
|
if (!cur || cur->region_number != i)
|
|
|
|
|
continue;
|
|
|
|
|
n_array[i] = duplicate_eh_region_1 (cur, map);
|
1997-04-23 20:11:52 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = 1; i <= ifun_last_region_number; ++i)
|
1997-04-23 20:11:52 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
cur = ifun->eh->region_array[i];
|
|
|
|
|
if (!cur || cur->region_number != i)
|
|
|
|
|
continue;
|
|
|
|
|
duplicate_eh_region_2 (cur, n_array);
|
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
root = n_array[ifun->eh->region_tree->region_number];
|
|
|
|
|
cur = cfun->eh->cur_region;
|
|
|
|
|
if (cur)
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *p = cur->inner;
|
|
|
|
|
if (p)
|
|
|
|
|
{
|
|
|
|
|
while (p->next_peer)
|
|
|
|
|
p = p->next_peer;
|
|
|
|
|
p->next_peer = root;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
cur->inner = root;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = 1; i <= ifun_last_region_number; ++i)
|
2001-08-01 01:37:31 +00:00
|
|
|
|
if (n_array[i] && n_array[i]->outer == NULL)
|
2001-03-28 03:04:51 -08:00
|
|
|
|
n_array[i]->outer = cur;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *p = cfun->eh->region_tree;
|
|
|
|
|
if (p)
|
|
|
|
|
{
|
|
|
|
|
while (p->next_peer)
|
|
|
|
|
p = p->next_peer;
|
|
|
|
|
p->next_peer = root;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
cfun->eh->region_tree = root;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
}
|
1999-11-18 17:50:56 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
free (n_array);
|
1999-11-18 17:50:56 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
i = cfun->eh->last_region_number;
|
|
|
|
|
cfun->eh->last_region_number = i + ifun_last_region_number;
|
|
|
|
|
return i;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
t2r_eq (pentry, pdata)
|
|
|
|
|
const PTR pentry;
|
|
|
|
|
const PTR pdata;
|
1997-12-03 20:04:31 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
tree entry = (tree) pentry;
|
|
|
|
|
tree data = (tree) pdata;
|
1997-12-03 20:04:31 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return TREE_PURPOSE (entry) == data;
|
1997-12-03 20:04:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static hashval_t
|
|
|
|
|
t2r_hash (pentry)
|
|
|
|
|
const PTR pentry;
|
|
|
|
|
{
|
|
|
|
|
tree entry = (tree) pentry;
|
|
|
|
|
return TYPE_HASH (TREE_PURPOSE (entry));
|
|
|
|
|
}
|
1997-12-03 20:04:31 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void
|
|
|
|
|
add_type_for_runtime (type)
|
|
|
|
|
tree type;
|
|
|
|
|
{
|
|
|
|
|
tree *slot;
|
1997-12-03 20:04:31 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
|
|
|
|
|
TYPE_HASH (type), INSERT);
|
|
|
|
|
if (*slot == NULL)
|
|
|
|
|
{
|
|
|
|
|
tree runtime = (*lang_eh_runtime_type) (type);
|
|
|
|
|
*slot = tree_cons (type, runtime, NULL_TREE);
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static tree
|
|
|
|
|
lookup_type_for_runtime (type)
|
|
|
|
|
tree type;
|
|
|
|
|
{
|
|
|
|
|
tree *slot;
|
1998-11-05 05:34:01 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
|
|
|
|
|
TYPE_HASH (type), NO_INSERT);
|
1998-11-05 05:34:01 +00:00
|
|
|
|
|
ChangeLog.0, [...]: Fix spelling errors.
* ChangeLog.0, ChangeLog.2, ChangeLog.3, ChangeLog.4, ChangeLog,
FSFChangeLog.10, c-decl.c, cppfiles.c, cppinit.c, cpplex.c,
cpplib.c, cppmain.c, cse.c, df.c, diagnostic.c, dominance.c,
dwarf2out.c, dwarfout.c, emit-rtl.c, errors.c, except.c, except.h,
explow.c, function.c, gcse.c, genrecog.c, predict.c, regmove.c,
sched-rgn.c, ssa-ccp.c, stmt.c, toplev.c: Fix spelling errors.
From-SVN: r47279
2001-11-23 02:05:19 +00:00
|
|
|
|
/* We should have always inserted the data earlier. */
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return TREE_VALUE (*slot);
|
|
|
|
|
}
|
1997-12-03 20:04:31 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* Represent an entry in @TTypes for either catch actions
|
|
|
|
|
or exception filter actions. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct ttypes_filter GTY(())
|
2001-03-28 03:04:51 -08:00
|
|
|
|
{
|
|
|
|
|
tree t;
|
|
|
|
|
int filter;
|
|
|
|
|
};
|
1998-11-05 05:34:01 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
|
|
|
|
|
(a tree) for a @TTypes type node we are thinking about adding. */
|
1998-11-05 05:34:01 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static int
|
|
|
|
|
ttypes_filter_eq (pentry, pdata)
|
|
|
|
|
const PTR pentry;
|
|
|
|
|
const PTR pdata;
|
|
|
|
|
{
|
|
|
|
|
const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
|
|
|
|
|
tree data = (tree) pdata;
|
1998-11-05 05:34:01 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return entry->t == data;
|
1997-12-03 20:04:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static hashval_t
|
|
|
|
|
ttypes_filter_hash (pentry)
|
|
|
|
|
const PTR pentry;
|
|
|
|
|
{
|
|
|
|
|
const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
|
|
|
|
|
return TYPE_HASH (entry->t);
|
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
|
|
|
|
|
exception specification list we are thinking about adding. */
|
|
|
|
|
/* ??? Currently we use the type lists in the order given. Someone
|
|
|
|
|
should put these in some canonical order. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
ehspec_filter_eq (pentry, pdata)
|
|
|
|
|
const PTR pentry;
|
|
|
|
|
const PTR pdata;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
|
|
|
|
|
const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
|
|
|
|
|
|
|
|
|
|
return type_list_equal (entry->t, data->t);
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Hash function for exception specification lists. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static hashval_t
|
|
|
|
|
ehspec_filter_hash (pentry)
|
|
|
|
|
const PTR pentry;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
|
|
|
|
|
hashval_t h = 0;
|
|
|
|
|
tree list;
|
|
|
|
|
|
|
|
|
|
for (list = entry->t; list ; list = TREE_CHAIN (list))
|
|
|
|
|
h = (h << 5) + (h >> 27) + TYPE_HASH (TREE_VALUE (list));
|
|
|
|
|
return h;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Add TYPE to cfun->eh->ttype_data, using TYPES_HASH to speed
|
|
|
|
|
up the search. Return the filter value to be used. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static int
|
|
|
|
|
add_ttypes_entry (ttypes_hash, type)
|
|
|
|
|
htab_t ttypes_hash;
|
|
|
|
|
tree type;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct ttypes_filter **slot, *n;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
slot = (struct ttypes_filter **)
|
|
|
|
|
htab_find_slot_with_hash (ttypes_hash, type, TYPE_HASH (type), INSERT);
|
|
|
|
|
|
|
|
|
|
if ((n = *slot) == NULL)
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Filter value is a 1 based table index. */
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
n = (struct ttypes_filter *) xmalloc (sizeof (*n));
|
|
|
|
|
n->t = type;
|
|
|
|
|
n->filter = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) + 1;
|
|
|
|
|
*slot = n;
|
|
|
|
|
|
|
|
|
|
VARRAY_PUSH_TREE (cfun->eh->ttype_data, type);
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
return n->filter;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
|
|
|
|
|
to speed up the search. Return the filter value to be used. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
add_ehspec_entry (ehspec_hash, ttypes_hash, list)
|
|
|
|
|
htab_t ehspec_hash;
|
|
|
|
|
htab_t ttypes_hash;
|
|
|
|
|
tree list;
|
1996-09-14 20:47:01 -04:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct ttypes_filter **slot, *n;
|
|
|
|
|
struct ttypes_filter dummy;
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
dummy.t = list;
|
|
|
|
|
slot = (struct ttypes_filter **)
|
|
|
|
|
htab_find_slot (ehspec_hash, &dummy, INSERT);
|
|
|
|
|
|
|
|
|
|
if ((n = *slot) == NULL)
|
|
|
|
|
{
|
|
|
|
|
/* Filter value is a -1 based byte index into a uleb128 buffer. */
|
|
|
|
|
|
|
|
|
|
n = (struct ttypes_filter *) xmalloc (sizeof (*n));
|
|
|
|
|
n->t = list;
|
|
|
|
|
n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1);
|
|
|
|
|
*slot = n;
|
|
|
|
|
|
|
|
|
|
/* Look up each type in the list and encode its filter
|
|
|
|
|
value as a uleb128. Terminate the list with 0. */
|
|
|
|
|
for (; list ; list = TREE_CHAIN (list))
|
2001-12-12 09:27:29 +01:00
|
|
|
|
push_uleb128 (&cfun->eh->ehspec_data,
|
2001-03-28 03:04:51 -08:00
|
|
|
|
add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
|
|
|
|
|
VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return n->filter;
|
1996-09-14 20:47:01 -04:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Generate the action filter values to be used for CATCH and
|
|
|
|
|
ALLOWED_EXCEPTIONS regions. When using dwarf2 exception regions,
|
|
|
|
|
we use lots of landing pads, and so every type or list can share
|
|
|
|
|
the same filter value, which saves table space. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
assign_filter_values ()
|
1998-05-14 13:39:15 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int i;
|
|
|
|
|
htab_t ttypes, ehspec;
|
1998-06-24 06:56:37 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
VARRAY_TREE_INIT (cfun->eh->ttype_data, 16, "ttype_data");
|
|
|
|
|
VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data");
|
1998-06-24 06:56:37 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
|
|
|
|
|
ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *r = cfun->eh->region_array[i];
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Mind we don't process a region more than once. */
|
|
|
|
|
if (!r || r->region_number != i)
|
|
|
|
|
continue;
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
switch (r->type)
|
|
|
|
|
{
|
|
|
|
|
case ERT_CATCH:
|
2001-11-16 13:48:18 +01:00
|
|
|
|
/* Whatever type_list is (NULL or true list), we build a list
|
|
|
|
|
of filters for the region. */
|
|
|
|
|
r->u.catch.filter_list = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
if (r->u.catch.type_list != NULL)
|
|
|
|
|
{
|
|
|
|
|
/* Get a filter value for each of the types caught and store
|
|
|
|
|
them in the region's dedicated list. */
|
|
|
|
|
tree tp_node = r->u.catch.type_list;
|
|
|
|
|
|
|
|
|
|
for (;tp_node; tp_node = TREE_CHAIN (tp_node))
|
|
|
|
|
{
|
|
|
|
|
int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node));
|
|
|
|
|
tree flt_node = build_int_2 (flt, 0);
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
|
|
|
|
r->u.catch.filter_list
|
2001-11-16 13:48:18 +01:00
|
|
|
|
= tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Get a filter value for the NULL list also since it will need
|
|
|
|
|
an action record anyway. */
|
|
|
|
|
int flt = add_ttypes_entry (ttypes, NULL);
|
|
|
|
|
tree flt_node = build_int_2 (flt, 0);
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
|
|
|
|
r->u.catch.filter_list
|
2001-11-16 13:48:18 +01:00
|
|
|
|
= tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
|
|
|
|
|
}
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
break;
|
1998-09-15 11:20:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_ALLOWED_EXCEPTIONS:
|
|
|
|
|
r->u.allowed.filter
|
|
|
|
|
= add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list);
|
|
|
|
|
break;
|
1998-09-15 11:20:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
htab_delete (ttypes);
|
|
|
|
|
htab_delete (ehspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
build_post_landing_pads ()
|
|
|
|
|
{
|
|
|
|
|
int i;
|
1998-09-15 11:20:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
1998-09-15 11:20:52 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *region = cfun->eh->region_array[i];
|
|
|
|
|
rtx seq;
|
1998-09-15 11:20:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Mind we don't process a region more than once. */
|
|
|
|
|
if (!region || region->region_number != i)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
switch (region->type)
|
system.h: Don't redefine abort or trim_filename.
1999-08-25 22:10 -0700 Zack Weinberg <zack@bitmover.com>
* system.h: Don't redefine abort or trim_filename.
* rtl.h: Define abort to fancy_abort (__FILE__, __LINE__, 0)
or fancy_abort (__FILE__, __LINE__, __FUNCTION__) depending on
whether or not __FUNCTION__ is available.
* tree.h: Duplicate rtl.h's definition of abort, for files
that don't include rtl.h. Delete all code to perform type
checking with a compiler other than GCC.
* varray.h: Delete all code to perform type checking with a
compiler other than GCC. Make VARRAY_CHECK() always evaluate
its arguments exactly once, using a statement expression.
Adjust the VARRAY_<type> accessor macros to match.
* toplev.h (fatal_insn, fatal_insn_not_found): Kill.
(_fatal_insn, _fatal_insn_not_found): New fns, take info on
caller's location. Define fatal_insn and fatal_insn_not_found
as macros that use _fatal_insn and _fatal_insn_not_found.
(fancy_abort, trim_filename): Kill prototypes.
* rtl.c (trim_filename): Move here from toplev.c.
(fancy_abort): New function.
(DIR_SEPARATOR): Provide default definition.
* tree.c (tree_check_failed, tree_class_check_failed): Go
through fancy_abort.
(tree_check, tree_class_check, cst_or_constructor_check,
expr_check): Delete.
* varray.c (varray_check_failed): New function.
* toplev.c (fatal_insn, fatal_insn_not_found): Replace with
_fatal_insn and _fatal_insn_not_found. Go through
fancy_abort.
(trim_filename, fancy_abort): Delete.
* builtins.c (expand_builtin_args_info): Report ICE with abort.
* except.c (start_catch_handler): Report ICE with error/abort
combo.
* final.c (output_operand_lossage): Likewise.
* flow.c (verify_flow_info): Likewise.
* gcc.c: Prototype fatal.
* gengenrtl.c: Undef abort after including rtl.h not system.h.
* genattr.c, genattrtab.c, genemit.c, genextract.c,
genflags.c, genopinit.c, genoutput.c, genpeep.c, genrecog.c:
Don't define fancy_abort.
From-SVN: r28889
1999-08-26 05:18:44 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_TRY:
|
|
|
|
|
/* ??? Collect the set of all non-overlapping catch handlers
|
|
|
|
|
all the way up the chain until blocked by a cleanup. */
|
|
|
|
|
/* ??? Outer try regions can share landing pads with inner
|
|
|
|
|
try regions if the types are completely non-overlapping,
|
ChangeLog.0, [...]: Fix spelling errors.
* ChangeLog.0, ChangeLog.2, ChangeLog.3, ChangeLog.4, ChangeLog,
FSFChangeLog.10, c-decl.c, cppfiles.c, cppinit.c, cpplex.c,
cpplib.c, cppmain.c, cse.c, df.c, diagnostic.c, dominance.c,
dwarf2out.c, dwarfout.c, emit-rtl.c, errors.c, except.c, except.h,
explow.c, function.c, gcse.c, genrecog.c, predict.c, regmove.c,
sched-rgn.c, ssa-ccp.c, stmt.c, toplev.c: Fix spelling errors.
From-SVN: r47279
2001-11-23 02:05:19 +00:00
|
|
|
|
and there are no intervening cleanups. */
|
1998-09-15 11:20:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
region->post_landing_pad = gen_label_rtx ();
|
1998-09-15 11:20:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
start_sequence ();
|
1998-09-15 11:20:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_label (region->post_landing_pad);
|
1998-09-15 11:20:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* ??? It is mighty inconvenient to call back into the
|
|
|
|
|
switch statement generation code in expand_end_case.
|
|
|
|
|
Rapid prototyping sez a sequence of ifs. */
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *c;
|
|
|
|
|
for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
|
|
|
|
|
{
|
2001-11-16 13:48:18 +01:00
|
|
|
|
if (c->u.catch.type_list == NULL)
|
2003-05-07 15:11:38 -07:00
|
|
|
|
emit_jump (c->label);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
else
|
2001-11-16 13:48:18 +01:00
|
|
|
|
{
|
|
|
|
|
/* Need for one cmp/jump per type caught. Each type
|
|
|
|
|
list entry has a matching entry in the filter list
|
|
|
|
|
(see assign_filter_values). */
|
|
|
|
|
tree tp_node = c->u.catch.type_list;
|
|
|
|
|
tree flt_node = c->u.catch.filter_list;
|
|
|
|
|
|
|
|
|
|
for (; tp_node; )
|
|
|
|
|
{
|
|
|
|
|
emit_cmp_and_jump_insns
|
|
|
|
|
(cfun->eh->filter,
|
|
|
|
|
GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)),
|
|
|
|
|
EQ, NULL_RTX, word_mode, 0, c->label);
|
|
|
|
|
|
|
|
|
|
tp_node = TREE_CHAIN (tp_node);
|
|
|
|
|
flt_node = TREE_CHAIN (flt_node);
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
1998-09-15 11:20:52 +00:00
|
|
|
|
|
2001-04-24 20:23:10 -04:00
|
|
|
|
/* We delay the generation of the _Unwind_Resume until we generate
|
|
|
|
|
landing pads. We emit a marker here so as to get good control
|
|
|
|
|
flow data in the meantime. */
|
|
|
|
|
region->resume
|
|
|
|
|
= emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
|
|
|
|
|
emit_barrier ();
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
seq = get_insns ();
|
|
|
|
|
end_sequence ();
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
2002-06-05 David S. Miller <davem@redhat.com>
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
* rtl.h (gen_sequence, emit_insns, emit_insns_before,
emit_insns_before_scope, emit_insns_after,
emit_insns_after_scope): Delete declaration.
* ada/misc.c (insert_code_for): Use emit_insn* instead of
emit_insns_foo.
* config/alpha/alpha.c (alpha_set_memflags_1): Abort on SEQUENCE.
(alpha_set_memflags): Fix comment.
(set_frame_related_p): Use get_insns instead of gen_sequence.
* config/alpha/alpha.md (setjmp receiver splitter): Avoid
emitting no insns.
* config/arm/arm.c (arm_finalize_pic): Use get_insns instead of
gen_sequence.
(arm_gen_load_multiple, arm_gen_store_multiple): Likewise.
* config/fr30/fr30.c (fr30_move_double): Likewise.
* config/i386/i386.c (ix86_expand_int_movcc, ix86_expand_movstr):
Likewise.
* config/ia64/ia64.c (spill_restore_mem): Likewise.
* config/ia64/ia64.md (conditional move spliiter): Avoid emitting
no insns.
* config/m32r/m32r.c (gen_split_move_double): Use get_insns
instead of gen_sequence.
* config/mips/mips.c (embedded_pic_fnaddr_reg): Likewise.
(mips_expand_prologue, mips16_gp_pseudo_reg): Likewise.
* config/sh/sh.c (sh_need_epilogue): Likewise.
* config/sparc/sparc.md (current_function_calls_alloca, flat): New
attributes.
(setjmp pattern and split): Use them to avoid splitter which emits
no RTL.
* genattrtab.c (main): Emit include of function.h
* config/stormy16/stormy16.c (xstormy16_split_cbranch): Use
get_insns instead of gen_sequence.
* config/cris/cris.c (cris_split_movdx): Likewise.
* emit-rtl.c (emit_insns*): Kill.
(try_split): Expect insn list instead of SEQUENCE.
(make_jump_insn_raw, make_call_insn_raw): Fix comments.
(emit_*insn*): Reimplement to work with INSN lists and PATTERNs.
Make them abort if a SEQUENCE is given and RTL checking is
enabled.
(emit_*_scope): Don't forget to set scope on final insn.
(gen_sequence): Move from here...
* ssa.c (gen_sequence): To here as private function.
* builtins.c (expand_builtin_apply_args): Use emit_insn_foo, fix
comments.
(expand_builtin_return, expand_builtin_mathfn): Likewise.
(expand_builtin_strlen): Use get_insns instead of gen_sequence.
(expand_builtin_saveregs): Use emit_insn_foo, fix comments.
(expand_builtin_expect_jump): Use get_insns and fix comments.
* calls.c (try_to_integrate): Use emit_insn_foo.
(expand_call, emit_library_call_value_1): Likewise.
* expr.c (emit_queue): Handle insn lists instead of SEQUENCE.
(emit_move_insn_1): Use get_insns instead of gen_sequence.
(expand_expr): Use emit_insn_foo.
* cfgrtl.c (commit_one_edge_insertion): Use emit_insn_foo.
* except.c (build_post_landing_pads): Likewise.
* flow.c (attempt_auto_inc): Likewise.
* stmt.c (expand_fixup, fixup_gotos, expand_nl_handler_label,
expand_nl_goto_receivers, expand_decl_cleanup): Likewise.
* function.c (fixup_var_refs_insn): Use get_insns instead of
gen_sequence.
(fixup_var_refs_1): Likewise and expect insn list from gen_foo.
(fixup_memory_subreg): Use get_insns instead of gen_sequence.
(fixup_stack_1, purge_addressof_1, expand_main_function,
get_arg_pointer_save_area): Likewise.
(optimize_bit_field, instantiate_virtual_regs_1, assign_parms,
expand_function_end): Use emit_insn_foo.
(record_insns, keep_stack_depressed): Work with insn list instead
of SEQUENCE, fix comments.
* ifcvt.c (noce_emit_store_flag, noce_try_store_flag,
noce_try_store_flag_constants, noce_try_store_flag_inc,
noce_try_store_flag_mask, noce_emit_cmove, noce_try_cmove_arith,
noce_try_minmax, noce_try_abs): Use emit_insn_foo.
(noce_process_if_block): Use get_insns instead of gen_sequence.
* optabs.c (add_equal_note): Work with insn list, fix comments.
(expand_binop): Expect insn list from GEN_FCN(), use emit_insn_foo.
(expand_unop, expand_complex_abs, expand_unop_insn,
expand_no_conflict_block): Likewise.
(gen_move_insn): Use get_insns instead of gen_sequence.
(gen_cond_trap): Likewise.
* integrate.c (copy_rtx_and_substitute): Likewise.
(emit_initial_value_sets): Use emit_insn_foo.
* reload1.c (emit_output_reload_insns, emit_reload_insns): Likewise.
(fixup_abnormal_edges): Avoid losing REG_NOTES more intelligently
now that RTL generators give insn lists.
* sibcall.c (replace_call_placeholder): Use emit_insn_foo.
* doloop.c (doloop_modify, doloop_modify_runtime): Use get_insns
instead of gen_sequence.
(doloop_optimize): Work with insn lists instead of SEQUENCE rtl.
* explow.c (emit_stack_save, emit_stack_restore): Use get_insns
instead of gen_sequence.
* loop.c (move_movables, emit_prefetch_instructions,
gen_add_mult, check_dbra_loop, gen_load_of_final_value):
Likewise.
(loop_regs_update): Work with insn list instead of SEQUENCE rtl.
(product_cheap_p): Likewise, and add commentary about RTL wastage
here.
* lcm.c (optimize_mode_switching): Use get_insns instead of
gen_sequence.
* profile.c (gen_edge_profiler): Likewise.
* regmove.c (copy_src_to_dest): Likewise.
* reg-stack.c (compensate_edge): Likewise and fix comment.
* gcse.c (process_insert_insn): Likewise.
(insert_insn_end_bb): Work with insn list instead of SEQUENCE rtl.
* jump.c (delete_prior_computation): Update comment.
* genemit.c (gen_expand, gen_split, main): Use get_insns instead
of gen_sequence, update comments to match.
* recog.c (peephole2_optimize): Work with insn lists instead of
SEQUENCE rtl.
* sched-vis.c (print_pattern): Abort on SEQUENCE.
* unroll.c (unroll_loop, find_splittable_givs, final_giv_value):
Use get_insns instead of gen_sequence.
(copy_loop_body): Likewise and don't emit dummy NOTE.
* genrecog.c: Don't mention SEQUENCE rtl in comments.
* combine.c (try_combine): Expect insn lists from split generator.
* reorg.c (relax_delay_slots): Emit SEQUENCE into insn list by
hand.
From-SVN: r54497
2002-06-11 05:22:48 -07:00
|
|
|
|
emit_insn_before (seq, region->u.try.catch->label);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
break;
|
1998-09-15 11:20:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_ALLOWED_EXCEPTIONS:
|
|
|
|
|
region->post_landing_pad = gen_label_rtx ();
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
start_sequence ();
|
1999-12-12 18:32:36 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_label (region->post_landing_pad);
|
1999-12-12 18:32:36 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_cmp_and_jump_insns (cfun->eh->filter,
|
|
|
|
|
GEN_INT (region->u.allowed.filter),
|
2001-11-15 23:44:58 +00:00
|
|
|
|
EQ, NULL_RTX, word_mode, 0, region->label);
|
1999-12-12 18:32:36 +00:00
|
|
|
|
|
2001-04-24 20:23:10 -04:00
|
|
|
|
/* We delay the generation of the _Unwind_Resume until we generate
|
|
|
|
|
landing pads. We emit a marker here so as to get good control
|
|
|
|
|
flow data in the meantime. */
|
|
|
|
|
region->resume
|
|
|
|
|
= emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
|
|
|
|
|
emit_barrier ();
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
seq = get_insns ();
|
|
|
|
|
end_sequence ();
|
|
|
|
|
|
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
2002-06-05 David S. Miller <davem@redhat.com>
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
* rtl.h (gen_sequence, emit_insns, emit_insns_before,
emit_insns_before_scope, emit_insns_after,
emit_insns_after_scope): Delete declaration.
* ada/misc.c (insert_code_for): Use emit_insn* instead of
emit_insns_foo.
* config/alpha/alpha.c (alpha_set_memflags_1): Abort on SEQUENCE.
(alpha_set_memflags): Fix comment.
(set_frame_related_p): Use get_insns instead of gen_sequence.
* config/alpha/alpha.md (setjmp receiver splitter): Avoid
emitting no insns.
* config/arm/arm.c (arm_finalize_pic): Use get_insns instead of
gen_sequence.
(arm_gen_load_multiple, arm_gen_store_multiple): Likewise.
* config/fr30/fr30.c (fr30_move_double): Likewise.
* config/i386/i386.c (ix86_expand_int_movcc, ix86_expand_movstr):
Likewise.
* config/ia64/ia64.c (spill_restore_mem): Likewise.
* config/ia64/ia64.md (conditional move spliiter): Avoid emitting
no insns.
* config/m32r/m32r.c (gen_split_move_double): Use get_insns
instead of gen_sequence.
* config/mips/mips.c (embedded_pic_fnaddr_reg): Likewise.
(mips_expand_prologue, mips16_gp_pseudo_reg): Likewise.
* config/sh/sh.c (sh_need_epilogue): Likewise.
* config/sparc/sparc.md (current_function_calls_alloca, flat): New
attributes.
(setjmp pattern and split): Use them to avoid splitter which emits
no RTL.
* genattrtab.c (main): Emit include of function.h
* config/stormy16/stormy16.c (xstormy16_split_cbranch): Use
get_insns instead of gen_sequence.
* config/cris/cris.c (cris_split_movdx): Likewise.
* emit-rtl.c (emit_insns*): Kill.
(try_split): Expect insn list instead of SEQUENCE.
(make_jump_insn_raw, make_call_insn_raw): Fix comments.
(emit_*insn*): Reimplement to work with INSN lists and PATTERNs.
Make them abort if a SEQUENCE is given and RTL checking is
enabled.
(emit_*_scope): Don't forget to set scope on final insn.
(gen_sequence): Move from here...
* ssa.c (gen_sequence): To here as private function.
* builtins.c (expand_builtin_apply_args): Use emit_insn_foo, fix
comments.
(expand_builtin_return, expand_builtin_mathfn): Likewise.
(expand_builtin_strlen): Use get_insns instead of gen_sequence.
(expand_builtin_saveregs): Use emit_insn_foo, fix comments.
(expand_builtin_expect_jump): Use get_insns and fix comments.
* calls.c (try_to_integrate): Use emit_insn_foo.
(expand_call, emit_library_call_value_1): Likewise.
* expr.c (emit_queue): Handle insn lists instead of SEQUENCE.
(emit_move_insn_1): Use get_insns instead of gen_sequence.
(expand_expr): Use emit_insn_foo.
* cfgrtl.c (commit_one_edge_insertion): Use emit_insn_foo.
* except.c (build_post_landing_pads): Likewise.
* flow.c (attempt_auto_inc): Likewise.
* stmt.c (expand_fixup, fixup_gotos, expand_nl_handler_label,
expand_nl_goto_receivers, expand_decl_cleanup): Likewise.
* function.c (fixup_var_refs_insn): Use get_insns instead of
gen_sequence.
(fixup_var_refs_1): Likewise and expect insn list from gen_foo.
(fixup_memory_subreg): Use get_insns instead of gen_sequence.
(fixup_stack_1, purge_addressof_1, expand_main_function,
get_arg_pointer_save_area): Likewise.
(optimize_bit_field, instantiate_virtual_regs_1, assign_parms,
expand_function_end): Use emit_insn_foo.
(record_insns, keep_stack_depressed): Work with insn list instead
of SEQUENCE, fix comments.
* ifcvt.c (noce_emit_store_flag, noce_try_store_flag,
noce_try_store_flag_constants, noce_try_store_flag_inc,
noce_try_store_flag_mask, noce_emit_cmove, noce_try_cmove_arith,
noce_try_minmax, noce_try_abs): Use emit_insn_foo.
(noce_process_if_block): Use get_insns instead of gen_sequence.
* optabs.c (add_equal_note): Work with insn list, fix comments.
(expand_binop): Expect insn list from GEN_FCN(), use emit_insn_foo.
(expand_unop, expand_complex_abs, expand_unop_insn,
expand_no_conflict_block): Likewise.
(gen_move_insn): Use get_insns instead of gen_sequence.
(gen_cond_trap): Likewise.
* integrate.c (copy_rtx_and_substitute): Likewise.
(emit_initial_value_sets): Use emit_insn_foo.
* reload1.c (emit_output_reload_insns, emit_reload_insns): Likewise.
(fixup_abnormal_edges): Avoid losing REG_NOTES more intelligently
now that RTL generators give insn lists.
* sibcall.c (replace_call_placeholder): Use emit_insn_foo.
* doloop.c (doloop_modify, doloop_modify_runtime): Use get_insns
instead of gen_sequence.
(doloop_optimize): Work with insn lists instead of SEQUENCE rtl.
* explow.c (emit_stack_save, emit_stack_restore): Use get_insns
instead of gen_sequence.
* loop.c (move_movables, emit_prefetch_instructions,
gen_add_mult, check_dbra_loop, gen_load_of_final_value):
Likewise.
(loop_regs_update): Work with insn list instead of SEQUENCE rtl.
(product_cheap_p): Likewise, and add commentary about RTL wastage
here.
* lcm.c (optimize_mode_switching): Use get_insns instead of
gen_sequence.
* profile.c (gen_edge_profiler): Likewise.
* regmove.c (copy_src_to_dest): Likewise.
* reg-stack.c (compensate_edge): Likewise and fix comment.
* gcse.c (process_insert_insn): Likewise.
(insert_insn_end_bb): Work with insn list instead of SEQUENCE rtl.
* jump.c (delete_prior_computation): Update comment.
* genemit.c (gen_expand, gen_split, main): Use get_insns instead
of gen_sequence, update comments to match.
* recog.c (peephole2_optimize): Work with insn lists instead of
SEQUENCE rtl.
* sched-vis.c (print_pattern): Abort on SEQUENCE.
* unroll.c (unroll_loop, find_splittable_givs, final_giv_value):
Use get_insns instead of gen_sequence.
(copy_loop_body): Likewise and don't emit dummy NOTE.
* genrecog.c: Don't mention SEQUENCE rtl in comments.
* combine.c (try_combine): Expect insn lists from split generator.
* reorg.c (relax_delay_slots): Emit SEQUENCE into insn list by
hand.
From-SVN: r54497
2002-06-11 05:22:48 -07:00
|
|
|
|
emit_insn_before (seq, region->label);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
break;
|
1999-12-12 18:32:36 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_CLEANUP:
|
2003-04-01 23:08:16 -08:00
|
|
|
|
case ERT_MUST_NOT_THROW:
|
2003-05-07 15:11:38 -07:00
|
|
|
|
region->post_landing_pad = region->label;
|
2003-04-01 23:08:16 -08:00
|
|
|
|
break;
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_CATCH:
|
|
|
|
|
case ERT_THROW:
|
|
|
|
|
/* Nothing to do. */
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-11-18 17:50:56 +00:00
|
|
|
|
|
2001-04-24 20:23:10 -04:00
|
|
|
|
/* Replace RESX patterns with jumps to the next handler if any, or calls to
|
|
|
|
|
_Unwind_Resume otherwise. */
|
|
|
|
|
|
1999-11-18 17:50:56 +00:00
|
|
|
|
static void
|
2001-03-28 03:04:51 -08:00
|
|
|
|
connect_post_landing_pads ()
|
1999-11-18 17:50:56 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int i;
|
1999-11-25 19:21:27 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *region = cfun->eh->region_array[i];
|
|
|
|
|
struct eh_region *outer;
|
2001-04-24 20:23:10 -04:00
|
|
|
|
rtx seq;
|
1999-11-18 17:50:56 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Mind we don't process a region more than once. */
|
|
|
|
|
if (!region || region->region_number != i)
|
|
|
|
|
continue;
|
1999-11-18 17:50:56 +00:00
|
|
|
|
|
2001-04-24 20:23:10 -04:00
|
|
|
|
/* If there is no RESX, or it has been deleted by flow, there's
|
|
|
|
|
nothing to fix up. */
|
|
|
|
|
if (! region->resume || INSN_DELETED_P (region->resume))
|
2001-03-28 03:04:51 -08:00
|
|
|
|
continue;
|
1999-11-25 19:21:27 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Search for another landing pad in this function. */
|
|
|
|
|
for (outer = region->outer; outer ; outer = outer->outer)
|
|
|
|
|
if (outer->post_landing_pad)
|
|
|
|
|
break;
|
1999-11-18 17:50:56 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
start_sequence ();
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (outer)
|
|
|
|
|
emit_jump (outer->post_landing_pad);
|
|
|
|
|
else
|
2001-04-03 17:48:51 -07:00
|
|
|
|
emit_library_call (unwind_resume_libfunc, LCT_THROW,
|
2002-07-09 15:28:22 +00:00
|
|
|
|
VOIDmode, 1, cfun->eh->exc_ptr, ptr_mode);
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
seq = get_insns ();
|
|
|
|
|
end_sequence ();
|
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
2002-06-05 David S. Miller <davem@redhat.com>
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
* rtl.h (gen_sequence, emit_insns, emit_insns_before,
emit_insns_before_scope, emit_insns_after,
emit_insns_after_scope): Delete declaration.
* ada/misc.c (insert_code_for): Use emit_insn* instead of
emit_insns_foo.
* config/alpha/alpha.c (alpha_set_memflags_1): Abort on SEQUENCE.
(alpha_set_memflags): Fix comment.
(set_frame_related_p): Use get_insns instead of gen_sequence.
* config/alpha/alpha.md (setjmp receiver splitter): Avoid
emitting no insns.
* config/arm/arm.c (arm_finalize_pic): Use get_insns instead of
gen_sequence.
(arm_gen_load_multiple, arm_gen_store_multiple): Likewise.
* config/fr30/fr30.c (fr30_move_double): Likewise.
* config/i386/i386.c (ix86_expand_int_movcc, ix86_expand_movstr):
Likewise.
* config/ia64/ia64.c (spill_restore_mem): Likewise.
* config/ia64/ia64.md (conditional move spliiter): Avoid emitting
no insns.
* config/m32r/m32r.c (gen_split_move_double): Use get_insns
instead of gen_sequence.
* config/mips/mips.c (embedded_pic_fnaddr_reg): Likewise.
(mips_expand_prologue, mips16_gp_pseudo_reg): Likewise.
* config/sh/sh.c (sh_need_epilogue): Likewise.
* config/sparc/sparc.md (current_function_calls_alloca, flat): New
attributes.
(setjmp pattern and split): Use them to avoid splitter which emits
no RTL.
* genattrtab.c (main): Emit include of function.h
* config/stormy16/stormy16.c (xstormy16_split_cbranch): Use
get_insns instead of gen_sequence.
* config/cris/cris.c (cris_split_movdx): Likewise.
* emit-rtl.c (emit_insns*): Kill.
(try_split): Expect insn list instead of SEQUENCE.
(make_jump_insn_raw, make_call_insn_raw): Fix comments.
(emit_*insn*): Reimplement to work with INSN lists and PATTERNs.
Make them abort if a SEQUENCE is given and RTL checking is
enabled.
(emit_*_scope): Don't forget to set scope on final insn.
(gen_sequence): Move from here...
* ssa.c (gen_sequence): To here as private function.
* builtins.c (expand_builtin_apply_args): Use emit_insn_foo, fix
comments.
(expand_builtin_return, expand_builtin_mathfn): Likewise.
(expand_builtin_strlen): Use get_insns instead of gen_sequence.
(expand_builtin_saveregs): Use emit_insn_foo, fix comments.
(expand_builtin_expect_jump): Use get_insns and fix comments.
* calls.c (try_to_integrate): Use emit_insn_foo.
(expand_call, emit_library_call_value_1): Likewise.
* expr.c (emit_queue): Handle insn lists instead of SEQUENCE.
(emit_move_insn_1): Use get_insns instead of gen_sequence.
(expand_expr): Use emit_insn_foo.
* cfgrtl.c (commit_one_edge_insertion): Use emit_insn_foo.
* except.c (build_post_landing_pads): Likewise.
* flow.c (attempt_auto_inc): Likewise.
* stmt.c (expand_fixup, fixup_gotos, expand_nl_handler_label,
expand_nl_goto_receivers, expand_decl_cleanup): Likewise.
* function.c (fixup_var_refs_insn): Use get_insns instead of
gen_sequence.
(fixup_var_refs_1): Likewise and expect insn list from gen_foo.
(fixup_memory_subreg): Use get_insns instead of gen_sequence.
(fixup_stack_1, purge_addressof_1, expand_main_function,
get_arg_pointer_save_area): Likewise.
(optimize_bit_field, instantiate_virtual_regs_1, assign_parms,
expand_function_end): Use emit_insn_foo.
(record_insns, keep_stack_depressed): Work with insn list instead
of SEQUENCE, fix comments.
* ifcvt.c (noce_emit_store_flag, noce_try_store_flag,
noce_try_store_flag_constants, noce_try_store_flag_inc,
noce_try_store_flag_mask, noce_emit_cmove, noce_try_cmove_arith,
noce_try_minmax, noce_try_abs): Use emit_insn_foo.
(noce_process_if_block): Use get_insns instead of gen_sequence.
* optabs.c (add_equal_note): Work with insn list, fix comments.
(expand_binop): Expect insn list from GEN_FCN(), use emit_insn_foo.
(expand_unop, expand_complex_abs, expand_unop_insn,
expand_no_conflict_block): Likewise.
(gen_move_insn): Use get_insns instead of gen_sequence.
(gen_cond_trap): Likewise.
* integrate.c (copy_rtx_and_substitute): Likewise.
(emit_initial_value_sets): Use emit_insn_foo.
* reload1.c (emit_output_reload_insns, emit_reload_insns): Likewise.
(fixup_abnormal_edges): Avoid losing REG_NOTES more intelligently
now that RTL generators give insn lists.
* sibcall.c (replace_call_placeholder): Use emit_insn_foo.
* doloop.c (doloop_modify, doloop_modify_runtime): Use get_insns
instead of gen_sequence.
(doloop_optimize): Work with insn lists instead of SEQUENCE rtl.
* explow.c (emit_stack_save, emit_stack_restore): Use get_insns
instead of gen_sequence.
* loop.c (move_movables, emit_prefetch_instructions,
gen_add_mult, check_dbra_loop, gen_load_of_final_value):
Likewise.
(loop_regs_update): Work with insn list instead of SEQUENCE rtl.
(product_cheap_p): Likewise, and add commentary about RTL wastage
here.
* lcm.c (optimize_mode_switching): Use get_insns instead of
gen_sequence.
* profile.c (gen_edge_profiler): Likewise.
* regmove.c (copy_src_to_dest): Likewise.
* reg-stack.c (compensate_edge): Likewise and fix comment.
* gcse.c (process_insert_insn): Likewise.
(insert_insn_end_bb): Work with insn list instead of SEQUENCE rtl.
* jump.c (delete_prior_computation): Update comment.
* genemit.c (gen_expand, gen_split, main): Use get_insns instead
of gen_sequence, update comments to match.
* recog.c (peephole2_optimize): Work with insn lists instead of
SEQUENCE rtl.
* sched-vis.c (print_pattern): Abort on SEQUENCE.
* unroll.c (unroll_loop, find_splittable_givs, final_giv_value):
Use get_insns instead of gen_sequence.
(copy_loop_body): Likewise and don't emit dummy NOTE.
* genrecog.c: Don't mention SEQUENCE rtl in comments.
* combine.c (try_combine): Expect insn lists from split generator.
* reorg.c (relax_delay_slots): Emit SEQUENCE into insn list by
hand.
From-SVN: r54497
2002-06-11 05:22:48 -07:00
|
|
|
|
emit_insn_before (seq, region->resume);
|
basic-block.h (flow_delete_insn, [...]): Kill.
* basic-block.h (flow_delete_insn, flow_delete_insn_chain): Kill.
* cfg.c (delete_insn): Rename from ....; use remove_insn; do not
remove some labels.
(flow_delete_insn): This one.
(delete_insn_chain): Rename from ...; do not care labels.
(flow_delete_insn_chain): ... this one.
(flow_delete_block): Remove the insns one BB has been expunged.
(merge_blocks_nomove): Likewise.
(try_redirect_by_replacing_jump): Use delete_insn[_chain]; do not care
updating BB boundaries.
(tidy_fallthru_edge): Likewise.
(commit_one_edge_insertion): Likewise.
* cfgbuild.c (find_basic_block): Likewise.
(find_basic_blocks_1): Likewise.
* cfgcleanup.c (merge_blocks_move_predecessor_nojumps): Likewise.
(try_crossjump_to_edge): Likewise.
(try_optimize_cfg): Likewise.
* cse.c (delete_trivially_dead_insns): Likewise.
* df.c (df_insn_delete): Likewise.
* doloop.c (doloop_modify): Use delete_related_insns.
* emit-rtl.c (try_split): Likewise.
(remove_insn): Update BB boundaries.
* expect.c (connect_post_landing_pads): Use delete_related_insns.
* flow.c (delete_dead_jumptables): Use delete_insn[_chain]; do not care
updating BB boundaries.
(propagate_block_delete_insn): Likewise.
(propagate_block_delete_libcall): Likewise.
* function.c (delete_handlers): Use delete_related_insns.
(thread_prologue_and_epilogue_insns): Likewise.
* gcse.c (delete_null_pointer_checks): Use delete_related_insns.
* genpeep.c (gen_peephole): Use delete_related_insns.
* ifcvt.c (noce_process_if_block): Use delete_insn; do not care updating
BB boundaries.
(find_cond_trap): Likewise.
* integrate.c (save_for_inline): Use delete_related_insns.
(copy_insn_list): Likewise.
* jump.c (pruge_linie_number_notes): Likewise.
(duplicate_loop_exit_test): Likewise.
(delete_computation): Likewise.
(delete_related_insn): Rename from ...; use delete_insn
(delete_insn): ... this one.
(redirect_jump): Use delete_related_insns.
* loop.c (scan_loop): Likewise.
(move_movables): Likewise.
(find_and_verify_loops): Likewise.
(check_dbra_loop): Likewise.
* recog.c (peephole2_optimize): Likewise.
* reg-stack.c (delete_insn_for_stacker): Remove.
(move_for_stack_reg): Use delete_insn.
* regmove.c (combine_stack_adjustments_for_block): Likewise.
* reload1.c (delete_address_reloads): Use delete_related_insns.
(fixup_abnormal_edges): Use delete_insn.
* recog.c (emit_delay_sequence): Use delete_related_insns.
(delete_from-delay_slot): Likewise.
(delete_scheduled_jump): likewise.
(optimize_skip): Likewise.
(try_merge_delay_insns): Likewise.
(full_simple_delay_slots): Likewise.
(fill_slots_from_thread): Likewise.
(relax_delay_slots): Likewise.
(make_return_insns): Likewise.
(dbr_schedule): Likewise.
* rtl.h (delete_insn): Rename to delete_related_insns.
(delete_insn, delete_insn_chain): New prototypes.
* ssa-ccp (sse_fast_dce): Remove deleting of DEF, as it is done
by df_insn_delete already.
* ssa-dce.c (delete_insn_bb): Use delete_insn.
* ssa.c (convert_from_ssa): Use delete_related_insns.
* unroll.c (unroll_loop): Likewise.
(calculate_giv_inc): Likewise.
(copy_loop_body): Likewise.
* i386-protos.h (ix86_libcall_value, ix86_function_value,
ix86_function_arg_regno_p, ix86_function_arg_boundary,
ix86_return_in_memory, ix86_function_value): Declare.
* i386.c (x86_64_int_parameter_registers, x86_64_int_return_registers):
new static valurables.
(x86_64_reg_class): New enum
(x86_64_reg_class_name): New array.
(classify_argument, examine_argument, construct_container,
merge_classes): New static functions.
(optimization_options): Enable flag_omit_frame_pointer and disable
flag_pcc_struct_return on 64bit.
(ix86_libcall_value, ix86_function_value,
ix86_function_arg_regno_p, ix86_function_arg_boundary,
ix86_return_in_memory, ix86_function_value): New global functions.
(init_cumulative_args): Refuse regparm on x86_64, set maybe_vaarg.
(function_arg_advance): Handle x86_64 passing conventions.
(function_arg): Likewise.
* i386.h (FUNCTION_ARG_BOUNDARY): New macro.
(RETURN_IN_MEMORY): Move offline.
(FUNCTION_VALUE, LIBCALL_VALUE): Likewise.
(FUNCTION_VALUE_REGNO_P): New macro.
(FUNCTION_ARG_REGNO_P): Move offline.
(struct ix86_args): Add maybe_vaarg.
* next.h (FUNCTION_VALUE_REGNO_P): Delete.
* unix.h (FUNCTION_VALUE_REGNO_P): Delete.
From-SVN: r45726
2001-09-21 14:55:18 +02:00
|
|
|
|
delete_insn (region->resume);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dw2_build_landing_pads ()
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-07-10 12:38:10 +02:00
|
|
|
|
int i;
|
|
|
|
|
unsigned int j;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *region = cfun->eh->region_array[i];
|
|
|
|
|
rtx seq;
|
2001-09-17 23:16:28 +00:00
|
|
|
|
bool clobbers_hard_regs = false;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Mind we don't process a region more than once. */
|
|
|
|
|
if (!region || region->region_number != i)
|
|
|
|
|
continue;
|
1997-11-21 20:20:41 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (region->type != ERT_CLEANUP
|
|
|
|
|
&& region->type != ERT_TRY
|
|
|
|
|
&& region->type != ERT_ALLOWED_EXCEPTIONS)
|
|
|
|
|
continue;
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
start_sequence ();
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
region->landing_pad = gen_label_rtx ();
|
|
|
|
|
emit_label (region->landing_pad);
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#ifdef HAVE_exception_receiver
|
|
|
|
|
if (HAVE_exception_receiver)
|
|
|
|
|
emit_insn (gen_exception_receiver ());
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef HAVE_nonlocal_goto_receiver
|
|
|
|
|
if (HAVE_nonlocal_goto_receiver)
|
|
|
|
|
emit_insn (gen_nonlocal_goto_receiver ());
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
{ /* Nothing */ }
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* If the eh_return data registers are call-saved, then we
|
|
|
|
|
won't have considered them clobbered from the call that
|
|
|
|
|
threw. Kill them now. */
|
|
|
|
|
for (j = 0; ; ++j)
|
|
|
|
|
{
|
|
|
|
|
unsigned r = EH_RETURN_DATA_REGNO (j);
|
|
|
|
|
if (r == INVALID_REGNUM)
|
|
|
|
|
break;
|
|
|
|
|
if (! call_used_regs[r])
|
2001-09-17 23:16:28 +00:00
|
|
|
|
{
|
|
|
|
|
emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, r)));
|
|
|
|
|
clobbers_hard_regs = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (clobbers_hard_regs)
|
|
|
|
|
{
|
|
|
|
|
/* @@@ This is a kludge. Not all machine descriptions define a
|
|
|
|
|
blockage insn, but we must not allow the code we just generated
|
|
|
|
|
to be reordered by scheduling. So emit an ASM_INPUT to act as
|
2001-10-09 14:03:13 +00:00
|
|
|
|
blockage insn. */
|
2001-09-17 23:16:28 +00:00
|
|
|
|
emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
1997-12-04 09:41:38 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_move_insn (cfun->eh->exc_ptr,
|
2002-07-09 15:28:22 +00:00
|
|
|
|
gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_move_insn (cfun->eh->filter,
|
2001-05-19 17:35:24 -07:00
|
|
|
|
gen_rtx_REG (word_mode, EH_RETURN_DATA_REGNO (1)));
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
seq = get_insns ();
|
|
|
|
|
end_sequence ();
|
1998-06-23 07:10:29 +00:00
|
|
|
|
|
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
2002-06-05 David S. Miller <davem@redhat.com>
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
* rtl.h (gen_sequence, emit_insns, emit_insns_before,
emit_insns_before_scope, emit_insns_after,
emit_insns_after_scope): Delete declaration.
* ada/misc.c (insert_code_for): Use emit_insn* instead of
emit_insns_foo.
* config/alpha/alpha.c (alpha_set_memflags_1): Abort on SEQUENCE.
(alpha_set_memflags): Fix comment.
(set_frame_related_p): Use get_insns instead of gen_sequence.
* config/alpha/alpha.md (setjmp receiver splitter): Avoid
emitting no insns.
* config/arm/arm.c (arm_finalize_pic): Use get_insns instead of
gen_sequence.
(arm_gen_load_multiple, arm_gen_store_multiple): Likewise.
* config/fr30/fr30.c (fr30_move_double): Likewise.
* config/i386/i386.c (ix86_expand_int_movcc, ix86_expand_movstr):
Likewise.
* config/ia64/ia64.c (spill_restore_mem): Likewise.
* config/ia64/ia64.md (conditional move spliiter): Avoid emitting
no insns.
* config/m32r/m32r.c (gen_split_move_double): Use get_insns
instead of gen_sequence.
* config/mips/mips.c (embedded_pic_fnaddr_reg): Likewise.
(mips_expand_prologue, mips16_gp_pseudo_reg): Likewise.
* config/sh/sh.c (sh_need_epilogue): Likewise.
* config/sparc/sparc.md (current_function_calls_alloca, flat): New
attributes.
(setjmp pattern and split): Use them to avoid splitter which emits
no RTL.
* genattrtab.c (main): Emit include of function.h
* config/stormy16/stormy16.c (xstormy16_split_cbranch): Use
get_insns instead of gen_sequence.
* config/cris/cris.c (cris_split_movdx): Likewise.
* emit-rtl.c (emit_insns*): Kill.
(try_split): Expect insn list instead of SEQUENCE.
(make_jump_insn_raw, make_call_insn_raw): Fix comments.
(emit_*insn*): Reimplement to work with INSN lists and PATTERNs.
Make them abort if a SEQUENCE is given and RTL checking is
enabled.
(emit_*_scope): Don't forget to set scope on final insn.
(gen_sequence): Move from here...
* ssa.c (gen_sequence): To here as private function.
* builtins.c (expand_builtin_apply_args): Use emit_insn_foo, fix
comments.
(expand_builtin_return, expand_builtin_mathfn): Likewise.
(expand_builtin_strlen): Use get_insns instead of gen_sequence.
(expand_builtin_saveregs): Use emit_insn_foo, fix comments.
(expand_builtin_expect_jump): Use get_insns and fix comments.
* calls.c (try_to_integrate): Use emit_insn_foo.
(expand_call, emit_library_call_value_1): Likewise.
* expr.c (emit_queue): Handle insn lists instead of SEQUENCE.
(emit_move_insn_1): Use get_insns instead of gen_sequence.
(expand_expr): Use emit_insn_foo.
* cfgrtl.c (commit_one_edge_insertion): Use emit_insn_foo.
* except.c (build_post_landing_pads): Likewise.
* flow.c (attempt_auto_inc): Likewise.
* stmt.c (expand_fixup, fixup_gotos, expand_nl_handler_label,
expand_nl_goto_receivers, expand_decl_cleanup): Likewise.
* function.c (fixup_var_refs_insn): Use get_insns instead of
gen_sequence.
(fixup_var_refs_1): Likewise and expect insn list from gen_foo.
(fixup_memory_subreg): Use get_insns instead of gen_sequence.
(fixup_stack_1, purge_addressof_1, expand_main_function,
get_arg_pointer_save_area): Likewise.
(optimize_bit_field, instantiate_virtual_regs_1, assign_parms,
expand_function_end): Use emit_insn_foo.
(record_insns, keep_stack_depressed): Work with insn list instead
of SEQUENCE, fix comments.
* ifcvt.c (noce_emit_store_flag, noce_try_store_flag,
noce_try_store_flag_constants, noce_try_store_flag_inc,
noce_try_store_flag_mask, noce_emit_cmove, noce_try_cmove_arith,
noce_try_minmax, noce_try_abs): Use emit_insn_foo.
(noce_process_if_block): Use get_insns instead of gen_sequence.
* optabs.c (add_equal_note): Work with insn list, fix comments.
(expand_binop): Expect insn list from GEN_FCN(), use emit_insn_foo.
(expand_unop, expand_complex_abs, expand_unop_insn,
expand_no_conflict_block): Likewise.
(gen_move_insn): Use get_insns instead of gen_sequence.
(gen_cond_trap): Likewise.
* integrate.c (copy_rtx_and_substitute): Likewise.
(emit_initial_value_sets): Use emit_insn_foo.
* reload1.c (emit_output_reload_insns, emit_reload_insns): Likewise.
(fixup_abnormal_edges): Avoid losing REG_NOTES more intelligently
now that RTL generators give insn lists.
* sibcall.c (replace_call_placeholder): Use emit_insn_foo.
* doloop.c (doloop_modify, doloop_modify_runtime): Use get_insns
instead of gen_sequence.
(doloop_optimize): Work with insn lists instead of SEQUENCE rtl.
* explow.c (emit_stack_save, emit_stack_restore): Use get_insns
instead of gen_sequence.
* loop.c (move_movables, emit_prefetch_instructions,
gen_add_mult, check_dbra_loop, gen_load_of_final_value):
Likewise.
(loop_regs_update): Work with insn list instead of SEQUENCE rtl.
(product_cheap_p): Likewise, and add commentary about RTL wastage
here.
* lcm.c (optimize_mode_switching): Use get_insns instead of
gen_sequence.
* profile.c (gen_edge_profiler): Likewise.
* regmove.c (copy_src_to_dest): Likewise.
* reg-stack.c (compensate_edge): Likewise and fix comment.
* gcse.c (process_insert_insn): Likewise.
(insert_insn_end_bb): Work with insn list instead of SEQUENCE rtl.
* jump.c (delete_prior_computation): Update comment.
* genemit.c (gen_expand, gen_split, main): Use get_insns instead
of gen_sequence, update comments to match.
* recog.c (peephole2_optimize): Work with insn lists instead of
SEQUENCE rtl.
* sched-vis.c (print_pattern): Abort on SEQUENCE.
* unroll.c (unroll_loop, find_splittable_givs, final_giv_value):
Use get_insns instead of gen_sequence.
(copy_loop_body): Likewise and don't emit dummy NOTE.
* genrecog.c: Don't mention SEQUENCE rtl in comments.
* combine.c (try_combine): Expect insn lists from split generator.
* reorg.c (relax_delay_slots): Emit SEQUENCE into insn list by
hand.
From-SVN: r54497
2002-06-11 05:22:48 -07:00
|
|
|
|
emit_insn_before (seq, region->post_landing_pad);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
struct sjlj_lp_info
|
|
|
|
|
{
|
|
|
|
|
int directly_reachable;
|
|
|
|
|
int action_index;
|
|
|
|
|
int dispatch_index;
|
|
|
|
|
int call_site_index;
|
|
|
|
|
};
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static bool
|
|
|
|
|
sjlj_find_directly_reachable_regions (lp_info)
|
|
|
|
|
struct sjlj_lp_info *lp_info;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx insn;
|
|
|
|
|
bool found_one = false;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *region;
|
2001-12-11 18:58:23 -08:00
|
|
|
|
enum reachable_code rc;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
tree type_thrown;
|
|
|
|
|
rtx note;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! INSN_P (insn))
|
|
|
|
|
continue;
|
1998-06-09 13:28:26 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
|
|
|
|
|
if (!note || INTVAL (XEXP (note, 0)) <= 0)
|
|
|
|
|
continue;
|
1997-12-04 19:52:49 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
|
1997-12-04 19:52:49 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
type_thrown = NULL_TREE;
|
|
|
|
|
if (region->type == ERT_THROW)
|
|
|
|
|
{
|
|
|
|
|
type_thrown = region->u.throw.type;
|
|
|
|
|
region = region->outer;
|
|
|
|
|
}
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Find the first containing region that might handle the exception.
|
|
|
|
|
That's the landing pad to which we will transfer control. */
|
2001-12-11 18:58:23 -08:00
|
|
|
|
rc = RNL_NOT_CAUGHT;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (; region; region = region->outer)
|
2001-12-11 18:58:23 -08:00
|
|
|
|
{
|
|
|
|
|
rc = reachable_next_level (region, type_thrown, 0);
|
|
|
|
|
if (rc != RNL_NOT_CAUGHT)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (rc == RNL_MAYBE_CAUGHT || rc == RNL_CAUGHT)
|
2001-03-28 03:04:51 -08:00
|
|
|
|
{
|
|
|
|
|
lp_info[region->region_number].directly_reachable = 1;
|
|
|
|
|
found_one = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return found_one;
|
|
|
|
|
}
|
1997-12-04 09:41:38 +00:00
|
|
|
|
|
|
|
|
|
static void
|
2001-03-28 03:04:51 -08:00
|
|
|
|
sjlj_assign_call_site_values (dispatch_label, lp_info)
|
|
|
|
|
rtx dispatch_label;
|
|
|
|
|
struct sjlj_lp_info *lp_info;
|
1997-12-04 09:41:38 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
htab_t ar_hash;
|
|
|
|
|
int i, index;
|
|
|
|
|
|
|
|
|
|
/* First task: build the action table. */
|
|
|
|
|
|
|
|
|
|
VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
|
|
|
|
|
ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
|
|
|
|
|
|
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
|
|
|
|
if (lp_info[i].directly_reachable)
|
1998-12-08 14:04:03 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *r = cfun->eh->region_array[i];
|
|
|
|
|
r->landing_pad = dispatch_label;
|
|
|
|
|
lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
|
|
|
|
|
if (lp_info[i].action_index != -1)
|
|
|
|
|
cfun->uses_eh_lsda = 1;
|
1998-12-08 14:04:03 +00:00
|
|
|
|
}
|
1997-12-04 09:41:38 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
htab_delete (ar_hash);
|
1999-11-25 19:21:27 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Next: assign dispatch values. In dwarf2 terms, this would be the
|
|
|
|
|
landing pad label for the region. For sjlj though, there is one
|
|
|
|
|
common landing pad from which we dispatch to the post-landing pads.
|
1999-11-25 19:21:27 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
A region receives a dispatch index if it is directly reachable
|
|
|
|
|
and requires in-function processing. Regions that share post-landing
|
ChangeLog.2, [...]: Fix spelling errors.
* ChangeLog.2, ChangeLog.3, ChangeLog.4, ChangeLog.5, ChangeLog,
cfg.c, cfganal.c, cfgcleanup.c, cfglayout.c, cfgloop.c, cfgrtl.c,
collect2.c, combine.c, config.in, configure, configure.in,
conflict.c, dwarf2out.c, dwarfout.c, except.c, final.c, flow.c,
genattrtab.c, ggc-page.c, jump.c, lcm.c, predict.c, reg-stack.c,
reload1.c, rtlanal.c, sched-rgn.c, toplev.c, unwind-dw2-fde.h: Fix
spelling errors.
From-SVN: r46928
2001-11-11 11:25:28 +00:00
|
|
|
|
pads may share dispatch indices. */
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* ??? Post-landing pad sharing doesn't actually happen at the moment
|
|
|
|
|
(see build_post_landing_pads) so we don't bother checking for it. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
index = 0;
|
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
2001-12-11 18:58:23 -08:00
|
|
|
|
if (lp_info[i].directly_reachable)
|
2001-03-28 03:04:51 -08:00
|
|
|
|
lp_info[i].dispatch_index = index++;
|
1999-11-25 19:21:27 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Finally: assign call-site values. If dwarf2 terms, this would be
|
|
|
|
|
the region number assigned by convert_to_eh_region_ranges, but
|
|
|
|
|
handles no-action and must-not-throw differently. */
|
1999-11-25 19:21:27 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
call_site_base = 1;
|
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
|
|
|
|
if (lp_info[i].directly_reachable)
|
|
|
|
|
{
|
|
|
|
|
int action = lp_info[i].action_index;
|
|
|
|
|
|
|
|
|
|
/* Map must-not-throw to otherwise unused call-site index 0. */
|
|
|
|
|
if (action == -2)
|
|
|
|
|
index = 0;
|
|
|
|
|
/* Map no-action to otherwise unused call-site index -1. */
|
|
|
|
|
else if (action == -1)
|
|
|
|
|
index = -1;
|
|
|
|
|
/* Otherwise, look it up in the table. */
|
|
|
|
|
else
|
|
|
|
|
index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action);
|
|
|
|
|
|
|
|
|
|
lp_info[i].call_site_index = index;
|
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void
|
|
|
|
|
sjlj_mark_call_sites (lp_info)
|
|
|
|
|
struct sjlj_lp_info *lp_info;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int last_call_site = -2;
|
|
|
|
|
rtx insn, mem;
|
|
|
|
|
|
|
|
|
|
for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
|
1997-04-23 20:11:52 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *region;
|
|
|
|
|
int this_call_site;
|
|
|
|
|
rtx note, before, p;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Reset value tracking at extended basic block boundaries. */
|
|
|
|
|
if (GET_CODE (insn) == CODE_LABEL)
|
|
|
|
|
last_call_site = -2;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! INSN_P (insn))
|
|
|
|
|
continue;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
|
|
|
|
|
if (!note)
|
|
|
|
|
{
|
|
|
|
|
/* Calls (and trapping insns) without notes are outside any
|
|
|
|
|
exception handling region in this function. Mark them as
|
|
|
|
|
no action. */
|
|
|
|
|
if (GET_CODE (insn) == CALL_INSN
|
|
|
|
|
|| (flag_non_call_exceptions
|
|
|
|
|
&& may_trap_p (PATTERN (insn))))
|
|
|
|
|
this_call_site = -1;
|
|
|
|
|
else
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Calls that are known to not throw need not be marked. */
|
|
|
|
|
if (INTVAL (XEXP (note, 0)) <= 0)
|
|
|
|
|
continue;
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
|
|
|
|
|
this_call_site = lp_info[region->region_number].call_site_index;
|
|
|
|
|
}
|
1997-04-23 20:11:52 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (this_call_site == last_call_site)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Don't separate a call from it's argument loads. */
|
|
|
|
|
before = insn;
|
|
|
|
|
if (GET_CODE (insn) == CALL_INSN)
|
2002-06-03 01:13:17 +00:00
|
|
|
|
before = find_first_parameter_load (insn, NULL_RTX);
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
start_sequence ();
|
2001-09-26 10:38:18 +00:00
|
|
|
|
mem = adjust_address (cfun->eh->sjlj_fc, TYPE_MODE (integer_type_node),
|
|
|
|
|
sjlj_fc_call_site_ofs);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_move_insn (mem, GEN_INT (this_call_site));
|
|
|
|
|
p = get_insns ();
|
|
|
|
|
end_sequence ();
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
2002-06-05 David S. Miller <davem@redhat.com>
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
* rtl.h (gen_sequence, emit_insns, emit_insns_before,
emit_insns_before_scope, emit_insns_after,
emit_insns_after_scope): Delete declaration.
* ada/misc.c (insert_code_for): Use emit_insn* instead of
emit_insns_foo.
* config/alpha/alpha.c (alpha_set_memflags_1): Abort on SEQUENCE.
(alpha_set_memflags): Fix comment.
(set_frame_related_p): Use get_insns instead of gen_sequence.
* config/alpha/alpha.md (setjmp receiver splitter): Avoid
emitting no insns.
* config/arm/arm.c (arm_finalize_pic): Use get_insns instead of
gen_sequence.
(arm_gen_load_multiple, arm_gen_store_multiple): Likewise.
* config/fr30/fr30.c (fr30_move_double): Likewise.
* config/i386/i386.c (ix86_expand_int_movcc, ix86_expand_movstr):
Likewise.
* config/ia64/ia64.c (spill_restore_mem): Likewise.
* config/ia64/ia64.md (conditional move spliiter): Avoid emitting
no insns.
* config/m32r/m32r.c (gen_split_move_double): Use get_insns
instead of gen_sequence.
* config/mips/mips.c (embedded_pic_fnaddr_reg): Likewise.
(mips_expand_prologue, mips16_gp_pseudo_reg): Likewise.
* config/sh/sh.c (sh_need_epilogue): Likewise.
* config/sparc/sparc.md (current_function_calls_alloca, flat): New
attributes.
(setjmp pattern and split): Use them to avoid splitter which emits
no RTL.
* genattrtab.c (main): Emit include of function.h
* config/stormy16/stormy16.c (xstormy16_split_cbranch): Use
get_insns instead of gen_sequence.
* config/cris/cris.c (cris_split_movdx): Likewise.
* emit-rtl.c (emit_insns*): Kill.
(try_split): Expect insn list instead of SEQUENCE.
(make_jump_insn_raw, make_call_insn_raw): Fix comments.
(emit_*insn*): Reimplement to work with INSN lists and PATTERNs.
Make them abort if a SEQUENCE is given and RTL checking is
enabled.
(emit_*_scope): Don't forget to set scope on final insn.
(gen_sequence): Move from here...
* ssa.c (gen_sequence): To here as private function.
* builtins.c (expand_builtin_apply_args): Use emit_insn_foo, fix
comments.
(expand_builtin_return, expand_builtin_mathfn): Likewise.
(expand_builtin_strlen): Use get_insns instead of gen_sequence.
(expand_builtin_saveregs): Use emit_insn_foo, fix comments.
(expand_builtin_expect_jump): Use get_insns and fix comments.
* calls.c (try_to_integrate): Use emit_insn_foo.
(expand_call, emit_library_call_value_1): Likewise.
* expr.c (emit_queue): Handle insn lists instead of SEQUENCE.
(emit_move_insn_1): Use get_insns instead of gen_sequence.
(expand_expr): Use emit_insn_foo.
* cfgrtl.c (commit_one_edge_insertion): Use emit_insn_foo.
* except.c (build_post_landing_pads): Likewise.
* flow.c (attempt_auto_inc): Likewise.
* stmt.c (expand_fixup, fixup_gotos, expand_nl_handler_label,
expand_nl_goto_receivers, expand_decl_cleanup): Likewise.
* function.c (fixup_var_refs_insn): Use get_insns instead of
gen_sequence.
(fixup_var_refs_1): Likewise and expect insn list from gen_foo.
(fixup_memory_subreg): Use get_insns instead of gen_sequence.
(fixup_stack_1, purge_addressof_1, expand_main_function,
get_arg_pointer_save_area): Likewise.
(optimize_bit_field, instantiate_virtual_regs_1, assign_parms,
expand_function_end): Use emit_insn_foo.
(record_insns, keep_stack_depressed): Work with insn list instead
of SEQUENCE, fix comments.
* ifcvt.c (noce_emit_store_flag, noce_try_store_flag,
noce_try_store_flag_constants, noce_try_store_flag_inc,
noce_try_store_flag_mask, noce_emit_cmove, noce_try_cmove_arith,
noce_try_minmax, noce_try_abs): Use emit_insn_foo.
(noce_process_if_block): Use get_insns instead of gen_sequence.
* optabs.c (add_equal_note): Work with insn list, fix comments.
(expand_binop): Expect insn list from GEN_FCN(), use emit_insn_foo.
(expand_unop, expand_complex_abs, expand_unop_insn,
expand_no_conflict_block): Likewise.
(gen_move_insn): Use get_insns instead of gen_sequence.
(gen_cond_trap): Likewise.
* integrate.c (copy_rtx_and_substitute): Likewise.
(emit_initial_value_sets): Use emit_insn_foo.
* reload1.c (emit_output_reload_insns, emit_reload_insns): Likewise.
(fixup_abnormal_edges): Avoid losing REG_NOTES more intelligently
now that RTL generators give insn lists.
* sibcall.c (replace_call_placeholder): Use emit_insn_foo.
* doloop.c (doloop_modify, doloop_modify_runtime): Use get_insns
instead of gen_sequence.
(doloop_optimize): Work with insn lists instead of SEQUENCE rtl.
* explow.c (emit_stack_save, emit_stack_restore): Use get_insns
instead of gen_sequence.
* loop.c (move_movables, emit_prefetch_instructions,
gen_add_mult, check_dbra_loop, gen_load_of_final_value):
Likewise.
(loop_regs_update): Work with insn list instead of SEQUENCE rtl.
(product_cheap_p): Likewise, and add commentary about RTL wastage
here.
* lcm.c (optimize_mode_switching): Use get_insns instead of
gen_sequence.
* profile.c (gen_edge_profiler): Likewise.
* regmove.c (copy_src_to_dest): Likewise.
* reg-stack.c (compensate_edge): Likewise and fix comment.
* gcse.c (process_insert_insn): Likewise.
(insert_insn_end_bb): Work with insn list instead of SEQUENCE rtl.
* jump.c (delete_prior_computation): Update comment.
* genemit.c (gen_expand, gen_split, main): Use get_insns instead
of gen_sequence, update comments to match.
* recog.c (peephole2_optimize): Work with insn lists instead of
SEQUENCE rtl.
* sched-vis.c (print_pattern): Abort on SEQUENCE.
* unroll.c (unroll_loop, find_splittable_givs, final_giv_value):
Use get_insns instead of gen_sequence.
(copy_loop_body): Likewise and don't emit dummy NOTE.
* genrecog.c: Don't mention SEQUENCE rtl in comments.
* combine.c (try_combine): Expect insn lists from split generator.
* reorg.c (relax_delay_slots): Emit SEQUENCE into insn list by
hand.
From-SVN: r54497
2002-06-11 05:22:48 -07:00
|
|
|
|
emit_insn_before (p, before);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
last_call_site = this_call_site;
|
|
|
|
|
}
|
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Construct the SjLj_Function_Context. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
sjlj_emit_function_enter (dispatch_label)
|
|
|
|
|
rtx dispatch_label;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx fn_begin, fc, mem, seq;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
fc = cfun->eh->sjlj_fc;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
start_sequence ();
|
2000-03-29 08:22:21 +00:00
|
|
|
|
|
2001-05-17 17:53:52 +00:00
|
|
|
|
/* We're storing this libcall's address into memory instead of
|
|
|
|
|
calling it directly. Thus, we must call assemble_external_libcall
|
|
|
|
|
here, as we can not depend on emit_library_call to do it for us. */
|
|
|
|
|
assemble_external_libcall (eh_personality_libfunc);
|
emit-rtl.c (adjust_address): New function.
* emit-rtl.c (adjust_address): New function.
* expr.h (adjust_address): Add declaration.
* builtins.c: Replace some calls to change_address with calls to it
or to validize_mem.
* caller-save.c, dwarf2out.c, except.c, expmed.c, expr.c: Likewise.
* function.c, config/a29k/a29k.md, config/alpha/alpha.c: Likewise.
* config/arm/arm.c, config/convex/convex.c: Likewise.
* config/dsp16xx/dsp16xx.md, config/fr30/fr30.c: Likewise.
* config/i386/i386.c, config/i386/i386.md: Likewise.
* config/ia64/ia64.c, config/ia64/ia64.md: Likewise.
* config/m32r/m32r.c, config/m68k/m68k.md: Likewise.
* config/m88k/m88k.c, config/mips/mips.md: Likewise.
* config/ns32k/ns32k.c, config/rs6000/rs6000.c: Likewise.
* config/sh/sh.c, config/sparc/sparc.md: Likewise.
From-SVN: r43702
2001-07-02 19:47:44 +00:00
|
|
|
|
mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_move_insn (mem, eh_personality_libfunc);
|
|
|
|
|
|
emit-rtl.c (adjust_address): New function.
* emit-rtl.c (adjust_address): New function.
* expr.h (adjust_address): Add declaration.
* builtins.c: Replace some calls to change_address with calls to it
or to validize_mem.
* caller-save.c, dwarf2out.c, except.c, expmed.c, expr.c: Likewise.
* function.c, config/a29k/a29k.md, config/alpha/alpha.c: Likewise.
* config/arm/arm.c, config/convex/convex.c: Likewise.
* config/dsp16xx/dsp16xx.md, config/fr30/fr30.c: Likewise.
* config/i386/i386.c, config/i386/i386.md: Likewise.
* config/ia64/ia64.c, config/ia64/ia64.md: Likewise.
* config/m32r/m32r.c, config/m68k/m68k.md: Likewise.
* config/m88k/m88k.c, config/mips/mips.md: Likewise.
* config/ns32k/ns32k.c, config/rs6000/rs6000.c: Likewise.
* config/sh/sh.c, config/sparc/sparc.md: Likewise.
From-SVN: r43702
2001-07-02 19:47:44 +00:00
|
|
|
|
mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (cfun->uses_eh_lsda)
|
|
|
|
|
{
|
|
|
|
|
char buf[20];
|
2002-06-17 10:47:22 -07:00
|
|
|
|
ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", current_function_funcdef_no);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_move_insn (mem, gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
|
2000-03-29 08:22:21 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
else
|
|
|
|
|
emit_move_insn (mem, const0_rtx);
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#ifdef DONT_USE_BUILTIN_SETJMP
|
|
|
|
|
{
|
|
|
|
|
rtx x, note;
|
2001-09-21 13:26:44 -07:00
|
|
|
|
x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
|
2001-03-28 03:04:51 -08:00
|
|
|
|
TYPE_MODE (integer_type_node), 1,
|
|
|
|
|
plus_constant (XEXP (fc, 0),
|
|
|
|
|
sjlj_fc_jbuf_ofs), Pmode);
|
|
|
|
|
|
|
|
|
|
note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
|
|
|
|
|
NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx);
|
|
|
|
|
|
|
|
|
|
emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
|
2001-11-15 23:44:58 +00:00
|
|
|
|
TYPE_MODE (integer_type_node), 0, dispatch_label);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
|
|
|
|
|
dispatch_label);
|
1996-07-23 20:20:04 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
|
|
|
|
|
1, XEXP (fc, 0), Pmode);
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
seq = get_insns ();
|
|
|
|
|
end_sequence ();
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* ??? Instead of doing this at the beginning of the function,
|
|
|
|
|
do this in a block that is at loop level 0 and dominates all
|
|
|
|
|
can_throw_internal instructions. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
|
|
|
|
|
if (GET_CODE (fn_begin) == NOTE
|
|
|
|
|
&& NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
|
|
|
|
|
break;
|
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
2002-06-05 David S. Miller <davem@redhat.com>
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
* rtl.h (gen_sequence, emit_insns, emit_insns_before,
emit_insns_before_scope, emit_insns_after,
emit_insns_after_scope): Delete declaration.
* ada/misc.c (insert_code_for): Use emit_insn* instead of
emit_insns_foo.
* config/alpha/alpha.c (alpha_set_memflags_1): Abort on SEQUENCE.
(alpha_set_memflags): Fix comment.
(set_frame_related_p): Use get_insns instead of gen_sequence.
* config/alpha/alpha.md (setjmp receiver splitter): Avoid
emitting no insns.
* config/arm/arm.c (arm_finalize_pic): Use get_insns instead of
gen_sequence.
(arm_gen_load_multiple, arm_gen_store_multiple): Likewise.
* config/fr30/fr30.c (fr30_move_double): Likewise.
* config/i386/i386.c (ix86_expand_int_movcc, ix86_expand_movstr):
Likewise.
* config/ia64/ia64.c (spill_restore_mem): Likewise.
* config/ia64/ia64.md (conditional move spliiter): Avoid emitting
no insns.
* config/m32r/m32r.c (gen_split_move_double): Use get_insns
instead of gen_sequence.
* config/mips/mips.c (embedded_pic_fnaddr_reg): Likewise.
(mips_expand_prologue, mips16_gp_pseudo_reg): Likewise.
* config/sh/sh.c (sh_need_epilogue): Likewise.
* config/sparc/sparc.md (current_function_calls_alloca, flat): New
attributes.
(setjmp pattern and split): Use them to avoid splitter which emits
no RTL.
* genattrtab.c (main): Emit include of function.h
* config/stormy16/stormy16.c (xstormy16_split_cbranch): Use
get_insns instead of gen_sequence.
* config/cris/cris.c (cris_split_movdx): Likewise.
* emit-rtl.c (emit_insns*): Kill.
(try_split): Expect insn list instead of SEQUENCE.
(make_jump_insn_raw, make_call_insn_raw): Fix comments.
(emit_*insn*): Reimplement to work with INSN lists and PATTERNs.
Make them abort if a SEQUENCE is given and RTL checking is
enabled.
(emit_*_scope): Don't forget to set scope on final insn.
(gen_sequence): Move from here...
* ssa.c (gen_sequence): To here as private function.
* builtins.c (expand_builtin_apply_args): Use emit_insn_foo, fix
comments.
(expand_builtin_return, expand_builtin_mathfn): Likewise.
(expand_builtin_strlen): Use get_insns instead of gen_sequence.
(expand_builtin_saveregs): Use emit_insn_foo, fix comments.
(expand_builtin_expect_jump): Use get_insns and fix comments.
* calls.c (try_to_integrate): Use emit_insn_foo.
(expand_call, emit_library_call_value_1): Likewise.
* expr.c (emit_queue): Handle insn lists instead of SEQUENCE.
(emit_move_insn_1): Use get_insns instead of gen_sequence.
(expand_expr): Use emit_insn_foo.
* cfgrtl.c (commit_one_edge_insertion): Use emit_insn_foo.
* except.c (build_post_landing_pads): Likewise.
* flow.c (attempt_auto_inc): Likewise.
* stmt.c (expand_fixup, fixup_gotos, expand_nl_handler_label,
expand_nl_goto_receivers, expand_decl_cleanup): Likewise.
* function.c (fixup_var_refs_insn): Use get_insns instead of
gen_sequence.
(fixup_var_refs_1): Likewise and expect insn list from gen_foo.
(fixup_memory_subreg): Use get_insns instead of gen_sequence.
(fixup_stack_1, purge_addressof_1, expand_main_function,
get_arg_pointer_save_area): Likewise.
(optimize_bit_field, instantiate_virtual_regs_1, assign_parms,
expand_function_end): Use emit_insn_foo.
(record_insns, keep_stack_depressed): Work with insn list instead
of SEQUENCE, fix comments.
* ifcvt.c (noce_emit_store_flag, noce_try_store_flag,
noce_try_store_flag_constants, noce_try_store_flag_inc,
noce_try_store_flag_mask, noce_emit_cmove, noce_try_cmove_arith,
noce_try_minmax, noce_try_abs): Use emit_insn_foo.
(noce_process_if_block): Use get_insns instead of gen_sequence.
* optabs.c (add_equal_note): Work with insn list, fix comments.
(expand_binop): Expect insn list from GEN_FCN(), use emit_insn_foo.
(expand_unop, expand_complex_abs, expand_unop_insn,
expand_no_conflict_block): Likewise.
(gen_move_insn): Use get_insns instead of gen_sequence.
(gen_cond_trap): Likewise.
* integrate.c (copy_rtx_and_substitute): Likewise.
(emit_initial_value_sets): Use emit_insn_foo.
* reload1.c (emit_output_reload_insns, emit_reload_insns): Likewise.
(fixup_abnormal_edges): Avoid losing REG_NOTES more intelligently
now that RTL generators give insn lists.
* sibcall.c (replace_call_placeholder): Use emit_insn_foo.
* doloop.c (doloop_modify, doloop_modify_runtime): Use get_insns
instead of gen_sequence.
(doloop_optimize): Work with insn lists instead of SEQUENCE rtl.
* explow.c (emit_stack_save, emit_stack_restore): Use get_insns
instead of gen_sequence.
* loop.c (move_movables, emit_prefetch_instructions,
gen_add_mult, check_dbra_loop, gen_load_of_final_value):
Likewise.
(loop_regs_update): Work with insn list instead of SEQUENCE rtl.
(product_cheap_p): Likewise, and add commentary about RTL wastage
here.
* lcm.c (optimize_mode_switching): Use get_insns instead of
gen_sequence.
* profile.c (gen_edge_profiler): Likewise.
* regmove.c (copy_src_to_dest): Likewise.
* reg-stack.c (compensate_edge): Likewise and fix comment.
* gcse.c (process_insert_insn): Likewise.
(insert_insn_end_bb): Work with insn list instead of SEQUENCE rtl.
* jump.c (delete_prior_computation): Update comment.
* genemit.c (gen_expand, gen_split, main): Use get_insns instead
of gen_sequence, update comments to match.
* recog.c (peephole2_optimize): Work with insn lists instead of
SEQUENCE rtl.
* sched-vis.c (print_pattern): Abort on SEQUENCE.
* unroll.c (unroll_loop, find_splittable_givs, final_giv_value):
Use get_insns instead of gen_sequence.
(copy_loop_body): Likewise and don't emit dummy NOTE.
* genrecog.c: Don't mention SEQUENCE rtl in comments.
* combine.c (try_combine): Expect insn lists from split generator.
* reorg.c (relax_delay_slots): Emit SEQUENCE into insn list by
hand.
From-SVN: r54497
2002-06-11 05:22:48 -07:00
|
|
|
|
emit_insn_after (seq, fn_begin);
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Call back from expand_function_end to know where we should put
|
|
|
|
|
the call to unwind_sjlj_unregister_libfunc if needed. */
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
sjlj_emit_function_exit_after (after)
|
|
|
|
|
rtx after;
|
|
|
|
|
{
|
|
|
|
|
cfun->eh->sjlj_exit_after = after;
|
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
|
|
|
|
static void
|
2001-03-28 03:04:51 -08:00
|
|
|
|
sjlj_emit_function_exit ()
|
|
|
|
|
{
|
|
|
|
|
rtx seq;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
start_sequence ();
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
|
|
|
|
|
1, XEXP (cfun->eh->sjlj_fc, 0), Pmode);
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
seq = get_insns ();
|
|
|
|
|
end_sequence ();
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* ??? Really this can be done in any block at loop level 0 that
|
|
|
|
|
post-dominates all can_throw_internal instructions. This is
|
|
|
|
|
the last possible moment. */
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
2002-06-05 David S. Miller <davem@redhat.com>
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
* rtl.h (gen_sequence, emit_insns, emit_insns_before,
emit_insns_before_scope, emit_insns_after,
emit_insns_after_scope): Delete declaration.
* ada/misc.c (insert_code_for): Use emit_insn* instead of
emit_insns_foo.
* config/alpha/alpha.c (alpha_set_memflags_1): Abort on SEQUENCE.
(alpha_set_memflags): Fix comment.
(set_frame_related_p): Use get_insns instead of gen_sequence.
* config/alpha/alpha.md (setjmp receiver splitter): Avoid
emitting no insns.
* config/arm/arm.c (arm_finalize_pic): Use get_insns instead of
gen_sequence.
(arm_gen_load_multiple, arm_gen_store_multiple): Likewise.
* config/fr30/fr30.c (fr30_move_double): Likewise.
* config/i386/i386.c (ix86_expand_int_movcc, ix86_expand_movstr):
Likewise.
* config/ia64/ia64.c (spill_restore_mem): Likewise.
* config/ia64/ia64.md (conditional move spliiter): Avoid emitting
no insns.
* config/m32r/m32r.c (gen_split_move_double): Use get_insns
instead of gen_sequence.
* config/mips/mips.c (embedded_pic_fnaddr_reg): Likewise.
(mips_expand_prologue, mips16_gp_pseudo_reg): Likewise.
* config/sh/sh.c (sh_need_epilogue): Likewise.
* config/sparc/sparc.md (current_function_calls_alloca, flat): New
attributes.
(setjmp pattern and split): Use them to avoid splitter which emits
no RTL.
* genattrtab.c (main): Emit include of function.h
* config/stormy16/stormy16.c (xstormy16_split_cbranch): Use
get_insns instead of gen_sequence.
* config/cris/cris.c (cris_split_movdx): Likewise.
* emit-rtl.c (emit_insns*): Kill.
(try_split): Expect insn list instead of SEQUENCE.
(make_jump_insn_raw, make_call_insn_raw): Fix comments.
(emit_*insn*): Reimplement to work with INSN lists and PATTERNs.
Make them abort if a SEQUENCE is given and RTL checking is
enabled.
(emit_*_scope): Don't forget to set scope on final insn.
(gen_sequence): Move from here...
* ssa.c (gen_sequence): To here as private function.
* builtins.c (expand_builtin_apply_args): Use emit_insn_foo, fix
comments.
(expand_builtin_return, expand_builtin_mathfn): Likewise.
(expand_builtin_strlen): Use get_insns instead of gen_sequence.
(expand_builtin_saveregs): Use emit_insn_foo, fix comments.
(expand_builtin_expect_jump): Use get_insns and fix comments.
* calls.c (try_to_integrate): Use emit_insn_foo.
(expand_call, emit_library_call_value_1): Likewise.
* expr.c (emit_queue): Handle insn lists instead of SEQUENCE.
(emit_move_insn_1): Use get_insns instead of gen_sequence.
(expand_expr): Use emit_insn_foo.
* cfgrtl.c (commit_one_edge_insertion): Use emit_insn_foo.
* except.c (build_post_landing_pads): Likewise.
* flow.c (attempt_auto_inc): Likewise.
* stmt.c (expand_fixup, fixup_gotos, expand_nl_handler_label,
expand_nl_goto_receivers, expand_decl_cleanup): Likewise.
* function.c (fixup_var_refs_insn): Use get_insns instead of
gen_sequence.
(fixup_var_refs_1): Likewise and expect insn list from gen_foo.
(fixup_memory_subreg): Use get_insns instead of gen_sequence.
(fixup_stack_1, purge_addressof_1, expand_main_function,
get_arg_pointer_save_area): Likewise.
(optimize_bit_field, instantiate_virtual_regs_1, assign_parms,
expand_function_end): Use emit_insn_foo.
(record_insns, keep_stack_depressed): Work with insn list instead
of SEQUENCE, fix comments.
* ifcvt.c (noce_emit_store_flag, noce_try_store_flag,
noce_try_store_flag_constants, noce_try_store_flag_inc,
noce_try_store_flag_mask, noce_emit_cmove, noce_try_cmove_arith,
noce_try_minmax, noce_try_abs): Use emit_insn_foo.
(noce_process_if_block): Use get_insns instead of gen_sequence.
* optabs.c (add_equal_note): Work with insn list, fix comments.
(expand_binop): Expect insn list from GEN_FCN(), use emit_insn_foo.
(expand_unop, expand_complex_abs, expand_unop_insn,
expand_no_conflict_block): Likewise.
(gen_move_insn): Use get_insns instead of gen_sequence.
(gen_cond_trap): Likewise.
* integrate.c (copy_rtx_and_substitute): Likewise.
(emit_initial_value_sets): Use emit_insn_foo.
* reload1.c (emit_output_reload_insns, emit_reload_insns): Likewise.
(fixup_abnormal_edges): Avoid losing REG_NOTES more intelligently
now that RTL generators give insn lists.
* sibcall.c (replace_call_placeholder): Use emit_insn_foo.
* doloop.c (doloop_modify, doloop_modify_runtime): Use get_insns
instead of gen_sequence.
(doloop_optimize): Work with insn lists instead of SEQUENCE rtl.
* explow.c (emit_stack_save, emit_stack_restore): Use get_insns
instead of gen_sequence.
* loop.c (move_movables, emit_prefetch_instructions,
gen_add_mult, check_dbra_loop, gen_load_of_final_value):
Likewise.
(loop_regs_update): Work with insn list instead of SEQUENCE rtl.
(product_cheap_p): Likewise, and add commentary about RTL wastage
here.
* lcm.c (optimize_mode_switching): Use get_insns instead of
gen_sequence.
* profile.c (gen_edge_profiler): Likewise.
* regmove.c (copy_src_to_dest): Likewise.
* reg-stack.c (compensate_edge): Likewise and fix comment.
* gcse.c (process_insert_insn): Likewise.
(insert_insn_end_bb): Work with insn list instead of SEQUENCE rtl.
* jump.c (delete_prior_computation): Update comment.
* genemit.c (gen_expand, gen_split, main): Use get_insns instead
of gen_sequence, update comments to match.
* recog.c (peephole2_optimize): Work with insn lists instead of
SEQUENCE rtl.
* sched-vis.c (print_pattern): Abort on SEQUENCE.
* unroll.c (unroll_loop, find_splittable_givs, final_giv_value):
Use get_insns instead of gen_sequence.
(copy_loop_body): Likewise and don't emit dummy NOTE.
* genrecog.c: Don't mention SEQUENCE rtl in comments.
* combine.c (try_combine): Expect insn lists from split generator.
* reorg.c (relax_delay_slots): Emit SEQUENCE into insn list by
hand.
From-SVN: r54497
2002-06-11 05:22:48 -07:00
|
|
|
|
emit_insn_after (seq, cfun->eh->sjlj_exit_after);
|
1998-05-14 13:39:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void
|
|
|
|
|
sjlj_emit_dispatch_table (dispatch_label, lp_info)
|
|
|
|
|
rtx dispatch_label;
|
|
|
|
|
struct sjlj_lp_info *lp_info;
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int i, first_reachable;
|
|
|
|
|
rtx mem, dispatch, seq, fc;
|
|
|
|
|
|
|
|
|
|
fc = cfun->eh->sjlj_fc;
|
|
|
|
|
|
|
|
|
|
start_sequence ();
|
|
|
|
|
|
|
|
|
|
emit_label (dispatch_label);
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#ifndef DONT_USE_BUILTIN_SETJMP
|
|
|
|
|
expand_builtin_setjmp_receiver (dispatch_label);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Load up dispatch index, exc_ptr and filter values from the
|
|
|
|
|
function context. */
|
emit-rtl.c (adjust_address): New function.
* emit-rtl.c (adjust_address): New function.
* expr.h (adjust_address): Add declaration.
* builtins.c: Replace some calls to change_address with calls to it
or to validize_mem.
* caller-save.c, dwarf2out.c, except.c, expmed.c, expr.c: Likewise.
* function.c, config/a29k/a29k.md, config/alpha/alpha.c: Likewise.
* config/arm/arm.c, config/convex/convex.c: Likewise.
* config/dsp16xx/dsp16xx.md, config/fr30/fr30.c: Likewise.
* config/i386/i386.c, config/i386/i386.md: Likewise.
* config/ia64/ia64.c, config/ia64/ia64.md: Likewise.
* config/m32r/m32r.c, config/m68k/m68k.md: Likewise.
* config/m88k/m88k.c, config/mips/mips.md: Likewise.
* config/ns32k/ns32k.c, config/rs6000/rs6000.c: Likewise.
* config/sh/sh.c, config/sparc/sparc.md: Likewise.
From-SVN: r43702
2001-07-02 19:47:44 +00:00
|
|
|
|
mem = adjust_address (fc, TYPE_MODE (integer_type_node),
|
|
|
|
|
sjlj_fc_call_site_ofs);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
dispatch = copy_to_reg (mem);
|
|
|
|
|
|
emit-rtl.c (adjust_address): New function.
* emit-rtl.c (adjust_address): New function.
* expr.h (adjust_address): Add declaration.
* builtins.c: Replace some calls to change_address with calls to it
or to validize_mem.
* caller-save.c, dwarf2out.c, except.c, expmed.c, expr.c: Likewise.
* function.c, config/a29k/a29k.md, config/alpha/alpha.c: Likewise.
* config/arm/arm.c, config/convex/convex.c: Likewise.
* config/dsp16xx/dsp16xx.md, config/fr30/fr30.c: Likewise.
* config/i386/i386.c, config/i386/i386.md: Likewise.
* config/ia64/ia64.c, config/ia64/ia64.md: Likewise.
* config/m32r/m32r.c, config/m68k/m68k.md: Likewise.
* config/m88k/m88k.c, config/mips/mips.md: Likewise.
* config/ns32k/ns32k.c, config/rs6000/rs6000.c: Likewise.
* config/sh/sh.c, config/sparc/sparc.md: Likewise.
From-SVN: r43702
2001-07-02 19:47:44 +00:00
|
|
|
|
mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (word_mode != Pmode)
|
|
|
|
|
{
|
|
|
|
|
#ifdef POINTERS_EXTEND_UNSIGNED
|
|
|
|
|
mem = convert_memory_address (Pmode, mem);
|
|
|
|
|
#else
|
|
|
|
|
mem = convert_to_mode (Pmode, mem, 0);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
emit_move_insn (cfun->eh->exc_ptr, mem);
|
|
|
|
|
|
emit-rtl.c (adjust_address): New function.
* emit-rtl.c (adjust_address): New function.
* expr.h (adjust_address): Add declaration.
* builtins.c: Replace some calls to change_address with calls to it
or to validize_mem.
* caller-save.c, dwarf2out.c, except.c, expmed.c, expr.c: Likewise.
* function.c, config/a29k/a29k.md, config/alpha/alpha.c: Likewise.
* config/arm/arm.c, config/convex/convex.c: Likewise.
* config/dsp16xx/dsp16xx.md, config/fr30/fr30.c: Likewise.
* config/i386/i386.c, config/i386/i386.md: Likewise.
* config/ia64/ia64.c, config/ia64/ia64.md: Likewise.
* config/m32r/m32r.c, config/m68k/m68k.md: Likewise.
* config/m88k/m88k.c, config/mips/mips.md: Likewise.
* config/ns32k/ns32k.c, config/rs6000/rs6000.c: Likewise.
* config/sh/sh.c, config/sparc/sparc.md: Likewise.
From-SVN: r43702
2001-07-02 19:47:44 +00:00
|
|
|
|
mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs + UNITS_PER_WORD);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_move_insn (cfun->eh->filter, mem);
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Jump to one of the directly reachable regions. */
|
|
|
|
|
/* ??? This really ought to be using a switch statement. */
|
|
|
|
|
|
|
|
|
|
first_reachable = 0;
|
|
|
|
|
for (i = cfun->eh->last_region_number; i > 0; --i)
|
1998-06-08 12:43:28 +00:00
|
|
|
|
{
|
2001-12-11 18:58:23 -08:00
|
|
|
|
if (! lp_info[i].directly_reachable)
|
2001-03-28 03:04:51 -08:00
|
|
|
|
continue;
|
1998-06-08 12:43:28 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! first_reachable)
|
|
|
|
|
{
|
|
|
|
|
first_reachable = i;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-11-15 23:44:58 +00:00
|
|
|
|
emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
|
|
|
|
|
EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
|
2001-03-28 03:04:51 -08:00
|
|
|
|
cfun->eh->region_array[i]->post_landing_pad);
|
1998-06-08 12:43:28 +00:00
|
|
|
|
}
|
1998-05-14 13:39:15 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
seq = get_insns ();
|
|
|
|
|
end_sequence ();
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
2002-06-05 David S. Miller <davem@redhat.com>
Delete SEQUENCE rtl usage outside of reorg and ssa passes.
* rtl.h (gen_sequence, emit_insns, emit_insns_before,
emit_insns_before_scope, emit_insns_after,
emit_insns_after_scope): Delete declaration.
* ada/misc.c (insert_code_for): Use emit_insn* instead of
emit_insns_foo.
* config/alpha/alpha.c (alpha_set_memflags_1): Abort on SEQUENCE.
(alpha_set_memflags): Fix comment.
(set_frame_related_p): Use get_insns instead of gen_sequence.
* config/alpha/alpha.md (setjmp receiver splitter): Avoid
emitting no insns.
* config/arm/arm.c (arm_finalize_pic): Use get_insns instead of
gen_sequence.
(arm_gen_load_multiple, arm_gen_store_multiple): Likewise.
* config/fr30/fr30.c (fr30_move_double): Likewise.
* config/i386/i386.c (ix86_expand_int_movcc, ix86_expand_movstr):
Likewise.
* config/ia64/ia64.c (spill_restore_mem): Likewise.
* config/ia64/ia64.md (conditional move spliiter): Avoid emitting
no insns.
* config/m32r/m32r.c (gen_split_move_double): Use get_insns
instead of gen_sequence.
* config/mips/mips.c (embedded_pic_fnaddr_reg): Likewise.
(mips_expand_prologue, mips16_gp_pseudo_reg): Likewise.
* config/sh/sh.c (sh_need_epilogue): Likewise.
* config/sparc/sparc.md (current_function_calls_alloca, flat): New
attributes.
(setjmp pattern and split): Use them to avoid splitter which emits
no RTL.
* genattrtab.c (main): Emit include of function.h
* config/stormy16/stormy16.c (xstormy16_split_cbranch): Use
get_insns instead of gen_sequence.
* config/cris/cris.c (cris_split_movdx): Likewise.
* emit-rtl.c (emit_insns*): Kill.
(try_split): Expect insn list instead of SEQUENCE.
(make_jump_insn_raw, make_call_insn_raw): Fix comments.
(emit_*insn*): Reimplement to work with INSN lists and PATTERNs.
Make them abort if a SEQUENCE is given and RTL checking is
enabled.
(emit_*_scope): Don't forget to set scope on final insn.
(gen_sequence): Move from here...
* ssa.c (gen_sequence): To here as private function.
* builtins.c (expand_builtin_apply_args): Use emit_insn_foo, fix
comments.
(expand_builtin_return, expand_builtin_mathfn): Likewise.
(expand_builtin_strlen): Use get_insns instead of gen_sequence.
(expand_builtin_saveregs): Use emit_insn_foo, fix comments.
(expand_builtin_expect_jump): Use get_insns and fix comments.
* calls.c (try_to_integrate): Use emit_insn_foo.
(expand_call, emit_library_call_value_1): Likewise.
* expr.c (emit_queue): Handle insn lists instead of SEQUENCE.
(emit_move_insn_1): Use get_insns instead of gen_sequence.
(expand_expr): Use emit_insn_foo.
* cfgrtl.c (commit_one_edge_insertion): Use emit_insn_foo.
* except.c (build_post_landing_pads): Likewise.
* flow.c (attempt_auto_inc): Likewise.
* stmt.c (expand_fixup, fixup_gotos, expand_nl_handler_label,
expand_nl_goto_receivers, expand_decl_cleanup): Likewise.
* function.c (fixup_var_refs_insn): Use get_insns instead of
gen_sequence.
(fixup_var_refs_1): Likewise and expect insn list from gen_foo.
(fixup_memory_subreg): Use get_insns instead of gen_sequence.
(fixup_stack_1, purge_addressof_1, expand_main_function,
get_arg_pointer_save_area): Likewise.
(optimize_bit_field, instantiate_virtual_regs_1, assign_parms,
expand_function_end): Use emit_insn_foo.
(record_insns, keep_stack_depressed): Work with insn list instead
of SEQUENCE, fix comments.
* ifcvt.c (noce_emit_store_flag, noce_try_store_flag,
noce_try_store_flag_constants, noce_try_store_flag_inc,
noce_try_store_flag_mask, noce_emit_cmove, noce_try_cmove_arith,
noce_try_minmax, noce_try_abs): Use emit_insn_foo.
(noce_process_if_block): Use get_insns instead of gen_sequence.
* optabs.c (add_equal_note): Work with insn list, fix comments.
(expand_binop): Expect insn list from GEN_FCN(), use emit_insn_foo.
(expand_unop, expand_complex_abs, expand_unop_insn,
expand_no_conflict_block): Likewise.
(gen_move_insn): Use get_insns instead of gen_sequence.
(gen_cond_trap): Likewise.
* integrate.c (copy_rtx_and_substitute): Likewise.
(emit_initial_value_sets): Use emit_insn_foo.
* reload1.c (emit_output_reload_insns, emit_reload_insns): Likewise.
(fixup_abnormal_edges): Avoid losing REG_NOTES more intelligently
now that RTL generators give insn lists.
* sibcall.c (replace_call_placeholder): Use emit_insn_foo.
* doloop.c (doloop_modify, doloop_modify_runtime): Use get_insns
instead of gen_sequence.
(doloop_optimize): Work with insn lists instead of SEQUENCE rtl.
* explow.c (emit_stack_save, emit_stack_restore): Use get_insns
instead of gen_sequence.
* loop.c (move_movables, emit_prefetch_instructions,
gen_add_mult, check_dbra_loop, gen_load_of_final_value):
Likewise.
(loop_regs_update): Work with insn list instead of SEQUENCE rtl.
(product_cheap_p): Likewise, and add commentary about RTL wastage
here.
* lcm.c (optimize_mode_switching): Use get_insns instead of
gen_sequence.
* profile.c (gen_edge_profiler): Likewise.
* regmove.c (copy_src_to_dest): Likewise.
* reg-stack.c (compensate_edge): Likewise and fix comment.
* gcse.c (process_insert_insn): Likewise.
(insert_insn_end_bb): Work with insn list instead of SEQUENCE rtl.
* jump.c (delete_prior_computation): Update comment.
* genemit.c (gen_expand, gen_split, main): Use get_insns instead
of gen_sequence, update comments to match.
* recog.c (peephole2_optimize): Work with insn lists instead of
SEQUENCE rtl.
* sched-vis.c (print_pattern): Abort on SEQUENCE.
* unroll.c (unroll_loop, find_splittable_givs, final_giv_value):
Use get_insns instead of gen_sequence.
(copy_loop_body): Likewise and don't emit dummy NOTE.
* genrecog.c: Don't mention SEQUENCE rtl in comments.
* combine.c (try_combine): Expect insn lists from split generator.
* reorg.c (relax_delay_slots): Emit SEQUENCE into insn list by
hand.
From-SVN: r54497
2002-06-11 05:22:48 -07:00
|
|
|
|
emit_insn_before (seq, (cfun->eh->region_array[first_reachable]
|
|
|
|
|
->post_landing_pad));
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void
|
|
|
|
|
sjlj_build_landing_pads ()
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct sjlj_lp_info *lp_info;
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
lp_info = (struct sjlj_lp_info *) xcalloc (cfun->eh->last_region_number + 1,
|
|
|
|
|
sizeof (struct sjlj_lp_info));
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (sjlj_find_directly_reachable_regions (lp_info))
|
|
|
|
|
{
|
|
|
|
|
rtx dispatch_label = gen_label_rtx ();
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
cfun->eh->sjlj_fc
|
|
|
|
|
= assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
|
|
|
|
|
int_size_in_bytes (sjlj_fc_type_node),
|
|
|
|
|
TYPE_ALIGN (sjlj_fc_type_node));
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
sjlj_assign_call_site_values (dispatch_label, lp_info);
|
|
|
|
|
sjlj_mark_call_sites (lp_info);
|
1998-06-08 12:43:28 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
sjlj_emit_function_enter (dispatch_label);
|
|
|
|
|
sjlj_emit_dispatch_table (dispatch_label, lp_info);
|
|
|
|
|
sjlj_emit_function_exit ();
|
|
|
|
|
}
|
1998-06-08 12:43:28 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
free (lp_info);
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
|
|
|
|
|
void
|
2001-03-28 03:04:51 -08:00
|
|
|
|
finish_eh_generation ()
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Nothing to do if no regions created. */
|
|
|
|
|
if (cfun->eh->region_tree == NULL)
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* The object here is to provide find_basic_blocks with detailed
|
|
|
|
|
information (via reachable_handlers) on how exception control
|
|
|
|
|
flows within the function. In this first pass, we can include
|
|
|
|
|
type information garnered from ERT_THROW and ERT_ALLOWED_EXCEPTIONS
|
|
|
|
|
regions, and hope that it will be useful in deleting unreachable
|
|
|
|
|
handlers. Subsequently, we will generate landing pads which will
|
|
|
|
|
connect many of the handlers, and then type information will not
|
|
|
|
|
be effective. Still, this is a win over previous implementations. */
|
|
|
|
|
|
2002-05-23 08:22:05 -07:00
|
|
|
|
cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* These registers are used by the landing pads. Make sure they
|
|
|
|
|
have been generated. */
|
2001-06-08 15:57:23 -07:00
|
|
|
|
get_exception_pointer (cfun);
|
|
|
|
|
get_exception_filter (cfun);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* Construct the landing pads. */
|
|
|
|
|
|
|
|
|
|
assign_filter_values ();
|
|
|
|
|
build_post_landing_pads ();
|
|
|
|
|
connect_post_landing_pads ();
|
|
|
|
|
if (USING_SJLJ_EXCEPTIONS)
|
|
|
|
|
sjlj_build_landing_pads ();
|
|
|
|
|
else
|
|
|
|
|
dw2_build_landing_pads ();
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
cfun->eh->built_landing_pads = 1;
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* We've totally changed the CFG. Start over. */
|
|
|
|
|
find_exception_handler_labels ();
|
2001-07-16 22:54:44 +02:00
|
|
|
|
rebuild_jump_labels (get_insns ());
|
2001-03-28 03:04:51 -08:00
|
|
|
|
find_basic_blocks (get_insns (), max_reg_num (), 0);
|
2002-05-23 08:22:05 -07:00
|
|
|
|
cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
|
except.c (func_eh_entry): Add emitted field.
2000-05-25 Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
* except.c (func_eh_entry): Add emitted field.
(new_eh_region_entry): Set emitted field to 0;
(output_exception_table_entry): Only emit previously un-emitted data,
and send it to the eh_data section.
(output_exception_table): Break out common parts. Output
exception table for entire compilation unit to eh_data section.
(output_exception_table_data): Common parts of output_exception_table.
Send output to eh_data section.
(output_function_exception_table): Output exception table data for
a single function to eh_data section.
(free_exception_table): New external to free the table.
* except.h (free_exception_table): Add prototype.
(output_function_exception_table): Add prototype.
* final.c (final_end_function): Output function exception table
for IA64_UNWIND_INFO.
(final_scan_insn): Emit any unwind directives for an insn.
* frame-dwarf2.c: New file containing all DWARF 2 specific code
from frame.c.
* frame.c: Remove all DWARF 2 specific code.
* config/ia64/frame-ia64.c: New file.
(gthread_stuff): Make all gthread available with
IA64_UNWIND_INFO.
(dwarf_fde): Define an IA64 struct for dwarf_fde.
(__register_frame_info, __register_frame): Move to common area of file.
(__register_frame_info_table, __register_frame_table): Move to common i
area.
(__deregister_frame_info, __deregister_frame): Move to common area.
(__frame_init, find_fde): New versions for IA64_UNWIND_INFO.
(read_uleb128): New version for ia64.
(get_unwind_record): Read the next IA-64 unwind record.
(read_R_record): Read a region header record.
(process_a_b_reg_code): X record helper.
(read_X_record): Read an X format record.
(read_B_record): Read a B format record.
(P3_record_types): List of record types matching the P3 format.
(P7_record_types): List of record types matching the P7 format.
(P8_record_types): List of record types matching the P8 format.
(read_P_record): Read a P format record.
(init_ia64_reg_loc): Set default fields for a register.
(init_ia64_unwind_frame): Set defaults for all register records.
(execute_one_ia64_descriptor): Execute one descriptor record.
(rse_address_add): Calculate the position of a local reg in memory.
(normalize_reg_loc): Turn a location descriptor into a memory address.
(maybe_normalize_reg_loc): Only normalize a descriptor if it falls
within a specified PC offset range.
(get_real_reg_value): Given a register location, retrieve its value.
(set_real_reg_value): Change the value of a register location.
(copy_reg_value): Copy reg values, if needed.
(copy_saved_reg_state): Copy all registers that need to be copied.
(process_state_between): Normalize all frame register records that
fall within the specified PC range.
(frame_translate): Take a processed frame description, and turn
everything into addresses.
(build_ia64_frame_state ): Find and create frame state record for a PC.
(get_personality): Get the personality routine for a given frame.
(get_except_table): Get the exception table for a given frame.
(record_name): Unwind record names for debugging.
(print_record): Print and unwind record.
(print_all_records): Print an entire unwind image.
(__ia64_backtrace): Print a backtrace.
(ia64_backtrace_helper): New function.
(__register_frame_info_aux): New function.
* config/ia64/crtend.asm (__do_frame_setup_aux): New function.
* frame.h (enum unw_record_type): New unwind record types.
(struct unw_p_record, unw_b_record, unw_x_record) : New unwind records.
(struct unw_r_record, unwind_record): New unwind record structs.
(struct unwind_info_ptr): Unwind information layout.
(IA64_UNW_LOC_TYPE_*): Macros for different types for location
descriptors.
(struct ia64_reg_loc): Register location description.
(struct ia64_frame_state): Location of all registers in a frame.
(struct object): Add pc_base and fde_end for IA64_UNWIND_INFO.
* libgcc2.c (__ia64_personality_v1): Personality routine.
(__calc_caller_bsp): Calculate the bsp register for the caller's
frame.
(ia64_throw_helper): Figure out who to return to and set up the
registers.
(__throw): Throw routine.
* output.h (assemble_eh_align, assemble_eh_label): New functions
to generate EH info where we want it.
(assemble_eh_integer): New function.
* toplev.c (compile_file): Output module level exception table for
non-ia64 targets.
(main): Set exceptions_via_longjump and flag_new_exceptions based
on IA64_UNWIND_INFO too.
* varasm.c (assemble_eh_label): Generate a label via
ASM_OUTPUT_EH_LABEL if it has been specified.
(assemble_eh_align): Generate an alignment directive via
ASM_OUTPUT_EH_ALIGN if it has been specified.
(assemble_eh_label): Generate an integer value via
ASM_OUTPUT_EH_type if they have been specified.
* config/ia64/ia64.c (rtx_needs_barrier): Add flushrs.
(ia64_init_builtins): Add __builtin_ia64_bsp
and __builtin_ia64_flushrs.
(ia64_expand_builtin): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.h (ia64_builtins): Add IA64_BUILTIN_BSP and
IA64_BUILTIN_FLUSHRS.
* config/ia64/ia64.md (flushrs): New insn to flush the register
stack. Add to unspec list.
* config/ia64/crtbegin.asm (frame_object): Change size.
(__do_frame_setup_aux): New function.
* config/ia64/crtend.asm: call __do_frame_setup_aux.
* config/ia64/t-ia64 (LIB2ADDEH): Add.
* Makefile.in (LIB2ADDEH): Add.
(LIB2ADD): Use LIB2ADDEH.
Co-Authored-By: Andrew Haley <aph@cygnus.com>
From-SVN: r34169
2000-05-25 15:21:51 +00:00
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2002-04-09 17:15:58 -07:00
|
|
|
|
static hashval_t
|
|
|
|
|
ehl_hash (pentry)
|
|
|
|
|
const PTR pentry;
|
|
|
|
|
{
|
|
|
|
|
struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
|
|
|
|
|
|
|
|
|
|
/* 2^32 * ((sqrt(5) - 1) / 2) */
|
|
|
|
|
const hashval_t scaled_golden_ratio = 0x9e3779b9;
|
|
|
|
|
return CODE_LABEL_NUMBER (entry->label) * scaled_golden_ratio;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
ehl_eq (pentry, pdata)
|
|
|
|
|
const PTR pentry;
|
|
|
|
|
const PTR pdata;
|
|
|
|
|
{
|
|
|
|
|
struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
|
|
|
|
|
struct ehl_map_entry *data = (struct ehl_map_entry *) pdata;
|
|
|
|
|
|
|
|
|
|
return entry->label == data->label;
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* This section handles removing dead code for flow. */
|
[multiple changes]
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.
* integrate.c (expand_inline_function): If the inline fn uses eh
context, make sure that the current fn has one.
* toplev.c (rest_of_compilation): Call emit_eh_context.
* except.c (use_eh_context): New fn.
(get_eh_context_once): New fn.
(call_get_eh_context): New fn.
(emit_eh_context): New fn.
(get_eh_context): Call either get_eh_context_once or
call_get_eh_context, depending on what we have.
(get_dynamic_handler_chain): Call get_eh_context_once.
* except.h: Prototypes for fns above.
* optabs.c (get_eh_context_libfunc): Removed.
(init_optabs): Don't initialize it.
* expr.h (get_eh_context_libfunc): Removed.
* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.
* config/pa/pa.h (CPP_SPEC): Support for -threads.
* config/pa/pa-hpux10.h (LIB_SPEC): Ditto.
* config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
New multilib for -threads.
* config/sparc/t-sol2: Added multilibs for -threads and
made -pthreads alias to it.
* config/sparc/sol2.h (CPP_SPEC, LIB_SPEC):
Added -threads and -pthreads options.
* libgcc-thr.h: New file.
* libgcc2.c: (__get_cpp_eh_context): Removed.
(struct cpp_eh_context): Removed.
(struct eh_context): Replaced cpp_eh_context with generic language
specific pointer.
(__get_eh_info): New function.
(__throw): Check eh_context::info.
(__sjthrow): Ditto.
* libgcc2.c: Include libgcc-thr.h.
(new_eh_context, __get_eh_context,
eh_pthread_initialize, eh_context_initialize, eh_context_static,
eh_context_specific, eh_context_free): New functions.
(get_eh_context, eh_context_key): New variables.
(__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use
get_eh_context to get the context.
(longjmp): Move the declaration inside
#ifdef DONT_USE_BUILTIN_SETJMP.
* frame.c: Include libgcc-thr.h.
(object_mutex): Mutex to protect the object list.
(find_fde, __register_frame, __register_frame_table,
__deregister_frame): Hold the lock while accessing objects.
* except.h (get_eh_context): Declare.
* except.c (current_function_ehc): Define.
(current_function_dhc, current_function_dcc): Removed.
(get_eh_context): New function.
(get_dynamic_handler_chain): Use get_eh_context.
(get_saved_pc_ref): Ditto.
(get_dynamic_cleanup_chain): Removed references to
current_function_dcc.
(save_eh_status, restore_eh_status): Save and restore
current_function_ehc instead.
* optabs.c (get_eh_context_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_eh_context_libfunc.
* function.h (struct function): Replaced dhc and dcc with ehc.
* except.c (get_saved_pc_ref): New functions.
(eh_saved_pc_rtx, eh_saved_pc): Deleted.
(expand_internal_throw_indirect): Use get_saved_pc_ref() instead
of eh_saved_pc.
(end_eh_unwinder): Likewise.
(init_eh): Remove initialization of eh_saved_pc.
* optabs.c (get_saved_pc_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_saved_pc_libfunc.
* except.h (eh_saved_pc_rtx): Deleted.
(get_saved_pc_ref): Declared.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* libgcc2.c (__get_saved_pc): New.
(__eh_type, __eh_pc): Deleted.
(__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc.
(__get_dynamic_handler_chain): Move __dynamic_handler_chain inside
this fcn.
cp/:
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.
(init_decl_processing): Initialize it.
* cp-tree.h: Declare it.
* exception.cc (__cp_exception_info): Use __get_eh_info.
(__cp_push_exception): Ditto.
(__cp_pop_exception): Ditto.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
saved_pc.
(init_exception_processing): Removed saved_pc initialization.
From-SVN: r17052
1997-12-12 04:53:20 +00:00
|
|
|
|
|
2002-04-09 17:15:58 -07:00
|
|
|
|
/* Remove LABEL from exception_handler_label_map. */
|
[multiple changes]
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.
* integrate.c (expand_inline_function): If the inline fn uses eh
context, make sure that the current fn has one.
* toplev.c (rest_of_compilation): Call emit_eh_context.
* except.c (use_eh_context): New fn.
(get_eh_context_once): New fn.
(call_get_eh_context): New fn.
(emit_eh_context): New fn.
(get_eh_context): Call either get_eh_context_once or
call_get_eh_context, depending on what we have.
(get_dynamic_handler_chain): Call get_eh_context_once.
* except.h: Prototypes for fns above.
* optabs.c (get_eh_context_libfunc): Removed.
(init_optabs): Don't initialize it.
* expr.h (get_eh_context_libfunc): Removed.
* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.
* config/pa/pa.h (CPP_SPEC): Support for -threads.
* config/pa/pa-hpux10.h (LIB_SPEC): Ditto.
* config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
New multilib for -threads.
* config/sparc/t-sol2: Added multilibs for -threads and
made -pthreads alias to it.
* config/sparc/sol2.h (CPP_SPEC, LIB_SPEC):
Added -threads and -pthreads options.
* libgcc-thr.h: New file.
* libgcc2.c: (__get_cpp_eh_context): Removed.
(struct cpp_eh_context): Removed.
(struct eh_context): Replaced cpp_eh_context with generic language
specific pointer.
(__get_eh_info): New function.
(__throw): Check eh_context::info.
(__sjthrow): Ditto.
* libgcc2.c: Include libgcc-thr.h.
(new_eh_context, __get_eh_context,
eh_pthread_initialize, eh_context_initialize, eh_context_static,
eh_context_specific, eh_context_free): New functions.
(get_eh_context, eh_context_key): New variables.
(__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use
get_eh_context to get the context.
(longjmp): Move the declaration inside
#ifdef DONT_USE_BUILTIN_SETJMP.
* frame.c: Include libgcc-thr.h.
(object_mutex): Mutex to protect the object list.
(find_fde, __register_frame, __register_frame_table,
__deregister_frame): Hold the lock while accessing objects.
* except.h (get_eh_context): Declare.
* except.c (current_function_ehc): Define.
(current_function_dhc, current_function_dcc): Removed.
(get_eh_context): New function.
(get_dynamic_handler_chain): Use get_eh_context.
(get_saved_pc_ref): Ditto.
(get_dynamic_cleanup_chain): Removed references to
current_function_dcc.
(save_eh_status, restore_eh_status): Save and restore
current_function_ehc instead.
* optabs.c (get_eh_context_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_eh_context_libfunc.
* function.h (struct function): Replaced dhc and dcc with ehc.
* except.c (get_saved_pc_ref): New functions.
(eh_saved_pc_rtx, eh_saved_pc): Deleted.
(expand_internal_throw_indirect): Use get_saved_pc_ref() instead
of eh_saved_pc.
(end_eh_unwinder): Likewise.
(init_eh): Remove initialization of eh_saved_pc.
* optabs.c (get_saved_pc_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_saved_pc_libfunc.
* except.h (eh_saved_pc_rtx): Deleted.
(get_saved_pc_ref): Declared.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* libgcc2.c (__get_saved_pc): New.
(__eh_type, __eh_pc): Deleted.
(__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc.
(__get_dynamic_handler_chain): Move __dynamic_handler_chain inside
this fcn.
cp/:
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.
(init_decl_processing): Initialize it.
* cp-tree.h: Declare it.
* exception.cc (__cp_exception_info): Use __get_eh_info.
(__cp_push_exception): Ditto.
(__cp_pop_exception): Ditto.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
saved_pc.
(init_exception_processing): Removed saved_pc initialization.
From-SVN: r17052
1997-12-12 04:53:20 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void
|
|
|
|
|
remove_exception_handler_label (label)
|
|
|
|
|
rtx label;
|
[multiple changes]
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.
* integrate.c (expand_inline_function): If the inline fn uses eh
context, make sure that the current fn has one.
* toplev.c (rest_of_compilation): Call emit_eh_context.
* except.c (use_eh_context): New fn.
(get_eh_context_once): New fn.
(call_get_eh_context): New fn.
(emit_eh_context): New fn.
(get_eh_context): Call either get_eh_context_once or
call_get_eh_context, depending on what we have.
(get_dynamic_handler_chain): Call get_eh_context_once.
* except.h: Prototypes for fns above.
* optabs.c (get_eh_context_libfunc): Removed.
(init_optabs): Don't initialize it.
* expr.h (get_eh_context_libfunc): Removed.
* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.
* config/pa/pa.h (CPP_SPEC): Support for -threads.
* config/pa/pa-hpux10.h (LIB_SPEC): Ditto.
* config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
New multilib for -threads.
* config/sparc/t-sol2: Added multilibs for -threads and
made -pthreads alias to it.
* config/sparc/sol2.h (CPP_SPEC, LIB_SPEC):
Added -threads and -pthreads options.
* libgcc-thr.h: New file.
* libgcc2.c: (__get_cpp_eh_context): Removed.
(struct cpp_eh_context): Removed.
(struct eh_context): Replaced cpp_eh_context with generic language
specific pointer.
(__get_eh_info): New function.
(__throw): Check eh_context::info.
(__sjthrow): Ditto.
* libgcc2.c: Include libgcc-thr.h.
(new_eh_context, __get_eh_context,
eh_pthread_initialize, eh_context_initialize, eh_context_static,
eh_context_specific, eh_context_free): New functions.
(get_eh_context, eh_context_key): New variables.
(__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use
get_eh_context to get the context.
(longjmp): Move the declaration inside
#ifdef DONT_USE_BUILTIN_SETJMP.
* frame.c: Include libgcc-thr.h.
(object_mutex): Mutex to protect the object list.
(find_fde, __register_frame, __register_frame_table,
__deregister_frame): Hold the lock while accessing objects.
* except.h (get_eh_context): Declare.
* except.c (current_function_ehc): Define.
(current_function_dhc, current_function_dcc): Removed.
(get_eh_context): New function.
(get_dynamic_handler_chain): Use get_eh_context.
(get_saved_pc_ref): Ditto.
(get_dynamic_cleanup_chain): Removed references to
current_function_dcc.
(save_eh_status, restore_eh_status): Save and restore
current_function_ehc instead.
* optabs.c (get_eh_context_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_eh_context_libfunc.
* function.h (struct function): Replaced dhc and dcc with ehc.
* except.c (get_saved_pc_ref): New functions.
(eh_saved_pc_rtx, eh_saved_pc): Deleted.
(expand_internal_throw_indirect): Use get_saved_pc_ref() instead
of eh_saved_pc.
(end_eh_unwinder): Likewise.
(init_eh): Remove initialization of eh_saved_pc.
* optabs.c (get_saved_pc_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_saved_pc_libfunc.
* except.h (eh_saved_pc_rtx): Deleted.
(get_saved_pc_ref): Declared.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* libgcc2.c (__get_saved_pc): New.
(__eh_type, __eh_pc): Deleted.
(__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc.
(__get_dynamic_handler_chain): Move __dynamic_handler_chain inside
this fcn.
cp/:
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.
(init_decl_processing): Initialize it.
* cp-tree.h: Declare it.
* exception.cc (__cp_exception_info): Use __get_eh_info.
(__cp_push_exception): Ditto.
(__cp_pop_exception): Ditto.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
saved_pc.
(init_exception_processing): Removed saved_pc initialization.
From-SVN: r17052
1997-12-12 04:53:20 +00:00
|
|
|
|
{
|
2002-04-09 17:15:58 -07:00
|
|
|
|
struct ehl_map_entry **slot, tmp;
|
1997-12-12 09:23:52 +00:00
|
|
|
|
|
2002-04-09 17:15:58 -07:00
|
|
|
|
/* If exception_handler_label_map was not built yet,
|
2002-01-14 22:06:26 +01:00
|
|
|
|
there is nothing to do. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
if (cfun->eh->exception_handler_label_map == NULL)
|
2002-01-14 22:06:26 +01:00
|
|
|
|
return;
|
|
|
|
|
|
2002-04-09 17:15:58 -07:00
|
|
|
|
tmp.label = label;
|
|
|
|
|
slot = (struct ehl_map_entry **)
|
2002-06-04 07:11:05 +00:00
|
|
|
|
htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
|
2002-04-09 17:15:58 -07:00
|
|
|
|
if (! slot)
|
|
|
|
|
abort ();
|
[multiple changes]
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.
* integrate.c (expand_inline_function): If the inline fn uses eh
context, make sure that the current fn has one.
* toplev.c (rest_of_compilation): Call emit_eh_context.
* except.c (use_eh_context): New fn.
(get_eh_context_once): New fn.
(call_get_eh_context): New fn.
(emit_eh_context): New fn.
(get_eh_context): Call either get_eh_context_once or
call_get_eh_context, depending on what we have.
(get_dynamic_handler_chain): Call get_eh_context_once.
* except.h: Prototypes for fns above.
* optabs.c (get_eh_context_libfunc): Removed.
(init_optabs): Don't initialize it.
* expr.h (get_eh_context_libfunc): Removed.
* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.
* config/pa/pa.h (CPP_SPEC): Support for -threads.
* config/pa/pa-hpux10.h (LIB_SPEC): Ditto.
* config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
New multilib for -threads.
* config/sparc/t-sol2: Added multilibs for -threads and
made -pthreads alias to it.
* config/sparc/sol2.h (CPP_SPEC, LIB_SPEC):
Added -threads and -pthreads options.
* libgcc-thr.h: New file.
* libgcc2.c: (__get_cpp_eh_context): Removed.
(struct cpp_eh_context): Removed.
(struct eh_context): Replaced cpp_eh_context with generic language
specific pointer.
(__get_eh_info): New function.
(__throw): Check eh_context::info.
(__sjthrow): Ditto.
* libgcc2.c: Include libgcc-thr.h.
(new_eh_context, __get_eh_context,
eh_pthread_initialize, eh_context_initialize, eh_context_static,
eh_context_specific, eh_context_free): New functions.
(get_eh_context, eh_context_key): New variables.
(__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use
get_eh_context to get the context.
(longjmp): Move the declaration inside
#ifdef DONT_USE_BUILTIN_SETJMP.
* frame.c: Include libgcc-thr.h.
(object_mutex): Mutex to protect the object list.
(find_fde, __register_frame, __register_frame_table,
__deregister_frame): Hold the lock while accessing objects.
* except.h (get_eh_context): Declare.
* except.c (current_function_ehc): Define.
(current_function_dhc, current_function_dcc): Removed.
(get_eh_context): New function.
(get_dynamic_handler_chain): Use get_eh_context.
(get_saved_pc_ref): Ditto.
(get_dynamic_cleanup_chain): Removed references to
current_function_dcc.
(save_eh_status, restore_eh_status): Save and restore
current_function_ehc instead.
* optabs.c (get_eh_context_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_eh_context_libfunc.
* function.h (struct function): Replaced dhc and dcc with ehc.
* except.c (get_saved_pc_ref): New functions.
(eh_saved_pc_rtx, eh_saved_pc): Deleted.
(expand_internal_throw_indirect): Use get_saved_pc_ref() instead
of eh_saved_pc.
(end_eh_unwinder): Likewise.
(init_eh): Remove initialization of eh_saved_pc.
* optabs.c (get_saved_pc_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_saved_pc_libfunc.
* except.h (eh_saved_pc_rtx): Deleted.
(get_saved_pc_ref): Declared.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* libgcc2.c (__get_saved_pc): New.
(__eh_type, __eh_pc): Deleted.
(__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc.
(__get_dynamic_handler_chain): Move __dynamic_handler_chain inside
this fcn.
cp/:
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.
(init_decl_processing): Initialize it.
* cp-tree.h: Declare it.
* exception.cc (__cp_exception_info): Use __get_eh_info.
(__cp_push_exception): Ditto.
(__cp_pop_exception): Ditto.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
saved_pc.
(init_exception_processing): Removed saved_pc initialization.
From-SVN: r17052
1997-12-12 04:53:20 +00:00
|
|
|
|
|
2002-06-04 07:11:05 +00:00
|
|
|
|
htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
|
[multiple changes]
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.
* integrate.c (expand_inline_function): If the inline fn uses eh
context, make sure that the current fn has one.
* toplev.c (rest_of_compilation): Call emit_eh_context.
* except.c (use_eh_context): New fn.
(get_eh_context_once): New fn.
(call_get_eh_context): New fn.
(emit_eh_context): New fn.
(get_eh_context): Call either get_eh_context_once or
call_get_eh_context, depending on what we have.
(get_dynamic_handler_chain): Call get_eh_context_once.
* except.h: Prototypes for fns above.
* optabs.c (get_eh_context_libfunc): Removed.
(init_optabs): Don't initialize it.
* expr.h (get_eh_context_libfunc): Removed.
* rtl.h, rtl.c: New reg_note REG_EH_CONTEXT.
* config/pa/pa.h (CPP_SPEC): Support for -threads.
* config/pa/pa-hpux10.h (LIB_SPEC): Ditto.
* config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
New multilib for -threads.
* config/sparc/t-sol2: Added multilibs for -threads and
made -pthreads alias to it.
* config/sparc/sol2.h (CPP_SPEC, LIB_SPEC):
Added -threads and -pthreads options.
* libgcc-thr.h: New file.
* libgcc2.c: (__get_cpp_eh_context): Removed.
(struct cpp_eh_context): Removed.
(struct eh_context): Replaced cpp_eh_context with generic language
specific pointer.
(__get_eh_info): New function.
(__throw): Check eh_context::info.
(__sjthrow): Ditto.
* libgcc2.c: Include libgcc-thr.h.
(new_eh_context, __get_eh_context,
eh_pthread_initialize, eh_context_initialize, eh_context_static,
eh_context_specific, eh_context_free): New functions.
(get_eh_context, eh_context_key): New variables.
(__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use
get_eh_context to get the context.
(longjmp): Move the declaration inside
#ifdef DONT_USE_BUILTIN_SETJMP.
* frame.c: Include libgcc-thr.h.
(object_mutex): Mutex to protect the object list.
(find_fde, __register_frame, __register_frame_table,
__deregister_frame): Hold the lock while accessing objects.
* except.h (get_eh_context): Declare.
* except.c (current_function_ehc): Define.
(current_function_dhc, current_function_dcc): Removed.
(get_eh_context): New function.
(get_dynamic_handler_chain): Use get_eh_context.
(get_saved_pc_ref): Ditto.
(get_dynamic_cleanup_chain): Removed references to
current_function_dcc.
(save_eh_status, restore_eh_status): Save and restore
current_function_ehc instead.
* optabs.c (get_eh_context_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_eh_context_libfunc.
* function.h (struct function): Replaced dhc and dcc with ehc.
* except.c (get_saved_pc_ref): New functions.
(eh_saved_pc_rtx, eh_saved_pc): Deleted.
(expand_internal_throw_indirect): Use get_saved_pc_ref() instead
of eh_saved_pc.
(end_eh_unwinder): Likewise.
(init_eh): Remove initialization of eh_saved_pc.
* optabs.c (get_saved_pc_libfunc): New variable.
(init_optabs): Initialize it.
* expr.h: Declare get_saved_pc_libfunc.
* except.h (eh_saved_pc_rtx): Deleted.
(get_saved_pc_ref): Declared.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* libgcc2.c (__get_saved_pc): New.
(__eh_type, __eh_pc): Deleted.
(__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc.
(__get_dynamic_handler_chain): Move __dynamic_handler_chain inside
this fcn.
cp/:
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.
(init_decl_processing): Initialize it.
* cp-tree.h: Declare it.
* exception.cc (__cp_exception_info): Use __get_eh_info.
(__cp_push_exception): Ditto.
(__cp_pop_exception): Ditto.
From Scott Snyder <snyder@d0sgif.fnal.gov>:
* except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
saved_pc.
(init_exception_processing): Removed saved_pc initialization.
From-SVN: r17052
1997-12-12 04:53:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Splice REGION from the region tree etc. */
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2000-05-11 16:20:31 +02:00
|
|
|
|
static void
|
2001-03-28 03:04:51 -08:00
|
|
|
|
remove_eh_handler (region)
|
|
|
|
|
struct eh_region *region;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2002-04-16 18:52:38 -07:00
|
|
|
|
struct eh_region **pp, **pp_start, *p, *outer, *inner;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx lab;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* For the benefit of efficiently handling REG_EH_REGION notes,
|
|
|
|
|
replace this region in the region array with its containing
|
|
|
|
|
region. Note that previous region deletions may result in
|
2002-04-09 17:15:58 -07:00
|
|
|
|
multiple copies of this region in the array, so we have a
|
|
|
|
|
list of alternate numbers by which we are known. */
|
|
|
|
|
|
2002-04-16 18:52:38 -07:00
|
|
|
|
outer = region->outer;
|
|
|
|
|
cfun->eh->region_array[region->region_number] = outer;
|
2002-04-09 17:15:58 -07:00
|
|
|
|
if (region->aka)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i,
|
2002-04-16 18:52:38 -07:00
|
|
|
|
{ cfun->eh->region_array[i] = outer; });
|
2002-04-09 17:15:58 -07:00
|
|
|
|
}
|
|
|
|
|
|
2002-04-16 18:52:38 -07:00
|
|
|
|
if (outer)
|
2002-04-09 17:15:58 -07:00
|
|
|
|
{
|
2002-04-16 18:52:38 -07:00
|
|
|
|
if (!outer->aka)
|
2002-06-04 07:11:05 +00:00
|
|
|
|
outer->aka = BITMAP_GGC_ALLOC ();
|
2002-04-09 17:15:58 -07:00
|
|
|
|
if (region->aka)
|
2002-04-16 18:52:38 -07:00
|
|
|
|
bitmap_a_or_b (outer->aka, outer->aka, region->aka);
|
|
|
|
|
bitmap_set_bit (outer->aka, region->region_number);
|
2002-04-09 17:15:58 -07:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
if (cfun->eh->built_landing_pads)
|
|
|
|
|
lab = region->landing_pad;
|
|
|
|
|
else
|
|
|
|
|
lab = region->label;
|
|
|
|
|
if (lab)
|
|
|
|
|
remove_exception_handler_label (lab);
|
|
|
|
|
|
2002-04-16 18:52:38 -07:00
|
|
|
|
if (outer)
|
|
|
|
|
pp_start = &outer->inner;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
else
|
2002-04-16 18:52:38 -07:00
|
|
|
|
pp_start = &cfun->eh->region_tree;
|
|
|
|
|
for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
|
2001-03-28 03:04:51 -08:00
|
|
|
|
continue;
|
2002-04-16 18:52:38 -07:00
|
|
|
|
*pp = region->next_peer;
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2002-04-16 18:52:38 -07:00
|
|
|
|
inner = region->inner;
|
|
|
|
|
if (inner)
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2002-04-16 18:52:38 -07:00
|
|
|
|
for (p = inner; p->next_peer ; p = p->next_peer)
|
|
|
|
|
p->outer = outer;
|
|
|
|
|
p->outer = outer;
|
|
|
|
|
|
|
|
|
|
p->next_peer = *pp_start;
|
|
|
|
|
*pp_start = inner;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
2000-05-11 16:20:31 +02:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (region->type == ERT_CATCH)
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *try, *next, *prev;
|
2000-05-11 16:20:31 +02:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (try = region->next_peer;
|
|
|
|
|
try->type == ERT_CATCH;
|
|
|
|
|
try = try->next_peer)
|
|
|
|
|
continue;
|
|
|
|
|
if (try->type != ERT_TRY)
|
|
|
|
|
abort ();
|
2000-05-11 16:20:31 +02:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
next = region->u.catch.next_catch;
|
|
|
|
|
prev = region->u.catch.prev_catch;
|
2000-05-11 16:20:31 +02:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (next)
|
|
|
|
|
next->u.catch.prev_catch = prev;
|
|
|
|
|
else
|
|
|
|
|
try->u.try.last_catch = prev;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->u.catch.next_catch = next;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
try->u.try.catch = next;
|
|
|
|
|
if (! next)
|
|
|
|
|
remove_eh_handler (try);
|
|
|
|
|
}
|
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* LABEL heads a basic block that is about to be deleted. If this
|
|
|
|
|
label corresponds to an exception region, we may be able to
|
|
|
|
|
delete the region. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
|
|
|
|
void
|
2001-03-28 03:04:51 -08:00
|
|
|
|
maybe_remove_eh_handler (label)
|
|
|
|
|
rtx label;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2002-04-09 17:15:58 -07:00
|
|
|
|
struct ehl_map_entry **slot, tmp;
|
|
|
|
|
struct eh_region *region;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* ??? After generating landing pads, it's not so simple to determine
|
|
|
|
|
if the region data is completely unused. One must examine the
|
|
|
|
|
landing pad and the post landing pad, and whether an inner try block
|
|
|
|
|
is referencing the catch handlers directly. */
|
|
|
|
|
if (cfun->eh->built_landing_pads)
|
1996-07-23 20:20:04 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2002-04-09 17:15:58 -07:00
|
|
|
|
tmp.label = label;
|
|
|
|
|
slot = (struct ehl_map_entry **)
|
2002-06-04 07:11:05 +00:00
|
|
|
|
htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
|
2002-04-09 17:15:58 -07:00
|
|
|
|
if (! slot)
|
|
|
|
|
return;
|
|
|
|
|
region = (*slot)->region;
|
|
|
|
|
if (! region)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Flow will want to remove MUST_NOT_THROW regions as unreachable
|
|
|
|
|
because there is no path to the fallback call to terminate.
|
|
|
|
|
But the region continues to affect call-site data until there
|
|
|
|
|
are no more contained calls, which we don't see here. */
|
|
|
|
|
if (region->type == ERT_MUST_NOT_THROW)
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
{
|
2002-06-04 07:11:05 +00:00
|
|
|
|
htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
|
2002-04-09 17:15:58 -07:00
|
|
|
|
region->label = NULL_RTX;
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
}
|
2002-04-09 17:15:58 -07:00
|
|
|
|
else
|
|
|
|
|
remove_eh_handler (region);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Invokes CALLBACK for every exception handler label. Only used by old
|
|
|
|
|
loop hackery; should not be used by new code. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
for_each_eh_label (callback)
|
|
|
|
|
void (*callback) PARAMS ((rtx));
|
|
|
|
|
{
|
2002-06-04 07:11:05 +00:00
|
|
|
|
htab_traverse (cfun->eh->exception_handler_label_map, for_each_eh_label_1,
|
2002-04-09 17:15:58 -07:00
|
|
|
|
(void *)callback);
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
}
|
|
|
|
|
|
2002-04-09 17:15:58 -07:00
|
|
|
|
static int
|
|
|
|
|
for_each_eh_label_1 (pentry, data)
|
|
|
|
|
PTR *pentry;
|
|
|
|
|
PTR data;
|
|
|
|
|
{
|
|
|
|
|
struct ehl_map_entry *entry = *(struct ehl_map_entry **)pentry;
|
|
|
|
|
void (*callback) PARAMS ((rtx)) = (void (*) PARAMS ((rtx))) data;
|
|
|
|
|
|
|
|
|
|
(*callback) (entry->label);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* This section describes CFG exception edges for flow. */
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* For communicating between calls to reachable_next_level. */
|
2002-06-04 07:11:05 +00:00
|
|
|
|
struct reachable_info GTY(())
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
tree types_caught;
|
|
|
|
|
tree types_allowed;
|
|
|
|
|
rtx handlers;
|
|
|
|
|
};
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* A subroutine of reachable_next_level. Return true if TYPE, or a
|
|
|
|
|
base class of TYPE, is in HANDLED. */
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static int
|
|
|
|
|
check_handled (handled, type)
|
|
|
|
|
tree handled, type;
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
tree t;
|
|
|
|
|
|
|
|
|
|
/* We can check for exact matches without front-end help. */
|
|
|
|
|
if (! lang_eh_type_covers)
|
1999-12-12 18:32:36 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (t = handled; t ; t = TREE_CHAIN (t))
|
|
|
|
|
if (TREE_VALUE (t) == type)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (t = handled; t ; t = TREE_CHAIN (t))
|
|
|
|
|
if ((*lang_eh_type_covers) (TREE_VALUE (t), type))
|
|
|
|
|
return 1;
|
1999-12-12 18:32:36 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
return 0;
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* A subroutine of reachable_next_level. If we are collecting a list
|
|
|
|
|
of handlers, add one. After landing pad generation, reference
|
|
|
|
|
it instead of the handlers themselves. Further, the handlers are
|
2001-12-12 09:27:29 +01:00
|
|
|
|
all wired together, so by referencing one, we've got them all.
|
2001-03-28 03:04:51 -08:00
|
|
|
|
Before landing pad generation we reference each handler individually.
|
|
|
|
|
|
|
|
|
|
LP_REGION contains the landing pad; REGION is the handler. */
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
|
|
|
|
|
static void
|
2001-03-28 03:04:51 -08:00
|
|
|
|
add_reachable_handler (info, lp_region, region)
|
|
|
|
|
struct reachable_info *info;
|
|
|
|
|
struct eh_region *lp_region;
|
|
|
|
|
struct eh_region *region;
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! info)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (cfun->eh->built_landing_pads)
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! info->handlers)
|
|
|
|
|
info->handlers = alloc_INSN_LIST (lp_region->landing_pad, NULL_RTX);
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
else
|
|
|
|
|
info->handlers = alloc_INSN_LIST (region->label, info->handlers);
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
}
|
|
|
|
|
|
2001-12-12 09:27:29 +01:00
|
|
|
|
/* Process one level of exception regions for reachability.
|
2001-03-28 03:04:51 -08:00
|
|
|
|
If TYPE_THROWN is non-null, then it is the *exact* type being
|
|
|
|
|
propagated. If INFO is non-null, then collect handler labels
|
|
|
|
|
and caught/allowed type information between invocations. */
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static enum reachable_code
|
|
|
|
|
reachable_next_level (region, type_thrown, info)
|
|
|
|
|
struct eh_region *region;
|
|
|
|
|
tree type_thrown;
|
|
|
|
|
struct reachable_info *info;
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
switch (region->type)
|
|
|
|
|
{
|
|
|
|
|
case ERT_CLEANUP:
|
|
|
|
|
/* Before landing-pad generation, we model control flow
|
|
|
|
|
directly to the individual handlers. In this way we can
|
|
|
|
|
see that catch handler types may shadow one another. */
|
|
|
|
|
add_reachable_handler (info, region, region);
|
|
|
|
|
return RNL_MAYBE_CAUGHT;
|
|
|
|
|
|
|
|
|
|
case ERT_TRY:
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *c;
|
|
|
|
|
enum reachable_code ret = RNL_NOT_CAUGHT;
|
1999-09-15 18:12:25 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
|
|
|
|
|
{
|
|
|
|
|
/* A catch-all handler ends the search. */
|
2001-11-16 13:48:18 +01:00
|
|
|
|
if (c->u.catch.type_list == NULL)
|
2001-03-28 03:04:51 -08:00
|
|
|
|
{
|
|
|
|
|
add_reachable_handler (info, region, c);
|
|
|
|
|
return RNL_CAUGHT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type_thrown)
|
|
|
|
|
{
|
2002-01-03 00:53:36 +00:00
|
|
|
|
/* If we have at least one type match, end the search. */
|
2001-11-16 13:48:18 +01:00
|
|
|
|
tree tp_node = c->u.catch.type_list;
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
for (; tp_node; tp_node = TREE_CHAIN (tp_node))
|
2001-03-28 03:04:51 -08:00
|
|
|
|
{
|
2001-11-16 13:48:18 +01:00
|
|
|
|
tree type = TREE_VALUE (tp_node);
|
|
|
|
|
|
|
|
|
|
if (type == type_thrown
|
|
|
|
|
|| (lang_eh_type_covers
|
|
|
|
|
&& (*lang_eh_type_covers) (type, type_thrown)))
|
|
|
|
|
{
|
|
|
|
|
add_reachable_handler (info, region, c);
|
|
|
|
|
return RNL_CAUGHT;
|
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If we have definitive information of a match failure,
|
|
|
|
|
the catch won't trigger. */
|
|
|
|
|
if (lang_eh_type_covers)
|
|
|
|
|
return RNL_NOT_CAUGHT;
|
|
|
|
|
}
|
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
/* At this point, we either don't know what type is thrown or
|
|
|
|
|
don't have front-end assistance to help deciding if it is
|
|
|
|
|
covered by one of the types in the list for this region.
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
We'd then like to add this region to the list of reachable
|
|
|
|
|
handlers since it is indeed potentially reachable based on the
|
2001-12-12 09:27:29 +01:00
|
|
|
|
information we have.
|
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
Actually, this handler is for sure not reachable if all the
|
|
|
|
|
types it matches have already been caught. That is, it is only
|
|
|
|
|
potentially reachable if at least one of the types it catches
|
|
|
|
|
has not been previously caught. */
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! info)
|
|
|
|
|
ret = RNL_MAYBE_CAUGHT;
|
2001-11-16 13:48:18 +01:00
|
|
|
|
else
|
2001-03-28 03:04:51 -08:00
|
|
|
|
{
|
2001-11-16 13:48:18 +01:00
|
|
|
|
tree tp_node = c->u.catch.type_list;
|
|
|
|
|
bool maybe_reachable = false;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
/* Compute the potential reachability of this handler and
|
|
|
|
|
update the list of types caught at the same time. */
|
|
|
|
|
for (; tp_node; tp_node = TREE_CHAIN (tp_node))
|
|
|
|
|
{
|
|
|
|
|
tree type = TREE_VALUE (tp_node);
|
|
|
|
|
|
|
|
|
|
if (! check_handled (info->types_caught, type))
|
|
|
|
|
{
|
|
|
|
|
info->types_caught
|
|
|
|
|
= tree_cons (NULL, type, info->types_caught);
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
maybe_reachable = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
if (maybe_reachable)
|
|
|
|
|
{
|
|
|
|
|
add_reachable_handler (info, region, c);
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
/* ??? If the catch type is a base class of every allowed
|
|
|
|
|
type, then we know we can stop the search. */
|
|
|
|
|
ret = RNL_MAYBE_CAUGHT;
|
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return ret;
|
|
|
|
|
}
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_ALLOWED_EXCEPTIONS:
|
|
|
|
|
/* An empty list of types definitely ends the search. */
|
|
|
|
|
if (region->u.allowed.type_list == NULL_TREE)
|
|
|
|
|
{
|
|
|
|
|
add_reachable_handler (info, region, region);
|
|
|
|
|
return RNL_CAUGHT;
|
|
|
|
|
}
|
Makefile.in (tree.o): Depend on ggc.h.
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119
1999-09-04 19:41:35 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Collect a list of lists of allowed types for use in detecting
|
|
|
|
|
when a catch may be transformed into a catch-all. */
|
|
|
|
|
if (info)
|
|
|
|
|
info->types_allowed = tree_cons (NULL_TREE,
|
|
|
|
|
region->u.allowed.type_list,
|
|
|
|
|
info->types_allowed);
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
ChangeLog.2, [...]: Fix spelling errors and typos.
* ChangeLog.2, ChangeLog.3, ChangeLog.4, FSFChangeLog.10,
FSFChangeLog.11, c-common.c, c-common.def, c-common.h, c-decl.c,
c-dump.c, c-typeck.c, except.c, sdbout.c, simplify-rtx.c,
timevar.h, tree.h, varasm.c: Fix spelling errors and typos.
From-SVN: r46621
2001-10-29 23:01:45 +00:00
|
|
|
|
/* If we have definitive information about the type hierarchy,
|
2001-03-28 03:04:51 -08:00
|
|
|
|
then we can tell if the thrown type will pass through the
|
|
|
|
|
filter. */
|
|
|
|
|
if (type_thrown && lang_eh_type_covers)
|
|
|
|
|
{
|
|
|
|
|
if (check_handled (region->u.allowed.type_list, type_thrown))
|
|
|
|
|
return RNL_NOT_CAUGHT;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
add_reachable_handler (info, region, region);
|
|
|
|
|
return RNL_CAUGHT;
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-09-07 15:20:58 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
add_reachable_handler (info, region, region);
|
|
|
|
|
return RNL_MAYBE_CAUGHT;
|
1999-09-07 15:20:58 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_CATCH:
|
2003-01-17 14:24:24 +00:00
|
|
|
|
/* Catch regions are handled by their controlling try region. */
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return RNL_NOT_CAUGHT;
|
1999-09-07 15:20:58 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_MUST_NOT_THROW:
|
|
|
|
|
/* Here we end our search, since no exceptions may propagate.
|
|
|
|
|
If we've touched down at some landing pad previous, then the
|
|
|
|
|
explicit function call we generated may be used. Otherwise
|
|
|
|
|
the call is made by the runtime. */
|
|
|
|
|
if (info && info->handlers)
|
1999-09-07 15:20:58 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
add_reachable_handler (info, region, region);
|
2002-06-03 01:13:17 +00:00
|
|
|
|
return RNL_CAUGHT;
|
1999-09-07 15:20:58 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
else
|
|
|
|
|
return RNL_BLOCKED;
|
1999-09-07 15:20:58 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_THROW:
|
|
|
|
|
case ERT_FIXUP:
|
2001-12-12 09:27:29 +01:00
|
|
|
|
case ERT_UNKNOWN:
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Shouldn't see these here. */
|
|
|
|
|
break;
|
1999-09-07 15:20:58 +00:00
|
|
|
|
}
|
1999-09-15 18:12:25 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
abort ();
|
1999-09-15 18:12:25 -07:00
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Retrieve a list of labels of exception handlers which can be
|
|
|
|
|
reached by a given insn. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx
|
|
|
|
|
reachable_handlers (insn)
|
1996-07-23 20:20:04 +00:00
|
|
|
|
rtx insn;
|
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct reachable_info info;
|
|
|
|
|
struct eh_region *region;
|
|
|
|
|
tree type_thrown;
|
|
|
|
|
int region_number;
|
2000-03-09 14:01:47 -05:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (GET_CODE (insn) == JUMP_INSN
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) == RESX)
|
|
|
|
|
region_number = XINT (PATTERN (insn), 0);
|
|
|
|
|
else
|
1999-08-10 16:19:16 +00:00
|
|
|
|
{
|
|
|
|
|
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (!note || INTVAL (XEXP (note, 0)) <= 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
region_number = INTVAL (XEXP (note, 0));
|
1997-04-23 20:11:52 +00:00
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
memset (&info, 0, sizeof (info));
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
region = cfun->eh->region_array[region_number];
|
2000-03-09 14:01:47 -05:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
type_thrown = NULL_TREE;
|
2001-07-25 12:59:39 -07:00
|
|
|
|
if (GET_CODE (insn) == JUMP_INSN
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) == RESX)
|
|
|
|
|
{
|
|
|
|
|
/* A RESX leaves a region instead of entering it. Thus the
|
|
|
|
|
region itself may have been deleted out from under us. */
|
|
|
|
|
if (region == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
region = region->outer;
|
|
|
|
|
}
|
|
|
|
|
else if (region->type == ERT_THROW)
|
2001-03-28 03:04:51 -08:00
|
|
|
|
{
|
|
|
|
|
type_thrown = region->u.throw.type;
|
|
|
|
|
region = region->outer;
|
|
|
|
|
}
|
2000-03-09 20:37:06 +00:00
|
|
|
|
|
2003-03-17 06:09:30 +00:00
|
|
|
|
while (region)
|
|
|
|
|
{
|
|
|
|
|
if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
|
2003-05-07 15:11:38 -07:00
|
|
|
|
break;
|
2003-03-17 06:09:30 +00:00
|
|
|
|
/* If we have processed one cleanup, there is no point in
|
|
|
|
|
processing any more of them. Each cleanup will have an edge
|
|
|
|
|
to the next outer cleanup region, so the flow graph will be
|
|
|
|
|
accurate. */
|
|
|
|
|
if (region->type == ERT_CLEANUP)
|
|
|
|
|
region = region->u.cleanup.prev_try;
|
|
|
|
|
else
|
|
|
|
|
region = region->outer;
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return info.handlers;
|
2000-03-09 14:01:47 -05:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Determine if the given INSN can throw an exception that is caught
|
|
|
|
|
within the function. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
bool
|
|
|
|
|
can_throw_internal (insn)
|
1996-07-23 20:20:04 +00:00
|
|
|
|
rtx insn;
|
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *region;
|
|
|
|
|
tree type_thrown;
|
|
|
|
|
rtx note;
|
1998-12-08 14:04:03 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! INSN_P (insn))
|
|
|
|
|
return false;
|
1996-09-14 20:47:01 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (GET_CODE (insn) == INSN
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
|
|
|
|
|
insn = XVECEXP (PATTERN (insn), 0, 0);
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (GET_CODE (insn) == CALL_INSN
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < 3; ++i)
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx sub = XEXP (PATTERN (insn), i);
|
|
|
|
|
for (; sub ; sub = NEXT_INSN (sub))
|
|
|
|
|
if (can_throw_internal (sub))
|
|
|
|
|
return true;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return false;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Every insn that might throw has an EH_REGION note. */
|
|
|
|
|
note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
|
|
|
|
|
if (!note || INTVAL (XEXP (note, 0)) <= 0)
|
|
|
|
|
return false;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
type_thrown = NULL_TREE;
|
|
|
|
|
if (region->type == ERT_THROW)
|
|
|
|
|
{
|
|
|
|
|
type_thrown = region->u.throw.type;
|
|
|
|
|
region = region->outer;
|
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* If this exception is ignored by each and every containing region,
|
|
|
|
|
then control passes straight out. The runtime may handle some
|
|
|
|
|
regions, which also do not require processing internally. */
|
|
|
|
|
for (; region; region = region->outer)
|
|
|
|
|
{
|
|
|
|
|
enum reachable_code how = reachable_next_level (region, type_thrown, 0);
|
|
|
|
|
if (how == RNL_BLOCKED)
|
|
|
|
|
return false;
|
|
|
|
|
if (how != RNL_NOT_CAUGHT)
|
2002-06-03 01:13:17 +00:00
|
|
|
|
return true;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Determine if the given INSN can throw an exception that is
|
|
|
|
|
visible outside the function. */
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
bool
|
|
|
|
|
can_throw_external (insn)
|
|
|
|
|
rtx insn;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *region;
|
|
|
|
|
tree type_thrown;
|
|
|
|
|
rtx note;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! INSN_P (insn))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (insn) == INSN
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
|
|
|
|
|
insn = XVECEXP (PATTERN (insn), 0, 0);
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (insn) == CALL_INSN
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < 3; ++i)
|
1996-07-23 20:20:04 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx sub = XEXP (PATTERN (insn), i);
|
|
|
|
|
for (; sub ; sub = NEXT_INSN (sub))
|
|
|
|
|
if (can_throw_external (sub))
|
|
|
|
|
return true;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return false;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
|
|
|
|
|
if (!note)
|
|
|
|
|
{
|
|
|
|
|
/* Calls (and trapping insns) without notes are outside any
|
|
|
|
|
exception handling region in this function. We have to
|
|
|
|
|
assume it might throw. Given that the front end and middle
|
|
|
|
|
ends mark known NOTHROW functions, this isn't so wildly
|
|
|
|
|
inaccurate. */
|
|
|
|
|
return (GET_CODE (insn) == CALL_INSN
|
|
|
|
|
|| (flag_non_call_exceptions
|
|
|
|
|
&& may_trap_p (PATTERN (insn))));
|
|
|
|
|
}
|
|
|
|
|
if (INTVAL (XEXP (note, 0)) <= 0)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
|
|
|
|
|
|
|
|
|
|
type_thrown = NULL_TREE;
|
|
|
|
|
if (region->type == ERT_THROW)
|
|
|
|
|
{
|
|
|
|
|
type_thrown = region->u.throw.type;
|
|
|
|
|
region = region->outer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If the exception is caught or blocked by any containing region,
|
|
|
|
|
then it is not seen by any calling function. */
|
|
|
|
|
for (; region ; region = region->outer)
|
|
|
|
|
if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
1996-07-23 20:20:04 +00:00
|
|
|
|
}
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2002-08-25 05:21:11 +00:00
|
|
|
|
/* Set current_function_nothrow and cfun->all_throwers_are_sibcalls. */
|
2000-03-08 16:30:17 -05:00
|
|
|
|
|
2002-08-25 05:21:11 +00:00
|
|
|
|
void
|
|
|
|
|
set_nothrow_function_flags ()
|
1999-08-10 16:19:16 +00:00
|
|
|
|
{
|
|
|
|
|
rtx insn;
|
2002-08-25 05:21:11 +00:00
|
|
|
|
|
|
|
|
|
current_function_nothrow = 1;
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2002-08-25 05:21:11 +00:00
|
|
|
|
/* Assume cfun->all_throwers_are_sibcalls until we encounter
|
|
|
|
|
something that can throw an exception. We specifically exempt
|
|
|
|
|
CALL_INSNs that are SIBLING_CALL_P, as these are really jumps,
|
|
|
|
|
and can't throw. Most CALL_INSNs are not SIBLING_CALL_P, so this
|
|
|
|
|
is optimistic. */
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2002-08-25 05:21:11 +00:00
|
|
|
|
cfun->all_throwers_are_sibcalls = 1;
|
|
|
|
|
|
|
|
|
|
if (! flag_exceptions)
|
|
|
|
|
return;
|
|
|
|
|
|
1999-08-10 16:19:16 +00:00
|
|
|
|
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (can_throw_external (insn))
|
2002-08-25 05:21:11 +00:00
|
|
|
|
{
|
|
|
|
|
current_function_nothrow = 0;
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn))
|
|
|
|
|
{
|
|
|
|
|
cfun->all_throwers_are_sibcalls = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (insn = current_function_epilogue_delay_list; insn;
|
|
|
|
|
insn = XEXP (insn, 1))
|
2002-08-25 05:21:11 +00:00
|
|
|
|
if (can_throw_external (insn))
|
|
|
|
|
{
|
|
|
|
|
current_function_nothrow = 0;
|
1999-11-08 04:56:18 +00:00
|
|
|
|
|
2002-08-25 05:21:11 +00:00
|
|
|
|
if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn))
|
|
|
|
|
{
|
|
|
|
|
cfun->all_throwers_are_sibcalls = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-08-10 16:19:16 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
1997-09-15 22:07:50 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Various hooks for unwind library. */
|
1997-09-15 22:07:50 -04:00
|
|
|
|
|
|
|
|
|
/* Do any necessary initialization to access arbitrary stack frames.
|
|
|
|
|
On the SPARC, this means flushing the register windows. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
expand_builtin_unwind_init ()
|
|
|
|
|
{
|
|
|
|
|
/* Set this so all the registers get saved in our frame; we need to be
|
2001-08-08 22:06:48 +00:00
|
|
|
|
able to copy the saved values for any registers from frames we unwind. */
|
1997-09-15 22:07:50 -04:00
|
|
|
|
current_function_has_nonlocal_label = 1;
|
|
|
|
|
|
|
|
|
|
#ifdef SETUP_FRAME_ADDRESSES
|
|
|
|
|
SETUP_FRAME_ADDRESSES ();
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx
|
|
|
|
|
expand_builtin_eh_return_data_regno (arglist)
|
|
|
|
|
tree arglist;
|
|
|
|
|
{
|
|
|
|
|
tree which = TREE_VALUE (arglist);
|
|
|
|
|
unsigned HOST_WIDE_INT iwhich;
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (which) != INTEGER_CST)
|
|
|
|
|
{
|
|
|
|
|
error ("argument of `__builtin_eh_return_regno' must be constant");
|
|
|
|
|
return constm1_rtx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iwhich = tree_low_cst (which, 1);
|
|
|
|
|
iwhich = EH_RETURN_DATA_REGNO (iwhich);
|
|
|
|
|
if (iwhich == INVALID_REGNUM)
|
|
|
|
|
return constm1_rtx;
|
|
|
|
|
|
|
|
|
|
#ifdef DWARF_FRAME_REGNUM
|
|
|
|
|
iwhich = DWARF_FRAME_REGNUM (iwhich);
|
|
|
|
|
#else
|
|
|
|
|
iwhich = DBX_REGISTER_NUMBER (iwhich);
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-12-12 09:27:29 +01:00
|
|
|
|
return GEN_INT (iwhich);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
|
|
|
|
|
1997-09-15 22:07:50 -04:00
|
|
|
|
/* Given a value extracted from the return address register or stack slot,
|
|
|
|
|
return the actual address encoded in that value. */
|
|
|
|
|
|
|
|
|
|
rtx
|
|
|
|
|
expand_builtin_extract_return_addr (addr_tree)
|
|
|
|
|
tree addr_tree;
|
|
|
|
|
{
|
|
|
|
|
rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
2002-09-26 21:39:14 +00:00
|
|
|
|
if (GET_MODE (addr) != Pmode
|
|
|
|
|
&& GET_MODE (addr) != VOIDmode)
|
|
|
|
|
{
|
|
|
|
|
#ifdef POINTERS_EXTEND_UNSIGNED
|
|
|
|
|
addr = convert_memory_address (Pmode, addr);
|
|
|
|
|
#else
|
|
|
|
|
addr = convert_to_mode (Pmode, addr, 0);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* First mask out any unwanted bits. */
|
|
|
|
|
#ifdef MASK_RETURN_ADDR
|
2002-02-21 22:11:08 +01:00
|
|
|
|
expand_and (Pmode, addr, MASK_RETURN_ADDR, addr);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Then adjust to find the real return address. */
|
|
|
|
|
#if defined (RETURN_ADDR_OFFSET)
|
|
|
|
|
addr = plus_constant (addr, RETURN_ADDR_OFFSET);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return addr;
|
1997-09-15 22:07:50 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Given an actual address in addr_tree, do any necessary encoding
|
|
|
|
|
and return the value to be stored in the return address register or
|
|
|
|
|
stack slot so the epilogue will return to that address. */
|
|
|
|
|
|
|
|
|
|
rtx
|
|
|
|
|
expand_builtin_frob_return_addr (addr_tree)
|
|
|
|
|
tree addr_tree;
|
|
|
|
|
{
|
2001-10-23 18:59:15 -04:00
|
|
|
|
rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
2001-06-02 10:52:11 +00:00
|
|
|
|
#ifdef POINTERS_EXTEND_UNSIGNED
|
2001-10-23 18:59:15 -04:00
|
|
|
|
if (GET_MODE (addr) != Pmode)
|
|
|
|
|
addr = convert_memory_address (Pmode, addr);
|
2001-06-02 10:52:11 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
1997-09-15 22:07:50 -04:00
|
|
|
|
#ifdef RETURN_ADDR_OFFSET
|
2001-03-28 03:04:51 -08:00
|
|
|
|
addr = force_reg (Pmode, addr);
|
1997-09-15 22:07:50 -04:00
|
|
|
|
addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
|
|
|
|
|
#endif
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
1997-09-15 22:07:50 -04:00
|
|
|
|
return addr;
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Set up the epilogue with the magic bits we'll need to return to the
|
|
|
|
|
exception handler. */
|
1997-09-15 22:07:50 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
expand_builtin_eh_return (stackadj_tree, handler_tree)
|
2003-05-10 22:59:04 +00:00
|
|
|
|
tree stackadj_tree ATTRIBUTE_UNUSED;
|
|
|
|
|
tree handler_tree;
|
1997-09-15 22:07:50 -04:00
|
|
|
|
{
|
2003-05-10 22:59:04 +00:00
|
|
|
|
rtx tmp;
|
1997-09-15 22:07:50 -04:00
|
|
|
|
|
2003-05-10 22:59:04 +00:00
|
|
|
|
#ifdef EH_RETURN_STACKADJ_RTX
|
|
|
|
|
tmp = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0);
|
2001-06-02 10:52:11 +00:00
|
|
|
|
#ifdef POINTERS_EXTEND_UNSIGNED
|
2003-05-10 22:59:04 +00:00
|
|
|
|
if (GET_MODE (tmp) != Pmode)
|
|
|
|
|
tmp = convert_memory_address (Pmode, tmp);
|
|
|
|
|
#endif
|
|
|
|
|
if (!cfun->eh->ehr_stackadj)
|
|
|
|
|
cfun->eh->ehr_stackadj = copy_to_reg (tmp);
|
|
|
|
|
else if (tmp != cfun->eh->ehr_stackadj)
|
|
|
|
|
emit_move_insn (cfun->eh->ehr_stackadj, tmp);
|
2001-06-02 10:52:11 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2003-05-10 22:59:04 +00:00
|
|
|
|
tmp = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0);
|
|
|
|
|
#ifdef POINTERS_EXTEND_UNSIGNED
|
|
|
|
|
if (GET_MODE (tmp) != Pmode)
|
|
|
|
|
tmp = convert_memory_address (Pmode, tmp);
|
|
|
|
|
#endif
|
|
|
|
|
if (!cfun->eh->ehr_handler)
|
|
|
|
|
cfun->eh->ehr_handler = copy_to_reg (tmp);
|
|
|
|
|
else if (tmp != cfun->eh->ehr_handler)
|
|
|
|
|
emit_move_insn (cfun->eh->ehr_handler, tmp);
|
1997-09-15 22:07:50 -04:00
|
|
|
|
|
2003-05-10 22:59:04 +00:00
|
|
|
|
if (!cfun->eh->ehr_label)
|
|
|
|
|
cfun->eh->ehr_label = gen_label_rtx ();
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_jump (cfun->eh->ehr_label);
|
1998-06-08 12:43:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused.
* tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused. Kill.
(BUILT_IN_FP, BUILT_IN_SP, BUILT_IN_SET_RETURN_ADDR_REG): Kill.
(BUILT_IN_EH_STUB_OLD, BUILT_IN_EH_STUB, BUILT_IN_SET_EH_REGS): Kill.
(BUILT_IN_EH_RETURN, BUILT_IN_DWARF_CFA): New.
* c-decl.c (init_decl_processing): Update accordingly.
* expr.c (expand_builtin): Likewise.
* cp/decl.c (init_decl_processing): Likewise.
* rtl.h (global_rtl): Add cfa entry.
(virtual_cfa_rtx, VIRTUAL_CFA_REGNUM): New.
(LAST_VIRTUAL_REGISTER): Update.
* emit-rtl.c (global_rtl): Add cfa entry.
(init_emit): Initialize it.
* function.c (cfa_offset): New.
(instantiate_virtual_regs): Initialize it.
(instantiate_virtual_regs_1): Instantiate virtual_cfa_rtx.
(expand_function_end): Call expand_eh_return.
* tm.texi (ARG_POINTER_CFA_OFFSET): New.
* except.c (current_function_eh_stub_label): Kill.
(current_function_eh_old_stub_label): Likwise; update all references.
(expand_builtin_set_return_addr_reg): Kill.
(expand_builtin_eh_stub_old, expand_builtin_eh_stub): Kill.
(expand_builtin_set_eh_regs): Kill.
(eh_regs): Produce a third reg for the actual handler address.
(eh_return_context, eh_return_stack_adjust): New.
(eh_return_handler, eh_return_stub_label): New.
(init_eh_for_function): Initialize them.
(expand_builtin_eh_return, expand_eh_return): New.
* except.h: Update prototypes.
* flow.c (find_basic_blocks_1): Update references to the stub label.
* function.h (struct function): Kill stub label elements.
* libgcc2.c (in_reg_window): For REG_SAVED_REG, check that the
register number is one that would be in the previous window.
Provide a dummy definition for non-windowed targets.
(get_reg_addr): New function.
(get_reg, put_reg, copy_reg): Use it.
(__throw): Rely on in_reg_window, not INCOMING_REGNO. Kill stub
generating code and use __builtin_eh_return. Use __builtin_dwarf_cfa.
* alpha.c (alpha_eh_epilogue_sp_ofs): New.
(alpha_init_expanders): Initialize it.
(alpha_expand_epilogue): Use it.
* alpha.h: Declare it.
* alpha.md (eh_epilogue): New.
* m68h.h (ARG_POINTER_CFA_OFFSET): New.
* sparc.h (ARG_POINTER_CFA_OFFSET): New.
From-SVN: r22436
1998-09-15 12:19:12 -07:00
|
|
|
|
void
|
|
|
|
|
expand_eh_return ()
|
1997-09-15 22:07:50 -04:00
|
|
|
|
{
|
2003-05-10 22:59:04 +00:00
|
|
|
|
rtx around_label;
|
1997-09-15 22:07:50 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (! cfun->eh->ehr_label)
|
tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused.
* tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused. Kill.
(BUILT_IN_FP, BUILT_IN_SP, BUILT_IN_SET_RETURN_ADDR_REG): Kill.
(BUILT_IN_EH_STUB_OLD, BUILT_IN_EH_STUB, BUILT_IN_SET_EH_REGS): Kill.
(BUILT_IN_EH_RETURN, BUILT_IN_DWARF_CFA): New.
* c-decl.c (init_decl_processing): Update accordingly.
* expr.c (expand_builtin): Likewise.
* cp/decl.c (init_decl_processing): Likewise.
* rtl.h (global_rtl): Add cfa entry.
(virtual_cfa_rtx, VIRTUAL_CFA_REGNUM): New.
(LAST_VIRTUAL_REGISTER): Update.
* emit-rtl.c (global_rtl): Add cfa entry.
(init_emit): Initialize it.
* function.c (cfa_offset): New.
(instantiate_virtual_regs): Initialize it.
(instantiate_virtual_regs_1): Instantiate virtual_cfa_rtx.
(expand_function_end): Call expand_eh_return.
* tm.texi (ARG_POINTER_CFA_OFFSET): New.
* except.c (current_function_eh_stub_label): Kill.
(current_function_eh_old_stub_label): Likwise; update all references.
(expand_builtin_set_return_addr_reg): Kill.
(expand_builtin_eh_stub_old, expand_builtin_eh_stub): Kill.
(expand_builtin_set_eh_regs): Kill.
(eh_regs): Produce a third reg for the actual handler address.
(eh_return_context, eh_return_stack_adjust): New.
(eh_return_handler, eh_return_stub_label): New.
(init_eh_for_function): Initialize them.
(expand_builtin_eh_return, expand_eh_return): New.
* except.h: Update prototypes.
* flow.c (find_basic_blocks_1): Update references to the stub label.
* function.h (struct function): Kill stub label elements.
* libgcc2.c (in_reg_window): For REG_SAVED_REG, check that the
register number is one that would be in the previous window.
Provide a dummy definition for non-windowed targets.
(get_reg_addr): New function.
(get_reg, put_reg, copy_reg): Use it.
(__throw): Rely on in_reg_window, not INCOMING_REGNO. Kill stub
generating code and use __builtin_eh_return. Use __builtin_dwarf_cfa.
* alpha.c (alpha_eh_epilogue_sp_ofs): New.
(alpha_init_expanders): Initialize it.
(alpha_expand_epilogue): Use it.
* alpha.h: Declare it.
* alpha.md (eh_epilogue): New.
* m68h.h (ARG_POINTER_CFA_OFFSET): New.
* sparc.h (ARG_POINTER_CFA_OFFSET): New.
From-SVN: r22436
1998-09-15 12:19:12 -07:00
|
|
|
|
return;
|
1997-09-15 22:07:50 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
current_function_calls_eh_return = 1;
|
1997-09-15 22:07:50 -04:00
|
|
|
|
|
2003-05-10 22:59:04 +00:00
|
|
|
|
#ifdef EH_RETURN_STACKADJ_RTX
|
|
|
|
|
emit_move_insn (EH_RETURN_STACKADJ_RTX, const0_rtx);
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
around_label = gen_label_rtx ();
|
|
|
|
|
emit_jump (around_label);
|
1997-09-15 22:07:50 -04:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_label (cfun->eh->ehr_label);
|
|
|
|
|
clobber_return_register ();
|
1997-09-15 22:07:50 -04:00
|
|
|
|
|
2003-05-10 22:59:04 +00:00
|
|
|
|
#ifdef EH_RETURN_STACKADJ_RTX
|
|
|
|
|
emit_move_insn (EH_RETURN_STACKADJ_RTX, cfun->eh->ehr_stackadj);
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#ifdef HAVE_eh_return
|
|
|
|
|
if (HAVE_eh_return)
|
2003-05-10 22:59:04 +00:00
|
|
|
|
emit_insn (gen_eh_return (cfun->eh->ehr_handler));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
else
|
tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused.
* tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused. Kill.
(BUILT_IN_FP, BUILT_IN_SP, BUILT_IN_SET_RETURN_ADDR_REG): Kill.
(BUILT_IN_EH_STUB_OLD, BUILT_IN_EH_STUB, BUILT_IN_SET_EH_REGS): Kill.
(BUILT_IN_EH_RETURN, BUILT_IN_DWARF_CFA): New.
* c-decl.c (init_decl_processing): Update accordingly.
* expr.c (expand_builtin): Likewise.
* cp/decl.c (init_decl_processing): Likewise.
* rtl.h (global_rtl): Add cfa entry.
(virtual_cfa_rtx, VIRTUAL_CFA_REGNUM): New.
(LAST_VIRTUAL_REGISTER): Update.
* emit-rtl.c (global_rtl): Add cfa entry.
(init_emit): Initialize it.
* function.c (cfa_offset): New.
(instantiate_virtual_regs): Initialize it.
(instantiate_virtual_regs_1): Instantiate virtual_cfa_rtx.
(expand_function_end): Call expand_eh_return.
* tm.texi (ARG_POINTER_CFA_OFFSET): New.
* except.c (current_function_eh_stub_label): Kill.
(current_function_eh_old_stub_label): Likwise; update all references.
(expand_builtin_set_return_addr_reg): Kill.
(expand_builtin_eh_stub_old, expand_builtin_eh_stub): Kill.
(expand_builtin_set_eh_regs): Kill.
(eh_regs): Produce a third reg for the actual handler address.
(eh_return_context, eh_return_stack_adjust): New.
(eh_return_handler, eh_return_stub_label): New.
(init_eh_for_function): Initialize them.
(expand_builtin_eh_return, expand_eh_return): New.
* except.h: Update prototypes.
* flow.c (find_basic_blocks_1): Update references to the stub label.
* function.h (struct function): Kill stub label elements.
* libgcc2.c (in_reg_window): For REG_SAVED_REG, check that the
register number is one that would be in the previous window.
Provide a dummy definition for non-windowed targets.
(get_reg_addr): New function.
(get_reg, put_reg, copy_reg): Use it.
(__throw): Rely on in_reg_window, not INCOMING_REGNO. Kill stub
generating code and use __builtin_eh_return. Use __builtin_dwarf_cfa.
* alpha.c (alpha_eh_epilogue_sp_ofs): New.
(alpha_init_expanders): Initialize it.
(alpha_expand_epilogue): Use it.
* alpha.h: Declare it.
* alpha.md (eh_epilogue): New.
* m68h.h (ARG_POINTER_CFA_OFFSET): New.
* sparc.h (ARG_POINTER_CFA_OFFSET): New.
From-SVN: r22436
1998-09-15 12:19:12 -07:00
|
|
|
|
#endif
|
2001-03-28 03:04:51 -08:00
|
|
|
|
{
|
2003-05-10 22:59:04 +00:00
|
|
|
|
#ifdef EH_RETURN_HANDLER_RTX
|
|
|
|
|
emit_move_insn (EH_RETURN_HANDLER_RTX, cfun->eh->ehr_handler);
|
|
|
|
|
#else
|
|
|
|
|
error ("__builtin_eh_return not supported on this target");
|
|
|
|
|
#endif
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused.
* tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused. Kill.
(BUILT_IN_FP, BUILT_IN_SP, BUILT_IN_SET_RETURN_ADDR_REG): Kill.
(BUILT_IN_EH_STUB_OLD, BUILT_IN_EH_STUB, BUILT_IN_SET_EH_REGS): Kill.
(BUILT_IN_EH_RETURN, BUILT_IN_DWARF_CFA): New.
* c-decl.c (init_decl_processing): Update accordingly.
* expr.c (expand_builtin): Likewise.
* cp/decl.c (init_decl_processing): Likewise.
* rtl.h (global_rtl): Add cfa entry.
(virtual_cfa_rtx, VIRTUAL_CFA_REGNUM): New.
(LAST_VIRTUAL_REGISTER): Update.
* emit-rtl.c (global_rtl): Add cfa entry.
(init_emit): Initialize it.
* function.c (cfa_offset): New.
(instantiate_virtual_regs): Initialize it.
(instantiate_virtual_regs_1): Instantiate virtual_cfa_rtx.
(expand_function_end): Call expand_eh_return.
* tm.texi (ARG_POINTER_CFA_OFFSET): New.
* except.c (current_function_eh_stub_label): Kill.
(current_function_eh_old_stub_label): Likwise; update all references.
(expand_builtin_set_return_addr_reg): Kill.
(expand_builtin_eh_stub_old, expand_builtin_eh_stub): Kill.
(expand_builtin_set_eh_regs): Kill.
(eh_regs): Produce a third reg for the actual handler address.
(eh_return_context, eh_return_stack_adjust): New.
(eh_return_handler, eh_return_stub_label): New.
(init_eh_for_function): Initialize them.
(expand_builtin_eh_return, expand_eh_return): New.
* except.h: Update prototypes.
* flow.c (find_basic_blocks_1): Update references to the stub label.
* function.h (struct function): Kill stub label elements.
* libgcc2.c (in_reg_window): For REG_SAVED_REG, check that the
register number is one that would be in the previous window.
Provide a dummy definition for non-windowed targets.
(get_reg_addr): New function.
(get_reg, put_reg, copy_reg): Use it.
(__throw): Rely on in_reg_window, not INCOMING_REGNO. Kill stub
generating code and use __builtin_eh_return. Use __builtin_dwarf_cfa.
* alpha.c (alpha_eh_epilogue_sp_ofs): New.
(alpha_init_expanders): Initialize it.
(alpha_expand_epilogue): Use it.
* alpha.h: Declare it.
* alpha.md (eh_epilogue): New.
* m68h.h (ARG_POINTER_CFA_OFFSET): New.
* sparc.h (ARG_POINTER_CFA_OFFSET): New.
From-SVN: r22436
1998-09-15 12:19:12 -07:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
emit_label (around_label);
|
tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused.
* tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused. Kill.
(BUILT_IN_FP, BUILT_IN_SP, BUILT_IN_SET_RETURN_ADDR_REG): Kill.
(BUILT_IN_EH_STUB_OLD, BUILT_IN_EH_STUB, BUILT_IN_SET_EH_REGS): Kill.
(BUILT_IN_EH_RETURN, BUILT_IN_DWARF_CFA): New.
* c-decl.c (init_decl_processing): Update accordingly.
* expr.c (expand_builtin): Likewise.
* cp/decl.c (init_decl_processing): Likewise.
* rtl.h (global_rtl): Add cfa entry.
(virtual_cfa_rtx, VIRTUAL_CFA_REGNUM): New.
(LAST_VIRTUAL_REGISTER): Update.
* emit-rtl.c (global_rtl): Add cfa entry.
(init_emit): Initialize it.
* function.c (cfa_offset): New.
(instantiate_virtual_regs): Initialize it.
(instantiate_virtual_regs_1): Instantiate virtual_cfa_rtx.
(expand_function_end): Call expand_eh_return.
* tm.texi (ARG_POINTER_CFA_OFFSET): New.
* except.c (current_function_eh_stub_label): Kill.
(current_function_eh_old_stub_label): Likwise; update all references.
(expand_builtin_set_return_addr_reg): Kill.
(expand_builtin_eh_stub_old, expand_builtin_eh_stub): Kill.
(expand_builtin_set_eh_regs): Kill.
(eh_regs): Produce a third reg for the actual handler address.
(eh_return_context, eh_return_stack_adjust): New.
(eh_return_handler, eh_return_stub_label): New.
(init_eh_for_function): Initialize them.
(expand_builtin_eh_return, expand_eh_return): New.
* except.h: Update prototypes.
* flow.c (find_basic_blocks_1): Update references to the stub label.
* function.h (struct function): Kill stub label elements.
* libgcc2.c (in_reg_window): For REG_SAVED_REG, check that the
register number is one that would be in the previous window.
Provide a dummy definition for non-windowed targets.
(get_reg_addr): New function.
(get_reg, put_reg, copy_reg): Use it.
(__throw): Rely on in_reg_window, not INCOMING_REGNO. Kill stub
generating code and use __builtin_eh_return. Use __builtin_dwarf_cfa.
* alpha.c (alpha_eh_epilogue_sp_ofs): New.
(alpha_init_expanders): Initialize it.
(alpha_expand_epilogue): Use it.
* alpha.h: Declare it.
* alpha.md (eh_epilogue): New.
* m68h.h (ARG_POINTER_CFA_OFFSET): New.
* sparc.h (ARG_POINTER_CFA_OFFSET): New.
From-SVN: r22436
1998-09-15 12:19:12 -07:00
|
|
|
|
}
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-08-03 16:15:51 -07:00
|
|
|
|
/* In the following functions, we represent entries in the action table
|
ChangeLog.2, [...]: Fix spelling errors.
* ChangeLog.2, ChangeLog.3, ChangeLog.4, ChangeLog.5, ChangeLog,
cfg.c, cfganal.c, cfgcleanup.c, cfglayout.c, cfgloop.c, cfgrtl.c,
collect2.c, combine.c, config.in, configure, configure.in,
conflict.c, dwarf2out.c, dwarfout.c, except.c, final.c, flow.c,
genattrtab.c, ggc-page.c, jump.c, lcm.c, predict.c, reg-stack.c,
reload1.c, rtlanal.c, sched-rgn.c, toplev.c, unwind-dw2-fde.h: Fix
spelling errors.
From-SVN: r46928
2001-11-11 11:25:28 +00:00
|
|
|
|
as 1-based indices. Special cases are:
|
2001-08-03 16:15:51 -07:00
|
|
|
|
|
|
|
|
|
0: null action record, non-null landing pad; implies cleanups
|
|
|
|
|
-1: null action record, null landing pad; implies no action
|
|
|
|
|
-2: no call-site entry; implies must_not_throw
|
|
|
|
|
-3: we have yet to process outer regions
|
|
|
|
|
|
|
|
|
|
Further, no special cases apply to the "next" field of the record.
|
|
|
|
|
For next, 0 means end of list. */
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct action_record
|
|
|
|
|
{
|
|
|
|
|
int offset;
|
|
|
|
|
int filter;
|
|
|
|
|
int next;
|
|
|
|
|
};
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static int
|
|
|
|
|
action_record_eq (pentry, pdata)
|
|
|
|
|
const PTR pentry;
|
|
|
|
|
const PTR pdata;
|
|
|
|
|
{
|
|
|
|
|
const struct action_record *entry = (const struct action_record *) pentry;
|
|
|
|
|
const struct action_record *data = (const struct action_record *) pdata;
|
|
|
|
|
return entry->filter == data->filter && entry->next == data->next;
|
|
|
|
|
}
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static hashval_t
|
|
|
|
|
action_record_hash (pentry)
|
|
|
|
|
const PTR pentry;
|
|
|
|
|
{
|
|
|
|
|
const struct action_record *entry = (const struct action_record *) pentry;
|
|
|
|
|
return entry->next * 1009 + entry->filter;
|
|
|
|
|
}
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static int
|
|
|
|
|
add_action_record (ar_hash, filter, next)
|
|
|
|
|
htab_t ar_hash;
|
|
|
|
|
int filter, next;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct action_record **slot, *new, tmp;
|
|
|
|
|
|
|
|
|
|
tmp.filter = filter;
|
|
|
|
|
tmp.next = next;
|
|
|
|
|
slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if ((new = *slot) == NULL)
|
1998-03-16 12:51:39 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
new = (struct action_record *) xmalloc (sizeof (*new));
|
|
|
|
|
new->offset = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
|
|
|
|
|
new->filter = filter;
|
|
|
|
|
new->next = next;
|
|
|
|
|
*slot = new;
|
|
|
|
|
|
|
|
|
|
/* The filter value goes in untouched. The link to the next
|
|
|
|
|
record is a "self-relative" byte offset, or zero to indicate
|
|
|
|
|
that there is no next record. So convert the absolute 1 based
|
ChangeLog.2, [...]: Fix spelling errors.
* ChangeLog.2, ChangeLog.3, ChangeLog.4, ChangeLog.5, ChangeLog,
cfg.c, cfganal.c, cfgcleanup.c, cfglayout.c, cfgloop.c, cfgrtl.c,
collect2.c, combine.c, config.in, configure, configure.in,
conflict.c, dwarf2out.c, dwarfout.c, except.c, final.c, flow.c,
genattrtab.c, ggc-page.c, jump.c, lcm.c, predict.c, reg-stack.c,
reload1.c, rtlanal.c, sched-rgn.c, toplev.c, unwind-dw2-fde.h: Fix
spelling errors.
From-SVN: r46928
2001-11-11 11:25:28 +00:00
|
|
|
|
indices we've been carrying around into a displacement. */
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
push_sleb128 (&cfun->eh->action_record_data, filter);
|
|
|
|
|
if (next)
|
|
|
|
|
next -= VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
|
|
|
|
|
push_sleb128 (&cfun->eh->action_record_data, next);
|
1998-03-16 12:51:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return new->offset;
|
|
|
|
|
}
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static int
|
|
|
|
|
collect_one_action_chain (ar_hash, region)
|
|
|
|
|
htab_t ar_hash;
|
|
|
|
|
struct eh_region *region;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct eh_region *c;
|
|
|
|
|
int next;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* If we've reached the top of the region chain, then we have
|
|
|
|
|
no actions, and require no landing pad. */
|
|
|
|
|
if (region == NULL)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
switch (region->type)
|
1998-03-16 12:51:39 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
case ERT_CLEANUP:
|
|
|
|
|
/* A cleanup adds a zero filter to the beginning of the chain, but
|
|
|
|
|
there are special cases to look out for. If there are *only*
|
|
|
|
|
cleanups along a path, then it compresses to a zero action.
|
|
|
|
|
Further, if there are multiple cleanups along a path, we only
|
|
|
|
|
need to represent one of them, as that is enough to trigger
|
|
|
|
|
entry to the landing pad at runtime. */
|
|
|
|
|
next = collect_one_action_chain (ar_hash, region->outer);
|
|
|
|
|
if (next <= 0)
|
|
|
|
|
return 0;
|
|
|
|
|
for (c = region->outer; c ; c = c->outer)
|
|
|
|
|
if (c->type == ERT_CLEANUP)
|
|
|
|
|
return next;
|
|
|
|
|
return add_action_record (ar_hash, 0, next);
|
|
|
|
|
|
|
|
|
|
case ERT_TRY:
|
|
|
|
|
/* Process the associated catch regions in reverse order.
|
|
|
|
|
If there's a catch-all handler, then we don't need to
|
|
|
|
|
search outer regions. Use a magic -3 value to record
|
ChangeLog.0, [...]: Fix spelling errors.
* ChangeLog.0, ChangeLog.2, ChangeLog.3, ChangeLog.4, ChangeLog,
FSFChangeLog.10, c-decl.c, cppfiles.c, cppinit.c, cpplex.c,
cpplib.c, cppmain.c, cse.c, df.c, diagnostic.c, dominance.c,
dwarf2out.c, dwarfout.c, emit-rtl.c, errors.c, except.c, except.h,
explow.c, function.c, gcse.c, genrecog.c, predict.c, regmove.c,
sched-rgn.c, ssa-ccp.c, stmt.c, toplev.c: Fix spelling errors.
From-SVN: r47279
2001-11-23 02:05:19 +00:00
|
|
|
|
that we haven't done the outer search. */
|
2001-03-28 03:04:51 -08:00
|
|
|
|
next = -3;
|
|
|
|
|
for (c = region->u.try.last_catch; c ; c = c->u.catch.prev_catch)
|
|
|
|
|
{
|
2001-11-16 13:48:18 +01:00
|
|
|
|
if (c->u.catch.type_list == NULL)
|
|
|
|
|
{
|
|
|
|
|
/* Retrieve the filter from the head of the filter list
|
|
|
|
|
where we have stored it (see assign_filter_values). */
|
2003-05-07 15:11:38 -07:00
|
|
|
|
int filter
|
|
|
|
|
= TREE_INT_CST_LOW (TREE_VALUE (c->u.catch.filter_list));
|
|
|
|
|
|
|
|
|
|
next = add_action_record (ar_hash, filter, 0);
|
2001-11-16 13:48:18 +01:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
else
|
|
|
|
|
{
|
2001-11-16 13:48:18 +01:00
|
|
|
|
/* Once the outer search is done, trigger an action record for
|
|
|
|
|
each filter we have. */
|
|
|
|
|
tree flt_node;
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (next == -3)
|
|
|
|
|
{
|
|
|
|
|
next = collect_one_action_chain (ar_hash, region->outer);
|
2001-08-03 16:15:51 -07:00
|
|
|
|
|
|
|
|
|
/* If there is no next action, terminate the chain. */
|
|
|
|
|
if (next == -1)
|
2001-03-28 03:04:51 -08:00
|
|
|
|
next = 0;
|
2001-08-03 16:15:51 -07:00
|
|
|
|
/* If all outer actions are cleanups or must_not_throw,
|
|
|
|
|
we'll have no action record for it, since we had wanted
|
|
|
|
|
to encode these states in the call-site record directly.
|
|
|
|
|
Add a cleanup action to the chain to catch these. */
|
|
|
|
|
else if (next <= 0)
|
|
|
|
|
next = add_action_record (ar_hash, 0, 0);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
2001-12-12 09:27:29 +01:00
|
|
|
|
|
2001-11-16 13:48:18 +01:00
|
|
|
|
flt_node = c->u.catch.filter_list;
|
|
|
|
|
for (; flt_node; flt_node = TREE_CHAIN (flt_node))
|
|
|
|
|
{
|
|
|
|
|
int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
|
|
|
|
|
next = add_action_record (ar_hash, filter, next);
|
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return next;
|
|
|
|
|
|
|
|
|
|
case ERT_ALLOWED_EXCEPTIONS:
|
|
|
|
|
/* An exception specification adds its filter to the
|
|
|
|
|
beginning of the chain. */
|
|
|
|
|
next = collect_one_action_chain (ar_hash, region->outer);
|
|
|
|
|
return add_action_record (ar_hash, region->u.allowed.filter,
|
|
|
|
|
next < 0 ? 0 : next);
|
|
|
|
|
|
|
|
|
|
case ERT_MUST_NOT_THROW:
|
|
|
|
|
/* A must-not-throw region with no inner handlers or cleanups
|
|
|
|
|
requires no call-site entry. Note that this differs from
|
|
|
|
|
the no handler or cleanup case in that we do require an lsda
|
|
|
|
|
to be generated. Return a magic -2 value to record this. */
|
|
|
|
|
return -2;
|
|
|
|
|
|
|
|
|
|
case ERT_CATCH:
|
|
|
|
|
case ERT_THROW:
|
|
|
|
|
/* CATCH regions are handled in TRY above. THROW regions are
|
|
|
|
|
for optimization information only and produce no output. */
|
|
|
|
|
return collect_one_action_chain (ar_hash, region->outer);
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
abort ();
|
1998-03-16 12:51:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static int
|
|
|
|
|
add_call_site (landing_pad, action)
|
|
|
|
|
rtx landing_pad;
|
|
|
|
|
int action;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct call_site_record *data = cfun->eh->call_site_data;
|
|
|
|
|
int used = cfun->eh->call_site_data_used;
|
|
|
|
|
int size = cfun->eh->call_site_data_size;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (used >= size)
|
|
|
|
|
{
|
|
|
|
|
size = (size ? size * 2 : 64);
|
|
|
|
|
data = (struct call_site_record *)
|
2002-06-04 07:11:05 +00:00
|
|
|
|
ggc_realloc (data, sizeof (*data) * size);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
cfun->eh->call_site_data = data;
|
|
|
|
|
cfun->eh->call_site_data_size = size;
|
|
|
|
|
}
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
data[used].landing_pad = landing_pad;
|
|
|
|
|
data[used].action = action;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
cfun->eh->call_site_data_used = used + 1;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return used + call_site_base;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
|
|
|
|
|
The new note numbers will not refer to region numbers, but
|
|
|
|
|
instead to call site entries. */
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
convert_to_eh_region_ranges ()
|
1998-03-16 12:51:39 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
rtx insn, iter, note;
|
|
|
|
|
htab_t ar_hash;
|
|
|
|
|
int last_action = -3;
|
|
|
|
|
rtx last_action_insn = NULL_RTX;
|
|
|
|
|
rtx last_landing_pad = NULL_RTX;
|
|
|
|
|
rtx first_no_action_insn = NULL_RTX;
|
2001-07-10 12:38:10 +02:00
|
|
|
|
int call_site = 0;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL)
|
|
|
|
|
return;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
|
|
|
|
|
if (INSN_P (iter))
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *region;
|
|
|
|
|
int this_action;
|
|
|
|
|
rtx this_landing_pad;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
insn = iter;
|
|
|
|
|
if (GET_CODE (insn) == INSN
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
|
|
|
|
|
insn = XVECEXP (PATTERN (insn), 0, 0);
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
|
|
|
|
|
if (!note)
|
|
|
|
|
{
|
|
|
|
|
if (! (GET_CODE (insn) == CALL_INSN
|
|
|
|
|
|| (flag_non_call_exceptions
|
|
|
|
|
&& may_trap_p (PATTERN (insn)))))
|
|
|
|
|
continue;
|
|
|
|
|
this_action = -1;
|
|
|
|
|
region = NULL;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (INTVAL (XEXP (note, 0)) <= 0)
|
|
|
|
|
continue;
|
|
|
|
|
region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
|
|
|
|
|
this_action = collect_one_action_chain (ar_hash, region);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Existence of catch handlers, or must-not-throw regions
|
|
|
|
|
implies that an lsda is needed (even if empty). */
|
|
|
|
|
if (this_action != -1)
|
|
|
|
|
cfun->uses_eh_lsda = 1;
|
|
|
|
|
|
|
|
|
|
/* Delay creation of region notes for no-action regions
|
|
|
|
|
until we're sure that an lsda will be required. */
|
|
|
|
|
else if (last_action == -3)
|
|
|
|
|
{
|
|
|
|
|
first_no_action_insn = iter;
|
|
|
|
|
last_action = -1;
|
|
|
|
|
}
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Cleanups and handlers may share action chains but not
|
|
|
|
|
landing pads. Collect the landing pad for this region. */
|
|
|
|
|
if (this_action >= 0)
|
|
|
|
|
{
|
|
|
|
|
struct eh_region *o;
|
|
|
|
|
for (o = region; ! o->landing_pad ; o = o->outer)
|
|
|
|
|
continue;
|
|
|
|
|
this_landing_pad = o->landing_pad;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
this_landing_pad = NULL_RTX;
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Differing actions or landing pads implies a change in call-site
|
|
|
|
|
info, which implies some EH_REGION note should be emitted. */
|
|
|
|
|
if (last_action != this_action
|
|
|
|
|
|| last_landing_pad != this_landing_pad)
|
|
|
|
|
{
|
|
|
|
|
/* If we'd not seen a previous action (-3) or the previous
|
|
|
|
|
action was must-not-throw (-2), then we do not need an
|
|
|
|
|
end note. */
|
|
|
|
|
if (last_action >= -1)
|
|
|
|
|
{
|
|
|
|
|
/* If we delayed the creation of the begin, do it now. */
|
|
|
|
|
if (first_no_action_insn)
|
|
|
|
|
{
|
|
|
|
|
call_site = add_call_site (NULL_RTX, 0);
|
|
|
|
|
note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
|
|
|
|
|
first_no_action_insn);
|
|
|
|
|
NOTE_EH_HANDLER (note) = call_site;
|
|
|
|
|
first_no_action_insn = NULL_RTX;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
note = emit_note_after (NOTE_INSN_EH_REGION_END,
|
|
|
|
|
last_action_insn);
|
|
|
|
|
NOTE_EH_HANDLER (note) = call_site;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If the new action is must-not-throw, then no region notes
|
|
|
|
|
are created. */
|
|
|
|
|
if (this_action >= -1)
|
|
|
|
|
{
|
2001-12-12 09:27:29 +01:00
|
|
|
|
call_site = add_call_site (this_landing_pad,
|
2001-03-28 03:04:51 -08:00
|
|
|
|
this_action < 0 ? 0 : this_action);
|
|
|
|
|
note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
|
|
|
|
|
NOTE_EH_HANDLER (note) = call_site;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
last_action = this_action;
|
|
|
|
|
last_landing_pad = this_landing_pad;
|
|
|
|
|
}
|
|
|
|
|
last_action_insn = iter;
|
|
|
|
|
}
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (last_action >= -1 && ! first_no_action_insn)
|
1999-08-10 16:19:16 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
|
|
|
|
|
NOTE_EH_HANDLER (note) = call_site;
|
1999-08-10 16:19:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
htab_delete (ar_hash);
|
|
|
|
|
}
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
push_uleb128 (data_area, value)
|
|
|
|
|
varray_type *data_area;
|
|
|
|
|
unsigned int value;
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
unsigned char byte = value & 0x7f;
|
|
|
|
|
value >>= 7;
|
|
|
|
|
if (value)
|
|
|
|
|
byte |= 0x80;
|
|
|
|
|
VARRAY_PUSH_UCHAR (*data_area, byte);
|
|
|
|
|
}
|
|
|
|
|
while (value);
|
|
|
|
|
}
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
static void
|
|
|
|
|
push_sleb128 (data_area, value)
|
|
|
|
|
varray_type *data_area;
|
|
|
|
|
int value;
|
|
|
|
|
{
|
|
|
|
|
unsigned char byte;
|
|
|
|
|
int more;
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
do
|
1999-08-10 16:19:16 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
byte = value & 0x7f;
|
|
|
|
|
value >>= 7;
|
|
|
|
|
more = ! ((value == 0 && (byte & 0x40) == 0)
|
|
|
|
|
|| (value == -1 && (byte & 0x40) != 0));
|
|
|
|
|
if (more)
|
|
|
|
|
byte |= 0x80;
|
|
|
|
|
VARRAY_PUSH_UCHAR (*data_area, byte);
|
1999-08-10 16:19:16 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
while (more);
|
|
|
|
|
}
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
#ifndef HAVE_AS_LEB128
|
|
|
|
|
static int
|
|
|
|
|
dw2_size_of_call_site_table ()
|
1999-08-10 16:19:16 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
int n = cfun->eh->call_site_data_used;
|
|
|
|
|
int size = n * (4 + 4 + 4);
|
|
|
|
|
int i;
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = 0; i < n; ++i)
|
|
|
|
|
{
|
|
|
|
|
struct call_site_record *cs = &cfun->eh->call_site_data[i];
|
|
|
|
|
size += size_of_uleb128 (cs->action);
|
|
|
|
|
}
|
2000-03-09 20:37:06 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
sjlj_size_of_call_site_table ()
|
|
|
|
|
{
|
|
|
|
|
int n = cfun->eh->call_site_data_used;
|
|
|
|
|
int size = 0;
|
|
|
|
|
int i;
|
1998-03-16 12:51:39 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = 0; i < n; ++i)
|
1999-08-10 16:19:16 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct call_site_record *cs = &cfun->eh->call_site_data[i];
|
|
|
|
|
size += size_of_uleb128 (INTVAL (cs->landing_pad));
|
|
|
|
|
size += size_of_uleb128 (cs->action);
|
1999-08-10 16:19:16 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dw2_output_call_site_table ()
|
|
|
|
|
{
|
c-parse.in (yyerror): Const-ification and/or static-ization.
* c-parse.in (yyerror): Const-ification and/or static-ization.
* c-typeck.c (push_member_name): Likewise.
* collect2.c (main): Likewise.
* dbxout.c (dbxout_parms): Likewise.
* diagnostic.c (format_with_decl): Likewise.
* dwarf2out.c (output_ranges): Likewise.
* dwarfout.c (fundamental_type_code): Likewise.
* except.c (dw2_output_call_site_table): Likewise.
* gcc.c (do_spec_1): Likewise.
* genopinit.c (optabs): Likewise.
* objc/objc-act.c (synth_id_with_class_suffix, start_class,
gen_declaration_1, handle_impent): Likewise.
* protoize.c (default_include, in_system_include_dir, abspath):
Likewise.
* sched-vis.c (visualize_stall_cycles): Likewise.
* sdbout.c (plain_type_1, sdbout_end_function,
sdbout_end_epilogue): Likewise.
* varasm.c (decode_reg_name): Likewise.
* 1750a.c (mod_regno_adjust): Likewise.
* alpha.c (alpha_write_one_linkage,
unicosmk_output_default_externs): Likewise.
* arm.c (arm_condition_codes): Likewise.
* arm.h (arm_condition_codes): Likewise.
* avr.c (output_movsisf, encode_section_info): Likewise.
* darwin.h (GEN_BINDER_NAME_FOR_STUB, GEN_SYMBOL_NAME_FOR_SYMBOL):
Likewise.
* i386.c (hi_reg_name, qi_reg_name, qi_high_reg_name): Likewise.
* i386.h (hi_reg_name, qi_reg_name, qi_high_reg_name): Likewise.
* m88k.c (output_function_profiler): Likewise.
* mips.c (mips_output_conditional_branch): Likewise.
* ns32k.c (ns32k_out_reg_names): Likewise.
* ns32k.h (ns32k_out_reg_names): Likewise.
* pj.c (pj_output_rval): Likewise.
* rs6000.c (GEN_LOCAL_LABEL_FOR_SYMBOL): Likewise.
* sparc.c (sparc_flat_function_prologue,
sparc_flat_function_epilogue): Likewise.
cp:
* decl.c (warn_extern_redeclared_static, cp_make_fname_decl):
Const-ification.
* pt.c (tsubst_decl): Likewise.
f:
* bad.c (ffebad_finish): Const-ification and/or static-ization.
* intrin.c (ffeintrin_cmp_name_): Likewise.
* stc.c (ffestc_R904): Likewise.
java:
* expr.c (expand_invoke): Const-ification.
* parse.y (patch_method_invocation): Likewise.
From-SVN: r45581
2001-09-13 14:37:29 +00:00
|
|
|
|
const char *const function_start_lab
|
2001-03-28 03:04:51 -08:00
|
|
|
|
= IDENTIFIER_POINTER (current_function_func_begin_label);
|
|
|
|
|
int n = cfun->eh->call_site_data_used;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < n; ++i)
|
1999-08-10 16:19:16 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct call_site_record *cs = &cfun->eh->call_site_data[i];
|
|
|
|
|
char reg_start_lab[32];
|
|
|
|
|
char reg_end_lab[32];
|
|
|
|
|
char landing_pad_lab[32];
|
|
|
|
|
|
|
|
|
|
ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
|
|
|
|
|
ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
|
|
|
|
|
|
|
|
|
|
if (cs->landing_pad)
|
|
|
|
|
ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
|
|
|
|
|
CODE_LABEL_NUMBER (cs->landing_pad));
|
|
|
|
|
|
|
|
|
|
/* ??? Perhaps use insn length scaling if the assembler supports
|
|
|
|
|
generic arithmetic. */
|
|
|
|
|
/* ??? Perhaps use attr_length to choose data1 or data2 instead of
|
|
|
|
|
data4 if the function is small enough. */
|
|
|
|
|
#ifdef HAVE_AS_LEB128
|
|
|
|
|
dw2_asm_output_delta_uleb128 (reg_start_lab, function_start_lab,
|
|
|
|
|
"region %d start", i);
|
|
|
|
|
dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
|
|
|
|
|
"length");
|
|
|
|
|
if (cs->landing_pad)
|
|
|
|
|
dw2_asm_output_delta_uleb128 (landing_pad_lab, function_start_lab,
|
|
|
|
|
"landing pad");
|
|
|
|
|
else
|
|
|
|
|
dw2_asm_output_data_uleb128 (0, "landing pad");
|
|
|
|
|
#else
|
|
|
|
|
dw2_asm_output_delta (4, reg_start_lab, function_start_lab,
|
|
|
|
|
"region %d start", i);
|
|
|
|
|
dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
|
|
|
|
|
if (cs->landing_pad)
|
|
|
|
|
dw2_asm_output_delta (4, landing_pad_lab, function_start_lab,
|
|
|
|
|
"landing pad");
|
|
|
|
|
else
|
|
|
|
|
dw2_asm_output_data (4, 0, "landing pad");
|
|
|
|
|
#endif
|
|
|
|
|
dw2_asm_output_data_uleb128 (cs->action, "action");
|
1999-08-10 16:19:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
call_site_base += n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
sjlj_output_call_site_table ()
|
|
|
|
|
{
|
|
|
|
|
int n = cfun->eh->call_site_data_used;
|
|
|
|
|
int i;
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
for (i = 0; i < n; ++i)
|
1999-08-10 16:19:16 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
struct call_site_record *cs = &cfun->eh->call_site_data[i];
|
1999-11-08 04:56:18 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
|
|
|
|
|
"region %d landing pad", i);
|
|
|
|
|
dw2_asm_output_data_uleb128 (cs->action, "action");
|
|
|
|
|
}
|
1999-11-08 04:56:18 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
call_site_base += n;
|
1999-08-10 16:19:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-26 13:34:25 +01:00
|
|
|
|
/* Tell assembler to switch to the section for the exception handling
|
|
|
|
|
table. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
default_exception_section ()
|
|
|
|
|
{
|
|
|
|
|
if (targetm.have_named_sections)
|
|
|
|
|
{
|
|
|
|
|
int flags;
|
|
|
|
|
#ifdef HAVE_LD_RO_RW_SECTION_MIXING
|
2002-11-28 02:10:46 +00:00
|
|
|
|
int tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
|
|
|
|
|
|
2002-11-26 13:34:25 +01:00
|
|
|
|
flags = (! flag_pic
|
|
|
|
|
|| ((tt_format & 0x70) != DW_EH_PE_absptr
|
|
|
|
|
&& (tt_format & 0x70) != DW_EH_PE_aligned))
|
|
|
|
|
? 0 : SECTION_WRITE;
|
|
|
|
|
#else
|
|
|
|
|
flags = SECTION_WRITE;
|
|
|
|
|
#endif
|
|
|
|
|
named_section_flags (".gcc_except_table", flags);
|
|
|
|
|
}
|
|
|
|
|
else if (flag_pic)
|
|
|
|
|
data_section ();
|
|
|
|
|
else
|
|
|
|
|
readonly_data_section ();
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
void
|
|
|
|
|
output_function_exception_table ()
|
|
|
|
|
{
|
2001-05-11 23:03:20 -07:00
|
|
|
|
int tt_format, cs_format, lp_format, i, n;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#ifdef HAVE_AS_LEB128
|
|
|
|
|
char ttype_label[32];
|
|
|
|
|
char cs_after_size_label[32];
|
|
|
|
|
char cs_end_label[32];
|
|
|
|
|
#else
|
|
|
|
|
int call_site_len;
|
|
|
|
|
#endif
|
|
|
|
|
int have_tt_data;
|
2001-07-10 12:38:10 +02:00
|
|
|
|
int tt_format_size = 0;
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Not all functions need anything. */
|
|
|
|
|
if (! cfun->uses_eh_lsda)
|
|
|
|
|
return;
|
2000-03-09 20:37:06 +00:00
|
|
|
|
|
2001-05-11 23:03:20 -07:00
|
|
|
|
#ifdef IA64_UNWIND_INFO
|
|
|
|
|
fputs ("\t.personality\t", asm_out_file);
|
|
|
|
|
output_addr_const (asm_out_file, eh_personality_libfunc);
|
|
|
|
|
fputs ("\n\t.handlerdata\n", asm_out_file);
|
|
|
|
|
/* Note that varasm still thinks we're in the function's code section.
|
|
|
|
|
The ".endp" directive that will immediately follow will take us back. */
|
|
|
|
|
#else
|
2001-10-22 14:43:31 +00:00
|
|
|
|
(*targetm.asm_out.exception_section) ();
|
2001-05-11 23:03:20 -07:00
|
|
|
|
#endif
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
have_tt_data = (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) > 0
|
|
|
|
|
|| VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) > 0);
|
|
|
|
|
|
2001-05-12 21:30:09 -07:00
|
|
|
|
/* Indicate the format of the @TType entries. */
|
|
|
|
|
if (! have_tt_data)
|
|
|
|
|
tt_format = DW_EH_PE_omit;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
|
|
|
|
|
#ifdef HAVE_AS_LEB128
|
2002-06-17 10:47:22 -07:00
|
|
|
|
ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT",
|
|
|
|
|
current_function_funcdef_no);
|
2001-05-12 21:30:09 -07:00
|
|
|
|
#endif
|
|
|
|
|
tt_format_size = size_of_encoded_value (tt_format);
|
|
|
|
|
|
2001-08-01 15:47:09 -07:00
|
|
|
|
assemble_align (tt_format_size * BITS_PER_UNIT);
|
2001-05-12 21:30:09 -07:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
2002-12-16 18:23:00 +00:00
|
|
|
|
(*targetm.asm_out.internal_label) (asm_out_file, "LLSDA",
|
2002-06-17 10:47:22 -07:00
|
|
|
|
current_function_funcdef_no);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* The LSDA header. */
|
|
|
|
|
|
|
|
|
|
/* Indicate the format of the landing pad start pointer. An omitted
|
|
|
|
|
field implies @LPStart == @Start. */
|
|
|
|
|
/* Currently we always put @LPStart == @Start. This field would
|
|
|
|
|
be most useful in moving the landing pads completely out of
|
|
|
|
|
line to another section, but it could also be used to minimize
|
|
|
|
|
the size of uleb128 landing pad offsets. */
|
2001-05-11 23:03:20 -07:00
|
|
|
|
lp_format = DW_EH_PE_omit;
|
|
|
|
|
dw2_asm_output_data (1, lp_format, "@LPStart format (%s)",
|
|
|
|
|
eh_data_format_name (lp_format));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
/* @LPStart pointer would go here. */
|
|
|
|
|
|
2001-05-11 23:03:20 -07:00
|
|
|
|
dw2_asm_output_data (1, tt_format, "@TType format (%s)",
|
|
|
|
|
eh_data_format_name (tt_format));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
#ifndef HAVE_AS_LEB128
|
|
|
|
|
if (USING_SJLJ_EXCEPTIONS)
|
|
|
|
|
call_site_len = sjlj_size_of_call_site_table ();
|
|
|
|
|
else
|
|
|
|
|
call_site_len = dw2_size_of_call_site_table ();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* A pc-relative 4-byte displacement to the @TType data. */
|
|
|
|
|
if (have_tt_data)
|
|
|
|
|
{
|
|
|
|
|
#ifdef HAVE_AS_LEB128
|
|
|
|
|
char ttype_after_disp_label[32];
|
2001-12-12 09:27:29 +01:00
|
|
|
|
ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, "LLSDATTD",
|
2002-06-17 10:47:22 -07:00
|
|
|
|
current_function_funcdef_no);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
|
|
|
|
|
"@TType base offset");
|
|
|
|
|
ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
|
|
|
|
|
#else
|
|
|
|
|
/* Ug. Alignment queers things. */
|
2001-05-12 21:30:09 -07:00
|
|
|
|
unsigned int before_disp, after_disp, last_disp, disp;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
before_disp = 1 + 1;
|
|
|
|
|
after_disp = (1 + size_of_uleb128 (call_site_len)
|
|
|
|
|
+ call_site_len
|
|
|
|
|
+ VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data)
|
2001-05-12 21:30:09 -07:00
|
|
|
|
+ (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data)
|
|
|
|
|
* tt_format_size));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
disp = after_disp;
|
|
|
|
|
do
|
1999-08-10 16:19:16 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
unsigned int disp_size, pad;
|
|
|
|
|
|
|
|
|
|
last_disp = disp;
|
|
|
|
|
disp_size = size_of_uleb128 (disp);
|
|
|
|
|
pad = before_disp + disp_size + after_disp;
|
2001-05-12 21:30:09 -07:00
|
|
|
|
if (pad % tt_format_size)
|
|
|
|
|
pad = tt_format_size - (pad % tt_format_size);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
else
|
|
|
|
|
pad = 0;
|
|
|
|
|
disp = after_disp + pad;
|
1999-08-10 16:19:16 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
while (disp != last_disp);
|
|
|
|
|
|
|
|
|
|
dw2_asm_output_data_uleb128 (disp, "@TType base offset");
|
|
|
|
|
#endif
|
1999-08-10 16:19:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
/* Indicate the format of the call-site offsets. */
|
|
|
|
|
#ifdef HAVE_AS_LEB128
|
2001-05-11 23:03:20 -07:00
|
|
|
|
cs_format = DW_EH_PE_uleb128;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#else
|
2001-05-11 23:03:20 -07:00
|
|
|
|
cs_format = DW_EH_PE_udata4;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
#endif
|
2001-05-11 23:03:20 -07:00
|
|
|
|
dw2_asm_output_data (1, cs_format, "call-site format (%s)",
|
|
|
|
|
eh_data_format_name (cs_format));
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
#ifdef HAVE_AS_LEB128
|
|
|
|
|
ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, "LLSDACSB",
|
2002-06-17 10:47:22 -07:00
|
|
|
|
current_function_funcdef_no);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
ASM_GENERATE_INTERNAL_LABEL (cs_end_label, "LLSDACSE",
|
2002-06-17 10:47:22 -07:00
|
|
|
|
current_function_funcdef_no);
|
2001-03-28 03:04:51 -08:00
|
|
|
|
dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
|
|
|
|
|
"Call-site table length");
|
|
|
|
|
ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
|
|
|
|
|
if (USING_SJLJ_EXCEPTIONS)
|
|
|
|
|
sjlj_output_call_site_table ();
|
|
|
|
|
else
|
|
|
|
|
dw2_output_call_site_table ();
|
|
|
|
|
ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
|
|
|
|
|
#else
|
|
|
|
|
dw2_asm_output_data_uleb128 (call_site_len,"Call-site table length");
|
|
|
|
|
if (USING_SJLJ_EXCEPTIONS)
|
|
|
|
|
sjlj_output_call_site_table ();
|
|
|
|
|
else
|
|
|
|
|
dw2_output_call_site_table ();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* ??? Decode and interpret the data for flag_debug_asm. */
|
|
|
|
|
n = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data);
|
|
|
|
|
for (i = 0; i < n; ++i)
|
|
|
|
|
dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->action_record_data, i),
|
|
|
|
|
(i ? NULL : "Action record table"));
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
if (have_tt_data)
|
2001-08-01 15:47:09 -07:00
|
|
|
|
assemble_align (tt_format_size * BITS_PER_UNIT);
|
1999-08-10 16:19:16 +00:00
|
|
|
|
|
2001-03-28 03:04:51 -08:00
|
|
|
|
i = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data);
|
|
|
|
|
while (i-- > 0)
|
1999-08-10 16:19:16 +00:00
|
|
|
|
{
|
2001-03-28 03:04:51 -08:00
|
|
|
|
tree type = VARRAY_TREE (cfun->eh->ttype_data, i);
|
2001-08-27 10:25:36 -07:00
|
|
|
|
rtx value;
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
if (type == NULL_TREE)
|
|
|
|
|
type = integer_zero_node;
|
|
|
|
|
else
|
|
|
|
|
type = lookup_type_for_runtime (type);
|
|
|
|
|
|
2001-08-27 10:25:36 -07:00
|
|
|
|
value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
|
|
|
|
|
if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
|
|
|
|
|
assemble_integer (value, tt_format_size,
|
|
|
|
|
tt_format_size * BITS_PER_UNIT, 1);
|
|
|
|
|
else
|
2002-06-03 01:13:17 +00:00
|
|
|
|
dw2_asm_output_encoded_addr_rtx (tt_format, value, NULL);
|
1999-08-10 16:19:16 +00:00
|
|
|
|
}
|
2001-03-28 03:04:51 -08:00
|
|
|
|
|
|
|
|
|
#ifdef HAVE_AS_LEB128
|
|
|
|
|
if (have_tt_data)
|
|
|
|
|
ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* ??? Decode and interpret the data for flag_debug_asm. */
|
|
|
|
|
n = VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data);
|
|
|
|
|
for (i = 0; i < n; ++i)
|
|
|
|
|
dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i),
|
|
|
|
|
(i ? NULL : "Exception specification table"));
|
|
|
|
|
|
|
|
|
|
function_section (current_function_decl);
|
1999-08-10 16:19:16 +00:00
|
|
|
|
}
|
2002-06-04 07:11:05 +00:00
|
|
|
|
|
|
|
|
|
#include "gt-except.h"
|