diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-01-15 13:20:06 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-01-15 13:20:06 +0000 |
commit | b6d2952820e82733b0686904a9b9b6134ba78e73 (patch) | |
tree | 0fbbc1c2d3ef4b3e01100c92cf3d83ab35b48950 /gcc | |
parent | aafb9581fe147e93331850662df862f77fd523ae (diff) | |
download | gcc-b6d2952820e82733b0686904a9b9b6134ba78e73.tar.gz |
2009-01-15 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r143392
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@143395 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
81 files changed, 2500 insertions, 838 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3ccd794827..aeab680011b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,137 @@ +2009-01-14 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/38245 + * calls.c (expand_call): Add stack arguments to + CALL_INSN_FUNCTION_USAGE even for pure calls (when + ACCUMULATE_OUTGOING_ARGS) and even for args partially passed + in regs and partially in memory or BLKmode arguments. + (emit_library_call_value_1): Add stack arguments to + CALL_INSN_FUNCTION_USAGE even for pure calls (when + ACCUMULATE_OUTGOING_ARGS). + * dce.c: Include tm_p.h. + (find_call_stack_args): New function. + (deletable_insn_p): Call it for CALL_P insns. Add ARG_STORES + argument. + (mark_insn): Call find_call_stack_args for CALL_Ps. + (prescan_insns_for_dce): Walk insns backwards in bb rather than + forwards. Allocate and free arg_stores bitmap if needed, pass it + down to deletable_insn_p, don't mark stores set in arg_stores + bitmap, clear the bitmap at the beginning of each bb. + * Makefile.in (dce.o): Depend on $(TM_P_H). + +2009-01-14 Michael Meissner <gnu@the-meissners.org> + + PR target/22599 + * i386.c (print_operand): Add tests for 'D', 'C', 'F', 'f' to make + sure the insn is a conditional test (bug 22599). Reformat a few long + lines. + +2009-01-14 Sebastian Pop <sebastian.pop@amd.com> + + PR middle-end/38431 + * graphite.c (get_vdef_before_scop, scop_adjust_vphi): New. + (scop_adjust_phis_for_liveouts): Call scop_adjust_vphi. + (gloog): Do not call cleanup_tree_cfg. + (graphite_transform_loops): Call cleanup_tree_cfg after all + scops have been code generated. + +2009-01-14 Vladimir Makarov <vmakarov@redhat.com> + + * testsuite/g++.dg/torture/pr38811.C: New file. + +2009-01-14 Basile Starynkevitch <basile@starynkevitch.net> + * doc/gty.texi (Invoking the garbage collector): Added new node + and section documenting ggc_collect. + +2009-01-14 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/38826 + PR middle-end/38477 + * tree-ssa-structalias.c (emit_alias_warning): Emit the pointer + initialization notes only if we actually emitted a warning. + (intra_create_variable_infos): Add constraints for a result decl + that is passed by hidden reference. + (build_pred_graph): Mark all related variables non-direct on + address-taking. + +2009-01-14 Nick Clifton <nickc@redhat.com> + + * ira-conflicts.c: Include addresses.h for the definition of + base_reg_class. + (ira_build_conflicts): Use base_reg_class instead of + BASE_REG_CLASS. + * Makefile.in: Add a dependency of ira-conflicts.o on + addresses.h. + +2009-01-13 Vladimir Makarov <vmakarov@redhat.com> + + PR target/38811 + * Makefile.in (ira-lives.o): Add except.h. + + * ira-lives.c: Include except.h. + (process_bb_node_lives): Process can_throw_internal. + +2009-01-13 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/38774 + * combine.c (simplify_set): When undoing cc_use change, don't do + PUT_CODE on the newly created comparison, but instead put back the + old comparison. + +2009-01-13 Joseph Myers <joseph@codesourcery.com> + + * doc/invoke.texi (ARM Options): Update lists of -mcpu and -march + values. Remove duplicate arm8 entry. + +2009-01-13 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/38786 + * graphite.c (expand_scalar_variables_ssa_name): New, outlined from + the SSA_NAME case of expand_scalar_variables_expr. + Set the type of an expression to the type of its assign statement. + (expand_scalar_variables_expr): Also gather the scalar computation + used to index the memory access. Do not pass loop_p. + Fix comment. Stop recursion on tcc_constant or tcc_declaration. + (expand_scalar_variables_stmt): Pass to expand_scalar_variables_expr + the gimple_stmt_iterator where it inserts new code. Do not pass loop_p. + (copy_bb_and_scalar_dependences): Do not pass loop_p. + (translate_clast): Update call to copy_bb_and_scalar_dependences. + +2009-01-13 Sebastian Pop <sebastian.pop@amd.com> + + * graphite.h (debug_value): Removed. + * graphite.c (debug_value): Removed. + +2009-01-13 Richard Earnshaw <rearnsha@arm.com> + + * arm.c (output_move_double): Don't synthesize thumb-2 ldrd/strd with + two 32-bit instructions. + +2009-01-13 Richard Earnshaw <rearnsha@arm.com> + + * arm.c (struct processors): Pass for speed down into cost helper + functions. + (const_ok_for_op): Handle COMPARE and inequality nodes. + (arm_rtx_costs_1): Rewrite. + (arm_size_rtx_costs): Update prototype. + (arm_rtx_costs): Pass speed down to helper functions. + (arm_slowmul_rtx_costs): Rework cost calculations. + (arm_fastmul_rtx_costs, arm_xscale_rtx_costs): Likewise. + (arm_9e_rtx_costs): Likewise. + +2009-01-13 Uros Bizjak <ubizjak@gmail.com> + + * config/alpha/alpha.c (alpha_legitimate_address_p): Explicit + relocations of local symbols wider than UNITS_PER_WORD are not valid. + (alpha_legitimize_address): Do not split local symbols wider than + UNITS_PER_WORD into HIGH/LO_SUM parts. + +2009-01-13 Danny Smith <dannysmith@users.sourceforge.net> + + PR bootstrap/38580 + * gcc.c (process_command): Replace call to execvp with calls + to pex_one and exit. + 2009-01-03 Anatoly Sokolov <aesok@post.ru> PR target/29141 @@ -26,9 +160,9 @@ 2009-01-12 Tomas Bily <tbily@suse.cz> PR middlend/38385 - * tree-loop-distribution.c (prop_phis): New function. - (generate_builtin): Call prop_phis. - * testsuite/gcc.dg/tree-ssa/pr38385.c: New file. + * tree-loop-distribution.c (prop_phis): New function. + (generate_builtin): Call prop_phis. + * testsuite/gcc.dg/tree-ssa/pr38385.c: New file. 2009-01-12 Jakub Jelinek <jakub@redhat.com> @@ -79,8 +213,7 @@ 2008-01-09 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/38495 - * ira-emit.c (print_move_list, ira_debug_move_list): New - functions. + * ira-emit.c (print_move_list, ira_debug_move_list): New functions. (add_range_and_copies_from_move_list): Print all added ranges. Add ranges to memory optimized destination. @@ -105,8 +238,7 @@ epilogue_size_needed to the epilogue expanders. PR c/35742 - * c-pretty-print.c (pp_c_expression): Handle GOTO_EXPR like - BIND_EXPR. + * c-pretty-print.c (pp_c_expression): Handle GOTO_EXPR like BIND_EXPR. 2009-01-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> diff --git a/gcc/ChangeLog-2006 b/gcc/ChangeLog-2006 index 00d47c29139..d57f42548e3 100644 --- a/gcc/ChangeLog-2006 +++ b/gcc/ChangeLog-2006 @@ -22671,7 +22671,7 @@ * basic-block.h: Remove the prototype for partition_hot_cold_basic_blocks. -2006-01-16 Rafael Ãvila de EspÃ�ndola <rafael.espindola@gmail.com> +2006-01-16 Rafael Ãvila de EspÃndola <rafael.espindola@gmail.com> * cppspec.c (lang_specific_spec_functions): Remove. * gcc.c (lookup_spec_function): Use static_spec_functions directly. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 6933e22e43b..a188b88a9ef 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20090113 +20090114 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 3e83138868d..d819716e730 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2738,7 +2738,7 @@ cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ $(DF_H) $(DBGCNT_H) dce.o : dce.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) $(DF_H) cselib.h \ - $(DBGCNT_H) dce.h $(TIMEVAR_H) tree-pass.h $(DBGCNT_H) + $(DBGCNT_H) dce.h $(TIMEVAR_H) tree-pass.h $(DBGCNT_H) $(TM_P_H) dse.o : dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(TM_P_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ $(RECOG_H) $(EXPR_H) $(DF_H) cselib.h $(DBGCNT_H) $(TIMEVAR_H) tree-pass.h \ @@ -2992,7 +2992,7 @@ ira-costs.o: ira-costs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ ira-conflicts.o: ira-conflicts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \ - $(DF_H) sparseset.h $(IRA_INT_H) + $(DF_H) sparseset.h addresses.h $(IRA_INT_H) ira-color.o: ira-color.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \ @@ -3002,7 +3002,7 @@ ira-emit.o: ira-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \ $(IRA_INT_H) ira-lives.o: ira-lives.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ - $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ + $(TARGET_H) $(RTL_H) $(REGS_H) except.h hard-reg-set.h $(FLAGS_H) \ insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \ $(DF_H) sparseset.h $(IRA_INT_H) ira.o: ira.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ diff --git a/gcc/calls.c b/gcc/calls.c index f6bc970b71b..a75e3b36569 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1,6 +1,6 @@ /* Convert function calls to rtl insns, for GNU C compiler. Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -2705,26 +2705,28 @@ expand_call (tree exp, rtx target, int ignore) but we do preallocate space here if they want that. */ for (i = 0; i < num_actuals; i++) - if (args[i].reg == 0 || args[i].pass_on_stack) - { - rtx before_arg = get_last_insn (); - - if (store_one_arg (&args[i], argblock, flags, - adjusted_args_size.var != 0, - reg_parm_stack_space) - || (pass == 0 - && check_sibcall_argument_overlap (before_arg, - &args[i], 1))) - sibcall_failure = 1; - - if (flags & ECF_CONST - && args[i].stack - && args[i].value == args[i].stack) - call_fusage = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_USE (VOIDmode, - args[i].value), - call_fusage); - } + { + if (args[i].reg == 0 || args[i].pass_on_stack) + { + rtx before_arg = get_last_insn (); + + if (store_one_arg (&args[i], argblock, flags, + adjusted_args_size.var != 0, + reg_parm_stack_space) + || (pass == 0 + && check_sibcall_argument_overlap (before_arg, + &args[i], 1))) + sibcall_failure = 1; + } + + if (((flags & ECF_CONST) + || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS)) + && args[i].stack) + call_fusage = gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_USE (VOIDmode, + args[i].stack), + call_fusage); + } /* If we have a parm that is passed in registers but not in memory and whose alignment does not permit a direct copy into registers, @@ -3672,7 +3674,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, NO_DEFER_POP; - if (flags & ECF_CONST) + if ((flags & ECF_CONST) + || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS)) { rtx use; diff --git a/gcc/combine.c b/gcc/combine.c index 82bf9f5e115..3aca075aae1 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -5706,6 +5706,7 @@ simplify_set (rtx x) { int other_changed_previously = other_changed; unsigned HOST_WIDE_INT mask; + rtx old_cc_use = *cc_use; SUBST (*cc_use, gen_rtx_fmt_ee (new_code, GET_MODE (*cc_use), dest, const0_rtx)); @@ -5728,7 +5729,7 @@ simplify_set (rtx x) if ((recog_for_combine (&pat, other_insn, ¬e) < 0 && ! check_asm_operands (pat))) { - PUT_CODE (*cc_use, old_code); + *cc_use = old_cc_use; other_changed = 0; op0 = simplify_gen_binary (XOR, GET_MODE (op0), diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 9c79f8883fc..7bafb0ae84b 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -864,9 +864,11 @@ alpha_legitimate_address_p (enum machine_mode mode, rtx x, int strict) } } - /* If we're managing explicit relocations, LO_SUM is valid, as - are small data symbols. */ - else if (TARGET_EXPLICIT_RELOCS) + /* If we're managing explicit relocations, LO_SUM is valid, as are small + data symbols. Avoid explicit relocations of modes larger than word + mode since i.e. $LC0+8($1) can fold around +/- 32k offset. */ + else if (TARGET_EXPLICIT_RELOCS + && GET_MODE_SIZE (mode) <= UNITS_PER_WORD) { if (small_symbolic_operand (x, Pmode)) return true; @@ -916,8 +918,7 @@ get_tls_get_addr (void) to be legitimate. If we find one, return the new, valid address. */ rtx -alpha_legitimize_address (rtx x, rtx scratch, - enum machine_mode mode ATTRIBUTE_UNUSED) +alpha_legitimize_address (rtx x, rtx scratch, enum machine_mode mode) { HOST_WIDE_INT addend; @@ -965,8 +966,12 @@ alpha_legitimize_address (rtx x, rtx scratch, goto split_addend; } - /* If this is a local symbol, split the address into HIGH/LO_SUM parts. */ - if (TARGET_EXPLICIT_RELOCS && symbolic_operand (x, Pmode)) + /* If this is a local symbol, split the address into HIGH/LO_SUM parts. + Avoid modes larger than word mode since i.e. $LC0+8($1) can fold + around +/- 32k offset. */ + if (TARGET_EXPLICIT_RELOCS + && GET_MODE_SIZE (mode) <= UNITS_PER_WORD + && symbolic_operand (x, Pmode)) { rtx r0, r16, eqv, tga, tp, insn, dest, seq; diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index dce0a523bd4..209682bb0fe 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -126,12 +126,12 @@ static bool arm_function_ok_for_sibcall (tree, tree); static void arm_internal_label (FILE *, const char *, unsigned long); static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); -static int arm_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code); -static bool arm_size_rtx_costs (rtx, int, int, int *); -static bool arm_slowmul_rtx_costs (rtx, int, int, int *); -static bool arm_fastmul_rtx_costs (rtx, int, int, int *); -static bool arm_xscale_rtx_costs (rtx, int, int, int *); -static bool arm_9e_rtx_costs (rtx, int, int, int *); +static bool arm_rtx_costs_1 (rtx, enum rtx_code, int*, bool); +static bool arm_size_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *); +static bool arm_slowmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool); +static bool arm_fastmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool); +static bool arm_xscale_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool); +static bool arm_9e_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool); static bool arm_rtx_costs (rtx, int, int, int *, bool); static int arm_address_cost (rtx, bool); static bool arm_memory_load_p (rtx); @@ -619,7 +619,7 @@ struct processors enum processor_type core; const char *arch; const unsigned long flags; - bool (* rtx_costs) (rtx, int, int, int *); + bool (* rtx_costs) (rtx, enum rtx_code, enum rtx_code, int *, bool); }; /* Not all of these give usefully different compilation alternatives, @@ -1883,6 +1883,24 @@ const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code) switch (code) { case PLUS: + case COMPARE: + case EQ: + case NE: + case GT: + case LE: + case LT: + case GE: + case GEU: + case LTU: + case GTU: + case LEU: + case UNORDERED: + case ORDERED: + case UNEQ: + case UNGE: + case UNLT: + case UNGT: + case UNLE: return const_ok_for_arm (ARM_SIGN_EXTEND (-i)); case MINUS: /* Should only occur with (MINUS I reg) => rsb */ @@ -4882,130 +4900,227 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer) } } - -/* Worker routine for arm_rtx_costs. */ -/* ??? This needs updating for thumb2. */ -static inline int -arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer) +static inline bool +arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed) { enum machine_mode mode = GET_MODE (x); enum rtx_code subcode; + rtx operand; + enum rtx_code code = GET_CODE (x); int extra_cost; + *total = 0; switch (code) { case MEM: /* Memory costs quite a lot for the first word, but subsequent words load at the equivalent of a single insn each. */ - return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD) - + (GET_CODE (x) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (x) ? 4 : 0)); + *total = COSTS_N_INSNS (2 + ARM_NUM_REGS (mode)); + return true; case DIV: case MOD: case UDIV: case UMOD: - return optimize_size ? COSTS_N_INSNS (2) : 100; + if (TARGET_HARD_FLOAT && mode == SFmode) + *total = COSTS_N_INSNS (2); + else if (TARGET_HARD_FLOAT && mode == DFmode) + *total = COSTS_N_INSNS (4); + else + *total = COSTS_N_INSNS (20); + return false; case ROTATE: - if (mode == SImode && GET_CODE (XEXP (x, 1)) == REG) - return 4; + if (GET_CODE (XEXP (x, 1)) == REG) + *total = COSTS_N_INSNS (1); /* Need to subtract from 32 */ + else if (GET_CODE (XEXP (x, 1)) != CONST_INT) + *total = rtx_cost (XEXP (x, 1), code, speed); + /* Fall through */ case ROTATERT: if (mode != SImode) - return 8; + { + *total += COSTS_N_INSNS (4); + return true; + } + /* Fall through */ case ASHIFT: case LSHIFTRT: case ASHIFTRT: + *total += rtx_cost (XEXP (x, 0), code, speed); if (mode == DImode) - return (8 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : 8) - + ((GET_CODE (XEXP (x, 0)) == REG - || (GET_CODE (XEXP (x, 0)) == SUBREG - && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG)) - ? 0 : 8)); + { + *total += COSTS_N_INSNS (3); + return true; + } - extra_cost = 1; + *total += COSTS_N_INSNS (1); /* Increase the cost of complex shifts because they aren't any faster, and reduce dual issue opportunities. */ if (arm_tune_cortex_a9 && outer != SET && GET_CODE (XEXP (x, 1)) != CONST_INT) - extra_cost++; - - return (extra_cost + ((GET_CODE (XEXP (x, 0)) == REG - || (GET_CODE (XEXP (x, 0)) == SUBREG - && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG)) - ? 0 : 4) - + ((GET_CODE (XEXP (x, 1)) == REG - || (GET_CODE (XEXP (x, 1)) == SUBREG - && GET_CODE (SUBREG_REG (XEXP (x, 1))) == REG) - || (GET_CODE (XEXP (x, 1)) == CONST_INT)) - ? 0 : 4)); + ++*total; + + return true; case MINUS: - if (GET_CODE (XEXP (x, 1)) == MULT && mode == SImode && arm_arch_thumb2) + if (TARGET_THUMB2) { - extra_cost = rtx_cost (XEXP (x, 1), code, true); - if (!REG_OR_SUBREG_REG (XEXP (x, 0))) - extra_cost += 4 * ARM_NUM_REGS (mode); - return extra_cost; + if (GET_MODE_CLASS (mode) == MODE_FLOAT) + { + if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + *total = COSTS_N_INSNS (1); + else + *total = COSTS_N_INSNS (20); + } + else + *total = COSTS_N_INSNS (ARM_NUM_REGS (mode)); + /* Thumb2 does not have RSB, so all arguments must be + registers (subtracting a constant is canonicalized as + addition of the negated constant). */ + return false; } if (mode == DImode) - return (4 + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 8) - + ((REG_OR_SUBREG_REG (XEXP (x, 0)) - || (GET_CODE (XEXP (x, 0)) == CONST_INT - && const_ok_for_arm (INTVAL (XEXP (x, 0))))) - ? 0 : 8)); + { + *total = COSTS_N_INSNS (ARM_NUM_REGS (mode)); + if (GET_CODE (XEXP (x, 0)) == CONST_INT + && const_ok_for_arm (INTVAL (XEXP (x, 0)))) + { + *total += rtx_cost (XEXP (x, 1), code, speed); + return true; + } + + if (GET_CODE (XEXP (x, 1)) == CONST_INT + && const_ok_for_arm (INTVAL (XEXP (x, 1)))) + { + *total += rtx_cost (XEXP (x, 0), code, speed); + return true; + } + + return false; + } if (GET_MODE_CLASS (mode) == MODE_FLOAT) - return (2 + ((REG_OR_SUBREG_REG (XEXP (x, 1)) - || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE - && arm_const_double_rtx (XEXP (x, 1)))) - ? 0 : 8) - + ((REG_OR_SUBREG_REG (XEXP (x, 0)) - || (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE - && arm_const_double_rtx (XEXP (x, 0)))) - ? 0 : 8)); - - if (((GET_CODE (XEXP (x, 0)) == CONST_INT - && const_ok_for_arm (INTVAL (XEXP (x, 0))) - && REG_OR_SUBREG_REG (XEXP (x, 1)))) - || (((subcode = GET_CODE (XEXP (x, 1))) == ASHIFT - || subcode == ASHIFTRT || subcode == LSHIFTRT - || subcode == ROTATE || subcode == ROTATERT - || (subcode == MULT - && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT - && ((INTVAL (XEXP (XEXP (x, 1), 1)) & - (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0))) - && REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 0)) - && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 1)) - || GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT) - && REG_OR_SUBREG_REG (XEXP (x, 0)))) - return 1; + { + if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + { + *total = COSTS_N_INSNS (1); + if (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE + && arm_const_double_rtx (XEXP (x, 0))) + { + *total += rtx_cost (XEXP (x, 1), code, speed); + return true; + } + + if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE + && arm_const_double_rtx (XEXP (x, 1))) + { + *total += rtx_cost (XEXP (x, 0), code, speed); + return true; + } + + return false; + } + *total = COSTS_N_INSNS (20); + return false; + } + + *total = COSTS_N_INSNS (1); + if (GET_CODE (XEXP (x, 0)) == CONST_INT + && const_ok_for_arm (INTVAL (XEXP (x, 0)))) + { + *total += rtx_cost (XEXP (x, 1), code, speed); + return true; + } + + subcode = GET_CODE (XEXP (x, 1)); + if (subcode == ASHIFT || subcode == ASHIFTRT + || subcode == LSHIFTRT + || subcode == ROTATE || subcode == ROTATERT) + { + *total += rtx_cost (XEXP (x, 0), code, speed); + *total += rtx_cost (XEXP (XEXP (x, 1), 0), subcode, speed); + return true; + } + + if (subcode == MULT + && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT + && ((INTVAL (XEXP (XEXP (x, 1), 1)) & + (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0)) + { + *total += rtx_cost (XEXP (x, 0), code, speed); + *total += rtx_cost (XEXP (XEXP (x, 1), 0), subcode, speed); + return true; + } + + if (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == RTX_COMPARE + || GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == RTX_COMM_COMPARE) + { + *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code, speed); + if (GET_CODE (XEXP (XEXP (x, 1), 0)) == REG + && REGNO (XEXP (XEXP (x, 1), 0)) != CC_REGNUM) + *total += COSTS_N_INSNS (1); + + return true; + } + /* Fall through */ case PLUS: - if (arm_arch6 && mode == SImode + if (code == PLUS && arm_arch6 && mode == SImode && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)) - return 1 + (GET_CODE (XEXP (XEXP (x, 0), 0)) == MEM ? 10 : 0) - + (GET_CODE (XEXP (x, 1)) == MEM ? 10 : 0); + { + *total = COSTS_N_INSNS (1); + *total += rtx_cost (XEXP (XEXP (x, 0), 0), GET_CODE (XEXP (x, 0)), + speed); + *total += rtx_cost (XEXP (x, 1), code, speed); + return true; + } - if (GET_CODE (XEXP (x, 0)) == MULT) + /* MLA: All arguments must be registers. We filter out + multiplication by a power of two, so that we fall down into + the code below. */ + if (GET_CODE (XEXP (x, 0)) == MULT + && ! (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT + && ((INTVAL (XEXP (XEXP (x, 0), 1)) & + (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0))) { - extra_cost = rtx_cost (XEXP (x, 0), code, true); - if (!REG_OR_SUBREG_REG (XEXP (x, 1))) - extra_cost += 4 * ARM_NUM_REGS (mode); - return extra_cost; + /* The cost comes from the cost of the multiply. */ + return false; } if (GET_MODE_CLASS (mode) == MODE_FLOAT) - return (2 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8) - + ((REG_OR_SUBREG_REG (XEXP (x, 1)) - || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE - && arm_const_double_rtx (XEXP (x, 1)))) - ? 0 : 8)); + { + if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + { + *total = COSTS_N_INSNS (1); + if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE + && arm_const_double_rtx (XEXP (x, 1))) + { + *total += rtx_cost (XEXP (x, 0), code, speed); + return true; + } + + return false; + } + + *total = COSTS_N_INSNS (20); + return false; + } + + if (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == RTX_COMPARE + || GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == RTX_COMM_COMPARE) + { + *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 1), code, speed); + if (GET_CODE (XEXP (XEXP (x, 0), 0)) == REG + && REGNO (XEXP (XEXP (x, 0), 0)) != CC_REGNUM) + *total += COSTS_N_INSNS (1); + return true; + } /* Fall through */ + case AND: case XOR: case IOR: extra_cost = 0; @@ -5019,38 +5134,56 @@ arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer) && GET_CODE (XEXP (x, 1)) != CONST_INT) || (REG_OR_SUBREG_REG (XEXP (x, 0)) && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0))))) - extra_cost = 4; + *total = 4; if (mode == DImode) - return (4 + extra_cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8) - + ((REG_OR_SUBREG_REG (XEXP (x, 1)) - || (GET_CODE (XEXP (x, 1)) == CONST_INT - && const_ok_for_op (INTVAL (XEXP (x, 1)), code))) - ? 0 : 8)); - - if (REG_OR_SUBREG_REG (XEXP (x, 0))) - return (1 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : extra_cost) - + ((REG_OR_SUBREG_REG (XEXP (x, 1)) - || (GET_CODE (XEXP (x, 1)) == CONST_INT - && const_ok_for_op (INTVAL (XEXP (x, 1)), code))) - ? 0 : 4)); - - else if (REG_OR_SUBREG_REG (XEXP (x, 1))) - return (1 + extra_cost - + ((((subcode = GET_CODE (XEXP (x, 0))) == ASHIFT - || subcode == LSHIFTRT || subcode == ASHIFTRT - || subcode == ROTATE || subcode == ROTATERT - || (subcode == MULT - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && ((INTVAL (XEXP (XEXP (x, 0), 1)) & - (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0))) - && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 0))) - && ((REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 1)) - && !arm_tune_cortex_a9) - || GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)) - ? 0 : 4)); + { + *total += COSTS_N_INSNS (2); + if (GET_CODE (XEXP (x, 1)) == CONST_INT + && const_ok_for_op (INTVAL (XEXP (x, 1)), code)) + { + *total += rtx_cost (XEXP (x, 0), code, speed); + return true; + } - return 8; + return false; + } + + *total += COSTS_N_INSNS (1); + if (GET_CODE (XEXP (x, 1)) == CONST_INT + && const_ok_for_op (INTVAL (XEXP (x, 1)), code)) + { + *total += rtx_cost (XEXP (x, 0), code, speed); + return true; + } + subcode = GET_CODE (XEXP (x, 0)); + if (subcode == ASHIFT || subcode == ASHIFTRT + || subcode == LSHIFTRT + || subcode == ROTATE || subcode == ROTATERT) + { + *total += rtx_cost (XEXP (x, 1), code, speed); + *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, speed); + return true; + } + + if (subcode == MULT + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT + && ((INTVAL (XEXP (XEXP (x, 0), 1)) & + (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)) + { + *total += rtx_cost (XEXP (x, 1), code, speed); + *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, speed); + return true; + } + + if (subcode == UMIN || subcode == UMAX + || subcode == SMIN || subcode == SMAX) + { + *total = COSTS_N_INSNS (3); + return true; + } + + return false; case MULT: /* This should have been handled by the CPU specific routines. */ @@ -5064,108 +5197,290 @@ arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer) == GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1))) && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND || GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND)) - return 8; - return 99; + { + *total = rtx_cost (XEXP (XEXP (x, 0), 0), LSHIFTRT, speed); + return true; + } + *total = COSTS_N_INSNS (2); /* Plus the cost of the MULT */ + return false; case NEG: if (GET_MODE_CLASS (mode) == MODE_FLOAT) - return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 6); + { + if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + { + *total = COSTS_N_INSNS (1); + return false; + } + *total = COSTS_N_INSNS (2); + return false; + } + /* Fall through */ case NOT: - if (mode == DImode) - return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4); + *total = COSTS_N_INSNS (ARM_NUM_REGS(mode)); + if (mode == SImode && code == NOT) + { + subcode = GET_CODE (XEXP (x, 0)); + if (subcode == ASHIFT || subcode == ASHIFTRT + || subcode == LSHIFTRT + || subcode == ROTATE || subcode == ROTATERT + || (subcode == MULT + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT + && ((INTVAL (XEXP (XEXP (x, 0), 1)) & + (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0))) + { + *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, speed); + /* Register shifts cost an extra cycle. */ + if (GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT) + *total += COSTS_N_INSNS (1) + rtx_cost (XEXP (XEXP (x, 0), 1), + subcode, speed); + return true; + } + } - return 1 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4); + return false; case IF_THEN_ELSE: if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC) - return 14; - return 2; + { + *total = COSTS_N_INSNS (4); + return true; + } + operand = XEXP (x, 0); + + if (!((GET_RTX_CLASS (GET_CODE (operand)) == RTX_COMPARE + || GET_RTX_CLASS (GET_CODE (operand)) == RTX_COMM_COMPARE) + && GET_CODE (XEXP (operand, 0)) == REG + && REGNO (XEXP (operand, 0)) == CC_REGNUM)) + *total += COSTS_N_INSNS (1); + *total += (rtx_cost (XEXP (x, 1), code, speed) + + rtx_cost (XEXP (x, 2), code, speed)); + return true; + + case NE: + if (mode == SImode && XEXP (x, 1) == const0_rtx) + { + *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code, speed); + return true; + } + goto scc_insn; + + case GE: + if ((GET_CODE (XEXP (x, 0)) != REG || REGNO (XEXP (x, 0)) != CC_REGNUM) + && mode == SImode && XEXP (x, 1) == const0_rtx) + { + *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code, speed); + return true; + } + goto scc_insn; + + case LT: + if ((GET_CODE (XEXP (x, 0)) != REG || REGNO (XEXP (x, 0)) != CC_REGNUM) + && mode == SImode && XEXP (x, 1) == const0_rtx) + { + *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code, speed); + return true; + } + goto scc_insn; + + case EQ: + case GT: + case LE: + case GEU: + case LTU: + case GTU: + case LEU: + case UNORDERED: + case ORDERED: + case UNEQ: + case UNGE: + case UNLT: + case UNGT: + case UNLE: + scc_insn: + /* SCC insns. In the case where the comparison has already been + performed, then they cost 2 instructions. Otherwise they need + an additional comparison before them. */ + *total = COSTS_N_INSNS (2); + if (GET_CODE (XEXP (x, 0)) == REG && REGNO (XEXP (x, 0)) == CC_REGNUM) + { + return true; + } + + /* Fall through */ case COMPARE: - return 1; + if (GET_CODE (XEXP (x, 0)) == REG && REGNO (XEXP (x, 0)) == CC_REGNUM) + { + *total = 0; + return true; + } + + *total += COSTS_N_INSNS (1); + if (GET_CODE (XEXP (x, 1)) == CONST_INT + && const_ok_for_op (INTVAL (XEXP (x, 1)), code)) + { + *total += rtx_cost (XEXP (x, 0), code, speed); + return true; + } + + subcode = GET_CODE (XEXP (x, 0)); + if (subcode == ASHIFT || subcode == ASHIFTRT + || subcode == LSHIFTRT + || subcode == ROTATE || subcode == ROTATERT) + { + *total += rtx_cost (XEXP (x, 1), code, speed); + *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, speed); + return true; + } + + if (subcode == MULT + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT + && ((INTVAL (XEXP (XEXP (x, 0), 1)) & + (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)) + { + *total += rtx_cost (XEXP (x, 1), code, speed); + *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, speed); + return true; + } + + return false; + + case UMIN: + case UMAX: + case SMIN: + case SMAX: + *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code, speed); + if (GET_CODE (XEXP (x, 1)) != CONST_INT + || !const_ok_for_arm (INTVAL (XEXP (x, 1)))) + *total += rtx_cost (XEXP (x, 1), code, speed); + return true; case ABS: - return 4 + (mode == DImode ? 4 : 0); + if (GET_MODE_CLASS (mode == MODE_FLOAT)) + { + if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + { + *total = COSTS_N_INSNS (1); + return false; + } + *total = COSTS_N_INSNS (20); + return false; + } + *total = COSTS_N_INSNS (1); + if (mode == DImode) + *total += COSTS_N_INSNS (3); + return false; case SIGN_EXTEND: - if (arm_arch_thumb2 && mode == SImode) - return 1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0); + if (GET_MODE_CLASS (mode) == MODE_INT) + { + *total = 0; + if (mode == DImode) + *total += COSTS_N_INSNS (1); + + if (GET_MODE (XEXP (x, 0)) != SImode) + { + if (arm_arch6) + { + if (GET_CODE (XEXP (x, 0)) != MEM) + *total += COSTS_N_INSNS (1); + } + else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM) + *total += COSTS_N_INSNS (2); + } + + return false; + } - if (GET_MODE (XEXP (x, 0)) == QImode) - return (4 + (mode == DImode ? 4 : 0) - + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0)); /* Fall through */ case ZERO_EXTEND: - if (arm_arch6 && mode == SImode) - return 1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0); - - switch (GET_MODE (XEXP (x, 0))) + *total = 0; + if (GET_MODE_CLASS (mode) == MODE_INT) { - case QImode: - return (1 + (mode == DImode ? 4 : 0) - + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0)); + if (mode == DImode) + *total += COSTS_N_INSNS (1); - case HImode: - return (4 + (mode == DImode ? 4 : 0) - + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0)); + if (GET_MODE (XEXP (x, 0)) != SImode) + { + if (arm_arch6) + { + if (GET_CODE (XEXP (x, 0)) != MEM) + *total += COSTS_N_INSNS (1); + } + else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM) + *total += COSTS_N_INSNS (GET_MODE (XEXP (x, 0)) == QImode ? + 1 : 2); + } - case SImode: - return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0)); + return false; + } + switch (GET_MODE (XEXP (x, 0))) + { case V8QImode: case V4HImode: case V2SImode: case V4QImode: case V2HImode: - return 1; + *total = COSTS_N_INSNS (1); + return false; default: gcc_unreachable (); } gcc_unreachable (); + case ZERO_EXTRACT: + case SIGN_EXTRACT: + *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code, speed); + return true; + case CONST_INT: - if (const_ok_for_arm (INTVAL (x))) - return outer == SET ? 2 : -1; - else if (outer == AND - && const_ok_for_arm (~INTVAL (x))) - return -1; - else if ((outer == COMPARE - || outer == PLUS || outer == MINUS) - && const_ok_for_arm (-INTVAL (x))) - return -1; + if (const_ok_for_arm (INTVAL (x)) + || const_ok_for_arm (~INTVAL (x))) + *total = COSTS_N_INSNS (1); else - return 5; + *total = COSTS_N_INSNS (arm_gen_constant (SET, mode, NULL_RTX, + INTVAL (x), NULL_RTX, + NULL_RTX, 0, 0)); + return true; case CONST: case LABEL_REF: case SYMBOL_REF: - return 6; + *total = COSTS_N_INSNS (3); + return true; case HIGH: + *total = COSTS_N_INSNS (1); + return true; + case LO_SUM: - return (outer == SET) ? 1 : -1; + *total = COSTS_N_INSNS (1); + *total += rtx_cost (XEXP (x, 0), code, speed); + return true; case CONST_DOUBLE: - if (arm_const_double_rtx (x) || vfp3_const_double_rtx (x)) - return outer == SET ? 2 : -1; - else if ((outer == COMPARE || outer == PLUS) - && neg_const_double_rtx_ok_for_fpa (x)) - return -1; - return 7; + if (TARGET_HARD_FLOAT && vfp3_const_double_rtx (x)) + *total = COSTS_N_INSNS (1); + else + *total = COSTS_N_INSNS (4); + return true; default: - return 99; + *total = COSTS_N_INSNS (4); + return false; } } /* RTX costs when optimizing for size. */ static bool -arm_size_rtx_costs (rtx x, int code, int outer_code, int *total) +arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, + int *total) { enum machine_mode mode = GET_MODE (x); - if (TARGET_THUMB1) { /* XXX TBD. For now, use the standard costs. */ @@ -5395,19 +5710,22 @@ arm_size_rtx_costs (rtx x, int code, int outer_code, int *total) /* RTX costs when optimizing for size. */ static bool -arm_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed) +arm_rtx_costs (rtx x, int code, int outer_code, int *total, + bool speed) { if (!speed) return arm_size_rtx_costs (x, code, outer_code, total); else - return all_cores[(int)arm_tune].rtx_costs (x, code, outer_code, total); + return all_cores[(int)arm_tune].rtx_costs (x, code, outer_code, total, + speed); } /* RTX costs for cores with a slow MUL implementation. Thumb-2 is not supported on any "slowmul" cores, so it can be ignored. */ static bool -arm_slowmul_rtx_costs (rtx x, int code, int outer_code, int *total) +arm_slowmul_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, + int *total, bool speed) { enum machine_mode mode = GET_MODE (x); @@ -5423,8 +5741,8 @@ arm_slowmul_rtx_costs (rtx x, int code, int outer_code, int *total) if (GET_MODE_CLASS (mode) == MODE_FLOAT || mode == DImode) { - *total = 30; - return true; + *total = COSTS_N_INSNS (20); + return false; } if (GET_CODE (XEXP (x, 1)) == CONST_INT) @@ -5440,20 +5758,19 @@ arm_slowmul_rtx_costs (rtx x, int code, int outer_code, int *total) for (j = 0; i && j < 32; j += booth_unit_size) { i >>= booth_unit_size; - cost += 2; + cost++; } - *total = cost; + *total = COSTS_N_INSNS (cost); + *total += rtx_cost (XEXP (x, 0), code, speed); return true; } - *total = 30 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4) - + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4); - return true; + *total = COSTS_N_INSNS (20); + return false; default: - *total = arm_rtx_costs_1 (x, code, outer_code); - return true; + return arm_rtx_costs_1 (x, outer_code, total, speed);; } } @@ -5461,7 +5778,8 @@ arm_slowmul_rtx_costs (rtx x, int code, int outer_code, int *total) /* RTX cost for cores with a fast multiply unit (M variants). */ static bool -arm_fastmul_rtx_costs (rtx x, int code, int outer_code, int *total) +arm_fastmul_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, + int *total, bool speed) { enum machine_mode mode = GET_MODE (x); @@ -5482,16 +5800,15 @@ arm_fastmul_rtx_costs (rtx x, int code, int outer_code, int *total) && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)) { - *total = 8; - return true; + *total = COSTS_N_INSNS(2); + return false; } - if (GET_MODE_CLASS (mode) == MODE_FLOAT - || mode == DImode) + if (mode == DImode) { - *total = 30; - return true; + *total = COSTS_N_INSNS (5); + return false; } if (GET_CODE (XEXP (x, 1)) == CONST_INT) @@ -5507,20 +5824,34 @@ arm_fastmul_rtx_costs (rtx x, int code, int outer_code, int *total) for (j = 0; i && j < 32; j += booth_unit_size) { i >>= booth_unit_size; - cost += 2; + cost++; } - *total = cost; - return true; + *total = COSTS_N_INSNS(cost); + return false; } - *total = 8 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4) - + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4); - return true; + if (mode == SImode) + { + *total = COSTS_N_INSNS (4); + return false; + } + + if (GET_MODE_CLASS (mode) == MODE_FLOAT) + { + if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + { + *total = COSTS_N_INSNS (1); + return false; + } + } + + /* Requires a lib call */ + *total = COSTS_N_INSNS (20); + return false; default: - *total = arm_rtx_costs_1 (x, code, outer_code); - return true; + return arm_rtx_costs_1 (x, outer_code, total, speed); } } @@ -5529,7 +5860,7 @@ arm_fastmul_rtx_costs (rtx x, int code, int outer_code, int *total) so it can be ignored. */ static bool -arm_xscale_rtx_costs (rtx x, int code, int outer_code, int *total) +arm_xscale_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, int *total, bool speed) { enum machine_mode mode = GET_MODE (x); @@ -5541,6 +5872,15 @@ arm_xscale_rtx_costs (rtx x, int code, int outer_code, int *total) switch (code) { + case COMPARE: + if (GET_CODE (XEXP (x, 0)) != MULT) + return arm_rtx_costs_1 (x, outer_code, total, speed); + + /* A COMPARE of a MULT is slow on XScale; the muls instruction + will stall until the multiplication is complete. */ + *total = COSTS_N_INSNS (3); + return false; + case MULT: /* There is no point basing this on the tuning, since it is always the fast variant if it exists at all. */ @@ -5549,60 +5889,58 @@ arm_xscale_rtx_costs (rtx x, int code, int outer_code, int *total) && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)) { - *total = 8; - return true; + *total = COSTS_N_INSNS (2); + return false; } - if (GET_MODE_CLASS (mode) == MODE_FLOAT - || mode == DImode) + if (mode == DImode) { - *total = 30; - return true; + *total = COSTS_N_INSNS (5); + return false; } if (GET_CODE (XEXP (x, 1)) == CONST_INT) { - unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1)) - & (unsigned HOST_WIDE_INT) 0xffffffff); - int cost, const_ok = const_ok_for_arm (i); + /* If operand 1 is a constant we can more accurately + calculate the cost of the multiply. The multiplier can + retire 15 bits on the first cycle and a further 12 on the + second. We do, of course, have to load the constant into + a register first. */ + unsigned HOST_WIDE_INT i = INTVAL (XEXP (x, 1)); + /* There's a general overhead of one cycle. */ + int cost = 1; unsigned HOST_WIDE_INT masked_const; - /* The cost will be related to two insns. - First a load of the constant (MOV or LDR), then a multiply. */ - cost = 2; - if (! const_ok) - cost += 1; /* LDR is probably more expensive because - of longer result latency. */ + if (i & 0x80000000) + i = ~i; + + i &= (unsigned HOST_WIDE_INT) 0xffffffff; + masked_const = i & 0xffff8000; - if (masked_const != 0 && masked_const != 0xffff8000) + if (masked_const != 0) { + cost++; masked_const = i & 0xf8000000; - if (masked_const == 0 || masked_const == 0xf8000000) - cost += 1; - else - cost += 2; + if (masked_const != 0) + cost++; } - *total = cost; - return true; + *total = COSTS_N_INSNS (cost); + return false; } - *total = 8 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4) - + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4); - return true; + if (mode == SImode) + { + *total = COSTS_N_INSNS (3); + return false; + } - case COMPARE: - /* A COMPARE of a MULT is slow on XScale; the muls instruction - will stall until the multiplication is complete. */ - if (GET_CODE (XEXP (x, 0)) == MULT) - *total = 4 + rtx_cost (XEXP (x, 0), code, true); - else - *total = arm_rtx_costs_1 (x, code, outer_code); - return true; + /* Requires a lib call */ + *total = COSTS_N_INSNS (20); + return false; default: - *total = arm_rtx_costs_1 (x, code, outer_code); - return true; + return arm_rtx_costs_1 (x, outer_code, total, speed); } } @@ -5610,11 +5948,10 @@ arm_xscale_rtx_costs (rtx x, int code, int outer_code, int *total) /* RTX costs for 9e (and later) cores. */ static bool -arm_9e_rtx_costs (rtx x, int code, int outer_code, int *total) +arm_9e_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, + int *total, bool speed) { enum machine_mode mode = GET_MODE (x); - int nonreg_cost; - int cost; if (TARGET_THUMB1) { @@ -5640,35 +5977,37 @@ arm_9e_rtx_costs (rtx x, int code, int outer_code, int *total) && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)) { - *total = 3; - return true; + *total = COSTS_N_INSNS (2); + return false; } - if (GET_MODE_CLASS (mode) == MODE_FLOAT) - { - *total = 30; - return true; - } if (mode == DImode) { - cost = 7; - nonreg_cost = 8; + *total = COSTS_N_INSNS (5); + return false; } - else + + if (mode == SImode) { - cost = 2; - nonreg_cost = 4; + *total = COSTS_N_INSNS (2); + return false; } + if (GET_MODE_CLASS (mode) == MODE_FLOAT) + { + if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + { + *total = COSTS_N_INSNS (1); + return false; + } + } - *total = cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : nonreg_cost) - + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : nonreg_cost); - return true; + *total = COSTS_N_INSNS (20); + return false; default: - *total = arm_rtx_costs_1 (x, code, outer_code); - return true; + return arm_rtx_costs_1 (x, outer_code, total, speed); } } /* All address computations that can be done are free, but rtx cost returns @@ -6038,7 +6377,7 @@ neon_valid_immediate (rtx op, enum machine_mode mode, int inverse, break; \ } - unsigned int i, elsize, idx = 0, n_elts = CONST_VECTOR_NUNITS (op); + unsigned int i, elsize = 0, idx = 0, n_elts = CONST_VECTOR_NUNITS (op); unsigned int innersize = GET_MODE_SIZE (GET_MODE_INNER (mode)); unsigned char bytes[16]; int immtype = -1, matches; @@ -10052,36 +10391,36 @@ output_move_double (rtx *operands) } else { - /* IWMMXT allows offsets larger than ldrd can handle, - fix these up with a pair of ldr. */ - if (GET_CODE (otherops[2]) == CONST_INT - && (INTVAL(otherops[2]) <= -256 - || INTVAL(otherops[2]) >= 256)) + /* Use a single insn if we can. + FIXME: IWMMXT allows offsets larger than ldrd can + handle, fix these up with a pair of ldr. */ + if (TARGET_THUMB2 + || GET_CODE (otherops[2]) != CONST_INT + || (INTVAL (otherops[2]) > -256 + && INTVAL (otherops[2]) < 256)) + output_asm_insn ("ldr%(d%)\t%0, [%1, %2]!", otherops); + else { output_asm_insn ("ldr%?\t%0, [%1, %2]!", otherops); - otherops[0] = gen_rtx_REG (SImode, 1 + reg0); - output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops); + output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops); } - else - output_asm_insn ("ldr%(d%)\t%0, [%1, %2]!", otherops); } } else { - /* IWMMXT allows offsets larger than ldrd can handle, + /* Use a single insn if we can. + FIXME: IWMMXT allows offsets larger than ldrd can handle, fix these up with a pair of ldr. */ - if (GET_CODE (otherops[2]) == CONST_INT - && (INTVAL(otherops[2]) <= -256 - || INTVAL(otherops[2]) >= 256)) + if (TARGET_THUMB2 + || GET_CODE (otherops[2]) != CONST_INT + || (INTVAL (otherops[2]) > -256 + && INTVAL (otherops[2]) < 256)) + output_asm_insn ("ldr%(d%)\t%0, [%1], %2", otherops); + else { - otherops[0] = gen_rtx_REG (SImode, 1 + reg0); - output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops); - otherops[0] = operands[0]; + output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops); output_asm_insn ("ldr%?\t%0, [%1], %2", otherops); } - else - /* We only allow constant increments, so this is safe. */ - output_asm_insn ("ldr%(d%)\t%0, [%1], %2", otherops); } break; @@ -10135,6 +10474,7 @@ output_move_double (rtx *operands) operands[1] = otherops[0]; if (TARGET_LDRD && (GET_CODE (otherops[2]) == REG + || TARGET_THUMB2 || (GET_CODE (otherops[2]) == CONST_INT && INTVAL (otherops[2]) > -256 && INTVAL (otherops[2]) < 256))) @@ -10247,23 +10587,19 @@ output_move_double (rtx *operands) /* IWMMXT allows offsets larger than ldrd can handle, fix these up with a pair of ldr. */ - if (GET_CODE (otherops[2]) == CONST_INT + if (!TARGET_THUMB2 + && GET_CODE (otherops[2]) == CONST_INT && (INTVAL(otherops[2]) <= -256 || INTVAL(otherops[2]) >= 256)) { - rtx reg1; - reg1 = gen_rtx_REG (SImode, 1 + REGNO (operands[1])); if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY) { output_asm_insn ("ldr%?\t%0, [%1, %2]!", otherops); - otherops[0] = reg1; - output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops); + output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops); } else { - otherops[0] = reg1; - output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops); - otherops[0] = operands[1]; + output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops); output_asm_insn ("ldr%?\t%0, [%1], %2", otherops); } } @@ -10298,6 +10634,7 @@ output_move_double (rtx *operands) } if (TARGET_LDRD && (GET_CODE (otherops[2]) == REG + || TARGET_THUMB2 || (GET_CODE (otherops[2]) == CONST_INT && INTVAL (otherops[2]) > -256 && INTVAL (otherops[2]) < 256))) @@ -10311,9 +10648,9 @@ output_move_double (rtx *operands) default: otherops[0] = adjust_address (operands[0], SImode, 4); - otherops[1] = gen_rtx_REG (SImode, 1 + REGNO (operands[1])); + otherops[1] = operands[1]; output_asm_insn ("str%?\t%1, %0", operands); - output_asm_insn ("str%?\t%1, %0", otherops); + output_asm_insn ("str%?\t%H1, %0", otherops); } } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b5fea236db2..d02f5c16fae 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -10834,7 +10834,8 @@ print_operand (FILE *file, rtx x, int code) fputs ("ord", file); break; default: - gcc_unreachable (); + output_operand_lossage ("operand is not a condition code, invalid operand code 'D'"); + return; } } else @@ -10872,7 +10873,8 @@ print_operand (FILE *file, rtx x, int code) fputs ("ord", file); break; default: - gcc_unreachable (); + output_operand_lossage ("operand is not a condition code, invalid operand code 'D'"); + return; } } return; @@ -10894,9 +10896,23 @@ print_operand (FILE *file, rtx x, int code) #endif return; case 'C': + if (!COMPARISON_P (x)) + { + output_operand_lossage ("operand is neither a constant nor a " + "condition code, invalid operand code " + "'C'"); + return; + } put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 0, file); return; case 'F': + if (!COMPARISON_P (x)) + { + output_operand_lossage ("operand is neither a constant nor a " + "condition code, invalid operand code " + "'F'"); + return; + } #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX if (ASSEMBLER_DIALECT == ASM_ATT) putc ('.', file); @@ -10909,13 +10925,22 @@ print_operand (FILE *file, rtx x, int code) /* Check to see if argument to %c is really a constant and not a condition code which needs to be reversed. */ if (!COMPARISON_P (x)) - { - output_operand_lossage ("operand is neither a constant nor a condition code, invalid operand code 'c'"); - return; - } + { + output_operand_lossage ("operand is neither a constant nor a " + "condition code, invalid operand " + "code 'c'"); + return; + } put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 0, file); return; case 'f': + if (!COMPARISON_P (x)) + { + output_operand_lossage ("operand is neither a constant nor a " + "condition code, invalid operand " + "code 'f'"); + return; + } #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX if (ASSEMBLER_DIALECT == ASM_ATT) putc ('.', file); @@ -11022,7 +11047,8 @@ print_operand (FILE *file, rtx x, int code) fputs ("une", file); break; default: - gcc_unreachable (); + output_operand_lossage ("operand is not a condition code, invalid operand code 'D'"); + return; } return; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7e35ecde16d..07b9c7e49e6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,23 @@ +2009-01-15 Dodji Seketeli <dodji@redhat.com> + + PR c++/38636 + * name-lookup.c (pushtag): Don't create members to types that are not + being created. + +2009-01-14 Nick Clifton <nickc@redhat.com> + + PR c++/37862 + * parser.c: Pass cp_id_kind computed in + cp_parser_postfix_dot_deref_expression to + cp_parser_primary_expression. + +2009-01-13 Jakub Jelinek <jakub@redhat.com> + + PR c++/38795 + * tree.c (cp_walk_subtrees): Handle REINTERPRET_CAST_EXPR, + STATIC_CAST_EXPR, CONST_CAST_EXPR and DYNAMIC_CAST_EXPR the same + as CAST_EXPR. + 2009-01-12 Jason Merrill <jason@redhat.com> Steve Ellcey <sje@cup.hp.com> diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 6dc244fccb8..f8d0204f099 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -5109,6 +5109,9 @@ pushtag (tree name, tree type, tag_scope scope) if (b->kind == sk_class) { + if (!TYPE_BEING_DEFINED (current_class_type)) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + if (!PROCESSING_REAL_TEMPLATE_DECL_P ()) /* Put this TYPE_DECL on the TYPE_FIELDS list for the class. But if it's a member template class, we want diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index bf742eea079..526a9a3acef 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1586,7 +1586,7 @@ static tree cp_parser_nested_name_specifier static tree cp_parser_qualifying_entity (cp_parser *, bool, bool, bool, bool, bool); static tree cp_parser_postfix_expression - (cp_parser *, bool, bool, bool); + (cp_parser *, bool, bool, bool, cp_id_kind *); static tree cp_parser_postfix_open_square_expression (cp_parser *, tree, bool); static tree cp_parser_postfix_dot_deref_expression @@ -1596,7 +1596,7 @@ static tree cp_parser_parenthesized_expression_list static void cp_parser_pseudo_destructor_name (cp_parser *, tree *, tree *); static tree cp_parser_unary_expression - (cp_parser *, bool, bool); + (cp_parser *, bool, bool, cp_id_kind *); static enum tree_code cp_parser_unary_operator (cp_token *); static tree cp_parser_new_expression @@ -1614,17 +1614,17 @@ static tree cp_parser_new_initializer static tree cp_parser_delete_expression (cp_parser *); static tree cp_parser_cast_expression - (cp_parser *, bool, bool); + (cp_parser *, bool, bool, cp_id_kind *); static tree cp_parser_binary_expression - (cp_parser *, bool, enum cp_parser_prec); + (cp_parser *, bool, enum cp_parser_prec, cp_id_kind *); static tree cp_parser_question_colon_clause (cp_parser *, tree); static tree cp_parser_assignment_expression - (cp_parser *, bool); + (cp_parser *, bool, cp_id_kind *); static enum tree_code cp_parser_assignment_operator_opt (cp_parser *); static tree cp_parser_expression - (cp_parser *, bool); + (cp_parser *, bool, cp_id_kind *); static tree cp_parser_constant_expression (cp_parser *, bool, bool *); static tree cp_parser_builtin_offsetof @@ -3251,7 +3251,7 @@ cp_parser_primary_expression (cp_parser *parser, else { /* Parse the parenthesized expression. */ - expr = cp_parser_expression (parser, cast_p); + expr = cp_parser_expression (parser, cast_p, idk); /* Let the front end know that this expression was enclosed in parentheses. This matters in case, for example, the expression is of the form `A::B', since @@ -3354,7 +3354,7 @@ cp_parser_primary_expression (cp_parser *parser, cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); /* Now, parse the assignment-expression. */ expression = cp_parser_assignment_expression (parser, - /*cast_p=*/false); + /*cast_p=*/false, NULL); /* Look for the `,'. */ cp_parser_require (parser, CPP_COMMA, "%<,%>"); /* Parse the type-id. */ @@ -4399,7 +4399,8 @@ cp_parser_qualifying_entity (cp_parser *parser, static tree cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, - bool member_access_only_p) + bool member_access_only_p, + cp_id_kind * pidk_return) { cp_token *token; enum rid keyword; @@ -4443,7 +4444,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* And the expression which is being cast. */ cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); - expression = cp_parser_expression (parser, /*cast_p=*/true); + expression = cp_parser_expression (parser, /*cast_p=*/true, & idk); cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); /* Only type conversions to integral or enumeration types @@ -4515,7 +4516,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, tree expression; /* Look for an expression. */ - expression = cp_parser_expression (parser, /*cast_p=*/false); + expression = cp_parser_expression (parser, /*cast_p=*/false, & idk); /* Compute its typeid. */ postfix_expression = build_typeid (expression); /* Look for the `)' token. */ @@ -4767,6 +4768,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, } if (BASELINK_P (fn)) + { postfix_expression = (build_new_method_call (instance, fn, args, NULL_TREE, @@ -4774,6 +4776,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL), /*fn_p=*/NULL, tf_warning_or_error)); + } else postfix_expression = finish_call_expr (postfix_expression, args, @@ -4862,6 +4865,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, break; default: + if (pidk_return != NULL) + * pidk_return = idk; if (member_access_only_p) return is_member_access? postfix_expression : error_mark_node; else @@ -4903,7 +4908,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, if (for_offsetof) index = cp_parser_constant_expression (parser, false, NULL); else - index = cp_parser_expression (parser, /*cast_p=*/false); + index = cp_parser_expression (parser, /*cast_p=*/false, NULL); /* Look for the closing `]'. */ cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"); @@ -4956,6 +4961,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, parser->qualifying_scope = NULL_TREE; parser->object_scope = NULL_TREE; *idk = CP_ID_KIND_NONE; + /* Enter the scope corresponding to the type of the object given by the POSTFIX_EXPRESSION. */ if (!dependent_p && TREE_TYPE (postfix_expression) != NULL_TREE) @@ -5185,7 +5191,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, *non_constant_p = true; } else - expr = cp_parser_assignment_expression (parser, cast_p); + expr = cp_parser_assignment_expression (parser, cast_p, NULL); if (fold_expr_p) expr = fold_non_dependent_expr (expr); @@ -5369,7 +5375,8 @@ cp_parser_pseudo_destructor_name (cp_parser* parser, Returns a representation of the expression. */ static tree -cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p) +cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, + cp_id_kind * pidk) { cp_token *token; enum tree_code unary_operator; @@ -5506,7 +5513,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p) cast_expression = cp_parser_cast_expression (parser, unary_operator == ADDR_EXPR, - /*cast_p=*/false); + /*cast_p=*/false, pidk); /* Now, build an appropriate representation. */ switch (unary_operator) { @@ -5548,7 +5555,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p) } return cp_parser_postfix_expression (parser, address_p, cast_p, - /*member_access_only_p=*/false); + /*member_access_only_p=*/false, + pidk); } /* Returns ERROR_MARK if TOKEN is not a unary-operator. If TOKEN is a @@ -5813,7 +5821,7 @@ cp_parser_direct_new_declarator (cp_parser* parser) if (!declarator) { cp_token *token = cp_lexer_peek_token (parser->lexer); - expression = cp_parser_expression (parser, /*cast_p=*/false); + expression = cp_parser_expression (parser, /*cast_p=*/false, NULL); /* The standard requires that the expression have integral type. DR 74 adds enumeration types. We believe that the real intent is that these expressions be handled like the @@ -6001,7 +6009,8 @@ cp_parser_token_starts_cast_expression (cp_token *token) Returns a representation of the expression. */ static tree -cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p) +cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p, + cp_id_kind * pidk) { /* If it's a `(', then we might be looking at a cast. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) @@ -6076,7 +6085,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p) cp_parser_parse_definitely (parser); expr = cp_parser_cast_expression (parser, /*address_p=*/false, - /*cast_p=*/true); + /*cast_p=*/true, pidk); /* Warn about old-style casts, if so requested. */ if (warn_old_style_cast @@ -6104,7 +6113,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p) /* If we get here, then it's not a cast, so it must be a unary-expression. */ - return cp_parser_unary_expression (parser, address_p, cast_p); + return cp_parser_unary_expression (parser, address_p, cast_p, pidk); } /* Parse a binary expression of the general form: @@ -6188,7 +6197,8 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p) static tree cp_parser_binary_expression (cp_parser* parser, bool cast_p, - enum cp_parser_prec prec) + enum cp_parser_prec prec, + cp_id_kind * pidk) { cp_parser_expression_stack stack; cp_parser_expression_stack_entry *sp = &stack[0]; @@ -6199,7 +6209,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, bool overloaded_p; /* Parse the first expression. */ - lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p); + lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p, pidk); lhs_type = ERROR_MARK; for (;;) @@ -6340,12 +6350,12 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr) expr = NULL_TREE; else /* Parse the expression. */ - expr = cp_parser_expression (parser, /*cast_p=*/false); + expr = cp_parser_expression (parser, /*cast_p=*/false, NULL); /* The next token should be a `:'. */ cp_parser_require (parser, CPP_COLON, "%<:%>"); /* Parse the assignment-expression. */ - assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false); + assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); /* Build the conditional-expression. */ return build_x_conditional_expr (logical_or_expr, @@ -6366,7 +6376,8 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr) Returns a representation for the expression. */ static tree -cp_parser_assignment_expression (cp_parser* parser, bool cast_p) +cp_parser_assignment_expression (cp_parser* parser, bool cast_p, + cp_id_kind * pidk) { tree expr; @@ -6379,7 +6390,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p) else { /* Parse the binary expressions (logical-or-expression). */ - expr = cp_parser_binary_expression (parser, cast_p, PREC_NOT_OPERATOR); + expr = cp_parser_binary_expression (parser, cast_p, PREC_NOT_OPERATOR, pidk); /* If the next token is a `?' then we're actually looking at a conditional-expression. */ if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY)) @@ -6514,7 +6525,7 @@ cp_parser_assignment_operator_opt (cp_parser* parser) Returns a representation of the expression. */ static tree -cp_parser_expression (cp_parser* parser, bool cast_p) +cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk) { tree expression = NULL_TREE; @@ -6524,7 +6535,7 @@ cp_parser_expression (cp_parser* parser, bool cast_p) /* Parse the next assignment-expression. */ assignment_expression - = cp_parser_assignment_expression (parser, cast_p); + = cp_parser_assignment_expression (parser, cast_p, pidk); /* If this is the first assignment-expression, we can just save it away. */ if (!expression) @@ -6603,7 +6614,7 @@ cp_parser_constant_expression (cp_parser* parser, For example, cp_parser_initializer_clauses uses this function to determine whether a particular assignment-expression is in fact constant. */ - expression = cp_parser_assignment_expression (parser, /*cast_p=*/false); + expression = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); /* Restore the old settings. */ parser->integral_constant_expression_p = saved_integral_constant_expression_p; @@ -7086,7 +7097,7 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr) /* If the next token is a ';', then there is no expression statement. */ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - statement = cp_parser_expression (parser, /*cast_p=*/false); + statement = cp_parser_expression (parser, /*cast_p=*/false, NULL); /* Consume the final `;'. */ cp_parser_consume_semicolon_at_end_of_statement (parser); @@ -7454,7 +7465,7 @@ cp_parser_condition (cp_parser* parser) cp_parser_abort_tentative_parse (parser); /* Otherwise, we are looking at an expression. */ - return cp_parser_expression (parser, /*cast_p=*/false); + return cp_parser_expression (parser, /*cast_p=*/false, NULL); } /* Parse an iteration-statement. @@ -7526,7 +7537,7 @@ cp_parser_iteration_statement (cp_parser* parser) /* Look for the `('. */ cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); /* Parse the expression. */ - expression = cp_parser_expression (parser, /*cast_p=*/false); + expression = cp_parser_expression (parser, /*cast_p=*/false, NULL); /* We're done with the do-statement. */ finish_do_stmt (expression, statement); /* Look for the `)'. */ @@ -7558,7 +7569,7 @@ cp_parser_iteration_statement (cp_parser* parser) /* If there's an expression, process it. */ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) - expression = cp_parser_expression (parser, /*cast_p=*/false); + expression = cp_parser_expression (parser, /*cast_p=*/false, NULL); finish_for_expr (expression, statement); /* Look for the `)'. */ cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); @@ -7699,7 +7710,7 @@ cp_parser_jump_statement (cp_parser* parser) expr = cp_parser_braced_list (parser, &expr_non_constant_p); } else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - expr = cp_parser_expression (parser, /*cast_p=*/false); + expr = cp_parser_expression (parser, /*cast_p=*/false, NULL); else /* If the next token is a `;', then there is no expression. */ @@ -7720,7 +7731,7 @@ cp_parser_jump_statement (cp_parser* parser) /* Consume the '*' token. */ cp_lexer_consume_token (parser->lexer); /* Parse the dependent expression. */ - finish_goto_stmt (cp_parser_expression (parser, /*cast_p=*/false)); + finish_goto_stmt (cp_parser_expression (parser, /*cast_p=*/false, NULL)); } else finish_goto_stmt (cp_parser_identifier (parser)); @@ -8857,7 +8868,7 @@ cp_parser_decltype (cp_parser *parser) /* Parse a class member access. */ expr = cp_parser_postfix_expression (parser, /*address_p=*/false, /*cast_p=*/false, - /*member_access_only_p=*/true); + /*member_access_only_p=*/true, NULL); if (expr && expr != error_mark_node @@ -8876,7 +8887,7 @@ cp_parser_decltype (cp_parser *parser) cp_parser_abort_tentative_parse (parser); /* Parse a full expression. */ - expr = cp_parser_expression (parser, /*cast_p=*/false); + expr = cp_parser_expression (parser, /*cast_p=*/false, NULL); } /* Go back to evaluating expressions. */ @@ -14424,7 +14435,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p) if (template_parm_p) push_deferring_access_checks (dk_no_deferred); default_argument - = cp_parser_assignment_expression (parser, /*cast_p=*/false); + = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); if (template_parm_p) pop_deferring_access_checks (); /* Restore saved state. */ @@ -16512,7 +16523,7 @@ cp_parser_throw_expression (cp_parser* parser) expression = NULL_TREE; else expression = cp_parser_assignment_expression (parser, - /*cast_p=*/false); + /*cast_p=*/false, NULL); return build_throw (expression); } @@ -16604,7 +16615,7 @@ cp_parser_asm_operand_list (cp_parser* parser) /* Look for the `('. */ cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); /* Parse the expression. */ - expression = cp_parser_expression (parser, /*cast_p=*/false); + expression = cp_parser_expression (parser, /*cast_p=*/false, NULL); /* Look for the `)'. */ cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); @@ -17875,7 +17886,7 @@ static tree cp_parser_simple_cast_expression (cp_parser *parser) { return cp_parser_cast_expression (parser, /*address_p=*/false, - /*cast_p=*/false); + /*cast_p=*/false, NULL); } /* Parse a functional cast to TYPE. Returns an expression @@ -18241,7 +18252,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) cp_parser_push_lexer_for_tokens (parser, tokens); /* Parse the assignment-expression. */ - parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false); + parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); if (!processing_template_decl) parsed_arg = check_default_argument (TREE_VALUE (parm), parsed_arg); @@ -18362,7 +18373,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword) looking at the unary-expression production. */ if (!expr) expr = cp_parser_unary_expression (parser, /*address_p=*/false, - /*cast_p=*/false); + /*cast_p=*/false, NULL); if (pack_expansion_p) /* Build a pack expansion. */ @@ -19090,7 +19101,7 @@ cp_parser_objc_message_receiver (cp_parser* parser) /* An Objective-C message receiver may be either (1) a type or (2) an expression. */ cp_parser_parse_tentatively (parser); - rcv = cp_parser_expression (parser, false); + rcv = cp_parser_expression (parser, false, NULL); if (cp_parser_parse_definitely (parser)) return rcv; @@ -19142,7 +19153,7 @@ cp_parser_objc_message_args (cp_parser* parser) maybe_unary_selector_p = false; cp_parser_require (parser, CPP_COLON, "%<:%>"); - arg = cp_parser_assignment_expression (parser, false); + arg = cp_parser_assignment_expression (parser, false, NULL); sel_args = chainon (sel_args, @@ -19157,7 +19168,7 @@ cp_parser_objc_message_args (cp_parser* parser) tree arg; cp_lexer_consume_token (parser->lexer); - arg = cp_parser_assignment_expression (parser, false); + arg = cp_parser_assignment_expression (parser, false, NULL); addl_args = chainon (addl_args, @@ -20057,7 +20068,7 @@ cp_parser_objc_synchronized_statement (cp_parser *parser) { location = cp_lexer_peek_token (parser->lexer)->location; cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); - lock = cp_parser_expression (parser, false); + lock = cp_parser_expression (parser, false, NULL); cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST @@ -20082,7 +20093,7 @@ cp_parser_objc_throw_statement (cp_parser *parser) { cp_parser_require_keyword (parser, RID_AT_THROW, "%<@throw%>"); if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - expr = cp_parser_assignment_expression (parser, false); + expr = cp_parser_assignment_expression (parser, false, NULL); cp_parser_consume_semicolon_at_end_of_statement (parser); @@ -20439,7 +20450,7 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list, if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) return list; - t = cp_parser_expression (parser, false); + t = cp_parser_expression (parser, false, NULL); if (t == error_mark_node || !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) @@ -20596,7 +20607,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location cp_lexer_consume_token (parser->lexer); token = cp_lexer_peek_token (parser->lexer); - t = cp_parser_assignment_expression (parser, false); + t = cp_parser_assignment_expression (parser, false, NULL); if (t == error_mark_node) goto resync_fail; @@ -20825,7 +20836,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok) cp_parser_require_pragma_eol (parser, pragma_tok); lhs = cp_parser_unary_expression (parser, /*address_p=*/false, - /*cast_p=*/false); + /*cast_p=*/false, NULL); switch (TREE_CODE (lhs)) { case ERROR_MARK: @@ -20882,7 +20893,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok) } cp_lexer_consume_token (parser->lexer); - rhs = cp_parser_expression (parser, false); + rhs = cp_parser_expression (parser, false, NULL); if (rhs == error_mark_node) goto saw_error; break; @@ -20956,7 +20967,7 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok) static tree cp_parser_omp_for_cond (cp_parser *parser, tree decl) { - tree lhs = cp_parser_cast_expression (parser, false, false), rhs; + tree lhs = cp_parser_cast_expression (parser, false, false, NULL), rhs; enum tree_code op; cp_token *token; @@ -20982,7 +20993,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl) cp_lexer_consume_token (parser->lexer); rhs = cp_parser_binary_expression (parser, false, - PREC_RELATIONAL_EXPRESSION); + PREC_RELATIONAL_EXPRESSION, NULL); if (rhs == error_mark_node || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) { @@ -21009,7 +21020,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) op = (token->type == CPP_PLUS_PLUS ? PREINCREMENT_EXPR : PREDECREMENT_EXPR); cp_lexer_consume_token (parser->lexer); - lhs = cp_parser_cast_expression (parser, false, false); + lhs = cp_parser_cast_expression (parser, false, false, NULL); if (lhs != decl) return error_mark_node; return build2 (op, TREE_TYPE (decl), decl, NULL_TREE); @@ -21034,13 +21045,13 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) if (op != NOP_EXPR) { - rhs = cp_parser_assignment_expression (parser, false); + rhs = cp_parser_assignment_expression (parser, false, NULL); rhs = build2 (op, TREE_TYPE (decl), decl, rhs); return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs); } lhs = cp_parser_binary_expression (parser, false, - PREC_ADDITIVE_EXPRESSION); + PREC_ADDITIVE_EXPRESSION, NULL); token = cp_lexer_peek_token (parser->lexer); decl_first = lhs == decl; if (decl_first) @@ -21054,7 +21065,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR; cp_lexer_consume_token (parser->lexer); rhs = cp_parser_binary_expression (parser, false, - PREC_ADDITIVE_EXPRESSION); + PREC_ADDITIVE_EXPRESSION, NULL); token = cp_lexer_peek_token (parser->lexer); if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first) { @@ -21224,7 +21235,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) { /* Consume '='. */ cp_lexer_consume_token (parser->lexer); - init = cp_parser_assignment_expression (parser, false); + init = cp_parser_assignment_expression (parser, false, NULL); non_class: if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE) @@ -21257,7 +21268,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) cp_parser_parse_definitely (parser); cp_parser_require (parser, CPP_EQ, "%<=%>"); - rhs = cp_parser_assignment_expression (parser, false); + rhs = cp_parser_assignment_expression (parser, false, NULL); finish_expr_stmt (build_x_modify_expr (decl, NOP_EXPR, rhs, tf_warning_or_error)); @@ -21267,7 +21278,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) { decl = NULL; cp_parser_abort_tentative_parse (parser); - init = cp_parser_expression (parser, false); + init = cp_parser_expression (parser, false, NULL); if (init) { if (TREE_CODE (init) == MODIFY_EXPR @@ -21384,7 +21395,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) || CLASS_TYPE_P (TREE_TYPE (decl)))) incr = cp_parser_omp_for_incr (parser, decl); else - incr = cp_parser_expression (parser, false); + incr = cp_parser_expression (parser, false, NULL); } if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index ad84cc8d8d3..8ac272095be 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1,6 +1,6 @@ /* Language-dependent node constructors for parse phase of GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) @@ -2443,6 +2443,10 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func, break; case CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case STATIC_CAST_EXPR: + case CONST_CAST_EXPR: + case DYNAMIC_CAST_EXPR: if (TREE_TYPE (*tp)) WALK_SUBTREE (TREE_TYPE (*tp)); diff --git a/gcc/dce.c b/gcc/dce.c index 08a0f5048e3..75e148cf434 100644 --- a/gcc/dce.c +++ b/gcc/dce.c @@ -1,5 +1,5 @@ /* RTL dead code elimination. - Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "timevar.h" #include "tree-pass.h" #include "dbgcnt.h" +#include "tm_p.h" DEF_VEC_I(int); DEF_VEC_ALLOC_I(int,heap); @@ -57,6 +58,7 @@ static sbitmap marked; static bitmap_obstack dce_blocks_bitmap_obstack; static bitmap_obstack dce_tmp_bitmap_obstack; +static bool find_call_stack_args (rtx, bool, bool, bitmap); /* A subroutine for which BODY is part of the instruction being tested; either the top-level pattern, or an element of a PARALLEL. The @@ -94,7 +96,7 @@ deletable_insn_p_1 (rtx body) the DCE pass. */ static bool -deletable_insn_p (rtx insn, bool fast) +deletable_insn_p (rtx insn, bool fast, bitmap arg_stores) { rtx body, x; int i; @@ -111,7 +113,7 @@ deletable_insn_p (rtx insn, bool fast) infinite loop. */ && (RTL_CONST_OR_PURE_CALL_P (insn) && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))) - return true; + return find_call_stack_args (insn, false, fast, arg_stores); if (!NONJUMP_INSN_P (insn)) return false; @@ -174,6 +176,12 @@ mark_insn (rtx insn, bool fast) SET_BIT (marked, INSN_UID (insn)); if (dump_file) fprintf (dump_file, " Adding insn %d to worklist\n", INSN_UID (insn)); + if (CALL_P (insn) + && !df_in_progress + && !SIBLING_CALL_P (insn) + && (RTL_CONST_OR_PURE_CALL_P (insn) + && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))) + find_call_stack_args (insn, true, fast, NULL); } } @@ -212,6 +220,254 @@ mark_nonreg_stores (rtx body, rtx insn, bool fast) } +/* Try to find all stack stores of CALL_INSN arguments if + ACCUMULATE_OUTGOING_ARGS. If all stack stores have been found + and it is therefore safe to eliminate the call, return true, + otherwise return false. This function should be first called + with DO_MARK false, and only when the CALL_INSN is actually + going to be marked called again with DO_MARK true. */ + +static bool +find_call_stack_args (rtx call_insn, bool do_mark, bool fast, + bitmap arg_stores) +{ + rtx p, insn, prev_insn; + bool ret; + HOST_WIDE_INT min_sp_off, max_sp_off; + bitmap sp_bytes; + + gcc_assert (CALL_P (call_insn)); + if (!ACCUMULATE_OUTGOING_ARGS) + return true; + + if (!do_mark) + { + gcc_assert (arg_stores); + bitmap_clear (arg_stores); + } + + min_sp_off = INTTYPE_MAXIMUM (HOST_WIDE_INT); + max_sp_off = 0; + + /* First determine the minimum and maximum offset from sp for + stored arguments. */ + for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1)) + if (GET_CODE (XEXP (p, 0)) == USE + && MEM_P (XEXP (XEXP (p, 0), 0))) + { + rtx mem = XEXP (XEXP (p, 0), 0), addr, size; + HOST_WIDE_INT off = 0; + size = MEM_SIZE (mem); + if (size == NULL_RTX) + return false; + addr = XEXP (mem, 0); + if (GET_CODE (addr) == PLUS + && REG_P (XEXP (addr, 0)) + && CONST_INT_P (XEXP (addr, 1))) + { + off = INTVAL (XEXP (addr, 1)); + addr = XEXP (addr, 0); + } + if (addr != stack_pointer_rtx) + { + if (!REG_P (addr)) + return false; + /* If not fast, use chains to see if addr wasn't set to + sp + offset. */ + if (!fast) + { + df_ref *use_rec; + struct df_link *defs; + rtx set; + + for (use_rec = DF_INSN_USES (call_insn); *use_rec; use_rec++) + if (rtx_equal_p (addr, DF_REF_REG (*use_rec))) + break; + + if (*use_rec == NULL) + return false; + + for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next) + if (! DF_REF_IS_ARTIFICIAL (defs->ref)) + break; + + if (defs == NULL) + return false; + + set = single_set (DF_REF_INSN (defs->ref)); + if (!set) + return false; + + if (GET_CODE (SET_SRC (set)) != PLUS + || XEXP (SET_SRC (set), 0) != stack_pointer_rtx + || !CONST_INT_P (XEXP (SET_SRC (set), 1))) + return false; + + off += INTVAL (XEXP (SET_SRC (set), 1)); + } + else + return false; + } + min_sp_off = MIN (min_sp_off, off); + max_sp_off = MAX (max_sp_off, off + INTVAL (size)); + } + + if (min_sp_off >= max_sp_off) + return true; + sp_bytes = BITMAP_ALLOC (NULL); + + /* Set bits in SP_BYTES bitmap for bytes relative to sp + min_sp_off + which contain arguments. Checking has been done in the previous + loop. */ + for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1)) + if (GET_CODE (XEXP (p, 0)) == USE + && MEM_P (XEXP (XEXP (p, 0), 0))) + { + rtx mem = XEXP (XEXP (p, 0), 0), addr; + HOST_WIDE_INT off = 0, byte; + addr = XEXP (mem, 0); + if (GET_CODE (addr) == PLUS + && REG_P (XEXP (addr, 0)) + && CONST_INT_P (XEXP (addr, 1))) + { + off = INTVAL (XEXP (addr, 1)); + addr = XEXP (addr, 0); + } + if (addr != stack_pointer_rtx) + { + df_ref *use_rec; + struct df_link *defs; + rtx set; + + for (use_rec = DF_INSN_USES (call_insn); *use_rec; use_rec++) + if (rtx_equal_p (addr, DF_REF_REG (*use_rec))) + break; + + for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next) + if (! DF_REF_IS_ARTIFICIAL (defs->ref)) + break; + + set = single_set (DF_REF_INSN (defs->ref)); + off += INTVAL (XEXP (SET_SRC (set), 1)); + } + for (byte = off; byte < off + INTVAL (MEM_SIZE (mem)); byte++) + { + gcc_assert (!bitmap_bit_p (sp_bytes, byte - min_sp_off)); + bitmap_set_bit (sp_bytes, byte - min_sp_off); + } + } + + /* Walk backwards, looking for argument stores. The search stops + when seeting another call, sp adjustment or memory store other than + argument store. */ + ret = false; + for (insn = PREV_INSN (call_insn); insn; insn = prev_insn) + { + rtx set, mem, addr; + HOST_WIDE_INT off, byte; + + if (insn == BB_HEAD (BLOCK_FOR_INSN (call_insn))) + prev_insn = NULL_RTX; + else + prev_insn = PREV_INSN (insn); + + if (CALL_P (insn)) + break; + + if (!INSN_P (insn)) + continue; + + set = single_set (insn); + if (!set || SET_DEST (set) == stack_pointer_rtx) + break; + + if (!MEM_P (SET_DEST (set))) + continue; + + mem = SET_DEST (set); + addr = XEXP (mem, 0); + off = 0; + if (GET_CODE (addr) == PLUS + && REG_P (XEXP (addr, 0)) + && CONST_INT_P (XEXP (addr, 1))) + { + off = INTVAL (XEXP (addr, 1)); + addr = XEXP (addr, 0); + } + if (addr != stack_pointer_rtx) + { + if (!REG_P (addr)) + break; + if (!fast) + { + df_ref *use_rec; + struct df_link *defs; + rtx set; + + for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) + if (rtx_equal_p (addr, DF_REF_REG (*use_rec))) + break; + + if (*use_rec == NULL) + break; + + for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next) + if (! DF_REF_IS_ARTIFICIAL (defs->ref)) + break; + + if (defs == NULL) + break; + + set = single_set (DF_REF_INSN (defs->ref)); + if (!set) + break; + + if (GET_CODE (SET_SRC (set)) != PLUS + || XEXP (SET_SRC (set), 0) != stack_pointer_rtx + || !CONST_INT_P (XEXP (SET_SRC (set), 1))) + break; + + off += INTVAL (XEXP (SET_SRC (set), 1)); + } + else + break; + } + + if (GET_MODE_SIZE (GET_MODE (mem)) == 0) + break; + + for (byte = off; byte < off + GET_MODE_SIZE (GET_MODE (mem)); byte++) + { + if (byte < min_sp_off + || byte >= max_sp_off + || !bitmap_bit_p (sp_bytes, byte - min_sp_off)) + break; + bitmap_clear_bit (sp_bytes, byte - min_sp_off); + } + + if (!deletable_insn_p (insn, fast, NULL)) + break; + + if (do_mark) + mark_insn (insn, fast); + else + bitmap_set_bit (arg_stores, INSN_UID (insn)); + + if (bitmap_empty_p (sp_bytes)) + { + ret = true; + break; + } + } + + BITMAP_FREE (sp_bytes); + if (!ret && arg_stores) + bitmap_clear (arg_stores); + + return ret; +} + + /* Delete all REG_EQUAL notes of the registers INSN writes, to prevent bad dangling REG_EQUAL notes. */ @@ -266,6 +522,9 @@ delete_unmarked_insns (void) else if (marked_insn_p (insn)) continue; + /* Beware that reaching a dbg counter limit here can easily result + in miscompiled file, whenever some insn is eliminated, but + insn that depends on it is not. */ if (!dbg_cnt (dce)) continue; @@ -300,20 +559,37 @@ static void prescan_insns_for_dce (bool fast) { basic_block bb; - rtx insn, next; - + rtx insn, prev; + bitmap arg_stores = NULL; + if (dump_file) fprintf (dump_file, "Finding needed instructions:\n"); - + + if (!df_in_progress && ACCUMULATE_OUTGOING_ARGS) + arg_stores = BITMAP_ALLOC (NULL); + FOR_EACH_BB (bb) - FOR_BB_INSNS_SAFE (bb, insn, next) - if (INSN_P (insn)) - { - if (deletable_insn_p (insn, fast)) - mark_nonreg_stores (PATTERN (insn), insn, fast); - else - mark_insn (insn, fast); - } + { + FOR_BB_INSNS_REVERSE_SAFE (bb, insn, prev) + if (INSN_P (insn)) + { + /* Don't mark argument stores now. They will be marked + if needed when the associated CALL is marked. */ + if (arg_stores && bitmap_bit_p (arg_stores, INSN_UID (insn))) + continue; + if (deletable_insn_p (insn, fast, arg_stores)) + mark_nonreg_stores (PATTERN (insn), insn, fast); + else + mark_insn (insn, fast); + } + /* find_call_stack_args only looks at argument stores in the + same bb. */ + if (arg_stores) + bitmap_clear (arg_stores); + } + + if (arg_stores) + BITMAP_FREE (arg_stores); if (dump_file) fprintf (dump_file, "Finished finding needed instructions:\n"); diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi index 17936146a2e..c5c0f9ed051 100644 --- a/gcc/doc/gty.texi +++ b/gcc/doc/gty.texi @@ -1,4 +1,4 @@ -@c Copyright (C) 2002, 2003, 2004, 2007, 2008 +@c Copyright (C) 2002, 2003, 2004, 2007, 2008, 2009 @c Free Software Foundation, Inc. @c This is part of the GCC manual. @c For copying conditions, see the file gcc.texi. @@ -69,6 +69,7 @@ These don't need to be marked. * GTY Options:: What goes inside a @code{GTY(())}. * GGC Roots:: Making global variables GGC roots. * Files:: How the generated files work. +* Invoking the garbage collector:: How to invoke the garbage collector. @end menu @node GTY Options @@ -448,3 +449,22 @@ source file. Don't forget to mention this file as a dependency in the For language frontends, there is another file that needs to be included somewhere. It will be called @file{gtype-@var{lang}.h}, where @var{lang} is the name of the subdirectory the language is contained in. + +@node Invoking the garbage collector +@section How to invoke the garbage collector +@cindex garbage collector, invocation +@findex ggc_collect + +The GCC garbage collector GGC is only invoked explicitly. In contrast +with many other garbage collectors, it is not implicitly invoked by +allocation routines when a lot of memory has been consumed. So the +only way to have GGC reclaim storage it to call the @code{ggc_collect} +function explicitly. This call is an expensive operation, as it may +have to scan the entire heap. Beware that local variables (on the GCC +call stack) are not followed by such an invocation (as many other +garbage collectors do): you should reference all your data from static +or external @code{GTY}-ed variables, and it is advised to call +@code{ggc_collect} with a shallow call stack. The GGC is an exact mark +and sweep garbage collector (so it does not scan the call stack for +pointers). In practice GCC passes don't often call @code{ggc_collect} +themselves, because it is called by the pass manager between passes. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 850d017fb16..9f96120bd60 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -8878,8 +8878,11 @@ assembly code. Permissible names are: @samp{arm2}, @samp{arm250}, @samp{arm620}, @samp{arm7}, @samp{arm7m}, @samp{arm7d}, @samp{arm7dm}, @samp{arm7di}, @samp{arm7dmi}, @samp{arm70}, @samp{arm700}, @samp{arm700i}, @samp{arm710}, @samp{arm710c}, @samp{arm7100}, +@samp{arm720}, @samp{arm7500}, @samp{arm7500fe}, @samp{arm7tdmi}, @samp{arm7tdmi-s}, -@samp{arm8}, @samp{strongarm}, @samp{strongarm110}, @samp{strongarm1100}, +@samp{arm710t}, @samp{arm720t}, @samp{arm740t}, +@samp{strongarm}, @samp{strongarm110}, @samp{strongarm1100}, +@samp{strongarm1110}, @samp{arm8}, @samp{arm810}, @samp{arm9}, @samp{arm9e}, @samp{arm920}, @samp{arm920t}, @samp{arm922t}, @samp{arm946e-s}, @samp{arm966e-s}, @samp{arm968e-s}, @samp{arm926ej-s}, @samp{arm940t}, @samp{arm9tdmi}, @@ -8887,7 +8890,8 @@ assembly code. Permissible names are: @samp{arm2}, @samp{arm250}, @samp{arm10e}, @samp{arm1020e}, @samp{arm1022e}, @samp{arm1136j-s}, @samp{arm1136jf-s}, @samp{mpcore}, @samp{mpcorenovfp}, @samp{arm1156t2-s}, @samp{arm1176jz-s}, @samp{arm1176jzf-s}, -@samp{cortex-a8}, @samp{cortex-r4}, @samp{cortex-r4f}, @samp{cortex-m3}, +@samp{cortex-a8}, @samp{cortex-a9}, +@samp{cortex-r4}, @samp{cortex-r4f}, @samp{cortex-m3}, @samp{cortex-m1}, @samp{xscale}, @samp{iwmmxt}, @samp{ep9312}. @@ -8909,7 +8913,8 @@ name to determine what kind of instructions it can emit when generating assembly code. This option can be used in conjunction with or instead of the @option{-mcpu=} option. Permissible names are: @samp{armv2}, @samp{armv2a}, @samp{armv3}, @samp{armv3m}, @samp{armv4}, @samp{armv4t}, -@samp{armv5}, @samp{armv5t}, @samp{armv5te}, @samp{armv6}, @samp{armv6j}, +@samp{armv5}, @samp{armv5t}, @samp{armv5e}, @samp{armv5te}, +@samp{armv6}, @samp{armv6j}, @samp{armv6t2}, @samp{armv6z}, @samp{armv6zk}, @samp{armv6-m}, @samp{armv7}, @samp{armv7-a}, @samp{armv7-r}, @samp{armv7-m}, @samp{iwmmxt}, @samp{ep9312}. diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b3d179910cc..d4eae5e593c 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,7 @@ +2009-01-14 Steven G. Kargl <kargl@gcc.gnu.org> + + * ChangeLog-2007: Clean out svn merge droppings. + 2009-01-10 Paul Thomas <pault@gcc.gnu.org> PR fortran/38763 diff --git a/gcc/fortran/ChangeLog-2007 b/gcc/fortran/ChangeLog-2007 index 9c34c79ca02..4597cb58fd3 100644 --- a/gcc/fortran/ChangeLog-2007 +++ b/gcc/fortran/ChangeLog-2007 @@ -87,7 +87,6 @@ * module.c (read_module): Check sym->module is there before using it in a string comparison. ->>>>>>> .r131138 2007-12-20 Tobias Burnus <burnus@net-b.de> PR fortran/34482 diff --git a/gcc/gcc.c b/gcc/gcc.c index 8e1938bd58a..e85d25de708 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -1,6 +1,6 @@ /* Compiler driver program that can handle many languages. Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -3382,6 +3382,9 @@ process_command (int argc, const char **argv) char **new_argv; char *new_argv0; int baselen; + int status = 0; + int err = 0; + const char *errmsg; while (argc > 1 && argv[1][0] == '-' && (argv[1][1] == 'V' @@ -3424,8 +3427,18 @@ process_command (int argc, const char **argv) new_argv = XDUPVEC (char *, argv, argc + 1); new_argv[0] = new_argv0; - execvp (new_argv0, new_argv); - fatal ("couldn't run '%s': %s", new_argv0, xstrerror (errno)); + errmsg = pex_one (PEX_SEARCH, new_argv0, new_argv, progname, NULL, + NULL, &status, &err); + + if (errmsg) + { + if (err == 0) + fatal ("couldn't run '%s': %s", new_argv0, errmsg); + else + fatal ("couldn't run '%s': %s: %s", new_argv0, errmsg, + xstrerror (err)); + } + exit (status); } /* Set up the default search paths. If there is no GCC_EXEC_PREFIX, diff --git a/gcc/graphite.c b/gcc/graphite.c index 27cadf3340d..116349b7202 100644 --- a/gcc/graphite.c +++ b/gcc/graphite.c @@ -61,14 +61,6 @@ along with GCC; see the file COPYING3. If not see static VEC (scop_p, heap) *current_scops; -/* Print GMP value V on stderr. */ - -void -debug_value (Value v) -{ - value_print (stderr, "%4s\n", v); -} - /* Converts a GMP constant V to a tree and returns it. */ static tree @@ -4090,31 +4082,123 @@ is_iv (tree name) } static void expand_scalar_variables_stmt (gimple, basic_block, scop_p, - loop_p, htab_t); + htab_t); +static tree +expand_scalar_variables_expr (tree, tree, enum tree_code, tree, basic_block, + scop_p, htab_t, gimple_stmt_iterator *); + +/* Copies at GSI all the scalar computations on which the ssa_name OP0 + depends on in the SCOP: these are all the scalar variables used in + the definition of OP0, that are defined outside BB and still in the + SCOP, i.e. not a parameter of the SCOP. The expression that is + returned contains only induction variables from the generated code: + MAP contains the induction variables renaming mapping, and is used + to translate the names of induction variables. */ + +static tree +expand_scalar_variables_ssa_name (tree op0, basic_block bb, + scop_p scop, htab_t map, + gimple_stmt_iterator *gsi) +{ + tree var0, var1, type; + gimple def_stmt; + enum tree_code subcode; + + if (is_parameter (scop, op0) + || is_iv (op0)) + return get_new_name_from_old_name (map, op0); + + def_stmt = SSA_NAME_DEF_STMT (op0); + + if (gimple_bb (def_stmt) == bb) + { + /* If the defining statement is in the basic block already + we do not need to create a new expression for it, we + only need to ensure its operands are expanded. */ + expand_scalar_variables_stmt (def_stmt, bb, scop, map); + return get_new_name_from_old_name (map, op0); + } + else + { + if (gimple_code (def_stmt) != GIMPLE_ASSIGN + || !bb_in_scop_p (gimple_bb (def_stmt), scop)) + return get_new_name_from_old_name (map, op0); -/* Constructs a tree which only contains old_ivs and parameters. Any - other variables that are defined outside BB will be eliminated by - using their definitions in the constructed tree. OLD_LOOP_FATHER - is the original loop that contained BB. */ + var0 = gimple_assign_rhs1 (def_stmt); + subcode = gimple_assign_rhs_code (def_stmt); + var1 = gimple_assign_rhs2 (def_stmt); + type = gimple_expr_type (def_stmt); + + return expand_scalar_variables_expr (type, var0, subcode, var1, bb, scop, + map, gsi); + } +} + +/* Copies at GSI all the scalar computations on which the expression + OP0 CODE OP1 depends on in the SCOP: these are all the scalar + variables used in OP0 and OP1, defined outside BB and still defined + in the SCOP, i.e. not a parameter of the SCOP. The expression that + is returned contains only induction variables from the generated + code: MAP contains the induction variables renaming mapping, and is + used to translate the names of induction variables. */ static tree expand_scalar_variables_expr (tree type, tree op0, enum tree_code code, tree op1, basic_block bb, scop_p scop, - loop_p old_loop_father, htab_t map) + htab_t map, gimple_stmt_iterator *gsi) { - if ((TREE_CODE_CLASS (code) == tcc_constant - && code == INTEGER_CST) - || TREE_CODE_CLASS (code) == tcc_reference) + if (TREE_CODE_CLASS (code) == tcc_constant + || TREE_CODE_CLASS (code) == tcc_declaration) return op0; + /* For data references we have to duplicate also its memory + indexing. */ + if (TREE_CODE_CLASS (code) == tcc_reference) + { + switch (code) + { + case INDIRECT_REF: + { + tree old_name = TREE_OPERAND (op0, 0); + tree expr = expand_scalar_variables_ssa_name + (old_name, bb, scop, map, gsi); + tree new_name = force_gimple_operand_gsi (gsi, expr, true, NULL, + true, GSI_SAME_STMT); + + set_symbol_mem_tag (SSA_NAME_VAR (new_name), + symbol_mem_tag (SSA_NAME_VAR (old_name))); + return fold_build1 (code, type, new_name); + } + + case ARRAY_REF: + { + tree op00 = TREE_OPERAND (op0, 0); + tree op01 = TREE_OPERAND (op0, 1); + tree op02 = TREE_OPERAND (op0, 2); + tree op03 = TREE_OPERAND (op0, 3); + tree base = expand_scalar_variables_expr + (TREE_TYPE (op00), op00, TREE_CODE (op00), NULL, bb, scop, + map, gsi); + tree subscript = expand_scalar_variables_expr + (TREE_TYPE (op01), op01, TREE_CODE (op01), NULL, bb, scop, + map, gsi); + + return build4 (ARRAY_REF, type, base, subscript, op02, op03); + } + + default: + /* The above cases should catch everything. */ + gcc_unreachable (); + } + } + if (TREE_CODE_CLASS (code) == tcc_unary) { tree op0_type = TREE_TYPE (op0); enum tree_code op0_code = TREE_CODE (op0); - tree op0_expr = - expand_scalar_variables_expr (op0_type, op0, op0_code, - NULL, bb, scop, old_loop_father, map); - + tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code, + NULL, bb, scop, map, gsi); + return fold_build1 (code, type, op0_expr); } @@ -4122,68 +4206,38 @@ expand_scalar_variables_expr (tree type, tree op0, enum tree_code code, { tree op0_type = TREE_TYPE (op0); enum tree_code op0_code = TREE_CODE (op0); - tree op0_expr = - expand_scalar_variables_expr (op0_type, op0, op0_code, - NULL, bb, scop, old_loop_father, map); + tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code, + NULL, bb, scop, map, gsi); tree op1_type = TREE_TYPE (op1); enum tree_code op1_code = TREE_CODE (op1); - tree op1_expr = - expand_scalar_variables_expr (op1_type, op1, op1_code, - NULL, bb, scop, old_loop_father, map); + tree op1_expr = expand_scalar_variables_expr (op1_type, op1, op1_code, + NULL, bb, scop, map, gsi); return fold_build2 (code, type, op0_expr, op1_expr); } if (code == SSA_NAME) - { - tree var0, var1; - gimple def_stmt; - enum tree_code subcode; - - if (is_parameter (scop, op0) - || is_iv (op0)) - return get_new_name_from_old_name (map, op0); - - def_stmt = SSA_NAME_DEF_STMT (op0); - - if (gimple_bb (def_stmt) == bb) - { - /* If the defining statement is in the basic block already - we do not need to create a new expression for it, we - only need to ensure its operands are expanded. */ - expand_scalar_variables_stmt (def_stmt, bb, scop, - old_loop_father, map); - return get_new_name_from_old_name (map, op0); - } - else - { - if (gimple_code (def_stmt) != GIMPLE_ASSIGN - || !bb_in_scop_p (gimple_bb (def_stmt), scop)) - return get_new_name_from_old_name (map, op0); - - var0 = gimple_assign_rhs1 (def_stmt); - subcode = gimple_assign_rhs_code (def_stmt); - var1 = gimple_assign_rhs2 (def_stmt); - - return expand_scalar_variables_expr (type, var0, subcode, var1, - bb, scop, old_loop_father, map); - } - } + return expand_scalar_variables_ssa_name (op0, bb, scop, map, gsi); gcc_unreachable (); return NULL; } -/* Replicates any uses of non-parameters and non-old-ivs variablesthat - are defind outside BB with code that is inserted in BB. - OLD_LOOP_FATHER is the original loop that contained STMT. */ +/* Copies at the beginning of BB all the scalar computations on which + STMT depends on in the SCOP: these are all the scalar variables used + in STMT, defined outside BB and still defined in the SCOP, i.e. not a + parameter of the SCOP. The expression that is returned contains + only induction variables from the generated code: MAP contains the + induction variables renaming mapping, and is used to translate the + names of induction variables. */ static void expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop, - loop_p old_loop_father, htab_t map) + htab_t map) { ssa_op_iter iter; use_operand_p use_p; + gimple_stmt_iterator gsi = gsi_after_labels (bb); FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) { @@ -4191,10 +4245,9 @@ expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop, tree type = TREE_TYPE (use); enum tree_code code = TREE_CODE (use); tree use_expr = expand_scalar_variables_expr (type, use, code, NULL, bb, - scop, old_loop_father, map); + scop, map, &gsi); if (use_expr != use) { - gimple_stmt_iterator gsi = gsi_after_labels (bb); tree new_use = force_gimple_operand_gsi (&gsi, use_expr, true, NULL, true, GSI_NEW_STMT); @@ -4205,21 +4258,23 @@ expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop, update_stmt (stmt); } -/* Copies the definitions outside of BB of variables that are not - induction variables nor parameters. BB must only contain - "external" references to these types of variables. OLD_LOOP_FATHER - is the original loop that contained BB. */ +/* Copies at the beginning of BB all the scalar computations on which + BB depends on in the SCOP: these are all the scalar variables used + in BB, defined outside BB and still defined in the SCOP, i.e. not a + parameter of the SCOP. The expression that is returned contains + only induction variables from the generated code: MAP contains the + induction variables renaming mapping, and is used to translate the + names of induction variables. */ static void -expand_scalar_variables (basic_block bb, scop_p scop, - loop_p old_loop_father, htab_t map) +expand_scalar_variables (basic_block bb, scop_p scop, htab_t map) { gimple_stmt_iterator gsi; for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);) { gimple stmt = gsi_stmt (gsi); - expand_scalar_variables_stmt (stmt, bb, scop, old_loop_father, map); + expand_scalar_variables_stmt (stmt, bb, scop, map); gsi_next (&gsi); } } @@ -4396,7 +4451,6 @@ register_scop_liveout_renames (scop_p scop, htab_t rename_map) static edge copy_bb_and_scalar_dependences (basic_block bb, scop_p scop, - loop_p context_loop, edge next_e, htab_t map) { basic_block new_bb = split_edge (next_e); @@ -4406,7 +4460,7 @@ copy_bb_and_scalar_dependences (basic_block bb, scop_p scop, remove_condition (new_bb); rename_variables (new_bb, map); remove_phi_nodes (new_bb); - expand_scalar_variables (new_bb, scop, context_loop, map); + expand_scalar_variables (new_bb, scop, map); register_scop_liveout_renames (scop, map); return next_e; @@ -4578,7 +4632,7 @@ translate_clast (scop_p scop, struct loop *context_loop, loop_iv_stack_patch_for_consts (ivstack, (struct clast_user_stmt *) stmt); build_iv_mapping (ivstack, map, gbb, scop); next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), scop, - context_loop, next_e, map); + next_e, map); htab_delete (map); loop_iv_stack_remove_constants (ivstack); update_ssa (TODO_update_ssa); @@ -5118,6 +5172,82 @@ scop_insert_phis_for_liveouts (sese region, basic_block bb, update_ssa (TODO_update_ssa); } +/* Get the definition of NAME before the SCOP. Keep track of the + basic blocks that have been VISITED in a bitmap. */ + +static tree +get_vdef_before_scop (scop_p scop, tree name, sbitmap visited) +{ + unsigned i; + gimple def_stmt = SSA_NAME_DEF_STMT (name); + basic_block def_bb = gimple_bb (def_stmt); + + if (!bb_in_scop_p (def_bb, scop)) + return name; + + if (TEST_BIT (visited, def_bb->index)) + return NULL_TREE; + + SET_BIT (visited, def_bb->index); + + switch (gimple_code (def_stmt)) + { + case GIMPLE_PHI: + for (i = 0; i < gimple_phi_num_args (def_stmt); i++) + { + tree arg = gimple_phi_arg_def (def_stmt, i); + tree res = get_vdef_before_scop (scop, arg, visited); + if (res) + return res; + } + return NULL_TREE; + + default: + return NULL_TREE; + } +} + +/* Adjust a virtual phi node PHI that is placed at the end of the + generated code for SCOP: + + | if (1) + | generated code from REGION; + | else + | REGION; + + The FALSE_E edge comes from the original code, TRUE_E edge comes + from the code generated for the SCOP. */ + +static void +scop_adjust_vphi (scop_p scop, gimple phi, edge true_e) +{ + unsigned i; + + gcc_assert (gimple_phi_num_args (phi) == 2); + + for (i = 0; i < gimple_phi_num_args (phi); i++) + if (gimple_phi_arg_edge (phi, i) == true_e) + { + tree true_arg, false_arg, before_scop_arg; + sbitmap visited; + + true_arg = gimple_phi_arg_def (phi, i); + if (!SSA_NAME_IS_DEFAULT_DEF (true_arg)) + return; + + false_arg = gimple_phi_arg_def (phi, i == 0 ? 1 : 0); + if (SSA_NAME_IS_DEFAULT_DEF (false_arg)) + return; + + visited = sbitmap_alloc (last_basic_block); + sbitmap_zero (visited); + before_scop_arg = get_vdef_before_scop (scop, false_arg, visited); + gcc_assert (before_scop_arg != NULL_TREE); + SET_PHI_ARG_DEF (phi, i, before_scop_arg); + sbitmap_free (visited); + } +} + /* Adjusts the phi nodes in the block BB for variables defined in SCOP_REGION and used outside the SCOP_REGION. The code generation moves SCOP_REGION in the else clause of an "if (1)" and generates @@ -5144,7 +5274,10 @@ scop_adjust_phis_for_liveouts (scop_p scop, basic_block bb, edge false_e, gimple phi = gsi_stmt (si); if (!is_gimple_reg (PHI_RESULT (phi))) - continue; + { + scop_adjust_vphi (scop, phi, true_e); + continue; + } for (i = 0; i < gimple_phi_num_args (phi); i++) if (gimple_phi_arg_edge (phi, i) == false_e) @@ -5326,9 +5459,6 @@ gloog (scop_p scop, struct clast_stmt *stmt) recompute_all_dominators (); graphite_verify (); - cleanup_tree_cfg (); - recompute_all_dominators (); - graphite_verify (); } /* Returns the number of data references in SCOP. */ @@ -6022,6 +6152,7 @@ graphite_transform_loops (void) } /* Cleanup. */ + cleanup_tree_cfg (); free_scops (current_scops); cloog_finalize (); free_original_copy_tables (); diff --git a/gcc/graphite.h b/gcc/graphite.h index a1801966ed1..76f26c8728a 100644 --- a/gcc/graphite.h +++ b/gcc/graphite.h @@ -381,7 +381,6 @@ extern void debug_rename_map (htab_t); extern void debug_ivtype_map (htab_t); extern void debug_loop_vec (graphite_bb_p); extern void debug_oldivs (scop_p); -extern void debug_value (Value); /* Describes the type of an iv stack entry. */ typedef enum { diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index 244d3bc9b3e..cce2abfd6f6 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "df.h" #include "sparseset.h" #include "ira-int.h" +#include "addresses.h" /* This file contains code responsible for allocno conflict creation, allocno copy creation and allocno info accumulation on upper level @@ -788,12 +789,12 @@ ira_build_conflicts (void) ira_free (conflicts); } } - if (! CLASS_LIKELY_SPILLED_P (BASE_REG_CLASS)) + if (! CLASS_LIKELY_SPILLED_P (base_reg_class (VOIDmode, ADDRESS, SCRATCH))) CLEAR_HARD_REG_SET (temp_hard_reg_set); else { COPY_HARD_REG_SET (temp_hard_reg_set, - reg_class_contents[BASE_REG_CLASS]); + reg_class_contents[base_reg_class (VOIDmode, ADDRESS, SCRATCH)]); AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs); AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set); } diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index c7868f39a54..0d1e402d82b 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "target.h" #include "flags.h" +#include "except.h" #include "hard-reg-set.h" #include "basic-block.h" #include "insn-config.h" @@ -985,6 +986,13 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) SET_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a)); SET_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a)); } + if (can_throw_internal (insn)) + { + IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), + call_used_reg_set); + IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), + call_used_reg_set); + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a34e95f44f9..237ce656c31 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,140 @@ +2009-01-15 Dodji Seketeli <dodji@redhat.com> + + PR c++/38636 + * g++.dg/parse/crash50.C: New test. + +2009-01-14 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/38245 + * gcc.dg/pr38245-3.c: New test. + * gcc.dg/pr38245-3.h: New file. + * gcc.dg/pr38245-4.c: New file. + * gcc.dg/pr38364.c: New test. + +2009-01-14 Adam Nemet <anemet@caviumnetworks.com> + + * gcc.target/mips/mips.exp (mips_option_tests(-mips16)): Make the + sequence PC-relative. + +2009-01-14 Mark Mitchell <mark@codesourcery.com> + + * gcc.target/arm/long-calls-1.c: Tolerate the lack of sibling + calls and/or PLT markers. + * gcc.target/arm/long-calls-2.c: Tolerate the lack of sibling + calls and/or PLT markers. + * gcc.target/arm/long-calls-3.c: Tolerate the lack of sibling + calls and/or PLT markers. + * gcc.target/arm/long-calls-4.c: Tolerate the lack of sibling + calls and/or PLT markers. + +2009-01-14 Daniel Jacobowitz <dan@codesourcery.com> + Nathan Froyd <froydnj@codesourcery.com> + Joseph Myers <joseph@codesourcery.com> + + * lib/target-supports.exp (check_effective_target_powerpc_spe_nocache): + New function. + * gcc.target/powerpc/20030218-1.c: Skip if not powerpc_spe_nocache + and use consistent CFLAGS. + * gcc.target/powerpc/20030505.c: Likewise. + * gcc.target/powerpc/20081204-1.c: Likewise. + * gcc.target/powerpc/ppc-spe.c: Likewise. + * gcc.target/powerpc/spe1.c: Likewise. + * g++.dg/ext/spe1.C: Likewise. + * g++.dg/other/opaque-1.C: Likewise. + * g++.dg/other/opaque-2.C: Likewise. + * g++.dg/other/opaque-3.C: Likewise. + +2009-01-14 Mark Mitchell <mark@codesourcery.com> + + * gcc.dg/vect/vect-105.c: Prevent compiler from hoisting abort + out of loop. + +2009-01-14 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/38826 + PR middle-end/38477 + * gcc.dg/Wstrict-aliasing-bogus-pta-1.c: New testcase. + +2009-01-13 Sebastian Pop <sebastian.pop@amd.com> + + * gcc.dg/graphite/pr38786.c: Fix commit problem. + +2009-01-14 Nick Clifton <nickc@redhat.com> + + PR c++/37862 + * g++.cp/parse/pr37862.C: New test. + +2009-01-14 Julian Brown <julian@codesourcery.com> + + * gcc.target/arm/eabi1.c (__eabi_uread4, __eabi_uwrite4) + (__eabi_uread8, __eabi_uwrite8): Change spellings of declarations + to... + (__aeabi_uread4, __aeabi_uwrite4, __aeabi_uread8, __aeabi_uwrite8): + These. + +2009-01-13 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/38774 + * gcc.dg/torture/pr38774.c: New test. + + PR c++/38795 + * g++.dg/cpp0x/pr38795.C: New test. + +2009-01-13 Daniel Jacobowitz <dan@codesourcery.com> + Nathan Froyd <froydnj@codesourcery.com> + Joseph Myers <joseph@codesourcery.com> + + * gcc.target/powerpc/altivec-consts.c: Run if vmx_hw, compile + otherwise. Do not check for AltiVec at runtime. + * gcc.target/powerpc/altivec-varargs-1.c: Likewise. + * gcc.target/powerpc/altivec-vec-merge.c: Likewise. + * gcc.target/powerpc/altivec-1.c: Likewise. + * gcc.target/powerpc/altivec-3.c: Likewise. + * gcc.target/powerpc/altivec-10.c: Likewise. + * gcc.target/powerpc/altivec-12.c: Likewise. + * gcc.target/powerpc/altivec-24.c: Likewise. + * gcc.target/powerpc/altivec-cell-2.c: Likewise. + * gcc.target/powerpc/altivec-cell-3.c: Likewise. + * gcc.target/powerpc/altivec-cell-4.c: Likewise. + * gcc.target/powerpc/pr35907.c: Likewise. + * gcc.target/powerpc/altivec-cell-8.c: Run if cell_hw, compile + otherwise. Do not check for Cell at runtime. + * gcc.target/powerpc/altivec_check.h: Delete. + + * g++.dg/ext/altivec-2.C: Do not check for AltiVec at runtime. + * g++.dg/ext/altivec-3.C: Run if vmx_hw, compile otherwise. Do + not check for AltiVec at runtime. + * g++.dg/ext/altivec-cell-2.C: Likewise. + * g++.dg/ext/altivec-cell-3.C: Likewise. + * g++.dg/ext/altivec-cell-4.C: Likewise. + * g++.dg/eh/simd-2.C: Only use -maltivec if vmx_hw. + * g++.dg/eh/check-vect.h (sig_ill_handler): Remove AltiVec runtime + check. + * g++.dg/ext/altivec_check.h: Delete. + +2009-01-13 Nathan Froyd <froydnj@codesourcery.com> + + * gcc.target/powerpc/altivec-macros.c: Require a powerpc_altivec_ok + effective target. Adjust line numbers accordingly. + +2009-01-13 Mark Mitchell <mark@codesourcery.com> + + * gcc.target/i386/sse-10.c: Pass -mno-omit-leaf-frame-pointer. + +2009-01-13 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/38786 + * gcc.dg/graphite/pr38786.c: New. + +2009-01-13 Uros Bizjak <ubizjak@gmail.com> + + Revert: + 2009-01-05 Uros Bizjak <ubizjak@gmail.com> + + * gcc.dg/compat/struct-layout-1_generate.c (dg-options): Add -mieee + for alpha*-*-* targets. + * g++.dg/compat/struct-layout-1_generate.c (dg-options): Ditto. + 2009-01-12 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libfortran/38772 diff --git a/gcc/testsuite/ChangeLog-2008 b/gcc/testsuite/ChangeLog-2008 index e89a011549a..281c8a66527 100644 --- a/gcc/testsuite/ChangeLog-2008 +++ b/gcc/testsuite/ChangeLog-2008 @@ -3280,7 +3280,6 @@ PR tree-optimization/37508 * gcc.dg/tree-ssa/pr37508.c: New testcase. ->>>>>>> .r140590 2008-09-15 Aldy Hernandez <aldyh@redhat.com> * g++.old-deja/g++.brendan/crash16.C: Function name is the correct diff --git a/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c b/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c index b314d7079b3..575ad61a01a 100644 --- a/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c +++ b/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c @@ -48,8 +48,7 @@ const char *dg_options[] = { "/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* powerpc*-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n", "/* { dg-options \"%s-I%s -mno-mmx -fno-common\" { target i?86-*-darwin* x86_64-*-darwin* } } */\n", "/* { dg-options \"%s-I%s -mno-base-addresses\" { target mmix-*-* } } */\n", -"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n", -"/* { dg-options \"%s-I%s -mieee\" { target alpha*-*-* } } */\n" +"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n" #define NDG_OPTIONS (sizeof (dg_options) / sizeof (dg_options[0])) }; diff --git a/gcc/testsuite/g++.dg/cpp0x/pr38795.C b/gcc/testsuite/g++.dg/cpp0x/pr38795.C new file mode 100644 index 00000000000..54fb361d3d4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr38795.C @@ -0,0 +1,13 @@ +// PR c++/38795 +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +template<typename... T> int foo(int i) +{ + return *reinterpret_cast<T*>(i); // { dg-error "not expanded with|T" } +} + +void bar(int i) +{ + foo<int>(i); +} diff --git a/gcc/testsuite/g++.dg/eh/check-vect.h b/gcc/testsuite/g++.dg/eh/check-vect.h index 4321be0a4a6..b46a8827598 100644 --- a/gcc/testsuite/g++.dg/eh/check-vect.h +++ b/gcc/testsuite/g++.dg/eh/check-vect.h @@ -13,10 +13,7 @@ sig_ill_handler (int sig) void check_vect (void) { signal(SIGILL, sig_ill_handler); -#if defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__) || defined(powerpc) - /* Altivec instruction, 'vor %v0,%v0,%v0'. */ - asm volatile (".long 0x10000484"); -#elif defined(__i386__) || defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) /* SSE2 instruction: movsd %xmm0,%xmm0 */ asm volatile (".byte 0xf2,0x0f,0x10,0xc0"); #elif defined(__sparc__) diff --git a/gcc/testsuite/g++.dg/eh/simd-2.C b/gcc/testsuite/g++.dg/eh/simd-2.C index e2af86636ac..b4c8690e9de 100644 --- a/gcc/testsuite/g++.dg/eh/simd-2.C +++ b/gcc/testsuite/g++.dg/eh/simd-2.C @@ -3,9 +3,7 @@ // { dg-options "-O" } // { dg-options "-O -w" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } // { dg-options "-O -w" { target powerpc*-*-* } } -// { dg-options "-O -w -maltivec" { target { powerpc*-*-linux* && powerpc_altivec_ok } } } -// { dg-options "-O -w -maltivec" { target { powerpc*-*-darwin* && powerpc_altivec_ok } } } -// { dg-xfail-if "" { "powerpc-*-eabispe*" "powerpc-ibm-aix*" } { "*" } { "" } } +// { dg-options "-O -w -maltivec" { target { powerpc*-*-* && vmx_hw } } } // { dg-do run } #include "check-vect.h" diff --git a/gcc/testsuite/g++.dg/ext/altivec-2.C b/gcc/testsuite/g++.dg/ext/altivec-2.C index 268ff998946..299693694f6 100644 --- a/gcc/testsuite/g++.dg/ext/altivec-2.C +++ b/gcc/testsuite/g++.dg/ext/altivec-2.C @@ -6,7 +6,6 @@ arguments. */ #include <altivec.h> -#include "altivec_check.h" int main (int argc, const char * argv[]) { @@ -15,8 +14,6 @@ int main (int argc, const char * argv[]) vector float v; const vector float cv = (vector float){1.0, 2.0, 3.0, 4.0}; - altivec_check (); - vec_dst(&cv, i, 0); v = vec_ld(0, &cv); v = vec_lde(0, &cf); diff --git a/gcc/testsuite/g++.dg/ext/altivec-3.C b/gcc/testsuite/g++.dg/ext/altivec-3.C index d42303d8140..15113205950 100644 --- a/gcc/testsuite/g++.dg/ext/altivec-3.C +++ b/gcc/testsuite/g++.dg/ext/altivec-3.C @@ -1,4 +1,5 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ @@ -10,7 +11,6 @@ #include <stdlib.h> #include <altivec.h> -#include "altivec_check.h" #define CHECK_INVARIANT(expr) \ if (!(expr)) { \ @@ -132,7 +132,6 @@ void main1(void) int main(void) { - altivec_check(); main1(); return 0; } diff --git a/gcc/testsuite/g++.dg/ext/altivec-cell-2.C b/gcc/testsuite/g++.dg/ext/altivec-cell-2.C index 969cc97aa8a..f0d3433cdd9 100644 --- a/gcc/testsuite/g++.dg/ext/altivec-cell-2.C +++ b/gcc/testsuite/g++.dg/ext/altivec-cell-2.C @@ -1,9 +1,9 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ /* Test the vec_extract VMX intrinsics. */ #include <altivec.h> -#include "altivec_check.h" extern "C" void abort (void); @@ -137,6 +137,5 @@ int main1(void) int main(void) { - altivec_check(); /* Exits if AltiVec not supported */ return main1 (); } diff --git a/gcc/testsuite/g++.dg/ext/altivec-cell-3.C b/gcc/testsuite/g++.dg/ext/altivec-cell-3.C index f7ebcae054e..bd7e774e3cd 100644 --- a/gcc/testsuite/g++.dg/ext/altivec-cell-3.C +++ b/gcc/testsuite/g++.dg/ext/altivec-cell-3.C @@ -1,9 +1,9 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ /* Test the vec_splats and vec_promote VMX intrinsics. */ #include <altivec.h> -#include "altivec_check.h" extern "C" void abort (void); @@ -33,6 +33,5 @@ int main1(int t) int main(void) { - altivec_check(); /* Exits if AltiVec not supported */ return main1 (0); } diff --git a/gcc/testsuite/g++.dg/ext/altivec-cell-4.C b/gcc/testsuite/g++.dg/ext/altivec-cell-4.C index 10ab162dad2..7d91adbb34e 100644 --- a/gcc/testsuite/g++.dg/ext/altivec-cell-4.C +++ b/gcc/testsuite/g++.dg/ext/altivec-cell-4.C @@ -1,10 +1,10 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ /* Test the vec_splats and vec_promote VMX intrinsics. */ #include <altivec.h> -#include "altivec_check.h" extern "C" void abort (void); @@ -38,6 +38,5 @@ int main1(int t) int main(void) { - altivec_check(); /* Exits if AltiVec not supported */ return main1 (0); } diff --git a/gcc/testsuite/g++.dg/ext/altivec_check.h b/gcc/testsuite/g++.dg/ext/altivec_check.h deleted file mode 100644 index 9e8b3f78ac2..00000000000 --- a/gcc/testsuite/g++.dg/ext/altivec_check.h +++ /dev/null @@ -1,27 +0,0 @@ -/* A runtime check for AltiVec capability. */ -/* Contributed by Ziemowit Laski <zlaski@apple.com> */ - -#include <signal.h> -extern -#ifdef __cplusplus -"C" -#endif -void exit(int); - -void -sig_ill_handler (int sig) -{ - exit (0); -} - -void altivec_check(void) { - - /* Exit on systems without AltiVec. */ - signal (SIGILL, sig_ill_handler); -#ifdef __MACH__ - asm volatile ("vor v0,v0,v0"); -#else - asm volatile ("vor 0,0,0"); -#endif - signal (SIGILL, SIG_DFL); -} diff --git a/gcc/testsuite/g++.dg/ext/spe1.C b/gcc/testsuite/g++.dg/ext/spe1.C index fdd213964b4..8b1e630ecc0 100644 --- a/gcc/testsuite/g++.dg/ext/spe1.C +++ b/gcc/testsuite/g++.dg/ext/spe1.C @@ -1,5 +1,6 @@ -/* { dg-do compile { target powerpc-*-eabi* } } */ +/* { dg-do compile } */ /* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single -O0" } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ typedef int v2si __attribute__ ((vector_size (8))); diff --git a/gcc/testsuite/g++.dg/other/opaque-1.C b/gcc/testsuite/g++.dg/other/opaque-1.C index fa79f6f2a1e..5cdaeafe31a 100644 --- a/gcc/testsuite/g++.dg/other/opaque-1.C +++ b/gcc/testsuite/g++.dg/other/opaque-1.C @@ -1,4 +1,6 @@ -/* { dg-do run { target { powerpc*-*-* && powerpc_spe } } } */ +/* { dg-do run } */ +/* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ #define __vector __attribute__((vector_size(8))) typedef float __vector __ev64_fs__; diff --git a/gcc/testsuite/g++.dg/other/opaque-2.C b/gcc/testsuite/g++.dg/other/opaque-2.C index 6b13ba2810d..3bb4af2c778 100644 --- a/gcc/testsuite/g++.dg/other/opaque-2.C +++ b/gcc/testsuite/g++.dg/other/opaque-2.C @@ -1,5 +1,6 @@ -/* { dg-do compile { target powerpc-*-eabi* powerpc*-*-linux*spe* } } */ +/* { dg-do compile } */ /* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ #define __vector __attribute__((vector_size(8))) typedef float __vector __ev64_fs__; diff --git a/gcc/testsuite/g++.dg/other/opaque-3.C b/gcc/testsuite/g++.dg/other/opaque-3.C index cf8119ffcac..5ece652c0cd 100644 --- a/gcc/testsuite/g++.dg/other/opaque-3.C +++ b/gcc/testsuite/g++.dg/other/opaque-3.C @@ -1,5 +1,6 @@ -/* { dg-do compile { target powerpc-*-eabi* powerpc*-*-linux*spe* } } */ +/* { dg-do compile } */ /* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ __ev64_opaque__ o; #define v __attribute__((vector_size(8))) diff --git a/gcc/testsuite/g++.dg/parse/crash50.C b/gcc/testsuite/g++.dg/parse/crash50.C new file mode 100644 index 00000000000..711048de160 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/crash50.C @@ -0,0 +1,10 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/38636 +// { dg-do compile } + +struct A; // { dg-error "forward declaration of 'struct A'" } + +A::A( + +struct B; // { dg-error "expected '\\)' before ';' token|invalid use of incomplete type 'struct A'" } + diff --git a/gcc/testsuite/g++.dg/parse/pr37862.C b/gcc/testsuite/g++.dg/parse/pr37862.C new file mode 100644 index 00000000000..89b4b699475 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr37862.C @@ -0,0 +1,25 @@ +// { dg-do run } +#include <stdlib.h> + +class A { +public: + virtual void get (void) { } +}; + +class B : public A { +public: + void get (void) { abort (); } +}; + +class C : public B { }; + +int main (void) +{ + C c; + C * p = &c; + + p->A::get (); + (p->A::get) (); // The C++ parser used to resolve this to B::get() + + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/pr38811.C b/gcc/testsuite/g++.dg/torture/pr38811.C new file mode 100644 index 00000000000..e9b304da6e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr38811.C @@ -0,0 +1,73 @@ +/* { dg-do compile } */ + +typedef unsigned long ULONG; +void iwos_ErrorMessage(long error, const char * const file_name, + ULONG line_num, const char * const message); +class AbcA2d { +public: + double x; + double y; + ~AbcA2d() { } +}; +enum AbcZyParamType { ABC_SP_1 }; +class AbcExtent2d { + AbcA2d m_vMin; + AbcA2d m_vMax; +public: + AbcExtent2d(const AbcA2d & rMin, const AbcA2d & rMax); + AbcA2d ClampPoint2d(const AbcA2d & rPoint) const; + AbcA2d GetMax() const { return m_vMax; } + AbcA2d GetMin() const { } + AbcA2d Evaluate(double dNormalizedX, double dNormalizedY) const; +}; +inline AbcExtent2d::AbcExtent2d(const AbcA2d & rMin, const AbcA2d & rMax) +{ + if (rMin.x > rMax.x || rMin.y > rMax.y) + { + long sErr = (1007); + if (sErr != 1000) + iwos_ErrorMessage(sErr,(const char * const)__null, + 0,(const char * const)__null); + } + else + { + m_vMin = rMin; + m_vMax = rMax; + } +} +inline AbcA2d AbcExtent2d::ClampPoint2d(const AbcA2d & rPoint) const +{ + AbcA2d sRet = rPoint; + if (rPoint.x < m_vMin.x) + sRet.x = m_vMin.x; + return sRet; +} +inline AbcA2d AbcExtent2d::Evaluate(double dNormalizedX, double dNormalizedY) +const +{ + AbcA2d sRet; + sRet.x = m_vMin.x + dNormalizedX * (m_vMax.x - m_vMin.x); + sRet.y = m_vMin.y + dNormalizedY * (m_vMax.y - m_vMin.y); + return ClampPoint2d(sRet); +} +class AbcAbcdTracer { + AbcExtent2d m_vUVDomain; + virtual long TestIsoAbcde(AbcZyParamType eZyParam, double dParam, + int & rbZyxIsSolution); + virtual int DoesPointLieOnAbcde(AbcA2d & rUV, int bRefinePoint) const; +}; +long AbcAbcdTracer::TestIsoAbcde(AbcZyParamType eZyParam, double dParam, + int & rbZyxIsSolution) +{ + AbcA2d sUV1(m_vUVDomain.GetMin()); + AbcA2d sUV2(m_vUVDomain.GetMax()); + AbcExtent2d sUVIso(sUV1,sUV2); + for (ULONG i=0; i<10; i++) + { + double dT = i / (10 -1.0); + AbcA2d sUV = sUVIso.Evaluate(dT,dT); + if (!DoesPointLieOnAbcde(sUV,0)) + ; + } +} + diff --git a/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-pta-1.c b/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-pta-1.c new file mode 100644 index 00000000000..a48827474d7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-pta-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall" } */ + +struct S { int *p; int *q; }; + +void foo (struct S *); + +int bar (int b) +{ + struct S s; + int *p; + float f; + foo (&s); + if (b) + p = s.q; + else + p = (int *)&f; + return *p; +} diff --git a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c index 26e65723323..a162dee42a4 100644 --- a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c +++ b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c @@ -48,8 +48,7 @@ const char *dg_options[] = { "/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* powerpc*-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n", "/* { dg-options \"%s-I%s -mno-mmx -fno-common\" { target i?86-*-darwin* x86_64-*-darwin* } } */\n", "/* { dg-options \"%s-I%s -mno-base-addresses\" { target mmix-*-* } } */\n", -"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n", -"/* { dg-options \"%s-I%s -mieee\" { target alpha*-*-* } } */\n" +"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n" #define NDG_OPTIONS (sizeof (dg_options) / sizeof (dg_options[0])) }; diff --git a/gcc/testsuite/gcc.dg/graphite/pr38786.c b/gcc/testsuite/gcc.dg/graphite/pr38786.c new file mode 100644 index 00000000000..47df44789f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/pr38786.c @@ -0,0 +1,20 @@ +/* { dg-options "-O2 -fgraphite-identity" } */ + +typedef struct +{ + int ****cofAC; +} ImageParameters; +typedef struct +{ + int ****cofAC; +} RD_DATA; +extern RD_DATA *rdopt; +extern ImageParameters *img; +dummy_slice_too_big (int bits_slice) +{ + int i, j, k, l; + for (j = 0; j < 4; j++) + for (k = 0; k < 2; k++) + for (l = 0; l < 65; l++) + img->cofAC[i][j][k][l] = rdopt->cofAC[i][j][k][l]; +} diff --git a/gcc/testsuite/gcc.dg/pr38245-3.c b/gcc/testsuite/gcc.dg/pr38245-3.c new file mode 100644 index 00000000000..6ef8372a14f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr38245-3.c @@ -0,0 +1,112 @@ +/* PR rtl-optimization/38245 */ +/* { dg-do run } */ +/* { dg-additional-sources "pr38245-4.c" } */ +/* { dg-options "-O2" } */ + +#include "pr38245-3.h" + +extern void abort (void); + +struct A { int i, j; union { short s[4]; long long l; }; char pad[512]; } a; +int globv = 6; + +void __attribute__((noinline)) +f1 (void) +{ + a.s[2] = b1 (6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21); + a.l = 6; +} + +void __attribute__((noinline)) +f2 (void) +{ + a.s[2] = b2 (6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21); + a.l = 6; +} + +void __attribute__((noinline)) +f3 (void) +{ + struct B b = { 30, 31, { 32, 33 } }; + a.s[2] = b3 (6, 7, 8, 9, 10, 11, 12, b, 14, b, 16, b, 18, 19, 20, 21, + 6, b, 8, b, 10, 11, 12, 13, 14, b, 16, b, 18, 19, 20, 21); + a.l = 6; +} + +void __attribute__((noinline)) +f4 (void) +{ + struct B b = { 30, 31, { 32, 33 } }; + a.s[2] = b4 (6, 7, 8, 9, 10, 11, 12, b, 14, b, 16, b, 18, 19, 20, 21, + 6, b, 8, b, 10, 11, 12, 13, 14, b, 16, b, 18, 19, 20, 21); + a.l = 6; +} + +void __attribute__((noinline)) +f5 (void) +{ + a.s[2] = b5 (6.0, 7, 8, 9, 10, 11, 21.0, 22.0, 23.0); + a.l = 6; +} + +void __attribute__((noinline)) +f6 (void) +{ + a.s[2] = b6 (6.0, 7, 8, 9, 10, 11, 21.0, 22.0, 23.0); + a.l = 6; +} + +void __attribute__((noinline)) +f7 (void) +{ + a.s[2] = b7 (6, 7); + a.l = 6; +} + +void __attribute__((noinline)) +f8 (void) +{ + a.s[2] = b8 (6, 7); + a.l = 6; +} + +void __attribute__((noinline)) +f9 (void) +{ + a.s[2] = b9 (6, 7, 8, 9, 10, 11, 12); + a.l = 6; +} + +void __attribute__((noinline)) +f10 (void) +{ + a.s[2] = b10 (6, 7, 8, 9, 10, 11, 12); + a.l = 6; +} + +int +main (void) +{ + char buf[256]; + int i; + for (i = 0; i < (int) sizeof buf; i++) + buf[i] = i; + asm volatile ("" : : "r" (buf) : "memory"); + f1 (); + f2 (); + f3 (); + f4 (); + f5 (); + f6 (); + f7 (); + f8 (); + f9 (); + f10 (); + asm volatile ("" : : "r" (buf) : "memory"); + for (i = 0; i < (int) sizeof buf; i++) + if (buf[i] != (char) i) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr38245-3.h b/gcc/testsuite/gcc.dg/pr38245-3.h new file mode 100644 index 00000000000..b1c2a0f67c2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr38245-3.h @@ -0,0 +1,35 @@ +/* PR rtl-optimization/38245 */ + +struct B { long a, b; char p[32]; }; +extern int globv; + +extern int b1 (long long, long, long, long, long, long, long, long, + long long, long, long, long, long, long, long, long, + long long, long, long, long, long, long, long, long, + long long, long, long, long, long, long, long, long) + __attribute__((pure, noinline)); +extern int b2 (long long, long, long, long, long, long, long, long, + long long, long, long, long, long, long, long, long, + long long, long, long, long, long, long, long, long, + long long, long, long, long, long, long, long, long) + __attribute__((const, noinline)); +extern int b3 (long long, long, long, long, long, long, long, struct B, + long long, struct B, long, struct B, long, long, long, long, + long long, struct B, long, struct B, long, long, long, long, + long long, struct B, long, struct B, long, long, long, long) + __attribute__((pure, noinline)); +extern int b4 (long long, long, long, long, long, long, long, struct B, + long long, struct B, long, struct B, long, long, long, long, + long long, struct B, long, struct B, long, long, long, long, + long long, struct B, long, struct B, long, long, long, long) + __attribute__((const, noinline)); +extern int b5 () __attribute__((pure, noinline)); +extern int b6 () __attribute__((const, noinline)); +extern int b7 (int, int) + __attribute__((pure, noinline)); +extern int b8 (int, int) + __attribute__((const, noinline)); +extern int b9 (int, int, int, int, int, int, int) + __attribute__((pure, noinline)); +extern int b10 (int, int, int, int, int, int, int) + __attribute__((const, noinline)); diff --git a/gcc/testsuite/gcc.dg/pr38245-4.c b/gcc/testsuite/gcc.dg/pr38245-4.c new file mode 100644 index 00000000000..c9b3d2d8fb8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr38245-4.c @@ -0,0 +1,107 @@ +/* PR rtl-optimization/38245 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +#include "pr38245-3.h" + +int +b1 (long long a1, long a2, long a3, long a4, + long a5, long a6, long a7, long a8, + long long a9, long a10, long a11, long a12, + long a13, long a14, long a15, long a16, + long long a17, long a18, long a19, long a20, + long a21, long a22, long a23, long a24, + long long a25, long a26, long a27, long a28, + long a29, long a30, long a31, long a32) +{ + return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20 + + a21 + a22 + a23 + a24 + a25 + a26 + a27 + a28 + a29 + a30 + + a31 + a32 + globv; +} + +int +b2 (long long a1, long a2, long a3, long a4, + long a5, long a6, long a7, long a8, + long long a9, long a10, long a11, long a12, + long a13, long a14, long a15, long a16, + long long a17, long a18, long a19, long a20, + long a21, long a22, long a23, long a24, + long long a25, long a26, long a27, long a28, + long a29, long a30, long a31, long a32) +{ + return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20 + + a21 + a22 + a23 + a24 + a25 + a26 + a27 + a28 + a29 + a30 + + a31 + a32; +} + +int +b3 (long long a1, long a2, long a3, long a4, + long a5, long a6, long a7, struct B a8, + long long a9, struct B a10, long a11, struct B a12, + long a13, long a14, long a15, long a16, + long long a17, struct B a18, long a19, struct B a20, + long a21, long a22, long a23, long a24, + long long a25, struct B a26, long a27, struct B a28, + long a29, long a30, long a31, long a32) +{ + return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8.a + a9 + a10.a + + a11 + a12.a + a13 + a14 + a15 + a16 + a17 + a18.a + a19 + a20.a + + a21 + a22 + a23 + a24 + a25 + a26.a + a27 + a28.a + a29 + a30 + + a31 + a32 + globv; +} + +int +b4 (long long a1, long a2, long a3, long a4, + long a5, long a6, long a7, struct B a8, + long long a9, struct B a10, long a11, struct B a12, + long a13, long a14, long a15, long a16, + long long a17, struct B a18, long a19, struct B a20, + long a21, long a22, long a23, long a24, + long long a25, struct B a26, long a27, struct B a28, + long a29, long a30, long a31, long a32) +{ + return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8.a + a9 + a10.a + + a11 + a12.a + a13 + a14 + a15 + a16 + a17 + a18.a + a19 + a20.a + + a21 + a22 + a23 + a24 + a25 + a26.a + a27 + a28.a + a29 + a30 + + a31 + a32; +} + +int +b5 (double a1, int a2, int a3, int a4, int a5, int a6, double a7, + double a8, double a9) +{ + return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + globv; +} + +int +b6 (double a1, int a2, int a3, int a4, int a5, int a6, double a7, + double a8, double a9) +{ + return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9; +} + +int +b7 (int a1, int a2) +{ + return a1 + a2 + globv; +} + +int +b8 (int a1, int a2) +{ + return a1 + a2; +} + +int +b9 (int a1, int a2, int a3, int a4, int a5, int a6, int a7) +{ + return a1 + a2 + a3 + a4 + a5 + a6 + a7 + globv; +} + +int +b10 (int a1, int a2, int a3, int a4, int a5, int a6, int a7) +{ + return a1 + a2 + a3 + a4 + a5 + a6 + a7; +} diff --git a/gcc/testsuite/gcc.dg/pr38364.c b/gcc/testsuite/gcc.dg/pr38364.c new file mode 100644 index 00000000000..23f72de74ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr38364.c @@ -0,0 +1,79 @@ +/* PR middle-end/38364 */ +/* { dg-do run } */ +/* { dg-options "-O2 -ftrapv" } */ + +extern void abort (void); + +static inline short +f1 (short x, short y) +{ + if (x > 0) + { + if (y > 0) + { + if (x > __SHRT_MAX__ / y) + return x; + } + else if (y < (-__SHRT_MAX__ - 1) / x) + return x; + } + else + { + if (y > 0) + { + if (x < (-__SHRT_MAX__ - 1) / y) + return x; + } + else if (x != 0 && y < __SHRT_MAX__ / x) + return x; + } + return x * y; +} + +static inline signed char +f2 (signed char x, signed char y) +{ + if (((x ^ y) & (((x ^ ((x ^ y) & (1 << (__CHAR_BIT__ - 1)))) - y) ^ y)) < 0) + return x; + return x - y; +} + +unsigned int v; + +int +f3 (int x, unsigned int y) +{ + f1 (1, 1); + return 1; +} + +int +f4 (unsigned short x) +{ + v = x; + return 1; +} + +int +f5 (int x) +{ + if (f2 (x, 1)) + f1 (1, f4 (1)); + return x; +} + +int +f6 (unsigned int x) +{ + f4 (x < (1 != f5 (0))); + return x; +} + +int +main (void) +{ + f6 (1); + if (v != 0) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr38774.c b/gcc/testsuite/gcc.dg/torture/pr38774.c new file mode 100644 index 00000000000..d6d7fcb0ff5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr38774.c @@ -0,0 +1,16 @@ +/* PR rtl-optimization/38774 */ +/* { dg-do compile } */ +/* { dg-options "" } */ +/* { dg-options "-march=i686" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +extern int bar (void); +volatile int g; + +int +foo (void) +{ + int a = 1 >= bar (); + if ((1 > 9223372036854775807LL - a && 1 - a ? : 1 + a) & 1) + return g; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-105.c b/gcc/testsuite/gcc.dg/vect/vect-105.c index eb21b160cff..bbf42af897f 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-105.c +++ b/gcc/testsuite/gcc.dg/vect/vect-105.c @@ -16,6 +16,8 @@ static int a[N][N] = {{1,2,3,11},{4,5,6,12},{7,8,9,13},{34,45,67,83}}; static int b[N][N] = {{17,28,15,23},{0,2,3,24},{4,31,82,25},{29,31,432,256}}; static int c[N][N] = {{1,2,3,11},{4,9,13,34},{45,67,83,13},{34,45,67,83}}; +volatile int y; + __attribute__ ((noinline)) int main1 (int x) { int i,j; @@ -28,7 +30,9 @@ int main1 (int x) { { p->a[i][j] = a[i][j]; p->b[i][j] = b[i][j]; - if (x == 135) + /* Because Y is volatile, the compiler cannot move this check out + of the loop. */ + if (y) abort (); /* to avoid vectorization */ } } diff --git a/gcc/testsuite/gcc.target/arm/eabi1.c b/gcc/testsuite/gcc.target/arm/eabi1.c index 06af6710299..e88ba021fdc 100644 --- a/gcc/testsuite/gcc.target/arm/eabi1.c +++ b/gcc/testsuite/gcc.target/arm/eabi1.c @@ -75,10 +75,10 @@ extern int __aeabi_lcmp (long long, long long); extern int __aeabi_ulcmp (unsigned long long, unsigned long long); extern int __aeabi_idiv (int, int); extern unsigned int __aeabi_uidiv (unsigned int, unsigned int); -extern int __eabi_uread4 (void *); -extern int __eabi_uwrite4 (int, void *); -extern long long __eabi_uread8 (void *); -extern long long __eabi_uwrite8 (long long, void *); +extern int __aeabi_uread4 (void *); +extern int __aeabi_uwrite4 (int, void *); +extern long long __aeabi_uread8 (void *); +extern long long __aeabi_uwrite8 (long long, void *); #define eq(a, b, type, abs, epsilon, format) \ { \ diff --git a/gcc/testsuite/gcc.target/arm/long-calls-1.c b/gcc/testsuite/gcc.target/arm/long-calls-1.c index 7c2e7fe1c71..587f6d6f25b 100644 --- a/gcc/testsuite/gcc.target/arm/long-calls-1.c +++ b/gcc/testsuite/gcc.target/arm/long-calls-1.c @@ -38,8 +38,14 @@ DO_TESTS_CALL_ATTR (weak_, EXTERN_CALL, weak) DO_TESTS_CALL_ATTR (static_, STATIC_CALL,) -/* Calls to remote_* should honor the call type sttribute, - with "short" being the default. */ +/* Calls to remote_* should honor the call type attribute, + with "short" being the default. + + In the regular expressions below: + + * We allow both "b" and "bl" in some cases to allow for the + possibility of sibling calls. As of this writing, GCC does not + use sibling calls in Thumb-2 mode. */ /* { dg-final { scan-assembler "\tbl\tremote_n1\n" } } */ /* { dg-final { scan-assembler "\tbl\tremote_n2\n" } } */ @@ -59,46 +65,46 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,) should be short. */ /* { dg-final { scan-assembler "\tbl\tstrong_n1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_n1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_n1\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_n2\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_n2\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_n2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_n3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_n3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_n3\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_l1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_l1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_l1\n" } } */ /* { dg-final { scan-assembler-not "\tbl?\tstrong_l2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_l3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_l3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_l3\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_s1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s1\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_s2\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s2\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_s3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s3\n" } } */ -/* Calls to weak_* should honor the call type sttribute, +/* Calls to weak_* should honor the call type attribute, with "short" being the default. */ /* { dg-final { scan-assembler "\tbl\tweak_n1\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_n1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_n1\n" } } */ /* { dg-final { scan-assembler "\tbl\tweak_n2\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_n2\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_n2\n" } } */ /* { dg-final { scan-assembler "\tbl\tweak_n3\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_n3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_n3\n" } } */ /* { dg-final { scan-assembler-not "\tbl?\tweak_l1\n" } } */ /* { dg-final { scan-assembler-not "\tbl?\tweak_l2\n" } } */ /* { dg-final { scan-assembler-not "\tbl?\tweak_l3\n" } } */ /* { dg-final { scan-assembler "\tbl\tweak_s1\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s1\n" } } */ /* { dg-final { scan-assembler "\tbl\tweak_s2\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s2\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s2\n" } } */ /* { dg-final { scan-assembler "\tbl\tweak_s3\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s3\n" } } */ /* Calls to static_*2 calls should honor the call type attribute, @@ -106,21 +112,21 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,) should be short. */ /* { dg-final { scan-assembler "\tbl\tstatic_n1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_n1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_n1\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_n2\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_n2\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_n2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_n3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_n3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_n3\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_l1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_l1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_l1\n" } } */ /* { dg-final { scan-assembler-not "\tbl?\tstatic_l2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_l3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_l3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_l3\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_s1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s1\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_s2\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s2\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_s3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s3\n" } } */ diff --git a/gcc/testsuite/gcc.target/arm/long-calls-2.c b/gcc/testsuite/gcc.target/arm/long-calls-2.c index c63f8abec3b..8ce2404c1f7 100644 --- a/gcc/testsuite/gcc.target/arm/long-calls-2.c +++ b/gcc/testsuite/gcc.target/arm/long-calls-2.c @@ -38,8 +38,14 @@ DO_TESTS_CALL_ATTR (weak_, EXTERN_CALL, weak) DO_TESTS_CALL_ATTR (static_, STATIC_CALL,) -/* Calls to remote_* should honor the call type sttribute, - with "long" being the default. */ +/* Calls to remote_* should honor the call type attribute, + with "long" being the default. + + In the regular expressions below: + + * We allow both "b" and "bl" in some cases to allow for the + possibility of sibling calls. As of this writing, GCC does not + use sibling calls in Thumb-2 mode. */ /* { dg-final { scan-assembler-not "\tbl\tremote_n1\n" } } */ /* { dg-final { scan-assembler-not "\tbl\tremote_n2\n" } } */ @@ -59,26 +65,26 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,) should be short. */ /* { dg-final { scan-assembler "\tbl\tstrong_n1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_n1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_n1\n" } } */ /* { dg-final { scan-assembler-not "\tbl\tstrong_n2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_n3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_n3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_n3\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_l1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_l1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_l1\n" } } */ /* { dg-final { scan-assembler-not "\tbl?\tstrong_l2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_l3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_l3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_l3\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_s1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s1\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_s2\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s2\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstrong_s3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s3\n" } } */ -/* Calls to weak_* should honor the call type sttribute, +/* Calls to weak_* should honor the call type attribute, with "long" being the default. */ /* { dg-final { scan-assembler-not "\tbl?\tweak_n1\n" } } */ @@ -90,11 +96,11 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,) /* { dg-final { scan-assembler-not "\tbl?\tweak_l3\n" } } */ /* { dg-final { scan-assembler "\tbl\tweak_s1\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s1\n" } } */ /* { dg-final { scan-assembler "\tbl\tweak_s2\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s2\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s2\n" } } */ /* { dg-final { scan-assembler "\tbl\tweak_s3\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s3\n" } } */ /* Calls to static_*2 calls should honor the call type attribute, @@ -102,20 +108,20 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,) should be short. */ /* { dg-final { scan-assembler "\tbl\tstatic_n1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_n1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_n1\n" } } */ /* { dg-final { scan-assembler-not "\tbl?\tstatic_n2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_n3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_n3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_n3\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_l1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_l1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_l1\n" } } */ /* { dg-final { scan-assembler-not "\tbl?\tstatic_l2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_l3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_l3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_l3\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_s1\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s1\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s1\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_s2\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s2\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s2\n" } } */ /* { dg-final { scan-assembler "\tbl\tstatic_s3\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s3\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s3\n" } } */ diff --git a/gcc/testsuite/gcc.target/arm/long-calls-3.c b/gcc/testsuite/gcc.target/arm/long-calls-3.c index 92817156370..bd1891c008b 100644 --- a/gcc/testsuite/gcc.target/arm/long-calls-3.c +++ b/gcc/testsuite/gcc.target/arm/long-calls-3.c @@ -39,79 +39,88 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,) /* Calls to remote_*, strong_* and weak_* should honor the call type - sttribute, with "short" being the default. */ + attribute, with "short" being the default. -/* { dg-final { scan-assembler "\tbl\tremote_n1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tremote_n2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tremote_n3\\(PLT\\)\n" } } */ + In the regular expressions below: + + * The PLT marker is optional, even though we are using -fpic, + because it is not used (or required) on some targets. -/* { dg-final { scan-assembler-not "\tbl\tremote_l1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl\tremote_l2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl\tremote_l3\\(PLT\\)\n" } } */ + * We allow both "b" and "bl" in some cases to allow for the + possibility of sibling calls. As of this writing, GCC does not + use sibling calls in Thumb-2 mode. */ -/* { dg-final { scan-assembler "\tbl\tremote_s1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tremote_s2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tremote_s3\\(PLT\\)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tremote_n1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tremote_n2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tremote_n3(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl\tremote_l1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl\tremote_l2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl\tremote_l3(\\(PLT\\))?\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstrong_n1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_n1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstrong_n2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_n2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstrong_n3\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_n3\\(PLT\\)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tremote_s1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tremote_s2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tremote_s3(\\(PLT\\))?\n" } } */ -/* { dg-final { scan-assembler-not "\tbl\tstrong_l1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tstrong_l2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl\tstrong_l3\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstrong_s1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstrong_s2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstrong_s3\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s3\\(PLT\\)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstrong_n1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_n1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstrong_n2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_n2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstrong_n3(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_n3(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl\tstrong_l1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tstrong_l2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl\tstrong_l3(\\(PLT\\))?\n" } } */ -/* { dg-final { scan-assembler "\tbl\tweak_n1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_n1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tweak_n2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_n2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tweak_n3\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_n3\\(PLT\\)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstrong_s1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstrong_s2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstrong_s3(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s3(\\(PLT\\))?\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tweak_l1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tweak_l2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tweak_l3\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tweak_s1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tweak_s2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tweak_s3\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s3\\(PLT\\)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tweak_n1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_n1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tweak_n2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_n2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tweak_n3(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_n3(\\(PLT\\))?\n" } } */ + +/* { dg-final { scan-assembler-not "\tbl?\tweak_l1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tweak_l2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tweak_l3(\\(PLT\\))?\n" } } */ + +/* { dg-final { scan-assembler "\tbl\tweak_s1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tweak_s2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tweak_s3(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s3(\\(PLT\\))?\n" } } */ /* Calls to static_*2 calls should honor the call type attribute, with "short" being the default. Calls to other static_* functions should be short. */ -/* { dg-final { scan-assembler "\tbl\tstatic_n1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_n1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstatic_n2(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_n2(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstatic_n3(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_n3(\\(PLT\\))\n" } } */ - -/* { dg-final { scan-assembler "\tbl\tstatic_l1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_l1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tstatic_l2(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstatic_l3(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_l3(\\(PLT\\))\n" } } */ - -/* { dg-final { scan-assembler "\tbl\tstatic_s1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstatic_s2(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s2(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstatic_s3(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s3(\\(PLT\\))\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstatic_n1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_n1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstatic_n2((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_n2((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstatic_n3((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_n3((\\(PLT\\))?)\n" } } */ + +/* { dg-final { scan-assembler "\tbl\tstatic_l1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_l1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tstatic_l2((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstatic_l3((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_l3((\\(PLT\\))?)\n" } } */ + +/* { dg-final { scan-assembler "\tbl\tstatic_s1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstatic_s2((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s2((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstatic_s3((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s3((\\(PLT\\))?)\n" } } */ diff --git a/gcc/testsuite/gcc.target/arm/long-calls-4.c b/gcc/testsuite/gcc.target/arm/long-calls-4.c index facf85c73b6..dc184b8f8be 100644 --- a/gcc/testsuite/gcc.target/arm/long-calls-4.c +++ b/gcc/testsuite/gcc.target/arm/long-calls-4.c @@ -39,72 +39,81 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,) /* Calls to remote_*, strong_* and weak_* should honor the call type - sttribute, with "long" being the default. */ + attribute, with "long" being the default. -/* { dg-final { scan-assembler-not "\tbl\tremote_n1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl\tremote_n2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl\tremote_n3\\(PLT\\)\n" } } */ + In the regular expressions below: + + * The PLT marker is optional, even though we are using -fpic, + because it is not used (or required) on some targets. -/* { dg-final { scan-assembler-not "\tbl\tremote_l1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl\tremote_l2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl\tremote_l3\\(PLT\\)\n" } } */ + * We allow both "b" and "bl" in some cases to allow for the + possibility of sibling calls. As of this writing, GCC does not + use sibling calls in Thumb-2 mode. */ -/* { dg-final { scan-assembler "\tbl\tremote_s1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tremote_s2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tremote_s3\\(PLT\\)\n" } } */ +/* { dg-final { scan-assembler-not "\tbl\tremote_n1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl\tremote_n2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl\tremote_n3(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl\tremote_l1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl\tremote_l2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl\tremote_l3(\\(PLT\\))?\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tstrong_n1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tstrong_n2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tstrong_n3\\(PLT\\)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tremote_s1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tremote_s2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tremote_s3(\\(PLT\\))?\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tstrong_l1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tstrong_l2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tstrong_l3\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstrong_s1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstrong_s2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstrong_s3\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tstrong_s3\\(PLT\\)\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tstrong_n1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tstrong_n2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tstrong_n3(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tstrong_l1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tstrong_l2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tstrong_l3(\\(PLT\\))?\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tweak_n1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tweak_n2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tweak_n3\\(PLT\\)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstrong_s1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstrong_s2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstrong_s3(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstrong_s3(\\(PLT\\))?\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tweak_l1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tweak_l2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tweak_l3\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tweak_s1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s1\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tweak_s2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s2\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tbl\tweak_s3\\(PLT\\)\n" } } */ -/* { dg-final { scan-assembler "\tb\tweak_s3\\(PLT\\)\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tweak_n1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tweak_n2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tweak_n3(\\(PLT\\))?\n" } } */ + +/* { dg-final { scan-assembler-not "\tbl?\tweak_l1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tweak_l2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tweak_l3(\\(PLT\\))?\n" } } */ + +/* { dg-final { scan-assembler "\tbl\tweak_s1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s1(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tweak_s2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s2(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl\tweak_s3(\\(PLT\\))?\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tweak_s3(\\(PLT\\))?\n" } } */ /* Calls to static_*2 calls should honor the call type attribute, with "long" being the default. Calls to other static_* functions should be short. */ -/* { dg-final { scan-assembler "\tbl\tstatic_n1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_n1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tstatic_n2(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstatic_n3(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_n3(\\(PLT\\))\n" } } */ - -/* { dg-final { scan-assembler "\tbl\tstatic_l1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_l1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler-not "\tbl?\tstatic_l2(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstatic_l3(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_l3(\\(PLT\\))\n" } } */ - -/* { dg-final { scan-assembler "\tbl\tstatic_s1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s1(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstatic_s2(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s2(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tbl\tstatic_s3(\\(PLT\\))\n" } } */ -/* { dg-final { scan-assembler "\tb\tstatic_s3(\\(PLT\\))\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstatic_n1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_n1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tstatic_n2((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstatic_n3((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_n3((\\(PLT\\))?)\n" } } */ + +/* { dg-final { scan-assembler "\tbl\tstatic_l1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_l1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler-not "\tbl?\tstatic_l2((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstatic_l3((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_l3((\\(PLT\\))?)\n" } } */ + +/* { dg-final { scan-assembler "\tbl\tstatic_s1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s1((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstatic_s2((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s2((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl\tstatic_s3((\\(PLT\\))?)\n" } } */ +/* { dg-final { scan-assembler "\tbl?\tstatic_s3((\\(PLT\\))?)\n" } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse-10.c b/gcc/testsuite/gcc.target/i386/sse-10.c index b5bc8f66b44..5cf0714f07b 100644 --- a/gcc/testsuite/gcc.target/i386/sse-10.c +++ b/gcc/testsuite/gcc.target/i386/sse-10.c @@ -1,6 +1,6 @@ /* PR 17930 */ /* { dg-do run } */ -/* { dg-options "-O1 -msse2 -mfpmath=sse -mno-accumulate-outgoing-args -fno-omit-frame-pointer" } */ +/* { dg-options "-O1 -msse2 -mfpmath=sse -mno-accumulate-outgoing-args -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer" } */ /* { dg-options "-O1 -msse2 -mfpmath=sse -fno-omit-frame-pointer" { target *-*-mingw* *-*-cygwin* } } */ #include "sse2-check.h" diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index e1496d9d6a7..c5d6089a964 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -269,15 +269,14 @@ set mips_abi_groups { # on a target that supports OPTION. set mips_option_tests(-mips16) { move $2,$31 - jal 1f - b 2f - .align 2 + bal 1f .set mips16 -1: jr $31 .set nomips16 .align 2 -2: +1: + ori $3,$31,1 + jalr $3 move $31,$2 } set mips_option_tests(-mpaired-single) { diff --git a/gcc/testsuite/gcc.target/powerpc/20030218-1.c b/gcc/testsuite/gcc.target/powerpc/20030218-1.c index 024f637f8ec..2a1c4e6d253 100644 --- a/gcc/testsuite/gcc.target/powerpc/20030218-1.c +++ b/gcc/testsuite/gcc.target/powerpc/20030218-1.c @@ -1,5 +1,6 @@ -/* { dg-do compile { target powerpc-*-eabi* } } */ -/* { dg-options "-mspe=yes -mfloat-gprs=single" } */ +/* { dg-do compile } */ +/* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ /* Test vectors that can interconvert without a cast. */ @@ -19,7 +20,7 @@ main (void) /* Just because this is a V2SI, it doesn't make it an opaque. */ vint = vshort; /* { dg-message "note: use -flax-vector-conversions to permit conversions between vectors with differing element types or numbers of subparts" } */ - /* { dg-error "incompatible types when assigning" "" { target *-*-* } 21 } */ + /* { dg-error "incompatible types when assigning" "" { target *-*-* } 22 } */ return 0; } diff --git a/gcc/testsuite/gcc.target/powerpc/20030505.c b/gcc/testsuite/gcc.target/powerpc/20030505.c index a8283934d71..2bef590bf7b 100644 --- a/gcc/testsuite/gcc.target/powerpc/20030505.c +++ b/gcc/testsuite/gcc.target/powerpc/20030505.c @@ -1,5 +1,6 @@ -/* { dg-do compile { target powerpc-*-eabi* } } */ +/* { dg-do compile } */ /* { dg-options "-W -mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ #define __vector __attribute__((vector_size(8))) diff --git a/gcc/testsuite/gcc.target/powerpc/20081204-1.c b/gcc/testsuite/gcc.target/powerpc/20081204-1.c index ba4df8f3e29..8a973d0ec52 100644 --- a/gcc/testsuite/gcc.target/powerpc/20081204-1.c +++ b/gcc/testsuite/gcc.target/powerpc/20081204-1.c @@ -2,6 +2,8 @@ TARGET_HARD_FLOAT && !TARGET_FPRS. */ /* { dg-do compile } */ /* { dg-options "-mcpu=750 -mfloat-gprs=single" } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ + static int comp(const void *a,const void *b){ return (*(float *)a<*(float *)b)-(*(float *)a>*(float *)b); } diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-1.c b/gcc/testsuite/gcc.target/powerpc/altivec-1.c index f235e7b57ac..b1809fe2c9c 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-1.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-1.c @@ -1,11 +1,11 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ /* Program to test PowerPC AltiVec instructions. */ #include <altivec.h> -#include "altivec_check.h" extern void abort (void); @@ -24,8 +24,6 @@ vector float f, g, h; int main () { - altivec_check(); /* Exits if AltiVec not supported */ - k = vec_add (a1, a2); if (!vec_all_eq (addi, k)) abort (); diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-10.c b/gcc/testsuite/gcc.target/powerpc/altivec-10.c index 82b3f45a391..f532eebbfab 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-10.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-10.c @@ -1,11 +1,12 @@ -/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec -mabi=altivec -fno-inline" } */ #include <altivec.h> -#include <signal.h> -#include "altivec_check.h" +extern void exit (int); +extern void abort (void); typedef union { @@ -72,8 +73,6 @@ check_cmple() int main() { - altivec_check (); - check_cmple (); check_vec_all_num (); exit (0); diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-12.c b/gcc/testsuite/gcc.target/powerpc/altivec-12.c index 296a3f7510a..39d26940d4e 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-12.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-12.c @@ -1,11 +1,11 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ /* Program to test PowerPC AltiVec instructions. */ #include <altivec.h> -#include "altivec_check.h" extern void abort (void); #define CHECK_IF(E) if(!(E)) abort() @@ -26,9 +26,6 @@ vector float f, g, h; int main () { - - altivec_check(); /* Exit if AltiVec not available. */ - k = vec_add (a1, a2); CHECK_IF (vec_all_eq (addi, k)); CHECK_IF (vec_all_ge (addi, k)); diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-24.c b/gcc/testsuite/gcc.target/powerpc/altivec-24.c index cb1a66832e7..d296fe24658 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-24.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-24.c @@ -1,9 +1,9 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ #include <altivec.h> -#include "altivec_check.h" extern void abort (void); @@ -28,7 +28,6 @@ int verify (void) int main (void) { - altivec_check (); /* Exit if hardware doesn't support AltiVec. */ initialize (MAGIC_NUMBER); verify (); return 0; diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-3.c b/gcc/testsuite/gcc.target/powerpc/altivec-3.c index 17f62fd8f03..d388ad299a4 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-3.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-3.c @@ -1,8 +1,10 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ -#include "altivec_check.h" +extern void exit (int); +extern void abort (void); typedef int int4 __attribute__ ((vector_size (16))); typedef float float4 __attribute__ ((vector_size (16))); @@ -73,7 +75,6 @@ main1 () int main () { - altivec_check (); main1 (); exit (0); } diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-cell-2.c b/gcc/testsuite/gcc.target/powerpc/altivec-cell-2.c index b9c7c90b303..fdb375c9efe 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-cell-2.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-cell-2.c @@ -1,9 +1,9 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ /* Test the vec_extract VMX intrinsics. */ #include <altivec.h> -#include "altivec_check.h" extern void abort (void); @@ -137,6 +137,5 @@ int main1(void) int main(void) { - altivec_check(); /* Exits if AltiVec not supported */ return main1 (); } diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-cell-3.c b/gcc/testsuite/gcc.target/powerpc/altivec-cell-3.c index abaf56f2770..b941ab186fa 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-cell-3.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-cell-3.c @@ -1,9 +1,9 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ /* Test the vec_splats and vec_promote VMX intrinsics. */ #include <altivec.h> -#include "altivec_check.h" extern void abort (void); @@ -33,6 +33,5 @@ int main1(int t) int main(void) { - altivec_check(); /* Exits if AltiVec not supported */ return main1 (0); } diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-cell-4.c b/gcc/testsuite/gcc.target/powerpc/altivec-cell-4.c index b800ea51105..c694691d475 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-cell-4.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-cell-4.c @@ -1,10 +1,10 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ /* Test the vec_splats and vec_promote VMX intrinsics. */ #include <altivec.h> -#include "altivec_check.h" extern void abort (void); @@ -38,6 +38,5 @@ int main1(int t) int main(void) { - altivec_check(); /* Exits if AltiVec not supported */ return main1 (0); } diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-cell-8.c b/gcc/testsuite/gcc.target/powerpc/altivec-cell-8.c index 12e13e00aa8..dda5eb0c114 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-cell-8.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-cell-8.c @@ -1,9 +1,11 @@ -/* { dg-do run } */ +/* { dg-do run { target { powerpc*-*-* && cell_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! cell_hw } } } } */ /* { dg-require-effective-target powerpc_ppu_ok } */ /* { dg-options "-O2 -maltivec -mabi=altivec -mcpu=cell" } */ #include <altivec.h> #include <string.h> -#include "altivec_check.h" + +extern void abort (void); typedef short int sint16; typedef signed char int8; @@ -51,6 +53,5 @@ return 0; int main(void) { - altivec_cell_check (); return main1(); } diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-consts.c b/gcc/testsuite/gcc.target/powerpc/altivec-consts.c index e06a5286b17..2c5bc99cff8 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-consts.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-consts.c @@ -1,11 +1,10 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec -mabi=altivec -O2" } */ /* Check that "easy" AltiVec constants are correctly synthesized. */ -#include "altivec_check.h" - extern void abort (void); typedef __attribute__ ((vector_size (16))) unsigned char v16qi; @@ -283,8 +282,6 @@ void v4si_vspltisw_neg_addself () int main () { - altivec_check (); /* Exit if hardware doesn't support AltiVec. */ - v16qi_vspltisb (); v16qi_vspltisb_neg (); v16qi_vspltisb_addself (); diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-macros.c b/gcc/testsuite/gcc.target/powerpc/altivec-macros.c index 8ea8df241db..c07eaa36a49 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-macros.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-macros.c @@ -1,6 +1,7 @@ /* Copyright (C) 2007 Free Software Foundation, Inc. */ /* { dg-do preprocess } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ /* Conditional macros should not be expanded by pragmas. */ @@ -48,16 +49,16 @@ _Pragma ("__vector") #define pixel newer_pixel #define bool newer_bool -/* { dg-warning "redefined" "__vector redefined" { target *-*-* } 44 } */ -/* { dg-warning "redefined" "__pixel redefined" { target *-*-* } 45 } */ -/* { dg-warning "redefined" "__bool redefined" { target *-*-* } 46 } */ -/* { dg-warning "redefined" "vector redefined" { target *-*-* } 47 } */ -/* { dg-warning "redefined" "pixel redefined" { target *-*-* } 48 } */ -/* { dg-warning "redefined" "bool redefined" { target *-*-* } 49 } */ - -/* { dg-message "location of the previous" "prev __vector defn" { target *-*-* } 24 } */ -/* { dg-message "location of the previous" "prev __pixel defn" { target *-*-* } 27 } */ -/* { dg-message "location of the previous" "prev __bool defn" { target *-*-* } 30 } */ -/* { dg-message "location of the previous" "prev vector defn" { target *-*-* } 33 } */ -/* { dg-message "location of the previous" "prev pixel defn" { target *-*-* } 36 } */ -/* { dg-message "location of the previous" "prev bool defn" { target *-*-* } 39 } */ +/* { dg-warning "redefined" "__vector redefined" { target *-*-* } 45 } */ +/* { dg-warning "redefined" "__pixel redefined" { target *-*-* } 46 } */ +/* { dg-warning "redefined" "__bool redefined" { target *-*-* } 47 } */ +/* { dg-warning "redefined" "vector redefined" { target *-*-* } 48 } */ +/* { dg-warning "redefined" "pixel redefined" { target *-*-* } 49 } */ +/* { dg-warning "redefined" "bool redefined" { target *-*-* } 50 } */ + +/* { dg-message "location of the previous" "prev __vector defn" { target *-*-* } 25 } */ +/* { dg-message "location of the previous" "prev __pixel defn" { target *-*-* } 28 } */ +/* { dg-message "location of the previous" "prev __bool defn" { target *-*-* } 31 } */ +/* { dg-message "location of the previous" "prev vector defn" { target *-*-* } 34 } */ +/* { dg-message "location of the previous" "prev pixel defn" { target *-*-* } 37 } */ +/* { dg-message "location of the previous" "prev bool defn" { target *-*-* } 40 } */ diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-varargs-1.c b/gcc/testsuite/gcc.target/powerpc/altivec-varargs-1.c index 2aa54a912a5..1349ae590d9 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-varargs-1.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-varargs-1.c @@ -1,11 +1,12 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec -mabi=altivec -fno-inline" } */ #include <stdarg.h> -#include <signal.h> -#include "altivec_check.h" +extern void exit (int); +extern void abort (void); #define vector __attribute__((vector_size (16))) @@ -77,8 +78,5 @@ int main1(void) int main (void) { - /* Exit on systems without AltiVec. */ - altivec_check (); - return main1 (); } diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-vec-merge.c b/gcc/testsuite/gcc.target/powerpc/altivec-vec-merge.c index e6027bdeff8..3689f97490c 100644 --- a/gcc/testsuite/gcc.target/powerpc/altivec-vec-merge.c +++ b/gcc/testsuite/gcc.target/powerpc/altivec-vec-merge.c @@ -1,9 +1,9 @@ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec -O2" } */ #include <altivec.h> -#include "altivec_check.h" int printf(const char * , ...); extern void abort(); @@ -600,7 +600,6 @@ int main(int argc, char **argv) { char toto[32] __attribute__((aligned(16))); - altivec_check (); /* Exit if hardware doesn't support AltiVec. */ foo(toto, toto, 0, 0); return 0; } diff --git a/gcc/testsuite/gcc.target/powerpc/altivec_check.h b/gcc/testsuite/gcc.target/powerpc/altivec_check.h deleted file mode 100644 index d966e238a10..00000000000 --- a/gcc/testsuite/gcc.target/powerpc/altivec_check.h +++ /dev/null @@ -1,43 +0,0 @@ -/* A runtime check for AltiVec capability. */ -/* Contributed by Ziemowit Laski <zlaski@apple.com> */ - -#include <signal.h> -extern void exit (int); -extern void abort (void); - -void -sig_ill_handler (int sig) -{ - exit (0); -} - -void altivec_check(void) { - - /* Exit on systems without AltiVec. */ - signal (SIGILL, sig_ill_handler); -#ifdef __MACH__ - asm volatile ("vor v0,v0,v0"); -#else - asm volatile ("vor 0,0,0"); -#endif - signal (SIGILL, SIG_DFL); -} - -void altivec_cell_check (void) -{ -#ifdef __PPU__ - /* Exit on systems without the Cell Altivec instructions. */ - signal (SIGILL, sig_ill_handler); -#ifdef __MACH__ - asm volatile ("vor v0,v0,v0"); - asm volatile ("lvlx v0,r0,r0"); -#else - asm volatile ("vor 0,0,0"); - asm volatile ("lvlx 0,0,0"); -#endif - signal (SIGILL, SIG_DFL); -#else - /* altivec_cell_check shouldn't be called without -mcpu=cell. */ - abort (); -#endif -} diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-spe.c b/gcc/testsuite/gcc.target/powerpc/ppc-spe.c index 841073b22b7..b5643943340 100644 --- a/gcc/testsuite/gcc.target/powerpc/ppc-spe.c +++ b/gcc/testsuite/gcc.target/powerpc/ppc-spe.c @@ -1,5 +1,6 @@ -/* { dg-do compile { target powerpc-*-eabi* } } */ +/* { dg-do compile } */ /* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single -O0" } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ /* (Test with -O0 so we don't optimize any of them away). */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr35907.c b/gcc/testsuite/gcc.target/powerpc/pr35907.c index e1749dea8c9..7d5465ea151 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr35907.c +++ b/gcc/testsuite/gcc.target/powerpc/pr35907.c @@ -1,10 +1,9 @@ /* PR target/35907 */ -/* { dg-do run { target powerpc*-*-* } } */ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ /* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-O2 -maltivec" } */ -#include "altivec_check.h" - #define vector __attribute__((vector_size (16))) union { @@ -53,7 +52,6 @@ test (void) int main () { - altivec_check (); test (); return 0; } diff --git a/gcc/testsuite/gcc.target/powerpc/spe-vector-memcpy.c b/gcc/testsuite/gcc.target/powerpc/spe-vector-memcpy.c index d12f6696eb0..09f8134829c 100644 --- a/gcc/testsuite/gcc.target/powerpc/spe-vector-memcpy.c +++ b/gcc/testsuite/gcc.target/powerpc/spe-vector-memcpy.c @@ -1,6 +1,6 @@ -/* { dg-do compile { target powerpc*-*-* } } */ -/* { dg-require-effective-target powerpc_spe } */ -/* { dg-options "-O -mspe=yes" } */ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ /* { dg-final { scan-assembler "evstdd" } } */ void foo(void) diff --git a/gcc/testsuite/gcc.target/powerpc/spe1.c b/gcc/testsuite/gcc.target/powerpc/spe1.c index 9803d8fdb7f..ddbb5a6e1c9 100644 --- a/gcc/testsuite/gcc.target/powerpc/spe1.c +++ b/gcc/testsuite/gcc.target/powerpc/spe1.c @@ -1,5 +1,6 @@ -/* { dg-do compile { target powerpc-*-eabi* } } */ +/* { dg-do compile } */ /* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single -O0" } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ /* (Test with -O0 so we don't optimize any of them away). */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 1aa1855a1ab..aaefa60cbcb 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -905,6 +905,40 @@ proc check_vmx_hw_available { } { }] } +# Return 1 if the target supports executing AltiVec and Cell PPU +# instructions, 0 otherwise. Cache the result. + +proc check_effective_target_cell_hw { } { + return [check_cached_effective_target cell_hw_available { + # Some simulators are known to not support VMX and PPU instructions. + if { [istarget powerpc-*-eabi*] } { + expr 0 + } else { + # Most targets don't require special flags for this test + # case, but Darwin and AIX do. + if { [istarget *-*-darwin*] + || [istarget *-*-aix*] } { + set options "-maltivec -mcpu=cell" + } else { + set options "-mcpu=cell" + } + check_runtime_nocache cell_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("vor v0,v0,v0"); + asm volatile ("lvlx v0,r0,r0"); + #else + asm volatile ("vor 0,0,0"); + asm volatile ("lvlx 0,0,0"); + #endif + return 0; + } + } $options + } + }] +} + # Return 1 if the target supports executing 64-bit instructions, 0 # otherwise. Cache the result. @@ -1501,6 +1535,23 @@ proc check_effective_target_powerpc_spu { } { } } +# Return 1 if this is a PowerPC SPE target. The check includes options +# specified by dg-options for this test, so don't cache the result. + +proc check_effective_target_powerpc_spe_nocache { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages_nocache powerpc_spe object { + #ifndef __SPE__ + #error not SPE + #else + int dummy; + #endif + } [current_compiler_flags]] + } else { + return 0 + } +} + # Return 1 if this is a PowerPC target with SPE enabled. proc check_effective_target_powerpc_spe { } { diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 3d64c1cbd33..8b49556b3c0 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -1129,6 +1129,8 @@ build_pred_graph (void) } else if (rhs.type == ADDRESSOF) { + varinfo_t v; + /* x = &y */ if (graph->points_to[lhsvar] == NULL) graph->points_to[lhsvar] = BITMAP_ALLOC (&predbitmap_obstack); @@ -1141,7 +1143,19 @@ build_pred_graph (void) /* Implicitly, *x = y */ add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar); + /* All related variables are no longer direct nodes. */ RESET_BIT (graph->direct_nodes, rhsvar); + v = get_varinfo (rhsvar); + if (!v->is_full_var) + { + v = lookup_vi_for_tree (v->decl); + do + { + RESET_BIT (graph->direct_nodes, v->id); + v = v->next; + } + while (v != NULL); + } bitmap_set_bit (graph->address_taken, rhsvar); } else if (lhsvar > anything_id @@ -4561,6 +4575,16 @@ intra_create_variable_infos (void) } } + /* Add a constraint for a result decl that is passed by reference. */ + if (DECL_RESULT (cfun->decl) + && DECL_BY_REFERENCE (DECL_RESULT (cfun->decl))) + { + varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (cfun->decl)); + + for (p = result_vi; p; p = p->next) + make_constraint_from (p, nonlocal_id); + } + /* Add a constraint for the incoming static chain parameter. */ if (cfun->static_chain_decl != NULL_TREE) { @@ -4735,7 +4759,7 @@ emit_alias_warning (tree ptr) { gimple use; imm_use_iterator ui; - unsigned warned = 0; + bool warned = false; FOR_EACH_IMM_USE_STMT (use, ui, ptr) { @@ -4773,13 +4797,12 @@ emit_alias_warning (tree ptr) && !TREE_NO_WARNING (deref)) { TREE_NO_WARNING (deref) = 1; - warning_at (gimple_location (use), OPT_Wstrict_aliasing, - "dereferencing pointer %qD does break strict-aliasing " - "rules", SSA_NAME_VAR (ptr)); - ++warned; + warned |= warning_at (gimple_location (use), OPT_Wstrict_aliasing, + "dereferencing pointer %qD does break " + "strict-aliasing rules", SSA_NAME_VAR (ptr)); } } - if (warned > 0) + if (warned) { bitmap visited = BITMAP_ALLOC (NULL); emit_pointer_definition (ptr, visited); |