OSDN Git Service

r383@cf-ppc-macosx: monabuilder | 2008-12-23 16:04:56 +0900
authormonabuilder <monabuilder@dabda00f-5829-0410-a8ea-e5f24da5a5ee>
Tue, 23 Dec 2008 07:08:48 +0000 (07:08 +0000)
committermonabuilder <monabuilder@dabda00f-5829-0410-a8ea-e5f24da5a5ee>
Tue, 23 Dec 2008 07:08:48 +0000 (07:08 +0000)
 smerge with /gcc.gnu.org/trunk/

git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/pf3gnuchains/trunk@14 dabda00f-5829-0410-a8ea-e5f24da5a5ee

199 files changed:
ChangeLog
MAINTAINERS
gcc/ChangeLog
gcc/DATESTAMP
gcc/Makefile.in
gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/utils.c
gcc/alias.c
gcc/builtins.c
gcc/c-decl.c
gcc/c-pretty-print.c
gcc/calls.c
gcc/cfgloopanal.c
gcc/cfgrtl.c
gcc/common.opt
gcc/config.gcc
gcc/config/alpha/alpha.c
gcc/config/alpha/sync.md
gcc/config/arm/arm.c
gcc/config/dfp-bit.c
gcc/config/fp-bit.c
gcc/config/i386/i386.c
gcc/config/i386/x86intrin.h [new file with mode: 0644]
gcc/config/ia64/ia64.md
gcc/config/m32c/m32c.h
gcc/config/mips/mips.h
gcc/config/mips/mips.md
gcc/config/mips/sync.md
gcc/config/rs6000/darwin-ldouble.c
gcc/config/rs6000/linux-unwind.h
gcc/config/s390/s390.md
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/mangle.c
gcc/cp/name-lookup.c
gcc/doc/invoke.texi
gcc/doc/md.texi
gcc/doc/sourcebuild.texi
gcc/doc/tm.texi
gcc/dwarf2out.c
gcc/emutls.c
gcc/final.c
gcc/fixed-value.c
gcc/flags.h
gcc/fortran/ChangeLog
gcc/fortran/Make-lang.in
gcc/fortran/check.c
gcc/fortran/cpp.c
gcc/fortran/cpp.h
gcc/fortran/expr.c
gcc/fortran/invoke.texi
gcc/fortran/lang-specs.h
gcc/fortran/lang.opt
gcc/fortran/trans-expr.c
gcc/function.c
gcc/function.h
gcc/genpreds.c
gcc/gimple.c
gcc/gimple.h
gcc/gimplify.c
gcc/graphite.c
gcc/graphite.h
gcc/ipa-inline.c
gcc/ira-build.c
gcc/ira-color.c
gcc/ira-conflicts.c
gcc/ira-costs.c
gcc/ira-emit.c
gcc/ira-int.h
gcc/ira-lives.c
gcc/ira.c
gcc/omp-low.c
gcc/opts.c
gcc/predict.c
gcc/reload1.c
gcc/stor-layout.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/debug/dwarf2/imported-module-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/fixed2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/packed1.C
gcc/testsuite/g++.dg/overload/defarg2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/overload/defarg3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/type-generic-1.C
gcc/testsuite/gcc.c-torture/compile/pr35468.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/20020919-1.c
gcc/testsuite/gcc.dg/ctor1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/block-1.c
gcc/testsuite/gcc.dg/graphite/block-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/block-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/block-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/block-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/pr37485.c
gcc/testsuite/gcc.dg/graphite/pr37684.c
gcc/testsuite/gcc.dg/graphite/pr37883.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/pr37928.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/pr38073.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/pr38084.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/pr38125.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/pr38413.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/pr38446.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/scop-15.c
gcc/testsuite/gcc.dg/graphite/scop-16.c
gcc/testsuite/gcc.dg/graphite/scop-17.c
gcc/testsuite/gcc.dg/graphite/scop-18.c
gcc/testsuite/gcc.dg/memcpy-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/memset-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr31866.c
gcc/testsuite/gcc.dg/pr35442.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr35443.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr35468.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr38271.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr38405.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/type-generic-1.c
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-10.c
gcc/testsuite/gcc.dg/tree-ssa/ssa-store-ccp-3.c
gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c
gcc/testsuite/gcc.dg/vect/pr36630.c
gcc/testsuite/gcc.target/i386/pr37248-2.c
gcc/testsuite/gcc.target/i386/pr37248-3.c
gcc/testsuite/gcc.target/i386/pr38240.c [new file with mode: 0644]
gcc/testsuite/gcc.target/ia64/versionid-1.c
gcc/testsuite/gcc.target/ia64/versionid-2.c
gcc/testsuite/gcc.target/mips/atomic-memory-1.c
gcc/testsuite/gcc.target/mips/fix-r10000-12.c
gcc/testsuite/gcc.target/mips/fix-r10000-6.c
gcc/testsuite/gfortran.dg/boz_14.f90
gcc/testsuite/gfortran.dg/boz_9.f90
gcc/testsuite/gfortran.dg/default_format_denormal_1.f90
gcc/testsuite/gfortran.dg/graphite/id-2.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/graphite/id-3.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/graphite/id-4.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/graphite/pr37852.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/graphite/pr37857.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/graphite/pr37980.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/graphite/pr38083.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/graphite/pr38459.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/init_flag_3.f90
gcc/testsuite/gfortran.dg/init_flag_4.f90
gcc/testsuite/gfortran.dg/init_flag_5.f90
gcc/testsuite/gfortran.dg/integer_exponentiation_1.f90
gcc/testsuite/gfortran.dg/integer_exponentiation_5.F90
gcc/testsuite/gfortran.dg/isnan_1.f90
gcc/testsuite/gfortran.dg/isnan_2.f90
gcc/testsuite/gfortran.dg/matmul_argument_types.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/module_nan.f90
gcc/testsuite/gfortran.dg/namelist_42.f90
gcc/testsuite/gfortran.dg/namelist_43.f90
gcc/testsuite/gfortran.dg/nan_1.f90
gcc/testsuite/gfortran.dg/nan_2.f90
gcc/testsuite/gfortran.dg/nan_3.f90
gcc/testsuite/gfortran.dg/nan_4.f90
gcc/testsuite/gfortran.dg/nearest_1.f90
gcc/testsuite/gfortran.dg/nearest_2.f90
gcc/testsuite/gfortran.dg/nearest_3.f90
gcc/testsuite/gfortran.dg/pr35983.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/pr37243.f
gcc/testsuite/gfortran.dg/real_const_3.f90
gcc/testsuite/gfortran.dg/transfer_simplify_2.f90
gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_spacing.x [new file with mode: 0644]
gcc/testsuite/gnat.dg/aggr10.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/aggr10_pkg.ads [new file with mode: 0644]
gcc/testsuite/gnat.dg/string_comparison.adb [new file with mode: 0644]
gcc/toplev.c
gcc/tree-cfg.c
gcc/tree-flow.h
gcc/tree-optimize.c
gcc/tree-parloops.c
gcc/tree-phinodes.c
gcc/tree-scalar-evolution.c
gcc/tree-sra.c
gcc/tree-ssa-ccp.c
gcc/tree-ssa-loop-ivopts.c
gcc/tree-ssa-pre.c
gcc/tree-ssa-structalias.c
gcc/tree-vrp.c
gcc/tree.c
gcc/tree.h
include/ChangeLog
libcpp/ChangeLog
libcpp/pch.c
libgfortran/ChangeLog
libgfortran/io/transfer.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c/pr36802-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/pr36802-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/pr36802-3.c [new file with mode: 0644]
libjava/ChangeLog
libstdc++-v3/ChangeLog
libstdc++-v3/acinclude.m4
libstdc++-v3/configure
libstdc++-v3/include/bits/forward_list.h
libstdc++-v3/include/tr1_impl/cmath
libstdc++-v3/testsuite/26_numerics/headers/cmath/37582.cc [new file with mode: 0644]
libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/functions.cc

index a49ff41..ee366db 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-12-08  Luis Machado  <luisgpm@br.ibm.com>
+
+       * MAINTAINERS:  Add myself to the write after approval list.
+
 2008-12-04  Jack Howarth  <howarth@bromo.med.uc.edu>
 
         * configure.ac: Add double brackets on darwin[912].
index 7d342e3..5d38f87 100644 (file)
@@ -381,6 +381,7 @@ Manuel L
 Martin v. Löwis                                        loewis@informatik.hu-berlin.de
 H.J. Lu                                                hjl.tools@gmail.com
 Xinliang David Li                              davidxl@google.com
+Luis Machado                                   luisgpm@br.ibm.com
 William Maddox                                 maddox@google.com
 Ziga Mahkovec                                  ziga.mahkovec@klika.si
 Simon Martin                                   simartin@users.sourceforge.net
index 0c889a1..c386069 100644 (file)
@@ -1,3 +1,577 @@
+2008-12-12  Dwarakanath Rajagopal  <dwarak.rajagopal@amd.com>
+
+       * config/i386/x86intrin.h: New header file to support all x86 
+       intrinsics
+       * config.gcc (extra_headers): For x86 and x86-64, add x86intrin.h
+       
+2008-12-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/38402
+       * gcc/doc/md.texi: Remove Y and document Yz, Y2, Yi and Ym
+       constraints for x86.
+
+2008-12-12  Andreas Schwab  <schwab@suse.de>
+
+       * cfgrtl.c (rtl_verify_flow_info_1): Don't apply BLOCK_FOR_INSN on
+       a BARRIER insn.
+
+2008-12-12  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/alpha/sync.md (memory_barrier): Remove mem:BLK from operands.
+       Use Pmode for scratch reg.
+       (*mb_internal): Use (match_dup 0) for unspec operand.
+
+2008-12-12  Alexandre Oliva  <aoliva@redhat.com>
+
+       * tree-vrp.c (extract_range_from_binary_expr): Don't shift by
+       floor_log2 of zero.  Negate widened zero.
+
+2008-12-12  Ben Elliston  <bje@au.ibm.com>
+
+       * config/fp-bit.c (nan): Rename from this ..
+       (makenan): .. to this.
+
+2008-12-11  Adam Nemet  <anemet@caviumnetworks.com>
+
+       * config/mips/mips.md (*branch_bit<bbv><mode>,
+       *branch_bit<bbv><mode>_inverted): Renumber operands so that the
+       label becomes operands[1].
+
+2008-12-11  Harsha Jagasia  <harsha.jagasia@amd.com>
+
+       PR tree-optimization/38446
+       * graphite.c (register_bb_in_sese): New.
+       (bb_in_sese_p): Check if bb belongs to sese region by explicitly
+       looking at the bbs in the region.
+       * graphite.h (sese): Add region_basic_blocks pointer set to
+       structure and initialize at the time of defining new scop.
+
+2008-12-11  Tobias Grosser  <grosser@fim.uni-passau.de>
+
+       * graphite.c (new_graphite_bb): Initialize GBB_STATIC_SCHEDULE.
+       (find_params_in_bb): Do not free data refs.
+       (free_graphite_bb): Add FIXME on disabled free_data_refs.
+
+2008-12-11  Sebastian Pop  <sebastian.pop@amd.com>
+
+       * graphite.c (struct ivtype_map_elt): New.
+       (debug_ivtype_elt, debug_ivtype_map_1, debug_ivtype_map,
+       new_ivtype_map_elt, ivtype_map_elt_info, eq_ivtype_map_elts,
+       gcc_type_for_cloog_iv): New.
+       (loop_iv_stack_patch_for_consts): Use the type of the induction
+       variable from the original loop, except for the automatically
+       generated loops, i.e., in the case of a strip-mined loop, in
+       which case there is no original loop: in that case just use
+       integer_type_node.
+       (new_graphite_bb): Initialize GBB_CLOOG_IV_TYPES.
+       (free_graphite_bb): Free GBB_CLOOG_IV_TYPES.
+       (clast_name_to_gcc): Accept params to be NULL.
+       (clast_to_gcc_expression): Take an extra parameter for the type.
+       Convert to that type all the expressions built by this function.
+       (gcc_type_for_clast_expr, gcc_type_for_clast_eq): New.
+       (graphite_translate_clast_equation): Compute the type of the
+       clast_equation before translating its LHS and RHS.
+       (clast_get_body_of_loop, gcc_type_for_iv_of_clast_loop): New.
+       (graphite_create_new_loop): Compute the type of the induction
+       variable before translating the lower and upper bounds and before
+       creating the induction variable.
+       (rename_variables_from_edge, rename_phis_end_scop): New.
+       (copy_bb_and_scalar_dependences): Call rename_phis_end_scop.
+       (sese_add_exit_phis_edge): Do not use integer_zero_node.
+       (find_cloog_iv_in_expr, compute_cloog_iv_types_1,
+       compute_cloog_iv_types): New.
+       (gloog): Call compute_cloog_iv_types before starting the
+       translation of the clast.
+
+       * graphite.h (struct graphite_bb): New field cloog_iv_types.
+       (GBB_CLOOG_IV_TYPES): New.
+       (debug_ivtype_map): Declared.
+       (oldiv_for_loop): New.
+
+2008-12-10  Tobias Grosser  <grosser@fim.uni-passau.de>
+
+       PR middle-end/38459
+       * graphite.c (new_scop): Initialize SCOP_ADD_PARAMS.
+       (param_index): Assert if parameter is not know after parameter
+       detection.
+       (find_params_in_bb): Detect params directly in GBB_CONDITIONS.
+       (find_scop_parameters): Mark, that we have finished parameter
+       detection.
+       (graphite_transform_loops): Move condition detection before parameter
+       detection.
+       * graphite.h (struct scop): Add SCOP_ADD_PARAMS.
+
+2008-12-11  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       PR testsuite/35677
+       * emutls.c (__emutls_get_address): Make sure offset is really zero
+       before initializing the object's offset.
+
+2008-12-11  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/38253
+       * gimplify.c (gimplify_init_constructor): Don't force constructor
+       into memory if there is just one nonzero element.
+
+2008-12-11  Sebastian Pop  <sebastian.pop@amd.com>
+
+       Fix testsuite/gfortran.dg/graphite/id-4.f90.
+       * graphite.c (scan_tree_for_params): Do not compute the multiplicand
+       when not needed.
+
+2008-12-11  Sebastian Pop  <sebastian.pop@amd.com>
+
+       * graphite.c (build_scops_1): Initialize open_scop.exit
+       and sinfo.last.
+
+2008-12-11  Sebastian Pop  <sebastian.pop@amd.com>
+           Jan Sjodin  <jan.sjodin@amd.com>
+           Harsha Jagasia  <harsha.jagasia@amd.com>
+
+       PR middle-end/37852
+       PR middle-end/37883
+       PR middle-end/37928
+       PR middle-end/37980
+       PR middle-end/38038
+       PR middle-end/38039
+       PR middle-end/38073
+       PR middle-end/38083
+       PR middle-end/38125
+
+       * tree-phinodes.c (remove_phi_nodes): New, extracted from...
+       * tree-cfg.c (remove_phi_nodes_and_edges_for_unreachable_block):
+       ... here.
+       * tree-flow.h (remove_phi_nodes, canonicalize_loop_ivs): Declared.
+       * Makefile.in (graphite.o): Depend on value-prof.h.
+       (graphite.o-warn): Removed -Wno-error.
+       * tree-parloops.c (canonicalize_loop_ivs): Allow reduction_list 
+       to be a NULL pointer.  Call update_stmt.  Return the newly created 
+       cannonical induction variable.
+
+       * graphite.h (debug_rename_map): Declared.  Fix some comments.
+
+       * graphite.c: Reimplement the code generation from graphite to gimple.
+       Include value-prof.h.
+       (loop_iv_stack_get_iv): Do not return NULL for constant substitutions.
+       (get_old_iv_from_ssa_name): Removed.
+       (graphite_stmt_p): New.
+       (new_graphite_bb): Test for useful statements before building a
+       graphite statement for the basic block.
+       (free_graphite_bb): Do not free GBB_DATA_REFS: this is a bug
+       in free_data_ref that calls BITMAP_FREE (DR_VOPS (dr)) without 
+       reason.
+       (recompute_all_dominators, graphite_verify,
+       nb_reductions_in_loop, graphite_loop_normal_form): New.
+       (scop_record_loop): Call graphite_loop_normal_form.
+       (build_scop_loop_nests): Iterate over all the blocks of the
+       function instead of relying on the incomplete information from
+       SCOP_BBS.  Return the success of the operation.
+       (find_params_in_bb): Use the data from GBB_DATA_REFS.
+       (add_bb_domains): Removed.
+       (build_loop_iteration_domains): Don't call add_bb_domains.
+       Add the iteration domain only to the basic blocks that have been
+       translated to graphite.
+       (build_scop_conditions_1): Add constraints only if the basic
+       block have been translated to graphite.
+       (build_scop_data_accesses): Completely disabled until data
+       dependence is correctly implemented.
+       (debug_rename_elt, debug_rename_map_1, debug_rename_map): New.
+       (remove_all_edges_1, remove_all_edges): Removed.
+       (get_new_name_from_old_name): New.
+       (graphite_rename_variables_in_stmt): Renamed 
+       rename_variables_in_stmt.  Call get_new_name_from_old_name.
+       Use replace_exp and update_stmt.
+       (is_old_iv): Renamed is_iv.
+       (expand_scalar_variables_stmt): Extra parameter for renaming map.
+       Use replace_exp and update_stmt.
+       (expand_scalar_variables_expr): Same.  Use the map to get the
+       new names for the renaming of induction variables and for the
+       renaming of variables after a basic block has been copied.
+       (expand_scalar_variables): Same.
+       (graphite_rename_variables): Renamed rename_variables.
+       (move_phi_nodes): Removed.
+       (get_false_edge_from_guard_bb): New.
+       (build_iv_mapping): Do not insert the induction variable of a
+       loop in the renaming iv map if the basic block does not belong
+       to that loop.
+       (register_old_new_names, graphite_copy_stmts_from_block,
+       copy_bb_and_scalar_dependences): New.
+       (translate_clast): Heavily reimplemented: copy basic blocks,
+       do not move them.  Finally, in call cleanup_tree_cfg in gloog.
+       At each translation step call graphite_verify ensuring the 
+       consistency of the SSA, loops and dominators information.
+       (collect_virtual_phis, find_vdef_for_var_in_bb,
+       find_vdef_for_var_1, find_vdef_for_var,
+       patch_phis_for_virtual_defs): Removed huge hack.
+       (mark_old_loops, remove_dead_loops, skip_phi_defs,
+       collect_scop_exit_phi_args, patch_scop_exit_phi_args,
+       gbb_can_be_ignored, scop_remove_ignoreable_gbbs, ): Removed.
+       (remove_sese_region, ifsese, if_region_entry, if_region_exit,
+       if_region_get_condition_block, if_region_set_false_region,
+       create_if_region_on_edge, move_sese_in_condition, bb_in_sese_p,
+       sese_find_uses_to_rename_use, sese_find_uses_to_rename_bb, 
+       sese_add_exit_phis_edge, sese_add_exit_phis_var,
+       rewrite_into_sese_closed_ssa): New.
+       (gloog): Remove dead code.  Early return if code cannot be
+       generated.  Call cleanup_tree_cfg once the scop has been code
+       generated.
+       (graphite_trans_scop_block, graphite_trans_loop_block): Do not 
+       block loops with less than two loops.
+       (graphite_apply_transformations): Remove the call to
+       scop_remove_ignoreable_gbbs.
+       (limit_scops): When build_scop_loop_nests fails, continue on next
+       scop.  Fix open_scop.entry.
+       (graphite_transform_loops): Call recompute_all_dominators: force the
+       recomputation of correct CDI_DOMINATORS and CDI_POST_DOMINATORS.
+       Call initialize_original_copy_tables and free_original_copy_tables
+       to be able to copy basic blocks during code generation.
+       When build_scop_loop_nests fails, continue on next scop.
+       (value_clast): New union.
+       (clast_to_gcc_expression): Fix type cast warning.
+
+2008-12-10  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/36792
+       * tree-ssa-pre.c (compute_avail): Handle tcc_comparison like
+       tcc_binary.
+
+2008-12-10  Daniel Berlin  <dberlin@dberlin.org>
+
+       PR tree-optimization/36792
+       * tree-ssa-pre.c (compute_avail): Don't insert defs into maximal set.
+
+2008-12-10  Alexandre Oliva  <aoliva@redhat.com>
+
+       PR target/37033
+       * dwarf2out.c (saved_do_cfi_asm): New.
+       (dwarf2out_do_frame): Take it into account.
+       (dwarf2out_d_cfi_asm): Likewise.  Set it when appropriate.
+
+2008-12-10  Alexandre Oliva  <aoliva@redhat.com>
+
+       PR middle-end/38271
+       * tree-sra.c (sra_build_bf_assignment): Avoid warnings for
+       variables initialized from SRAed bit fields.
+
+2008-12-10  Martin Guy <martinwguy@yahoo.it>
+
+       PR target/37668
+       * arm.c (arm_size_rtx_costs, case NEG): Don't fall through if the
+       result will be in an FPU register.
+
+2008-12-10  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR target/37170
+       PR target/38448
+       * final.c (output_addr_const) <SYMBOL_REF>: Call assemble_external
+       on the associated SYMBOL_REF_DECL node, if any.
+
+2008-12-09 David Daney <ddaney@caviumnetworks.com>
+
+       * config/mips/sync.md (sync_<optab>_12): Replace
+       MIPS_SYNC_OP_12_NOT_NOP with MIPS_SYNC_OP_12_AND.
+       (sync_old_<optab>_12): Remove third paramater to
+       MIPS_SYNC_OLD_OP_12 macro, replace MIPS_SYNC_OLD_OP_12_NOT_NOP
+       with MIPS_SYNC_OLD_OP_12_AND.
+       (sync_new_<optab>_12): Replace MIPS_SYNC_NEW_OP_12_NOT_NOP
+       with MIPS_SYNC_NEW_OP_12_AND.
+       (sync_nand_12): Replace MIPS_SYNC_OP_12_NOT_NOT with
+       MIPS_SYNC_OP_12_XOR, reduce length attribute to 40.
+       (sync_old_nand_12): Remove third paramater to MIPS_SYNC_OLD_OP_12
+       macro, replace MIPS_SYNC_OLD_OP_12_NOT_NOT with
+       MIPS_SYNC_OLD_OP_12_XOR and reduce length attribute to 40.
+       (sync_new_nand_12): Replace MIPS_SYNC_NEW_OP_12_NOT_NOT with
+       MIPS_SYNC_NEW_OP_12_XOR.
+       * config/mips/mips.h (MIPS_SYNC_OP_12, MIPS_SYNC_OP_12_NOT_NOP,
+       MIPS_SYNC_OP_12_NOT_NOT,MIPS_SYNC_OLD_OP_12_NOT_NOP,
+       MIPS_SYNC_OLD_OP_12_NOT_NOT, MIPS_SYNC_NEW_OP_12,
+       MIPS_SYNC_NEW_OP_12_NOT_NOP, MIPS_SYNC_NEW_OP_12_NOT_NOT,
+       MIPS_SYNC_NAND, MIPS_SYNC_OLD_NAND, MIPS_SYNC_NEW_NAND): Rewritten
+       to implement new __sync_nand semantics.
+       (MIPS_SYNC_OLD_OP_12): Implement new __sync_nand semantics, and
+       remove third parameter.
+       (MIPS_SYNC_OLD_OP_12_NOT_NOP_REG,
+       MIPS_SYNC_OLD_OP_12_NOT_NOT_REG): Removed.
+       (MIPS_SYNC_OP_12_NOT_NOP): Renamed to MIPS_SYNC_OP_12_AND.
+       (MIPS_SYNC_OP_12_NOT_NOT): Renamed to MIPS_SYNC_OP_12_XOR.
+       (MIPS_SYNC_OLD_OP_12_NOT_NOP): Renamed to MIPS_SYNC_OLD_OP_12_AND.
+       (MIPS_SYNC_OLD_OP_12_NOT_NOT): Renamed to MIPS_SYNC_OLD_OP_12_XOR.
+       (MIPS_SYNC_NEW_OP_12_NOT_NOP): Renamed to MIPS_SYNC_NEW_OP_12_AND.
+       (MIPS_SYNC_NEW_OP_12_NOT_NOT): Renamed to MIPS_SYNC_NEW_OP_12_XOR
+
+2008-12-09  Tobias Grosser  <grosser@fim.uni-passau.de>
+
+       * graphite.c (graphite_transform_loops): Always call find_transform ()
+       in ENABLE_CHECKING.  So we test these code paths, even if we do not
+       generate code.
+
+2008-12-09  Tobias Grosser  <grosser@fim.uni-passau.de>
+
+       * graphite.c (print_graphite_bb): Fix printing to file != dump_file.
+
+2008-12-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/38454
+       * function.h (struct function): Add always_inline_functions_inlined.
+       * ipa-inline.c (cgraph_early_inlining): Set it to true.
+       * tree-optimize.c (execute_fixup_cfg): Likewise.
+       * builtins.c (avoid_folding_inline_builtin): New function.
+       (fold_call_expr): Don't optimize always_inline builtins before
+       inlining.
+       (fold_call_stmt): Likewise.
+       (fold_builtin_call_array): Likewise.  Don't call
+       fold_builtin_varargs for BUILT_IN_MD builtins.
+
+       PR tree-optimization/37416
+       * tree-scalar-evolution.c (follow_ssa_edge_in_rhs): Handle NOP_EXPR.
+
+2008-12-09  Janis Johnson  <janis187@us.ibm.com>
+
+       * doc/sourcebuild.texi (Test Directives): Fix formatting.
+
+2008-12-09  Vladimir Makarov  <vmakarov@redhat.com>
+
+       * doc/tm.texi (TARGET_IRA_COVER_CLASSES): Modify description.
+
+       * doc/invoke.texi (-fira-region): Describe new option.
+       (-fira-algorithm): Change the values.
+
+       * ira-conflicts.c (build_conflict_bit_table,
+       build_allocno_conflicts): Use ira_reg_classes_intersect_p.
+       (ira_build_conflicts): Use flag flag_ira_region instead of
+       flag_ira_algorithm.  Prohibit usage of callee-saved likely spilled
+       base registers for allocnos crossing calls.
+
+       * flags.h (enum ira_algorithm): Redefine.
+       (enum ira_region): New.
+       (flag_ira_region): New.
+
+       * cfgloopanal.c (estimate_reg_pressure_cost): Use flag_ira_region
+       instead of flag_ira_algorithm.
+
+       * toplev.c (flag_ira_algorithm): Change the initial value.
+       (flag_ira_region): New.
+
+       * ira-int.h (ira_reg_classes_intersect_p,
+       ira_reg_class_super_classes): New.
+
+       * ira-color.c (update_copy_costs): Use
+       ira_reg_classes_intersect_p.  Use right class to find hard reg
+       index.
+       (update_conflict_hard_regno_costs): Ditto.  Add a new parameter.
+       (assign_hard_reg): Ditto.  Pass additional argument to
+       update_conflict_hard_regno_costs.  Do not uncoalesce for priority
+       coloring.
+       (allocno_priorities, setup_allocno_priorities,
+       allocno_priority_compare_func): Move before color_allocnos.
+       (color_allocnos): Add priority coloring.  Use flag flag_ira_region
+       instead of flag_ira_algorithm.
+       (move_spill_restore): Check classes of the same reg allocno from
+       different regions.
+       (update_curr_costs): Use ira_reg_classes_intersect_p.
+       (ira_reassign_conflict_allocnos): Ditto.
+
+       * opts.c (decode_options): Always set up flag_ira.  Set up
+       flag_ira_algorithm.  Warn CB can not be used for architecture.
+       (common_handle_option): Modify code for -fira-algorithm.  Add code
+       to process -fira-region.
+
+       * ira-lives.c (update_allocno_pressure_excess_length): Process
+       superclasses too.
+       (set_allocno_live, clear_allocno_live, mark_reg_live,
+       mark_reg_dead, process_bb_node_lives): Ditto.
+
+       * ira-emit.c (ira_emit): Fix insn codes.
+       
+       * ira-build.c (propagate_allocno_info): Use flag flag_ira_region
+       instead of flag_ira_algorithm.
+       (allocno_range_compare_func): Ignore classes for priority
+       coloring.
+       (setup_min_max_conflict_allocno_ids): Ditto.
+       (ira_flattening): Use ira_reg_classes_intersect_p.
+
+       * genpreds.c (write_enum_constraint_num): Output
+       CONSTRAINT__LIMIT.
+       
+       * common.opt (fira-algorithm): Modify.
+       (fira-region): New.
+
+       * ira.c (setup_class_hard_regs): Initialize.
+       (setup_cover_and_important_classes): Modify code setting class
+       related info for priority coloring.
+       (setup_class_translate): Ditto.
+       (ira_reg_classes_intersect_p, ira_reg_class_super_classes): New.
+       (setup_reg_class_intersect_union): Rename to
+       setup_reg_class_relations.  Add code for setting up new variables.
+       (find_reg_class_closure): Do not check targetm.ira_cover_classes.
+       (ira): Use flag flag_ira_region instead of flag_ira_algorithm.
+
+       * ira-costs.c (common_classes): New.
+       (print_costs): Use flag flag_ira_region instead of
+       flag_ira_algorithm.
+       (find_allocno_class_costs): Ditto.  Use common_classes.  Translate
+       alt_class.
+       (ira_costs): Allocate/deallocate common_classes.
+       
+       * config/m32c/m32.h (REG_ALLOC_ORDER): Add reg 19.
+       (REG_CLASS_CONTENTS, reg_class, REG_CLASS_NAMES): New entries for
+       R02A_REGS.
+
+       * reload1.c (choose_reload_regs): Use MODE_INT for partial ints in
+       smallest_mode_for_size.
+       
+2008-12-10  Ben Elliston  <bje@au.ibm.com>
+
+       * config/rs6000/linux-unwind.h (get_regs): Constify casts.
+
+2008-12-09  Jan Hubicka  <jh@suse.cz>
+
+       * predict.c (estimate_bb_frequencies): Fix test if profile is present.
+
+2008-12-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/35468
+       * tree-ssa-ccp.c (fold_stmt_r): Don't fold reads from constant
+       string on LHS.
+
+2008-12-09  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/38445
+       * tree-ssa-structalias.c (emit_pointer_definition): Only visit
+       names once.
+       (emit_alias_warning): Adjust.
+
+2008-12-09  Andrew Haley  <aph@redhat.com>
+
+       * fixed-value.c (do_fixed_add): Add comment.
+       * tree-ssa-loop-ivopts.c (iv_ca_cost): Likewise.
+       * builtins.c (fold_builtin_sqrt): Likewise.
+
+2008-12-09  Kai Tietz  <kai.tietz@onevision.com>
+
+       PR/38366
+       * function.c (aggregate_value_p): Get fntype from CALL_EXPR in any
+       case.
+       * calls.c (nitialize_argument_information): Add fntype argument 
+       and use it for calls.promote_function_args.
+       (expand_call): Pass fntype to aggregate_value_p if no fndecl
+       available and pass additional fntype to
+       initialize_argument_information.
+       * config/i386/i386.c (ix86_reg_parm_stack_space): Remove cfun part
+       to get function abi type.
+       (init_cumulative_args): Use for abi kind detection fntype, when no
+       fndecl is available.
+
+2008-12-09  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       * config/s390/s390.md (movti, movdi_64, movdi_31,
+         *movsi_zarch, *movhi, *movqi, *mov<mode>_64, *mov<mode>_31,
+         *mov<mode>_64dfp, *mov<mode>_64, *mov<mode>_31, mov<mode>): Remove
+         Q->Q alternative.
+         (Integer->BLKmode splitter): Removed.
+
+2008-12-08  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/alpha/alpha.c (alpha_set_memflags): Process memory
+       references in full insn sequence.
+
+2008-12-09  Jason Merrill  <jason@redhat.com>
+
+       * gimplify.c (gimplify_init_constructor): Revert to using < rather
+       than <= for sparseness test.
+
+       PR c++/38410
+       * gimplify.c (gimplify_init_constructor): Don't write out a static
+       copy of the CONSTRUCTOR for TREE_ADDRESSABLE types or small sparse
+       initializers.
+
+2008-12-09 Tobias Grosser  <grosser@fim.uni-passau.de>
+
+       PR middle-end/38084
+       Fix testsuite/gfortran.dg/graphite/id-3.f90.
+       * graphite.c (scopdet_basic_block_info): Fix bug that found some
+       regions more than once.
+
+2008-12-09  Ben Elliston  <bje@au.ibm.com>
+
+       * emutls.c (__emutls_get_address): Prototype.
+       (__emutls_register_common): Likewise.
+
+       * config/dfp-bit.c (DFP_TO_INT): Remove unnecessary cast.
+
+2008-12-09  Ben Elliston  <bje@au.ibm.com>
+
+       * config/rs6000/darwin-ldouble.c (fmsub): Remove unused variable, v.
+
+2008-12-08  Steve Ellcey  <sje@cup.hp.com>
+
+       * config/ia64/ia64.md (UNSPECV_GOTO_RECEIVER): New constant.
+       (nonlocal_goto_receiver): New instruction.
+
+2008-12-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/35443
+       * c-pretty-print.c (pp_c_expression): Handle BIND_EXPR.
+
+       PR c/35442
+       * c-pretty-print.c (pp_c_cast_expression, pp_c_expression): Handle
+       VIEW_CONVERT_EXPR the same as CASE_CONVERT.
+
+2008-12-08  Richard Henderson  <rth@redhat.com>
+
+       PR 38240
+       * tree.h (TYPE_MODE): Invoke vector_type_mode when needed.
+       (SET_TYPE_MODE): New.
+       * c-decl.c (parser_xref_tag): Use it.
+       (finish_enum): Likewise.
+       * tree.c (build_pointer_type_for_mode): Likewise.
+       (build_reference_type_for_mode, build_index_type): Likewise.
+       (build_range_type, make_vector_type): Likewise.
+       (build_common_tree_nodes_2): Likewise.
+       * stor-layout.c (compute_record_mode): Likewise.
+       (finalize_type_size, layout_type, make_fract_type): Likewise.
+       (make_accum_type, initialize_sizetypes): Likewise.
+       (vector_type_mode): New.
+       * function.c (allocate_struct_function): Call
+       invoke_set_current_function_hook before querying anything else.
+
+       * config/i386/i386.c (ix86_valid_target_attribute_inner_p): Add avx.
+
+2008-12-08  Luis Machado  <luisgpm@br.ibm.com>
+
+       * alias.c (find_base_term): Synch LO_SUM handling with what
+       find_base_value does.
+
+2008-12-08  Andrew Haley  <aph@redhat.com>
+           Kamaraju Kusumanchi <raju.mailinglists@gmail.com>
+
+       * gimple.h (gimple_build_try): Fix declaration.
+
+       * builtins.c (fold_builtin_sqrt): Don't use a conditional operator.
+       * fixed-value.c (do_fixed_add): Likewise.
+       * tree-ssa-loop-ivopts.c (iv_ca_cost): Likewise.
+
+2008-12-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/36802
+       * omp-low.c (use_pointer_for_field): Only call maybe_lookup_decl
+       on parallel and task contexts.
+
+2008-12-07  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gimple.c (recalculate_side_effects) <tcc_constant>: New case.
+
+2008-12-07  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/38405
+       * tree-vrp.c (simplify_truth_ops_using_ranges): Make sure to
+       not sign-extend truth values.
+
+2008-12-07  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * tree-sra.c (scalarize_use): Create another temporary with the proper
+       type for signed types in the use_all && !is_output bitfield case.
+
 2008-12-06  Steven Bosscher  <steven@gcc.gnu.org>
 
        PR rtl-optimization/36365
index b2d83e6..6a9c232 100644 (file)
@@ -1 +1 @@
-20081207
+20081212
index 097159c..644694b 100644 (file)
@@ -183,8 +183,6 @@ dfp.o-warn = -Wno-error
 bitmap.o-warn = -Wno-error
 # dominance.c contains a -Wc++compat warning.
 dominance.o-warn = -Wno-error
-# graphite.c contains code calling cloog that has problems.
-graphite.o-warn = -Wno-error
 # mips-tfile.c contains -Wcast-qual warnings.
 mips-tfile.o-warn = -Wno-error
 
@@ -2368,7 +2366,8 @@ tree-data-ref.o: tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
 graphite.o: graphite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TOPLEV_H) \
    $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(GIMPLE_H) domwalk.h \
-   $(TREE_DATA_REF_H) $(SCEV_H) tree-pass.h tree-chrec.h graphite.h pointer-set.h
+   $(TREE_DATA_REF_H) $(SCEV_H) tree-pass.h tree-chrec.h graphite.h pointer-set.h \
+   value-prof.h
 tree-vect-analyze.o: tree-vect-analyze.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RECOG_H) $(BASIC_BLOCK_H) \
    $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
index b2425ba..166baa8 100644 (file)
@@ -1,3 +1,10 @@
+2008-12-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR ada/38450
+       * gcc-interface/utils.c (finish_record_type): Use SET_TYPE_MODE.
+       * gcc-interface/decl.c (gnat_to_gnu_entity, make_aligning_type):
+       Likewise.
+
 2008-12-05  Sebastian Pop  <sebastian.pop@amd.com>
 
        PR bootstrap/38262
index 14fcd63..20c5fb4 100644 (file)
@@ -2032,7 +2032,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
           corresponding fat pointer.  */
        TREE_TYPE (gnu_type) = TYPE_POINTER_TO (gnu_type)
          = TYPE_REFERENCE_TO (gnu_type) = gnu_fat_type;
-       TYPE_MODE (gnu_type) = BLKmode;
+       SET_TYPE_MODE (gnu_type, BLKmode);
        TYPE_ALIGN (gnu_type) = TYPE_ALIGN (tem);
        SET_TYPE_UNCONSTRAINED_ARRAY (gnu_fat_type, gnu_type);
 
@@ -2873,7 +2873,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
           that these objects will always be placed in memory.  Do the
           same thing for limited record types.  */
        if (Is_Tagged_Type (gnat_entity) || Is_Limited_Record (gnat_entity))
-         TYPE_MODE (gnu_type) = BLKmode;
+         SET_TYPE_MODE (gnu_type, BLKmode);
 
        /* If this is a derived type, we must make the alias set of this type
           the same as that of the type we are derived from.  We assume here
@@ -5572,7 +5572,7 @@ make_aligning_type (tree type, unsigned int align, tree size,
     = size_binop (PLUS_EXPR, size,
                  size_int (room + align / BITS_PER_UNIT));
 
-  TYPE_MODE (record_type) = BLKmode;
+  SET_TYPE_MODE (record_type, BLKmode);
 
   copy_alias_set (record_type, type);
   return record_type;
@@ -5721,8 +5721,8 @@ make_packable_type (tree type, bool in_record)
   /* Try harder to get a packable type if necessary, for example
      in case the record itself contains a BLKmode field.  */
   if (in_record && TYPE_MODE (new_type) == BLKmode)
-    TYPE_MODE (new_type)
-      = mode_for_size_tree (TYPE_SIZE (new_type), MODE_INT, 1);
+    SET_TYPE_MODE (new_type,
+                  mode_for_size_tree (TYPE_SIZE (new_type), MODE_INT, 1));
 
   /* If neither the mode nor the size has shrunk, return the old type.  */
   if (TYPE_MODE (new_type) == BLKmode && new_size >= size)
index 131b237..7b52d90 100644 (file)
@@ -839,7 +839,7 @@ finish_record_type (tree record_type, tree fieldlist, int rep_level,
   if (rep_level > 0)
     {
       TYPE_ALIGN (record_type) = MAX (BITS_PER_UNIT, TYPE_ALIGN (record_type));
-      TYPE_MODE (record_type) = BLKmode;
+      SET_TYPE_MODE (record_type, BLKmode);
 
       if (!had_size_unit)
        TYPE_SIZE_UNIT (record_type) = size_zero_node;
index 4cadb6b..e5133d6 100644 (file)
@@ -1408,6 +1408,9 @@ find_base_term (rtx x)
        return 0;
       /* Fall through.  */
     case LO_SUM:
+      /* The standard form is (lo_sum reg sym) so look only at the
+         second operand.  */
+      return find_base_term (XEXP (x, 1));
     case PLUS:
     case MINUS:
       {
index 4d507cf..afb3b3f 100644 (file)
@@ -7681,8 +7681,13 @@ fold_builtin_sqrt (tree arg, tree type)
          tree arg0 = CALL_EXPR_ARG (arg, 0);
          tree tree_root;
          /* The inner root was either sqrt or cbrt.  */
-         REAL_VALUE_TYPE dconstroot =
-           BUILTIN_SQRT_P (fcode) ? dconsthalf : dconst_third ();
+         /* This was a conditional expression but it triggered a bug
+            in the Solaris 8 compiler.  */
+         REAL_VALUE_TYPE dconstroot;
+         if (BUILTIN_SQRT_P (fcode))
+           dconstroot = dconsthalf;
+         else
+           dconstroot = dconst_third ();
 
          /* Adjust for the outer root.  */
          SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
@@ -10792,6 +10797,22 @@ fold_builtin_varargs (tree fndecl, tree exp, bool ignore ATTRIBUTE_UNUSED)
   return NULL_TREE;
 }
 
+/* Return true if FNDECL shouldn't be folded right now.
+   If a built-in function has an inline attribute always_inline
+   wrapper, defer folding it after always_inline functions have
+   been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
+   might not be performed.  */
+
+static bool
+avoid_folding_inline_builtin (tree fndecl)
+{
+  return (DECL_DECLARED_INLINE_P (fndecl)
+         && DECL_DISREGARD_INLINE_LIMITS (fndecl)
+         && cfun
+         && !cfun->always_inline_functions_inlined
+         && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
+}
+
 /* A wrapper function for builtin folding that prevents warnings for
    "statement without effect" and the like, caused by removing the
    call node earlier than the warning is generated.  */
@@ -10824,6 +10845,9 @@ fold_call_expr (tree exp, bool ignore)
            return NULL_TREE;
        }
 
+      if (avoid_folding_inline_builtin (fndecl))
+       return NULL_TREE;
+
       /* FIXME: Don't use a list in this interface.  */
       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
          return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
@@ -10926,6 +10950,8 @@ fold_builtin_call_array (tree type,
                && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
              return build_call_array (type, fn, n, argarray);
          }
+       if (avoid_folding_inline_builtin (fndecl))
+         return build_call_array (type, fn, n, argarray);
         if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
           {
             tree arglist = NULL_TREE;
@@ -10934,6 +10960,7 @@ fold_builtin_call_array (tree type,
             ret = targetm.fold_builtin (fndecl, arglist, false);
             if (ret)
               return ret;
+           return build_call_array (type, fn, n, argarray);
           }
         else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
           {
@@ -13642,6 +13669,8 @@ fold_call_stmt (gimple stmt, bool ignore)
     {
       int nargs = gimple_call_num_args (stmt);
 
+      if (avoid_folding_inline_builtin (fndecl))
+       return NULL_TREE;
       /* FIXME: Don't use a list in this interface.  */
       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
         {
index 6f88f62..7f7f2b0 100644 (file)
@@ -5302,7 +5302,7 @@ parser_xref_tag (enum tree_code code, tree name)
     {
       /* Give the type a default layout like unsigned int
         to avoid crashing if it does not get defined.  */
-      TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
+      SET_TYPE_MODE (ref, TYPE_MODE (unsigned_type_node));
       TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node);
       TYPE_USER_ALIGN (ref) = 0;
       TYPE_UNSIGNED (ref) = 1;
@@ -5952,7 +5952,7 @@ finish_enum (tree enumtype, tree values, tree attributes)
       TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype);
       TYPE_SIZE (tem) = TYPE_SIZE (enumtype);
       TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype);
-      TYPE_MODE (tem) = TYPE_MODE (enumtype);
+      SET_TYPE_MODE (tem, TYPE_MODE (enumtype));
       TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
       TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
       TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype);
index cf1c6c3..8676205 100644 (file)
@@ -1629,6 +1629,7 @@ pp_c_cast_expression (c_pretty_printer *pp, tree e)
     case FLOAT_EXPR:
     case FIX_TRUNC_EXPR:
     CASE_CONVERT:
+    case VIEW_CONVERT_EXPR:
       pp_c_type_cast (pp, TREE_TYPE (e));
       pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
       break;
@@ -2020,6 +2021,7 @@ pp_c_expression (c_pretty_printer *pp, tree e)
     case FLOAT_EXPR:
     case FIX_TRUNC_EXPR:
     CASE_CONVERT:
+    case VIEW_CONVERT_EXPR:
       pp_c_cast_expression (pp, e);
       break;
 
@@ -2101,6 +2103,12 @@ pp_c_expression (c_pretty_printer *pp, tree e)
       pp_postfix_expression (pp, TREE_OPERAND (e, 1));
       break;
 
+    case BIND_EXPR:
+      /* We don't yet have a way of dumping statements in a
+         human-readable format.  */
+      pp_string (pp, "({...})");
+      break;
+
     default:
       pp_unsupported_tree (pp, e);
       break;
index e2c4fcb..03994d4 100644 (file)
@@ -136,7 +136,7 @@ static int compute_argument_block_size (int, struct args_size *, tree, tree, int
 static void initialize_argument_information (int, struct arg_data *,
                                             struct args_size *, int,
                                             tree, tree,
-                                            tree, CUMULATIVE_ARGS *, int,
+                                            tree, tree, CUMULATIVE_ARGS *, int,
                                             rtx *, int *, int *, int *,
                                             bool *, bool);
 static void compute_argument_addresses (struct arg_data *, rtx, int);
@@ -938,7 +938,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
                                 struct args_size *args_size,
                                 int n_named_args ATTRIBUTE_UNUSED,
                                 tree exp, tree struct_value_addr_value,
-                                tree fndecl,
+                                tree fndecl, tree fntype,
                                 CUMULATIVE_ARGS *args_so_far,
                                 int reg_parm_stack_space,
                                 rtx *old_stack_level, int *old_pending_adj,
@@ -1119,7 +1119,9 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
       mode = TYPE_MODE (type);
       unsignedp = TYPE_UNSIGNED (type);
 
-      if (targetm.calls.promote_function_args (fndecl ? TREE_TYPE (fndecl) : 0))
+      if (targetm.calls.promote_function_args (fndecl
+                                              ? TREE_TYPE (fndecl)
+                                              : fntype))
        mode = promote_mode (type, mode, &unsignedp, 1);
 
       args[i].unsignedp = unsignedp;
@@ -2088,7 +2090,7 @@ expand_call (tree exp, rtx target, int ignore)
   /* Set up a place to return a structure.  */
 
   /* Cater to broken compilers.  */
-  if (aggregate_value_p (exp, fndecl))
+  if (aggregate_value_p (exp, (!fndecl ? fntype : fndecl)))
     {
       /* This call returns a big structure.  */
       flags &= ~(ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE);
@@ -2245,7 +2247,7 @@ expand_call (tree exp, rtx target, int ignore)
      arguments into ARGS_SIZE, etc.  */
   initialize_argument_information (num_actuals, args, &args_size,
                                   n_named_args, exp,
-                                  structure_value_addr_value, fndecl,
+                                  structure_value_addr_value, fndecl, fntype,
                                   &args_so_far, reg_parm_stack_space,
                                   &old_stack_level, &old_pending_adj,
                                   &must_preallocate, &flags,
index d59fa2f..88c5e95 100644 (file)
@@ -396,8 +396,8 @@ estimate_reg_pressure_cost (unsigned n_new, unsigned n_old, bool speed)
        one.  */
     cost = target_spill_cost [speed] * n_new;
 
-  if (optimize && flag_ira && (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL
-                              || flag_ira_algorithm == IRA_ALGORITHM_MIXED)
+  if (optimize && flag_ira && (flag_ira_region == IRA_REGION_ALL
+                              || flag_ira_region == IRA_REGION_MIXED)
       && number_of_loops () <= (unsigned) IRA_MAX_LOOPS_NUM)
     /* IRA regional allocation deals with high register pressure
        better.  So decrease the cost (to do more accurate the cost
index a7dc507..0e1bb0a 100644 (file)
@@ -1731,7 +1731,8 @@ rtl_verify_flow_info_1 (void)
        }
 
       FOR_BB_INSNS (bb, insn)
-       if (BLOCK_FOR_INSN (insn) != bb)
+       if (!BARRIER_P (insn)
+           && BLOCK_FOR_INSN (insn) != bb)
          {
            error ("insn %d basic block pointer is %d, should be %d",
                   INSN_UID (insn),
index 4e68067..4ffe1fd 100644 (file)
@@ -683,7 +683,11 @@ Use integrated register allocator.
 
 fira-algorithm=
 Common Joined RejectNegative
--fira-algorithm=[regional|CB|mixed] Set the used IRA algorithm
+-fira-algorithm=[CB|priority] Set the used IRA algorithm
+
+fira-region=
+Common Joined RejectNegative
+-fira-region=[one|all|mixed] Set regions for IRA
 
 fira-coalesce
 Common Report Var(flag_ira_coalesce) Init(0)
index 5e9e89d..ba44a95 100644 (file)
@@ -298,7 +298,8 @@ i[34567]86-*-*)
        extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
                       pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
                       nmmintrin.h bmmintrin.h mmintrin-common.h
-                      wmmintrin.h immintrin.h avxintrin.h cross-stdarg.h"
+                      wmmintrin.h immintrin.h x86intrin.h avxintrin.h 
+                      cross-stdarg.h"
        ;;
 x86_64-*-*)
        cpu_type=i386
@@ -307,7 +308,8 @@ x86_64-*-*)
        extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
                       pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
                       nmmintrin.h bmmintrin.h mmintrin-common.h
-                      wmmintrin.h immintrin.h avxintrin.h cross-stdarg.h"
+                      wmmintrin.h immintrin.h x86intrin.h avxintrin.h 
+                      cross-stdarg.h"
        need_64bit_hwint=yes
        ;;
 ia64-*-*)
index 26feea5..52ae122 100644 (file)
@@ -1603,18 +1603,17 @@ alpha_set_memflags_1 (rtx *xp, void *data)
   return -1;
 }
 
-/* Given INSN, which is an INSN list or the PATTERN of a single insn
-   generated to perform a memory operation, look for any MEMs in either
+/* Given SEQ, which is an INSN list, look for any MEMs in either
    a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
    volatile flags from REF into each of the MEMs found.  If REF is not
    a MEM, don't do anything.  */
 
 void
-alpha_set_memflags (rtx insn, rtx ref)
+alpha_set_memflags (rtx seq, rtx ref)
 {
-  rtx *base_ptr;
+  rtx insn;
 
-  if (GET_CODE (ref) != MEM)
+  if (!MEM_P (ref))
     return;
 
   /* This is only called from alpha.md, after having had something
@@ -1627,11 +1626,11 @@ alpha_set_memflags (rtx insn, rtx ref)
       && !MEM_READONLY_P (ref))
     return;
 
-  if (INSN_P (insn))
-    base_ptr = &PATTERN (insn);
-  else
-    base_ptr = &insn;
-  for_each_rtx (base_ptr, alpha_set_memflags_1, (void *) ref);
+  for (insn = seq; insn; insn = NEXT_INSN (insn))
+    if (INSN_P (insn))
+      for_each_rtx (&PATTERN (insn), alpha_set_memflags_1, (void *) ref);
+    else
+      gcc_unreachable ();
 }
 \f
 static rtx alpha_emit_set_const (rtx, enum machine_mode, HOST_WIDE_INT,
index fe8301f..1c7ee45 100644 (file)
 
 
 (define_expand "memory_barrier"
-  [(set (mem:BLK (match_dup 0))
-       (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MB))]
+  [(set (match_dup 0)
+       (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
   ""
 {
-  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
+  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
   MEM_VOLATILE_P (operands[0]) = 1;
 })
 
 (define_insn "*mb_internal"
   [(set (match_operand:BLK 0 "" "")
-       (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MB))]
+       (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
   ""
   "mb"
   [(set_attr "type" "mb")])
index a1cef0b..497564a 100644 (file)
@@ -5281,7 +5281,11 @@ arm_size_rtx_costs (rtx x, int code, int outer_code, int *total)
 
     case NEG:
       if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
-       *total = COSTS_N_INSNS (1);
+       {
+         *total = COSTS_N_INSNS (1);
+         return false;
+       }
+
       /* Fall through */
     case NOT:
       *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
index bfce851..8437491 100644 (file)
@@ -536,7 +536,7 @@ DFP_TO_INT (DFP_C_TYPE x)
   /* Rescale if the exponent is less than zero.  */
   decNumberToIntegralValue (&n2, &n1, &context);
   /* Get a value to use for the quantize call.  */
-  decNumberFromString (&qval, (char *) "1.", &context);
+  decNumberFromString (&qval, "1.", &context);
   /* Force the exponent to zero.  */
   decNumberQuantize (&n1, &n2, &qval, &context);
   /* Get a string, which at this point will not include an exponent.  */
index bdf04ff..1da69b2 100644 (file)
@@ -140,7 +140,7 @@ extern const fp_number_type __thenan_df;
 
 INLINE
 static fp_number_type *
-nan (void)
+makenan (void)
 {
   /* Discard the const qualifier...  */
 #ifdef TFLOAT
@@ -621,7 +621,7 @@ _fpadd_parts (fp_number_type * a,
     {
       /* Adding infinities with opposite signs yields a NaN.  */
       if (isinf (b) && a->sign != b->sign)
-       return nan ();
+       return makenan ();
       return a;
     }
   if (isinf (b))
@@ -802,7 +802,7 @@ _fpmul_parts ( fp_number_type *  a,
   if (isinf (a))
     {
       if (iszero (b))
-       return nan ();
+       return makenan ();
       a->sign = a->sign != b->sign;
       return a;
     }
@@ -810,7 +810,7 @@ _fpmul_parts ( fp_number_type *  a,
     {
       if (iszero (a))
        {
-         return nan ();
+         return makenan ();
        }
       b->sign = a->sign != b->sign;
       return b;
@@ -988,7 +988,7 @@ _fpdiv_parts (fp_number_type * a,
   if (isinf (a) || iszero (a))
     {
       if (a->class == b->class)
-       return nan ();
+       return makenan ();
       return a;
     }
 
index f83ed7e..12e9e5a 100644 (file)
@@ -3408,6 +3408,7 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[])
     IX86_ATTR_ISA ("3dnow",    OPT_m3dnow),
     IX86_ATTR_ISA ("abm",      OPT_mabm),
     IX86_ATTR_ISA ("aes",      OPT_maes),
+    IX86_ATTR_ISA ("avx",      OPT_mavx),
     IX86_ATTR_ISA ("mmx",      OPT_mmmx),
     IX86_ATTR_ISA ("pclmul",   OPT_mpclmul),
     IX86_ATTR_ISA ("popcnt",   OPT_mpopcnt),
@@ -4548,16 +4549,12 @@ ix86_must_pass_in_stack (enum machine_mode mode, const_tree type)
 int
 ix86_reg_parm_stack_space (const_tree fndecl)
 {
-  int call_abi = 0;
-  /* For libcalls it is possible that there is no fndecl at hand.
-     Therefore assume for this case the default abi of the target.  */
-  if (!fndecl)
-    call_abi = (cfun ? cfun->machine->call_abi : DEFAULT_ABI);
-  else if (TREE_CODE (fndecl) == FUNCTION_DECL)
+  int call_abi = SYSV_ABI;
+  if (fndecl != NULL_TREE && TREE_CODE (fndecl) == FUNCTION_DECL)
     call_abi = ix86_function_abi (fndecl);
   else
     call_abi = ix86_function_type_abi (fndecl);
-  if (call_abi == 1)
+  if (call_abi == MS_ABI)
     return 32;
   return 0;
 }
@@ -4646,7 +4643,10 @@ init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
   struct cgraph_local_info *i = fndecl ? cgraph_local_info (fndecl) : NULL;
   memset (cum, 0, sizeof (*cum));
 
-  cum->call_abi = ix86_function_type_abi (fntype);
+  if (fndecl)
+   cum->call_abi = ix86_function_abi (fndecl);
+  else
+   cum->call_abi = ix86_function_type_abi (fntype);
   /* Set up the number of registers to use for passing arguments.  */
   cum->nregs = ix86_regparm;
   if (TARGET_64BIT)
diff --git a/gcc/config/i386/x86intrin.h b/gcc/config/i386/x86intrin.h
new file mode 100644 (file)
index 0000000..ab18869
--- /dev/null
@@ -0,0 +1,73 @@
+/* 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 2, 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 COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you include this header file into source
+   files compiled by GCC, this header file 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.  */
+
+#ifndef _X86INTRIN_H_INCLUDED
+#define _X86INTRIN_H_INCLUDED
+
+#ifdef __MMX__
+#include <mmintrin.h>
+#endif
+
+#ifdef __SSE__
+#include <xmmintrin.h>
+#endif
+
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+
+#ifdef __SSE3__
+#include <pmmintrin.h>
+#endif
+
+#ifdef __SSSE3__
+#include <tmmintrin.h>
+#endif
+
+#ifdef __SSE4a__
+#include <ammintrin.h>
+#endif
+
+#if defined (__SSE4_2__) || defined (__SSE4_1__)
+#include <smmintrin.h>
+#endif
+
+#ifdef __SSE5__
+#include <bmmintrin.h>
+#endif
+
+#if defined (__AES__) || defined (__PCLMUL__)
+#include <wmmintrin.h>
+#endif
+
+/* For including AVX instructions */
+#include <immintrin.h>
+
+#ifdef __3dNOW__
+#include <mm3dnow.h>
+#endif
+
+#endif /* _X86INTRIN_H_INCLUDED */
index b03032d..b4894ab 100644 (file)
    (UNSPECV_PSAC_ALL           5)      ; pred.safe_across_calls
    (UNSPECV_PSAC_NORMAL                6)
    (UNSPECV_SETJMP_RECEIVER    7)
+   (UNSPECV_GOTO_RECEIVER      8)
   ])
 
 (include "predicates.md")
   DONE;
 })
 
+(define_insn_and_split "nonlocal_goto_receiver"
+  [(unspec_volatile [(const_int 0)] UNSPECV_GOTO_RECEIVER)]
+  ""
+  "#"
+  "reload_completed"
+  [(const_int 0)]
+{
+  ia64_reload_gp ();
+  DONE;
+})
+
 (define_insn_and_split "builtin_setjmp_receiver"
   [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)]
   ""
index 2fb636a..2292a33 100644 (file)
@@ -224,7 +224,7 @@ machine_function;
 
 #define REG_ALLOC_ORDER { \
        0, 1, 2, 3, 4, 5, /* r0..r3, a0, a1 */ \
-       12, 13, 14, 15, 16, 17, 18, /* mem0..mem7 */  \
+        12, 13, 14, 15, 16, 17, 18, 19, /* mem0..mem7 */       \
        6, 7, 8, 9, 10, 11 /* sb, fb, sp, pc, flg, ap */ }
 
 /* How Values Fit in Registers */
@@ -270,6 +270,7 @@ machine_function;
   { 0x000001f0 }, /* PS  - a0 a1 sb fp sp */\
   { 0x0000000f }, /* SI  - r0r2 r1r3 a0a1 */\
   { 0x0000003f }, /* HI  - r0 r1 r2 r3 a0 a1 */\
+  { 0x00000033 }, /* R02A  - r0r2 a0 a1 */ \
   { 0x0000003f }, /* RA  - r0..r3 a0 a1 */\
   { 0x0000007f }, /* GENERAL */\
   { 0x00000400 }, /* FLG */\
@@ -308,6 +309,7 @@ enum reg_class
   PS_REGS,
   SI_REGS,
   HI_REGS,
+  R02A_REGS,
   RA_REGS,
   GENERAL_REGS,
   FLG_REGS,
@@ -348,6 +350,7 @@ enum reg_class
 "PS_REGS", \
 "SI_REGS", \
 "HI_REGS", \
+"R02A_REGS", \
 "RA_REGS", \
 "GENERAL_REGS", \
 "FLG_REGS", \
index 6f98cd0..a6444b5 100644 (file)
@@ -3183,24 +3183,25 @@ while (0)
 
      - Uses scratch register %4.
 
-    NOT_OP are the optional instructions to do a bit-wise not
-    operation in conjunction with an AND INSN to generate a sync_nand
-    operation.  */
-#define MIPS_SYNC_OP_12(INSN, NOT_OP)          \
+    AND_OP is an instruction done after INSN to mask INSN's result
+    with the mask.  For most operations, this is an AND with the
+    inclusive mask (%1).  For nand operations -- where the result of
+    INSN is already correctly masked -- it instead performs a bitwise
+    not.  */
+#define MIPS_SYNC_OP_12(INSN, AND_OP)          \
   "%(%<%[%|sync\n"                             \
   "1:\tll\t%4,%0\n"                            \
   "\tand\t%@,%4,%2\n"                          \
-  NOT_OP                                       \
   "\t" INSN "\t%4,%4,%z3\n"                    \
-  "\tand\t%4,%4,%1\n"                          \
+  AND_OP                                       \
   "\tor\t%@,%@,%4\n"                           \
   "\tsc\t%@,%0\n"                              \
   "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"
 
-#define MIPS_SYNC_OP_12_NOT_NOP ""
-#define MIPS_SYNC_OP_12_NOT_NOT "\tnor\t%4,%4,%.\n"
+#define MIPS_SYNC_OP_12_AND "\tand\t%4,%4,%1\n"
+#define MIPS_SYNC_OP_12_XOR "\txor\t%4,%4,%1\n"
 
 /* Return an asm string that atomically:
 
@@ -3213,29 +3214,25 @@ while (0)
 
      - Uses scratch register %5.
 
-    NOT_OP are the optional instructions to do a bit-wise not
-    operation in conjunction with an AND INSN to generate a sync_nand
-    operation.
-
-    REG is used in conjunction with NOT_OP and is used to select the
-    register operated on by the INSN.  */
-#define MIPS_SYNC_OLD_OP_12(INSN, NOT_OP, REG) \
+    AND_OP is an instruction done after INSN to mask INSN's result
+    with the mask.  For most operations, this is an AND with the
+    inclusive mask (%1).  For nand operations -- where the result of
+    INSN is already correctly masked -- it instead performs a bitwise
+    not.  */
+#define MIPS_SYNC_OLD_OP_12(INSN, AND_OP)      \
   "%(%<%[%|sync\n"                             \
   "1:\tll\t%0,%1\n"                            \
   "\tand\t%@,%0,%3\n"                          \
-  NOT_OP                                       \
-  "\t" INSN "\t%5," REG ",%z4\n"               \
-  "\tand\t%5,%5,%2\n"                          \
+  "\t" INSN "\t%5,%0,%z4\n"                    \
+  AND_OP                                       \
   "\tor\t%@,%@,%5\n"                           \
   "\tsc\t%@,%1\n"                              \
   "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"
 
-#define MIPS_SYNC_OLD_OP_12_NOT_NOP ""
-#define MIPS_SYNC_OLD_OP_12_NOT_NOP_REG "%0"
-#define MIPS_SYNC_OLD_OP_12_NOT_NOT "\tnor\t%5,%0,%.\n"
-#define MIPS_SYNC_OLD_OP_12_NOT_NOT_REG "%5"
+#define MIPS_SYNC_OLD_OP_12_AND "\tand\t%5,%5,%2\n"
+#define MIPS_SYNC_OLD_OP_12_XOR "\txor\t%5,%5,%2\n"
 
 /* Return an asm string that atomically:
 
@@ -3246,24 +3243,25 @@ while (0)
 
      - Sets %0 to the new value of %1.
 
-    NOT_OP are the optional instructions to do a bit-wise not
-    operation in conjunction with an AND INSN to generate a sync_nand
-    operation.  */
-#define MIPS_SYNC_NEW_OP_12(INSN, NOT_OP)      \
+    AND_OP is an instruction done after INSN to mask INSN's result
+    with the mask.  For most operations, this is an AND with the
+    inclusive mask (%1).  For nand operations -- where the result of
+    INSN is already correctly masked -- it instead performs a bitwise
+    not.  */
+#define MIPS_SYNC_NEW_OP_12(INSN, AND_OP)      \
   "%(%<%[%|sync\n"                             \
   "1:\tll\t%0,%1\n"                            \
   "\tand\t%@,%0,%3\n"                          \
-  NOT_OP                                       \
   "\t" INSN "\t%0,%0,%z4\n"                    \
-  "\tand\t%0,%0,%2\n"                          \
+  AND_OP                                       \
   "\tor\t%@,%@,%0\n"                           \
   "\tsc\t%@,%1\n"                              \
   "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
   "\tsync%-%]%>%)"
 
-#define MIPS_SYNC_NEW_OP_12_NOT_NOP ""
-#define MIPS_SYNC_NEW_OP_12_NOT_NOT "\tnor\t%0,%0,%.\n"
+#define MIPS_SYNC_NEW_OP_12_AND "\tand\t%0,%0,%2\n"
+#define MIPS_SYNC_NEW_OP_12_XOR "\txor\t%0,%0,%2\n"
 
 /* Return an asm string that atomically:
 
@@ -3301,7 +3299,7 @@ while (0)
 
 /* Return an asm string that atomically:
 
-     - Sets memory reference %0 to ~%0 AND %1.
+     - Sets memory reference %0 to ~(%0 AND %1).
 
    SUFFIX is the suffix that should be added to "ll" and "sc"
    instructions.  INSN is the and instruction needed to and a register
@@ -3309,8 +3307,8 @@ while (0)
 #define MIPS_SYNC_NAND(SUFFIX, INSN)           \
   "%(%<%[%|sync\n"                             \
   "1:\tll" SUFFIX "\t%@,%0\n"                  \
-  "\tnor\t%@,%@,%.\n"                          \
   "\t" INSN "\t%@,%@,%1\n"                     \
+  "\tnor\t%@,%@,%.\n"                          \
   "\tsc" SUFFIX "\t%@,%0\n"                    \
   "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
@@ -3318,7 +3316,7 @@ while (0)
 
 /* Return an asm string that atomically:
 
-     - Sets memory reference %1 to ~%1 AND %2.
+     - Sets memory reference %1 to ~(%1 AND %2).
 
      - Sets register %0 to the old value of memory reference %1.
 
@@ -3328,8 +3326,8 @@ while (0)
 #define MIPS_SYNC_OLD_NAND(SUFFIX, INSN)       \
   "%(%<%[%|sync\n"                             \
   "1:\tll" SUFFIX "\t%0,%1\n"                  \
-  "\tnor\t%@,%0,%.\n"                          \
-  "\t" INSN "\t%@,%@,%2\n"                     \
+  "\t" INSN "\t%@,%0,%2\n"                     \
+  "\tnor\t%@,%@,%.\n"                          \
   "\tsc" SUFFIX "\t%@,%1\n"                    \
   "\tbeq%?\t%@,%.,1b\n"                                \
   "\tnop\n"                                    \
@@ -3337,7 +3335,7 @@ while (0)
 
 /* Return an asm string that atomically:
 
-     - Sets memory reference %1 to ~%1 AND %2.
+     - Sets memory reference %1 to ~(%1 AND %2).
 
      - Sets register %0 to the new value of memory reference %1.
 
@@ -3347,11 +3345,11 @@ while (0)
 #define MIPS_SYNC_NEW_NAND(SUFFIX, INSN)       \
   "%(%<%[%|sync\n"                             \
   "1:\tll" SUFFIX "\t%0,%1\n"                  \
-  "\tnor\t%0,%0,%.\n"                          \
-  "\t" INSN "\t%@,%0,%2\n"                     \
+  "\t" INSN "\t%0,%0,%2\n"                     \
+  "\tnor\t%@,%0,%.\n"                          \
   "\tsc" SUFFIX "\t%@,%1\n"                    \
   "\tbeq%?\t%@,%.,1b%~\n"                      \
-  "\t" INSN "\t%0,%0,%2\n"                     \
+  "\tnor\t%0,%0,%.\n"                          \
   "\tsync%-%]%>%)"
 
 /* Return an asm string that atomically:
index b9226c5..1b26f02 100644 (file)
   [(set (pc)
        (if_then_else
         (equality_op (zero_extract:GPR
-                      (match_operand:GPR 1 "register_operand" "d")
+                      (match_operand:GPR 0 "register_operand" "d")
                       (const_int 1)
                       (match_operand 2 "const_int_operand" ""))
                      (const_int 0))
-        (label_ref (match_operand 0 ""))
+        (label_ref (match_operand 1 ""))
         (pc)))]
   "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
 {
   return
     mips_output_conditional_branch (insn, operands,
-                                   MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"),
-                                   MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"));
+                                   MIPS_BRANCH ("bbit<bbv>", "%0,%2,%1"),
+                                   MIPS_BRANCH ("bbit<bbinv>", "%0,%2,%1"));
 }
   [(set_attr "type"         "branch")
    (set_attr "mode"         "none")
   [(set (pc)
        (if_then_else
         (equality_op (zero_extract:GPR
-                      (match_operand:GPR 1 "register_operand" "d")
+                      (match_operand:GPR 0 "register_operand" "d")
                       (const_int 1)
                       (match_operand 2 "const_int_operand" ""))
                      (const_int 0))
         (pc)
-        (label_ref (match_operand 0 ""))))]
+        (label_ref (match_operand 1 ""))))]
   "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
 {
   return
     mips_output_conditional_branch (insn, operands,
-                                   MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"),
-                                   MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"));
+                                   MIPS_BRANCH ("bbit<bbinv>", "%0,%2,%1"),
+                                   MIPS_BRANCH ("bbit<bbv>", "%0,%2,%1"));
 }
   [(set_attr "type"         "branch")
    (set_attr "mode"         "none")
index 286ca36..f053be6 100644 (file)
   "GENERATE_LL_SC"
 {
     return (mips_output_sync_loop
-           (MIPS_SYNC_OP_12 ("<insn>", MIPS_SYNC_OP_12_NOT_NOP)));
+           (MIPS_SYNC_OP_12 ("<insn>", MIPS_SYNC_OP_12_AND)));
 }
   [(set_attr "length" "40")])
 
   "GENERATE_LL_SC"
 {
     return (mips_output_sync_loop
-           (MIPS_SYNC_OLD_OP_12 ("<insn>", MIPS_SYNC_OLD_OP_12_NOT_NOP,
-                                 MIPS_SYNC_OLD_OP_12_NOT_NOP_REG)));
+           (MIPS_SYNC_OLD_OP_12 ("<insn>", MIPS_SYNC_OLD_OP_12_AND)));
 }
   [(set_attr "length" "40")])
 
   "GENERATE_LL_SC"
 {
     return (mips_output_sync_loop
-           (MIPS_SYNC_NEW_OP_12 ("<insn>", MIPS_SYNC_NEW_OP_12_NOT_NOP)));
+           (MIPS_SYNC_NEW_OP_12 ("<insn>", MIPS_SYNC_NEW_OP_12_AND)));
 }
   [(set_attr "length" "40")])
 
   "GENERATE_LL_SC"
 {
     return (mips_output_sync_loop
-           (MIPS_SYNC_OP_12 ("and", MIPS_SYNC_OP_12_NOT_NOT)));
+           (MIPS_SYNC_OP_12 ("and", MIPS_SYNC_OP_12_XOR)));
 }
-  [(set_attr "length" "44")])
+  [(set_attr "length" "40")])
 
 (define_expand "sync_old_nand<mode>"
   [(parallel [
   "GENERATE_LL_SC"
 {
     return (mips_output_sync_loop
-           (MIPS_SYNC_OLD_OP_12 ("and", MIPS_SYNC_OLD_OP_12_NOT_NOT,
-                                 MIPS_SYNC_OLD_OP_12_NOT_NOT_REG)));
+           (MIPS_SYNC_OLD_OP_12 ("and", MIPS_SYNC_OLD_OP_12_XOR)));
 }
-  [(set_attr "length" "44")])
+  [(set_attr "length" "40")])
 
 (define_expand "sync_new_nand<mode>"
   [(parallel [
   "GENERATE_LL_SC"
 {
     return (mips_output_sync_loop
-           (MIPS_SYNC_NEW_OP_12 ("and", MIPS_SYNC_NEW_OP_12_NOT_NOT)));
+           (MIPS_SYNC_NEW_OP_12 ("and", MIPS_SYNC_NEW_OP_12_XOR)));
 }
   [(set_attr "length" "40")])
 
index 15cac65..b16389c 100644 (file)
@@ -387,7 +387,7 @@ fmsub (double a, double b, double c)
     FP_DECL_Q(V);
     FP_DECL_D(R);
     double r;
-    long double u, v, x, y, z;
+    long double u, x, y, z;
 
     FP_INIT_ROUNDMODE;
     FP_UNPACK_RAW_D (A, a);
index 86392f4..defdde6 100644 (file)
@@ -162,10 +162,10 @@ get_regs (struct _Unwind_Context *context)
   /* li r0, 0x0077; sc  (sigreturn new)  */
   /* li r0, 0x6666; sc  (rt_sigreturn old)  */
   /* li r0, 0x00AC; sc  (rt_sigreturn new)  */
-  if (*(unsigned int *) (pc + 4) != 0x44000002)
+  if (*(const unsigned int *) (pc + 4) != 0x44000002)
     return NULL;
-  if (*(unsigned int *) (pc + 0) == 0x38007777
-      || *(unsigned int *) (pc + 0) == 0x38000077)
+  if (*(const unsigned int *) (pc + 0) == 0x38007777
+      || *(const unsigned int *) (pc + 0) == 0x38000077)
     {
       struct sigframe {
        char gap[SIGNAL_FRAMESIZE];
@@ -174,8 +174,8 @@ get_regs (struct _Unwind_Context *context)
       } *frame = (struct sigframe *) context->cfa;
       return frame->regs;
     }
-  else if (*(unsigned int *) (pc + 0) == 0x38006666
-          || *(unsigned int *) (pc + 0) == 0x380000AC)
+  else if (*(const unsigned int *) (pc + 0) == 0x38006666
+          || *(const unsigned int *) (pc + 0) == 0x380000AC)
     {
       struct rt_sigframe {
        char gap[SIGNAL_FRAMESIZE + 16];
index 2598039..1691fdb 100644 (file)
 ;
 
 (define_insn "movti"
-  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q")
-        (match_operand:TI 1 "general_operand" "QS,d,dPRT,d,Q"))]
+  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o")
+        (match_operand:TI 1 "general_operand" "QS,d,dPRT,d"))]
   "TARGET_64BIT"
   "@
    lmg\t%0,%N0,%S1
    stmg\t%1,%N1,%S0
    #
-   #
    #"
-  [(set_attr "op_type" "RSY,RSY,*,*,SS")
-   (set_attr "type" "lm,stm,*,*,*")])
+  [(set_attr "op_type" "RSY,RSY,*,*")
+   (set_attr "type" "lm,stm,*,*")])
 
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
 (define_insn "*movdi_64"
   [(set (match_operand:DI 0 "nonimmediate_operand"
                             "=d,d,d,d,d,d,d,d,f,d,d,d,d,d,
-                             RT,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,?Q")
+                             RT,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t")
         (match_operand:DI 1 "general_operand"
                             "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,RT,
-                             d,*f,R,T,*f,*f,d,K,t,d,t,Q,?Q"))]
+                             d,*f,R,T,*f,*f,d,K,t,d,t,Q"))]
   "TARGET_64BIT"
   "@
    lghi\t%0,%h1
    #
    #
    stam\t%1,%N1,%S0
-   lam\t%0,%N0,%S1
-   #"
+   lam\t%0,%N0,%S1"
   [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
-                        RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,SS")
+                        RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS")
    (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
                      floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,
-                     *,*,*")
+                     *,*")
    (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
                              z10,*,*,*,*,*,longdisp,*,longdisp,
-                             z10,z10,*,*,*,*,*")
+                             z10,z10,*,*,*,*")
    (set_attr "z10prop" "z10_fwd_A1,
                         z10_fwd_E1,
                         z10_fwd_E1,
                         *,
                         *,
                         *,
-                        *,
                         *")
 ])
 
 
 (define_insn "*movdi_31"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-                            "=d,d,Q,S,d   ,o,!*f,!*f,!*f,!R,!T,Q,d")
+                            "=d,d,Q,S,d   ,o,!*f,!*f,!*f,!R,!T,d")
         (match_operand:DI 1 "general_operand"
-                            " Q,S,d,d,dPRT,d, *f,  R,  T,*f,*f,Q,b"))]
+                            " Q,S,d,d,dPRT,d, *f,  R,  T,*f,*f,b"))]
   "!TARGET_64BIT"
   "@
    lm\t%0,%N0,%S1
    ldy\t%0,%1
    std\t%1,%0
    stdy\t%1,%0
-   #
    #"
-  [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,SS,*")
-   (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*")
-   (set_attr "cpu_facility" "*,*,*,*,*,*,*,*,*,*,*,*,z10")])
+  [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
+   (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
+   (set_attr "cpu_facility" "*,*,*,*,*,*,*,*,*,*,*,z10")])
 
 ; For a load from a symbol ref we can use one of the target registers
 ; together with larl to load the address.
 
 (define_insn "*movsi_zarch"
   [(set (match_operand:SI 0 "nonimmediate_operand"
-                           "=d,d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,b,Q,t,?Q")
+                           "=d,d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,b,Q,t")
         (match_operand:SI 1 "general_operand"
-                           "K,N0HS0,N1HS0,Os,L,b,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,d,K,Q,?Q"))]
+                           "K,N0HS0,N1HS0,Os,L,b,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,d,K,Q"))]
   "TARGET_ZARCH"
   "@
    lhi\t%0,%h1
    stam\t%1,%1,%S0
    strl\t%1,%0
    mvhi\t%0,%1
-   lam\t%0,%0,%S1
-   #"
+   lam\t%0,%0,%S1"
   [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
-                        RR,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,SS")
+                        RR,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS")
    (set_attr "type" "*,
                      *,
                      *,
                      *,
                      larl,
                      *,
-                     *,
                      *")
    (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
-                             *,*,longdisp,*,longdisp,*,*,*,z10,z10,*,*")
+                             *,*,longdisp,*,longdisp,*,*,*,z10,z10,*")
    (set_attr "z10prop" "z10_fwd_A1,
                         z10_fwd_E1,
                         z10_fwd_E1,
                         *,
                         z10_rec,
                         z10_super,
-                        *,
                         *")])
 
 (define_insn "*movsi_esa"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,d,t,Q,t,?Q")
-        (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,t,d,t,Q,?Q"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,d,t,Q,t")
+        (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,t,d,t,Q"))]
   "!TARGET_ZARCH"
   "@
    lhi\t%0,%h1
    ear\t%0,%1
    sar\t%0,%1
    stam\t%1,%1,%S0
-   lam\t%0,%0,%S1
-   #"
-  [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,RRE,RRE,RS,RS,SS")
-   (set_attr "type" "*,lr,load,store,floadsf,floadsf,fstoresf,*,*,*,*,*")
+   lam\t%0,%0,%S1"
+  [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,RRE,RRE,RS,RS")
+   (set_attr "type" "*,lr,load,store,floadsf,floadsf,fstoresf,*,*,*,*")
    (set_attr "z10prop" "z10_fwd_A1,
                         z10_fr_E1,
                         z10_fwd_A3,
                         z10_super_E1,
                         z10_super,
                         *,
-                        *,
                         *")
 ])
 
 })
 
 (define_insn "*movhi"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,?Q")
-        (match_operand:HI 1 "general_operand"      " d,n,R,T,b,d,d,d,K,?Q"))]
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q")
+        (match_operand:HI 1 "general_operand"      " d,n,R,T,b,d,d,d,K"))]
   ""
   "@
    lr\t%0,%1
    sth\t%1,%0
    sthy\t%1,%0
    sthrl\t%1,%0
-   mvhhi\t%0,%1
-   #"
-  [(set_attr "op_type"      "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,SS")
-   (set_attr "type"         "lr,*,*,*,larl,store,store,store,*,*")
-   (set_attr "cpu_facility" "*,*,*,*,z10,*,*,z10,z10,*")
+   mvhhi\t%0,%1"
+  [(set_attr "op_type"      "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL")
+   (set_attr "type"         "lr,*,*,*,larl,store,store,store,*")
+   (set_attr "cpu_facility" "*,*,*,*,z10,*,*,z10,z10")
    (set_attr "z10prop" "z10_fr_E1,
                        z10_fwd_A1,
                        z10_super_E1,
                        z10_super,
                        z10_rec,
                        z10_rec,
-                       z10_super,
-                       *")])
+                       z10_super")])
 
 (define_peephole2
   [(set (match_operand:HI 0 "register_operand" "")
 })
 
 (define_insn "*movqi"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q")
-        (match_operand:QI 1 "general_operand" "d,n,R,T,d,d,n,n,?Q"))]
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S")
+        (match_operand:QI 1 "general_operand" "d,n,R,T,d,d,n,n"))]
   ""
   "@
    lr\t%0,%1
    stc\t%1,%0
    stcy\t%1,%0
    mvi\t%S0,%b1
-   mviy\t%S0,%b1
-   #"
-  [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS")
-   (set_attr "type" "lr,*,*,*,store,store,store,store,*")
+   mviy\t%S0,%b1"
+  [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY")
+   (set_attr "type" "lr,*,*,*,store,store,store,store")
    (set_attr "z10prop" "z10_fr_E1,
                         z10_fwd_A1,
                         z10_super_E1,
                         z10_super,
                         z10_rec,
                         z10_super,
-                        z10_super,
-                        *")])
+                        z10_super")])
 
 (define_peephole2
   [(set (match_operand:QI 0 "nonimmediate_operand" "")
   "")
 
 (define_insn "*mov<mode>_64"
-  [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o, d,QS, d,o,Q")
-        (match_operand:TD_TF 1 "general_operand"      " G,f,o,f,QS, d,dRT,d,Q"))]
+  [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o, d,QS,  d,o")
+        (match_operand:TD_TF 1 "general_operand"      " G,f,o,f,QS, d,dRT,d"))]
   "TARGET_64BIT"
   "@
    lzxr\t%0
    lmg\t%0,%N0,%S1
    stmg\t%1,%N1,%S0
    #
-   #
    #"
-  [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*,*")
-   (set_attr "type"    "fsimptf,fsimptf,*,*,lm,stm,*,*,*")])
+  [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
+   (set_attr "type"    "fsimptf,fsimptf,*,*,lm,stm,*,*")])
 
 (define_insn "*mov<mode>_31"
-  [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,Q")
-        (match_operand:TD_TF 1 "general_operand"      " G,f,o,f,Q"))]
+  [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
+        (match_operand:TD_TF 1 "general_operand"      " G,f,o,f"))]
   "!TARGET_64BIT"
   "@
    lzxr\t%0
    lxr\t%0,%1
    #
-   #
    #"
-  [(set_attr "op_type" "RRE,RRE,*,*,*")
-   (set_attr "type"    "fsimptf,fsimptf,*,*,*")])
+  [(set_attr "op_type" "RRE,RRE,*,*")
+   (set_attr "type"    "fsimptf,fsimptf,*,*")])
 
 ; TFmode in GPRs splitters
 
 
 (define_insn "*mov<mode>_64dfp"
   [(set (match_operand:DD_DF 0 "nonimmediate_operand"
-                              "=f,f,f,d,f,f,R,T,d,d,RT,?Q")
+                              "=f,f,f,d,f,f,R,T,d, d,RT")
         (match_operand:DD_DF 1 "general_operand"
-                              "G,f,d,f,R,T,f,f,d,RT,d,?Q"))]
+                              " G,f,d,f,R,T,f,f,d,RT, d"))]
   "TARGET_64BIT && TARGET_DFP"
   "@
    lzdr\t%0
    stdy\t%1,%0
    lgr\t%0,%1
    lg\t%0,%1
-   stg\t%1,%0
-   #"
-  [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
+   stg\t%1,%0"
+  [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RRE,RXY,RXY")
    (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
-                     fstoredf,fstoredf,lr,load,store,*")
+                     fstoredf,fstoredf,lr,load,store")
    (set_attr "z10prop" "*,
                         *,
                         *,
                         *,
                         z10_fr_E1,
                         z10_fwd_A3,
-                        z10_rec,
-                        *")
+                        z10_rec")
 ])
 
 (define_insn "*mov<mode>_64"
-  [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d, d,RT,?Q")
-        (match_operand:DD_DF 1 "general_operand"       "G,f,R,T,f,f,d,RT, d,?Q"))]
+  [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d, d,RT")
+        (match_operand:DD_DF 1 "general_operand"       "G,f,R,T,f,f,d,RT, d"))]
   "TARGET_64BIT"
   "@
    lzdr\t%0
    stdy\t%1,%0
    lgr\t%0,%1
    lg\t%0,%1
-   stg\t%1,%0
-   #"
-  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
+   stg\t%1,%0"
+  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RRE,RXY,RXY")
    (set_attr "type" "fsimp<mode>,fload<mode>,fload<mode>,fload<mode>,
-                     fstore<mode>,fstore<mode>,lr,load,store,*")
+                     fstore<mode>,fstore<mode>,lr,load,store")
    (set_attr "z10prop" "*,
                         *,
                         *,
                         *,
                         z10_fr_E1,
                         z10_fwd_A3,
-                        z10_rec,
-                        *")])
+                        z10_rec")])
 
 (define_insn "*mov<mode>_31"
   [(set (match_operand:DD_DF 0 "nonimmediate_operand"
-                               "=f,f,f,f,R,T,d,d,Q,S,   d,o,Q")
+                               "=f,f,f,f,R,T,d,d,Q,S,   d,o")
         (match_operand:DD_DF 1 "general_operand"
-                               " G,f,R,T,f,f,Q,S,d,d,dPRT,d,Q"))]
+                               " G,f,R,T,f,f,Q,S,d,d,dPRT,d"))]
   "!TARGET_64BIT"
   "@
    lzdr\t%0
    stm\t%1,%N1,%S0
    stmy\t%1,%N1,%S0
    #
-   #
    #"
-  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS")
+  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
    (set_attr "type" "fsimp<mode>,fload<mode>,fload<mode>,fload<mode>,
-                     fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*,*")])
+                     fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")])
 
 (define_split
   [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
 
 (define_insn "mov<mode>"
   [(set (match_operand:SD_SF 0 "nonimmediate_operand"
-                              "=f,f,f,f,R,T,d,d,d,R,T,?Q")
+                              "=f,f,f,f,R,T,d,d,d,R,T")
         (match_operand:SD_SF 1 "general_operand"
-                              " G,f,R,T,f,f,d,R,T,d,d,?Q"))]
+                              " G,f,R,T,f,f,d,R,T,d,d"))]
   ""
   "@
    lzer\t%0
    l\t%0,%1
    ly\t%0,%1
    st\t%1,%0
-   sty\t%1,%0
-   #"
-  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
+   sty\t%1,%0"
+  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY")
    (set_attr "type" "fsimp<mode>,fload<mode>,fload<mode>,fload<mode>,
-                     fstore<mode>,fstore<mode>,lr,load,load,store,store,*")
+                     fstore<mode>,fstore<mode>,lr,load,load,store,store")
    (set_attr "z10prop" "*,
                         *,
                         *,
                         z10_fwd_A3,
                         z10_fwd_A3,
                         z10_super,
-                        z10_rec,
-                        *")])
+                        z10_rec")])
 
 ;
 ; movcc instruction pattern
   "mvc\t%O0(%2,%R0),%S1"
   [(set_attr "op_type" "SS")])
 
-(define_split
-  [(set (match_operand 0 "memory_operand" "")
-        (match_operand 1 "memory_operand" ""))]
-  "reload_completed
-   && GET_MODE (operands[0]) == GET_MODE (operands[1])
-   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
-  [(parallel
-    [(set (match_dup 0) (match_dup 1))
-     (use (match_dup 2))])]
-{
-  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
-  operands[0] = adjust_address (operands[0], BLKmode, 0);
-  operands[1] = adjust_address (operands[1], BLKmode, 0);
-})
-
 (define_peephole2
   [(parallel
     [(set (match_operand:BLK 0 "memory_operand" "")
index dab6ed0..4b33059 100644 (file)
@@ -1,3 +1,38 @@
+2008-12-10  Jason Merrill  <jason@redhat.com>
+
+       PR c++/35319
+       * mangle.c (write_builtin_type): Add mangling for decimal floating 
+       point and fixed point types.
+       (write_type): Pass FIXED_POINT_TYPE along.
+
+2008-12-09  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/37971
+       * class.c (resolve_address_of_overloaded_function): Check
+       accessibility of member functions unless FLAGS indicates
+       otherwise.
+       * call.c (standard_conversion): Adjust flags passed to
+       instantiate_type.
+       (convert_default_arg): Do not perform access checks.
+       * cp-tree.h (tsubst_flags_t): Add tf_no_access_control.
+
+2008-12-08  Steve Ellcey  <sje@cup.hp.com>
+
+       * decl2.c (mark_used): Remove assemble_external call.
+
+2008-12-08  Dodji Seketeli  <dodji@redhat.com>
+
+       PR debug/38390
+       * name-lookup.c (kept_level_p): Don't forget the case of levels
+         having using directives.
+
+2008-12-08  Richard Henderson  <rth@redhat.com>
+
+       PR 38240
+       * class.c (finish_struct_bits): Use SET_TYPE_MODE.
+       * decl.c (record_unknown_type): Likewise.
+       (start_enum, finish_enum): Likewise.
+
 2008-12-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/35336
index 273599e..952e151 100644 (file)
@@ -706,7 +706,10 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
   if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
       && expr && type_unknown_p (expr))
     {
-      expr = instantiate_type (to, expr, tf_conv);
+      tsubst_flags_t tflags = tf_conv;
+      if (!(flags & LOOKUP_PROTECT))
+       tflags |= tf_no_access_control;
+      expr = instantiate_type (to, expr, tflags);
       if (expr == error_mark_node)
        return NULL;
       from = TREE_TYPE (expr);
@@ -1360,9 +1363,8 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
 
 /* Returns the implicit conversion sequence (see [over.ics]) from type
    FROM to type TO.  The optional expression EXPR may affect the
-   conversion.  FLAGS are the usual overloading flags.  Only
-   LOOKUP_NO_CONVERSION is significant.  If C_CAST_P is true, this
-   conversion is coming from a C-style cast.  */
+   conversion.  FLAGS are the usual overloading flags.  If C_CAST_P is
+   true, this conversion is coming from a C-style cast.  */
 
 static conversion *
 implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
@@ -4954,8 +4956,17 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
   if (fn && DECL_TEMPLATE_INFO (fn))
     arg = tsubst_default_argument (fn, type, arg);
 
-  arg = break_out_target_exprs (arg);
+  /* Due to:
+
+       [dcl.fct.default]
 
+       The names in the expression are bound, and the semantic
+       constraints are checked, at the point where the default
+       expressions appears.
+
+     we must not perform access checks here.  */
+  push_deferring_access_checks (dk_no_check);
+  arg = break_out_target_exprs (arg);
   if (TREE_CODE (arg) == CONSTRUCTOR)
     {
       arg = digest_init (type, arg);
@@ -4978,6 +4989,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
                                         tf_warning_or_error);
       arg = convert_for_arg_passing (type, arg);
     }
+  pop_deferring_access_checks();
 
   VEC_pop (tree, default_arg_context);
 
index 8553139..805e513 100644 (file)
@@ -1494,7 +1494,7 @@ finish_struct_bits (tree t)
       DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;
       for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))
        {
-         TYPE_MODE (variants) = BLKmode;
+         SET_TYPE_MODE (variants, BLKmode);
          TREE_ADDRESSABLE (variants) = 1;
        }
     }
@@ -5923,9 +5923,13 @@ pop_lang_context (void)
    control of FLAGS.  Permit pointers to member function if FLAGS
    permits.  If TEMPLATE_ONLY, the name of the overloaded function was
    a template-id, and EXPLICIT_TARGS are the explicitly provided
-   template arguments.  If OVERLOAD is for one or more member
-   functions, then ACCESS_PATH is the base path used to reference
-   those member functions.  */
+   template arguments.  
+
+   If OVERLOAD is for one or more member functions, then ACCESS_PATH
+   is the base path used to reference those member functions.  If
+   TF_NO_ACCESS_CONTROL is not set in FLAGS, and the address is
+   resolved to a member function, access checks will be performed and
+   errors issued if appropriate.  */
 
 static tree
 resolve_address_of_overloaded_function (tree target_type,
@@ -6190,14 +6194,16 @@ resolve_address_of_overloaded_function (tree target_type,
        return error_mark_node;
       
       mark_used (fn);
-      /* We could not check access when this expression was originally
-        created since we did not know at that time to which function
-        the expression referred.  */
-      if (DECL_FUNCTION_MEMBER_P (fn))
-       {
-         gcc_assert (access_path);
-         perform_or_defer_access_check (access_path, fn, fn);
-       }
+    }
+
+  /* We could not check access to member functions when this
+     expression was originally created since we did not know at that
+     time to which function the expression referred.  */
+  if (!(flags & tf_no_access_control) 
+      && DECL_FUNCTION_MEMBER_P (fn))
+    {
+      gcc_assert (access_path);
+      perform_or_defer_access_check (access_path, fn, fn);
     }
 
   if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
index 7f33ff1..bf22eb4 100644 (file)
@@ -3560,20 +3560,22 @@ typedef enum linkage_kind {
 
 /* Bitmask flags to control type substitution.  */
 typedef enum tsubst_flags_t {
-  tf_none = 0,                 /* nothing special */
-  tf_error = 1 << 0,           /* give error messages  */
-  tf_warning = 1 << 1,         /* give warnings too  */
-  tf_ignore_bad_quals = 1 << 2,        /* ignore bad cvr qualifiers */
-  tf_keep_type_decl = 1 << 3,  /* retain typedef type decls
-                                  (make_typename_type use) */
-  tf_ptrmem_ok = 1 << 4,       /* pointers to member ok (internal
-                                  instantiate_type use) */
-  tf_user = 1 << 5,            /* found template must be a user template
-                                  (lookup_template_class use) */
-  tf_conv = 1 << 6,            /* We are determining what kind of
-                                  conversion might be permissible,
-                                  not actually performing the
-                                  conversion.  */
+  tf_none = 0,                  /* nothing special */
+  tf_error = 1 << 0,            /* give error messages  */
+  tf_warning = 1 << 1,          /* give warnings too  */
+  tf_ignore_bad_quals = 1 << 2,         /* ignore bad cvr qualifiers */
+  tf_keep_type_decl = 1 << 3,   /* retain typedef type decls
+                                   (make_typename_type use) */
+  tf_ptrmem_ok = 1 << 4,        /* pointers to member ok (internal
+                                   instantiate_type use) */
+  tf_user = 1 << 5,             /* found template must be a user template
+                                   (lookup_template_class use) */
+  tf_conv = 1 << 6,             /* We are determining what kind of
+                                   conversion might be permissible,
+                                   not actually performing the
+                                   conversion.  */
+  tf_no_access_control = 1 << 7, /* Do not perform access checks, even
+                                   when issuing other errors.   */
   /* Convenient substitution flags combinations.  */
   tf_warning_or_error = tf_warning | tf_error
 } tsubst_flags_t;
index 70ccd32..e786b39 100644 (file)
@@ -3199,7 +3199,7 @@ record_unknown_type (tree type, const char* name)
   TYPE_SIZE (type) = TYPE_SIZE (void_type_node);
   TYPE_ALIGN (type) = 1;
   TYPE_USER_ALIGN (type) = 0;
-  TYPE_MODE (type) = TYPE_MODE (void_type_node);
+  SET_TYPE_MODE (type, TYPE_MODE (void_type_node));
 }
 
 /* A string for which we should create an IDENTIFIER_NODE at
@@ -10912,7 +10912,7 @@ start_enum (tree name, tree underlying_type, bool scoped_enum_p)
           TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (underlying_type);
           TYPE_SIZE (enumtype) = TYPE_SIZE (underlying_type);
           TYPE_SIZE_UNIT (enumtype) = TYPE_SIZE_UNIT (underlying_type);
-          TYPE_MODE (enumtype) = TYPE_MODE (underlying_type);
+          SET_TYPE_MODE (enumtype, TYPE_MODE (underlying_type));
           TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type);
           TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type);
           TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type);
@@ -11065,7 +11065,7 @@ finish_enum (tree enumtype)
          applied to the underlying type.  */
       TYPE_SIZE (enumtype) = TYPE_SIZE (underlying_type);
       TYPE_SIZE_UNIT (enumtype) = TYPE_SIZE_UNIT (underlying_type);
-      TYPE_MODE (enumtype) = TYPE_MODE (underlying_type);
+      SET_TYPE_MODE (enumtype, TYPE_MODE (underlying_type));
       TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type);
       TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type);
       TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (underlying_type);
@@ -11133,7 +11133,7 @@ finish_enum (tree enumtype)
       TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (enumtype);
       TYPE_SIZE (t) = TYPE_SIZE (enumtype);
       TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (enumtype);
-      TYPE_MODE (t) = TYPE_MODE (enumtype);
+      SET_TYPE_MODE (t, TYPE_MODE (enumtype));
       TYPE_PRECISION (t) = TYPE_PRECISION (enumtype);
       TYPE_ALIGN (t) = TYPE_ALIGN (enumtype);
       TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (enumtype);
index da9201e..c888725 100644 (file)
@@ -3849,8 +3849,6 @@ mark_used (tree decl)
       note_vague_linkage_fn (decl);
     }
 
-  assemble_external (decl);
-
   /* Is it a synthesized method that needs to be synthesized?  */
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
index c0282d8..36b984e 100644 (file)
@@ -1598,6 +1598,7 @@ write_type (tree type)
            case BOOLEAN_TYPE:
            case INTEGER_TYPE:  /* Includes wchar_t.  */
            case REAL_TYPE:
+           case FIXED_POINT_TYPE:
              {
                /* If this is a typedef, TYPE may not be one of
                   the standard builtin type nodes, but an alias of one.  Use
@@ -1852,6 +1853,59 @@ write_builtin_type (tree type)
        gcc_unreachable ();
       break;
 
+    case FIXED_POINT_TYPE:
+      write_string ("DF");
+      if (GET_MODE_IBIT (TYPE_MODE (type)) > 0)
+       write_unsigned_number (GET_MODE_IBIT (TYPE_MODE (type)));
+      if (type == fract_type_node
+         || type == sat_fract_type_node
+         || type == accum_type_node
+         || type == sat_accum_type_node)
+       write_char ('i');
+      else if (type == unsigned_fract_type_node
+              || type == sat_unsigned_fract_type_node
+              || type == unsigned_accum_type_node
+              || type == sat_unsigned_accum_type_node)
+       write_char ('j');
+      else if (type == short_fract_type_node
+              || type == sat_short_fract_type_node
+              || type == short_accum_type_node
+              || type == sat_short_accum_type_node)
+       write_char ('s');
+      else if (type == unsigned_short_fract_type_node
+              || type == sat_unsigned_short_fract_type_node
+              || type == unsigned_short_accum_type_node
+              || type == sat_unsigned_short_accum_type_node)
+       write_char ('t');
+      else if (type == long_fract_type_node
+              || type == sat_long_fract_type_node
+              || type == long_accum_type_node
+              || type == sat_long_accum_type_node)
+       write_char ('l');
+      else if (type == unsigned_long_fract_type_node
+              || type == sat_unsigned_long_fract_type_node
+              || type == unsigned_long_accum_type_node
+              || type == sat_unsigned_long_accum_type_node)
+       write_char ('m');
+      else if (type == long_long_fract_type_node
+              || type == sat_long_long_fract_type_node
+              || type == long_long_accum_type_node
+              || type == sat_long_long_accum_type_node)
+       write_char ('x');
+      else if (type == unsigned_long_long_fract_type_node
+              || type == sat_unsigned_long_long_fract_type_node
+              || type == unsigned_long_long_accum_type_node
+              || type == sat_unsigned_long_long_accum_type_node)
+       write_char ('y');
+      else
+       sorry ("mangling unknown fixed point type");
+      write_unsigned_number (GET_MODE_FBIT (TYPE_MODE (type)));
+      if (TYPE_SATURATING (type))
+       write_char ('s');
+      else
+       write_char ('n');
+      break;
+
     default:
       gcc_unreachable ();
     }
index 0da373c..b5d14b3 100644 (file)
@@ -1548,7 +1548,8 @@ kept_level_p (void)
   return (current_binding_level->blocks != NULL_TREE
          || current_binding_level->keep
          || current_binding_level->kind == sk_cleanup
-         || current_binding_level->names != NULL_TREE);
+         || current_binding_level->names != NULL_TREE
+         || current_binding_level->using_directives);
 }
 
 /* Returns the kind of the innermost scope.  */
index 7e6da15..66d28c7 100644 (file)
@@ -338,7 +338,7 @@ Objective-C and Objective-C++ Dialects}.
 -finline-small-functions -fipa-cp -fipa-cp-clone -fipa-matrix-reorg -fipa-pta @gol 
 -fipa-pure-const -fipa-reference -fipa-struct-reorg @gol
 -fipa-type-escape -fira -fira-algorithm=@var{algorithm} @gol
--fira-coalesce -fno-ira-share-save-slots @gol
+-fira-region=@var{region} -fira-coalesce -fno-ira-share-save-slots @gol
 -fno-ira-share-spill-slots -fira-verbose=@var{n} @gol
 -fivopts -fkeep-inline-functions -fkeep-static-consts @gol
 -floop-block -floop-interchange -floop-strip-mine @gol
@@ -5728,17 +5728,25 @@ allocation.  It is a default if @acronym{IRA} has been ported for the
 target.
 
 @item -fira-algorithm=@var{algorithm}
-Use specified algorithm for the integrated register allocator.  The
-@var{algorithm} argument should be one of @code{regional}, @code{CB},
-or @code{mixed}.  The second algorithm specifies Chaitin-Briggs
-coloring, the first one specifies regional coloring based on
-Chaitin-Briggs coloring, and the third one which is the default
-specifies a mix of Chaitin-Briggs and regional algorithms where loops
-with small register pressure are ignored.  The first algorithm can
-give best result for machines with small size and irregular register
-set, the second one is faster and generates decent code and the
-smallest size code, and the mixed algorithm usually give the best
-results in most cases and for most architectures.
+Use specified coloring algorithm for the integrated register
+allocator.  The @var{algorithm} argument should be @code{priority} or
+@code{CB}.  The first algorithm specifies Chow's priority coloring,
+the second one specifies Chaitin-Briggs coloring.  The second
+algorithm can be unimplemented for some architectures.  If it is
+implemented, it is the default because Chaitin-Briggs coloring as a
+rule generates a better code.
+
+@item -fira-region=@var{region}
+Use specified regions for the integrated register allocator.  The
+@var{region} argument should be one of @code{all}, @code{mixed}, or
+@code{one}.  The first value means using all loops as register
+allocation regions, the second value which is the default means using
+all loops except for loops with small register pressure as the
+regions, and third one means using all function as a single region.
+The first value can give best result for machines with small size and
+irregular register set, the third one results in faster and generates
+decent code and the smallest size code, and the default value usually
+give the best results in most cases and for most architectures.
 
 @item -fira-coalesce
 @opindex fira-coalesce
index 3505dea..50767a2 100644 (file)
@@ -2050,9 +2050,18 @@ Any MMX register.
 @item x
 Any SSE register.
 
+@item Yz
+First SSE register (@code{%xmm0}).
+
 @ifset INTERNALS
-@item Y
-Any SSE2 register.
+@item Y2
+Any SSE register, when SSE2 is enabled.
+
+@item Yi
+Any SSE register, when SSE2 and inter-unit moves are enabled.
+
+@item Ym
+Any MMX register, when inter-unit moves are enabled.
 @end ifset
 
 @item I
index 672f6d1..3d3a529 100644 (file)
@@ -1005,7 +1005,7 @@ the test
 
 @item variable @var{tool_timeout} defined by the set of tests
 
-@item @var{gcc,,timeout} set in the target board
+@item @var{gcc},@var{timeout} set in the target board
 
 @item 300
 @end itemize
index 7dfb46b..5a76a6e 100644 (file)
@@ -2841,7 +2841,8 @@ options have been processed. It is then re-examined by every call to
 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.
+allocator with Chaitin-Briggs coloring. If the macro is not defined,
+the only available coloring algorithm is Chow's priority coloring.
 @end deftypefn
 
 @defmac IRA_COVER_CLASSES
index 68d0ee8..669948b 100644 (file)
@@ -110,6 +110,9 @@ static void dwarf2out_source_line (unsigned int, const char *);
 #define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO)
 #endif
 
+/* Save the result of dwarf2out_do_frame across PCH.  */
+static GTY(()) bool saved_do_cfi_asm = 0;
+
 /* Decide whether we want to emit frame unwind information for the current
    translation unit.  */
 
@@ -121,7 +124,7 @@ dwarf2out_do_frame (void)
      we're not going to output frame or unwind info.  */
   return (write_symbols == DWARF2_DEBUG
          || write_symbols == VMS_AND_DWARF2_DEBUG
-         || DWARF2_FRAME_INFO
+         || DWARF2_FRAME_INFO || saved_do_cfi_asm
 #ifdef DWARF2_UNWIND_INFO
          || (DWARF2_UNWIND_INFO
              && (flag_unwind_tables
@@ -142,7 +145,7 @@ dwarf2out_do_cfi_asm (void)
 #endif
   if (!flag_dwarf2_cfi_asm || !dwarf2out_do_frame ())
     return false;
-  if (!eh_personality_libfunc)
+  if (saved_do_cfi_asm || !eh_personality_libfunc)
     return true;
   if (!HAVE_GAS_CFI_PERSONALITY_DIRECTIVE)
     return false;
@@ -156,6 +159,7 @@ dwarf2out_do_cfi_asm (void)
   if ((enc & 0x70) != 0 && (enc & 0x70) != DW_EH_PE_pcrel)
     return false;
 
+  saved_do_cfi_asm = true;
   return true;
 }
 
index c3374a1..32e14a1 100644 (file)
@@ -54,6 +54,9 @@ struct __emutls_array
   void **data[];
 };
 
+void *__emutls_get_address (struct __emutls_object *);
+void __emutls_register_common (struct __emutls_object *, word, word, void *);
+
 #ifdef __GTHREADS
 #ifdef __GTHREAD_MUTEX_INIT
 static __gthread_mutex_t emutls_mutex = __GTHREAD_MUTEX_INIT;
@@ -144,8 +147,12 @@ __emutls_get_address (struct __emutls_object *obj)
       static __gthread_once_t once = __GTHREAD_ONCE_INIT;
       __gthread_once (&once, emutls_init);
       __gthread_mutex_lock (&emutls_mutex);
-      offset = ++emutls_size;
-      obj->loc.offset = offset;
+      offset = obj->loc.offset;
+      if (offset == 0)
+       {
+         offset = ++emutls_size;
+         obj->loc.offset = offset;
+       }
       __gthread_mutex_unlock (&emutls_mutex);
     }
 
index aceeb7c..1735a73 100644 (file)
@@ -3440,7 +3440,10 @@ output_addr_const (FILE *file, rtx x)
 
     case SYMBOL_REF:
       if (SYMBOL_REF_DECL (x))
-       mark_decl_referenced (SYMBOL_REF_DECL (x));
+       {
+         mark_decl_referenced (SYMBOL_REF_DECL (x));
+         assemble_external (SYMBOL_REF_DECL (x));
+       }
 #ifdef ASM_OUTPUT_SYMBOL_REF
       ASM_OUTPUT_SYMBOL_REF (file, x);
 #else
index 8c8d371..d7f6413 100644 (file)
@@ -291,9 +291,19 @@ do_fixed_add (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a,
              const FIXED_VALUE_TYPE *b, bool subtract_p, bool sat_p)
 {
   bool overflow_p = false;
-  double_int temp = subtract_p ? double_int_neg (b->data) : b->data;
-  bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
-  int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
+  bool unsigned_p;
+  double_int temp;
+  int i_f_bits;
+
+  /* This was a conditional expression but it triggered a bug in the
+     Solaris 8 compiler.  */
+  if (subtract_p)
+    temp = double_int_neg (b->data);
+  else
+    temp = b->data;
+
+  unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
+  i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
   f->mode = a->mode;
   f->data = double_int_add (a->data, temp);
   if (unsigned_p) /* Unsigned type.  */
index 4a209b3..0fff4f2 100644 (file)
@@ -209,13 +209,22 @@ extern int flag_dump_rtl_in_asm;
 /* The algorithm used for the integrated register allocator (IRA).  */
 enum ira_algorithm
 {
-  IRA_ALGORITHM_REGIONAL,
   IRA_ALGORITHM_CB,
-  IRA_ALGORITHM_MIXED
+  IRA_ALGORITHM_PRIORITY
 };
 
 extern enum ira_algorithm flag_ira_algorithm;
 
+/* The regions used for the integrated register allocator (IRA).  */
+enum ira_region
+{
+  IRA_REGION_ONE,
+  IRA_REGION_ALL,
+  IRA_REGION_MIXED
+};
+
+extern enum ira_region flag_ira_region;
+
 extern unsigned int flag_ira_verbose;
 
 \f
index 7f53a8e..db1fe42 100644 (file)
@@ -1,3 +1,48 @@
+2008-12-12  Daniel Franke  <franke.daniel@gmail.com>
+
+       PR fortran/36355
+       * check.c (gfc_check_matmul): Fixed error message for invalid
+       types to correctly identify the offending argument, added check
+       for mismatching types.
+
+2008-12-11  Richard Guenther  <rguenther@suse.de>
+
+       * Make-lang.in (install-finclude-dir): Use correct mode argument
+       for mkinstalldirs.
+
+2008-12-09  Daniel Franke  <franke.daniel@gmail.com>
+
+       PR fortran/36376
+       PR fortran/37468
+       * lang-specs.h: Pass on -i* options to f951 to (probably) report
+       them as unknown. Duplicate gcc.c (cpp_options), but omit
+       -fpch-preprocess on -save-temps.
+
+2008-12-09  Daniel Franke  <franke.daniel@gmail.com>
+
+       PR fortran/36457
+       * lang.opt: Added option idirafter.
+       * cpp.h (gfc_cpp_add_include_path_after): New prototype.
+       * cpp.c (gfc_cpp_handle_option): Recognize and handle OPT_dirafter.
+       (gfc_cpp_add_include_path_after): New, adds user-defined search path
+       after any other paths.
+       * invoke.texi (idirafter): New.
+       (no-range-check): Fixed entry in option-index.
+
+2008-12-09  Mikael Morin  <mikael.morin@tele2.fr>
+
+       PR fortran/37469
+       * expr.c (find_array_element): Simplify array bounds.
+       Assert that both bounds are constant expressions.
+
+2008-12-09  Mikael Morin  <mikael.morin@tele2.fr>
+
+       PR fortran/35983
+       * trans-expr.c (gfc_trans_subcomponent_assign):
+       Add se's pre and post blocks to current block.
+       (gfc_trans_structure_assign): Remove specific handling
+       of C_NULL_PTR and C_NULL_FUNPTR.
+
 2008-12-06  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/38425
index ff5d03e..1600d18 100644 (file)
@@ -211,7 +211,7 @@ doc/gfc-internals.pdf: $(GFC_INTERNALS_TEXI)
 
 # Create or recreate the gfortran private include file directory.
 install-finclude-dir: installdirs
-       $(mkinstalldirs) -m a+rx $(DESTDIR)$(libsubdir)/finclude
+       $(mkinstalldirs) -m 0755 $(DESTDIR)$(libsubdir)/finclude
 #\f
 # Install hooks:
 # f951 is installed elsewhere as part of $(COMPILERS).
index de50767..8ca67f2 100644 (file)
@@ -1794,7 +1794,7 @@ gfc_check_malloc (gfc_expr *size)
 gfc_try
 gfc_check_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b)
 {
-  if ((matrix_a->ts.type != BT_LOGICAL) && !gfc_numeric_ts (&matrix_b->ts))
+  if ((matrix_a->ts.type != BT_LOGICAL) && !gfc_numeric_ts (&matrix_a->ts))
     {
       gfc_error ("'%s' argument of '%s' intrinsic at %L must be numeric "
                 "or LOGICAL", gfc_current_intrinsic_arg[0],
@@ -1802,7 +1802,7 @@ gfc_check_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b)
       return FAILURE;
     }
 
-  if ((matrix_b->ts.type != BT_LOGICAL) && !gfc_numeric_ts (&matrix_a->ts))
+  if ((matrix_b->ts.type != BT_LOGICAL) && !gfc_numeric_ts (&matrix_b->ts))
     {
       gfc_error ("'%s' argument of '%s' intrinsic at %L must be numeric "
                 "or LOGICAL", gfc_current_intrinsic_arg[1],
@@ -1810,6 +1810,15 @@ gfc_check_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b)
       return FAILURE;
     }
 
+  if ((matrix_a->ts.type == BT_LOGICAL && gfc_numeric_ts (&matrix_b->ts))
+      || (gfc_numeric_ts (&matrix_a->ts) && matrix_b->ts.type == BT_LOGICAL))
+    {
+      gfc_error ("Argument types of '%s' intrinsic at %L must match (%s/%s)",
+                gfc_current_intrinsic, &matrix_a->where,
+                gfc_typename(&matrix_a->ts), gfc_typename(&matrix_b->ts));
+       return FAILURE;
+    }
+
   switch (matrix_a->rank)
     {
     case 1:
index 51c8e85..d45d0c1 100644 (file)
@@ -346,6 +346,10 @@ gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED
       gfc_cpp_option.working_directory = value;
       break;
 
+    case OPT_idirafter:
+      gfc_cpp_add_include_path_after (xstrdup(arg), true);
+      break;
+
     case OPT_imultilib:
       gfc_cpp_option.multilib = arg;
       break;
@@ -634,6 +638,13 @@ gfc_cpp_add_include_path (char *path, bool user_supplied)
 }
 
 void
+gfc_cpp_add_include_path_after (char *path, bool user_supplied)
+{
+  int cxx_aware = 0;
+  add_path (path, AFTER, cxx_aware, user_supplied);
+}
+
+void
 gfc_cpp_register_include_paths (void)
 {
   int cxx_stdinc = 0;
index db24502..54a899f 100644 (file)
@@ -41,6 +41,7 @@ gfc_try gfc_cpp_preprocess (const char *source_file);
 void gfc_cpp_done (void);
 
 void gfc_cpp_add_include_path (char *path, bool user_supplied);
+void gfc_cpp_add_include_path_after (char *path, bool user_supplied);
 
 void gfc_cpp_register_include_paths (void);
 
index 07dfc7a..4bdee7c 100644 (file)
@@ -1028,6 +1028,14 @@ find_array_element (gfc_constructor *cons, gfc_array_ref *ar,
   mpz_init_set_ui (span, 1);
   for (i = 0; i < ar->dimen; i++)
     {
+      if (gfc_reduce_init_expr (ar->as->lower[i]) == FAILURE
+         || gfc_reduce_init_expr (ar->as->upper[i]) == FAILURE)
+       {
+         t = FAILURE;
+         cons = NULL;
+         goto depart;
+       }
+
       e = gfc_copy_expr (ar->start[i]);
       if (e->expr_type != EXPR_CONSTANT)
        {
@@ -1035,14 +1043,15 @@ find_array_element (gfc_constructor *cons, gfc_array_ref *ar,
          goto depart;
        }
 
+      gcc_assert (ar->as->upper[i]->expr_type == EXPR_CONSTANT
+                 && ar->as->lower[i]->expr_type == EXPR_CONSTANT);
+
       /* Check the bounds.  */
       if ((ar->as->upper[i]
-          && ar->as->upper[i]->expr_type == EXPR_CONSTANT
           && mpz_cmp (e->value.integer,
                       ar->as->upper[i]->value.integer) > 0)
-         || (ar->as->lower[i]->expr_type == EXPR_CONSTANT
-             && mpz_cmp (e->value.integer,
-                         ar->as->lower[i]->value.integer) < 0))
+         || (mpz_cmp (e->value.integer,
+                      ar->as->lower[i]->value.integer) < 0))
        {
          gfc_error ("Index in dimension %d is out of bounds "
                     "at %L", i + 1, &ar->c_where[i]);
index 8e47df4..675413c 100644 (file)
@@ -446,6 +446,15 @@ but this can be inhibited with the negated form
 in the command line, this option has no effect, since no @code{#line}
 directives are emitted whatsoever.
 
+@item -idirafter @var{dir}
+@opindex @code{idirafter @var{dir}}
+@cindex preprocessing, include path
+Search @var{dir} for include files, but do it after all directories
+specified with @option{-I} and the standard system directories have
+been exhausted. @var{dir} is treated as a system include directory.
+If dir begins with @code{=}, then the @code{=} will be replaced by
+the sysroot prefix; see @option{--sysroot} and @option{-isysroot}.
+
 @item -imultilib @var{dir}
 @opindex @code{imultilib @var{dir}}
 @cindex preprocessing, include path
@@ -977,7 +986,7 @@ variable override the default specified by @option{-fconvert}.}
 
 
 @item -fno-range-check
-@opindex @code{-fno-range-check}
+@opindex @code{fno-range-check}
 Disable range checking of input values during integer @code{READ} operations.
 For example, GNU Fortran will give an error if an input value is
 outside of the relevant range of [@code{-HUGE()}:@code{HUGE()}]. In other words,
index a766162..a622dcb 100644 (file)
 /* This is the contribution to the `default_compilers' array in gcc.c
    for the f95 language.  */
 
+/* Identical to gcc.c (cpp_options), but omitting %(cpp_unique_options)
+   and -fpch-preprocess on -save-temps.  */
+#define CPP_ONLY_OPTIONS    "%1 %{m*} %{f*} %{g*:%{!g0:%{g*} \
+                            %{!fno-working-directory:-fworking-directory}}} \
+                            %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} \
+                            %{O*} %{undef}"
 
-#define F951_CPP_OPTIONS "%{!nocpp: -cpp %g.f90 %(cpp_options)\
-                          %{E|M|MM:%(cpp_debug_options) -fsyntax-only} %{E}}"
-#define F951_OPTIONS     "%(cc1_options) %{J*} %{!cpp: %{I*}}\
-                          %{!nostdinc:-fintrinsic-modules-path finclude%s}\
-                          %{!fsyntax-only:%(invoke_as)}"
-#define F951_SOURCE_FORM  "%{!ffree-form:-ffixed-form}"
+/* Options that f951 should know about, even if not preprocessing.  */
+#define CPP_FORWARD_OPTIONS "%{i*} %{I*}"
+
+#define F951_CPP_OPTIONS    "%{!nocpp: -cpp %g.f90 %{E} %(cpp_unique_options) \
+                            %{E|M|MM:%(cpp_debug_options) " CPP_ONLY_OPTIONS \
+                            " -fsyntax-only};: " CPP_FORWARD_OPTIONS "}"
+#define F951_OPTIONS        "%(cc1_options) %{J*} \
+                            %{!nostdinc:-fintrinsic-modules-path finclude%s}\
+                            %{!fsyntax-only:%(invoke_as)}"
+#define F951_SOURCE_FORM    "%{!ffree-form:-ffixed-form}"
 
 
 {".F",   "@f77-cpp-input", 0, 0, 0},
 {".FPP", "@f77-cpp-input", 0, 0, 0},
 {"@f77-cpp-input",
     "f951 %i " F951_SOURCE_FORM " " \
-               F951_CPP_OPTIONS " %{!E:" F951_OPTIONS "}", 0, 0, 0},
+         F951_CPP_OPTIONS " %{!E:" F951_OPTIONS "}", 0, 0, 0},
 {".f",   "@f77", 0, 0, 0},
 {".for", "@f77", 0, 0, 0},
 {".ftn", "@f77", 0, 0, 0},
 {"@f77",
     "f951 %i " F951_SOURCE_FORM " \
           %{E:%{!cpp:%egfortran does not support -E without -cpp}} \
-          %{cpp:" F951_CPP_OPTIONS "} %{!E:" F951_OPTIONS "}", 0, 0, 0},
+          %{cpp:" F951_CPP_OPTIONS ";: " CPP_FORWARD_OPTIONS  "} \
+         %{!E:" F951_OPTIONS "}", 0, 0, 0},
 {".F90", "@f95-cpp-input", 0, 0, 0},
 {".F95", "@f95-cpp-input", 0, 0, 0},
 {".F03", "@f95-cpp-input", 0, 0, 0},
 {".f95", "@f95", 0, 0, 0},
 {".f03", "@f95", 0, 0, 0},
 {".f08", "@f95", 0, 0, 0},
-{"@f95", 
+{"@f95",
     "f951 %i %{E:%{!cpp:%egfortran does not support -E without -cpp}}\
-          %{cpp:" F951_CPP_OPTIONS "} %{!E:" F951_OPTIONS "}", 0, 0, 0},
+         %{cpp:" F951_CPP_OPTIONS ";:  " CPP_FORWARD_OPTIONS  "} \
+         %{!E:" F951_OPTIONS "}", 0, 0, 0},
 
 
+#undef CPP_ONLY_OPTIONS
+#undef CPP_FORWARD_OPTIONS
 #undef F951_SOURCE_FORM
 #undef F951_CPP_OPTIONS
 #undef F951_OPTIONS
index 04682c1..e49ff76 100644 (file)
@@ -360,6 +360,10 @@ fworking-directory
 Fortran
 ; Documented in C
 
+idirafter
+Fortran Joined Separate
+; Documented in C
+
 imultilib
 Fortran Joined Separate
 ; Documented in C
index 5d3894c..4ecfa08 100644 (file)
@@ -3670,8 +3670,10 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
        {
          gfc_init_se (&se, NULL);
          gfc_conv_expr (&se, expr);
+         gfc_add_block_to_block (&block, &se.pre);
          gfc_add_modify (&block, dest,
                               fold_convert (TREE_TYPE (dest), se.expr));
+         gfc_add_block_to_block (&block, &se.post);
        }
       else
        {
@@ -3713,21 +3715,8 @@ gfc_trans_structure_assign (tree dest, gfc_expr * expr)
     {
       /* Skip absent members in default initializers.  */
       if (!c->expr)
-        continue;
+       continue;
 
-      /* Update the type/kind of the expression if it represents either
-        C_NULL_PTR or C_NULL_FUNPTR.  This is done here because this may
-        be the first place reached for initializing output variables that
-        have components of type C_PTR/C_FUNPTR that are initialized.  */
-      if (c->expr->ts.type == BT_DERIVED && c->expr->ts.derived
-         && c->expr->ts.derived->attr.is_iso_c)
-        {
-         c->expr->expr_type = EXPR_NULL;
-         c->expr->ts.type = c->expr->ts.derived->ts.type;
-         c->expr->ts.f90_type = c->expr->ts.derived->ts.f90_type;
-         c->expr->ts.kind = c->expr->ts.derived->ts.kind;
-       }
-      
       field = cm->backend_decl;
       tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field),
                         dest, field, NULL_TREE);
index 0320871..29fe1b0 100644 (file)
@@ -1766,7 +1766,9 @@ aggregate_value_p (const_tree exp, const_tree fntype)
       {
       case CALL_EXPR:
        fndecl = get_callee_fndecl (fntype);
-       fntype = fndecl ? TREE_TYPE (fndecl) : 0;
+       fntype = (fndecl
+                 ? TREE_TYPE (fndecl)
+                 : TREE_TYPE (CALL_EXPR_FN (fntype)));
        break;
       case FUNCTION_DECL:
        fndecl = fntype;
@@ -3987,6 +3989,8 @@ allocate_struct_function (tree fndecl, bool abstract_p)
   OVERRIDE_ABI_FORMAT (fndecl);
 #endif
 
+  invoke_set_current_function_hook (fndecl);
+
   if (fndecl != NULL_TREE)
     {
       DECL_STRUCT_FUNCTION (fndecl) = cfun;
@@ -4012,8 +4016,6 @@ allocate_struct_function (tree fndecl, bool abstract_p)
       cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE;
       cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
     }
-
-  invoke_set_current_function_hook (fndecl);
 }
 
 /* This is like allocate_struct_function, but pushes a new cfun for FNDECL
index 16f2324..68df55e 100644 (file)
@@ -578,6 +578,7 @@ struct function GTY(())
   unsigned int dont_save_pending_sizes_p : 1;
 
   unsigned int after_inlining : 1;
+  unsigned int always_inline_functions_inlined : 1;
 
   /* Fields below this point are not set for abstract functions; see
      allocate_struct_function.  */
index bf53944..84b2e90 100644 (file)
@@ -959,7 +959,7 @@ write_enum_constraint_num (void)
         "  CONSTRAINT__UNKNOWN = 0", stdout);
   FOR_ALL_CONSTRAINTS (c)
     printf (",\n  CONSTRAINT_%s", c->c_name);
-  puts ("\n};\n");
+  puts (",\n  CONSTRAINT__LIMIT\n};\n");
 }
 
 /* Write out a function which looks at a string and determines what
index c0f8f1d..90de9b3 100644 (file)
@@ -3108,8 +3108,11 @@ recalculate_side_effects (tree t)
        }
       break;
 
+    case tcc_constant:
+      /* No side-effects.  */
+      return;
+
     default:
-      /* Can never be used with non-expressions.  */
       gcc_unreachable ();
    }
 }
index debba12..8f8e49b 100644 (file)
@@ -793,7 +793,7 @@ gimple gimple_build_asm_vec (const char *, VEC(tree,gc) *, VEC(tree,gc) *,
                              VEC(tree,gc) *);
 gimple gimple_build_catch (tree, gimple_seq);
 gimple gimple_build_eh_filter (tree, gimple_seq);
-gimple gimple_build_try (gimple_seq, gimple_seq, unsigned int);
+gimple gimple_build_try (gimple_seq, gimple_seq, enum gimple_try_flags);
 gimple gimple_build_wce (gimple_seq);
 gimple gimple_build_resx (int);
 gimple gimple_build_switch (unsigned, tree, tree, ...);
index 2fea882..e000241 100644 (file)
@@ -3582,8 +3582,13 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
           be dropped to memory, and then memcpy'd out.  Don't do this
           for sparse arrays, though, as it's more efficient to follow
           the standard CONSTRUCTOR behavior of memset followed by
-          individual element initialization.  */
-       if (valid_const_initializer && !cleared)
+          individual element initialization.  Also don't do this for small
+          all-zero initializers (which aren't big enough to merit
+          clearing), and don't try to make bitwise copies of
+          TREE_ADDRESSABLE types.  */
+       if (valid_const_initializer
+           && !(cleared || num_nonzero_elements == 0)
+           && !TREE_ADDRESSABLE (type))
          {
            HOST_WIDE_INT size = int_size_in_bytes (type);
            unsigned int align;
@@ -3605,7 +3610,9 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
            else
              align = TYPE_ALIGN (type);
 
-           if (size > 0 && !can_move_by_pieces (size, align))
+           if (size > 0
+               && num_nonzero_elements > 1
+               && !can_move_by_pieces (size, align))
              {
                tree new_tree;
 
index 8a464c1..877dffe 100644 (file)
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-scalar-evolution.h"
 #include "tree-pass.h"
 #include "domwalk.h"
+#include "value-prof.h"
 #include "pointer-set.h"
 #include "gimple.h"
 
@@ -63,9 +64,9 @@ static VEC (scop_p, heap) *current_scops;
 /* Converts a GMP constant V to a tree and returns it.  */
 
 static tree
-gmp_cst_to_tree (Value v)
+gmp_cst_to_tree (tree type, Value v)
 {
-  return build_int_cst (integer_type_node, value_get_si (v));
+  return build_int_cst (type, value_get_si (v));
 }
 
 /* Debug the list of old induction variables for this SCOP.  */
@@ -167,13 +168,9 @@ static tree
 loop_iv_stack_get_iv (loop_iv_stack stack, int index)
 {
   iv_stack_entry_p entry = VEC_index (iv_stack_entry_p, *stack, index);
+  iv_stack_entry_data data = entry->data;
 
-  tree result = NULL;
-
-  if (entry->kind != iv_stack_entry_const)
-    result = entry->data.iv->t;
-
-  return result;
+  return iv_stack_entry_is_iv (entry) ? data.iv->t : data.constant;
 }
 
 /* Get the IV from its NAME in STACK.  */
@@ -247,6 +244,98 @@ free_loop_iv_stack (loop_iv_stack stack)
   VEC_free (iv_stack_entry_p, heap, *stack);
 }
 
+\f
+
+/* Structure containing the mapping between the CLooG's induction
+   variable and the type of the old induction variable.  */
+typedef struct ivtype_map_elt
+{
+  tree type;
+  const char *cloog_iv;
+} *ivtype_map_elt;
+
+/* Print to stderr the element ELT.  */
+
+static void
+debug_ivtype_elt (ivtype_map_elt elt)
+{
+  fprintf (stderr, "(%s, ", elt->cloog_iv);
+  print_generic_expr (stderr, elt->type, 0);
+  fprintf (stderr, ")\n");
+}
+
+/* Helper function for debug_ivtype_map.  */
+
+static int
+debug_ivtype_map_1 (void **slot, void *s ATTRIBUTE_UNUSED)
+{
+  struct ivtype_map_elt *entry = (struct ivtype_map_elt *) *slot;
+  debug_ivtype_elt (entry);
+  return 1;
+}
+
+/* Print to stderr all the elements of MAP.  */
+
+void
+debug_ivtype_map (htab_t map)
+{
+  htab_traverse (map, debug_ivtype_map_1, NULL);
+}
+
+/* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW.  */
+
+static inline ivtype_map_elt
+new_ivtype_map_elt (const char *cloog_iv, tree type)
+{
+  ivtype_map_elt res;
+  
+  res = XNEW (struct ivtype_map_elt);
+  res->cloog_iv = cloog_iv;
+  res->type = type;
+
+  return res;
+}
+
+/* Computes a hash function for database element ELT.  */
+
+static hashval_t
+ivtype_map_elt_info (const void *elt)
+{
+  return htab_hash_pointer (((const struct ivtype_map_elt *) elt)->cloog_iv);
+}
+
+/* Compares database elements E1 and E2.  */
+
+static int
+eq_ivtype_map_elts (const void *e1, const void *e2)
+{
+  const struct ivtype_map_elt *elt1 = (const struct ivtype_map_elt *) e1;
+  const struct ivtype_map_elt *elt2 = (const struct ivtype_map_elt *) e2;
+
+  return (elt1->cloog_iv == elt2->cloog_iv);
+}
+
+\f
+
+/* Given a CLOOG_IV, returns the type that it should have in GCC land.
+   If the information is not available, i.e. in the case one of the
+   transforms created the loop, just return integer_type_node.  */
+
+static tree
+gcc_type_for_cloog_iv (const char *cloog_iv, graphite_bb_p gbb)
+{
+  struct ivtype_map_elt tmp;
+  PTR *slot;
+
+  tmp.cloog_iv = cloog_iv;
+  slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, NO_INSERT);
+
+  if (slot && *slot)
+    return ((ivtype_map_elt) *slot)->type;
+
+  return integer_type_node;
+}
+
 /* Inserts constants derived from the USER_STMT argument list into the
    STACK.  This is needed to map old ivs to constants when loops have
    been eliminated.  */
@@ -257,16 +346,23 @@ loop_iv_stack_patch_for_consts (loop_iv_stack stack,
 {
   struct clast_stmt *t;
   int index = 0;
+  CloogStatement *cs = user_stmt->statement;
+  graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
+
   for (t = user_stmt->substitutions; t; t = t->next) 
     {
-      struct clast_term *term = (struct clast_term*) 
+      struct clast_expr *expr = (struct clast_expr *) 
        ((struct clast_assignment *)t)->RHS;
+      struct clast_term *term = (struct clast_term *) expr;
 
       /* FIXME: What should be done with expr_bin, expr_red?  */
-      if (((struct clast_assignment *)t)->RHS->type == expr_term
+      if (expr->type == expr_term
          && !term->var)
        {
-         tree value = gmp_cst_to_tree (term->val);
+         loop_p loop = gbb_loop_at_index (gbb, index);
+         tree oldiv = oldiv_for_loop (GBB_SCOP (gbb), loop);
+         tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node;
+         tree value = gmp_cst_to_tree (type, term->val);
          loop_iv_stack_insert_constant (stack, index, value);
        }
       index = index + 1;
@@ -293,33 +389,6 @@ loop_iv_stack_remove_constants (loop_iv_stack stack)
     }
 }
 
-/* In SCOP, get the induction variable from NAME.  OLD is the original
-   loop that contained the definition of NAME.  */
-
-static name_tree
-get_old_iv_from_ssa_name (scop_p scop, loop_p old, tree name)
-{
-  tree var = SSA_NAME_VAR (name);
-  int i;
-  name_tree oldiv;
-  
-  for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, oldiv); i++)
-    {
-      loop_p current = old;
-
-      while (current)
-       {
-         if (var == oldiv->t
-             && oldiv->loop == current)
-           return oldiv;
-
-         current = loop_outer (current);
-       }
-    }
-  return NULL;
-
-}
-
 /* Returns a new loop_to_cloog_loop_str structure.  */
 
 static inline struct loop_to_cloog_loop_str *
@@ -495,7 +564,7 @@ print_graphite_bb (FILE *file, graphite_bb_p gb, int indent, int verbosity)
   if (GBB_DOMAIN (gb))
     {
       fprintf (file, "       (domain: \n");
-      cloog_matrix_print (dump_file, GBB_DOMAIN (gb));
+      cloog_matrix_print (file, GBB_DOMAIN (gb));
       fprintf (file, "       )\n");
     }
 
@@ -525,7 +594,7 @@ print_graphite_bb (FILE *file, graphite_bb_p gb, int indent, int verbosity)
   if (GBB_CONDITIONS (gb))
     {
       fprintf (file, "       (conditions: \n");
-      dump_gbb_conditions (dump_file, gb);
+      dump_gbb_conditions (file, gb);
       fprintf (file, "       )\n");
     }
 
@@ -610,14 +679,6 @@ debug_scops (int verbosity)
   print_scops (stderr, verbosity);
 }
 
-/* Return true when BB is contained in SCOP.  */
-
-static inline bool
-bb_in_scop_p (basic_block bb, scop_p scop)
-{
-  return bitmap_bit_p (SCOP_BBS_B (scop), bb->index);
-}
-
 /* Pretty print to FILE the SCOP in DOT format.  */
 
 static void 
@@ -818,15 +879,6 @@ dot_all_scops (void)
 #endif
 }
 
-/* Returns true when LOOP is in SCOP.  */
-
-static inline bool 
-loop_in_scop_p (struct loop *loop, scop_p scop)
-{
-  return (bb_in_scop_p (loop->header, scop)
-         && bb_in_scop_p (loop->latch, scop));
-}
-
 /* Returns the outermost loop in SCOP that contains BB.  */
 
 static struct loop *
@@ -1025,23 +1077,87 @@ harmful_stmt_in_bb (basic_block scop_entry, basic_block bb)
   return NULL;
 }
 
+/* Returns true when BB will be represented in graphite.  Return false
+   for the basic blocks that contain code eliminated in the code
+   generation pass: i.e. induction variables and exit conditions.  */
+
+static bool
+graphite_stmt_p (scop_p scop, basic_block bb,
+                VEC (data_reference_p, heap) *drs)
+{
+  gimple_stmt_iterator gsi;
+  loop_p loop = bb->loop_father;
+
+  if (VEC_length (data_reference_p, drs) > 0)
+    return true;
+
+  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+    {
+      gimple stmt = gsi_stmt (gsi);
+
+      switch (gimple_code (stmt))
+        {
+          /* Control flow expressions can be ignored, as they are
+             represented in the iteration domains and will be
+             regenerated by graphite.  */
+       case GIMPLE_COND:
+       case GIMPLE_GOTO:
+       case GIMPLE_SWITCH:
+         break;
+
+       case GIMPLE_ASSIGN:
+         {
+           tree var = gimple_assign_lhs (stmt);
+           var = analyze_scalar_evolution (loop, var);
+           var = instantiate_scev (block_before_scop (scop), loop, var);
+
+           if (chrec_contains_undetermined (var))
+             return true;
+
+           break;
+         }
+
+       default:
+         return true;
+        }
+    }
+
+  return false;
+}
+
 /* Store the GRAPHITE representation of BB.  */
 
 static void
 new_graphite_bb (scop_p scop, basic_block bb)
 {
-  struct graphite_bb *gbb = XNEW (struct graphite_bb);
+  struct graphite_bb *gbb;
+  VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
+  struct loop *nest = outermost_loop_in_scop (scop, bb);
+  gimple_stmt_iterator gsi;
+
+  bitmap_set_bit (SCOP_BBS_B (scop), bb->index);
+
+  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+    find_data_references_in_stmt (nest, gsi_stmt (gsi), &drs);
+
+  if (!graphite_stmt_p (scop, bb, drs))
+    {
+      free_data_refs (drs);
+      return;
+    }
 
+  gbb = XNEW (struct graphite_bb);
   bb->aux = gbb;
   GBB_BB (gbb) = bb;
   GBB_SCOP (gbb) = scop;
-  GBB_DATA_REFS (gbb) = NULL; 
+  GBB_DATA_REFS (gbb) = drs;
   GBB_DOMAIN (gbb) = NULL;
   GBB_CONDITIONS (gbb) = NULL;
   GBB_CONDITION_CASES (gbb) = NULL;
   GBB_LOOPS (gbb) = NULL;
+  GBB_STATIC_SCHEDULE (gbb) = NULL;
+  GBB_CLOOG_IV_TYPES (gbb) = NULL;
   VEC_safe_push (graphite_bb_p, heap, SCOP_BBS (scop), gbb);
-  bitmap_set_bit (SCOP_BBS_B (scop), bb->index);
 }
 
 /* Frees GBB.  */
@@ -1052,15 +1168,41 @@ free_graphite_bb (struct graphite_bb *gbb)
   if (GBB_DOMAIN (gbb))
     cloog_matrix_free (GBB_DOMAIN (gbb));
 
-  free_data_refs (GBB_DATA_REFS (gbb));
+  if (GBB_CLOOG_IV_TYPES (gbb))
+    htab_delete (GBB_CLOOG_IV_TYPES (gbb));
+
+  /* FIXME: free_data_refs is disabled for the moment, but should be
+     enabled.
+
+     free_data_refs (GBB_DATA_REFS (gbb)); */
+
   VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
   VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
   VEC_free (loop_p, heap, GBB_LOOPS (gbb));
-
   GBB_BB (gbb)->aux = 0;
   XDELETE (gbb);
 }
 
+/* Register basic blocks belonging to a region in a pointer set.  */
+
+static void
+register_bb_in_sese (basic_block entry_bb, basic_block exit_bb, sese region)
+{
+  edge_iterator ei;
+  edge e;
+  basic_block bb = entry_bb;
+
+  FOR_EACH_EDGE (e, ei, bb->succs)
+    {
+      if (!pointer_set_contains (SESE_REGION_BBS (region), e->dest) &&
+         e->dest->index != exit_bb->index)
+       {       
+         pointer_set_insert (SESE_REGION_BBS (region), e->dest);
+         register_bb_in_sese (e->dest, exit_bb, region);
+       }
+    }
+}
+
 /* Creates a new scop starting with ENTRY.  */
 
 static scop_p
@@ -1073,11 +1215,15 @@ new_scop (edge entry, edge exit)
   SCOP_REGION (scop) = XNEW (struct sese);
   SESE_ENTRY (SCOP_REGION (scop)) = entry;
   SESE_EXIT (SCOP_REGION (scop)) = exit;
+  SESE_REGION_BBS (SCOP_REGION (scop)) = pointer_set_create ();
+  register_bb_in_sese (SCOP_ENTRY (scop), SCOP_EXIT (scop),
+                      SCOP_REGION (scop));
   SCOP_BBS (scop) = VEC_alloc (graphite_bb_p, heap, 3);
   SCOP_OLDIVS (scop) = VEC_alloc (name_tree, heap, 3);
   SCOP_BBS_B (scop) = BITMAP_ALLOC (NULL);
   SCOP_LOOPS (scop) = BITMAP_ALLOC (NULL);
   SCOP_LOOP_NEST (scop) = VEC_alloc (loop_p, heap, 3);
+  SCOP_ADD_PARAMS (scop) = true;
   SCOP_PARAMS (scop) = VEC_alloc (name_tree, heap, 3);
   SCOP_PROG (scop) = cloog_program_malloc ();
   cloog_program_set_names (SCOP_PROG (scop), cloog_names_malloc ());
@@ -1318,7 +1464,7 @@ scopdet_basic_block_info (basic_block bb, VEC (sd_region, heap) **scops,
 
     case GBB_LOOP_MULT_EXIT_HEADER:
       {
-        /* XXX: For now we just do not join loops with multiple exits. If the 
+        /* XXX: For now we just do not join loops with multiple exits.  If the 
            exits lead to the same bb it may be possible to join the loop.  */
         VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3);
         VEC (edge, heap) *exits = get_loop_exit_edges (loop);
@@ -1326,28 +1472,27 @@ scopdet_basic_block_info (basic_block bb, VEC (sd_region, heap) **scops,
         int i;
         build_scops_1 (bb, &tmp_scops, loop);
 
-
-       /* Start at all bbs dominated by a loop exit that only exists in this
-          loop.  */ 
+       /* Scan the code dominated by this loop.  This means all bbs, that are
+          are dominated by a bb in this loop, but are not part of this loop.
+          
+          The easiest case:
+            - The loop exit destination is dominated by the exit sources.  
+        
+          TODO: We miss here the more complex cases:
+                 - The exit destinations are dominated by another bb inside the
+                   loop.
+                 - The loop dominates bbs, that are not exit destinations.  */
         for (i = 0; VEC_iterate (edge, exits, i, e); i++)
-          if (e->src->loop_father == loop)
-            {  
-             VEC (basic_block, heap) *dominated;
-             basic_block b;
-             int j;
-             dominated = get_dominated_by (CDI_DOMINATORS, e->src);
-             for (j = 0; VEC_iterate (basic_block, dominated, j, b); j++)
-               /* Loop exit.  */
-               if (loop_depth (find_common_loop (loop, b->loop_father))
-                   < loop_depth (loop))
-                 {
-                   /* Pass loop_outer to recognize b as loop header in
-                      build_scops_1.  */
-                   if (b->loop_father->header == b)
-                     build_scops_1 (b, &tmp_scops, loop_outer (b->loop_father));
-                   else
-                     build_scops_1 (b, &tmp_scops, b->loop_father);
-                 }
+          if (e->src->loop_father == loop
+             && dominated_by_p (CDI_DOMINATORS, e->dest, e->src))
+           {
+             /* Pass loop_outer to recognize e->dest as loop header in
+                build_scops_1.  */
+             if (e->dest->loop_father->header == e->dest)
+               build_scops_1 (e->dest, &tmp_scops,
+                              loop_outer (e->dest->loop_father));
+             else
+               build_scops_1 (e->dest, &tmp_scops, e->dest->loop_father);
            }
 
         result.next = NULL; 
@@ -1500,7 +1645,6 @@ scopdet_basic_block_info (basic_block bb, VEC (sd_region, heap) **scops,
 static struct scopdet_info 
 build_scops_1 (basic_block current, VEC (sd_region, heap) **scops, loop_p loop)
 {
-
   bool in_scop = false;
   sd_region open_scop;
   struct scopdet_info sinfo;
@@ -1512,6 +1656,8 @@ build_scops_1 (basic_block current, VEC (sd_region, heap) **scops, loop_p loop)
   result.next = NULL;
   result.last = NULL;
   open_scop.entry = NULL;
+  open_scop.exit = NULL;
+  sinfo.last = NULL;
 
   /* Loop over the dominance tree.  If we meet a difficult bb, close
      the current SCoP.  Loop and condition header start a new layer,
@@ -1800,6 +1946,29 @@ mark_exit_edges (VEC (sd_region, heap) *regions)
        e->aux = s;
 }
 
+/* Free and compute again all the dominators information.  */
+
+static inline void
+recompute_all_dominators (void)
+{
+  free_dominance_info (CDI_DOMINATORS);
+  free_dominance_info (CDI_POST_DOMINATORS);
+  calculate_dominance_info (CDI_DOMINATORS);
+  calculate_dominance_info (CDI_POST_DOMINATORS);
+}
+
+/* Verifies properties that GRAPHITE should maintain during translation.  */
+
+static inline void
+graphite_verify (void)
+{
+#ifdef ENABLE_CHECKING
+  verify_loop_structure ();
+  verify_dominators (CDI_DOMINATORS);
+  verify_dominators (CDI_POST_DOMINATORS);
+  verify_ssa (false);
+#endif
+}
 
 /* Create for all scop regions a single entry and a single exit edge.  */
 
@@ -1938,64 +2107,108 @@ build_scop_bbs (scop_p scop)
   sbitmap_free (visited);
 }
 
+/* Returns the number of reduction phi nodes in LOOP.  */
 
-/* Record LOOP as occuring in SCOP.  */
+static int
+nb_reductions_in_loop (loop_p loop)
+{
+  int res = 0;
+  gimple_stmt_iterator gsi;
 
-static void
-scop_record_loop (scop_p scop, struct loop *loop)
+  for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
+    {
+      gimple phi = gsi_stmt (gsi);
+      tree scev;
+
+      if (!is_gimple_reg (PHI_RESULT (phi)))
+       continue;
+
+      scev = analyze_scalar_evolution (loop, PHI_RESULT (phi));
+      scev = instantiate_parameters (loop, scev);
+      if (chrec_contains_undetermined (scev))
+       res++;
+    }
+
+  return res;
+}
+
+/* A LOOP is in normal form when it contains only one scalar phi node
+   that defines the main induction variable of the loop, only one
+   increment of the IV, and only one exit condition. */
+
+static tree
+graphite_loop_normal_form (loop_p loop)
 {
-  loop_p parent;
-  tree induction_var;
+  struct tree_niter_desc niter;
+  tree nit;
+  gimple_seq stmts;
+  edge exit = single_dom_exit (loop);
 
-  if (bitmap_bit_p (SCOP_LOOPS (scop), loop->num))
-    return;
+  if (!number_of_iterations_exit (loop, exit, &niter, false))
+    gcc_unreachable ();
 
-  parent = loop_outer (loop);
-  induction_var = find_induction_var_from_exit_cond (loop);
+  nit = force_gimple_operand (unshare_expr (niter.niter), &stmts, true,
+                             NULL_TREE);
+  if (stmts)
+    gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
 
-  if (!bb_in_scop_p (parent->latch, scop))
-    parent = NULL;
+  /* One IV per loop.  */
+  if (nb_reductions_in_loop (loop) > 0)
+    return NULL_TREE;
 
-  if (induction_var != NULL_TREE)
-    {
-      name_tree oldiv = XNEW (struct name_tree);
-      oldiv->t = SSA_NAME_VAR (induction_var);
-      if (DECL_NAME (oldiv->t))
-       oldiv->name = IDENTIFIER_POINTER (DECL_NAME (oldiv->t));
-      else
-       {
-         int len = 2 + 16;
-         char *n = XNEWVEC (char, len);
-         snprintf (n, len, "D.%u", DECL_UID (oldiv->t));
-         oldiv->name = n;
-       }
-      oldiv->loop = loop;
+  return canonicalize_loop_ivs (loop, NULL, nit);
+}
 
-      VEC_safe_push (name_tree, heap, SCOP_OLDIVS (scop), oldiv);
-    }
+/* Record LOOP as occuring in SCOP.  Returns true when the operation
+   was successful.  */
+
+static bool
+scop_record_loop (scop_p scop, loop_p loop)
+{
+  tree induction_var;
+  name_tree oldiv;
+
+  if (bitmap_bit_p (SCOP_LOOPS (scop), loop->num))
+    return true;
 
   bitmap_set_bit (SCOP_LOOPS (scop), loop->num);
   VEC_safe_push (loop_p, heap, SCOP_LOOP_NEST (scop), loop);
+
+  induction_var = graphite_loop_normal_form (loop);
+  if (!induction_var)
+    return false;
+
+  oldiv = XNEW (struct name_tree);
+  oldiv->t = induction_var;
+  oldiv->name = get_name (SSA_NAME_VAR (oldiv->t));
+  oldiv->loop = loop;
+  VEC_safe_push (name_tree, heap, SCOP_OLDIVS (scop), oldiv);
+  return true;
 }
 
-/* Build the loop nests contained in SCOP.  */
+/* Build the loop nests contained in SCOP.  Returns true when the
+   operation was successful.  */
 
-static void
+static bool
 build_scop_loop_nests (scop_p scop)
 {
   unsigned i;
-  graphite_bb_p gb;
+  basic_block bb;
   struct loop *loop0, *loop1;
 
-  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
-    {
-      struct loop *loop = gbb_loop (gb);
+  FOR_EACH_BB (bb)
+    if (bb_in_scop_p (bb, scop))
+      {
+       struct loop *loop = bb->loop_father;
 
-      /* Only add loops, if they are completely contained in the SCoP.  */
-      if (loop->header == GBB_BB (gb)
-         && bb_in_scop_p (loop->latch, scop))
-        scop_record_loop (scop, gbb_loop (gb));
-    }
+       /* Only add loops if they are completely contained in the SCoP.  */
+       if (loop->header == bb
+           && bb_in_scop_p (loop->latch, scop))
+         {
+           if (!scop_record_loop (scop, loop))
+             return false;
+         }
+      }
 
   /* Make sure that the loops in the SCOP_LOOP_NEST are ordered.  It
      can be the case that an inner loop is inserted before an outer
@@ -2012,20 +2225,37 @@ build_scop_loop_nests (scop_p scop)
          VEC_replace (loop_p, SCOP_LOOP_NEST (scop), i + 1, loop0);
        }
     }
+
+  return true;
 }
 
-/* Calculate the number of loops around GB in the current SCOP.  */
+/* Build dynamic schedules for all the BBs. */
 
-static inline int
-nb_loops_around_gb (graphite_bb_p gb)
+static void
+build_scop_dynamic_schedules (scop_p scop)
 {
-  scop_p scop = GBB_SCOP (gb);
-  struct loop *l = gbb_loop (gb);
-  int d = 0;
+  int i, dim, loop_num, row, col;
+  graphite_bb_p gb;
 
-  for (; loop_in_scop_p (l, scop); d++, l = loop_outer (l));
+  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
+    {
+      loop_num = GBB_BB (gb)->loop_father->num;
 
-  return d;
+      if (loop_num != 0)
+        {
+          dim = nb_loops_around_gb (gb);
+          GBB_DYNAMIC_SCHEDULE (gb) = cloog_matrix_alloc (dim, dim);
+
+          for (row = 0; row < GBB_DYNAMIC_SCHEDULE (gb)->NbRows; row++)
+            for (col = 0; col < GBB_DYNAMIC_SCHEDULE (gb)->NbColumns; col++)
+              if (row == col)
+                value_set_si (GBB_DYNAMIC_SCHEDULE (gb)->p[row][col], 1);
+              else
+                value_set_si (GBB_DYNAMIC_SCHEDULE (gb)->p[row][col], 0);
+        }
+      else
+        GBB_DYNAMIC_SCHEDULE (gb) = NULL;
+    }
 }
 
 /* Build for BB the static schedule.
@@ -2139,6 +2369,8 @@ param_index (tree var, scop_p scop)
     if (p->t == var)
       return i;
 
+  gcc_assert (SCOP_ADD_PARAMS (scop));
+
   nvar = XNEW (struct name_tree);
   nvar->t = var;
   nvar->name = NULL;
@@ -2218,26 +2450,28 @@ scan_tree_for_params (scop_p s, tree e, CloogMatrix *c, int r, Value k,
     case MULT_EXPR:
       if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
        {
-         Value val;
-
-         gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
-
-         value_init (val);
-         value_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
-         value_multiply (k, k, val);
-         value_clear (val);
+         if (c)
+           {
+             Value val;
+             gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
+             value_init (val);
+             value_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
+             value_multiply (k, k, val);
+             value_clear (val);
+           }
          scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
        }
       else
        {
-         Value val;
-
-         gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
-
-         value_init (val);
-         value_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
-         value_multiply (k, k, val);
-         value_clear (val);
+         if (c)
+           {
+             Value val;
+             gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
+             value_init (val);
+             value_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
+             value_multiply (k, k, val);
+             value_clear (val);
+           }
          scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
        }
       break;
@@ -2348,58 +2582,43 @@ idx_record_params (tree base, tree *idx, void *dta)
    access functions, conditions and loop bounds.  */
 
 static void
-find_params_in_bb (scop_p scop, basic_block bb)
+find_params_in_bb (scop_p scop, graphite_bb_p gb)
 {
   int i;
   data_reference_p dr;
-  VEC (data_reference_p, heap) *drs;
-  gimple_stmt_iterator gsi;
-  struct loop *nest = outermost_loop_in_scop (scop, bb);
-
-  /* Find the parameters used in the memory access functions.  */
-  drs = VEC_alloc (data_reference_p, heap, 5);
-  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-    find_data_references_in_stmt (nest, gsi_stmt (gsi), &drs);
+  gimple stmt;
+  loop_p father = GBB_BB (gb)->loop_father;
 
-  for (i = 0; VEC_iterate (data_reference_p, drs, i, dr); i++)
+  for (i = 0; VEC_iterate (data_reference_p, GBB_DATA_REFS (gb), i, dr); i++)
     {
       struct irp_data irp;
 
-      irp.loop = bb->loop_father;
+      irp.loop = father;
       irp.scop = scop;
       for_each_index (&dr->ref, idx_record_params, &irp);
-      free_data_ref (dr);
     }
 
-  VEC_free (data_reference_p, heap, drs);
-
   /* Find parameters in conditional statements.  */ 
-  gsi = gsi_last_bb (bb);
-  if (!gsi_end_p (gsi))
+  for (i = 0; VEC_iterate (gimple, GBB_CONDITIONS (gb), i, stmt); i++)
     {
-      gimple stmt = gsi_stmt (gsi);
+      Value one;
+      loop_p loop = father;
 
-      if (gimple_code (stmt) == GIMPLE_COND)
-        {
-          Value one;
-          loop_p loop = bb->loop_father;
-
-          tree lhs, rhs;
-          
-          lhs = gimple_cond_lhs (stmt);
-          lhs = analyze_scalar_evolution (loop, lhs);
-          lhs = instantiate_scev (block_before_scop (scop), loop, lhs);
-
-          rhs = gimple_cond_rhs (stmt);
-          rhs = analyze_scalar_evolution (loop, rhs);
-          rhs = instantiate_scev (block_before_scop (scop), loop, rhs);
-
-          value_init (one);
-          scan_tree_for_params (scop, lhs, NULL, 0, one, false);
-          value_set_si (one, 1);
-          scan_tree_for_params (scop, rhs, NULL, 0, one, false);
-          value_clear (one);
-       }
+      tree lhs, rhs;
+
+      lhs = gimple_cond_lhs (stmt);
+      lhs = analyze_scalar_evolution (loop, lhs);
+      lhs = instantiate_scev (block_before_scop (scop), loop, lhs);
+
+      rhs = gimple_cond_rhs (stmt);
+      rhs = analyze_scalar_evolution (loop, rhs);
+      rhs = instantiate_scev (block_before_scop (scop), loop, rhs);
+
+      value_init (one);
+      scan_tree_for_params (scop, lhs, NULL, 0, one, false);
+      value_set_si (one, 1);
+      scan_tree_for_params (scop, rhs, NULL, 0, one, false);
+      value_clear (one);
     }
 }
 
@@ -2523,7 +2742,9 @@ find_scop_parameters (scop_p scop)
 
   /* Find the parameters used in data accesses.  */
   for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
-    find_params_in_bb (scop, GBB_BB (gb));
+    find_params_in_bb (scop, gb);
+
+  SCOP_ADD_PARAMS (scop) = false;
 }
 
 /* Build the context constraints for SCOP: constraints and relations
@@ -2555,24 +2776,6 @@ gbb_from_bb (basic_block bb)
   return (graphite_bb_p) bb->aux;
 }
 
-/* Add DOMAIN to all the basic blocks in LOOP.  */
-
-static void
-add_bb_domains (struct loop *loop, CloogMatrix *domain)
-{
-  basic_block *bbs = get_loop_body (loop);
-  unsigned i;
-
-  for (i = 0; i < loop->num_nodes; i++)
-    if (bbs[i]->loop_father == loop)
-      {
-        graphite_bb_p gbb = gbb_from_bb (bbs[i]);
-        GBB_DOMAIN (gbb) = cloog_matrix_copy (domain);
-      }
-
-  free (bbs);
-}
-
 /* Builds the constraint matrix for LOOP in SCOP.  NB_OUTER_LOOPS is the
    number of loops surrounding LOOP in SCOP.  OUTER_CSTR gives the
    constraints matrix for the surrounding loops.  */
@@ -2583,6 +2786,7 @@ build_loop_iteration_domains (scop_p scop, struct loop *loop,
 {
   int i, j, row;
   CloogMatrix *cstr;
+  graphite_bb_p gb;
 
   int nb_rows = outer_cstr->NbRows + 1;
   int nb_cols = outer_cstr->NbColumns + 1;
@@ -2663,7 +2867,9 @@ build_loop_iteration_domains (scop_p scop, struct loop *loop,
   if (nb_outer_loops != 0 && loop->next && loop_in_scop_p (loop->next, scop))
     build_loop_iteration_domains (scop, loop->next, outer_cstr, nb_outer_loops);
 
-  add_bb_domains (loop, cstr);
+  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
+    if (gbb_loop (gb) == loop)
+      GBB_DOMAIN (gb) = cloog_matrix_copy (cstr);
 
   cloog_matrix_free (cstr);
 }
@@ -2885,10 +3091,12 @@ build_scop_conditions_1 (VEC (gimple, heap) **conditions,
 
   /* Record conditions in graphite_bb.  */
   gbb = gbb_from_bb (bb);
-  GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
-  GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
-
-  add_conditions_to_domain (gbb);
+  if (gbb)
+    {
+      GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
+      GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
+      add_conditions_to_domain (gbb);
+    }
 
   dom = get_dominated_by (CDI_DOMINATORS, bb);
 
@@ -3050,27 +3258,31 @@ build_scop_iteration_domain (scop_p scop)
 }
 
 /* Initializes an equation CY of the access matrix using the
-   information for a subscript from ACCESS_FUN, relatively to the loop
+   information for a subscript from AF, relatively to the loop
    indexes from LOOP_NEST and parameter indexes from PARAMS.  NDIM is
    the dimension of the array access, i.e. the number of
    subscripts.  Returns true when the operation succeeds.  */
 
 static bool
-build_access_matrix_with_af (tree access_fun, lambda_vector cy,
+build_access_matrix_with_af (tree af, lambda_vector cy,
                             scop_p scop, int ndim)
 {
-  switch (TREE_CODE (access_fun))
+  int param_col;
+
+  switch (TREE_CODE (af))
     {
     case POLYNOMIAL_CHREC:
       {
-       tree left = CHREC_LEFT (access_fun);
-       tree right = CHREC_RIGHT (access_fun);
+        struct loop *outer_loop;
+       tree left = CHREC_LEFT (af);
+       tree right = CHREC_RIGHT (af);
        int var;
 
        if (TREE_CODE (right) != INTEGER_CST)
          return false;
-        
-       var = loop_iteration_vector_dim (CHREC_VARIABLE (access_fun), scop);
+
+        outer_loop = get_loop (CHREC_VARIABLE (af));
+        var = nb_loops_around_loop_in_scop (outer_loop, scop);
        cy[var] = int_cst_value (right);
 
        switch (TREE_CODE (left))
@@ -3083,12 +3295,27 @@ build_access_matrix_with_af (tree access_fun, lambda_vector cy,
            return true;
 
          default:
-           /* FIXME: access_fn can have parameters.  */
-           return false;
+           return build_access_matrix_with_af (left, cy, scop, ndim);
          }
       }
+
+    case PLUS_EXPR:
+      build_access_matrix_with_af (TREE_OPERAND (af, 0), cy, scop, ndim);
+      build_access_matrix_with_af (TREE_OPERAND (af, 1), cy, scop, ndim);
+      return true;
+      
+    case MINUS_EXPR:
+      build_access_matrix_with_af (TREE_OPERAND (af, 0), cy, scop, ndim);
+      build_access_matrix_with_af (TREE_OPERAND (af, 1), cy, scop, ndim);
+      return true;
+
     case INTEGER_CST:
-      cy[ndim - 1] = int_cst_value (access_fun);
+      cy[ndim - 1] = int_cst_value (af);
+      return true;
+
+    case SSA_NAME:
+      param_col = param_index (af, scop);      
+      cy [ndim - scop_nb_params (scop) + param_col - 1] = 1; 
       return true;
 
     default:
@@ -3134,23 +3361,14 @@ build_scop_data_accesses (scop_p scop)
   int i;
   graphite_bb_p gb;
 
+  /* FIXME: Construction of access matrix is disabled until some
+     pass, like the data dependence analysis, is using it.  */
+  return;
+
   for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
     {
       int j;
-      gimple_stmt_iterator gsi;
       data_reference_p dr;
-      struct loop *nest = outermost_loop_in_scop (scop, GBB_BB (gb));
-
-      /* On each statement of the basic block, gather all the occurences
-        to read/write memory.  */
-      GBB_DATA_REFS (gb) = VEC_alloc (data_reference_p, heap, 5);
-      for (gsi = gsi_start_bb (GBB_BB (gb)); !gsi_end_p (gsi); gsi_next (&gsi))
-       find_data_references_in_stmt (nest, gsi_stmt (gsi),
-                                     &GBB_DATA_REFS (gb));
-
-      /* FIXME: Construction of access matrix is disabled until some
-        pass, like the data dependence analysis, is using it.  */
-      continue;
 
       /* Construct the access matrix for each data ref, with respect to
         the loop nest of the current BB in the considered SCOP.  */
@@ -3189,9 +3407,10 @@ clast_name_to_gcc (const char *name, VEC (name_tree, heap) *params,
   name_tree t;
   tree iv;
 
-  for (i = 0; VEC_iterate (name_tree, params, i, t); i++)
-    if (!strcmp (name, t->name))
-      return t->t;
+  if (params)
+    for (i = 0; VEC_iterate (name_tree, params, i, t); i++)
+      if (!strcmp (name, t->name))
+       return t->t;
 
   iv = loop_iv_stack_get_iv_from_name (ivstack, name);
   if (iv)
@@ -3200,17 +3419,24 @@ clast_name_to_gcc (const char *name, VEC (name_tree, heap) *params,
   gcc_unreachable ();
 }
 
-/* Converts a Cloog AST expression E back to a GCC expression tree.   */
+/* Returns the maximal precision type for expressions E1 and E2.  */
+
+static inline tree
+max_precision_type (tree e1, tree e2)
+{
+  tree type1 = TREE_TYPE (e1);
+  tree type2 = TREE_TYPE (e2);
+  return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
+}
+
+/* Converts a Cloog AST expression E back to a GCC expression tree
+   of type TYPE.  */
 
 static tree
-clast_to_gcc_expression (struct clast_expr *e,
+clast_to_gcc_expression (tree type, struct clast_expr *e,
                         VEC (name_tree, heap) *params,
                         loop_iv_stack ivstack)
 {
-  tree type = integer_type_node;
-
-  gcc_assert (e);
-
   switch (e->type)
     {
     case expr_term:
@@ -3220,53 +3446,62 @@ clast_to_gcc_expression (struct clast_expr *e,
        if (t->var)
          {
            if (value_one_p (t->val))
-             return clast_name_to_gcc (t->var, params, ivstack);
+             {
+               tree name = clast_name_to_gcc (t->var, params, ivstack);
+               return fold_convert (type, name);
+             }
 
            else if (value_mone_p (t->val))
-             return fold_build1 (NEGATE_EXPR, type,
-                                 clast_name_to_gcc (t->var, params, ivstack));
+             {
+               tree name = clast_name_to_gcc (t->var, params, ivstack);
+               name = fold_convert (type, name);
+               return fold_build1 (NEGATE_EXPR, type, name);
+             }
            else
-             return fold_build2 (MULT_EXPR, type,
-                                 gmp_cst_to_tree (t->val),
-                                 clast_name_to_gcc (t->var, params, ivstack));
+             {
+               tree name = clast_name_to_gcc (t->var, params, ivstack);
+               tree cst = gmp_cst_to_tree (type, t->val);
+               name = fold_convert (type, name);
+               return fold_build2 (MULT_EXPR, type, cst, name);
+             }
          }
        else
-         return gmp_cst_to_tree (t->val);
+         return gmp_cst_to_tree (type, t->val);
       }
 
     case expr_red:
       {
         struct clast_reduction *r = (struct clast_reduction *) e;
-        tree left, right;
 
         switch (r->type)
           {
          case clast_red_sum:
            if (r->n == 1)
-             return clast_to_gcc_expression (r->elts[0], params, ivstack);
+             return clast_to_gcc_expression (type, r->elts[0], params, ivstack);
 
            else 
              {
+               tree tl = clast_to_gcc_expression (type, r->elts[0], params, ivstack);
+               tree tr = clast_to_gcc_expression (type, r->elts[1], params, ivstack);
+
                gcc_assert (r->n >= 1
                            && r->elts[0]->type == expr_term
                            && r->elts[1]->type == expr_term);
 
-               left = clast_to_gcc_expression (r->elts[0], params, ivstack);
-               right = clast_to_gcc_expression (r->elts[1], params, ivstack);
-               return fold_build2 (PLUS_EXPR, type, left, right);
+               return fold_build2 (PLUS_EXPR, type, tl, tr);
              }
 
            break;
 
          case clast_red_min:
            if (r->n == 1)
-             return clast_to_gcc_expression (r->elts[0], params, ivstack);
+             return clast_to_gcc_expression (type, r->elts[0], params, ivstack);
 
            else if (r->n == 2)
              {
-               left = clast_to_gcc_expression (r->elts[0], params, ivstack);
-               right = clast_to_gcc_expression (r->elts[1], params, ivstack);
-               return fold_build2 (MIN_EXPR, type, left, right);
+               tree tl = clast_to_gcc_expression (type, r->elts[0], params, ivstack);
+               tree tr = clast_to_gcc_expression (type, r->elts[1], params, ivstack);
+               return fold_build2 (MIN_EXPR, type, tl, tr);
              }
 
            else
@@ -3276,13 +3511,13 @@ clast_to_gcc_expression (struct clast_expr *e,
 
          case clast_red_max:
            if (r->n == 1)
-             return clast_to_gcc_expression (r->elts[0], params, ivstack);
+             return clast_to_gcc_expression (type, r->elts[0], params, ivstack);
 
            else if (r->n == 2)
              {
-               left = clast_to_gcc_expression (r->elts[0], params, ivstack);
-               right = clast_to_gcc_expression (r->elts[1], params, ivstack);
-               return fold_build2 (MAX_EXPR, type, left, right);
+               tree tl = clast_to_gcc_expression (type, r->elts[0], params, ivstack);
+               tree tr = clast_to_gcc_expression (type, r->elts[1], params, ivstack);
+               return fold_build2 (MAX_EXPR, type, tl, tr);
              }
 
            else
@@ -3300,15 +3535,8 @@ clast_to_gcc_expression (struct clast_expr *e,
       {
        struct clast_binary *b = (struct clast_binary *) e;
        struct clast_expr *lhs = (struct clast_expr *) b->LHS;
-       struct clast_expr *rhs = (struct clast_expr *) b->RHS;
-       tree tl = clast_to_gcc_expression (lhs, params, ivstack);
-
-       /* FIXME: The next statement produces a warning: Cloog assumes
-          that the RHS is a constant, but this is a "void *" pointer
-          that should be casted into a Value, but this cast cannot be
-          done as Value is a GMP type, that is an array.  Cloog must
-          be fixed for removing this warning.  */
-       tree tr = gmp_cst_to_tree (rhs);
+       tree tl = clast_to_gcc_expression (type, lhs, params, ivstack);
+       tree tr = gmp_cst_to_tree (type, b->RHS);
 
        switch (b->type)
          {
@@ -3336,6 +3564,72 @@ clast_to_gcc_expression (struct clast_expr *e,
   return NULL_TREE;
 }
 
+/* Returns the type for the expression E.  */
+
+static tree
+gcc_type_for_clast_expr (struct clast_expr *e,
+                        VEC (name_tree, heap) *params,
+                        loop_iv_stack ivstack)
+{
+  switch (e->type)
+    {
+    case expr_term:
+      {
+       struct clast_term *t = (struct clast_term *) e;
+
+       if (t->var)
+         return TREE_TYPE (clast_name_to_gcc (t->var, params, ivstack));
+       else
+         return NULL_TREE;
+      }
+
+    case expr_red:
+      {
+        struct clast_reduction *r = (struct clast_reduction *) e;
+
+       if (r->n == 1)
+         return gcc_type_for_clast_expr (r->elts[0], params, ivstack);
+       else 
+         {
+           int i;
+           for (i = 0; i < r->n; i++)
+             {
+               tree type = gcc_type_for_clast_expr (r->elts[i], params, ivstack);
+               if (type)
+                 return type;
+             }
+           return NULL_TREE;
+         }
+      }
+
+    case expr_bin:
+      {
+       struct clast_binary *b = (struct clast_binary *) e;
+       struct clast_expr *lhs = (struct clast_expr *) b->LHS;
+       return gcc_type_for_clast_expr (lhs, params, ivstack);
+      }
+
+    default:
+      gcc_unreachable ();
+    }
+
+  return NULL_TREE;
+}
+
+/* Returns the type for the equation CLEQ.  */
+
+static tree
+gcc_type_for_clast_eq (struct clast_equation *cleq,
+                      VEC (name_tree, heap) *params,
+                      loop_iv_stack ivstack)
+{
+  tree type = gcc_type_for_clast_expr (cleq->LHS, params, ivstack);
+  if (type)
+    return type;
+
+  return gcc_type_for_clast_expr (cleq->RHS, params, ivstack);
+}
+
 /* Translates a clast equation CLEQ to a tree.  */
 
 static tree
@@ -3344,8 +3638,9 @@ graphite_translate_clast_equation (scop_p scop,
                                   loop_iv_stack ivstack)
 {
   enum tree_code comp;
-  tree lhs = clast_to_gcc_expression (cleq->LHS, SCOP_PARAMS (scop), ivstack);
-  tree rhs = clast_to_gcc_expression (cleq->RHS, SCOP_PARAMS (scop), ivstack);
+  tree type = gcc_type_for_clast_eq (cleq, SCOP_PARAMS (scop), ivstack);
+  tree lhs = clast_to_gcc_expression (type, cleq->LHS, SCOP_PARAMS (scop), ivstack);
+  tree rhs = clast_to_gcc_expression (type, cleq->RHS, SCOP_PARAMS (scop), ivstack);
 
   if (cleq->sign == 0)
     comp = EQ_EXPR;
@@ -3356,7 +3651,7 @@ graphite_translate_clast_equation (scop_p scop,
   else
     comp = LE_EXPR;
 
-  return fold_build2 (comp, integer_type_node, lhs, rhs);
+  return fold_build2 (comp, type, lhs, rhs);
 }
 
 /* Creates the test for the condition in STMT.  */
@@ -3373,7 +3668,7 @@ graphite_create_guard_cond_expr (scop_p scop, struct clast_guard *stmt,
       tree eq = graphite_translate_clast_equation (scop, &stmt->eq[i], ivstack);
 
       if (cond)
-       cond = fold_build2 (TRUTH_AND_EXPR, integer_type_node, cond, eq);
+       cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
       else
        cond = eq;
     }
@@ -3393,6 +3688,41 @@ graphite_create_new_guard (scop_p scop, edge entry_edge,
   return exit_edge;
 }
 
+/* Walks a CLAST and returns the first statement in the body of a
+   loop.  */
+
+static struct clast_user_stmt *
+clast_get_body_of_loop (struct clast_stmt *stmt)
+{
+  if (!stmt
+      || CLAST_STMT_IS_A (stmt, stmt_user))
+    return (struct clast_user_stmt *) stmt;
+
+  if (CLAST_STMT_IS_A (stmt, stmt_for))
+    return clast_get_body_of_loop (((struct clast_for *) stmt)->body);
+
+  if (CLAST_STMT_IS_A (stmt, stmt_guard))
+    return clast_get_body_of_loop (((struct clast_guard *) stmt)->then);
+
+  if (CLAST_STMT_IS_A (stmt, stmt_block))
+    return clast_get_body_of_loop (((struct clast_block *) stmt)->body);
+
+  gcc_unreachable ();
+}
+
+/* Returns the induction variable for the loop that gets translated to
+   STMT.  */
+
+static tree
+gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for)
+{
+  struct clast_user_stmt *stmt = clast_get_body_of_loop ((struct clast_stmt *) stmt_for);
+  const char *cloog_iv = stmt_for->iterator;
+  CloogStatement *cs = stmt->statement;
+  graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
+
+  return gcc_type_for_cloog_iv (cloog_iv, gbb);
+}
 
 /* Creates a new LOOP corresponding to Cloog's STMT.  Inserts an induction 
    variable for the new LOOP.  New LOOP is attached to CFG starting at
@@ -3404,63 +3734,114 @@ graphite_create_new_loop (scop_p scop, edge entry_edge,
                          struct clast_for *stmt, loop_iv_stack ivstack,
                          loop_p outer)
 {
-  struct loop *loop;
-  tree ivvar;
-  tree stride, lowb, upb;
+  tree type = gcc_type_for_iv_of_clast_loop (stmt);
+  VEC (name_tree, heap) *params = SCOP_PARAMS (scop);
+  tree lb = clast_to_gcc_expression (type, stmt->LB, params, ivstack);
+  tree ub = clast_to_gcc_expression (type, stmt->UB, params, ivstack);
+  tree stride = gmp_cst_to_tree (type, stmt->stride);
+  tree ivvar = create_tmp_var (type, "graphiteIV");
   tree iv_before;
+  loop_p loop = create_empty_loop_on_edge
+    (entry_edge, lb, stride, ub, ivvar, &iv_before,
+     outer ? outer : entry_edge->src->loop_father);
 
-  gcc_assert (stmt->LB
-             && stmt->UB);
-
-  stride = gmp_cst_to_tree (stmt->stride);
-  lowb = clast_to_gcc_expression (stmt->LB, SCOP_PARAMS (scop), ivstack);
-  ivvar = create_tmp_var (integer_type_node, "graphiteIV");
   add_referenced_var (ivvar);
-
-  upb = clast_to_gcc_expression (stmt->UB, SCOP_PARAMS (scop), ivstack);
-  loop = create_empty_loop_on_edge (entry_edge, lowb, stride, upb, ivvar,
-                                   &iv_before, outer ? outer
-                                   : entry_edge->src->loop_father);
-
   loop_iv_stack_push_iv (ivstack, iv_before, stmt->iterator);
-
   return loop;
 }
 
-/* Remove all the edges from EDGES except the edge KEEP.  */
+/* Structure containing the mapping between the old names and the new
+   names used after block copy in the new loop context.  */
+typedef struct rename_map_elt
+{
+  tree old_name, new_name;
+} *rename_map_elt;
+
+
+/* Print to stderr the element ELT.  */
 
 static void
-remove_all_edges_1 (VEC (edge, gc) *edges, edge keep)
+debug_rename_elt (rename_map_elt elt)
 {
-  edge e;
-  edge_iterator ei;
+  fprintf (stderr, "(");
+  print_generic_expr (stderr, elt->old_name, 0);
+  fprintf (stderr, ", ");
+  print_generic_expr (stderr, elt->new_name, 0);
+  fprintf (stderr, ")\n");
+}
 
-  for (ei = ei_start (edges); (e = ei_safe_edge (ei)); )
-    {
-      if (e != keep)
-       {
-         remove_edge (e);
-         e = ei_safe_edge (ei);
-       }
-      else
-       ei_next (&ei);
-    }
+/* Helper function for debug_rename_map.  */
+
+static int
+debug_rename_map_1 (void **slot, void *s ATTRIBUTE_UNUSED)
+{
+  struct rename_map_elt *entry = (struct rename_map_elt *) *slot;
+  debug_rename_elt (entry);
+  return 1;
 }
 
-/* Remove all the edges from BB except the edge KEEP.  */
+/* Print to stderr all the elements of MAP.  */
 
-static void
-remove_all_edges (basic_block bb, edge keep)
+void
+debug_rename_map (htab_t map)
+{
+  htab_traverse (map, debug_rename_map_1, NULL);
+}
+
+/* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW.  */
+
+static inline rename_map_elt
+new_rename_map_elt (tree old_name, tree new_name)
+{
+  rename_map_elt res;
+  
+  res = XNEW (struct rename_map_elt);
+  res->old_name = old_name;
+  res->new_name = new_name;
+
+  return res;
+}
+
+/* Computes a hash function for database element ELT.  */
+
+static hashval_t
+rename_map_elt_info (const void *elt)
+{
+  return htab_hash_pointer (((const struct rename_map_elt *) elt)->old_name);
+}
+
+/* Compares database elements E1 and E2.  */
+
+static int
+eq_rename_map_elts (const void *e1, const void *e2)
 {
-  remove_all_edges_1 (bb->succs, keep);
-  remove_all_edges_1 (bb->preds, keep);
+  const struct rename_map_elt *elt1 = (const struct rename_map_elt *) e1;
+  const struct rename_map_elt *elt2 = (const struct rename_map_elt *) e2;
+
+  return (elt1->old_name == elt2->old_name);
+}
+
+/* Returns the new name associated to OLD_NAME in MAP.  */
+
+static tree
+get_new_name_from_old_name (htab_t map, tree old_name)
+{
+  struct rename_map_elt tmp;
+  PTR *slot;
+
+  tmp.old_name = old_name;
+  slot = htab_find_slot (map, &tmp, NO_INSERT);
+
+  if (slot && *slot)
+    return ((rename_map_elt) *slot)->new_name;
+
+  return old_name;
 }
 
 /* Rename the SSA_NAMEs used in STMT and that appear in IVSTACK.  */
 
 static void 
-graphite_rename_ivs_stmt (gimple stmt, graphite_bb_p gbb, scop_p scop,
-                         loop_p old, loop_iv_stack ivstack)
+rename_variables_in_stmt (gimple stmt, htab_t map)
 {
   ssa_op_iter iter;
   use_operand_p use_p;
@@ -3468,16 +3849,12 @@ graphite_rename_ivs_stmt (gimple stmt, graphite_bb_p gbb, scop_p scop,
   FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
     {
       tree use = USE_FROM_PTR (use_p);
-      tree new_iv = NULL;
-      name_tree old_iv = get_old_iv_from_ssa_name (scop, old, use);
-      
-      if (old_iv)
-       new_iv = loop_iv_stack_get_iv (ivstack,
-                                      gbb_loop_index (gbb, old_iv->loop));
+      tree new_name = get_new_name_from_old_name (map, use);
 
-      if (new_iv)
-       SET_USE (use_p, new_iv);
+      replace_exp (use_p, new_name);
     }
+
+  update_stmt (stmt);
 }
 
 /* Returns true if SSA_NAME is a parameter of SCOP.  */
@@ -3496,28 +3873,26 @@ is_parameter (scop_p scop, tree ssa_name)
   return false;
 }
 
-/* Returns true if NAME is an old induction variable in SCOP.  OLD is
-   the original loop that contained the definition of NAME.  */
+/* Returns true if NAME is an induction variable.  */
 
 static bool
-is_old_iv (scop_p scop, loop_p old, tree name)
+is_iv (tree name)
 {
-  return get_old_iv_from_ssa_name (scop, old, name) != NULL;
-
+  return gimple_code (SSA_NAME_DEF_STMT (name)) == GIMPLE_PHI;
 }
 
-static void expand_scalar_variables_stmt (gimple, graphite_bb_p, scop_p, loop_p,
-                                         loop_iv_stack);
+static void expand_scalar_variables_stmt (gimple, basic_block, scop_p,
+                                         loop_p, htab_t);
 
 /* Constructs a tree which only contains old_ivs and parameters.  Any
-   other variables that are defined outside GBB will be eliminated by
+   other variables that are defined outside BB will be eliminated by
    using their definitions in the constructed tree.  OLD_LOOP_FATHER
-   is the original loop that contained GBB.  */
+   is the original loop that contained BB.  */
 
 static tree
 expand_scalar_variables_expr (tree type, tree op0, enum tree_code code, 
-                             tree op1, graphite_bb_p gbb, scop_p scop, 
-                             loop_p old_loop_father, loop_iv_stack ivstack)
+                             tree op1, basic_block bb, scop_p scop, 
+                             loop_p old_loop_father, htab_t map)
 {
   if ((TREE_CODE_CLASS (code) == tcc_constant
        && code == INTEGER_CST)
@@ -3530,8 +3905,7 @@ expand_scalar_variables_expr (tree type, tree op0, enum tree_code code,
       enum tree_code op0_code = TREE_CODE (op0);
       tree op0_expr = 
        expand_scalar_variables_expr (op0_type, op0, op0_code,
-                                     NULL, gbb, scop, old_loop_father,
-                                     ivstack);
+                                     NULL, bb, scop, old_loop_father, map);
 
       return fold_build1 (code, type, op0_expr);
     }
@@ -3542,14 +3916,12 @@ expand_scalar_variables_expr (tree type, tree op0, enum tree_code code,
       enum tree_code op0_code = TREE_CODE (op0);
       tree op0_expr = 
        expand_scalar_variables_expr (op0_type, op0, op0_code,
-                                     NULL, gbb, scop, old_loop_father,
-                                     ivstack);
+                                     NULL, bb, scop, old_loop_father, map);
       tree op1_type = TREE_TYPE (op1);
       enum tree_code op1_code = TREE_CODE (op1);
       tree op1_expr = 
        expand_scalar_variables_expr (op1_type, op1, op1_code,
-                                     NULL, gbb, scop, old_loop_father,
-                                     ivstack);
+                                     NULL, bb, scop, old_loop_father, map);
 
       return fold_build2 (code, type, op0_expr, op1_expr);
     }
@@ -3560,34 +3932,34 @@ expand_scalar_variables_expr (tree type, tree op0, enum tree_code code,
       gimple def_stmt;
       enum tree_code subcode;
       
-      if(is_parameter (scop, op0) ||
-        is_old_iv (scop, old_loop_father, op0))
-       return op0;
+      if (is_parameter (scop, op0)
+         || is_iv (op0))
+       return get_new_name_from_old_name (map, op0);
       
       def_stmt = SSA_NAME_DEF_STMT (op0);
       
-      if (gimple_bb (def_stmt) == GBB_BB (gbb))
+      if (gimple_bb (def_stmt) == bb)
        {
          /* If the defining statement is in the basic block already
             we do not need to create a new expression for it, we
             only need to ensure its operands are expanded.  */
-         expand_scalar_variables_stmt (def_stmt, gbb, scop,
-                                       old_loop_father, ivstack);
-         return op0;
+         expand_scalar_variables_stmt (def_stmt, bb, scop,
+                                       old_loop_father, map);
+         return get_new_name_from_old_name (map, op0);
          
        }
       else
        {
-         if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
-           return op0;
+         if (gimple_code (def_stmt) != GIMPLE_ASSIGN
+             || !bb_in_scop_p (gimple_bb (def_stmt), scop))
+           return get_new_name_from_old_name (map, op0);
          
          var0 = gimple_assign_rhs1 (def_stmt);
          subcode = gimple_assign_rhs_code (def_stmt);
          var1 = gimple_assign_rhs2 (def_stmt);
          
-         return expand_scalar_variables_expr (type, var0, subcode, var1, 
-                                              gbb, scop, old_loop_father, 
-                                              ivstack);
+         return expand_scalar_variables_expr (type, var0, subcode, var1,
+                                              bb, scop, old_loop_father, map);
        }
     }
 
@@ -3596,106 +3968,96 @@ expand_scalar_variables_expr (tree type, tree op0, enum tree_code code,
 }
 
 /* Replicates any uses of non-parameters and non-old-ivs variablesthat
-   are defind outside GBB with code that is inserted in GBB.
+   are defind outside BB with code that is inserted in BB.
    OLD_LOOP_FATHER is the original loop that contained STMT.  */
  
 static void
-expand_scalar_variables_stmt (gimple stmt, graphite_bb_p gbb, scop_p scop,
-                             loop_p old_loop_father, loop_iv_stack ivstack)
+expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop,
+                             loop_p old_loop_father, htab_t map)
 {
   ssa_op_iter iter;
   use_operand_p use_p;
-  basic_block bb = GBB_BB (gbb);
 
   FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
     {
       tree use = USE_FROM_PTR (use_p);
       tree type = TREE_TYPE (use);
       enum tree_code code  = TREE_CODE (use);
-      tree use_expr = expand_scalar_variables_expr (type, use, code, NULL,
-                                                   gbb, scop, old_loop_father, 
-                                                   ivstack);
+      tree use_expr = expand_scalar_variables_expr (type, use, code, NULL, bb,
+                                                   scop, old_loop_father, map);
       if (use_expr != use)
        {
          gimple_stmt_iterator gsi = gsi_after_labels (bb);
          tree new_use =
            force_gimple_operand_gsi (&gsi, use_expr, true, NULL,
                                      true, GSI_NEW_STMT);
-         SET_USE (use_p, new_use);
+         replace_exp (use_p, new_use);
        }
     }
+
+  update_stmt (stmt);
 }
 
-/* Copies the definitions outside of GBB of variables that are not
-   induction variables nor parameters. GBB must only contain
+/* Copies the definitions outside of BB of variables that are not
+   induction variables nor parameters.  BB must only contain
    "external" references to these types of variables.  OLD_LOOP_FATHER
-   is the original loop that contained GBB.  */
+   is the original loop that contained BB.  */
 
 static void 
-expand_scalar_variables (graphite_bb_p gbb, scop_p scop, 
-                        loop_p old_loop_father, loop_iv_stack ivstack)
+expand_scalar_variables (basic_block bb, scop_p scop, 
+                        loop_p old_loop_father, htab_t map)
 {
-  basic_block bb = GBB_BB (gbb);
   gimple_stmt_iterator gsi;
   
   for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
     {
       gimple stmt = gsi_stmt (gsi);
-      expand_scalar_variables_stmt (stmt, gbb, scop, old_loop_father, 
-                                   ivstack); 
+      expand_scalar_variables_stmt (stmt, bb, scop, old_loop_father, map);
       gsi_next (&gsi);
     }
 }
 
-/* Rename all the SSA_NAMEs from block GBB that appear in IVSTACK in
-   terms of new induction variables.  OLD_LOOP_FATHER is the original
-   loop that contained GBB.  */
+/* Rename all the SSA_NAMEs from block BB according to the MAP.  */
 
 static void 
-graphite_rename_ivs (graphite_bb_p gbb, scop_p scop, loop_p old_loop_father,
-                    loop_iv_stack ivstack)
+rename_variables (basic_block bb, htab_t map)
 {
-  basic_block bb = GBB_BB (gbb);
   gimple_stmt_iterator gsi;
   
-  for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
-    {
-      gimple stmt = gsi_stmt (gsi);
+  for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+    rename_variables_in_stmt (gsi_stmt (gsi), map);
+}
 
-      if (gimple_get_lhs (stmt)
-         && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME
-         && get_old_iv_from_ssa_name (scop, old_loop_father,
-                                      gimple_get_lhs (stmt)))
-       gsi_remove (&gsi, false);
-      else
-       {
-         graphite_rename_ivs_stmt (stmt, gbb, scop, old_loop_father, ivstack); 
-         gsi_next (&gsi);
-       }
-    }
+/* Rename following the information from MAP the PHI node argument
+   corresponding to the edge E.  In order to allow several renames of
+   that argument, we match the original SSA_NAME on the argument
+   coming from the edge different than E.  */
+
+static void
+rename_variables_from_edge (edge e, gimple phi, htab_t map)
+{
+  int n = e->dest_idx == 0 ? 1 : 0;
+  tree old_name = gimple_phi_arg_def (phi, n);
+  tree new_name = get_new_name_from_old_name (map, old_name);
+
+  gcc_assert (gimple_phi_num_args (phi) == 2
+             && gimple_phi_arg_edge (phi, e->dest_idx) == e);
+
+  SET_PHI_ARG_DEF (phi, n, new_name);
 }
 
-/* Move all the PHI nodes from block FROM to block TO.
-   OLD_LOOP_FATHER is the original loop that contained FROM.  */
+/* Rename all the phi arguments for the edges comming from the scop
+   according to the MAP.  */
 
 static void
-move_phi_nodes (scop_p scop, loop_p old_loop_father, basic_block from,
-               basic_block to)
+rename_phis_end_scop (scop_p scop, htab_t map)
 {
+  basic_block after_scop = SCOP_EXIT (scop);
+  edge e = SESE_EXIT (SCOP_REGION (scop));
   gimple_stmt_iterator gsi;
 
-  for (gsi = gsi_start_phis (from); !gsi_end_p (gsi);)
-    {
-      gimple phi = gsi_stmt (gsi);
-      tree op = gimple_phi_result (phi);
-
-      if (get_old_iv_from_ssa_name (scop, old_loop_father, op) == NULL)
-       {
-         gimple new_phi = make_phi_node (op, 0);
-         add_phi_node_to_bb (new_phi, to);
-       }
-      remove_phi_node (&gsi, false);
-    }
+  for (gsi = gsi_start_phis (after_scop); !gsi_end_p (gsi); gsi_next (&gsi))
+    rename_variables_from_edge (e, gsi_stmt (gsi), map);
 }
 
 /* Remove condition from BB.  */
@@ -3728,6 +4090,132 @@ get_true_edge_from_guard_bb (basic_block bb)
   return NULL;
 }
 
+/* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag cleared.  */
+
+static edge
+get_false_edge_from_guard_bb (basic_block bb)
+{
+  edge e;
+  edge_iterator ei;
+
+  FOR_EACH_EDGE (e, ei, bb->succs)
+    if (!(e->flags & EDGE_TRUE_VALUE)) 
+      return e;
+
+  gcc_unreachable ();
+  return NULL;
+}
+
+/* Inserts in MAP a tuple (OLD_NAME, NEW_NAME) for the induction
+   variables of the loops around GBB in SCOP, i.e. GBB_LOOPS.
+   NEW_NAME is obtained from IVSTACK.  IVSTACK has the same stack
+   ordering as GBB_LOOPS.  */
+
+static void
+build_iv_mapping (loop_iv_stack ivstack, htab_t map, gbb_p gbb, scop_p scop)
+{
+  int i;
+  name_tree iv;
+  PTR *slot;
+
+  for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, iv); i++)
+    {
+      struct rename_map_elt tmp;
+
+      if (!flow_bb_inside_loop_p (iv->loop, GBB_BB (gbb)))
+       continue;
+
+      tmp.old_name = iv->t;
+      slot = htab_find_slot (map, &tmp, INSERT);
+
+      if (!*slot)
+       {
+         tree new_name = loop_iv_stack_get_iv (ivstack, 
+                                               gbb_loop_index (gbb, iv->loop));
+         *slot = new_rename_map_elt (iv->t, new_name);
+       }
+    }
+}
+
+/* Register in MAP the tuple (old_name, new_name).  */
+
+static void
+register_old_new_names (htab_t map, tree old_name, tree new_name)
+{
+  struct rename_map_elt tmp;
+  PTR *slot;
+
+  tmp.old_name = old_name;
+  slot = htab_find_slot (map, &tmp, INSERT);
+
+  if (!*slot)
+    *slot = new_rename_map_elt (old_name, new_name);
+}
+
+/* Create a duplicate of the basic block BB.  NOTE: This does not
+   preserve SSA form.  */
+
+static void
+graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb, htab_t map)
+{
+  gimple_stmt_iterator gsi, gsi_tgt;
+
+  gsi_tgt = gsi_start_bb (new_bb);
+  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+    {
+      def_operand_p def_p;
+      ssa_op_iter op_iter;
+      int region;
+      gimple stmt = gsi_stmt (gsi);
+      gimple copy;
+
+      if (gimple_code (stmt) == GIMPLE_LABEL)
+       continue;
+
+      /* Create a new copy of STMT and duplicate STMT's virtual
+        operands.  */
+      copy = gimple_copy (stmt);
+      gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
+      mark_symbols_for_renaming (copy);
+
+      region = lookup_stmt_eh_region (stmt);
+      if (region >= 0)
+       add_stmt_to_eh_region (copy, region);
+      gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);
+
+      /* Create new names for all the definitions created by COPY and
+        add replacement mappings for each new name.  */
+      FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_DEF)
+       {
+         tree old_name = DEF_FROM_PTR (def_p);
+         tree new_name = create_new_def_for (old_name, copy, def_p);
+         register_old_new_names (map, old_name, new_name);
+       }
+    }
+}
+
+/* Copies BB and includes in the copied BB all the statements that can
+   be reached following the use-def chains from the memory accesses,
+   and returns the next edge following this new block.  */
+static edge
+copy_bb_and_scalar_dependences (basic_block bb, scop_p scop,
+                               loop_p context_loop,
+                               edge next_e, htab_t map)
+{
+  basic_block new_bb = split_edge (next_e);
+
+  next_e = single_succ_edge (new_bb);
+  graphite_copy_stmts_from_block (bb, new_bb, map);
+  remove_condition (new_bb);
+  rename_variables (new_bb, map);
+  remove_phi_nodes (new_bb);
+  expand_scalar_variables (new_bb, scop, context_loop, map);
+  rename_phis_end_scop (scop, map);
+
+  return next_e;
+}
+
 /* Translates a CLAST statement STMT to GCC representation.  NEXT_E is
    the edge where new generated code should be attached.  BB_EXIT is the last
    basic block that defines the scope of code generation.  CONTEXT_LOOP is the
@@ -3745,35 +4233,23 @@ translate_clast (scop_p scop, struct loop *context_loop,
 
   if (CLAST_STMT_IS_A (stmt, stmt_user))
     {
+      htab_t map;
       CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
       graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
-      basic_block bb = gbb->bb;
-      loop_p old_loop_father = bb->loop_father;
 
-      if (bb == ENTRY_BLOCK_PTR)
+      if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
        return next_e;
 
-      remove_condition (bb);
-      expand_scalar_variables (gbb, scop, old_loop_father, ivstack);
-      remove_all_edges (bb, next_e);
-      move_phi_nodes (scop, old_loop_father, bb, next_e->src); 
-      redirect_edge_succ_nodup (next_e, bb);
-
-      if (context_loop)
-       {
-         remove_bb_from_loops (bb);
-         add_bb_to_loop (bb, context_loop);
-       }
-
-      set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src); 
-      mark_virtual_ops_in_bb (bb);
-      next_e = make_edge (bb,
-                         context_loop ? context_loop->latch : EXIT_BLOCK_PTR,
-                         EDGE_FALLTHRU);
-      loop_iv_stack_patch_for_consts (ivstack,
-                                     (struct clast_user_stmt *) stmt);
-      graphite_rename_ivs (gbb, scop, old_loop_father, ivstack);
+      map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free);
+      loop_iv_stack_patch_for_consts (ivstack, (struct clast_user_stmt *) stmt);
+      build_iv_mapping (ivstack, map, gbb, scop);
+      next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), scop,
+                                              context_loop, next_e, map);
+      htab_delete (map);
       loop_iv_stack_remove_constants (ivstack);
+      update_ssa (TODO_update_ssa);
+      recompute_all_dominators ();
+      graphite_verify ();
       return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
     }
 
@@ -3791,7 +4267,9 @@ translate_clast (scop_p scop, struct loop *context_loop,
        
       set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
       loop_iv_stack_pop (ivstack);
-
+      last_e = single_succ_edge (split_edge (last_e));
+      recompute_all_dominators ();
+      graphite_verify ();
       return translate_clast (scop, context_loop, stmt->next, last_e, ivstack);
     }
 
@@ -3804,7 +4282,7 @@ translate_clast (scop_p scop, struct loop *context_loop,
       next_e = translate_clast (scop, context_loop, 
                                ((struct clast_guard *) stmt)->then,
                                true_e, ivstack);
-      redirect_edge_succ_nodup (next_e, last_e->src);
+      graphite_verify ();
       return translate_clast (scop, context_loop, stmt->next, last_e, ivstack);
     }
 
@@ -3813,6 +4291,7 @@ translate_clast (scop_p scop, struct loop *context_loop,
       next_e = translate_clast (scop, context_loop,
                                ((struct clast_block *) stmt)->body,
                                next_e, ivstack);
+      graphite_verify ();
       return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
     }
 
@@ -4027,295 +4506,449 @@ find_transform (scop_p scop)
   return stmt;
 }
 
-/* Return a vector of all the virtual phi nodes in the current
-   function.  */
-static VEC (gimple, heap) *
-collect_virtual_phis (void)     
+/* Returns true when it is possible to generate code for this STMT.
+   For the moment we cannot generate code when Cloog decides to
+   duplicate a statement, as we do not do a copy, but a move.
+   USED_BASIC_BLOCKS records the blocks that have already been seen.
+   We return false if we have to generate code twice for the same
+   block.  */
+
+static bool 
+can_generate_code_stmt (struct clast_stmt *stmt,
+                       struct pointer_set_t *used_basic_blocks)
 {
-  gimple_stmt_iterator si;
-  gimple_vec phis = VEC_alloc (gimple, heap, 3);
-  basic_block bb;
+  if (!stmt)
+    return true;
 
-  FOR_EACH_BB (bb) 
-    for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
-      /* The phis we moved will have 0 arguments because the
-        original edges were removed.  */
-      if (gimple_phi_num_args (gsi_stmt (si)) == 0)
-       VEC_safe_push (gimple, heap, phis, gsi_stmt (si));
+  if (CLAST_STMT_IS_A (stmt, stmt_root))
+    return can_generate_code_stmt (stmt->next, used_basic_blocks);
 
-  /* Deallocate if we did not find any.  */
-  if (VEC_length (gimple, phis) == 0)
+  if (CLAST_STMT_IS_A (stmt, stmt_user))
     {
-      VEC_free (gimple, heap, phis);
-      phis = NULL;
-    }
+      CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
+      graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
 
-  return phis;
+      if (pointer_set_contains (used_basic_blocks, gbb))
+       return false;
+      pointer_set_insert (used_basic_blocks, gbb);
+      return can_generate_code_stmt (stmt->next, used_basic_blocks);
+    }
+
+  if (CLAST_STMT_IS_A (stmt, stmt_for))
+    return can_generate_code_stmt (((struct clast_for *) stmt)->body,
+                                  used_basic_blocks)
+      && can_generate_code_stmt (stmt->next, used_basic_blocks);
+
+  if (CLAST_STMT_IS_A (stmt, stmt_guard))
+    return can_generate_code_stmt (((struct clast_guard *) stmt)->then,
+                                  used_basic_blocks);
+
+  if (CLAST_STMT_IS_A (stmt, stmt_block))
+    return can_generate_code_stmt (((struct clast_block *) stmt)->body,
+                                  used_basic_blocks)
+      && can_generate_code_stmt (stmt->next, used_basic_blocks);
+
+  return false;
 }
 
-/* Find a virtual definition for variable VAR in BB.  */
+/* Returns true when it is possible to generate code for this STMT.  */
 
-static tree
-find_vdef_for_var_in_bb (basic_block bb, tree var)
+static bool 
+can_generate_code (struct clast_stmt *stmt)
 {
-  gimple_stmt_iterator gsi;
-  gimple phi;
-  def_operand_p def_var;
-  vuse_vec_p vv;
-  ssa_op_iter op_iter;
-
-  for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
-    FOR_EACH_SSA_VDEF_OPERAND (def_var, vv, gsi_stmt (gsi), op_iter)
-      if (SSA_NAME_VAR (*def_var) == var)
-       return *def_var;
-
-  for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
-    FOR_EACH_SSA_DEF_OPERAND (def_var, gsi_stmt (gsi), op_iter, SSA_OP_DEF)
-      if (SSA_NAME_VAR (*def_var) == var)
-       return *def_var;
-
-  for (gsi = gsi_start_phis (bb); !gsi_end_p(gsi); gsi_next (&gsi))
-    {
-      phi = gsi_stmt (gsi);
-      if (SSA_NAME_VAR (PHI_RESULT (phi)) == var)
-       return PHI_RESULT (phi);
-    }
+  bool result;
+  struct pointer_set_t *used_basic_blocks = pointer_set_create ();
 
-  return NULL;
+  result = can_generate_code_stmt (stmt, used_basic_blocks);
+  pointer_set_destroy (used_basic_blocks);
+  return result;
 }
 
-/* Recursive helper.  */
+/* Remove from the CFG the REGION.  */
 
-static tree
-find_vdef_for_var_1 (basic_block bb, struct pointer_set_t *visited, tree var)
+static inline void
+remove_sese_region (sese region)
 {
-  tree result = NULL;
-  edge_iterator ei;
-  edge pred_edge;
-
-  if (pointer_set_contains (visited, bb))
-    return NULL;
+  VEC (basic_block, heap) *bbs = NULL;
+  basic_block entry_bb = SESE_ENTRY (region)->dest;
+  basic_block exit_bb = SESE_EXIT (region)->dest;
+  basic_block bb;
+  int i;
 
-  pointer_set_insert (visited, bb);
-  result = find_vdef_for_var_in_bb (bb, var);
+  VEC_safe_push (basic_block, heap, bbs, entry_bb);
+  gather_blocks_in_sese_region (entry_bb, exit_bb, &bbs);
 
-  if (!result)
-    FOR_EACH_EDGE (pred_edge, ei, bb->preds)
-      if (!result)
-       result = find_vdef_for_var_1 (pred_edge->src, visited, var);
+  for (i = 0; VEC_iterate (basic_block, bbs, i, bb); i++)
+    delete_basic_block (bb);
 
-  return result;
+  VEC_free (basic_block, heap, bbs);
 }
 
-/* Finds a virtual definition for variable VAR.  */
+typedef struct ifsese {
+  sese region;
+  sese true_region;
+  sese false_region;
+} *ifsese;
 
-static tree
-find_vdef_for_var (basic_block bb, tree var)
+static inline edge
+if_region_entry (ifsese if_region)
 {
-  struct pointer_set_t *visited = pointer_set_create ();
-  tree def = find_vdef_for_var_1 (bb, visited, var);
+  return SESE_ENTRY (if_region->region);
+}
 
-  pointer_set_destroy (visited);
-  return def;
+static inline edge
+if_region_exit (ifsese if_region)
+{
+  return SESE_EXIT (if_region->region);
 }
 
-/* Update the virtual phis after loop bodies are moved to new
-   loops.  */
+static inline basic_block
+if_region_get_condition_block (ifsese if_region)
+{
+  return if_region_entry (if_region)->dest;
+}
 
-static void
-patch_phis_for_virtual_defs (void)
+static inline void
+if_region_set_false_region (ifsese if_region, sese region)
 {
-  int i;
-  gimple phi;
-  VEC (gimple, heap) *virtual_phis = collect_virtual_phis ();
-  
-  for (i = 0; VEC_iterate (gimple, virtual_phis, i, phi); i++)
+  basic_block condition = if_region_get_condition_block (if_region);
+  edge false_edge = get_false_edge_from_guard_bb (condition);
+  edge entry_region = SESE_ENTRY (region);
+  edge exit_region = SESE_EXIT (region);
+  basic_block before_region = entry_region->src;
+  basic_block last_in_region = exit_region->src;
+  void **slot = htab_find_slot_with_hash (current_loops->exits, exit_region,
+                                         htab_hash_pointer (exit_region),
+                                         NO_INSERT);
+
+  entry_region->flags = false_edge->flags;
+  false_edge->flags = exit_region->flags;
+
+  redirect_edge_pred (entry_region, condition);
+  redirect_edge_pred (exit_region, before_region);
+  redirect_edge_pred (false_edge, last_in_region);
+
+  exit_region->flags = EDGE_FALLTHRU;
+  recompute_all_dominators ();
+
+  SESE_EXIT (region) = single_succ_edge (false_edge->dest);
+  if_region->false_region = region;
+
+  if (slot)
     {
-      basic_block bb = gimple_bb (phi);
-      edge_iterator ei;
-      edge pred_edge;
-      gimple_stmt_iterator gsi;
-      gimple new_phi;
-      tree phi_result = PHI_RESULT (phi);
-      tree var = SSA_NAME_VAR (phi_result);
+      struct loop_exit *loop_exit = GGC_CNEW (struct loop_exit);
 
-      new_phi = create_phi_node (phi_result, bb);
-      SSA_NAME_DEF_STMT (phi_result) = new_phi;
+      memcpy (loop_exit, *((struct loop_exit **) slot), sizeof (struct loop_exit));
+      htab_clear_slot (current_loops->exits, slot);
 
-      FOR_EACH_EDGE (pred_edge, ei, bb->preds)
-       {
-         tree def = find_vdef_for_var (pred_edge->src, var);
+      slot = htab_find_slot_with_hash (current_loops->exits, false_edge,
+                                      htab_hash_pointer (false_edge),
+                                      INSERT);
+      loop_exit->e = false_edge;
+      *slot = loop_exit;
+      false_edge->src->loop_father->exits->next = loop_exit;
+    }
+}
 
-         if (def)
-           add_phi_arg (new_phi, def, pred_edge);
-         else
-           add_phi_arg (new_phi, gimple_default_def (cfun, var), pred_edge);
-       }
+static ifsese
+create_if_region_on_edge (edge entry, tree condition)
+{
+  edge e;
+  edge_iterator ei;
+  sese sese_region = GGC_NEW (struct sese);
+  sese true_region = GGC_NEW (struct sese);
+  sese false_region = GGC_NEW (struct sese);
+  ifsese if_region = GGC_NEW (struct ifsese);
+  edge exit = create_empty_if_region_on_edge (entry, condition);
 
-      gsi = gsi_for_stmt (phi);
-      remove_phi_node (&gsi, false);
+  if_region->region = sese_region;
+  if_region->region->entry = entry;
+  if_region->region->exit = exit;
+
+  FOR_EACH_EDGE (e, ei, entry->dest->succs)
+    {
+      if (e->flags & EDGE_TRUE_VALUE)
+       {
+         true_region->entry = e;
+         true_region->exit = single_succ_edge (e->dest);
+         if_region->true_region = true_region;
+       }
+      else if (e->flags & EDGE_FALSE_VALUE)
+       {
+         false_region->entry = e;
+         false_region->exit = single_succ_edge (e->dest);
+         if_region->false_region = false_region;
+       }
     }
 
-  VEC_free (gimple, heap, virtual_phis);
+  return if_region;
 }
 
-/* Mark the original loops of SCOP for removal, replacing their header
-   field with NULL.  */
+/* Moves REGION in a condition expression:
+   | if (1)
+   |   ;
+   | else
+   |   REGION;
+*/
 
-static void
-mark_old_loops (scop_p scop)
+static ifsese
+move_sese_in_condition (sese region)
 {
-  int i;
-  struct loop *loop;
+  basic_block pred_block = split_edge (SESE_ENTRY (region));
+  ifsese if_region = NULL;
 
-  for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++)
-    {
-      loop->header = NULL;
-      loop->latch = NULL;
-    }
+  SESE_ENTRY (region) = single_succ_edge (pred_block);
+  if_region = create_if_region_on_edge (single_pred_edge (pred_block), integer_one_node);
+  if_region_set_false_region (if_region, region);
+
+  return if_region;
+}
+
+/* Returns true when BB is in REGION.  */
+
+static bool
+bb_in_sese_p (basic_block bb, sese region)
+{
+  return pointer_set_contains (SESE_REGION_BBS (region), bb);
 }
 
-/* Scan the loops and remove the ones that have been marked for
-   removal.  */
+/* For USE in BB, if it is used outside of the REGION it is defined in,
+   mark it for rewrite.  Record basic block BB where it is used
+   to USE_BLOCKS.  Record the ssa name index to NEED_PHIS bitmap.  */
 
 static void
-remove_dead_loops (void)
+sese_find_uses_to_rename_use (sese region, basic_block bb, tree use,
+                             bitmap *use_blocks, bitmap need_phis)
 {
-  struct loop *loop, *ploop;
-  loop_iterator li;
+  unsigned ver;
+  basic_block def_bb;
 
-  FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
-    {
-      /* Remove only those loops that we marked to be removed with
-        mark_old_loops.  */
-      if (loop->header)
-       continue;
+  if (TREE_CODE (use) != SSA_NAME)
+    return;
 
-      while (loop->inner)
-       {
-         ploop = loop->inner;
-         flow_loop_tree_node_remove (ploop);
-         flow_loop_tree_node_add (loop_outer (loop), ploop);
-       }
+  ver = SSA_NAME_VERSION (use);
+  def_bb = gimple_bb (SSA_NAME_DEF_STMT (use));
+  if (!def_bb
+      || !bb_in_sese_p (def_bb, region)
+      || bb_in_sese_p (bb, region))
+    return;
 
-      /* Remove the loop and free its data.  */
-      delete_loop (loop);
-    }
+  if (!use_blocks[ver])
+    use_blocks[ver] = BITMAP_ALLOC (NULL);
+  bitmap_set_bit (use_blocks[ver], bb->index);
+
+  bitmap_set_bit (need_phis, ver);
 }
 
-/* Returns true when it is possible to generate code for this STMT.
-   For the moment we cannot generate code when Cloog decides to
-   duplicate a statement, as we do not do a copy, but a move.
-   USED_BASIC_BLOCKS records the blocks that have already been seen.
-   We return false if we have to generate code twice for the same
-   block.  */
+/* Marks names that are used in BB and outside of the loop they are
+   defined in for rewrite.  Records the set of blocks in that the ssa
+   names are defined to USE_BLOCKS.  Record the SSA names that will
+   need exit PHIs in NEED_PHIS.  */
 
-static bool 
-can_generate_code_stmt (struct clast_stmt *stmt,
-                       struct pointer_set_t *used_basic_blocks)
+static void
+sese_find_uses_to_rename_bb (sese region, basic_block bb,
+                            bitmap *use_blocks, bitmap need_phis)
 {
-  if (!stmt)
-    return true;
+  gimple_stmt_iterator bsi;
+  edge e;
+  edge_iterator ei;
+  ssa_op_iter iter;
+  tree var;
 
-  if (CLAST_STMT_IS_A (stmt, stmt_root))
-    return can_generate_code_stmt (stmt->next, used_basic_blocks);
+  FOR_EACH_EDGE (e, ei, bb->succs)
+    for (bsi = gsi_start_phis (e->dest); !gsi_end_p (bsi); gsi_next (&bsi))
+      sese_find_uses_to_rename_use (region, bb,
+                                   PHI_ARG_DEF_FROM_EDGE (gsi_stmt (bsi), e),
+                                   use_blocks, need_phis);
 
-  if (CLAST_STMT_IS_A (stmt, stmt_user))
-    {
-      CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
-      graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
+  for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+    FOR_EACH_SSA_TREE_OPERAND (var, gsi_stmt (bsi), iter, SSA_OP_ALL_USES)
+      sese_find_uses_to_rename_use (region, bb, var, use_blocks, need_phis);
+}
 
-      if (pointer_set_contains (used_basic_blocks, gbb))
-       return false;
-      pointer_set_insert (used_basic_blocks, gbb);
-      return can_generate_code_stmt (stmt->next, used_basic_blocks);
-    }
+/* Add exit phis for USE on EXIT.  */
 
-  if (CLAST_STMT_IS_A (stmt, stmt_for))
-    return can_generate_code_stmt (((struct clast_for *) stmt)->body,
-                                  used_basic_blocks)
-      && can_generate_code_stmt (stmt->next, used_basic_blocks);
+static void
+sese_add_exit_phis_edge (basic_block exit, tree use, edge false_e, edge true_e)
+{
+  gimple phi = create_phi_node (use, exit);
 
-  if (CLAST_STMT_IS_A (stmt, stmt_guard))
-    return can_generate_code_stmt (((struct clast_guard *) stmt)->then,
-                                  used_basic_blocks);
+  create_new_def_for (gimple_phi_result (phi), phi,
+                     gimple_phi_result_ptr (phi));
+  add_phi_arg (phi, use, false_e);
+  add_phi_arg (phi, use, true_e);
+}
 
-  if (CLAST_STMT_IS_A (stmt, stmt_block))
-    return can_generate_code_stmt (((struct clast_block *) stmt)->body,
-                                  used_basic_blocks)
-      && can_generate_code_stmt (stmt->next, used_basic_blocks);
+/* Add phi nodes for VAR that is used in LIVEIN.  Phi nodes are
+   inserted in block WHERE.  */
 
-  return false;
+static void
+sese_add_exit_phis_var (basic_block where, tree var, bitmap livein,
+                       edge false_e, edge true_e)
+{
+  bitmap def;
+  basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (var));
+
+  if (is_gimple_reg (var))
+    bitmap_clear_bit (livein, def_bb->index);
+  else
+    bitmap_set_bit (livein, def_bb->index);
+
+  def = BITMAP_ALLOC (NULL);
+  bitmap_set_bit (def, def_bb->index);
+  compute_global_livein (livein, def);
+  BITMAP_FREE (def);
+
+  sese_add_exit_phis_edge (where, var, false_e, true_e);
 }
 
-/* Returns true when it is possible to generate code for this STMT.  */
+/* Insert in the block WHERE phi nodes for variables defined in REGION
+   and used outside the REGION.  */
 
-static bool 
-can_generate_code (struct clast_stmt *stmt)
+static void
+rewrite_into_sese_closed_ssa (sese region, basic_block where,
+                             edge false_e, edge true_e)
 {
-  bool result;
-  struct pointer_set_t *used_basic_blocks = pointer_set_create ();
+  unsigned i;
+  basic_block bb;
+  bitmap_iterator bi;
+  bitmap names_to_rename = BITMAP_ALLOC (NULL);
+  unsigned old_num_ssa_names = num_ssa_names;
+  bitmap *use_blocks = XCNEWVEC (bitmap, old_num_ssa_names);
 
-  result = can_generate_code_stmt (stmt, used_basic_blocks);
-  pointer_set_destroy (used_basic_blocks);
-  return result;
+  update_ssa (TODO_update_ssa);
+
+  FOR_EACH_BB (bb)
+    sese_find_uses_to_rename_bb (region, bb, use_blocks, names_to_rename);
+
+  EXECUTE_IF_SET_IN_BITMAP (names_to_rename, 0, i, bi)
+    sese_add_exit_phis_var (where, ssa_name (i), use_blocks[i],
+                           false_e, true_e);
+
+  update_ssa (TODO_update_ssa);
+
+  for (i = 0; i < old_num_ssa_names; i++)
+    BITMAP_FREE (use_blocks[i]);
+
+  free (use_blocks);
+  BITMAP_FREE (names_to_rename);
 }
 
-/* Skip any definition that is a phi node with a single phi def.  */
+/* Returns the first cloog name used in EXPR.  */
 
-static tree 
-skip_phi_defs (tree ssa_name)
+static const char *
+find_cloog_iv_in_expr (struct clast_expr *expr)
 {
-  tree result = ssa_name;
-  gimple def_stmt = SSA_NAME_DEF_STMT (ssa_name);
+  struct clast_term *term = (struct clast_term *) expr;
 
-  if (gimple_code (def_stmt) == GIMPLE_PHI 
-      && gimple_phi_num_args (def_stmt) == 1)
-    result = skip_phi_defs (gimple_phi_arg(def_stmt,0)->def);
+  if (expr->type == expr_term
+      && !term->var)
+    return NULL;
 
-  return result;
+  if (expr->type == expr_term)
+    return term->var;
+
+  if (expr->type == expr_red)
+    {
+      int i;
+      struct clast_reduction *red = (struct clast_reduction *) expr;
+
+      for (i = 0; i < red->n; i++)
+       {
+         const char *res = find_cloog_iv_in_expr ((red)->elts[i]);
+
+         if (res)
+           return res;
+       }
+    }
+
+  return NULL;
 }
 
-/* Returns a VEC containing the phi-arg defs coming from SCOP_EXIT in
-   the destination block of SCOP_EXIT.  */
+/* Build for a clast_user_stmt USER_STMT a map between the CLAST
+   induction variables and the corresponding GCC old induction
+   variables.  This information is stored on each GRAPHITE_BB.  */
 
-static VEC (tree, heap) *
-collect_scop_exit_phi_args (edge scop_exit)
+static void
+compute_cloog_iv_types_1 (graphite_bb_p gbb,
+                         struct clast_user_stmt *user_stmt)
 {
-  VEC (tree, heap) *phi_args = VEC_alloc (tree, heap, 1);
-  gimple_stmt_iterator gsi;
+  struct clast_stmt *t;
+  int index = 0;
 
-  for (gsi = gsi_start_phis (scop_exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
+  for (t = user_stmt->substitutions; t; t = t->next, index++)
     {
-      gimple phi = gsi_stmt (gsi);
-      tree phi_arg = skip_phi_defs(PHI_ARG_DEF_FROM_EDGE (phi, scop_exit));
+      PTR *slot;
+      struct ivtype_map_elt tmp;
+      struct clast_expr *expr = (struct clast_expr *) 
+       ((struct clast_assignment *)t)->RHS;
 
-      VEC_safe_push (tree, heap, phi_args, phi_arg);
-    }
+      /* Create an entry (clast_var, type).  */
+      tmp.cloog_iv = find_cloog_iv_in_expr (expr);
+      if (!tmp.cloog_iv)
+       continue;
+
+      slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, INSERT);
 
-  return phi_args;
+      if (!*slot)
+       {
+         loop_p loop = gbb_loop_at_index (gbb, index);
+         tree oldiv = oldiv_for_loop (GBB_SCOP (gbb), loop);
+         tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node;
+         *slot = new_ivtype_map_elt (tmp.cloog_iv, type);
+       }
+    }
 }
 
-/* Patches (adds) PHI_ARGS to the phi nodes in SCOP_EXIT destination.  */
+/* Walk the CLAST tree starting from STMT and build for each
+   clast_user_stmt a map between the CLAST induction variables and the
+   corresponding GCC old induction variables.  This information is
+   stored on each GRAPHITE_BB.  */
 
 static void
-patch_scop_exit_phi_args (edge scop_exit,
-                         VEC (tree, heap) *phi_args)
+compute_cloog_iv_types (struct clast_stmt *stmt)
 {
-  int i = 0;
-  gimple_stmt_iterator gsi;
+  if (!stmt)
+    return;
+
+  if (CLAST_STMT_IS_A (stmt, stmt_root))
+    goto next;
 
-  for (gsi = gsi_start_phis (scop_exit->dest); !gsi_end_p (gsi);
-       gsi_next (&gsi), i++)
+  if (CLAST_STMT_IS_A (stmt, stmt_user))
     {
-      tree def = VEC_index (tree, phi_args, i);
-      gimple phi = gsi_stmt (gsi);
+      CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
+      graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
+      GBB_CLOOG_IV_TYPES (gbb) = htab_create (10, ivtype_map_elt_info,
+                                             eq_ivtype_map_elts, free);
+      compute_cloog_iv_types_1 (gbb, (struct clast_user_stmt *) stmt);
+      goto next;
+    }
 
-      gcc_assert (PHI_ARG_DEF_FROM_EDGE (phi, scop_exit) == NULL);
+  if (CLAST_STMT_IS_A (stmt, stmt_for))
+    {
+      struct clast_stmt *s = ((struct clast_for *) stmt)->body;
+      compute_cloog_iv_types (s);
+      goto next;
+    }
 
-      add_phi_arg (phi, def, scop_exit);
+  if (CLAST_STMT_IS_A (stmt, stmt_guard))
+    {
+      struct clast_stmt *s = ((struct clast_guard *) stmt)->then;
+      compute_cloog_iv_types (s);
+      goto next;
     }
+
+  if (CLAST_STMT_IS_A (stmt, stmt_block))
+    {
+      struct clast_stmt *s = ((struct clast_block *) stmt)->body;
+      compute_cloog_iv_types (s);
+      goto next;
+    }
+
+  gcc_unreachable ();
+
+ next:
+  compute_cloog_iv_types (stmt->next);
 }
 
 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
@@ -4325,14 +4958,10 @@ static void
 gloog (scop_p scop, struct clast_stmt *stmt)
 {
   edge new_scop_exit_edge = NULL;
-  basic_block scop_exit = SCOP_EXIT (scop);
-  VEC (tree, heap) *phi_args =
-    collect_scop_exit_phi_args (SESE_EXIT (SCOP_REGION (scop)));
-  VEC (iv_stack_entry_p, heap) *ivstack = 
-    VEC_alloc (iv_stack_entry_p, heap, 10);
-  edge construction_edge = SESE_ENTRY (SCOP_REGION (scop));
-  basic_block old_scop_exit_idom = get_immediate_dominator (CDI_DOMINATORS,
-                                                           scop_exit);
+  VEC (iv_stack_entry_p, heap) *ivstack = VEC_alloc (iv_stack_entry_p, heap,
+                                                    10);
+  loop_p context_loop;
+  ifsese if_region = NULL;
 
   if (!can_generate_code (stmt))
     {
@@ -4340,39 +4969,23 @@ gloog (scop_p scop, struct clast_stmt *stmt)
       return;
     }
 
-  redirect_edge_succ_nodup (construction_edge, EXIT_BLOCK_PTR);
-  new_scop_exit_edge = translate_clast (scop, 
-                                       construction_edge->src->loop_father,
-                                       stmt, construction_edge, &ivstack);
+  if_region = move_sese_in_condition (SCOP_REGION (scop));
+  rewrite_into_sese_closed_ssa (SCOP_REGION (scop),
+                               if_region->region->exit->src,
+                               if_region->false_region->exit,
+                               if_region->true_region->exit);
+  graphite_verify ();
+  context_loop = SESE_ENTRY (SCOP_REGION (scop))->src->loop_father;
+  compute_cloog_iv_types (stmt);
+  new_scop_exit_edge = translate_clast (scop, context_loop,
+                                       stmt, if_region->true_region->entry,
+                                       &ivstack);
+  graphite_verify ();
+  cleanup_tree_cfg ();
+  recompute_all_dominators ();
+  graphite_verify ();
   free_loop_iv_stack (&ivstack);
-  redirect_edge_succ (new_scop_exit_edge, scop_exit);
-
-  if (!old_scop_exit_idom
-      || !dominated_by_p (CDI_DOMINATORS, SCOP_ENTRY (scop),
-                         old_scop_exit_idom)
-      || SCOP_ENTRY (scop) == old_scop_exit_idom)
-    set_immediate_dominator (CDI_DOMINATORS,
-                            new_scop_exit_edge->dest,
-                            new_scop_exit_edge->src);
-
   cloog_clast_free (stmt);
-
-  if (new_scop_exit_edge->dest == EXIT_BLOCK_PTR)
-    new_scop_exit_edge->flags = 0;
-  delete_unreachable_blocks ();
-  patch_phis_for_virtual_defs ();
-  patch_scop_exit_phi_args (new_scop_exit_edge, phi_args);
-  VEC_free (tree, heap, phi_args);
-  mark_old_loops (scop);
-  remove_dead_loops ();
-  rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); 
-
-#ifdef ENABLE_CHECKING
-  verify_loop_structure ();
-  verify_dominators (CDI_DOMINATORS);
-  verify_ssa (false);
-#endif
 }
 
 /* Returns the number of data references in SCOP.  */
@@ -4390,104 +5003,6 @@ nb_data_refs_in_scop (scop_p scop)
   return res;
 }
 
-/* Check if a graphite bb can be ignored in graphite.  We ignore all
-   bbs, that only contain code, that will be eliminated later.
-
-   TODO: - Move PHI nodes and scalar variables out of these bbs, that only
-           remain conditions and induction variables.  */
-
-static bool
-gbb_can_be_ignored (graphite_bb_p gb)
-{
-  gimple_stmt_iterator gsi;
-  scop_p scop = GBB_SCOP (gb);
-  loop_p loop = GBB_BB (gb)->loop_father;
-
-  if (VEC_length (data_reference_p, GBB_DATA_REFS(gb)))
-    return false;
-
-  /* Check statements.  */
-  for (gsi = gsi_start_bb (GBB_BB (gb)); !gsi_end_p (gsi); gsi_next (&gsi))
-    {
-      gimple stmt = gsi_stmt (gsi);
-      switch (gimple_code (stmt))
-        {
-          /* Control flow expressions can be ignored, as they are
-             represented in the iteration domains and will be
-             regenerated by graphite.  */
-          case GIMPLE_COND:
-         case GIMPLE_GOTO:
-         case GIMPLE_SWITCH:
-            break;
-
-          /* Scalar variables can be ignored, if we can regenerate
-             them later using their scalar evolution function.
-             XXX: Just a heuristic, that needs further investigation.  */
-          case GIMPLE_ASSIGN:
-           {
-             tree var = gimple_assign_lhs (stmt);
-             var = analyze_scalar_evolution (loop, var);
-             var = instantiate_scev (block_before_scop (scop), loop, var);
-
-             if (TREE_CODE (var) == SCEV_NOT_KNOWN)
-               return false;
-
-             break;
-           }
-          /* Otherwise not ignoreable.  */
-          default:
-            return false;
-        }
-    }
-
-  return true;
-}
-
-/* Remove all ignoreable gbbs from SCOP.  */
-
-static void
-scop_remove_ignoreable_gbbs (scop_p scop)
-{
-  graphite_bb_p gb;
-  int i;
-
-  int max_schedule = scop_max_loop_depth (scop) + 1;
-  lambda_vector last_schedule = lambda_vector_new (max_schedule);
-  lambda_vector_clear (last_schedule, max_schedule);
-
-  /* Update schedules.  */
-  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
-    {
-      int nb_loops = gbb_nb_loops (gb);
-
-      if (GBB_STATIC_SCHEDULE (gb) [nb_loops] == 0)
-        last_schedule [nb_loops] = 0;
-
-      if (gbb_can_be_ignored (gb))
-        {
-          /* Mark gbb for remove.  */
-          bitmap_clear_bit (SCOP_BBS_B (scop), gb->bb->index);
-          GBB_SCOP (gb) = NULL;
-          last_schedule [nb_loops]--;
-        }
-      else
-        lambda_vector_add (GBB_STATIC_SCHEDULE (gb), last_schedule,
-                           GBB_STATIC_SCHEDULE (gb), nb_loops + 1);
-    }
-
-  /* Remove gbbs.  */
-  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
-    if (GBB_SCOP (gb) == NULL)
-      {
-        VEC_unordered_remove (graphite_bb_p, SCOP_BBS (scop), i);
-        free_graphite_bb (gb);
-        /* XXX: Hackish? But working.  */
-        i--;
-      }  
-
-  graphite_sort_gbbs (scop);
-}
-
 /* Move the loop at index LOOP and insert it before index NEW_LOOP_POS.
    This transformartion is only valid, if the loop nest between i and k is
    perfectly nested. Therefore we do not need to change the static schedule.
@@ -4963,11 +5478,6 @@ graphite_trans_loop_block (VEC (graphite_bb_p, heap) *bbs, int loops)
   /* TODO: - Calculate the stride size automatically.  */
   int stride_size = 64;
 
-  /* It makes no sense to block a single loop.  */
-  for (i = 0; VEC_iterate (graphite_bb_p, bbs, i, gb); i++)
-    if (gbb_nb_loops (gb) < 2)
-      return false;
-
   for (i = 0; VEC_iterate (graphite_bb_p, bbs, i, gb); i++)
     transform_done |= graphite_trans_bb_block (gb, stride_size, loops);
 
@@ -5050,7 +5560,7 @@ graphite_trans_scop_block (scop_p scop)
       j++;
 
       /* Found perfect loop nest.  */
-      if (perfect && last_nb_loops - j > 0)
+      if (perfect && last_nb_loops - j >= 2)
         transform_done |= graphite_trans_loop_block (bbs, last_nb_loops - j);
  
       /* Check if we start with a new loop.
@@ -5109,7 +5619,6 @@ graphite_apply_transformations (scop_p scop)
 
   /* Sort the list of bbs.  Keep them always sorted.  */
   graphite_sort_gbbs (scop);
-  scop_remove_ignoreable_gbbs (scop);
 
   if (flag_loop_block)
     transform_done = graphite_trans_scop_block (scop);
@@ -5158,13 +5667,15 @@ limit_scops (void)
       int j;
       loop_p loop;
       build_scop_bbs (scop);
-      build_scop_loop_nests (scop);
+
+      if (!build_scop_loop_nests (scop))
+       continue;
 
       for (j = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), j, loop); j++) 
         if (!loop_in_scop_p (loop_outer (loop), scop))
           {
            sd_region open_scop;
-           open_scop.entry = loop_preheader_edge (loop)->dest;
+           open_scop.entry = loop->header;
            open_scop.exit = single_exit (loop)->dest;
            VEC_safe_push (sd_region, heap, tmp_scops, &open_scop);
          }
@@ -5191,13 +5702,12 @@ graphite_transform_loops (void)
     return;
 
   current_scops = VEC_alloc (scop_p, heap, 3);
-
-  calculate_dominance_info (CDI_DOMINATORS);
-  calculate_dominance_info (CDI_POST_DOMINATORS);
+  recompute_all_dominators ();
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "Graphite loop transformations \n");
 
+  initialize_original_copy_tables ();
   cloog_initialize ();
   build_scops ();
   limit_scops ();
@@ -5209,9 +5719,12 @@ graphite_transform_loops (void)
   for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
     {
       build_scop_bbs (scop);
-      build_scop_loop_nests (scop);
+      if (!build_scop_loop_nests (scop))
+       continue;
+
       build_scop_canonical_schedules (scop);
       build_bb_loops (scop);
+      build_scop_conditions (scop);
       find_scop_parameters (scop);
       build_scop_context (scop);
 
@@ -5227,8 +5740,8 @@ graphite_transform_loops (void)
       if (!build_scop_iteration_domain (scop))
        continue;
 
-      build_scop_conditions (scop);
       build_scop_data_accesses (scop);
+      build_scop_dynamic_schedules (scop);
 
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
@@ -5238,11 +5751,19 @@ graphite_transform_loops (void)
 
       if (graphite_apply_transformations (scop))
         gloog (scop, find_transform (scop));
+#ifdef ENABLE_CHECKING
+      else
+       {
+         struct clast_stmt *stmt = find_transform (scop);
+         cloog_clast_free (stmt);
+       }
+#endif
     }
 
   /* Cleanup.  */
   free_scops (current_scops);
   cloog_finalize ();
+  free_original_copy_tables ();
 }
 
 #else /* If Cloog is not available: #ifndef HAVE_cloog.  */
index 2e2904a..92a6816 100644 (file)
@@ -18,6 +18,9 @@ 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/>.  */
 
+#ifndef GCC_GRAPHITE_H
+#define GCC_GRAPHITE_H
+
 #include "tree-data-ref.h"
 
 typedef struct graphite_bb *graphite_bb_p;
@@ -31,7 +34,7 @@ static inline int scop_nb_loops (scop_p scop);
 static inline unsigned scop_nb_params (scop_p scop);
 static inline bool scop_contains_loop (scop_p scop, struct loop *loop);
 
-struct graphite_bb
+typedef struct graphite_bb
 {
   basic_block bb;
   scop_p scop;
@@ -116,7 +119,7 @@ struct graphite_bb
    CloogMatrix *domain;
 
   /* Lists containing the restrictions of the conditional statements
-     dominating this bb. This bb can only be executed, if all conditions
+     dominating this bb.  This bb can only be executed, if all conditions
      are true.
  
      Example:
@@ -129,13 +132,13 @@ struct graphite_bb
          B
      }
  
-     So for B there is a additional condition (2i <= 8).
+     So for B there is an additional condition (2i <= 8).
  
-     TODO: Add this restrictions to the domain matrix.
+     TODO: Add these restrictions to the domain matrix.
       
-     List of COND_EXPR and SWITCH_EXPR. A COND_EXPR is true only if the 
-     corresponding element in CONDITION_CASES is not NULL_TREE. For a 
-     SWITCH_EXPR the corresponding element in CONDITION_CASES is a 
+     List of COND_EXPR and SWITCH_EXPR.  A COND_EXPR is true only if the
+     corresponding element in CONDITION_CASES is not NULL_TREE.  For a
+     SWITCH_EXPR the corresponding element in CONDITION_CASES is a
      CASE_LABEL_EXPR.  */
   VEC (gimple, heap) *conditions;
   VEC (gimple, heap) *condition_cases;
@@ -190,7 +193,8 @@ struct graphite_bb
   lambda_vector compressed_alpha_matrix;
   CloogMatrix *dynamic_schedule;
   VEC (data_reference_p, heap) *data_refs;
-};
+  htab_t cloog_iv_types;
+} *gbb_p;
 
 #define GBB_BB(GBB) GBB->bb
 #define GBB_SCOP(GBB) GBB->scop
@@ -202,6 +206,7 @@ struct graphite_bb
 #define GBB_CONDITIONS(GBB) GBB->conditions
 #define GBB_CONDITION_CASES(GBB) GBB->condition_cases
 #define GBB_LOOPS(GBB) GBB->loops
+#define GBB_CLOOG_IV_TYPES(GBB) GBB->cloog_iv_types
 
 /* Return the loop that contains the basic block GBB.  */
 
@@ -234,7 +239,7 @@ gbb_loop_at_index (graphite_bb_p gb, int index)
   return VEC_index (loop_p, GBB_LOOPS (gb), index);
 }
 
-/* Returns the corresponding loop iterator index for a gimple loop.  */
+/* Returns the index of LOOP in the loop nest around GB.  */
 
 static inline int
 gbb_loop_index (graphite_bb_p gb, loop_p loop)
@@ -271,10 +276,12 @@ DEF_VEC_ALLOC_P (name_tree, heap);
 typedef struct sese
 {
   edge entry, exit;
+  struct pointer_set_t *region_basic_blocks;
 } *sese;
 
 #define SESE_ENTRY(S) (S->entry)
 #define SESE_EXIT(S) (S->exit)
+#define SESE_REGION_BBS(S) (S->region_basic_blocks)
 
 /* A SCOP is a Static Control Part of the program, simple enough to be
    represented in polyhedral form.  */
@@ -305,8 +312,13 @@ struct scop
   /* ???  It looks like a global mapping loop_id -> cloog_loop would work.  */
   htab_t loop2cloog_loop;
 
-  /* CLooG representation of this SCOP.  */
+  /* Cloog representation of this scop.  */
   CloogProgram *program;
+
+  /* Are we allowed to add more params?  This is for debugging purpose.  We
+     can only add new params before generating the bb domains, otherwise they
+     become invalid.  */
+  bool add_params;
 };
 
 #define SCOP_BBS(S) S->bbs
@@ -319,9 +331,11 @@ struct scop
    but just a boundary.  SCOP_ENTRY is considered part of the scop.  */
 #define SCOP_ENTRY(S) (SESE_ENTRY (SCOP_REGION (S))->dest)
 #define SCOP_EXIT(S) (SESE_EXIT (SCOP_REGION (S))->dest)
+#define SCOP_REGION_BBS(S) (SESE_REGION_BBS (SCOP_REGION (S)))
 #define SCOP_STATIC_SCHEDULE(S) S->static_schedule
 #define SCOP_LOOPS(S) S->loops
 #define SCOP_LOOP_NEST(S) S->loop_nest
+#define SCOP_ADD_PARAMS(S) S->add_params
 #define SCOP_PARAMS(S) S->params
 #define SCOP_OLDIVS(S) S->old_ivs
 #define SCOP_PROG(S) S->program
@@ -335,9 +349,9 @@ extern void debug_gbb (graphite_bb_p, int);
 extern void dot_scop (scop_p);
 extern void dot_all_scops (void);
 extern void debug_clast_stmt (struct clast_stmt *);
-
-
-extern void debug_loop_vec (graphite_bb_p gb);
+extern void debug_rename_map (htab_t);
+extern void debug_ivtype_map (htab_t);
+extern void debug_loop_vec (graphite_bb_p);
 extern void debug_oldivs (scop_p);
 
 /* Describes the type of an iv stack entry.  */
@@ -369,6 +383,24 @@ DEF_VEC_ALLOC_P(iv_stack_entry_p,heap);
 typedef VEC(iv_stack_entry_p, heap) **loop_iv_stack;
 extern void debug_loop_iv_stack (loop_iv_stack);
 
+/* Return the old induction variable of the LOOP that is in normal
+   form in SCOP.  */
+
+static inline tree
+oldiv_for_loop (scop_p scop, loop_p loop)
+{
+  int i;
+  name_tree iv;
+
+  if (!loop)
+    return NULL_TREE;
+
+  for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, iv); i++)
+    if (iv->loop == loop)
+      return iv->t;
+
+  return NULL_TREE;
+}
 
 /* Return the number of gimple loops contained in SCOP.  */
 
@@ -422,15 +454,6 @@ loop_domain_dim (unsigned int loop_num, scop_p scop)
   return cloog_domain_dim (cloog_loop_domain (slot->cloog_loop)) + 2;
 }
 
-/* Returns the dimensionality of an enclosing loop iteration domain
-   with respect to enclosing SCoP for a given data reference REF.  */
-
-static inline int
-ref_nb_loops (data_reference_p ref)
-{
-  return loop_domain_dim (loop_containing_stmt (DR_STMT (ref))->num, DR_SCOP (ref));
-}
-
 /* Returns the dimensionality of a loop iteration vector in a loop
    iteration domain for a given loop (identified by LOOP_NUM) with
    respect to SCOP.  */
@@ -521,22 +544,59 @@ scop_gimple_loop_depth (scop_p scop, loop_p loop)
   return depth;
 }
 
-/* Associate a POLYHEDRON dependence description to two data
-   references A and B.  */
-struct data_dependence_polyhedron
+/* Static inline function prototypes.  */
+
+static inline unsigned scop_nb_params (scop_p scop);
+
+/* Returns true when BB is in SCOP.  */
+
+static inline bool
+bb_in_scop_p (basic_block bb, scop_p scop)
+{
+  return bitmap_bit_p (SCOP_BBS_B (scop), bb->index);
+}
+
+/* Returns true when LOOP is in SCOP.  */
+
+static inline bool 
+loop_in_scop_p (struct loop *loop, scop_p scop)
 {
-  struct data_reference *a;
-  struct data_reference *b;
-  bool reversed_p;
-  bool loop_carried; /*TODO:konrad get rid of this, make level signed */
-  signed level;
-  CloogDomain *polyhedron;  
-};
+  return (bb_in_scop_p (loop->header, scop)
+         && bb_in_scop_p (loop->latch, scop));
+}
+
+/* Calculate the number of loops around LOOP in the SCOP.  */
+
+static inline int
+nb_loops_around_loop_in_scop (struct loop *l, scop_p scop)
+{
+  int d = 0;
+
+  for (; loop_in_scop_p (l, scop); d++, l = loop_outer (l));
 
-#define RDGE_DDP(E)   ((struct data_dependence_polyhedron*) ((E)->data))
+  return d;
+}
+
+/* Calculate the number of loops around GB in the current SCOP.  */
+
+static inline int
+nb_loops_around_gb (graphite_bb_p gb)
+{
+  return nb_loops_around_loop_in_scop (gbb_loop (gb), GBB_SCOP (gb));
+}
 
-typedef struct data_dependence_polyhedron *ddp_p;
+/* Returns the dimensionality of an enclosing loop iteration domain
+   with respect to enclosing SCoP for a given data reference REF.  The
+   returned dimensionality is homogeneous (depth of loop nest + number
+   of SCoP parameters + const).  */
+
+static inline int
+ref_nb_loops (data_reference_p ref)
+{
+  loop_p loop = loop_containing_stmt (DR_STMT (ref));
+  scop_p scop = DR_SCOP (ref);
 
-DEF_VEC_P(ddp_p);
-DEF_VEC_ALLOC_P(ddp_p,heap);
+  return nb_loops_around_loop_in_scop (loop, scop) + scop_nb_params (scop) + 2;
+}
 
+#endif  /* GCC_GRAPHITE_H  */
index 662cff6..35ec9a6 100644 (file)
@@ -1528,6 +1528,7 @@ cgraph_early_inlining (void)
       todo = optimize_inline_calls (current_function_decl);
       timevar_pop (TV_INTEGRATION);
     }
+  cfun->always_inline_functions_inlined = true;
   return todo;
 }
 
index b10aa46..9e47333 100644 (file)
@@ -1583,8 +1583,8 @@ propagate_allocno_info (void)
   ira_loop_tree_node_t parent;
   enum reg_class cover_class;
 
-  if (flag_ira_algorithm != IRA_ALGORITHM_REGIONAL
-      && flag_ira_algorithm != IRA_ALGORITHM_MIXED)
+  if (flag_ira_region != IRA_REGION_ALL
+      && flag_ira_region != IRA_REGION_MIXED)
     return;
   for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
     for (a = ira_regno_allocno_map[i];
@@ -2116,9 +2116,10 @@ setup_min_max_allocno_live_range_point (void)
 }
 
 /* Sort allocnos according to their live ranges.  Allocnos with
-   smaller cover class are put first.  Allocnos with the same cove
-   class are ordered according their start (min).  Allocnos with the
-   same start are ordered according their finish (max).  */
+   smaller cover class are put first unless we use priority coloring.
+   Allocnos with the same cove class are ordered according their start
+   (min).  Allocnos with the same start are ordered according their
+   finish (max).  */
 static int
 allocno_range_compare_func (const void *v1p, const void *v2p)
 {
@@ -2126,7 +2127,8 @@ allocno_range_compare_func (const void *v1p, const void *v2p)
   ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
   ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
 
-  if ((diff = ALLOCNO_COVER_CLASS (a1) - ALLOCNO_COVER_CLASS (a2)) != 0)
+  if (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY
+      && (diff = ALLOCNO_COVER_CLASS (a1) - ALLOCNO_COVER_CLASS (a2)) != 0)
     return diff;
   if ((diff = ALLOCNO_MIN (a1) - ALLOCNO_MIN (a2)) != 0)
     return diff;
@@ -2161,7 +2163,7 @@ sort_conflict_id_allocno_map (void)
 static void
 setup_min_max_conflict_allocno_ids (void)
 {
-  enum reg_class cover_class;
+  int cover_class;
   int i, j, min, max, start, finish, first_not_finished, filled_area_start;
   int *live_range_min, *last_lived;
   ira_allocno_t a;
@@ -2174,7 +2176,9 @@ setup_min_max_conflict_allocno_ids (void)
       a = ira_conflict_id_allocno_map[i];
       if (a == NULL)
        continue;
-      if (cover_class != ALLOCNO_COVER_CLASS (a))
+      if (cover_class < 0
+         || (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY
+             && cover_class != (int) ALLOCNO_COVER_CLASS (a)))
        {
          cover_class = ALLOCNO_COVER_CLASS (a);
          min = i;
@@ -2208,7 +2212,9 @@ setup_min_max_conflict_allocno_ids (void)
       a = ira_conflict_id_allocno_map[i];
       if (a == NULL)
        continue;
-      if (cover_class != ALLOCNO_COVER_CLASS (a))
+      if (cover_class < 0
+         || (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY
+             && cover_class != (int) ALLOCNO_COVER_CLASS (a)))
        {
          cover_class = ALLOCNO_COVER_CLASS (a);
          for (j = 0; j < ira_max_point; j++)
@@ -2503,7 +2509,8 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
                {
                  ira_allocno_t live_a = ira_allocnos[n];
 
-                 if (cover_class == ALLOCNO_COVER_CLASS (live_a)
+                 if (ira_reg_classes_intersect_p
+                     [cover_class][ALLOCNO_COVER_CLASS (live_a)]
                      /* Don't set up conflict for the allocno with itself.  */
                      && num != (int) n)
                    ira_add_allocno_conflict (a, live_a);
index 4b99091..c9cb184 100644 (file)
@@ -279,7 +279,8 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p)
          else
            gcc_unreachable ();
 
-         if (cover_class != ALLOCNO_COVER_CLASS (another_allocno)
+         cover_class = ALLOCNO_COVER_CLASS (another_allocno);
+         if (! ira_reg_classes_intersect_p[rclass][cover_class]
              || ALLOCNO_ASSIGNED_P (another_allocno))
            continue;
 
@@ -301,6 +302,8 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p)
            (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
             cover_class, 0,
             ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
+         i = ira_class_hard_reg_index[cover_class][hard_regno];
+         ira_assert (i >= 0);
          ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno)[i] += update_cost;
          ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno)[i]
            += update_cost;
@@ -311,17 +314,19 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p)
   while (get_next_update_cost (&allocno, &divisor));
 }
 
-/* This function updates COSTS (decrease if DECR_P) by conflict costs
-   of the unassigned allocnos connected by copies with allocnos in
-   update_cost_queue.  This update increases chances to remove some
-   copies.  */
+/* This function updates COSTS (decrease if DECR_P) for hard_registers
+   of COVER_CLASS by conflict costs of the unassigned allocnos
+   connected by copies with allocnos in update_cost_queue.  This
+   update increases chances to remove some copies.  */
 static void
-update_conflict_hard_regno_costs (int *costs, bool decr_p)
+update_conflict_hard_regno_costs (int *costs, enum reg_class cover_class,
+                                 bool decr_p)
 {
   int i, cost, class_size, freq, mult, div, divisor;
+  int index, hard_regno;
   int *conflict_costs;
   bool cont_p;
-  enum reg_class cover_class;
+  enum reg_class another_cover_class;
   ira_allocno_t allocno, another_allocno;
   ira_copy_t cp, next_cp;
 
@@ -340,16 +345,17 @@ update_conflict_hard_regno_costs (int *costs, bool decr_p)
          }
        else
          gcc_unreachable ();
-       cover_class = ALLOCNO_COVER_CLASS (allocno);
-       if (cover_class != ALLOCNO_COVER_CLASS (another_allocno)
+       another_cover_class = ALLOCNO_COVER_CLASS (another_allocno);
+       if (! ira_reg_classes_intersect_p[cover_class][another_cover_class]
            || ALLOCNO_ASSIGNED_P (another_allocno)
            || ALLOCNO_MAY_BE_SPILLED_P (ALLOCNO_FIRST_COALESCED_ALLOCNO
                                         (another_allocno)))
          continue;
-       class_size = ira_class_hard_regs_num[cover_class];
+       class_size = ira_class_hard_regs_num[another_cover_class];
        ira_allocate_and_copy_costs
          (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
-          cover_class, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
+          another_cover_class,
+          ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
        conflict_costs
          = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
        if (conflict_costs == NULL)
@@ -364,13 +370,18 @@ update_conflict_hard_regno_costs (int *costs, bool decr_p)
            cont_p = false;
            for (i = class_size - 1; i >= 0; i--)
              {
+               hard_regno = ira_class_hard_regs[another_cover_class][i];
+               ira_assert (hard_regno >= 0);
+               index = ira_class_hard_reg_index[cover_class][hard_regno];
+               if (index < 0)
+                 continue;
                cost = conflict_costs [i] * mult / div;
                if (cost == 0)
                  continue;
                cont_p = true;
                if (decr_p)
                  cost = -cost;
-               costs[i] += cost;
+               costs[index] += cost;
              }
          }
        /* Probably 5 hops will be enough.  */
@@ -429,11 +440,11 @@ static bool
 assign_hard_reg (ira_allocno_t allocno, bool retry_p)
 {
   HARD_REG_SET conflicting_regs;
-  int i, j, hard_regno, best_hard_regno, class_size;
+  int i, j, k, hard_regno, best_hard_regno, class_size;
   int cost, mem_cost, min_cost, full_cost, min_full_cost, add_cost;
   int *a_costs;
   int *conflict_costs;
-  enum reg_class cover_class, rclass;
+  enum reg_class cover_class, rclass, conflict_cover_class;
   enum machine_mode mode;
   ira_allocno_t a, conflict_allocno;
   ira_allocno_conflict_iterator aci;
@@ -490,7 +501,9 @@ assign_hard_reg (ira_allocno_t allocno, bool retry_p)
        if (retry_p || bitmap_bit_p (consideration_allocno_bitmap,
                                     ALLOCNO_NUM (conflict_allocno)))
          {
-           ira_assert (cover_class == ALLOCNO_COVER_CLASS (conflict_allocno));
+           conflict_cover_class = ALLOCNO_COVER_CLASS (conflict_allocno);
+           ira_assert (ira_reg_classes_intersect_p
+                       [cover_class][conflict_cover_class]);
            if (allocno_coalesced_p)
              {
                if (bitmap_bit_p (processed_coalesced_allocno_bitmap,
@@ -501,7 +514,8 @@ assign_hard_reg (ira_allocno_t allocno, bool retry_p)
              }
            if (ALLOCNO_ASSIGNED_P (conflict_allocno))
              {
-               if ((hard_regno = ALLOCNO_HARD_REGNO (conflict_allocno)) >= 0)
+               if ((hard_regno = ALLOCNO_HARD_REGNO (conflict_allocno)) >= 0
+                   && ira_class_hard_reg_index[cover_class][hard_regno] >= 0)
                  {
                    IOR_HARD_REG_SET
                      (conflicting_regs,
@@ -511,20 +525,27 @@ assign_hard_reg (ira_allocno_t allocno, bool retry_p)
                                               conflicting_regs))
                      goto fail;
                  }
-               continue;
              }
            else if (! ALLOCNO_MAY_BE_SPILLED_P (ALLOCNO_FIRST_COALESCED_ALLOCNO
                                                 (conflict_allocno)))
              {
                ira_allocate_and_copy_costs
                  (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_allocno),
-                  cover_class,
+                  conflict_cover_class,
                   ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_allocno));
                conflict_costs
                  = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_allocno);
                if (conflict_costs != NULL)
                  for (j = class_size - 1; j >= 0; j--)
-                   full_costs[j] -= conflict_costs[j];
+                   {
+                     hard_regno = ira_class_hard_regs[cover_class][j];
+                     ira_assert (hard_regno >= 0);
+                     k = (ira_class_hard_reg_index
+                          [conflict_cover_class][hard_regno]);
+                     if (k < 0)
+                       continue;
+                     full_costs[j] -= conflict_costs[k];
+                   }
                queue_update_cost (conflict_allocno, COST_HOP_DIVISOR);
              }
          }
@@ -533,7 +554,7 @@ assign_hard_reg (ira_allocno_t allocno, bool retry_p)
     }
   /* Take into account preferences of allocnos connected by copies to
      the conflict allocnos.  */
-  update_conflict_hard_regno_costs (full_costs, true);
+  update_conflict_hard_regno_costs (full_costs, cover_class, true);
 
   /* Take preferences of allocnos connected by copies into
      account.  */
@@ -545,7 +566,7 @@ assign_hard_reg (ira_allocno_t allocno, bool retry_p)
       if (a == allocno)
        break;
     }
-  update_conflict_hard_regno_costs (full_costs, false);
+  update_conflict_hard_regno_costs (full_costs, cover_class, false);
   min_cost = min_full_cost = INT_MAX;
   /* We don't care about giving callee saved registers to allocnos no
      living through calls because call clobbered registers are
@@ -594,7 +615,8 @@ assign_hard_reg (ira_allocno_t allocno, bool retry_p)
       best_hard_regno = -1;
     }
  fail:
-  if (best_hard_regno < 0
+  if (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY
+      && best_hard_regno < 0
       && ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno) != allocno)
     {
       for (j = 0, a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
@@ -1605,6 +1627,10 @@ coalesce_allocnos (bool reload_p)
            {
              next_cp = cp->next_first_allocno_copy;
              regno = ALLOCNO_REGNO (cp->second);
+             /* For priority coloring we coalesce allocnos only with
+                the same cover class not with intersected cover
+                classes as it were possible.  It is done for
+                simplicity.  */
              if ((reload_p
                   || (ALLOCNO_COVER_CLASS (cp->second) == cover_class
                       && ALLOCNO_MODE (cp->second) == mode))
@@ -1659,12 +1685,72 @@ coalesce_allocnos (bool reload_p)
   ira_free (sorted_copies);
 }
 
+/* Map: allocno number -> allocno priority.  */
+static int *allocno_priorities;
+
+/* Set up priorities for N allocnos in array
+   CONSIDERATION_ALLOCNOS.  */
+static void
+setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
+{
+  int i, length, nrefs, priority, max_priority, mult;
+  ira_allocno_t a;
+
+  max_priority = 0;
+  for (i = 0; i < n; i++)
+    {
+      a = consideration_allocnos[i];
+      nrefs = ALLOCNO_NREFS (a);
+      ira_assert (nrefs >= 0);
+      mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
+      ira_assert (mult >= 0);
+      allocno_priorities[ALLOCNO_NUM (a)]
+       = priority
+       = (mult
+          * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_COVER_CLASS_COST (a))
+          * ira_reg_class_nregs[ALLOCNO_COVER_CLASS (a)][ALLOCNO_MODE (a)]);
+      if (priority < 0)
+       priority = -priority;
+      if (max_priority < priority)
+       max_priority = priority;
+    }
+  mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
+  for (i = 0; i < n; i++)
+    {
+      a = consideration_allocnos[i];
+      length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
+      if (length <= 0)
+       length = 1;
+      allocno_priorities[ALLOCNO_NUM (a)]
+       = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
+    }
+}
+
+/* Sort allocnos according to their priorities which are calculated
+   analogous to ones in file `global.c'.  */
+static int
+allocno_priority_compare_func (const void *v1p, const void *v2p)
+{
+  ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
+  ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
+  int pri1, pri2;
+
+  pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
+  pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
+  if (pri2 - pri1)
+    return pri2 - pri1;
+
+  /* If regs are equally good, sort by allocnos, so that the results of
+     qsort leave nothing to chance.  */
+  return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
+}
+
 /* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
    taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP.  */
 static void
 color_allocnos (void)
 {
-  unsigned int i;
+  unsigned int i, n;
   bitmap_iterator bi;
   ira_allocno_t a;
 
@@ -1672,30 +1758,83 @@ color_allocnos (void)
   processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
   if (flag_ira_coalesce)
     coalesce_allocnos (false);
-  /* Put the allocnos into the corresponding buckets.  */
-  colorable_allocno_bucket = NULL;
-  uncolorable_allocno_bucket = NULL;
-  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
+  if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
     {
-      a = ira_allocnos[i];
-      if (ALLOCNO_COVER_CLASS (a) == NO_REGS)
+      n = 0;
+      EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
        {
-         ALLOCNO_HARD_REGNO (a) = -1;
-         ALLOCNO_ASSIGNED_P (a) = true;
-         ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
-         ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
-         if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
+         a = ira_allocnos[i];
+         if (ALLOCNO_COVER_CLASS (a) == NO_REGS)
            {
-             fprintf (ira_dump_file, "      Spill");
-             print_coalesced_allocno (a);
-             fprintf (ira_dump_file, "\n");
+             ALLOCNO_HARD_REGNO (a) = -1;
+             ALLOCNO_ASSIGNED_P (a) = true;
+             ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
+             ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
+             if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
+               {
+                 fprintf (ira_dump_file, "      Spill");
+                 print_coalesced_allocno (a);
+                 fprintf (ira_dump_file, "\n");
+               }
+             continue;
            }
-         continue;
+         sorted_allocnos[n++] = a;
        }
-      put_allocno_into_bucket (a);
+      if (n != 0)
+       {
+         setup_allocno_priorities (sorted_allocnos, n);
+         qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
+                allocno_priority_compare_func);
+         for (i = 0; i < n; i++)
+           {
+             a = sorted_allocnos[i];
+             if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
+               {
+                 fprintf (ira_dump_file, "      ");
+                 print_coalesced_allocno (a);
+                 fprintf (ira_dump_file, "  -- ");
+               }
+             if (assign_hard_reg (a, false))
+               {
+                 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
+                   fprintf (ira_dump_file, "assign hard reg %d\n",
+                            ALLOCNO_HARD_REGNO (a));
+               }
+             else
+               {
+                 if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
+                   fprintf (ira_dump_file, "assign memory\n");
+               }
+           }
+       }
+    }
+  else
+    {
+      /* Put the allocnos into the corresponding buckets.  */
+      colorable_allocno_bucket = NULL;
+      uncolorable_allocno_bucket = NULL;
+      EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
+       {
+         a = ira_allocnos[i];
+         if (ALLOCNO_COVER_CLASS (a) == NO_REGS)
+           {
+             ALLOCNO_HARD_REGNO (a) = -1;
+             ALLOCNO_ASSIGNED_P (a) = true;
+             ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
+             ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
+             if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
+               {
+                 fprintf (ira_dump_file, "      Spill");
+                 print_coalesced_allocno (a);
+                 fprintf (ira_dump_file, "\n");
+               }
+             continue;
+           }
+         put_allocno_into_bucket (a);
+       }
+      push_allocnos_to_stack ();
+      pop_allocnos_from_stack ();
     }
-  push_allocnos_to_stack ();
-  pop_allocnos_from_stack ();
   if (flag_ira_coalesce)
     /* We don't need coalesced allocnos for ira_reassign_pseudos.  */
     EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
@@ -1796,8 +1935,8 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
   /* Color all mentioned allocnos including transparent ones.  */
   color_allocnos ();
   /* Process caps.  They are processed just once.  */
-  if (flag_ira_algorithm == IRA_ALGORITHM_MIXED
-      || flag_ira_algorithm == IRA_ALGORITHM_REGIONAL)
+  if (flag_ira_region == IRA_REGION_MIXED
+      || flag_ira_region == IRA_REGION_ALL)
     EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
       {
        a = ira_allocnos[j];
@@ -1806,9 +1945,9 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
        /* Remove from processing in the next loop.  */
        bitmap_clear_bit (consideration_allocno_bitmap, j);
        rclass = ALLOCNO_COVER_CLASS (a);
-       if ((flag_ira_algorithm == IRA_ALGORITHM_MIXED
-            && loop_tree_node->reg_pressure[rclass]
-            <= ira_available_class_regs[rclass]))
+       if (flag_ira_region == IRA_REGION_MIXED
+           && (loop_tree_node->reg_pressure[rclass]
+               <= ira_available_class_regs[rclass]))
          {
            mode = ALLOCNO_MODE (a);
            hard_regno = ALLOCNO_HARD_REGNO (a);
@@ -1843,6 +1982,7 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
          mode = ALLOCNO_MODE (a);
          rclass = ALLOCNO_COVER_CLASS (a);
          hard_regno = ALLOCNO_HARD_REGNO (a);
+         /* Use hard register class here.  ??? */
          if (hard_regno >= 0)
            {
              index = ira_class_hard_reg_index[rclass][hard_regno];
@@ -1854,9 +1994,10 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
          if (subloop_allocno == NULL
              || ALLOCNO_CAP (subloop_allocno) != NULL)
            continue;
+         ira_assert (ALLOCNO_COVER_CLASS (subloop_allocno) == rclass);
          ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
                                    ALLOCNO_NUM (subloop_allocno)));
-         if (flag_ira_algorithm == IRA_ALGORITHM_MIXED
+         if ((flag_ira_region == IRA_REGION_MIXED)
              && (loop_tree_node->reg_pressure[rclass]
                  <= ira_available_class_regs[rclass]))
            {
@@ -2002,6 +2143,7 @@ move_spill_restore (void)
              subloop_allocno = subloop_node->regno_allocno_map[regno];
              if (subloop_allocno == NULL)
                continue;
+             ira_assert (rclass == ALLOCNO_COVER_CLASS (subloop_allocno));
              /* We have accumulated cost.  To get the real cost of
                 allocno usage in the loop we should subtract costs of
                 the subloop allocnos.  */
@@ -2027,6 +2169,7 @@ move_spill_restore (void)
          if ((parent = loop_node->parent) != NULL
              && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
            {
+             ira_assert (rclass == ALLOCNO_COVER_CLASS (parent_allocno));
              exit_freq = ira_loop_edge_freq (loop_node, regno, true);
              enter_freq = ira_loop_edge_freq (loop_node, regno, false);
              if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
@@ -2094,13 +2237,15 @@ update_curr_costs (ira_allocno_t a)
        }
       else
        gcc_unreachable ();
-      if (cover_class != ALLOCNO_COVER_CLASS (another_a)
+      if (! ira_reg_classes_intersect_p[cover_class][ALLOCNO_COVER_CLASS
+                                                    (another_a)]
          || ! ALLOCNO_ASSIGNED_P (another_a)
          || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
        continue;
       rclass = REGNO_REG_CLASS (hard_regno);
       i = ira_class_hard_reg_index[cover_class][hard_regno];
-      ira_assert (i >= 0);
+      if (i < 0)
+       continue;
       cost = (cp->first == a
              ? ira_register_move_cost[mode][rclass][cover_class]
              : ira_register_move_cost[mode][cover_class][rclass]);
@@ -2116,66 +2261,6 @@ update_curr_costs (ira_allocno_t a)
     }
 }
 
-/* Map: allocno number -> allocno priority.  */
-static int *allocno_priorities;
-
-/* Set up priorities for N allocnos in array
-   CONSIDERATION_ALLOCNOS.  */
-static void
-setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
-{
-  int i, length, nrefs, priority, max_priority, mult;
-  ira_allocno_t a;
-
-  max_priority = 0;
-  for (i = 0; i < n; i++)
-    {
-      a = consideration_allocnos[i];
-      nrefs = ALLOCNO_NREFS (a);
-      ira_assert (nrefs >= 0);
-      mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
-      ira_assert (mult >= 0);
-      allocno_priorities[ALLOCNO_NUM (a)]
-       = priority
-       = (mult
-          * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_COVER_CLASS_COST (a))
-          * ira_reg_class_nregs[ALLOCNO_COVER_CLASS (a)][ALLOCNO_MODE (a)]);
-      if (priority < 0)
-       priority = -priority;
-      if (max_priority < priority)
-       max_priority = priority;
-    }
-  mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
-  for (i = 0; i < n; i++)
-    {
-      a = consideration_allocnos[i];
-      length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
-      if (length <= 0)
-       length = 1;
-      allocno_priorities[ALLOCNO_NUM (a)]
-       = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
-    }
-}
-
-/* Sort allocnos according to their priorities which are calculated
-   analogous to ones in file `global.c'.  */
-static int
-allocno_priority_compare_func (const void *v1p, const void *v2p)
-{
-  ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
-  ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
-  int pri1, pri2;
-
-  pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
-  pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
-  if (pri2 - pri1)
-    return pri2 - pri1;
-
-  /* If regs are equally good, sort by allocnos, so that the results of
-     qsort leave nothing to chance.  */
-  return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
-}
-
 /* Try to assign hard registers to the unassigned allocnos and
    allocnos conflicting with them or conflicting with allocnos whose
    regno >= START_REGNO.  The function is called after ira_flattening,
@@ -2215,7 +2300,8 @@ ira_reassign_conflict_allocnos (int start_regno)
        continue;
       FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci)
        {
-         ira_assert (cover_class == ALLOCNO_COVER_CLASS (conflict_a));
+         ira_assert (ira_reg_classes_intersect_p
+                     [cover_class][ALLOCNO_COVER_CLASS (conflict_a)]);
          if (bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
            continue;
          bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a));
index 6e7d769..ff116b5 100644 (file)
@@ -114,7 +114,8 @@ build_conflict_bit_table (void)
          EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, j)
            {
              live_a = ira_allocnos[j];
-             if (cover_class == ALLOCNO_COVER_CLASS (live_a)
+             if (ira_reg_classes_intersect_p
+                 [cover_class][ALLOCNO_COVER_CLASS (live_a)]
                  /* Don't set up conflict for the allocno with itself.  */
                  && num != (int) j)
                {
@@ -555,8 +556,8 @@ build_allocno_conflicts (ira_allocno_t a)
                           ALLOCNO_MIN (a), ALLOCNO_MAX (a), i, asi)
     {
       another_a = ira_conflict_id_allocno_map[i];
-      ira_assert (ALLOCNO_COVER_CLASS (a)
-                 == ALLOCNO_COVER_CLASS (another_a));
+      ira_assert (ira_reg_classes_intersect_p
+                 [ALLOCNO_COVER_CLASS (a)][ALLOCNO_COVER_CLASS (another_a)]);
       collected_conflict_allocnos[px++] = another_a;
     }
   if (ira_conflict_vector_profitable_p (a, px))
@@ -592,8 +593,8 @@ build_allocno_conflicts (ira_allocno_t a)
                           ALLOCNO_MIN (a), ALLOCNO_MAX (a), i, asi)
     {
       another_a = ira_conflict_id_allocno_map[i];
-      ira_assert (ALLOCNO_COVER_CLASS (a)
-                 == ALLOCNO_COVER_CLASS (another_a));
+      ira_assert (ira_reg_classes_intersect_p
+                 [ALLOCNO_COVER_CLASS (a)][ALLOCNO_COVER_CLASS (another_a)]);
       if ((another_parent_a = ALLOCNO_CAP (another_a)) == NULL
          && (another_parent_a = (parent->regno_allocno_map
                                  [ALLOCNO_REGNO (another_a)])) == NULL)
@@ -740,6 +741,7 @@ ira_build_conflicts (void)
 {
   ira_allocno_t a;
   ira_allocno_iterator ai;
+  HARD_REG_SET temp_hard_reg_set;
 
   if (optimize)
     {
@@ -747,8 +749,8 @@ ira_build_conflicts (void)
       build_conflicts ();
       ira_traverse_loop_tree (true, ira_loop_tree_root, NULL, add_copies);
       /* We need finished conflict table for the subsequent call.  */
-      if (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL
-         || flag_ira_algorithm == IRA_ALGORITHM_MIXED)
+      if (flag_ira_region == IRA_REGION_ALL
+         || flag_ira_region == IRA_REGION_MIXED)
        propagate_copies ();
       /* Now we can free memory for the conflict table (see function
         build_allocno_conflicts for details).  */
@@ -759,6 +761,14 @@ ira_build_conflicts (void)
        }
       ira_free (conflicts);
     }
+  if (! CLASS_LIKELY_SPILLED_P (BASE_REG_CLASS))
+    CLEAR_HARD_REG_SET (temp_hard_reg_set);
+  else
+    {
+      COPY_HARD_REG_SET (temp_hard_reg_set, reg_class_contents[BASE_REG_CLASS]);
+      AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs);
+      AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set);
+    }
   FOR_EACH_ALLOCNO (a, ai)
     {
       if (ALLOCNO_CALLS_CROSSED_NUM (a) == 0)
@@ -775,9 +785,15 @@ ira_build_conflicts (void)
        {
          IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
                            no_caller_save_reg_set);
+         IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
+                           temp_hard_reg_set);
          if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
-           IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
-                             no_caller_save_reg_set);
+           {
+             IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
+                               no_caller_save_reg_set);
+             IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
+                               temp_hard_reg_set);
+           }
        }
     }
   if (optimize && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
index 3daeb07..a2df9bd 100644 (file)
@@ -105,6 +105,9 @@ static enum reg_class *allocno_pref;
 /* Allocated buffers for allocno_pref.  */
 static enum reg_class *allocno_pref_buffer;
 
+/* Record register class of each allocno with the same regno.  */
+static enum reg_class *common_classes;
+
 /* Execution frequency of the current insn.  */
 static int frequency;
 
@@ -1082,8 +1085,8 @@ print_costs (FILE *f)
            {
              fprintf (f, " %s:%d", reg_class_names[rclass],
                       COSTS_OF_ALLOCNO (allocno_costs, i)->cost[k]);
-             if (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL
-                 || flag_ira_algorithm == IRA_ALGORITHM_MIXED)
+             if (flag_ira_region == IRA_REGION_ALL
+                 || flag_ira_region == IRA_REGION_MIXED)
                fprintf (f, ",%d", COSTS_OF_ALLOCNO (total_costs, i)->cost[k]);
            }
        }
@@ -1173,7 +1176,7 @@ find_allocno_class_costs (void)
          int rclass, a_num, parent_a_num;
          ira_loop_tree_node_t parent;
          int best_cost, allocno_cost;
-         enum reg_class best, alt_class, common_class;
+         enum reg_class best, alt_class;
 #ifdef FORBIDDEN_INC_DEC_CLASSES
          int inc_dec_p = false;
 #endif
@@ -1187,8 +1190,8 @@ find_allocno_class_costs (void)
               a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
            {
              a_num = ALLOCNO_NUM (a);
-             if ((flag_ira_algorithm == IRA_ALGORITHM_REGIONAL
-                  || flag_ira_algorithm == IRA_ALGORITHM_MIXED)
+             if ((flag_ira_region == IRA_REGION_ALL
+                  || flag_ira_region == IRA_REGION_MIXED)
                  && (parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) != NULL
                  && (parent_a = parent->regno_allocno_map[i]) != NULL
                  /* There are no caps yet.  */
@@ -1247,6 +1250,7 @@ find_allocno_class_costs (void)
                      > reg_class_size[alt_class]))
                alt_class = reg_class_subunion[alt_class][rclass];
            }
+         alt_class = ira_class_translate[alt_class];
          if (pass == flag_expensive_optimizations)
            {
              if (best_cost > temp_costs->mem_cost)
@@ -1260,18 +1264,22 @@ find_allocno_class_costs (void)
                         i, reg_class_names[best], reg_class_names[alt_class]);
            }
          if (best_cost > temp_costs->mem_cost)
-           common_class = NO_REGS;
+           common_classes[i] = NO_REGS;
+         else if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
+           /* Make the common class the biggest class of best and
+              alt_class.  */
+           common_classes[i] = alt_class == NO_REGS ? best : alt_class;
          else
            /* Make the common class a cover class.  Remember all
               allocnos with the same regno should have the same cover
               class.  */
-           common_class = ira_class_translate[best];
+           common_classes[i] = ira_class_translate[best];
          for (a = ira_regno_allocno_map[i];
               a != NULL;
               a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
            {
              a_num = ALLOCNO_NUM (a);
-             if (common_class == NO_REGS)
+             if (common_classes[i] == NO_REGS)
                best = NO_REGS;
              else
                {             
@@ -1283,7 +1291,7 @@ find_allocno_class_costs (void)
                  for (k = 0; k < cost_classes_num; k++)
                    {
                      rclass = cost_classes[k];
-                     if (! ira_class_subset_p[rclass][common_class])
+                     if (! ira_class_subset_p[rclass][common_classes[i]])
                        continue;
                      /* Ignore classes that are too small for this
                         operand or invalid for an operand that was
@@ -1319,6 +1327,8 @@ find_allocno_class_costs (void)
                    }
                  ALLOCNO_COVER_CLASS_COST (a) = allocno_cost;
                }
+             ira_assert (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY
+                         || ira_class_translate[best] == common_classes[i]);
              if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL
                  && (pass == 0 || allocno_pref[a_num] != best))
                {
@@ -1330,7 +1340,7 @@ find_allocno_class_costs (void)
                             ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
                  fprintf (ira_dump_file, ") best %s, cover %s\n",
                           reg_class_names[best],
-                          reg_class_names[ira_class_translate[best]]);
+                          reg_class_names[common_classes[i]]);
                }
              allocno_pref[a_num] = best;
            }
@@ -1439,7 +1449,7 @@ setup_allocno_cover_class_and_costs (void)
     {
       i = ALLOCNO_NUM (a);
       mode = ALLOCNO_MODE (a);
-      cover_class = ira_class_translate[allocno_pref[i]];
+      cover_class = common_classes[ALLOCNO_REGNO (a)];
       ira_assert (allocno_pref[i] == NO_REGS || cover_class != NO_REGS);
       ALLOCNO_MEMORY_COST (a) = COSTS_OF_ALLOCNO (allocno_costs, i)->mem_cost;
       ira_set_allocno_cover_class (a, cover_class);
@@ -1572,6 +1582,9 @@ ira_costs (void)
   allocno_pref_buffer
     = (enum reg_class *) ira_allocate (sizeof (enum reg_class)
                                       * ira_allocnos_num);
+  common_classes
+    = (enum reg_class *) ira_allocate (sizeof (enum reg_class)
+                                      * max_reg_num ());
   find_allocno_class_costs ();
   setup_allocno_cover_class_and_costs ();
   /* Because we could process operands only as subregs, check mode of
@@ -1580,6 +1593,7 @@ ira_costs (void)
     if (ira_register_move_cost[ALLOCNO_MODE (a)] == NULL
        && have_regs_of_mode[ALLOCNO_MODE (a)])
       ira_init_register_move_cost (ALLOCNO_MODE (a));
+  ira_free (common_classes);
   ira_free (allocno_pref_buffer);
   ira_free (total_costs);
   ira_free (allocno_costs);
index 29f3fdf..536d6ee 100644 (file)
@@ -1025,6 +1025,7 @@ void
 ira_emit (bool loops_p)
 {
   basic_block bb;
+  rtx insn;
   edge_iterator ei;
   edge e;
   ira_allocno_t a;
@@ -1085,6 +1086,14 @@ ira_emit (bool loops_p)
   ira_free (allocno_last_set_check);
   ira_free (allocno_last_set);
   commit_edge_insertions ();
+  /* Fix insn codes.  It is necessary to do it before reload because
+     reload assumes initial insn codes defined.  The insn codes can be
+     invalidated by CFG infrastructure for example in jump
+     redirection.  */
+  FOR_EACH_BB (bb)
+    FOR_BB_INSNS_REVERSE (bb, insn)
+      if (INSN_P (insn))
+       recog_memoized (insn);
   ira_free (at_bb_end);
   ira_free (at_bb_start);
 }
index 5c6b355..1fc6da2 100644 (file)
@@ -819,6 +819,16 @@ extern enum reg_class ira_class_translate[N_REG_CLASSES];
    taking all hard-registers including fixed ones into account.  */
 extern enum reg_class ira_reg_class_intersect[N_REG_CLASSES][N_REG_CLASSES];
 
+/* True if the two classes (that is calculated taking only hard
+   registers available for allocation into account) are
+   intersected.  */
+extern bool ira_reg_classes_intersect_p[N_REG_CLASSES][N_REG_CLASSES];
+
+/* Classes with end marker LIM_REG_CLASSES which are intersected with
+   given class (the first index).  That includes given class itself.
+   This is calculated taking only hard registers available for
+   allocation into account.  */
+extern enum reg_class ira_reg_class_super_classes[N_REG_CLASSES][N_REG_CLASSES];
 /* The biggest important class inside of union of the two classes
    (that is calculated taking only hard registers available for
    allocation into account).  If the both classes contain no hard
index 83b5ec8..c7868f3 100644 (file)
@@ -117,18 +117,23 @@ make_regno_born (int regno)
 static void
 update_allocno_pressure_excess_length (ira_allocno_t a)
 {
-  int start;
-  enum reg_class cover_class;
+  int start, i;
+  enum reg_class cover_class, cl;
   allocno_live_range_t p;
 
   cover_class = ALLOCNO_COVER_CLASS (a);
-  if (high_pressure_start_point[cover_class] < 0)
-    return;
-  p = ALLOCNO_LIVE_RANGES (a);
-  ira_assert (p != NULL);
-  start = (high_pressure_start_point[cover_class] > p->start
-          ? high_pressure_start_point[cover_class] : p->start);
-  ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) += curr_point - start + 1;
+  for (i = 0;
+       (cl = ira_reg_class_super_classes[cover_class][i]) != LIM_REG_CLASSES;
+       i++)
+    {
+      if (high_pressure_start_point[cl] < 0)
+       continue;
+      p = ALLOCNO_LIVE_RANGES (a);
+      ira_assert (p != NULL);
+      start = (high_pressure_start_point[cl] > p->start
+              ? high_pressure_start_point[cl] : p->start);
+      ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) += curr_point - start + 1;
+    }
 }
 
 /* Process the death of register REGNO.  This updates hard_regs_live
@@ -165,8 +170,8 @@ static int curr_reg_pressure[N_REG_CLASSES];
 static void
 set_allocno_live (ira_allocno_t a)
 {
-  int nregs;
-  enum reg_class cover_class;
+  int i;
+  enum reg_class cover_class, cl;
 
   /* Invalidate because it is referenced.  */
   allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
@@ -176,15 +181,17 @@ set_allocno_live (ira_allocno_t a)
   IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), hard_regs_live);
   IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), hard_regs_live);
   cover_class = ALLOCNO_COVER_CLASS (a);
-  nregs = ira_reg_class_nregs[cover_class][ALLOCNO_MODE (a)];
-  curr_reg_pressure[cover_class] += nregs;
-  if (high_pressure_start_point[cover_class] < 0
-      && (curr_reg_pressure[cover_class]
-         > ira_available_class_regs[cover_class]))
-    high_pressure_start_point[cover_class] = curr_point;
-  if (curr_bb_node->reg_pressure[cover_class]
-      < curr_reg_pressure[cover_class])
-    curr_bb_node->reg_pressure[cover_class] = curr_reg_pressure[cover_class];
+  for (i = 0;
+       (cl = ira_reg_class_super_classes[cover_class][i]) != LIM_REG_CLASSES;
+       i++)
+    {
+      curr_reg_pressure[cl] += ira_reg_class_nregs[cl][ALLOCNO_MODE (a)];
+      if (high_pressure_start_point[cl] < 0
+         && (curr_reg_pressure[cl] > ira_available_class_regs[cl]))
+       high_pressure_start_point[cl] = curr_point;
+      if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
+       curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
+    }
 }
 
 /* Mark allocno A as currently not living and update current register
@@ -193,26 +200,40 @@ set_allocno_live (ira_allocno_t a)
 static void
 clear_allocno_live (ira_allocno_t a)
 {
-  unsigned int i;
-  enum reg_class cover_class;
+  int i;
+  unsigned int j;
+  enum reg_class cover_class, cl;
+  bool set_p;
 
   /* Invalidate because it is referenced.  */
   allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
   if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
     {
       cover_class = ALLOCNO_COVER_CLASS (a);
-      curr_reg_pressure[cover_class]
-       -= ira_reg_class_nregs[cover_class][ALLOCNO_MODE (a)];
-      ira_assert (curr_reg_pressure[cover_class] >= 0);
-      if (high_pressure_start_point[cover_class] >= 0
-         && (curr_reg_pressure[cover_class]
-             <= ira_available_class_regs[cover_class]))
+      set_p = false;
+      for (i = 0;
+          (cl = ira_reg_class_super_classes[cover_class][i])
+            != LIM_REG_CLASSES;
+          i++)
        {
-         EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
-           {
-             update_allocno_pressure_excess_length (ira_allocnos[i]);
-           }
-         high_pressure_start_point[cover_class] = -1;
+         curr_reg_pressure[cl] -= ira_reg_class_nregs[cl][ALLOCNO_MODE (a)];
+         ira_assert (curr_reg_pressure[cl] >= 0);
+         if (high_pressure_start_point[cl] >= 0
+             && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
+           set_p = true;
+       }
+      if (set_p)
+       {
+         EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, j)
+           update_allocno_pressure_excess_length (ira_allocnos[j]);
+         for (i = 0;
+              (cl = ira_reg_class_super_classes[cover_class][i])
+                != LIM_REG_CLASSES;
+              i++)
+           if (high_pressure_start_point[cl] >= 0
+               && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
+             high_pressure_start_point[cl] = -1;
+         
        }
     }
   sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (a));
@@ -225,7 +246,7 @@ clear_allocno_live (ira_allocno_t a)
 static void
 mark_reg_live (rtx reg)
 {
-  int regno;
+  int i, regno;
 
   gcc_assert (REG_P (reg));
   regno = REGNO (reg);
@@ -249,7 +270,7 @@ mark_reg_live (rtx reg)
   else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
     {
       int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
-      enum reg_class cover_class;
+      enum reg_class cover_class, cl;
 
       while (regno < last)
        {
@@ -257,20 +278,26 @@ mark_reg_live (rtx reg)
              && ! TEST_HARD_REG_BIT (eliminable_regset, regno))
            {
              cover_class = ira_hard_regno_cover_class[regno];
-             if (cover_class != NO_REGS)
+             for (i = 0;
+                  (cl = ira_reg_class_super_classes[cover_class][i])
+                    != LIM_REG_CLASSES;
+                  i++)
                {
-                 curr_reg_pressure[cover_class]++;
-                 if (high_pressure_start_point[cover_class] < 0
-                     && (curr_reg_pressure[cover_class]
-                         > ira_available_class_regs[cover_class]))
-                   high_pressure_start_point[cover_class] = curr_point;
+                 curr_reg_pressure[cl]++;
+                 if (high_pressure_start_point[cl] < 0
+                     && (curr_reg_pressure[cl]
+                         > ira_available_class_regs[cl]))
+                   high_pressure_start_point[cl] = curr_point;
                }
              make_regno_born (regno);
-             if (cover_class != NO_REGS
-                 && (curr_bb_node->reg_pressure[cover_class]
-                     < curr_reg_pressure[cover_class]))
-               curr_bb_node->reg_pressure[cover_class]
-                 = curr_reg_pressure[cover_class];
+             for (i = 0;
+                  (cl = ira_reg_class_super_classes[cover_class][i])
+                    != LIM_REG_CLASSES;
+                  i++)
+               {
+                 if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
+                   curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
+               }
            }
          regno++;
        }
@@ -317,30 +344,41 @@ mark_reg_dead (rtx reg)
     }
   else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
     {
-      unsigned int i;
+      int i;
+      unsigned int j;
       int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
-      enum reg_class cover_class;
+      enum reg_class cover_class, cl;
+      bool set_p;
 
       while (regno < last)
        {
          if (TEST_HARD_REG_BIT (hard_regs_live, regno))
            {
+             set_p = false;
              cover_class = ira_hard_regno_cover_class[regno];
-             if (cover_class != NO_REGS)
+             for (i = 0;
+                  (cl = ira_reg_class_super_classes[cover_class][i])
+                    != LIM_REG_CLASSES;
+                  i++)
+               {
+                 curr_reg_pressure[cl]--;
+                 if (high_pressure_start_point[cl] >= 0
+                     && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
+                   set_p = true;
+                 ira_assert (curr_reg_pressure[cl] >= 0);
+               }
+             if (set_p)
                {
-                 curr_reg_pressure[cover_class]--;
-                 if (high_pressure_start_point[cover_class] >= 0
-                     && (curr_reg_pressure[cover_class]
-                         <= ira_available_class_regs[cover_class]))
-                   {
-                     EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
-                       {
-                         update_allocno_pressure_excess_length
-                           (ira_allocnos[i]);
-                       }
-                     high_pressure_start_point[cover_class] = -1;
-                   }
-                 ira_assert (curr_reg_pressure[cover_class] >= 0);
+                 EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, j)
+                   update_allocno_pressure_excess_length (ira_allocnos[j]);
+                 for (i = 0;
+                      (cl = ira_reg_class_super_classes[cover_class][i])
+                        != LIM_REG_CLASSES;
+                      i++)
+                   if (high_pressure_start_point[cl] >= 0
+                       && (curr_reg_pressure[cl]
+                           <= ira_available_class_regs[cl]))
+                     high_pressure_start_point[cl] = -1;
                }
              make_regno_dead (regno);
            }
@@ -807,18 +845,20 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        if (TEST_HARD_REG_BIT (hard_regs_live, i))
          {
-           enum reg_class cover_class;
+           enum reg_class cover_class, cl;
            
-           cover_class = ira_hard_regno_cover_class[i];
-           if (cover_class == NO_REGS)
-             continue;
-           curr_reg_pressure[cover_class]++;
-           if (curr_bb_node->reg_pressure[cover_class]
-               < curr_reg_pressure[cover_class])
-             curr_bb_node->reg_pressure[cover_class]
-               = curr_reg_pressure[cover_class];
-           ira_assert (curr_reg_pressure[cover_class]
-                       <= ira_available_class_regs[cover_class]);
+           cover_class = ira_class_translate[REGNO_REG_CLASS (i)];
+           for (j = 0;
+                (cl = ira_reg_class_super_classes[cover_class][j])
+                  != LIM_REG_CLASSES;
+                j++)
+             {
+               curr_reg_pressure[cl]++;
+               if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
+                 curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
+               ira_assert (curr_reg_pressure[cl]
+                           <= ira_available_class_regs[cl]);
+             }
          }
       EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
        {
index 4b68542..44f7032 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -434,6 +434,8 @@ setup_class_hard_regs (void)
       COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
       AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
       CLEAR_HARD_REG_SET (processed_hard_reg_set);
+      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+       ira_class_hard_reg_index[cl][0] = -1;
       for (n = 0, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        {
 #ifdef REG_ALLOC_ORDER
@@ -714,22 +716,72 @@ enum reg_class ira_important_classes[N_REG_CLASSES];
    classes.  */
 int ira_important_class_nums[N_REG_CLASSES];
 
-/* Check IRA_COVER_CLASSES and sets the four global variables defined
-   above.  */
+/* Set the four global variables defined above.  */
 static void
 setup_cover_and_important_classes (void)
 {
-  int i, j;
+  int i, j, n;
+  bool set_p, eq_p;
   enum reg_class cl;
-  const enum reg_class *classes;
+  const enum reg_class *cover_classes;
   HARD_REG_SET temp_hard_regset2;
+  static enum reg_class classes[LIM_REG_CLASSES + 1];
+
+  if (targetm.ira_cover_classes == NULL)
+    cover_classes = NULL;
+  else
+    cover_classes = targetm.ira_cover_classes ();
+  if (cover_classes == NULL)
+    ira_assert (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY);
+  else
+    {
+      for (i = 0; (cl = cover_classes[i]) != LIM_REG_CLASSES; i++)
+       classes[i] = cl;
+      classes[i] = LIM_REG_CLASSES;
+    }
+
+  if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
+    {
+      n = 0;
+      for (i = 0; i <= LIM_REG_CLASSES; i++)
+       {
+         if (i == NO_REGS)
+           continue;
+#ifdef CONSTRAINT__LIMIT
+         for (j = 0; j < CONSTRAINT__LIMIT; j++)
+           if ((int) regclass_for_constraint (j) == i)
+             break;
+         if (j < CONSTRAINT__LIMIT)
+           {
+             classes[n++] = i;
+             continue;
+           }
+#endif
+         COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[i]);
+         AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
+         for (j = 0; j < LIM_REG_CLASSES; j++)
+           {
+             if (i == j)
+               continue;
+             COPY_HARD_REG_SET (temp_hard_regset2, reg_class_contents[j]);
+             AND_COMPL_HARD_REG_SET (temp_hard_regset2,
+                                     no_unit_alloc_regs);
+             if (hard_reg_set_equal_p (temp_hard_regset,
+                                       temp_hard_regset2))
+                   break;
+           }
+         if (j >= i)
+           classes[n++] = i;
+       }
+      classes[n] = LIM_REG_CLASSES;
+    }
 
-  classes = targetm.ira_cover_classes ();
   ira_reg_class_cover_size = 0;
   for (i = 0; (cl = classes[i]) != LIM_REG_CLASSES; i++)
     {
       for (j = 0; j < i; j++)
-       if (reg_classes_intersect_p (cl, classes[j]))
+       if (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY
+           && reg_classes_intersect_p (cl, classes[j]))
          gcc_unreachable ();
       COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
       AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
@@ -742,22 +794,34 @@ setup_cover_and_important_classes (void)
       COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
       AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
       if (! hard_reg_set_empty_p (temp_hard_regset))
-       for (j = 0; j < ira_reg_class_cover_size; j++)
-         {
-           COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
-           AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
-           COPY_HARD_REG_SET (temp_hard_regset2,
-                              reg_class_contents[ira_reg_class_cover[j]]);
-           AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs);
-           if (cl == ira_reg_class_cover[j]
-               || (hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2)
-                   && ! hard_reg_set_equal_p (temp_hard_regset,
-                                              temp_hard_regset2)))
-             {
-               ira_important_class_nums[cl] = ira_important_classes_num;
-               ira_important_classes[ira_important_classes_num++] = cl;
-             }
-         }
+       {
+         set_p = eq_p = false;
+         for (j = 0; j < ira_reg_class_cover_size; j++)
+           {
+             COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
+             AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
+             COPY_HARD_REG_SET (temp_hard_regset2,
+                                reg_class_contents[ira_reg_class_cover[j]]);
+             AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs);
+             if (cl == ira_reg_class_cover[j])
+               {
+                 eq_p = false;
+                 set_p = true;
+                 break;
+               }
+             else if (hard_reg_set_equal_p (temp_hard_regset,
+                                            temp_hard_regset2))
+               eq_p = true;
+             else if (hard_reg_set_subset_p (temp_hard_regset,
+                                             temp_hard_regset2))
+               set_p = true;
+           }
+         if (set_p && ! eq_p)
+           {
+             ira_important_class_nums[cl] = ira_important_classes_num;
+             ira_important_classes[ira_important_classes_num++] = cl;
+           }
+       }
     }
 }
 
@@ -776,25 +840,44 @@ setup_class_translate (void)
 
   for (cl = 0; cl < N_REG_CLASSES; cl++)
     ira_class_translate[cl] = NO_REGS;
+  
+  if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
+    for (cl = 0; cl < LIM_REG_CLASSES; cl++)
+      {
+       COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
+       AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
+       for (i = 0; i < ira_reg_class_cover_size; i++)
+         {
+           HARD_REG_SET temp_hard_regset2;
+           
+           cover_class = ira_reg_class_cover[i];
+           COPY_HARD_REG_SET (temp_hard_regset2,
+                              reg_class_contents[cover_class]);
+           AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs);
+           if (hard_reg_set_equal_p (temp_hard_regset, temp_hard_regset2))
+             ira_class_translate[cl] = cover_class;
+         }
+      }
   for (i = 0; i < ira_reg_class_cover_size; i++)
     {
       cover_class = ira_reg_class_cover[i];
-      for (cl_ptr = &alloc_reg_class_subclasses[cover_class][0];
-          (cl = *cl_ptr) != LIM_REG_CLASSES;
-          cl_ptr++)
-       {
-         if (ira_class_translate[cl] == NO_REGS)
-           ira_class_translate[cl] = cover_class;
+      if (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY)
+       for (cl_ptr = &alloc_reg_class_subclasses[cover_class][0];
+            (cl = *cl_ptr) != LIM_REG_CLASSES;
+            cl_ptr++)
+         {
+           if (ira_class_translate[cl] == NO_REGS)
+             ira_class_translate[cl] = cover_class;
 #ifdef ENABLE_IRA_CHECKING
-         else
-           {
-             COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
-             AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
-             if (! hard_reg_set_empty_p (temp_hard_regset))
-               gcc_unreachable ();
-           }
+           else
+             {
+               COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
+               AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
+               if (! hard_reg_set_empty_p (temp_hard_regset))
+                 gcc_unreachable ();
+             }
 #endif
-       }
+         }
       ira_class_translate[cover_class] = cover_class;
     }
   /* For classes which are not fully covered by a cover class (in
@@ -842,6 +925,17 @@ setup_class_translate (void)
    account.  */
 enum reg_class ira_reg_class_intersect[N_REG_CLASSES][N_REG_CLASSES];
 
+/* True if the two classes (that is calculated taking only hard
+   registers available for allocation into account) are
+   intersected.  */
+bool ira_reg_classes_intersect_p[N_REG_CLASSES][N_REG_CLASSES];
+
+/* Important classes with end marker LIM_REG_CLASSES which are
+   supersets with given important class (the first index).  That
+   includes given class itself.  This is calculated taking only hard
+   registers available for allocation into account.  */
+enum reg_class ira_reg_class_super_classes[N_REG_CLASSES][N_REG_CLASSES];
+
 /* The biggest important reg_class inside of union of the two
    reg_classes (that is calculated taking only hard registers
    available for allocation into account).  If the both reg_classes
@@ -851,17 +945,23 @@ 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];
 
-/* Set up IRA_REG_CLASS_INTERSECT and IRA_REG_CLASS_UNION.  */
+/* Set up the above reg class relations.  */
 static void
-setup_reg_class_intersect_union (void)
+setup_reg_class_relations (void)
 {
   int i, cl1, cl2, cl3;
   HARD_REG_SET intersection_set, union_set, temp_set2;
+  bool important_class_p[N_REG_CLASSES];
 
+  memset (important_class_p, 0, sizeof (important_class_p));
+  for (i = 0; i < ira_important_classes_num; i++)
+    important_class_p[ira_important_classes[i]] = true;
   for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++)
     {
+      ira_reg_class_super_classes[cl1][0] = LIM_REG_CLASSES;
       for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
        {
+         ira_reg_classes_intersect_p[cl1][cl2] = false;
          ira_reg_class_intersect[cl1][cl2] = NO_REGS;
          COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl1]);
          AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
@@ -882,6 +982,19 @@ setup_reg_class_intersect_union (void)
              ira_reg_class_union[cl1][cl2] = reg_class_subunion[cl1][cl2];
              continue;
            }
+         ira_reg_classes_intersect_p[cl1][cl2]
+           = hard_reg_set_intersect_p (temp_hard_regset, temp_set2);
+         if (important_class_p[cl1] && important_class_p[cl2]
+             && hard_reg_set_subset_p (temp_hard_regset, temp_set2))
+           {
+             enum reg_class *p;
+
+             p = &ira_reg_class_super_classes[cl1][0];
+             while (*p != LIM_REG_CLASSES)
+               p++;
+             *p++ = (enum reg_class) cl2;
+             *p = LIM_REG_CLASSES;
+           }
          ira_reg_class_union[cl1][cl2] = NO_REGS;
          COPY_HARD_REG_SET (intersection_set, reg_class_contents[cl1]);
          AND_HARD_REG_SET (intersection_set, reg_class_contents[cl2]);
@@ -966,12 +1079,9 @@ static void
 find_reg_class_closure (void)
 {
   setup_reg_subclasses ();
-  if (targetm.ira_cover_classes)
-    {
-      setup_cover_and_important_classes ();
-      setup_class_translate ();
-      setup_reg_class_intersect_union ();
-    }
+  setup_cover_and_important_classes ();
+  setup_class_translate ();
+  setup_reg_class_relations ();
 }
 
 \f
@@ -1804,8 +1914,8 @@ ira (FILE *f)
   if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
     fprintf (ira_dump_file, "Building IRA IR\n");
   loops_p = ira_build (optimize
-                      && (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL
-                          || flag_ira_algorithm == IRA_ALGORITHM_MIXED));
+                      && (flag_ira_region == IRA_REGION_ALL
+                          || flag_ira_region == IRA_REGION_MIXED));
 
   saved_flag_ira_share_spill_slots = flag_ira_share_spill_slots;
   if (too_high_register_pressure_p ())
index 8781418..b7885e6 100644 (file)
@@ -760,10 +760,10 @@ use_pointer_for_field (tree decl, omp_context *shared_ctx)
          omp_context *up;
 
          for (up = shared_ctx->outer; up; up = up->outer)
-           if (maybe_lookup_decl (decl, up))
+           if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
              break;
 
-         if (up && is_taskreg_ctx (up))
+         if (up)
            {
              tree c;
 
index a87fb49..42e3bee 100644 (file)
@@ -870,9 +870,11 @@ decode_options (unsigned int argc, const char **argv)
        }
     }
   
-  /* Use IRA if it is implemented for the target.  */
-  if (targetm.ira_cover_classes)
-    flag_ira = 1;
+  flag_ira = 1;
+  /* Use priority coloring if cover classes is not defined for the
+     target.  */
+  if (targetm.ira_cover_classes == NULL)
+    flag_ira_algorithm = IRA_ALGORITHM_PRIORITY;
 
   /* -O1 optimizations.  */
   opt1 = (optimize >= 1);
@@ -1096,10 +1098,12 @@ decode_options (unsigned int argc, const char **argv)
   if (!flag_sel_sched_pipelining)
     flag_sel_sched_pipelining_outer_loops = 0;
 
-  if (flag_ira && !targetm.ira_cover_classes)
+  if (flag_ira && !targetm.ira_cover_classes
+      && flag_ira_algorithm == IRA_ALGORITHM_CB)
     {
-      inform (input_location, "-fira does not work on this architecture");
-      flag_ira = 0;
+      inform (input_location,
+             "-fira-algorithm=CB does not work on this architecture");
+      flag_ira_algorithm = IRA_ALGORITHM_PRIORITY;
     }
 
   /* Save the current optimization options if this is the first call.  */
@@ -1976,16 +1980,25 @@ common_handle_option (size_t scode, const char *arg, int value,
       break;
 
     case OPT_fira_algorithm_:
-      if (!strcmp (arg, "regional"))
-       flag_ira_algorithm = IRA_ALGORITHM_REGIONAL;
-      else if (!strcmp (arg, "CB"))
+      if (!strcmp (arg, "CB"))
        flag_ira_algorithm = IRA_ALGORITHM_CB;
-      else if (!strcmp (arg, "mixed"))
-       flag_ira_algorithm = IRA_ALGORITHM_MIXED;
+      else if (!strcmp (arg, "priority"))
+       flag_ira_algorithm = IRA_ALGORITHM_PRIORITY;
       else
        warning (0, "unknown ira algorithm \"%s\"", arg);
       break;
 
+    case OPT_fira_region_:
+      if (!strcmp (arg, "one"))
+       flag_ira_region = IRA_REGION_ONE;
+      else if (!strcmp (arg, "all"))
+       flag_ira_region = IRA_REGION_ALL;
+      else if (!strcmp (arg, "mixed"))
+       flag_ira_region = IRA_REGION_MIXED;
+      else
+       warning (0, "unknown ira region \"%s\"", arg);
+      break;
+
     case OPT_fira_verbose_:
       flag_ira_verbose = value;
       break;
index 73dbcbd..22e71ce 100644 (file)
@@ -2052,7 +2052,7 @@ estimate_bb_frequencies (void)
   basic_block bb;
   sreal freq_max;
 
-  if (cfun->function_frequency != PROFILE_READ || !counts_to_freqs ())
+  if (profile_status != PROFILE_READ || !counts_to_freqs ())
     {
       static int real_values_initialized = 0;
 
index ac1e874..ffde2bf 100644 (file)
@@ -6084,9 +6084,10 @@ choose_reload_regs (struct insn_chain *chain)
                    need_mode = mode;
                  else
                    need_mode
-                     = smallest_mode_for_size (GET_MODE_BITSIZE (mode)
-                                               + byte * BITS_PER_UNIT,
-                                               GET_MODE_CLASS (mode));
+                     = smallest_mode_for_size
+                       (GET_MODE_BITSIZE (mode) + byte * BITS_PER_UNIT,
+                        GET_MODE_CLASS (mode) == MODE_PARTIAL_INT
+                        ? MODE_INT : GET_MODE_CLASS (mode));
 
                  if ((GET_MODE_SIZE (GET_MODE (last_reg))
                       >= GET_MODE_SIZE (need_mode))
index 1765461..0e7caa5 100644 (file)
@@ -1316,7 +1316,7 @@ compute_record_mode (tree type)
      However, if possible, we use a mode that fits in a register
      instead, in order to allow for better optimization down the
      line.  */
-  TYPE_MODE (type) = BLKmode;
+  SET_TYPE_MODE (type, BLKmode);
 
   if (! host_integerp (TYPE_SIZE (type), 1))
     return;
@@ -1360,9 +1360,9 @@ compute_record_mode (tree type)
   if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode
       && host_integerp (TYPE_SIZE (type), 1)
       && GET_MODE_BITSIZE (mode) == TREE_INT_CST_LOW (TYPE_SIZE (type)))
-    TYPE_MODE (type) = mode;
+    SET_TYPE_MODE (type, mode);
   else
-    TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
+    SET_TYPE_MODE (type, mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1));
 
   /* If structure's known alignment is less than what the scalar
      mode would need, and it matters, then stick with BLKmode.  */
@@ -1374,7 +1374,7 @@ compute_record_mode (tree type)
       /* If this is the only reason this type is BLKmode, then
         don't force containing types to be BLKmode.  */
       TYPE_NO_FORCE_BLK (type) = 1;
-      TYPE_MODE (type) = BLKmode;
+      SET_TYPE_MODE (type, BLKmode);
     }
 }
 
@@ -1458,7 +1458,7 @@ finalize_type_size (tree type)
          TYPE_SIZE_UNIT (variant) = size_unit;
          TYPE_ALIGN (variant) = align;
          TYPE_USER_ALIGN (variant) = user_align;
-         TYPE_MODE (variant) = mode;
+         SET_TYPE_MODE (variant, mode);
        }
     }
 }
@@ -1580,14 +1580,15 @@ layout_type (tree type)
          && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0)
        TYPE_UNSIGNED (type) = 1;
 
-      TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type),
-                                                MODE_INT);
+      SET_TYPE_MODE (type,
+                    smallest_mode_for_size (TYPE_PRECISION (type), MODE_INT));
       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
       TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
       break;
 
     case REAL_TYPE:
-      TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0);
+      SET_TYPE_MODE (type,
+                    mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0));
       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
       TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
       break;
@@ -1600,11 +1601,11 @@ layout_type (tree type)
 
     case COMPLEX_TYPE:
       TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
-      TYPE_MODE (type)
-       = mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)),
-                        (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE
-                         ? MODE_COMPLEX_FLOAT : MODE_COMPLEX_INT),
-                        0);
+      SET_TYPE_MODE (type,
+                    mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)),
+                                   (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE
+                                    ? MODE_COMPLEX_FLOAT : MODE_COMPLEX_INT),
+                                    0));
       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
       TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
       break;
@@ -1636,10 +1637,11 @@ layout_type (tree type)
            else
              mode = MIN_MODE_VECTOR_INT;
 
+           /* Do not check vector_mode_supported_p here.  We'll do that
+              later in vector_type_mode.  */
            for (; mode != VOIDmode ; mode = GET_MODE_WIDER_MODE (mode))
              if (GET_MODE_NUNITS (mode) == nunits
-                 && GET_MODE_INNER (mode) == innermode
-                 && targetm.vector_mode_supported_p (mode))
+                 && GET_MODE_INNER (mode) == innermode)
                break;
 
            /* For integers, try mapping it to a same-sized scalar mode.  */
@@ -1648,10 +1650,12 @@ layout_type (tree type)
              mode = mode_for_size (nunits * GET_MODE_BITSIZE (innermode),
                                    MODE_INT, 0);
 
-           if (mode == VOIDmode || !have_regs_of_mode[mode])
-             TYPE_MODE (type) = BLKmode;
+           if (mode == VOIDmode ||
+               (GET_MODE_CLASS (mode) == MODE_INT
+                && !have_regs_of_mode[mode]))
+             SET_TYPE_MODE (type, BLKmode);
            else
-             TYPE_MODE (type) = mode;
+             SET_TYPE_MODE (type, mode);
          }
 
        TYPE_SATURATING (type) = TYPE_SATURATING (TREE_TYPE (type));
@@ -1672,7 +1676,7 @@ layout_type (tree type)
       /* This is an incomplete type and so doesn't have a size.  */
       TYPE_ALIGN (type) = 1;
       TYPE_USER_ALIGN (type) = 0;
-      TYPE_MODE (type) = VOIDmode;
+      SET_TYPE_MODE (type, VOIDmode);
       break;
 
     case OFFSET_TYPE:
@@ -1680,7 +1684,7 @@ layout_type (tree type)
       TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
       /* A pointer might be MODE_PARTIAL_INT,
         but ptrdiff_t must be integral.  */
-      TYPE_MODE (type) = mode_for_size (POINTER_SIZE, MODE_INT, 0);
+      SET_TYPE_MODE (type, mode_for_size (POINTER_SIZE, MODE_INT, 0));
       break;
 
     case FUNCTION_TYPE:
@@ -1688,7 +1692,7 @@ layout_type (tree type)
       /* It's hard to see what the mode and size of a function ought to
         be, but we do know the alignment is FUNCTION_BOUNDARY, so
         make it consistent with that.  */
-      TYPE_MODE (type) = mode_for_size (FUNCTION_BOUNDARY, MODE_INT, 0);
+      SET_TYPE_MODE (type, mode_for_size (FUNCTION_BOUNDARY, MODE_INT, 0));
       TYPE_SIZE (type) = bitsize_int (FUNCTION_BOUNDARY);
       TYPE_SIZE_UNIT (type) = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
       break;
@@ -1696,7 +1700,6 @@ layout_type (tree type)
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       {
-
        enum machine_mode mode = ((TREE_CODE (type) == REFERENCE_TYPE
                                   && reference_types_internal)
                                  ? Pmode : TYPE_MODE (type));
@@ -1792,7 +1795,7 @@ layout_type (tree type)
             fall back on structural equality. */
          SET_TYPE_STRUCTURAL_EQUALITY (type);
        TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
-       TYPE_MODE (type) = BLKmode;
+       SET_TYPE_MODE (type, BLKmode);
        if (TYPE_SIZE (type) != 0
 #ifdef MEMBER_TYPE_FORCES_BLK
            && ! MEMBER_TYPE_FORCES_BLK (type, VOIDmode)
@@ -1805,17 +1808,17 @@ layout_type (tree type)
            /* One-element arrays get the component type's mode.  */
            if (simple_cst_equal (TYPE_SIZE (type),
                                  TYPE_SIZE (TREE_TYPE (type))))
-             TYPE_MODE (type) = TYPE_MODE (TREE_TYPE (type));
+             SET_TYPE_MODE (type, TYPE_MODE (TREE_TYPE (type)));
            else
-             TYPE_MODE (type)
-               = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
+             SET_TYPE_MODE (type, mode_for_size_tree (TYPE_SIZE (type),
+                                                      MODE_INT, 1));
 
            if (TYPE_MODE (type) != BLKmode
                && STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
                && TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
              {
                TYPE_NO_FORCE_BLK (type) = 1;
-               TYPE_MODE (type) = BLKmode;
+               SET_TYPE_MODE (type, BLKmode);
              }
          }
        /* When the element size is constant, check that it is at least as
@@ -1877,6 +1880,45 @@ layout_type (tree type)
   if (AGGREGATE_TYPE_P (type))
     gcc_assert (!TYPE_ALIAS_SET_KNOWN_P (type));
 }
+
+/* Vector types need to re-check the target flags each time we report
+   the machine mode.  We need to do this because attribute target can
+   change the result of vector_mode_supported_p and have_regs_of_mode
+   on a per-function basis.  Thus the TYPE_MODE of a VECTOR_TYPE can
+   change on a per-function basis.  */
+/* ??? Possibly a better solution is to run through all the types 
+   referenced by a function and re-compute the TYPE_MODE once, rather
+   than make the TYPE_MODE macro call a function.  */
+
+enum machine_mode
+vector_type_mode (const_tree t)
+{
+  enum machine_mode mode;
+
+  gcc_assert (TREE_CODE (t) == VECTOR_TYPE);
+
+  mode = t->type.mode;
+  if (VECTOR_MODE_P (mode)
+      && (!targetm.vector_mode_supported_p (mode)
+         || !have_regs_of_mode[mode]))
+    {
+      enum machine_mode innermode = TREE_TYPE (t)->type.mode;
+
+      /* For integers, try mapping it to a same-sized scalar mode.  */
+      if (GET_MODE_CLASS (innermode) == MODE_INT)
+       {
+         mode = mode_for_size (TYPE_VECTOR_SUBPARTS (t)
+                               * GET_MODE_BITSIZE (innermode), MODE_INT, 0);
+
+         if (mode != VOIDmode && have_regs_of_mode[mode])
+           return mode;
+       }
+
+      return BLKmode;
+    }
+
+  return mode;
+}
 \f
 /* Create and return a type for signed integers of PRECISION bits.  */
 
@@ -1921,10 +1963,10 @@ make_fract_type (int precision, int unsignedp, int satp)
   if (unsignedp)
     {
       TYPE_UNSIGNED (type) = 1;
-      TYPE_MODE (type) = mode_for_size (precision, MODE_UFRACT, 0);
+      SET_TYPE_MODE (type, mode_for_size (precision, MODE_UFRACT, 0));
     }
   else
-    TYPE_MODE (type) = mode_for_size (precision, MODE_FRACT, 0);
+    SET_TYPE_MODE (type, mode_for_size (precision, MODE_FRACT, 0));
   layout_type (type);
 
   return type;
@@ -1947,10 +1989,10 @@ make_accum_type (int precision, int unsignedp, int satp)
   if (unsignedp)
     {
       TYPE_UNSIGNED (type) = 1;
-      TYPE_MODE (type) = mode_for_size (precision, MODE_UACCUM, 0);
+      SET_TYPE_MODE (type, mode_for_size (precision, MODE_UACCUM, 0));
     }
   else
-    TYPE_MODE (type) = mode_for_size (precision, MODE_ACCUM, 0);
+    SET_TYPE_MODE (type, mode_for_size (precision, MODE_ACCUM, 0));
   layout_type (type);
 
   return type;
@@ -1965,7 +2007,7 @@ initialize_sizetypes (bool signed_p)
   tree t = make_node (INTEGER_TYPE);
   int precision = GET_MODE_BITSIZE (SImode);
 
-  TYPE_MODE (t) = SImode;
+  SET_TYPE_MODE (t, SImode);
   TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode);
   TYPE_USER_ALIGN (t) = 0;
   TYPE_IS_SIZETYPE (t) = 1;
index d7490b0..a3c9d7c 100644 (file)
@@ -1,3 +1,217 @@
+2008-12-12 Daniel Franke  <franke.daniel@gmail.com>
+
+       PR fortran/36355
+       * gfortran.dg/matmul_argument_types.f90: New.
+
+2008-12-11  Janis Johnson  <janis187@us.ibm.com>
+
+       PR testsuite/29071
+       * gcc.dg/20020919-1.c: Fix a preprocessor check.
+
+2008-12-11  Sebastian Pop  <sebastian.pop@amd.com>
+
+       PR middle-end/38413
+       * gcc.dg/graphite/pr38413.c: New.
+
+2008-12-11  Sebastian Pop  <sebastian.pop@amd.com>
+
+       PR middle-end/37857
+       * gfortran.dg/graphite/pr37857.f90: New.
+
+2008-12-11  Harsha Jagasia  <harsha.jagasia@amd.com>
+
+       PR tree-optimization/38446
+       * gcc.dg/graphite/pr38446.c: New.
+
+2008-12-11  Sebastian Pop  <sebastian.pop@amd.com>
+
+       * gcc.dg/graphite/scop-16.c: Test only scop specific info.
+       * gcc.dg/graphite/scop-17.c: Same.
+       * gcc.dg/graphite/block-5.c: New.
+       * gcc.dg/graphite/block-6.c: New.
+       * gcc.dg/graphite/pr37485.c: Clean dump file after.
+       * gcc.dg/graphite/pr37684.c: Same.
+       * gcc.dg/graphite/block-2.c: Same.
+
+2008-12-10  Tobias Grosser  <grosser@fim.uni-passau.de>
+
+       PR middle-end/38459
+       * gfortran.dg/graphite/pr38459.f90: New.
+
+2008-12-11  Sebastian Pop  <sebastian.pop@amd.com>
+
+       PR middle-end/37852
+       PR middle-end/37883
+       PR middle-end/37928
+       PR middle-end/37980
+       PR middle-end/38038
+       PR middle-end/38039
+       PR middle-end/38073
+       PR middle-end/38083
+       PR middle-end/38125
+       * gcc.dg/graphite/pr37928.c: New.
+       * gcc.dg/graphite/pr37883.c: New.
+       * gcc.dg/graphite/pr38073.c: New.
+       * gcc.dg/graphite/pr38125.c: New.
+       * gfortran.dg/graphite/pr38083.f90: New.
+       * gfortran.dg/graphite/pr37852.f90: New.
+       * gfortran.dg/graphite/pr37980.f90: New.
+       * gfortran.dg/graphite/id-2.f90: New.
+       * gfortran.dg/graphite/id-4.f90: New.
+
+       * gcc.dg/graphite/scop-18.c: Remove reduction, test for
+       the number of detected scops.  Copy exact same test for loop blocking...
+       * gcc.dg/graphite/block-1.c: Fix the number of expected loops
+       to be blocked as reductions are not handled.
+       * gcc.dg/graphite/block-4.c: ...here.  New.
+
+2008-12-11  Ira Rosen  <irar@il.ibm.com>
+
+       PR tree-optimization/38464
+       * gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c: Check that three
+       loops are vectorized.
+
+2008-12-10  Jason Merrill  <jason@redhat.com>
+
+       PR c++/35319
+       * g++.dg/ext/fixed2.C: New test.
+
+2008-12-10  Daniel Berlin  <dberlin@dberlin.org>
+
+       PR tree-optimization/36792
+       * gcc.dg/tree-ssa/ssa-fre-10.c: Update expected results.
+
+2008-12-10  Alexandre Oliva  <aoliva@redhat.com>
+
+       PR middle-end/38271
+       * gcc.dg/torture/pr38271.c: New.
+
+2008-12-10  Ira Rosen  <irar@il.ibm.com>
+
+       PR tree-optimization/37416
+       * gcc.dg/vect/pr36630.c: Expect 1 vectorized loop.
+
+2008-12-10 Uros Bizjak <ubizjak@gmail.com>
+
+       * gcc.dg/20020919-1.c: Correct target selector to alpha*-*-*.
+       * gcc.dg/pr31866.c: Ditto.
+       * gcc.dg/torture/type-generic-1.c: Add -mieee for alpha*-*-* targets.
+       * g++.dg/torture/type-generic-1.C: Ditto.
+       * gfortran.dg/boz_9.f90: Ditto.
+       * gfortran.dg/boz_14.f90: Ditto.
+       * gfortran.dg/init_flag_3.f90: Ditto.
+       * gfortran.dg/init_flag_4.f90: Ditto.
+       * gfortran.dg/init_flag_5.f90: Ditto.
+       * gfortran.dg/integer_exponentiation_1.f90: Ditto.
+       * gfortran.dg/integer_exponentiation_5.F90: Ditto.
+       * gfortran.dg/isnan_1.f90: Ditto.
+       * gfortran.dg/isnan_2.f90: Ditto.
+       * gfortran.dg/module_nan.f90: Ditto.
+       * gfortran.dg/nan_1.f90: Ditto.
+       * gfortran.dg/nan_2.f90: Ditto.
+       * gfortran.dg/nan_3.f90: Ditto.
+       * gfortran.dg/nan_4.f90: Ditto.
+       * gfortran.dg/namelist_42.f90: Ditto.
+       * gfortran.dg/namelist_43.f90: Ditto.
+       * gfortran.dg/nearest_1.f90: Ditto.
+       * gfortran.dg/nearest_2.f90: Ditto.
+       * gfortran.dg/nearest_3.f90: Ditto.
+       * gfortran.dg/pr37243.f: Ditto.
+       * gfortran.dg/real_const_3.f90: Ditto.
+       * gfortran.dg/transfer_simplify_2.f90: Ditto.
+       * gfortran.fortran-torture/execute/intrinsic_spacing.x: New file.
+
+       * gfortran.dg/default_format_denormal_1.f90: XFAIL on alpha.
+
+2008-12-09  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/37971
+       * g++.dg/overload/defarg2.C: New test.
+       * g++.dg/overload/defarg3.C: Likewise.
+
+2008-12-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/38454
+       * gcc.dg/memset-1.c: New test.
+       * gcc.dg/memcpy-2.c: New test.
+
+2008-12-09  Mikael Morin  <mikael.morin@tele2.fr>
+
+       PR fortran/35983
+       * gfortran.dg/pr35983.f90: New test.
+
+2008-12-09  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR testsuite/38420
+       * gcc.target/i386/pr37248-2.c: Support hex dump on 32bit host.
+       * gcc.target/i386/pr37248-3.c: Likewise.
+
+2008-12-09  Steve Ellcey  <sje@cup.hp.com>
+
+       PR testsuite/37326
+       * gcc.dg/tree-ssa/ssa-store-ccp-3.c: Skip on hppa*64-*-*.
+
+2008-12-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/35468
+       * gcc.dg/pr35468.c: New test.
+       * gcc.c-torture/compile/pr35468.c: New test.
+
+2008-12-08  Jason Merrill  <jason@redhat.com>
+
+       PR c++/38410
+       * gcc.dg/ctor1.c: New test.
+
+2008-12-09 Tobias Grosser  <grosser@fim.uni-passau.de>
+
+       PR middle-end/38084
+       * gfortran.dg/graphite/id-3.f90: New.
+       * gcc.dg/graphite/pr38084.c: New.
+
+2008-12-08  Uros Bizjak  <ubizjak@gmail.com>
+
+       * gcc.target/mips/fix-r10000-6.c: Add dg-message to look for
+       the note about changed semantics of NAND builtin.
+       * gcc.target/mips/fix-r10000-12.c: Ditto.
+       * gcc.target/mips/atomic-memory-1.c: Ditto.
+       (main): Correct __sync_nand_and_fetch results.
+
+2008-12-08  Dodji Seketeli  <dodji@redhat.com>
+
+       PR debug/38390
+       * g++.dg/debug/dwarf2/imported-module-2.C: New test.
+
+2008-12-08  Steve Ellcey  <sje@cup.hp.com>
+
+       * g++.dg/other/packed1.C: Remove ia64-hp-hpux* XFAIL.
+
+2008-12-08  Steve Ellcey  <sje@cup.hp.com>
+
+       * gcc.target/ia64/versionid-1.c (dg-final): Fix syntax.
+       * gcc.target/ia64/versionid-2.c (dg-final): Ditto.
+
+2008-12-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/35443
+       * gcc.dg/pr35443.c: New test.
+
+       PR c/35442
+       * gcc.dg/pr35442.c: New test.
+
+2008-12-07  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/string_comparison.adb: New test.
+
+2008-12-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR tree-optimization/38405
+       * gcc.dg/torture/pr38405.c: New.
+
+2008-12-07  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/aggr10.adb: New test.
+       * gnat.dg/aggr10_pkg.ads: New helper.
+
 2008-12-06  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/38425
 
 2008-09-24  Steve Ellcey  <sje@cup.hp.com>
 
-       *  gcc.dg/vect/O3-vect-pr34223.c: Check vect_int_mult.
+       * gcc.dg/vect/O3-vect-pr34223.c: Check vect_int_mult.
 
 2008-09-24  Aldy Hernandez  <aldyh@redhat.com>
 
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/imported-module-2.C b/gcc/testsuite/g++.dg/debug/dwarf2/imported-module-2.C
new file mode 100644 (file)
index 0000000..8612897
--- /dev/null
@@ -0,0 +1,18 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin: PR debug/38390
+// { dg-do compile  }
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler "DW_TAG_imported" }  }
+
+namespace A
+{
+  int v;
+}
+
+int
+f ()
+{
+  using namespace A;
+  return v;
+}
+
diff --git a/gcc/testsuite/g++.dg/ext/fixed2.C b/gcc/testsuite/g++.dg/ext/fixed2.C
new file mode 100644 (file)
index 0000000..a4766eb
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/35319
+// { dg-options "" }
+
+void foo()
+{
+  throw 0r;
+}
index 5d19eb0..b1b829b 100644 (file)
@@ -1,4 +1,4 @@
-// { dg-do run { xfail arm-*-* sh-*-* ia64-hp-hpux* } }
+// { dg-do run { xfail arm-*-* sh-*-* } }
 
 // NMS:2003-04-21 this fails on strict aligned architectures again,
 // the patch was reverted because it broke something more important.
diff --git a/gcc/testsuite/g++.dg/overload/defarg2.C b/gcc/testsuite/g++.dg/overload/defarg2.C
new file mode 100644 (file)
index 0000000..d8ecb2f
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/37971
+// { dg-do compile }
+
+class C {
+private:
+  static int f(int);
+  static int f(char);
+
+public:  
+  static void g(int (*)(int) = f);
+};
+
+void h() {
+  /* Although C::f is inaccessible here, it is accessible in the
+     context of C::g, so there is no error.  */
+  C::g();
+}
diff --git a/gcc/testsuite/g++.dg/overload/defarg3.C b/gcc/testsuite/g++.dg/overload/defarg3.C
new file mode 100644 (file)
index 0000000..6622e43
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/37971
+// { dg-do compile }
+
+class C {
+private:
+  static int f(int); // { dg-error "private" }
+  static int f(char);
+};
+
+class D {
+public:
+  /* C::f is inaccessible, so this is an error, even if this function
+     is never called.  */
+  static void g(int (*)(int) = C::f); // { dg-error "context" }
+};
index 7db2e69..e9c17c3 100644 (file)
@@ -2,7 +2,7 @@
    without any fast-math flags.  */
 
 /* { dg-do run } */
-/* { dg-options "-mieee" { target sh*-*-* } } */
+/* { dg-options "-mieee" { target alpha*-*-* sh*-*-* } } */
 /* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */
 
 #include "../../gcc.dg/tg-tests.h"
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr35468.c b/gcc/testsuite/gcc.c-torture/compile/pr35468.c
new file mode 100644 (file)
index 0000000..16d064b
--- /dev/null
@@ -0,0 +1,7 @@
+/* PR tree-optimization/35468 */
+
+void
+foo (void)
+{
+  *(char *) "c" = 'x';
+}
index 15519be..e0fab27 100644 (file)
@@ -8,7 +8,7 @@
    You must be this tall ---> fit two long longs in asm-declared registers
    to enter this amusement.  */
 
-/* { dg-do compile { target alpha-*-* cris-*-* crisv32-*-* i?86-*-* mmix-*-* powerpc*-*-* rs6000-*-* x86_64-*-* } } */
+/* { dg-do compile { target alpha*-*-* cris-*-* crisv32-*-* i?86-*-* mmix-*-* powerpc*-*-* rs6000-*-* x86_64-*-* } } */
 /* { dg-options "-O2" } */
 
 /* Constructed examples; input/output (same register), output, input, and
@@ -41,7 +41,7 @@
        || defined (__POWERPC__) || defined (PPC) || defined (_IBMR2)
 # define REG1 "6"
 # define REG2 "7"
-# ifndef __powerpc64__
+# if !defined(__powerpc64__) && !defined(__LP64__)
 #  define REG3 "8"
 #  define REG4 "9"
 # endif
diff --git a/gcc/testsuite/gcc.dg/ctor1.c b/gcc/testsuite/gcc.dg/ctor1.c
new file mode 100644 (file)
index 0000000..6c1cd72
--- /dev/null
@@ -0,0 +1,10 @@
+/* Related to PR c++/38410.
+   We shouldn't write out a static variable for an all-zero aggregate
+   initializer.  The variable named C.0 was created by
+   gimplify_init_constructor. */
+/* { dg-final { scan-assembler-not "C\\.0" } } */
+
+int main()
+{
+  int a[] = { 0,0 };
+}
index 039b974..857f8d5 100644 (file)
@@ -2,6 +2,8 @@
 
 #define MAX 8192
 
+void bar (void);
+
 int main()
 {
   int i, j;
@@ -9,6 +11,8 @@ int main()
   int A[MAX * MAX];
   int B[MAX * MAX];
 
+  bar ();
+
   for (i = 0; i < MAX; i++)
     for (j = 0; j < MAX; j++)
       {
@@ -20,6 +24,11 @@ int main()
     for (j = 0; j < MAX; j++)
       A[i*MAX + j] += B[j*MAX + i];
 
+  bar ();
+
+  /* FIXME: For now, reductions are not handled by the code generation
+     of graphite.  We have to bound the scop to the above loops.  */
+
   for(i = 0; i < MAX; i++)
     for(j = 0; j < MAX; j++)
       sum += A[i*MAX + j];
@@ -27,5 +36,5 @@ int main()
   return sum;
 }
 
-/* { dg-final { scan-tree-dump-times "Loop blocked" 3 "graphite"} } */ 
+/* { dg-final { scan-tree-dump-times "Loop blocked" 2 "graphite"} } */ 
 /* { dg-final { cleanup-tree-dump "graphite" } } */
diff --git a/gcc/testsuite/gcc.dg/graphite/block-2.c b/gcc/testsuite/gcc.dg/graphite/block-2.c
new file mode 100644 (file)
index 0000000..cf0969b
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */
+
+typedef unsigned char   UChar;
+typedef int             Int32;
+typedef unsigned int    UInt32;
+
+void fallbackSort ( UInt32* fmap, 
+                    UInt32* eclass, 
+                    Int32   nblock,
+                    Int32   verb )
+{
+   Int32 ftab[257];
+   Int32 ftabCopy[256];
+   Int32 H, i, j, k, l, r, cc, cc1;
+   Int32 nNotDone;
+   Int32 nBhtab;
+   UChar* eclass8 = (UChar*)eclass;
+
+   if (verb >= 4)
+      VPrintf0 ( "        bucket sorting ...\n" );
+   for (i = 0; i < 257;    i++) ftab[i] = 0;
+   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
+   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
+   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
+
+   for (i = 0; i < nblock; i++) {
+      j = eclass8[i] + ftab [i];
+   }
+   AssertH ( j < 256, 1005 );
+}
+/* { dg-final { scan-tree-dump-times "Loop blocked" 1 "graphite" { xfail *-*-* }} } */
+/* { dg-final { cleanup-tree-dump "graphite" } } */
diff --git a/gcc/testsuite/gcc.dg/graphite/block-4.c b/gcc/testsuite/gcc.dg/graphite/block-4.c
new file mode 100644 (file)
index 0000000..4b550b4
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */
+
+#define N 24
+#define M 1000
+
+float A[1000][1000], B[1000][1000], C[1000][1000];
+
+void test (void)
+{
+  int i, j, k;
+
+  /* These loops contain too few iterations for being strip-mined by 64.  */
+  for (i = 0; i < 24; i++)
+    for (j = 0; j < 24; j++)
+      for (k = 0; k < 24; k++)
+        A[i][j] = B[i][k] * C[k][j];
+
+  /* These loops should still be strip mined.  */
+  for (i = 0; i < 1000; i++)
+    for (j = 0; j < 1000; j++)
+      for (k = 0; k < 1000; k++)
+        A[i][j] = B[i][k] * C[k][j];
+}
+
+/* { dg-final { scan-tree-dump-times "Strip Mining is not profitable" 2 "graphite" } } */
+/* { dg-final { cleanup-tree-dump "graphite" } } */
diff --git a/gcc/testsuite/gcc.dg/graphite/block-5.c b/gcc/testsuite/gcc.dg/graphite/block-5.c
new file mode 100644 (file)
index 0000000..e0bd468
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */
+
+#define N 10000
+void foo (int);
+int test ()
+{
+  int a[N][N];
+  int b[N][N];
+  unsigned i, j;
+
+  for (i = 0; i < N; i++) 
+    for (j = 0; j < N; j++)
+      a[i][j] = i*j;
+
+  for (j = 1; j < N; j++) 
+    for (i = 0; i < N; i++)
+      a[i][j] = a[i][j-1] + b[i][j];
+
+  for (i = 0; i < N; i++) 
+    for (j = 0; j < N; j++) 
+      foo (a[i][j]); 
+}
+
+/* Interchange is legal for loops 0 and 1 of the first two SCoPs */
+/* { dg-final { scan-tree-dump-times "Interchange valid for loops 0 and 1:" 2 "graphite"} } */
+/* { dg-final { cleanup-tree-dump "graphite" } } */
diff --git a/gcc/testsuite/gcc.dg/graphite/block-6.c b/gcc/testsuite/gcc.dg/graphite/block-6.c
new file mode 100644 (file)
index 0000000..77429f1
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */
+
+#define N 10000
+void foo (int);
+int test ()
+{
+  int a[N][N];
+  unsigned i, j;
+
+  for (i = 0; i < N; i++) 
+    for (j = 0; j < N; j++)
+       a[i][j] = i*j;
+
+  for (i = 1; i < N; i++) 
+    for (j = 1; j < (N-1) ; j++)
+       a[i][j] = a[i-1][j+1] * a[i-1][j+1]/2;
+
+  for (i = 0; i < N; i++) 
+    for (j = 0; j < N; j++)
+      foo (a[i][j]); 
+}
+
+/* Interchange is not legal for loops 0 and 1 of SCoP 2.  */
+/* { dg-final { scan-tree-dump-times "Interchange not valid for loops 0 and 1:" 1 "graphite"} } */
+/* { dg-final { cleanup-tree-dump "graphite" } } */
index 6766191..cf0969b 100644 (file)
@@ -29,3 +29,4 @@ void fallbackSort ( UInt32* fmap,
    AssertH ( j < 256, 1005 );
 }
 /* { dg-final { scan-tree-dump-times "Loop blocked" 1 "graphite" { xfail *-*-* }} } */
+/* { dg-final { cleanup-tree-dump "graphite" } } */
index 35c3291..a9e6f5a 100644 (file)
@@ -63,3 +63,5 @@ int BZ2_bzCompressInit
    }
    prepare_new_block ( s );
 }
+
+/* { dg-final { cleanup-tree-dump "graphite" } } */
diff --git a/gcc/testsuite/gcc.dg/graphite/pr37883.c b/gcc/testsuite/gcc.dg/graphite/pr37883.c
new file mode 100644 (file)
index 0000000..2ab043a
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-options "-O3 -floop-block" } */
+
+void test_sort()
+{
+  char *base;
+  register char c, *i, *hi;
+
+  for (i = base; i < hi; i++)
+    *i++ = c;
+}
+
diff --git a/gcc/testsuite/gcc.dg/graphite/pr37928.c b/gcc/testsuite/gcc.dg/graphite/pr37928.c
new file mode 100644 (file)
index 0000000..47ad5bc
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-options "-O3 -floop-block" } */
+
+int get_state(int size, int *node, int *hash)
+{
+  int i=0;
+  while(hash[i])
+    {
+     if(node[hash[i]] == 0)
+           return hash[i]-1;
+      i++;
+     if(i==5)
+       i=0;
+    }
+  return -1;
+}
+
+void foo (int);
+
+int gate1(int size, int *node, int *hash)
+{
+  int i, j ;
+  int add_size=0;
+  for(i=0; i<size; i++)
+  {
+     j = get_state(size,node, hash);
+     if(j == -1)
+     {
+       add_size++;
+     }
+  }
+
+  foo (size+add_size);
+}
diff --git a/gcc/testsuite/gcc.dg/graphite/pr38073.c b/gcc/testsuite/gcc.dg/graphite/pr38073.c
new file mode 100644 (file)
index 0000000..9c48d8d
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-options "-O3 -fgraphite-identity" } */
+
+test_seg(int a, int b)
+{
+  int i,r=1;
+  for(i=0; i<b ;i++)
+    r*=a;
+  return r;
+}
diff --git a/gcc/testsuite/gcc.dg/graphite/pr38084.c b/gcc/testsuite/gcc.dg/graphite/pr38084.c
new file mode 100644 (file)
index 0000000..7193f96
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-options "-O3 -fgraphite-identity" } */
+
+typedef struct {
+  unsigned int avail_out;
+  void *state;
+} stream;
+
+typedef struct {
+  stream* test;
+  int num;
+} state_in;
+
+int test_in ( stream *test, int action )
+{
+  state_in* tst;
+  if (test == ((void *)0)) return (-2);
+  if (tst == ((void *)0)) return (-2);
+  if (tst->test != test) return (-2);
+ jump_here:
+  switch (tst->num) {
+  case 1:
+    return (-1);
+  case 2:
+    if (action == 0) {
+    }
+    if (action == 1) {
+      goto jump_here;
+    }
+  }
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/graphite/pr38125.c b/gcc/testsuite/gcc.dg/graphite/pr38125.c
new file mode 100644 (file)
index 0000000..780e6f6
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-options "-O3 -fgraphite-identity" } */
+
+typedef struct sv TEST_SV;
+typedef struct av TEST_AV;
+typedef struct magic TEST_MAGIC;
+typedef struct xpvav TEST_XPVAV;
+struct sv 
+{
+    void* sv_any;
+};
+struct av 
+{
+    TEST_XPVAV* sv_any;
+};
+struct xpvav 
+{
+    char* xav_array;
+    long int xav_fill;
+    long int xav_max;
+};
+struct magic {
+    TEST_SV* mg_obj;
+};
+extern TEST_SV PL_sv_undef;
+Perl_av_fill( register TEST_AV *av, int fill)
+{
+    TEST_MAGIC *mg;
+    int key = ((TEST_XPVAV*) (av)->sv_any)->xav_fill;
+    TEST_SV** ary = ((TEST_SV**)((TEST_XPVAV*) (av)->sv_any)->xav_array);
+    while (key < fill)
+          ary[++key] = &PL_sv_undef;
+}
diff --git a/gcc/testsuite/gcc.dg/graphite/pr38413.c b/gcc/testsuite/gcc.dg/graphite/pr38413.c
new file mode 100644 (file)
index 0000000..6c2b23a
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-options "-O2 -fgraphite-identity" } */
+
+static int qsz;
+
+void specqsort(base, n, size, compar)
+     char *base;
+{
+  register char c, *i, *j, *lo, *hi;
+  qsz = size;
+  for (i = base, hi = base + qsz; i < hi; ) 
+    {
+      *i++ = c;
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/graphite/pr38446.c b/gcc/testsuite/gcc.dg/graphite/pr38446.c
new file mode 100644 (file)
index 0000000..b7b346c
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-options "-O2 -fgraphite-identity" } */
+
+void copy_data()
+{
+  int ****source;
+  int ****dest;
+
+  int i, j, k, l;
+  for (i = 0; i < 10; i++)
+      for (k = 0; k < 2; k++)
+        for (l = 0; l < 65; l++)
+          source[i][j][k][l] = dest[i][j][k][l];
+}
+
index 7e24253..9324631 100644 (file)
@@ -48,5 +48,6 @@ int longest_match(IPos cur_match)
             && --chain_length != 0);
     return best_len;
 }
+
 /* { dg-final { scan-tree-dump-times "number of SCoPs: 0" 1 "graphite"} } */
 /* { dg-final { cleanup-tree-dump "graphite" } } */
index 42f7b6a..d0b32f6 100644 (file)
@@ -1,4 +1,5 @@
-/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */
+/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */
+
 #define N 10000
 void foo (int);
 int test ()
@@ -20,6 +21,5 @@ int test ()
       foo (a[i][j]); 
 }
 
-/* Interchange is legal for loops 0 and 1 of the first two SCoPs */
-/* { dg-final { scan-tree-dump-times "Interchange valid for loops 0 and 1:" 2 "graphite"} } */
+/* { dg-final { scan-tree-dump-times "number of SCoPs: 2" 1 "graphite"} } */
 /* { dg-final { cleanup-tree-dump "graphite" } } */
index 4c1b0ca..c2fec3f 100644 (file)
@@ -1,4 +1,5 @@
-/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */
+/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */
+
 #define N 10000
 void foo (int);
 int test ()
@@ -19,6 +20,5 @@ int test ()
       foo (a[i][j]); 
 }
 
-/* Interchange is not legal for loops 0 and 1 of SCoP 2.  */
-/* { dg-final { scan-tree-dump-times "Interchange not valid for loops 0 and 1:" 1 "graphite"} } */
+/* { dg-final { scan-tree-dump-times "number of SCoPs: 2" 1 "graphite"} } */
 /* { dg-final { cleanup-tree-dump "graphite" } } */
index fe2d5f4..6264116 100644 (file)
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -floop-block -fdump-tree-graphite-all" } */
+/* { dg-options "-O2 -fgraphite -fdump-tree-graphite-all" } */
 
 #define N 24
 #define M 1000
@@ -13,14 +13,14 @@ void test (void)
   for (i = 0; i < 24; i++)
     for (j = 0; j < 24; j++)
       for (k = 0; k < 24; k++)
-        A[i][j] += B[i][k] * C[k][j];
+        A[i][j] = B[i][k] * C[k][j];
 
   /* These loops should still be strip mined.  */
   for (i = 0; i < 1000; i++)
     for (j = 0; j < 1000; j++)
       for (k = 0; k < 1000; k++)
-        A[i][j] += B[i][k] * C[k][j];
+        A[i][j] = B[i][k] * C[k][j];
 }
 
-/* { dg-final { scan-tree-dump-times "Strip Mining is not profitable" 3 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "number of SCoPs: 2" 1 "graphite"} } */ 
 /* { dg-final { cleanup-tree-dump "graphite" } } */
diff --git a/gcc/testsuite/gcc.dg/memcpy-2.c b/gcc/testsuite/gcc.dg/memcpy-2.c
new file mode 100644 (file)
index 0000000..24464ab
--- /dev/null
@@ -0,0 +1,25 @@
+/* PR middle-end/38454 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern inline __attribute__((gnu_inline, always_inline, artificial)) void *
+memcpy (void *__restrict dest, const void *__restrict src, size_t len)
+{
+  return __builtin___memcpy_chk (dest, /* { dg-warning "will always overflow destination buffer" } */
+                                src, len, __builtin_object_size (dest, 0));
+}
+
+struct S { char buf[10]; } s;
+
+void
+foo (void)
+{
+  char buf[12];
+  char *p = buf + 4;
+  struct S *q = (struct S *) p;
+  memcpy (q, &s, sizeof (s));
+}
+
+/* { dg-final { scan-assembler "__memcpy_chk" } } */
diff --git a/gcc/testsuite/gcc.dg/memset-1.c b/gcc/testsuite/gcc.dg/memset-1.c
new file mode 100644 (file)
index 0000000..677ae91
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern void warn_memset_zero_len (void)
+__attribute__((__warning__ ("memset used with constant zero length parameter;"
+                           " this could be due to transposed parameters")));
+
+extern inline __attribute__((gnu_inline, always_inline, artificial)) void *
+memset (void *dest, int ch, size_t len)
+{
+  if (__builtin_constant_p (len) && len == 0)
+    {
+      warn_memset_zero_len (); /* { dg-warning "memset used with constant zero" } */
+      return dest;
+    }
+  return __builtin_memset (dest, ch, len);
+}
+
+char buf[10];
+
+int
+main (void)
+{
+  memset (buf, sizeof (buf), 0);
+  return 0;
+}
index f1afd93..4081c0e 100644 (file)
@@ -1,5 +1,5 @@
 /* PR tree-optimization/31866 */
-/* { dg-do compile { target alpha-*-* cris-*-* crisv32-*-* i?86-*-* mmix-*-* powerpc*-*-* rs6000-*-* x86_64-*-* } } */
+/* { dg-do compile { target alpha*-*-* cris-*-* crisv32-*-* i?86-*-* mmix-*-* powerpc*-*-* rs6000-*-* x86_64-*-* } } */
 /* { dg-options "-O2" } */
 
 #if defined (__alpha__)
diff --git a/gcc/testsuite/gcc.dg/pr35442.c b/gcc/testsuite/gcc.dg/pr35442.c
new file mode 100644 (file)
index 0000000..4f1e3cc
--- /dev/null
@@ -0,0 +1,11 @@
+/* PR c/35442 */
+/* { dg-bogus "not supported by" "" { target *-*-* } 0 } */
+
+typedef char A __attribute__ ((vector_size (64)));
+typedef int B __attribute__ ((vector_size (64)));
+
+void
+foo (A a)
+{
+  ((B) a) ();  /* { dg-error "is not a function" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr35443.c b/gcc/testsuite/gcc.dg/pr35443.c
new file mode 100644 (file)
index 0000000..5dfc299
--- /dev/null
@@ -0,0 +1,9 @@
+/* PR c/35443 */
+/* { dg-options "" } */
+/* { dg-bogus "not supported by" "" { target *-*-* } 0 } */
+
+void
+foo ()
+{
+  ({ int i; i; })();   /* { dg-error "is not a function" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr35468.c b/gcc/testsuite/gcc.dg/pr35468.c
new file mode 100644 (file)
index 0000000..085c073
--- /dev/null
@@ -0,0 +1,10 @@
+/* PR tree-optimization/35468 */
+/* { dg-do compile  }*/
+/* { dg-options "-O2 -fno-tree-dce" } */
+
+char *const f(void)
+{
+  char *const line = "/dev/ptyXX";
+  line[8] = 1;
+  return line;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr38271.c b/gcc/testsuite/gcc.dg/torture/pr38271.c
new file mode 100644 (file)
index 0000000..2c64a9b
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-Wuninitialized" } */
+
+struct xxx {
+    short a;
+    short b;
+    void *c;
+};
+
+void bar(struct xxx);
+
+void foo(struct xxx *p, int i)
+{
+  struct xxx s0 = *p;
+  struct xxx s = s0;
+  if (s.a) i++;
+  bar(s);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr38405.c b/gcc/testsuite/gcc.dg/torture/pr38405.c
new file mode 100644 (file)
index 0000000..3f93445
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+extern void abort ();
+extern int printf (char *__format, ...);
+
+struct vpiBinaryConst {
+ int signed_flag :1;
+ int sized_flag :1;
+};
+
+int binary_get(int code, struct vpiBinaryConst *rfp)
+{
+ switch (code) {
+  case 1:
+   return rfp->signed_flag ? 1 : 0;
+  default:
+   printf("error: %d not supported\n", code);
+   return code;
+ }
+}
+
+int main(void)
+{
+ struct vpiBinaryConst x={1,0};
+ int y=binary_get(1, &x);
+ if (y!=1)
+   abort ();
+ return 0;
+}
index 9a8e9d0..96b5d01 100644 (file)
@@ -2,7 +2,7 @@
    without any fast-math flags.  */
 
 /* { dg-do run } */
-/* { dg-options "-mieee" { target sh*-*-* } } */
+/* { dg-options "-mieee" { target alpha*-*-* sh*-*-* } } */
 /* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */
 
 #include "../tg-tests.h"
index cfbb9c9..a27f2d6 100644 (file)
@@ -4,6 +4,8 @@
 union loc {  unsigned reg; signed offset; };
 void __frame_state_for (volatile char *state_in, int x)
 {
+  /* We should move all the loads out of this loop. Right now, we only
+     move one.  It takes two insertions because we insert a cast.  */
     union loc fs;
     int reg;
     for (;;)     {
@@ -16,5 +18,5 @@ void __frame_state_for (volatile char *state_in, int x)
     }
 }
 
-/* { dg-final { scan-tree-dump-not "Insertions:" "pre" } } */
+/* { dg-final { scan-tree-dump "Insertions: 2" "pre" } } */
 /* { dg-final { cleanup-tree-dump "pre" } } */
index 01eb785..1db56a1 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-skip-if "" { *-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { *-*-darwin* hppa*64*-*-* } { "*" } { "" } } */
 /* { dg-options "-O2 -fno-common -fdump-tree-optimized" } */
 
 const int conststaticvariable;
index 752c4f6..5eb01eb 100644 (file)
@@ -114,7 +114,7 @@ int main (void)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  {target { vect_strided && vect_int_mult } } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" {target { vect_strided && vect_int_mult } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect"  {target { vect_strided && vect_int_mult } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" {target { vect_strided && vect_int_mult } } } } */
 /* { dg-final { cleanup-tree-dump "vect" } } */
   
index 9d85aff..2253f75 100644 (file)
@@ -13,4 +13,5 @@ foo (unsigned char *x, short y)
       i = i + 1;
     }
 }
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
 /* { dg-final { cleanup-tree-dump "vect" } } */
index 25fb106..ed48383 100644 (file)
@@ -19,5 +19,5 @@ foo (struct S x)
   return x.a && x.g && x.b && x.f && x.c && x.e;
 }
 
-/* { dg-final { scan-tree-dump "& 3758096391\[^\n\t\]*== 3758096391" "optimized" } } */
+/* { dg-final { scan-tree-dump "& (3758096391|0x0e0000007)\[^\n\t\]*== (3758096391|0x0e0000007)" "optimized" } } */
 /* { dg-final { cleanup-tree-dump "optimized" } } */
index d5d2d98..3b320d7 100644 (file)
@@ -21,5 +21,5 @@ foo (struct S x)
   return x.a && x.i && x.b && x.h && x.c && x.g && x.e == 131;
 }
 
-/* { dg-final { scan-tree-dump "& 3766484487\[^\n\t\]*== 3758163463" "optimized" } } */
+/* { dg-final { scan-tree-dump "& (3766484487|0x0e07ffe07)\[^\n\t\]*== (3758163463|0x0e0010607)" "optimized" } } */
 /* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr38240.c b/gcc/testsuite/gcc.target/i386/pr38240.c
new file mode 100644 (file)
index 0000000..6a35687
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+typedef float V
+  __attribute__ ((__vector_size__ (16), __may_alias__));
+
+V __attribute__((target("sse"))) f(const V *ptr) { return *ptr; }
+
+V g(const V *ptr) { return *ptr; }
index 7a461da..4ee8224 100644 (file)
@@ -7,4 +7,4 @@ int bar(int i)
        return (foo() + 1);
 }
 
-/* { dg-final { scan-assembler "alias.*foo.*foo{20040821}" } } */
+/* { dg-final { scan-assembler "alias.*foo.*foo\\\{20040821\\\}" } } */
index 5a90aed..258de09 100644 (file)
@@ -7,4 +7,4 @@ int foo(int i)
        return (1);
 }
 
-/* { dg-final { scan-assembler "alias.*foo.*foo{20040821}" } } */
+/* { dg-final { scan-assembler "alias.*foo.*foo\\\{20040821\\\}" } } */
index e9a95ea..b2316ee 100644 (file)
@@ -1,4 +1,7 @@
 /* { dg-do run } */
+
+/* { dg-message "note: '__sync_nand_and_fetch' changed semantics in GCC 4.4" "" { target *-*-* } 0 } */
+
 extern void abort (void);
 extern void exit (int);
 
@@ -16,9 +19,9 @@ NOMIPS16 int main ()
   __sync_sub_and_fetch (&v, 0x7fff);
   if (v != 34465)
     abort();
-  if (__sync_nand_and_fetch (&v, 0xff) != 94)
+  if (__sync_nand_and_fetch (&v, 0xff) != -162)
     abort();
-  if (__sync_fetch_and_add (&v, 6) != 94)
+  if (__sync_fetch_and_add (&v, 262) != -162)
     abort();
   if (v != 100)
     abort();
index 0381c24..160f9ae 100644 (file)
@@ -2,6 +2,8 @@
 /* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
 /* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
 
+/* { dg-message "note: '__sync_nand_and_fetch' changed semantics in GCC 4.4" "" { target *-*-* } 0 } */
+
 NOMIPS16 int
 f1 (int *z)
 {
index 2751369..1f81e5b 100644 (file)
@@ -2,6 +2,8 @@
 /* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
 /* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
 
+/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "" { target *-*-* } 0 } */
+
 NOMIPS16 int
 f1 (int *z)
 {
index a6690ce..dd7e58e 100644 (file)
@@ -1,4 +1,5 @@
 ! { dg-do run }
+! { dg-options "-mieee" { target alpha*-*-* } } 
 
 ! PR fortran/36214
 ! For BOZ-initialization of floats, the precision used to be wrong sometimes.
index 1488c6d..db35da0 100644 (file)
@@ -1,5 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-fno-range-check" }
+! { dg-options "-fno-range-check -mieee" { target alpha*-*-* } } 
 !
 ! PR fortran/34342
 !
index 181ae9d..c4d6086 100644 (file)
@@ -1,4 +1,4 @@
-! { dg-do run { xfail *-*-darwin[89]* *-*-freebsd* *-*-mingw* } }
+! { dg-do run { xfail alpha*-*-* *-*-darwin[89]* *-*-freebsd* *-*-mingw* } }
 ! Test XFAILed on these platforms because the system's printf() lacks
 ! proper support for denormals.
 !
diff --git a/gcc/testsuite/gfortran.dg/graphite/id-2.f90 b/gcc/testsuite/gfortran.dg/graphite/id-2.f90
new file mode 100644 (file)
index 0000000..0c9f54b
--- /dev/null
@@ -0,0 +1,15 @@
+! { dg-options "-O2 -fgraphite-identity" }
+
+module solv_cap
+  integer, parameter, public :: dp = selected_real_kind(5)
+contains
+  subroutine prod0( G, X )
+    real(kind=dp), intent(in out), dimension(:,:)    :: X
+    real(kind=dp), dimension(size(X,1),size(X,2)) :: Y
+    X = Y
+  end subroutine prod0
+  function Ginteg(xq1,yq1, xq2,yq2, xp,yp)  result(G)
+  end function Ginteg
+  subroutine fourir(A,ntot,kconjg, E,useold)
+  end subroutine fourir
+end module solv_cap
diff --git a/gcc/testsuite/gfortran.dg/graphite/id-3.f90 b/gcc/testsuite/gfortran.dg/graphite/id-3.f90
new file mode 100644 (file)
index 0000000..394bdf7
--- /dev/null
@@ -0,0 +1,21 @@
+! { dg-options "-O2 -fgraphite-identity" }
+
+subroutine gentrs (ptrst, ncls, xmin, dcls, xdont, ndon) 
+do icls1 = 1, ncls
+   prec:    do
+      select case (isns)
+      case (-1)
+         do icls = icls1, 1, -1
+         enddo
+      case (+1)
+         do icls = icls1, ncls
+            if (xale > rtrst (icls1, icls)) then
+            endif
+         enddo
+      end select
+   enddo prec
+enddo
+contains
+real function genuni (jsee)
+end function genuni
+end subroutine gentrs
diff --git a/gcc/testsuite/gfortran.dg/graphite/id-4.f90 b/gcc/testsuite/gfortran.dg/graphite/id-4.f90
new file mode 100644 (file)
index 0000000..896d608
--- /dev/null
@@ -0,0 +1,34 @@
+! { dg-options "-O2 -fgraphite-identity" }
+
+MODULE Vcimage
+  CHARACTER (LEN=80), SAVE :: CARD, FIELD
+END MODULE Vcimage
+MODULE Vimage
+  LOGICAL, SAVE ::  EOFF
+END MODULE Vimage
+SUBROUTINE READIN(PROB, TITLE, CSTOP, FCYCLE, DCYCLE, DHIST, VHIST&
+     &    , IMAX, PHIST, DEBUG, NSTAT, STATS, MAXSTA, NCORE, PPLOT,     &
+     &    DPLOT, VPLOT, TPLOT, SLIST, D0, E0, NODES, SHEAT, GAMMA, COLD &
+     &    , THIST, NVISC, SCREEN, WEIGHT, TSTOP, STABF)
+  USE Vcimage
+  USE Vimage
+  INTEGER, DIMENSION(MAXSTA) :: STATS
+  IF (.NOT.EOFF) THEN
+     IF (FIELD=='PROB' .OR. FIELD=='PROBLEM_NUMBER') THEN
+        CALL QSORT (STATS(1:NSTAT))
+        WRITE (16,                                                 &
+             &'(//'' YOU HAVE REQUESTED A PRINTOUT OF THE STATION'',            &
+             &    '' ABORT''//)')
+     ENDIF
+  ENDIF
+CONTAINS
+  RECURSIVE SUBROUTINE QSORT (LIST)
+    INTEGER, DIMENSION(:), INTENT(INOUT) :: LIST
+    INTEGER, DIMENSION(SIZE(LIST)) :: SMALLER,LARGER
+    IF (SIZE(LIST) > 1) THEN
+       LIST(NUMBER_SMALLER+1:NUMBER_SMALLER+NUMBER_EQUAL) = CHOSEN
+       CALL QSORT (LARGER(1:NUMBER_LARGER))
+       LIST(NUMBER_SMALLER+NUMBER_EQUAL+1:) = LARGER(1:NUMBER_LARGER)
+    END IF
+  END SUBROUTINE QSORT
+END SUBROUTINE READIN
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr37852.f90 b/gcc/testsuite/gfortran.dg/graphite/pr37852.f90
new file mode 100644 (file)
index 0000000..50e2342
--- /dev/null
@@ -0,0 +1,13 @@
+! { dg-options "-O2 -floop-block" }
+
+PROGRAM TEST_FPU
+CHARACTER (LEN=36) :: invert_id(1) = &
+                      (/ 'Test1 - Gauss 2000 (101x101) inverts'/)
+END PROGRAM TEST_FPU
+
+SUBROUTINE Gauss (a,n)
+INTEGER, PARAMETER :: RK8 = SELECTED_REAL_KIND(15, 300)
+REAL(RK8) :: a(n,n)
+INTEGER ::  ipvt(n)
+a(:,ipvt) = b
+END SUBROUTINE Gauss
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr37857.f90 b/gcc/testsuite/gfortran.dg/graphite/pr37857.f90
new file mode 100644 (file)
index 0000000..de2d3a1
--- /dev/null
@@ -0,0 +1,9 @@
+! { dg-options "-O2 -floop-block" }
+
+program superficie_proteina
+  integer, parameter :: LONGreal = selected_real_kind(12,90)
+  integer :: number_of_polypeptides, maximum_polypeptide_length
+  real (kind = LONGreal), dimension (:,:), allocatable :: individual_conformations
+  allocate (individual_conformations(-number_of_bins:0,number_of_polypeptides))
+  individual_conformations = 0.0_LONGreal
+end program superficie_proteina
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr37980.f90 b/gcc/testsuite/gfortran.dg/graphite/pr37980.f90
new file mode 100644 (file)
index 0000000..5306aa8
--- /dev/null
@@ -0,0 +1,11 @@
+! { dg-options "-O2 -floop-block" }
+
+module INT_MODULE
+contains
+  pure function spher_cartesians(in1) result(out1)
+    integer(kind=kind(1)) :: in1 
+    intent(in) :: in1 
+    real(kind=kind(1.0d0)), dimension(0:in1,0:in1,0:in1) :: mat0
+    mat0 = 0.0d0
+  end function spher_cartesians
+end module INT_MODULE
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr38083.f90 b/gcc/testsuite/gfortran.dg/graphite/pr38083.f90
new file mode 100644 (file)
index 0000000..834d33a
--- /dev/null
@@ -0,0 +1,16 @@
+! { dg-options "-O3 -floop-block" }
+
+SUBROUTINE IVSORT (IL,IH,NSEGS,IOUNIT)
+  INTEGER IOUNIT  
+
+  INTEGER, PARAMETER :: MAXGS = 32
+
+10 IF (IL .GE. IH) GO TO 80
+20 NSEGS = (IH + IL) / 2
+  IF (NSEGS .GT. MAXSGS) THEN
+     WRITE (IOUNIT),MAXSGS
+  ENDIF
+80 NSEGS = NSEGS - 1
+90 IF (IH - IL .GE. 11) GO TO 20
+110 IF (IL .EQ. IH) GO TO 80
+END SUBROUTINE IVSORT
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr38459.f90 b/gcc/testsuite/gfortran.dg/graphite/pr38459.f90
new file mode 100644 (file)
index 0000000..1feb6e5
--- /dev/null
@@ -0,0 +1,14 @@
+! { dg-options "-O2 -fgraphite-identity" }
+# 1 "mltfftsg.F"
+# 1 "<built-in>"
+SUBROUTINE mltfftsg ( a, ldax, lday, b, ldbx, ldby, &
+                      n, m)
+  INTEGER, PARAMETER :: dbl = SELECTED_REAL_KIND ( 14, 200 )
+
+! Arguments
+  INTEGER, INTENT ( IN ) :: ldbx, ldby, n, m
+  COMPLEX ( dbl ), INTENT ( INOUT ) :: b ( ldbx, ldby )
+
+   B(N+1:LDBX,1:M) = CMPLX(0._dbl,0._dbl,dbl)
+    
+END SUBROUTINE mltfftsg
index 7d6ab33..9724d39 100644 (file)
@@ -1,6 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-finit-integer=-1 -finit-logical=false -finit-real=nan" }
-! { dg-options "-mieee -finit-integer=-1 -finit-logical=false -finit-real=nan" { target sh*-*-* } }
+! { dg-options "-finit-integer=-1 -finit-logical=false -finit-real=nan -mieee" { target alpha*-*-* sh*-*-* } }
 
 program init_flag_3
   call real_test
index 8ec40bc..8e1265e 100644 (file)
@@ -1,5 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-finit-real=inf" }
+! { dg-options "-finit-real=inf -mieee" { target alpha*-*-* } } */
 
 program init_flag_4
   call real_test
index 51dbd16..5531251 100644 (file)
@@ -1,5 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-finit-real=-inf" }
+! { dg-options "-finit-real=-inf -mieee" { target alpha*-*-* } } */
 
 program init_flag_5
   call real_test
index bed7c6a..77ef84c 100644 (file)
@@ -1,4 +1,5 @@
 ! { dg-do run }
+! { dg-options "-pedantic -mieee" { target alpha*-*-* } }
 ! PR 30981 - this used to go into an endless loop during execution.
 program test
   a = 3.0
index 07127c6..2fc8df3 100644 (file)
@@ -1,5 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-fno-range-check" }
+! { dg-options "-fno-range-check -mieee" { target alpha*-*-* } } */
 module mod_check
   implicit none
 
index db8f569..3c0cce8 100644 (file)
@@ -1,7 +1,7 @@
 ! Test for the ISNAN intrinsic
 !
 ! { dg-do run }
-! { dg-options "-pedantic-errors -mieee" { target sh*-*-* } }
+! { dg-options "-pedantic-errors -mieee" { target alpha*-*-* sh*-*-* } }
 !
   implicit none
   real :: x
index e16ce9d..37b5363 100644 (file)
@@ -2,7 +2,7 @@
 !
 ! { dg-do run }
 ! { dg-options "-fno-range-check" }
-! { dg-options "-fno-range-check -pedantic-errors -mieee" { target sh*-*-* } }
+! { dg-options "-fno-range-check -pedantic-errors -mieee" { target alpha*-*-* sh*-*-* } }
 !
   implicit none
   character(len=1) :: s
diff --git a/gcc/testsuite/gfortran.dg/matmul_argument_types.f90 b/gcc/testsuite/gfortran.dg/matmul_argument_types.f90
new file mode 100644 (file)
index 0000000..1480655
--- /dev/null
@@ -0,0 +1,32 @@
+! { dg-do compile }
+!
+! PR fortran/36355
+! Check MATMUL argument types:
+!
+!           numeric   logical   other
+! numeric      1         2        3
+! logical      2         1        3
+! other        3         3        3
+!
+! where
+!   1    ok
+!   2    argument type mismatch
+!   3    invalid argument types
+!
+
+  INTEGER :: a(2,2)
+  LOGICAL :: b(2,2)
+  CHARACTER :: c
+
+  a = MATMUL(a, a)            ! ok
+  a = MATMUL(a, b)            ! { dg-error "must match" }
+  a = MATMUL(a, c)            ! { dg-error "must be numeric or LOGICAL" }
+
+  b = MATMUL(b, a)            ! { dg-error "must match" }
+  b = MATMUL(b, b)            ! ok
+  b = MATMUL(b, c)            ! { dg-error "must be numeric or LOGICAL" }
+
+  c = MATMUL(c, a)            ! { dg-error "must be numeric or LOGICAL" }
+  c = MATMUL(c, b)            ! { dg-error "must be numeric or LOGICAL" }
+  c = MATMUL(c, c)            ! { dg-error "must be numeric or LOGICAL" }
+END
index 956b90c..52fa8a9 100644 (file)
@@ -1,6 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-fno-range-check" }
-! { dg-options "-fno-range-check -mieee" { target sh*-*-* } }
+! { dg-options "-fno-range-check -mieee" { target alpha*-*-* sh*-*-* } }
 !
 ! PR fortran/34318
 !
index 55dd2ca..1aa75ab 100644 (file)
@@ -1,5 +1,5 @@
 ! { dg-do run { target fd_truncate } }
-! { dg-options "-mieee" { target sh*-*-* } }
+! { dg-options "-mieee" { target alpha*-*-* sh*-*-* } }
 !
 ! PR fortran/34427
 !
index abad355..ad518dd 100644 (file)
@@ -1,5 +1,5 @@
 ! { dg-do run { target fd_truncate } }
-! { dg-options "-mieee" { target sh*-*-* } }
+! { dg-options "-mieee" { target alpha*-*-* sh*-*-* } }
 !
 ! PR fortran/34427
 !
index 0c9eb04..6b7e19f 100644 (file)
@@ -2,7 +2,7 @@
 ! as arguments
 !
 ! { dg-do run }
-! { dg-options "-pedantic-errors -mieee" { target sh*-*-* } } 
+! { dg-options "-pedantic-errors -mieee" { target alpha*-*-* sh*-*-* } } 
 !
 module aux2
   interface isnan
index 49e1c39..3098771 100644 (file)
@@ -1,6 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-fno-range-check -pedantic" }
-! { dg-options "-fno-range-check -pedantic -mieee" { target sh*-*-* } }
+! { dg-options "-fno-range-check -pedantic -mieee" { target alpha*-*-* sh*-*-* } }
 !
 ! PR fortran/34333
 !
index 957b94d..adc9276 100644 (file)
@@ -1,6 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-fno-range-check" }
-! { dg-options "-fno-range-check -mieee" { target sh*-*-* } }
+! { dg-options "-fno-range-check -mieee" { target alpha*-*-* sh*-*-* } }
 !
 ! PR fortran/34319
 !
index 771aad0..7c37671 100644 (file)
@@ -1,6 +1,6 @@
 ! { dg-do compile }
 ! { dg-options "-std=gnu" } 
-! { dg-options "-std=gnu -mieee" { target sh*-*-* } } 
+! { dg-options "-std=gnu -mieee" { target alpha*-*-* sh*-*-* } } 
 !
 ! PR fortran/34398.
 !
index c80f3a6..64e2b85 100644 (file)
@@ -1,5 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-O0 -ffloat-store" }
+! { dg-options "-O0 -ffloat-store -mieee" { target alpha*-*-* } }
 ! PR fortran/27021
 ! Original code submitted by Dominique d'Humieres
 ! Converted to Dejagnu for the testsuite by Steven G. Kargl
index 08c7744..8bb4768 100644 (file)
@@ -1,6 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-fno-range-check" }
-! { dg-options "-fno-range-check -mieee" { target sh*-*-* } }
+! { dg-options "-fno-range-check -mieee" { target alpha*-*-* sh*-*-* } }
 !
 ! PR fortran/34192
 !
index 4262a8c..3af4cfc 100644 (file)
@@ -1,5 +1,5 @@
 ! { dg-do run }
-! { dg-options "-pedantic-errors -mieee" { target sh*-*-* } } 
+! { dg-options "-pedantic-errors -mieee" { target alpha*-*-* sh*-*-* } } 
 !
 ! PR fortran/34209
 !
diff --git a/gcc/testsuite/gfortran.dg/pr35983.f90 b/gcc/testsuite/gfortran.dg/pr35983.f90
new file mode 100644 (file)
index 0000000..5cc3855
--- /dev/null
@@ -0,0 +1,24 @@
+! { dg-do run }
+!
+! PR fortran/35983
+! C_LOC expanded to a NULL_PTR expr if called from a structure constructor
+!
+! Contributed by François-Xavier Coudert
+
+program main
+   use ISO_C_BINDING
+   implicit none
+   type, bind(C) :: descr
+      type(C_PTR) :: address
+   end type descr
+   type(descr) :: DD
+   double precision, target :: buf(1)
+   integer (C_INTPTR_T) :: i, j
+
+   buf = (/ 0 /)
+   DD = descr(c_loc(buf))
+   i = transfer (DD%address, 0_c_intptr_t)
+   j = transfer (c_loc(buf), 0_c_intptr_t)
+   if (any((/ i,j /) == 0_c_intptr_t)) call abort
+   if (i /= j) call abort
+end program main
index 143800c..ba65212 100644 (file)
@@ -1,5 +1,6 @@
 ! PR rtl-optimization/37243
 ! { dg-do run }
+! { dg-options "-mieee" { target alpha*-*-* } }
 ! Check if register allocator handles IR flattening correctly.
       SUBROUTINE SCHMD(V,M,N,LDV)
       IMPLICIT DOUBLE PRECISION(A-H,O-Z)
index a05986f..90e8208 100644 (file)
@@ -1,6 +1,6 @@
 !{ dg-do run }
 !{ dg-options "-fno-range-check" }
-!{ dg-options "-fno-range-check -mieee" { target sh*-*-* } }
+!{ dg-options "-fno-range-check -mieee" { target alpha*-*-* sh*-*-* } }
 ! PR19310 and PR19904, allow disabling range check during compile.
 ! Contributed by Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 program main
index 96bf283..dbad84e 100644 (file)
@@ -1,5 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-O2" }
+! { dg-options "-O2 -mieee" { target alpha*-*-* } }
 ! Tests the fix for the meta-bug PR31237 (TRANSFER intrinsic)
 ! Exercises gfc_simplify_transfer a random walk through types and shapes
 ! and compares its results with the middle-end version that operates on
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_spacing.x b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_spacing.x
new file mode 100644 (file)
index 0000000..dad399d
--- /dev/null
@@ -0,0 +1,2 @@
+add-ieee-options
+return 0
diff --git a/gcc/testsuite/gnat.dg/aggr10.adb b/gcc/testsuite/gnat.dg/aggr10.adb
new file mode 100644 (file)
index 0000000..6fbb8ed
--- /dev/null
@@ -0,0 +1,23 @@
+-- { dg-do compile }
+-- { dg-options "-O2" }
+
+with Aggr10_Pkg; use Aggr10_Pkg;
+
+procedure Aggr10 is
+
+   No_Name_Location : constant Name_Location :=
+                        (Name     => Name_Id'First,
+                         Location => Int'First,
+                         Source   => Source_Id'First,
+                         Except   => False,
+                         Found    => False);
+
+   Name_Loc : Name_Location;
+
+begin
+   Name_Loc := Get;
+   if Name_Loc = No_Name_Location then  -- { dg-bogus "comparison always false" }
+      raise Program_Error;
+   end if;
+   Set (Name_Loc);
+end;
diff --git a/gcc/testsuite/gnat.dg/aggr10_pkg.ads b/gcc/testsuite/gnat.dg/aggr10_pkg.ads
new file mode 100644 (file)
index 0000000..92400f9
--- /dev/null
@@ -0,0 +1,18 @@
+package Aggr10_Pkg is
+
+   type Name_Id is range 300_000_000 .. 399_999_999;
+   type Int is range -2 ** 31 .. +2 ** 31 - 1;
+   type Source_Id is range 5_000_000 .. 5_999_999;
+
+   type Name_Location is record
+      Name     : Name_Id;
+      Location : Int;
+      Source   : Source_Id;
+      Except   : Boolean;
+      Found    : Boolean := False;
+   end record;
+
+   function Get return Name_Location;
+   procedure Set (Name_Loc : Name_Location);
+
+end Aggr10_Pkg;
diff --git a/gcc/testsuite/gnat.dg/string_comparison.adb b/gcc/testsuite/gnat.dg/string_comparison.adb
new file mode 100644 (file)
index 0000000..22e6c9e
--- /dev/null
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure String_Comparison is
+   package Bool_IO is new Enumeration_IO (Boolean);
+   use Bool_IO;
+begin
+   Put (Boolean'Image (True) = "True");
+end;
index 42ad2a4..8417cfe 100644 (file)
@@ -271,9 +271,11 @@ int flag_next_runtime = 0;
 
 enum tls_model flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
 
-/* Set the default algorithm for the integrated register allocator.  */
+/* Set the default region and algorithm for the integrated register
+   allocator.  */
 
-enum ira_algorithm flag_ira_algorithm = IRA_ALGORITHM_MIXED;
+enum ira_algorithm flag_ira_algorithm = IRA_ALGORITHM_CB;
+enum ira_region flag_ira_region = IRA_REGION_MIXED;
 
 /* Set the default value for -fira-verbose.  */
 
index 28ee8ef..89621f0 100644 (file)
@@ -2072,14 +2072,9 @@ struct gimple_opt_pass pass_remove_useless_stmts =
 static void
 remove_phi_nodes_and_edges_for_unreachable_block (basic_block bb)
 {
-  gimple_stmt_iterator gsi;
-
   /* Since this block is no longer reachable, we can just delete all
      of its PHI nodes.  */
-  for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
-    remove_phi_node (&gsi, true);
-
-  set_phi_nodes (bb, NULL);
+  remove_phi_nodes (bb);
 
   /* Remove edges to BB's successors.  */
   while (EDGE_COUNT (bb->succs) > 0)
index 6004978..d4e0004 100644 (file)
@@ -787,6 +787,7 @@ extern gimple create_phi_node (tree, basic_block);
 extern void add_phi_arg (gimple, tree, edge);
 extern void remove_phi_args (edge);
 extern void remove_phi_node (gimple_stmt_iterator *, bool);
+extern void remove_phi_nodes (basic_block);
 extern void init_phinodes (void);
 extern void fini_phinodes (void);
 extern void release_phi_node (gimple);
@@ -988,6 +989,7 @@ unsigned int tree_ssa_prefetch_arrays (void);
 unsigned int remove_empty_loops (void);
 void tree_ssa_iv_optimize (void);
 unsigned tree_predictive_commoning (void);
+tree canonicalize_loop_ivs (struct loop *, htab_t, tree);
 bool parallelize_loops (void);
 
 bool loop_only_exit_p (const struct loop *, const_edge);
index ba3d0fc..0802e5a 100644 (file)
@@ -293,6 +293,7 @@ execute_fixup_cfg (void)
   int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
 
   cfun->after_inlining = true;
+  cfun->always_inline_functions_inlined = true;
 
   if (cfun->eh)
     FOR_EACH_BB (bb)
index d6e94b3..91ce890 100644 (file)
@@ -1325,9 +1325,10 @@ create_loop_fn (void)
 /* Bases all the induction variables in LOOP on a single induction variable
    (unsigned with base 0 and step 1), whose final value is compared with
    NIT.  The induction variable is incremented in the loop latch.  
-   REDUCTION_LIST describes the reductions in LOOP.  */
+   REDUCTION_LIST describes the reductions in LOOP.  Return the induction 
+   variable that was created.  */
 
-static void
+tree
 canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
 {
   unsigned precision = TYPE_PRECISION (TREE_TYPE (nit));
@@ -1368,7 +1369,12 @@ canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
        }
 
       ok = simple_iv (loop, phi, res, &iv, true);
-      red = reduction_phi (reduction_list, phi);
+
+      if (reduction_list)
+       red = reduction_phi (reduction_list, phi);
+      else
+       red = NULL;
+
       /* We preserve the reduction phi nodes.  */
       if (!ok && red)
        {
@@ -1406,6 +1412,9 @@ canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
   gimple_cond_set_code (stmt, LT_EXPR);
   gimple_cond_set_lhs (stmt, var_before);
   gimple_cond_set_rhs (stmt, nit);
+  update_stmt (stmt);
+
+  return var_before;
 }
 
 /* Moves the exit condition of LOOP to the beginning of its header, and
index 7fd5a8f..fd6ac3a 100644 (file)
@@ -474,4 +474,17 @@ remove_phi_node (gimple_stmt_iterator *gsi, bool release_lhs_p)
     release_ssa_name (gimple_phi_result (phi));
 }
 
+/* Remove all the phi nodes from BB.  */
+
+void
+remove_phi_nodes (basic_block bb)
+{
+  gimple_stmt_iterator gsi;
+
+  for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
+    remove_phi_node (&gsi, true);
+
+  set_phi_nodes (bb, NULL);
+}
+
 #include "gt-tree-phinodes.h"
index 51bbd4b..e3d60e9 100644 (file)
@@ -1229,6 +1229,18 @@ follow_ssa_edge_in_rhs (struct loop *loop, gimple stmt,
     case GIMPLE_SINGLE_RHS:
       return follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
                                   halting_phi, evolution_of_loop, limit);
+    case GIMPLE_UNARY_RHS:
+      if (code == NOP_EXPR)
+       {
+         /* This assignment is under the form "a_1 = (cast) rhs.  */
+         t_bool res
+           = follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
+                                   halting_phi, evolution_of_loop, limit);
+         *evolution_of_loop = chrec_convert (type, *evolution_of_loop, stmt);
+         return res;
+       }
+      /* FALLTHRU */
+
     default:
       return t_false;
     }
index 8cada85..01c0e12 100644 (file)
@@ -2354,14 +2354,17 @@ sra_build_bf_assignment (tree dst, tree src)
       tmp = var;
       if (!is_gimple_variable (tmp))
        tmp = unshare_expr (var);
+      else
+       TREE_NO_WARNING (var) = true;
 
       tmp2 = make_rename_temp (utype, "SR");
 
       if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
-       stmt = gimple_build_assign (tmp2, fold_convert (utype, tmp));
+       tmp = fold_convert (utype, tmp);
       else
-       stmt = gimple_build_assign (tmp2, fold_build1 (VIEW_CONVERT_EXPR,
-                                                      utype, tmp));
+       tmp = fold_build1 (VIEW_CONVERT_EXPR, utype, tmp);
+
+      stmt = gimple_build_assign (tmp2, tmp);
       gimple_seq_add_stmt (&seq, stmt);
     }
   else
@@ -3223,12 +3226,20 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, gimple_stmt_iterator *gsi,
       if (!elt->use_block_copy)
        {
          tree type = TREE_TYPE (bfexpr);
-         tree var, vpos;
+         tree var = make_rename_temp (type, "SR"), tmp, vpos;
+         gimple st = NULL;
 
-         if (!TYPE_UNSIGNED (type))
-           type = unsigned_type_for (type);
+         gimple_assign_set_rhs1 (stmt, var);
+         update = true;
 
-         var = make_rename_temp (type, "SR");
+         if (!TYPE_UNSIGNED (type))
+           {
+             type = unsigned_type_for (type);
+             tmp = make_rename_temp (type, "SR");
+             st = gimple_build_assign (var,
+                                       fold_convert (TREE_TYPE (var), tmp));
+             var = tmp;
+           }
 
          gimple_seq_add_stmt (&seq,
                                gimple_build_assign
@@ -3245,8 +3256,8 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, gimple_stmt_iterator *gsi,
          sra_explode_bitfield_assignment
            (var, vpos, true, &seq, blen, bpos, elt);
 
-         gimple_assign_set_rhs1 (stmt, var);
-         update = true;
+         if (st)
+           gimple_seq_add_stmt (&seq, st);
        }
       else
        sra_sync_for_bitfield_assignment
index 82933f8..0908d54 100644 (file)
@@ -2191,6 +2191,9 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
 
       t = maybe_fold_stmt_indirect (expr, TREE_OPERAND (expr, 0),
                                    integer_zero_node);
+      /* Avoid folding *"abc" = 5 into 'a' = 5.  */
+      if (wi->is_lhs && t && TREE_CODE (t) == INTEGER_CST)
+       t = NULL_TREE;
       if (!t
          && TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
        /* If we had a good reason for propagating the address here,
@@ -2219,8 +2222,10 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
         Otherwise we'd be wasting time.  */
     case ARRAY_REF:
       /* If we are not processing expressions found within an
-        ADDR_EXPR, then we can fold constant array references.  */
-      if (!*inside_addr_expr_p)
+        ADDR_EXPR, then we can fold constant array references.
+        Don't fold on LHS either, to avoid folding "abc"[0] = 5
+        into 'a' = 5.  */
+      if (!*inside_addr_expr_p && !wi->is_lhs)
        t = fold_read_from_constant_string (expr);
       else
        t = NULL;
index aa0472e..683d7d4 100644 (file)
@@ -4355,7 +4355,12 @@ iv_ca_add_use (struct ivopts_data *data, struct iv_ca *ivs,
 static comp_cost
 iv_ca_cost (struct iv_ca *ivs)
 {
-  return (ivs->bad_uses ? infinite_cost : ivs->cost);
+  /* This was a conditional expression but it triggered a bug in the
+     Solaris 8 compiler.  */
+  if (ivs->bad_uses)
+    return infinite_cost;
+  else
+    return ivs->cost;
 }
 
 /* Returns true if all dependences of CP are among invariants in IVS.  */
index 7773fe9..2fb4710 100644 (file)
@@ -3644,10 +3644,7 @@ compute_avail (void)
 
              add_to_value (get_expr_value_id (e), e);
              if (!in_fre)
-               {
-                 bitmap_insert_into_set (TMP_GEN (block), e);
-                 bitmap_value_insert_into_set (maximal_set, e);
-               }
+               bitmap_insert_into_set (TMP_GEN (block), e);
              bitmap_value_insert_into_set (AVAIL_OUT (block), e);
            }
 
@@ -3716,6 +3713,7 @@ compute_avail (void)
                    if (is_exception_related (stmt))
                      continue;
                  case tcc_binary:
+                 case tcc_comparison:
                    {
                      vn_nary_op_t nary;
                      unsigned int i;
index 46781b8..3d64c1c 100644 (file)
@@ -4704,8 +4704,9 @@ static bool have_alias_info = false;
 /* Emit a note for the pointer initialization point DEF.  */
 
 static void
-emit_pointer_definition (gimple def)
+emit_pointer_definition (tree ptr, bitmap visited)
 {
+  gimple def = SSA_NAME_DEF_STMT (ptr);
   if (gimple_code (def) == GIMPLE_PHI)
     {
       use_operand_p argp;
@@ -4715,7 +4716,10 @@ emit_pointer_definition (gimple def)
        {
          tree arg = USE_FROM_PTR (argp);
          if (TREE_CODE (arg) == SSA_NAME)
-           emit_pointer_definition (SSA_NAME_DEF_STMT (arg));
+           {
+             if (bitmap_set_bit (visited, SSA_NAME_VERSION (arg)))
+               emit_pointer_definition (arg, visited);
+           }
          else
            inform (0, "initialized from %qE", arg);
        }
@@ -4729,7 +4733,6 @@ emit_pointer_definition (gimple def)
 static void
 emit_alias_warning (tree ptr)
 {
-  gimple def = SSA_NAME_DEF_STMT (ptr);
   gimple use;
   imm_use_iterator ui;
   unsigned warned = 0;
@@ -4777,7 +4780,11 @@ emit_alias_warning (tree ptr)
        }
     }
   if (warned > 0)
-    emit_pointer_definition (def);
+    {
+      bitmap visited = BITMAP_ALLOC (NULL);
+      emit_pointer_definition (ptr, visited);
+      BITMAP_FREE (visited);
+    }
 }
 
 /* Given a pointer variable P, fill in its points-to set, or return
index 1289c49..9d23b24 100644 (file)
@@ -2557,11 +2557,11 @@ extract_range_from_binary_expr (value_range_t *vr,
          ior_max.high = vr0_max.high | vr1_max.high;
          if (ior_max.high != 0)
            {
-             ior_max.low = ~0u;
+             ior_max.low = ~(unsigned HOST_WIDE_INT)0u;
              ior_max.high |= ((HOST_WIDE_INT) 1
                               << floor_log2 (ior_max.high)) - 1;
            }
-         else
+         else if (ior_max.low != 0)
            ior_max.low |= ((unsigned HOST_WIDE_INT) 1u
                            << floor_log2 (ior_max.low)) - 1;
 
@@ -6512,6 +6512,12 @@ simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
     !useless_type_conversion_p (TREE_TYPE (gimple_assign_lhs (stmt)),
                                TREE_TYPE (op0));
 
+  /* Make sure to not sign-extend -1 as a boolean value.  */
+  if (need_conversion
+      && !TYPE_UNSIGNED (TREE_TYPE (op0))
+      && TYPE_PRECISION (TREE_TYPE (op0)) == 1)
+    return false;
+
   switch (rhs_code)
     {
     case TRUTH_AND_EXPR:
index e74b779..03c54cc 100644 (file)
@@ -5522,7 +5522,7 @@ build_pointer_type_for_mode (tree to_type, enum machine_mode mode,
   t = make_node (POINTER_TYPE);
 
   TREE_TYPE (t) = to_type;
-  TYPE_MODE (t) = mode;
+  SET_TYPE_MODE (t, mode);
   TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
   TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (to_type);
   TYPE_POINTER_TO (to_type) = t;
@@ -5586,7 +5586,7 @@ build_reference_type_for_mode (tree to_type, enum machine_mode mode,
   t = make_node (REFERENCE_TYPE);
 
   TREE_TYPE (t) = to_type;
-  TYPE_MODE (t) = mode;
+  SET_TYPE_MODE (t, mode);
   TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
   TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (to_type);
   TYPE_REFERENCE_TO (to_type) = t;
@@ -5655,7 +5655,7 @@ build_index_type (tree maxval)
   TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
   TYPE_MIN_VALUE (itype) = size_zero_node;
   TYPE_MAX_VALUE (itype) = fold_convert (sizetype, maxval);
-  TYPE_MODE (itype) = TYPE_MODE (sizetype);
+  SET_TYPE_MODE (itype, TYPE_MODE (sizetype));
   TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
   TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (sizetype);
   TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
@@ -5711,7 +5711,7 @@ build_range_type (tree type, tree lowval, tree highval)
   TYPE_MAX_VALUE (itype) = highval ? fold_convert (type, highval) : NULL;
 
   TYPE_PRECISION (itype) = TYPE_PRECISION (type);
-  TYPE_MODE (itype) = TYPE_MODE (type);
+  SET_TYPE_MODE (itype, TYPE_MODE (type));
   TYPE_SIZE (itype) = TYPE_SIZE (type);
   TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (type);
   TYPE_ALIGN (itype) = TYPE_ALIGN (type);
@@ -7296,7 +7296,7 @@ make_vector_type (tree innertype, int nunits, enum machine_mode mode)
   t = make_node (VECTOR_TYPE);
   TREE_TYPE (t) = TYPE_MAIN_VARIANT (innertype);
   SET_TYPE_VECTOR_SUBPARTS (t, nunits);
-  TYPE_MODE (t) = mode;
+  SET_TYPE_MODE (t, mode);
   TYPE_READONLY (t) = TYPE_READONLY (innertype);
   TYPE_VOLATILE (t) = TYPE_VOLATILE (innertype);
 
@@ -7553,19 +7553,19 @@ build_common_tree_nodes_2 (int short_double)
   dfloat32_type_node = make_node (REAL_TYPE);
   TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE; 
   layout_type (dfloat32_type_node);
-  TYPE_MODE (dfloat32_type_node) = SDmode;
+  SET_TYPE_MODE (dfloat32_type_node, SDmode);
   dfloat32_ptr_type_node = build_pointer_type (dfloat32_type_node);
 
   dfloat64_type_node = make_node (REAL_TYPE);
   TYPE_PRECISION (dfloat64_type_node) = DECIMAL64_TYPE_SIZE;
   layout_type (dfloat64_type_node);
-  TYPE_MODE (dfloat64_type_node) = DDmode;
+  SET_TYPE_MODE (dfloat64_type_node, DDmode);
   dfloat64_ptr_type_node = build_pointer_type (dfloat64_type_node);
 
   dfloat128_type_node = make_node (REAL_TYPE);
   TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE; 
   layout_type (dfloat128_type_node);
-  TYPE_MODE (dfloat128_type_node) = TDmode;
+  SET_TYPE_MODE (dfloat128_type_node, TDmode);
   dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);
 
   complex_integer_type_node = build_complex_type (integer_type_node);
index d85918f..55163b6 100644 (file)
@@ -2050,7 +2050,6 @@ struct tree_block GTY(())
 #define TYPE_UID(NODE) (TYPE_CHECK (NODE)->type.uid)
 #define TYPE_SIZE(NODE) (TYPE_CHECK (NODE)->type.size)
 #define TYPE_SIZE_UNIT(NODE) (TYPE_CHECK (NODE)->type.size_unit)
-#define TYPE_MODE(NODE) (TYPE_CHECK (NODE)->type.mode)
 #define TYPE_VALUES(NODE) (ENUMERAL_TYPE_CHECK (NODE)->type.values)
 #define TYPE_DOMAIN(NODE) (ARRAY_TYPE_CHECK (NODE)->type.values)
 #define TYPE_FIELDS(NODE) (RECORD_OR_UNION_CHECK (NODE)->type.values)
@@ -2078,6 +2077,14 @@ struct tree_block GTY(())
 #define TYPE_MAIN_VARIANT(NODE) (TYPE_CHECK (NODE)->type.main_variant)
 #define TYPE_CONTEXT(NODE) (TYPE_CHECK (NODE)->type.context)
 
+/* Vector types need to check target flags to determine type.  */
+extern enum machine_mode vector_type_mode (const_tree);
+#define TYPE_MODE(NODE) \
+  (TREE_CODE (TYPE_CHECK (NODE)) == VECTOR_TYPE \
+   ? vector_type_mode (NODE) : (NODE)->type.mode)
+#define SET_TYPE_MODE(NODE, MODE) \
+  (TYPE_CHECK (NODE)->type.mode = (MODE))
+
 /* The "canonical" type for this type node, which can be used to
    compare the type for equality with another type. If two types are
    equal (based on the semantics of the language), then they will have
index 73892f5..be1afad 100644 (file)
@@ -1,27 +1,8 @@
 2008-12-10  Jason Merrill  <jason@redhat.com>
 
-       * demangle.h (enum demangle_component_type): Add
+       * demangle.h (enum demangle_component_type): Add 
        DEMANGLE_COMPONENT_FIXED_TYPE.
 
-2008-12-01  Cary Coutant  <ccoutant@google.com>
-
-       * plugin-api.h (ld_plugin_message): Change format parameter to const.
-
-2008-12-01  Cary Coutant  <ccoutant@google.com>
-
-       * plugin-api.h: Fix syntax error when compiling with C++.
-
-2008-11-26  Alan Modra  <amodra@bigpond.net.au>
-
-       PR 7047
-       * bfdlink.h (struct bfd_elf_version_expr): Delete "symbol".
-       Add "literal".
-
-2008-11-21  Sterling Augustine  <sterling@tensilica.com>
-
-       * xtensa-isa-internal.h (XTENSA_STATE_IS_SHARED_OR): New flag.
-       * xtensa-isa.h (xtensa_state_is_shared_or): New prototype.
-
 2008-11-19  Bob Wilson  <bob.wilson@acm.org>
        
        * xtensa-config.h (XCHAL_HAVE_MUL16, XCHAL_HAVE_MUL32, XCHAL_HAVE_DIV32)
index 9f6148e..a6378bc 100644 (file)
@@ -1,3 +1,9 @@
+2008-12-10  Alexandre Oliva  <aoliva@redhat.com>
+
+       PR target/37033
+       * pch.c (cpp_valid_state): Improve message for poisoned symbols.
+       Allow for differences in __GCC_HAVE_DWARF2_CFI_ASM.
+
 2008-11-29  Joseph Myers  <joseph@codesourcery.com>
 
        * lex.c (cpp_token_len): Use 6 as default length.
index bf7b9be..f459d2c 100644 (file)
@@ -1,5 +1,5 @@
 /* Part of CPP library.  (Precompiled header reading/writing.)
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008
    Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify it
@@ -477,11 +477,32 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
 
       h = cpp_lookup (r, namebuf, m.name_length);
       if (m.flags & NODE_POISONED
-         || h->type != NT_MACRO
          || h->flags & NODE_POISONED)
        {
          if (CPP_OPTION (r, warn_invalid_pch))
            cpp_error (r, CPP_DL_WARNING_SYSHDR,
+                      "%s: not used because `%.*s' is poisoned",
+                      name, m.name_length, namebuf);
+         goto fail;
+       }
+
+      if (h->type != NT_MACRO)
+       {
+         /* It's ok if __GCC_HAVE_DWARF2_CFI_ASM becomes undefined,
+            as in, when the PCH file is created with -g and we're
+            attempting to use it without -g.  Restoring the PCH file
+            is supposed to bring in this definition *and* enable the
+            generation of call frame information, so that precompiled
+            definitions that take this macro into accout, to decide
+            what asm to emit, won't issue .cfi directives when the
+            compiler doesn't.  */
+         if (!(h->flags & NODE_USED)
+             && m.name_length == sizeof ("__GCC_HAVE_DWARF2_CFI_ASM") - 1
+             && !memcmp (namebuf, "__GCC_HAVE_DWARF2_CFI_ASM", m.name_length))
+           continue;
+
+         if (CPP_OPTION (r, warn_invalid_pch))
+           cpp_error (r, CPP_DL_WARNING_SYSHDR,
                       "%s: not used because `%.*s' not defined",
                       name, m.name_length, namebuf);
          goto fail;
index 765bbd7..dcc4867 100644 (file)
@@ -1,3 +1,12 @@
+2008-12-08  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
+
+       PR libfortran/38430
+       * io/transfer.c (data_transfer_init): Move constraint check for REC=
+       and STREAM access into condition for other REC= constraints to simplify.
+       Comment out this constraint to avoid breaking compatibility with 4.3
+       until later.  Added a TODO for above comment and this one.
+       Fix test for max pos.
+
 2008-12-06  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR libfortran/38291
index 318d221..ea63a0d 100644 (file)
@@ -1986,15 +1986,6 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
       return;
     }
 
-  if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM
-      && (cf & IOPARM_DT_HAS_REC) != 0)
-    {
-      generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
-                     "Record number not allowed for stream access "
-                     "data transfer");
-      return;
-    }
-
   /* Process the ADVANCE option.  */
 
   dtp->u.p.advance_status
@@ -2141,7 +2132,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
              return;
            }
 
-         if (dtp->rec >= dtp->u.p.current_unit->maxrec)
+         if (dtp->pos >= dtp->u.p.current_unit->maxrec)
            {
              generate_error (&dtp->common, LIBERROR_BAD_OPTION,
                              "POS=specifier too large");
@@ -2231,10 +2222,20 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
          return;
        }
 
-      /* This is required to maintain compatibility between
-        4.3 and 4.4 runtime.  */
+      /* TODO: This is required to maintain compatibility between
+        4.3 and 4.4 runtime. Remove when ABI changes from 4.3 */
+
       if (is_stream_io (dtp))
        dtp->u.p.current_unit->strm_pos = dtp->rec;
+      
+      /* TODO: Un-comment this code when ABI changes from 4.3.
+      if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM)
+       {
+         generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
+                     "Record number not allowed for stream access "
+                     "data transfer");
+         return;
+       }  */
 
     }
 
index 46536c8..98a3073 100644 (file)
@@ -1,3 +1,10 @@
+2008-12-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/36802
+       * testsuite/libgomp.c/pr36802-1.c: New test.
+       * testsuite/libgomp.c/pr36802-2.c: New test.
+       * testsuite/libgomp.c/pr36802-3.c: New test.
+
 2008-12-01  Janis Johnson  <janis187@us.ibm.com>
 
        PR libgomp/38270
diff --git a/libgomp/testsuite/libgomp.c/pr36802-1.c b/libgomp/testsuite/libgomp.c/pr36802-1.c
new file mode 100644 (file)
index 0000000..4ed5e12
--- /dev/null
@@ -0,0 +1,34 @@
+/* PR middle-end/36802 */
+
+extern void abort (void);
+
+int
+foo (int k)
+{
+  int i = 0;
+#pragma omp parallel
+  #pragma omp single
+    {
+      if (!k)
+       {
+         int j;
+         for (j = 0; j < 10; j++)
+         #pragma omp task
+           if (j == 4)  
+             i++;
+       }
+      else
+       i++;
+    }
+  return i;
+}
+
+int
+main (void)
+{
+  if (foo (0) != 1)
+    abort ();
+  if (foo (1) != 1)
+    abort ();
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pr36802-2.c b/libgomp/testsuite/libgomp.c/pr36802-2.c
new file mode 100644 (file)
index 0000000..06e792f
--- /dev/null
@@ -0,0 +1,46 @@
+/* PR middle-end/36802 */
+
+extern void abort (void);
+
+int q;
+
+int
+foo (int k)
+{
+  int i = 6, n = 0;
+  omp_set_dynamic (0);
+  omp_set_nested (1);
+#pragma omp parallel shared (i) num_threads (3)
+  {
+    int l;
+
+    if (omp_get_num_threads () != 3)
+    #pragma omp atomic
+      n += 1;
+    else
+    #pragma omp for
+      for (l = 0; l < 3; l++)
+       if (k)
+       #pragma omp atomic
+         q += i;
+       else
+       #pragma omp parallel shared (i) num_threads (4)
+         {
+           if (omp_get_num_threads () != 4)
+           #pragma omp atomic
+             n += 1;
+           #pragma omp critical
+             i += 1;
+         }
+  }
+  if (n == 0 && i != 6 + 3 * 4)
+    abort ();
+  return 0;
+}
+
+int
+main (void)
+{
+  foo (0);
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pr36802-3.c b/libgomp/testsuite/libgomp.c/pr36802-3.c
new file mode 100644 (file)
index 0000000..f11baa0
--- /dev/null
@@ -0,0 +1,46 @@
+/* PR middle-end/36802 */
+
+extern void abort (void);
+
+int q;
+
+int
+foo (int k)
+{
+  int i = 6, n = 0;
+  omp_set_dynamic (0);
+  omp_set_nested (1);
+#pragma omp parallel shared (i) num_threads (3)
+  {
+    int l;
+
+    if (omp_get_num_threads () != 3)
+    #pragma omp atomic
+      n += 1;
+    else
+    #pragma omp for
+      for (l = 0; l < 3; l++)
+       if (!k)
+       #pragma omp parallel shared (i) num_threads (4)
+         {
+           if (omp_get_num_threads () != 4)
+           #pragma omp atomic
+             n += 1;
+           #pragma omp critical
+             i += 1;
+         }
+       else
+       #pragma omp atomic
+         q += i;
+  }
+  if (n == 0 && i != 6 + 3 * 4)
+    abort ();
+  return 0;
+}
+
+int
+main (void)
+{
+  foo (0);
+  return 0;
+}
index 005ef71..e090ae9 100644 (file)
@@ -1,7 +1,13 @@
+2008-12-11  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR libgcj/38006
+       * classpath/tools/resource/gnu/classpath/tools/gjdoc/htmldoclet/inherit.png:
+       Set svn:mime-type to application/octet-stream.
+
 2008-12-04  Jack Howarth  <howarth@bromo.med.uc.edu>
 
-        * configure.ac: Add double brackets on darwin[912].
-        * configure: Regenerate.
+       * configure.ac: Add double brackets on darwin[912].
+       * configure: Regenerate.
 
 2008-12-02  Jack Howarth  <howarth@bromo.med.uc.edu>
 
index 7bcae27..4070761 100644 (file)
@@ -1,3 +1,20 @@
+2008-12-11  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/37582
+       * testsuite/26_numerics/headers/cmath/37582.cc: New.
+
+2008-12-08  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * include/tr1_impl/cmath: Undef remquof / remquol too; add using
+       declarations.
+       * acinclude.m4 [GLIBCXX_CHECK_C99_TR1]: Check remquof / remquol too.
+       * testsuite/tr1/8_c_compatibility/cmath/functions.cc: Adjust.
+       * configure: Regenerate.
+
+2008-12-08  Edward Smith-Rowland  <3dw4rd@verizon.net>
+
+       * include/bits/forward_list.h: Fixed spurious "forward_swap" in doxy.
+
 2008-12-06  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR libstdc++/38421
index bec563f..f4a8346 100644 (file)
@@ -1523,8 +1523,8 @@ AC_DEFUN([GLIBCXX_CHECK_C99_TR1], [
                  remainderf(0.0f, 0.0f);
                  remainderl(0.0l, 0.0l);
                  remquo(0.0, 0.0, 0);
-                 remquo(0.0f, 0.0f, 0);
-                 remquo(0.0l, 0.0l, 0);
+                 remquof(0.0f, 0.0f, 0);
+                 remquol(0.0l, 0.0l, 0);
                  rint(0.0);
                  rintf(0.0f);
                  rintl(0.0l);
index c344b4c..23b0500 100644 (file)
@@ -1075,10 +1075,10 @@ Optional Packages:
   --with-pic              try to use only PIC/non-PIC objects [default=use
                           both]
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
-  --with-system-libunwind use installed libunwind
   --with-gnu-ld           assume the C compiler uses GNU ld default=no
   --with-libiconv-prefix[=DIR]  search for libiconv in DIR/include and DIR/lib
   --without-libiconv-prefix     don't search for libiconv in includedir and libdir
+  --with-system-libunwind use installed libunwind
   --with-gxx-include-dir=DIR
                           installation directory for include files
 
@@ -20965,8 +20965,8 @@ typedef double_t  my_double_t;
                  remainderf(0.0f, 0.0f);
                  remainderl(0.0l, 0.0l);
                  remquo(0.0, 0.0, 0);
-                 remquo(0.0f, 0.0f, 0);
-                 remquo(0.0l, 0.0l, 0);
+                 remquof(0.0f, 0.0f, 0);
+                 remquol(0.0l, 0.0l, 0);
                  rint(0.0);
                  rintf(0.0f);
                  rintl(0.0l);
@@ -41961,40 +41961,6 @@ _ACEOF
 
   fi
 
-  # For _Unwind_GetIPInfo.
-
-
-# Check whether --with-system-libunwind or --without-system-libunwind was given.
-if test "${with_system_libunwind+set}" = set; then
-  withval="$with_system_libunwind"
-
-fi;
-  # If system-libunwind was not specifically set, pick a default setting.
-  if test x$with_system_libunwind = x; then
-    case ${target} in
-      ia64-*-hpux*) with_system_libunwind=yes ;;
-      *) with_system_libunwind=no ;;
-    esac
-  fi
-  # Based on system-libunwind and target, do we have ipinfo?
-  if  test x$with_system_libunwind = xyes; then
-    case ${target} in
-      ia64-*-*) have_unwind_getipinfo=no ;;
-      *) have_unwind_getipinfo=yes ;;
-    esac
-  else
-     have_unwind_getipinfo=yes
-  fi
-
-  if test x$have_unwind_getipinfo = xyes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETIPINFO 1
-_ACEOF
-
-  fi
-
-
   # For iconv support.
 
       if test "X$prefix" = "XNONE"; then
@@ -104361,13 +104327,42 @@ _ACEOF
 _ACEOF
 
   fi
+fi
+
+# Check for _Unwind_GetIPInfo.
 
-  # Assume we have _Unwind_GetIPInfo for cross-compiles.
-  cat >>confdefs.h <<\_ACEOF
+
+# Check whether --with-system-libunwind or --without-system-libunwind was given.
+if test "${with_system_libunwind+set}" = set; then
+  withval="$with_system_libunwind"
+
+fi;
+  # If system-libunwind was not specifically set, pick a default setting.
+  if test x$with_system_libunwind = x; then
+    case ${target} in
+      ia64-*-hpux*) with_system_libunwind=yes ;;
+      *) with_system_libunwind=no ;;
+    esac
+  fi
+  # Based on system-libunwind and target, do we have ipinfo?
+  if  test x$with_system_libunwind = xyes; then
+    case ${target} in
+      ia64-*-*) have_unwind_getipinfo=no ;;
+      *) have_unwind_getipinfo=yes ;;
+    esac
+  else
+     have_unwind_getipinfo=yes
+  fi
+
+  if test x$have_unwind_getipinfo = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
 #define HAVE_GETIPINFO 1
 _ACEOF
 
-fi
+  fi
+
+
 
  # Check whether --enable-linux-futex or --disable-linux-futex was given.
 if test "${enable_linux_futex+set}" = set; then
index cb73978..473982c 100644 (file)
@@ -1311,21 +1311,21 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                const forward_list<_Tp, _Alloc>& __ly)
     { return !(__ly < __lx); }
 
-  /// See std::forward_list::forward_swap().
+  /// See std::forward_list::swap().
   template<typename _Tp, typename _Alloc>
     inline void
     swap(forward_list<_Tp, _Alloc>& __lx,
          forward_list<_Tp, _Alloc>& __ly)
     { __lx.swap(__ly); }
 
-  /// See std::forward_list::forward_swap().
+  /// See std::forward_list::swap().
   template<typename _Tp, typename _Alloc>
     inline void
     swap(forward_list<_Tp, _Alloc>&& __lx,
          forward_list<_Tp, _Alloc>& __ly)
     { __lx.swap(__ly); }
 
-  /// See std::forward_list::forward_swap().
+  /// See std::forward_list::swap().
   template<typename _Tp, typename _Alloc>
     inline void 
     swap(forward_list<_Tp, _Alloc>& __lx,
index d969a8f..044d122 100644 (file)
 #undef remainderf
 #undef remainderl
 #undef remquo
-#undef remquo
-#undef remquo
+#undef remquof
+#undef remquol
 #undef rint
 #undef rintf
 #undef rintl
@@ -266,8 +266,8 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
   using ::remainderl;
 
   using ::remquo;
-  using ::remquo;
-  using ::remquo;
+  using ::remquof;
+  using ::remquol;
 
   using ::rint;
   using ::rintf;
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/37582.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/37582.cc
new file mode 100644 (file)
index 0000000..33c9070
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library 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 this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file 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.
+
+// { dg-do compile }
+
+#include <cmath>
+
+struct foo
+{
+  foo (double);
+};
+
+bool operator &&(int, const foo &);
+
+// libstdc++/37582
+double
+test01(double x)
+{
+  return std::pow (x, 2.0);
+}
index 3bb6d9d..6bbb148 100644 (file)
@@ -2,7 +2,7 @@
 
 // 2006-02-07  Paolo Carlini  <pcarlini@suse.de>
 //
-// Copyright (C) 2006 Free Software Foundation, Inc.
+// Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -156,8 +156,8 @@ void test01()
   ldret = std::tr1::remainderl(ld0, ld0);
 
   ret = std::tr1::remquo(d0, d0, pquo);
-  fret = std::tr1::remquo(f0, f0, pquo);
-  ldret = std::tr1::remquo(ld0, ld0, pquo);
+  fret = std::tr1::remquof(f0, f0, pquo);
+  ldret = std::tr1::remquol(ld0, ld0, pquo);
 
   ret = std::tr1::rint(d0);
   fret = std::tr1::rintf(f0);