summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--ChangeLog.melt3
-rw-r--r--MAINTAINERS1
-rw-r--r--gcc/ChangeLog145
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in3
-rw-r--r--gcc/ada/ChangeLog27
-rw-r--r--gcc/ada/exp_dbug.ads2
-rw-r--r--gcc/ada/gcc-interface/Makefile.in35
-rw-r--r--gcc/ada/gcc-interface/decl.c10
-rw-r--r--gcc/ada/gcc-interface/trans.c27
-rw-r--r--gcc/ada/gcc-interface/utils.c18
-rw-r--r--gcc/config/darwin.c24
-rw-r--r--gcc/config/i386/i386.md70
-rw-r--r--gcc/config/i386/t-cygming3
-rw-r--r--gcc/config/i386/t-cygwin2
-rw-r--r--gcc/config/mips/mips.c4
-rw-r--r--gcc/config/mips/mips.h1
-rw-r--r--gcc/config/mips/mips.md3
-rw-r--r--gcc/config/mips/octeon.md88
-rw-r--r--gcc/config/sparc/sparc-protos.h3
-rw-r--r--gcc/config/sparc/sparc.c82
-rw-r--r--gcc/config/sparc/sparc.md514
-rw-r--r--gcc/config/xtensa/xtensa.md19
-rw-r--r--gcc/doc/gccint.texi8
-rw-r--r--gcc/doc/generic.texi179
-rw-r--r--gcc/doc/gimple.texi2498
-rw-r--r--gcc/doc/tm.texi19
-rw-r--r--gcc/doc/tree-ssa.texi722
-rw-r--r--gcc/final.c38
-rw-r--r--gcc/fortran/ChangeLog31
-rw-r--r--gcc/fortran/decl.c6
-rw-r--r--gcc/fortran/resolve.c9
-rw-r--r--gcc/fortran/trans-array.c28
-rw-r--r--gcc/fortran/trans-decl.c4
-rw-r--r--gcc/fortran/trans-expr.c93
-rw-r--r--gcc/fortran/trans.h2
-rw-r--r--gcc/gimple.c6
-rw-r--r--gcc/gimple.h2
-rw-r--r--gcc/ipa-cp.c14
-rw-r--r--gcc/ira.c24
-rw-r--r--gcc/opts.c9
-rw-r--r--gcc/target-def.h7
-rw-r--r--gcc/target.h3
-rw-r--r--gcc/targhooks.c9
-rw-r--r--gcc/targhooks.h3
-rw-r--r--gcc/testsuite/ChangeLog66
-rw-r--r--gcc/testsuite/g++.dg/ext/inline1.C34
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr11832.c4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr33009.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vector-2.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vector-3.c20
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr37539.c45
-rw-r--r--gcc/testsuite/gcc.dg/weak/weak-15.c39
-rw-r--r--gcc/testsuite/gcc.dg/weak/weak-16.c21
-rw-r--r--gcc/testsuite/gfortran.dg/entry_18.f9036
-rw-r--r--gcc/testsuite/gfortran.dg/nested_array_constructor_1.f9019
-rw-r--r--gcc/testsuite/gfortran.dg/nested_array_constructor_2.f9022
-rw-r--r--gcc/testsuite/gfortran.dg/nested_array_constructor_3.f9022
-rw-r--r--gcc/testsuite/gfortran.dg/nested_array_constructor_4.f9017
-rw-r--r--gcc/testsuite/gfortran.dg/nested_array_constructor_5.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/nested_array_constructor_6.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_proc_4.f032
-rw-r--r--gcc/tree-ssa-ter.c27
-rw-r--r--gcc/tree-ssa.c78
-rw-r--r--gcc/tree-vect-transform.c27
-rw-r--r--gcc/varasm.c32
-rw-r--r--libada/ChangeLog9
-rw-r--r--libada/Makefile.in26
-rwxr-xr-xlibada/configure1042
-rw-r--r--libada/configure.ac48
-rw-r--r--libgomp/ChangeLog9
-rw-r--r--libgomp/Makefile.in1
-rw-r--r--libgomp/config/bsd/proc.c117
-rwxr-xr-xlibgomp/configure3
-rw-r--r--libgomp/configure.ac2
-rw-r--r--libgomp/configure.tgt4
-rw-r--r--libgomp/testsuite/Makefile.in1
-rw-r--r--libstdc++-v3/ChangeLog5
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h2
80 files changed, 5252 insertions, 1389 deletions
diff --git a/ChangeLog b/ChangeLog
index f04ae63c501..e5223ad0e96 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-09-20 Steven Bosscher <steven@gcc.gnu.org>
+
+ * MAINTAINERS: Add myself in "Write After Approval".
+
2008-09-18 Steve Ellcey <sje@cup.hp.com>
* MAINTAINERS: Add myself as ia64 maintainer.
diff --git a/ChangeLog.melt b/ChangeLog.melt
index fe654381e3b..c3838e8ab61 100644
--- a/ChangeLog.melt
+++ b/ChangeLog.melt
@@ -1,3 +1,6 @@
+2008-09-22 Basile Starynkevitch <basile@starynkevitch.net>
+ MELT branch merged with trunk r140542
+
2008-09-18 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r140490
diff --git a/MAINTAINERS b/MAINTAINERS
index 111f17cc6c6..6c8314021d4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -280,6 +280,7 @@ Segher Boessenkool segher@kernel.crashing.org
Andrea Bona andrea.bona@st.com
Paolo Bonzini bonzini@gnu.org
Neil Booth neil@daikokuya.co.uk
+Steven Bosscher steven@gcc.gnu.org
Robert Bowdidge bowdidge@apple.com
Joel Brobecker brobecker@gnat.com
Dave Brolley brolley@redhat.com
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ac957740e4c..9f67a4c0e91 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,148 @@
+2008-09-21 Jan Hubicka <jh@suse.cz>
+
+ * ipa-cp.c (ipcp_estimate_growth): Check recursive calls.
+ (ipcp_insert_stage): Update dead_nodes bitmap.
+
+2008-09-22 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR target/37528
+ * config/i386/t-cygming (SHLIB_LC): Remove.
+ (SHLIB_LINK): Don't add static objects to SHLIB_IMPLIB
+ * config/i386/t-cygwin (SHLIB_LC): Specify all required
+ libraries.
+
+2008-09-22 Hans-Peter Nilsson <hp@axis.com>
+
+ PR middle-end/37170
+ PR middle-end/37280
+ * final.c (mark_symbol_ref_as_used): New helper function.
+ (output_operand): Instead of just looking inside MEMs for
+ SYMBOL_REFs, use new helper function and for_each_rtx.
+ * varasm.c (assemble_external): Move #ifndef ASM_OUTPUT_EXTERNAL
+ to after weak-handling. Don't mark decls with TREE_STATIC as weak.
+ Make head comment more general.
+ * config/darwin.c (machopic_output_indirection): Handle weak
+ references here, like in assemble_external.
+
+2008-09-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/sparc/sparc-protos.h (gen_compare_operator): Declare.
+ (sparc_emit_float_lib_cmp): Change return type.
+ * config/sparc/sparc.c (gen_compare_reg): Add comment about TFmode.
+ (gen_compare_operator): New function.
+ (sparc_emit_float_lib_cmp): Return the new operator to be used in
+ the comparison sequence. Minor tweaks.
+ * config/sparc/sparc.md (seq, sne, sgt, slt, sge, sle): Assert
+ that the final operator and the result of sparc_emit_float_lib_cmp
+ match for software TFmode; use emit_insn in lieu of emit_jump_insn.
+ (beq, bne, bgt, blt, bge, ble, bunordered, bordered, bungt, bunlt,
+ buneq, bunge, bunle, bltgt): Assert that the final operator and the
+ result of sparc_emit_float_lib_cmp match for software TFmode.
+ (movqicc, movhicc, movsicc, movdicc): Merge into...
+ (mov<I:mode>cc): ...this.
+ (movsfcc, movdfcc, movtfcc): Merge into...
+ (mov<F:mode>cc): ...this.
+ (movqi_cc_sp64, movhi_cc_sp64, movsi_cc_sp64, movdi_cc_sp64): Merge
+ into...
+ (mov<I:mode>_cc_v9): ...this.
+ (movdi_cc_sp64_trunc): Delete.
+ (movqi_cc_reg_sp64, movhi_cc_reg_sp64, movsi_cc_reg_sp64,
+ movdi_cc_reg_sp64): Merge into...
+ (mov<I:mode>_cc_reg_sp64): ...this.
+ (movsf_cc_sp64): Rename into...
+ (movsf_cc_v9): ...this.
+ (movdf_cc_sp64): Rename into...
+ (movdf_cc_v9): ...this.
+ (movtf_cc_hq_sp64): Rename into...
+ (movtf_cc_hq_v9): ...this.
+ (movtf_cc_sp64): Rename into...
+ (movtf_cc_v9): ...this. Adjust for renaming of movdf_cc_sp64.
+
+2008-09-21 Diego Novillo <dnovillo@google.com>
+
+ * doc/gccint.texi: Include generic.texi and gimple.texi.
+ Re-order index.
+ * doc/tree-ssa.texi (GENERIC): Move to generic.texi.
+ (GIMPLE): Move to gimple.texi.
+ (Annotations): Remove references to to stmt_ann_t and
+ ssa_name_ann_t.
+ (SSA Operands): Rename from 'Statement Operands'.
+ * doc/generic.texi: New.
+ * doc/gimple.texi: New.
+ * Makefile.in (TEXI_GCCINT_FILES): Add generic.texi and
+ gimple.texi.
+ * Makefile.in (TEXI_GCCINT_FILES):
+ * gimple.c (gimple_copy_call_skip_args): Rename from
+ giple_copy_call_skip_args. Update all users.
+ * doc/gimple.texi (gimple_copy_call_skip_args): Document.
+
+2008-09-21 Ira Rosen <irar@il.ibm.com>
+
+ PR tree-optimization/37539
+ * tree-vect-transform.c (vect_transform_strided_load): Save vector
+ statement in related statement field only for the first load of the
+ group of loads with the same data reference.
+
+2008-09-20 Adam Nemet <anemet@caviumnetworks.com>
+
+ * config/mips/mips.h (TUNE_OCTEON): New macro.
+ * config/mips/mips.c (mips_issue_rate): Return 2 for Octeon.
+ (mips_multipass_dfa_lookahead): Return 2 for Octeon.
+ * config/mips/octeon.md: New file.
+ * config/mips/mips.md: Include octeon.md. Restore
+ semi-alphabetical order of include files.
+
+2008-09-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/37571
+ * config/i386/i386.md (*jcc_fused_1): Removed.
+ (*jcc_fused_2): Likewise.
+ (*jcc_fused_3): Likewise.
+ (*jcc_fused_4): Likewise.
+
+2008-09-20 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * doc/tm.texi (TARGET_IRA_COVER_CLASSES): Define.
+ (IRA_COVER_CLASSES): Refer to TARGET_IRA_COVER_CLASSES.
+ * target.h (gcc_target): Add ira_cover_classes.
+ * ira.c: Remove IRA_COVER_CLASSES guards.
+ (setup_cover_and_important_classes): Use targetm.ira_cover_classes
+ instead of IRA_COVER_CLASSES.
+ (setup_cover_and_important_classes): Remove IRA_COVER_CLASSES guard.
+ (setup_class_translate): Likewise.
+ (setup_reg_class_intersect_union): Likewise.
+ (find_reg_class_closure): Replace IRA_COVER_CLASSES guard with a
+ test of targetm.ira_cover_classes.
+ * opts.c (decode_options): Use targetm.ira_cover_classes instead
+ of IRA_COVER_CLASSES.
+ * target-def.h (TARGET_IRA_COVER_CLASSES): Define.
+ (TARGET_INITIALIZER): Include it.
+ * targhooks.h (default_ira_cover_classes): Declare.
+ * targhooks.c (default_ira_cover_classes): New function.
+
+2008-09-19 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.md (reload<mode>_literal): Handle MEM operands.
+
+2008-09-19 Ian Lance Taylor <iant@google.com>
+
+ * varasm.c (narrowing_initializer_constant_valid_p): Return
+ NULL_TREE if ENDTYPE is not an integer.
+
+2008-09-19 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR tree-opt/30930
+ * tree-ssa.c (execute_update_addresses_taken): Also update
+ DECL_GIMPLE_REG_P for vector and complex types.
+
+2008-09-19 Andrew MacLeod <amacleod@redhat.com>
+ Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/37567
+ * tree-ssa-ter.c (free_temp_expr_table): Make sure fields are actually
+ empty before freeing them.
+ (find_replaceable_exprs): Move asserts to free_temp_expr_table.
+
2008-09-18 Bob Wilson <bob.wilson@acm.org>
* configure.ac: Add HAVE_AS_TLS check for Xtensa.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 7b605fab072..0257b41a77b 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20080919
+20080922
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 42486eca87b..6befd2f08f9 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3913,7 +3913,8 @@ TEXI_GCCINT_FILES = gccint.texi gcc-common.texi gcc-vers.texi \
configfiles.texi collect2.texi headerdirs.texi funding.texi \
gnu.texi gpl_v3.texi fdl.texi contrib.texi languages.texi \
sourcebuild.texi gty.texi libgcc.texi cfg.texi tree-ssa.texi \
- loop.texi melt.texi
+ loop.texi generic.texi gimple.texi melt.texi
+
TEXI_GCCINSTALL_FILES = install.texi install-old.texi fdl.texi \
gcc-common.texi gcc-vers.texi
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 5d6ecc80329..fe89a54c22f 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,30 @@
+2008-09-21 Laurent Guerby <laurent@guerby.net>
+
+ PR ada/5911
+ * gcc-interface/Makefile.in: Add multilib handling for x86_64
+ and sparc.
+ * system-linux-sparcv9.ads: New file.
+
+2008-09-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_dbug.ads: Document new convention for the XVZ variable.
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Generate
+ debug info if necessary for the type padding the component type.
+ <E_Array_Subtype>: Likewise.
+ (maybe_pad_type): Emit the XVZ variable in units.
+ * gcc-interface/trans.c (Loop_Statement_to_gnu): Fix formatting nits.
+ (Subprogram_Body_to_gnu): Set the source line of the subprogram's node
+ on statements generated to initialize the parameter attributes cache.
+ Set the source line of the end label of the body on the special return
+ statement built for a procedure with copy-in copy-out parameters.
+
+2008-09-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/37585
+ * gcc-interface/utils.c (create_subprog_decl): Disable inlining for
+ inlined external functions if they contain a nested function not
+ declared inline.
+
2008-09-18 Jan Hubicka <jh@suse.cz>
* gcc-interface/utils.c (create_subprog_decl): Use DECL_DECLARED_INLINE_P.
diff --git a/gcc/ada/exp_dbug.ads b/gcc/ada/exp_dbug.ads
index 71c2f79b14f..3a6297ce9ee 100644
--- a/gcc/ada/exp_dbug.ads
+++ b/gcc/ada/exp_dbug.ads
@@ -851,7 +851,7 @@ package Exp_Dbug is
-- The size of the objects typed as x should be obtained from the
-- structure of x (and x___XVE, if applicable) as for ordinary types
-- unless there is a variable named x___XVZ, which, if present, will
- -- hold the size (in bits) of x.
+ -- hold the size (in bytes) of x.
-- The type x will either be a subtype of y (see also Subtypes of
-- Variant Records, below) or will contain no fields at all. The layout,
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index ccd20bd1733..59803ca1ed2 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -316,6 +316,18 @@ else
osys:=$(word 3,$(targ))
endif
+# Make arch match the current multilib so that the RTS selection code
+# picks up the right files. For a given target this must be coherent
+# with MULTILIB_DIRNAMES defined in gcc/config/target/t-*.
+
+ifeq ($(strip $(filter-out %x86_64, $(arch))),)
+ ifeq ($(strip $(MULTISUBDIR)),/32)
+ arch:=i686
+ endif
+endif
+
+# ???: handle more multilib targets
+
# LIBGNAT_TARGET_PAIRS is a list of pairs of filenames.
# The members of each pair must be separated by a '<' and no whitespace.
# Each pair must be separated by some amount of whitespace from the following
@@ -1467,7 +1479,7 @@ ifeq ($(strip $(filter-out powerpc% linux%,$(arch) $(osys))),)
endif
ifeq ($(strip $(filter-out sparc% linux%,$(arch) $(osys))),)
- LIBGNAT_TARGET_PAIRS = \
+ LIBGNAT_TARGET_PAIRS_32 = \
a-intnam.ads<a-intnam-linux.ads \
s-inmaop.adb<s-inmaop-posix.adb \
s-intman.adb<s-intman-posix.adb \
@@ -1482,6 +1494,27 @@ ifeq ($(strip $(filter-out sparc% linux%,$(arch) $(osys))),)
s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
system.ads<system-linux-sparc.ads
+ LIBGNAT_TARGET_PAIRS_64 = \
+ a-intnam.ads<a-intnam-linux.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-linux.ads<s-linux.ads \
+ s-osinte.adb<s-osinte-posix.adb \
+ s-osinte.ads<s-osinte-linux.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-linux.adb \
+ s-tasinf.ads<s-tasinf-linux.ads \
+ s-tasinf.adb<s-tasinf-linux.adb \
+ s-taspri.ads<s-taspri-posix-noaltstack.ads \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ system.ads<system-linux-sparcv9.ads
+
+ ifeq ($(strip $(MULTISUBDIR)),/64)
+ LIBGNAT_TARGET_PAIRS = $(LIBGNAT_TARGET_PAIRS_64)
+ else
+ LIBGNAT_TARGET_PAIRS = $(LIBGNAT_TARGET_PAIRS_32)
+ endif
+
TOOLS_TARGET_PAIRS = \
mlib-tgt-specific.adb<mlib-tgt-specific-linux.adb \
indepsw.adb<indepsw-gnu.adb
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index c254990d45c..a8fa1badac3 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -1955,8 +1955,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
never be declared otherwise. This is necessary to ensure
that its subtrees are properly marked. */
if (tem != orig_tem)
- create_type_decl (TYPE_NAME (tem), tem, NULL, true, false,
- gnat_entity);
+ create_type_decl (TYPE_NAME (tem), tem, NULL, true,
+ debug_info_p, gnat_entity);
}
if (Has_Volatile_Components (gnat_entity))
@@ -2324,7 +2324,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
to ensure that its subtrees are properly marked. */
if (gnu_type != orig_gnu_type)
create_type_decl (TYPE_NAME (gnu_type), gnu_type, NULL,
- true, false, gnat_entity);
+ true, debug_info_p, gnat_entity);
}
if (Has_Volatile_Components (Base_Type (gnat_entity)))
@@ -5867,8 +5867,8 @@ maybe_pad_type (tree type, tree size, unsigned int align,
if (size && TREE_CODE (size) != INTEGER_CST && definition)
create_var_decl (concat_id_with_name (name, "XVZ"), NULL_TREE,
- bitsizetype, TYPE_SIZE (record), false, false, false,
- false, NULL, gnat_entity);
+ sizetype, TYPE_SIZE_UNIT (record), false, false,
+ false, false, NULL, gnat_entity);
}
rest_of_record_type_compilation (record);
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 938408bf8e1..9a6f4cf36ef 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -1689,17 +1689,20 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
push_stack (&gnu_loop_label_stack, NULL_TREE,
LOOP_STMT_LABEL (gnu_loop_stmt));
- /* Set the condition that under which the loop should continue.
- For "LOOP .... END LOOP;" the condition is always true. */
+ /* Set the condition under which the loop must keep going.
+ For the case "LOOP .... END LOOP;" the condition is always true. */
if (No (gnat_iter_scheme))
;
- /* The case "WHILE condition LOOP ..... END LOOP;" */
+
+ /* For the case "WHILE condition LOOP ..... END LOOP;" it's immediate. */
else if (Present (Condition (gnat_iter_scheme)))
LOOP_STMT_TOP_COND (gnu_loop_stmt)
= gnat_to_gnu (Condition (gnat_iter_scheme));
+
+ /* Otherwise we have an iteration scheme and the condition is given by
+ the bounds of the subtype of the iteration variable. */
else
{
- /* We have an iteration scheme. */
Node_Id gnat_loop_spec = Loop_Parameter_Specification (gnat_iter_scheme);
Entity_Id gnat_loop_var = Defining_Entity (gnat_loop_spec);
Entity_Id gnat_type = Etype (gnat_loop_var);
@@ -1745,7 +1748,7 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
gnu_loop_var = convert (get_base_type (gnu_type), gnu_loop_var);
/* Set either the top or bottom exit condition as appropriate depending
- on whether or not we know an overflow cannot occur. */
+ on whether or not we know an overflow cannot occur. */
if (gnu_cond_expr)
LOOP_STMT_BOT_COND (gnu_loop_stmt)
= build_binary_op (NE_EXPR, integer_type_node,
@@ -1763,12 +1766,12 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
convert (TREE_TYPE (gnu_loop_var),
integer_one_node));
set_expr_location_from_node (LOOP_STMT_UPDATE (gnu_loop_stmt),
- gnat_iter_scheme);
+ gnat_iter_scheme);
}
/* If the loop was named, have the name point to this loop. In this case,
the association is not a ..._DECL node, but the end label from this
- LOOP_STMT. */
+ LOOP_STMT. */
if (Present (Identifier (gnat_node)))
save_gnu_tree (Entity (Identifier (gnat_node)),
LOOP_STMT_LABEL (gnu_loop_stmt), true);
@@ -1788,7 +1791,7 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
}
/* If we have an outer COND_EXPR, that's our result and this loop is its
- "true" statement. Otherwise, the result is the LOOP_STMT. */
+ "true" statement. Otherwise, the result is the LOOP_STMT. */
if (gnu_cond_expr)
{
COND_EXPR_THEN (gnu_cond_expr) = gnu_loop_stmt;
@@ -1981,11 +1984,11 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
for (i = 0; VEC_iterate (parm_attr, cache, i, pa); i++)
{
if (pa->first)
- add_stmt (pa->first);
+ add_stmt_with_node (pa->first, gnat_node);
if (pa->last)
- add_stmt (pa->last);
+ add_stmt_with_node (pa->last, gnat_node);
if (pa->length)
- add_stmt (pa->length);
+ add_stmt_with_node (pa->length, gnat_node);
}
add_stmt (gnu_result);
@@ -2017,7 +2020,7 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
add_stmt_with_node
(build_return_expr (DECL_RESULT (gnu_subprog_decl), gnu_retval),
- gnat_node);
+ End_Label (Handled_Statement_Sequence (gnat_node)));
gnat_poplevel ();
gnu_result = end_stmt_group ();
}
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 608f6ecd865..7f1bc7bebbb 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -1973,12 +1973,16 @@ create_subprog_decl (tree subprog_name, tree asm_name,
tree return_type = TREE_TYPE (subprog_type);
tree subprog_decl = build_decl (FUNCTION_DECL, subprog_name, subprog_type);
- /* If this is a function nested inside an inlined external function, it
- means we aren't going to compile the outer function unless it is
- actually inlined, so do the same for us. */
- if (current_function_decl && DECL_DECLARED_INLINE_P (current_function_decl)
+ /* If this is a non-inline function nested inside an inlined external
+ function, we cannot honor both requests without cloning the nested
+ function in the current unit since it is private to the other unit.
+ We could inline the nested function as well but it's probably better
+ to err on the side of too little inlining. */
+ if (!inline_flag
+ && current_function_decl
+ && DECL_DECLARED_INLINE_P (current_function_decl)
&& DECL_EXTERNAL (current_function_decl))
- extern_flag = true;
+ DECL_DECLARED_INLINE_P (current_function_decl) = 0;
DECL_EXTERNAL (subprog_decl) = extern_flag;
TREE_PUBLIC (subprog_decl) = public_flag;
@@ -1986,6 +1990,7 @@ create_subprog_decl (tree subprog_name, tree asm_name,
TREE_READONLY (subprog_decl) = TYPE_READONLY (subprog_type);
TREE_THIS_VOLATILE (subprog_decl) = TYPE_VOLATILE (subprog_type);
TREE_SIDE_EFFECTS (subprog_decl) = TYPE_VOLATILE (subprog_type);
+ DECL_DECLARED_INLINE_P (subprog_decl) = inline_flag;
DECL_ARGUMENTS (subprog_decl) = param_decl_list;
DECL_RESULT (subprog_decl) = build_decl (RESULT_DECL, 0, return_type);
DECL_ARTIFICIAL (DECL_RESULT (subprog_decl)) = 1;
@@ -2004,9 +2009,6 @@ create_subprog_decl (tree subprog_name, tree asm_name,
DECL_BY_REFERENCE (result_decl) = 1;
}
- if (inline_flag)
- DECL_DECLARED_INLINE_P (subprog_decl) = 1;
-
if (asm_name)
{
SET_DECL_ASSEMBLER_NAME (subprog_decl, asm_name);
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 20cce264101..fe332738c54 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -1002,6 +1002,30 @@ machopic_output_indirection (void **slot, void *data)
rtx init = const0_rtx;
switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
+
+ /* Mach-O symbols are passed around in code through indirect
+ references and the original symbol_ref hasn't passed through
+ the generic handling and reference-catching in
+ output_operand, so we need to manually mark weak references
+ as such. */
+ if (SYMBOL_REF_WEAK (symbol))
+ {
+ tree decl = SYMBOL_REF_DECL (symbol);
+ gcc_assert (DECL_P (decl));
+
+ if (decl != NULL_TREE
+ && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
+ /* Handle only actual external-only definitions, not
+ e.g. extern inline code or variables for which
+ storage has been allocated. */
+ && !TREE_STATIC (decl))
+ {
+ fputs ("\t.weak_reference ", asm_out_file);
+ assemble_name (asm_out_file, sym_name);
+ fputc ('\n', asm_out_file);
+ }
+ }
+
assemble_name (asm_out_file, ptr_name);
fprintf (asm_out_file, ":\n");
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 66d186686f7..de58df39edc 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -14267,76 +14267,6 @@
(const_int 2)
(const_int 6)))])
-;; ??? Handle alignment requirements for compare and branch fused macro-op;
-;; the branch instruction does not start at a 16-byte boundary or cross
-;; a 16-byte boundary.
-
-(define_insn "*jcc_fused_1"
- [(set (pc)
- (if_then_else (match_operator 1 "comparison_operator"
- [(match_operand:SWI32 2 "register_operand" "<r>")
- (match_operand:SWI32 3 "const0_operand" "")])
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
-{
- return "test{<imodesuffix>}\t%2, %2\n\t"
- "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
-}
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*jcc_fused_2"
- [(set (pc)
- (if_then_else (match_operator 1 "comparison_operator"
- [(match_operand:SWI32 2 "register_operand" "<r>")
- (match_operand:SWI32 3 "const0_operand" "")])
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
-{
- return "test{<imodesuffix>}\t%2, %2\n\t"
- "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
-}
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*jcc_fused_3"
- [(set (pc)
- (if_then_else
- (match_operator 1 "ix86_comparison_uns_operator"
- [(match_operand:SWI32 2 "nonimmediate_operand" "<r>,m,<r>")
- (match_operand:SWI32 3 "<general_operand>" "<r><i>,<r>,m")])
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
- && !(MEM_P (operands[2])
- && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
-{
- return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
- "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
-}
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*jcc_fused_4"
- [(set (pc)
- (if_then_else
- (match_operator 1 "ix86_comparison_uns_operator"
- [(match_operand:SWI32 2 "nonimmediate_operand" "<r>,m,<r>")
- (match_operand:SWI32 3 "<general_operand>" "<r><i>,<r>,m")])
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
- && !(MEM_P (operands[2])
- && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
-{
- return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
- "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
-}
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
;; In general it is not safe to assume too much about CCmode registers,
;; so simplify-rtx stops when it sees a second one. Under certain
;; conditions this is safe on x86, so help combine not create
diff --git a/gcc/config/i386/t-cygming b/gcc/config/i386/t-cygming
index c6e6cac7811..ecfe2d1d2a3 100644
--- a/gcc/config/i386/t-cygming
+++ b/gcc/config/i386/t-cygming
@@ -54,7 +54,6 @@ SHLIB_MAP = @shlib_map_file@
SHLIB_OBJS = @shlib_objs@
SHLIB_DIR = @multilib_dir@/shlib
SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
-SHLIB_LC = -luser32 -lkernel32 -ladvapi32 -lshell32
SHLIB_LINK = $(LN_S) $(SHLIB_MAP) $(SHLIB_MAP).def && \
if [ ! -d $(SHLIB_DIR) ]; then \
@@ -65,8 +64,6 @@ SHLIB_LINK = $(LN_S) $(SHLIB_MAP) $(SHLIB_MAP).def && \
-Wl,--out-implib,$(SHLIB_DIR)/$(SHLIB_IMPLIB).tmp \
-o $(SHLIB_DIR)/$(SHLIB_SONAME).tmp @multilib_flags@ \
$(SHLIB_OBJS) $(SHLIB_LC) && \
- $(AR_FOR_TARGET) -r $(SHLIB_DIR)/$(SHLIB_IMPLIB).tmp \
- _chkstk.o _ctors.o gthr-win32.o && \
if [ -f $(SHLIB_DIR)/$(SHLIB_SONAME) ]; then \
mv -f $(SHLIB_DIR)/$(SHLIB_SONAME) \
$(SHLIB_DIR)/$(SHLIB_SONAME).backup; \
diff --git a/gcc/config/i386/t-cygwin b/gcc/config/i386/t-cygwin
index 3715c0b450c..7433138d692 100644
--- a/gcc/config/i386/t-cygwin
+++ b/gcc/config/i386/t-cygwin
@@ -15,4 +15,4 @@ cygwin2.o: $(srcdir)/config/i386/cygwin2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(srcdir)/config/i386/cygwin2.c
# Cygwin-specific parts of LIB_SPEC
-SHLIB_LC += -lcygwin
+SHLIB_LC = -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 799570cc7ae..20532ba3de2 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -10377,6 +10377,7 @@ mips_issue_rate (void)
case PROCESSOR_R5500:
case PROCESSOR_R7000:
case PROCESSOR_R9000:
+ case PROCESSOR_OCTEON:
return 2;
case PROCESSOR_SB1:
@@ -10518,6 +10519,9 @@ mips_multipass_dfa_lookahead (void)
if (TUNE_LOONGSON_2EF)
return 4;
+ if (TUNE_OCTEON)
+ return 2;
+
return 0;
}
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index effa34ba261..ab248692f56 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -281,6 +281,7 @@ enum mips_code_readable_setting {
#define TUNE_MIPS6000 (mips_tune == PROCESSOR_R6000)
#define TUNE_MIPS7000 (mips_tune == PROCESSOR_R7000)
#define TUNE_MIPS9000 (mips_tune == PROCESSOR_R9000)
+#define TUNE_OCTEON (mips_tune == PROCESSOR_OCTEON)
#define TUNE_SB1 (mips_tune == PROCESSOR_SB1 \
|| mips_tune == PROCESSOR_SB1A)
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 593fae30ba6..58d1fd6637f 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -935,10 +935,11 @@
(include "6000.md")
(include "7000.md")
(include "9000.md")
+(include "loongson2ef.md")
+(include "octeon.md")
(include "sb1.md")
(include "sr71k.md")
(include "xlr.md")
-(include "loongson2ef.md")
(include "generic.md")
;;
diff --git a/gcc/config/mips/octeon.md b/gcc/config/mips/octeon.md
new file mode 100644
index 00000000000..0d94e6eecff
--- /dev/null
+++ b/gcc/config/mips/octeon.md
@@ -0,0 +1,88 @@
+;; Octeon pipeline description.
+;; Copyright (C) 2008
+;; Free Software Foundation, Inc.
+
+;; This file is part of GCC.
+
+;; 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 3, or (at your option)
+;; any later version.
+
+;; 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.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+;; Copyright (C) 2004, 2005, 2006 Cavium Networks.
+
+
+;; Octeon is a dual-issue processor that can issue all instructions on
+;; pipe0 and a subset on pipe1.
+
+(define_automaton "octeon_main, octeon_mult")
+
+(define_cpu_unit "octeon_pipe0" "octeon_main")
+(define_cpu_unit "octeon_pipe1" "octeon_main")
+(define_cpu_unit "octeon_mult" "octeon_mult")
+
+(define_insn_reservation "octeon_arith" 1
+ (and (eq_attr "cpu" "octeon")
+ (eq_attr "type" "arith,const,logical,move,shift,signext,slt,nop"))
+ "octeon_pipe0 | octeon_pipe1")
+
+(define_insn_reservation "octeon_condmove" 2
+ (and (eq_attr "cpu" "octeon")
+ (eq_attr "type" "condmove"))
+ "octeon_pipe0 | octeon_pipe1")
+
+(define_insn_reservation "octeon_load" 2
+ (and (eq_attr "cpu" "octeon")
+ (eq_attr "type" "load,prefetch,mtc,mfc"))
+ "octeon_pipe0")
+
+(define_insn_reservation "octeon_store" 1
+ (and (eq_attr "cpu" "octeon")
+ (eq_attr "type" "store"))
+ "octeon_pipe0")
+
+(define_insn_reservation "octeon_brj" 1
+ (and (eq_attr "cpu" "octeon")
+ (eq_attr "type" "branch,jump,call,trap"))
+ "octeon_pipe0")
+
+(define_insn_reservation "octeon_imul3" 5
+ (and (eq_attr "cpu" "octeon")
+ (eq_attr "type" "imul3,pop,clz"))
+ "(octeon_pipe0 | octeon_pipe1) + octeon_mult")
+
+(define_insn_reservation "octeon_imul" 2
+ (and (eq_attr "cpu" "octeon")
+ (eq_attr "type" "imul,mthilo"))
+ "(octeon_pipe0 | octeon_pipe1) + octeon_mult, octeon_mult")
+
+(define_insn_reservation "octeon_mfhilo" 5
+ (and (eq_attr "cpu" "octeon")
+ (eq_attr "type" "mfhilo"))
+ "(octeon_pipe0 | octeon_pipe1) + octeon_mult")
+
+(define_insn_reservation "octeon_imadd" 4
+ (and (eq_attr "cpu" "octeon")
+ (eq_attr "type" "imadd"))
+ "(octeon_pipe0 | octeon_pipe1) + octeon_mult, octeon_mult*3")
+
+(define_insn_reservation "octeon_idiv" 72
+ (and (eq_attr "cpu" "octeon")
+ (eq_attr "type" "idiv"))
+ "(octeon_pipe0 | octeon_pipe1) + octeon_mult, octeon_mult*71")
+
+;; Assume both pipes are needed for unknown and multiple-instruction
+;; patterns.
+
+(define_insn_reservation "octeon_unknown" 1
+ (and (eq_attr "cpu" "octeon")
+ (eq_attr "type" "unknown,multi"))
+ "octeon_pipe0 + octeon_pipe1")
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index 7c56925c01d..a15837fccc0 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -54,7 +54,8 @@ extern void sparc_output_scratch_registers (FILE *);
extern enum machine_mode select_cc_mode (enum rtx_code, rtx, rtx);
/* Define the function that build the compare insn for scc and bcc. */
extern rtx gen_compare_reg (enum rtx_code code);
-extern void sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
+extern rtx gen_compare_operator (enum rtx_code code);
+extern enum rtx_code sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
extern void sparc_emit_floatunsdi (rtx [2], enum machine_mode);
extern void sparc_emit_fixunsdi (rtx [2], enum machine_mode);
extern void emit_tfmode_binop (enum rtx_code, rtx *);
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 0852cd94e79..fd566532067 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -2001,8 +2001,7 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y ATTRIBUTE_UNUSED)
}
}
-/* X and Y are two things to compare using CODE. Emit the compare insn and
- return the rtx for the cc reg in the proper mode. */
+/* Emit the compare insn and return the CC reg for a CODE comparison. */
rtx
gen_compare_reg (enum rtx_code code)
@@ -2065,12 +2064,28 @@ gen_compare_reg (enum rtx_code code)
else
cc_reg = gen_rtx_REG (mode, SPARC_ICC_REG);
- emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
- gen_rtx_COMPARE (mode, x, y)));
+ /* We shouldn't get there for TFmode if !TARGET_HARD_QUAD. If we do, this
+ will only result in an unrecognizable insn so no point in asserting. */
+ emit_insn (gen_rtx_SET (VOIDmode, cc_reg, gen_rtx_COMPARE (mode, x, y)));
return cc_reg;
}
+/* Same as above but return the whole compare operator. */
+
+rtx
+gen_compare_operator (enum rtx_code code)
+{
+ rtx cc_reg;
+
+ if (GET_MODE (sparc_compare_op0) == TFmode && !TARGET_HARD_QUAD)
+ code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, code);
+
+ cc_reg = gen_compare_reg (code);
+ return gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+}
+
/* This function is used for v9 only.
CODE is the code for an Scc's comparison.
OPERANDS[0] is the target of the Scc insn.
@@ -6099,41 +6114,45 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
}
/* Emit a library call comparison between floating point X and Y.
- COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
+ COMPARISON is the operator to compare with (EQ, NE, GT, etc).
+ Return the new operator to be used in the comparison sequence.
+
TARGET_ARCH64 uses _Qp_* functions, which use pointers to TFmode
values as arguments instead of the TFmode registers themselves,
that's why we cannot call emit_float_lib_cmp. */
-void
+
+enum rtx_code
sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
{
const char *qpfunc;
rtx slot0, slot1, result, tem, tem2;
enum machine_mode mode;
+ enum rtx_code new_comparison;
switch (comparison)
{
case EQ:
- qpfunc = (TARGET_ARCH64) ? "_Qp_feq" : "_Q_feq";
+ qpfunc = (TARGET_ARCH64 ? "_Qp_feq" : "_Q_feq");
break;
case NE:
- qpfunc = (TARGET_ARCH64) ? "_Qp_fne" : "_Q_fne";
+ qpfunc = (TARGET_ARCH64 ? "_Qp_fne" : "_Q_fne");
break;
case GT:
- qpfunc = (TARGET_ARCH64) ? "_Qp_fgt" : "_Q_fgt";
+ qpfunc = (TARGET_ARCH64 ? "_Qp_fgt" : "_Q_fgt");
break;
case GE:
- qpfunc = (TARGET_ARCH64) ? "_Qp_fge" : "_Q_fge";
+ qpfunc = (TARGET_ARCH64 ? "_Qp_fge" : "_Q_fge");
break;
case LT:
- qpfunc = (TARGET_ARCH64) ? "_Qp_flt" : "_Q_flt";
+ qpfunc = (TARGET_ARCH64 ? "_Qp_flt" : "_Q_flt");
break;
case LE:
- qpfunc = (TARGET_ARCH64) ? "_Qp_fle" : "_Q_fle";
+ qpfunc = (TARGET_ARCH64 ? "_Qp_fle" : "_Q_fle");
break;
case ORDERED:
@@ -6144,7 +6163,7 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
case UNGE:
case UNLE:
case LTGT:
- qpfunc = (TARGET_ARCH64) ? "_Qp_cmp" : "_Q_cmp";
+ qpfunc = (TARGET_ARCH64 ? "_Qp_cmp" : "_Q_cmp");
break;
default:
@@ -6153,27 +6172,26 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
if (TARGET_ARCH64)
{
- if (GET_CODE (x) != MEM)
+ if (MEM_P (x))
+ slot0 = x;
+ else
{
slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
emit_move_insn (slot0, x);
}
- else
- slot0 = x;
- if (GET_CODE (y) != MEM)
+ if (MEM_P (y))
+ slot1 = y;
+ else
{
slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
emit_move_insn (slot1, y);
}
- else
- slot1 = y;
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
DImode, 2,
XEXP (slot0, 0), Pmode,
XEXP (slot1, 0), Pmode);
-
mode = DImode;
}
else
@@ -6181,7 +6199,6 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
SImode, 2,
x, TFmode, y, TFmode);
-
mode = SImode;
}
@@ -6195,20 +6212,22 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
switch (comparison)
{
default:
- emit_cmp_insn (result, const0_rtx, NE, NULL_RTX, mode, 0);
+ new_comparison = NE;
+ emit_cmp_insn (result, const0_rtx, new_comparison, NULL_RTX, mode, 0);
break;
case ORDERED:
case UNORDERED:
- emit_cmp_insn (result, GEN_INT(3), comparison == UNORDERED ? EQ : NE,
- NULL_RTX, mode, 0);
+ new_comparison = (comparison == UNORDERED ? EQ : NE);
+ emit_cmp_insn (result, GEN_INT(3), new_comparison, NULL_RTX, mode, 0);
break;
case UNGT:
case UNGE:
- emit_cmp_insn (result, const1_rtx,
- comparison == UNGT ? GT : NE, NULL_RTX, mode, 0);
+ new_comparison = (comparison == UNGT ? GT : NE);
+ emit_cmp_insn (result, const1_rtx, new_comparison, NULL_RTX, mode, 0);
break;
case UNLE:
- emit_cmp_insn (result, const2_rtx, NE, NULL_RTX, mode, 0);
+ new_comparison = NE;
+ emit_cmp_insn (result, const2_rtx, new_comparison, NULL_RTX, mode, 0);
break;
case UNLT:
tem = gen_reg_rtx (mode);
@@ -6216,7 +6235,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
emit_insn (gen_andsi3 (tem, result, const1_rtx));
else
emit_insn (gen_anddi3 (tem, result, const1_rtx));
- emit_cmp_insn (tem, const0_rtx, NE, NULL_RTX, mode, 0);
+ new_comparison = NE;
+ emit_cmp_insn (tem, const0_rtx, new_comparison, NULL_RTX, mode, 0);
break;
case UNEQ:
case LTGT:
@@ -6230,10 +6250,12 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
emit_insn (gen_andsi3 (tem2, tem, const2_rtx));
else
emit_insn (gen_anddi3 (tem2, tem, const2_rtx));
- emit_cmp_insn (tem2, const0_rtx, comparison == UNEQ ? EQ : NE,
- NULL_RTX, mode, 0);
+ new_comparison = (comparison == UNEQ ? EQ : NE);
+ emit_cmp_insn (tem2, const0_rtx, new_comparison, NULL_RTX, mode, 0);
break;
}
+
+ return new_comparison;
}
/* Generate an unsigned DImode to FP conversion. This is the same code
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index bc29bcf819c..d0b73893945 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -621,8 +621,10 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
- emit_jump_insn (gen_sne (operands[0]));
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
+ gcc_assert (code == NE);
+ emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@@ -673,8 +675,10 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
- emit_jump_insn (gen_sne (operands[0]));
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
+ gcc_assert (code == NE);
+ emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@@ -693,8 +697,10 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
- emit_jump_insn (gen_sne (operands[0]));
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
+ gcc_assert (code == NE);
+ emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@@ -713,8 +719,10 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
- emit_jump_insn (gen_sne (operands[0]));
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
+ gcc_assert (code == NE);
+ emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@@ -733,8 +741,10 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
- emit_jump_insn (gen_sne (operands[0]));
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
+ gcc_assert (code == NE);
+ emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@@ -753,8 +763,10 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
- emit_jump_insn (gen_sne (operands[0]));
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
+ gcc_assert (code == NE);
+ emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@@ -1270,7 +1282,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
+ gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@@ -1293,7 +1307,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
+ gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@@ -1316,7 +1332,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
+ gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@@ -1349,7 +1367,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
+ gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@@ -1382,7 +1402,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
+ gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@@ -1415,7 +1437,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
+ gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@@ -1441,8 +1465,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
- UNORDERED);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNORDERED);
+ gcc_assert (code == EQ);
emit_jump_insn (gen_beq (operands[0]));
DONE;
}
@@ -1458,7 +1483,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
+ gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@@ -1474,7 +1501,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
+ gcc_assert (code == GT);
emit_jump_insn (gen_bgt (operands[0]));
DONE;
}
@@ -1490,7 +1519,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
+ gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@@ -1506,7 +1537,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
+ gcc_assert (code == EQ);
emit_jump_insn (gen_beq (operands[0]));
DONE;
}
@@ -1522,7 +1555,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
+ gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@@ -1538,7 +1573,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
+ gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@@ -1554,7 +1591,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
- sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
+ enum rtx_code code
+ = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
+ gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@@ -3015,7 +3054,7 @@
})
-;; SPARC-V9 conditional move instructions.
+;; SPARC-V9 conditional move instructions
;; We can handle larger constants here for some flavors, but for now we keep
;; it simple and only allow those constants supported by all flavors.
@@ -3023,40 +3062,14 @@
;; 3 contains the constant if one is present, but we handle either for
;; generality (sparc.c puts a constant in operand 2).
-(define_expand "movqicc"
- [(set (match_operand:QI 0 "register_operand" "")
- (if_then_else:QI (match_operand 1 "comparison_operator" "")
- (match_operand:QI 2 "arith10_operand" "")
- (match_operand:QI 3 "arith10_operand" "")))]
- "TARGET_V9"
-{
- enum rtx_code code = GET_CODE (operands[1]);
-
- if (GET_MODE (sparc_compare_op0) == DImode
- && ! TARGET_ARCH64)
- FAIL;
-
- if (sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode
- && v9_regcmp_p (code))
- {
- operands[1] = gen_rtx_fmt_ee (code, DImode,
- sparc_compare_op0, sparc_compare_op1);
- }
- else
- {
- rtx cc_reg = gen_compare_reg (code);
- operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
- }
-})
+(define_mode_iterator I [QI HI SI DI])
-(define_expand "movhicc"
- [(set (match_operand:HI 0 "register_operand" "")
- (if_then_else:HI (match_operand 1 "comparison_operator" "")
- (match_operand:HI 2 "arith10_operand" "")
- (match_operand:HI 3 "arith10_operand" "")))]
- "TARGET_V9"
+(define_expand "mov<I:mode>cc"
+ [(set (match_operand:I 0 "register_operand" "")
+ (if_then_else:I (match_operand 1 "comparison_operator" "")
+ (match_operand:I 2 "arith10_operand" "")
+ (match_operand:I 3 "arith10_operand" "")))]
+ "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
{
enum rtx_code code = GET_CODE (operands[1]);
@@ -3068,72 +3081,18 @@
&& GET_CODE (sparc_compare_op0) == REG
&& GET_MODE (sparc_compare_op0) == DImode
&& v9_regcmp_p (code))
- {
- operands[1] = gen_rtx_fmt_ee (code, DImode,
- sparc_compare_op0, sparc_compare_op1);
- }
- else
- {
- rtx cc_reg = gen_compare_reg (code);
- operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
- }
-})
-
-(define_expand "movsicc"
- [(set (match_operand:SI 0 "register_operand" "")
- (if_then_else:SI (match_operand 1 "comparison_operator" "")
- (match_operand:SI 2 "arith10_operand" "")
- (match_operand:SI 3 "arith10_operand" "")))]
- "TARGET_V9"
-{
- enum rtx_code code = GET_CODE (operands[1]);
- enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
-
- if (sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
- {
- operands[1] = gen_rtx_fmt_ee (code, op0_mode,
- sparc_compare_op0, sparc_compare_op1);
- }
+ operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
else
- {
- rtx cc_reg = gen_compare_reg (code);
- operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
- cc_reg, const0_rtx);
- }
+ operands[1] = gen_compare_operator (code);
})
-(define_expand "movdicc"
- [(set (match_operand:DI 0 "register_operand" "")
- (if_then_else:DI (match_operand 1 "comparison_operator" "")
- (match_operand:DI 2 "arith10_operand" "")
- (match_operand:DI 3 "arith10_operand" "")))]
- "TARGET_ARCH64"
-{
- enum rtx_code code = GET_CODE (operands[1]);
-
- if (sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode
- && v9_regcmp_p (code))
- {
- operands[1] = gen_rtx_fmt_ee (code, DImode,
- sparc_compare_op0, sparc_compare_op1);
- }
- else
- {
- rtx cc_reg = gen_compare_reg (code);
- operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
- cc_reg, const0_rtx);
- }
-})
+(define_mode_iterator F [SF DF TF])
-(define_expand "movsfcc"
- [(set (match_operand:SF 0 "register_operand" "")
- (if_then_else:SF (match_operand 1 "comparison_operator" "")
- (match_operand:SF 2 "register_operand" "")
- (match_operand:SF 3 "register_operand" "")))]
+(define_expand "mov<F:mode>cc"
+ [(set (match_operand:F 0 "register_operand" "")
+ (if_then_else:F (match_operand 1 "comparison_operator" "")
+ (match_operand:F 2 "register_operand" "")
+ (match_operand:F 3 "register_operand" "")))]
"TARGET_V9 && TARGET_FPU"
{
enum rtx_code code = GET_CODE (operands[1]);
@@ -3146,160 +3105,73 @@
&& GET_CODE (sparc_compare_op0) == REG
&& GET_MODE (sparc_compare_op0) == DImode
&& v9_regcmp_p (code))
- {
- operands[1] = gen_rtx_fmt_ee (code, DImode,
- sparc_compare_op0, sparc_compare_op1);
- }
+ operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
else
- {
- rtx cc_reg = gen_compare_reg (code);
- operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
- }
+ operands[1] = gen_compare_operator (code);
})
-(define_expand "movdfcc"
- [(set (match_operand:DF 0 "register_operand" "")
- (if_then_else:DF (match_operand 1 "comparison_operator" "")
- (match_operand:DF 2 "register_operand" "")
- (match_operand:DF 3 "register_operand" "")))]
- "TARGET_V9 && TARGET_FPU"
-{
- enum rtx_code code = GET_CODE (operands[1]);
-
- if (GET_MODE (sparc_compare_op0) == DImode
- && ! TARGET_ARCH64)
- FAIL;
-
- if (sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode
- && v9_regcmp_p (code))
- {
- operands[1] = gen_rtx_fmt_ee (code, DImode,
- sparc_compare_op0, sparc_compare_op1);
- }
- else
- {
- rtx cc_reg = gen_compare_reg (code);
- operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
- }
-})
-
-(define_expand "movtfcc"
- [(set (match_operand:TF 0 "register_operand" "")
- (if_then_else:TF (match_operand 1 "comparison_operator" "")
- (match_operand:TF 2 "register_operand" "")
- (match_operand:TF 3 "register_operand" "")))]
- "TARGET_V9 && TARGET_FPU"
-{
- enum rtx_code code = GET_CODE (operands[1]);
-
- if (GET_MODE (sparc_compare_op0) == DImode
- && ! TARGET_ARCH64)
- FAIL;
-
- if (sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode
- && v9_regcmp_p (code))
- {
- operands[1] = gen_rtx_fmt_ee (code, DImode,
- sparc_compare_op0, sparc_compare_op1);
- }
- else
- {
- rtx cc_reg = gen_compare_reg (code);
- operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
- }
-})
-
-;; Conditional move define_insns.
-
-(define_insn "*movqi_cc_sp64"
- [(set (match_operand:QI 0 "register_operand" "=r,r")
- (if_then_else:QI (match_operator 1 "comparison_operator"
- [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
- (const_int 0)])
- (match_operand:QI 3 "arith11_operand" "rL,0")
- (match_operand:QI 4 "arith11_operand" "0,rL")))]
- "TARGET_V9"
- "@
- mov%C1\t%x2, %3, %0
- mov%c1\t%x2, %4, %0"
- [(set_attr "type" "cmove")])
-
-(define_insn "*movhi_cc_sp64"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (if_then_else:HI (match_operator 1 "comparison_operator"
- [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
- (const_int 0)])
- (match_operand:HI 3 "arith11_operand" "rL,0")
- (match_operand:HI 4 "arith11_operand" "0,rL")))]
- "TARGET_V9"
- "@
- mov%C1\t%x2, %3, %0
- mov%c1\t%x2, %4, %0"
- [(set_attr "type" "cmove")])
-
-(define_insn "*movsi_cc_sp64"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (if_then_else:SI (match_operator 1 "comparison_operator"
- [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
- (const_int 0)])
- (match_operand:SI 3 "arith11_operand" "rL,0")
- (match_operand:SI 4 "arith11_operand" "0,rL")))]
- "TARGET_V9"
- "@
- mov%C1\t%x2, %3, %0
- mov%c1\t%x2, %4, %0"
- [(set_attr "type" "cmove")])
+;; Conditional move define_insns
-(define_insn "*movdi_cc_sp64"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (if_then_else:DI (match_operator 1 "comparison_operator"
- [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
- (const_int 0)])
- (match_operand:DI 3 "arith11_operand" "rL,0")
- (match_operand:DI 4 "arith11_operand" "0,rL")))]
- "TARGET_ARCH64"
+(define_insn "*mov<I:mode>_cc_v9"
+ [(set (match_operand:I 0 "register_operand" "=r,r")
+ (if_then_else:I (match_operator 1 "comparison_operator"
+ [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
+ (const_int 0)])
+ (match_operand:I 3 "arith11_operand" "rL,0")
+ (match_operand:I 4 "arith11_operand" "0,rL")))]
+ "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
"@
mov%C1\t%x2, %3, %0
mov%c1\t%x2, %4, %0"
[(set_attr "type" "cmove")])
-(define_insn "*movdi_cc_sp64_trunc"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (if_then_else:SI (match_operator 1 "comparison_operator"
- [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
+(define_insn "*mov<I:mode>_cc_reg_sp64"
+ [(set (match_operand:I 0 "register_operand" "=r,r")
+ (if_then_else:I (match_operator 1 "v9_register_compare_operator"
+ [(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
- (match_operand:SI 3 "arith11_operand" "rL,0")
- (match_operand:SI 4 "arith11_operand" "0,rL")))]
+ (match_operand:I 3 "arith10_operand" "rM,0")
+ (match_operand:I 4 "arith10_operand" "0,rM")))]
"TARGET_ARCH64"
"@
- mov%C1\t%x2, %3, %0
- mov%c1\t%x2, %4, %0"
+ movr%D1\t%2, %r3, %0
+ movr%d1\t%2, %r4, %0"
[(set_attr "type" "cmove")])
-(define_insn "*movsf_cc_sp64"
+(define_insn "*movsf_cc_v9"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(if_then_else:SF (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
- (match_operand:SF 3 "register_operand" "f,0")
- (match_operand:SF 4 "register_operand" "0,f")))]
+ (match_operand:SF 3 "register_operand" "f,0")
+ (match_operand:SF 4 "register_operand" "0,f")))]
"TARGET_V9 && TARGET_FPU"
"@
fmovs%C1\t%x2, %3, %0
fmovs%c1\t%x2, %4, %0"
[(set_attr "type" "fpcmove")])
-(define_insn "movdf_cc_sp64"
+(define_insn "*movsf_cc_reg_sp64"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
+ [(match_operand:DI 2 "register_operand" "r,r")
+ (const_int 0)])
+ (match_operand:SF 3 "register_operand" "f,0")
+ (match_operand:SF 4 "register_operand" "0,f")))]
+ "TARGET_ARCH64 && TARGET_FPU"
+ "@
+ fmovrs%D1\t%2, %3, %0
+ fmovrs%d1\t%2, %4, %0"
+ [(set_attr "type" "fpcrmove")])
+
+;; Named because invoked by movtf_cc_v9
+(define_insn "movdf_cc_v9"
[(set (match_operand:DF 0 "register_operand" "=e,e")
(if_then_else:DF (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
- (match_operand:DF 3 "register_operand" "e,0")
- (match_operand:DF 4 "register_operand" "0,e")))]
+ (match_operand:DF 3 "register_operand" "e,0")
+ (match_operand:DF 4 "register_operand" "0,e")))]
"TARGET_V9 && TARGET_FPU"
"@
fmovd%C1\t%x2, %3, %0
@@ -3307,26 +3179,54 @@
[(set_attr "type" "fpcmove")
(set_attr "fptype" "double")])
-(define_insn "*movtf_cc_hq_sp64"
+;; Named because invoked by movtf_cc_reg_sp64
+(define_insn "movdf_cc_reg_sp64"
+ [(set (match_operand:DF 0 "register_operand" "=e,e")
+ (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
+ [(match_operand:DI 2 "register_operand" "r,r")
+ (const_int 0)])
+ (match_operand:DF 3 "register_operand" "e,0")
+ (match_operand:DF 4 "register_operand" "0,e")))]
+ "TARGET_ARCH64 && TARGET_FPU"
+ "@
+ fmovrd%D1\t%2, %3, %0
+ fmovrd%d1\t%2, %4, %0"
+ [(set_attr "type" "fpcrmove")
+ (set_attr "fptype" "double")])
+
+(define_insn "*movtf_cc_hq_v9"
[(set (match_operand:TF 0 "register_operand" "=e,e")
(if_then_else:TF (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
- (match_operand:TF 3 "register_operand" "e,0")
- (match_operand:TF 4 "register_operand" "0,e")))]
+ (match_operand:TF 3 "register_operand" "e,0")
+ (match_operand:TF 4 "register_operand" "0,e")))]
"TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
"@
fmovq%C1\t%x2, %3, %0
fmovq%c1\t%x2, %4, %0"
[(set_attr "type" "fpcmove")])
-(define_insn_and_split "*movtf_cc_sp64"
+(define_insn "*movtf_cc_reg_hq_sp64"
+ [(set (match_operand:TF 0 "register_operand" "=e,e")
+ (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
+ [(match_operand:DI 2 "register_operand" "r,r")
+ (const_int 0)])
+ (match_operand:TF 3 "register_operand" "e,0")
+ (match_operand:TF 4 "register_operand" "0,e")))]
+ "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
+ "@
+ fmovrq%D1\t%2, %3, %0
+ fmovrq%d1\t%2, %4, %0"
+ [(set_attr "type" "fpcrmove")])
+
+(define_insn_and_split "*movtf_cc_v9"
[(set (match_operand:TF 0 "register_operand" "=e,e")
(if_then_else:TF (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
- (match_operand:TF 3 "register_operand" "e,0")
- (match_operand:TF 4 "register_operand" "0,e")))]
+ (match_operand:TF 3 "register_operand" "e,0")
+ (match_operand:TF 4 "register_operand" "0,e")))]
"TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
"#"
"&& reload_completed"
@@ -3351,117 +3251,25 @@
if ((third && reg_overlap_mentioned_p (dest1, srcb2))
|| (!third && reg_overlap_mentioned_p (dest1, srca2)))
{
- emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
- emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
+ emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
+ emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
}
else
{
- emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
- emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
+ emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
+ emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
}
DONE;
}
[(set_attr "length" "2")])
-(define_insn "*movqi_cc_reg_sp64"
- [(set (match_operand:QI 0 "register_operand" "=r,r")
- (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
- [(match_operand:DI 2 "register_operand" "r,r")
- (const_int 0)])
- (match_operand:QI 3 "arith10_operand" "rM,0")
- (match_operand:QI 4 "arith10_operand" "0,rM")))]
- "TARGET_ARCH64"
- "@
- movr%D1\t%2, %r3, %0
- movr%d1\t%2, %r4, %0"
- [(set_attr "type" "cmove")])
-
-(define_insn "*movhi_cc_reg_sp64"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
- [(match_operand:DI 2 "register_operand" "r,r")
- (const_int 0)])
- (match_operand:HI 3 "arith10_operand" "rM,0")
- (match_operand:HI 4 "arith10_operand" "0,rM")))]
- "TARGET_ARCH64"
- "@
- movr%D1\t%2, %r3, %0
- movr%d1\t%2, %r4, %0"
- [(set_attr "type" "cmove")])
-
-(define_insn "*movsi_cc_reg_sp64"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
- [(match_operand:DI 2 "register_operand" "r,r")
- (const_int 0)])
- (match_operand:SI 3 "arith10_operand" "rM,0")
- (match_operand:SI 4 "arith10_operand" "0,rM")))]
- "TARGET_ARCH64"
- "@
- movr%D1\t%2, %r3, %0
- movr%d1\t%2, %r4, %0"
- [(set_attr "type" "cmove")])
-
-(define_insn "*movdi_cc_reg_sp64"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
- [(match_operand:DI 2 "register_operand" "r,r")
- (const_int 0)])
- (match_operand:DI 3 "arith10_operand" "rM,0")
- (match_operand:DI 4 "arith10_operand" "0,rM")))]
- "TARGET_ARCH64"
- "@
- movr%D1\t%2, %r3, %0
- movr%d1\t%2, %r4, %0"
- [(set_attr "type" "cmove")])
-
-(define_insn "*movsf_cc_reg_sp64"
- [(set (match_operand:SF 0 "register_operand" "=f,f")
- (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
- [(match_operand:DI 2 "register_operand" "r,r")
- (const_int 0)])
- (match_operand:SF 3 "register_operand" "f,0")
- (match_operand:SF 4 "register_operand" "0,f")))]
- "TARGET_ARCH64 && TARGET_FPU"
- "@
- fmovrs%D1\t%2, %3, %0
- fmovrs%d1\t%2, %4, %0"
- [(set_attr "type" "fpcrmove")])
-
-(define_insn "movdf_cc_reg_sp64"
- [(set (match_operand:DF 0 "register_operand" "=e,e")
- (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
- [(match_operand:DI 2 "register_operand" "r,r")
- (const_int 0)])
- (match_operand:DF 3 "register_operand" "e,0")
- (match_operand:DF 4 "register_operand" "0,e")))]
- "TARGET_ARCH64 && TARGET_FPU"
- "@
- fmovrd%D1\t%2, %3, %0
- fmovrd%d1\t%2, %4, %0"
- [(set_attr "type" "fpcrmove")
- (set_attr "fptype" "double")])
-
-(define_insn "*movtf_cc_reg_hq_sp64"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
- [(match_operand:DI 2 "register_operand" "r,r")
- (const_int 0)])
- (match_operand:TF 3 "register_operand" "e,0")
- (match_operand:TF 4 "register_operand" "0,e")))]
- "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
- "@
- fmovrq%D1\t%2, %3, %0
- fmovrq%d1\t%2, %4, %0"
- [(set_attr "type" "fpcrmove")])
-
(define_insn_and_split "*movtf_cc_reg_sp64"
[(set (match_operand:TF 0 "register_operand" "=e,e")
(if_then_else:TF (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
- (match_operand:TF 3 "register_operand" "e,0")
- (match_operand:TF 4 "register_operand" "0,e")))]
+ (match_operand:TF 3 "register_operand" "e,0")
+ (match_operand:TF 4 "register_operand" "0,e")))]
"TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
"#"
"&& reload_completed"
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 29119ed16bb..abaf29d7333 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -898,13 +898,22 @@
rtx lit, scratch;
unsigned word_off, byte_off;
- gcc_assert (GET_CODE (operands[1]) == SUBREG);
- lit = SUBREG_REG (operands[1]);
- scratch = operands[2];
- word_off = SUBREG_BYTE (operands[1]) & ~(UNITS_PER_WORD - 1);
- byte_off = SUBREG_BYTE (operands[1]) - word_off;
+ if (MEM_P (operands[1]))
+ {
+ lit = operands[1];
+ word_off = 0;
+ byte_off = 0;
+ }
+ else
+ {
+ gcc_assert (GET_CODE (operands[1]) == SUBREG);
+ lit = SUBREG_REG (operands[1]);
+ word_off = SUBREG_BYTE (operands[1]) & ~(UNITS_PER_WORD - 1);
+ byte_off = SUBREG_BYTE (operands[1]) - word_off;
+ }
lit = adjust_address (lit, SImode, word_off);
+ scratch = operands[2];
emit_insn (gen_movsi (scratch, lit));
emit_insn (gen_mov<mode> (operands[0],
gen_rtx_SUBREG (<MODE>mode, scratch, byte_off)));
diff --git a/gcc/doc/gccint.texi b/gcc/doc/gccint.texi
index 6acc2d28190..1d127cb7f67 100644
--- a/gcc/doc/gccint.texi
+++ b/gcc/doc/gccint.texi
@@ -110,8 +110,10 @@ Additional tutorial information is linked to from
* Passes:: Order of passes, what they do, and what each file is for.
* Trees:: The source representation used by the C and C++ front ends.
* RTL:: The intermediate representation that most passes work on.
+* GENERIC:: Language-independent representation generated by Front Ends
+* GIMPLE:: Tuple representation used by Tree SSA optimizers
+* Tree SSA:: Analysis and optimization of GIMPLE
* Control Flow:: Maintaining and manipulating the control flow graph.
-* Tree SSA:: Analysis and optimization of the tree representation.
* MELT:: the Middle End Lisp Translator.
* Loop Analysis and Representation:: Analysis and representation of loops
* Machine Desc:: How to write machine description instruction patterns.
@@ -143,10 +145,12 @@ Additional tutorial information is linked to from
@include options.texi
@include passes.texi
@include c-tree.texi
+@include rtl.texi
+@include generic.texi
+@include gimple.texi
@include tree-ssa.texi
@include melt.texi
@include loop.texi
-@include rtl.texi
@include cfg.texi
@include md.texi
@include tm.texi
diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi
new file mode 100644
index 00000000000..14284cc397e
--- /dev/null
+++ b/gcc/doc/generic.texi
@@ -0,0 +1,179 @@
+@c Copyright (c) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+@c Free Software Foundation, Inc.
+@c This is part of the GCC manual.
+@c For copying conditions, see the file gcc.texi.
+
+@c ---------------------------------------------------------------------
+@c GENERIC
+@c ---------------------------------------------------------------------
+
+@node GENERIC
+@chapter GENERIC
+@cindex GENERIC
+
+The purpose of GENERIC is simply to provide a
+language-independent way of representing an entire function in
+trees. To this end, it was necessary to add a few new tree codes
+to the back end, but most everything was already there. If you
+can express it with the codes in @code{gcc/tree.def}, it's
+GENERIC@.
+
+Early on, there was a great deal of debate about how to think
+about statements in a tree IL@. In GENERIC, a statement is
+defined as any expression whose value, if any, is ignored. A
+statement will always have @code{TREE_SIDE_EFFECTS} set (or it
+will be discarded), but a non-statement expression may also have
+side effects. A @code{CALL_EXPR}, for instance.
+
+It would be possible for some local optimizations to work on the
+GENERIC form of a function; indeed, the adapted tree inliner
+works fine on GENERIC, but the current compiler performs inlining
+after lowering to GIMPLE (a restricted form described in the next
+section). Indeed, currently the frontends perform this lowering
+before handing off to @code{tree_rest_of_compilation}, but this
+seems inelegant.
+
+If necessary, a front end can use some language-dependent tree
+codes in its GENERIC representation, so long as it provides a
+hook for converting them to GIMPLE and doesn't expect them to
+work with any (hypothetical) optimizers that run before the
+conversion to GIMPLE@. The intermediate representation used while
+parsing C and C++ looks very little like GENERIC, but the C and
+C++ gimplifier hooks are perfectly happy to take it as input and
+spit out GIMPLE@.
+
+@menu
+* Statements::
+@end menu
+
+@node Statements
+@section Statements
+@cindex Statements
+
+Most statements in GIMPLE are assignment statements, represented by
+@code{GIMPLE_ASSIGN}. No other C expressions can appear at statement level;
+a reference to a volatile object is converted into a
+@code{GIMPLE_ASSIGN}.
+
+There are also several varieties of complex statements.
+
+@menu
+* Blocks::
+* Statement Sequences::
+* Empty Statements::
+* Jumps::
+* Cleanups::
+@end menu
+
+@node Blocks
+@subsection Blocks
+@cindex Blocks
+
+Block scopes and the variables they declare in GENERIC are
+expressed using the @code{BIND_EXPR} code, which in previous
+versions of GCC was primarily used for the C statement-expression
+extension.
+
+Variables in a block are collected into @code{BIND_EXPR_VARS} in
+declaration order. Any runtime initialization is moved out of
+@code{DECL_INITIAL} and into a statement in the controlled block.
+When gimplifying from C or C++, this initialization replaces the
+@code{DECL_STMT}.
+
+Variable-length arrays (VLAs) complicate this process, as their
+size often refers to variables initialized earlier in the block.
+To handle this, we currently split the block at that point, and
+move the VLA into a new, inner @code{BIND_EXPR}. This strategy
+may change in the future.
+
+A C++ program will usually contain more @code{BIND_EXPR}s than
+there are syntactic blocks in the source code, since several C++
+constructs have implicit scopes associated with them. On the
+other hand, although the C++ front end uses pseudo-scopes to
+handle cleanups for objects with destructors, these don't
+translate into the GIMPLE form; multiple declarations at the same
+level use the same @code{BIND_EXPR}.
+
+@node Statement Sequences
+@subsection Statement Sequences
+@cindex Statement Sequences
+
+Multiple statements at the same nesting level are collected into
+a @code{STATEMENT_LIST}. Statement lists are modified and
+traversed using the interface in @samp{tree-iterator.h}.
+
+@node Empty Statements
+@subsection Empty Statements
+@cindex Empty Statements
+
+Whenever possible, statements with no effect are discarded. But
+if they are nested within another construct which cannot be
+discarded for some reason, they are instead replaced with an
+empty statement, generated by @code{build_empty_stmt}.
+Initially, all empty statements were shared, after the pattern of
+the Java front end, but this caused a lot of trouble in practice.
+
+An empty statement is represented as @code{(void)0}.
+
+@node Jumps
+@subsection Jumps
+@cindex Jumps
+
+Other jumps are expressed by either @code{GOTO_EXPR} or
+@code{RETURN_EXPR}.
+
+The operand of a @code{GOTO_EXPR} must be either a label or a
+variable containing the address to jump to.
+
+The operand of a @code{RETURN_EXPR} is either @code{NULL_TREE},
+@code{RESULT_DECL}, or a @code{MODIFY_EXPR} which sets the return
+value. It would be nice to move the @code{MODIFY_EXPR} into a
+separate statement, but the special return semantics in
+@code{expand_return} make that difficult. It may still happen in
+the future, perhaps by moving most of that logic into
+@code{expand_assignment}.
+
+@node Cleanups
+@subsection Cleanups
+@cindex Cleanups
+
+Destructors for local C++ objects and similar dynamic cleanups are
+represented in GIMPLE by a @code{TRY_FINALLY_EXPR}.
+@code{TRY_FINALLY_EXPR} has two operands, both of which are a sequence
+of statements to execute. The first sequence is executed. When it
+completes the second sequence is executed.
+
+The first sequence may complete in the following ways:
+
+@enumerate
+
+@item Execute the last statement in the sequence and fall off the
+end.
+
+@item Execute a goto statement (@code{GOTO_EXPR}) to an ordinary
+label outside the sequence.
+
+@item Execute a return statement (@code{RETURN_EXPR}).
+
+@item Throw an exception. This is currently not explicitly represented in
+GIMPLE.
+
+@end enumerate
+
+The second sequence is not executed if the first sequence completes by
+calling @code{setjmp} or @code{exit} or any other function that does
+not return. The second sequence is also not executed if the first
+sequence completes via a non-local goto or a computed goto (in general
+the compiler does not know whether such a goto statement exits the
+first sequence or not, so we assume that it doesn't).
+
+After the second sequence is executed, if it completes normally by
+falling off the end, execution continues wherever the first sequence
+would have continued, by falling off the end, or doing a goto, etc.
+
+@code{TRY_FINALLY_EXPR} complicates the flow graph, since the cleanup
+needs to appear on every edge out of the controlled block; this
+reduces the freedom to move code across these edges. Therefore, the
+EH lowering pass which runs before most of the optimization passes
+eliminates these expressions by explicitly adding the cleanup to each
+edge. Rethrowing the exception is represented using @code{RESX_EXPR}.
diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi
new file mode 100644
index 00000000000..8277a8ca715
--- /dev/null
+++ b/gcc/doc/gimple.texi
@@ -0,0 +1,2498 @@
+@c Copyright (c) 2008 Free Software Foundation, Inc.
+@c Free Software Foundation, Inc.
+@c This is part of the GCC manual.
+@c For copying conditions, see the file gcc.texi.
+
+@node GIMPLE
+@chapter GIMPLE
+@cindex GIMPLE
+
+GIMPLE is a three-address representation derived from GENERIC by
+breaking down GENERIC expressions into tuples of no more than 3
+operands (with some exceptions like function calls). GIMPLE was
+heavily influenced by the SIMPLE IL used by the McCAT compiler
+project at McGill University, though we have made some different
+choices. For one thing, SIMPLE doesn't support @code{goto}.
+
+Temporaries are introduced to hold intermediate values needed to
+compute complex expressions. Additionally, all the control
+structures used in GENERIC are lowered into conditional jumps,
+lexical scopes are removed and exception regions are converted
+into an on the side exception region tree.
+
+The compiler pass which converts GENERIC into GIMPLE is referred to as
+the @samp{gimplifier}. The gimplifier works recursively, generating
+GIMPLE tuples out of the original GENERIC expressions.
+
+One of the early implementation strategies used for the GIMPLE
+representation was to use the same internal data structures used
+by front ends to represent parse trees. This simplified
+implementation because we could leverage existing functionality
+and interfaces. However, GIMPLE is a much more restrictive
+representation than abstract syntax trees (AST), therefore it
+does not require the full structural complexity provided by the
+main tree data structure.
+
+The GENERIC representation of a function is stored in the
+@code{DECL_SAVED_TREE} field of the associated @code{FUNCTION_DECL}
+tree node. It is converted to GIMPLE by a call to
+@code{gimplify_function_tree}.
+
+If a front end wants to include language-specific tree codes in the tree
+representation which it provides to the back end, it must provide a
+definition of @code{LANG_HOOKS_GIMPLIFY_EXPR} which knows how to
+convert the front end trees to GIMPLE@. Usually such a hook will involve
+much of the same code for expanding front end trees to RTL@. This function
+can return fully lowered GIMPLE, or it can return GENERIC trees and let the
+main gimplifier lower them the rest of the way; this is often simpler.
+GIMPLE that is not fully lowered is known as ``High GIMPLE'' and
+consists of the IL before the pass @code{pass_lower_cf}. High GIMPLE
+contains some container statements like lexical scopes
+(represented by @code{GIMPLE_BIND}) and nested expressions (e.g.,
+@code{GIMPLE_TRY}), while ``Low GIMPLE'' exposes all of the
+implicit jumps for control and exception expressions directly in
+the IL and EH region trees.
+
+The C and C++ front ends currently convert directly from front end
+trees to GIMPLE, and hand that off to the back end rather than first
+converting to GENERIC@. Their gimplifier hooks know about all the
+@code{_STMT} nodes and how to convert them to GENERIC forms. There
+was some work done on a genericization pass which would run first, but
+the existence of @code{STMT_EXPR} meant that in order to convert all
+of the C statements into GENERIC equivalents would involve walking the
+entire tree anyway, so it was simpler to lower all the way. This
+might change in the future if someone writes an optimization pass
+which would work better with higher-level trees, but currently the
+optimizers all expect GIMPLE@.
+
+You can request to dump a C-like representation of the GIMPLE form
+with the flag @option{-fdump-tree-gimple}.
+
+@menu
+* Tuple representation::
+* GIMPLE instruction set::
+* GIMPLE Exception Handling::
+* Temporaries::
+* Operands::
+* Manipulating GIMPLE statements::
+* Tuple specific accessors::
+* GIMPLE sequences::
+* Sequence iterators::
+* Adding a new GIMPLE statement code::
+* Statement and operand traversals::
+@end menu
+
+@node Tuple representation
+@section Tuple representation
+@cindex tuples
+
+GIMPLE instructions are tuples of variable size divided in two
+groups: a header describing the instruction and its locations,
+and a variable length body with all the operands. Tuples are
+organized into a hierarchy with 3 main classes of tuples.
+
+@subsection @code{gimple_statement_base} (gsbase)
+@cindex gimple_statement_base
+
+This is the root of the hierarchy, it holds basic information
+needed by most GIMPLE statements. There are some fields that
+may not be relevant to every GIMPLE statement, but those were
+moved into the base structure to take advantage of holes left by
+other fields (thus making the structure more compact). The
+structure takes 4 words (32 bytes) on 64 bit hosts:
+
+@multitable {@code{references_memory_p}} {Size (bits)}
+@item Field @tab Size (bits)
+@item @code{code} @tab 8
+@item @code{subcode} @tab 16
+@item @code{no_warning} @tab 1
+@item @code{visited} @tab 1
+@item @code{nontemporal_move} @tab 1
+@item @code{plf} @tab 2
+@item @code{modifed} @tab 1
+@item @code{has_volatile_ops} @tab 1
+@item @code{references_memory_p} @tab 1
+@item @code{uid} @tab 32
+@item @code{location} @tab 32
+@item @code{num_ops} @tab 32
+@item @code{bb} @tab 64
+@item @code{block} @tab 63
+@item Total size @tab 32 bytes
+@end multitable
+
+@itemize @bullet
+@item @code{code}
+Main identifier for a GIMPLE instruction.
+
+@item @code{subcode}
+Used to distinguish different variants of the same basic
+instruction or provide flags applicable to a given code. The
+@code{subcode} flags field has different uses depending on the code of
+the instruction, but mostly it distinguishes instructions of the
+same family. The most prominent use of this field is in
+assignments, where subcode indicates the operation done on the
+RHS of the assignment. For example, a = b + c is encoded as
+@code{GIMPLE_ASSIGN <PLUS_EXPR, a, b, c>}.
+
+@item @code{no_warning}
+Bitflag to indicate whether a warning has already been issued on
+this statement.
+
+@item @code{visited}
+General purpose ``visited'' marker. Set and cleared by each pass
+when needed.
+
+@item @code{nontemporal_move}
+Bitflag used in assignments that represent non-temporal moves.
+Although this bitflag is only used in assignments, it was moved
+into the base to take advantage of the bit holes left by the
+previous fields.
+
+@item @code{plf}
+Pass Local Flags. This 2-bit mask can be used as general purpose
+markers by any pass. Passes are responsible for clearing and
+setting these two flags accordingly.
+
+@item @code{modified}
+Bitflag to indicate whether the statement has been modified.
+Used mainly by the operand scanner to determine when to re-scan a
+statement for operands.
+
+@item @code{has_volatile_ops}
+Bitflag to indicate whether this statement contains operands that
+have been marked volatile.
+
+@item @code{references_memory_p}
+Bitflag to indicate whether this statement contains memory
+references (i.e., its operands are either global variables, or
+pointer dereferences or anything that must reside in memory).
+
+@item @code{uid}
+This is an unsigned integer used by passes that want to assign
+IDs to every statement. These IDs must be assigned and used by
+each pass.
+
+@item @code{location}
+This is a @code{location_t} identifier to specify source code
+location for this statement. It is inherited from the front
+end.
+
+@item @code{num_ops}
+Number of operands that this statement has. This specifies the
+size of the operand vector embedded in the tuple. Only used in
+some tuples, but it is declared in the base tuple to take
+advantage of the 32-bit hole left by the previous fields.
+
+@item @code{bb}
+Basic block holding the instruction.
+
+@item @code{block}
+Lexical block holding this statement. Also used for debug
+information generation.
+@end itemize
+
+@subsection @code{gimple_statement_with_ops}
+@cindex gimple_statement_with_ops
+
+This tuple is actually split in two:
+@code{gimple_statement_with_ops_base} and
+@code{gimple_statement_with_ops}. This is needed to accommodate the
+way the operand vector is allocated. The operand vector is
+defined to be an array of 1 element. So, to allocate a dynamic
+number of operands, the memory allocator (@code{gimple_alloc}) simply
+allocates enough memory to hold the structure itself plus @code{N
+- 1} operands which run ``off the end'' of the structure. For
+example, to allocate space for a tuple with 3 operands,
+@code{gimple_alloc} reserves @code{sizeof (struct
+gimple_statement_with_ops) + 2 * sizeof (tree)} bytes.
+
+On the other hand, several fields in this tuple need to be shared
+with the @code{gimple_statement_with_memory_ops} tuple. So, these
+common fields are placed in @code{gimple_statement_with_ops_base} which
+is then inherited from the other two tuples.
+
+
+@multitable {@code{addresses_taken}} {56 + 8 * @code{num_ops} bytes}
+@item @code{gsbase} @tab 256
+@item @code{addresses_taken} @tab 64
+@item @code{def_ops} @tab 64
+@item @code{use_ops} @tab 64
+@item @code{op} @tab @code{num_ops} * 64
+@item Total size @tab 56 + 8 * @code{num_ops} bytes
+@end multitable
+
+@itemize @bullet
+@item @code{gsbase}
+Inherited from @code{struct gimple_statement_base}.
+
+@item @code{addresses_taken}
+Bitmap holding the UIDs of all the @code{VAR_DECL}s whose addresses are
+taken by this statement. For example, a statement of the form
+@code{p = &b} will have the UID for symbol @code{b} in this set.
+
+@item @code{def_ops}
+Array of pointers into the operand array indicating all the slots that
+contain a variable written-to by the statement. This array is
+also used for immediate use chaining. Note that it would be
+possible to not rely on this array, but the changes required to
+implement this are pretty invasive.
+
+@item @code{use_ops}
+Similar to @code{def_ops} but for variables read by the statement.
+
+@item @code{op}
+Array of trees with @code{num_ops} slots.
+@end itemize
+
+@subsection @code{gimple_statement_with_memory_ops}
+
+This tuple is essentially identical to @code{gimple_statement_with_ops},
+except that it contains 4 additional fields to hold vectors
+related memory stores and loads. Similar to the previous case,
+the structure is split in two to accomodate for the operand
+vector (@code{gimple_statement_with_memory_ops_base} and
+@code{gimple_statement_with_memory_ops}).
+
+
+@multitable {@code{addresses_taken}} {88 + 8 * @code{num_ops} bytes}
+@item Field @tab Size (bits)
+@item @code{gsbase} @tab 256
+@item @code{addresses_taken} @tab 64
+@item @code{def_ops} @tab 64
+@item @code{use_ops} @tab 64
+@item @code{vdef_ops} @tab 64
+@item @code{vuse_ops} @tab 64
+@item @code{stores} @tab 64
+@item @code{loads} @tab 64
+@item @code{op} @tab @code{num_ops} * 64
+@item Total size @tab 88 + 8 * @code{num_ops} bytes
+@end multitable
+
+@itemize @bullet
+@item @code{vdef_ops}
+Similar to @code{def_ops} but for @code{VDEF} operators. There is
+one entry per memory symbol written by this statement. This is
+used to maintain the memory SSA use-def and def-def chains.
+
+@item @code{vuse_ops}
+Similar to @code{use_ops} but for @code{VUSE} operators. There is
+one entry per memory symbol loaded by this statement. This is
+used to maintain the memory SSA use-def chains.
+
+@item @code{stores}
+Bitset with all the UIDs for the symbols written-to by the
+statement. This is different than @code{vdef_ops} in that all the
+affected symbols are mentioned in this set. If memory
+partitioning is enabled, the @code{vdef_ops} vector will refer to memory
+partitions. Furthermore, no SSA information is stored in this
+set.
+
+@item @code{loads}
+Similar to @code{stores}, but for memory loads. (Note that there
+is some amount of redundancy here, it should be possible to
+reduce memory utilization further by removing these sets).
+@end itemize
+
+All the other tuples are defined in terms of these three basic
+ones. Each tuple will add some fields. The main gimple type
+is defined to be the union of all these structures (@code{GTY} markers
+elided for clarity):
+
+@smallexample
+union gimple_statement_d
+@{
+ struct gimple_statement_base gsbase;
+ struct gimple_statement_with_ops gsops;
+ struct gimple_statement_with_memory_ops gsmem;
+ struct gimple_statement_omp omp;
+ struct gimple_statement_bind gimple_bind;
+ struct gimple_statement_catch gimple_catch;
+ struct gimple_statement_eh_filter gimple_eh_filter;
+ struct gimple_statement_phi gimple_phi;
+ struct gimple_statement_resx gimple_resx;
+ struct gimple_statement_try gimple_try;
+ struct gimple_statement_wce gimple_wce;
+ struct gimple_statement_asm gimple_asm;
+ struct gimple_statement_omp_critical gimple_omp_critical;
+ struct gimple_statement_omp_for gimple_omp_for;
+ struct gimple_statement_omp_parallel gimple_omp_parallel;
+ struct gimple_statement_omp_task gimple_omp_task;
+ struct gimple_statement_omp_sections gimple_omp_sections;
+ struct gimple_statement_omp_single gimple_omp_single;
+ struct gimple_statement_omp_continue gimple_omp_continue;
+ struct gimple_statement_omp_atomic_load gimple_omp_atomic_load;
+ struct gimple_statement_omp_atomic_store gimple_omp_atomic_store;
+@};
+@end smallexample
+
+
+@node GIMPLE instruction set
+@section GIMPLE instruction set
+@cindex GIMPLE instruction set
+
+The following table briefly describes the GIMPLE instruction set.
+
+@multitable {@code{GIMPLE_CHANGE_DYNAMIC_TYPE}} {High GIMPLE} {Low GIMPLE}
+@item Instruction @tab High GIMPLE @tab Low GIMPLE
+@item @code{GIMPLE_ASM} @tab x @tab x
+@item @code{GIMPLE_ASSIGN} @tab x @tab x
+@item @code{GIMPLE_BIND} @tab x @tab
+@item @code{GIMPLE_CALL} @tab x @tab x
+@item @code{GIMPLE_CATCH} @tab x @tab
+@item @code{GIMPLE_CHANGE_DYNAMIC_TYPE} @tab x @tab x
+@item @code{GIMPLE_COND} @tab x @tab x
+@item @code{GIMPLE_EH_FILTER} @tab x @tab
+@item @code{GIMPLE_GOTO} @tab x @tab x
+@item @code{GIMPLE_LABEL} @tab x @tab x
+@item @code{GIMPLE_NOP} @tab x @tab x
+@item @code{GIMPLE_OMP_ATOMIC_LOAD} @tab x @tab x
+@item @code{GIMPLE_OMP_ATOMIC_STORE} @tab x @tab x
+@item @code{GIMPLE_OMP_CONTINUE} @tab x @tab x
+@item @code{GIMPLE_OMP_CRITICAL} @tab x @tab x
+@item @code{GIMPLE_OMP_FOR} @tab x @tab x
+@item @code{GIMPLE_OMP_MASTER} @tab x @tab x
+@item @code{GIMPLE_OMP_ORDERED} @tab x @tab x
+@item @code{GIMPLE_OMP_PARALLEL} @tab x @tab x
+@item @code{GIMPLE_OMP_RETURN} @tab x @tab x
+@item @code{GIMPLE_OMP_SECTION} @tab x @tab x
+@item @code{GIMPLE_OMP_SECTIONS} @tab x @tab x
+@item @code{GIMPLE_OMP_SECTIONS_SWITCH} @tab x @tab x
+@item @code{GIMPLE_OMP_SINGLE} @tab x @tab x
+@item @code{GIMPLE_PHI} @tab @tab x
+@item @code{GIMPLE_RESX} @tab @tab x
+@item @code{GIMPLE_RETURN} @tab x @tab x
+@item @code{GIMPLE_SWITCH} @tab x @tab x
+@item @code{GIMPLE_TRY} @tab x @tab
+@end multitable
+
+@node GIMPLE Exception Handling
+@section Exception Handling
+@cindex GIMPLE Exception Handling
+
+Other exception handling constructs are represented using
+@code{GIMPLE_TRY_CATCH}. @code{GIMPLE_TRY_CATCH} has two operands. The
+first operand is a sequence of statements to execute. If executing
+these statements does not throw an exception, then the second operand
+is ignored. Otherwise, if an exception is thrown, then the second
+operand of the @code{GIMPLE_TRY_CATCH} is checked. The second
+operand may have the following forms:
+
+@enumerate
+
+@item A sequence of statements to execute. When an exception occurs,
+these statements are executed, and then the exception is rethrown.
+
+@item A sequence of @code{GIMPLE_CATCH} statements. Each
+@code{GIMPLE_CATCH} has a list of applicable exception types and
+handler code. If the thrown exception matches one of the caught
+types, the associated handler code is executed. If the handler
+code falls off the bottom, execution continues after the original
+@code{GIMPLE_TRY_CATCH}.
+
+@item An @code{GIMPLE_EH_FILTER} statement. This has a list of
+permitted exception types, and code to handle a match failure. If the
+thrown exception does not match one of the allowed types, the
+associated match failure code is executed. If the thrown exception
+does match, it continues unwinding the stack looking for the next
+handler.
+
+@end enumerate
+
+Currently throwing an exception is not directly represented in
+GIMPLE, since it is implemented by calling a function. At some
+point in the future we will want to add some way to express that
+the call will throw an exception of a known type.
+
+Just before running the optimizers, the compiler lowers the
+high-level EH constructs above into a set of @samp{goto}s, magic
+labels, and EH regions. Continuing to unwind at the end of a
+cleanup is represented with a @code{GIMPLE_RESX}.
+
+
+@node Temporaries
+@section Temporaries
+@cindex Temporaries
+
+When gimplification encounters a subexpression that is too
+complex, it creates a new temporary variable to hold the value of
+the subexpression, and adds a new statement to initialize it
+before the current statement. These special temporaries are known
+as @samp{expression temporaries}, and are allocated using
+@code{get_formal_tmp_var}. The compiler tries to always evaluate
+identical expressions into the same temporary, to simplify
+elimination of redundant calculations.
+
+We can only use expression temporaries when we know that it will
+not be reevaluated before its value is used, and that it will not
+be otherwise modified@footnote{These restrictions are derived
+from those in Morgan 4.8.}. Other temporaries can be allocated
+using @code{get_initialized_tmp_var} or @code{create_tmp_var}.
+
+Currently, an expression like @code{a = b + 5} is not reduced any
+further. We tried converting it to something like
+@smallexample
+ T1 = b + 5;
+ a = T1;
+@end smallexample
+but this bloated the representation for minimal benefit. However, a
+variable which must live in memory cannot appear in an expression; its
+value is explicitly loaded into a temporary first. Similarly, storing
+the value of an expression to a memory variable goes through a
+temporary.
+
+@node Operands
+@section Operands
+@cindex Operands
+
+In general, expressions in GIMPLE consist of an operation and the
+appropriate number of simple operands; these operands must either be a
+GIMPLE rvalue (@code{is_gimple_val}), i.e.@: a constant or a register
+variable. More complex operands are factored out into temporaries, so
+that
+@smallexample
+ a = b + c + d
+@end smallexample
+becomes
+@smallexample
+ T1 = b + c;
+ a = T1 + d;
+@end smallexample
+
+The same rule holds for arguments to a @code{GIMPLE_CALL}.
+
+The target of an assignment is usually a variable, but can also be an
+@code{INDIRECT_REF} or a compound lvalue as described below.
+
+@menu
+* Compound Expressions::
+* Compound Lvalues::
+* Conditional Expressions::
+* Logical Operators::
+@end menu
+
+@node Compound Expressions
+@subsection Compound Expressions
+@cindex Compound Expressions
+
+The left-hand side of a C comma expression is simply moved into a separate
+statement.
+
+@node Compound Lvalues
+@subsection Compound Lvalues
+@cindex Compound Lvalues
+
+Currently compound lvalues involving array and structure field references
+are not broken down; an expression like @code{a.b[2] = 42} is not reduced
+any further (though complex array subscripts are). This restriction is a
+workaround for limitations in later optimizers; if we were to convert this
+to
+
+@smallexample
+ T1 = &a.b;
+ T1[2] = 42;
+@end smallexample
+
+alias analysis would not remember that the reference to @code{T1[2]} came
+by way of @code{a.b}, so it would think that the assignment could alias
+another member of @code{a}; this broke @code{struct-alias-1.c}. Future
+optimizer improvements may make this limitation unnecessary.
+
+@node Conditional Expressions
+@subsection Conditional Expressions
+@cindex Conditional Expressions
+
+A C @code{?:} expression is converted into an @code{if} statement with
+each branch assigning to the same temporary. So,
+
+@smallexample
+ a = b ? c : d;
+@end smallexample
+becomes
+@smallexample
+ if (b == 1)
+ T1 = c;
+ else
+ T1 = d;
+ a = T1;
+@end smallexample
+
+The GIMPLE level if-conversion pass re-introduces @code{?:}
+expression, if appropriate. It is used to vectorize loops with
+conditions using vector conditional operations.
+
+Note that in GIMPLE, @code{if} statements are represented using
+@code{GIMPLE_COND}, as described below.
+
+@node Logical Operators
+@subsection Logical Operators
+@cindex Logical Operators
+
+Except when they appear in the condition operand of a
+@code{GIMPLE_COND}, logical `and' and `or' operators are simplified
+as follows: @code{a = b && c} becomes
+
+@smallexample
+ T1 = (bool)b;
+ if (T1 == true)
+ T1 = (bool)c;
+ a = T1;
+@end smallexample
+
+Note that @code{T1} in this example cannot be an expression temporary,
+because it has two different assignments.
+
+@subsection Manipulating operands
+
+All gimple operands are of type @code{tree}. But only certain
+types of trees are allowed to be used as operand tuples. Basic
+validation is controlled by the function
+@code{get_gimple_rhs_class}, which given a tree code, returns an
+@code{enum} with the following values of type @code{enum
+gimple_rhs_class}
+
+@itemize @bullet
+@item @code{GIMPLE_INVALID_RHS}
+The tree cannot be used as a GIMPLE operand.
+
+@item @code{GIMPLE_BINARY_RHS}
+The tree is a valid GIMPLE binary operation.
+
+@item @code{GIMPLE_UNARY_RHS}
+The tree is a valid GIMPLE unary operation.
+
+@item @code{GIMPLE_SINGLE_RHS}
+The tree is a single object, that cannot be split into simpler
+operands (for instance, @code{SSA_NAME}, @code{VAR_DECL}, @code{COMPONENT_REF}, etc).
+
+This operand class also acts as an escape hatch for tree nodes
+that may be flattened out into the operand vector, but would need
+more than two slots on the RHS. For instance, a @code{COND_EXPR}
+expression of the form @code{(a op b) ? x : y} could be flattened
+out on the operand vector using 4 slots, but it would also
+require additional processing to distinguish @code{c = a op b}
+from @code{c = a op b ? x : y}. Something similar occurs with
+@code{ASSERT_EXPR}. In time, these special case tree
+expressions should be flattened into the operand vector.
+@end itemize
+
+For tree nodes in the categories @code{GIMPLE_BINARY_RHS} and
+@code{GIMPLE_UNARY_RHS}, they cannot be stored inside tuples directly.
+They first need to be flattened and separated into individual
+components. For instance, given the GENERIC expression
+
+@smallexample
+a = b + c
+@end smallexample
+
+its tree representation is:
+
+@smallexample
+MODIFY_EXPR <VAR_DECL <a>, PLUS_EXPR <VAR_DECL <b>, VAR_DECL <c>>>
+@end smallexample
+
+In this case, the GIMPLE form for this statement is logically
+identical to its GENERIC form but in GIMPLE, the @code{PLUS_EXPR}
+on the RHS of the assignment is not represented as a tree,
+instead the two operands are taken out of the @code{PLUS_EXPR} sub-tree
+and flattened into the GIMPLE tuple as follows:
+
+@smallexample
+GIMPLE_ASSIGN <PLUS_EXPR, VAR_DECL <a>, VAR_DECL <b>, VAR_DECL <c>>
+@end smallexample
+
+@subsection Operand vector allocation
+
+The operand vector is stored at the bottom of the three tuple
+structures that accept operands. This means, that depending on
+the code of a given statement, its operand vector will be at
+different offsets from the base of the structure. To access
+tuple operands use the following accessors
+
+@deftypefn {GIMPLE function} unsigned gimple_num_ops (gimple g)
+Returns the number of operands in statement G.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_op (gimple g, unsigned i)
+Returns operand @code{I} from statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_ops (gimple g)
+Returns a pointer into the operand vector for statement @code{G}. This
+is computed using an internal table called @code{gimple_ops_offset_}[].
+This table is indexed by the gimple code of @code{G}.
+
+When the compiler is built, this table is filled-in using the
+sizes of the structures used by each statement code defined in
+gimple.def. Since the operand vector is at the bottom of the
+structure, for a gimple code @code{C} the offset is computed as sizeof
+(struct-of @code{C}) - sizeof (tree).
+
+This mechanism adds one memory indirection to every access when
+using @code{gimple_op}(), if this becomes a bottleneck, a pass can
+choose to memoize the result from @code{gimple_ops}() and use that to
+access the operands.
+@end deftypefn
+
+@subsection Operand validation
+
+When adding a new operand to a gimple statement, the operand will
+be validated according to what each tuple accepts in its operand
+vector. These predicates are called by the
+@code{gimple_<name>_set_...()}. Each tuple will use one of the
+following predicates (Note, this list is not exhaustive):
+
+@deftypefn {GIMPLE function} is_gimple_operand (tree t)
+This is the most permissive of the predicates. It essentially
+checks whether t has a @code{gimple_rhs_class} of @code{GIMPLE_SINGLE_RHS}.
+@end deftypefn
+
+
+@deftypefn {GIMPLE function} is_gimple_val (tree t)
+Returns true if t is a "GIMPLE value", which are all the
+non-addressable stack variables (variables for which
+@code{is_gimple_reg} returns true) and constants (expressions for which
+@code{is_gimple_min_invariant} returns true).
+@end deftypefn
+
+@deftypefn {GIMPLE function} is_gimple_addressable (tree t)
+Returns true if t is a symbol or memory reference whose address
+can be taken.
+@end deftypefn
+
+@deftypefn {GIMPLE function} is_gimple_asm_val (tree t)
+Similar to @code{is_gimple_val} but it also accepts hard registers.
+@end deftypefn
+
+@deftypefn {GIMPLE function} is_gimple_call_addr (tree t)
+Return true if t is a valid expression to use as the function
+called by a @code{GIMPLE_CALL}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} is_gimple_constant (tree t)
+Return true if t is a valid gimple constant.
+@end deftypefn
+
+@deftypefn {GIMPLE function} is_gimple_min_invariant (tree t)
+Return true if t is a valid minimal invariant. This is different
+from constants, in that the specific value of t may not be known
+at compile time, but it is known that it doesn't change (e.g.,
+the address of a function local variable).
+@end deftypefn
+
+@deftypefn {GIMPLE function} is_gimple_min_invariant_address (tree t)
+Return true if t is an @code{ADDR_EXPR} that does not change once the
+program is running.
+@end deftypefn
+
+
+@subsection Statement validation
+
+@deftypefn {GIMPLE function} is_gimple_assign (gimple g)
+Return true if the code of g is @code{GIMPLE_ASSIGN}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} is_gimple_call (gimple g)
+Return true if the code of g is @code{GIMPLE_CALL}
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_assign_cast_p (gimple g)
+Return true if g is a @code{GIMPLE_ASSIGN} that performs a type cast
+operation
+@end deftypefn
+
+@node Manipulating GIMPLE statements
+@section Manipulating GIMPLE statements
+@cindex Manipulating GIMPLE statements
+
+This section documents all the functions available to handle each
+of the GIMPLE instructions.
+
+@subsection Common accessors
+The following are common accessors for gimple statements.
+
+@deftypefn {GIMPLE function} enum gimple_code gimple_code (gimple g)
+Return the code for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} basic_block gimple_bb (gimple g)
+Return the basic block to which statement @code{G} belongs to.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_block (gimple g)
+Return the lexical scope block holding statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_expr_type (gimple stmt)
+Return the type of the main expression computed by @code{STMT}. Return
+@code{void_type_node} if @code{STMT} computes nothing. This will only return
+something meaningful for @code{GIMPLE_ASSIGN}, @code{GIMPLE_COND} and
+@code{GIMPLE_CALL}. For all other tuple codes, it will return
+@code{void_type_node}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} enum tree_code gimple_expr_code (gimple stmt)
+Return the tree code for the expression computed by @code{STMT}. This
+is only meaningful for @code{GIMPLE_CALL}, @code{GIMPLE_ASSIGN} and
+@code{GIMPLE_COND}. If @code{STMT} is @code{GIMPLE_CALL}, it will return @code{CALL_EXPR}.
+For @code{GIMPLE_COND}, it returns the code of the comparison predicate.
+For @code{GIMPLE_ASSIGN} it returns the code of the operation performed
+by the @code{RHS} of the assignment.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_set_block (gimple g, tree block)
+Set the lexical scope block of @code{G} to @code{BLOCK}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} location_t gimple_locus (gimple g)
+Return locus information for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_set_locus (gimple g, location_t locus)
+Set locus information for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_locus_empty_p (gimple g)
+Return true if @code{G} does not have locus information.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_no_warning_p (gimple stmt)
+Return true if no warnings should be emitted for statement @code{STMT}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_set_visited (gimple stmt, bool visited_p)
+Set the visited status on statement @code{STMT} to @code{VISITED_P}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_visited_p (gimple stmt)
+Return the visited status on statement @code{STMT}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_set_plf (gimple stmt, enum plf_mask plf, bool val_p)
+Set pass local flag @code{PLF} on statement @code{STMT} to @code{VAL_P}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} unsigned int gimple_plf (gimple stmt, enum plf_mask plf)
+Return the value of pass local flag @code{PLF} on statement @code{STMT}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_has_ops (gimple g)
+Return true if statement @code{G} has register or memory operands.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_has_mem_ops (gimple g)
+Return true if statement @code{G} has memory operands.
+@end deftypefn
+
+@deftypefn {GIMPLE function} unsigned gimple_num_ops (gimple g)
+Return the number of operands for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_ops (gimple g)
+Return the array of operands for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_op (gimple g, unsigned i)
+Return operand @code{I} for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_op_ptr (gimple g, unsigned i)
+Return a pointer to operand @code{I} for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_set_op (gimple g, unsigned i, tree op)
+Set operand @code{I} of statement @code{G} to @code{OP}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bitmap gimple_addresses_taken (gimple stmt)
+Return the set of symbols that have had their address taken by
+@code{STMT}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} struct def_optype_d *gimple_def_ops (gimple g)
+Return the set of @code{DEF} operands for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_set_def_ops (gimple g, struct def_optype_d *def)
+Set @code{DEF} to be the set of @code{DEF} operands for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} struct use_optype_d *gimple_use_ops (gimple g)
+Return the set of @code{USE} operands for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_set_use_ops (gimple g, struct use_optype_d *use)
+Set @code{USE} to be the set of @code{USE} operands for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} struct voptype_d *gimple_vuse_ops (gimple g)
+Return the set of @code{VUSE} operands for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_set_vuse_ops (gimple g, struct voptype_d *ops)
+Set @code{OPS} to be the set of @code{VUSE} operands for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} struct voptype_d *gimple_vdef_ops (gimple g)
+Return the set of @code{VDEF} operands for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_set_vdef_ops (gimple g, struct voptype_d *ops)
+Set @code{OPS} to be the set of @code{VDEF} operands for statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bitmap gimple_loaded_syms (gimple g)
+Return the set of symbols loaded by statement @code{G}. Each element of
+the set is the @code{DECL_UID} of the corresponding symbol.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bitmap gimple_stored_syms (gimple g)
+Return the set of symbols stored by statement @code{G}. Each element of
+the set is the @code{DECL_UID} of the corresponding symbol.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_modified_p (gimple g)
+Return true if statement @code{G} has operands and the modified field
+has been set.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_has_volatile_ops (gimple stmt)
+Return true if statement @code{STMT} contains volatile operands.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_set_has_volatile_ops (gimple stmt, bool volatilep)
+Return true if statement @code{STMT} contains volatile operands.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void update_stmt (gimple s)
+Mark statement @code{S} as modified, and update it.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void update_stmt_if_modified (gimple s)
+Update statement @code{S} if it has been marked modified.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple gimple_copy (gimple stmt)
+Return a deep copy of statement @code{STMT}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple gimple_copy_call_skip_args (gimple stmt, bitmap args_to_skip)
+Build a @code{GIMPLE_CALL} identical to @code{STMT} but skipping the arguments
+in the positions marked by the set @code{ARGS_TO_SKIP}.
+@end deftypefn
+
+@node Tuple specific accessors
+@section Tuple specific accessors
+@cindex Tuple specific accessors
+
+@menu
+* @code{GIMPLE_ASM}::
+* @code{GIMPLE_ASSIGN}::
+* @code{GIMPLE_BIND}::
+* @code{GIMPLE_CALL}::
+* @code{GIMPLE_CATCH}::
+* @code{GIMPLE_CHANGE_DYNAMIC_TYPE}::
+* @code{GIMPLE_COND}::
+* @code{GIMPLE_EH_FILTER}::
+* @code{GIMPLE_LABEL}::
+* @code{GIMPLE_NOP}::
+* @code{GIMPLE_OMP_ATOMIC_LOAD}::
+* @code{GIMPLE_OMP_ATOMIC_STORE}::
+* @code{GIMPLE_OMP_CONTINUE}::
+* @code{GIMPLE_OMP_CRITICAL}::
+* @code{GIMPLE_OMP_FOR}::
+* @code{GIMPLE_OMP_MASTER}::
+* @code{GIMPLE_OMP_ORDERED}::
+* @code{GIMPLE_OMP_PARALLEL}::
+* @code{GIMPLE_OMP_RETURN}::
+* @code{GIMPLE_OMP_SECTION}::
+* @code{GIMPLE_OMP_SECTIONS}::
+* @code{GIMPLE_OMP_SINGLE}::
+* @code{GIMPLE_PHI}::
+* @code{GIMPLE_RESX}::
+* @code{GIMPLE_RETURN}::
+* @code{GIMPLE_SWITCH}::
+* @code{GIMPLE_TRY}::
+* @code{GIMPLE_WITH_CLEANUP_EXPR}::
+@end menu
+
+
+@node @code{GIMPLE_ASM}
+@subsection @code{GIMPLE_ASM}
+@cindex @code{GIMPLE_ASM}
+
+@deftypefn {GIMPLE function} gimple gimple_build_asm (const char *string, ninputs, noutputs, nclobbers, ...)
+Build a @code{GIMPLE_ASM} statement. This statement is used for
+building in-line assembly constructs. @code{STRING} is the assembly
+code. @code{NINPUT} is the number of register inputs. @code{NOUTPUT} is the
+number of register outputs. @code{NCLOBBERS} is the number of clobbered
+registers. The rest of the arguments trees for each input,
+output, and clobbered registers.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple gimple_build_asm_vec (const char *, VEC(tree,gc) *, VEC(tree,gc) *, VEC(tree,gc) *)
+Identical to gimple_build_asm, but the arguments are passed in
+VECs.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_asm_ninputs (gimple g)
+Return the number of input operands for @code{GIMPLE_ASM} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_asm_noutputs (gimple g)
+Return the number of output operands for @code{GIMPLE_ASM} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_asm_nclobbers (gimple g)
+Return the number of clobber operands for @code{GIMPLE_ASM} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_asm_input_op (gimple g, unsigned index)
+Return input operand @code{INDEX} of @code{GIMPLE_ASM} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_asm_set_input_op (gimple g, unsigned index, tree in_op)
+Set @code{IN_OP} to be input operand @code{INDEX} in @code{GIMPLE_ASM} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_asm_output_op (gimple g, unsigned index)
+Return output operand @code{INDEX} of @code{GIMPLE_ASM} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_asm_set_output_op (gimple g, unsigne
+index, tree out_op)
+Set @code{OUT_OP} to be output operand @code{INDEX} in @code{GIMPLE_ASM} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_asm_clobber_op (gimple g, unsigned index)
+Return clobber operand @code{INDEX} of @code{GIMPLE_ASM} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_asm_set_clobber_op (gimple g, unsigned index, tree clobber_op)
+Set @code{CLOBBER_OP} to be clobber operand @code{INDEX} in @code{GIMPLE_ASM} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} const char *gimple_asm_string (gimple g)
+Return the string representing the assembly instruction in
+@code{GIMPLE_ASM} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_asm_volatile_p (gimple g)
+Return true if @code{G} is an asm statement marked volatile.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_asm_set_volatile (gimple g)
+Mark asm statement @code{G} as volatile.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_asm_clear_volatile (gimple g)
+Remove volatile marker from asm statement @code{G}.
+@end deftypefn
+
+@node @code{GIMPLE_ASSIGN}
+@subsection @code{GIMPLE_ASSIGN}
+@cindex @code{GIMPLE_ASSIGN}
+
+@deftypefn {GIMPLE function} gimple gimple_build_assign (tree lhs, tree rhs)
+Build a @code{GIMPLE_ASSIGN} statement. The left-hand side is an lvalue
+passed in lhs. The right-hand side can be either a unary or
+binary tree expression. The expression tree rhs will be
+flattened and its operands assigned to the corresponding operand
+slots in the new statement. This function is useful when you
+already have a tree expression that you want to convert into a
+tuple. However, try to avoid building expression trees for the
+sole purpose of calling this function. If you already have the
+operands in separate trees, it is better to use
+@code{gimple_build_assign_with_ops}.
+@end deftypefn
+
+
+@deftypefn {GIMPLE function} gimple gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
+Build a new @code{GIMPLE_ASSIGN} tuple and append it to the end of
+@code{*SEQ_P}.
+@end deftypefn
+
+@code{DST}/@code{SRC} are the destination and source respectively. You can
+pass ungimplified trees in @code{DST} or @code{SRC}, in which
+case they will be converted to a gimple operand if necessary.
+
+This function returns the newly created @code{GIMPLE_ASSIGN} tuple.
+
+@deftypefn {GIMPLE function} gimple gimple_build_assign_with_ops (enum tree_code subcode, tree lhs, tree op1, tree op2)
+This function is similar to @code{gimple_build_assign}, but is used to
+build a @code{GIMPLE_ASSIGN} statement when the operands of the
+right-hand side of the assignment are already split into
+different operands.
+
+The left-hand side is an lvalue passed in lhs. Subcode is the
+@code{tree_code} for the right-hand side of the assignment. Op1 and op2
+are the operands. If op2 is null, subcode must be a @code{tree_code}
+for a unary expression.
+@end deftypefn
+
+@deftypefn {GIMPLE function} enum tree_code gimple_assign_rhs_code (gimple g)
+Return the code of the expression computed on the @code{RHS} of
+assignment statement @code{G}.
+@end deftypefn
+
+
+@deftypefn {GIMPLE function} enum gimple_rhs_class gimple_assign_rhs_class (gimple g)
+Return the gimple rhs class of the code fo the expression
+computed on the rhs of assignment statment @code{G}. This will never
+return @code{GIMPLE_INVALID_RHS}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_assign_lhs (gimple g)
+Return the @code{LHS} of assignment statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_assign_lhs_ptr (gimple g)
+Return a pointer to the @code{LHS} of assignment statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_assign_rhs1 (gimple g)
+Return the first operand on the @code{RHS} of assignment statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_assign_rhs1_ptr (gimple g)
+Return the address of the first operand on the @code{RHS} of assignment
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_assign_rhs2 (gimple g)
+Return the second operand on the @code{RHS} of assignment statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_assign_rhs2_ptr (gimple g)
+Return the address of the second operand on the @code{RHS} of assignment
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_assign_set_lhs (gimple g, tree lhs)
+Set @code{LHS} to be the @code{LHS} operand of assignment statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_assign_set_rhs1 (gimple g, tree rhs)
+Set @code{RHS} to be the first operand on the @code{RHS} of assignment
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_assign_rhs2 (gimple g)
+Return the second operand on the @code{RHS} of assignment statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_assign_rhs2_ptr (gimple g)
+Return a pointer to the second operand on the @code{RHS} of assignment
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_assign_set_rhs2 (gimple g, tree rhs)
+Set @code{RHS} to be the second operand on the @code{RHS} of assignment
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_assign_cast_p (gimple s)
+Return true if @code{S} is an type-cast assignment.
+@end deftypefn
+
+
+@node @code{GIMPLE_BIND}
+@subsection @code{GIMPLE_BIND}
+@cindex @code{GIMPLE_BIND}
+
+@deftypefn {GIMPLE function} gimple gimple_build_bind (tree vars, gimple_seq body)
+Build a @code{GIMPLE_BIND} statement with a list of variables in @code{VARS}
+and a body of statements in sequence @code{BODY}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_bind_vars (gimple g)
+Return the variables declared in the @code{GIMPLE_BIND} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_bind_set_vars (gimple g, tree vars)
+Set @code{VARS} to be the set of variables declared in the @code{GIMPLE_BIND}
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_bind_append_vars (gimple g, tree vars)
+Append @code{VARS} to the set of variables declared in the @code{GIMPLE_BIND}
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gimple_bind_body (gimple g)
+Return the GIMPLE sequence contained in the @code{GIMPLE_BIND} statement
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_bind_set_body (gimple g, gimple_seq seq)
+Set @code{SEQ} to be sequence contained in the @code{GIMPLE_BIND} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_bind_add_stmt (gimple gs, gimple stmt)
+Append a statement to the end of a @code{GIMPLE_BIND}'s body.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_bind_add_seq (gimple gs, gimple_seq seq)
+Append a sequence of statements to the end of a @code{GIMPLE_BIND}'s
+body.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_bind_block (gimple g)
+Return the @code{TREE_BLOCK} node associated with @code{GIMPLE_BIND} statement
+@code{G}. This is analogous to the @code{BIND_EXPR_BLOCK} field in trees.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_bind_set_block (gimple g, tree block)
+Set @code{BLOCK} to be the @code{TREE_BLOCK} node associated with @code{GIMPLE_BIND}
+statement @code{G}.
+@end deftypefn
+
+
+@node @code{GIMPLE_CALL}
+@subsection @code{GIMPLE_CALL}
+@cindex @code{GIMPLE_CALL}
+
+@deftypefn {GIMPLE function} gimple gimple_build_call (tree fn, unsigned nargs, ...)
+Build a @code{GIMPLE_CALL} statement to function @code{FN}. The argument @code{FN}
+must be either a @code{FUNCTION_DECL} or a gimple call address as
+determined by @code{is_gimple_call_addr}. @code{NARGS} are the number of
+arguments. The rest of the arguments follow the argument @code{NARGS},
+and must be trees that are valid as rvalues in gimple (i.e., each
+operand is validated with @code{is_gimple_operand}).
+@end deftypefn
+
+
+@deftypefn {GIMPLE function} gimple gimple_build_call_from_tree (tree call_expr)
+Build a @code{GIMPLE_CALL} from a @code{CALL_EXPR} node. The arguments and the
+function are taken from the expression directly. This routine
+assumes that @code{call_expr} is already in GIMPLE form. That is, its
+operands are GIMPLE values and the function call needs no further
+simplification. All the call flags in @code{call_expr} are copied over
+to the new @code{GIMPLE_CALL}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple gimple_build_call_vec (tree fn, @code{VEC}(tree, heap) *args)
+Identical to @code{gimple_build_call} but the arguments are stored in a
+@code{VEC}().
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_call_lhs (gimple g)
+Return the @code{LHS} of call statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_call_lhs_ptr (gimple g)
+Return a pointer to the @code{LHS} of call statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_call_set_lhs (gimple g, tree lhs)
+Set @code{LHS} to be the @code{LHS} operand of call statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_call_fn (gimple g)
+Return the tree node representing the function called by call
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_call_set_fn (gimple g, tree fn)
+Set @code{FN} to be the function called by call statement @code{G}. This has
+to be a gimple value specifying the address of the called
+function.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_call_fndecl (gimple g)
+If a given @code{GIMPLE_CALL}'s callee is a @code{FUNCTION_DECL}, return it.
+Otherwise return @code{NULL}. This function is analogous to
+@code{get_callee_fndecl} in @code{GENERIC}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_call_set_fndecl (gimple g, tree fndecl)
+Set the called function to @code{FNDECL}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_call_return_type (gimple g)
+Return the type returned by call statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_call_chain (gimple g)
+Return the static chain for call statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_call_set_chain (gimple g, tree chain)
+Set @code{CHAIN} to be the static chain for call statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_call_num_args (gimple g)
+Return the number of arguments used by call statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_call_arg (gimple g, unsigned index)
+Return the argument at position @code{INDEX} for call statement @code{G}. The
+first argument is 0.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_call_arg_ptr (gimple g, unsigned index)
+Return a pointer to the argument at position @code{INDEX} for call
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_call_set_arg (gimple g, unsigned index, tree arg)
+Set @code{ARG} to be the argument at position @code{INDEX} for call statement
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_call_set_tail (gimple s)
+Mark call statement @code{S} as being a tail call (i.e., a call just
+before the exit of a function). These calls are candidate for
+tail call optimization.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_call_tail_p (gimple s)
+Return true if @code{GIMPLE_CALL} @code{S} is marked as a tail call.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_call_mark_uninlinable (gimple s)
+Mark @code{GIMPLE_CALL} @code{S} as being uninlinable.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_call_cannot_inline_p (gimple s)
+Return true if @code{GIMPLE_CALL} @code{S} cannot be inlined.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_call_noreturn_p (gimple s)
+Return true if @code{S} is a noreturn call.
+@end deftypefn
+
+
+@node @code{GIMPLE_CATCH}
+@subsection @code{GIMPLE_CATCH}
+@cindex @code{GIMPLE_CATCH}
+
+@deftypefn {GIMPLE function} gimple gimple_build_catch (tree types, gimple_seq handler)
+Build a @code{GIMPLE_CATCH} statement. @code{TYPES} are the tree types this
+catch handles. @code{HANDLER} is a sequence of statements with the code
+for the handler.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_catch_types (gimple g)
+Return the types handled by @code{GIMPLE_CATCH} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_catch_types_ptr (gimple g)
+Return a pointer to the types handled by @code{GIMPLE_CATCH} statement
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gimple_catch_handler (gimple g)
+Return the GIMPLE sequence representing the body of the handler
+of @code{GIMPLE_CATCH} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_catch_set_types (gimple g, tree t)
+Set @code{T} to be the set of types handled by @code{GIMPLE_CATCH} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_catch_set_handler (gimple g, gimple_seq handler)
+Set @code{HANDLER} to be the body of @code{GIMPLE_CATCH} @code{G}.
+@end deftypefn
+
+@node @code{GIMPLE_CHANGE_DYNAMIC_TYPE}
+@subsection @code{GIMPLE_CHANGE_DYNAMIC_TYPE}
+@cindex @code{GIMPLE_CHANGE_DYNAMIC_TYPE}
+
+@deftypefn {GIMPLE function} gimple gimple_build_cdt (tree type, tree ptr)
+Build a @code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement. @code{TYPE} is the new
+type for the location @code{PTR}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_cdt_new_type (gimple g)
+Return the new type set by @code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_cdt_new_type_ptr (gimple g)
+Return a pointer to the new type set by
+@code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_cdt_set_new_type (gimple g, tree new_type)
+Set @code{NEW_TYPE} to be the type returned by
+@code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_cdt_location (gimple g)
+Return the location affected by @code{GIMPLE_CHANGE_DYNAMIC_TYPE}
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_cdt_location_ptr (gimple g)
+Return a pointer to the location affected by
+@code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_cdt_set_location (gimple g, tree ptr)
+Set @code{PTR} to be the location affected by @code{GIMPLE_CHANGE_DYNAMIC_TYPE}
+statement @code{G}.
+@end deftypefn
+
+
+@node @code{GIMPLE_COND}
+@subsection @code{GIMPLE_COND}
+@cindex @code{GIMPLE_COND}
+
+@deftypefn {GIMPLE function} gimple gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs, tree t_label, tree f_label)
+Build a @code{GIMPLE_COND} statement. @code{A} @code{GIMPLE_COND} statement compares
+@code{LHS} and @code{RHS} and if the condition in @code{PRED_CODE} is true, jump to
+the label in @code{t_label}, otherwise jump to the label in @code{f_label}.
+@code{PRED_CODE} are relational operator tree codes like @code{EQ_EXPR},
+@code{LT_EXPR}, @code{LE_EXPR}, @code{NE_EXPR}, etc.
+@end deftypefn
+
+
+@deftypefn {GIMPLE function} gimple gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label)
+Build a @code{GIMPLE_COND} statement from the conditional expression
+tree @code{COND}. @code{T_LABEL} and @code{F_LABEL} are as in @code{gimple_build_cond}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} enum tree_code gimple_cond_code (gimple g)
+Return the code of the predicate computed by conditional
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_cond_set_code (gimple g, enum tree_code code)
+Set @code{CODE} to be the predicate code for the conditional statement
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_cond_lhs (gimple g)
+Return the @code{LHS} of the predicate computed by conditional statement
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_cond_set_lhs (gimple g, tree lhs)
+Set @code{LHS} to be the @code{LHS} operand of the predicate computed by
+conditional statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_cond_rhs (gimple g)
+Return the @code{RHS} operand of the predicate computed by conditional
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_cond_set_rhs (gimple g, tree rhs)
+Set @code{RHS} to be the @code{RHS} operand of the predicate computed by
+conditional statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_cond_true_label (gimple g)
+Return the label used by conditional statement @code{G} when its
+predicate evaluates to true.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_cond_set_true_label (gimple g, tree label)
+Set @code{LABEL} to be the label used by conditional statement @code{G} when
+its predicate evaluates to true.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_cond_set_false_label (gimple g, tree label)
+Set @code{LABEL} to be the label used by conditional statement @code{G} when
+its predicate evaluates to false.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_cond_false_label (gimple g)
+Return the label used by conditional statement @code{G} when its
+predicate evaluates to false.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_cond_make_false (gimple g)
+Set the conditional @code{COND_STMT} to be of the form 'if (1 == 0)'.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_cond_make_true (gimple g)
+Set the conditional @code{COND_STMT} to be of the form 'if (1 == 1)'.
+@end deftypefn
+
+@node @code{GIMPLE_EH_FILTER}
+@subsection @code{GIMPLE_EH_FILTER}
+@cindex @code{GIMPLE_EH_FILTER}
+
+@deftypefn {GIMPLE function} gimple gimple_build_eh_filter (tree types, gimple_seq failure)
+Build a @code{GIMPLE_EH_FILTER} statement. @code{TYPES} are the filter's
+types. @code{FAILURE} is a sequence with the filter's failure action.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_eh_filter_types (gimple g)
+Return the types handled by @code{GIMPLE_EH_FILTER} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_eh_filter_types_ptr (gimple g)
+Return a pointer to the types handled by @code{GIMPLE_EH_FILTER}
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gimple_eh_filter_failure (gimple g)
+Return the sequence of statement to execute when @code{GIMPLE_EH_FILTER}
+statement fails.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_eh_filter_set_types (gimple g, tree types)
+Set @code{TYPES} to be the set of types handled by @code{GIMPLE_EH_FILTER} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_eh_filter_set_failure (gimple g, gimple_seq failure)
+Set @code{FAILURE} to be the sequence of statements to execute on
+failure for @code{GIMPLE_EH_FILTER} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_eh_filter_must_not_throw (gimple g)
+Return the @code{EH_FILTER_MUST_NOT_THROW} flag.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_eh_filter_set_must_not_throw (gimple g, bool mntp)
+Set the @code{EH_FILTER_MUST_NOT_THROW} flag.
+@end deftypefn
+
+
+@node @code{GIMPLE_LABEL}
+@subsection @code{GIMPLE_LABEL}
+@cindex @code{GIMPLE_LABEL}
+
+@deftypefn {GIMPLE function} gimple gimple_build_label (tree label)
+Build a @code{GIMPLE_LABEL} statement with corresponding to the tree
+label, @code{LABEL}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_label_label (gimple g)
+Return the @code{LABEL_DECL} node used by @code{GIMPLE_LABEL} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_label_set_label (gimple g, tree label)
+Set @code{LABEL} to be the @code{LABEL_DECL} node used by @code{GIMPLE_LABEL}
+statement @code{G}.
+@end deftypefn
+
+
+@deftypefn {GIMPLE function} gimple gimple_build_goto (tree dest)
+Build a @code{GIMPLE_GOTO} statement to label @code{DEST}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_goto_dest (gimple g)
+Return the destination of the unconditional jump @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_goto_set_dest (gimple g, tree dest)
+Set @code{DEST} to be the destination of the unconditonal jump @code{G}.
+@end deftypefn
+
+
+@node @code{GIMPLE_NOP}
+@subsection @code{GIMPLE_NOP}
+@cindex @code{GIMPLE_NOP}
+
+@deftypefn {GIMPLE function} gimple gimple_build_nop (void)
+Build a @code{GIMPLE_NOP} statement.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_nop_p (gimple g)
+Returns @code{TRUE} if statement @code{G} is a @code{GIMPLE_NOP}.
+@end deftypefn
+
+@node @code{GIMPLE_OMP_ATOMIC_LOAD}
+@subsection @code{GIMPLE_OMP_ATOMIC_LOAD}
+@cindex @code{GIMPLE_OMP_ATOMIC_LOAD}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_atomic_load (tree lhs, tree rhs)
+Build a @code{GIMPLE_OMP_ATOMIC_LOAD} statement. @code{LHS} is the left-hand
+side of the assignment. @code{RHS} is the right-hand side of the
+assignment.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_atomic_load_set_lhs (gimple g, tree lhs)
+Set the @code{LHS} of an atomic load.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_atomic_load_lhs (gimple g)
+Get the @code{LHS} of an atomic load.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_atomic_load_set_rhs (gimple g, tree rhs)
+Set the @code{RHS} of an atomic set.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_atomic_load_rhs (gimple g)
+Get the @code{RHS} of an atomic set.
+@end deftypefn
+
+
+@node @code{GIMPLE_OMP_ATOMIC_STORE}
+@subsection @code{GIMPLE_OMP_ATOMIC_STORE}
+@cindex @code{GIMPLE_OMP_ATOMIC_STORE}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_atomic_store (tree val)
+Build a @code{GIMPLE_OMP_ATOMIC_STORE} statement. @code{VAL} is the value to be
+stored.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_atomic_store_set_val (gimple g, tree val)
+Set the value being stored in an atomic store.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_atomic_store_val (gimple g)
+Return the value being stored in an atomic store.
+@end deftypefn
+
+@node @code{GIMPLE_OMP_CONTINUE}
+@subsection @code{GIMPLE_OMP_CONTINUE}
+@cindex @code{GIMPLE_OMP_CONTINUE}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_continue (tree control_def, tree control_use)
+Build a @code{GIMPLE_OMP_CONTINUE} statement. @code{CONTROL_DEF} is the
+definition of the control variable. @code{CONTROL_USE} is the use of
+the control variable.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_continue_control_def (gimple s)
+Return the definition of the control variable on a
+@code{GIMPLE_OMP_CONTINUE} in @code{S}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_continue_control_def_ptr (gimple s)
+Same as above, but return the pointer.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_continue_set_control_def (gimple s)
+Set the control variable definition for a @code{GIMPLE_OMP_CONTINUE}
+statement in @code{S}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_continue_control_use (gimple s)
+Return the use of the control variable on a @code{GIMPLE_OMP_CONTINUE}
+in @code{S}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_continue_control_use_ptr (gimple s)
+Same as above, but return the pointer.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_continue_set_control_use (gimple s)
+Set the control variable use for a @code{GIMPLE_OMP_CONTINUE} statement
+in @code{S}.
+@end deftypefn
+
+
+@node @code{GIMPLE_OMP_CRITICAL}
+@subsection @code{GIMPLE_OMP_CRITICAL}
+@cindex @code{GIMPLE_OMP_CRITICAL}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_critical (gimple_seq body, tree name)
+Build a @code{GIMPLE_OMP_CRITICAL} statement. @code{BODY} is the sequence of
+statements for which only one thread can execute. @code{NAME} is an
+optional identifier for this critical block.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_critical_name (gimple g)
+Return the name associated with @code{OMP_CRITICAL} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_critical_name_ptr (gimple g)
+Return a pointer to the name associated with @code{OMP} critical
+statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_critical_set_name (gimple g, tree name)
+Set @code{NAME} to be the name associated with @code{OMP} critical statement @code{G}.
+@end deftypefn
+
+@node @code{GIMPLE_OMP_FOR}
+@subsection @code{GIMPLE_OMP_FOR}
+@cindex @code{GIMPLE_OMP_FOR}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_for (gimple_seq body, tre
+clauses, tree index, tree initial, tree final, tree incr,
+gimple_seq pre_body, enum tree_code omp_for_cond)
+Build a @code{GIMPLE_OMP_FOR} statement. @code{BODY} is sequence of statements
+inside the for loop. @code{CLAUSES}, are any of the @code{OMP} loop
+construct's clauses: private, firstprivate, lastprivate,
+reductions, ordered, schedule, and nowait. @code{PRE_BODY} is the
+sequence of statements that are loop invariant. @code{INDEX} is the
+index variable. @code{INITIAL} is the initial value of @code{INDEX}. @code{FINAL} is
+final value of @code{INDEX}. OMP_FOR_COND is the predicate used to
+compare @code{INDEX} and @code{FINAL}. @code{INCR} is the increment expression.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_for_clauses (gimple g)
+Return the clauses associated with @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_for_clauses_ptr (gimple g)
+Return a pointer to the @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_for_set_clauses (gimple g, tree clauses)
+Set @code{CLAUSES} to be the list of clauses associated with @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_for_index (gimple g)
+Return the index variable for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_for_index_ptr (gimple g)
+Return a pointer to the index variable for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_for_set_index (gimple g, tree index)
+Set @code{INDEX} to be the index variable for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_for_initial (gimple g)
+Return the initial value for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_for_initial_ptr (gimple g)
+Return a pointer to the initial value for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_for_set_initial (gimple g, tree initial)
+Set @code{INTIAL} to be the initial value for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_for_final (gimple g)
+Return the final value for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_for_final_ptr (gimple g)
+turn a pointer to the final value for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_for_set_final (gimple g, tree final)
+Set @code{FINAL} to be the final value for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_for_incr (gimple g)
+Return the increment value for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_for_incr_ptr (gimple g)
+Return a pointer to the increment value for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_for_set_incr (gimple g, tree incr)
+Set @code{INCR} to be the increment value for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gimple_omp_for_pre_body (gimple g)
+Return the sequence of statements to execute before the @code{OMP_FOR}
+statement @code{G} starts.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_for_set_pre_body (gimple g, gimple_seq pre_body)
+Set @code{PRE_BODY} to be the sequence of statements to execute before
+the @code{OMP_FOR} statement @code{G} starts.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_for_set_cond (gimple g, enum tree_code cond)
+Set @code{COND} to be the condition code for @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} enum tree_code gimple_omp_for_cond (gimple g)
+Return the condition code associated with @code{OMP_FOR} @code{G}.
+@end deftypefn
+
+
+@node @code{GIMPLE_OMP_MASTER}
+@subsection @code{GIMPLE_OMP_MASTER}
+@cindex @code{GIMPLE_OMP_MASTER}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_master (gimple_seq body)
+Build a @code{GIMPLE_OMP_MASTER} statement. @code{BODY} is the sequence of
+statements to be executed by just the master.
+@end deftypefn
+
+
+@node @code{GIMPLE_OMP_ORDERED}
+@subsection @code{GIMPLE_OMP_ORDERED}
+@cindex @code{GIMPLE_OMP_ORDERED}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_ordered (gimple_seq body)
+Build a @code{GIMPLE_OMP_ORDERED} statement.
+@end deftypefn
+
+@code{BODY} is the sequence of statements inside a loop that will
+executed in sequence.
+
+
+@node @code{GIMPLE_OMP_PARALLEL}
+@subsection @code{GIMPLE_OMP_PARALLEL}
+@cindex @code{GIMPLE_OMP_PARALLEL}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_parallel (gimple_seq body, tree clauses, tree child_fn, tree data_arg)
+Build a @code{GIMPLE_OMP_PARALLEL} statement.
+@end deftypefn
+
+@code{BODY} is sequence of statements which are executed in parallel.
+@code{CLAUSES}, are the @code{OMP} parallel construct's clauses. @code{CHILD_FN} is
+the function created for the parallel threads to execute.
+@code{DATA_ARG} are the shared data argument(s).
+
+@deftypefn {GIMPLE function} bool gimple_omp_parallel_combined_p (gimple g)
+Return true if @code{OMP} parallel statement @code{G} has the
+@code{GF_OMP_PARALLEL_COMBINED} flag set.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_parallel_set_combined_p (gimple g)
+Set the @code{GF_OMP_PARALLEL_COMBINED} field in @code{OMP} parallel statement
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gimple_omp_body (gimple g)
+Return the body for the @code{OMP} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_set_body (gimple g, gimple_seq body)
+Set @code{BODY} to be the body for the @code{OMP} statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_parallel_clauses (gimple g)
+Return the clauses associated with @code{OMP_PARALLEL} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_parallel_clauses_ptr (gimple g)
+Return a pointer to the clauses associated with @code{OMP_PARALLEL} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_parallel_set_clauses (gimple g, tree clauses)
+Set @code{CLAUSES} to be the list of clauses associated with
+@code{OMP_PARALLEL} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_parallel_child_fn (gimple g)
+Return the child function used to hold the body of @code{OMP_PARALLEL}
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_parallel_child_fn_ptr (gimple g)
+Return a pointer to the child function used to hold the body of
+@code{OMP_PARALLEL} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_parallel_set_child_fn (gimple g, tree child_fn)
+Set @code{CHILD_FN} to be the child function for @code{OMP_PARALLEL} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_parallel_data_arg (gimple g)
+Return the artificial argument used to send variables and values
+from the parent to the children threads in @code{OMP_PARALLEL} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_parallel_data_arg_ptr (gimple g)
+Return a pointer to the data argument for @code{OMP_PARALLEL} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_parallel_set_data_arg (gimple g, tree data_arg)
+Set @code{DATA_ARG} to be the data argument for @code{OMP_PARALLEL} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool is_gimple_omp (gimple stmt)
+Returns true when the gimple statment @code{STMT} is any of the OpenMP
+types.
+@end deftypefn
+
+
+@node @code{GIMPLE_OMP_RETURN}
+@subsection @code{GIMPLE_OMP_RETURN}
+@cindex @code{GIMPLE_OMP_RETURN}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_return (bool wait_p)
+Build a @code{GIMPLE_OMP_RETURN} statement. @code{WAIT_P} is true if this is a
+non-waiting return.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_return_set_nowait (gimple s)
+Set the nowait flag on @code{GIMPLE_OMP_RETURN} statement @code{S}.
+@end deftypefn
+
+
+@deftypefn {GIMPLE function} bool gimple_omp_return_nowait_p (gimple g)
+Return true if @code{OMP} return statement @code{G} has the
+@code{GF_OMP_RETURN_NOWAIT} flag set.
+@end deftypefn
+
+@node @code{GIMPLE_OMP_SECTION}
+@subsection @code{GIMPLE_OMP_SECTION}
+@cindex @code{GIMPLE_OMP_SECTION}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_section (gimple_seq body)
+Build a @code{GIMPLE_OMP_SECTION} statement for a sections statement.
+@end deftypefn
+
+@code{BODY} is the sequence of statements in the section.
+
+@deftypefn {GIMPLE function} bool gimple_omp_section_last_p (gimple g)
+Return true if @code{OMP} section statement @code{G} has the
+@code{GF_OMP_SECTION_LAST} flag set.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_section_set_last (gimple g)
+Set the @code{GF_OMP_SECTION_LAST} flag on @code{G}.
+@end deftypefn
+
+@node @code{GIMPLE_OMP_SECTIONS}
+@subsection @code{GIMPLE_OMP_SECTIONS}
+@cindex @code{GIMPLE_OMP_SECTIONS}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_sections (gimple_seq body, tree clauses)
+Build a @code{GIMPLE_OMP_SECTIONS} statement. @code{BODY} is a sequence of
+section statements. @code{CLAUSES} are any of the @code{OMP} sections
+contsruct's clauses: private, firstprivate, lastprivate,
+reduction, and nowait.
+@end deftypefn
+
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_sections_switch (void)
+Build a @code{GIMPLE_OMP_SECTIONS_SWITCH} statement.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_sections_control (gimple g)
+Return the control variable associated with the
+@code{GIMPLE_OMP_SECTIONS} in @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_sections_control_ptr (gimple g)
+Return a pointer to the clauses associated with the
+@code{GIMPLE_OMP_SECTIONS} in @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_sections_set_control (gimple g, tree control)
+Set @code{CONTROL} to be the set of clauses associated with the
+@code{GIMPLE_OMP_SECTIONS} in @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_sections_clauses (gimple g)
+Return the clauses associated with @code{OMP_SECTIONS} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_sections_clauses_ptr (gimple g)
+Return a pointer to the clauses associated with @code{OMP_SECTIONS} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_sections_set_clauses (gimple g, tree clauses)
+Set @code{CLAUSES} to be the set of clauses associated with @code{OMP_SECTIONS}
+@code{G}.
+@end deftypefn
+
+
+@node @code{GIMPLE_OMP_SINGLE}
+@subsection @code{GIMPLE_OMP_SINGLE}
+@cindex @code{GIMPLE_OMP_SINGLE}
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_single (gimple_seq body, tree clauses)
+Build a @code{GIMPLE_OMP_SINGLE} statement. @code{BODY} is the sequence of
+statements that will be executed once. @code{CLAUSES} are any of the
+@code{OMP} single construct's clauses: private, firstprivate,
+copyprivate, nowait.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_omp_single_clauses (gimple g)
+Return the clauses associated with @code{OMP_SINGLE} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_omp_single_clauses_ptr (gimple g)
+Return a pointer to the clauses associated with @code{OMP_SINGLE} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_omp_single_set_clauses (gimple g, tree clauses)
+Set @code{CLAUSES} to be the clauses associated with @code{OMP_SINGLE} @code{G}.
+@end deftypefn
+
+
+@node @code{GIMPLE_PHI}
+@subsection @code{GIMPLE_PHI}
+@cindex @code{GIMPLE_PHI}
+
+@deftypefn {GIMPLE function} gimple make_phi_node (tree var, int len)
+Build a @code{PHI} node with len argument slots for variable var.
+@end deftypefn
+
+@deftypefn {GIMPLE function} unsigned gimple_phi_capacity (gimple g)
+Return the maximum number of arguments supported by @code{GIMPLE_PHI} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} unsigned gimple_phi_num_args (gimple g)
+Return the number of arguments in @code{GIMPLE_PHI} @code{G}. This must always
+be exactly the number of incoming edges for the basic block
+holding @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_phi_result (gimple g)
+Return the @code{SSA} name created by @code{GIMPLE_PHI} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree *gimple_phi_result_ptr (gimple g)
+Return a pointer to the @code{SSA} name created by @code{GIMPLE_PHI} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_phi_set_result (gimple g, tree result)
+Set @code{RESULT} to be the @code{SSA} name created by @code{GIMPLE_PHI} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} struct phi_arg_d *gimple_phi_arg (gimple g, index)
+Return the @code{PHI} argument corresponding to incoming edge @code{INDEX} for
+@code{GIMPLE_PHI} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_phi_set_arg (gimple g, index, struct phi_arg_d * phiarg)
+Set @code{PHIARG} to be the argument corresponding to incoming edge
+@code{INDEX} for @code{GIMPLE_PHI} @code{G}.
+@end deftypefn
+
+@node @code{GIMPLE_RESX}
+@subsection @code{GIMPLE_RESX}
+@cindex @code{GIMPLE_RESX}
+
+@deftypefn {GIMPLE function} gimple gimple_build_resx (int region)
+Build a @code{GIMPLE_RESX} statement which is a statement. This
+statement is a placeholder for _Unwind_Resume before we know if a
+function call or a branch is needed. @code{REGION} is the exception
+region from which control is flowing.
+@end deftypefn
+
+@deftypefn {GIMPLE function} int gimple_resx_region (gimple g)
+Return the region number for @code{GIMPLE_RESX} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_resx_set_region (gimple g, int region)
+Set @code{REGION} to be the region number for @code{GIMPLE_RESX} @code{G}.
+@end deftypefn
+
+@node @code{GIMPLE_RETURN}
+@subsection @code{GIMPLE_RETURN}
+@cindex @code{GIMPLE_RETURN}
+
+@deftypefn {GIMPLE function} gimple gimple_build_return (tree retval)
+Build a @code{GIMPLE_RETURN} statement whose return value is retval.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_return_retval (gimple g)
+Return the return value for @code{GIMPLE_RETURN} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_return_set_retval (gimple g, tree retval)
+Set @code{RETVAL} to be the return value for @code{GIMPLE_RETURN} @code{G}.
+@end deftypefn
+
+@node @code{GIMPLE_SWITCH}
+@subsection @code{GIMPLE_SWITCH}
+@cindex @code{GIMPLE_SWITCH}
+
+@deftypefn {GIMPLE function} gimple gimple_build_switch ( nlabels, tree index, tree default_label, ...)
+Build a @code{GIMPLE_SWITCH} statement. @code{NLABELS} are the number of
+labels excluding the default label. The default label is passed
+in @code{DEFAULT_LABEL}. The rest of the arguments are trees
+representing the labels. Each label is a tree of code
+@code{CASE_LABEL_EXPR}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple gimple_build_switch_vec (tree index, tree default_label, @code{VEC}(tree,heap) *args)
+This function is an alternate way of building @code{GIMPLE_SWITCH}
+statements. @code{INDEX} and @code{DEFAULT_LABEL} are as in
+gimple_build_switch. @code{ARGS} is a vector of @code{CASE_LABEL_EXPR} trees
+that contain the labels.
+@end deftypefn
+
+@deftypefn {GIMPLE function} unsigned gimple_switch_num_labels (gimple g)
+Return the number of labels associated with the switch statement
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_switch_set_num_labels (gimple g, unsigned nlabels)
+Set @code{NLABELS} to be the number of labels for the switch statement
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_switch_index (gimple g)
+Return the index variable used by the switch statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_switch_set_index (gimple g, tree index)
+Set @code{INDEX} to be the index variable for switch statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_switch_label (gimple g, unsigned index)
+Return the label numbered @code{INDEX}. The default label is 0, followed
+by any labels in a switch statement.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_switch_set_label (gimple g, unsigned index, tree label)
+Set the label number @code{INDEX} to @code{LABEL}. 0 is always the default
+label.
+@end deftypefn
+
+@deftypefn {GIMPLE function} tree gimple_switch_default_label (gimple g)
+Return the default label for a switch statement.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_switch_set_default_label (gimple g, tree label)
+Set the default label for a switch statement.
+@end deftypefn
+
+
+@node @code{GIMPLE_TRY}
+@subsection @code{GIMPLE_TRY}
+@cindex @code{GIMPLE_TRY}
+
+@deftypefn {GIMPLE function} gimple gimple_build_try (gimple_seq eval, gimple_seq cleanup, unsigned int kind)
+Build a @code{GIMPLE_TRY} statement. @code{EVAL} is a sequence with the
+expression to evaluate. @code{CLEANUP} is a sequence of statements to
+run at clean-up time. @code{KIND} is the enumeration value
+@code{GIMPLE_TRY_CATCH} if this statement denotes a try/catch construct
+or @code{GIMPLE_TRY_FINALLY} if this statement denotes a try/finally
+construct.
+@end deftypefn
+
+@deftypefn {GIMPLE function} enum gimple_try_flags gimple_try_kind (gimple g)
+Return the kind of try block represented by @code{GIMPLE_TRY} @code{G}. This is
+either @code{GIMPLE_TRY_CATCH} or @code{GIMPLE_TRY_FINALLY}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_try_catch_is_cleanup (gimple g)
+Return the @code{GIMPLE_TRY_CATCH_IS_CLEANUP} flag.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gimple_try_eval (gimple g)
+Return the sequence of statements used as the body for @code{GIMPLE_TRY}
+@code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gimple_try_cleanup (gimple g)
+Return the sequence of statements used as the cleanup body for
+@code{GIMPLE_TRY} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_try_set_catch_is_cleanup (gimple g, bool catch_is_cleanup)
+Set the @code{GIMPLE_TRY_CATCH_IS_CLEANUP} flag.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_try_set_eval (gimple g, gimple_seq eval)
+Set @code{EVAL} to be the sequence of statements to use as the body for
+@code{GIMPLE_TRY} @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_try_set_cleanup (gimple g, gimple_seq cleanup)
+Set @code{CLEANUP} to be the sequence of statements to use as the
+cleanup body for @code{GIMPLE_TRY} @code{G}.
+@end deftypefn
+
+@node @code{GIMPLE_WITH_CLEANUP_EXPR}
+@subsection @code{GIMPLE_WITH_CLEANUP_EXPR}
+@cindex @code{GIMPLE_WITH_CLEANUP_EXPR}
+
+@deftypefn {GIMPLE function} gimple gimple_build_wce (gimple_seq cleanup)
+Build a @code{GIMPLE_WITH_CLEANUP_EXPR} statement. @code{CLEANUP} is the
+clean-up expression.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gimple_wce_cleanup (gimple g)
+Return the cleanup sequence for cleanup statement @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_wce_set_canup (gimple g, gimple_seq cleanup)
+Set @code{CLEANUP} to be the cleanup sequence for @code{G}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_wce_cleanup_eh_only (gimple g)
+Return the @code{CLEANUP_EH_ONLY} flag for a @code{WCE} tuple.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_wce_set_cleanup_eh_only (gimple g, bool eh_only_p)
+Set the @code{CLEANUP_EH_ONLY} flag for a @code{WCE} tuple.
+@end deftypefn
+
+
+@node GIMPLE sequences
+@section GIMPLE sequences
+@cindex GIMPLE sequences
+
+GIMPLE sequences are the tuple equivalent of @code{STATEMENT_LIST}'s
+used in @code{GENERIC}. They are used to chain statements together, and
+when used in conjunction with sequence iterators, provide a
+framework for iterating through statements.
+
+GIMPLE sequences are of type struct @code{gimple_sequence}, but are more
+commonly passed by reference to functions dealing with sequences.
+The type for a sequence pointer is @code{gimple_seq} which is the same
+as struct @code{gimple_sequence} *. When declaring a local sequence,
+you can define a local variable of type struct @code{gimple_sequence}.
+When declaring a sequence allocated on the garbage collected
+heap, use the function @code{gimple_seq_alloc} documented below.
+
+There are convenience functions for iterating through sequences
+in the section entitled Sequence Iterators.
+
+Below is a list of functions to manipulate and query sequences.
+
+@deftypefn {GIMPLE function} void gimple_seq_add_stmt (gimple_seq *seq, gimple g)
+Link a gimple statement to the end of the sequence *@code{SEQ} if @code{G} is
+not @code{NULL}. If *@code{SEQ} is @code{NULL}, allocate a sequence before linking.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_seq_add_seq (gimple_seq *dest, gimple_seq src)
+Append sequence @code{SRC} to the end of sequence *@code{DEST} if @code{SRC} is not
+@code{NULL}. If *@code{DEST} is @code{NULL}, allocate a new sequence before
+appending.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gimple_seq_deep_copy (gimple_seq src)
+Perform a deep copy of sequence @code{SRC} and return the result.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gimple_seq_reverse (gimple_seq seq)
+Reverse the order of the statements in the sequence @code{SEQ}. Return
+@code{SEQ}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple gimple_seq_first (gimple_seq s)
+Return the first statement in sequence @code{S}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple gimple_seq_last (gimple_seq s)
+Return the last statement in sequence @code{S}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_seq_set_last (gimple_seq s, gimple last)
+Set the last statement in sequence @code{S} to the statement in @code{LAST}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_seq_set_first (gimple_seq s, gimple first)
+Set the first statement in sequence @code{S} to the statement in @code{FIRST}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_seq_init (gimple_seq s)
+Initialize sequence @code{S} to an empty sequence.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gimple_seq_alloc (void)
+Allocate a new sequence in the garbage collected store and return
+it.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gimple_seq_copy (gimple_seq dest, gimple_seq src)
+Copy the sequence @code{SRC} into the sequence @code{DEST}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_seq_empty_p (gimple_seq s)
+Return true if the sequence @code{S} is empty.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq bb_seq (basic_block bb)
+Returns the sequence of statements in @code{BB}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void set_bb_seq (basic_block bb, gimple_seq seq)
+Sets the sequence of statements in @code{BB} to @code{SEQ}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gimple_seq_singleton_p (gimple_seq seq)
+Determine whether @code{SEQ} contains exactly one statement.
+@end deftypefn
+
+@node Sequence iterators
+@section Sequence iterators
+@cindex Sequence iterators
+
+Sequence iterators are convenience constructs for iterating
+through statements in a sequence. Given a sequence @code{SEQ}, here is
+a typical use of gimple sequence iterators:
+
+@smallexample
+gimple_stmt_iterator gsi;
+
+for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
+ @{
+ gimple g = gsi_stmt (gsi);
+ /* Do something with gimple statement @code{G}. */
+ @}
+@end smallexample
+
+Backward iterations are possible:
+
+@smallexample
+ for (gsi = gsi_last (seq); !gsi_end_p (gsi); gsi_prev (&gsi))
+@end smallexample
+
+Forward and backward iterations on basic blocks are possible with
+@code{gsi_start_bb} and @code{gsi_last_bb}.
+
+In the documentation below we sometimes refer to enum
+@code{gsi_iterator_update}. The valid options for this enumeration are:
+
+@itemize @bullet
+@item @code{GSI_NEW_STMT}
+Only valid when a single statement is added. Move the iterator to it.
+
+@item @code{GSI_SAME_STMT}
+Leave the iterator at the same statement.
+
+@item @code{GSI_CONTINUE_LINKING}
+Move iterator to whatever position is suitable for linking other
+statements in the same direction.
+@end itemize
+
+Below is a list of the functions used to manipulate and use
+statement iterators.
+
+@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_start (gimple_seq seq)
+Return a new iterator pointing to the sequence @code{SEQ}'s first
+statement. If @code{SEQ} is empty, the iterator's basic block is @code{NULL}.
+Use @code{gsi_start_bb} instead when the iterator needs to always have
+the correct basic block set.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_start_bb (basic_block bb)
+Return a new iterator pointing to the first statement in basic
+block @code{BB}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_last (gimple_seq seq)
+Return a new iterator initially pointing to the last statement of
+sequence @code{SEQ}. If @code{SEQ} is empty, the iterator's basic block is
+@code{NULL}. Use @code{gsi_last_bb} instead when the iterator needs to always
+have the correct basic block set.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_last_bb (basic_block bb)
+Return a new iterator pointing to the last statement in basic
+block @code{BB}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gsi_end_p (gimple_stmt_iterator i)
+Return @code{TRUE} if at the end of @code{I}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} bool gsi_one_before_end_p (gimple_stmt_iterator i)
+Return @code{TRUE} if we're one statement before the end of @code{I}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_next (gimple_stmt_iterator *i)
+Advance the iterator to the next gimple statement.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_prev (gimple_stmt_iterator *i)
+Advance the iterator to the previous gimple statement.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple gsi_stmt (gimple_stmt_iterator i)
+Return the current stmt.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_after_labels (basic_block bb)
+Return a block statement iterator that points to the first
+non-label statement in block @code{BB}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple *gsi_stmt_ptr (gimple_stmt_iterator *i)
+Return a pointer to the current stmt.
+@end deftypefn
+
+@deftypefn {GIMPLE function} basic_block gsi_bb (gimple_stmt_iterator i)
+Return the basic block associated with this iterator.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gsi_seq (gimple_stmt_iterator i)
+Return the sequence associated with this iterator.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_remove (gimple_stmt_iterator *i, bool remove_eh_info)
+Remove the current stmt from the sequence. The iterator is
+updated to point to the next statement. When @code{REMOVE_EH_INFO} is
+true we remove the statement pointed to by iterator @code{I} from the @code{EH}
+tables. Otherwise we do not modify the @code{EH} tables. Generally,
+@code{REMOVE_EH_INFO} should be true when the statement is going to be
+removed from the @code{IL} and not reinserted elsewhere.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_link_seq_before (gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode)
+Links the sequence of statements @code{SEQ} before the statement pointed
+by iterator @code{I}. @code{MODE} indicates what to do with the iterator
+after insertion (see @code{enum gsi_iterator_update} above).
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_link_before (gimple_stmt_iterator *i, gimple g, enum gsi_iterator_update mode)
+Links statement @code{G} before the statement pointed-to by iterator @code{I}.
+Updates iterator @code{I} according to @code{MODE}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_link_seq_after (gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode)
+Links sequence @code{SEQ} after the statement pointed-to by iterator @code{I}.
+@code{MODE} is as in @code{gsi_insert_after}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_link_after (gimple_stmt_iterator *i, gimple g, enum gsi_iterator_update mode)
+Links statement @code{G} after the statement pointed-to by iterator @code{I}.
+@code{MODE} is as in @code{gsi_insert_after}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gsi_split_seq_after (gimple_stmt_iterator i)
+Move all statements in the sequence after @code{I} to a new sequence.
+Return this new sequence.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_seq gsi_split_seq_before (gimple_stmt_iterator *i)
+Move all statements in the sequence before @code{I} to a new sequence.
+Return this new sequence.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_replace (gimple_stmt_iterator *i, gimple stmt, bool update_eh_info)
+Replace the statement pointed-to by @code{I} to @code{STMT}. If @code{UPDATE_EH_INFO}
+is true, the exception handling information of the original
+statement is moved to the new statement.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_insert_before (gimple_stmt_iterator *i, gimple stmt, enum gsi_iterator_update mode)
+Insert statement @code{STMT} before the statement pointed-to by iterator
+@code{I}, update @code{STMT}'s basic block and scan it for new operands. @code{MODE}
+specifies how to update iterator @code{I} after insertion (see enum
+@code{gsi_iterator_update}).
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_insert_seq_before (gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode)
+Like @code{gsi_insert_before}, but for all the statements in @code{SEQ}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_insert_after (gimple_stmt_iterator *i, gimple stmt, enum gsi_iterator_update mode)
+Insert statement @code{STMT} after the statement pointed-to by iterator
+@code{I}, update @code{STMT}'s basic block and scan it for new operands. @code{MODE}
+specifies how to update iterator @code{I} after insertion (see enum
+@code{gsi_iterator_update}).
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_insert_seq_after (gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode)
+Like @code{gsi_insert_after}, but for all the statements in @code{SEQ}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_for_stmt (gimple stmt)
+Finds iterator for @code{STMT}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_move_after (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
+Move the statement at @code{FROM} so it comes right after the statement
+at @code{TO}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
+Move the statement at @code{FROM} so it comes right before the statement
+at @code{TO}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_move_to_bb_end (gimple_stmt_iterator *from, basic_block bb)
+Move the statement at @code{FROM} to the end of basic block @code{BB}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_insert_on_edge (edge e, gimple stmt)
+Add @code{STMT} to the pending list of edge @code{E}. No actual insertion is
+made until a call to @code{gsi_commit_edge_inserts}() is made.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_insert_seq_on_edge (edge e, gimple_seq seq)
+Add the sequence of statements in @code{SEQ} to the pending list of edge
+@code{E}. No actual insertion is made until a call to
+@code{gsi_commit_edge_inserts}() is made.
+@end deftypefn
+
+@deftypefn {GIMPLE function} basic_block gsi_insert_on_edge_immediate (edge e, gimple stmt)
+Similar to @code{gsi_insert_on_edge}+@code{gsi_commit_edge_inserts}. If a new
+block has to be created, it is returned.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_commit_one_edge_insert (edge e, basic_block *new_bb)
+Commit insertions pending at edge @code{E}. If a new block is created,
+set @code{NEW_BB} to this block, otherwise set it to @code{NULL}.
+@end deftypefn
+
+@deftypefn {GIMPLE function} void gsi_commit_edge_inserts (void)
+This routine will commit all pending edge insertions, creating
+any new basic blocks which are necessary.
+@end deftypefn
+
+
+@node Adding a new GIMPLE statement code
+@section Adding a new GIMPLE statement code
+@cindex Adding a new GIMPLE statement code
+
+The first step in adding a new GIMPLE statement code, is
+modifying the file @code{gimple.def}, which contains all the GIMPLE
+codes. Then you must add a corresponding structure, and an entry
+in @code{union gimple_statement_d}, both of which are located in
+@code{gimple.h}. This in turn, will require you to add a corresponding
+@code{GTY} tag in @code{gsstruct.def}, and code to handle this tag in
+@code{gss_for_code} which is located in @code{gimple.c}.
+
+In order for the garbage collector to know the size of the
+structure you created in @code{gimple.h}, you need to add a case to
+handle your new GIMPLE statement in @code{gimple_size} which is located
+in @code{gimple.c}.
+
+You will probably want to create a function to build the new
+gimple statement in @code{gimple.c}. The function should be called
+@code{gimple_build_<@code{NEW_TUPLE_NAME}>}, and should return the new tuple
+of type gimple.
+
+If your new statement requires accessors for any members or
+operands it may have, put simple inline accessors in
+@code{gimple.h} and any non-trivial accessors in @code{gimple.c} with a
+corresponding prototype in @code{gimple.h}.
+
+
+@node Statement and operand traversals
+@section Statement and operand traversals
+@cindex Statement and operand traversals
+
+There are two functions available for walking statements and
+sequences: @code{walk_gimple_stmt} and @code{walk_gimple_seq},
+accordingly, and a third function for walking the operands in a
+statement: @code{walk_gimple_op}.
+
+@deftypefn {GIMPLE function} tree walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt, walk_tree_fn callback_op, struct walk_stmt_info *wi)
+This function is used to walk the current statement in @code{GSI},
+optionally using traversal state stored in @code{WI}. If @code{WI} is @code{NULL}, no
+state is kept during the traversal.
+
+The callback @code{CALLBACK_STMT} is called. If @code{CALLBACK_STMT} returns
+true, it means that the callback function has handled all the
+operands of the statement and it is not necessary to walk its
+operands.
+
+If @code{CALLBACK_STMT} is @code{NULL} or it returns false, @code{CALLBACK_OP} is
+called on each operand of the statement via @code{walk_gimple_op}. If
+@code{walk_gimple_op} returns non-@code{NULL} for any operand, the remaining
+operands are not scanned.
+
+The return value is that returned by the last call to
+@code{walk_gimple_op}, or @code{NULL_TREE} if no @code{CALLBACK_OP} is specified.
+@end deftypefn
+
+
+@deftypefn {GIMPLE function} tree walk_gimple_op (gimple stmt, walk_tree_fn callback_op, struct walk_stmt_info *wi)
+Use this function to walk the operands of statement @code{STMT}. Every
+operand is walked via @code{walk_tree} with optional state information
+in @code{WI}.
+
+@code{CALLBACK_OP} is called on each operand of @code{STMT} via @code{walk_tree}.
+Additional parameters to @code{walk_tree} must be stored in @code{WI}. For
+each operand @code{OP}, @code{walk_tree} is called as:
+
+@smallexample
+ walk_tree (&@code{OP}, @code{CALLBACK_OP}, @code{WI}, @code{WI}- @code{PSET})
+@end smallexample
+
+If @code{CALLBACK_OP} returns non-@code{NULL} for an operand, the remaining
+operands are not scanned. The return value is that returned by
+the last call to @code{walk_tree}, or @code{NULL_TREE} if no @code{CALLBACK_OP} is
+specified.
+@end deftypefn
+
+
+@deftypefn {GIMPLE function} tree walk_gimple_seq (gimple_seq seq, walk_stmt_fn callback_stmt, walk_tree_fn callback_op, struct walk_stmt_info *wi)
+This function walks all the statements in the sequence @code{SEQ}
+calling @code{walk_gimple_stmt} on each one. @code{WI} is as in
+@code{walk_gimple_stmt}. If @code{walk_gimple_stmt} returns non-@code{NULL}, the walk
+is stopped and the value returned. Otherwise, all the statements
+are walked and @code{NULL_TREE} returned.
+@end deftypefn
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index eba39cde164..dbff5761efe 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2826,17 +2826,26 @@ as below:
@end smallexample
@end defmac
-@defmac IRA_COVER_CLASSES
-The macro defines cover classes for the Integrated Register Allocator
+@deftypefn {Target Hook} {const enum reg_class *} TARGET_IRA_COVER_CLASSES ()
+Return an array of cover classes for the Integrated Register Allocator
(@acronym{IRA}). Cover classes are a set of non-intersecting register
classes covering all hard registers used for register allocation
purposes. If a move between two registers in the same cover class is
possible, it should be cheaper than a load or store of the registers.
-The macro value should be the initializer for an array of register
-class values, with @code{LIM_REG_CLASSES} used as the end marker.
+The array is terminated by a @code{LIM_REG_CLASSES} element.
+
+This hook is called once at compiler startup, after the command-line
+options have been processed. It is then re-examined by every call to
+@code{target_reinit}.
-You must define this macro in order to use the integrated register
+The default implementation returns @code{IRA_COVER_CLASSES}, if defined,
+otherwise there is no default implementation. You must define either this
+macro or @code{IRA_COVER_CLASSES} in order to use the integrated register
allocator for the target.
+@end deftypefn
+
+@defmac IRA_COVER_CLASSES
+See the documentation for @code{TARGET_IRA_COVER_CLASSES}.
@end defmac
@node Old Constraints
diff --git a/gcc/doc/tree-ssa.texi b/gcc/doc/tree-ssa.texi
index ea3d0ab4c59..bd0edc44226 100644
--- a/gcc/doc/tree-ssa.texi
+++ b/gcc/doc/tree-ssa.texi
@@ -8,7 +8,7 @@
@c ---------------------------------------------------------------------
@node Tree SSA
-@chapter Analysis and Optimization of GIMPLE Trees
+@chapter Analysis and Optimization of GIMPLE tuples
@cindex Tree SSA
@cindex Optimization infrastructure for GIMPLE
@@ -37,728 +37,28 @@ functions and programming constructs needed to implement optimization
passes for GIMPLE@.
@menu
-* GENERIC:: A high-level language-independent representation.
-* GIMPLE:: A lower-level factored tree representation.
-* Annotations:: Attributes for statements and variables.
-* Statement Operands:: Variables referenced by GIMPLE statements.
+* Annotations:: Attributes for variables.
+* SSA Operands:: SSA names referenced by GIMPLE statements.
* SSA:: Static Single Assignment representation.
* Alias analysis:: Representing aliased loads and stores.
@end menu
-@node GENERIC
-@section GENERIC
-@cindex GENERIC
-
-The purpose of GENERIC is simply to provide a language-independent way of
-representing an entire function in trees. To this end, it was necessary to
-add a few new tree codes to the back end, but most everything was already
-there. If you can express it with the codes in @code{gcc/tree.def}, it's
-GENERIC@.
-
-Early on, there was a great deal of debate about how to think about
-statements in a tree IL@. In GENERIC, a statement is defined as any
-expression whose value, if any, is ignored. A statement will always
-have @code{TREE_SIDE_EFFECTS} set (or it will be discarded), but a
-non-statement expression may also have side effects. A
-@code{CALL_EXPR}, for instance.
-
-It would be possible for some local optimizations to work on the
-GENERIC form of a function; indeed, the adapted tree inliner works
-fine on GENERIC, but the current compiler performs inlining after
-lowering to GIMPLE (a restricted form described in the next section).
-Indeed, currently the frontends perform this lowering before handing
-off to @code{tree_rest_of_compilation}, but this seems inelegant.
-
-If necessary, a front end can use some language-dependent tree codes
-in its GENERIC representation, so long as it provides a hook for
-converting them to GIMPLE and doesn't expect them to work with any
-(hypothetical) optimizers that run before the conversion to GIMPLE@.
-The intermediate representation used while parsing C and C++ looks
-very little like GENERIC, but the C and C++ gimplifier hooks are
-perfectly happy to take it as input and spit out GIMPLE@.
-
-@node GIMPLE
-@section GIMPLE
-@cindex GIMPLE
-
-GIMPLE is a simplified subset of GENERIC for use in optimization. The
-particular subset chosen (and the name) was heavily influenced by the
-SIMPLE IL used by the McCAT compiler project at McGill University,
-though we have made some different choices. For one thing, SIMPLE
-doesn't support @code{goto}; a production compiler can't afford that
-kind of restriction.
-
-GIMPLE retains much of the structure of the parse trees: lexical
-scopes are represented as containers, rather than markers. However,
-expressions are broken down into a 3-address form, using temporary
-variables to hold intermediate values. Also, control structures are
-lowered to gotos.
-
-In GIMPLE no container node is ever used for its value; if a
-@code{COND_EXPR} or @code{BIND_EXPR} has a value, it is stored into a
-temporary within the controlled blocks, and that temporary is used in
-place of the container.
-
-The compiler pass which lowers GENERIC to GIMPLE is referred to as the
-@samp{gimplifier}. The gimplifier works recursively, replacing complex
-statements with sequences of simple statements.
-
-@c Currently, the only way to
-@c tell whether or not an expression is in GIMPLE form is by recursively
-@c examining it; in the future there will probably be a flag to help avoid
-@c redundant work. FIXME FIXME
-
-@menu
-* Interfaces::
-* Temporaries::
-* GIMPLE Expressions::
-* Statements::
-* GIMPLE Example::
-* Rough GIMPLE Grammar::
-@end menu
-
-@node Interfaces
-@subsection Interfaces
-@cindex gimplification
-
-The tree representation of a function is stored in
-@code{DECL_SAVED_TREE}. It is lowered to GIMPLE by a call to
-@code{gimplify_function_tree}.
-
-If a front end wants to include language-specific tree codes in the tree
-representation which it provides to the back end, it must provide a
-definition of @code{LANG_HOOKS_GIMPLIFY_EXPR} which knows how to
-convert the front end trees to GIMPLE@. Usually such a hook will involve
-much of the same code for expanding front end trees to RTL@. This function
-can return fully lowered GIMPLE, or it can return GENERIC trees and let the
-main gimplifier lower them the rest of the way; this is often simpler.
-GIMPLE that is not fully lowered is known as ``high GIMPLE'' and
-consists of the IL before the pass @code{pass_lower_cf}. High GIMPLE
-still contains lexical scopes and nested expressions, while low GIMPLE
-exposes all of the implicit jumps for control expressions like
-@code{COND_EXPR}.
-
-The C and C++ front ends currently convert directly from front end
-trees to GIMPLE, and hand that off to the back end rather than first
-converting to GENERIC@. Their gimplifier hooks know about all the
-@code{_STMT} nodes and how to convert them to GENERIC forms. There
-was some work done on a genericization pass which would run first, but
-the existence of @code{STMT_EXPR} meant that in order to convert all
-of the C statements into GENERIC equivalents would involve walking the
-entire tree anyway, so it was simpler to lower all the way. This
-might change in the future if someone writes an optimization pass
-which would work better with higher-level trees, but currently the
-optimizers all expect GIMPLE@.
-
-A front end which wants to use the tree optimizers (and already has
-some sort of whole-function tree representation) only needs to provide
-a definition of @code{LANG_HOOKS_GIMPLIFY_EXPR}, call
-@code{gimplify_function_tree} to lower to GIMPLE, and then hand off to
-@code{tree_rest_of_compilation} to compile and output the function.
-
-You can tell the compiler to dump a C-like representation of the GIMPLE
-form with the flag @option{-fdump-tree-gimple}.
-
-@node Temporaries
-@subsection Temporaries
-@cindex Temporaries
-
-When gimplification encounters a subexpression which is too complex, it
-creates a new temporary variable to hold the value of the subexpression,
-and adds a new statement to initialize it before the current statement.
-These special temporaries are known as @samp{expression temporaries}, and are
-allocated using @code{get_formal_tmp_var}. The compiler tries to
-always evaluate identical expressions into the same temporary, to simplify
-elimination of redundant calculations.
-
-We can only use expression temporaries when we know that it will not be
-reevaluated before its value is used, and that it will not be otherwise
-modified@footnote{These restrictions are derived from those in Morgan 4.8.}.
-Other temporaries can be allocated using
-@code{get_initialized_tmp_var} or @code{create_tmp_var}.
-
-Currently, an expression like @code{a = b + 5} is not reduced any
-further. We tried converting it to something like
-@smallexample
- T1 = b + 5;
- a = T1;
-@end smallexample
-but this bloated the representation for minimal benefit. However, a
-variable which must live in memory cannot appear in an expression; its
-value is explicitly loaded into a temporary first. Similarly, storing
-the value of an expression to a memory variable goes through a
-temporary.
-
-@node GIMPLE Expressions
-@subsection Expressions
-@cindex GIMPLE Expressions
-
-In general, expressions in GIMPLE consist of an operation and the
-appropriate number of simple operands; these operands must either be a
-GIMPLE rvalue (@code{is_gimple_val}), i.e.@: a constant or a register
-variable. More complex operands are factored out into temporaries, so
-that
-@smallexample
- a = b + c + d
-@end smallexample
-becomes
-@smallexample
- T1 = b + c;
- a = T1 + d;
-@end smallexample
-
-The same rule holds for arguments to a @code{CALL_EXPR}.
-
-The target of an assignment is usually a variable, but can also be an
-@code{INDIRECT_REF} or a compound lvalue as described below.
-
-@menu
-* Compound Expressions::
-* Compound Lvalues::
-* Conditional Expressions::
-* Logical Operators::
-@end menu
-
-@node Compound Expressions
-@subsubsection Compound Expressions
-@cindex Compound Expressions
-
-The left-hand side of a C comma expression is simply moved into a separate
-statement.
-
-@node Compound Lvalues
-@subsubsection Compound Lvalues
-@cindex Compound Lvalues
-
-Currently compound lvalues involving array and structure field references
-are not broken down; an expression like @code{a.b[2] = 42} is not reduced
-any further (though complex array subscripts are). This restriction is a
-workaround for limitations in later optimizers; if we were to convert this
-to
-
-@smallexample
- T1 = &a.b;
- T1[2] = 42;
-@end smallexample
-
-alias analysis would not remember that the reference to @code{T1[2]} came
-by way of @code{a.b}, so it would think that the assignment could alias
-another member of @code{a}; this broke @code{struct-alias-1.c}. Future
-optimizer improvements may make this limitation unnecessary.
-
-@node Conditional Expressions
-@subsubsection Conditional Expressions
-@cindex Conditional Expressions
-
-A C @code{?:} expression is converted into an @code{if} statement with
-each branch assigning to the same temporary. So,
-
-@smallexample
- a = b ? c : d;
-@end smallexample
-becomes
-@smallexample
- if (b)
- T1 = c;
- else
- T1 = d;
- a = T1;
-@end smallexample
-
-Tree level if-conversion pass re-introduces @code{?:} expression, if appropriate.
-It is used to vectorize loops with conditions using vector conditional operations.
-
-Note that in GIMPLE, @code{if} statements are also represented using
-@code{COND_EXPR}, as described below.
-
-@node Logical Operators
-@subsubsection Logical Operators
-@cindex Logical Operators
-
-Except when they appear in the condition operand of a @code{COND_EXPR},
-logical `and' and `or' operators are simplified as follows:
-@code{a = b && c} becomes
-
-@smallexample
- T1 = (bool)b;
- if (T1)
- T1 = (bool)c;
- a = T1;
-@end smallexample
-
-Note that @code{T1} in this example cannot be an expression temporary,
-because it has two different assignments.
-
-@node Statements
-@subsection Statements
-@cindex Statements
-
-Most statements will be assignment statements, represented by
-@code{MODIFY_EXPR}. A @code{CALL_EXPR} whose value is ignored can
-also be a statement. No other C expressions can appear at statement level;
-a reference to a volatile object is converted into a @code{MODIFY_EXPR}.
-In GIMPLE form, type of @code{MODIFY_EXPR} is not meaningful. Instead, use type
-of LHS or RHS@.
-
-There are also several varieties of complex statements.
-
-@menu
-* Blocks::
-* Statement Sequences::
-* Empty Statements::
-* Loops::
-* Selection Statements::
-* Jumps::
-* Cleanups::
-* GIMPLE Exception Handling::
-@end menu
-
-@node Blocks
-@subsubsection Blocks
-@cindex Blocks
-
-Block scopes and the variables they declare in GENERIC and GIMPLE are
-expressed using the @code{BIND_EXPR} code, which in previous versions of
-GCC was primarily used for the C statement-expression extension.
-
-Variables in a block are collected into @code{BIND_EXPR_VARS} in
-declaration order. Any runtime initialization is moved out of
-@code{DECL_INITIAL} and into a statement in the controlled block. When
-gimplifying from C or C++, this initialization replaces the
-@code{DECL_STMT}.
-
-Variable-length arrays (VLAs) complicate this process, as their size often
-refers to variables initialized earlier in the block. To handle this, we
-currently split the block at that point, and move the VLA into a new, inner
-@code{BIND_EXPR}. This strategy may change in the future.
-
-@code{DECL_SAVED_TREE} for a GIMPLE function will always be a
-@code{BIND_EXPR} which contains declarations for the temporary variables
-used in the function.
-
-A C++ program will usually contain more @code{BIND_EXPR}s than there are
-syntactic blocks in the source code, since several C++ constructs have
-implicit scopes associated with them. On the other hand, although the C++
-front end uses pseudo-scopes to handle cleanups for objects with
-destructors, these don't translate into the GIMPLE form; multiple
-declarations at the same level use the same @code{BIND_EXPR}.
-
-@node Statement Sequences
-@subsubsection Statement Sequences
-@cindex Statement Sequences
-
-Multiple statements at the same nesting level are collected into a
-@code{STATEMENT_LIST}. Statement lists are modified and traversed
-using the interface in @samp{tree-iterator.h}.
-
-@node Empty Statements
-@subsubsection Empty Statements
-@cindex Empty Statements
-
-Whenever possible, statements with no effect are discarded. But if they
-are nested within another construct which cannot be discarded for some
-reason, they are instead replaced with an empty statement, generated by
-@code{build_empty_stmt}. Initially, all empty statements were shared,
-after the pattern of the Java front end, but this caused a lot of trouble in
-practice.
-
-An empty statement is represented as @code{(void)0}.
-
-@node Loops
-@subsubsection Loops
-@cindex Loops
-
-At one time loops were expressed in GIMPLE using @code{LOOP_EXPR}, but
-now they are lowered to explicit gotos.
-
-@node Selection Statements
-@subsubsection Selection Statements
-@cindex Selection Statements
-
-A simple selection statement, such as the C @code{if} statement, is
-expressed in GIMPLE using a void @code{COND_EXPR}. If only one branch is
-used, the other is filled with an empty statement.
-
-Normally, the condition expression is reduced to a simple comparison. If
-it is a shortcut (@code{&&} or @code{||}) expression, however, we try to
-break up the @code{if} into multiple @code{if}s so that the implied shortcut
-is taken directly, much like the transformation done by @code{do_jump} in
-the RTL expander.
-
-A @code{SWITCH_EXPR} in GIMPLE contains the condition and a
-@code{TREE_VEC} of @code{CASE_LABEL_EXPR}s describing the case values
-and corresponding @code{LABEL_DECL}s to jump to. The body of the
-@code{switch} is moved after the @code{SWITCH_EXPR}.
-
-@node Jumps
-@subsubsection Jumps
-@cindex Jumps
-
-Other jumps are expressed by either @code{GOTO_EXPR} or @code{RETURN_EXPR}.
-
-The operand of a @code{GOTO_EXPR} must be either a label or a variable
-containing the address to jump to.
-
-The operand of a @code{RETURN_EXPR} is either @code{NULL_TREE},
-@code{RESULT_DECL}, or a @code{MODIFY_EXPR} which sets the return value. It
-would be nice to move the @code{MODIFY_EXPR} into a separate statement, but the
-special return semantics in @code{expand_return} make that difficult. It may
-still happen in the future, perhaps by moving most of that logic into
-@code{expand_assignment}.
-
-@node Cleanups
-@subsubsection Cleanups
-@cindex Cleanups
-
-Destructors for local C++ objects and similar dynamic cleanups are
-represented in GIMPLE by a @code{TRY_FINALLY_EXPR}.
-@code{TRY_FINALLY_EXPR} has two operands, both of which are a sequence
-of statements to execute. The first sequence is executed. When it
-completes the second sequence is executed.
-
-The first sequence may complete in the following ways:
-
-@enumerate
-
-@item Execute the last statement in the sequence and fall off the
-end.
-
-@item Execute a goto statement (@code{GOTO_EXPR}) to an ordinary
-label outside the sequence.
-
-@item Execute a return statement (@code{RETURN_EXPR}).
-
-@item Throw an exception. This is currently not explicitly represented in
-GIMPLE.
-
-@end enumerate
-
-The second sequence is not executed if the first sequence completes by
-calling @code{setjmp} or @code{exit} or any other function that does
-not return. The second sequence is also not executed if the first
-sequence completes via a non-local goto or a computed goto (in general
-the compiler does not know whether such a goto statement exits the
-first sequence or not, so we assume that it doesn't).
-
-After the second sequence is executed, if it completes normally by
-falling off the end, execution continues wherever the first sequence
-would have continued, by falling off the end, or doing a goto, etc.
-
-@code{TRY_FINALLY_EXPR} complicates the flow graph, since the cleanup
-needs to appear on every edge out of the controlled block; this
-reduces the freedom to move code across these edges. Therefore, the
-EH lowering pass which runs before most of the optimization passes
-eliminates these expressions by explicitly adding the cleanup to each
-edge. Rethrowing the exception is represented using @code{RESX_EXPR}.
-
-
-@node GIMPLE Exception Handling
-@subsubsection Exception Handling
-@cindex GIMPLE Exception Handling
-
-Other exception handling constructs are represented using
-@code{TRY_CATCH_EXPR}. @code{TRY_CATCH_EXPR} has two operands. The
-first operand is a sequence of statements to execute. If executing
-these statements does not throw an exception, then the second operand
-is ignored. Otherwise, if an exception is thrown, then the second
-operand of the @code{TRY_CATCH_EXPR} is checked. The second operand
-may have the following forms:
-
-@enumerate
-
-@item A sequence of statements to execute. When an exception occurs,
-these statements are executed, and then the exception is rethrown.
-
-@item A sequence of @code{CATCH_EXPR} expressions. Each @code{CATCH_EXPR}
-has a list of applicable exception types and handler code. If the
-thrown exception matches one of the caught types, the associated
-handler code is executed. If the handler code falls off the bottom,
-execution continues after the original @code{TRY_CATCH_EXPR}.
-
-@item An @code{EH_FILTER_EXPR} expression. This has a list of
-permitted exception types, and code to handle a match failure. If the
-thrown exception does not match one of the allowed types, the
-associated match failure code is executed. If the thrown exception
-does match, it continues unwinding the stack looking for the next
-handler.
-
-@end enumerate
-
-Currently throwing an exception is not directly represented in GIMPLE,
-since it is implemented by calling a function. At some point in the future
-we will want to add some way to express that the call will throw an
-exception of a known type.
-
-Just before running the optimizers, the compiler lowers the high-level
-EH constructs above into a set of @samp{goto}s, magic labels, and EH
-regions. Continuing to unwind at the end of a cleanup is represented
-with a @code{RESX_EXPR}.
-
-@node GIMPLE Example
-@subsection GIMPLE Example
-@cindex GIMPLE Example
-
-@smallexample
-struct A @{ A(); ~A(); @};
-
-int i;
-int g();
-void f()
-@{
- A a;
- int j = (--i, i ? 0 : 1);
-
- for (int x = 42; x > 0; --x)
- @{
- i += g()*4 + 32;
- @}
-@}
-@end smallexample
-
-becomes
-
-@smallexample
-void f()
-@{
- int i.0;
- int T.1;
- int iftmp.2;
- int T.3;
- int T.4;
- int T.5;
- int T.6;
-
- @{
- struct A a;
- int j;
-
- __comp_ctor (&a);
- try
- @{
- i.0 = i;
- T.1 = i.0 - 1;
- i = T.1;
- i.0 = i;
- if (i.0 == 0)
- iftmp.2 = 1;
- else
- iftmp.2 = 0;
- j = iftmp.2;
- @{
- int x;
-
- x = 42;
- goto test;
- loop:;
-
- T.3 = g ();
- T.4 = T.3 * 4;
- i.0 = i;
- T.5 = T.4 + i.0;
- T.6 = T.5 + 32;
- i = T.6;
- x = x - 1;
-
- test:;
- if (x > 0)
- goto loop;
- else
- goto break_;
- break_:;
- @}
- @}
- finally
- @{
- __comp_dtor (&a);
- @}
- @}
-@}
-@end smallexample
-
-@node Rough GIMPLE Grammar
-@subsection Rough GIMPLE Grammar
-@cindex Rough GIMPLE Grammar
-
-@smallexample
- function : FUNCTION_DECL
- DECL_SAVED_TREE -> compound-stmt
-
- compound-stmt: STATEMENT_LIST
- members -> stmt
-
- stmt : block
- | if-stmt
- | switch-stmt
- | goto-stmt
- | return-stmt
- | resx-stmt
- | label-stmt
- | try-stmt
- | modify-stmt
- | call-stmt
-
- block : BIND_EXPR
- BIND_EXPR_VARS -> chain of DECLs
- BIND_EXPR_BLOCK -> BLOCK
- BIND_EXPR_BODY -> compound-stmt
-
- if-stmt : COND_EXPR
- op0 -> condition
- op1 -> compound-stmt
- op2 -> compound-stmt
-
- switch-stmt : SWITCH_EXPR
- op0 -> val
- op1 -> NULL
- op2 -> TREE_VEC of CASE_LABEL_EXPRs
- The CASE_LABEL_EXPRs are sorted by CASE_LOW,
- and default is last.
-
- goto-stmt : GOTO_EXPR
- op0 -> LABEL_DECL | val
-
- return-stmt : RETURN_EXPR
- op0 -> return-value
-
- return-value : NULL
- | RESULT_DECL
- | MODIFY_EXPR
- op0 -> RESULT_DECL
- op1 -> lhs
-
- resx-stmt : RESX_EXPR
-
- label-stmt : LABEL_EXPR
- op0 -> LABEL_DECL
-
- try-stmt : TRY_CATCH_EXPR
- op0 -> compound-stmt
- op1 -> handler
- | TRY_FINALLY_EXPR
- op0 -> compound-stmt
- op1 -> compound-stmt
-
- handler : catch-seq
- | EH_FILTER_EXPR
- | compound-stmt
-
- catch-seq : STATEMENT_LIST
- members -> CATCH_EXPR
-
- modify-stmt : MODIFY_EXPR
- op0 -> lhs
- op1 -> rhs
-
- call-stmt : CALL_EXPR
- op0 -> val | OBJ_TYPE_REF
- op1 -> call-arg-list
-
- call-arg-list: TREE_LIST
- members -> lhs | CONST
-
- addr-expr-arg: ID
- | compref
-
- addressable : addr-expr-arg
- | indirectref
-
- with-size-arg: addressable
- | call-stmt
-
- indirectref : INDIRECT_REF
- op0 -> val
-
- lhs : addressable
- | bitfieldref
- | WITH_SIZE_EXPR
- op0 -> with-size-arg
- op1 -> val
-
- min-lval : ID
- | indirectref
-
- bitfieldref : BIT_FIELD_REF
- op0 -> inner-compref
- op1 -> CONST
- op2 -> val
-
- compref : inner-compref
- | TARGET_MEM_REF
- op0 -> ID
- op1 -> val
- op2 -> val
- op3 -> CONST
- op4 -> CONST
- | REALPART_EXPR
- op0 -> inner-compref
- | IMAGPART_EXPR
- op0 -> inner-compref
-
- inner-compref: min-lval
- | COMPONENT_REF
- op0 -> inner-compref
- op1 -> FIELD_DECL
- op2 -> val
- | ARRAY_REF
- op0 -> inner-compref
- op1 -> val
- op2 -> val
- op3 -> val
- | ARRAY_RANGE_REF
- op0 -> inner-compref
- op1 -> val
- op2 -> val
- op3 -> val
- | VIEW_CONVERT_EXPR
- op0 -> inner-compref
-
- condition : val
- | RELOP
- op0 -> val
- op1 -> val
-
- val : ID
- | invariant ADDR_EXPR
- op0 -> addr-expr-arg
- | CONST
-
- rhs : lhs
- | CONST
- | call-stmt
- | ADDR_EXPR
- op0 -> addr-expr-arg
- | UNOP
- op0 -> val
- | BINOP
- op0 -> val
- op1 -> val
- | RELOP
- op0 -> val
- op1 -> val
- | COND_EXPR
- op0 -> condition
- op1 -> val
- op2 -> val
-@end smallexample
-
@node Annotations
@section Annotations
@cindex annotations
-The optimizers need to associate attributes with statements and
-variables during the optimization process. For instance, we need to
-know what basic block a statement belongs to or whether a variable
-has aliases. All these attributes are stored in data structures
-called annotations which are then linked to the field @code{ann} in
-@code{struct tree_common}.
+The optimizers need to associate attributes with variables during the
+optimization process. For instance, we need to know whether a
+variable has aliases. All these attributes are stored in data
+structures called annotations which are then linked to the field
+@code{ann} in @code{struct tree_common}.
-Presently, we define annotations for statements (@code{stmt_ann_t}),
-variables (@code{var_ann_t}) and SSA names (@code{ssa_name_ann_t}).
+Presently, we define annotations for variables (@code{var_ann_t}).
Annotations are defined and documented in @file{tree-flow.h}.
-@node Statement Operands
-@section Statement Operands
+@node SSA Operands
+@section SSA Operands
@cindex operands
@cindex virtual operands
@cindex real operands
diff --git a/gcc/final.c b/gcc/final.c
index a9b51caeeca..e2d9e5a9766 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -3349,6 +3349,31 @@ output_asm_label (rtx x)
assemble_name (asm_out_file, buf);
}
+/* Helper rtx-iteration-function for output_operand. Marks
+ SYMBOL_REFs as referenced through use of assemble_external. */
+
+static int
+mark_symbol_ref_as_used (rtx *xp, void *dummy ATTRIBUTE_UNUSED)
+{
+ rtx x = *xp;
+
+ /* If we have a used symbol, we may have to emit assembly
+ annotations corresponding to whether the symbol is external, weak
+ or has non-default visibility. */
+ if (GET_CODE (x) == SYMBOL_REF)
+ {
+ tree t;
+
+ t = SYMBOL_REF_DECL (x);
+ if (t)
+ assemble_external (t);
+
+ return -1;
+ }
+
+ return 0;
+}
+
/* Print operand X using machine-dependent assembler syntax.
The macro PRINT_OPERAND is defined just to control this function.
CODE is a non-digit that preceded the operand-number in the % spec,
@@ -3369,14 +3394,11 @@ output_operand (rtx x, int code ATTRIBUTE_UNUSED)
gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);
PRINT_OPERAND (asm_out_file, x, code);
- if (x && MEM_P (x) && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
- {
- tree t;
- x = XEXP (x, 0);
- t = SYMBOL_REF_DECL (x);
- if (t)
- assemble_external (t);
- }
+
+ if (x == NULL_RTX)
+ return;
+
+ for_each_rtx (&x, mark_symbol_ref_as_used, NULL);
}
/* Print a memory reference operand for address X
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index c972097a67b..e3624139157 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,34 @@
+2008-09-21 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/37583
+ * decl.c (scalarize_intrinsic_call): Both subroutines and
+ functions can give a true for get_proc_mame's last argument so
+ remove the &&gfc_current_ns->proc_name->attr.function.
+ resolve.c (resolve_actual_arglist): Add check for recursion by
+ reference to procedure as actual argument.
+
+2008-09-21 Daniel Kraft <d@domob.eu>
+
+ PR fortran/35846
+ * trans.h (gfc_conv_string_length): New argument `expr'.
+ * trans-expr.c (flatten_array_ctors_without_strlen): New method.
+ (gfc_conv_string_length): New argument `expr' that is used in a new
+ special case handling if cl->length is NULL.
+ (gfc_conv_subref_array_arg): Pass expr to gfc_conv_string_length.
+ * trans-array.c (gfc_conv_expr_descriptor): Ditto.
+ (gfc_trans_auto_array_allocation): Pass NULL as new expr.
+ (gfc_trans_g77_array), (gfc_trans_dummy_array_bias): Ditto.
+ (gfc_trans_deferred_array): Ditto.
+ (gfc_trans_array_constructor): Save and restore old values of globals
+ used for bounds checking.
+ * trans-decl.c (gfc_trans_dummy_character): Ditto.
+ (gfc_trans_auto_character_variable): Ditto.
+
+2008-09-21 Daniel Kraft <d@domob.eu>
+
+ * decl.c (match_procedure_in_type): Changed misleading error message
+ for not yet implemented PROCEDURE(interface) syntax.
+
2008-09-18 Paul Thomas <pault@gcc.gnu.org>
PR fortran/35945
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 7e4cabf21ad..370ac10b3a9 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -4639,8 +4639,7 @@ gfc_match_entry (void)
created symbols attached to the current namespace. */
if (get_proc_name (name, &entry,
gfc_current_ns->parent != NULL
- && module_procedure
- && gfc_current_ns->proc_name->attr.function))
+ && module_procedure))
return MATCH_ERROR;
proc = gfc_current_block ();
@@ -6907,8 +6906,7 @@ match_procedure_in_type (void)
/* TODO: Really implement PROCEDURE(interface). */
if (gfc_match (" (") == MATCH_YES)
{
- gfc_error ("Procedure with interface only allowed in abstract types at"
- " %C");
+ gfc_error ("PROCEDURE(interface) at %C is not yet implemented");
return MATCH_ERROR;
}
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index f8f2df972cc..a7c62c30532 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -1176,6 +1176,15 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype,
/* Just in case a specific was found for the expression. */
sym = e->symtree->n.sym;
+ if (sym->attr.entry && sym->ns->entries
+ && sym->ns == gfc_current_ns
+ && !sym->ns->entries->sym->attr.recursive)
+ {
+ gfc_error ("Reference to ENTRY '%s' at %L is recursive, but procedure "
+ "'%s' is not declared as RECURSIVE",
+ sym->name, &e->where, sym->ns->entries->sym->name);
+ }
+
/* If the symbol is the function that names the current (or
parent) scope, then we really have a variable reference. */
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index f4af4f25da1..42b9967764f 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -1694,6 +1694,13 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where)
tree type;
tree loopfrom;
bool dynamic;
+ bool old_first_len, old_typespec_chararray_ctor;
+ tree old_first_len_val;
+
+ /* Save the old values for nested checking. */
+ old_first_len = first_len;
+ old_first_len_val = first_len_val;
+ old_typespec_chararray_ctor = typespec_chararray_ctor;
/* Do bounds-checking here and in gfc_trans_array_ctor_element only if no
typespec was given for the array constructor. */
@@ -1792,7 +1799,7 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where)
if (size && compare_tree_int (size, nelem) == 0)
{
gfc_trans_constant_array_constructor (loop, ss, type);
- return;
+ goto finish;
}
}
}
@@ -1849,6 +1856,12 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where)
gcc_unreachable ();
}
#endif
+
+finish:
+ /* Restore old values of globals. */
+ first_len = old_first_len;
+ first_len_val = old_first_len_val;
+ typespec_chararray_ctor = old_typespec_chararray_ctor;
}
@@ -4080,7 +4093,7 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
if (sym->ts.type == BT_CHARACTER
&& onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
{
- gfc_conv_string_length (sym->ts.cl, &block);
+ gfc_conv_string_length (sym->ts.cl, NULL, &block);
gfc_trans_vla_type_sizes (sym, &block);
@@ -4104,7 +4117,7 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
if (sym->ts.type == BT_CHARACTER
&& !INTEGER_CST_P (sym->ts.cl->backend_decl))
- gfc_conv_string_length (sym->ts.cl, &block);
+ gfc_conv_string_length (sym->ts.cl, NULL, &block);
size = gfc_trans_array_bounds (type, sym, &offset, &block);
@@ -4170,7 +4183,7 @@ gfc_trans_g77_array (gfc_symbol * sym, tree body)
if (sym->ts.type == BT_CHARACTER
&& TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
- gfc_conv_string_length (sym->ts.cl, &block);
+ gfc_conv_string_length (sym->ts.cl, NULL, &block);
/* Evaluate the bounds of the array. */
gfc_trans_array_bounds (type, sym, &offset, &block);
@@ -4262,7 +4275,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
if (sym->ts.type == BT_CHARACTER
&& TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
- gfc_conv_string_length (sym->ts.cl, &block);
+ gfc_conv_string_length (sym->ts.cl, NULL, &block);
checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
@@ -4848,7 +4861,6 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
break;
}
-
gfc_init_loopinfo (&loop);
/* Associate the SS with the loop. */
@@ -4872,7 +4884,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
loop.temp_ss->next = gfc_ss_terminator;
if (expr->ts.type == BT_CHARACTER && !expr->ts.cl->backend_decl)
- gfc_conv_string_length (expr->ts.cl, &se->pre);
+ gfc_conv_string_length (expr->ts.cl, expr, &se->pre);
loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
@@ -5672,7 +5684,7 @@ gfc_trans_deferred_array (gfc_symbol * sym, tree body)
if (sym->ts.type == BT_CHARACTER
&& !INTEGER_CST_P (sym->ts.cl->backend_decl))
{
- gfc_conv_string_length (sym->ts.cl, &fnblock);
+ gfc_conv_string_length (sym->ts.cl, NULL, &fnblock);
gfc_trans_vla_type_sizes (sym, &fnblock);
}
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index ec00ee2ee8f..20253e668ca 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -2583,7 +2583,7 @@ gfc_trans_dummy_character (gfc_symbol *sym, gfc_charlen *cl, tree fnbody)
gfc_start_block (&body);
/* Evaluate the string length expression. */
- gfc_conv_string_length (cl, &body);
+ gfc_conv_string_length (cl, NULL, &body);
gfc_trans_vla_type_sizes (sym, &body);
@@ -2607,7 +2607,7 @@ gfc_trans_auto_character_variable (gfc_symbol * sym, tree fnbody)
gfc_start_block (&body);
/* Evaluate the string length expression. */
- gfc_conv_string_length (sym->ts.cl, &body);
+ gfc_conv_string_length (sym->ts.cl, NULL, &body);
gfc_trans_vla_type_sizes (sym, &body);
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 216b3df1c96..e0f2f77cd59 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -241,17 +241,102 @@ gfc_get_expr_charlen (gfc_expr *e)
return length;
}
-
+
+/* For each character array constructor subexpression without a ts.cl->length,
+ replace it by its first element (if there aren't any elements, the length
+ should already be set to zero). */
+
+static void
+flatten_array_ctors_without_strlen (gfc_expr* e)
+{
+ gfc_actual_arglist* arg;
+ gfc_constructor* c;
+
+ if (!e)
+ return;
+
+ switch (e->expr_type)
+ {
+
+ case EXPR_OP:
+ flatten_array_ctors_without_strlen (e->value.op.op1);
+ flatten_array_ctors_without_strlen (e->value.op.op2);
+ break;
+
+ case EXPR_COMPCALL:
+ /* TODO: Implement as with EXPR_FUNCTION when needed. */
+ gcc_unreachable ();
+
+ case EXPR_FUNCTION:
+ for (arg = e->value.function.actual; arg; arg = arg->next)
+ flatten_array_ctors_without_strlen (arg->expr);
+ break;
+
+ case EXPR_ARRAY:
+
+ /* We've found what we're looking for. */
+ if (e->ts.type == BT_CHARACTER && !e->ts.cl->length)
+ {
+ gfc_expr* new_expr;
+ gcc_assert (e->value.constructor);
+
+ new_expr = e->value.constructor->expr;
+ e->value.constructor->expr = NULL;
+
+ flatten_array_ctors_without_strlen (new_expr);
+ gfc_replace_expr (e, new_expr);
+ break;
+ }
+
+ /* Otherwise, fall through to handle constructor elements. */
+ case EXPR_STRUCTURE:
+ for (c = e->value.constructor; c; c = c->next)
+ flatten_array_ctors_without_strlen (c->expr);
+ break;
+
+ default:
+ break;
+
+ }
+}
+
/* Generate code to initialize a string length variable. Returns the
- value. */
+ value. For array constructors, cl->length might be NULL and in this case,
+ the first element of the constructor is needed. expr is the original
+ expression so we can access it but can be NULL if this is not needed. */
void
-gfc_conv_string_length (gfc_charlen * cl, stmtblock_t * pblock)
+gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
{
gfc_se se;
gfc_init_se (&se, NULL);
+
+ /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
+ "flatten" array constructors by taking their first element; all elements
+ should be the same length or a cl->length should be present. */
+ if (!cl->length)
+ {
+ gfc_expr* expr_flat;
+ gcc_assert (expr);
+
+ expr_flat = gfc_copy_expr (expr);
+ flatten_array_ctors_without_strlen (expr_flat);
+ gfc_resolve_expr (expr_flat);
+
+ gfc_conv_expr (&se, expr_flat);
+ gfc_add_block_to_block (pblock, &se.pre);
+ cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
+
+ gfc_free_expr (expr_flat);
+ return;
+ }
+
+ /* Convert cl->length. */
+
+ gcc_assert (cl->length);
+
gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
se.expr = fold_build2 (MAX_EXPR, gfc_charlen_type_node, se.expr,
build_int_cst (gfc_charlen_type_node, 0));
@@ -2092,7 +2177,7 @@ gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr,
/* Build an ss for the temporary. */
if (expr->ts.type == BT_CHARACTER && !expr->ts.cl->backend_decl)
- gfc_conv_string_length (expr->ts.cl, &parmse->pre);
+ gfc_conv_string_length (expr->ts.cl, expr, &parmse->pre);
base_type = gfc_typenode_for_spec (&expr->ts);
if (GFC_ARRAY_TYPE_P (base_type)
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 36553ea255b..b3a0368160f 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -340,7 +340,7 @@ tree gfc_conv_string_tmp (gfc_se *, tree, tree);
/* Get the string length variable belonging to an expression. */
tree gfc_get_expr_charlen (gfc_expr *);
/* Initialize a string length variable. */
-void gfc_conv_string_length (gfc_charlen *, stmtblock_t *);
+void gfc_conv_string_length (gfc_charlen *, gfc_expr *, stmtblock_t *);
/* Ensure type sizes can be gimplified. */
void gfc_trans_vla_type_sizes (gfc_symbol *, stmtblock_t *);
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 9075b2e58e2..f6a14505658 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -3188,9 +3188,11 @@ canonicalize_cond_expr_cond (tree t)
return NULL_TREE;
}
-/* Build call same as STMT but skipping arguments ARGS_TO_SKIP. */
+/* Build a GIMPLE_CALL identical to STMT but skipping the arguments in
+ the positions marked by the set ARGS_TO_SKIP. */
+
gimple
-giple_copy_call_skip_args (gimple stmt, bitmap args_to_skip)
+gimple_copy_call_skip_args (gimple stmt, bitmap args_to_skip)
{
int i;
tree fn = gimple_call_fn (stmt);
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 03b6217ebab..85fc75e0a52 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -4479,7 +4479,7 @@ basic_block gsi_insert_on_edge_immediate (edge, gimple);
basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq);
void gsi_commit_one_edge_insert (edge, basic_block *);
void gsi_commit_edge_inserts (void);
-gimple giple_copy_call_skip_args (gimple, bitmap);
+gimple gimple_copy_call_skip_args (gimple, bitmap);
/* Convenience routines to walk all statements of a gimple function.
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 455ba91ec35..46981972f16 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -967,7 +967,8 @@ ipcp_update_callgraph (void)
current_function_decl = cs->caller->decl;
push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
- new_stmt = giple_copy_call_skip_args (cs->call_stmt, args_to_skip);
+ new_stmt = gimple_copy_call_skip_args (cs->call_stmt,
+ args_to_skip);
gsi = gsi_for_stmt (cs->call_stmt);
gsi_replace (&gsi, new_stmt, true);
cgraph_set_call_stmt (cs, new_stmt);
@@ -1050,7 +1051,7 @@ ipcp_estimate_growth (struct cgraph_node *node)
int growth;
for (cs = node->callers; cs != NULL; cs = cs->next_caller)
- if (!ipcp_need_redirect_p (cs))
+ if (cs->caller == node || !ipcp_need_redirect_p (cs))
redirectable_node_callers++;
else
need_original = true;
@@ -1158,7 +1159,6 @@ ipcp_insert_stage (void)
int i;
VEC (cgraph_edge_p, heap) * redirect_callers;
varray_type replace_trees;
- struct cgraph_edge *cs;
int node_callers, count;
tree parm_tree;
struct ipa_replace_map *replace_param;
@@ -1208,6 +1208,7 @@ ipcp_insert_stage (void)
struct ipa_node_params *info;
int growth = 0;
bitmap args_to_skip;
+ struct cgraph_edge *cs;
node = (struct cgraph_node *)fibheap_extract_min (heap);
node->aux = NULL;
@@ -1229,6 +1230,13 @@ ipcp_insert_stage (void)
new_insns += growth;
+ /* Look if original function becomes dead after clonning. */
+ for (cs = node->callers; cs != NULL; cs = cs->next_caller)
+ if (cs->caller == node || ipcp_need_redirect_p (cs))
+ break;
+ if (!cs && !node->needed)
+ bitmap_set_bit (dead_nodes, node->uid);
+
info = IPA_NODE_REF (node);
count = ipa_get_param_count (info);
diff --git a/gcc/ira.c b/gcc/ira.c
index dfaf34fa4aa..f4d399cb491 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -714,8 +714,6 @@ enum reg_class ira_important_classes[N_REG_CLASSES];
classes. */
int ira_important_class_nums[N_REG_CLASSES];
-#ifdef IRA_COVER_CLASSES
-
/* Check IRA_COVER_CLASSES and sets the four global variables defined
above. */
static void
@@ -723,9 +721,10 @@ setup_cover_and_important_classes (void)
{
int i, j;
enum reg_class cl;
- static enum reg_class classes[] = IRA_COVER_CLASSES;
+ const enum reg_class *classes;
HARD_REG_SET temp_hard_regset2;
+ classes = targetm.ira_cover_classes ();
ira_reg_class_cover_size = 0;
for (i = 0; (cl = classes[i]) != LIM_REG_CLASSES; i++)
{
@@ -761,15 +760,12 @@ setup_cover_and_important_classes (void)
}
}
}
-#endif
/* Map of all register classes to corresponding cover class containing
the given class. If given class is not a subset of a cover class,
we translate it into the cheapest cover class. */
enum reg_class ira_class_translate[N_REG_CLASSES];
-#ifdef IRA_COVER_CLASSES
-
/* Set up array IRA_CLASS_TRANSLATE. */
static void
setup_class_translate (void)
@@ -837,7 +833,6 @@ setup_class_translate (void)
ira_class_translate[cl] = best_class;
}
}
-#endif
/* The biggest important reg_class inside of intersection of the two
reg_classes (that is calculated taking only hard registers
@@ -856,8 +851,6 @@ enum reg_class ira_reg_class_intersect[N_REG_CLASSES][N_REG_CLASSES];
reg_class_subunion value. */
enum reg_class ira_reg_class_union[N_REG_CLASSES][N_REG_CLASSES];
-#ifdef IRA_COVER_CLASSES
-
/* Set up IRA_REG_CLASS_INTERSECT and IRA_REG_CLASS_UNION. */
static void
setup_reg_class_intersect_union (void)
@@ -943,8 +936,6 @@ setup_reg_class_intersect_union (void)
}
}
-#endif
-
/* Output all cover classes and the translation map into file F. */
static void
print_class_cover (FILE *f)
@@ -975,11 +966,12 @@ static void
find_reg_class_closure (void)
{
setup_reg_subclasses ();
-#ifdef IRA_COVER_CLASSES
- setup_cover_and_important_classes ();
- setup_class_translate ();
- setup_reg_class_intersect_union ();
-#endif
+ if (targetm.ira_cover_classes)
+ {
+ setup_cover_and_important_classes ();
+ setup_class_translate ();
+ setup_reg_class_intersect_union ();
+ }
}
diff --git a/gcc/opts.c b/gcc/opts.c
index b45c0c53a57..6e210ea7ceb 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -870,10 +870,9 @@ decode_options (unsigned int argc, const char **argv)
}
}
-#ifdef IRA_COVER_CLASSES
/* Use IRA if it is implemented for the target. */
- flag_ira = 1;
-#endif
+ if (targetm.ira_cover_classes)
+ flag_ira = 1;
/* -O1 optimizations. */
opt1 = (optimize >= 1);
@@ -1097,13 +1096,11 @@ decode_options (unsigned int argc, const char **argv)
if (!flag_sel_sched_pipelining)
flag_sel_sched_pipelining_outer_loops = 0;
-#ifndef IRA_COVER_CLASSES
- if (flag_ira)
+ if (flag_ira && !targetm.ira_cover_classes)
{
inform (input_location, "-fira does not work on this architecture");
flag_ira = 0;
}
-#endif
/* Save the current optimization options if this is the first call. */
if (first_time_p)
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 07b7f33a2eb..3a332d88efd 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -631,6 +631,12 @@
#define TARGET_HANDLE_PRAGMA_EXTERN_PREFIX 0
#endif
+#ifdef IRA_COVER_CLASSES
+#define TARGET_IRA_COVER_CLASSES default_ira_cover_classes
+#else
+#define TARGET_IRA_COVER_CLASSES 0
+#endif
+
#ifndef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD default_secondary_reload
#endif
@@ -907,6 +913,7 @@
TARGET_INVALID_CONVERSION, \
TARGET_INVALID_UNARY_OP, \
TARGET_INVALID_BINARY_OP, \
+ TARGET_IRA_COVER_CLASSES, \
TARGET_SECONDARY_RELOAD, \
TARGET_EXPAND_TO_RTL_HOOK, \
TARGET_INSTANTIATE_DECLS, \
diff --git a/gcc/target.h b/gcc/target.h
index de8150eb9ba..a7d601ff3ef 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -899,6 +899,9 @@ struct gcc_target
is not permitted on TYPE1 and TYPE2, NULL otherwise. */
const char *(*invalid_binary_op) (int op, const_tree type1, const_tree type2);
+ /* Return the array of IRA cover classes for the current target. */
+ const enum reg_class *(*ira_cover_classes) (void);
+
/* Return the class for a secondary reload, and fill in extra information. */
enum reg_class (*secondary_reload) (bool, rtx, enum reg_class,
enum machine_mode,
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 8edfcfce846..2ea438be336 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -575,6 +575,15 @@ default_internal_arg_pointer (void)
return virtual_incoming_args_rtx;
}
+#ifdef IRA_COVER_CLASSES
+const enum reg_class *
+default_ira_cover_classes (void)
+{
+ static enum reg_class classes[] = IRA_COVER_CLASSES;
+ return classes;
+}
+#endif
+
enum reg_class
default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
enum reg_class reload_class ATTRIBUTE_UNUSED,
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index f8d75e881c8..f5a7a248369 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -88,6 +88,9 @@ extern const char *hook_invalid_arg_for_unprototyped_fn
extern bool hook_bool_const_rtx_commutative_p (const_rtx, int);
extern rtx default_function_value (const_tree, const_tree, bool);
extern rtx default_internal_arg_pointer (void);
+#ifdef IRA_COVER_CLASSES
+extern const enum reg_class *default_ira_cover_classes (void);
+#endif
extern enum reg_class default_secondary_reload (bool, rtx, enum reg_class,
enum machine_mode,
secondary_reload_info *);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 247d214cb47..ca0e70872a9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,53 @@
+2008-09-22 Hans-Peter Nilsson <hp@axis.com>
+
+ PR middle-end/37170
+ PR middle-end/37280
+ * gcc.dg/weak/weak-15.c, gcc.dg/weak/weak-16.c,
+ g++.dg/ext/inline1.C: New tests.
+
+2008-09-21 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR rtl-optimization/33642
+ * gcc.c-torture/compile/pr11832.c: XFAIL on sh*-*-*.
+ * gcc.c-torture/compile/pr33009.c: Likewise.
+
+2008-09-21 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/37583
+ * gfortran.dg/entry_18.f90: New test.
+
+2008-09-21 Daniel Kraft <d@domob.eu>
+
+ PR fortran/35846
+ * gfortran.dg/nested_array_constructor_1.f90: New test.
+ * gfortran.dg/nested_array_constructor_2.f90: New test.
+ * gfortran.dg/nested_array_constructor_3.f90: New test.
+ * gfortran.dg/nested_array_constructor_4.f90: New test.
+ * gfortran.dg/nested_array_constructor_5.f90: New test.
+ * gfortran.dg/nested_array_constructor_6.f90: New test.
+
+2008-09-21 Daniel Kraft <d@domob.eu>
+
+ * gfortran.dg/typebound_proc_4.f03: Changed expected error for not
+ yet implemented PROCEDURE(interface).
+
+2008-09-21 Ira Rosen <irar@il.ibm.com>
+
+ PR tree-optimization/37539
+ * gcc.dg/vect/pr37539.c: New test.
+
+2008-09-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR rtl-optimization/33642
+ * gcc.c-torture/compile/pr11832.c: XFAIL on SPARC.
+ * gcc.c-torture/compile/pr33009.c: Likewise.
+
+2008-09-19 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR tree-opt/30930
+ * gcc.dg/tree-ssa/vector-2.c: New test.
+ * gcc.dg/tree-ssa/vector-3.c: New test.
+
2008-09-18 Bob Wilson <bob.wilson@acm.org>
* gcc.c-torture/compile/pr11832.c: xfail on xtensa*-*-*.
@@ -2695,7 +2745,7 @@
* gfortran.dg/cshift_char_3.f90: New test case.
* gfortran.dg/cshift_nan_1.f90: New test case.
-2008-08-14 Rafael Ávila de Espíndola <espindola@google.com>
+2008-08-14 Rafael Ávila de Espíndola <espindola@google.com>
* gcc.dg/visibility-14.c: New test.
* gcc.dg/visibility-15.c: New test.
@@ -3417,7 +3467,7 @@
PR tree-optimization/36967
* gfortran.dg/pr36967.f: New testcase.
-2008-07-30 Rafael Ávila de Espíndola <espindola@google.com>
+2008-07-30 Rafael Ávila de Espíndola <espindola@google.com>
* gcc.dg/visibility-14.c: New test.
* gcc.dg/visibility-15.c: New test.
@@ -5111,7 +5161,7 @@
dg-additional-sources.
(profopt-execute): Handle additional sources.
-2008-05-28 Rafael Espíndola <espindola@google.com>
+2008-05-28 Rafael Espíndola <espindola@google.com>
* gcc.dg/20080528-1.c: New test.
@@ -5248,7 +5298,7 @@
* g++.dg/template/inline1.C: For the not-defined symbol, use the
pattern from g++.dg/template/qualttp17.C.
-2008-05-23 Rafael Espíndola <espindola@google.com>
+2008-05-23 Rafael Espíndola <espindola@google.com>
* gcc.c-torture/compile/20080522-1.c: Move to gcc.dg.
* gcc.dg/20080522-1.c: Moved from gcc.c-torture.
@@ -5286,7 +5336,7 @@
* gfortran.dg/cshift_large_1.f90: New test.
* gfortran.dg/eoshift_large_1.f90: New test.
-2008-05-22 Rafael Espíndola <espindola@google.com>
+2008-05-22 Rafael Espíndola <espindola@google.com>
* gcc.c-torture/compile/20080522-1.c: New testcase.
@@ -6051,7 +6101,7 @@
PR fortran/36162
* gfortran.dg/module_widestring_1.f90: New test.
-2008-05-08 Rafael Espíndola <espindola@google.com>
+2008-05-08 Rafael Espíndola <espindola@google.com>
* gcc.dg/vect/vect-111.c: Rename to no-trapping-math-vect-111.c
* gcc.dg/vect/vect-ifcvt-11.c: Rename to no-trapping-math-vect-ifcvt-11.c
@@ -6990,7 +7040,7 @@
PR fortran/35780
* gfortran.dg/simplify_argN_1.f90: New test.
-2008-04-06 Tobias Schlüter <tobi@gcc.gnu.org>
+2008-04-06 Tobias Schlüter <tobi@gcc.gnu.org>
PR fortran/35832
* gfortran.dg/io_constraints_2.f90: Adapt to new error message.
@@ -8751,7 +8801,7 @@
* g++.dg/torture/pr35164-1.C: New testcase.
* g++.dg/torture/pr35164-2.C: Likewise.
-2008-02-15 Dominique d'Humières <dominiq@lps.ens.fr>
+2008-02-15 Dominique d'Humières <dominiq@lps.ens.fr>
PR testsuite/35119
* g++.dg/template/spec35.C: Change the regular expressions
diff --git a/gcc/testsuite/g++.dg/ext/inline1.C b/gcc/testsuite/g++.dg/ext/inline1.C
new file mode 100644
index 00000000000..7e5f062e058
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/inline1.C
@@ -0,0 +1,34 @@
+// { dg-do compile }
+// { dg-options "-O" }
+// Make sure inlined non-outlined functions aren't marked weak.
+// We'd get a ".weak xyzzy" annotation trigged by the second declaration.
+
+// { dg-final { scan-assembler-not "weak\[^ \t\]*\[ \t\]_?xyzzy" } }
+
+// The next check isn't really part of the actual test, just to make
+// sure there's no outline-copy of xyzzy, because if that really
+// happened, it *should* be marked linkonce or perhaps weak.
+// { dg-final { scan-assembler-not "xyzzy" } }
+
+extern int x;
+extern void foo(void);
+extern void bar(void);
+
+extern "C" inline int xyzzy(int a)
+{
+ foo();
+ return a + x;
+}
+
+extern "C" int xyzzy(int);
+
+extern inline int plugh(int c)
+{
+ return xyzzy (c);
+}
+
+int y;
+void doit(int b)
+{
+ y = xyzzy (b) + plugh (b);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr11832.c b/gcc/testsuite/gcc.c-torture/compile/pr11832.c
index 3be76363299..05bcf0d76f8 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr11832.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr11832.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* Currently ICEs for IA64, HPPA, MIPS, CRIS, Xtensa and PowerPC; see PR33642. */
-/* { dg-xfail-if "PR33642" { hppa*-*-* mips*-*-* powerpc*-*-linux* cris-*-* crisv32-*-* ia64-*-* xtensa*-*-* } { "*" } { "" } } */
+/* Currently ICEs for IA64, HPPA, MIPS, CRIS, Xtensa, PowerPC, SH and SPARC; see PR33642. */
+/* { dg-xfail-if "PR33642" { hppa*-*-* mips*-*-* powerpc*-*-linux* cris-*-* crisv32-*-* ia64-*-* xtensa*-*-* sh*-*-* sparc*-*-* } { "*" } { "" } } */
/* Currently ICEs for (x86 && ilp32 && pic). */
/* { dg-xfail-if "PR33642/36240" { { i?86-*-* x86_64-*-* } && { ilp32 && { ! nonpic } } } { "*" } { "" } } */
/* { dg-prune-output ".*internal compiler error.*" }
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr33009.c b/gcc/testsuite/gcc.c-torture/compile/pr33009.c
index a897c36bdd7..38944b2414a 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr33009.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr33009.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* Currently ICEs for IA64, HPPA, MIPS, CRIS, Xtensa and PowerPC; see PR33642. */
-/* { dg-xfail-if "PR33642" { hppa*-*-* mips*-*-* powerpc*-*-linux* cris-*-* crisv32-*-* ia64-*-* xtensa*-*-* } { "*" } { "" } } */
+/* Currently ICEs for IA64, HPPA, MIPS, CRIS, Xtensa, PowerPC, SH and SPARC; see PR33642. */
+/* { dg-xfail-if "PR33642" { hppa*-*-* mips*-*-* powerpc*-*-linux* cris-*-* crisv32-*-* ia64-*-* xtensa*-*-* sh*-*-* sparc*-*-* } { "*" } { "" } } */
/* Currently ICEs for (x86 && ilp32 && pic). */
/* { dg-xfail-if "PR33642/36240" { { i?86-*-* x86_64-*-* } && { ilp32 && { ! nonpic } } } { "*" } { "" } } */
/* { dg-prune-output ".*internal compiler error.*" }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vector-2.c b/gcc/testsuite/gcc.dg/tree-ssa/vector-2.c
new file mode 100644
index 00000000000..2ce438899a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vector-2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-w -O1 -fdump-tree-final_cleanup" } */
+
+#define vector __attribute__(( vector_size(16) ))
+
+float f(vector float a, int b, vector float c)
+{
+ vector float dd = c*a;
+ a = (vector float){0,0,0,0};
+ c = (vector float){0,0,0,0};
+ {
+ float d = ((float*)&a)[0];
+ float d1 = ((float*)&c)[0];
+ return d*d1;
+ }
+}
+
+/* We should be able to optimize this to just "return 0.0;" */
+/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 0 "final_cleanup"} } */
+/* { dg-final { scan-tree-dump-times "0.0" 1 "final_cleanup"} } */
+
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vector-3.c b/gcc/testsuite/gcc.dg/tree-ssa/vector-3.c
new file mode 100644
index 00000000000..332e127ddcc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vector-3.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-w -O1 -fdump-tree-final_cleanup" } */
+
+#define vector __attribute((vector_size(16) ))
+vector float a;
+
+float f(float b)
+{
+ vector float c = {0, 0, 0, 0};
+ vector float d = {0, 0, 0, 0};
+ d += c;
+ return ((float*)&c)[2];
+}
+
+/* We should be able to optimize this to just "return 0.0;" */
+/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 0 "final_cleanup"} } */
+/* { dg-final { scan-tree-dump-times "0.0" 1 "final_cleanup"} } */
+
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/pr37539.c b/gcc/testsuite/gcc.dg/vect/pr37539.c
new file mode 100644
index 00000000000..1d569a9986e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr37539.c
@@ -0,0 +1,45 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+__attribute__ ((noinline)) void
+ayuv2yuyv_ref (int *d, int *src, int n)
+{
+ char *dest = (char *)d;
+ int i;
+
+ for(i=0;i<n/2;i++){
+ dest[i*4 + 0] = (src[i*2 + 0])>>16;
+ dest[i*4 + 1] = (src[i*2 + 1])>>8;
+ dest[i*4 + 2] = (src[i*2 + 0])>>16;
+ dest[i*4 + 3] = (src[i*2 + 0])>>0;
+ }
+
+ /* Check results. */
+ for(i=0;i<n/2;i++){
+ if (dest[i*4 + 0] != (src[i*2 + 0])>>16
+ || dest[i*4 + 1] != (src[i*2 + 1])>>8
+ || dest[i*4 + 2] != (src[i*2 + 0])>>16
+ || dest[i*4 + 3] != (src[i*2 + 0])>>0)
+ abort();
+ }
+}
+
+int main ()
+{
+ int d[256], src[128], i;
+
+ for (i = 0; i < 128; i++)
+ src[i] = i;
+
+ ayuv2yuyv_ref(d, src, 128);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_strided_wide } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
+
+
diff --git a/gcc/testsuite/gcc.dg/weak/weak-15.c b/gcc/testsuite/gcc.dg/weak/weak-15.c
new file mode 100644
index 00000000000..2218ca4a746
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/weak/weak-15.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-require-weak "" } */
+/* { dg-options "-fno-common" } */
+
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?a" } } */
+/* { dg-final { scan-assembler-not "weak\[^ \t\]*\[ \t\]_?b" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?c" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?d" } } */
+
+#pragma weak a
+extern char a[];
+
+char *user_a(void)
+{
+ return a+1;
+}
+
+int x;
+int extern inline b(int y)
+{
+ return x+y;
+}
+
+extern int b(int y);
+
+int user_b(int z)
+{
+ return b(z);
+}
+
+#pragma weak c
+extern int c;
+
+int *user_c = &c;
+
+#pragma weak d
+extern char d[];
+
+char *user_d = &d[1];
diff --git a/gcc/testsuite/gcc.dg/weak/weak-16.c b/gcc/testsuite/gcc.dg/weak/weak-16.c
new file mode 100644
index 00000000000..3bcf3885d7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/weak/weak-16.c
@@ -0,0 +1,21 @@
+/* From PR37280. */
+/* { dg-do compile } */
+/* { dg-require-weak "" } */
+/* { dg-options "-fno-common -Os" } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?kallsyms_token_index" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?kallsyms_token_table" } } */
+
+extern int kallsyms_token_index[] __attribute__((weak));
+extern int kallsyms_token_table[] __attribute__((weak));
+void kallsyms_expand_symbol(int *result)
+{
+ int len = *result;
+ int *tptr;
+ while(len) {
+ tptr = &kallsyms_token_table[ kallsyms_token_index[*result] ];
+ len--;
+ while (*tptr) tptr++;
+ *tptr = 1;
+ }
+ *result = 0;
+}
diff --git a/gcc/testsuite/gfortran.dg/entry_18.f90 b/gcc/testsuite/gfortran.dg/entry_18.f90
new file mode 100644
index 00000000000..e00aea7d6b8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/entry_18.f90
@@ -0,0 +1,36 @@
+! { dg-do compile }
+! Test fix for PR37583, in which:
+! (i) the reference to glocal prior to the ENTRY caused an internal
+! error and
+! (ii) the need for a RECURSIVE attribute was ignored.
+!
+! Contributed by Arjen Markus <arjen.markus@wldelft.nl>
+!
+module gsub
+contains
+recursive subroutine suba( g ) ! prefix with "RECURSIVE"
+ interface
+ real function g(x)
+ real x
+ end function
+ end interface
+ real :: x, y
+ call mysub( glocala )
+ return
+entry glocala( x, y )
+ y = x
+end subroutine
+subroutine subb( g )
+ interface
+ real function g(x)
+ real x
+ end function
+ end interface
+ real :: x, y
+ call mysub( glocalb ) ! { dg-error "is recursive" }
+ return
+entry glocalb( x, y )
+ y = x
+end subroutine
+end module
+! { dg-final { cleanup-modules "gsub" } }
diff --git a/gcc/testsuite/gfortran.dg/nested_array_constructor_1.f90 b/gcc/testsuite/gfortran.dg/nested_array_constructor_1.f90
new file mode 100644
index 00000000000..54417a0dedd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/nested_array_constructor_1.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! This test is run with result-checking and -fbounds-check as
+! nested_array_constructor_2.f90
+
+! PR fortran/35846
+! This used to ICE because the charlength of the trim-expression was
+! NULL.
+
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+implicit none
+character(len=2) :: c(3)
+
+c = 'a'
+c = (/ (/ trim(c(1)), 'a' /)//'c', 'cd' /)
+
+print *, c
+
+end
diff --git a/gcc/testsuite/gfortran.dg/nested_array_constructor_2.f90 b/gcc/testsuite/gfortran.dg/nested_array_constructor_2.f90
new file mode 100644
index 00000000000..28c2b49e816
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/nested_array_constructor_2.f90
@@ -0,0 +1,22 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+
+! PR fortran/35846
+! This used to ICE because the charlength of the trim-expression was
+! NULL.
+
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+implicit none
+character(len=2) :: c(3)
+
+c = 'a'
+c = (/ (/ trim(c(1)), 'a' /)//'c', 'cd' /)
+
+print *, c
+
+if (c(1) /= 'ac' .or. c(2) /= 'ac' .or. c(3) /= 'cd') then
+ call abort ()
+end if
+
+end
diff --git a/gcc/testsuite/gfortran.dg/nested_array_constructor_3.f90 b/gcc/testsuite/gfortran.dg/nested_array_constructor_3.f90
new file mode 100644
index 00000000000..dd10e5fafc9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/nested_array_constructor_3.f90
@@ -0,0 +1,22 @@
+! { dg-do run }
+
+! PR fortran/35846
+! Alternate test that also produced an ICE because of a missing length.
+
+PROGRAM test
+ IMPLICIT NONE
+ CHARACTER(LEN=2) :: x
+
+ x = 'a'
+ CALL sub ( (/ TRIM(x), 'a' /) // 'c')
+END PROGRAM
+
+SUBROUTINE sub(str)
+ IMPLICIT NONE
+ CHARACTER(LEN=*) :: str(2)
+ WRITE (*,*) str
+
+ IF (str(1) /= 'ac' .OR. str(2) /= 'ac') THEN
+ CALL abort ()
+ END IF
+END SUBROUTINE sub
diff --git a/gcc/testsuite/gfortran.dg/nested_array_constructor_4.f90 b/gcc/testsuite/gfortran.dg/nested_array_constructor_4.f90
new file mode 100644
index 00000000000..cb113e9c9ae
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/nested_array_constructor_4.f90
@@ -0,0 +1,17 @@
+! { dg-do run }
+
+! PR fortran/35846
+! Alternate test that also produced an ICE because of a missing length.
+
+PROGRAM test
+ IMPLICIT NONE
+ CHARACTER(LEN=2) :: x
+ INTEGER :: length
+
+ x = 'a'
+ length = LEN ( (/ TRIM(x), 'a' /) // 'c')
+
+ IF (length /= 2) THEN
+ CALL abort ()
+ END IF
+END PROGRAM
diff --git a/gcc/testsuite/gfortran.dg/nested_array_constructor_5.f90 b/gcc/testsuite/gfortran.dg/nested_array_constructor_5.f90
new file mode 100644
index 00000000000..7744f1ffe94
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/nested_array_constructor_5.f90
@@ -0,0 +1,16 @@
+! { dg-do compile }
+
+! PR fortran/35846
+! This used to ICE because the charlength of the trim-expression was
+! NULL, but it is switched around to test for the right operand of // being
+! not a constant, too.
+
+implicit none
+character(len=2) :: c(2)
+
+c = 'a'
+c = (/ (/ trim(c(1)), 'a' /) // (/ trim(c(1)), 'a' /) /)
+
+print *, c
+
+end
diff --git a/gcc/testsuite/gfortran.dg/nested_array_constructor_6.f90 b/gcc/testsuite/gfortran.dg/nested_array_constructor_6.f90
new file mode 100644
index 00000000000..6eee6d0b32e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/nested_array_constructor_6.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+
+! PR fortran/35846
+! Nested three levels deep.
+
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+implicit none
+character(len=3) :: c(3)
+c = 'a'
+c = (/ (/ 'A'//(/ trim(c(1)), 'a' /)/)//'c', 'dcd' /)
+print *, c(1)
+print *, c(2)
+print *, c(3)
+end
diff --git a/gcc/testsuite/gfortran.dg/typebound_proc_4.f03 b/gcc/testsuite/gfortran.dg/typebound_proc_4.f03
index bf5be562776..3eb9687ad02 100644
--- a/gcc/testsuite/gfortran.dg/typebound_proc_4.f03
+++ b/gcc/testsuite/gfortran.dg/typebound_proc_4.f03
@@ -33,7 +33,7 @@ MODULE testmod
! TODO: Correct these when things get implemented.
PROCEDURE, DEFERRED :: x ! { dg-error "not yet implemented" }
- PROCEDURE(abc) ! { dg-error "abstract type" }
+ PROCEDURE(abc) ! { dg-error "not yet implemented" }
END TYPE t
CONTAINS
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index 099c19742e4..cb393fba32b 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -220,22 +220,22 @@ static gimple *
free_temp_expr_table (temp_expr_table_p t)
{
gimple *ret = NULL;
- unsigned i;
#ifdef ENABLE_CHECKING
unsigned x;
for (x = 0; x <= num_var_partitions (t->map); x++)
gcc_assert (!t->kill_list[x]);
+ for (x = 0; x < num_ssa_names + 1; x++)
+ {
+ gcc_assert (t->expr_decl_uids[x] == NULL);
+ gcc_assert (t->partition_dependencies[x] == NULL);
+ }
#endif
BITMAP_FREE (t->partition_in_use);
BITMAP_FREE (t->new_replaceable_dependencies);
- for (i = 0; i <= num_ssa_names; i++)
- if (t->expr_decl_uids[i])
- BITMAP_FREE (t->expr_decl_uids[i]);
free (t->expr_decl_uids);
-
free (t->kill_list);
free (t->partition_dependencies);
free (t->num_in_part);
@@ -664,27 +664,14 @@ find_replaceable_exprs (var_map map)
FOR_EACH_BB (bb)
{
find_replaceable_in_bb (table, bb);
- gcc_assert (bitmap_empty_p (table->partition_in_use));
-
#ifdef ENABLE_CHECKING
- {
- unsigned i;
- /* Make sure all the tables have been cleared out. */
- for (i = 0; i < num_ssa_names + 1; i++)
- {
- gcc_assert (table->partition_dependencies[i] == NULL);
- gcc_assert (table->expr_decl_uids[i] == NULL);
- if (i < num_var_partitions (map))
- gcc_assert (table->kill_list[i] == NULL);
- }
- }
+ gcc_assert (bitmap_empty_p (table->partition_in_use));
#endif
}
ret = free_temp_expr_table (table);
return ret;
-}
-
+}
/* Dump TER expression table EXPR to file F. */
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 6a1f6f353c8..073e1290b3c 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1653,7 +1653,7 @@ struct gimple_opt_pass pass_late_warn_uninitialized =
}
};
-/* Compute TREE_ADDRESSABLE for local variables. */
+/* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables. */
static unsigned int
execute_update_addresses_taken (void)
@@ -1663,6 +1663,7 @@ execute_update_addresses_taken (void)
gimple_stmt_iterator gsi;
basic_block bb;
bitmap addresses_taken = BITMAP_ALLOC (NULL);
+ bitmap not_reg_needs = BITMAP_ALLOC (NULL);
bitmap vars_updated = BITMAP_ALLOC (NULL);
bool update_vops = false;
@@ -1672,9 +1673,26 @@ execute_update_addresses_taken (void)
{
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- bitmap taken = gimple_addresses_taken (gsi_stmt (gsi));
+ const_gimple stmt = gsi_stmt (gsi);
+ enum gimple_code code = gimple_code (stmt);
+ bitmap taken = gimple_addresses_taken (stmt);
+
if (taken)
bitmap_ior_into (addresses_taken, taken);
+
+ /* If we have a call or an assignment, see if the lhs contains
+ a local decl that requires not to be a gimple register. */
+ if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
+ {
+ tree lhs = gimple_get_lhs (stmt);
+ /* A plain decl does not need it set. */
+ if (lhs && handled_component_p (lhs))
+ {
+ var = get_base_address (lhs);
+ if (DECL_P (var))
+ bitmap_set_bit (not_reg_needs, DECL_UID (var));
+ }
+ }
}
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -1693,25 +1711,46 @@ execute_update_addresses_taken (void)
}
}
- /* When possible, clear ADDRESSABLE bit and mark variable for conversion into
- SSA. */
+ /* When possible, clear ADDRESSABLE bit or set the REGISTER bit
+ and mark variable for conversion into SSA. */
FOR_EACH_REFERENCED_VAR (var, rvi)
- if (!is_global_var (var)
- && TREE_CODE (var) != RESULT_DECL
- && TREE_ADDRESSABLE (var)
- && !bitmap_bit_p (addresses_taken, DECL_UID (var)))
- {
- TREE_ADDRESSABLE (var) = 0;
- if (is_gimple_reg (var))
+ {
+ /* Global Variables, result decls cannot be changed. */
+ if (is_global_var (var)
+ || TREE_CODE (var) == RESULT_DECL
+ || bitmap_bit_p (addresses_taken, DECL_UID (var)))
+ continue;
+
+ if (TREE_ADDRESSABLE (var))
+ {
+ TREE_ADDRESSABLE (var) = 0;
+ if (is_gimple_reg (var))
+ mark_sym_for_renaming (var);
+ update_vops = true;
+ bitmap_set_bit (vars_updated, DECL_UID (var));
+ if (dump_file)
+ {
+ fprintf (dump_file, "No longer having address taken ");
+ print_generic_expr (dump_file, var, 0);
+ fprintf (dump_file, "\n");
+ }
+ }
+ if (!DECL_GIMPLE_REG_P (var)
+ && !bitmap_bit_p (not_reg_needs, DECL_UID (var))
+ && (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
+ || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE))
+ {
+ DECL_GIMPLE_REG_P (var) = 1;
mark_sym_for_renaming (var);
- update_vops = true;
- bitmap_set_bit (vars_updated, DECL_UID (var));
- if (dump_file)
- {
- fprintf (dump_file, "No longer having address taken ");
- print_generic_expr (dump_file, var, 0);
- fprintf (dump_file, "\n");
- }
+ update_vops = true;
+ bitmap_set_bit (vars_updated, DECL_UID (var));
+ if (dump_file)
+ {
+ fprintf (dump_file, "Decl is now a gimple register ");
+ print_generic_expr (dump_file, var, 0);
+ fprintf (dump_file, "\n");
+ }
+ }
}
/* Operand caches needs to be recomputed for operands referencing the updated
@@ -1728,6 +1767,7 @@ execute_update_addresses_taken (void)
&& bitmap_intersect_p (gimple_stored_syms (stmt), vars_updated)))
update_stmt (stmt);
}
+ BITMAP_FREE (not_reg_needs);
BITMAP_FREE (addresses_taken);
BITMAP_FREE (vars_updated);
return 0;
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index 06d6791e639..4965da4ad0c 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -5947,17 +5947,24 @@ vect_transform_strided_load (gimple stmt, VEC(tree,heap) *dr_chain, int size,
STMT_VINFO_VEC_STMT (vinfo_for_stmt (next_stmt)) = new_stmt;
else
{
- gimple prev_stmt =
- STMT_VINFO_VEC_STMT (vinfo_for_stmt (next_stmt));
- gimple rel_stmt =
- STMT_VINFO_RELATED_STMT (vinfo_for_stmt (prev_stmt));
- while (rel_stmt)
- {
- prev_stmt = rel_stmt;
- rel_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (rel_stmt));
- }
- STMT_VINFO_RELATED_STMT (vinfo_for_stmt (prev_stmt)) = new_stmt;
+ if (!DR_GROUP_SAME_DR_STMT (vinfo_for_stmt (next_stmt)))
+ {
+ gimple prev_stmt =
+ STMT_VINFO_VEC_STMT (vinfo_for_stmt (next_stmt));
+ gimple rel_stmt =
+ STMT_VINFO_RELATED_STMT (vinfo_for_stmt (prev_stmt));
+ while (rel_stmt)
+ {
+ prev_stmt = rel_stmt;
+ rel_stmt =
+ STMT_VINFO_RELATED_STMT (vinfo_for_stmt (rel_stmt));
+ }
+
+ STMT_VINFO_RELATED_STMT (vinfo_for_stmt (prev_stmt)) =
+ new_stmt;
+ }
}
+
next_stmt = DR_GROUP_NEXT_DR (vinfo_for_stmt (next_stmt));
gap_count = 1;
/* If NEXT_STMT accesses the same DR as the previous statement,
diff --git a/gcc/varasm.c b/gcc/varasm.c
index e74adaed983..4fe3c967032 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2290,9 +2290,10 @@ process_pending_assemble_externals (void)
to be emitted. */
static GTY(()) tree weak_decls;
-/* Output something to declare an external symbol to the assembler.
- (Most assemblers don't need this, so we normally output nothing.)
- Do nothing if DECL is not external. */
+/* Output something to declare an external symbol to the assembler,
+ and qualifiers such as weakness. (Most assemblers don't need
+ extern declaration, so we normally output nothing.) Do nothing if
+ DECL is not external. */
void
assemble_external (tree decl ATTRIBUTE_UNUSED)
@@ -2303,15 +2304,22 @@ assemble_external (tree decl ATTRIBUTE_UNUSED)
open. If it's not, we should not be calling this function. */
gcc_assert (asm_out_file);
-#ifdef ASM_OUTPUT_EXTERNAL
if (!DECL_P (decl) || !DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
return;
- if (SUPPORTS_WEAK && DECL_WEAK (decl))
+ /* We want to output annotation for weak and external symbols at
+ very last to check if they are references or not. */
+
+ if (SUPPORTS_WEAK && DECL_WEAK (decl)
+ /* TREE_STATIC is a weird and abused creature which is not
+ generally the right test for whether an entity has been
+ locally emitted, inlined or otherwise not-really-extern, but
+ for declarations that can be weak, it happens to be
+ match. */
+ && !TREE_STATIC (decl))
weak_decls = tree_cons (NULL, decl, weak_decls);
- /* We want to output external symbols at very last to check if they
- are references or not. */
+#ifdef ASM_OUTPUT_EXTERNAL
pending_assemble_externals = tree_cons (0, decl,
pending_assemble_externals);
#endif
@@ -4064,9 +4072,10 @@ constructor_static_from_elts_p (const_tree ctor)
}
/* A subroutine of initializer_constant_valid_p. VALUE is either a
- MINUS_EXPR or a POINTER_PLUS_EXPR, and ENDTYPE is a narrowing
- conversion to something smaller than a pointer. This returns
- null_pointer_node if the resulting value is an absolute constant
+ MINUS_EXPR or a POINTER_PLUS_EXPR. This looks for cases of VALUE
+ which are valid when ENDTYPE is an integer of any size; in
+ particular, this does not accept a pointer minus a constant. This
+ returns null_pointer_node if the VALUE is an absolute constant
which can be used to initialize a static variable. Otherwise it
returns NULL. */
@@ -4075,6 +4084,9 @@ narrowing_initializer_constant_valid_p (tree value, tree endtype)
{
tree op0, op1;
+ if (!INTEGRAL_TYPE_P (endtype))
+ return NULL_TREE;
+
op0 = TREE_OPERAND (value, 0);
op1 = TREE_OPERAND (value, 1);
diff --git a/libada/ChangeLog b/libada/ChangeLog
index 4f1c8217784..55766736d33 100644
--- a/libada/ChangeLog
+++ b/libada/ChangeLog
@@ -1,3 +1,12 @@
+2008-09-21 Laurent Guerby <laurent@guerby.net>
+ Paolo Bonzini <bonzini@gnu.org>
+
+ PR ada/5911
+ * Makefile.in (all, install, mostlyclean, clean, distclean): Add
+ multilib handling.
+ * configure.ac: Add multilib handling.
+ * configure: Regenerate.
+
2008-08-29 Laurent Guerby <laurent@guerby.net>
* Makefile.in (FLAGS_TO_PASS): renamed to LIBADA_FLAGS_TO_PASS to
diff --git a/libada/Makefile.in b/libada/Makefile.in
index 05a42335f01..2c568688609 100644
--- a/libada/Makefile.in
+++ b/libada/Makefile.in
@@ -17,6 +17,17 @@
# Default target; must be first.
all: gnatlib
+ $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
+
+.PHONY: all install
+
+## Multilib support variables.
+MULTISRCTOP =
+MULTIBUILDTOP =
+MULTIDIRS =
+MULTISUBDIR =
+MULTIDO = true
+MULTICLEAN = true
# Standard autoconf-set variables.
SHELL = @SHELL@
@@ -48,12 +59,12 @@ GNATLIBCFLAGS= -g -O2
# Get target-specific overrides for TARGET_LIBGCC2_CFLAGS.
host_subdir = @host_subdir@
-GCC_DIR=../../$(host_subdir)/gcc
+GCC_DIR=$(MULTIBUILDTOP)../../$(host_subdir)/gcc
include $(GCC_DIR)/libgcc.mvars
target_noncanonical:=@target_noncanonical@
version := $(shell cat $(srcdir)/../gcc/BASE-VER)
-libsubdir := $(libdir)/gcc/$(target_noncanonical)/$(version)
+libsubdir := $(libdir)/gcc/$(target_noncanonical)/$(version)$(MULTISUBDIR)
# exeext should not be used because it's the *host* exeext. We're building
# a *target* library, aren't we?!? Likewise for CC. Still, provide bogus
@@ -64,11 +75,12 @@ LIBADA_FLAGS_TO_PASS = \
"LDFLAGS=$(LDFLAGS)" \
"LN_S=$(LN_S)" \
"SHELL=$(SHELL)" \
- "GNATLIBFLAGS=$(GNATLIBFLAGS)" \
- "GNATLIBCFLAGS=$(GNATLIBCFLAGS)" \
+ "GNATLIBFLAGS=$(GNATLIBFLAGS) $(MULTIFLAGS)" \
+ "GNATLIBCFLAGS=$(GNATLIBCFLAGS) $(MULTIFLAGS)" \
"TARGET_LIBGCC2_CFLAGS=$(TARGET_LIBGCC2_CFLAGS)" \
"THREAD_KIND=$(THREAD_KIND)" \
"TRACE=$(TRACE)" \
+ "MULTISUBDIR=$(MULTISUBDIR)" \
"libsubdir=$(libsubdir)" \
"objext=$(objext)" \
"prefix=$(prefix)" \
@@ -119,7 +131,8 @@ html:
TAGS:
# Installation rules.
-install:
+install: install-gnatlib
+ $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do # $(MAKE)
install-info:
@@ -129,10 +142,13 @@ install-html:
# Cleaning rules.
mostlyclean:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean # $(MAKE)
clean:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean # $(MAKE)
distclean:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
$(RM) Makefile config.status config.log
maintainer-clean:
diff --git a/libada/configure b/libada/configure
index 4364253f75e..56a4b481136 100755
--- a/libada/configure
+++ b/libada/configure
@@ -272,7 +272,7 @@ PACKAGE_STRING=
PACKAGE_BUGREPORT=
ac_unique_file="Makefile.in"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical build_libsubdir build_subdir host_subdir target_subdir MAINT enable_shared LN_S default_gnatlib_target CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT warn_cflags LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical build_libsubdir build_subdir host_subdir target_subdir MAINT multi_basedir toolexecdir toolexeclibdir CC ac_ct_CC EXEEXT OBJEXT CFLAGS enable_shared LN_S default_gnatlib_target LDFLAGS CPPFLAGS warn_cflags LIBOBJS LTLIBOBJS'
ac_subst_files=''
ac_pwd=`pwd`
@@ -808,6 +808,7 @@ Optional Features:
--enable-maintainer-mode
enable make rules and dependencies not useful (and
sometimes confusing) to the casual installer
+ --enable-multilib build many library versions (default)
--disable-shared don't provide a shared libgnat
Optional Packages:
@@ -1456,51 +1457,78 @@ else
MAINT='#'
fi;
-# Check whether --enable-shared or --disable-shared was given.
-if test "${enable_shared+set}" = set; then
- enableval="$enable_shared"
-case $enable_shared in
- yes | no) ;;
- *)
- enable_shared=no
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
- for pkg in $enableval; do
- case $pkg in
- ada | libada)
- enable_shared=yes ;;
- esac
- done
- IFS="$ac_save_ifs"
- ;;
-esac
+target_alias=${target_alias-$host_alias}
+# Default to --enable-multilib
+# Check whether --enable-multilib or --disable-multilib was given.
+if test "${enable_multilib+set}" = set; then
+ enableval="$enable_multilib"
+ case "$enableval" in
+ yes) multilib=yes ;;
+ no) multilib=no ;;
+ *) { { echo "$as_me:$LINENO: error: bad value $enableval for multilib option" >&5
+echo "$as_me: error: bad value $enableval for multilib option" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
else
- enable_shared=yes
+ multilib=yes
fi;
+# We may get other options which we leave undocumented:
+# --with-target-subdir, --with-multisrctop, --with-multisubdir
+# See config-ml.in if you want the gory details.
-# Need to pass this down for now :-P
-echo "$as_me:$LINENO: checking whether ln -s works" >&5
-echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
-LN_S=$as_ln_s
-if test "$LN_S" = "ln -s"; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+if test "$srcdir" = "."; then
+ if test "$with_target_subdir" != "."; then
+ multi_basedir="$srcdir/$with_multisrctop../.."
+ else
+ multi_basedir="$srcdir/$with_multisrctop.."
+ fi
else
- echo "$as_me:$LINENO: result: no, using $LN_S" >&5
-echo "${ECHO_T}no, using $LN_S" >&6
+ multi_basedir="$srcdir/.."
fi
-# Determine what to build for 'gnatlib'
-if test $build = $target \
- && test ${enable_shared} = yes ; then
- # Note that build=target is almost certainly the wrong test; FIXME
- default_gnatlib_target="gnatlib-shared"
-else
- default_gnatlib_target="gnatlib-plain"
-fi
+ ac_config_commands="$ac_config_commands default-1"
+
+# Calculate toolexeclibdir
+# Also toolexecdir, though it's only used in toolexeclibdir
+case ${enable_version_specific_runtime_libs} in
+ yes)
+ # Need the gcc compiler version to know where to install libraries
+ # and header files if --enable-version-specific-runtime-libs option
+ # is selected.
+ toolexecdir='$(libdir)/gcc/$(target_alias)'
+ toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
+ ;;
+ no)
+ if test -n "$with_cross_host" &&
+ test x"$with_cross_host" != x"no"; then
+ # Install a library built with a cross compiler in tooldir, not libdir.
+ toolexecdir='$(exec_prefix)/$(target_alias)'
+ toolexeclibdir='$(toolexecdir)/lib'
+ else
+ toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
+ toolexeclibdir='$(libdir)'
+ fi
+ multi_os_directory=`$CC -print-multi-os-directory`
+ case $multi_os_directory in
+ .) ;; # Avoid trailing /.
+ *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+ esac
+ ;;
+esac
+
+
+#TODO: toolexeclibdir is currently disregarded
+
+# Check the compiler.
+# The same as in boehm-gc and libstdc++. Have to borrow it from there.
+# We must force CC to /not/ be precious variables; otherwise
+# the wrong, non-multilib-adjusted value will be used in multilibs.
+# As a side effect, we have to subst CFLAGS ourselves.
+
ac_ext=c
@@ -2443,6 +2471,788 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+
+case $enable_shared in
+ yes | no) ;;
+ *)
+ enable_shared=no
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ case $pkg in
+ ada | libada)
+ enable_shared=yes ;;
+ esac
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+
+else
+ enable_shared=yes
+fi;
+
+
+# Need to pass this down for now :-P
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+
+# Determine what to build for 'gnatlib'
+if test $build = $target \
+ && test ${enable_shared} = yes ; then
+ # Note that build=target is almost certainly the wrong test; FIXME
+ default_gnatlib_target="gnatlib-shared"
+else
+ default_gnatlib_target="gnatlib-plain"
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
warn_cflags=
if test "x$GCC" = "xyes"; then
warn_cflags='$(GCC_WARN_CFLAGS)'
@@ -2896,6 +3706,9 @@ Usage: $0 [OPTIONS] [FILE]...
Configuration files:
$config_files
+Configuration commands:
+$config_commands
+
Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
@@ -2994,7 +3807,24 @@ fi
_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+
+srcdir="$srcdir"
+host="$host"
+target="$target"
+with_multisubdir="$with_multisubdir"
+with_multisrctop="$with_multisrctop"
+with_target_subdir="$with_target_subdir"
+ac_configure_args="${multilib_arg} ${ac_configure_args}"
+multi_basedir="$multi_basedir"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+CC="$CC"
+_ACEOF
@@ -3004,6 +3834,7 @@ do
case "$ac_config_target" in
# Handling of arguments.
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
{ (exit 1); exit 1; }; };;
@@ -3016,6 +3847,7 @@ done
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
fi
# Have a temporary directory for convenience. Make it in the build tree
@@ -3105,16 +3937,19 @@ s,@build_subdir@,$build_subdir,;t t
s,@host_subdir@,$host_subdir,;t t
s,@target_subdir@,$target_subdir,;t t
s,@MAINT@,$MAINT,;t t
+s,@multi_basedir@,$multi_basedir,;t t
+s,@toolexecdir@,$toolexecdir,;t t
+s,@toolexeclibdir@,$toolexeclibdir,;t t
+s,@CC@,$CC,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CFLAGS@,$CFLAGS,;t t
s,@enable_shared@,$enable_shared,;t t
s,@LN_S@,$LN_S,;t t
s,@default_gnatlib_target@,$default_gnatlib_target,;t t
-s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
s,@LDFLAGS@,$LDFLAGS,;t t
s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@ac_ct_CC@,$ac_ct_CC,;t t
-s,@EXEEXT@,$EXEEXT,;t t
-s,@OBJEXT@,$OBJEXT,;t t
s,@warn_cflags@,$warn_cflags,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
@@ -3351,6 +4186,131 @@ s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
done
_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+ ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_dest" : 'X\(//\)[^/]' \| \
+ X"$ac_dest" : 'X\(//\)$' \| \
+ X"$ac_dest" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+ case $ac_dest in
+ default-1 )
+# Only add multilib support code if we just rebuilt the top-level
+# Makefile.
+case " $CONFIG_FILES " in
+ *" Makefile "*)
+ ac_file=Makefile . ${multi_basedir}/config-ml.in
+ ;;
+esac ;;
+ esac
+done
+_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
diff --git a/libada/configure.ac b/libada/configure.ac
index b0a46d00332..c456e17d00a 100644
--- a/libada/configure.ac
+++ b/libada/configure.ac
@@ -49,6 +49,54 @@ AC_ARG_ENABLE([maintainer-mode],
[MAINT='#'])
AC_SUBST([MAINT])dnl
+AC_CANONICAL_SYSTEM
+target_alias=${target_alias-$host_alias}
+
+AM_ENABLE_MULTILIB(, ..)
+# Calculate toolexeclibdir
+# Also toolexecdir, though it's only used in toolexeclibdir
+case ${enable_version_specific_runtime_libs} in
+ yes)
+ # Need the gcc compiler version to know where to install libraries
+ # and header files if --enable-version-specific-runtime-libs option
+ # is selected.
+ toolexecdir='$(libdir)/gcc/$(target_alias)'
+ toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
+ ;;
+ no)
+ if test -n "$with_cross_host" &&
+ test x"$with_cross_host" != x"no"; then
+ # Install a library built with a cross compiler in tooldir, not libdir.
+ toolexecdir='$(exec_prefix)/$(target_alias)'
+ toolexeclibdir='$(toolexecdir)/lib'
+ else
+ toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
+ toolexeclibdir='$(libdir)'
+ fi
+ multi_os_directory=`$CC -print-multi-os-directory`
+ case $multi_os_directory in
+ .) ;; # Avoid trailing /.
+ *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+ esac
+ ;;
+esac
+AC_SUBST(toolexecdir)
+AC_SUBST(toolexeclibdir)
+#TODO: toolexeclibdir is currently disregarded
+
+# Check the compiler.
+# The same as in boehm-gc and libstdc++. Have to borrow it from there.
+# We must force CC to /not/ be precious variables; otherwise
+# the wrong, non-multilib-adjusted value will be used in multilibs.
+# As a side effect, we have to subst CFLAGS ourselves.
+
+m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
+m4_define([_AC_ARG_VAR_PRECIOUS],[])
+AC_PROG_CC
+m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
+
+AC_SUBST(CFLAGS)
+
AC_ARG_ENABLE([shared],
[AC_HELP_STRING([--disable-shared],
[don't provide a shared libgnat])],
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index eaa08f9ca30..965bc0416a4 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,12 @@
+2008-09-19 Jakub Jelinek <jakub@redhat.com>
+ Andreas Tobler <a.tobler@schweiz.org>
+
+ * config/bsd/proc.c: New file.
+ * configure.tgt (*-*-darwin*): Use config_path "bsd posix".
+ * configure.ac: Check for header <sys/sysctl.h>
+ * configure: Regenerate.
+ * config.h.in: Likewise.
+
2008-09-05 Janis Johnson <janis187@us.ibm.com>
* testsuite/ligbomp.c/c.exp: Unset lang_test_file only if it exists.
diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in
index a0e008f34e0..81cbb01702e 100644
--- a/libgomp/Makefile.in
+++ b/libgomp/Makefile.in
@@ -38,7 +38,6 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-LIBOBJDIR =
DIST_COMMON = $(am__configure_deps) $(srcdir)/../config.guess \
$(srcdir)/../config.sub $(srcdir)/../depcomp \
$(srcdir)/../install-sh $(srcdir)/../ltmain.sh \
diff --git a/libgomp/config/bsd/proc.c b/libgomp/config/bsd/proc.c
new file mode 100644
index 00000000000..513d8df3910
--- /dev/null
+++ b/libgomp/config/bsd/proc.c
@@ -0,0 +1,117 @@
+/* Copyright (C) 2005, 2006, 2008 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+ This file is part of the GNU OpenMP Library (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ Libgomp 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 Lesser General Public License for
+ more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with libgomp; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* As a special exception, if you link this library with other files, some
+ of which are compiled with GCC, to produce an executable, this library
+ does not by itself cause the resulting executable to be covered by the
+ GNU General Public License. This exception does not however invalidate
+ any other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+/* This file contains system specific routines related to counting
+ online processors and dynamic load balancing. It is expected that
+ a system may well want to write special versions of each of these.
+
+ The following implementation uses a mix of POSIX and BSD routines. */
+
+#include "libgomp.h"
+#include <unistd.h>
+#include <stdlib.h>
+#ifdef HAVE_GETLOADAVG
+# ifdef HAVE_SYS_LOADAVG_H
+# include <sys/loadavg.h>
+# endif
+#endif
+#ifdef HAVE_SYS_SYSCTL_H
+# include <sys/sysctl.h>
+#endif
+
+static int
+get_num_procs (void)
+{
+#ifdef _SC_NPROCESSORS_ONLN
+ return sysconf (_SC_NPROCESSORS_ONLN);
+#elif defined HW_NCPU
+ int ncpus = 1;
+ size_t len = sizeof(ncpus);
+ sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0);
+ return ncpus;
+#else
+ return 0;
+#endif
+}
+
+/* At startup, determine the default number of threads. It would seem
+ this should be related to the number of cpus online. */
+
+void
+gomp_init_num_threads (void)
+{
+ int ncpus = get_num_procs ();
+
+ if (ncpus > 0)
+ gomp_global_icv.nthreads_var = ncpus;
+}
+
+/* When OMP_DYNAMIC is set, at thread launch determine the number of
+ threads we should spawn for this team. */
+/* ??? I have no idea what best practice for this is. Surely some
+ function of the number of processors that are *still* online and
+ the load average. Here I use the number of processors online
+ minus the 15 minute load average. */
+
+unsigned
+gomp_dynamic_max_threads (void)
+{
+ unsigned n_onln, loadavg;
+ unsigned nthreads_var = gomp_icv (false)->nthreads_var;
+
+ n_onln = get_num_procs ();
+ if (!n_onln || n_onln > nthreads_var)
+ n_onln = nthreads_var;
+
+ loadavg = 0;
+#ifdef HAVE_GETLOADAVG
+ {
+ double dloadavg[3];
+ if (getloadavg (dloadavg, 3) == 3)
+ {
+ /* Add 0.1 to get a kind of biased rounding. */
+ loadavg = dloadavg[2] + 0.1;
+ }
+ }
+#endif
+
+ if (loadavg >= n_onln)
+ return 1;
+ else
+ return n_onln - loadavg;
+}
+
+int
+omp_get_num_procs (void)
+{
+ int ncpus = get_num_procs ();
+ if (ncpus <= 0)
+ ncpus = gomp_icv (false)->nthreads_var;
+ return ncpus;
+}
+
+ialias (omp_get_num_procs)
diff --git a/libgomp/configure b/libgomp/configure
index 1fc0891b26f..a9f7df510f0 100755
--- a/libgomp/configure
+++ b/libgomp/configure
@@ -13540,7 +13540,8 @@ fi
-for ac_header in unistd.h semaphore.h sys/loadavg.h sys/time.h
+
+for ac_header in unistd.h semaphore.h sys/loadavg.h sys/time.h sys/time.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
diff --git a/libgomp/configure.ac b/libgomp/configure.ac
index 21aed2ba819..db8e2811a30 100644
--- a/libgomp/configure.ac
+++ b/libgomp/configure.ac
@@ -154,7 +154,7 @@ AC_SUBST(libtool_VERSION)
AC_STDC_HEADERS
AC_HEADER_TIME
ACX_HEADER_STRING
-AC_CHECK_HEADERS(unistd.h semaphore.h sys/loadavg.h sys/time.h)
+AC_CHECK_HEADERS(unistd.h semaphore.h sys/loadavg.h sys/time.h sys/time.h)
GCC_HEADER_STDINT(gstdint.h)
diff --git a/libgomp/configure.tgt b/libgomp/configure.tgt
index ef44a12a4bd..d66899fbf5f 100644
--- a/libgomp/configure.tgt
+++ b/libgomp/configure.tgt
@@ -111,6 +111,10 @@ case "${target}" in
XLDFLAGS="${XLDFLAGS} -lposix4"
;;
+ *-*-darwin*)
+ config_path="bsd posix"
+ ;;
+
*)
;;
diff --git a/libgomp/testsuite/Makefile.in b/libgomp/testsuite/Makefile.in
index 6ce379e8a0c..ae1806fb2da 100644
--- a/libgomp/testsuite/Makefile.in
+++ b/libgomp/testsuite/Makefile.in
@@ -36,7 +36,6 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-LIBOBJDIR =
subdir = testsuite
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 99340ec117c..cbb6671a568 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,8 @@
+2008-09-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/stl_algo.h (minmax(initializer_list<>): Use make_pair,
+ consistently with the other overload for initializer_list.
+
2008-09-19 Johannes Singler <singler@ira.uka.de>
PR libstdc++/37470
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index 373881c7f1b..d956376d8dd 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -4121,7 +4121,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
pair<const _Tp*, const _Tp*> __p =
std::minmax_element(__l.begin(), __l.end());
- return std::pair<_Tp, _Tp>(*__p.first, *__p.second);
+ return std::make_pair(*__p.first, *__p.second);
}
template<typename _Tp, typename _Compare>