summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-07-31 13:10:52 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-07-31 13:10:52 +0000
commit777d46780c3e30ecc800f0a613d65562caea9abf (patch)
treeeffc283a6f03409b0c3e0e3e20c70c5ab627776d /gcc
parent4c65aab8b90fdd8ef4e2b77e33c7a821297f60e6 (diff)
downloadgcc-777d46780c3e30ecc800f0a613d65562caea9abf.tar.gz
2008-07-31 Basile Starynkevitch <basile@starynkevitch.net>
the yesterday's version failed to compile any simple C file. Fixed! MELT branch merged with trunk r138355 * gcc/passes.c: better order for basilys related passes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@138403 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog638
-rw-r--r--gcc/ChangeLog.melt6
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog134
-rw-r--r--gcc/ada/back_end.adb2
-rw-r--r--gcc/ada/einfo.adb36
-rw-r--r--gcc/ada/einfo.ads22
-rw-r--r--gcc/ada/exp_ch9.adb1022
-rw-r--r--gcc/ada/exp_ch9.ads12
-rw-r--r--gcc/ada/exp_util.adb14
-rw-r--r--gcc/ada/exp_util.ads8
-rw-r--r--gcc/ada/g-pehage.adb228
-rw-r--r--gcc/ada/g-pehage.ads36
-rw-r--r--gcc/ada/gcc-interface/Makefile.in2
-rw-r--r--gcc/ada/gcc-interface/decl.c33
-rw-r--r--gcc/ada/gcc-interface/gigi.h1
-rw-r--r--gcc/ada/gcc-interface/misc.c1
-rw-r--r--gcc/ada/gcc-interface/trans.c28
-rw-r--r--gcc/ada/gcc-interface/utils.c16
-rw-r--r--gcc/ada/gnatlink.adb2
-rw-r--r--gcc/ada/rtsfind.adb71
-rw-r--r--gcc/ada/sem_ch3.adb129
-rw-r--r--gcc/ada/sem_ch6.adb215
-rw-r--r--gcc/ada/sem_ch6.ads8
-rw-r--r--gcc/ada/sem_ch8.adb58
-rw-r--r--gcc/ada/uintp.adb2
-rw-r--r--gcc/builtins.c25
-rw-r--r--gcc/caller-save.c12
-rw-r--r--gcc/calls.c6
-rw-r--r--gcc/cfgexpand.c109
-rw-r--r--gcc/config/arm/arm.c132
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c488
-rw-r--r--gcc/config/i386/i386.h42
-rw-r--r--gcc/config/i386/i386.md2
-rw-r--r--gcc/config/i386/i386.opt10
-rw-r--r--gcc/config/rs6000/rs6000.h5
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/init.c64
-rw-r--r--gcc/cp/tree.c45
-rw-r--r--gcc/cp/typeck.c2
-rw-r--r--gcc/defaults.h21
-rw-r--r--gcc/doc/extend.texi12
-rw-r--r--gcc/doc/invoke.texi26
-rw-r--r--gcc/doc/tm.texi29
-rw-r--r--gcc/dse.c21
-rw-r--r--gcc/dwarf2out.c281
-rw-r--r--gcc/emit-rtl.c9
-rw-r--r--gcc/final.c3
-rw-r--r--gcc/function.c140
-rw-r--r--gcc/function.h48
-rw-r--r--gcc/global.c6
-rw-r--r--gcc/passes.c23
-rw-r--r--gcc/reload1.c12
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/stmt.c2
-rw-r--r--gcc/target-def.h4
-rw-r--r--gcc/target.h7
-rw-r--r--gcc/testsuite/ChangeLog101
-rw-r--r--gcc/testsuite/g++.dg/expr/anew4.C3
-rw-r--r--gcc/testsuite/g++.dg/init/value3.C31
-rw-r--r--gcc/testsuite/g++.dg/lookup/new1.C4
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/check.h36
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C56
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C43
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C39
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C39
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C57
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C72
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C77
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp39
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C17
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h132
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/throw-1.C61
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/throw-2.C52
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/throw-3.C52
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/throw-4.C54
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C12
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C16
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C29
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C35
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C17
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C31
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C31
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c21
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c118
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/alloca-1.c44
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c30
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-3.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-4.c29
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/builtin-return-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/check.h36
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/comp-goto-1.c41
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/fastcall-1.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/global-1.c27
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/inline-1.c28
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/inline-2.c45
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/nested-1.c44
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/nested-2.c45
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/nested-3.c62
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/nested-4.c33
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/nested-5.c38
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/nested-6.c28
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-1.c55
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-2.c56
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-3.c42
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-4.c38
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-5.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/pr16660-1.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/pr16660-2.c12
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/pr16660-3.c14
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/regparm-1.c60
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/ret-struct-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/setjmp-1.c43
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/setjmp-2.c46
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/setjmp-3.c37
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/setjmp-4.c39
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/sibcall-1.c35
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp52
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/struct-1.c28
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/vararg-1.c59
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/vararg-2.c65
-rw-r--r--gcc/testsuite/gcc.target/i386/20060512-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/20060512-2.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/20060512-3.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/20060512-4.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/align-main-1.c25
-rw-r--r--gcc/testsuite/gcc.target/i386/align-main-2.c25
-rw-r--r--gcc/testsuite/gcc.target/i386/pr32000-2.c26
-rw-r--r--gcc/testsuite/gcc.target/i386/stackalign/asm-1.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/stackalign/return-1.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/stackalign/return-2.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/stackalign/return-3.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/stackalign/return-4.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/stackalign/return-5.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/stackalign/return-6.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/stackalign/stackalign.exp47
-rw-r--r--gcc/testsuite/gfortran.dg/pr36967.f25
-rw-r--r--gcc/testsuite/gnat.dg/boolean_expr.adb30
-rw-r--r--gcc/testsuite/gnat.dg/boolean_expr.ads5
-rw-r--r--gcc/testsuite/lib/target-supports.exp15
-rw-r--r--gcc/tree-predcom.c5
-rw-r--r--gcc/tree-vectorizer.c4
146 files changed, 5952 insertions, 1334 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 423ac34d678..3584c53ca45 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,223 @@
+2008-07-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/36554
+ * dwarf2out.c (is_subrange_type): Deal with BOOLEAN_TYPE.
+
+2008-07-30 Rafael Avila de Espindola <espindola@google.com>
+
+ PR 36974
+ * final.c (call_from_call_insn): Handle COND_EXEC
+
+2008-07-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * builtins.c (std_gimplify_va_arg_expr): Replace
+ PREFERRED_STACK_BOUNDARY with MAX_SUPPORTED_STACK_ALIGNMENT.
+ * config/i386/i386.c (ix86_gimplify_va_arg): Likewise.
+
+2008-07-30 Joey Ye <joey.ye@intel.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * builtins.c (expand_builtin_setjmp_receiver): Replace
+ virtual_incoming_args_rtx with crtl->args.internal_arg_pointer.
+ (expand_builtin_apply_args_1): Likewise.
+ (expand_builtin_longjmp): Need DRAP for stack alignment.
+ (expand_builtin_apply): Likewise.
+
+ * caller-save.c (setup_save_areas): Call assign_stack_local_1
+ instead of assign_stack_local to allow alignment reduction.
+
+ * calls.c (emit_call_1): Need DRAP for stack alignment if
+ return pops.
+ (expand_call): Replace virtual_incoming_args_rtx with
+ crtl->args.internal_arg_pointer.
+ * stmt.c (expand_nl_goto_receiver): Likewise.
+
+ * cfgexpand.c (get_decl_align_unit): Estimate stack variable
+ alignment and store to stack_alignment_estimated and
+ max_used_stack_slot_alignment.
+ (expand_one_var): Likewise.
+ (expand_stack_alignment): New function.
+ (tree_expand_cfg): Initialize max_used_stack_slot_alignment
+ and stack_alignment_estimated fields in rtl_data. Call
+ expand_stack_alignment at end.
+
+ * defaults.h (INCOMING_STACK_BOUNDARY): New.
+ (MAX_STACK_ALIGNMENT): Likewise.
+ (MAX_SUPPORTED_STACK_ALIGNMENT): Likewise.
+ (SUPPORTS_STACK_ALIGNMENT): Likewise.
+
+ * emit-rtl.c (gen_reg_rtx): Estimate stack alignment for
+ stack alignment when generating virtual registers.
+
+ * function.c (assign_stack_local): Renamed to ...
+ (assign_stack_local_1): This. Add a parameter to indicate
+ if it is OK to reduce alignment.
+ (assign_stack_local): Use it.
+ (instantiate_new_reg): Instantiate virtual incoming args rtx
+ to vDRAP if stack realignment and DRAP is needed.
+ (assign_parms): Collect parameter/return type alignment and
+ contribute to stack_alignment_estimated.
+ (locate_and_pad_parm): Likewise.
+ (get_arg_pointer_save_area): Replace virtual_incoming_args_rtx
+ with crtl->args.internal_arg_pointer.
+
+ * function.h (rtl_data): Add new field drap_reg,
+ max_used_stack_slot_alignment, stack_alignment_estimated,
+ stack_realign_needed, need_drap, stack_realign_processed and
+ stack_realign_finalized.
+ (stack_realign_fp): New macro.
+ (stack_realign_drap): Likewise.
+
+ * global.c (compute_regsets): Frame pointer is needed when
+ stack is realigned. Can eliminate frame pointer when stack is
+ realigned and dynamic realigned argument pointer isn't used.
+
+ * reload1.c (update_eliminables): Frame pointer is needed
+ when stack is realigned.
+ (init_elim_table): Can eliminate frame pointer when stack is
+ realigned and dynamic realigned argument pointer isn't used.
+
+ * rtl.h (assign_stack_local_1): Declare new funtion.
+
+ * target-def.h (TARGET_UPDATE_STACK_BOUNDARY): New.
+ (TARGET_GET_DRAP_RTX): Likewise.
+ (TARGET_CALLS): Add TARGET_UPDATE_STACK_BOUNDARY and
+ TARGET_GET_DRAP_RTX.
+
+ * target.h (gcc_target): Add update_stack_boundary and
+ get_drap_rtx.
+
+ * tree-vectorizer.c (vect_can_force_dr_alignment_p): Replace
+ STACK_BOUNDARY with MAX_STACK_ALIGNMENT.
+
+2008-07-30 Xuepeng Guo <xuepeng.guo@intel.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * dwarf2out.c (dw_fde_struct): Add stack_realignment, drap_reg,
+ vdrap_reg, stack_realign and drap_reg_saved.
+ (add_cfi): Don't allow redefining CFA when DRAP is used.
+ (reg_save): Handle stack alignment.
+ (dwarf2out_frame_debug_expr): Add rules 16-20 to handle stack
+ alignment. Don't generate DWARF information for (set fp sp)
+ when DRAP is used.
+ (dwarf2out_begin_prologue): Initialize drap_reg and vdrap_reg
+ to INVALID_REGNUM.
+ (int_loc_descriptor): Move prototype forward. Also define if
+ DWARF2_UNWIND_INFO is true.
+ (output_cfa_loc): Handle DW_CFA_expression.
+ (build_cfa_aligned_loc): New.
+ (based_loc_descr): Update assert for stack realign. For local
+ variables, use sp+offset when stack is aligned without drap and
+ fp+offset when stack is aligned with drap. For arguments, use
+ cfa+offset when drap is used to align stack.
+
+2008-07-30 Joey Ye <joey.ye@intel.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.c (ix86_force_align_arg_pointer_string):
+ Break long line.
+ (ix86_gen_andsp): New.
+ (ix86_user_incoming_stack_boundary): Likewise.
+ (ix86_default_incoming_stack_boundary): Likewise.
+ (ix86_incoming_stack_boundary): Likewise.
+ (ix86_can_eliminate): Likewise.
+ (find_drap_reg): Likewise.
+ (ix86_update_stack_boundary): Likewise.
+ (ix86_get_drap_rtx): Likewise.
+ (ix86_finalize_stack_realign_flags): Likewise.
+ (TARGET_UPDATE_STACK_BOUNDARY): Likewise.
+ (TARGET_GET_DRAP_RTX): Likewise.
+ (override_options): Overide option value for new options.
+ (ix86_function_ok_for_sibcall): Remove check for
+ force_align_arg_pointer.
+ (ix86_handle_cconv_attribute): Likewise.
+ (ix86_function_regparm): Likewise.
+ (setup_incoming_varargs_64): Don't set stack_alignment_needed
+ here.
+ (ix86_va_start): Replace virtual_incoming_args_rtx with
+ crtl->args.internal_arg_pointer.
+ (ix86_select_alt_pic_regnum): Check DRAP register.
+ (ix86_save_reg): Replace force_align_arg_pointer with drap_reg.
+ (ix86_compute_frame_layout): Compute frame layout wrt stack
+ realignment.
+ (ix86_internal_arg_pointer): Just return
+ virtual_incoming_args_rtx.
+ (ix86_expand_prologue): Decide if stack realignment is needed
+ and generate prologue code accordingly.
+ (ix86_expand_epilogue): Generate epilogue code wrt stack
+ realignment is really needed or not.
+
+ * config/i386/i386.h (MAIN_STACK_BOUNDARY): New.
+ (ABI_STACK_BOUNDARY): Likewise.
+ (PREFERRED_STACK_BOUNDARY_DEFAULT): Likewise.
+ (STACK_REALIGN_DEFAULT): Likewise.
+ (INCOMING_STACK_BOUNDARY): Likewise.
+ (MAX_STACK_ALIGNMENT): Likewise.
+ (ix86_incoming_stack_boundary): Likewise.
+ (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): Removed.
+ (REAL_PIC_OFFSET_TABLE_REGNUM): Updated to use BX_REG.
+ (CAN_ELIMINATE): Defined with ix86_can_eliminate.
+ (machine_function): Remove force_align_arg_pointer.
+
+ * config/i386/i386.md (BX_REG): New.
+ (R13_REG): Likewise.
+
+ * config/i386/i386.opt (mforce_drap): New.
+ (mincoming-stack-boundary): Likewise.
+ (mstackrealign): Add Init(-1).
+
+ * config/i386/i386-protos.h (ix86_can_eliminate): New
+
+2008-07-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * doc/extend.texi: Update force_align_arg_pointer.
+
+ * doc/invoke.texi: Document -mincoming-stack-boundary. Update
+ -mstackrealign.
+
+ * doc/tm.texi (MAX_STACK_ALIGNMENT): Add macro.
+ (INCOMING_STACK_BOUNDARY): Likewise.
+ (TARGET_UPDATE_STACK_BOUNDARY): New target hook.
+ (TARGET_GET_DRAP_RTX): Likewise.
+
+2008-07-30 Andreas Schwab <schwab@suse.de>
+
+ PR rtl-optimization/36929
+ * dse.c (replace_inc_dec): Use emit_insn_before instead of
+ add_insn_before and fix argument order.
+ (replace_inc_dec_mem): Handle NULL rtx.
+
+2008-07-30 Andrew Jenner <andrew@codesourcery.com>
+
+ * config/arm/arm.c (arm_compute_static_chain_stack_bytes): New
+ function.
+ (arm_compute_initial_elimination_offset): Use it.
+ (arm_compute_save_reg_mask): Include static chain save slot when
+ calculating alignment.
+ (arm_get_frame_offsets): Ditto.
+ (thumb1_compute_save_reg_mask): Ensure we have a low register saved
+ that we can use to decrement the stack when the stack decrement
+ could be too big for an immediate value in a single insn.
+ (thumb1_expand_prologue): Avoid using r12 for stack decrement.
+
+2008-07-30 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/36967
+ * tree-predcom.c (remove_stmt): Use gimple_assign_ssa_name_copy_p.
+ Release defs of statements we remove.
+
+2008-07-30 Nathan Froyd <froydnj@codesourcery.com>
+
+ * config/arm/arm.c (arm_expand_prologue): Use 0-length rtvec
+ instead of NULL_RTVEC.
+
+2008-07-30 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR target/35866
+
+ * config/rs6000/rs6000.h (SLOW_UNALIGNED_ACCESS): Add clause for
+ vector modes.
+
2008-07-30 Rafael Avila de Espindola <espindola@google.com>
* final.c (call_from_call_insn): New.
@@ -28,7 +248,7 @@
(conversion_warning): Use the new function. Handle non-negative
constant in bitwise-and.
* c-common.h (shorten_binary_op): Declare.
-
+
2008-07-30 Olivier Hainque <hainque@adacore.com>
* scan.c (make_sstring_space): Add explicit conversions of
@@ -119,7 +339,7 @@
PR 34985
* c-decl.c (merge_decls): Merge USED flags.
-
+
2008-07-29 Kaz Kojima <kkojima@gcc.gnu.org>
* config/sh/sh.c (sh_gimplify_va_arg_expr): Unshare the addr,
@@ -387,7 +607,7 @@
(is_ctor_dtor): Return symkind instead of int. Adjust prototype,
code and head comment accordingly.
(scan_prog_file): Use symkind names instead of bare integers.
-
+
2008-07-25 Jan Hubicka <jh@suse.cz>
* cgraph.c (cgraph_function_possibly_inlined_p): Do not rely on DECL_INLINE.
@@ -396,7 +616,7 @@
* dojump.c (clear_pending_stack_adjust): Likewise.
* print-tree.c (print_node): Ignore DECL_INLINE.
* tree-inline.c (inlinable_function_p): Likewise.
-
+
2008-07-25 Michael Meissner <gnu@the-meissners.org>
* doc/extend.texi (hot attribute): Document that the hot attribute
@@ -490,7 +710,7 @@
(cgraph_gate_early_inlining): Likewise.
(gate_inline_passes): Remove.
(pass_inline_parameters, pass_ipa_inline): Remove gates.
- (cgraph_gate_O0_always_inline, cgraph_O0_always_inline,
+ (cgraph_gate_O0_always_inline, cgraph_O0_always_inline,
pass_O0_always_inline): Remove.
* c-pch.c (c_pch_matching): Remove -funit-at-a-time.
* dwarf2out.c (reference_to_unused): Remove flag_unit_at_a_time check.
@@ -545,7 +765,7 @@
* config/i386/i386.c (get_dllimport_decl): Treat user_label_prefix for
imp symbol extension.
- 2008-07-23 Ian Lance Taylor <iant@google.com>
+ 2008-07-23 Ian Lance Taylor <iant@google.com>
* tree-vrp.c (infer_value_range): Ignore asm statements when
looking for memory accesses for -fdelete-null-pointer-checks.
@@ -572,10 +792,10 @@
2008-07-23 Martin Jambor <mjambor@suse.cz>
- * ipa-cp.c (ipcp_print_edge_profiles): Test for node->analyzed
+ * ipa-cp.c (ipcp_print_edge_profiles): Test for node->analyzed
rather than for DECL_SAVED_TREE.
* ipa-prop.c: Include diagnostic.h.
- (ipa_check_stmt_modifications): Check LHS of GIMPLE_MODIFY_EXPRs
+ (ipa_check_stmt_modifications): Check LHS of GIMPLE_MODIFY_EXPRs
thoroughly.
(ipa_detect_param_modifications): Function rewritten from scratch.
(ipa_compute_jump_functions): Changed accesses to modification flags.
@@ -583,9 +803,9 @@
(ipa_node_duplication_hook): Update flags duplication.
(ipa_print_all_params_modified): Updated flag access.
* ipa-prop.h (struct ipa_param_flags): New structure.
- (struct ipa_node_params): New field modification_analysis_done,
- modified_flags changed into param_flags.
- (ipa_is_ith_param_modified): Changed to use new flags.
+ (struct ipa_node_params): New field modification_analysis_done,
+ modified_flags changed into param_flags.
+ (ipa_is_ith_param_modified): Changed to use new flags.
* Makefile.in (ipa-prop.o): Add $(DIAGNOSTIC_H) to dependencies.
* ipa-prop.c (ipa_print_all_jump_functions): Moved here from
@@ -614,18 +834,18 @@
* doc/invoke.texi (Optimize options): Add description of
-findirect-inlining.
* common.opt (flag_indirect_inlining): New flag.
- * opts.c (decode_options): Set flag_indirect_inlining when
+ * opts.c (decode_options): Set flag_indirect_inlining when
optimize >= 3.
* ipa-inline.c: Include ipa-prop.h.
(inline_indirect_intraprocedural_analysis): New function.
(inline_generate_summary): Allocate parameter and argument info
structures, call inline_indirect_intraprocedural_analysis on each
- node when doing indirect inlining and deallocate indirect inlining
+ node when doing indirect inlining and deallocate indirect inlining
data structures in the end.
* ipa-prop.c (ipa_create_param_decls_array): Return if already done.
(free_all_ipa_structures_after_iinln): New function.
- (free_all_ipa_structures_after_ipa_cp): Checks whether iinln will be
+ (free_all_ipa_structures_after_ipa_cp): Checks whether iinln will be
done.
* Makefile.in (ipa-inline.o): Added $(IPA_PROP_H) to dependencies.
@@ -634,7 +854,7 @@
of computing the frequency separately.
(rebuild_cgraph_edges): Call compute_call_stmt_bb_frequency instead
of computing the frequency separately.
- * ipa-cp.c (ipcp_print_all_structures): Replace a call to
+ * ipa-cp.c (ipcp_print_all_structures): Replace a call to
ipa_print_all_param_modified with a call to ipa_print_all_param_flags.
* ipa-prop.c (ipa_get_member_ptr_load_param): New function.
(ipa_get_stmt_member_ptr_load_param): New function.
@@ -696,7 +916,7 @@
* testsuite/g++.dg/ipa/iinline-1.C: New testcase.
* testsuite/gcc.dg/ipa/iinline-1.c: New testcase.
* testsuite/gcc.dg/ipa/modif-1.c: New testcase.
-
+
2008-07-23 Michael Meissner <gnu@the-meissners.org>
PR 36907
@@ -723,7 +943,7 @@
* c-typeck.c: All calls to pedwarn changed.
* c-common.c: All calls to pedwarn changed.
* c-parser.c: All calls to pedwarn changed.
-
+
2008-07-23 Michael Meissner <gnu@the-meissners.org>
Karthik Kumar <karthikkumar@gmail.com>
@@ -1190,7 +1410,7 @@
PR tree-opt/36879
* tree-switch-conversion.c (build_one_array): Call
- varpool_mark_needed_node and varpool_finalize_decl
+ varpool_mark_needed_node and varpool_finalize_decl
instead of assemble_variable.
2008-07-19 Jan Hubicka <jh@suse.cz>
@@ -1281,7 +1501,7 @@
(gen_array_type_die): Factorize comments about the MIPS_DEBUG_INFO
issues, centralize the nested array types collapsing control and
disable the transformation for Ada.
-
+
2008-07-18 Uros Bizjak <ubizjak@gmail.com>
PR target/36786
@@ -1473,10 +1693,10 @@
* config/sh/sh.md (symGOT_load): Don't add REG_EQUAL note.
2008-07-15 Bob Wilson <bob.wilson@acm.org>
-
+
* config/xtensa/libgcc-xtensa.ver: New file.
* config/xtensa/t-linux (SHLIB_MAPFILES): Append libgcc-xtensa.ver.
-
+
2008-07-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* df-problems.c (df_set_note): Avoid C++ keywords.
@@ -1728,7 +1948,7 @@
* config/h8300/h8300.md (length): Fix branch offset limit.
-2008-07-11 Anatoly Sokolov <aesok@post.ru>
+2008-07-11 Anatoly Sokolov <aesok@post.ru>
* config/avr/avr-protos.h (avr_peep2_scratch_safe): Remove prototype.
* config/avr/avr.c (avr_peep2_scratch_safe): Remove.
@@ -1867,7 +2087,7 @@
callers.
* omp-low.c (lower_omp_sections, lower_omp_single, lower_omp_master,
lower_omp_ordered, lower_omp_critical, lower_omp_for,
- create_task_copyfn, lower_omp_taskreg, execute_lower_omp):
+ create_task_copyfn, lower_omp_taskreg, execute_lower_omp):
* tree-ssa-ccp.c (convert_to_gimple_builtin): Likewise.
* tree-sra.c (generate_element_init): Likewise.
* tree-mudflap.c (execute_mudflap_function_ops,
@@ -1976,7 +2196,7 @@
* tree-sra.c (sra_build_assignment): Handle CONVERT_EXPR_P dst.
2008-07-05 Daniel Berlin <dberlin@dberlin.org>
-
+
Fix PR tree-optimization/23455
Fix PR tree-optimization/35286
Fix PR tree-optimization/35287
@@ -2029,7 +2249,7 @@
(vn_nary_op_compute_hash): De-staticify.
(vn_nary_op_eq): Ditto.
(vn_nary_op_lookup_pieces): New function.
- (vn_nary_op_lookup): Add new argument.
+ (vn_nary_op_lookup): Add new argument.
(vn_nary_op_insert_pieces): New function.
(vn_nary_op_insert): Add return type. Modify to deal with value ids.
(vn_phi_insert): Ditto.
@@ -2038,7 +2258,7 @@
(visit_reference_op_load): Ditto.
(visit_reference_op_store): Ditto.
(init_scc_vn): Init next_value_id, constant_to_value_id and
- constant_value_ids.
+ constant_value_ids.
(free_scc_vn): Free them.
(set_hashtable_value_ids): New function.
(run_scc_vn): Use it.
@@ -2051,7 +2271,7 @@
above).
* tree.c (iterative_hash_hashval_t): Made non-static
* tree.h (iterative_hash_hashval_t): Declare it.
-
+
2008-07-08 Martin Jambor <mjambor@suse.cz>
* ipa-cp.c (ipcp_init_cloned_node): Call ipa_check_create_node_params
@@ -2083,7 +2303,7 @@
(ipa_register_cgraph_hooks): New function.
(ipa_unregister_cgraph_hooks): New function.
(free_all_ipa_structures_after_ipa_cp): New function.
-
+
* ipa-prop.h: Include vec.h.
(ipa_node_params_t): New typedef with vector types for it.
(ipa_edge_args_t): New typedef with vector types for it.
@@ -2091,10 +2311,10 @@
(IPA_EDGE_REF): Changed to access an on-the-side vector.
(ipa_check_create_node_params): New function.
(ipa_check_create_edge_args): New function.
-
+
* Makefile.in (IPA_PROP_H): New variable for ipa-prop.h. Converted
all users.
-
+
2008-07-07 Tom Tromey <tromey@redhat.com>
* configure, config.in: Rebuilt.
@@ -2177,7 +2397,7 @@
-print-sysroot option.
(main): Print the sysroot if requested.
* doc/invoke.texi (Debugging Options): Document -print-sysroot.
-
+
2008-07-07 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
PR target/34780
@@ -2230,7 +2450,7 @@
2008-07-07 Maxim Kuvyrkov <maxim@codesourcery.com>
* config/m68k/m68k.c (m68k_return_in_memory): Fix arguments types.
-
+
2008-07-07 Mark Shinwell <shinwell@codesourcery.com>
* config/m68k/lb1sf68.asm: Add PIC macros for Linux targets.
@@ -2628,7 +2848,7 @@
2008-07-02 Martin Jambor <mjambor@suse.cz>
* tree-switch-conversion.c: Included timevar.h which I forgot before.
-
+
2008-07-02 Martin Jambor <mjambor@suse.cz>
* tree-switch-conversion.c: Included timevar.h
@@ -2756,7 +2976,7 @@
2008-06-30 Kenneth Zadeck <zadeck@naturalbridge.com>
* ifcvt.c (cond_move_process_if_block): Free vectors on false return.
-
+
2008-06-30 Kenneth Zadeck <zadeck@naturalbridge.com>
PR rtl-optimization/34744
@@ -2785,7 +3005,7 @@
(ix86_init_builtins): Here.
(ix86_scalar_mode_supported_p): Always return true for TFmode.
(ix86_c_mode_for_suffix): Always return TFmode and XFmode for
- 'q' and 'w', respectively.
+ 'q' and 'w', respectively.
* config/i386/i386.md (movtf): Check TARGET_SSE2 instead of
TARGET_64BIT.
@@ -3669,7 +3889,7 @@
2008-06-22 Andy Hutchinson <hutchinsonandy@aim.com>
* config/avr/avr.h (SUPPORTS_INIT_PRIORITY): Define.
-
+
2008-06-22 Laurynas Biveinis <laurynas.biveinis@gmail.com>
PR middle-end/34906
@@ -3817,7 +4037,7 @@
* tree-ssa-loop-im.c (mem_ref_in_stmt, memref_hash, memref_eq,
memref_free, gather_mem_refs_stmt, vtoe_hash, vtoe_eq, vtoe_free,
record_vop_access, get_vop_accesses, get_vop_stores): Likewise.
- * tree-ssa-loop-prefetch.c (determine_loop_nest_reuse): Likewise.
+ * tree-ssa-loop-prefetch.c (determine_loop_nest_reuse): Likewise.
* tree-ssa-sccvn.c (VN_INFO_GET, free_phi, free_reference,
vn_nary_op_insert): Likewise.
* tree-ssa.c (redirect_edge_var_map_add,
@@ -4143,20 +4363,20 @@
2008-06-17 Eric B. Weddington <eric.weddington@atmel.com>
* config/avr/avr.c (avr_mcu_t): Remove atmega32hvb.
- * config/avr/avr.h (LINK_SPEC, CRT_BINUTILS_SPECS): Likewise.
- * config/avr/t-avr (MULTILIB_MATCHES): Likewise.
+ * config/avr/avr.h (LINK_SPEC, CRT_BINUTILS_SPECS): Likewise.
+ * config/avr/t-avr (MULTILIB_MATCHES): Likewise.
2008-06-17 Eric B. Weddington <eric.weddington@atmel.com>
* config/avr/avr.c (avr_mcu_t): Add attiny167.
- * config/avr/avr.h (LINK_SPEC, CRT_BINUTILS_SPECS): Likewise.
- * gcc/config/avr/t-avr (MULTILIB_MATCHES): Likewise.
+ * config/avr/avr.h (LINK_SPEC, CRT_BINUTILS_SPECS): Likewise.
+ * gcc/config/avr/t-avr (MULTILIB_MATCHES): Likewise.
2008-06-17 Eric B. Weddington <eric.weddington@atmel.com>
* config/avr/avr.c (avr_mcu_t): Add atmega32u4.
- * config/avr/avr.h (LINK_SPEC, CRT_BINUTILS_SPECS): Likewise.
- * config/avr/t-avr (MULTILIB_MATCHES): Likewise.
+ * config/avr/avr.h (LINK_SPEC, CRT_BINUTILS_SPECS): Likewise.
+ * config/avr/t-avr (MULTILIB_MATCHES): Likewise.
2008-06-17 Bernhard Fischer <aldot@gcc.gnu.org>
@@ -4217,7 +4437,7 @@
(delete_unmarked_insns): Don't handle libcall blocks.
(preserve_libcall_for_dce): Remove.
(prescan_insns_for_dce): Don't special-case libcall block insns.
- * reload1 (reload): Don't handle libcall notes.
+ * reload1 (reload): Don't handle libcall notes.
* doc/rtl.texi (REG_LIBCALL, REG_RETVAL, REG_LIBCALL_ID): Remove
documentation.
@@ -4231,7 +4451,7 @@
* config/avr/avr.c (avr_mcu_t): Add atmega32m1.
* config/avr/avr.h (LINK_SPEC, CRT_BINUTILS_SPECS): Likewise.
- * config/avr/t-avr (MULTILIB_MATCHES): Likewise.
+ * config/avr/t-avr (MULTILIB_MATCHES): Likewise.
2008-06-16 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
@@ -4252,7 +4472,7 @@
2008-06-015 Andy Hutchinson <hutchinsonandy@aim.com>
PR target/36336
- * config/avr/avr.h (LEGITIMIZE_RELOAD_ADDRESS): Add check for
+ * config/avr/avr.h (LEGITIMIZE_RELOAD_ADDRESS): Add check for
reg_equiv_constant.
2008-06-15 Maxim Kuvyrkov <maxim@codesourcery.com>
@@ -4328,7 +4548,7 @@
Nathan Sidwell <nathan@codesourcery.com>
Maxim Kuvyrkov <maxim@codesourcery.com>
Richard Sandiford <rdsandiford@googlemail.com>
-
+
* config/mips/mips-modes.def: Add V8QI, V4HI and V2SI modes.
* config/mips/mips-protos.h (mips_expand_vector_init): New.
* config/mips/mips-ftypes.def: Add function types for Loongson-2E/2F
@@ -4631,7 +4851,7 @@
2008-06-09 Andy Hutchinson <hutchinsonandy@aim.com>
PR middle-end/36447
- * simplify-rtx.c (simplify_subreg): Add check for shift count
+ * simplify-rtx.c (simplify_subreg): Add check for shift count
greater than size.
2008-06-09 Richard Sandiford <rdsandiford@googlemail.com>
@@ -4746,7 +4966,7 @@
* doc/invoke.texi (Wenum-compare): Mention that it is enabled by
default.
-
+
2008-06-08 Joseph Myers <joseph@codesourcery.com>
PR tree-optimization/36218
@@ -4760,8 +4980,8 @@
PR target/36424
* config/avr/avr.h (HARD_REGNO_RENAME_OK): Define.
- * config/avr/avr.c (avr_hard_regno_rename_ok): New function.
- * config/avr/avr-protos.h (avr_hard_regno_rename_ok): New prototype.
+ * config/avr/avr.c (avr_hard_regno_rename_ok): New function.
+ * config/avr/avr-protos.h (avr_hard_regno_rename_ok): New prototype.
2008-06-07 Danny Smith <dannysmith@users.sourceforge.net>
@@ -5089,7 +5309,7 @@
Rename parallel_nesting_level to taskreg_nesting_level.
(scan_omp_task): New function.
(lower_rec_input_clauses): Don't run constructors for firstprivate
- explicit task vars which are initialized by *_omp_cpyfn*.
+ explicit task vars which are initialized by *_omp_cpyfn*.
Pass outer var ref to omp_clause_default_ctor hook if
OMP_CLAUSE_PRIVATE_OUTER_REF or OMP_CLAUSE_LASTPRIVATE.
Replace OMP_CLAUSE_REDUCTION_PLACEHOLDER decls in
@@ -5363,11 +5583,11 @@
PR target/30243
* builtins.c (expand_builtin_signbit): Don't take lowpart when
- register is already smaller or equal to required mode.
+ register is already smaller or equal to required mode.
2008-06-04 Xinliang David Li <davidxl@google.com>
- * tree-call-cdce.c: New file.
+ * tree-call-cdce.c: New file.
(cond_dead_built_in_calls): New static variable.
(input_domain): New struct.
(check_pow): New function.
@@ -5542,7 +5762,7 @@
* config/i386/mingw32.h (EXTRA_OS_CPP_BUILTINS): Replace
TARGET_64BIT_MS_ABI by DEFAULT_ABI compare to MS_ABI.
-2008-06-02 Andy Hutchinson <hutchinsonandy@aim.com>
+2008-06-02 Andy Hutchinson <hutchinsonandy@aim.com>
PR target/34879
* config/avr/avr.c (TARGET_BUILTIN_SETJMP_FRAME_VALUE): Redefine.
@@ -5678,10 +5898,10 @@
* config/avr/avr.md (UNSPECV_WRITE_SP_IRQ_ON): New constants.
(UNSPECV_WRITE_SP_IRQ_OFF): (Ditto.).
(movhi_sp_r_irq_off, movhi_sp_r_irq_on): New insn.
- * config/avr/avr.c (expand_prologue, expand_epilogue): Use
- movhi_sp_r_irq_off and movhi_sp_r_irq_on insns for writing to the
+ * config/avr/avr.c (expand_prologue, expand_epilogue): Use
+ movhi_sp_r_irq_off and movhi_sp_r_irq_on insns for writing to the
stack pointer register.
- (output_movhi): Remove code for interrupt specific writing to the
+ (output_movhi): Remove code for interrupt specific writing to the
stack pointer register.
2008-05-31 Richard Guenther <rguenther@suse.de>
@@ -5810,7 +6030,7 @@
call clobber check for NMTs.
2008-05-28 Seongbae Park <seongbae.park@gmail.com>
-
+
* value-prof.c (tree_ic_transform): Use HOST_WIDEST_INT_PRINT_DEC
for printing gcov_type.
@@ -6048,9 +6268,9 @@
that the bitfield is of integral type before testing its precision.
2008-05-27 Trevor Smigiel <trevor_smigiel@playstation.sony.com>
- Sa Liu <saliu@de.ibm.com>
+ Sa Liu <saliu@de.ibm.com>
- * config/spu/spu.c (spu_init_libfuncs): Add __multi3, __divti3,
+ * config/spu/spu.c (spu_init_libfuncs): Add __multi3, __divti3,
__modti3, __udivti3, __umodti3 and __udivmodti4.
* config/spu/t-spu-elf (LIB2FUNCS_STATIC_EXTRA): Add files
that implement TImode mul and div functions.
@@ -6089,7 +6309,7 @@
* config/avr/avr.md ("call_prologue_saves"): Use hi8(gs())/lo8(gs())
instead of pm_lo8/pm_hi8 to makes this call working on avr6.
- * config/avr/avr.c (expand_prologue): Tune "call_prologue"
+ * config/avr/avr.c (expand_prologue): Tune "call_prologue"
optimization for 'avr6' architecture.
2008-05-26 Andy Hutchinson <hutchinsonandy@aim.com>
@@ -6627,7 +6847,7 @@
* tree-data-ref.c (dr_analyze_indices): Replace resolve_mixers with
instantiate_scev.
(analyze_siv_subscript): Pass in the loop nest number.
- Call evolution_function_is_affine_in_loop instead of
+ Call evolution_function_is_affine_in_loop instead of
evolution_function_is_affine_p.
(analyze_overlapping_iterations): Pass in the loop nest number.
@@ -6693,7 +6913,7 @@
2008-05-19 Xinliang David Li <davidxl@google.com>
- * tree-ssa-dce.c: Revert patches of 2008-05-17 and 2008-05-18.
+ * tree-ssa-dce.c: Revert patches of 2008-05-17 and 2008-05-18.
* opts.c: Ditto.
* common.opt: Ditto.
* doc/invoke.texi: Ditto.
@@ -6752,7 +6972,7 @@
2008-05-18 Xinliang David Li <davidxl@google.com>
* gcc/tree-ssa-dce.c: Coding style fix.
- (check_pow): Documentation comment.
+ (check_pow): Documentation comment.
(check_log): Documenation comment. Coding style fix.
(is_unnecessary_except_errno_call): Ditto.
(gen_conditions_for_pow): Ditto.
@@ -6760,7 +6980,7 @@
(gen_shrink_wrap_conditions): Ditto.
(shrink_wrap_one_built_in_calls): Ditto.
* gcc/doc/invoke.texi: Better documentation string.
- * ChangeLog: Fix wrong change log entries from
+ * ChangeLog: Fix wrong change log entries from
May 17 checkin on function call DCE.
2008-05-17 Kaz Kojima <kkojima@gcc.gnu.org>
@@ -6772,7 +6992,7 @@
* doc/rtl.texi (RTL_CONST_CALL_P, RTL_PURE_CALL_P): Fixed typos.
* df-problems.c (simulation routines): Fixed block comment to
properly say how to add forwards scanning functions.
-
+
2008-05-17 Eric Botcazou <ebotcazou@adacore.com>
* tree-inline.c (setup_one_parameter): Remove dead code.
@@ -6785,8 +7005,8 @@
2008-05-17 Xinliang David Li <davidxl@google.com>
* gcc/tree-ssa-dce.c (cond_dead_built_in_calls): New static variable.
- (check_pow, check_log, is_unnecessary_except_errno_call): New
- functions to check for eliminating math functions that are pure
+ (check_pow, check_log, is_unnecessary_except_errno_call): New
+ functions to check for eliminating math functions that are pure
except for setting errno.
(gen_conditions_for_pow, gen_conditionas_for_log): New functions to
general condition expressions for shrink-wrapping pow/log calls.
@@ -6849,7 +7069,7 @@
2008-05-16 Kenneth Zadeck <zadeck@naturalbridge.com>
* tree-ssa-dse (max_stmt_uid): Removed.
- (get_stmt_uid, dse_possible_dead_store_p, dse_optimize_stmt,
+ (get_stmt_uid, dse_possible_dead_store_p, dse_optimize_stmt,
tree_ssa_dse): Encapsulate all uses of stmt_ann->uid.
* tree-ssa-sccvn.c (compare_ops, init_scc_vn): Ditto.
* function.h (cfun.last_stmt_uid): New field.
@@ -6928,7 +7148,7 @@
write_summary, read_summary.
* cgraphunit.c (cgraph_process_new_functions): Changed call from
pass_ipa_inline.function_generate_summary, to
- compute_inline_parameters.
+ compute_inline_parameters.
* ipa-inline.c (compute_inline_parameters): Made public and added
node parameter.
(compute_inline_parameters_for_current): New function.
@@ -6938,19 +7158,19 @@
(pass_ipa_inline): Updated for new IPA_PASS structure.
* passes.c (execute_ipa_summary_passes): Now is called once per
pass rather than once per node*pass.
-
+
2008-05-15 Anatoly Sokolov <aesok@post.ru>
- * config/avr/avr.c (avr_base_arch_macro, avr_have_movw_lpmx_p,
+ * config/avr/avr.c (avr_base_arch_macro, avr_have_movw_lpmx_p,
avr_have_mul_p, avr_asm_only_p): Remove variables.
(avr_override_options): Remove initialization of removed variables.
- (avr_file_start): Convert removed variables to fields of
- 'struct base_arch_s *avr_current_arch'.
+ (avr_file_start): Convert removed variables to fields of
+ 'struct base_arch_s *avr_current_arch'.
* config/avr/avr.h (TARGET_CPU_CPP_BUILTINS): (Ditto.).
(AVR_HAVE_MUL): (Ditto.).
(AVR_HAVE_MOVW): (Ditto.).
- (AVR_HAVE_LPMX): (Ditto.).
- (avr_base_arch_macro, avr_have_movw_lpmx_p, avr_have_mul_p,
+ (AVR_HAVE_LPMX): (Ditto.).
+ (avr_base_arch_macro, avr_have_movw_lpmx_p, avr_have_mul_p,
avr_asm_only_p): Remove declaration.
2008-05-15 Diego Novillo <dnovillo@google.com>
@@ -6966,7 +7186,7 @@
(record_truncated_value): Turn it into a for_each_rtx callback.
(record_truncated_values): New function.
(combine_instructions): Call note_uses with record_truncated_values.
- Change name of check_conversion to check_promoted_subreg.
+ Change name of check_conversion to check_promoted_subreg.
2008-05-15 Janis Johnson <janis187@us.ibm.com>
@@ -7250,14 +7470,14 @@
* optabs.c (prepare_cmp_insn): Changed LCT_PURE_MAKE_BLOCK to
LCT_PURE and LCT_CONST_MAKE_BLOCK to LCT_CONST in calls to
- emit_library_call_value.
+ emit_library_call_value.
* builtins.c (expand_builtin_powi, expand_builtin_memcmp): Ditto.
* tree.h (ECF_LIBCALL_BLOCK): Removed.
- * calls.c (initialize_argument_information, precompute_arguments,
+ * calls.c (initialize_argument_information, precompute_arguments,
expand_call, emit_library_call_value_1): Remove ECF_LIBCALL_BLOCK.
(precompute_arguments): Removed flags parameter.
* rtl.h (LCT_CONST_MAKE_BLOCK, LCT_PURE_MAKE_BLOCK): Removed.
-
+
2008-05-14 Richard Guenther <rguenther@suse.de>
* tree-ssa-dse.c (dse_possible_dead_store_p): Remove dead code.
@@ -7445,7 +7665,7 @@
2008-05-10 Kenneth Zadeck <zadeck@naturalbridge.com>
* gcse.c (store_killed_in_insn): Negated call to RTL_CONST_CALL_P.
-
+
2008-05-10 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (bdesc_ptest): Removed.
@@ -7588,7 +7808,7 @@
CONVERT_EXPR_P.
(CONVERT_EXPR_P): Define.
(CASE_CONVERT): Define.
-
+
2008-05-08 Kenneth Zadeck <zadeck@naturalbridge.com>
PR middle-end/36117
@@ -7672,7 +7892,7 @@
2008-05-08 David Daney <ddaney@avtrex.com>
Richard Sandiford <rsandifo@nildram.co.uk>
-
+
* config/mips/mips.md (mips_expand_compare_and_swap_12): Handle
special case of constant zero operands.
* config/mips/mips.c (mips_expand_compare_and_swap_12): Zero extend
@@ -7897,9 +8117,9 @@
(analyze_function): Rename DECL_IS_PURE to DECL_PURE_P.
(static_execute): Set looping true for recursive functions.
Undo setting state to IPA_NEITHER for recursive functions.
- * cse.c (cse_insn):
+ * cse.c (cse_insn):
* ifcvt.c (noce_can_store_speculate_p): Changed
- CONST_OR_PURE_CALL_P and pure_call_p to RTL_CONST_CALL_P or
+ CONST_OR_PURE_CALL_P and pure_call_p to RTL_CONST_CALL_P or
RTL_CONST_OR_PURE_CALL_P.
* dse.c (scan_insn): Ditto.
* local-alloc.c (validate_equiv_mem, memref_used_between_p): Ditto.
@@ -7941,7 +8161,7 @@
DECL_PURE_P.
* tree-cfg.c (update_call_expr_flags): Do not clear tree side
effects for looping pure or const calls.
- (verify_gimple_expr): Added verification code.
+ (verify_gimple_expr): Added verification code.
* config/alpha/alpha.c (alpha_legitimize_address,
alpha_emit_xfloating_libcall): Changed CONST_OR_PURE_CALL_P to
RTL_CONST_CALL_P.
@@ -8235,14 +8455,14 @@
(ipcp_redirect): Removed newly unused local variable callee.
(ipcp_redirect): Removed (a bit confusing) local variable type.
(ipcp_insert_stage): Added local variable info.
- (ipcp_cval_changed): Renamed to ipcp_lattice_changed, parameters
+ (ipcp_cval_changed): Renamed to ipcp_lattice_changed, parameters
renamed too
(ipcp_formal_create): Removed.
(ipcp_method_cval_set): Removed.
(ipcp_propagate_stage): Renamed lattice variables.
(ipcp_method_cval_set_cvalue_type): Removed.
(ipcp_method_cval_print): Renamed to ipcp_print_all_lattices
- (ipcp_print_all_lattices): Changed printed strings to refer to
+ (ipcp_print_all_lattices): Changed printed strings to refer to
lattices rather than cvals.
(ipcp_method_cval_init): Renamed to ipcp_initialize_node_lattices
(ipcp_propagate_const): Changed formal parameters.
@@ -8253,7 +8473,7 @@
(ipcp_after_propagate): Renamed to ipcp_change_tops_to_bottom
(ipcp_callsite_param_print): Renamed to ipcp_print_all_jump_functions
(ipcp_profile_mt_count_print): Renamed to ipcp_print_func_profile_counts
- (ipcp_print_func_profile_counts): Changed string from "method" to
+ (ipcp_print_func_profile_counts): Changed string from "method" to
"function"
(ipcp_profile_cs_count_print): Renamed to ipcp_print_call_profile_counts
(ipcp_profile_edge_print): Renamed to ipcp_print_edge_profiles
@@ -8263,7 +8483,7 @@
(ipcp_lat_is_const): Changed parameters and made inline.
(ipcp_replace_map_create): Renamed to ipcp_create_replace_map
(ipcp_redirect): Renamed to ipcp_need_redirect_p
- (ipcp_need_redirect_p): Calls ipcp_lat_is_const instead of using
+ (ipcp_need_redirect_p): Calls ipcp_lat_is_const instead of using
the predicate condition directly
(ipcp_propagate_stage): Added local variable args. Removed local
variable callee. (Both are mere code simplifications.)
@@ -8390,13 +8610,13 @@
* gthr-single.h: Add in required interface elements as per gthr.h.
Add stub types for __gthread_key_t, __gthread_once_t. Add defines
for __GTHREAD_ONCE_INIT, __GTHREAD_RECURSIVE_MUTEX_INIT.
- Generalize UNUSED macro.
+ Generalize UNUSED macro.
(__gthread_once): Add.
(__gthread_key_create): Add.
(__gthread_key_delete): Add.
(__gthread_getspecific): Add.
(__gthread_setspecific): Add.
-
+
2008-05-05 Andrew Pinski <Andrew.Pinski@playstation.sony.com>
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): If we have
@@ -8478,7 +8698,7 @@
* doc/invoke.texi (max-flow-memory-locations): Removed.
* params.def (PARAM_MAX_FLOW_MEMORY_LOCATIONS): Removed.
-
+
2008-05-03 Richard Guenther <rguenther@suse.de>
PR middle-end/34973
@@ -8760,13 +8980,13 @@
* ipa-cp.c (ipcp_init_stage): Calls ipa_set_called_with_variable_arg
instead of setting number of formal parameters to zero.
- (ipcp_init_stage): Do not set the number of actual parameters to zero
+ (ipcp_init_stage): Do not set the number of actual parameters to zero
either.
(ipcp_propagate_stage): Explicitly skipping all calls to nodes
which are called with variable number of arguments.
(ipcp_insert_stage): Explicitely skipping all nodes which are
called with variable number of arguments.
- (ipcp_callsite_param_print): Skipps callsites to nodes with varaible
+ (ipcp_callsite_param_print): Skipps callsites to nodes with varaible
number of parameters.
* ipa-prop.h (struct ipa_node_params): Added flag
@@ -8778,13 +8998,13 @@
(ipa_is_called_with_var_arguments): Added.
(ipa_get_ith_param): Added. All readers of param_decls converted
to use it instead.
- (ipa_set_cs_argument_count): Added, sole writer to argument_count
- changed to use it.
+ (ipa_set_cs_argument_count): Added, sole writer to argument_count
+ changed to use it.
(ipa_get_cs_argument_count): Added, all readers of argument_count
changed to cal it.
- (ipa_get_ith_jump_func): Added. Accessors of jump values changed
+ (ipa_get_ith_jump_func): Added. Accessors of jump values changed
to use it.
-
+
* ipa-prop.h (struct ipcp_formal): Renamed to ipcp_lattice
(struct ipcp_lattice): Renamed cval_type to type
(struct ipa_node_params): ipcp_cval renamed to ipcp_lattices
@@ -8796,9 +9016,9 @@
(build_const_val): Changed the type of parameter cvalue to tree
(ipcp_propagate_const): Changed the type of parameter cvalue to tree
(ipcp_method_cval_set_cvalue_type): Renamed parameter cval_type1 to type
-
- * ipa-prop.h (struct ipcp_formal): Replaced cvalue with tree called
- constant
+
+ * ipa-prop.h (struct ipcp_formal): Replaced cvalue with tree called
+ constant
* ipa-prop.c (ipa_methodlist_init): Renamed to ipa_init_func_list
(ipa_methodlist_not_empty): Removed, the sole user now checks directly
@@ -8816,7 +9036,7 @@
(ipa_method_tree_map_create): Removed.
(ipa_method_compute_tree_map): Renamed to ipa_create_param_decls_array
(ipa_create_param_decls_array): Creates the array itself
- (ipa_create_param_decls_array): Temporary variable info instead of
+ (ipa_create_param_decls_array): Temporary variable info instead of
a few dereferences.
(ipa_method_formal_compute_count): Renamed to ipa_count_formal_params
(ipa_method_compute_modify): Renamed to ipa_detect_param_modifications
@@ -8828,7 +9048,7 @@
(ipa_edges_create): Renamed to ipa_create_all_edge_args
(ipa_edges_free): Renamed to ipa_free_all_edge_args
(ipa_nodes_free): Integrated into ipa_free_all_node_params and removed
- (ipa_free_all_node_params): Deallocation to jump_functions moved to
+ (ipa_free_all_node_params): Deallocation to jump_functions moved to
ipa_free_all_edge_args
(ipa_method_tree_print): Renamed to ipa_print_all_tree_maps
(ipa_method_modify_print): Renamed to ipa_print_all_params_modified
@@ -8839,22 +9059,22 @@
(ipa_methodlist_next_method_set): Removed.
(ipa_method_is_modified): Removed.
(ipa_method_modify_create): Removed.
- (ipa_method_modify_init): Temporary variable info instead of a few
+ (ipa_method_modify_init): Temporary variable info instead of a few
dereferences.
- (ipa_detect_param_modifications): Temporary variable info instead of
+ (ipa_detect_param_modifications): Temporary variable info instead of
a few dereferences.
- (ipa_compute_jump_functions): Temporary variable info instead of
+ (ipa_compute_jump_functions): Temporary variable info instead of
a few dereferences.
(ipa_method_modify_set): Removed.
(ipa_method_tree_map): Renamed to ipa_get_param_decl_index
- (ipa_get_param_decl_index): Now accepts struct ipa_node_params rather
+ (ipa_get_param_decl_index): Now accepts struct ipa_node_params rather
than craph_node as the first parameter.
(ipa_method_modify_stmt): Renamed to ipa_check_stmt_modifications
(ipa_method_modify_init): Removed.
- (ipa_compute_jump_functions): Added a temp variable instead of
+ (ipa_compute_jump_functions): Added a temp variable instead of
repeatadly dereferencing the cgraph_edge.aux pointer
(ipa_callsite_param_set_type): Removed.
- (ipa_compute_jump_functions): i renamed to index and moved to
+ (ipa_compute_jump_functions): i renamed to index and moved to
an inner block
(ipa_callsite_param_set_info_type_formal): Removed.
(ipa_callsite_param_set_info_type): Removed.
@@ -8865,9 +9085,9 @@
* ipa-prop.h (enum cvalue_type): Renamed to ipa_lattice_type,
prefixed all values with IPA_. Changed all users.
- (enum jump_func_type): Rnamed UNKNOWN_IPATYPE to IPA_UNKNOWN,
- CONST_IPATYPE to IPA_CONST, CONST_IPATYPE_REF to IPA_CONST_REF
- and FORMAL_IPATYPE IPA_PASS_THROUGH.
+ (enum jump_func_type): Rnamed UNKNOWN_IPATYPE to IPA_UNKNOWN,
+ CONST_IPATYPE to IPA_CONST, CONST_IPATYPE_REF to IPA_CONST_REF
+ and FORMAL_IPATYPE IPA_PASS_THROUGH.
(union parameter_info): Renamed to jump_func_value.
(union jump_func_value): Renamed value to constant
(struct ipa_jump_func): Renamed info_type to value
@@ -9024,7 +9244,7 @@
* tree-ssa-loop-manip.c (find_uses_to_rename_use): Only record
uses outside of the loop.
(tree_duplicate_loop_to_header_edge): Only verify loop-closed SSA
- form if it is available.
+ form if it is available.
* tree-flow.h (tree_unroll_loops_completely): Add extra parameter.
* passes.c (init_optimization_passes): Schedule complete inner
loop unrolling pass before the first CCP pass after final inlining.
@@ -9366,9 +9586,9 @@
(init_elim_table): Update.
2008-04-25 Bob Wilson <bob.wilson@acm.org>
-
+
* optabs.c (expand_float): Fix REG_EQUAL for UNSIGNED_FLOAT libcall.
-
+
2008-04-25 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/sse.md (mov<mode>): Replace SSEMODEI with SSEMODE.
@@ -9439,7 +9659,7 @@
of code delimited by two edges in the CFG.
(separate_decls_in_loop_name): Renamed separate_decls_in_region_name.
(separate_decls_in_loop_stmt): Renamed separate_decls_in_region_stmt.
- (separate_decls_in_loop): Renamed separate_decls_in_region. Isolate
+ (separate_decls_in_loop): Renamed separate_decls_in_region. Isolate
the case of parallelisation of reductions.
(expr_invariant_in_region_p): New.
@@ -9606,7 +9826,7 @@
PR middle-end/36003
* passes.c (init_optimization_passes): Remove
pass_fast_rtl_byte_dce.
-
+
2008-04-22 Uros Bizjak <ubizjak@gmail.com>
PR target/29096
@@ -9697,14 +9917,14 @@
* dbgcnt.def (ra_byte_scan): Added.
* dbgcnt.c (dbg_cnt): Added code to print message to dump_file
- when the last hit happens for a counter.
+ when the last hit happens for a counter.
* timevar.def (TV_DF_BYTE_LR): New variable.
* tree-pass.h (pass_fast_rtl_byte_dce): New pass.
* passes.c (pass_fast_rtl_byte_dce): New pass.
* fwprop.c (update_df): Added mode to call df_ref_create.
Renamed DF_REF_WIDTH and DF_REF_OFFSET to DF_REF_EXTRACT_WIDTH and
DF_REF_EXTRACT_OFFSET.
- * df.h (DF_BYTE_LR, DF_BYTE_LR_BB_INFO, DF_BYTE_LR_IN,
+ * df.h (DF_BYTE_LR, DF_BYTE_LR_BB_INFO, DF_BYTE_LR_IN,
DF_BYTE_LR_OUT, df_byte_lr): New macro.
(df_mm): New enum.
(df_ref_extract): Added mode field.
@@ -9712,7 +9932,7 @@
DF_REF_EXTRACT_OFFSET.
(DF_REF_EXTRACT_MODE): New macro.
(df_byte_lr_bb_info): New structure.
- (df_print_byte_regset, df_compute_accessed_bytes,
+ (df_print_byte_regset, df_compute_accessed_bytes,
df_byte_lr_add_problem, df_byte_lr_get_regno_start,
df_byte_lr_get_regno_len, df_byte_lr_simulate_defs,
df_byte_lr_simulate_uses,
@@ -9723,9 +9943,9 @@
(df_byte_lr_get_bb_info): New inline function.
* df-scan.c (df_ref_record, df_uses_record,
df_ref_create_structure): Added mode parameter.
- (df_ref_create, df_notes_rescan, df_ref_record, df_def_record_1,
+ (df_ref_create, df_notes_rescan, df_ref_record, df_def_record_1,
df_defs_record, df_uses_record, df_get_conditional_uses,
- df_get_call_refs, df_insn_refs_collect, df_bb_refs_collect,
+ df_get_call_refs, df_insn_refs_collect, df_bb_refs_collect,
df_entry_block_defs_collect, df_exit_block_uses_collect):
Added mode parameter to calls to df_ref_record, df_uses_record,
df_ref_create_structure.
@@ -9736,25 +9956,25 @@
* df-core.c (df_print_byte_regset): New function.
* df-byte-scan.c: New file.
* df-problems.c (df_rd_transfer_function): Removed unnecessary
- calls to BITMAP_FREE.
+ calls to BITMAP_FREE.
(df_byte_lr_problem_data, df_problem problem_BYTE_LR): New structure.
(df_byte_lr_get_regno_start, df_byte_lr_get_regno_len,
- df_byte_lr_set_bb_info, df_byte_lr_free_bb_info,
- df_byte_lr_check_regs, df_byte_lr_expand_bitmap,
+ df_byte_lr_set_bb_info, df_byte_lr_free_bb_info,
+ df_byte_lr_check_regs, df_byte_lr_expand_bitmap,
df_byte_lr_alloc, df_byte_lr_reset, df_byte_lr_bb_local_compute,
df_byte_lr_local_compute, df_byte_lr_init,
- df_byte_lr_confluence_0, df_byte_lr_confluence_n,
- df_byte_lr_transfer_function, df_byte_lr_free,
+ df_byte_lr_confluence_0, df_byte_lr_confluence_n,
+ df_byte_lr_transfer_function, df_byte_lr_free,
df_byte_lr_top_dump, df_byte_lr_bottom_dump,
- df_byte_lr_add_problem, df_byte_lr_simulate_defs,
+ df_byte_lr_add_problem, df_byte_lr_simulate_defs,
df_byte_lr_simulate_uses,
df_byte_lr_simulate_artificial_refs_at_top,
df_byte_lr_simulate_artificial_refs_at_end): New function.
* dce.c (byte_dce_process_block): New function.
(dce_process_block): au is now passed in rather than computed
locally. Changed loops that look at artificial defs to not look
- for conditional or partial ones, because there never are any.
- (fast_dce): Now is able to drive byte_dce_process_block or
+ for conditional or partial ones, because there never are any.
+ (fast_dce): Now is able to drive byte_dce_process_block or
dce_process_block depending on the kind of dce being done.
(rest_of_handle_fast_dce): Add parameter to fast_dce.
(rest_of_handle_fast_byte_dce): New function.
@@ -9802,14 +10022,14 @@
pointer_may_wrap_p to disable some false positives.
2008-04-18 Kris Van Hees <kris.van.hees@oracle.com>
-
+
* c-common.c (CHAR16_TYPE, CHAR32_TYPE): New macros.
(fname_as_string): Match updated cpp_interpret_string prototype.
(fix_string_type): Support char16_t* and char32_t*.
(c_common_nodes_and_builtins): Add char16_t and char32_t (and
derivative) nodes. Register as builtin if C++0x.
(c_parse_error): Support CPP_CHAR{16,32}.
- * c-common.h (RID_CHAR16, RID_CHAR32): New elements.
+ * c-common.h (RID_CHAR16, RID_CHAR32): New elements.
(enum c_tree_index) <CTI_CHAR16_TYPE, CTI_SIGNED_CHAR16_TYPE,
CTI_UNSIGNED_CHAR16_TYPE, CTI_CHAR32_TYPE, CTI_SIGNED_CHAR32_TYPE,
CTI_UNSIGNED_CHAR32_TYPE, CTI_CHAR16_ARRAY_TYPE,
@@ -9975,7 +10195,7 @@
* config/sh/sh.c (expand_cbranchdi4): Use original operands for
msw_skip comparison.
-
+
2008-04-16 Jakub Jelinek <jakub@redhat.com>
PR c/35739
@@ -10031,7 +10251,7 @@
unused.
Move filter, exc_ptr, ttype_data, ehspec_data, action_record_data and
exception_handler_label_map, ehr_stackadj, ehr_handler, ehr_label,
- sjlj_fc, sjlj_exit_after to rth_eh in function.h.
+ sjlj_fc, sjlj_exit_after to rth_eh in function.h.
Remove call_site_data_used, call_site_data_size.
Turn call_site_record into vector in function.h.
(note_current_region_may_contain_throw): Remove.
@@ -10041,7 +10261,7 @@
add_ttypes_entry, add_ehspec_entry, assign_filter_values,
build_post_landing_pads, dw2_build_landing_pads,
sjlj_assign_call_site_values, sjlj_mark_call_sites,
- sjlj_emit_function_enter, sjlj_emit_function_enter,
+ sjlj_emit_function_enter, sjlj_emit_function_enter,
sjlj_emit_function_exit, sjlj_emit_dispatch_table,
sjlj_build_landing_pads, finish_eh_generation,
remove_exception_handler_label, remove_eh_handler,
@@ -10267,7 +10487,7 @@
(*<code>extendsfdf2): Macroize insn pattern from *absextendsfdf2 and
*negextendsfdf2 patterns using absneg code iterator.
* config/i386/sse.md (<code><mode>2): Macroize expander from
- abs<mode>2 and neg<mode>2 patterns using absneg code iterator.
+ abs<mode>2 and neg<mode>2 patterns using absneg code iterator.
2008-04-10 Andreas Krebbel <krebbel1@de.ibm.com>
@@ -10507,10 +10727,10 @@
2008-04-08 Anatoly Sokolov <aesok@post.ru>
- * config/avr/avr.h (TARGET_CPU_CPP_BUILTINS): Define
- __AVR_HAVE_EIJMP_EICALL__ macro if device have EIJMP and EICALL
+ * config/avr/avr.h (TARGET_CPU_CPP_BUILTINS): Define
+ __AVR_HAVE_EIJMP_EICALL__ macro if device have EIJMP and EICALL
instructions.
- * config/avr/avr.c (avr_mcu_types): Set AVR31 architecture for
+ * config/avr/avr.c (avr_mcu_types): Set AVR31 architecture for
atmega103 device.
2008-04-07 Jan Hubicka <jh@suse.cz>
@@ -10531,7 +10751,7 @@
(assign_stack_local): Update
(expand_function_end): Update.
(get_art_pointer_save_area): Update
- * function.h
+ * function.h
* emit-rtl.c (rtl): Declare.
(regno_reg_rtx): Declare.
(first_insn, last_insn, cur_insn_uid, last_location, first_label_num):
@@ -10626,7 +10846,7 @@
(avr_asm_init_sections): (Ditto.).
(avr_rtx_costs): (Ditto.).
* config/avr/avr.md: (Ditto.).
- * config/avr/avr.h: Use '__AVR_HAVE_JMP_CALL__' instead of
+ * config/avr/avr.h: Use '__AVR_HAVE_JMP_CALL__' instead of
'__AVR_MEGA__'.
2008-04-06 Richard Guenther <rguenther@suse.de>
@@ -10794,7 +11014,7 @@
* c-objc-common.h (LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P):
Rename to LANG_HOOKS_MISSING_NORETURN_OK_P.
-
+
2008-04-04 Jakub Jelinek <jakub@redhat.com>
PR c/35440
@@ -10990,10 +11210,10 @@
2008-04-02 Anatoly Sokolov <aesok@post.ru>
- * config/avr/predicates.md (io_address_operand): New predicate.
+ * config/avr/predicates.md (io_address_operand): New predicate.
* config/avr/avr-protos.h (avr_io_address_p): Remove declaration.
* config/avr/avr.c (avr_io_address_p): Remove function.
- (out_movqi_r_mr): Use 'io_address_operand' predicate instead of
+ (out_movqi_r_mr): Use 'io_address_operand' predicate instead of
'avr_io_address_p' function.
(out_movhi_r_mr): (Ditto.).
(out_movqi_mr_r): (Ditto.).
@@ -11690,7 +11910,7 @@
* config/alpha/x-vms (EXTRA_PROGRAMS): Remove.
* config/t-openbsd-thread: Remove commented out lines.
-
+
* config/x-interix: Remove.
* config/m68hc11/t-m68hc11-gas: Rename to...
@@ -11814,7 +12034,7 @@
(reload_reg_rtx_for_input): New variable.
(reload_reg_rtx_for_output): Likewise.
(emit_input_reload_insns): Use reloadreg rather than rl->reg_rtx
- when reassigning a pseudo register. Load reloadreg from
+ when reassigning a pseudo register. Load reloadreg from
reload_reg_rtx_for_input, moving the mode and register
calculation to...
(do_input_reload): ...here. Use the mode-adjusted reg_rtx
@@ -11856,12 +12076,12 @@
(build/genflags.o): Likewise.
2008-03-25 Bob Wilson <bob.wilson@acm.org>
-
+
* config/xtensa/xtensa.c (xtensa_va_start): Use build_int_cst
instead of size_int for integer types.
(xtensa_gimplify_va_arg_expr): Likewise. Convert index to sizetype
to match type of MINUS_EXPR.
-
+
2008-03-25 Tom Tromey <tromey@redhat.com>
* configure: Rebuilt.
@@ -11979,7 +12199,7 @@
2008-03-25 Naveen.H.S <naveen.hs@kpitcummins.com>
* config/sh/sh.md (prefetch): Add condition for SH2A target.
- (prefetch_sh2a): New.
+ (prefetch_sh2a): New.
2008-03-25 Jayant Sonar <Jayant.sonar@kpitcummins.com>
Naveen.H.S <naveen.hs@kpitcummins.com>
@@ -12032,7 +12252,7 @@
* diagnostic.c (diagnostic_count_diagnostic): Delete.
(diagnostic_report_diagnostic): Update. Handle ICEs here.
-
+
2008-03-24 Nathan Sidwell <nathan@codesourcery.com>
* gthr-vxworks.h (UNUSED): Define.
@@ -12045,7 +12265,7 @@
* doc/extend.texi (Function Attributes): Add missing comma in the
example of the "alloc_size" attribute.
-
+
2008-03-23 Uros Bizjak <ubizjak@gmail.com>
Revert:
@@ -12523,22 +12743,22 @@
* config/avr/avr.c (avr_arch_types): Add avr6 entry.
(avr_arch): Add ARCH_AVR6.
(avr_mcu_types): Add 'atmega2560' and 'atmega2561' entry.
- (initial_elimination_offset): Initialize and use 'avr_pc_size'
+ (initial_elimination_offset): Initialize and use 'avr_pc_size'
instead of fixed value 2.
(print_operand_address): Use gs() asm specifier instead of pm().
(avr_assemble_integer): (Ditto.).
(avr_output_addr_vec_elt): (Ditto.).
(print_operand): Handle "!" code.
- * config/avr/avr.h (TARGET_CPU_CPP_BUILTINS): Add
+ * config/avr/avr.h (TARGET_CPU_CPP_BUILTINS): Add
__AVR_3_BYTE_PC__, __AVR_2_BYTE_PC__ and __AVR_HAVE_JMP_CALL__.
(AVR_HAVE_EIJMP_EICALL): Define.
(AVR_3_BYTE_PC): Redefine.
(AVR_2_BYTE_PC): (Ditto.).
(PRINT_OPERAND_PUNCT_VALID_P): Add '!' code.
(LINK_SPEC): Add atmega2560 and atmega2561.
- (CRT_BINUTILS_SPEC): Add atmega2560 (crtm2560.o) and atmega2561
+ (CRT_BINUTILS_SPEC): Add atmega2560 (crtm2560.o) and atmega2561
(crtm2561.o).
- * config/avr/avr.md (call_insn): Use eicall instead of icall
+ * config/avr/avr.md (call_insn): Use eicall instead of icall
for 3 byte PC devices.
(call_value_insn): (Ditto.).
(*tablejump_enh): Use eijmp instead of ijmp for 3 byte PC devices.
@@ -12546,11 +12766,11 @@
(*tablejump): (Ditto.).
(*indirect_jump_avr6): Add insn.
(*tablejump_rjmp): Don't use for 3 byte PC devices.
- * config/avr/libgcc.S (__prologue_saves__): Use eijmp
+ * config/avr/libgcc.S (__prologue_saves__): Use eijmp
instead of ijmp for 3 byte PC devices.
(__tablejump2__): (Ditto.).
* config/avr/t-avr (MULITLIB_OPTIONS): Add avr6 architecture.
- (MULITLIB_DIRNAMES): (Ditto.).
+ (MULITLIB_DIRNAMES): (Ditto.).
(MULTILIB_MATCHES): Add atmega2560 and atmega2561 to list.
2008-03-15 Uros Bizjak <ubizjak@gmail.com>
@@ -12577,7 +12797,7 @@
being a PHI_NODE.
2008-03-14 Bob Wilson <bob.wilson@acm.org>
-
+
* doc/invoke.texi (Option Summary, Xtensa Options): Document
-mserialize-volatile and -mno-serialize-volatile Xtensa options.
* config/xtensa/xtensa.c (print_operand): Do not emit MEMW instructions
@@ -13195,7 +13415,7 @@
(df_ref_create_structure): Allocate df_ref_extract if offset and
width fields are used.
(df_def_record_1): Get offset and width from ZERO_EXTRACT.
- (df_uses_record): Get offset and width from ZERO_EXTRACT
+ (df_uses_record): Get offset and width from ZERO_EXTRACT
and SIGN_EXTRACT.
* global.c (build_insn_chain): Change DF_REF_EXTRACT to either
DF_REF_ZERO_EXTRACT or DF_REF_SIGN_EXTRACT. Change
@@ -13206,7 +13426,7 @@
(df_ref_extract): New structure.
(DF_REF_WIDTH, DF_REF_OFFSET): New macros.
(df_ref_create): Add width and offset parameters.
-
+
2008-03-05 Richard Guenther <rguenther@suse.de>
* tree-ssa-structalias.c (get_constraint_for_component_ref):
@@ -13437,7 +13657,7 @@
* Makefile.in (OBJS-common): Remove struct-equiv.o.
(struct-equiv.o): Remove rule.
* basic-block.h (struct_equiv_checkpoint, STRUCT_EQUIV_*,
- insns_match_p, struct_equiv_block_eq, struct_equiv_init,
+ insns_match_p, struct_equiv_block_eq, struct_equiv_init,
rtx_equiv_p, condjump_equiv_p): Remove prototypes.
2008-03-01 Alexandre Oliva <aoliva@redhat.com>
@@ -13624,7 +13844,7 @@
* tree-vect-analyze.c: Remove unused static decls.
* lambda.h (dependence_level): New.
* common.opt (ftree-loop-distribution): New.
- * tree-flow.h (mark_virtual_ops_in_bb,
+ * tree-flow.h (mark_virtual_ops_in_bb,
slpeel_tree_duplicate_loop_to_edge_cfg,
rename_variables_in_loop): Declared.
* Makefile.in (TREE_DATA_REF_H): Depend on tree-chrec.h.
@@ -13834,7 +14054,7 @@
2008-02-26 Jason Merrill <jason@redhat.com>
PR c++/35315
- * attribs.c (decl_attributes): Leave ATTR_FLAG_TYPE_IN_PLACE
+ * attribs.c (decl_attributes): Leave ATTR_FLAG_TYPE_IN_PLACE
alone if it's the naming decl for the type's main variant.
2008-02-26 Tom Tromey <tromey@redhat.com>
@@ -13928,7 +14148,7 @@
* builtins.c (expand_builtin): Remove BUILT_IN_STDARG_START.
* tree-stdarg.c (execute_optimize_stdarg): Likewise.
* tree-inline.c (inline_forbidden_p_1): Likewise.
-
+
2008-02-26 Richard Guenther <rguenther@suse.de>
* tree-flow.h (uid_decl_map_hash, uid_decl_map_eq): Move ...
@@ -13997,7 +14217,7 @@
Wvolatile-register-var.
* common.opt: Move Wvolatile-register-var to...
* c.opt: ...here.
-
+
2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
* common.opt (Wlarger-than=): New.
@@ -14008,7 +14228,7 @@
* opth-gen.awk: Likewise.
* stor-layout.c (layout_decl): Use -Wlarger-than= for warning.
* tree-optimize.c (tree_rest_of_compilation): Likewise.
-
+
2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
* c-common.c (match_case_to_enum_1): Add appropriate
@@ -14031,7 +14251,7 @@
(print_ignored_options): New.
(handle_option): Postpone errors for unknown -Wno-* options.
* opts.h (print_ignored_options): Declare.
-
+
2008-02-25 Richard Sandiford <rsandifo@nildram.co.uk>
* config/mips/mips.md (loadgp_blockage, blockage): Change type
@@ -14110,7 +14330,7 @@
PR c/35162
* doc/invoke.texi (-fcx-limited-range): Correct to be in line with
actual behaviour and C99.
-
+
2008-02-26 Ben Elliston <bje@au.ibm.com>
* config/rs6000/rs6000.h (ASM_CPU_POWER5_SPEC): Define.
@@ -14213,7 +14433,7 @@
unused local variable `has_hot_blocks'.
(fix_crossing_conditional_branches): Remove unused local variable
`prev_bb'.
-
+
2008-02-25 Uros Bizjak <ubizjak@gmail.com>
PR middle-end/19984
@@ -14305,7 +14525,7 @@
2008-02-23 Uros Bizjak <ubizjak@gmail.com>
PR target/22076
- PR target/34256
+ PR target/34256
* config/i386/mmx.md (*mov<mode>_internal_rex64): Use "!y" to
prevent reload from using MMX registers.
(*mov<mode>_internal): Ditto.
@@ -14440,7 +14660,7 @@
* config/h8300/h8300.c (h8300_expand_epilogue): Emit return insn
as a jump, not as a plain insn.
-
+
2008-02-20 Seongbae Park <seongbae.park@gmail.com>
* doc/invoke.texi (Warning Options): Add new option
@@ -14493,7 +14713,7 @@
* doc/install.texi: Correct references to CFLAGS, replacing them
with BOOT_CFLAGS. Document flags used during bootstrap for
target libraries.
-
+
2008-02-20 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.h (SSE_VEC_FLOAT_MODE_P): New define.
@@ -14626,7 +14846,7 @@
cannot be disambiguated.
* c.opt (v): Pass on to the common option handler.
-2008-02-19 Revital Eres <eres@il.ibm.com>
+2008-02-19 Revital Eres <eres@il.ibm.com>
* modulo-sched.c (sms_schedule): Change dump message when
create_ddg function fails.
@@ -14748,7 +14968,7 @@
2008-02-17 Uros Bizjak <ubizjak@gmail.com>
Revert:
- 2008-02-15 Uros Bizjak <ubizjak@gmail.com>
+ 2008-02-15 Uros Bizjak <ubizjak@gmail.com>
* config/i386/sfp-machine.h (CMPtype): Define as typedef using
libgcc_cmp_return mode.
@@ -14924,7 +15144,7 @@
Add -fdump-ipa-inline.
* tree-dump.c (dump_files): Remove tree-inlined dump.
* tree-pass.h (tree_dump_index): Remove TDI_inlined.
-
+
2008-02-12 Richard Guenther <rguenther@suse.de>
PR tree-optimization/35171
@@ -15014,7 +15234,7 @@
2008-02-08 Sa Liu <saliu@de.ibm.com>
- * config/spu/spu-builtins.def: Fixed wrong parameter type in spu
+ * config/spu/spu-builtins.def: Fixed wrong parameter type in spu
intrinsics spu_convts, spu_convtu, spu_convtf.
2008-02-08 Hans-Peter Nilsson <hp@axis.com>
@@ -15029,7 +15249,7 @@
optc-gen.awk.
* opts-common.c: Likewise.
* optc-gen.awk: Likewise.
-
+
2008-02-07 Andreas Krebbel <krebbel1@de.ibm.com>
* config/s390/s390.h (FUNCTION_ARG_REGNO_P): Fix fprs for 64 bit.
@@ -15038,7 +15258,7 @@
PR rtl-opt/33410
* config/alpha/alpha.c (alpha_emit_xfloating_compare): Use an
- EXPR_LIST for the REG_EQUAL instead of a comparison with a
+ EXPR_LIST for the REG_EQUAL instead of a comparison with a
funny mode.
2008-02-07 Uros Bizjak <ubizjak@gmail.com>
@@ -15075,7 +15295,7 @@
2008-02-06 Ralf Corsepius <ralf.corsepius@rtems.org>
- * config/arm/rtems-elf.h (TARGET_OS_CPP_BUILTINS): Add
+ * config/arm/rtems-elf.h (TARGET_OS_CPP_BUILTINS): Add
builtin_define ("__USE_INIT_FINI__").
* config/h8300/t-rtems (MULTILIB_OPTION,MULTILIB_DIRNAMES): Add
-msx multilibs.
@@ -15208,16 +15428,16 @@
* doc/c-tree.texi (Types): Fix grammar.
(Expression trees): Ditto.
* doc/passes.texi (Tree-SSA passes): Ditto.
-
+
* doc/configterms.texi (Configure Terms): Fix typo.
* doc/cpp.texi (Common Predefined Macros): Ditto.
* doc/md.texi (Machine Constraints): Ditto.
-
+
* doc/makefile.texi (Makefile): Add comma.
2008-01-31 Tom Browder <tom.browder@gmail.com>
Gerald Pfeifer <gerald@pfeifer.com>
-
+
* doc/sourcebuild.texi (Front End): Remove references to CVS
and CVSROOT/modules.
(Texinfo Manuals): Replace reference to CVS by one to SVN.
@@ -15238,7 +15458,7 @@
options. Minor fixes.
(-std): Move reference to standards closer to where language
standards are first mentioned.
-
+
2008-01-31 Richard Sandiford <rsandifo@nildram.co.uk>
PR rtl-optimization/34995
@@ -15334,7 +15554,7 @@
2008-01-28 Andy Hutchinson <hutchinsonandy@netscape.net>
PR target/34412
- * config/avr/avr.c (expand_prologue): Use correct QI mode frame
+ * config/avr/avr.c (expand_prologue): Use correct QI mode frame
pointer for tiny stack.
2008-01-28 Bernhard Fischer <aldot@gcc.gnu.org>
@@ -15419,7 +15639,7 @@
Change type of cost to comp_cost.
(determine_iv_cost): Increase cost of non-original ivs, instead
of decreasing the cost of original ones.
- (get_address_cost): Indicate the complexity of the addressing mode
+ (get_address_cost): Indicate the complexity of the addressing mode
in comp_cost.
(try_add_cand_for): Prefer using ivs not specific to some object.
* tree-flow.h (force_expr_to_var_cost): Declaration removed.
@@ -15662,10 +15882,10 @@
* ipa-struct-reorg.c (remove_str_allocs_in_func, remove_str_allocs):
New functions.
(remove_structure): Update allocations list before removing structure.
-
+
2008-01-25 Golovanevsky Olga <olga@il.ibm.com>
- * ipa-struct-reorg.c (is_safe_cond_expr,
+ * ipa-struct-reorg.c (is_safe_cond_expr,
create_new_stmts_for_cond_expr): Use integer_zerop function,
that recognize not only zero-pointer, but zero-integer too.
@@ -15721,7 +15941,7 @@
PR c++/25701
* doc/gcc.texi (Software development): Add a direntry for g++.
-
+
2008-01-23 Hans-Peter Nilsson <hp@axis.com>
* config/cris/cris.h (CC1PLUS_SPEC, OPTIMIZATION_OPTIONS): Drop
@@ -15749,17 +15969,17 @@
(avr_arch_types): Add 'avr31' and 'avr51' entries.
(avr_arch): Add 'ARCH_AVR31' and 'ARCH_AVR51'.
(avr_mcu_types): Add 'avr31' and 'avr51' architectures.
- (avr_override_options): Init 'avr_current_arch'.
+ (avr_override_options): Init 'avr_current_arch'.
(base_arch_s): Move from here...
- * config/avr/avr.h (base_arch_s): ... here. Add new members
- 'have_elpm', 'have_elpmx', 'have_eijmp_eicall', 'reserved'. Rename
+ * config/avr/avr.h (base_arch_s): ... here. Add new members
+ 'have_elpm', 'have_elpmx', 'have_eijmp_eicall', 'reserved'. Rename
'mega' to 'have_jmp_call'.
- (TARGET_CPU_CPP_BUILTINS): Define "__AVR_HAVE_JMP_CALL__",
+ (TARGET_CPU_CPP_BUILTINS): Define "__AVR_HAVE_JMP_CALL__",
"__AVR_HAVE_RAMPZ__", "__AVR_HAVE_ELPM__" and "__AVR_HAVE_ELPMX__"
macros.
- (LINK_SPEC, CRT_BINUTILS_SPECS, ASM_SPEC): Add 'avr31' and 'avr51'
+ (LINK_SPEC, CRT_BINUTILS_SPECS, ASM_SPEC): Add 'avr31' and 'avr51'
architectures.
- * config/avr/t-avr (MULTILIB_OPTIONS, MULTILIB_DIRNAMES,
+ * config/avr/t-avr (MULTILIB_OPTIONS, MULTILIB_DIRNAMES,
MULTILIB_MATCHES): (Ditto.).
2008-01-23 Richard Guenther <rguenther@suse.de>
@@ -15929,7 +16149,7 @@
2008-01-21 Alon Dayan <alond@il.ibm.com>
Olga Golovanevsky <olga@il.ibm.com>
-
+
PR tree-optimization/34701
* ipa-struct-reorg.c (gen_size): Fix the malloc parameter calculation
when the structure size is not a power of 2.
@@ -15937,7 +16157,7 @@
2008-01-20 Kenneth Zadeck <zadeck@naturalbridge.com>
* doc/install.texi: Add doc for --enable-checking=df.
-
+
2008-01-20 Kaz Kojima <kkojima@gcc.gnu.org>
PR rtl-optimization/34808
@@ -16011,7 +16231,7 @@
(df_live_init): Init the df_live sets only with the variables
found live by df_lr.
(df_live_transfer_function): Use the df_lr sets to prune the
- df_live sets as they are being computed.
+ df_live sets as they are being computed.
(df_live_free): Free df_live_scratch.
2008-01-18 Ian Lance Taylor <iant@google.com>
@@ -16193,7 +16413,7 @@
2008-01-16 Sebastian Pop <sebastian.pop@amd.com>
- * tree-data-ref.c (subscript_dependence_tester_1): Call
+ * tree-data-ref.c (subscript_dependence_tester_1): Call
free_conflict_function.
(compute_self_dependence): Same.
@@ -16232,7 +16452,7 @@
PR c++/24924
* c-opts (c_common_post_options): Do not enable CPP
flag_pedantic_errors by default.
-
+
2008-01-14 Eric Botcazou <ebotcazou@adacore.com>
PR rtl-optimization/31944
@@ -16294,9 +16514,9 @@
correct type.
2008-01-11 Bob Wilson <bob.wilson@acm.org>
-
+
* config/xtensa/xtensa.c (override_options): Set flag_shlib.
-
+
2008-01-11 James E. Wilson <wilson@specifix.com>
PR target/26015
@@ -16304,8 +16524,8 @@
2008-01-11 Anatoly Sokolov <aesok@post.ru>
- * config/avr/avr.c (expand_prologue, expand_epilogue): Don't
- save/restore frame pointer register and don't use 'call-prologues'
+ * config/avr/avr.c (expand_prologue, expand_epilogue): Don't
+ save/restore frame pointer register and don't use 'call-prologues'
optimization in function with "OS_task" attribute.
2008-01-11 Eric Botcazou <ebotcazou@adacore.com>
@@ -16431,13 +16651,13 @@
2008-01-05 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (ix86_builtin_reciprocal): Remove check
- for TARGET_RECIP.
-
+ for TARGET_RECIP.
+
2008-01-08 Jan Sjodin <jan.sjodin@amd.com>
-
+
* config/i386/i386.c (k8_cost, amdfam10_cost): Branch costs
for vectorization tuned.
-
+
2008-01-08 Richard Guenther <rguenther@suse.de>
PR tree-optimization/34683
diff --git a/gcc/ChangeLog.melt b/gcc/ChangeLog.melt
index 5a05918c1ac..94e619a8128 100644
--- a/gcc/ChangeLog.melt
+++ b/gcc/ChangeLog.melt
@@ -1,3 +1,9 @@
+2008-07-31 Basile Starynkevitch <basile@starynkevitch.net>
+ the yesterday's version failed to compile any simple C file. Fixed!
+ MELT branch merged with trunk r138355
+
+ * passes.c: better order for basilys related passes.
+
2008-07-30 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r138310
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index bbceca5500f..7b1dc56be4e 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20080730
+20080731
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index aa6615cdc91..05f5a3470f6 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,131 @@
+2008-07-30 Aaron W. LaFramboise <aaronavay62@aaronwl.com>
+
+ * gcc-interface/Makefile.in (EXTRA_GNATRTL_NONTASKING_OBJS)
+ [WINDOWS]: Add s-winext.o.
+
+2008-07-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/36554
+ * back_end.adb (Call_Back_End): Pass Standard_Boolean to gigi.
+ * gcc-interface/gigi.h (gigi): Take new standard_boolean parameter.
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Enumeration_Subtype>:
+ Set precision to 1 for subtype of BOOLEAN_TYPE.
+ (set_rm_size): Set TYPE_RM_SIZE_NUM for BOOLEAN_TYPE.
+ (make_type_from_size): Deal with BOOLEAN_TYPE.
+ * gcc-interface/misc.c (gnat_print_type): Likewise.
+ * gcc-interface/trans.c (gigi): Take new standard_boolean parameter.
+ Set boolean_type_node as its translation in the table, as well
+ as boolean_false_node for False and boolean_true_node for True.
+ * gcc-interface/utils.c (gnat_init_decl_processing): Create custom
+ 8-bit boolean_type_node and set its TYPE_RM_SIZE_NUM.
+ (create_param_decl): Deal with BOOLEAN_TYPE.
+ (build_vms_descriptor): Likewise.
+ (build_vms_descriptor64): Likewise.
+ (convert): Deal with BOOLEAN_TYPE like with ENUMERAL_TYPE.
+
+2008-07-30 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch9.adb: Minor reformatting
+
+ * exp_util.ads (Find_Prim_Op): Document that Program_Error is raised
+ if no primitive operation is found.
+
+ * exp_util.adb: (Find_Prim_Op): Add comments for previous change
+
+ * sem_ch8.adb: Minor reformatting
+
+2008-07-30 Laurent Pautet <pautet@adacore.com>
+
+ * g-pehage.adb:
+ Remove a limitation on the length of the words handled by the minimal
+ perfect hash function generator.
+
+ * g-pehage.ads:
+ Detail the use of subprograms Insert, Initialize, Compute and Finalize.
+ Fix some typos.
+
+2008-07-30 Robert Dewar <dewar@adacore.com>
+
+ * gnatlink.adb: Minor reformatting
+
+2008-07-30 Thomas Quinot <quinot@adacore.com>
+
+ * rtsfind.adb (Check_RPC): Check version consistency even when not
+ generating RCI stubs. Provide more detailed error message in case of
+ mismatch.
+
+2008-07-30 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch8.adb (Analyze_Subprogram_Renaming): When renaming an attribute
+ as a actual in an instance, check for a missing attribute to prevent
+ program_error on an illegal program.
+
+ * exp_util.adb (Find_Prim_Op): Rather than Assert (False), raise program
+ error if primitive is not found, so that exception can be handled
+ elsewhere on illegal programs.
+
+2008-07-30 Robert Dewar <dewar@adacore.com>
+
+ * uintp.adb (UI_GCD): Fix potential overflow
+
+2008-07-30 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * einfo.adb: Flag245 is now used.
+ (Is_Primitive_Wrapper, Set_Is_Primitive_Wrapper): Relax the assertion
+ check to include functions.
+ (Is_Private_Primitive, Set_Is_Private_Primitive): New subprograms.
+ (Wrapped_Entity, Set_Wrapped_Entity): Relax the assertion check to
+ include functions.
+ (Write_Entity_Flags): Move flag Is_Primitive, add Is_Private_Primitive
+ to the list of displayed flags.
+
+ * einfo.ads: Update comment on the usage of Is_Primitive_Wrapper and
+ Wrapped_Entity. These two flags are now present in functions.
+ New flag Is_Private_Primitive.
+ (Is_Private_Primitive, Set_Is_Private_Primitive): New subprograms.
+
+ * exp_ch9.adb:
+ (Build_Wrapper_Bodies): New subprogram.
+ (Build_Wrapper_Body): The spec and body have been moved to in
+ Build_Wrapper_ Bodies. Code cleanup.
+ (Build_Wrapper_Spec): Moved to the spec of Exp_Ch9. Code cleanup.
+ Wrappers are now generated for primitives declared between the private
+ and full view of a concurrent type that implements an interface.
+ (Build_Wrapper_Specs): New subprogram.
+ (Expand_N_Protected_Body): Code reformatting. Replace the wrapper body
+ creation mechanism with a call to Build_Wrapper_Bodies.
+ (Expand_N_Protected_Type_Declaration): Code reformatting. Replace the
+ wrapper spec creation mechanism with a call to Build_Wrapper_Specs.
+ (Expand_N_Task_Body): Replace the wrapper body creation
+ mechanism with a call to Build_Wrapper_Bodies.
+ (Expand_N_Task_Type_Declaration): Replace the wrapper spec
+ creation mechanism with a call to Build_Wrapper_Specs.
+ (Is_Private_Primitive_Subprogram): New subprogram.
+ (Overriding_Possible): Code cleanup.
+ (Replicate_Entry_Formals): Renamed to Replicate_Formals, code cleanup.
+
+ * exp_ch9.ads (Build_Wrapper_Spec): Moved from the body of Exp_Ch9.
+
+ * sem_ch3.adb: Add with and use clause for Exp_Ch9.
+ (Process_Full_View): Build wrapper specs for all primitives
+ that belong to a private view completed by a concurrent type
+ implementing an interface.
+
+ * sem_ch6.adb (Analyze_Subprogram_Body): When the current subprogram
+ is a primitive of a
+ concurrent type with a private view that implements an interface, try to
+ find the proper spec.
+ (Analyze_Subprogram_Declaration): Mark a subprogram as a private
+ primitive if the type of its first parameter is a non-generic tagged
+ private type.
+ (Analyze_Subprogram_Specification): Code reformatting.
+ (Disambiguate_Spec): New routine.
+ (Find_Corresponding_Spec): Add a flag to controll the output of errors.
+ (Is_Private_Concurrent_Primitive): New routine.
+
+ * sem_ch6.ads:
+ (Find_Corresponding_Spec): Add a formal to control the output of errors.
+
2008-07-30 Doug Rupp <rupp@adacore.com>
* gigi.h (build_vms_descriptor64): New function prototype.
@@ -16845,7 +16973,7 @@ PR ada/10768
* utils.c (create_var_decl): Use have_global_bss_p when deciding
whether to make the decl common.
-2006-02-20 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+2006-02-20 Rafael �vila de Esp�ndola <rafael.espindola@gmail.com>
* Make-lang.in (Ada): Remove.
(.PHONY): Remove Ada
@@ -19303,11 +19431,11 @@ PR ada/10768
* s-bitops.adb: Clarify comment for Bits_Array
-2005-12-07 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+2005-12-07 Rafael �vila de Esp�ndola <rafael.espindola@gmail.com>
* Make-lang.in (ada.install-normal): Remove.
-2005-12-07 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+2005-12-07 Rafael �vila de Esp�ndola <rafael.espindola@gmail.com>
* Make-lang.in: Remove all dependencies on s-gtype.
diff --git a/gcc/ada/back_end.adb b/gcc/ada/back_end.adb
index a6600764988..7a4e4dadf0f 100644
--- a/gcc/ada/back_end.adb
+++ b/gcc/ada/back_end.adb
@@ -76,6 +76,7 @@ package body Back_End is
number_file : Nat;
file_info_ptr : Address;
+ gigi_standard_boolean : Entity_Id;
gigi_standard_integer : Entity_Id;
gigi_standard_long_long_float : Entity_Id;
gigi_standard_exception_type : Entity_Id;
@@ -112,6 +113,7 @@ package body Back_End is
number_file => Num_Source_Files,
file_info_ptr => File_Info_Array'Address,
+ gigi_standard_boolean => Standard_Boolean,
gigi_standard_integer => Standard_Integer,
gigi_standard_long_long_float => Standard_Long_Long_Float,
gigi_standard_exception_type => Standard_Exception_Type,
diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb
index 49dffae047b..01d384ec4f6 100644
--- a/gcc/ada/einfo.adb
+++ b/gcc/ada/einfo.adb
@@ -504,9 +504,8 @@ package body Einfo is
-- Optimize_Alignment_Time Flag242
-- Overlays_Constant Flag243
-- Is_RACW_Stub_Type Flag244
+ -- Is_Private_Primitive Flag245
- -- (unused) Flag169
- -- (unused) Flag245
-- (unused) Flag246
-- (unused) Flag247
@@ -1929,7 +1928,8 @@ package body Einfo is
function Is_Primitive_Wrapper (Id : E) return B is
begin
- pragma Assert (Ekind (Id) = E_Procedure);
+ pragma Assert (Ekind (Id) = E_Function
+ or else Ekind (Id) = E_Procedure);
return Flag195 (Id);
end Is_Primitive_Wrapper;
@@ -1944,6 +1944,13 @@ package body Einfo is
return Flag53 (Id);
end Is_Private_Descendant;
+ function Is_Private_Primitive (Id : E) return B is
+ begin
+ pragma Assert (Ekind (Id) = E_Function
+ or else Ekind (Id) = E_Procedure);
+ return Flag245 (Id);
+ end Is_Private_Primitive;
+
function Is_Protected_Interface (Id : E) return B is
begin
pragma Assert (Is_Interface (Id));
@@ -2702,8 +2709,9 @@ package body Einfo is
function Wrapped_Entity (Id : E) return E is
begin
- pragma Assert (Ekind (Id) = E_Procedure
- and then Is_Primitive_Wrapper (Id));
+ pragma Assert ((Ekind (Id) = E_Function
+ or else Ekind (Id) = E_Procedure)
+ and then Is_Primitive_Wrapper (Id));
return Node27 (Id);
end Wrapped_Entity;
@@ -4372,7 +4380,8 @@ package body Einfo is
procedure Set_Is_Primitive_Wrapper (Id : E; V : B := True) is
begin
- pragma Assert (Ekind (Id) = E_Procedure);
+ pragma Assert (Ekind (Id) = E_Function
+ or else Ekind (Id) = E_Procedure);
Set_Flag195 (Id, V);
end Set_Is_Primitive_Wrapper;
@@ -4387,6 +4396,13 @@ package body Einfo is
Set_Flag53 (Id, V);
end Set_Is_Private_Descendant;
+ procedure Set_Is_Private_Primitive (Id : E; V : B := True) is
+ begin
+ pragma Assert (Ekind (Id) = E_Function
+ or else Ekind (Id) = E_Procedure);
+ Set_Flag245 (Id, V);
+ end Set_Is_Private_Primitive;
+
procedure Set_Is_Protected_Interface (Id : E; V : B := True) is
begin
pragma Assert (Is_Interface (Id));
@@ -5168,8 +5184,9 @@ package body Einfo is
procedure Set_Wrapped_Entity (Id : E; V : E) is
begin
- pragma Assert (Ekind (Id) = E_Procedure
- and then Is_Primitive_Wrapper (Id));
+ pragma Assert ((Ekind (Id) = E_Function
+ or else Ekind (Id) = E_Procedure)
+ and then Is_Primitive_Wrapper (Id));
Set_Node27 (Id, V);
end Set_Wrapped_Entity;
@@ -7597,9 +7614,11 @@ package body Einfo is
W ("Is_Packed_Array_Type", Flag138 (Id));
W ("Is_Potentially_Use_Visible", Flag9 (Id));
W ("Is_Preelaborated", Flag59 (Id));
+ W ("Is_Primitive", Flag218 (Id));
W ("Is_Primitive_Wrapper", Flag195 (Id));
W ("Is_Private_Composite", Flag107 (Id));
W ("Is_Private_Descendant", Flag53 (Id));
+ W ("Is_Private_Primitive", Flag245 (Id));
W ("Is_Protected_Interface", Flag198 (Id));
W ("Is_Public", Flag10 (Id));
W ("Is_Pure", Flag44 (Id));
@@ -7666,7 +7685,6 @@ package body Einfo is
W ("Suppress_Init_Proc", Flag105 (Id));
W ("Suppress_Style_Checks", Flag165 (Id));
W ("Suppress_Value_Tracking_On_Call", Flag217 (Id));
- W ("Is_Primitive", Flag218 (Id));
W ("Treat_As_Volatile", Flag41 (Id));
W ("Universal_Aliasing", Flag216 (Id));
W ("Used_As_Generic_Actual", Flag222 (Id));
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index 43e0e17ab1d..8316a68018a 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -2513,9 +2513,9 @@ package Einfo is
-- indicators in bodies.
-- Is_Primitive_Wrapper (Flag195)
--- Present in all entities. Set for procedure entries that are used as
--- primitive wrappers. which are generated by the expander to wrap
--- entries of protected or task types implementing a limited interface.
+-- Present in functions and procedures created by the expander to serve
+-- as an indirection mechanism to overriding primitives of concurrent
+-- types, entries and protected procedures.
-- Is_Prival (synthesized)
-- Applies to all entities, true for renamings of private protected
@@ -2533,6 +2533,10 @@ package Einfo is
-- functions, procedures). Set if the library unit is itself a private
-- child unit, or if it is the descendent of a private child unit.
+-- Is_Private_Primitive (Flag245)
+-- Present in subprograms. Set if the first parameter of the subprogram
+-- is of concurrent tagged type with a private view.
+
-- Is_Private_Type (synthesized)
-- Applies to all entities, true for private types and subtypes,
-- as well as for record with private types as subtypes
@@ -3723,8 +3727,8 @@ package Einfo is
-- attribute when the limited-view is installed (Ada 2005: AI-217).
-- Wrapped_Entity (Node27)
--- Present in an E_Procedure classified as an Is_Primitive_Wrapper. Set
--- to the entity that is being wrapped.
+-- Present in functions and procedures which have been classified as
+-- Is_Primitive_Wrapper. Set to the entity being wrapper.
------------------
-- Access Kinds --
@@ -5013,6 +5017,7 @@ package Einfo is
-- Protection_Object (Node23) (for concurrent kind)
-- Interface_Alias (Node25)
-- Overridden_Operation (Node26)
+ -- Wrapped_Entity (Node27) (non-generic case only)
-- Extra_Formals (Node28)
-- Body_Needed_For_SAL (Flag40)
-- Elaboration_Entity_Required (Flag174)
@@ -5039,7 +5044,9 @@ package Einfo is
-- Is_Machine_Code_Subprogram (Flag137) (non-generic case only)
-- Is_Overriding_Operation (Flag39) (non-generic case only)
-- Is_Primitive (Flag218)
+ -- Is_Primitive_Wrapper (Flag195) (non-generic case only)
-- Is_Private_Descendant (Flag53)
+ -- Is_Private_Primitive (Flag245) (non-generic case only)
-- Is_Pure (Flag44)
-- Is_Thunk (Flag225)
-- Is_Visible_Child_Unit (Flag116)
@@ -5305,6 +5312,7 @@ package Einfo is
-- Is_Primitive (Flag218)
-- Is_Primitive_Wrapper (Flag195) (non-generic case only)
-- Is_Private_Descendant (Flag53)
+ -- Is_Private_Primitive (Flag245) (non-generic case only)
-- Is_Pure (Flag44)
-- Is_Thunk (Flag225)
-- Is_Valued_Procedure (Flag127)
@@ -5974,6 +5982,7 @@ package Einfo is
function Is_Primitive_Wrapper (Id : E) return B;
function Is_Private_Composite (Id : E) return B;
function Is_Private_Descendant (Id : E) return B;
+ function Is_Private_Primitive (Id : E) return B;
function Is_Protected_Interface (Id : E) return B;
function Is_Public (Id : E) return B;
function Is_Pure (Id : E) return B;
@@ -6538,6 +6547,7 @@ package Einfo is
procedure Set_Is_Primitive_Wrapper (Id : E; V : B := True);
procedure Set_Is_Private_Composite (Id : E; V : B := True);
procedure Set_Is_Private_Descendant (Id : E; V : B := True);
+ procedure Set_Is_Private_Primitive (Id : E; V : B := True);
procedure Set_Is_Protected_Interface (Id : E; V : B := True);
procedure Set_Is_Public (Id : E; V : B := True);
procedure Set_Is_Pure (Id : E; V : B := True);
@@ -7216,6 +7226,7 @@ package Einfo is
pragma Inline (Is_Primitive_Wrapper);
pragma Inline (Is_Private_Composite);
pragma Inline (Is_Private_Descendant);
+ pragma Inline (Is_Private_Primitive);
pragma Inline (Is_Private_Type);
pragma Inline (Is_Protected_Interface);
pragma Inline (Is_Protected_Type);
@@ -7609,6 +7620,7 @@ package Einfo is
pragma Inline (Set_Is_Primitive_Wrapper);
pragma Inline (Set_Is_Private_Composite);
pragma Inline (Set_Is_Private_Descendant);
+ pragma Inline (Set_Is_Private_Primitive);
pragma Inline (Set_Is_Protected_Interface);
pragma Inline (Set_Is_Public);
pragma Inline (Set_Is_Pure);
diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index 572dae04ea0..574d01f0ac8 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -152,29 +152,25 @@ package body Exp_Ch9 is
-- <formalN> : AnnN;
-- end record;
- function Build_Wrapper_Body
- (Loc : Source_Ptr;
- Proc_Nam : Entity_Id;
- Obj_Typ : Entity_Id;
- Formals : List_Id) return Node_Id;
- -- Ada 2005 (AI-345): Build the body that wraps a primitive operation
- -- associated with a protected or task type. This is required to implement
- -- dispatching calls through interfaces. Proc_Nam is the entry name to be
- -- wrapped, Obj_Typ is the type of the newly added formal parameter to
- -- handle object notation, Formals are the original entry formals that will
- -- be explicitly replicated.
-
- function Build_Wrapper_Spec
- (Loc : Source_Ptr;
- Proc_Nam : Entity_Id;
- Obj_Typ : Entity_Id;
- Formals : List_Id) return Node_Id;
- -- Ada 2005 (AI-345): Build the specification of a primitive operation
- -- associated with a protected or task type. This is required implement
- -- dispatching calls through interfaces. Proc_Nam is the entry name to be
- -- wrapped, Obj_Typ is the type of the newly added formal parameter to
- -- handle object notation, Formals are the original entry formals that will
- -- be explicitly replicated.
+ procedure Build_Wrapper_Bodies
+ (Loc : Source_Ptr;
+ Typ : Entity_Id;
+ N : Node_Id);
+ -- Ada 2005 (AI-345): Typ is either a concurrent type or the corresponding
+ -- record of a concurrent type. N is the insertion node where all bodies
+ -- will be placed. This routine builds the bodies of the subprograms which
+ -- serve as an indirection mechanism to overriding primitives of concurrent
+ -- types, entries and protected procedures. Any new body is analyzed.
+
+ procedure Build_Wrapper_Specs
+ (Loc : Source_Ptr;
+ Typ : Entity_Id;
+ N : in out Node_Id);
+ -- Ada 2005 (AI-345): Typ is either a concurrent type or the corresponding
+ -- record of a concurrent type. N is the insertion node where all specs
+ -- will be placed. This routine builds the specs of the subprograms which
+ -- serve as an indirection mechanism to overriding primitives of concurrent
+ -- types, entries and protected procedures. Any new spec is analyzed.
function Build_Find_Body_Index (Typ : Entity_Id) return Node_Id;
-- Build the function that translates the entry index in the call
@@ -359,6 +355,10 @@ package body Exp_Ch9 is
Lo : Node_Id;
Hi : Node_Id) return Boolean;
+ function Is_Private_Primitive_Subprogram (Id : Entity_Id) return Boolean;
+ -- Determine whether Id is a function or a procedure and is marked as a
+ -- private primitive.
+
function Null_Statements (Stats : List_Id) return Boolean;
-- Used to check DO-END sequence. Checks for equivalent of DO NULL; END.
-- Allows labels, and pragma Warnings/Unreferenced in the sequence as
@@ -1541,144 +1541,241 @@ package body Exp_Ch9 is
return Rec_Nam;
end Build_Parameter_Block;
- ------------------------
- -- Build_Wrapper_Body --
- ------------------------
+ --------------------------
+ -- Build_Wrapper_Bodies --
+ --------------------------
- function Build_Wrapper_Body
- (Loc : Source_Ptr;
- Proc_Nam : Entity_Id;
- Obj_Typ : Entity_Id;
- Formals : List_Id) return Node_Id
+ procedure Build_Wrapper_Bodies
+ (Loc : Source_Ptr;
+ Typ : Entity_Id;
+ N : Node_Id)
is
- Actuals : List_Id := No_List;
- Body_Spec : Node_Id;
- Conv_Id : Node_Id;
- First_Formal : Node_Id;
- Formal : Node_Id;
-
- begin
- Body_Spec := Build_Wrapper_Spec (Loc, Proc_Nam, Obj_Typ, Formals);
+ Rec_Typ : Entity_Id;
- -- If we did not generate the specification do have nothing else to do
+ function Build_Wrapper_Body
+ (Loc : Source_Ptr;
+ Subp_Id : Entity_Id;
+ Obj_Typ : Entity_Id;
+ Formals : List_Id) return Node_Id;
+ -- Ada 2005 (AI-345): Build the body that wraps a primitive operation
+ -- associated with a protected or task type. Subp_Id is the subprogram
+ -- name which will be wrapped. Obj_Typ is the type of the new formal
+ -- parameter which handles dispatching and object notation. Formals are
+ -- the original formals of Subp_Id which will be explicitly replicated.
+
+ ------------------------
+ -- Build_Wrapper_Body --
+ ------------------------
+
+ function Build_Wrapper_Body
+ (Loc : Source_Ptr;
+ Subp_Id : Entity_Id;
+ Obj_Typ : Entity_Id;
+ Formals : List_Id) return Node_Id
+ is
+ Body_Spec : Node_Id;
- if Body_Spec = Empty then
- return Empty;
- end if;
+ begin
+ Body_Spec := Build_Wrapper_Spec (Loc, Subp_Id, Obj_Typ, Formals);
- -- Map formals to actuals. Use the list built for the wrapper spec,
- -- skipping the object notation parameter.
+ -- The subprogram is not overriding or is not a primitive declared
+ -- between two views.
- First_Formal := First (Parameter_Specifications (Body_Spec));
+ if No (Body_Spec) then
+ return Empty;
+ end if;
- Formal := First_Formal;
- Next (Formal);
+ declare
+ Actuals : List_Id := No_List;
+ Conv_Id : Node_Id;
+ First_Formal : Node_Id;
+ Formal : Node_Id;
+ Nam : Node_Id;
- if Present (Formal) then
- Actuals := New_List;
+ begin
+ -- Map formals to actuals. Use the list built for the wrapper
+ -- spec, skipping the object notation parameter.
- while Present (Formal) loop
- Append_To (Actuals,
- Make_Identifier (Loc, Chars =>
- Chars (Defining_Identifier (Formal))));
+ First_Formal := First (Parameter_Specifications (Body_Spec));
+ Formal := First_Formal;
Next (Formal);
- end loop;
- end if;
- -- An access-to-variable first parameter will require an explicit
- -- dereference in the unchecked conversion. This case occurs when
- -- a protected entry wrapper must override an interface-level
- -- procedure with interface access as first parameter.
+ if Present (Formal) then
+ Actuals := New_List;
- -- SubprgName (O.all).Proc_Nam (Formal_1 .. Formal_N)
+ while Present (Formal) loop
+ Append_To (Actuals,
+ Make_Identifier (Loc, Chars =>
+ Chars (Defining_Identifier (Formal))));
- if Nkind (Parameter_Type (First_Formal)) = N_Access_Definition then
- Conv_Id :=
- Make_Explicit_Dereference (Loc,
- Prefix =>
- Make_Identifier (Loc, Chars => Name_uO));
+ Next (Formal);
+ end loop;
+ end if;
+
+ -- Special processing for primitives declared between a private
+ -- type and its completion.
+
+ if Is_Private_Primitive_Subprogram (Subp_Id) then
+ if No (Actuals) then
+ Actuals := New_List;
+ end if;
+
+ Prepend_To (Actuals,
+ Unchecked_Convert_To (
+ Corresponding_Concurrent_Type (Obj_Typ),
+ Make_Identifier (Loc, Name_uO)));
+
+ Nam := New_Reference_To (Subp_Id, Loc);
+
+ else
+ -- An access-to-variable object parameter requires an explicit
+ -- dereference in the unchecked conversion. This case occurs
+ -- when a protected entry wrapper must override an interface
+ -- level procedure with interface access as first parameter.
+
+ -- O.all.Subp_Id (Formal_1 .. Formal_N)
+
+ if Nkind (Parameter_Type (First_Formal)) =
+ N_Access_Definition
+ then
+ Conv_Id :=
+ Make_Explicit_Dereference (Loc,
+ Prefix => Make_Identifier (Loc, Name_uO));
+ else
+ Conv_Id := Make_Identifier (Loc, Name_uO);
+ end if;
+
+ Nam :=
+ Make_Selected_Component (Loc,
+ Prefix =>
+ Unchecked_Convert_To (
+ Corresponding_Concurrent_Type (Obj_Typ),
+ Conv_Id),
+ Selector_Name =>
+ New_Reference_To (Subp_Id, Loc));
+ end if;
+
+ -- Create the subprogram body
+
+ if Ekind (Subp_Id) = E_Function then
+ return
+ Make_Subprogram_Body (Loc,
+ Specification => Body_Spec,
+ Declarations => Empty_List,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (
+ Make_Simple_Return_Statement (Loc,
+ Make_Function_Call (Loc,
+ Name => Nam,
+ Parameter_Associations => Actuals)))));
+
+ else
+ return
+ Make_Subprogram_Body (Loc,
+ Specification => Body_Spec,
+ Declarations => Empty_List,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (
+ Make_Procedure_Call_Statement (Loc,
+ Name => Nam,
+ Parameter_Associations => Actuals))));
+ end if;
+ end;
+ end Build_Wrapper_Body;
+
+ -- Start of processing for Build_Wrapper_Bodies
+
+ begin
+ if Is_Concurrent_Type (Typ) then
+ Rec_Typ := Corresponding_Record_Type (Typ);
else
- Conv_Id :=
- Make_Identifier (Loc, Chars => Name_uO);
+ Rec_Typ := Typ;
end if;
- if Ekind (Proc_Nam) = E_Function then
- return
- Make_Subprogram_Body (Loc,
- Specification => Body_Spec,
- Declarations => Empty_List,
- Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements =>
- New_List (
- Make_Simple_Return_Statement (Loc,
- Make_Function_Call (Loc,
- Name =>
- Make_Selected_Component (Loc,
- Prefix =>
- Unchecked_Convert_To (
- Corresponding_Concurrent_Type (Obj_Typ),
- Conv_Id),
- Selector_Name =>
- New_Reference_To (Proc_Nam, Loc)),
- Parameter_Associations => Actuals)))));
- else
- return
- Make_Subprogram_Body (Loc,
- Specification => Body_Spec,
- Declarations => Empty_List,
- Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements =>
- New_List (
- Make_Procedure_Call_Statement (Loc,
- Name =>
- Make_Selected_Component (Loc,
- Prefix =>
- Unchecked_Convert_To (
- Corresponding_Concurrent_Type (Obj_Typ),
- Conv_Id),
- Selector_Name =>
- New_Reference_To (Proc_Nam, Loc)),
- Parameter_Associations => Actuals))));
+ -- Generate wrapper bodies for a concurrent type which implements an
+ -- interface.
+
+ if Present (Interfaces (Rec_Typ)) then
+ declare
+ Insert_Nod : Node_Id;
+ Prim : Entity_Id;
+ Prim_Elmt : Elmt_Id;
+ Prim_Decl : Node_Id;
+ Subp : Entity_Id;
+ Wrap_Body : Node_Id;
+ Wrap_Id : Entity_Id;
+
+ begin
+ Insert_Nod := N;
+
+ -- Examine all primitive operations of the corresponding record
+ -- type, looking for wrapper specs. Generate bodies in order to
+ -- complete them.
+
+ Prim_Elmt := First_Elmt (Primitive_Operations (Rec_Typ));
+ while Present (Prim_Elmt) loop
+ Prim := Node (Prim_Elmt);
+
+ if (Ekind (Prim) = E_Function
+ or else Ekind (Prim) = E_Procedure)
+ and then Is_Primitive_Wrapper (Prim)
+ then
+ Subp := Wrapped_Entity (Prim);
+ Prim_Decl := Parent (Parent (Prim));
+
+ Wrap_Body :=
+ Build_Wrapper_Body (Loc,
+ Subp_Id => Subp,
+ Obj_Typ => Rec_Typ,
+ Formals => Parameter_Specifications (Parent (Subp)));
+ Wrap_Id := Defining_Unit_Name (Specification (Wrap_Body));
+
+ Set_Corresponding_Spec (Wrap_Body, Prim);
+ Set_Corresponding_Body (Prim_Decl, Wrap_Id);
+
+ Insert_After (Insert_Nod, Wrap_Body);
+ Insert_Nod := Wrap_Body;
+
+ Analyze (Wrap_Body);
+ end if;
+
+ Next_Elmt (Prim_Elmt);
+ end loop;
+ end;
end if;
- end Build_Wrapper_Body;
+ end Build_Wrapper_Bodies;
------------------------
-- Build_Wrapper_Spec --
------------------------
function Build_Wrapper_Spec
- (Loc : Source_Ptr;
- Proc_Nam : Entity_Id;
- Obj_Typ : Entity_Id;
- Formals : List_Id) return Node_Id
+ (Loc : Source_Ptr;
+ Subp_Id : Entity_Id;
+ Obj_Typ : Entity_Id;
+ Formals : List_Id) return Node_Id
is
- New_Name_Id : constant Entity_Id :=
- Make_Defining_Identifier (Loc, Chars (Proc_Nam));
-
- First_Param : Node_Id := Empty;
- Iface : Entity_Id;
- Iface_Elmt : Elmt_Id := No_Elmt;
- New_Formals : List_Id;
- Obj_Param : Node_Id;
- Obj_Param_Typ : Node_Id;
- Iface_Prim_Op : Entity_Id;
- Iface_Prim_Op_Elmt : Elmt_Id;
+ First_Param : Node_Id;
+ Iface : Entity_Id;
+ Iface_Elmt : Elmt_Id;
+ Iface_Op : Entity_Id;
+ Iface_Op_Elmt : Elmt_Id;
function Overriding_Possible
- (Iface_Prim_Op : Entity_Id;
- Proc_Nam : Entity_Id) return Boolean;
- -- Determine whether a primitive operation can be overridden by the
- -- wrapper. Iface_Prim_Op is the candidate primitive operation of an
- -- abstract interface type, Proc_Nam is the generated entry wrapper.
+ (Iface_Op : Entity_Id;
+ Wrapper : Entity_Id) return Boolean;
+ -- Determine whether a primitive operation can be overridden by Wrapper.
+ -- Iface_Op is the candidate primitive operation of an interface type,
+ -- Wrapper is the generated entry wrapper.
- function Replicate_Entry_Formals
+ function Replicate_Formals
(Loc : Source_Ptr;
Formals : List_Id) return List_Id;
- -- An explicit parameter replication is required due to the
- -- Is_Entry_Formal flag being set for all the formals. The explicit
+ -- An explicit parameter replication is required due to the Is_Entry_
+ -- Formal flag being set for all the formals of an entry. The explicit
-- replication removes the flag that would otherwise cause a different
-- path of analysis.
@@ -1687,18 +1784,15 @@ package body Exp_Ch9 is
-------------------------
function Overriding_Possible
- (Iface_Prim_Op : Entity_Id;
- Proc_Nam : Entity_Id) return Boolean
+ (Iface_Op : Entity_Id;
+ Wrapper : Entity_Id) return Boolean
is
- Prim_Op_Spec : constant Node_Id := Parent (Iface_Prim_Op);
- Proc_Spec : constant Node_Id := Parent (Proc_Nam);
-
- Is_Access_To_Variable : Boolean;
- Is_Out_Present : Boolean;
+ Iface_Op_Spec : constant Node_Id := Parent (Iface_Op);
+ Wrapper_Spec : constant Node_Id := Parent (Wrapper);
function Type_Conformant_Parameters
- (Prim_Op_Param_Specs : List_Id;
- Proc_Param_Specs : List_Id) return Boolean;
+ (Iface_Op_Params : List_Id;
+ Wrapper_Params : List_Id) return Boolean;
-- Determine whether the parameters of the generated entry wrapper
-- and those of a primitive operation are type conformant. During
-- this check, the first parameter of the primitive operation is
@@ -1709,40 +1803,40 @@ package body Exp_Ch9 is
--------------------------------
function Type_Conformant_Parameters
- (Prim_Op_Param_Specs : List_Id;
- Proc_Param_Specs : List_Id) return Boolean
+ (Iface_Op_Params : List_Id;
+ Wrapper_Params : List_Id) return Boolean
is
- Prim_Op_Param : Node_Id;
- Prim_Op_Typ : Entity_Id;
- Proc_Param : Node_Id;
- Proc_Typ : Entity_Id;
+ Iface_Op_Param : Node_Id;
+ Iface_Op_Typ : Entity_Id;
+ Wrapper_Param : Node_Id;
+ Wrapper_Typ : Entity_Id;
begin
-- Skip the first parameter of the primitive operation
- Prim_Op_Param := Next (First (Prim_Op_Param_Specs));
- Proc_Param := First (Proc_Param_Specs);
- while Present (Prim_Op_Param)
- and then Present (Proc_Param)
+ Iface_Op_Param := Next (First (Iface_Op_Params));
+ Wrapper_Param := First (Wrapper_Params);
+ while Present (Iface_Op_Param)
+ and then Present (Wrapper_Param)
loop
- Prim_Op_Typ := Find_Parameter_Type (Prim_Op_Param);
- Proc_Typ := Find_Parameter_Type (Proc_Param);
+ Iface_Op_Typ := Find_Parameter_Type (Iface_Op_Param);
+ Wrapper_Typ := Find_Parameter_Type (Wrapper_Param);
-- The two parameters must be mode conformant
if not Conforming_Types
- (Prim_Op_Typ, Proc_Typ, Mode_Conformant)
+ (Iface_Op_Typ, Wrapper_Typ, Mode_Conformant)
then
return False;
end if;
- Next (Prim_Op_Param);
- Next (Proc_Param);
+ Next (Iface_Op_Param);
+ Next (Wrapper_Param);
end loop;
-- One of the lists is longer than the other
- if Present (Prim_Op_Param) or else Present (Proc_Param) then
+ if Present (Iface_Op_Param) or else Present (Wrapper_Param) then
return False;
end if;
@@ -1752,47 +1846,41 @@ package body Exp_Ch9 is
-- Start of processing for Overriding_Possible
begin
- if Chars (Iface_Prim_Op) /= Chars (Proc_Nam) then
+ if Chars (Iface_Op) /= Chars (Wrapper) then
return False;
end if;
- -- Special check for protected procedures: If an inherited subprogram
- -- is implemented by a protected procedure or an entry, then the
- -- first parameter of the inherited subprogram shall be of mode OUT
- -- or IN OUT, or an access-to-variable parameter.
-
- if Ekind (Iface_Prim_Op) = E_Procedure then
-
- Is_Out_Present :=
- Present (Parameter_Specifications (Prim_Op_Spec))
- and then
- Out_Present (First (Parameter_Specifications (Prim_Op_Spec)));
+ -- If an inherited subprogram is implemented by a protected procedure
+ -- or an entry, then the first parameter of the inherited subprogram
+ -- shall be of mode OUT or IN OUT, or access-to-variable parameter.
- Is_Access_To_Variable :=
- Present (Parameter_Specifications (Prim_Op_Spec))
- and then
- Nkind (Parameter_Type
- (First
- (Parameter_Specifications (Prim_Op_Spec)))) =
- N_Access_Definition;
-
- if not Is_Out_Present
- and then not Is_Access_To_Variable
- then
- return False;
- end if;
+ if Ekind (Iface_Op) = E_Procedure
+ and then Present (Parameter_Specifications (Iface_Op_Spec))
+ then
+ declare
+ Obj_Param : constant Node_Id :=
+ First (Parameter_Specifications (Iface_Op_Spec));
+ begin
+ if not Out_Present (Obj_Param)
+ and then Nkind (Parameter_Type (Obj_Param)) /=
+ N_Access_Definition
+ then
+ return False;
+ end if;
+ end;
end if;
- return Type_Conformant_Parameters (
- Parameter_Specifications (Prim_Op_Spec),
- Parameter_Specifications (Proc_Spec));
+ return
+ Type_Conformant_Parameters (
+ Parameter_Specifications (Iface_Op_Spec),
+ Parameter_Specifications (Wrapper_Spec));
end Overriding_Possible;
- -----------------------------
- -- Replicate_Entry_Formals --
- -----------------------------
+ -----------------------
+ -- Replicate_Formals --
+ -----------------------
- function Replicate_Entry_Formals
+ function Replicate_Formals
(Loc : Source_Ptr;
Formals : List_Id) return List_Id
is
@@ -1802,6 +1890,14 @@ package body Exp_Ch9 is
begin
Formal := First (Formals);
+
+ -- Skip the object parameter when dealing with primitives declared
+ -- between two views.
+
+ if Is_Private_Primitive_Subprogram (Subp_Id) then
+ Formal := Next (Formal);
+ end if;
+
while Present (Formal) loop
-- Create an explicit copy of the entry parameter
@@ -1835,166 +1931,229 @@ package body Exp_Ch9 is
end loop;
return New_Formals;
- end Replicate_Entry_Formals;
+ end Replicate_Formals;
-- Start of processing for Build_Wrapper_Spec
begin
- -- The mode is determined by the first parameter of the interface-level
- -- procedure that the current entry is trying to override.
-
- pragma Assert (Is_Non_Empty_List (Abstract_Interface_List (Obj_Typ)));
-
- -- We must examine all the protected operations of the implemented
- -- interfaces in order to discover a possible overriding candidate.
-
- Iface := Etype (First (Abstract_Interface_List (Obj_Typ)));
-
- Examine_Parents : loop
- if Present (Primitive_Operations (Iface)) then
- Iface_Prim_Op_Elmt := First_Elmt (Primitive_Operations (Iface));
- while Present (Iface_Prim_Op_Elmt) loop
- Iface_Prim_Op := Node (Iface_Prim_Op_Elmt);
+ -- There is no point in building wrappers for non-tagged concurrent
+ -- types.
- if not Is_Predefined_Dispatching_Operation (Iface_Prim_Op) then
- while Present (Alias (Iface_Prim_Op)) loop
- Iface_Prim_Op := Alias (Iface_Prim_Op);
- end loop;
+ pragma Assert (Is_Tagged_Type (Obj_Typ));
- -- The current primitive operation can be overridden by the
- -- generated entry wrapper.
+ -- An entry or a protected procedure can override a routine where the
+ -- controlling formal is either IN OUT, OUT or is of access-to-variable
+ -- type. Since the wrapper must have the exact same signature as that of
+ -- the overridden subprogram, we try to find the overriding candidate
+ -- and use its controlling formal.
- if Overriding_Possible (Iface_Prim_Op, Proc_Nam) then
- First_Param := First (Parameter_Specifications
- (Parent (Iface_Prim_Op)));
+ First_Param := Empty;
- goto Found;
- end if;
- end if;
+ -- Check every implemented interface
- Next_Elmt (Iface_Prim_Op_Elmt);
- end loop;
- end if;
-
- exit Examine_Parents when Etype (Iface) = Iface;
-
- Iface := Etype (Iface);
- end loop Examine_Parents;
-
- if Present (Interfaces
- (Corresponding_Record_Type (Scope (Proc_Nam))))
- then
- Iface_Elmt := First_Elmt
- (Interfaces
- (Corresponding_Record_Type (Scope (Proc_Nam))));
- Examine_Interfaces : while Present (Iface_Elmt) loop
+ if Present (Interfaces (Obj_Typ)) then
+ Iface_Elmt := First_Elmt (Interfaces (Obj_Typ));
+ Search : while Present (Iface_Elmt) loop
Iface := Node (Iface_Elmt);
+ -- Check every interface primitive
+
if Present (Primitive_Operations (Iface)) then
- Iface_Prim_Op_Elmt := First_Elmt (Primitive_Operations (Iface));
- while Present (Iface_Prim_Op_Elmt) loop
- Iface_Prim_Op := Node (Iface_Prim_Op_Elmt);
+ Iface_Op_Elmt := First_Elmt (Primitive_Operations (Iface));
+ while Present (Iface_Op_Elmt) loop
+ Iface_Op := Node (Iface_Op_Elmt);
- if not Is_Predefined_Dispatching_Operation
- (Iface_Prim_Op)
- then
- while Present (Alias (Iface_Prim_Op)) loop
- Iface_Prim_Op := Alias (Iface_Prim_Op);
- end loop;
+ -- Ignore predefined primitives
+
+ if not Is_Predefined_Dispatching_Operation (Iface_Op) then
+ Iface_Op := Ultimate_Alias (Iface_Op);
-- The current primitive operation can be overridden by
-- the generated entry wrapper.
- if Overriding_Possible (Iface_Prim_Op, Proc_Nam) then
- First_Param := First (Parameter_Specifications
- (Parent (Iface_Prim_Op)));
+ if Overriding_Possible (Iface_Op, Subp_Id) then
+ First_Param :=
+ First (Parameter_Specifications (Parent (Iface_Op)));
- goto Found;
+ exit Search;
end if;
end if;
- Next_Elmt (Iface_Prim_Op_Elmt);
+ Next_Elmt (Iface_Op_Elmt);
end loop;
end if;
Next_Elmt (Iface_Elmt);
- end loop Examine_Interfaces;
+ end loop Search;
+ end if;
+
+ -- If the subprogram to be wrapped is not overriding anything or is not
+ -- a primitive declared between two views, do not produce anything. This
+ -- avoids spurious errors involving overriding.
+
+ if No (First_Param)
+ and then not Is_Private_Primitive_Subprogram (Subp_Id)
+ then
+ return Empty;
end if;
- -- Return if no interface primitive can be overridden
+ declare
+ Wrapper_Id : constant Entity_Id :=
+ Make_Defining_Identifier (Loc, Chars (Subp_Id));
+ New_Formals : List_Id;
+ Obj_Param : Node_Id;
+ Obj_Param_Typ : Entity_Id;
+
+ begin
+ -- Minimum decoration is needed to catch the entity in
+ -- Sem_Ch6.Override_Dispatching_Operation.
- return Empty;
+ if Ekind (Subp_Id) = E_Function then
+ Set_Ekind (Wrapper_Id, E_Function);
+ else
+ Set_Ekind (Wrapper_Id, E_Procedure);
+ end if;
- <<Found>>
+ Set_Is_Primitive_Wrapper (Wrapper_Id);
+ Set_Wrapped_Entity (Wrapper_Id, Subp_Id);
+ Set_Is_Private_Primitive (Wrapper_Id,
+ Is_Private_Primitive_Subprogram (Subp_Id));
- New_Formals := Replicate_Entry_Formals (Loc, Formals);
+ -- Process the formals
- -- ??? Certain source packages contain protected or task types that do
- -- not implement any interfaces and are compiled with the -gnat05
- -- switch. In this case, a default first parameter is created.
+ New_Formals := Replicate_Formals (Loc, Formals);
- -- If the interface operation has an access parameter, create a copy
- -- of it, with the same null exclusion indicator if present.
+ -- Routine Subp_Id has been found to override an interface primitive.
+ -- If the interface operation has an access parameter, create a copy
+ -- of it, with the same null exclusion indicator if present.
- if Present (First_Param) then
- if Nkind (Parameter_Type (First_Param)) = N_Access_Definition then
- Obj_Param_Typ :=
- Make_Access_Definition (Loc,
- Subtype_Mark =>
- New_Reference_To (Obj_Typ, Loc));
- Set_Null_Exclusion_Present (Obj_Param_Typ,
- Null_Exclusion_Present (Parameter_Type (First_Param)));
+ if Present (First_Param) then
+ if Nkind (Parameter_Type (First_Param)) = N_Access_Definition then
+ Obj_Param_Typ :=
+ Make_Access_Definition (Loc,
+ Subtype_Mark =>
+ New_Reference_To (Obj_Typ, Loc));
+ Set_Null_Exclusion_Present (Obj_Param_Typ,
+ Null_Exclusion_Present (Parameter_Type (First_Param)));
+ else
+ Obj_Param_Typ := New_Reference_To (Obj_Typ, Loc);
+ end if;
+
+ Obj_Param :=
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier =>
+ Make_Defining_Identifier (Loc,
+ Chars => Name_uO),
+ In_Present => In_Present (First_Param),
+ Out_Present => Out_Present (First_Param),
+ Parameter_Type => Obj_Param_Typ);
+
+ -- If we are dealing with a primitive declared between two views,
+ -- create a default parameter.
+
+ else pragma Assert (Is_Private_Primitive_Subprogram (Subp_Id));
+ Obj_Param :=
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier =>
+ Make_Defining_Identifier (Loc, Name_uO),
+ In_Present => True,
+ Out_Present => Ekind (Subp_Id) /= E_Function,
+ Parameter_Type => New_Reference_To (Obj_Typ, Loc));
+ end if;
+
+ Prepend_To (New_Formals, Obj_Param);
+
+ -- Build the final spec
+
+ if Ekind (Subp_Id) = E_Function then
+ return
+ Make_Function_Specification (Loc,
+ Defining_Unit_Name => Wrapper_Id,
+ Parameter_Specifications => New_Formals,
+ Result_Definition =>
+ New_Copy (Result_Definition (Parent (Subp_Id))));
else
- Obj_Param_Typ := New_Reference_To (Obj_Typ, Loc);
+ return
+ Make_Procedure_Specification (Loc,
+ Defining_Unit_Name => Wrapper_Id,
+ Parameter_Specifications => New_Formals);
end if;
+ end;
+ end Build_Wrapper_Spec;
- Obj_Param :=
- Make_Parameter_Specification (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc, Name_uO),
- In_Present => In_Present (First_Param),
- Out_Present => Out_Present (First_Param),
- Parameter_Type => Obj_Param_Typ);
+ -------------------------
+ -- Build_Wrapper_Specs --
+ -------------------------
- else
- Obj_Param :=
- Make_Parameter_Specification (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc, Name_uO),
- In_Present => True,
- Out_Present => True,
- Parameter_Type => New_Reference_To (Obj_Typ, Loc));
+ procedure Build_Wrapper_Specs
+ (Loc : Source_Ptr;
+ Typ : Entity_Id;
+ N : in out Node_Id)
+ is
+ Def : Node_Id;
+ Rec_Typ : Entity_Id;
+
+ begin
+ if Is_Protected_Type (Typ) then
+ Def := Protected_Definition (Parent (Typ));
+ else pragma Assert (Is_Task_Type (Typ));
+ Def := Task_Definition (Parent (Typ));
end if;
- Prepend_To (New_Formals, Obj_Param);
+ Rec_Typ := Corresponding_Record_Type (Typ);
- -- Minimum decoration needed to catch the entity in
- -- Sem_Ch6.Override_Dispatching_Operation
+ -- Generate wrapper specs for a concurrent type which implements an
+ -- interface and has visible entries and/or protected procedures.
- if Ekind (Proc_Nam) = E_Procedure
- or else Ekind (Proc_Nam) = E_Entry
+ if Present (Interfaces (Rec_Typ))
+ and then Present (Def)
+ and then Present (Visible_Declarations (Def))
then
- Set_Ekind (New_Name_Id, E_Procedure);
- Set_Is_Primitive_Wrapper (New_Name_Id);
- Set_Wrapped_Entity (New_Name_Id, Proc_Nam);
+ declare
+ Decl : Node_Id;
+ Wrap_Decl : Node_Id;
+ Wrap_Spec : Node_Id;
- return
- Make_Procedure_Specification (Loc,
- Defining_Unit_Name => New_Name_Id,
- Parameter_Specifications => New_Formals);
+ begin
+ Decl := First (Visible_Declarations (Def));
+ while Present (Decl) loop
+ Wrap_Spec := Empty;
- else pragma Assert (Ekind (Proc_Nam) = E_Function);
- Set_Ekind (New_Name_Id, E_Function);
+ if Nkind (Decl) = N_Entry_Declaration
+ and then Ekind (Defining_Identifier (Decl)) = E_Entry
+ then
+ Wrap_Spec :=
+ Build_Wrapper_Spec (Loc,
+ Subp_Id => Defining_Identifier (Decl),
+ Obj_Typ => Rec_Typ,
+ Formals => Parameter_Specifications (Decl));
- return
- Make_Function_Specification (Loc,
- Defining_Unit_Name => New_Name_Id,
- Parameter_Specifications => New_Formals,
- Result_Definition =>
- New_Copy (Result_Definition (Parent (Proc_Nam))));
+ elsif Nkind (Decl) = N_Subprogram_Declaration then
+ Wrap_Spec :=
+ Build_Wrapper_Spec (Loc,
+ Subp_Id => Defining_Unit_Name (Specification (Decl)),
+ Obj_Typ => Rec_Typ,
+ Formals =>
+ Parameter_Specifications (Specification (Decl)));
+ end if;
+
+ if Present (Wrap_Spec) then
+ Wrap_Decl :=
+ Make_Subprogram_Declaration (Loc,
+ Specification => Wrap_Spec);
+
+ Insert_After (N, Wrap_Decl);
+ N := Wrap_Decl;
+
+ Analyze (Wrap_Decl);
+ end if;
+
+ Next (Decl);
+ end loop;
+ end;
end if;
- end Build_Wrapper_Spec;
+ end Build_Wrapper_Specs;
---------------------------
-- Build_Find_Body_Index --
@@ -6903,13 +7062,13 @@ package body Exp_Ch9 is
procedure Expand_N_Protected_Body (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Pid : constant Entity_Id := Corresponding_Spec (N);
- Op_Body : Node_Id;
- Op_Decl : Node_Id;
- Op_Id : Entity_Id;
+ Current_Node : Node_Id;
Disp_Op_Body : Node_Id;
New_Op_Body : Node_Id;
- Current_Node : Node_Id;
Num_Entries : Natural := 0;
+ Op_Body : Node_Id;
+ Op_Decl : Node_Id;
+ Op_Id : Entity_Id;
function Build_Dispatching_Subprogram_Body
(N : Node_Id;
@@ -7002,14 +7161,12 @@ package body Exp_Ch9 is
return;
end if;
- if Nkind (Parent (N)) = N_Subunit then
-
- -- This is the proper body corresponding to a stub. The declarations
- -- must be inserted at the point of the stub, which is in the decla-
- -- rative part of the parent unit.
+ -- This is the proper body corresponding to a stub. The declarations
+ -- must be inserted at the point of the stub, which in turn is in the
+ -- declarative part of the parent unit.
+ if Nkind (Parent (N)) = N_Subunit then
Current_Node := Corresponding_Stub (Parent (N));
-
else
Current_Node := N;
end if;
@@ -7171,63 +7328,12 @@ package body Exp_Ch9 is
Analyze (New_Op_Body);
end if;
- -- Ada 2005 (AI-345): Construct the primitive entry wrapper bodies after
- -- the protected body. At this point the entry specs have been created,
+ -- Ada 2005 (AI-345): Construct the primitive wrapper bodies after the
+ -- protected body. At this point all wrapper specs have been created,
-- frozen and included in the dispatch table for the protected type.
- pragma Assert (Present (Corresponding_Record_Type (Pid)));
-
- if Ada_Version >= Ada_05
- and then Present (Protected_Definition (Parent (Pid)))
- and then Present (Interfaces (Corresponding_Record_Type (Pid)))
- then
- declare
- Vis_Decl : Node_Id :=
- First (Visible_Declarations
- (Protected_Definition (Parent (Pid))));
- Wrap_Body : Node_Id;
-
- begin
- -- Examine the visible declarations of the protected type, looking
- -- for an entry declaration. We do not consider entry families
- -- since they cannot have dispatching operations, thus they do not
- -- need entry wrappers.
-
- while Present (Vis_Decl) loop
- if Nkind (Vis_Decl) = N_Entry_Declaration then
- Wrap_Body :=
- Build_Wrapper_Body (Loc,
- Proc_Nam => Defining_Identifier (Vis_Decl),
- Obj_Typ => Corresponding_Record_Type (Pid),
- Formals => Parameter_Specifications (Vis_Decl));
-
- if Wrap_Body /= Empty then
- Insert_After (Current_Node, Wrap_Body);
- Current_Node := Wrap_Body;
-
- Analyze (Wrap_Body);
- end if;
-
- elsif Nkind (Vis_Decl) = N_Subprogram_Declaration then
- Wrap_Body :=
- Build_Wrapper_Body (Loc,
- Proc_Nam => Defining_Unit_Name
- (Specification (Vis_Decl)),
- Obj_Typ => Corresponding_Record_Type (Pid),
- Formals => Parameter_Specifications
- (Specification (Vis_Decl)));
-
- if Wrap_Body /= Empty then
- Insert_After (Current_Node, Wrap_Body);
- Current_Node := Wrap_Body;
-
- Analyze (Wrap_Body);
- end if;
- end if;
-
- Next (Vis_Decl);
- end loop;
- end;
+ if Ada_Version >= Ada_05 then
+ Build_Wrapper_Bodies (Loc, Pid, Current_Node);
end if;
end Expand_N_Protected_Body;
@@ -7625,67 +7731,11 @@ package body Exp_Ch9 is
Analyze (Rec_Decl, Suppress => All_Checks);
-- Ada 2005 (AI-345): Construct the primitive entry wrappers before
- -- the corresponding record is frozen
-
- if Ada_Version >= Ada_05
- and then Present (Visible_Declarations (Pdef))
- and then Present (Corresponding_Record_Type
- (Defining_Identifier (Parent (Pdef))))
- and then Present (Interfaces
- (Corresponding_Record_Type
- (Defining_Identifier (Parent (Pdef)))))
- then
- declare
- Current_Node : Node_Id := Rec_Decl;
- Vis_Decl : Node_Id;
- Wrap_Spec : Node_Id;
- New_N : Node_Id;
-
- begin
- -- Examine the visible declarations of the protected type, looking
- -- for declarations of entries, and subprograms. We do not
- -- consider entry families since they cannot have dispatching
- -- operations, thus they do not need entry wrappers.
-
- Vis_Decl := First (Visible_Declarations (Pdef));
-
- while Present (Vis_Decl) loop
+ -- the corresponding record is frozen. If any wrappers are generated,
+ -- Current_Node is updated accordingly.
- Wrap_Spec := Empty;
-
- if Nkind (Vis_Decl) = N_Entry_Declaration
- and then No (Discrete_Subtype_Definition (Vis_Decl))
- then
- Wrap_Spec :=
- Build_Wrapper_Spec (Loc,
- Proc_Nam => Defining_Identifier (Vis_Decl),
- Obj_Typ => Defining_Identifier (Rec_Decl),
- Formals => Parameter_Specifications (Vis_Decl));
-
- elsif Nkind (Vis_Decl) = N_Subprogram_Declaration then
- Wrap_Spec :=
- Build_Wrapper_Spec (Loc,
- Proc_Nam => Defining_Unit_Name
- (Specification (Vis_Decl)),
- Obj_Typ => Defining_Identifier (Rec_Decl),
- Formals => Parameter_Specifications
- (Specification (Vis_Decl)));
-
- end if;
-
- if Wrap_Spec /= Empty then
- New_N := Make_Subprogram_Declaration (Loc,
- Specification => Wrap_Spec);
-
- Insert_After (Current_Node, New_N);
- Current_Node := New_N;
-
- Analyze (New_N);
- end if;
-
- Next (Vis_Decl);
- end loop;
- end;
+ if Ada_Version >= Ada_05 then
+ Build_Wrapper_Specs (Loc, Prot_Typ, Current_Node);
end if;
-- Collect pointers to entry bodies and their barriers, to be placed
@@ -7694,9 +7744,7 @@ package body Exp_Ch9 is
-- this array. The array is declared after all protected subprograms.
if Has_Entries (Prot_Typ) then
- Entries_Aggr :=
- Make_Aggregate (Loc, Expressions => New_List);
-
+ Entries_Aggr := Make_Aggregate (Loc, Expressions => New_List);
else
Entries_Aggr := Empty;
end if;
@@ -9461,6 +9509,9 @@ package body Exp_Ch9 is
Call : Node_Id;
New_N : Node_Id;
+ Insert_Nod : Node_Id;
+ -- Used to determine the proper location of wrapper body insertions
+
begin
-- Add renaming declarations for discriminals and a declaration for the
-- entry family index (if applicable).
@@ -9527,56 +9578,17 @@ package body Exp_Ch9 is
end if;
-- Ada 2005 (AI-345): Construct the primitive entry wrapper bodies after
- -- the task body. At this point the entry specs have been created,
+ -- the task body. At this point all wrapper specs have been created,
-- frozen and included in the dispatch table for the task type.
- pragma Assert (Present (Corresponding_Record_Type (Ttyp)));
-
- if Ada_Version >= Ada_05
- and then Present (Task_Definition (Parent (Ttyp)))
- and then Present (Interfaces (Corresponding_Record_Type (Ttyp)))
- then
- declare
- Current_Node : Node_Id;
- Vis_Decl : Node_Id :=
- First (Visible_Declarations (Task_Definition (Parent (Ttyp))));
- Wrap_Body : Node_Id;
-
- begin
- if Nkind (Parent (N)) = N_Subunit then
- Current_Node := Corresponding_Stub (Parent (N));
- else
- Current_Node := N;
- end if;
-
- -- Examine the visible declarations of the task type, looking for
- -- an entry declaration. We do not consider entry families since
- -- they cannot have dispatching operations, thus they do not need
- -- entry wrappers.
-
- while Present (Vis_Decl) loop
- if Nkind (Vis_Decl) = N_Entry_Declaration
- and then Ekind (Defining_Identifier (Vis_Decl)) = E_Entry
- then
- -- Create the specification of the wrapper
-
- Wrap_Body :=
- Build_Wrapper_Body (Loc,
- Proc_Nam => Defining_Identifier (Vis_Decl),
- Obj_Typ => Corresponding_Record_Type (Ttyp),
- Formals => Parameter_Specifications (Vis_Decl));
-
- if Wrap_Body /= Empty then
- Insert_After (Current_Node, Wrap_Body);
- Current_Node := Wrap_Body;
-
- Analyze (Wrap_Body);
- end if;
- end if;
+ if Ada_Version >= Ada_05 then
+ if Nkind (Parent (N)) = N_Subunit then
+ Insert_Nod := Corresponding_Stub (Parent (N));
+ else
+ Insert_Nod := N;
+ end if;
- Next (Vis_Decl);
- end loop;
- end;
+ Build_Wrapper_Bodies (Loc, Ttyp, Insert_Nod);
end if;
end Expand_N_Task_Body;
@@ -10025,51 +10037,8 @@ package body Exp_Ch9 is
-- Ada 2005 (AI-345): Construct the primitive entry wrapper specs before
-- the corresponding record has been frozen.
- if Ada_Version >= Ada_05
- and then Present (Taskdef)
- and then Present (Corresponding_Record_Type
- (Defining_Identifier (Parent (Taskdef))))
- and then Present (Interfaces
- (Corresponding_Record_Type
- (Defining_Identifier (Parent (Taskdef)))))
- then
- declare
- Current_Node : Node_Id := Rec_Decl;
- Vis_Decl : Node_Id := First (Visible_Declarations (Taskdef));
- Wrap_Spec : Node_Id;
- New_N : Node_Id;
-
- begin
- -- Examine the visible declarations of the task type, looking for
- -- an entry declaration. We do not consider entry families since
- -- they cannot have dispatching operations, thus they do not need
- -- entry wrappers.
-
- while Present (Vis_Decl) loop
- if Nkind (Vis_Decl) = N_Entry_Declaration
- and then Ekind (Defining_Identifier (Vis_Decl)) = E_Entry
- then
- Wrap_Spec :=
- Build_Wrapper_Spec (Loc,
- Proc_Nam => Defining_Identifier (Vis_Decl),
- Obj_Typ => Etype (Rec_Ent),
- Formals => Parameter_Specifications (Vis_Decl));
-
- if Wrap_Spec /= Empty then
- New_N :=
- Make_Subprogram_Declaration (Loc,
- Specification => Wrap_Spec);
-
- Insert_After (Current_Node, New_N);
- Current_Node := New_N;
-
- Analyze (New_N);
- end if;
- end if;
-
- Next (Vis_Decl);
- end loop;
- end;
+ if Ada_Version >= Ada_05 then
+ Build_Wrapper_Specs (Loc, Tasktyp, Rec_Decl);
end if;
-- Ada 2005 (AI-345): We must defer freezing to allow further
@@ -11408,6 +11377,17 @@ package body Exp_Ch9 is
or else Denotes_Discriminant (Hi, True));
end Is_Potentially_Large_Family;
+ -------------------------------------
+ -- Is_Private_Primitive_Subprogram --
+ -------------------------------------
+
+ function Is_Private_Primitive_Subprogram (Id : Entity_Id) return Boolean is
+ begin
+ return
+ (Ekind (Id) = E_Function or else Ekind (Id) = E_Procedure)
+ and then Is_Private_Primitive (Id);
+ end Is_Private_Primitive_Subprogram;
+
------------------
-- Index_Object --
------------------
diff --git a/gcc/ada/exp_ch9.ads b/gcc/ada/exp_ch9.ads
index a4c618a61cb..1cfa74d3635 100644
--- a/gcc/ada/exp_ch9.ads
+++ b/gcc/ada/exp_ch9.ads
@@ -153,6 +153,18 @@ package Exp_Ch9 is
-- aggregate. It replaces the call to Init (Args) done by
-- Build_Task_Allocate_Block.
+ function Build_Wrapper_Spec
+ (Loc : Source_Ptr;
+ Subp_Id : Entity_Id;
+ Obj_Typ : Entity_Id;
+ Formals : List_Id) return Node_Id;
+ -- Ada 2005 (AI-345): Build the specification of a primitive operation
+ -- associated with a protected or task type. This is required to implement
+ -- dispatching calls through interfaces. Subp_Id is the primitive to be
+ -- wrapped, Obj_Typ is the type of the newly added formal parameter to
+ -- handle object notation, Formals are the original entry formals that
+ -- will be explicitly replicated.
+
function Concurrent_Ref (N : Node_Id) return Node_Id;
-- Given the name of a concurrent object (task or protected object), or
-- the name of an access to a concurrent object, this function returns an
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index d41a6bc383c..09850f644d4 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -1581,7 +1581,12 @@ package body Exp_Util is
or else Etype (First_Entity (Op)) = Etype (Last_Entity (Op)));
Next_Elmt (Prim);
- pragma Assert (Present (Prim));
+
+ -- Raise Program_Error if no primitive found
+
+ if No (Prim) then
+ raise Program_Error;
+ end if;
end loop;
return Node (Prim);
@@ -1608,7 +1613,12 @@ package body Exp_Util is
Prim := First_Elmt (Primitive_Operations (Typ));
while not Is_TSS (Node (Prim), Name) loop
Next_Elmt (Prim);
- pragma Assert (Present (Prim));
+
+ -- Raise program error if no primitive found
+
+ if No (Prim) then
+ raise Program_Error;
+ end if;
end loop;
return Node (Prim);
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 5e57147b720..5848d5d7171 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -360,7 +360,10 @@ package Exp_Util is
-- Find the first primitive operation of type T whose name is 'Name'.
-- This function allows the use of a primitive operation which is not
-- directly visible. If T is a class wide type, then the reference is
- -- to an operation of the corresponding root type.
+ -- to an operation of the corresponding root type. Raises Program_Error
+ -- exception if no primitive operation is found. This is normally an
+ -- internal error, but in some cases is an expected consequence of
+ -- illegalities elsewhere.
function Find_Prim_Op
(T : Entity_Id;
@@ -370,6 +373,9 @@ package Exp_Util is
-- with the indicated suffix). This function allows use of a primitive
-- operation which is not directly visible. If T is a class wide type,
-- then the reference is to an operation of the corresponding root type.
+ -- Raises Program_Error exception if no primitive operation is found.
+ -- This is normally an internal error, but in some cases is an expected
+ -- consequence of illegalities elsewhere.
function Find_Protection_Object (Scop : Entity_Id) return Entity_Id;
-- Traverse the scope stack starting from Scop and look for an entry,
diff --git a/gcc/ada/g-pehage.adb b/gcc/ada/g-pehage.adb
index 8d4733334d6..c779fac7ca7 100644
--- a/gcc/ada/g-pehage.adb
+++ b/gcc/ada/g-pehage.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002-2007, AdaCore --
+-- Copyright (C) 2002-2008, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -51,8 +51,8 @@ package body GNAT.Perfect_Hash_Generators is
-- where f1 and f2 are functions that map strings into integers, and g is a
-- function that maps integers into [0, m-1]. h can be order preserving.
- -- For instance, let W = {w_0, ..., w_i, ...,
- -- w_m-1}, h can be defined such that h (w_i) = i.
+ -- For instance, let W = {w_0, ..., w_i, ..., w_m-1}, h can be defined
+ -- such that h (w_i) = i.
-- This algorithm defines two possible constructions of f1 and f2. Method
-- b) stores the hash function in less memory space at the expense of
@@ -82,10 +82,10 @@ package body GNAT.Perfect_Hash_Generators is
-- probability of generating an acyclic graph, n >= 2m. If it is not
-- acyclic, Tk have to be regenerated.
- -- In the assignment step, the algorithm builds function g. As is acyclic,
- -- there is a vertex v1 with only one neighbor v2. Let w_i be the word such
- -- that v1 = f1 (w_i) and v2 = f2 (w_i). Let g (v1) = 0 by construction and
- -- g (v2) = (i - g (v1)) mod n (or to be general, (h (i) - g (v1) mod n).
+ -- In the assignment step, the algorithm builds function g. As G is
+ -- acyclic, there is a vertex v1 with only one neighbor v2. Let w_i be
+ -- the word such that v1 = f1 (w_i) and v2 = f2 (w_i). Let g (v1) = 0 by
+ -- construction and g (v2) = (i - g (v1)) mod n (or h (i) - g (v1) mod n).
-- If word w_j is such that v2 = f1 (w_j) and v3 = f2 (w_j), g (v3) = (j -
-- g (v2)) mod (or to be general, (h (j) - g (v2)) mod n). If w_i has no
-- neighbor, then another vertex is selected. The algorithm traverses G to
@@ -102,11 +102,12 @@ package body GNAT.Perfect_Hash_Generators is
No_Edge : constant Edge_Id := -1;
No_Table : constant Table_Id := -1;
- Max_Word_Length : constant := 32;
- subtype Word_Type is String (1 .. Max_Word_Length);
- Null_Word : constant Word_Type := (others => ASCII.NUL);
- -- Store keyword in a word. Note that the length of word is limited to 32
- -- characters.
+ type Word_Type is new String_Access;
+ procedure Free_Word (W : in out Word_Type);
+ function New_Word (S : String) return Word_Type;
+
+ procedure Resize_Word (W : in out Word_Type; Len : Natural);
+ -- Resize string W to have a length Len
type Key_Type is record
Edge : Edge_Id;
@@ -130,8 +131,12 @@ package body GNAT.Perfect_Hash_Generators is
package WT is new GNAT.Table (Word_Type, Word_Id, 0, 32, 32);
package IT is new GNAT.Table (Integer, Integer, 0, 32, 32);
- -- The two main tables. IT is used to store several tables of components
- -- containing only integers.
+ -- The two main tables. WT is used to store the words in their initial
+ -- version and in their reduced version (that is words reduced to
+ -- their significant characters). As an instance of GNAT.Table, WT does
+ -- not initialize string pointers to null. This initialization has to be
+ -- done manually when the table is allocated. IT is used to store several
+ -- tables of components containing only integers.
function Image (Int : Integer; W : Natural := 0) return String;
function Image (Str : String; W : Natural := 0) return String;
@@ -298,9 +303,6 @@ package body GNAT.Perfect_Hash_Generators is
function Allocate (N : Natural; S : Natural := 1) return Table_Id;
-- Allocate N * S ints from IT table
- procedure Free_Tmp_Tables;
- -- Deallocate the tables used by the algorithm (but not the keys table)
-
----------
-- Keys --
----------
@@ -408,7 +410,7 @@ package body GNAT.Perfect_Hash_Generators is
-- Optimization mode (memory vs CPU)
Max_Key_Len : Natural := 0;
- Min_Key_Len : Natural := Max_Word_Length;
+ Min_Key_Len : Natural := 0;
-- Maximum and minimum of all the word length
S : Natural;
@@ -530,26 +532,27 @@ package body GNAT.Perfect_Hash_Generators is
procedure Apply_Position_Selection is
begin
- WT.Set_Last (2 * NK);
for J in 0 .. NK - 1 loop
declare
- I_Word : constant Word_Type := WT.Table (Initial (J));
- R_Word : Word_Type := Null_Word;
- Index : Natural := I_Word'First - 1;
+ IW : constant String := WT.Table (Initial (J)).all;
+ RW : String (1 .. IW'Length) := (others => ASCII.NUL);
+ N : Natural := IW'First - 1;
begin
-- Select the characters of Word included in the position
-- selection.
for C in 0 .. Char_Pos_Set_Len - 1 loop
- exit when I_Word (Get_Char_Pos (C)) = ASCII.NUL;
- Index := Index + 1;
- R_Word (Index) := I_Word (Get_Char_Pos (C));
+ exit when IW (Get_Char_Pos (C)) = ASCII.NUL;
+ N := N + 1;
+ RW (N) := IW (Get_Char_Pos (C));
end loop;
- -- Build the new table with the reduced word
+ -- Build the new table with the reduced word. Be careful
+ -- to deallocate the old version to avoid memory leaks.
- WT.Table (Reduced (J)) := R_Word;
+ Free_Word (WT.Table (Reduced (J)));
+ WT.Table (Reduced (J)) := New_Word (RW);
Set_Key (J, (Edge => No_Edge));
end;
end loop;
@@ -588,7 +591,7 @@ package body GNAT.Perfect_Hash_Generators is
-- Start of processing for Assign_Values_To_Vertices
begin
- -- Value -1 denotes an uninitialized value as it is supposed to
+ -- Value -1 denotes an unitialized value as it is supposed to
-- be in the range 0 .. NK.
if G = No_Table then
@@ -628,9 +631,9 @@ package body GNAT.Perfect_Hash_Generators is
Success : Boolean := False;
begin
- NV := Natural (K2V * Float (NK));
-
- Keys := Allocate (NK);
+ if NK = 0 then
+ raise Program_Error with "keywords set cannot be empty";
+ end if;
if Verbose then
Put_Initial_Keys (Output, "Initial Key Table");
@@ -861,23 +864,16 @@ package body GNAT.Perfect_Hash_Generators is
procedure Finalize is
begin
- Free_Tmp_Tables;
+ -- Deallocate all the WT components (both initial and reduced
+ -- ones) to avoid memory leaks.
+ for W in 0 .. WT.Last loop
+ Free_Word (WT.Table (W));
+ end loop;
WT.Release;
IT.Release;
- NK := 0;
- Max_Key_Len := 0;
- Min_Key_Len := Max_Word_Length;
- end Finalize;
-
- ---------------------
- -- Free_Tmp_Tables --
- ---------------------
-
- procedure Free_Tmp_Tables is
- begin
- IT.Init;
+ -- Reset all variables for next usage
Keys := No_Table;
@@ -901,7 +897,22 @@ package body GNAT.Perfect_Hash_Generators is
Vertices := No_Table;
NV := 0;
- end Free_Tmp_Tables;
+
+ NK := 0;
+ Max_Key_Len := 0;
+ Min_Key_Len := 0;
+ end Finalize;
+
+ ---------------
+ -- Free_Word --
+ ---------------
+
+ procedure Free_Word (W : in out Word_Type) is
+ begin
+ if W /= null then
+ Free (W);
+ end if;
+ end Free_Word;
----------------------------
-- Generate_Mapping_Table --
@@ -1130,20 +1141,76 @@ package body GNAT.Perfect_Hash_Generators is
Tries : Positive := Default_Tries)
is
begin
- -- Free previous tables (the settings may have changed between two runs)
+ -- Deallocated the part of the table concerning the reduced
+ -- words. Initial words are already present in the table. We
+ -- may have reduced words already there because a previous
+ -- computation failed. We are currently retrying and the
+ -- reduced words have to be deallocated.
+
+ for W in NK .. WT.Last loop
+ Free_Word (WT.Table (W));
+ end loop;
+ IT.Init;
- Free_Tmp_Tables;
+ -- Initialize of computation variables
- if K_To_V <= 2.0 then
- Put (Output, "K to V ratio cannot be lower than 2.0");
- New_Line (Output);
- raise Program_Error;
- end if;
+ Keys := No_Table;
+
+ Char_Pos_Set := No_Table;
+ Char_Pos_Set_Len := 0;
+
+ Used_Char_Set := No_Table;
+ Used_Char_Set_Len := 0;
+
+ T1 := No_Table;
+ T2 := No_Table;
+
+ T1_Len := 0;
+ T2_Len := 0;
+
+ G := No_Table;
+ G_Len := 0;
+
+ Edges := No_Table;
+ Edges_Len := 0;
+
+ Vertices := No_Table;
+ NV := 0;
S := Seed;
K2V := K_To_V;
Opt := Optim;
NT := Tries;
+
+ if K2V <= 2.0 then
+ raise Program_Error with "K to V ratio cannot be lower than 2.0";
+ end if;
+
+ -- Do not accept a value of K2V too close to 2.0 such that once
+ -- rounded up, NV = 2 * NK because the algorithm would not converge.
+
+ NV := Natural (Float (NK) * K2V);
+ if NV <= 2 * NK then
+ NV := 2 * NK + 1;
+ end if;
+
+ Keys := Allocate (NK);
+
+ -- Resize initial words to have all of them at the same size
+ -- (so the size of the largest one).
+
+ for K in 0 .. NK - 1 loop
+ Resize_Word (WT.Table (Initial (K)), Max_Key_Len);
+ end loop;
+
+ -- Allocated the table to store the reduced words. As WT is a
+ -- GNAT.Table (using C memory management), pointers have to be
+ -- explicitly initialized to null.
+
+ WT.Set_Last (Reduced (NK - 1));
+ for W in 0 .. NK - 1 loop
+ WT.Table (Reduced (W)) := null;
+ end loop;
end Initialize;
------------
@@ -1151,28 +1218,18 @@ package body GNAT.Perfect_Hash_Generators is
------------
procedure Insert (Value : String) is
- Word : Word_Type := Null_Word;
Len : constant Natural := Value'Length;
begin
- Word (1 .. Len) := Value (Value'First .. Value'First + Len - 1);
WT.Set_Last (NK);
- WT.Table (NK) := Word;
+ WT.Table (NK) := New_Word (Value);
NK := NK + 1;
- NV := Natural (Float (NK) * K2V);
-
- -- Do not accept a value of K2V too close to 2.0 such that once rounded
- -- up, NV = 2 * NK because the algorithm would not converge.
-
- if NV <= 2 * NK then
- NV := 2 * NK + 1;
- end if;
if Max_Key_Len < Len then
Max_Key_Len := Len;
end if;
- if Len < Min_Key_Len then
+ if Min_Key_Len = 0 or else Len < Min_Key_Len then
Min_Key_Len := Len;
end if;
end Insert;
@@ -1188,6 +1245,15 @@ package body GNAT.Perfect_Hash_Generators is
end if;
end New_Line;
+ --------------
+ -- New_Word --
+ --------------
+
+ function New_Word (S : String) return Word_Type is
+ begin
+ return new String'(S);
+ end New_Word;
+
------------------------------
-- Parse_Position_Selection --
------------------------------
@@ -1761,7 +1827,7 @@ package body GNAT.Perfect_Hash_Generators is
K := Get_Key (J);
Put (File, Image (J, M), F1, L1, J, 1, 3, 1);
Put (File, Image (K.Edge, M), F1, L1, J, 1, 3, 2);
- Put (File, WT.Table (Initial (J)), F1, L1, J, 1, 3, 3);
+ Put (File, WT.Table (Initial (J)).all, F1, L1, J, 1, 3, 3);
end loop;
end Put_Initial_Keys;
@@ -1842,7 +1908,7 @@ package body GNAT.Perfect_Hash_Generators is
K := Get_Key (J);
Put (File, Image (J, M), F1, L1, J, 1, 3, 1);
Put (File, Image (K.Edge, M), F1, L1, J, 1, 3, 2);
- Put (File, WT.Table (Reduced (J)), F1, L1, J, 1, 3, 3);
+ Put (File, WT.Table (Reduced (J)).all, F1, L1, J, 1, 3, 3);
end loop;
end Put_Reduced_Keys;
@@ -1920,6 +1986,22 @@ package body GNAT.Perfect_Hash_Generators is
return K + NK + 1;
end Reduced;
+ -----------------
+ -- Resize_Word --
+ -----------------
+
+ procedure Resize_Word (W : in out Word_Type; Len : Natural) is
+ S1 : constant String := W.all;
+ S2 : String (1 .. Len) := (others => ASCII.NUL);
+ L : constant Natural := S1'Length;
+ begin
+ if L /= Len then
+ Free_Word (W);
+ S2 (1 .. L) := S1;
+ W := New_Word (S2);
+ end if;
+ end Resize_Word;
+
--------------------------
-- Select_Char_Position --
--------------------------
@@ -1985,11 +2067,11 @@ package body GNAT.Perfect_Hash_Generators is
begin
if L = 0 then
- Left := Reduced (0) - 1;
+ Left := NK;
Right := Offset + R;
elsif R = 0 then
Left := Offset + L;
- Right := Reduced (0) - 1;
+ Right := NK;
else
Left := Offset + L;
Right := Offset + R;
@@ -2007,17 +2089,18 @@ package body GNAT.Perfect_Hash_Generators is
begin
if From = 0 then
- Source := Reduced (0) - 1;
+ Source := NK;
Target := Offset + To;
elsif To = 0 then
Source := Offset + From;
- Target := Reduced (0) - 1;
+ Target := NK;
else
Source := Offset + From;
Target := Offset + To;
end if;
WT.Table (Target) := WT.Table (Source);
+ WT.Table (Source) := null;
end Move;
package Sorting is new GNAT.Heap_Sort_G (Move, Lt);
@@ -2120,9 +2203,8 @@ package body GNAT.Perfect_Hash_Generators is
begin
-- Initialize the reduced words set
- WT.Set_Last (2 * NK);
for K in 0 .. NK - 1 loop
- WT.Table (Reduced (K)) := WT.Table (Initial (K));
+ WT.Table (Reduced (K)) := New_Word (WT.Table (Initial (K)).all);
end loop;
declare
@@ -2220,7 +2302,7 @@ package body GNAT.Perfect_Hash_Generators is
Same_Keys_Sets_Table (J).First ..
Same_Keys_Sets_Table (J).Last
loop
- Put (Output, WT.Table (Reduced (K)));
+ Put (Output, WT.Table (Reduced (K)).all);
New_Line (Output);
end loop;
Put (Output, "--");
diff --git a/gcc/ada/g-pehage.ads b/gcc/ada/g-pehage.ads
index b2aea490eed..277a2a4580b 100644
--- a/gcc/ada/g-pehage.ads
+++ b/gcc/ada/g-pehage.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002-2005, AdaCore --
+-- Copyright (C) 2002-2008, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -60,7 +60,7 @@
-- The hash table size corresponds to the exact size of W and *no larger*.
-- This represents the "minimal" property.
--- The functions generated by this package require the key set to be known in
+-- The functions generated by this package require the words to be known in
-- advance (they are "static" hash functions). The hash functions are also
-- order preserving. If w2 is inserted after w1 in the generator, then (w1)
-- < f (w2). These hashing functions are convenient for use with realtime
@@ -99,27 +99,33 @@ package GNAT.Perfect_Hash_Generators is
K_To_V : Float := Default_K_To_V;
Optim : Optimization := CPU_Time;
Tries : Positive := Default_Tries);
- -- Initialize the generator and its internal structures. Set the ratio of
- -- vertices over keys in the random graphs. This value has to be greater
- -- than 2.0 in order for the algorithm to succeed. The key set is not
- -- modified (in particular when it is already set). For instance, it is
- -- possible to run several times the generator with different settings on
- -- the same key set.
+ -- Initialize the generator and its internal structures. Set the
+ -- ratio of vertices over keys in the random graphs. This value
+ -- has to be greater than 2.0 in order for the algorithm to
+ -- succeed. The word set is not modified (in particular when it is
+ -- already set). For instance, it is possible to run several times
+ -- the generator with different settings on the same words.
+
+ -- A classical way of doing is to Insert all the words and then to
+ -- invoke Initialize and Compute. If Compute fails to find a
+ -- perfect hash function, invoke Initialize another time with
+ -- other configuration parameters (probably with a greater K_To_V
+ -- ratio). Once successful, invoke Produce and Finalize.
procedure Finalize;
- -- Deallocate the internal structures and the key table
+ -- Deallocate the internal structures and the words table
procedure Insert (Value : String);
- -- Insert a new key in the table
+ -- Insert a new word in the table
Too_Many_Tries : exception;
-- Raised after Tries unsuccessful runs
procedure Compute (Position : String := Default_Position);
-- Compute the hash function. Position allows to define selection of
- -- character positions used in the keywords hash function. Positions can be
+ -- character positions used in the word hash function. Positions can be
-- separated by commas and range like x-y may be used. Character '$'
- -- represents the final character of a key. With an empty position, the
+ -- represents the final character of a word. With an empty position, the
-- generator automatically produces positions to reduce the memory usage.
-- Raise Too_Many_Tries in case that the algorithm does not succeed in less
-- than Tries attempts (see Initialize).
@@ -144,7 +150,7 @@ package GNAT.Perfect_Hash_Generators is
-- F1 and F2 are two functions based on two function tables T1 and T2.
-- Their definition depends on the chosen optimization mode.
- -- Only some character positions are used in the keys because they are
+ -- Only some character positions are used in the words because they are
-- significant. They are listed in a character position table (P in the
-- pseudo-code below). For instance, in {"jan", "feb", "mar", "apr", "jun",
-- "jul", "aug", "sep", "oct", "nov", "dec"}, only positions 2 and 3 are
@@ -152,7 +158,7 @@ package GNAT.Perfect_Hash_Generators is
-- {2, 3}
-- When Optimization is CPU_Time, the first dimension of T1 and T2
- -- corresponds to the character position in the key and the second to the
+ -- corresponds to the character position in the word and the second to the
-- character set. As all the character set is not used, we define a used
-- character table which associates a distinct index to each used character
-- (unused characters are mapped to zero). In this case, the second
@@ -177,7 +183,7 @@ package GNAT.Perfect_Hash_Generators is
-- end Hash;
-- When Optimization is Memory_Space, the first dimension of T1 and T2
- -- corresponds to the character position in the key and the second
+ -- corresponds to the character position in the word and the second
-- dimension is ignored. T1 and T2 are no longer matrices but vectors.
-- Therefore, the used character table is not available. The hash function
-- has the following form:
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index a8c0c1bbb25..9ac7b8b7a92 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -1353,7 +1353,7 @@ ifeq ($(strip $(filter-out cygwin32% mingw32% pe,$(osys))),)
s-taprop.adb<s-taprop-mingw.adb \
system.ads<system-mingw.ads
- EXTRA_GNATRTL_NONTASKING_OBJS = s-win32.o g-regist.o
+ EXTRA_GNATRTL_NONTASKING_OBJS = s-win32.o s-winext.o g-regist.o
EXTRA_GNATRTL_TASKING_OBJS = a-exetim.o
MISCLIB = -lwsock32
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 61ae653de2a..b02b9a04132 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -1536,15 +1536,20 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_expr, 0);
gnu_type = make_node (INTEGER_TYPE);
+ TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));
+
+ /* Set the precision to the Esize except for bit-packed arrays and
+ subtypes of Standard.Boolean. */
if (Is_Packed_Array_Type (gnat_entity)
&& Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
{
esize = UI_To_Int (RM_Size (gnat_entity));
TYPE_PACKED_ARRAY_TYPE_P (gnu_type) = 1;
}
+ else if (TREE_CODE (TREE_TYPE (gnu_type)) == BOOLEAN_TYPE)
+ esize = 1;
TYPE_PRECISION (gnu_type) = esize;
- TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));
TYPE_MIN_VALUE (gnu_type)
= convert (TREE_TYPE (gnu_type),
@@ -1596,7 +1601,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
are uninitialized. Both goals are accomplished by wrapping the
modular value in an enclosing struct. */
if (Is_Packed_Array_Type (gnat_entity)
- && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
+ && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
{
tree gnu_field_type = gnu_type;
tree gnu_field;
@@ -7106,7 +7111,8 @@ set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity)
if (TREE_CODE (gnu_type) == INTEGER_TYPE
&& Is_Discrete_Or_Fixed_Point_Type (gnat_entity))
TYPE_RM_SIZE_NUM (gnu_type) = size;
- else if (TREE_CODE (gnu_type) == ENUMERAL_TYPE)
+ else if (TREE_CODE (gnu_type) == ENUMERAL_TYPE
+ || TREE_CODE (gnu_type) == BOOLEAN_TYPE)
TYPE_RM_SIZE_NUM (gnu_type) = size;
else if ((TREE_CODE (gnu_type) == RECORD_TYPE
|| TREE_CODE (gnu_type) == UNION_TYPE
@@ -7124,7 +7130,7 @@ static tree
make_type_from_size (tree type, tree size_tree, bool for_biased)
{
unsigned HOST_WIDE_INT size;
- bool biased_p;
+ bool biased_p, boolean_p;
tree new_type;
/* If size indicates an error, just return TYPE to avoid propagating
@@ -7138,13 +7144,23 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
{
case INTEGER_TYPE:
case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
biased_p = (TREE_CODE (type) == INTEGER_TYPE
&& TYPE_BIASED_REPRESENTATION_P (type));
+ boolean_p = (TREE_CODE (type) == BOOLEAN_TYPE
+ || (TREE_CODE (type) == INTEGER_TYPE
+ && TREE_TYPE (type)
+ && TREE_CODE (TREE_TYPE (type)) == BOOLEAN_TYPE));
+
+ if (boolean_p)
+ size = round_up_to_align (size, BITS_PER_UNIT);
+
/* Only do something if the type is not a packed array type and
doesn't already have the proper size. */
if (TYPE_PACKED_ARRAY_TYPE_P (type)
- || (TYPE_PRECISION (type) == size && biased_p == for_biased))
+ || (biased_p == for_biased && TYPE_PRECISION (type) == size)
+ || (boolean_p && compare_tree_int (TYPE_SIZE (type), size) == 0))
break;
biased_p |= for_biased;
@@ -7154,13 +7170,18 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
new_type = make_unsigned_type (size);
else
new_type = make_signed_type (size);
+ if (boolean_p)
+ TYPE_PRECISION (new_type) = 1;
TREE_TYPE (new_type) = TREE_TYPE (type) ? TREE_TYPE (type) : type;
TYPE_MIN_VALUE (new_type)
= convert (TREE_TYPE (new_type), TYPE_MIN_VALUE (type));
TYPE_MAX_VALUE (new_type)
= convert (TREE_TYPE (new_type), TYPE_MAX_VALUE (type));
TYPE_BIASED_REPRESENTATION_P (new_type) = biased_p;
- TYPE_RM_SIZE_NUM (new_type) = bitsize_int (size);
+ if (boolean_p)
+ TYPE_RM_SIZE_NUM (new_type) = bitsize_int (1);
+ else
+ TYPE_RM_SIZE_NUM (new_type) = bitsize_int (size);
return new_type;
case RECORD_TYPE:
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index 685bb383bbd..8055359863c 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -218,6 +218,7 @@ extern void gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
struct List_Header *list_headers_ptr,
Nat number_file,
struct File_Info_Type *file_info_ptr,
+ Entity_Id standard_boolean,
Entity_Id standard_integer,
Entity_Id standard_long_long_float,
Entity_Id standard_exception_type,
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 02397d7f445..47d249a4578 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -544,6 +544,7 @@ gnat_print_type (FILE *file, tree node, int indent)
break;
case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
print_node (file, "RM size", TYPE_RM_SIZE_NUM (node), indent + 4);
break;
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 3b15e30a222..9d3f807c6e6 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -231,12 +231,12 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
struct Elist_Header *elists_ptr, struct Elmt_Item *elmts_ptr,
struct String_Entry *strings_ptr, Char_Code *string_chars_ptr,
struct List_Header *list_headers_ptr, Nat number_file,
- struct File_Info_Type *file_info_ptr,
+ struct File_Info_Type *file_info_ptr, Entity_Id standard_boolean,
Entity_Id standard_integer, Entity_Id standard_long_long_float,
Entity_Id standard_exception_type, Int gigi_operating_mode)
{
- tree gnu_standard_long_long_float;
- tree gnu_standard_exception_type;
+ Entity_Id gnat_literal;
+ tree gnu_standard_long_long_float, gnu_standard_exception_type, t;
struct elab_info *info;
int i;
@@ -311,6 +311,8 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
/* Give names and make TYPE_DECLs for common types. */
create_type_decl (get_identifier (SIZE_TYPE), sizetype,
NULL, false, true, Empty);
+ create_type_decl (get_identifier ("boolean"), boolean_type_node,
+ NULL, false, true, Empty);
create_type_decl (get_identifier ("integer"), integer_type_node,
NULL, false, true, Empty);
create_type_decl (get_identifier ("unsigned char"), char_type_node,
@@ -318,6 +320,26 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
create_type_decl (get_identifier ("long integer"), long_integer_type_node,
NULL, false, true, Empty);
+ /* Save the type we made for boolean as the type for Standard.Boolean. */
+ save_gnu_tree (Base_Type (standard_boolean), TYPE_NAME (boolean_type_node),
+ false);
+ gnat_literal = First_Literal (Base_Type (standard_boolean));
+ t = UI_To_gnu (Enumeration_Rep (gnat_literal), boolean_type_node);
+ gcc_assert (t == boolean_false_node);
+ t = create_var_decl (get_entity_name (gnat_literal), NULL_TREE,
+ boolean_type_node, t, true, false, false, false,
+ NULL, gnat_literal);
+ DECL_IGNORED_P (t) = 1;
+ save_gnu_tree (gnat_literal, t, false);
+ gnat_literal = Next_Literal (gnat_literal);
+ t = UI_To_gnu (Enumeration_Rep (gnat_literal), boolean_type_node);
+ gcc_assert (t == boolean_true_node);
+ t = create_var_decl (get_entity_name (gnat_literal), NULL_TREE,
+ boolean_type_node, t, true, false, false, false,
+ NULL, gnat_literal);
+ DECL_IGNORED_P (t) = 1;
+ save_gnu_tree (gnat_literal, t, false);
+
/* Save the type we made for integer as the type for Standard.Integer.
Then make the rest of the standard types. Note that some of these
may be subtypes. */
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 01cc9b8948e..882293895cc 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -523,6 +523,13 @@ gnat_init_decl_processing (void)
this before we can expand the GNAT types. */
size_type_node = gnat_type_for_size (GET_MODE_BITSIZE (Pmode), 0);
set_sizetype (size_type_node);
+
+ /* In Ada, we use an unsigned 8-bit type for the default boolean type. */
+ boolean_type_node = make_node (BOOLEAN_TYPE);
+ TYPE_PRECISION (boolean_type_node) = 1;
+ fixup_unsigned_type (boolean_type_node);
+ TYPE_RM_SIZE_NUM (boolean_type_node) = bitsize_int (1);
+
build_common_tree_nodes_2 (0);
ptr_void_type_node = build_pointer_type (void_type_node);
@@ -1762,7 +1769,8 @@ create_param_decl (tree param_name, tree param_type, bool readonly)
lead to various ABI violations. */
if (targetm.calls.promote_prototypes (param_type)
&& (TREE_CODE (param_type) == INTEGER_TYPE
- || TREE_CODE (param_type) == ENUMERAL_TYPE)
+ || TREE_CODE (param_type) == ENUMERAL_TYPE
+ || TREE_CODE (param_type) == BOOLEAN_TYPE)
&& TYPE_PRECISION (param_type) < TYPE_PRECISION (integer_type_node))
{
/* We have to be careful about biased types here. Make a subtype
@@ -2690,6 +2698,7 @@ build_vms_descriptor (tree type, Mechanism_Type mech, Entity_Id gnat_entity)
{
case INTEGER_TYPE:
case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
if (TYPE_VAX_FLOATING_POINT_P (type))
switch (tree_low_cst (TYPE_DIGITS_VALUE (type), 1))
{
@@ -2992,6 +3001,7 @@ build_vms_descriptor64 (tree type, Mechanism_Type mech, Entity_Id gnat_entity)
{
case INTEGER_TYPE:
case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
if (TYPE_VAX_FLOATING_POINT_P (type))
switch (tree_low_cst (TYPE_DIGITS_VALUE (type), 1))
{
@@ -4035,9 +4045,6 @@ convert (tree type, tree expr)
case VOID_TYPE:
return fold_build1 (CONVERT_EXPR, type, expr);
- case BOOLEAN_TYPE:
- return fold_convert (type, gnat_truthvalue_conversion (expr));
-
case INTEGER_TYPE:
if (TYPE_HAS_ACTUAL_BOUNDS_P (type)
&& (ecode == ARRAY_TYPE || ecode == UNCONSTRAINED_ARRAY_TYPE
@@ -4052,6 +4059,7 @@ convert (tree type, tree expr)
/* ... fall through ... */
case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
/* If we are converting an additive expression to an integer type
with lower precision, be wary of the optimization that can be
applied by convert_to_integer. There are 2 problematic cases:
diff --git a/gcc/ada/gnatlink.adb b/gcc/ada/gnatlink.adb
index c9b496c0ee8..4da260d67d1 100644
--- a/gcc/ada/gnatlink.adb
+++ b/gcc/ada/gnatlink.adb
@@ -1670,6 +1670,7 @@ begin
end if;
elsif RTX_RTSS_Kernel_Module_On_Target then
+
-- Use Microsoft linker for RTSS modules
Linker_Path := System.OS_Lib.Locate_Exec_On_Path ("link");
@@ -1899,6 +1900,7 @@ begin
end loop;
elsif RTX_RTSS_Kernel_Module_On_Target then
+
-- Remove flags not relevant for Microsoft linker and adapt some
-- others.
diff --git a/gcc/ada/rtsfind.adb b/gcc/ada/rtsfind.adb
index a0efccc3f06..fda3b2ff082 100644
--- a/gcc/ada/rtsfind.adb
+++ b/gcc/ada/rtsfind.adb
@@ -914,25 +914,6 @@ package body Rtsfind is
---------------
procedure Check_RPC is
-
- procedure Check_RPC_Failure (Msg : String);
- pragma No_Return (Check_RPC_Failure);
- -- Display Msg on standard error and raise Unrecoverable_Error
-
- -----------------------
- -- Check_RPC_Failure --
- -----------------------
-
- procedure Check_RPC_Failure (Msg : String) is
- begin
- Set_Standard_Error;
- Write_Str (Msg);
- Write_Eol;
- raise Unrecoverable_Error;
- end Check_RPC_Failure;
-
- -- Start of processing for Check_RPC
-
begin
-- Bypass this check if debug flag -gnatdR set
@@ -940,30 +921,44 @@ package body Rtsfind is
return;
end if;
- -- Otherwise we need the check if we are going after one of
- -- the critical entities in System.RPC in stubs mode.
-
- -- ??? Should we do this for other s-parint entities too?
-
- if (Distribution_Stub_Mode = Generate_Receiver_Stub_Body
- or else
- Distribution_Stub_Mode = Generate_Caller_Stub_Body)
- and then (E = RE_Do_Rpc
- or else
- E = RE_Do_Apc
- or else
- E = RE_Params_Stream_Type
- or else
- E = RE_Request_Access)
+ -- Otherwise we need the check if we are going after one of the
+ -- critical entities in System.RPC / System.Partition_Interface.
+
+ if E = RE_Do_Rpc
+ or else
+ E = RE_Do_Apc
+ or else
+ E = RE_Params_Stream_Type
+ or else
+ E = RE_Request_Access
then
- if Get_PCS_Name = Name_No_DSA then
- Check_RPC_Failure ("distribution feature not supported");
+ -- If generating RCI stubs, check that we have a real PCS
+
+ if (Distribution_Stub_Mode = Generate_Receiver_Stub_Body
+ or else
+ Distribution_Stub_Mode = Generate_Caller_Stub_Body)
+ and then Get_PCS_Name = Name_No_DSA
+ then
+ Set_Standard_Error;
+ Write_Str ("distribution feature not supported");
+ Write_Eol;
+ raise Unrecoverable_Error;
+
+ -- In all cases, check Exp_Dist and System.Partition_Interface
+ -- consistency.
elsif Get_PCS_Version /=
Exp_Dist.PCS_Version_Number (Get_PCS_Name)
then
- Check_RPC_Failure ("PCS version mismatch");
-
+ Set_Standard_Error;
+ Write_Str ("PCS version mismatch: expander ");
+ Write_Int (Exp_Dist.PCS_Version_Number (Get_PCS_Name));
+ Write_Str (", PCS (");
+ Write_Name (Get_PCS_Name);
+ Write_Str (") ");
+ Write_Int (Get_PCS_Version);
+ Write_Eol;
+ raise Unrecoverable_Error;
end if;
end if;
end Check_RPC;
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index b6ccb6028fc..f67d34d60f8 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -31,6 +31,7 @@ with Einfo; use Einfo;
with Errout; use Errout;
with Eval_Fat; use Eval_Fat;
with Exp_Ch3; use Exp_Ch3;
+with Exp_Ch9; use Exp_Ch9;
with Exp_Disp; use Exp_Disp;
with Exp_Dist; use Exp_Dist;
with Exp_Tss; use Exp_Tss;
@@ -15811,48 +15812,117 @@ package body Sem_Ch3 is
-- If the private view was tagged, copy the new primitive operations
-- from the private view to the full view.
- -- Note: Subprograms covering interface primitives were previously
- -- propagated to the full view by Derive_Progenitor_Primitives
-
- if Is_Tagged_Type (Full_T)
- and then not Is_Concurrent_Type (Full_T)
- then
+ if Is_Tagged_Type (Full_T) then
declare
- Priv_List : Elist_Id;
- Full_List : constant Elist_Id := Primitive_Operations (Full_T);
- P1, P2 : Elmt_Id;
+ Disp_Typ : Entity_Id;
+ Full_List : Elist_Id;
Prim : Entity_Id;
- D_Type : Entity_Id;
+ Prim_Elmt : Elmt_Id;
+ Priv_List : Elist_Id;
+
+ function Contains
+ (E : Entity_Id;
+ L : Elist_Id) return Boolean;
+ -- Determine whether list L contains element E
+
+ --------------
+ -- Contains --
+ --------------
+
+ function Contains
+ (E : Entity_Id;
+ L : Elist_Id) return Boolean
+ is
+ List_Elmt : Elmt_Id;
+
+ begin
+ List_Elmt := First_Elmt (L);
+ while Present (List_Elmt) loop
+ if Node (List_Elmt) = E then
+ return True;
+ end if;
+
+ Next_Elmt (List_Elmt);
+ end loop;
+
+ return False;
+ end Contains;
+
+ -- Start of processing
begin
if Is_Tagged_Type (Priv_T) then
Priv_List := Primitive_Operations (Priv_T);
+ Prim_Elmt := First_Elmt (Priv_List);
+
+ -- In the case of a concurrent type completing a private tagged
+ -- type, primivies may have been declared in between the two
+ -- views. These subprograms need to be wrapped the same way
+ -- entries and protected procedures are handled because they
+ -- cannot be directly shared by the two views.
+
+ if Is_Concurrent_Type (Full_T) then
+ declare
+ Conc_Typ : constant Entity_Id :=
+ Corresponding_Record_Type (Full_T);
+ Loc : constant Source_Ptr := Sloc (Conc_Typ);
+ Curr_Nod : Node_Id := Parent (Conc_Typ);
+ Wrap_Spec : Node_Id;
- P1 := First_Elmt (Priv_List);
- while Present (P1) loop
- Prim := Node (P1);
+ begin
+ while Present (Prim_Elmt) loop
+ Prim := Node (Prim_Elmt);
- -- Transfer explicit primitives, not those inherited from
- -- parent of partial view, which will be re-inherited on
- -- the full view.
+ if Comes_From_Source (Prim)
+ and then not Is_Abstract_Subprogram (Prim)
+ then
+ Wrap_Spec :=
+ Make_Subprogram_Declaration (Loc,
+ Specification =>
+ Build_Wrapper_Spec (Loc,
+ Subp_Id => Prim,
+ Obj_Typ => Conc_Typ,
+ Formals =>
+ Parameter_Specifications (
+ Parent (Prim))));
+
+ Insert_After (Curr_Nod, Wrap_Spec);
+ Curr_Nod := Wrap_Spec;
+
+ Analyze (Wrap_Spec);
+ end if;
- if Comes_From_Source (Prim) then
- P2 := First_Elmt (Full_List);
- while Present (P2) and then Node (P2) /= Prim loop
- Next_Elmt (P2);
+ Next_Elmt (Prim_Elmt);
end loop;
- -- If not found, that is a new one
+ return;
+ end;
+
+ -- For non-concurrent types, transfer explicit primitives, but
+ -- omit those inherited from the parent of the private view
+ -- since they will be re-inherited later on.
+
+ else
+ Full_List := Primitive_Operations (Full_T);
+
+ while Present (Prim_Elmt) loop
+ Prim := Node (Prim_Elmt);
- if No (P2) then
+ if Comes_From_Source (Prim)
+ and then not Contains (Prim, Full_List)
+ then
Append_Elmt (Prim, Full_List);
end if;
- end if;
- Next_Elmt (P1);
- end loop;
+ Next_Elmt (Prim_Elmt);
+ end loop;
+ end if;
+
+ -- Untagged private view
else
+ Full_List := Primitive_Operations (Full_T);
+
-- In this case the partial view is untagged, so here we locate
-- all of the earlier primitives that need to be treated as
-- dispatching (those that appear between the two views). Note
@@ -15871,10 +15941,9 @@ package body Sem_Ch3 is
or else
Ekind (Prim) = E_Function
then
+ Disp_Typ := Find_Dispatching_Type (Prim);
- D_Type := Find_Dispatching_Type (Prim);
-
- if D_Type = Full_T
+ if Disp_Typ = Full_T
and then (Chars (Prim) /= Name_Op_Ne
or else Comes_From_Source (Prim))
then
@@ -15887,13 +15956,13 @@ package body Sem_Ch3 is
end if;
elsif Is_Dispatching_Operation (Prim)
- and then D_Type /= Full_T
+ and then Disp_Typ /= Full_T
then
-- Verify that it is not otherwise controlled by a
-- formal or a return value of type T.
- Check_Controlling_Formals (D_Type, Prim);
+ Check_Controlling_Formals (Disp_Typ, Prim);
end if;
end if;
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 0116a83517c..04413a19602 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -1306,6 +1306,17 @@ package body Sem_Ch6 is
-- If pragma does not appear after the body, check whether there is
-- an inline pragma before any local declarations.
+ function Disambiguate_Spec return Entity_Id;
+ -- When a primitive is declared between the private view and the full
+ -- view of a concurrent type which implements an interface, a special
+ -- mechanism is used to find the corresponding spec of the primitive
+ -- body.
+
+ function Is_Private_Concurrent_Primitive
+ (Subp_Id : Entity_Id) return Boolean;
+ -- Determine whether subprogram Subp_Id is a primitive of a concurrent
+ -- type that implements an interface and has a private view.
+
procedure Set_Trivial_Subprogram (N : Node_Id);
-- Sets the Is_Trivial_Subprogram flag in both spec and body of the
-- subprogram whose body is being analyzed. N is the statement node
@@ -1457,6 +1468,128 @@ package body Sem_Ch6 is
end if;
end Check_Inline_Pragma;
+ -----------------------
+ -- Disambiguate_Spec --
+ -----------------------
+
+ function Disambiguate_Spec return Entity_Id is
+ Priv_Spec : Entity_Id;
+ Spec_N : Entity_Id;
+
+ procedure Replace_Types (To_Corresponding : Boolean);
+ -- Depending on the flag, replace the type of formal parameters of
+ -- Body_Id if it is a concurrent type implementing interfaces with
+ -- the corresponding record type or the other way around.
+
+ procedure Replace_Types (To_Corresponding : Boolean) is
+ Formal : Entity_Id;
+ Formal_Typ : Entity_Id;
+
+ begin
+ Formal := First_Formal (Body_Id);
+ while Present (Formal) loop
+ Formal_Typ := Etype (Formal);
+
+ -- From concurrent type to corresponding record
+
+ if To_Corresponding then
+ if Is_Concurrent_Type (Formal_Typ)
+ and then Present (Corresponding_Record_Type (Formal_Typ))
+ and then Present (Interfaces (
+ Corresponding_Record_Type (Formal_Typ)))
+ then
+ Set_Etype (Formal,
+ Corresponding_Record_Type (Formal_Typ));
+ end if;
+
+ -- From corresponding record to concurrent type
+
+ else
+ if Is_Concurrent_Record_Type (Formal_Typ)
+ and then Present (Interfaces (Formal_Typ))
+ then
+ Set_Etype (Formal,
+ Corresponding_Concurrent_Type (Formal_Typ));
+ end if;
+ end if;
+
+ Next_Formal (Formal);
+ end loop;
+ end Replace_Types;
+
+ -- Start of processing for Disambiguate_Spec
+
+ begin
+ -- Try to retrieve the specification of the body as is. All error
+ -- messages are suppressed because the body may not have a spec in
+ -- its current state.
+
+ Spec_N := Find_Corresponding_Spec (N, False);
+
+ -- It is possible that this is the body of a primitive declared
+ -- between a private and a full view of a concurrent type. The
+ -- controlling parameter of the spec carries the concurrent type,
+ -- not the corresponding record type as transformed by Analyze_
+ -- Subprogram_Specification. In such cases, we undo the change
+ -- made by the analysis of the specification and try to find the
+ -- spec again.
+
+ if No (Spec_N) then
+
+ -- Restore all references of corresponding record types to the
+ -- original concurrent types.
+
+ Replace_Types (To_Corresponding => False);
+ Priv_Spec := Find_Corresponding_Spec (N, False);
+
+ -- The current body truly belongs to a primitive declared between
+ -- a private and a full view. We leave the modified body as is,
+ -- and return the true spec.
+
+ if Present (Priv_Spec)
+ and then Is_Private_Primitive (Priv_Spec)
+ then
+ return Priv_Spec;
+ end if;
+
+ -- In case that this is some sort of error, restore the original
+ -- state of the body.
+
+ Replace_Types (To_Corresponding => True);
+ end if;
+
+ return Spec_N;
+ end Disambiguate_Spec;
+
+ -------------------------------------
+ -- Is_Private_Concurrent_Primitive --
+ -------------------------------------
+
+ function Is_Private_Concurrent_Primitive
+ (Subp_Id : Entity_Id) return Boolean
+ is
+ Formal_Typ : Entity_Id;
+
+ begin
+ if Present (First_Formal (Subp_Id)) then
+ Formal_Typ := Etype (First_Formal (Subp_Id));
+
+ if Is_Concurrent_Record_Type (Formal_Typ) then
+ Formal_Typ := Corresponding_Concurrent_Type (Formal_Typ);
+ end if;
+
+ -- The type of the first formal is a concurrent tagged type with
+ -- a private view.
+
+ return
+ Is_Concurrent_Type (Formal_Typ)
+ and then Is_Tagged_Type (Formal_Typ)
+ and then Has_Private_Declaration (Formal_Typ);
+ end if;
+
+ return False;
+ end Is_Private_Concurrent_Primitive;
+
----------------------------
-- Set_Trivial_Subprogram --
----------------------------
@@ -1581,7 +1714,11 @@ package body Sem_Ch6 is
if Nkind (N) = N_Subprogram_Body_Stub
or else No (Corresponding_Spec (N))
then
- Spec_Id := Find_Corresponding_Spec (N);
+ if Is_Private_Concurrent_Primitive (Body_Id) then
+ Spec_Id := Disambiguate_Spec;
+ else
+ Spec_Id := Find_Corresponding_Spec (N);
+ end if;
-- If this is a duplicate body, no point in analyzing it
@@ -2322,6 +2459,22 @@ package body Sem_Ch6 is
New_Overloaded_Entity (Designator);
Check_Delayed_Subprogram (Designator);
+ -- If the type of the first formal of the current subprogram is a non
+ -- generic tagged private type , mark the subprogram as being a private
+ -- primitive.
+
+ if Present (First_Formal (Designator)) then
+ declare
+ Formal_Typ : constant Entity_Id :=
+ Etype (First_Formal (Designator));
+ begin
+ Set_Is_Private_Primitive (Designator,
+ Is_Tagged_Type (Formal_Typ)
+ and then Is_Private_Type (Formal_Typ)
+ and then not Is_Generic_Actual_Type (Formal_Typ));
+ end;
+ end if;
+
-- Ada 2005 (AI-251): Abstract interface primitives must be abstract
-- or null.
@@ -2435,8 +2588,6 @@ package body Sem_Ch6 is
function Analyze_Subprogram_Specification (N : Node_Id) return Entity_Id is
Designator : constant Entity_Id := Defining_Entity (N);
Formals : constant List_Id := Parameter_Specifications (N);
- Formal : Entity_Id;
- Formal_Typ : Entity_Id;
-- Start of processing for Analyze_Subprogram_Specification
@@ -2466,21 +2617,29 @@ package body Sem_Ch6 is
-- record, to match the proper signature of an overriding operation.
if Ada_Version >= Ada_05 then
- Formal := First_Formal (Designator);
- while Present (Formal) loop
- Formal_Typ := Etype (Formal);
+ declare
+ Formal : Entity_Id;
+ Formal_Typ : Entity_Id;
+ Rec_Typ : Entity_Id;
- if Is_Concurrent_Type (Formal_Typ)
- and then Present (Corresponding_Record_Type (Formal_Typ))
- and then Present (Interfaces
- (Corresponding_Record_Type (Formal_Typ)))
- then
- Set_Etype (Formal,
- Corresponding_Record_Type (Formal_Typ));
- end if;
+ begin
+ Formal := First_Formal (Designator);
+ while Present (Formal) loop
+ Formal_Typ := Etype (Formal);
- Formal := Next_Formal (Formal);
- end loop;
+ if Is_Concurrent_Type (Formal_Typ)
+ and then Present (Corresponding_Record_Type (Formal_Typ))
+ then
+ Rec_Typ := Corresponding_Record_Type (Formal_Typ);
+
+ if Present (Interfaces (Rec_Typ)) then
+ Set_Etype (Formal, Rec_Typ);
+ end if;
+ end if;
+
+ Next_Formal (Formal);
+ end loop;
+ end;
end if;
End_Scope;
@@ -5161,7 +5320,10 @@ package body Sem_Ch6 is
-- Find_Corresponding_Spec --
-----------------------------
- function Find_Corresponding_Spec (N : Node_Id) return Entity_Id is
+ function Find_Corresponding_Spec
+ (N : Node_Id;
+ Post_Error : Boolean := True) return Entity_Id
+ is
Spec : constant Node_Id := Specification (N);
Designator : constant Entity_Id := Defining_Entity (Spec);
@@ -5205,7 +5367,6 @@ package body Sem_Ch6 is
end if;
if not Has_Completion (E) then
-
if Nkind (N) /= N_Subprogram_Body_Stub then
Set_Corresponding_Spec (N, E);
end if;
@@ -5250,14 +5411,15 @@ package body Sem_Ch6 is
return Empty;
end if;
- -- If body already exists, this is an error unless the
- -- previous declaration is the implicit declaration of
- -- a derived subprogram, or this is a spurious overloading
- -- in an instance.
+ -- If the body already exists, then this is an error unless
+ -- the previous declaration is the implicit declaration of a
+ -- derived subprogram, or this is a spurious overloading in an
+ -- instance.
elsif No (Alias (E))
and then not Is_Intrinsic_Subprogram (E)
and then not In_Instance
+ and then Post_Error
then
Error_Msg_Sloc := Sloc (E);
if Is_Imported (E) then
@@ -5269,16 +5431,17 @@ package body Sem_Ch6 is
end if;
end if;
+ -- Child units cannot be overloaded, so a conformance mismatch
+ -- between body and a previous spec is an error.
+
elsif Is_Child_Unit (E)
and then
Nkind (Unit_Declaration_Node (Designator)) = N_Subprogram_Body
and then
Nkind (Parent (Unit_Declaration_Node (Designator))) =
- N_Compilation_Unit
+ N_Compilation_Unit
+ and then Post_Error
then
- -- Child units cannot be overloaded, so a conformance mismatch
- -- between body and a previous spec is an error.
-
Error_Msg_N
("body of child unit does not match previous declaration", N);
end if;
diff --git a/gcc/ada/sem_ch6.ads b/gcc/ada/sem_ch6.ads
index 689ac8b690a..e54c1e1117c 100644
--- a/gcc/ada/sem_ch6.ads
+++ b/gcc/ada/sem_ch6.ads
@@ -136,8 +136,8 @@ package Sem_Ch6 is
Get_Inst : Boolean := False) return Boolean;
-- Check that the types of two formal parameters are conforming. In most
-- cases this is just a name comparison, but within an instance it involves
- -- generic actual types, and in the presence of anonymous access types
- -- it must examine the designated types.
+ -- generic actual types, and in the presence of anonymous access types it
+ -- must examine the designated types.
procedure Create_Extra_Formals (E : Entity_Id);
-- For each parameter of a subprogram or entry that requires an additional
@@ -147,7 +147,9 @@ package Sem_Ch6 is
-- the end of Subp's parameter list (with each subsequent extra formal
-- being attached to the preceding extra formal).
- function Find_Corresponding_Spec (N : Node_Id) return Entity_Id;
+ function Find_Corresponding_Spec
+ (N : Node_Id;
+ Post_Error : Boolean := True) return Entity_Id;
-- Use the subprogram specification in the body to retrieve the previous
-- subprogram declaration, if any.
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index c5edce6d085..16c79d99f04 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -1578,25 +1578,45 @@ package body Sem_Ch8 is
-- an abstract formal subprogram must be dispatching
-- operation).
- case Attribute_Name (Nam) is
- when Name_Input =>
- Stream_Prim :=
- Find_Prim_Op (Prefix_Type, TSS_Stream_Input);
- when Name_Output =>
- Stream_Prim :=
- Find_Prim_Op (Prefix_Type, TSS_Stream_Output);
- when Name_Read =>
- Stream_Prim :=
- Find_Prim_Op (Prefix_Type, TSS_Stream_Read);
- when Name_Write =>
- Stream_Prim :=
- Find_Prim_Op (Prefix_Type, TSS_Stream_Write);
- when others =>
- Error_Msg_N
- ("attribute must be a primitive dispatching operation",
- Nam);
- return;
- end case;
+ begin
+ case Attribute_Name (Nam) is
+ when Name_Input =>
+ Stream_Prim :=
+ Find_Prim_Op (Prefix_Type, TSS_Stream_Input);
+ when Name_Output =>
+ Stream_Prim :=
+ Find_Prim_Op (Prefix_Type, TSS_Stream_Output);
+ when Name_Read =>
+ Stream_Prim :=
+ Find_Prim_Op (Prefix_Type, TSS_Stream_Read);
+ when Name_Write =>
+ Stream_Prim :=
+ Find_Prim_Op (Prefix_Type, TSS_Stream_Write);
+ when others =>
+ Error_Msg_N
+ ("attribute must be a primitive"
+ & " dispatching operation", Nam);
+ return;
+ end case;
+
+ exception
+
+ -- If no operation was found, and the type is limited,
+ -- the user should have defined one.
+
+ when Program_Error =>
+ if Is_Limited_Type (Prefix_Type) then
+ Error_Msg_NE
+ ("stream operation not defined for type&",
+ N, Prefix_Type);
+ return;
+
+ -- Otherwise, compiler should have generated default
+
+ else
+ raise;
+ end if;
+ end;
-- Rewrite the attribute into the name of its corresponding
-- primitive dispatching subprogram. We can then proceed with
diff --git a/gcc/ada/uintp.adb b/gcc/ada/uintp.adb
index 416d5d88681..b1f05993608 100644
--- a/gcc/ada/uintp.adb
+++ b/gcc/ada/uintp.adb
@@ -1832,7 +1832,7 @@ package body Uintp is
Den1 := V_Hat + C;
Den2 := V_Hat + D;
- exit when (Den1 * Den2) = Int_0;
+ exit when Den1 = Int_0 or else Den2 = Int_0;
-- Compute Q, the trial quotient
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 288ad59717e..ca551915c50 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -743,7 +743,7 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
{
/* Now restore our arg pointer from the address at which it
was saved in our stack frame. */
- emit_move_insn (virtual_incoming_args_rtx,
+ emit_move_insn (crtl->args.internal_arg_pointer,
copy_to_reg (get_arg_pointer_save_area ()));
}
}
@@ -778,6 +778,11 @@ expand_builtin_longjmp (rtx buf_addr, rtx value)
rtx fp, lab, stack, insn, last;
enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
+ /* DRAP is needed for stack realign if longjmp is expanded to current
+ function */
+ if (SUPPORTS_STACK_ALIGNMENT)
+ crtl->need_drap = true;
+
if (setjmp_alias_set == -1)
setjmp_alias_set = new_alias_set ();
@@ -1345,7 +1350,7 @@ expand_builtin_apply_args_1 (void)
}
/* Save the arg pointer to the block. */
- tem = copy_to_reg (virtual_incoming_args_rtx);
+ tem = copy_to_reg (crtl->args.internal_arg_pointer);
#ifdef STACK_GROWS_DOWNWARD
/* We need the pointer as the caller actually passed them to us, not
as we might have pretended they were passed. Make sure it's a valid
@@ -1453,6 +1458,14 @@ expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
/* Allocate a block of memory onto the stack and copy the memory
arguments to the outgoing arguments address. */
allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
+
+ /* Set DRAP flag to true, even though allocate_dynamic_stack_space
+ may have already set current_function_calls_alloca to true.
+ current_function_calls_alloca won't be set if argsize is zero,
+ so we have to guarantee need_drap is true here. */
+ if (SUPPORTS_STACK_ALIGNMENT)
+ crtl->need_drap = true;
+
dest = virtual_outgoing_args_rtx;
#ifndef STACK_GROWS_DOWNWARD
if (GET_CODE (argsize) == CONST_INT)
@@ -4785,11 +4798,11 @@ std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
/* When we align parameter on stack for caller, if the parameter
- alignment is beyond PREFERRED_STACK_BOUNDARY, it will be
- aligned at PREFERRED_STACK_BOUNDARY. We will match callee
+ alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
+ aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
here with caller. */
- if (boundary > PREFERRED_STACK_BOUNDARY)
- boundary = PREFERRED_STACK_BOUNDARY;
+ if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
+ boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
boundary /= BITS_PER_UNIT;
diff --git a/gcc/caller-save.c b/gcc/caller-save.c
index 233caca74f2..e3d76c654be 100644
--- a/gcc/caller-save.c
+++ b/gcc/caller-save.c
@@ -356,10 +356,16 @@ setup_save_areas (void)
if (! do_save)
continue;
- /* We have found an acceptable mode to store in. */
+ /* We have found an acceptable mode to store in. Since hard
+ register is always saved in the widest mode available,
+ the mode may be wider than necessary, it is OK to reduce
+ the alignment of spill space. We will verify that it is
+ equal to or greater than required when we restore and save
+ the hard register in insert_restore and insert_save. */
regno_save_mem[i][j]
- = assign_stack_local (regno_save_mode[i][j],
- GET_MODE_SIZE (regno_save_mode[i][j]), 0);
+ = assign_stack_local_1 (regno_save_mode[i][j],
+ GET_MODE_SIZE (regno_save_mode[i][j]),
+ 0, true);
/* Setup single word save area just in case... */
for (k = 0; k < j; k++)
diff --git a/gcc/calls.c b/gcc/calls.c
index 71bdf8c003b..d48c0d15654 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -415,6 +415,10 @@ emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED,
rounded_stack_size -= n_popped;
rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
stack_pointer_delta -= n_popped;
+
+ /* If popup is needed, stack realign must use DRAP */
+ if (SUPPORTS_STACK_ALIGNMENT)
+ crtl->need_drap = true;
}
if (!ACCUMULATE_OUTGOING_ARGS)
@@ -2405,7 +2409,7 @@ expand_call (tree exp, rtx target, int ignore)
incoming argument block. */
if (pass == 0)
{
- argblock = virtual_incoming_args_rtx;
+ argblock = crtl->args.internal_arg_pointer;
argblock
#ifdef STACK_GROWS_DOWNWARD
= plus_constant (argblock, crtl->args.pretend_args_size);
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 6040b4460c2..623ad85afb4 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -499,10 +499,25 @@ get_decl_align_unit (tree decl)
align = DECL_ALIGN (decl);
align = LOCAL_ALIGNMENT (TREE_TYPE (decl), align);
- if (align > PREFERRED_STACK_BOUNDARY)
- align = PREFERRED_STACK_BOUNDARY;
+
+ if (align > MAX_SUPPORTED_STACK_ALIGNMENT)
+ align = MAX_SUPPORTED_STACK_ALIGNMENT;
+
+ if (SUPPORTS_STACK_ALIGNMENT)
+ {
+ if (crtl->stack_alignment_estimated < align)
+ {
+ gcc_assert(!crtl->stack_realign_processed);
+ crtl->stack_alignment_estimated = align;
+ }
+ }
+
+ /* stack_alignment_needed > PREFERRED_STACK_BOUNDARY is permitted.
+ So here we only make sure stack_alignment_needed >= align. */
if (crtl->stack_alignment_needed < align)
crtl->stack_alignment_needed = align;
+ if (crtl->max_used_stack_slot_alignment < crtl->stack_alignment_needed)
+ crtl->max_used_stack_slot_alignment = crtl->stack_alignment_needed;
return align / BITS_PER_UNIT;
}
@@ -1059,6 +1074,31 @@ defer_stack_allocation (tree var, bool toplevel)
static HOST_WIDE_INT
expand_one_var (tree var, bool toplevel, bool really_expand)
{
+ if (SUPPORTS_STACK_ALIGNMENT
+ && TREE_TYPE (var) != error_mark_node
+ && TREE_CODE (var) == VAR_DECL)
+ {
+ unsigned int align;
+
+ /* Because we don't know if VAR will be in register or on stack,
+ we conservatively assume it will be on stack even if VAR is
+ eventually put into register after RA pass. For non-automatic
+ variables, which won't be on stack, we collect alignment of
+ type and ignore user specified alignment. */
+ if (TREE_STATIC (var) || DECL_EXTERNAL (var))
+ align = TYPE_ALIGN (TREE_TYPE (var));
+ else
+ align = DECL_ALIGN (var);
+
+ if (crtl->stack_alignment_estimated < align)
+ {
+ /* stack_alignment_estimated shouldn't change after stack
+ realign decision made */
+ gcc_assert(!crtl->stack_realign_processed);
+ crtl->stack_alignment_estimated = align;
+ }
+ }
+
if (TREE_CODE (var) != VAR_DECL)
;
else if (DECL_EXTERNAL (var))
@@ -2136,6 +2176,66 @@ discover_nonconstant_array_refs (void)
}
}
+/* This function sets crtl->args.internal_arg_pointer to a virtual
+ register if DRAP is needed. Local register allocator will replace
+ virtual_incoming_args_rtx with the virtual register. */
+
+static void
+expand_stack_alignment (void)
+{
+ rtx drap_rtx;
+ unsigned int preferred_stack_boundary;
+
+ if (! SUPPORTS_STACK_ALIGNMENT)
+ return;
+
+ if (cfun->calls_alloca
+ || cfun->has_nonlocal_label
+ || crtl->has_nonlocal_goto)
+ crtl->need_drap = true;
+
+ gcc_assert (crtl->stack_alignment_needed
+ <= crtl->stack_alignment_estimated);
+
+ /* Update stack boundary if needed. */
+ if (targetm.calls.update_stack_boundary)
+ targetm.calls.update_stack_boundary ();
+
+ /* Update crtl->stack_alignment_estimated and use it later to align
+ stack. We check PREFERRED_STACK_BOUNDARY if there may be non-call
+ exceptions since callgraph doesn't collect incoming stack alignment
+ in this case. */
+ if (flag_non_call_exceptions
+ && PREFERRED_STACK_BOUNDARY > crtl->preferred_stack_boundary)
+ preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
+ else
+ preferred_stack_boundary = crtl->preferred_stack_boundary;
+ if (preferred_stack_boundary > crtl->stack_alignment_estimated)
+ crtl->stack_alignment_estimated = preferred_stack_boundary;
+ if (preferred_stack_boundary > crtl->stack_alignment_needed)
+ crtl->stack_alignment_needed = preferred_stack_boundary;
+
+ crtl->stack_realign_needed
+ = INCOMING_STACK_BOUNDARY < crtl->stack_alignment_estimated;
+
+ crtl->stack_realign_processed = true;
+
+ /* Target has to redefine TARGET_GET_DRAP_RTX to support stack
+ alignment. */
+ gcc_assert (targetm.calls.get_drap_rtx != NULL);
+ drap_rtx = targetm.calls.get_drap_rtx ();
+
+ /* Do nothing if NULL is returned, which means DRAP is not needed. */
+ if (NULL != drap_rtx)
+ {
+ crtl->args.internal_arg_pointer = drap_rtx;
+
+ /* Call fixup_tail_calls to clean up REG_EQUIV note if DRAP is
+ needed. */
+ fixup_tail_calls ();
+ }
+}
+
/* Translate the intermediate representation contained in the CFG
from GIMPLE trees to RTL.
@@ -2174,6 +2274,8 @@ gimple_expand_cfg (void)
targetm.expand_to_rtl_hook ();
crtl->stack_alignment_needed = STACK_BOUNDARY;
+ crtl->max_used_stack_slot_alignment = STACK_BOUNDARY;
+ crtl->stack_alignment_estimated = STACK_BOUNDARY;
crtl->preferred_stack_boundary = STACK_BOUNDARY;
cfun->cfg->max_jumptable_ents = 0;
@@ -2248,6 +2350,9 @@ gimple_expand_cfg (void)
sbitmap_free (blocks);
compact_blocks ();
+
+ expand_stack_alignment ();
+
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index dfee7c3740e..a89229ec12a 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -62,6 +62,7 @@ const struct attribute_spec arm_attribute_table[];
void (*arm_lang_output_object_attributes_hook)(void);
/* Forward function declarations. */
+static int arm_compute_static_chain_stack_bytes (void);
static arm_stack_offsets *arm_get_frame_offsets (void);
static void arm_add_gc_roots (void);
static int arm_gen_constant (enum rtx_code, enum machine_mode, rtx,
@@ -10792,6 +10793,24 @@ arm_compute_save_reg0_reg12_mask (void)
}
+/* Compute the number of bytes used to store the static chain register on the
+ stack, above the stack frame. We need to know this accurately to get the
+ alignment of the rest of the stack frame correct. */
+
+static int arm_compute_static_chain_stack_bytes (void)
+{
+ unsigned long func_type = arm_current_func_type ();
+ int static_chain_stack_bytes = 0;
+
+ if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM &&
+ IS_NESTED (func_type) &&
+ df_regs_ever_live_p (3) && crtl->args.pretend_args_size == 0)
+ static_chain_stack_bytes = 4;
+
+ return static_chain_stack_bytes;
+}
+
+
/* Compute a bit mask of which registers need to be
saved on the stack for the current function.
This is used by arm_get_frame_offsets, which may add extra registers. */
@@ -10844,7 +10863,9 @@ arm_compute_save_reg_mask (void)
if (TARGET_REALLY_IWMMXT
&& ((bit_count (save_reg_mask)
- + ARM_NUM_INTS (crtl->args.pretend_args_size)) % 2) != 0)
+ + ARM_NUM_INTS (crtl->args.pretend_args_size +
+ arm_compute_static_chain_stack_bytes())
+ ) % 2) != 0)
{
/* The total number of registers that are going to be pushed
onto the stack is odd. We need to ensure that the stack
@@ -10929,6 +10950,26 @@ thumb1_compute_save_reg_mask (void)
mask |= 1 << reg;
}
+ /* The 504 below is 8 bytes less than 512 because there are two possible
+ alignment words. We can't tell here if they will be present or not so we
+ have to play it safe and assume that they are. */
+ if ((CALLER_INTERWORKING_SLOT_SIZE +
+ ROUND_UP_WORD (get_frame_size ()) +
+ crtl->outgoing_args_size) >= 504)
+ {
+ /* This is the same as the code in thumb1_expand_prologue() which
+ determines which register to use for stack decrement. */
+ for (reg = LAST_ARG_REGNUM + 1; reg <= LAST_LO_REGNUM; reg++)
+ if (mask & (1 << reg))
+ break;
+
+ if (reg > LAST_LO_REGNUM)
+ {
+ /* Make sure we have a register available for stack decrement. */
+ mask |= 1 << LAST_LO_REGNUM;
+ }
+ }
+
return mask;
}
@@ -12064,7 +12105,8 @@ arm_get_frame_offsets (void)
offsets->saved_args = crtl->args.pretend_args_size;
/* In Thumb mode this is incorrect, but never used. */
- offsets->frame = offsets->saved_args + (frame_pointer_needed ? 4 : 0);
+ offsets->frame = offsets->saved_args + (frame_pointer_needed ? 4 : 0) +
+ arm_compute_static_chain_stack_bytes();
if (TARGET_32BIT)
{
@@ -12111,7 +12153,8 @@ arm_get_frame_offsets (void)
}
/* Saved registers include the stack frame. */
- offsets->saved_regs = offsets->saved_args + saved;
+ offsets->saved_regs = offsets->saved_args + saved +
+ arm_compute_static_chain_stack_bytes();
offsets->soft_frame = offsets->saved_regs + CALLER_INTERWORKING_SLOT_SIZE;
/* A leaf function does not need any stack alignment if it has nothing
on the stack. */
@@ -12203,14 +12246,9 @@ arm_compute_initial_elimination_offset (unsigned int from, unsigned int to)
return offsets->soft_frame - offsets->saved_args;
case ARM_HARD_FRAME_POINTER_REGNUM:
- /* If there is no stack frame then the hard
- frame pointer and the arg pointer coincide. */
- if (offsets->frame == offsets->saved_regs)
- return 0;
- /* FIXME: Not sure about this. Maybe we should always return 0 ? */
- return (frame_pointer_needed
- && cfun->static_chain_decl != NULL
- && ! cfun->machine->uses_anonymous_args) ? 4 : 0;
+ /* This is only non-zero in the case where the static chain register
+ is stored above the frame. */
+ return offsets->frame - offsets->saved_args - 4;
case STACK_POINTER_REGNUM:
/* If nothing has been pushed on the stack at all
@@ -12438,7 +12476,9 @@ arm_expand_prologue (void)
r0 = gen_rtx_REG (SImode, 0);
r1 = gen_rtx_REG (SImode, 1);
- dwarf = gen_rtx_UNSPEC (SImode, NULL_RTVEC, UNSPEC_STACK_ALIGN);
+ /* Use a real rtvec rather than NULL_RTVEC so the rest of the
+ compiler won't choke. */
+ dwarf = gen_rtx_UNSPEC (SImode, rtvec_alloc (0), UNSPEC_STACK_ALIGN);
dwarf = gen_rtx_SET (VOIDmode, r0, dwarf);
insn = gen_movsi (r0, stack_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
@@ -12496,6 +12536,9 @@ arm_expand_prologue (void)
insn = emit_set_insn (gen_rtx_REG (SImode, 3), ip_rtx);
else if (args_to_push == 0)
{
+ gcc_assert(arm_compute_static_chain_stack_bytes() == 4);
+ saved_regs += 4;
+
rtx dwarf;
insn = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx);
@@ -17006,62 +17049,25 @@ thumb1_expand_prologue (void)
been pushed at the start of the prologue and so we can corrupt
it now. */
for (regno = LAST_ARG_REGNUM + 1; regno <= LAST_LO_REGNUM; regno++)
- if (live_regs_mask & (1 << regno)
- && !(frame_pointer_needed
- && (regno == THUMB_HARD_FRAME_POINTER_REGNUM)))
+ if (live_regs_mask & (1 << regno))
break;
- if (regno > LAST_LO_REGNUM) /* Very unlikely. */
- {
- rtx spare = gen_rtx_REG (SImode, IP_REGNUM);
-
- /* Choose an arbitrary, non-argument low register. */
- reg = gen_rtx_REG (SImode, LAST_LO_REGNUM);
-
- /* Save it by copying it into a high, scratch register. */
- emit_insn (gen_movsi (spare, reg));
- /* Add a USE to stop propagate_one_insn() from barfing. */
- emit_insn (gen_prologue_use (spare));
+ gcc_assert(regno <= LAST_LO_REGNUM);
- /* Decrement the stack. */
- emit_insn (gen_movsi (reg, GEN_INT (- amount)));
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx, reg));
- RTX_FRAME_RELATED_P (insn) = 1;
- dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (stack_pointer_rtx,
- -amount));
- RTX_FRAME_RELATED_P (dwarf) = 1;
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
- REG_NOTES (insn));
-
- /* Restore the low register's original value. */
- emit_insn (gen_movsi (reg, spare));
-
- /* Emit a USE of the restored scratch register, so that flow
- analysis will not consider the restore redundant. The
- register won't be used again in this function and isn't
- restored by the epilogue. */
- emit_insn (gen_prologue_use (reg));
- }
- else
- {
- reg = gen_rtx_REG (SImode, regno);
+ reg = gen_rtx_REG (SImode, regno);
- emit_insn (gen_movsi (reg, GEN_INT (- amount)));
+ emit_insn (gen_movsi (reg, GEN_INT (- amount)));
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx, reg));
- RTX_FRAME_RELATED_P (insn) = 1;
- dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (stack_pointer_rtx,
- -amount));
- RTX_FRAME_RELATED_P (dwarf) = 1;
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
- REG_NOTES (insn));
- }
+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx, reg));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx,
+ -amount));
+ RTX_FRAME_RELATED_P (dwarf) = 1;
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
+ REG_NOTES (insn));
}
}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 3ebfd3cd9a9..3276bd8e202 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -28,6 +28,7 @@ extern int ix86_frame_pointer_required (void);
extern void ix86_setup_frame_addresses (void);
extern void ix86_file_end (void);
+extern int ix86_can_eliminate (int, int);
extern HOST_WIDE_INT ix86_initial_elimination_offset (int, int);
extern void ix86_expand_prologue (void);
extern void ix86_expand_epilogue (int);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index dc3854ba53f..46505cc4804 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1708,7 +1708,8 @@ static int ix86_regparm;
/* -mstackrealign option */
extern int ix86_force_align_arg_pointer;
-static const char ix86_force_align_arg_pointer_string[] = "force_align_arg_pointer";
+static const char ix86_force_align_arg_pointer_string[]
+ = "force_align_arg_pointer";
static rtx (*ix86_gen_leave) (void);
static rtx (*ix86_gen_pop1) (rtx);
@@ -1717,10 +1718,21 @@ static rtx (*ix86_gen_sub3) (rtx, rtx, rtx);
static rtx (*ix86_gen_sub3_carry) (rtx, rtx, rtx, rtx);
static rtx (*ix86_gen_one_cmpl2) (rtx, rtx);
static rtx (*ix86_gen_monitor) (rtx, rtx, rtx);
+static rtx (*ix86_gen_andsp) (rtx, rtx, rtx);
/* Preferred alignment for stack boundary in bits. */
unsigned int ix86_preferred_stack_boundary;
+/* Alignment for incoming stack boundary in bits specified at
+ command line. */
+static unsigned int ix86_user_incoming_stack_boundary;
+
+/* Default alignment for incoming stack boundary in bits. */
+static unsigned int ix86_default_incoming_stack_boundary;
+
+/* Alignment for incoming stack boundary in bits. */
+unsigned int ix86_incoming_stack_boundary;
+
/* Values 1-5: see jump.c */
int ix86_branch_cost;
@@ -3015,11 +3027,9 @@ override_options (bool main_args_p)
if (TARGET_SSE4_2 || TARGET_ABM)
ix86_isa_flags |= OPTION_MASK_ISA_POPCNT & ~ix86_isa_flags_explicit;
- /* Validate -mpreferred-stack-boundary= value, or provide default.
- The default of 128 bits is for Pentium III's SSE __m128. We can't
- change it because of optimize_size. Otherwise, we can't mix object
- files compiled with -Os and -On. */
- ix86_preferred_stack_boundary = 128;
+ /* Validate -mpreferred-stack-boundary= value or default it to
+ PREFERRED_STACK_BOUNDARY_DEFAULT. */
+ ix86_preferred_stack_boundary = PREFERRED_STACK_BOUNDARY_DEFAULT;
if (ix86_preferred_stack_boundary_string)
{
i = atoi (ix86_preferred_stack_boundary_string);
@@ -3030,6 +3040,31 @@ override_options (bool main_args_p)
ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
}
+ /* Set the default value for -mstackrealign. */
+ if (ix86_force_align_arg_pointer == -1)
+ ix86_force_align_arg_pointer = STACK_REALIGN_DEFAULT;
+
+ /* Validate -mincoming-stack-boundary= value or default it to
+ ABI_STACK_BOUNDARY/PREFERRED_STACK_BOUNDARY. */
+ if (ix86_force_align_arg_pointer)
+ ix86_default_incoming_stack_boundary = ABI_STACK_BOUNDARY;
+ else
+ ix86_default_incoming_stack_boundary = PREFERRED_STACK_BOUNDARY;
+ ix86_incoming_stack_boundary = ix86_default_incoming_stack_boundary;
+ if (ix86_incoming_stack_boundary_string)
+ {
+ i = atoi (ix86_incoming_stack_boundary_string);
+ if (i < (TARGET_64BIT ? 4 : 2) || i > 12)
+ error ("-mincoming-stack-boundary=%d is not between %d and 12",
+ i, TARGET_64BIT ? 4 : 2);
+ else
+ {
+ ix86_user_incoming_stack_boundary = (1 << i) * BITS_PER_UNIT;
+ ix86_incoming_stack_boundary
+ = ix86_user_incoming_stack_boundary;
+ }
+ }
+
/* Accept -msseregparm only if at least SSE support is enabled. */
if (TARGET_SSEREGPARM
&& ! TARGET_SSE)
@@ -3162,6 +3197,7 @@ override_options (bool main_args_p)
ix86_gen_sub3_carry = gen_subdi3_carry_rex64;
ix86_gen_one_cmpl2 = gen_one_cmpldi2;
ix86_gen_monitor = gen_sse3_monitor64;
+ ix86_gen_andsp = gen_anddi3;
}
else
{
@@ -3172,6 +3208,7 @@ override_options (bool main_args_p)
ix86_gen_sub3_carry = gen_subsi3_carry;
ix86_gen_one_cmpl2 = gen_one_cmplsi2;
ix86_gen_monitor = gen_sse3_monitor;
+ ix86_gen_andsp = gen_andsi3;
}
#ifdef USE_IX86_CLD
@@ -4002,11 +4039,6 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
&& ix86_function_regparm (TREE_TYPE (decl), NULL) >= 3)
return false;
- /* If we forced aligned the stack, then sibcalling would unalign the
- stack, which may break the called function. */
- if (cfun->machine->force_align_arg_pointer)
- return false;
-
/* Otherwise okay. That also includes certain types of indirect calls. */
return true;
}
@@ -4057,15 +4089,6 @@ ix86_handle_cconv_attribute (tree *node, tree name,
*no_add_attrs = true;
}
- if (!TARGET_64BIT
- && lookup_attribute (ix86_force_align_arg_pointer_string,
- TYPE_ATTRIBUTES (*node))
- && compare_tree_int (cst, REGPARM_MAX-1))
- {
- error ("%s functions limited to %d register parameters",
- ix86_force_align_arg_pointer_string, REGPARM_MAX-1);
- }
-
return NULL_TREE;
}
@@ -4227,8 +4250,7 @@ ix86_function_regparm (const_tree type, const_tree decl)
/* We can't use regparm(3) for nested functions as these use
static chain pointer in third argument. */
if (local_regparm == 3
- && (decl_function_context (decl)
- || ix86_force_align_arg_pointer)
+ && decl_function_context (decl)
&& !DECL_NO_STATIC_CHAIN (decl))
local_regparm = 2;
@@ -4237,13 +4259,11 @@ ix86_function_regparm (const_tree type, const_tree decl)
the callee DECL_STRUCT_FUNCTION is gone, so we fall back to
scanning the attributes for the self-realigning property. */
f = DECL_STRUCT_FUNCTION (decl);
- if (local_regparm == 3
- && (f ? !!f->machine->force_align_arg_pointer
- : !!lookup_attribute (ix86_force_align_arg_pointer_string,
- TYPE_ATTRIBUTES (TREE_TYPE (decl)))))
- local_regparm = 2;
+ /* Since current internal arg pointer won't conflict with
+ parameter passing regs, so no need to change stack
+ realignment and adjust regparm number.
- /* Each fixed register usage increases register pressure,
+ Each fixed register usage increases register pressure,
so less registers should be used for argument passing.
This functionality can be overriden by an explicit
regparm value. */
@@ -6154,14 +6174,6 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
/* Indicate to allocate space on the stack for varargs save area. */
ix86_save_varrargs_registers = 1;
- /* We need 16-byte stack alignment to save SSE registers. If user
- asked for lower preferred_stack_boundary, lets just hope that he knows
- what he is doing and won't varargs SSE values.
-
- We also may end up assuming that only 64bit values are stored in SSE
- register let some floating point program work. */
- if (ix86_preferred_stack_boundary >= BIGGEST_ALIGNMENT)
- crtl->stack_alignment_needed = BIGGEST_ALIGNMENT;
save_area = frame_pointer_rtx;
set = get_varargs_alias_set ();
@@ -6344,7 +6356,7 @@ ix86_va_start (tree valist, rtx nextarg)
/* Find the overflow area. */
type = TREE_TYPE (ovf);
- t = make_tree (type, virtual_incoming_args_rtx);
+ t = make_tree (type, crtl->args.internal_arg_pointer);
if (words != 0)
t = build2 (POINTER_PLUS_EXPR, type, t,
size_int (words * UNITS_PER_WORD));
@@ -6573,12 +6585,12 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
/* ... otherwise out of the overflow area. */
/* When we align parameter on stack for caller, if the parameter
- alignment is beyond PREFERRED_STACK_BOUNDARY, it will be
- aligned at PREFERRED_STACK_BOUNDARY. We will match callee
+ alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
+ aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
here with caller. */
arg_boundary = FUNCTION_ARG_BOUNDARY (VOIDmode, type);
- if ((unsigned int) arg_boundary > PREFERRED_STACK_BOUNDARY)
- arg_boundary = PREFERRED_STACK_BOUNDARY;
+ if ((unsigned int) arg_boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
+ arg_boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
/* Care for on-stack alignment if needed. */
if (arg_boundary <= 64
@@ -7101,9 +7113,14 @@ ix86_select_alt_pic_regnum (void)
if (current_function_is_leaf && !crtl->profile
&& !ix86_current_function_calls_tls_descriptor)
{
- int i;
+ int i, drap;
+ /* Can't use the same register for both PIC and DRAP. */
+ if (crtl->drap_reg)
+ drap = REGNO (crtl->drap_reg);
+ else
+ drap = -1;
for (i = 2; i >= 0; --i)
- if (!df_regs_ever_live_p (i))
+ if (i != drap && !df_regs_ever_live_p (i))
return i;
}
@@ -7139,8 +7156,8 @@ ix86_save_reg (unsigned int regno, int maybe_eh_return)
}
}
- if (cfun->machine->force_align_arg_pointer
- && regno == REGNO (cfun->machine->force_align_arg_pointer))
+ if (crtl->drap_reg
+ && regno == REGNO (crtl->drap_reg))
return 1;
return (df_regs_ever_live_p (regno)
@@ -7163,6 +7180,24 @@ ix86_nsaved_regs (void)
return nregs;
}
+/* Given FROM and TO register numbers, say whether this elimination is
+ allowed. If stack alignment is needed, we can only replace argument
+ pointer with hard frame pointer, or replace frame pointer with stack
+ pointer. Otherwise, frame pointer elimination is automatically
+ handled and all other eliminations are valid. */
+
+int
+ix86_can_eliminate (int from, int to)
+{
+ if (stack_realign_fp)
+ return ((from == ARG_POINTER_REGNUM
+ && to == HARD_FRAME_POINTER_REGNUM)
+ || (from == FRAME_POINTER_REGNUM
+ && to == STACK_POINTER_REGNUM));
+ else
+ return to == STACK_POINTER_REGNUM ? !frame_pointer_needed : 1;
+}
+
/* Return the offset between two registers, one to be eliminated, and the other
its replacement, at the start of a routine. */
@@ -7206,6 +7241,10 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
stack_alignment_needed = crtl->stack_alignment_needed / BITS_PER_UNIT;
preferred_alignment = crtl->preferred_stack_boundary / BITS_PER_UNIT;
+ gcc_assert (!size || stack_alignment_needed);
+ gcc_assert (preferred_alignment >= STACK_BOUNDARY / BITS_PER_UNIT);
+ gcc_assert (preferred_alignment <= stack_alignment_needed);
+
/* During reload iteration the amount of registers saved can change.
Recompute the value as needed. Do not recompute when amount of registers
didn't change as reload does multiple calls to the function and does not
@@ -7248,18 +7287,9 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
frame->hard_frame_pointer_offset = offset;
- /* Do some sanity checking of stack_alignment_needed and
- preferred_alignment, since i386 port is the only using those features
- that may break easily. */
-
- gcc_assert (!size || stack_alignment_needed);
- gcc_assert (preferred_alignment >= STACK_BOUNDARY / BITS_PER_UNIT);
- gcc_assert (preferred_alignment <= PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT);
- gcc_assert (stack_alignment_needed
- <= PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT);
-
- if (stack_alignment_needed < STACK_BOUNDARY / BITS_PER_UNIT)
- stack_alignment_needed = STACK_BOUNDARY / BITS_PER_UNIT;
+ /* Set offset to aligned because the realigned frame tarts from here. */
+ if (stack_realign_fp)
+ offset = (offset + stack_alignment_needed -1) & -stack_alignment_needed;
/* Register save area */
offset += frame->nregs * UNITS_PER_WORD;
@@ -7425,38 +7455,131 @@ pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, int style)
RTX_FRAME_RELATED_P (insn) = 1;
}
-/* Handle the TARGET_INTERNAL_ARG_POINTER hook. */
+/* Find an available register to be used as dynamic realign argument
+ pointer regsiter. Such a register will be written in prologue and
+ used in begin of body, so it must not be
+ 1. parameter passing register.
+ 2. GOT pointer.
+ We reuse static-chain register if it is available. Otherwise, we
+ use DI for i386 and R13 for x86-64. We chose R13 since it has
+ shorter encoding.
+
+ Return: the regno of chosen register. */
+
+static unsigned int
+find_drap_reg (void)
+{
+ tree decl = cfun->decl;
+
+ if (TARGET_64BIT)
+ {
+ /* Use R13 for nested function or function need static chain.
+ Since function with tail call may use any caller-saved
+ registers in epilogue, DRAP must not use caller-saved
+ register in such case. */
+ if ((decl_function_context (decl)
+ && !DECL_NO_STATIC_CHAIN (decl))
+ || crtl->tail_call_emit)
+ return R13_REG;
+
+ return R10_REG;
+ }
+ else
+ {
+ /* Use DI for nested function or function need static chain.
+ Since function with tail call may use any caller-saved
+ registers in epilogue, DRAP must not use caller-saved
+ register in such case. */
+ if ((decl_function_context (decl)
+ && !DECL_NO_STATIC_CHAIN (decl))
+ || crtl->tail_call_emit)
+ return DI_REG;
+
+ /* Reuse static chain register if it isn't used for parameter
+ passing. */
+ if (ix86_function_regparm (TREE_TYPE (decl), decl) <= 2
+ && !lookup_attribute ("fastcall",
+ TYPE_ATTRIBUTES (TREE_TYPE (decl))))
+ return CX_REG;
+ else
+ return DI_REG;
+ }
+}
+
+/* Update incoming stack boundary and estimated stack alignment. */
+
+static void
+ix86_update_stack_boundary (void)
+{
+ /* Prefer the one specified at command line. */
+ ix86_incoming_stack_boundary
+ = (ix86_user_incoming_stack_boundary
+ ? ix86_user_incoming_stack_boundary
+ : ix86_default_incoming_stack_boundary);
+
+ /* Incoming stack alignment can be changed on individual functions
+ via force_align_arg_pointer attribute. We use the smallest
+ incoming stack boundary. */
+ if (ix86_incoming_stack_boundary > ABI_STACK_BOUNDARY
+ && lookup_attribute (ix86_force_align_arg_pointer_string,
+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
+ ix86_incoming_stack_boundary = ABI_STACK_BOUNDARY;
+
+ /* Stack at entrance of main is aligned by runtime. We use the
+ smallest incoming stack boundary. */
+ if (ix86_incoming_stack_boundary > MAIN_STACK_BOUNDARY
+ && DECL_NAME (current_function_decl)
+ && MAIN_NAME_P (DECL_NAME (current_function_decl))
+ && DECL_FILE_SCOPE_P (current_function_decl))
+ ix86_incoming_stack_boundary = MAIN_STACK_BOUNDARY;
+
+ /* x86_64 vararg needs 16byte stack alignment for register save
+ area. */
+ if (TARGET_64BIT
+ && cfun->stdarg
+ && crtl->stack_alignment_estimated < 128)
+ crtl->stack_alignment_estimated = 128;
+}
+
+/* Handle the TARGET_GET_DRAP_RTX hook. Return NULL if no DRAP is
+ needed or an rtx for DRAP otherwise. */
static rtx
-ix86_internal_arg_pointer (void)
+ix86_get_drap_rtx (void)
{
- bool has_force_align_arg_pointer =
- (0 != lookup_attribute (ix86_force_align_arg_pointer_string,
- TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))));
- if ((FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
- && DECL_NAME (current_function_decl)
- && MAIN_NAME_P (DECL_NAME (current_function_decl))
- && DECL_FILE_SCOPE_P (current_function_decl))
- || ix86_force_align_arg_pointer
- || has_force_align_arg_pointer)
- {
- /* Nested functions can't realign the stack due to a register
- conflict. */
- if (DECL_CONTEXT (current_function_decl)
- && TREE_CODE (DECL_CONTEXT (current_function_decl)) == FUNCTION_DECL)
- {
- if (ix86_force_align_arg_pointer)
- warning (0, "-mstackrealign ignored for nested functions");
- if (has_force_align_arg_pointer)
- error ("%s not supported for nested functions",
- ix86_force_align_arg_pointer_string);
- return virtual_incoming_args_rtx;
- }
- cfun->machine->force_align_arg_pointer = gen_rtx_REG (Pmode, CX_REG);
- return copy_to_reg (cfun->machine->force_align_arg_pointer);
+ if (ix86_force_drap || !ACCUMULATE_OUTGOING_ARGS)
+ crtl->need_drap = true;
+
+ if (stack_realign_drap)
+ {
+ /* Assign DRAP to vDRAP and returns vDRAP */
+ unsigned int regno = find_drap_reg ();
+ rtx drap_vreg;
+ rtx arg_ptr;
+ rtx seq, insn;
+
+ arg_ptr = gen_rtx_REG (Pmode, regno);
+ crtl->drap_reg = arg_ptr;
+
+ start_sequence ();
+ drap_vreg = copy_to_reg (arg_ptr);
+ seq = get_insns ();
+ end_sequence ();
+
+ insn = emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ return drap_vreg;
}
else
- return virtual_incoming_args_rtx;
+ return NULL;
+}
+
+/* Handle the TARGET_INTERNAL_ARG_POINTER hook. */
+
+static rtx
+ix86_internal_arg_pointer (void)
+{
+ return virtual_incoming_args_rtx;
}
/* Handle the TARGET_DWARF_HANDLE_FRAME_UNSPEC hook.
@@ -7483,6 +7606,31 @@ ix86_dwarf_handle_frame_unspec (const char *label, rtx pattern, int index)
}
}
+/* Finalize stack_realign_needed flag, which will guide prologue/epilogue
+ to be generated in correct form. */
+static void
+ix86_finalize_stack_realign_flags (void)
+{
+ /* Check if stack realign is really needed after reload, and
+ stores result in cfun */
+ unsigned int stack_realign = (ix86_incoming_stack_boundary
+ < (current_function_is_leaf
+ ? crtl->max_used_stack_slot_alignment
+ : crtl->stack_alignment_needed));
+
+ if (crtl->stack_realign_finalized)
+ {
+ /* After stack_realign_needed is finalized, we can't no longer
+ change it. */
+ gcc_assert (crtl->stack_realign_needed == stack_realign);
+ }
+ else
+ {
+ crtl->stack_realign_needed = stack_realign;
+ crtl->stack_realign_finalized = true;
+ }
+}
+
/* Expand the prologue into a bunch of separate insns. */
void
@@ -7493,52 +7641,58 @@ ix86_expand_prologue (void)
struct ix86_frame frame;
HOST_WIDE_INT allocate;
+ ix86_finalize_stack_realign_flags ();
+
+ /* DRAP should not coexist with stack_realign_fp */
+ gcc_assert (!(crtl->drap_reg && stack_realign_fp));
+
ix86_compute_frame_layout (&frame);
- if (cfun->machine->force_align_arg_pointer)
+ /* Emit prologue code to adjust stack alignment and setup DRAP, in case
+ of DRAP is needed and stack realignment is really needed after reload */
+ if (crtl->drap_reg && crtl->stack_realign_needed)
{
rtx x, y;
+ int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
+ int param_ptr_offset = (call_used_regs[REGNO (crtl->drap_reg)]
+ ? 0 : STACK_BOUNDARY / BITS_PER_UNIT);
+
+ gcc_assert (stack_realign_drap);
/* Grab the argument pointer. */
- x = plus_constant (stack_pointer_rtx, 4);
- y = cfun->machine->force_align_arg_pointer;
- insn = emit_insn (gen_rtx_SET (VOIDmode, y, x));
- RTX_FRAME_RELATED_P (insn) = 1;
+ x = plus_constant (stack_pointer_rtx,
+ (STACK_BOUNDARY / BITS_PER_UNIT
+ + param_ptr_offset));
+ y = crtl->drap_reg;
- /* The unwind info consists of two parts: install the fafp as the cfa,
- and record the fafp as the "save register" of the stack pointer.
- The later is there in order that the unwinder can see where it
- should restore the stack pointer across the and insn. */
- x = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx), UNSPEC_DEF_CFA);
- x = gen_rtx_SET (VOIDmode, y, x);
- RTX_FRAME_RELATED_P (x) = 1;
- y = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, stack_pointer_rtx),
- UNSPEC_REG_SAVE);
- y = gen_rtx_SET (VOIDmode, cfun->machine->force_align_arg_pointer, y);
- RTX_FRAME_RELATED_P (y) = 1;
- x = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, x, y));
- x = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, x, NULL);
- REG_NOTES (insn) = x;
+ /* Only need to push parameter pointer reg if it is caller
+ saved reg */
+ if (!call_used_regs[REGNO (crtl->drap_reg)])
+ {
+ /* Push arg pointer reg */
+ insn = emit_insn (gen_push (y));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
+ insn = emit_insn (gen_rtx_SET (VOIDmode, y, x));
+ RTX_FRAME_RELATED_P (insn) = 1;
/* Align the stack. */
- emit_insn (gen_andsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-16)));
-
- /* And here we cheat like madmen with the unwind info. We force the
- cfa register back to sp+4, which is exactly what it was at the
- start of the function. Re-pushing the return address results in
- the return at the same spot relative to the cfa, and thus is
- correct wrt the unwind info. */
- x = cfun->machine->force_align_arg_pointer;
- x = gen_frame_mem (Pmode, plus_constant (x, -4));
- insn = emit_insn (gen_push (x));
+ insn = emit_insn ((*ix86_gen_andsp) (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (-align_bytes)));
RTX_FRAME_RELATED_P (insn) = 1;
- x = GEN_INT (4);
- x = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, x), UNSPEC_DEF_CFA);
- x = gen_rtx_SET (VOIDmode, stack_pointer_rtx, x);
- x = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, x, NULL);
- REG_NOTES (insn) = x;
+ /* Replicate the return address on the stack so that return
+ address can be reached via (argp - 1) slot. This is needed
+ to implement macro RETURN_ADDR_RTX and intrinsic function
+ expand_builtin_return_addr etc. */
+ x = crtl->drap_reg;
+ x = gen_frame_mem (Pmode,
+ plus_constant (x,
+ -(STACK_BOUNDARY / BITS_PER_UNIT)));
+ insn = emit_insn (gen_push (x));
+ RTX_FRAME_RELATED_P (insn) = 1;
}
/* Note: AT&T enter does NOT have reversed args. Enter is probably
@@ -7553,6 +7707,18 @@ ix86_expand_prologue (void)
RTX_FRAME_RELATED_P (insn) = 1;
}
+ if (stack_realign_fp)
+ {
+ int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
+ gcc_assert (align_bytes > STACK_BOUNDARY / BITS_PER_UNIT);
+
+ /* Align the stack. */
+ insn = emit_insn ((*ix86_gen_andsp) (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (-align_bytes)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
allocate = frame.to_allocate;
if (!frame.save_regs_using_mov)
@@ -7567,7 +7733,9 @@ ix86_expand_prologue (void)
a red zone location */
if (!TARGET_64BIT_MS_ABI && TARGET_RED_ZONE && frame.save_regs_using_mov
&& (! TARGET_STACK_PROBE || allocate < CHECK_STACK_LIMIT))
- ix86_emit_save_regs_using_mov (frame_pointer_needed ? hard_frame_pointer_rtx
+ ix86_emit_save_regs_using_mov ((frame_pointer_needed
+ && !crtl->stack_realign_needed)
+ ? hard_frame_pointer_rtx
: stack_pointer_rtx,
-frame.nregs * UNITS_PER_WORD);
@@ -7626,8 +7794,11 @@ ix86_expand_prologue (void)
&& !(!TARGET_64BIT_MS_ABI && TARGET_RED_ZONE
&& (! TARGET_STACK_PROBE || allocate < CHECK_STACK_LIMIT)))
{
- if (!frame_pointer_needed || !frame.to_allocate)
- ix86_emit_save_regs_using_mov (stack_pointer_rtx, frame.to_allocate);
+ if (!frame_pointer_needed
+ || !frame.to_allocate
+ || crtl->stack_realign_needed)
+ ix86_emit_save_regs_using_mov (stack_pointer_rtx,
+ frame.to_allocate);
else
ix86_emit_save_regs_using_mov (hard_frame_pointer_rtx,
-frame.nregs * UNITS_PER_WORD);
@@ -7678,6 +7849,16 @@ ix86_expand_prologue (void)
emit_insn (gen_blockage ());
}
+ if (crtl->drap_reg && !crtl->stack_realign_needed)
+ {
+ /* vDRAP is setup but after reload it turns out stack realign
+ isn't necessary, here we will emit prologue to setup DRAP
+ without stack realign adjustment */
+ int drap_bp_offset = STACK_BOUNDARY / BITS_PER_UNIT * 2;
+ rtx x = plus_constant (hard_frame_pointer_rtx, drap_bp_offset);
+ insn = emit_insn (gen_rtx_SET (VOIDmode, crtl->drap_reg, x));
+ }
+
/* Emit cld instruction if stringops are used in the function. */
if (TARGET_CLD && ix86_current_function_needs_cld)
emit_insn (gen_cld ());
@@ -7719,10 +7900,17 @@ void
ix86_expand_epilogue (int style)
{
int regno;
- int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging;
+ int sp_valid;
struct ix86_frame frame;
HOST_WIDE_INT offset;
+ ix86_finalize_stack_realign_flags ();
+
+ /* When stack is realigned, SP must be valid. */
+ sp_valid = (!frame_pointer_needed
+ || current_function_sp_is_unchanging
+ || stack_realign_fp);
+
ix86_compute_frame_layout (&frame);
/* Calculate start of saved registers relative to ebp. Special care
@@ -7756,11 +7944,16 @@ ix86_expand_epilogue (int style)
{
/* Restore registers. We can use ebp or esp to address the memory
locations. If both are available, default to ebp, since offsets
- are known to be small. Only exception is esp pointing directly to the
- end of block of saved registers, where we may simplify addressing
- mode. */
+ are known to be small. Only exception is esp pointing directly
+ to the end of block of saved registers, where we may simplify
+ addressing mode.
+
+ If we are realigning stack with bp and sp, regs restore can't
+ be addressed by bp. sp must be used instead. */
- if (!frame_pointer_needed || (sp_valid && !frame.to_allocate))
+ if (!frame_pointer_needed
+ || (sp_valid && !frame.to_allocate)
+ || stack_realign_fp)
ix86_emit_restore_regs_using_mov (stack_pointer_rtx,
frame.to_allocate, style == 2);
else
@@ -7772,6 +7965,9 @@ ix86_expand_epilogue (int style)
{
rtx tmp, sa = EH_RETURN_STACKADJ_RTX;
+ /* Stack align doesn't work with eh_return. */
+ gcc_assert (!crtl->stack_realign_needed);
+
if (frame_pointer_needed)
{
tmp = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
@@ -7813,10 +8009,16 @@ ix86_expand_epilogue (int style)
else
{
/* First step is to deallocate the stack frame so that we can
- pop the registers. */
+ pop the registers.
+
+ If we realign stack with frame pointer, then stack pointer
+ won't be able to recover via lea $offset(%bp), %sp, because
+ there is a padding area between bp and sp for realign.
+ "add $to_allocate, %sp" must be used instead. */
if (!sp_valid)
{
gcc_assert (frame_pointer_needed);
+ gcc_assert (!stack_realign_fp);
pro_epilogue_adjust_stack (stack_pointer_rtx,
hard_frame_pointer_rtx,
GEN_INT (offset), style);
@@ -7835,15 +8037,31 @@ ix86_expand_epilogue (int style)
if (TARGET_USE_LEAVE)
emit_insn ((*ix86_gen_leave) ());
else
- emit_insn ((*ix86_gen_pop1) (hard_frame_pointer_rtx));
+ {
+ /* For stack realigned really happens, recover stack
+ pointer to hard frame pointer is a must, if not using
+ leave. */
+ if (stack_realign_fp)
+ pro_epilogue_adjust_stack (stack_pointer_rtx,
+ hard_frame_pointer_rtx,
+ const0_rtx, style);
+ emit_insn ((*ix86_gen_pop1) (hard_frame_pointer_rtx));
+ }
}
}
- if (cfun->machine->force_align_arg_pointer)
+ if (crtl->drap_reg && crtl->stack_realign_needed)
{
- emit_insn (gen_addsi3 (stack_pointer_rtx,
- cfun->machine->force_align_arg_pointer,
- GEN_INT (-4)));
+ int param_ptr_offset = (call_used_regs[REGNO (crtl->drap_reg)]
+ ? 0 : STACK_BOUNDARY / BITS_PER_UNIT);
+ gcc_assert (stack_realign_drap);
+ emit_insn ((*ix86_gen_add3) (stack_pointer_rtx,
+ crtl->drap_reg,
+ GEN_INT (-(STACK_BOUNDARY / BITS_PER_UNIT
+ + param_ptr_offset))));
+ if (!call_used_regs[REGNO (crtl->drap_reg)])
+ emit_insn ((*ix86_gen_pop1) (crtl->drap_reg));
+
}
/* Sibcall epilogues don't want a return instruction. */
@@ -27275,6 +27493,10 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree)
#define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference
#undef TARGET_INTERNAL_ARG_POINTER
#define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
+#undef TARGET_UPDATE_STACK_BOUNDARY
+#define TARGET_UPDATE_STACK_BOUNDARY ix86_update_stack_boundary
+#undef TARGET_GET_DRAP_RTX
+#define TARGET_GET_DRAP_RTX ix86_get_drap_rtx
#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
#define TARGET_DWARF_HANDLE_FRAME_UNSPEC ix86_dwarf_handle_frame_unspec
#undef TARGET_STRICT_ARGUMENT_NAMING
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index c7d33c7eb05..a98e278e9ad 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -648,16 +648,32 @@ enum target_cpu_default
#define STACK_BOUNDARY (TARGET_64BIT && DEFAULT_ABI == MS_ABI ? 128 \
: BITS_PER_WORD)
+/* Stack boundary of the main function guaranteed by OS. */
+#define MAIN_STACK_BOUNDARY (TARGET_64BIT ? 128 : 32)
+
+/* Stack boundary guaranteed by ABI. */
+#define ABI_STACK_BOUNDARY (TARGET_64BIT ? 128 : 32)
+
/* Boundary (in *bits*) on which the stack pointer prefers to be
aligned; the compiler cannot rely on having this alignment. */
#define PREFERRED_STACK_BOUNDARY ix86_preferred_stack_boundary
-/* As of July 2001, many runtimes do not align the stack properly when
- entering main. This causes expand_main_function to forcibly align
- the stack, which results in aligned frames for functions called from
- main, though it does nothing for the alignment of main itself. */
-#define FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN \
- (ix86_preferred_stack_boundary > STACK_BOUNDARY && !TARGET_64BIT)
+/* It should be ABI_STACK_BOUNDARY. But we set it to 128 bits for
+ both 32bit and 64bit, to support codes that need 128 bit stack
+ alignment for SSE instructions, but can't realign the stack. */
+#define PREFERRED_STACK_BOUNDARY_DEFAULT 128
+
+/* 1 if -mstackrealign should be turned on by default. It will
+ generate an alternate prologue and epilogue that realigns the
+ runtime stack if nessary. This supports mixing codes that keep a
+ 4-byte aligned stack, as specified by i386 psABI, with codes that
+ need a 16-byte aligned stack, as required by SSE instructions. If
+ STACK_REALIGN_DEFAULT is 1 and PREFERRED_STACK_BOUNDARY_DEFAULT is
+ 128, stacks for all functions may be realigned. */
+#define STACK_REALIGN_DEFAULT 0
+
+/* Boundary (in *bits*) on which the incoming stack is aligned. */
+#define INCOMING_STACK_BOUNDARY ix86_incoming_stack_boundary
/* Target OS keeps a vector-aligned (128-bit, 16-byte) stack. This is
mandatory for the 64-bit ABI, and may or may not be true for other
@@ -684,6 +700,9 @@ enum target_cpu_default
#define BIGGEST_ALIGNMENT 128
+/* Maximum stack alignment. */
+#define MAX_STACK_ALIGNMENT MAX_OFILE_ALIGNMENT
+
/* Decide whether a variable of mode MODE should be 128 bit aligned. */
#define ALIGN_MODE_128(MODE) \
((MODE) == XFmode || SSE_REG_MODE_P (MODE))
@@ -1110,7 +1129,7 @@ do { \
the pic register when possible. The change is visible after the
prologue has been emitted. */
-#define REAL_PIC_OFFSET_TABLE_REGNUM 3
+#define REAL_PIC_OFFSET_TABLE_REGNUM BX_REG
#define PIC_OFFSET_TABLE_REGNUM \
((TARGET_64BIT && ix86_cmodel == CM_SMALL_PIC) \
@@ -1629,12 +1648,9 @@ typedef struct ix86_args {
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} \
/* Given FROM and TO register numbers, say whether this elimination is
- allowed. Frame pointer elimination is automatically handled.
-
- All other eliminations are valid. */
+ allowed. */
-#define CAN_ELIMINATE(FROM, TO) \
- ((TO) == STACK_POINTER_REGNUM ? !frame_pointer_needed : 1)
+#define CAN_ELIMINATE(FROM, TO) ix86_can_eliminate ((FROM), (TO))
/* Define the offset between two registers, one to be eliminated, and the other
its replacement, at the start of a routine. */
@@ -2203,6 +2219,7 @@ enum asm_dialect {
extern enum asm_dialect ix86_asm_dialect;
extern unsigned int ix86_preferred_stack_boundary;
+extern unsigned int ix86_incoming_stack_boundary;
extern int ix86_branch_cost, ix86_section_threshold;
/* Smallest class containing REGNO. */
@@ -2304,7 +2321,6 @@ struct machine_function GTY(())
{
struct stack_local_entry *stack_locals;
const char *some_ld_name;
- rtx force_align_arg_pointer;
int save_varrargs_registers;
int accesses_prev_frame;
int optimize_mode_switching[MAX_386_ENTITIES];
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index e7a9827c5b9..2e737b10abe 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -245,6 +245,7 @@
[(AX_REG 0)
(DX_REG 1)
(CX_REG 2)
+ (BX_REG 3)
(SI_REG 4)
(DI_REG 5)
(BP_REG 6)
@@ -254,6 +255,7 @@
(FPCR_REG 19)
(R10_REG 39)
(R11_REG 40)
+ (R13_REG 42)
])
;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index d5c0978dde5..fc59b77ac7b 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -112,6 +112,10 @@ mfancy-math-387
Target RejectNegative Report InverseMask(NO_FANCY_MATH_387, USE_FANCY_MATH_387) Save
Generate sin, cos, sqrt for FPU
+mforce-drap
+Target Report Var(ix86_force_drap)
+Always use Dynamic Realigned Argument Pointer (DRAP) to realign stack
+
mfp-ret-in-387
Target Report Mask(FLOAT_RETURNS) Save
Return values of functions in FPU registers
@@ -168,6 +172,10 @@ mpreferred-stack-boundary=
Target RejectNegative Joined Var(ix86_preferred_stack_boundary_string)
Attempt to keep stack aligned to this power of 2
+mincoming-stack-boundary=
+Target RejectNegative Joined Var(ix86_incoming_stack_boundary_string)
+Assume incoming stack aligned to this power of 2
+
mpush-args
Target Report InverseMask(NO_PUSH_ARGS, PUSH_ARGS) Save
Use push instructions to save outgoing arguments
@@ -193,7 +201,7 @@ Target RejectNegative Mask(SSEREGPARM) Save
Use SSE register passing conventions for SF and DF mode
mstackrealign
-Target Report Var(ix86_force_align_arg_pointer)
+Target Report Var(ix86_force_align_arg_pointer) Init(-1)
Realign stack in prologue
mstack-arg-probe
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 8a926e43c44..def3b53ab95 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -644,12 +644,15 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
/* Define this macro to be the value 1 if unaligned accesses have a cost
many times greater than aligned accesses, for example if they are
emulated in a trap handler. */
+/* Altivec vector memory instructions simply ignore the low bits; SPE
+ vector memory instructions trap on unaligned accesses. */
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \
(STRICT_ALIGNMENT \
|| (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \
|| (MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode \
|| (MODE) == DImode) \
- && (ALIGN) < 32))
+ && (ALIGN) < 32) \
+ || (VECTOR_MODE_P ((MODE)) && (ALIGN) < GET_MODE_BITSIZE ((MODE))))
/* Standard register usage. */
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e98283ad6ca..f01593df6df 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2008-07-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/11309
+ * tree.c (build_aggr_init_expr): Split out...
+ (build_cplus_new): ...from here.
+ (stabilize_init): Don't mess with AGGR_INIT_EXPR either.
+ * init.c (build_new_1): new T() means value-initialization,
+ not default-initialization.
+ (build_vec_init): Likewise.
+ (build_value_init_1): Use build_aggr_init_expr.
+
2008-07-30 Dodji Seketeli <dseketel@redhat.com>
PR c++/36767
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f9a2af8bb01..02d358a8fe6 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4742,6 +4742,7 @@ extern tree build_min_nt (enum tree_code, ...);
extern tree build_min_non_dep (enum tree_code, tree, ...);
extern tree build_min_non_dep_call_list (tree, tree, tree);
extern tree build_cplus_new (tree, tree);
+extern tree build_aggr_init_expr (tree, tree);
extern tree get_target_expr (tree);
extern tree build_cplus_array_type (tree, tree);
extern tree build_array_of_n_type (tree, int);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 3deb85d432b..5535033e1be 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -347,7 +347,7 @@ build_value_init_1 (tree type, bool have_ctor)
if (CLASS_TYPE_P (type))
{
if (type_has_user_provided_constructor (type) && !have_ctor)
- return build_cplus_new
+ return build_aggr_init_expr
(type,
build_special_member_call (NULL_TREE, complete_ctor_identifier,
NULL_TREE, type, LOOKUP_NORMAL,
@@ -511,7 +511,7 @@ perform_member_init (tree member, tree init)
{
/* Initialization of one array from another. */
finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init),
- /*explicit_default_init_p=*/false,
+ /*explicit_value_init_p=*/false,
/* from_array=*/1,
tf_warning_or_error));
}
@@ -1286,7 +1286,7 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED)
itype = TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
stmt_expr = build_vec_init (exp, NULL_TREE, init,
- /*explicit_default_init_p=*/false,
+ /*explicit_value_init_p=*/false,
itype && same_type_p (itype,
TREE_TYPE (exp)),
complain);
@@ -2154,19 +2154,19 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (is_initialized)
{
bool stable;
+ bool explicit_value_init_p = false;
init_expr = cp_build_indirect_ref (data_addr, NULL, complain);
- if (array_p)
+ if (init == void_zero_node)
{
- bool explicit_default_init_p = false;
+ init = NULL_TREE;
+ explicit_value_init_p = true;
+ }
- if (init == void_zero_node)
- {
- init = NULL_TREE;
- explicit_default_init_p = true;
- }
- else if (init)
+ if (array_p)
+ {
+ if (init)
{
if (complain & tf_error)
permerror ("ISO C++ forbids initialization in array new");
@@ -2179,7 +2179,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
integer_one_node,
complain),
init,
- explicit_default_init_p,
+ explicit_value_init_p,
/*from_array=*/0,
complain);
@@ -2190,17 +2190,19 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
}
else
{
- if (init == void_zero_node)
- init = build_default_init (full_type, nelts);
-
- if (TYPE_NEEDS_CONSTRUCTING (type))
+ if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p)
{
init_expr = build_special_member_call (init_expr,
complete_ctor_identifier,
init, elt_type,
LOOKUP_NORMAL,
complain);
- stable = stabilize_init (init_expr, &init_preeval_expr);
+ }
+ else if (explicit_value_init_p)
+ {
+ /* Something like `new int()'. */
+ init_expr = build2 (INIT_EXPR, full_type,
+ init_expr, build_value_init (full_type));
}
else
{
@@ -2216,8 +2218,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, init,
complain);
- stable = stabilize_init (init_expr, &init_preeval_expr);
}
+ stable = stabilize_init (init_expr, &init_preeval_expr);
}
if (init_expr == error_mark_node)
@@ -2662,8 +2664,8 @@ get_temp_regvar (tree type, tree init)
INIT is the (possibly NULL) initializer.
- If EXPLICIT_DEFAULT_INIT_P is true, then INIT must be NULL. All
- elements in the array are default-initialized.
+ If EXPLICIT_VALUE_INIT_P is true, then INIT must be NULL. All
+ elements in the array are value-initialized.
FROM_ARRAY is 0 if we should init everything with INIT
(i.e., every element initialized from INIT).
@@ -2674,7 +2676,7 @@ get_temp_regvar (tree type, tree init)
tree
build_vec_init (tree base, tree maxindex, tree init,
- bool explicit_default_init_p,
+ bool explicit_value_init_p,
int from_array, tsubst_flags_t complain)
{
tree rval;
@@ -2704,7 +2706,7 @@ build_vec_init (tree base, tree maxindex, tree init,
if (maxindex == NULL_TREE || maxindex == error_mark_node)
return error_mark_node;
- if (explicit_default_init_p)
+ if (explicit_value_init_p)
gcc_assert (!init);
inner_elt_type = strip_array_types (atype);
@@ -2840,7 +2842,7 @@ build_vec_init (tree base, tree maxindex, tree init,
We do need to keep going if we're copying an array. */
if (from_array
- || ((TYPE_NEEDS_CONSTRUCTING (type) || explicit_default_init_p)
+ || ((TYPE_NEEDS_CONSTRUCTING (type) || explicit_value_init_p)
&& ! (host_integerp (maxindex, 0)
&& (num_initialized_elts
== tree_low_cst (maxindex, 0) + 1))))
@@ -2889,17 +2891,17 @@ build_vec_init (tree base, tree maxindex, tree init,
("cannot initialize multi-dimensional array with initializer");
elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
0, 0,
- /*explicit_default_init_p=*/false,
+ explicit_value_init_p,
0, complain);
}
- else if (!TYPE_NEEDS_CONSTRUCTING (type))
- elt_init = (cp_build_modify_expr
- (to, INIT_EXPR,
- build_zero_init (type, size_one_node,
- /*static_storage_p=*/false),
- complain));
+ else if (explicit_value_init_p)
+ elt_init = build2 (INIT_EXPR, type, to,
+ build_value_init (type));
else
- elt_init = build_aggr_init (to, init, 0, complain);
+ {
+ gcc_assert (TYPE_NEEDS_CONSTRUCTING (type));
+ elt_init = build_aggr_init (to, init, 0, complain);
+ }
current_stmt_tree ()->stmts_are_full_exprs_p = 1;
finish_expr_stmt (elt_init);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 50c3049c3d0..4114f868d41 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -339,15 +339,17 @@ build_aggr_init_array (tree return_type, tree fn, tree slot, int nargs,
}
/* INIT is a CALL_EXPR or AGGR_INIT_EXPR which needs info about its
- target. TYPE is the type that this initialization should appear to
- have.
+ target. TYPE is the type to be initialized.
- Build an encapsulation of the initialization to perform
- and return it so that it can be processed by language-independent
- and language-specific expression expanders. */
+ Build an AGGR_INIT_EXPR to represent the initialization. This function
+ differs from build_cplus_new in that an AGGR_INIT_EXPR can only be used
+ to initialize another object, whereas a TARGET_EXPR can either
+ initialize another object or create its own temporary object, and as a
+ result building up a TARGET_EXPR requires that the type's destructor be
+ callable. */
tree
-build_cplus_new (tree type, tree init)
+build_aggr_init_expr (tree type, tree init)
{
tree fn;
tree slot;
@@ -369,8 +371,6 @@ build_cplus_new (tree type, tree init)
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
- slot = build_local_temp (type);
-
/* We split the CALL_EXPR into its function and its arguments here.
Then, in expand_expr, we put them back together. The reason for
this is that this expression might be a default argument
@@ -384,6 +384,8 @@ build_cplus_new (tree type, tree init)
type, don't mess with AGGR_INIT_EXPR. */
if (is_ctor || TREE_ADDRESSABLE (type))
{
+ slot = build_local_temp (type);
+
if (TREE_CODE(init) == CALL_EXPR)
rval = build_aggr_init_array (void_type_node, fn, slot,
call_expr_nargs (init),
@@ -398,6 +400,30 @@ build_cplus_new (tree type, tree init)
else
rval = init;
+ return rval;
+}
+
+/* INIT is a CALL_EXPR or AGGR_INIT_EXPR which needs info about its
+ target. TYPE is the type that this initialization should appear to
+ have.
+
+ Build an encapsulation of the initialization to perform
+ and return it so that it can be processed by language-independent
+ and language-specific expression expanders. */
+
+tree
+build_cplus_new (tree type, tree init)
+{
+ tree rval = build_aggr_init_expr (type, init);
+ tree slot;
+
+ if (TREE_CODE (rval) == AGGR_INIT_EXPR)
+ slot = AGGR_INIT_EXPR_SLOT (rval);
+ else if (TREE_CODE (rval) == CALL_EXPR)
+ slot = build_local_temp (type);
+ else
+ return rval;
+
rval = build_target_expr (slot, rval);
TARGET_EXPR_IMPLICIT_P (rval) = 1;
@@ -2687,7 +2713,8 @@ stabilize_init (tree init, tree *initp)
return true;
if (TREE_CODE (t) == INIT_EXPR
- && TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR)
+ && TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR
+ && TREE_CODE (TREE_OPERAND (t, 1)) != AGGR_INIT_EXPR)
{
TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
return true;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index ba1d0286079..feb6b5f8f54 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6114,7 +6114,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
? 1 + (modifycode != INIT_EXPR): 0;
return build_vec_init (lhs, NULL_TREE, newrhs,
- /*explicit_default_init_p=*/false,
+ /*explicit_value_init_p=*/false,
from_array, complain);
}
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 80294305850..e68a0651a67 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -563,6 +563,12 @@ along with GCC; see the file COPYING3. If not see
#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY
#endif
+/* Set INCOMING_STACK_BOUNDARY to PREFERRED_STACK_BOUNDARY if it is not
+ defined. */
+#ifndef INCOMING_STACK_BOUNDARY
+#define INCOMING_STACK_BOUNDARY PREFERRED_STACK_BOUNDARY
+#endif
+
#ifndef TARGET_DEFAULT_PACK_STRUCT
#define TARGET_DEFAULT_PACK_STRUCT 0
#endif
@@ -950,6 +956,21 @@ along with GCC; see the file COPYING3. If not see
#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 0
#endif
+/* MAX_STACK_ALIGNMENT is the maximum stack alignment guaranteed by
+ the backend. MAX_SUPPORTED_STACK_ALIGNMENT is the maximum best
+ effort stack alignment supported by the backend. If the backend
+ supports stack alignment, MAX_SUPPORTED_STACK_ALIGNMENT and
+ MAX_STACK_ALIGNMENT are the same. Otherwise, the incoming stack
+ boundary will limit the maximum guaranteed stack alignment. */
+#ifdef MAX_STACK_ALIGNMENT
+#define MAX_SUPPORTED_STACK_ALIGNMENT MAX_STACK_ALIGNMENT
+#else
+#define MAX_STACK_ALIGNMENT STACK_BOUNDARY
+#define MAX_SUPPORTED_STACK_ALIGNMENT PREFERRED_STACK_BOUNDARY
+#endif
+
+#define SUPPORTS_STACK_ALIGNMENT (MAX_STACK_ALIGNMENT > STACK_BOUNDARY)
+
#ifndef LOCAL_ALIGNMENT
#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
#endif
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 4c82dc60f2c..9557ba3bad9 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2959,15 +2959,9 @@ floating point arguments on the stack.
@cindex @code{force_align_arg_pointer} attribute
On the Intel x86, the @code{force_align_arg_pointer} attribute may be
applied to individual function definitions, generating an alternate
-prologue and epilogue that realigns the runtime stack. This supports
-mixing legacy codes that run with a 4-byte aligned stack with modern
-codes that keep a 16-byte stack for SSE compatibility. The alternate
-prologue and epilogue are slower and bigger than the regular ones, and
-the alternate prologue requires a scratch register; this lowers the
-number of registers available if used in conjunction with the
-@code{regparm} attribute. The @code{force_align_arg_pointer}
-attribute is incompatible with nested functions; this is considered a
-hard error.
+prologue and epilogue that realigns the runtime stack if necessary.
+This supports mixing legacy codes that run with a 4-byte aligned stack
+with modern codes that keep a 16-byte stack for SSE compatibility.
@item resbank
@cindex @code{resbank} attribute
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ea5d284f6e8..f638f7d3d85 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -556,7 +556,9 @@ Objective-C and Objective-C++ Dialects}.
-masm=@var{dialect} -mno-fancy-math-387 @gol
-mno-fp-ret-in-387 -msoft-float @gol
-mno-wide-multiply -mrtd -malign-double @gol
--mpreferred-stack-boundary=@var{num} -mcld -mcx16 -msahf -mrecip @gol
+-mpreferred-stack-boundary=@var{num}
+-mincoming-stack-boundary=@var{num}
+-mcld -mcx16 -msahf -mrecip @gol
-mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 @gol
-maes -mpclmul @gol
-msse4a -m3dnow -mpopcnt -mabm -msse5 @gol
@@ -10744,17 +10746,11 @@ when this option is used to set the precision to less than extended precision.
@item -mstackrealign
@opindex mstackrealign
-Realign the stack at entry. On the Intel x86, the
-@option{-mstackrealign} option will generate an alternate prologue and
-epilogue that realigns the runtime stack. This supports mixing legacy
-codes that keep a 4-byte aligned stack with modern codes that keep a
-16-byte stack for SSE compatibility. The alternate prologue and
-epilogue are slower and bigger than the regular ones, and the
-alternate prologue requires an extra scratch register; this lowers the
-number of registers available if used in conjunction with the
-@code{regparm} attribute. The @option{-mstackrealign} option is
-incompatible with the nested function prologue; this is considered a
-hard error. See also the attribute @code{force_align_arg_pointer},
+Realign the stack at entry. On the Intel x86, the @option{-mstackrealign}
+option will generate an alternate prologue and epilogue that realigns the
+runtime stack if necessary. This supports mixing legacy codes that keep
+a 4-byte aligned stack with modern codes that keep a 16-byte stack for
+SSE compatibility. See also the attribute @code{force_align_arg_pointer},
applicable to individual functions.
@item -mpreferred-stack-boundary=@var{num}
@@ -10763,6 +10759,12 @@ Attempt to keep the stack boundary aligned to a 2 raised to @var{num}
byte boundary. If @option{-mpreferred-stack-boundary} is not specified,
the default is 4 (16 bytes or 128 bits).
+@item -mincoming-stack-boundary=@var{num}
+@opindex mincoming-stack-boundary
+Assume the incoming stack is aligned to a 2 raised to @var{num} byte
+boundary. If @option{-mincoming-stack-boundary} is not specified,
+the one specified by @option{-mpreferred-stack-boundary} will be used.
+
On Pentium and PentiumPro, @code{double} and @code{long double} values
should be aligned to an 8 byte boundary (see @option{-malign-double}) or
suffer significant run time performance penalties. On Pentium III, the
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 5183736ccae..228af27d621 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1084,6 +1084,12 @@ macro must evaluate to a value equal to or larger than
@code{STACK_BOUNDARY}.
@end defmac
+@defmac INCOMING_STACK_BOUNDARY
+Define this macro if the incoming stack boundary may be different
+from @code{PREFERRED_STACK_BOUNDARY}. This macro must evaluate
+to a value equal to or larger than @code{STACK_BOUNDARY}.
+@end defmac
+
@defmac FUNCTION_BOUNDARY
Alignment required for a function entry point, in bits.
@end defmac
@@ -1122,6 +1128,18 @@ field alignment has not been set by the
@code{__attribute__ ((aligned (@var{n})))} construct.
@end defmac
+@defmac MAX_STACK_ALIGNMENT
+Biggest stack alignment guaranteed by the backend. Use this macro
+to specify the maximum alignment of a variable on stack.
+
+If not defined, the default value is @code{STACK_BOUNDARY}.
+
+@c FIXME: The default should be @code{PREFERRED_STACK_BOUNDARY}.
+@c But the fix for PR 32893 indicates that we can only guarantee
+@c maximum stack alignment on stack up to @code{STACK_BOUNDARY}, not
+@c @code{PREFERRED_STACK_BOUNDARY}, if stack alignment isn't supported.
+@end defmac
+
@defmac MAX_OFILE_ALIGNMENT
Biggest alignment supported by the object file format of this machine.
Use this macro to limit the alignment which can be specified using the
@@ -10586,6 +10604,17 @@ call stack unwinding. It is used in declarations in @file{unwind-generic.h}
and the associated definitions of those functions.
@end defmac
+@deftypefn {Target Hook} void TARGET_UPDATE_STACK_BOUNDARY (void)
+Define this macro to update the current function stack boundary if
+necessary.
+@end deftypefn
+
+@deftypefn {Target Hook} rtx TARGET_GET_DRAP_RTX (void)
+Define this macro to an rtx for Dynamic Realign Argument Pointer if a
+different argument pointer register is needed to access the function's
+argument list when stack is aligned.
+@end deftypefn
+
@deftypefn {Target Hook} {bool} TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS (void)
When optimization is disabled, this hook indicates whether or not
arguments should be allocated to stack slots. Normally, GCC allocates
diff --git a/gcc/dse.c b/gcc/dse.c
index 4d5120160fa..99233266377 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -783,10 +783,9 @@ replace_inc_dec (rtx *r, void *d)
{
rtx r1 = XEXP (x, 0);
rtx c = gen_int_mode (Pmode, data->size);
- add_insn_before (data->insn,
- gen_rtx_SET (Pmode, r1,
- gen_rtx_PLUS (Pmode, r1, c)),
- NULL);
+ emit_insn_before (gen_rtx_SET (Pmode, r1,
+ gen_rtx_PLUS (Pmode, r1, c)),
+ data->insn);
return -1;
}
@@ -795,10 +794,9 @@ replace_inc_dec (rtx *r, void *d)
{
rtx r1 = XEXP (x, 0);
rtx c = gen_int_mode (Pmode, -data->size);
- add_insn_before (data->insn,
- gen_rtx_SET (Pmode, r1,
- gen_rtx_PLUS (Pmode, r1, c)),
- NULL);
+ emit_insn_before (gen_rtx_SET (Pmode, r1,
+ gen_rtx_PLUS (Pmode, r1, c)),
+ data->insn);
return -1;
}
@@ -809,8 +807,7 @@ replace_inc_dec (rtx *r, void *d)
insn that contained it. */
rtx add = XEXP (x, 0);
rtx r1 = XEXP (add, 0);
- add_insn_before (data->insn,
- gen_rtx_SET (Pmode, r1, add), NULL);
+ emit_insn_before (gen_rtx_SET (Pmode, r1, add), data->insn);
return -1;
}
@@ -827,12 +824,12 @@ static int
replace_inc_dec_mem (rtx *r, void *d)
{
rtx x = *r;
- if (GET_CODE (x) == MEM)
+ if (x != NULL_RTX && MEM_P (x))
{
struct insn_size data;
data.size = GET_MODE_SIZE (GET_MODE (x));
- data.insn = (rtx)d;
+ data.insn = (rtx) d;
for_each_rtx (&XEXP (x, 0), replace_inc_dec, &data);
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index a8e06efb22d..f553f2e454a 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -239,9 +239,18 @@ typedef struct dw_fde_struct GTY(())
bool dw_fde_switched_sections;
dw_cfi_ref dw_fde_cfi;
unsigned funcdef_number;
+ HOST_WIDE_INT stack_realignment;
+ /* Dynamic realign argument pointer register. */
+ unsigned int drap_reg;
+ /* Virtual dynamic realign argument pointer register. */
+ unsigned int vdrap_reg;
unsigned all_throwers_are_sibcalls : 1;
unsigned nothrow : 1;
unsigned uses_eh_lsda : 1;
+ /* Whether we did stack realign in this call frame. */
+ unsigned stack_realign : 1;
+ /* Whether dynamic realign argument pointer register has been saved. */
+ unsigned drap_reg_saved: 1;
}
dw_fde_node;
@@ -388,6 +397,8 @@ static void get_cfa_from_loc_descr (dw_cfa_location *,
struct dw_loc_descr_struct *);
static struct dw_loc_descr_struct *build_cfa_loc
(dw_cfa_location *, HOST_WIDE_INT);
+static struct dw_loc_descr_struct *build_cfa_aligned_loc
+ (HOST_WIDE_INT, HOST_WIDE_INT);
static void def_cfa_1 (const char *, dw_cfa_location *);
/* How to start an assembler comment. */
@@ -621,6 +632,23 @@ static inline void
add_cfi (dw_cfi_ref *list_head, dw_cfi_ref cfi)
{
dw_cfi_ref *p;
+ dw_fde_ref fde = current_fde ();
+
+ /* When DRAP is used, CFA is defined with an expression. Redefine
+ CFA may lead to a different CFA value. */
+ if (fde && fde->drap_reg != INVALID_REGNUM)
+ switch (cfi->dw_cfi_opc)
+ {
+ case DW_CFA_def_cfa_register:
+ case DW_CFA_def_cfa_offset:
+ case DW_CFA_def_cfa_offset_sf:
+ case DW_CFA_def_cfa:
+ case DW_CFA_def_cfa_sf:
+ gcc_unreachable ();
+
+ default:
+ break;
+ }
/* Find the end of the chain. */
for (p = list_head; (*p) != NULL; p = &(*p)->dw_cfi_next)
@@ -880,10 +908,22 @@ static void
reg_save (const char *label, unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset)
{
dw_cfi_ref cfi = new_cfi ();
+ dw_fde_ref fde = current_fde ();
cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg;
- if (sreg == INVALID_REGNUM)
+ /* When stack is aligned, store REG using DW_CFA_expression with
+ FP. */
+ if (fde
+ && fde->stack_realign
+ && sreg == INVALID_REGNUM)
+ {
+ cfi->dw_cfi_opc = DW_CFA_expression;
+ cfi->dw_cfi_oprnd2.dw_cfi_reg_num = reg;
+ cfi->dw_cfi_oprnd1.dw_cfi_loc
+ = build_cfa_aligned_loc (offset, fde->stack_realignment);
+ }
+ else if (sreg == INVALID_REGNUM)
{
if (reg & ~0x3f)
/* The register number won't fit in 6 bits, so we have to use
@@ -1445,6 +1485,11 @@ static dw_cfa_location cfa_temp;
difference of the original location and cfa_store's
location (or cfa_temp's location if cfa_temp is used).
+ Rules 16-20: If AND operation happens on sp in prologue, we assume
+ stack is realigned. We will use a group of DW_OP_XXX
+ expressions to represent the location of the stored
+ register instead of CFA+offset.
+
The Rules
"{a,b}" indicates a choice of a xor b.
@@ -1538,13 +1583,48 @@ static dw_cfa_location cfa_temp;
Rule 15:
(set <reg> {unspec, unspec_volatile})
- effects: target-dependent */
+ effects: target-dependent
+
+ Rule 16:
+ (set sp (and: sp <const_int>))
+ constraints: cfa_store.reg == sp
+ effects: current_fde.stack_realign = 1
+ cfa_store.offset = 0
+ fde->drap_reg = cfa.reg if cfa.reg != sp and cfa.reg != fp
+
+ Rule 17:
+ (set (mem ({pre_inc, pre_dec} sp)) (mem (plus (cfa.reg) (const_int))))
+ effects: cfa_store.offset += -/+ mode_size(mem)
+
+ Rule 18:
+ (set (mem ({pre_inc, pre_dec} sp)) fp)
+ constraints: fde->stack_realign == 1
+ effects: cfa_store.offset = 0
+ cfa.reg != HARD_FRAME_POINTER_REGNUM
+
+ Rule 19:
+ (set (mem ({pre_inc, pre_dec} sp)) cfa.reg)
+ constraints: fde->stack_realign == 1
+ && cfa.offset == 0
+ && cfa.indirect == 0
+ && cfa.reg != HARD_FRAME_POINTER_REGNUM
+ effects: Use DW_CFA_def_cfa_expression to define cfa
+ cfa.reg == fde->drap_reg
+
+ Rule 20:
+ (set reg fde->drap_reg)
+ constraints: fde->vdrap_reg == INVALID_REGNUM
+ effects: fde->vdrap_reg = reg.
+ (set mem fde->drap_reg)
+ constraints: fde->drap_reg_saved == 1
+ effects: none. */
static void
dwarf2out_frame_debug_expr (rtx expr, const char *label)
{
rtx src, dest, span;
HOST_WIDE_INT offset;
+ dw_fde_ref fde;
/* If RTX_FRAME_RELATED_P is set on a PARALLEL, process each member of
the PARALLEL independently. The first element is always processed if
@@ -1621,6 +1701,26 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
src = rsi;
}
+ fde = current_fde ();
+
+ if (GET_CODE (src) == REG
+ && fde
+ && fde->drap_reg == REGNO (src)
+ && (fde->drap_reg_saved
+ || GET_CODE (dest) == REG))
+ {
+ /* Rule 20 */
+ /* If we are saving dynamic realign argument pointer to a
+ register, the destination is virtual dynamic realign
+ argument pointer. It may be used to access argument. */
+ if (GET_CODE (dest) == REG)
+ {
+ gcc_assert (fde->vdrap_reg == INVALID_REGNUM);
+ fde->vdrap_reg = REGNO (dest);
+ }
+ return;
+ }
+
switch (GET_CODE (dest))
{
case REG:
@@ -1649,7 +1749,19 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
/* For the SPARC and its register window. */
|| (DWARF_FRAME_REGNUM (REGNO (src))
== DWARF_FRAME_RETURN_COLUMN));
- queue_reg_save (label, src, dest, 0);
+
+ /* After stack is aligned, we can only save SP in FP
+ if drap register is used. In this case, we have
+ to restore stack pointer with the CFA value and we
+ don't generate this DWARF information. */
+ if (fde
+ && fde->stack_realign
+ && REGNO (src) == STACK_POINTER_REGNUM)
+ gcc_assert (REGNO (dest) == HARD_FRAME_POINTER_REGNUM
+ && fde->drap_reg != INVALID_REGNUM
+ && cfa.reg != REGNO (src));
+ else
+ queue_reg_save (label, src, dest, 0);
}
break;
@@ -1782,6 +1894,24 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
targetm.dwarf_handle_frame_unspec (label, expr, XINT (src, 1));
return;
+ /* Rule 16 */
+ case AND:
+ /* If this AND operation happens on stack pointer in prologue,
+ we assume the stack is realigned and we extract the
+ alignment. */
+ if (fde && XEXP (src, 0) == stack_pointer_rtx)
+ {
+ gcc_assert (cfa_store.reg == REGNO (XEXP (src, 0)));
+ fde->stack_realign = 1;
+ fde->stack_realignment = INTVAL (XEXP (src, 1));
+ cfa_store.offset = 0;
+
+ if (cfa.reg != STACK_POINTER_REGNUM
+ && cfa.reg != HARD_FRAME_POINTER_REGNUM)
+ fde->drap_reg = cfa.reg;
+ }
+ return;
+
default:
gcc_unreachable ();
}
@@ -1790,7 +1920,6 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
break;
case MEM:
- gcc_assert (REG_P (src));
/* Saving a register to the stack. Make sure dest is relative to the
CFA register. */
@@ -1821,10 +1950,23 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
if (GET_CODE (XEXP (dest, 0)) == PRE_INC)
offset = -offset;
- gcc_assert (REGNO (XEXP (XEXP (dest, 0), 0)) == STACK_POINTER_REGNUM
+ gcc_assert ((REGNO (XEXP (XEXP (dest, 0), 0))
+ == STACK_POINTER_REGNUM)
&& cfa_store.reg == STACK_POINTER_REGNUM);
cfa_store.offset += offset;
+
+ /* Rule 18: If stack is aligned, we will use FP as a
+ reference to represent the address of the stored
+ regiser. */
+ if (fde
+ && fde->stack_realign
+ && src == hard_frame_pointer_rtx)
+ {
+ gcc_assert (cfa.reg != HARD_FRAME_POINTER_REGNUM);
+ cfa_store.offset = 0;
+ }
+
if (cfa.reg == STACK_POINTER_REGNUM)
cfa.offset = cfa_store.offset;
@@ -1893,6 +2035,32 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
if (cfa.offset == 0)
{
+ /* Rule 19 */
+ /* If stack is aligned, putting CFA reg into stack means
+ we can no longer use reg + offset to represent CFA.
+ Here we use DW_CFA_def_cfa_expression instead. The
+ result of this expression equals to the original CFA
+ value. */
+ if (fde
+ && fde->stack_realign
+ && cfa.indirect == 0
+ && cfa.reg != HARD_FRAME_POINTER_REGNUM)
+ {
+ dw_cfa_location cfa_exp;
+
+ gcc_assert (fde->drap_reg == cfa.reg);
+
+ cfa_exp.indirect = 1;
+ cfa_exp.reg = HARD_FRAME_POINTER_REGNUM;
+ cfa_exp.base_offset = offset;
+ cfa_exp.offset = 0;
+
+ fde->drap_reg_saved = 1;
+
+ def_cfa_1 (label, &cfa_exp);
+ break;
+ }
+
/* If the source register is exactly the CFA, assume
we're saving SP like any other register; this happens
on the ARM. */
@@ -1917,6 +2085,12 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
break;
}
}
+ /* Rule 17 */
+ /* If the source operand of this MEM operation is not a
+ register, basically the source is return address. Here
+ we only care how much stack grew and we don't save it. */
+ if (!REG_P (src))
+ break;
def_cfa_1 (label, &cfa);
{
@@ -2693,6 +2867,8 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
fde->nothrow = TREE_NOTHROW (current_function_decl);
fde->uses_eh_lsda = crtl->uses_eh_lsda;
fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls;
+ fde->drap_reg = INVALID_REGNUM;
+ fde->vdrap_reg = INVALID_REGNUM;
args_size = old_args_size = 0;
@@ -2924,6 +3100,7 @@ typedef struct dw_loc_list_struct GTY(())
static const char *dwarf_stack_op_name (unsigned);
static dw_loc_descr_ref new_loc_descr (enum dwarf_location_atom,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);
+static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
static void add_loc_descr (dw_loc_descr_ref *, dw_loc_descr_ref);
static unsigned long size_of_loc_descr (dw_loc_descr_ref);
static unsigned long size_of_locs (dw_loc_descr_ref);
@@ -3583,6 +3760,9 @@ output_cfa_loc (dw_cfi_ref cfi)
dw_loc_descr_ref loc;
unsigned long size;
+ if (cfi->dw_cfi_opc == DW_CFA_expression)
+ dw2_asm_output_data (1, cfi->dw_cfi_oprnd2.dw_cfi_reg_num, NULL);
+
/* Output the size of the block. */
loc = cfi->dw_cfi_oprnd1.dw_cfi_loc;
size = size_of_locs (loc);
@@ -3642,6 +3822,38 @@ build_cfa_loc (dw_cfa_location *cfa, HOST_WIDE_INT offset)
return head;
}
+/* This function builds a dwarf location descriptor sequence for
+ the address at OFFSET from the CFA when stack is aligned to
+ ALIGNMENT byte. */
+
+static struct dw_loc_descr_struct *
+build_cfa_aligned_loc (HOST_WIDE_INT offset, HOST_WIDE_INT alignment)
+{
+ struct dw_loc_descr_struct *head;
+ unsigned int dwarf_fp
+ = DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM);
+
+ /* When CFA is defined as FP+OFFSET, emulate stack alignment. */
+ if (cfa.reg == HARD_FRAME_POINTER_REGNUM && cfa.indirect == 0)
+ {
+ if (dwarf_fp <= 31)
+ head = new_loc_descr (DW_OP_breg0 + dwarf_fp, 0, 0);
+ else
+ head = new_loc_descr (DW_OP_bregx, dwarf_fp, 0);
+
+ add_loc_descr (&head, int_loc_descriptor (alignment));
+ add_loc_descr (&head, new_loc_descr (DW_OP_and, 0, 0));
+
+ add_loc_descr (&head, int_loc_descriptor (offset));
+ add_loc_descr (&head, new_loc_descr (DW_OP_plus, 0, 0));
+ }
+ else if (dwarf_fp <= 31)
+ head = new_loc_descr (DW_OP_breg0 + dwarf_fp, offset, 0);
+ else
+ head = new_loc_descr (DW_OP_bregx, dwarf_fp, offset);
+ return head;
+}
+
/* This function fills in aa dw_cfa_location structure from a dwarf location
descriptor sequence. */
@@ -4310,7 +4522,6 @@ static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int,
enum var_init_status);
static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx,
enum var_init_status);
-static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
static dw_loc_descr_ref based_loc_descr (rtx, HOST_WIDE_INT,
enum var_init_status);
static int is_based_loc (const_rtx);
@@ -8635,7 +8846,8 @@ is_subrange_type (const_tree type)
return false;
if (TREE_CODE (subtype) != INTEGER_TYPE
- && TREE_CODE (subtype) != ENUMERAL_TYPE)
+ && TREE_CODE (subtype) != ENUMERAL_TYPE
+ && TREE_CODE (subtype) != BOOLEAN_TYPE)
return false;
if (TREE_CODE (type) == TREE_CODE (subtype)
@@ -8997,6 +9209,10 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs,
return loc_result;
}
+#endif /* DWARF2_DEBUGGING_INFO */
+
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
+
/* Return a location descriptor that designates a constant. */
static dw_loc_descr_ref
@@ -9035,6 +9251,9 @@ int_loc_descriptor (HOST_WIDE_INT i)
return new_loc_descr (op, i, 0);
}
+#endif
+
+#ifdef DWARF2_DEBUGGING_INFO
/* Return a location descriptor that designates a base+offset location. */
@@ -9044,6 +9263,7 @@ based_loc_descr (rtx reg, HOST_WIDE_INT offset,
{
unsigned int regno;
dw_loc_descr_ref result;
+ dw_fde_ref fde = current_fde ();
/* We only use "frame base" when we're sure we're talking about the
post-prologue local stack frame. We do this by *not* running
@@ -9060,13 +9280,45 @@ based_loc_descr (rtx reg, HOST_WIDE_INT offset,
offset += INTVAL (XEXP (elim, 1));
elim = XEXP (elim, 0);
}
- gcc_assert (elim == (frame_pointer_needed ? hard_frame_pointer_rtx
- : stack_pointer_rtx));
- offset += frame_pointer_fb_offset;
+ gcc_assert ((SUPPORTS_STACK_ALIGNMENT
+ && (elim == hard_frame_pointer_rtx
+ || elim == stack_pointer_rtx))
+ || elim == (frame_pointer_needed
+ ? hard_frame_pointer_rtx
+ : stack_pointer_rtx));
+
+ /* If drap register is used to align stack, use frame
+ pointer + offset to access stack variables. If stack
+ is aligned without drap, use stack pointer + offset to
+ access stack variables. */
+ if (fde
+ && fde->stack_realign
+ && cfa.reg == HARD_FRAME_POINTER_REGNUM
+ && reg == frame_pointer_rtx)
+ {
+ int base_reg
+ = DWARF_FRAME_REGNUM (cfa.indirect
+ ? HARD_FRAME_POINTER_REGNUM
+ : STACK_POINTER_REGNUM);
+ if (base_reg <= 31)
+ return new_loc_descr (DW_OP_breg0 + base_reg, offset, 0);
+ else
+ return new_loc_descr (DW_OP_bregx, base_reg, offset);
+ }
+ offset += frame_pointer_fb_offset;
return new_loc_descr (DW_OP_fbreg, offset, 0);
}
}
+ else if (fde
+ && fde->drap_reg != INVALID_REGNUM
+ && (fde->drap_reg == REGNO (reg)
+ || fde->vdrap_reg == REGNO (reg)))
+ {
+ /* Use cfa+offset to represent the location of arguments passed
+ on stack when drap is used to align stack. */
+ return new_loc_descr (DW_OP_fbreg, offset, 0);
+ }
regno = dbx_reg_number (reg);
if (regno <= 31)
@@ -11111,8 +11363,13 @@ compute_frame_pointer_to_fb_displacement (HOST_WIDE_INT offset)
offset += INTVAL (XEXP (elim, 1));
elim = XEXP (elim, 0);
}
- gcc_assert (elim == (frame_pointer_needed ? hard_frame_pointer_rtx
- : stack_pointer_rtx));
+
+ gcc_assert ((SUPPORTS_STACK_ALIGNMENT
+ && (elim == hard_frame_pointer_rtx
+ || elim == stack_pointer_rtx))
+ || elim == (frame_pointer_needed
+ ? hard_frame_pointer_rtx
+ : stack_pointer_rtx));
frame_pointer_fb_offset = -offset;
}
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 65fa8e457ec..a0af7b39436 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -864,9 +864,18 @@ rtx
gen_reg_rtx (enum machine_mode mode)
{
rtx val;
+ unsigned int align = GET_MODE_ALIGNMENT (mode);
gcc_assert (can_create_pseudo_p ());
+ /* If a virtual register with bigger mode alignment is generated,
+ increase stack alignment estimation because it might be spilled
+ to stack later. */
+ if (SUPPORTS_STACK_ALIGNMENT
+ && crtl->stack_alignment_estimated < align
+ && !crtl->stack_realign_processed)
+ crtl->stack_alignment_estimated = align;
+
if (generating_concat_p
&& (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_INT))
diff --git a/gcc/final.c b/gcc/final.c
index 2a9d40ba754..099942a37a0 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -1758,6 +1758,9 @@ call_from_call_insn (rtx insn)
{
default:
gcc_unreachable ();
+ case COND_EXEC:
+ x = COND_EXEC_CODE (x);
+ break;
case PARALLEL:
x = XVECEXP (x, 0, 0);
break;
diff --git a/gcc/function.c b/gcc/function.c
index ea3ddf45604..b9d9ec59cc0 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -350,10 +350,14 @@ get_stack_local_alignment (tree type, enum machine_mode mode)
-2 means use BITS_PER_UNIT,
positive specifies alignment boundary in bits.
+ If REDUCE_ALIGNMENT_OK is true, it is OK to reduce alignment.
+
We do not round to stack_boundary here. */
rtx
-assign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
+assign_stack_local_1 (enum machine_mode mode, HOST_WIDE_INT size,
+ int align,
+ bool reduce_alignment_ok ATTRIBUTE_UNUSED)
{
rtx x, addr;
int bigend_correction = 0;
@@ -375,17 +379,52 @@ assign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
else
alignment = align / BITS_PER_UNIT;
+ alignment_in_bits = alignment * BITS_PER_UNIT;
+
if (FRAME_GROWS_DOWNWARD)
frame_offset -= size;
- /* Ignore alignment we can't do with expected alignment of the boundary. */
- if (alignment * BITS_PER_UNIT > PREFERRED_STACK_BOUNDARY)
- alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
+ /* Ignore alignment if it exceeds MAX_SUPPORTED_STACK_ALIGNMENT. */
+ if (alignment_in_bits > MAX_SUPPORTED_STACK_ALIGNMENT)
+ {
+ alignment_in_bits = MAX_SUPPORTED_STACK_ALIGNMENT;
+ alignment = alignment_in_bits / BITS_PER_UNIT;
+ }
- alignment_in_bits = alignment * BITS_PER_UNIT;
+ if (SUPPORTS_STACK_ALIGNMENT)
+ {
+ if (crtl->stack_alignment_estimated < alignment_in_bits)
+ {
+ if (!crtl->stack_realign_processed)
+ crtl->stack_alignment_estimated = alignment_in_bits;
+ else
+ {
+ /* If stack is realigned and stack alignment value
+ hasn't been finalized, it is OK not to increase
+ stack_alignment_estimated. The bigger alignment
+ requirement is recorded in stack_alignment_needed
+ below. */
+ gcc_assert (!crtl->stack_realign_finalized);
+ if (!crtl->stack_realign_needed)
+ {
+ /* It is OK to reduce the alignment as long as the
+ requested size is 0 or the estimated stack
+ alignment >= mode alignment. */
+ gcc_assert (reduce_alignment_ok
+ || size == 0
+ || (crtl->stack_alignment_estimated
+ >= GET_MODE_ALIGNMENT (mode)));
+ alignment_in_bits = crtl->stack_alignment_estimated;
+ alignment = alignment_in_bits / BITS_PER_UNIT;
+ }
+ }
+ }
+ }
if (crtl->stack_alignment_needed < alignment_in_bits)
crtl->stack_alignment_needed = alignment_in_bits;
+ if (crtl->max_used_stack_slot_alignment < crtl->stack_alignment_needed)
+ crtl->max_used_stack_slot_alignment = crtl->stack_alignment_needed;
/* Calculate how many bytes the start of local variables is off from
stack alignment. */
@@ -449,6 +488,14 @@ assign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
return x;
}
+
+/* Wrap up assign_stack_local_1 with last parameter as false. */
+
+rtx
+assign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
+{
+ return assign_stack_local_1 (mode, size, align, false);
+}
/* Removes temporary slot TEMP from LIST. */
@@ -1167,7 +1214,17 @@ instantiate_new_reg (rtx x, HOST_WIDE_INT *poffset)
HOST_WIDE_INT offset;
if (x == virtual_incoming_args_rtx)
- new = arg_pointer_rtx, offset = in_arg_offset;
+ {
+ /* Replace virtual_incoming_args_rtx to internal arg pointer here */
+ if (crtl->args.internal_arg_pointer != virtual_incoming_args_rtx)
+ {
+ gcc_assert (stack_realign_drap);
+ new = crtl->args.internal_arg_pointer;
+ offset = 0;
+ }
+ else
+ new = arg_pointer_rtx, offset = in_arg_offset;
+ }
else if (x == virtual_stack_vars_rtx)
new = frame_pointer_rtx, offset = var_offset;
else if (x == virtual_stack_dynamic_rtx)
@@ -2947,6 +3004,20 @@ assign_parms (tree fndecl)
continue;
}
+ /* Estimate stack alignment from parameter alignment. */
+ if (SUPPORTS_STACK_ALIGNMENT)
+ {
+ unsigned int align = FUNCTION_ARG_BOUNDARY (data.promoted_mode,
+ data.passed_type);
+ if (TYPE_ALIGN (data.nominal_type) > align)
+ align = TYPE_ALIGN (data.passed_type);
+ if (crtl->stack_alignment_estimated < align)
+ {
+ gcc_assert (!crtl->stack_realign_processed);
+ crtl->stack_alignment_estimated = align;
+ }
+ }
+
if (cfun->stdarg && !TREE_CHAIN (parm))
assign_parms_setup_varargs (&all, &data, false);
@@ -2984,6 +3055,28 @@ assign_parms (tree fndecl)
now that all parameters have been copied out of hard registers. */
emit_insn (all.first_conversion_insn);
+ /* Estimate reload stack alignment from scalar return mode. */
+ if (SUPPORTS_STACK_ALIGNMENT)
+ {
+ if (DECL_RESULT (fndecl))
+ {
+ tree type = TREE_TYPE (DECL_RESULT (fndecl));
+ enum machine_mode mode = TYPE_MODE (type);
+
+ if (mode != BLKmode
+ && mode != VOIDmode
+ && !AGGREGATE_TYPE_P (type))
+ {
+ unsigned int align = GET_MODE_ALIGNMENT (mode);
+ if (crtl->stack_alignment_estimated < align)
+ {
+ gcc_assert (!crtl->stack_realign_processed);
+ crtl->stack_alignment_estimated = align;
+ }
+ }
+ }
+ }
+
/* If we are receiving a struct value address as the first argument, set up
the RTL for the function result. As this might require code to convert
the transmitted address to Pmode, we do this here to ensure that possible
@@ -3257,15 +3350,43 @@ locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
= type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
- if (boundary > PREFERRED_STACK_BOUNDARY)
- boundary = PREFERRED_STACK_BOUNDARY;
locate->where_pad = where_pad;
+
+ /* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT. */
+ if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
+ boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
+
locate->boundary = boundary;
+ if (SUPPORTS_STACK_ALIGNMENT)
+ {
+ /* stack_alignment_estimated can't change after stack has been
+ realigned. */
+ if (crtl->stack_alignment_estimated < boundary)
+ {
+ if (!crtl->stack_realign_processed)
+ crtl->stack_alignment_estimated = boundary;
+ else
+ {
+ /* If stack is realigned and stack alignment value
+ hasn't been finalized, it is OK not to increase
+ stack_alignment_estimated. The bigger alignment
+ requirement is recorded in stack_alignment_needed
+ below. */
+ gcc_assert (!crtl->stack_realign_finalized
+ && crtl->stack_realign_needed);
+ }
+ }
+ }
+
/* Remember if the outgoing parameter requires extra alignment on the
calling function side. */
if (crtl->stack_alignment_needed < boundary)
crtl->stack_alignment_needed = boundary;
+ if (crtl->max_used_stack_slot_alignment < crtl->stack_alignment_needed)
+ crtl->max_used_stack_slot_alignment = crtl->stack_alignment_needed;
+ if (crtl->preferred_stack_boundary < boundary)
+ crtl->preferred_stack_boundary = boundary;
#ifdef ARGS_GROW_DOWNWARD
locate->slot_offset.constant = -initial_offset_ptr->constant;
@@ -4602,7 +4723,8 @@ get_arg_pointer_save_area (void)
generated stack slot may not be a valid memory address, so we
have to check it and fix it if necessary. */
start_sequence ();
- emit_move_insn (validize_mem (ret), virtual_incoming_args_rtx);
+ emit_move_insn (validize_mem (ret),
+ crtl->args.internal_arg_pointer);
seq = get_insns ();
end_sequence ();
diff --git a/gcc/function.h b/gcc/function.h
index 94f4642dc32..ebba29f3862 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -311,6 +311,9 @@ struct rtl_data GTY(())
needed by inner routines. */
rtx x_arg_pointer_save_area;
+ /* Dynamic Realign Argument Pointer used for realigning stack. */
+ rtx drap_reg;
+
/* Offset to end of allocated area of stack frame.
If stack grows down, this is the address of the last stack slot allocated.
If stack grows up, this is the address for the next slot. */
@@ -328,12 +331,26 @@ struct rtl_data GTY(())
/* Current nesting level for temporaries. */
int x_temp_slot_level;
- /* The largest alignment of slot allocated on the stack. */
+ /* The largest alignment needed on the stack, including requirement
+ for outgoing stack alignment. */
unsigned int stack_alignment_needed;
- /* Preferred alignment of the end of stack frame. */
+ /* Preferred alignment of the end of stack frame, which is preferred
+ to call other functions. */
unsigned int preferred_stack_boundary;
+ /* The largest alignment of slot allocated on the stack. */
+ unsigned int max_used_stack_slot_alignment;
+
+ /* The stack alignment estimated before reload, with consideration of
+ following factors:
+ 1. Alignment of local stack variables (max_used_stack_slot_alignment)
+ 2. Alignment requirement to call other functions
+ (preferred_stack_boundary)
+ 3. Alignment of non-local stack variables but might be spilled in
+ local stack. */
+ unsigned int stack_alignment_estimated;
+
/* For reorg. */
/* If some insns can be deferred to the delay slots of the epilogue, the
@@ -393,13 +410,32 @@ struct rtl_data GTY(())
/* Nonzero if code to initialize arg_pointer_save_area has been emitted. */
bool arg_pointer_save_area_init;
- /* Nonzero means current function must be given a frame pointer.
- Set in stmt.c if anything is allocated on the stack there.
- Set in reload1.c if anything is allocated on the stack there. */
+ /* Nonzero if current function must be given a frame pointer.
+ Set in global.c if anything is allocated on the stack there. */
bool frame_pointer_needed;
/* When set, expand should optimize for speed. */
bool maybe_hot_insn_p;
+
+ /* Nonzero if function stack realignment is needed. This flag may be
+ set twice: before and after reload. It is set before reload wrt
+ stack alignment estimation before reload. It will be changed after
+ reload if by then criteria of stack realignment is different.
+ The value set after reload is the accurate one and is finalized. */
+ bool stack_realign_needed;
+
+ /* Nonzero if function being compiled needs dynamic realigned
+ argument pointer (drap) if stack needs realigning. */
+ bool need_drap;
+
+ /* Nonzero if function stack realignment estimation is done, namely
+ stack_realign_needed flag has been set before reload wrt
+ estimated stack alignment info. */
+ bool stack_realign_processed;
+
+ /* Nonzero if function stack realignment has been finalized, namely
+ stack_realign_needed flag has been set and finalized after reload. */
+ bool stack_realign_finalized;
};
#define return_label (crtl->x_return_label)
@@ -414,6 +450,8 @@ struct rtl_data GTY(())
#define temp_slot_level (crtl->x_temp_slot_level)
#define nonlocal_goto_handler_labels (crtl->x_nonlocal_goto_handler_labels)
#define frame_pointer_needed (crtl->frame_pointer_needed)
+#define stack_realign_fp (crtl->stack_realign_needed && !crtl->need_drap)
+#define stack_realign_drap (crtl->stack_realign_needed && crtl->need_drap)
extern GTY(()) struct rtl_data x_rtl;
diff --git a/gcc/global.c b/gcc/global.c
index c47033e5754..690a80c8a85 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -233,6 +233,7 @@ compute_regsets (HARD_REG_SET *elim_set,
= (! flag_omit_frame_pointer
|| (cfun->calls_alloca && EXIT_IGNORE_STACK)
|| crtl->accesses_prior_frames
+ || crtl->stack_realign_needed
|| FRAME_POINTER_REQUIRED);
frame_pointer_needed = need_fp;
@@ -256,7 +257,10 @@ compute_regsets (HARD_REG_SET *elim_set,
{
bool cannot_elim
= (! CAN_ELIMINATE (eliminables[i].from, eliminables[i].to)
- || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp));
+ || (eliminables[i].to == STACK_POINTER_REGNUM
+ && need_fp
+ && (! SUPPORTS_STACK_ALIGNMENT
+ || ! stack_realign_fp)));
if (!regs_asm_clobbered[eliminables[i].from])
{
diff --git a/gcc/passes.c b/gcc/passes.c
index bd4a7ce0926..675d83b55eb 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -524,7 +524,9 @@ init_optimization_passes (void)
NEXT_PASS (pass_warn_function_return);
NEXT_PASS (pass_build_cgraph_edges);
NEXT_PASS (pass_inline_parameters);
+#if ENABLE_BASILYSMELT
NEXT_PASS (pass_basilys_lowering);
+#endif
*p = NULL;
/* Interprocedural optimization passes. */
@@ -548,10 +550,10 @@ init_optimization_passes (void)
NEXT_PASS (pass_referenced_vars);
NEXT_PASS (pass_reset_cc_flags);
NEXT_PASS (pass_build_ssa);
+ NEXT_PASS (pass_early_warn_uninitialized);
NEXT_PASS (pass_all_early_optimizations);
{
struct opt_pass **p = &pass_all_early_optimizations.pass.sub;
- NEXT_PASS (pass_early_warn_uninitialized);
NEXT_PASS (pass_rebuild_cgraph_edges);
NEXT_PASS (pass_early_inline);
NEXT_PASS (pass_cleanup_cfg);
@@ -576,7 +578,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_simple_dse);
NEXT_PASS (pass_tail_recursion);
NEXT_PASS (pass_convert_switch);
-#if ENABLE_BASILYSMELT
+#if ENABLE_BASILYSMELT
NEXT_PASS (pass_basilys_earlyopt);
#endif /*ENABLE_BASILYSMELT*/
NEXT_PASS (pass_profile);
@@ -593,7 +595,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_ipa_type_escape);
NEXT_PASS (pass_ipa_pta);
NEXT_PASS (pass_ipa_struct_reorg);
-#if ENABLE_BASILYSMELT
+#if ENABLE_BASILYSMELT
NEXT_PASS (pass_basilys_ipa);
#endif /*ENABLE_BASILYSMELT*/
*p = NULL;
@@ -715,24 +717,19 @@ init_optimization_passes (void)
NEXT_PASS (pass_tail_calls);
NEXT_PASS (pass_rename_ssa_copies);
NEXT_PASS (pass_uncprop);
-#if ENABLE_BASILYSMELT
+#if ENABLE_BASILYSMELT
NEXT_PASS (pass_basilys_lateopt);
#endif /*ENABLE_BASILYSMELT*/
- NEXT_PASS (pass_del_ssa);
- NEXT_PASS (pass_nrv);
- NEXT_PASS (pass_mark_used_blocks);
- NEXT_PASS (pass_cleanup_cfg_post_optimizing);
}
-
-#if ENABLE_COMPILER_PROBE
- NEXT_PASS(pass_compiler_probe);
-#endif
-
NEXT_PASS (pass_del_ssa);
NEXT_PASS (pass_nrv);
NEXT_PASS (pass_mark_used_blocks);
NEXT_PASS (pass_cleanup_cfg_post_optimizing);
+#if ENABLE_COMPILER_PROBE
+ NEXT_PASS(pass_compiler_probe);
+#endif
+
NEXT_PASS (pass_warn_function_noreturn);
NEXT_PASS (pass_free_datastructures);
NEXT_PASS (pass_mudflap_2);
diff --git a/gcc/reload1.c b/gcc/reload1.c
index f28b01c2714..9b81062216f 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -3663,8 +3663,11 @@ update_eliminables (HARD_REG_SET *pset)
frame_pointer_needed = 1;
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
{
- if (ep->can_eliminate && ep->from == FRAME_POINTER_REGNUM
- && ep->to != HARD_FRAME_POINTER_REGNUM)
+ if (ep->can_eliminate
+ && ep->from == FRAME_POINTER_REGNUM
+ && ep->to != HARD_FRAME_POINTER_REGNUM
+ && (! SUPPORTS_STACK_ALIGNMENT
+ || ! crtl->stack_realign_needed))
frame_pointer_needed = 0;
if (! ep->can_eliminate && ep->can_eliminate_previous)
@@ -3720,7 +3723,10 @@ init_elim_table (void)
ep->to = ep1->to;
ep->can_eliminate = ep->can_eliminate_previous
= (CAN_ELIMINATE (ep->from, ep->to)
- && ! (ep->to == STACK_POINTER_REGNUM && frame_pointer_needed));
+ && ! (ep->to == STACK_POINTER_REGNUM
+ && frame_pointer_needed
+ && (! SUPPORTS_STACK_ALIGNMENT
+ || ! stack_realign_fp)));
}
#else
reg_eliminate[0].from = reg_eliminate_1[0].from;
diff --git a/gcc/rtl.h b/gcc/rtl.h
index b2b561c3421..5281b1484db 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1572,6 +1572,7 @@ extern rtx simplify_subtraction (rtx);
/* In function.c */
extern rtx assign_stack_local (enum machine_mode, HOST_WIDE_INT, int);
+extern rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int, bool);
extern rtx assign_stack_temp (enum machine_mode, HOST_WIDE_INT, int);
extern rtx assign_stack_temp_for_type (enum machine_mode,
HOST_WIDE_INT, int, tree);
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 664c91049b4..38d7b439aec 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -1813,7 +1813,7 @@ expand_nl_goto_receiver (void)
{
/* Now restore our arg pointer from the address at which it
was saved in our stack frame. */
- emit_move_insn (virtual_incoming_args_rtx,
+ emit_move_insn (crtl->args.internal_arg_pointer,
copy_to_reg (get_arg_pointer_save_area ()));
}
}
diff --git a/gcc/target-def.h b/gcc/target-def.h
index bf8c7e79eac..cd64b386e9e 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -571,6 +571,8 @@
#define TARGET_FUNCTION_VALUE default_function_value
#define TARGET_INTERNAL_ARG_POINTER default_internal_arg_pointer
+#define TARGET_UPDATE_STACK_BOUNDARY NULL
+#define TARGET_GET_DRAP_RTX NULL
#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS hook_bool_void_true
#define TARGET_CALLS { \
@@ -592,6 +594,8 @@
TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN, \
TARGET_FUNCTION_VALUE, \
TARGET_INTERNAL_ARG_POINTER, \
+ TARGET_UPDATE_STACK_BOUNDARY, \
+ TARGET_GET_DRAP_RTX, \
TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS \
}
diff --git a/gcc/target.h b/gcc/target.h
index 331cc53d8f4..3a104c5632b 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -839,6 +839,13 @@ struct gcc_target
current function. */
rtx (*internal_arg_pointer) (void);
+ /* Update the current function stack boundary if needed. */
+ void (*update_stack_boundary) (void);
+
+ /* Handle stack alignment and return an rtx for Dynamic Realign
+ Argument Pointer if necessary. */
+ rtx (*get_drap_rtx) (void);
+
/* Return true if all function parameters should be spilled to the
stack. */
bool (*allocate_stack_slots_for_args) (void);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c53755b4db0..a4025292059 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,102 @@
+2008-07-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/boolean_expr.ad[sb]: New test.
+
+2008-07-30 H.J. Lu <hongjiu.lu@intel.com>
+ Joey Ye <joey.ye@intel.com>
+
+ * gcc.dg/dfp/func-vararg-alternate-d128-2.c: New.
+ * gcc.dg/dfp/func-vararg-mixed-2.c: Likewise.
+ * gcc.dg/torture/stackalign/alloca-1.c: Likewise.
+ * gcc.dg/torture/stackalign/builtin-apply-1.c: Likewise.
+ * gcc.dg/torture/stackalign/builtin-apply-2.c: Likewise.
+ * gcc.dg/torture/stackalign/builtin-apply-3.c: Likewise.
+ * gcc.dg/torture/stackalign/builtin-apply-4.c: Likewise.
+ * gcc.dg/torture/stackalign/builtin-return-1.c: Likewise.
+ * gcc.dg/torture/stackalign/check.h: Likewise.
+ * gcc.dg/torture/stackalign/comp-goto-1.c: Likewise.
+ * gcc.dg/torture/stackalign/fastcall-1.c: Likewise.
+ * gcc.dg/torture/stackalign/global-1.c: Likewise.
+ * gcc.dg/torture/stackalign/inline-1.c: Likewise.
+ * gcc.dg/torture/stackalign/inline-2.c: Likewise.
+ * gcc.dg/torture/stackalign/nested-1.c: Likewise.
+ * gcc.dg/torture/stackalign/nested-2.c: Likewise.
+ * gcc.dg/torture/stackalign/nested-3.c: Likewise.
+ * gcc.dg/torture/stackalign/nested-4.c: Likewise.
+ * gcc.dg/torture/stackalign/nested-5.c: Likewise.
+ * gcc.dg/torture/stackalign/nested-6.c: Likewise.
+ * gcc.dg/torture/stackalign/non-local-goto-1.c: Likewise.
+ * gcc.dg/torture/stackalign/non-local-goto-2.c: Likewise.
+ * gcc.dg/torture/stackalign/non-local-goto-3.c: Likewise.
+ * gcc.dg/torture/stackalign/non-local-goto-4.c: Likewise.
+ * gcc.dg/torture/stackalign/non-local-goto-5.c: Likewise.
+ * gcc.dg/torture/stackalign/pr16660-1.c: Likewise.
+ * gcc.dg/torture/stackalign/pr16660-2.c: Likewise.
+ * gcc.dg/torture/stackalign/pr16660-3.c: Likewise.
+ * gcc.dg/torture/stackalign/regparm-1.c: Likewise.
+ * gcc.dg/torture/stackalign/ret-struct-1.c: Likewise.
+ * gcc.dg/torture/stackalign/setjmp-1.c: Likewise.
+ * gcc.dg/torture/stackalign/setjmp-2.c: Likewise.
+ * gcc.dg/torture/stackalign/setjmp-3.c: Likewise.
+ * gcc.dg/torture/stackalign/setjmp-4.c: Likewise.
+ * gcc.dg/torture/stackalign/sibcall-1.c: Likewise.
+ * gcc.dg/torture/stackalign/stackalign.exp: Likewise.
+ * gcc.dg/torture/stackalign/struct-1.c: Likewise.
+ * gcc.dg/torture/stackalign/vararg-1.c: Likewise.
+ * gcc.dg/torture/stackalign/vararg-2.c: Likewise.
+ * gcc.target/i386/align-main-1.c: Likewise.
+ * gcc.target/i386/align-main-2.c: Likewise.
+ * gcc.target/i386/pr32000-2.c: Likewise.
+ * gcc.target/i386/stackalign/asm-1.c: Likewise.
+ * gcc.target/i386/stackalign/return-1.c: Likewise.
+ * gcc.target/i386/stackalign/return-2.c: Likewise.
+ * gcc.target/i386/stackalign/return-3.c: Likewise.
+ * gcc.target/i386/stackalign/return-4.c: Likewise.
+ * gcc.target/i386/stackalign/return-5.c: Likewise.
+ * gcc.target/i386/stackalign/return-6.c: Likewise.
+ * gcc.target/i386/stackalign/stackalign.exp: Likewise.
+ * g++.dg/torture/stackalign/check.h: Likewise.
+ * g++.dg/torture/stackalign/eh-alloca-1.C: Likewise.
+ * g++.dg/torture/stackalign/eh-fastcall-1.C: Likewise.
+ * g++.dg/torture/stackalign/eh-global-1.C: Likewise.
+ * g++.dg/torture/stackalign/eh-inline-1.C: Likewise.
+ * g++.dg/torture/stackalign/eh-inline-2.C: Likewise.
+ * g++.dg/torture/stackalign/eh-vararg-1.C: Likewise.
+ * g++.dg/torture/stackalign/eh-vararg-2.C: Likewise.
+ * g++.dg/torture/stackalign/stackalign.exp: Likewise.
+ * g++.dg/torture/stackalign/stdcall-1.C: Likewise.
+ * g++.dg/torture/stackalign/test-unwind.h: Likewise.
+ * g++.dg/torture/stackalign/throw-1.C: Likewise.
+ * g++.dg/torture/stackalign/throw-2.C: Likewise.
+ * g++.dg/torture/stackalign/throw-3.C: Likewise.
+ * g++.dg/torture/stackalign/throw-4.C: Likewise.
+ * g++.dg/torture/stackalign/unwind-0.C: Likewise.
+ * g++.dg/torture/stackalign/unwind-1.C: Likewise.
+ * g++.dg/torture/stackalign/unwind-2.C: Likewise.
+ * g++.dg/torture/stackalign/unwind-3.C: Likewise.
+ * g++.dg/torture/stackalign/unwind-4.C: Likewise.
+ * g++.dg/torture/stackalign/unwind-5.C: Likewise.
+ * g++.dg/torture/stackalign/unwind-6.C: Likewise.
+
+ * gcc.target/i386/20060512-1.c: Add -mpreferred-stack-boundary=4.
+ (main): Move "popl" after check.
+ * gcc.target/i386/20060512-3.c: Likewise.
+
+ * gcc.target/i386/20060512-2.c: Add -mpreferred-stack-boundary=4.
+ Remove dg-error.
+
+ * gcc.target/i386/20060512-4.c: Add -mpreferred-stack-boundary=4.
+ Remove dg-warning.
+
+ * lib/target-supports.exp (check_effective_target_unaligned_stack):
+ Always return 0.
+ (check_effective_target_automatic_stack_alignment): New.
+
+2008-07-30 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/36967
+ * gfortran.dg/pr36967.f: New testcase.
+
2008-07-30 Rafael Avila de Espindola <espindola@google.com>
* gcc.dg/visibility-14.c: New test.
@@ -3571,7 +3670,7 @@
PR fortran/35780
* gfortran.dg/simplify_argN_1.f90: New test.
-2008-04-06 Tobias Schlüter <tobi@gcc.gnu.org>
+2008-04-06 Tobias Schl�ter <tobi@gcc.gnu.org>
PR fortran/35832
* gfortran.dg/io_constraints_2.f90: Adapt to new error message.
diff --git a/gcc/testsuite/g++.dg/expr/anew4.C b/gcc/testsuite/g++.dg/expr/anew4.C
index d86d5251412..4ce1d8899f9 100644
--- a/gcc/testsuite/g++.dg/expr/anew4.C
+++ b/gcc/testsuite/g++.dg/expr/anew4.C
@@ -1,5 +1,4 @@
-// { dg-do run { xfail *-*-* } }
-// XFAILed until PR2123 is fixed
+// { dg-do run }
// PR 11228: array operator new, with zero-initialization and a variable sized array.
// Regression test for PR
// Author: Matt Austern <austern@apple.com>
diff --git a/gcc/testsuite/g++.dg/init/value3.C b/gcc/testsuite/g++.dg/init/value3.C
new file mode 100644
index 00000000000..487baabeceb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/value3.C
@@ -0,0 +1,31 @@
+// Testcase for value-initialization in new-expressions.
+// { dg-do run }
+
+#include <stdlib.h>
+#include <string.h>
+
+// Make sure that we return memory that isn't already set to 0.
+void *operator new(size_t s)
+{
+ void *p = malloc (s);
+ memset (p, 42, s);
+ return p;
+}
+
+struct A { A() {} ~A() {} };
+struct B { A a; int i; };
+
+int main()
+{
+ B *p = new B();
+ if (p->i != 0)
+ abort();
+
+ p = new B[2]();
+ if (p[0].i != 0 || p[1].i != 0)
+ abort();
+
+ B(*p2)[2] = new B[2][2]();
+ if (p2[0][0].i != 0 || p2[0][1].i != 0)
+ abort();
+}
diff --git a/gcc/testsuite/g++.dg/lookup/new1.C b/gcc/testsuite/g++.dg/lookup/new1.C
index b9d0bef88f6..ae1121339cf 100644
--- a/gcc/testsuite/g++.dg/lookup/new1.C
+++ b/gcc/testsuite/g++.dg/lookup/new1.C
@@ -4,10 +4,10 @@
int main() {
int i;
- void* operator new(unsigned s, int* p);
+ void* operator new(__SIZE_TYPE__ s, int* p);
int* e = new(&i) int; // { dg-error "no matching function" }
int* f = new int;
return 0;
}
-// { dg-excess-errors "operator new" }
+// { dg-error "candidate" "" { target *-*-* } 0 }
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/check.h b/gcc/testsuite/g++.dg/torture/stackalign/check.h
new file mode 100644
index 00000000000..af198851274
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/check.h
@@ -0,0 +1,36 @@
+#include <stddef.h>
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" void abort (void);
+#else
+extern void abort (void);
+#endif
+
+int
+check_int (int *i, int align)
+{
+ *i = 20;
+ if ((((ptrdiff_t) i) & (align - 1)) != 0)
+ {
+#ifdef DEBUG
+ printf ("\nUnalign address (%d): %p!\n", align, i);
+#endif
+ abort ();
+ }
+ return *i;
+}
+
+void
+check (void *p, int align)
+{
+ if ((((ptrdiff_t) p) & (align - 1)) != 0)
+ {
+#ifdef DEBUG
+ printf ("\nUnalign address (%d): %p!\n", align, p);
+#endif
+ abort ();
+ }
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C
new file mode 100644
index 00000000000..a20f074bcd2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+void
+foo (int size) throw (B,A)
+{
+ char *p = (char*) __builtin_alloca (size + 1);
+ aligned i;
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ throw A();
+}
+
+int
+main()
+{
+ try { foo (5); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C
new file mode 100644
index 00000000000..4b849a2e42e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C
@@ -0,0 +1,43 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+__attribute__ ((fastcall))
+void
+foo (int j, int k, int m, int n, int o) throw (B,A)
+{
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ if (i != 20 || j != 1 || k != 2 || m != 3 || n != 4 || o != 5)
+ abort ();
+
+ throw A();
+}
+
+int
+main()
+{
+ try { foo (1, 2, 3, 4, 5); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C
new file mode 100644
index 00000000000..2692f947c7b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+void
+foo (void) throw (B,A)
+{
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ throw A();
+}
+
+int
+main()
+{
+ try { foo (); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C
new file mode 100644
index 00000000000..72ac7fd2443
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+static void
+inline __attribute__((always_inline))
+foo (void) throw (B,A)
+{
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+ throw A();
+}
+
+int
+main()
+{
+ try { foo (); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C
new file mode 100644
index 00000000000..4feb3f09fc7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+static void
+inline __attribute__((always_inline))
+foo (int size) throw (B,A)
+{
+ char *p = (char *) __builtin_alloca (size + 1);
+ aligned i;
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ throw A();
+}
+
+int
+main()
+{
+ try { foo (5); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C
new file mode 100644
index 00000000000..74b48faa599
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+
+#include <stdarg.h>
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+void
+foo (const char *fmt, ...) throw (B,A)
+{
+ va_list arg;
+ char *p;
+ aligned i;
+ int size;
+ double x;
+
+ va_start (arg, fmt);
+ size = va_arg (arg, int);
+ if (size != 5)
+ abort ();
+ p = (char *) __builtin_alloca (size + 1);
+
+ x = va_arg (arg, double);
+ if (x != 5.0)
+ abort ();
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ throw A();
+
+ va_end (arg);
+}
+
+int
+main()
+{
+ try { foo ("foo", 5, 5.0); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C
new file mode 100644
index 00000000000..719c839a748
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C
@@ -0,0 +1,77 @@
+/* { dg-do run } */
+
+#include <stdarg.h>
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+void
+test (va_list arg) throw (B,A)
+{
+ char *p;
+ aligned i;
+ int size;
+ double x;
+
+ size = va_arg (arg, int);
+ if (size != 5)
+ abort ();
+
+ p = (char *) __builtin_alloca (size + 1);
+
+ x = va_arg (arg, double);
+ if (x != 5.0)
+ abort ();
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ throw A();
+}
+
+void
+foo (const char *fmt, ...)
+{
+ va_list arg;
+ va_start (arg, fmt);
+ test (arg);
+ va_end (arg);
+}
+int
+main()
+{
+ try { foo ("foo", 5, 5.0); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp b/gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp
new file mode 100644
index 00000000000..bfa413eab48
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp
@@ -0,0 +1,39 @@
+# Copyright (C) 2008
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# This harness is for tests that should be run at all optimisation levels.
+
+load_lib g++-dg.exp
+
+# Only run on targets which support automatic stack alignment.
+if { ![check_effective_target_automatic_stack_alignment] } then {
+ return
+}
+
+set additional_flags ""
+if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
+ lappend additional_flags "-mstackrealign"
+ lappend additional_flags "-mpreferred-stack-boundary=5"
+}
+
+dg-init
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.C]] $additional_flags
+if { [check_effective_target_fpic] } then {
+ lappend additional_flags "-fpic"
+ gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.C]] $additional_flags
+}
+dg-finish
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C b/gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C
new file mode 100644
index 00000000000..393b37e7b6b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C
@@ -0,0 +1,17 @@
+// { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
+
+// This case is to detect an assertion failure in stack branch development.
+
+bool f();
+struct S {
+ __attribute__ ((stdcall)) ~S();
+};
+void g() {
+ for (;;) {
+ S s1, s2, s3;
+ if (f())
+ continue;
+ if (f())
+ return;
+ }
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h b/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h
new file mode 100644
index 00000000000..e6493ffedb2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h
@@ -0,0 +1,132 @@
+#include "check.h"
+
+#ifdef __cplusplus
+extern "C" void abort (void);
+#else
+extern void abort (void);
+#endif
+
+extern void foo(void);
+
+#define INIT_EDI 1
+#define INIT_ESI 2
+#define INIT_EBX 3
+
+/* Set DI/SI/BX to wrong value
+ Use following template so that RA will save/restore callee
+ save registers in prologue/epilogue */
+#define ALTER_REGS() \
+ { \
+ int dummy; \
+ __asm__ __volatile__ (\
+ "movl %1, %0" : "=D" (dummy) : "i" (-INIT_EDI)\
+ );\
+ __asm__ __volatile__ (\
+ "movl %1, %0" : "=S" (dummy) : "i" (-INIT_ESI)\
+ );\
+ __asm__ __volatile__ (\
+ "movl %1, %0" : "=b" (dummy) : "i" (-INIT_EBX)\
+ );\
+ }
+
+#ifdef __PIC__
+int
+main ()
+{
+ return 0;
+}
+#else
+void __attribute__ ((noinline))
+copy (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+int g_edi=INIT_EDI, g_esi=INIT_ESI, g_ebx=INIT_EBX;
+int g_ebp, g_ebp_save, g_esp, g_esp_save;
+int n_error;
+
+int
+main()
+{
+ int dummy;
+ // Init registers to correct value.
+ // Use following template so that RA will save/restore callee
+ // save registers in prologue/epilogue
+ __asm__ __volatile__ (
+ "movl %1, %0"
+ : "=D" (dummy)
+ : "i" (INIT_EDI)
+ );
+ __asm__ __volatile__ (
+ "movl %1, %0"
+ : "=S" (dummy)
+ : "i" (INIT_ESI)
+ );
+ __asm__ __volatile__ (
+ "movl %1, %0"
+ : "=b" (dummy)
+ : "i" (INIT_EBX)
+ );
+ __asm__ __volatile__ (
+ "movl %ebp, g_ebp_save\n\t"
+ "movl %esp, g_esp_save\n\t"
+ );
+ try {
+ foo();
+ }
+ catch (...)
+ {
+ }
+
+ // Get DI/SI/BX register value after exception caught
+ __asm__ __volatile__ (
+ "movl %edi, g_edi\n\t"
+ "movl %esi, g_esi\n\t"
+ "movl %ebx, g_ebx\n\t"
+ "movl %ebp, g_ebp\n\t"
+ "movl %esp, g_esp\n\t"
+ );
+
+ // Check if DI/SI/BX register value are the same as before calling
+ // foo.
+ if (g_edi != INIT_EDI)
+ {
+ n_error++;
+#ifdef DEBUG
+ printf("edi=%d, correct value:%d\n", g_edi, INIT_EDI);
+#endif
+ }
+ if (g_esi != INIT_ESI)
+ {
+ n_error++;
+#ifdef DEBUG
+ printf("esi=%d, correct value:%d\n", g_esi, INIT_ESI);
+#endif
+ }
+ if (g_ebx != INIT_EBX)
+ {
+ n_error++;
+#ifdef DEBUG
+ printf("ebx=%d, correct value:%d\n", g_ebx, INIT_EBX);
+#endif
+ }
+ if (g_ebp != g_ebp_save)
+ {
+ n_error++;
+#ifdef DEBUG
+ printf("ebp=0x%x, correct value:0x%x\n", g_ebp, g_ebp_save);
+#endif
+ }
+ if (g_esp != g_esp_save)
+ {
+ n_error++;
+#ifdef DEBUG
+ printf("esp=0x%x, correct value:0x%x\n", g_esp, g_esp_save);
+#endif
+ }
+ if (n_error !=0)
+ abort();
+ return 0;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-1.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-1.C
new file mode 100644
index 00000000000..b1d2e278953
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-1.C
@@ -0,0 +1,61 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+ volatile t_align a = 1;
+ int i,j,k,l,m,n;
+ i=j=k=0;
+ for (i=0; i < global; i++)
+ for (j=0; j < i; j++)
+ for (k=0; k < j; k++)
+ for (l=0; l < k; l++)
+ for (m=0; m < l; m++)
+ for (n=0; n < m; n++)
+ global2 = k;
+ if (check_int ((int *) &a, __alignof__(a)) != a)
+ abort ();
+ throw 0;
+}
+
+void foo()
+{
+ bar();
+}
+
+int main()
+{
+ int ll = 1;
+ int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+ try {
+ for (; i < global; i++)
+ for (; j < i; j++)
+ for (; k < j; k++)
+ for (; l < k; l++)
+ for (; m < l; m++)
+ for (; n < m; n++)
+ global2 = k;
+ foo();
+ }
+ catch (...)
+ {
+ }
+ ll = i+j+k+l+m+n;
+ if (ll != 15)
+ {
+#ifdef DEBUG
+ printf("FAIL: sum %d != 15\n", ll);
+#endif
+ abort();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-2.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-2.C
new file mode 100644
index 00000000000..5f3f1dc0737
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-2.C
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+ volatile t_align a = 1;
+ int i,j,k;
+ i=j=k=0;
+ for (i=0; i < global; i++)
+ for (j=0; j < i; j++)
+ global2 = k;
+ if (check_int ((int *) &a, __alignof__(a)) != a)
+ abort ();
+ throw 0;
+}
+
+int main()
+{
+ int ll = 1;
+ int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+ try {
+ for (; i < global; i++)
+ for (; j < i; j++)
+ for (; k < j; k++)
+ for (; l < k; l++)
+ for (; m < l; m++)
+ for (; n < m; n++)
+ global2 = k;
+ bar ();
+ }
+ catch (...)
+ {
+ }
+ ll = i+j+k+l+m+n;
+ if (ll != 15)
+ {
+#ifdef DEBUG
+ printf("FAIL: sum %d != 15\n", ll);
+#endif
+ abort();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-3.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-3.C
new file mode 100644
index 00000000000..d3e53b8292d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-3.C
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+ volatile t_align a = 1;
+ int i,j,k;
+ i=j=k=0;
+ for (i=0; i < global; i++)
+ for (j=0; j < i; j++)
+ global2 = k;
+ throw 0;
+ if (check_int ((int *) &a, __alignof__(a)) != a)
+ abort ();
+}
+
+int main()
+{
+ int ll = 1;
+ int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+ try {
+ for (; i < global; i++)
+ for (; j < i; j++)
+ for (; k < j; k++)
+ for (; l < k; l++)
+ for (; m < l; m++)
+ for (; n < m; n++)
+ global2 = k;
+ bar ();
+ }
+ catch (...)
+ {
+ }
+ ll = i+j+k+l+m+n;
+ if (ll != 15)
+ {
+#ifdef DEBUG
+ printf("FAIL: sum %d != 15\n", ll);
+#endif
+ abort();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-4.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-4.C
new file mode 100644
index 00000000000..a9c15bd43c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-4.C
@@ -0,0 +1,54 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+ volatile t_align a = 1;
+ int i,j,k;
+ i=j=k=0;
+ for (i=0; i < global; i++)
+ for (j=0; j < i; j++)
+ {
+ global2 = k;
+ throw 0;
+ }
+ if (check_int ((int *) &a, __alignof__(a)) != a)
+ abort ();
+}
+
+int main()
+{
+ int ll = 1;
+ int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+ try {
+ for (; i < global; i++)
+ for (; j < i; j++)
+ for (; k < j; k++)
+ for (; l < k; l++)
+ for (; m < l; m++)
+ for (; n < m; n++)
+ global2 = k;
+ bar ();
+ }
+ catch (...)
+ {
+ }
+ ll = i+j+k+l+m+n;
+ if (ll != 15)
+ {
+#ifdef DEBUG
+ printf("FAIL: sum %d != 15\n", ll);
+#endif
+ abort();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C
new file mode 100644
index 00000000000..546123bdd0e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C
@@ -0,0 +1,12 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+void __attribute__ ((noinline)) foo()
+{
+ ALTER_REGS();
+ // Throw the except and expect returning to main
+ throw 1;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C
new file mode 100644
index 00000000000..3b809642ab7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C
@@ -0,0 +1,16 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+/* Test situation 1: Stack really realign without DRAP */
+void __attribute__ ((noinline))
+foo ()
+{
+ int __attribute__ ((aligned(64))) a=1;
+ if (check_int (&a, __alignof__(a)) != a)
+ abort ();
+ ALTER_REGS();
+ throw a;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C
new file mode 100644
index 00000000000..1569ed84b7d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C
@@ -0,0 +1,29 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+/* Test situation 2: stack really realign with DRAP reg CX */
+void __attribute__ ((noinline))
+foo ()
+{
+ int __attribute__ ((aligned(64))) a=4;
+ char * s = (char *) __builtin_alloca (a + 1);
+
+ copy (s, a);
+ if (__builtin_strncmp (s, "good", a) != 0)
+ {
+#ifdef DEBUG
+ s[a] = '\0';
+ printf ("Failed: %s != good\n", s);
+#endif
+ abort ();
+ }
+
+ if (check_int (&a, __alignof__(a)) != a)
+ abort ();
+
+ ALTER_REGS();
+ throw a;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C
new file mode 100644
index 00000000000..48eddaf5565
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C
@@ -0,0 +1,35 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+/* Test situation 3: Stack realign really happen with DRAP reg DI */
+void __attribute__ ((noinline)) __attribute__ ((regparm(3)))
+bar (int arg1, int arg2, int arg3)
+{
+ int __attribute__ ((aligned(64))) a=1;
+ char * s = (char *) __builtin_alloca (arg3 + 1);
+
+ copy (s, arg3);
+ if (__builtin_strncmp (s, "good", arg3) != 0)
+ {
+#ifdef DEBUG
+ s[arg3] = '\0';
+ printf ("Failed: %s != good\n", s);
+#endif
+ abort ();
+ }
+
+ if (check_int (&a, __alignof__(a)) != a)
+ abort ();
+
+ ALTER_REGS();
+ throw arg1+arg2+arg3+a;
+}
+
+void
+foo()
+{
+ bar (1,2,3);
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C
new file mode 100644
index 00000000000..dacbd3dede9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C
@@ -0,0 +1,17 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+volatile int __attribute__ ((aligned(32))) g_a=1;
+/* Test situation 4: no Drap and stack realign doesn't really happen */
+void __attribute__ ((noinline))
+foo()
+{
+ int i;
+ ALTER_REGS();
+ for (i=0; i < 10; i++)
+ g_a++;
+ throw g_a;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C
new file mode 100644
index 00000000000..fde430bfb72
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C
@@ -0,0 +1,31 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+double g_f=1.0;
+/* Test situation 5: Stack realign dosn't really happen with DRAP reg CX */
+void __attribute__ ((noinline)) __attribute__ ((regparm(2)))
+bar(int arg1, int arg2, int arg3, int arg4)
+{
+ char * s = (char *) __builtin_alloca (arg4 + 1);
+
+ copy (s, arg4);
+ if (__builtin_strncmp (s, "good", arg4) != 0)
+ {
+#ifdef DEBUG
+ s[arg4] = '\0';
+ printf ("Failed: %s != good\n", s);
+#endif
+ abort ();
+ }
+ ALTER_REGS();
+ if (g_f) throw arg1+arg2+arg3+ g_f;
+}
+
+void __attribute__((noinline))
+foo()
+{
+ bar(1,2,3,4);
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C
new file mode 100644
index 00000000000..7c9dee13338
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C
@@ -0,0 +1,31 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+double g_f=1.0;
+/* Test situation 6: Stack realign dosn't really happen with DRAP reg DI */
+void __attribute__ ((noinline)) __attribute__ ((regparm(3)))
+bar(int arg1, int arg2, int arg3, int arg4)
+{
+ char * s = (char *) __builtin_alloca (arg4 + 1);
+
+ copy (s, arg4);
+ if (__builtin_strncmp (s, "good", arg4) != 0)
+ {
+#ifdef DEBUG
+ s[arg4] = '\0';
+ printf ("Failed: %s != good\n", s);
+#endif
+ abort ();
+ }
+ ALTER_REGS();
+ if (g_f) throw arg1+arg2+arg3+ g_f;
+}
+
+void __attribute__((noinline))
+foo()
+{
+ bar(1,2,3,4);
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C
index 0fd60275b53..d2edb1953a3 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C
@@ -20,5 +20,5 @@ double foo (void)
return v.a[2];
}
-/* { dg-final { scan-tree-dump "Replaced .*iftmp.* != 0B. with .1" "forwprop1" } } */
+/* { dg-final { scan-tree-dump "Replaced .* != 0B. with .1" "forwprop1" } } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c
new file mode 100644
index 00000000000..167da24b889
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c
@@ -0,0 +1,21 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-std=gnu99 -mpreferred-stack-boundary=2" } */
+
+/* Simple test of vararg passing for problematic types with and without
+ double values passed between them. */
+
+#define DTYPE _Decimal128
+#define ONE 1.0dl
+#define THREE 3.0dl
+#define SEVEN 7.0dl
+#define ELEVEN 11.0dl
+#define INTS 4
+
+#include "func-vararg-alternate.h"
+
+int
+main ()
+{
+ doit ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c
new file mode 100644
index 00000000000..c1b349c6728
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c
@@ -0,0 +1,118 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-std=gnu99 -mpreferred-stack-boundary=2" } */
+
+/* C99 6.5.2.2 Function calls.
+ Test passing varargs of the combination of decimal float types and
+ other types. */
+
+#include <stdarg.h>
+
+extern void abort (void);
+static int failcnt = 0;
+
+/* Support compiling the test to report individual failures; default is
+ to abort as soon as a check fails. */
+#ifdef DBG
+#include <stdio.h>
+#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
+#else
+#define FAILURE abort ();
+#endif
+
+/* Supposing the list of varying number of arguments is:
+ unsigned int, _Decimal128, double, _Decimal32, _Decimal64. */
+
+static _Decimal32
+vararg_d32 (unsigned arg, ...)
+{
+ va_list ap;
+ _Decimal32 result;
+
+ va_start (ap, arg);
+
+ va_arg (ap, unsigned int);
+ va_arg (ap, _Decimal128);
+ va_arg (ap, double);
+ result = va_arg (ap, _Decimal32);
+
+ va_end (ap);
+ return result;
+}
+
+static _Decimal32
+vararg_d64 (unsigned arg, ...)
+{
+ va_list ap;
+ _Decimal64 result;
+
+ va_start (ap, arg);
+
+ va_arg (ap, unsigned int);
+ va_arg (ap, _Decimal128);
+ va_arg (ap, double);
+ va_arg (ap, _Decimal32);
+ result = va_arg (ap, _Decimal64);
+
+ va_end (ap);
+ return result;
+}
+
+static _Decimal128
+vararg_d128 (unsigned arg, ...)
+{
+ va_list ap;
+ _Decimal128 result;
+
+ va_start (ap, arg);
+
+ va_arg (ap, unsigned int);
+ result = va_arg (ap, _Decimal128);
+
+ va_end (ap);
+ return result;
+}
+
+static unsigned int
+vararg_int (unsigned arg, ...)
+{
+ va_list ap;
+ unsigned int result;
+
+ va_start (ap, arg);
+
+ result = va_arg (ap, unsigned int);
+
+ va_end (ap);
+ return result;
+}
+
+static double
+vararg_double (unsigned arg, ...)
+{
+ va_list ap;
+ float result;
+
+ va_start (ap, arg);
+
+ va_arg (ap, unsigned int);
+ va_arg (ap, _Decimal128);
+ result = va_arg (ap, double);
+
+ va_end (ap);
+ return result;
+}
+
+
+int
+main ()
+{
+ if (vararg_d32 (3, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 3.0df) FAILURE
+ if (vararg_d64 (4, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 4.0dd) FAILURE
+ if (vararg_d128 (1, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 1.0dl) FAILURE
+ if (vararg_int (0, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 0) FAILURE
+ if (vararg_double (2, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 2.0) FAILURE
+
+ if (failcnt != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/alloca-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-1.c
new file mode 100644
index 00000000000..1370f63c292
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-1.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+void
+foo (int size)
+{
+ char *p = __builtin_alloca (size + 1);
+ aligned i;
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+}
+
+int
+main()
+{
+ foo (5);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-1.c
new file mode 100644
index 00000000000..38b384e7cca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-1.c
@@ -0,0 +1,9 @@
+/* PR 11184 */
+/* Origin: Dara Hazeghi <dhazeghi@yahoo.com> */
+
+void *
+objc_msg_sendv (char * arg_frame, void (*foo)())
+{
+ return __builtin_apply ( foo, arg_frame, 4);
+}
+
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
new file mode 100644
index 00000000000..a1ba20fce53
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
@@ -0,0 +1,30 @@
+/* PR target/12503 */
+/* Origin: <pierre.nguyen-tuong@asim.lip6.fr> */
+
+/* Verify that __builtin_apply behaves correctly on targets
+ with pre-pushed arguments (e.g. SPARC). */
+
+/* { dg-do run } */
+
+
+#define INTEGER_ARG 5
+
+extern void abort(void);
+
+void foo(char *name, double d, double e, double f, int g)
+{
+ if (g != INTEGER_ARG)
+ abort();
+}
+
+void bar(char *name, ...)
+{
+ __builtin_apply(foo, __builtin_apply_args(), 64);
+}
+
+int main(void)
+{
+ bar("eeee", 5.444567, 8.90765, 4.567789, INTEGER_ARG);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-3.c
new file mode 100644
index 00000000000..1335d09022a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-3.c
@@ -0,0 +1,31 @@
+/* PR middle-end/12210 */
+/* Origin: Ossadchy Yury A. <waspcoder@mail.ru> */
+
+/* This used to fail on i686 because the argument was not copied
+ to the right location by __builtin_apply after the direct call. */
+
+/* { dg-do run } */
+
+
+#define INTEGER_ARG 5
+
+extern void abort(void);
+
+void foo(int arg)
+{
+ if (arg != INTEGER_ARG)
+ abort();
+}
+
+void bar(int arg)
+{
+ foo(arg);
+ __builtin_apply(foo, __builtin_apply_args(), 16);
+}
+
+int main(void)
+{
+ bar(INTEGER_ARG);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-4.c
new file mode 100644
index 00000000000..28dc6106d07
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-4.c
@@ -0,0 +1,29 @@
+/* PR tree-optimization/20076 */
+/* { dg-do run } */
+
+extern void abort (void);
+
+double
+foo (int arg)
+{
+ if (arg != 116)
+ abort();
+ return arg + 1;
+}
+
+inline double
+bar (int arg)
+{
+ foo (arg);
+ __builtin_return (__builtin_apply ((void (*) ()) foo,
+ __builtin_apply_args (), 16));
+}
+
+int
+main (int argc, char **argv)
+{
+ if (bar (116) != 117.0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-return-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-return-1.c
new file mode 100644
index 00000000000..75c9acdf72a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-return-1.c
@@ -0,0 +1,34 @@
+/* PR middle-end/11151 */
+/* Originator: Andrew Church <gcczilla@achurch.org> */
+/* { dg-do run } */
+
+/* This used to fail on SPARC because the (undefined) return
+ value of 'bar' was overwriting that of 'foo'. */
+
+extern void abort(void);
+
+int foo(int n)
+{
+ return n+1;
+}
+
+int bar(int n)
+{
+ __builtin_return(__builtin_apply((void (*)(void))foo, __builtin_apply_args(), 64));
+}
+
+char *g;
+
+int main(void)
+{
+ /* Allocate 64 bytes on the stack to make sure that __builtin_apply
+ can read at least 64 bytes above the return address. */
+ char dummy[64];
+
+ g = dummy;
+
+ if (bar(1) != 2)
+ abort();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/check.h b/gcc/testsuite/gcc.dg/torture/stackalign/check.h
new file mode 100644
index 00000000000..af198851274
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/check.h
@@ -0,0 +1,36 @@
+#include <stddef.h>
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" void abort (void);
+#else
+extern void abort (void);
+#endif
+
+int
+check_int (int *i, int align)
+{
+ *i = 20;
+ if ((((ptrdiff_t) i) & (align - 1)) != 0)
+ {
+#ifdef DEBUG
+ printf ("\nUnalign address (%d): %p!\n", align, i);
+#endif
+ abort ();
+ }
+ return *i;
+}
+
+void
+check (void *p, int align)
+{
+ if ((((ptrdiff_t) p) & (align - 1)) != 0)
+ {
+#ifdef DEBUG
+ printf ("\nUnalign address (%d): %p!\n", align, p);
+#endif
+ abort ();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/comp-goto-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/comp-goto-1.c
new file mode 100644
index 00000000000..7558f01e2e8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/comp-goto-1.c
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+
+#ifdef STACK_SIZE
+#define DEPTH ((STACK_SIZE) / 512 + 1)
+#else
+#define DEPTH 1000
+#endif
+
+extern void abort (void);
+extern void exit (int);
+
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+int
+x(a)
+{
+ __label__ xlab;
+ void y(a)
+ {
+ void *x = &&llab;
+ if (a==-1)
+ goto *x;
+ if (a==0)
+ goto xlab;
+ llab:
+ y (a-1);
+ }
+ y (a);
+ xlab:;
+ return a;
+}
+#endif
+
+int
+main ()
+{
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+ if (x (DEPTH) != DEPTH)
+ abort ();
+#endif
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/fastcall-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/fastcall-1.c
new file mode 100644
index 00000000000..d1cda10103b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/fastcall-1.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+__attribute__ ((fastcall))
+void
+foo (int j, int k, int m, int n, int o)
+{
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ if (i != 20 || j != 1 || k != 2 || m != 3 || n != 4 || o != 5)
+ abort ();
+}
+
+int
+main()
+{
+ foo (1, 2, 3, 4, 5);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/global-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/global-1.c
new file mode 100644
index 00000000000..284daad0eaf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/global-1.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+foo (void)
+{
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+}
+
+int
+main()
+{
+ foo ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/inline-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/inline-1.c
new file mode 100644
index 00000000000..11e71c60a4c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/inline-1.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+static void
+inline __attribute__((always_inline))
+foo (void)
+{
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+}
+
+int
+main()
+{
+ foo ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/inline-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/inline-2.c
new file mode 100644
index 00000000000..fd51b5f7110
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/inline-2.c
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+static void
+inline __attribute__((always_inline))
+foo (int size)
+{
+ char *p = __builtin_alloca (size + 1);
+ aligned i;
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+}
+
+int
+main()
+{
+ foo (5);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-1.c
new file mode 100644
index 00000000000..4e2c8729af0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-1.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+foo (void)
+{
+ aligned j;
+
+ void bar ()
+ {
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ if (check_int (&j, __alignof__(j)) != j)
+ abort ();
+
+ j = -20;
+ }
+ bar ();
+
+ if (j != -20)
+ abort ();
+
+ if (check_int (&j, __alignof__(j)) != j)
+ abort ();
+}
+
+int
+main()
+{
+ foo ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-2.c
new file mode 100644
index 00000000000..d54e3b92c9f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-2.c
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+foo (void)
+{
+ aligned j;
+
+ __attribute__ ((__noinline__))
+ void bar ()
+ {
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ if (check_int (&j, __alignof__(j)) != j)
+ abort ();
+
+ j = -20;
+ }
+ bar ();
+
+ if (j != -20)
+ abort ();
+
+ if (check_int (&j, __alignof__(j)) != j)
+ abort ();
+}
+
+int
+main()
+{
+ foo ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-3.c
new file mode 100644
index 00000000000..373299185a8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-3.c
@@ -0,0 +1,62 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+copy (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+void
+foo (int size)
+{
+ aligned j;
+
+ __attribute__ ((__noinline__))
+ void bar (int size)
+ {
+ char *p = __builtin_alloca (size + 1);
+ aligned i;
+
+ copy (p, size);
+ if (strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ if (check_int (&j, __alignof__(j)) != j)
+ abort ();
+
+ j = -20;
+ }
+ bar (size);
+
+ if (j != -20)
+ abort ();
+
+ if (check_int (&j, __alignof__(j)) != j)
+ abort ();
+}
+
+int
+main()
+{
+ foo (5);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-4.c
new file mode 100644
index 00000000000..60322fc62b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-4.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int n;
+
+void
+g (void)
+{
+ __label__ lab;
+ void h (void)
+ {
+ aligned t;
+ if (check_int (&t, __alignof__(t)) != t)
+ abort ();
+ if (n+t == 0) goto lab;
+ }
+ h();
+lab:
+ return;
+}
+
+int main()
+{
+ g();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-5.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-5.c
new file mode 100644
index 00000000000..95eba0482f6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-5.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+
+extern void abort (void);
+extern void exit (int);
+
+#ifndef NO_TRAMPOLINES
+static void recursive (int n, void (*proc) (void))
+{
+ __label__ l1;
+
+ void do_goto (void)
+ {
+ goto l1;
+ }
+
+ if (n == 3)
+ recursive (n - 1, do_goto);
+ else if (n > 0)
+ recursive (n - 1, proc);
+ else
+ (*proc) ();
+ return;
+
+l1:
+ if (n == 3)
+ exit (0);
+ else
+ abort ();
+}
+
+int main ()
+{
+ recursive (10, abort);
+ abort ();
+}
+#else
+int main () { return 0; }
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-6.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-6.c
new file mode 100644
index 00000000000..d853825feb7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/nested-6.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+#ifndef NO_TRAMPOLINES
+
+typedef __SIZE_TYPE__ size_t;
+extern void abort (void);
+extern void exit (int);
+extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
+
+int main ()
+{
+ __label__ nonlocal;
+ int compare (const void *a, const void *b)
+ {
+ goto nonlocal;
+ }
+
+ char array[3];
+ qsort (array, 3, 1, compare);
+ abort ();
+
+ nonlocal:
+ exit (0);
+}
+
+#else
+int main() { return 0; }
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-1.c
new file mode 100644
index 00000000000..263d4486cf7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-1.c
@@ -0,0 +1,55 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+int global;
+
+static void foo(void) __attribute__((noinline));
+
+static void foo(void)
+{
+ global = 1;
+}
+
+static void bar(void)
+{
+ foo ();
+}
+
+int execute(int cmd)
+{
+ __label__ start;
+
+ void raise(void)
+ {
+ goto start;
+ }
+
+ int last = -1;
+
+ bar ();
+
+ last = 0;
+
+start:
+
+ if (last == 0)
+ while (1)
+ {
+ last = 1;
+ raise ();
+ }
+
+ if (last == 0)
+ return 0;
+ else
+ return cmd;
+}
+
+int main(void)
+{
+ if (execute (1) == 0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-2.c
new file mode 100644
index 00000000000..5a64d541964
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-2.c
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+int global;
+
+static void foo(void) __attribute__((noinline));
+
+static void foo(void)
+{
+ global = 1;
+}
+
+static void bar(void)
+{
+ foo ();
+ global = 0;
+}
+
+int execute(int cmd)
+{
+ __label__ start;
+
+ void raise(void)
+ {
+ goto start;
+ }
+
+ int last = -1;
+
+ bar ();
+
+ last = 0;
+
+start:
+
+ if (last == 0)
+ while (1)
+ {
+ last = 1;
+ raise ();
+ }
+
+ if (last == 0)
+ return 0;
+ else
+ return cmd;
+}
+
+int main(void)
+{
+ if (execute (1) == 0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-3.c
new file mode 100644
index 00000000000..3afc8cc6a31
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-3.c
@@ -0,0 +1,42 @@
+/* { dg-do run } */
+
+#ifndef NO_TRAMPOLINES
+extern void abort (void);
+
+int x(int a, int b)
+{
+ __label__ xlab;
+
+ void y(int b)
+ {
+ switch (b)
+ {
+ case 1: goto xlab;
+ case 2: goto xlab;
+ }
+ }
+
+ a = a + 2;
+ y (b);
+
+ xlab:
+ return a;
+}
+
+int main ()
+{
+ int i, j;
+
+ for (j = 1; j <= 2; ++j)
+ for (i = 1; i <= 2; ++i)
+ {
+ int a = x (j, i);
+ if (a != 2 + j)
+ abort ();
+ }
+
+ return 0;
+}
+#else
+int main() { return 0; }
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-4.c
new file mode 100644
index 00000000000..3673f1ac337
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-4.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+
+extern void abort (void);
+extern void exit (int);
+
+#ifdef STACK_SIZE
+#define DEPTH ((STACK_SIZE) / 512 + 1)
+#else
+#define DEPTH 1000
+#endif
+
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+int
+
+x(a)
+{
+ __label__ xlab;
+ void y(a)
+ {
+ if (a==0)
+ goto xlab;
+ y (a-1);
+ }
+ y (a);
+ xlab:;
+ return a;
+}
+#endif
+
+int
+main ()
+{
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+ if (x (DEPTH) != DEPTH)
+ abort ();
+#endif
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-5.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-5.c
new file mode 100644
index 00000000000..08ca95d765c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-5.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+
+#if !defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+extern void abort (void);
+extern void exit (int);
+int s(i){if(i>0){__label__ l1;int f(int i){if(i==2)goto l1;return 0;}return f(i);l1:;}return 1;}
+int x(){return s(0)==1&&s(1)==0&&s(2)==1;}
+int main(){if(x()!=1)abort();exit(0);}
+#else
+int main(){ exit (0); }
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-1.c
new file mode 100644
index 00000000000..b68c3d07ec1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-1.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+
+void
+f ()
+{
+ unsigned long tmp[4] __attribute__((aligned(16)));
+ asm("movaps %%xmm0, (%0)" : : "r" (tmp) : "memory");
+}
+
+int
+main()
+{
+ f();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-2.c
new file mode 100644
index 00000000000..9a039eb2bf5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-2.c
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+typedef __SIZE_TYPE__ size_t;
+#define ALIGNMENT 256
+int main(void)
+{
+ int a[ALIGNMENT/sizeof(int)] __attribute__((aligned(ALIGNMENT)));
+ check (&a, ALIGNMENT);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-3.c
new file mode 100644
index 00000000000..1c1ddd1dd74
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-3.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+typedef __SIZE_TYPE__ size_t;
+#define ALIGNMENT 256
+int main(void)
+{
+ int a[ALIGNMENT/sizeof(int)] __attribute__((aligned(ALIGNMENT)));
+ check (&a, ALIGNMENT);
+ int b[ALIGNMENT/sizeof(int)] __attribute__((aligned(ALIGNMENT)));
+ check (&b, ALIGNMENT);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/regparm-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/regparm-1.c
new file mode 100644
index 00000000000..9dac024cc1b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/regparm-1.c
@@ -0,0 +1,60 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int test_nested (int i)
+{
+ aligned y;
+
+ int __attribute__ ((__noinline__, __regparm__(2))) foo (int j, int k, int l)
+ {
+ aligned x;
+
+ if (check_int (&x, __alignof__(x)) != x)
+ abort ();
+
+ if (x != 20)
+ abort ();
+
+ return i + j + k + l;
+ }
+
+ if (check_int (&y, __alignof__(y)) != y)
+ abort ();
+
+ if (y != 20)
+ abort ();
+
+ return foo(i, i+1, i+2) * i;
+}
+
+int __attribute__ ((__noinline__, __regparm__(3), __force_align_arg_pointer__))
+test_realigned (int j, int k, int l)
+{
+ aligned y;
+
+ if (check_int (&y, __alignof__(y)) != y)
+ abort ();
+
+ if (y != 20)
+ abort ();
+
+ return j + k + l;
+}
+
+int main ()
+{
+ if (test_nested(10) != 430)
+ abort ();
+
+ if (test_realigned(10, 11, 12) != 33)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/ret-struct-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/ret-struct-1.c
new file mode 100644
index 00000000000..163e54c5908
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/ret-struct-1.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+extern void abort();
+typedef struct my_struct
+{
+ char str[31];
+} stype ;
+
+stype g_s;
+
+stype __attribute__((noinline))
+foo (char arg1, char arg2, char arg3)
+{
+ stype __attribute__((aligned(ALIGNMENT))) s;
+ s.str[0] = arg1;
+ s.str[1] = arg2;
+ s.str[30] = arg3;
+ check(&s, ALIGNMENT);
+ return s;
+}
+
+int main()
+{
+ g_s = foo(1,2,3);
+
+ if (g_s.str[0] != 1 || g_s.str[1] != 2 || g_s.str[30] !=3)
+ abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-1.c
new file mode 100644
index 00000000000..6ab67e395fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-1.c
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+
+extern int strcmp(const char *, const char *);
+extern char *strcpy(char *, const char *);
+extern void abort(void);
+extern void exit(int);
+
+void *buf[20];
+
+void __attribute__((noinline))
+sub2 (void)
+{
+ __builtin_longjmp (buf, 1);
+}
+
+int
+main ()
+{
+ char *p = 0;
+
+ p = (char *) __builtin_alloca (20);
+
+ strcpy (p, "test");
+
+ if (__builtin_setjmp (buf))
+ {
+ if (strcmp (p, "test") != 0)
+ abort ();
+
+ exit (0);
+ }
+
+ {
+ int *q = (int *) __builtin_alloca (p[2] * sizeof (int));
+ int i;
+
+ for (i = 0; i < p[2]; i++)
+ q[i] = 0;
+
+ while (1)
+ sub2 ();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-2.c
new file mode 100644
index 00000000000..c93ffa8673e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-2.c
@@ -0,0 +1,46 @@
+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
+
+#include <setjmp.h>
+#include <signal.h>
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+static jmp_buf segv_jmpbuf;
+
+static void segv_handler(int seg)
+{
+ __builtin_longjmp(segv_jmpbuf, 1);
+}
+
+static int is_addressable(void *p, size_t size)
+{
+ volatile char * volatile cp = (volatile char *)p;
+ volatile int ret;
+ struct sigaction sa, origsa;
+ sigset_t mask;
+
+ sa.sa_handler = segv_handler;
+ sa.sa_flags = 0;
+ sigfillset(&sa.sa_mask);
+ sigaction(SIGSEGV, &sa, &origsa);
+ sigprocmask(SIG_SETMASK, NULL, &mask);
+
+ if (__builtin_setjmp(segv_jmpbuf) == 0) {
+ while(size--)
+ *cp++;
+ ret = 1;
+ } else
+ ret = 0;
+
+ sigaction(SIGSEGV, &origsa, NULL);
+ sigprocmask(SIG_SETMASK, &mask, NULL);
+
+ return ret;
+}
+
+int main(int argc, char **argv)
+{
+ is_addressable(0x0, 1);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-3.c
new file mode 100644
index 00000000000..fee0d281ffa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-3.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+
+#include <setjmp.h>
+
+extern void abort (void);
+
+jmp_buf buf;
+
+void raise0(void)
+{
+ __builtin_longjmp (buf, 1);
+}
+
+int execute(int cmd)
+{
+ int last = 0;
+
+ if (__builtin_setjmp (buf) == 0)
+ while (1)
+ {
+ last = 1;
+ raise0 ();
+ }
+
+ if (last == 0)
+ return 0;
+ else
+ return cmd;
+}
+
+int main(void)
+{
+ if (execute (1) == 0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-4.c
new file mode 100644
index 00000000000..d1671223adb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-4.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+
+#include <setjmp.h>
+
+extern void abort (void);
+
+jmp_buf buf;
+
+void raise0(void)
+{
+ __builtin_longjmp (buf, 1);
+}
+
+int execute(int cmd)
+{
+ int last = 0;
+
+ __builtin_setjmp (buf);
+
+ if (last == 0)
+ while (1)
+ {
+ last = 1;
+ raise0 ();
+ }
+
+ if (last == 0)
+ return 0;
+ else
+ return cmd;
+}
+
+int main(void)
+{
+ if (execute (1) == 0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/sibcall-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/sibcall-1.c
new file mode 100644
index 00000000000..8c174758fc1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/sibcall-1.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+
+extern int ok (int);
+extern void exit ();
+static int gen_x86_64_shrd (int);
+static int
+gen_x86_64_shrd(int a __attribute__ ((__unused__)))
+{
+ return 0;
+}
+
+extern int gen_x86_shrd_1 (int);
+extern void ix86_split_ashr (int);
+
+void
+ix86_split_ashr (int mode)
+{
+ (mode != 0
+ ? ok
+ : gen_x86_64_shrd) (0);
+}
+
+volatile int one = 1;
+int
+main (void)
+{
+ ix86_split_ashr (one);
+ return 1;
+}
+
+int
+ok (int i)
+{
+ exit (i);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp b/gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp
new file mode 100644
index 00000000000..3574e4dc891
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp
@@ -0,0 +1,52 @@
+# Copyright (C) 2008
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# This harness is for tests that should be run at all optimisation levels.
+
+load_lib gcc-dg.exp
+
+# Only run on targets which support automatic stack alignment.
+if { ![check_effective_target_automatic_stack_alignment] } then {
+ return
+}
+
+set additional_flags ""
+if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
+ lappend additional_flags "-mstackrealign"
+ lappend additional_flags "-mpreferred-stack-boundary=5"
+}
+
+dg-init
+
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags
+if { [check_effective_target_fpic] } then {
+ set pic_additional_flags $additional_flags
+ lappend pic_additional_flags "-fpic"
+ gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $pic_additional_flags
+}
+
+if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
+ lappend additional_flags "-mforce-drap"
+ gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags
+ if { [check_effective_target_fpic] } then {
+ set pic_additional_flags $additional_flags
+ lappend pic_additional_flags "-fpic"
+ gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $pic_additional_flags
+ }
+}
+
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/struct-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/struct-1.c
new file mode 100644
index 00000000000..79e3733484b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/struct-1.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+void
+foo (void)
+{
+ struct i
+ {
+ aligned i;
+ } i;
+
+ if (check_int (&i.i, __alignof__(i.i)) != i.i)
+ abort ();
+}
+
+int
+main()
+{
+ foo ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/vararg-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-1.c
new file mode 100644
index 00000000000..62b236522ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-1.c
@@ -0,0 +1,59 @@
+/* { dg-do run } */
+
+#include <stdarg.h>
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+void
+foo (const char *fmt, ...)
+{
+ va_list arg;
+ char *p;
+ aligned i;
+ int size;
+ double x;
+
+ va_start (arg, fmt);
+ size = va_arg (arg, int);
+ if (size != 5)
+ abort ();
+ p = __builtin_alloca (size + 1);
+
+ x = va_arg (arg, double);
+ if (x != 5.0)
+ abort ();
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+ va_end (arg);
+}
+
+int
+main()
+{
+ foo ("foo", 5, 5.0);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/vararg-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-2.c
new file mode 100644
index 00000000000..00b723b0dc4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-2.c
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdarg.h>
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+void
+test (va_list arg)
+{
+ char *p;
+ aligned i;
+ int size;
+ double x;
+
+ size = va_arg (arg, int);
+ if (size != 5)
+ abort ();
+
+ p = __builtin_alloca (size + 1);
+
+ x = va_arg (arg, double);
+ if (x != 5.0)
+ abort ();
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+}
+
+void
+foo (const char *fmt, ...)
+{
+ va_list arg;
+ va_start (arg, fmt);
+ test (arg);
+ va_end (arg);
+}
+int
+main()
+{
+ foo ("foo", 5, 5.0);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/20060512-1.c b/gcc/testsuite/gcc.target/i386/20060512-1.c
index 3defe648ba7..8109f94b75c 100644
--- a/gcc/testsuite/gcc.target/i386/20060512-1.c
+++ b/gcc/testsuite/gcc.target/i386/20060512-1.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-std=gnu99 -msse2" } */
+/* { dg-options "-std=gnu99 -msse2 -mpreferred-stack-boundary=4" } */
#include "sse2-check.h"
@@ -28,7 +28,7 @@ sse2_test (void)
int result;
asm ("pushl %esi"); /* Disalign runtime stack. */
result = self_aligning_function (g_1, g_2);
- asm ("popl %esi");
if (result != 42)
abort ();
+ asm ("popl %esi");
}
diff --git a/gcc/testsuite/gcc.target/i386/20060512-2.c b/gcc/testsuite/gcc.target/i386/20060512-2.c
index 0e446cf899e..fe1af563578 100644
--- a/gcc/testsuite/gcc.target/i386/20060512-2.c
+++ b/gcc/testsuite/gcc.target/i386/20060512-2.c
@@ -1,12 +1,12 @@
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-std=gnu99" } */
+/* { dg-options "-std=gnu99 -mpreferred-stack-boundary=4" } */
int
outer_function (int x, int y)
{
int __attribute__ ((__noinline__, __force_align_arg_pointer__))
nested_function (int x, int y)
- { /* { dg-error "force_align_arg_pointer not supported for nested functions" } */
+ {
return (x + y);
}
return (3 + nested_function (x, y));
diff --git a/gcc/testsuite/gcc.target/i386/20060512-3.c b/gcc/testsuite/gcc.target/i386/20060512-3.c
index 5ffa8129e38..847f0eb6d35 100644
--- a/gcc/testsuite/gcc.target/i386/20060512-3.c
+++ b/gcc/testsuite/gcc.target/i386/20060512-3.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-std=gnu99 -msse2 -mstackrealign" } */
+/* { dg-options "-std=gnu99 -msse2 -mstackrealign -mpreferred-stack-boundary=4" } */
#include "sse2-check.h"
@@ -28,7 +28,7 @@ sse2_test (void)
int result;
asm ("pushl %esi"); /* Disalign runtime stack. */
result = self_aligning_function (g_1, g_2);
- asm ("popl %esi");
if (result != 42)
abort ();
+ asm ("popl %esi");
}
diff --git a/gcc/testsuite/gcc.target/i386/20060512-4.c b/gcc/testsuite/gcc.target/i386/20060512-4.c
index f2dd26486b6..ee7b8a4ad88 100644
--- a/gcc/testsuite/gcc.target/i386/20060512-4.c
+++ b/gcc/testsuite/gcc.target/i386/20060512-4.c
@@ -1,12 +1,12 @@
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-mstackrealign" } */
+/* { dg-options "-mstackrealign -mpreferred-stack-boundary=4" } */
int
outer_function (int x, int y)
{
int __attribute__ ((__noinline__))
nested_function (int x, int y)
- { /* { dg-warning "-mstackrealign ignored for nested functions" } */
+ {
return (x + y);
}
return (3 + nested_function (x, y));
diff --git a/gcc/testsuite/gcc.target/i386/align-main-1.c b/gcc/testsuite/gcc.target/i386/align-main-1.c
new file mode 100644
index 00000000000..5bbc101c0c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/align-main-1.c
@@ -0,0 +1,25 @@
+/* Test for stack alignment when PREFERRED_STACK_BOUNDARY < alignment
+ of local variable. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mpreferred-stack-boundary=6 -mincoming-stack-boundary=6" } */
+/* { dg-final { scan-assembler "and\[lq\]?\[\\t \]*\\$-128,\[\\t \]*%\[re\]?sp" } } */
+/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]*\\$-64,\[\\t \]*%\[re\]?sp" } } */
+
+#include <stddef.h>
+
+#define ALIGNMENT 128
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+extern void abort(void);
+
+void check(void * a)
+{
+ if (((ptrdiff_t)a & (ALIGNMENT-1)) != 0)
+ abort();
+}
+
+int main()
+{
+ aligned a = 1;
+ check(&a);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/align-main-2.c b/gcc/testsuite/gcc.target/i386/align-main-2.c
new file mode 100644
index 00000000000..df45f0e5106
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/align-main-2.c
@@ -0,0 +1,25 @@
+/* Test for stack alignment when PREFERRED_STACK_BOUNDARY > alignment
+ of local variable. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mpreferred-stack-boundary=6 -mincoming-stack-boundary=6" } */
+/* { dg-final { scan-assembler "and\[lq\]?\[\\t \]*\\$-64,\[\\t \]*%\[re\]?sp" } } */
+/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]*\\$-128,\[\\t \]*%\[re\]?sp" } } */
+
+#include <stddef.h>
+
+#define ALIGNMENT 32
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+extern void abort(void);
+
+void check(void * a)
+{
+ if (((ptrdiff_t)a & (ALIGNMENT-1)) != 0)
+ abort();
+}
+
+int main()
+{
+ aligned a = 1;
+ check(&a);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr32000-2.c b/gcc/testsuite/gcc.target/i386/pr32000-2.c
new file mode 100644
index 00000000000..7230258045d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32000-2.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ilp32 && dfp } */
+/* { dg-options "-O -msse2 -std=gnu99 -mpreferred-stack-boundary=2" } */
+
+#include "sse2-check.h"
+
+typedef struct { _Decimal128 f __attribute__((packed)); } packed;
+
+_Decimal128 __attribute__((noinline))
+foo (_Decimal128 a1, _Decimal128 a2, _Decimal128 a3, _Decimal128 a4,
+ _Decimal128 a5, _Decimal128 a6, _Decimal128 a7, _Decimal128 a8,
+ int b1, int b2, int b3, int b4, int b5, int b6, int b7, packed y)
+{
+ return y.f;
+}
+
+void
+sse2_test (void)
+{
+ packed x;
+ _Decimal128 y = -1;
+ x.f = y;
+ y = foo (0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, -1, x);
+ if (__builtin_memcmp (&y, &x.f, sizeof (y)))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/asm-1.c b/gcc/testsuite/gcc.target/i386/stackalign/asm-1.c
new file mode 100644
index 00000000000..e4d4f20bb18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/stackalign/asm-1.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-mpreferred-stack-boundary=2" } */
+
+/* This case is to detect a compile time regression introduced in stack
+ branch development. */
+f(){asm("%0"::"r"(1.5F));}g(){asm("%0"::"r"(1.5));}
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-1.c b/gcc/testsuite/gcc.target/i386/stackalign/return-1.c
new file mode 100644
index 00000000000..c5b32e5c421
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/stackalign/return-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-mpreferred-stack-boundary=2" } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+ development. */
+
+double
+foo (void)
+{
+}
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-2.c b/gcc/testsuite/gcc.target/i386/stackalign/return-2.c
new file mode 100644
index 00000000000..113e71b80da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/stackalign/return-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-mpreferred-stack-boundary=2" } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+ development. */
+void baz (void);
+
+double foo (void)
+{
+ baz ();
+ return;
+}
+
+double bar (void)
+{
+ baz ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-3.c b/gcc/testsuite/gcc.target/i386/stackalign/return-3.c
new file mode 100644
index 00000000000..d8ab69bbea0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/stackalign/return-3.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 && dfp } */
+/* { dg-options "-msse -std=gnu99 -mpreferred-stack-boundary=2" } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+ development. */
+_Decimal128 test (void)
+{
+ return 1234123412341234.123412341234dl;
+}
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-4.c b/gcc/testsuite/gcc.target/i386/stackalign/return-4.c
new file mode 100644
index 00000000000..c66c369c8fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/stackalign/return-4.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mpreferred-stack-boundary=4" } */
+/* { dg-final { scan-assembler-not "andl\[^\\n\]*-64,\[^\\n\]*sp" } } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+ development. */
+typedef int aligned __attribute__((aligned(64)));
+
+aligned
+foo (void) { }
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-5.c b/gcc/testsuite/gcc.target/i386/stackalign/return-5.c
new file mode 100644
index 00000000000..84531ddfe29
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/stackalign/return-5.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-mpreferred-stack-boundary=4" } */
+/* { dg-final { scan-assembler-not "andl\[^\\n\]*-64,\[^\\n\]*sp" } } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+ development. */
+struct bar
+{
+ int x;
+} __attribute__((aligned(64)));
+
+
+struct bar
+foo (void) { }
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-6.c b/gcc/testsuite/gcc.target/i386/stackalign/return-6.c
new file mode 100644
index 00000000000..ceadbad1acf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/stackalign/return-6.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-mpreferred-stack-boundary=4" } */
+/* { dg-final { scan-assembler-not "andl\[^\\n\]*-64,\[^\\n\]*sp" } } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+ development. */
+struct bar
+{
+ int x __attribute__((aligned(64)));
+};
+
+
+struct bar
+foo (void) { }
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/stackalign.exp b/gcc/testsuite/gcc.target/i386/stackalign/stackalign.exp
new file mode 100644
index 00000000000..463ba612e0f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/stackalign/stackalign.exp
@@ -0,0 +1,47 @@
+# Copyright (C) 2008
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Exit immediately if this isn't a x86 target.
+if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then {
+ return
+}
+
+load_lib gcc-dg.exp
+
+# Only run on targets which support automatic stack alignment.
+if { ![check_effective_target_automatic_stack_alignment] } then {
+ return
+}
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS "-w"
+}
+
+# Initialize `dg'.
+dg-init
+
+set additional_flags "-mstackrealign"
+
+dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags $DEFAULT_CFLAGS
+
+set additional_flags "-mno-stackrealign"
+
+dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags $DEFAULT_CFLAGS
+
+dg-finish
diff --git a/gcc/testsuite/gfortran.dg/pr36967.f b/gcc/testsuite/gfortran.dg/pr36967.f
new file mode 100644
index 00000000000..4f8589771b8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr36967.f
@@ -0,0 +1,25 @@
+! { dg-options "-O2 -fpredictive-commoning" }
+ subroutine foo(x,y,n)
+ integer n
+ real*8 y(n,n,n),x(n,n,n)
+ integer k, j, i
+ do k = 2, n-1
+ do j = 2, n-1
+ do I = 2, n-1
+ y(i,j,k) = y(i,j,k)
+ + + (x(i-1,j-1,k)
+ + + x(i,j-1,k-1)
+ + + x(i,j+1,k-1)
+ + + x(i,j+1,k+1)
+ + + x(i+1,j,k+1))
+ + + (x(i-1,j-1,k-1)
+ + + x(i+1,j-1,k-1)
+ + + x(i-1,j+1,k-1)
+ + + x(i+1,j+1,k-1)
+ + + x(i-1,j+1,k+1)
+ + + x(i+1,j+1,k+1))
+ enddo
+ enddo
+ enddo
+ return
+ end
diff --git a/gcc/testsuite/gnat.dg/boolean_expr.adb b/gcc/testsuite/gnat.dg/boolean_expr.adb
new file mode 100644
index 00000000000..6ac086dfe6d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/boolean_expr.adb
@@ -0,0 +1,30 @@
+-- PR middle-end/36554
+-- Origin: Laurent Guerby <laurent@guerby.net>
+
+-- { dg-do compile }
+-- { dg-options "-O2" }
+
+package body Boolean_Expr is
+
+ function Long_Float_Is_Valid (X : in Long_Float) return Boolean is
+ Is_Nan : constant Boolean := X /= X;
+ Is_P_Inf : constant Boolean := X > Long_Float'Last;
+ Is_M_Inf : constant Boolean := X < Long_Float'First;
+ Is_Invalid : constant Boolean := Is_Nan or Is_P_Inf or Is_M_Inf;
+ begin
+ return not Is_Invalid;
+ end Long_Float_Is_Valid;
+
+ function S (V : in Long_Float) return String is
+ begin
+ if not Long_Float_Is_Valid (V) then
+ return "INVALID";
+ else
+ return "OK";
+ end if;
+ exception
+ when others =>
+ return "ERROR";
+ end S;
+
+end Boolean_Expr;
diff --git a/gcc/testsuite/gnat.dg/boolean_expr.ads b/gcc/testsuite/gnat.dg/boolean_expr.ads
new file mode 100644
index 00000000000..8190ce77bd5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/boolean_expr.ads
@@ -0,0 +1,5 @@
+package Boolean_Expr is
+
+ function S (V : in Long_Float) return String;
+
+end Boolean_Expr;
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 5f426669265..f56b3f4f212 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -1841,10 +1841,6 @@ proc check_effective_target_unaligned_stack { } {
verbose "check_effective_target_unaligned_stack: using cached result" 2
} else {
set et_unaligned_stack_saved 0
- if { ( [istarget i?86-*-*] || [istarget x86_64-*-*] )
- && (! [istarget *-*-darwin*] ) } {
- set et_unaligned_stack_saved 1
- }
}
verbose "check_effective_target_unaligned_stack: returning $et_unaligned_stack_saved" 2
return $et_unaligned_stack_saved
@@ -2466,3 +2462,14 @@ proc check_effective_target_4byte_wchar_t { } {
int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1];
}]
}
+
+# Return 1 if the target supports automatic stack alignment.
+
+proc check_effective_target_automatic_stack_alignment { } {
+ if { [istarget i?86*-*-*]
+ || [istarget x86_64-*-*] } then {
+ return 1
+ } else {
+ return 0
+ }
+}
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index 63911b3dbe5..94245a4678b 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -1707,7 +1707,7 @@ remove_stmt (gimple stmt)
remove_phi_node (&psi, true);
if (!next
- || !gimple_assign_copy_p (next)
+ || !gimple_assign_ssa_name_copy_p (next)
|| gimple_assign_rhs1 (next) != name)
return;
@@ -1727,9 +1727,10 @@ remove_stmt (gimple stmt)
mark_virtual_ops_for_renaming (stmt);
gsi_remove (&bsi, true);
+ release_defs (stmt);
if (!next
- || !gimple_assign_copy_p (next)
+ || !gimple_assign_ssa_name_copy_p (next)
|| gimple_assign_rhs1 (next) != name)
return;
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 3526de45bb3..22e2e0c4cee 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -1830,9 +1830,7 @@ vect_can_force_dr_alignment_p (const_tree decl, unsigned int alignment)
if (TREE_STATIC (decl))
return (alignment <= MAX_OFILE_ALIGNMENT);
else
- /* This used to be PREFERRED_STACK_BOUNDARY, however, that is not 100%
- correct until someone implements forced stack alignment. */
- return (alignment <= STACK_BOUNDARY);
+ return (alignment <= MAX_STACK_ALIGNMENT);
}