Submitted By: Jim Gifford (jim at linuxfromscratch dot org) Date: 12-21-2008 Initial Package Version: 4.3.2 Origin: Upstream Upstream Status: Applied Description: This is a branch update for gcc-4.3.2, and should be rechecked periodically. diff -Naur gcc-4.3.2.orig/contrib/ChangeLog gcc-4.3.2/contrib/ChangeLog --- gcc-4.3.2.orig/contrib/ChangeLog 2008-08-27 11:03:13.000000000 -0700 +++ gcc-4.3.2/contrib/ChangeLog 2008-12-04 15:00:19.000000000 -0800 @@ -1,3 +1,11 @@ +2008-12-04 Janis Johnson + + Backport from mainline: + 2008-10-18 Jakub Jelinek + Janis Johnson + + * dg-extract-results.sh: New file. + 2008-08-27 Release Manager * GCC 4.3.2 released. diff -Naur gcc-4.3.2.orig/contrib/dg-extract-results.sh gcc-4.3.2/contrib/dg-extract-results.sh --- gcc-4.3.2.orig/contrib/dg-extract-results.sh 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/contrib/dg-extract-results.sh 2008-12-04 15:00:19.000000000 -0800 @@ -0,0 +1,416 @@ +#! /bin/sh + +# For a specified tool and optional list of test variants, extract +# test results from one or more test summary (.sum) files and combine +# the results into a new test summary file, sent to the standard output. +# The resulting file can be used with test result comparison scripts for +# results from tests that were run in parallel. See usage() below. + +# Copyright (C) 2008 Free Software Foundation +# Contributed by Janis Johnson +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +PROGNAME=dg-extract-results.sh + +usage() { + cat <&2 +Usage: $PROGNAME [-t tool] [-l variant-list] [-L] sum-file ... + + tool The tool (e.g. g++, libffi) for which to create a + new test summary file. If not specified then all + specified sum files must be for the same tool. + variant-list One or more test variant names. If the list is + not specified then one is constructed from all + variants in the files for . + sum-file A test summary file with the format of those + created by runtest from DejaGnu. + If -L is used, merge *.log files instead of *.sum. In this + mode the exact order of lines may not be preserved, just different + Running *.exp chunks should be in correct order. +EOF +} + +# Write a message to the standard error. + +msg() { + echo "$@" >&2 +} + +# Parse the command-line options. + +VARIANTS="" +TOOL="" +MODE="sum" + +while getopts "l:t:L" ARG; do + case $ARG in + l) VARIANTS="${VARIANTS} ${OPTARG}";; + t) test -z "$TOOL" || (msg "${PROGNAME}: only one tool can be specified"; exit 1); + TOOL="${OPTARG}";; + L) MODE="log";; + \?) usage; exit 0;; + esac +done +shift `expr ${OPTIND} - 1` + +if test $# -lt 1 ; then + usage + exit 1 +fi + +TMPDIR=${TMPDIR-/tmp} +SUM_FILES="$@" +FIRST_SUM=$1 +TMP= +trap 'EXIT_STATUS=$?; rm -rf $TMP && exit $EXIT_STATUS' 0 +# Create a (secure) tmp directory for tmp files. +{ + TMP=`(umask 077 && mktemp -d -q "${TMPDIR}/dg-combine-results-$$-XXXXXX") 2>/dev/null` && + test -n "$TMP" && test -d "$TMP" +} || +{ + TMP=${TMPDIR}/dg-combine-results-$$-$RANDOM + (umask 077 && mkdir $TMP) +} || +{ + msg "${PROGNAME}: cannot create a temporary directory" + { (exit 1); exit 1; } +} + +# Find a good awk. + +if test -z "$AWK" ; then + for AWK in gawk nawk awk + do + if type $AWK 2>&1 | grep 'not found' > /dev/null 2>&1 ; then + : + else + break + fi + done +fi + +# Verify that the specified summary files exist. + +ERROR=0 +for FILE in $SUM_FILES +do + if ! test -f $FILE ; then + msg "${PROGNAME}: file $FILE does not exist." + ERROR=1 + fi +done +test $ERROR -eq 0 || exit 1 + +if [ -z "$TOOL" ]; then + # If no tool was specified, all specified summary files must be for + # the same tool. + + CNT=`grep '=== .* tests ===' $SUM_FILES | $AWK '{ print $3 }' | sort -u | wc -l` + if [ $CNT -eq 1 ]; then + TOOL=`grep '=== .* tests ===' $FIRST_SUM | $AWK '{ print $2 }'` + else + msg "${PROGNAME}: sum files are for multiple tools, specify a tool" + msg "" + usage + exit 1 + fi +else + # Ignore the specified summary files that are not for this tool. This + # should keep the relevant files in the same order. + + SUM_FILES=`grep -l "=== $TOOL" $SUM_FILES` + if test -z "$SUM_FILES" ; then + msg "${PROGNAME}: none of the specified files are results for $TOOL" + exit 1 + fi +fi + +if [ "$TOOL" = acats ]; then + # Acats *.sum or *.log files aren't dejagnu generated, and they have + # somewhat different format. + ACATS_AWK=${TMP}/acats.awk + cat < $ACATS_AWK +BEGIN { + print_prologue=1; chapter=""; insummary=0 + passcnt=0; failcnt=0; unsupcnt=0; failures="" +} +/=== acats configuration ===/ { + insummary=0 + if (print_prologue) print + next +} +/=== acats tests ===/ { + if (print_prologue) print + print_prologue=0 + next +} +/^Running chapter / { + chapter=\$3 + print > "${TMP}/chapter-"chapter + next +} +/=== acats Summary ===/ { + chapter="" + insummary=1 + next +} +/^# of expected passes/ { if (insummary == 1) passcnt += \$5; next; } +/^# of unexpected failures/ { if (insummary == 1) failcnt += \$5; next; } +/^# of unsupported tests/ { if (insummary == 1) unsupcnt += \$5; next; } +/^\*\*\* FAILURES: / { + if (insummary == 1) { + if (failures) sub(/^\*\*\* FAILURES:/,"") + failures=failures""\$0 + } +} +{ + if (print_prologue) { print; next } + if (chapter) print > "${TMP}/chapter-"chapter +} +END { + system ("cat ${TMP}/chapter-*") + print " === acats Summary ===" + print "# of expected passes " passcnt + print "# of unexpected failures " failcnt + if (unsupcnt) print "# of unsupported tests " unsupcnt + if (failures) print failures +} +EOF + + $AWK -f $ACATS_AWK $SUM_FILES + exit 0 +fi + +# If no variants were specified, find all variants in the remaining +# summary files. Otherwise, ignore specified variants that aren't in +# any of those summary files. + +if test -z "$VARIANTS" ; then + VAR_AWK=${TMP}/variants.awk + cat < $VAR_AWK +/^Schedule of variations:/ { in_vars=1; next } +/^$/ { in_vars=0 } +/^Running target/ { exit } +{ if (in_vars==1) print \$1; else next } +EOF + + touch ${TMP}/varlist + for FILE in $SUM_FILES; do + $AWK -f $VAR_AWK $FILE >> ${TMP}/varlist + done + VARIANTS="`sort -u ${TMP}/varlist`" +else + VARS="$VARIANTS" + VARIANTS="" + for VAR in $VARS + do + grep -q "Running target $VAR" $SUM_FILES && VARIANTS="$VARIANTS $VAR" + done +fi + +# Find out if we have more than one variant, or any at all. + +VARIANT_COUNT=0 +for VAR in $VARIANTS +do + VARIANT_COUNT=`expr $VARIANT_COUNT + 1` +done + +if test $VARIANT_COUNT -eq 0 ; then + msg "${PROGNAME}: no file for $TOOL has results for the specified variants" + exit 1 +fi + +cat $SUM_FILES \ + | $AWK '/^Running/ { if ($2 != "target" && $3 == "...") print "EXPFILE: "$2 } ' \ + | sort -u > ${TMP}/expfiles + +# Write the begining of the combined summary file. + +head -n 2 $FIRST_SUM +echo +echo " === $TOOL tests ===" +echo +echo "Schedule of variations:" +for VAR in $VARIANTS +do + echo " $VAR" +done +echo + +# For each test variant for the tool, copy test reports from each of the +# summary files. Set up two awk scripts from within the loop to +# initialize VAR and TOOL with the script, rather than assuming that the +# available version of awk can pass variables from the command line. + +for VAR in $VARIANTS +do + GUTS_AWK=${TMP}/guts.awk + cat << EOF > $GUTS_AWK +BEGIN { + variant="$VAR" + firstvar=1 + expfileno=1 + cnt=0 + print_using=0 +} +/^EXPFILE: / { + expfiles[expfileno] = \$2 + expfilesr[\$2] = expfileno + expfileno = expfileno + 1 +} +/^Running target / { + curvar = \$3 + if (variant == curvar && firstvar == 1) { print; print_using=1; firstvar = 0 } + next +} +/^Using / { + if (variant == curvar && print_using) { print; next } +} +/^Running / { + print_using=0 + if (variant == curvar) { + curfile="${TMP}/list"expfilesr[\$2] + expfileseen[\$2]=expfileseen[\$2] + 1 + testname="00" + next + } +} +/\===/ { curvar = ""; next } +/^(PASS|XPASS|FAIL|XFAIL|UNRESOLVED|WARNING|ERROR|UNSUPPORTED|UNTESTED|KFAIL):/ { + testname=\$2 + # Ugly hack for gfortran.dg/dg.exp + if ("$TOOL" == "gfortran" && testname ~ /^gfortran.dg\/g77\//) + testname="h"testname +} +/^$/ { if ("$MODE" == "sum") next } +{ if (variant == curvar && curfile) { + if ("$MODE" == "sum") { + printf "%s %08d|", testname, cnt > curfile + cnt = cnt + 1 + } + filewritten[curfile]=1 + print > curfile + } else + next +} +END { + n=1 + while (n < expfileno) { + if (expfileseen[expfiles[n]]) { + print "Running "expfiles[n]" ..." + if (filewritten["${TMP}/list"n]) { + if (expfileseen[expfiles[n]] == 1) + cmd="cat" + else + cmd="LC_ALL=C sort" + if ("$MODE" == "sum") + system (cmd" ${TMP}/list"n" | sed -n 's/^[^ ]* [^ |]*|//p'") + else + system ("cat ${TMP}/list"n) + } + } + n = n + 1 + } +} +EOF + + SUMS_AWK=${TMP}/sums.awk + rm -f $SUMS_AWK + cat << EOF > $SUMS_AWK +BEGIN { + variant="$VAR" + tool="$TOOL" + passcnt=0; failcnt=0; untstcnt=0; xpasscnt=0; xfailcnt=0; unsupcnt=0; unrescnt=0; + curvar=""; insummary=0 +} +/^Running target / { curvar = \$3; next } +/^# of / { if (variant == curvar) insummary = 1 } +/^# of expected passes/ { if (insummary == 1) passcnt += \$5; next; } +/^# of unexpected successes/ { if (insummary == 1) xpasscnt += \$5; next; } +/^# of unexpected failures/ { if (insummary == 1) failcnt += \$5; next; } +/^# of expected failures/ { if (insummary == 1) xfailcnt += \$5; next; } +/^# of untested testcases/ { if (insummary == 1) untstcnt += \$5; next; } +/^# of unresolved testcases/ { if (insummary == 1) unrescnt += \$5; next; } +/^# of unsupported tests/ { if (insummary == 1) unsupcnt += \$5; next; } +/^$/ { if (insummary == 1) + { insummary = 0; curvar = "" } + next + } +{ next } +END { + printf ("\t\t=== %s Summary for %s ===\n\n", tool, variant) + if (passcnt != 0) printf ("# of expected passes\t\t%d\n", passcnt) + if (xpasscnt != 0) printf ("# of unexpected successes\t%d\n", xpasscnt) + if (failcnt != 0) printf ("# of unexpected failures\t%d\n", failcnt) + if (xfailcnt != 0) printf ("# of expected failures\t\t%d\n", xfailcnt) + if (untstcnt != 0) printf ("# of untested testcases\t\t%d\n", untstcnt) + if (unrescnt != 0) printf ("# of unresolved testcases\t%d\n", unrescnt) + if (unsupcnt != 0) printf ("# of unsupported tests\t\t%d\n", unsupcnt) +} +EOF + + PVAR=`echo $VAR | sed 's,/,.,g'` + TMPFILE=${TMP}/var-$PVAR + rm -f $TMPFILE + rm -f ${TMP}/list* + cat ${TMP}/expfiles $SUM_FILES | $AWK -f $GUTS_AWK + cat $SUM_FILES | $AWK -f $SUMS_AWK > $TMPFILE + # If there are multiple variants, output the counts for this one; + # otherwise there will just be the final counts at the end. + test $VARIANT_COUNT -eq 1 || cat $TMPFILE +done + +# Set up an awk script to get the combined summary counts for the tool. + +TOTAL_AWK=${TMP}/total.awk +cat << EOF > $TOTAL_AWK +BEGIN { + tool="$TOOL" + passcnt=0; failcnt=0; untstcnt=0; xpasscnt=0; xfailcnt=0; unsupcnt=0; unrescnt=0 +} +/^# of expected passes/ { passcnt += \$5 } +/^# of unexpected failures/ { failcnt += \$5 } +/^# of unexpected successes/ { xpasscnt += \$5 } +/^# of expected failures/ { xfailcnt += \$5 } +/^# of untested testcases/ { untstcnt += \$5 } +/^# of unresolved testcases/ { unrescnt += \$5 } +/^# of unsupported tests/ { unsupcnt += \$5 } +END { + printf ("\n\t\t=== %s Summary ===\n\n", tool) + if (passcnt != 0) printf ("# of expected passes\t\t%d\n", passcnt) + if (failcnt != 0) printf ("# of unexpected failures\t%d\n", failcnt) + if (xpasscnt != 0) printf ("# of unexpected successes\t%d\n", xpasscnt) + if (xfailcnt != 0) printf ("# of expected failures\t\t%d\n", xfailcnt) + if (untstcnt != 0) printf ("# of untested testcases\t\t%d\n", untstcnt) + if (unrescnt != 0) printf ("# of unresolved testcases\t%d\n", unrescnt) + if (unsupcnt != 0) printf ("# of unsupported tests\t\t%d\n", unsupcnt) +} +EOF + +# Find the total summaries for the tool and add to the end of the output. +cat ${TMP}/var-* | $AWK -f $TOTAL_AWK + +# This is ugly, but if there's version output from the compiler under test +# at the end of the file, we want it. The other thing that might be there +# is the final summary counts. +tail -n 2 $FIRST_SUM | grep -q '^#' || tail -n 2 $FIRST_SUM + +exit 0 diff -Naur gcc-4.3.2.orig/fixincludes/ChangeLog gcc-4.3.2/fixincludes/ChangeLog --- gcc-4.3.2.orig/fixincludes/ChangeLog 2008-08-27 11:02:53.000000000 -0700 +++ gcc-4.3.2/fixincludes/ChangeLog 2008-12-15 10:19:57.000000000 -0800 @@ -1,3 +1,8 @@ +2008-12-10 Steve Ellcey + + * inclhack.def (hpux_spu_info): Match PA as well as IA64. + * fixincl.x: Regenerate. + 2008-08-27 Release Manager * GCC 4.3.2 released. diff -Naur gcc-4.3.2.orig/fixincludes/fixincl.x gcc-4.3.2/fixincludes/fixincl.x --- gcc-4.3.2.orig/fixincludes/fixincl.x 2008-03-06 17:40:11.000000000 -0800 +++ gcc-4.3.2/fixincludes/fixincl.x 2008-12-15 10:19:57.000000000 -0800 @@ -2,11 +2,11 @@ * * DO NOT EDIT THIS FILE (fixincl.x) * - * It has been AutoGen-ed Wednesday February 20, 2008 at 05:10:00 AM CET + * It has been AutoGen-ed Monday December 15, 2008 at 10:16:56 AM PST * From the definitions inclhack.def * and the template file fixincl */ -/* DO NOT SVN-MERGE THIS FILE, EITHER Wed Feb 20 05:10:00 CET 2008 +/* DO NOT SVN-MERGE THIS FILE, EITHER Mon Dec 15 10:16:56 PST 2008 * * You must regenerate it. Use the ./genfixes script. * @@ -22,23 +22,18 @@ * inclhack copyright (c) 1998, 1999, 2000, 2001 * The Free Software Foundation, Inc. * - * inclhack is free software. + * inclhack is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * You may redistribute it and/or modify it under the terms of the - * GNU General Public License, as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * inclhack is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * inclhack is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with inclhack. If not, write to: - * The Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ /* * * * * * * * * * * * * * * * * * * * * * * * * * @@ -3301,7 +3296,7 @@ * File name selection pattern */ tSCC zHpux_Spu_InfoList[] = - "ia64/sys/getppdp.h\0"; + "*/sys/getppdp.h\0"; /* * Machine/OS name selection pattern */ diff -Naur gcc-4.3.2.orig/fixincludes/inclhack.def gcc-4.3.2/fixincludes/inclhack.def --- gcc-4.3.2.orig/fixincludes/inclhack.def 2008-03-06 17:40:11.000000000 -0800 +++ gcc-4.3.2/fixincludes/inclhack.def 2008-12-15 10:19:57.000000000 -0800 @@ -1927,7 +1927,7 @@ fix = { hackname = hpux_spu_info; mach = "*-hp-hpux*"; - files = ia64/sys/getppdp.h; + files = "*/sys/getppdp.h"; select = "^.*extern.*spu_info.*"; c_fix = format; diff -Naur gcc-4.3.2.orig/gcc/ChangeLog gcc-4.3.2/gcc/ChangeLog --- gcc-4.3.2.orig/gcc/ChangeLog 2008-08-27 11:01:53.000000000 -0700 +++ gcc-4.3.2/gcc/ChangeLog 2008-12-18 13:55:31.000000000 -0800 @@ -1,3 +1,687 @@ +2008-12-18 Andrew Pinski + + PR middle-end/38565 + * gimplifier.c (gimplify_init_constructor): For constant vector + CONSTRUCTORs use GENERIC_TREE_OPERAND instead of TREE_OPERAND. + +2008-12-14 John David Anglin + + PR target/38062 + Backport from mainline: + 2008-04-08 John David Anglin + + * collect2.c (write_c_file): Don't wrap in "#ifdef __cplusplus". + +2008-12-12 Rainer Emrich + + PR bootstrap/38383 + * pa64-hpux.h (LINK_GCC_C_SEQUENCE_SPEC): Don't hardcode search path + for the milli.a library. + +2008-12-12 H.J. Lu + + Backport from mainline: + 2008-12-12 H.J. Lu + + PR target/38402 + * gcc/doc/md.texi: Remove Y and document Yz, Y2, Yi and Ym + constraints for x86. + +2008-12-11 John David Anglin + + PR testsuite/35677 + * emutls.c (__emutls_get_address): Make sure offset is really zero + before initializing the object's offset. + +2008-12-10 Richard Guenther + + Backport from trunk the fix for PR38051. + + PR tree-optimization/38478 + * tree-ssa-structalias.c (update_alias_info): Manually find + written variables. + +2008-12-09 Janis Johnson + + * doc/sourcebuild.texi (Test Directives): Fix formatting. + +2008-12-07 Eric Botcazou + + * tree-sra.c (scalarize_use): Create another temporary with the proper + type for signed types in the use_all && !is_output bitfield case. + +2008-12-05 Janis Johnson + + Backport from mainline: + 2008-05-15 Janis Johnson + + * doc/sourcebuild.texi: Document support for torture tests. + +2008-12-04 Janis Johnson + + Backport from mainline: + 2008-10-18 Jakub Jelinek + Janis Johnson + + * Makefile.in (lang_checks_parallelized, check_gcc_parallelize, + check_p_tool, check_p_vars, check_p_subno, check_p_comma, + check_p_subwork, check_p_numbers, check_p_subdir, check_p_subdirs): + New variables. + (check-subtargets, check-%-subtargets, check-parallel-%): New + targets. + (check-%): For test targets listed in lang_checks_parallelized + if -j is used and RUNTESTFLAGS doesn't specify tests to execute, + run the testing in multiple make goals, possibly parallel, and + afterwards run dg-extract-results.sh to merge the sum and log files. + +2008-12-04 Eric Botcazou + Gary Funck + + * cse.c (lookup_as_function): Delete mode frobbing code. + (equiv_constant): Re-implement it there for SUBREGs. + +2008-12-04 Eric Botcazou + + * cse.c (equiv_constant): Fix pasto. + +2008-12-04 Danny Smith + + Backport from mainline: + 2008-12-02 Danny Smith + + PR target/38054 + * config/i386/winnt.c (i386_pe_encode_section_info): Condition stdcall + decoration of function RTL names here on Ada language. + +2008-12-02 Janis Johnson + + Backport from mainline: + 2008-11-26 Janis Johnson + + PR testsuite/28870 + * doc/sourcebuild.texi (Test Directives): Add dg-timeout and + dg-timeout-factor. + +2008-12-01 Uros Bizjak + + Backport from mainline: + 2008-11-25 Uros Bizjak + + PR target/38254 + * config/i386/sync.md (memory_barrier_nosse): New insn pattern. + (memory_barrier): Generate memory_barrier_nosse insn for + !(TARGET_64BIT || TARGET_SSE2). + * config/i386/sse.md (*sse2_mfence): Also enable for TARGET_64BIT. + +2008-11-30 Eric Botcazou + + PR target/38287 + * config/sparc/sparc.md (divsi3 expander): Remove constraints. + (divsi3_sp32): Add new alternative with 'K' for operand #2. + (cmp_sdiv_cc_set): Factor common string. + (udivsi3_sp32): Add new alternative with 'K' for operand #2. + Add TARGET_V9 case. + (cmp_udiv_cc_set): Factor common string. + +2008-11-26 Fredrik Unger + + * config/soft-fp/floatuntisf.c (__floatuntisf): Correct + function name from __floatundisf. + * config/soft-fp/fixdfti.c (__fixdfti): Correct argument type to + DFtype. + +2008-11-25 Eric Botcazou + + * regrename.c (merge_overlapping_regs): Add registers artificially + defined at the top of the basic block to the set of live ones just + before the first insn. + +2008-11-24 Jakub Jelinek + Eric Botcazou + + * df-scan.c (df_get_call_refs): For unconditional noreturn calls + add EH_USES regs as artificial uses. + (df_get_entry_block_def_set): Don't handle EH_USES here. + +2008-11-22 Eric Botcazou + + * config/sparc/sparc.c (TARGET_ASM_OUTPUT_DWARF_DTPREL): Define + only if HAVE_AS_SPARC_UA_PCREL is defined. + +2008-11-21 Paolo Carlini + + PR other/38214 + * doc/invoke.texi (Optimization Options): Fix typo. + +2008-11-20 Rainer Orth + + PR bootstrap/33100 + * config.gcc (i[34567]86-*-solaris2*): Don't include + i386/t-crtstuff here. + Move extra_parts, i386/t-sol2 in tmake_file to libgcc/config.host. + * config/i386/t-sol2: Move to libgcc/config/i386. + +2008-11-20 Richard Guenther + + PR tree-optimization/37868 + * tree-ssa-structalias.c (set_uids_in_ptset): Add SFTs based on + pointed to variable and access size. + + Backport from mainline: + 2008-07-07 Richard Guenther + + * tree-ssa-structalias.c (struct variable_info): Add is_full_var flag. + (new_var_info): Set it to false. + (solution_set_add): Correctly handle pointers outside a var and + inside a field. + (type_safe): Treat variables with is_full_var properly. + (do_sd_constraint): Likewise. + (do_ds_constraint): Likewise. + (process_constraint): Remove zeroing offset for !use_field_sensitive. + (get_constraint_for_ptr_offset): New function. + (get_constraint_for_component_ref): Handle is_full_vars properly. + (get_constraint_for): Handle POINTER_PLUS_EXPR. + (handle_ptr_arith): Remove. + (find_func_aliases): Handle POINTER_PLUS_EXPR through generic + get_constraint_for code. + (create_function_info_for): For parameter and result varinfos set + is_full_var flag. + (create_variable_info_for): Set is_full_var flag whenever we + just created a single varinfo for a decl. + (init_alias_vars): Initialize use_field_sensitive from + max-fields-for-field-sensitive parameter. + +2008-11-18 Ben Elliston + + Backport from mainline: + 2008-09-28 Andrew Pinski + + PR target/37640 + * config/rs6000/rs6000.c (rs6000_expand_compare_and_swapqhi): Force + address to a register before taking the lower part. + +2008-11-16 Eric Botcazou + + * config/sparc/sparc.c (function_arg_vector_value): Remove 'base_mode' + parameter. Use DImode for computing the number of registers. + (function_arg): Adjust for above change. + (function_value): Likewise. + +2008-11-14 Ulrich Weigand + + * config/spu/spu-elf.h (STANDARD_STARTFILE_PREFIX_2): Disable default. + (STANDARD_INCLUDE_DIR): Redefine to "/include". + (LOCAL_INCLUDE_DIR): Undefine. + * config/spu/t-spu-elf (NATIVE_SYSTEM_HEADER_DIR): Define. + +2008-11-14 Dodji Seketeli + + PR debug/27574 + * cgraph.h: New abstract_and_needed member to struct cgraph_node. + * cgraphunit.c (cgraph_analyze_functions): Flag abstract functions + -which clones are reachable - as "abstract and needed". + * cgraph.c (cgraph_release_function_body): If a node is + "abstract and needed", do not release its DECL_INITIAL() content + will be needed to emit debug info. + +2008-11-13 Uros Bizjak + + Backport from mainline: + 2008-06-06 Uros Bizjak + + PR rtl-optimization/36438 + * cse.c (fold_rtx) [ASHIFT, LSHIFTRT, ASHIFTRT]: Break out early + for vector shifts with constant scalar shift operands. + +2008-11-12 Jason Merrill + + PR c++/38007 + * c-common.c (c_common_signed_or_unsigned_type): Remove C++ + special casing. + +2008-11-12 Ulrich Weigand + + * gcc/config/s390/s390.h (INITIAL_FRAME_ADDRESS_RTX): Remove + packed-stack special handling. + (FRAME_ADDR_RTX): Add definition. + +2008-11-12 Ira Rosen + + PR tree-optimization/38079 + * tree-vect-analyze.c (vect_analyze_data_refs): Replace dump_file + with vect_dump. + +2008-11-10 Andrew Haley + + Backport from mainline: + + PR bootstrap/33304 + * vec.h (VEC_TA): New. + (DEF_VEC_I, DEF_VEC_P, DEF_VEC_ALLOC_I, DEF_VEC_ALLOC_P, + DEF_VEC_O, DEF_VEC_ALLOC_O: Use VEC_TA. + * c-common.c (C_COMMON_FIXED_TYPES_SAT): New macro. + (C_COMMON_FIXED_MODE_TYPES_SAT): New macro. + (C_COMMON_FIXED_TYPES): Remove first arg. + (C_COMMON_FIXED_MODE_TYPES): Likewise. + * tree.c (MAKE_FIXED_TYPE_NODE): Break into two macros, + MAKE_FIXED_TYPE_NODE and MAKE_FIXED_TYPE_NODE_WIDTH in order + not to use empty macro arguments. + +2008-11-10 Uros Bizjak + + Backport from mainline: + 2008-11-10 Ralph Loader + + PR middle-end/37807 + PR middle-end/37809 + * combine.c (force_to_mode): Do not process vector types. + + * rtlanal.c (nonzero_bits1): Do not process vector types. + (num_sign_bit_copies1): Likewise. + +2008-11-06 Richard Guenther + + Backport from mainline: + 2008-09-13 H.J. Lu + + PR rtl-optimization/37489 + * cse.c (fold_rtx): Don't return const_true_rtx for float + compare if FLOAT_STORE_FLAG_VALUE is undefined. + +2008-11-06 Kazu Hirata + + PR target/35574 + * config/sparc/predicates.md (const_double_or_vector_operand): + New. + * config/sparc/sparc.c (sparc_extra_constraint_check): Handle the + 'D' constraint. + * config/sparc/sparc.h: Document the 'D' constraint. + * config/sparc/sparc.md (*movdf_insn_sp32_v9, *movdf_insn_sp64): + Use the 'D' constraint in addition to 'F' in some alternatives. + (DF splitter): Generalize for V64mode. + * doc/md.texi (SPARC): Document the 'D' constraint. + +2008-11-05 Jakub Jelinek + + PR c/37924 + * combine.c (make_compound_operation): Don't call make_extraction with + non-positive length. + (simplify_shift_const_1): Canonicalize count even if complement_p. + + PR tree-optimization/37879 + * predict.c (tree_estimate_probability): Check if last_stmt is + non-NULL before dereferencing it. + + PR middle-end/37858 + * passes.c (execute_one_pass): Don't look at cfun->curr_properties + for ipa and simple ipa passes. + + PR middle-end/37870 + * expmed.c (extract_bit_field_1): If int_mode_for_mode returns + BLKmode for non-memory, convert using a wider MODE_INT mode + or through memory. + +2008-11-05 Hans-Peter Nilsson + + PR target/38016 + * config/cris/cris.c (cris_order_for_addsi3): Test for !REG_P, not + just MEM_P. + +2008-11-03 Eric Botcazou + + * tree-sra.c (bitfield_overlaps_p): Fix oversight. + +2008-11-01 Hans-Peter Nilsson + + PR target/37939 + * config/cris/cris.c (cris_rtx_costs) : Return 0 for an ADDI + operand. + +2008-11-01 Kaz Kojima + + Backport from mainline: + 2008-10-24 Kaz Kojima + + PR rtl-optimization/37769 + * regmove.c (optimize_reg_copy_2): Update REG_INC note if needed. + +2008-10-31 Kaz Kojima + + PR target/37909 + Backport from mainline: + * config/sh/sh.c (untangle_mova): Return -1 when NEW_MOVA has + no address. + +2008-10-25 Kaz Kojima + + Backport from mainline: + * config/sh/t-sh: Use $(MULTILIB_CFLAGS) when compiling to + unwind-dw2-Os-4-200.o. + +2008-10-22 Chao-ying Fu + + * config/mips/mips.opt (msmartmips): Accept -mno-smartmips. + +2008-10-22 Jakub Jelinek + + PR middle-end/37882 + * fold-const.c (build_range_type): For 1 .. signed_max + range call build_nonstandard_inter_type if signed_type_for + returned a type with bigger precision. + +2008-10-22 Richard Guenther + + * tree-ssa-alias-warnings.c (skip_this_pointer): Skip pointers + for which we merged aliases of SMTs into their points-to sets. + * real.c (vax_f_format): Add missing initializer. + +2008-10-19 Richard Guenther + + * tree-ssa-alias.c (may_alias_p): Remove bogus shortcut. + +2008-10-17 Andrew MacLeod + + PR tree-optimization/37102 + * tree-outof-ssa.c (remove_gimple_phi_args): Remove all the PHI args + from a node. Check to see if another PHI is dead. + (eliminate_useless_phis): Rename from eliminate_virtual_phis and remove + real PHIs which have no uses. + (rewrite_out_of_ssa): Call eliminate_useless_phis. + +2008-10-08 Simon Martin + + PR c/35437 + * expr.c (count_type_elements): Handle ERROR_MARK. + +2008-10-07 H.J. Lu + + Backport from mainline: + 2008-10-07 H.J. Lu + + PR middle-end/37731 + * expmed.c (expand_mult): Properly check DImode constant in + CONST_DOUBLE. + +2008-10-07 Eric Botcazou + + * tree-ssa-loop-ivopts.c (may_be_nonaddressable_p) : + Return true for non-addressable GIMPLE operands. + +2008-10-04 Gerald Pfeifer + + * config/freebsd.h (HANDLE_PRAGMA_PACK_PUSH_POP): Define. + +2000-10-04 John David Anglin + + PR target/37603 + * pa.c (legitimize_pic_address): Force function labels to memory in + word mode. + +2008-10-01 Richard Henderson + + PR tree-opt/35737 + * tree-complex.c (set_component_ssa_name): Don't optimize + is_gimple_min_invariant values with ssa_names in abnormal phis. + +2008-09-30 Joseph Myers + + * ifcvt.c (noce_emit_store_flag): If using condition from original + jump, reverse it if if_info->cond was reversed. + +2008-09-28 Eric Botcazou + + PR middle-end/36575 + * fold-const.c (div_and_round_double) : Fix typo. + +2008-09-25 Jakub Jelinek + + PR c/37645 + * c-common.c (handle_weakref_attribute): Ignore the attribute unless + the decl is a VAR_DECL or FUNCTION_DECL. + +2008-09-24 Richard Henderson + + * dwarf2.h (DW_OP_GNU_encoded_addr): New. + * unwind-dw2.c (execute_stack_op): Handle it. + +2008-09-21 Ira Rosen + + PR tree-optimization/37539 + * tree-vect-transform.c (vect_transform_strided_load): Save vector + statement in related statement field only for the first load of the + group of loads with the same data reference. + +2008-09-20 Richard Guenther + + Backport from mainline: + 2008-08-29 Richard Guenther + + PR middle-end/37236 + * tree-ssa-structalias.c (intra_create_variable_infos): Mark + PARAM_NOALIAS tags with is_heapvar. + * tree-ssa-operands.c (access_can_touch_variable): Offset + based tests do not apply for heapvars. Fix offset test. + +2008-09-19 Richard Guenther + + PR tree-optimization/36343 + * tree-ssa-structalias.c (struct variable_info): Remove + directly_dereferenced member. + (new_var_info): Do not set it. + (process_constraint_1): Likewise. + (set_uids_in_ptset): Remove TBAA-pruning code. + (find_what_p_points_to): Do not pass TBAA-pruning related + parameters. + +2008-09-19 Uros Bizjak + + Backport from mainline: + 2008-09-18 Uros Bizjak + + PR rtl-optimization/37544 + * regrename.c (maybe_mode_change): Exit early when copy_mode + is narrower than orig_mode and narrower than new_mode. + +2008-09-18 Janis Johnson + + Backport from mainline: + 2008-04-08 Janis Johnson + PR target/35620 + * config/rs6000/rs6000.c (rs6000_check_sdmode): Handle additional + kinds of indirect references. + + Backport from mainline: + 2008-04-03 Janis Johnson + + PR target/35713 + * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Use integer + constants of the appropriate size for runtime calculations. + + Backport from mainline: + 2008-04-03 Janis Johnson + PR c/35712 + * dfp.c (decimal_from_decnumber): Retain trailing zeroes for + decimal-float literal constant zero. + +2008-09-18 Andreas Krebbel + + * doc/invoke.texi: Document -mhard-dfp, -mno-hard-dfp. + Mention -march=z9-109 and z9-ec. + +2008-09-12 Anatoly Sokolov + + PR target/37466 + * config/avr/avr.md (movsi_lreg_const peephole2): Add match_dup for + scratch register after 'set' pattern. + +2008-09-12 Ulrich Weigand + + * emit-rtl.c (set_reg_attrs_from_value): Fix invalid alignment + information passed to mark_reg_pointer. + * explow.c (force_reg): Likewise. + +2008-09-12 Ulrich Weigand + + * config/spu/spu.c (spu_override_options): Default to -mno-safe-hints + when building for the celledp architecture. + +2008-09-09 Trevor Smigiel + + Improved branch hints, safe hints, and scheduling for Cell SPU. + + * haifa-sched.c (sched_emit_insn) : Define. + * sched-int.h (sched_emit_insn) : Add prototype. + * doc/invoke.texi (-mdual-nops, -mhint-max-nops, + -mhint-max-distance -msafe-hints) : Document. + * config/spu/spu.c (spu_flag_var_tracking): New. + (TARGET_SCHED_INIT_GLOBAL, TARGET_SCHED_INIT, + TARGET_SCHED_REORDER, TARGET_SCHED_REORDER2, + TARGET_ASM_FILE_START): Define. + (TARGET_SCHED_ADJUST_PRIORITY): Remove. + (STOP_HINT_P, HINTED_P, SCHED_ON_EVEN_P): Define. + (spu_emit_branch_hint): Add blocks argument. + (insert_branch_hints, insert_nops): Remove. + (pad_bb, insert_hbrp_for_ilb_runout, insert_hbrp, in_spu_reorg, + uses_ls_unit, spu_sched_init_global, spu_sched_init, + spu_sched_reorder, asm_file_start): New functions. + (clock_var, spu_sched_length, pipe0_clock, + pipe1_clock, prev_clock_var, prev_priority, + spu_ls_first, prev_ls_clock): New static variables. + * config/spu/spu.h (TARGET_DEFAULT): Add MASK_SAFE_HINTS. + * config/spu.md (iprefetch): Add operand, make it clobber MEM. + (nopn_nv): Add a non-volatile version of nop. + * config/spu/spu.opt (-mdual-nops, -mhint-max-nops, + -mhint-max-distance, -msafe-hints): New options. + +2008-09-09 Jakub Jelinek + + PR rtl-optimization/37408 + * function.c (assign_parm_find_stack_rtl): Set correct MEM_SIZE + if parm is promoted. + +2008-09-08 Richard Henderson + + * config/alpha/alpha.c (alpha_split_lock_test_and_set): Move + memory barrier to below the test-and-set. + (alpha_split_lock_test_and_set_12): Likewise. + +2008-09-07 Richard Guenther + Ira Rosen + + PR tree-optimization/36630 + * tree-vect-transform.c (vect_update_ivs_after_vectorizer): + Call STRIP_NOPS before calling evolution_part_in_loop_num. + +2008-09-04 Ian Lance Taylor + + * varasm.c (narrowing_initializer_constant_valid_p): New + static function. + (initializer_constant_valid_p): Call it. + +2008-09-02 Jakub Jelinek + + PR target/36332 + * real.c (real_maxval): Clear a lower bit to make real_maxval + match get_max_float for IBM long double format. + +2008-09-02 Bob Wilson + + * config/xtensa/xtensa.md (mulsidi3): Use a temporary register. + +2008-09-01 Jakub Jelinek + + PR middle-end/37248 + PR middle-end/36449 + * fold-const.c (make_bit_field_ref): Change bitpos and bitsize + arguments to HOST_WIDE_INT. + (fold_truthop): Change first_bit and end_bit to HOST_WIDE_INT. + + Revert: + 2008-06-11 Richard Guenther + PR middle-end/36449 + * fold-const.c (fold_truthop): Remove code generating + BIT_FIELD_REFs of structure bases. + (fold_binary): Likewise. + (make_bit_field_ref): Remove. + (optimize_bit_field_compare): Remove. + (all_ones_mask_p): Remove. + +2008-08-31 Jakub Jelinek + + PR target/37168 + * config/rs6000/rs6000-protos.h (const_vector_elt_as_int): Add + prototype. + * config/rs6000/rs6000.c (const_vector_elt_as_int): No longer static. + * config/rs6000/altivec.md (easy_vector_constant_add_self splitter): + Also split V4SFmode. + * config/rs6000/predicates.md (easy_vector_constant_add_self): Handle + vector float modes. + +2008-08-29 Jakub Jelinek + + PR c/37261 + * fold-const.c (fold_binary): In (X | C1) & C2 canonicalization + compute new & and | in type rather than TREE_TYPE (arg0). + +2008-08-28 Ulrich Weigand + + * config/spu/spu_mfcio.h (mfc_begin_critical_section): New function. + (mfc_end_critical_section): Likewise. + +2008-08-28 Ulrich Weigand + + * config/rs6000/rs6000.c (rs6000_handle_altivec_attribute): Propagate + all type qualifiers from element type to vector type. + +2008-08-28 Dodji Seketeli + + PR c++/36741 + * tree.c (int_fits_type_p): Don't forget unsigned integers + of type sizetype which higher end word equals -1. + +2008-08-28 Richard Guenther + + PR middle-end/36548 + PR middle-end/37125 + * fold-const.c (extract_muldiv_1): Optimize (X * C1) % C2 only + if the multiplication does not overflow. + +2008-08-28 Richard Guenther + + PR middle-end/36817 + * tree-chrec.c (chrec_apply): Always call chrec_fold_plus which + makes sure to produce a result of the correct type. + +2008-08-28 Uros Bizjak + + PR target/37184 + * config/i386/i386.c (ix86_match_ccmode): Handle CCAmode, + CCCmode, CCOmode and CCSmode destination modes. + + PR target/37191 + * config/i386/mmx.md (*vec_extractv2sf_0): Avoid combining registers + from different units in a single alternative. + (*vec_extractv2sf_1): Ditto. + (*vec_extractv2si_0): Ditto. + (*vec_extractv2si_1): Ditto. + * config/i386/sse.md (sse2_storehpd): Ditto. + (sse2_storelpd): Ditto. + (sse2_loadhpd): Ditto. + (sse2_loadlpd): Ditto. + + PR target/37197 + * config/i386/i386.md (clzsi2_abm): Fix operand 1 constraints. + (popcountsi2): Ditto. + (clzdi2_abm): Ditto. + (popcountdi2): Ditto. + (clzhi2_abm): Ditto. + (popcounthi2): Ditto. + +2008-08-27 Joseph Myers + + * BASE-VER: Set to 4.3.3. + * DEV-PHASE: Set to prerelease. + 2008-08-27 Release Manager * GCC 4.3.2 released. diff -Naur gcc-4.3.2.orig/gcc/Makefile.in gcc-4.3.2/gcc/Makefile.in --- gcc-4.3.2.orig/gcc/Makefile.in 2008-08-01 02:51:03.000000000 -0700 +++ gcc-4.3.2/gcc/Makefile.in 2008-12-04 15:00:19.000000000 -0800 @@ -420,6 +420,23 @@ xm_include_list=@xm_include_list@ xm_defines=@xm_defines@ lang_checks=check-gcc +lang_checks_parallelized=check-gcc +# This lists a couple of test files that take most time during check-gcc. +# When doing parallelized check-gcc, these can run in parallel with the +# remaining tests. Each word in this variable stands for work for one +# make goal and one extra make goal is added to handle all the *.exp +# files not handled explicitly already. If multiple *.exp files +# should be run in the same runtest invocation (usually if they aren't +# very long running, but still should be split of from the check-parallel-$lang +# remaining tests runtest invocation), they should be concatenated with commas. +# Note that [a-zA-Z] wildcards need to have []s prefixed with \ (needed +# by tcl) and as the *.exp arguments are mached both as is and with +# */ prefixed to it in runtest_file_p, it is usually desirable to include +# a subdirectory name. +check_gcc_parallelize=execute.exp=execute/2* \ + execute.exp=execute/\[013-9a-zA-Z\]* \ + compile.exp dg.exp \ + struct-layout-1.exp,unsorted.exp,stackalign.exp,i386.exp lang_opt_files=@lang_opt_files@ $(srcdir)/c.opt $(srcdir)/common.opt lang_specs_files=@lang_specs_files@ lang_tree_files=@lang_tree_files@ @@ -4275,6 +4292,8 @@ check: $(CHECK_TARGETS) +check-subtargets: $(patsubst %,%-subtargets,$(CHECK_TARGETS)) + # The idea is to parallelize testing of multilibs, for example: # make -j3 check-gcc//sh-hms-sim/{-m1,-m2,-m3,-m3e,-m4}/{,-nofpu} # will run 3 concurrent sessions of check-gcc, eventually testing @@ -4296,7 +4315,8 @@ -rm -f $@ sed '/set tmpdir/ s|testsuite|$(TESTSUITEDIR)|' < site.exp > $@ -$(lang_checks): check-% : site.exp +# This is only used for check-% targets that aren't parallelized. +$(filter-out $(lang_checks_parallelized),$(lang_checks)): check-% : site.exp -test -d $(TESTSUITEDIR) || mkdir $(TESTSUITEDIR) test -d $(TESTSUITEDIR)/$* || mkdir $(TESTSUITEDIR)/$* -(rootme=`${PWD_COMMAND}`; export rootme; \ @@ -4313,6 +4333,108 @@ GCC_EXEC_PREFIX="$(libdir)/gcc/" ; export GCC_EXEC_PREFIX ; \ $(RUNTEST) --tool $* $(RUNTESTFLAGS)) +$(patsubst %,%-subtargets,$(filter-out $(lang_checks_parallelized),$(lang_checks))): check-%-subtargets: + @echo check-$* + +check_p_tool=$(firstword $(subst _, ,$*)) +check_p_vars=$(check_$(check_p_tool)_parallelize) +check_p_subno=$(word 2,$(subst _, ,$*)) +check_p_comma=, +check_p_subwork=$(subst $(check_p_comma), ,$(if $(check_p_subno),$(word $(check_p_subno),$(check_p_vars)))) +check_p_numbers=1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 +check_p_subdir=$(subst _,,$*) +check_p_subdirs=$(wordlist 1,$(words $(check_$*_parallelize)),$(check_p_numbers)) + +# For parallelized check-% targets, this decides whether parallelization +# is desirable (if -jN is used and RUNTESTFLAGS doesn't contain anything +# but optionally --target_board argument). If it is desirable, +# recursive make is run with check-parallel-$lang{,1,2,3,4,5} etc. goals, +# which can be executed in parallel, as they are run in separate directories. +# check-parallel-$lang{1,2,3,4,5} etc. goals invoke runtest with the longest +# running *.exp files from the testsuite, as determined by check_$lang_parallelize +# variable. The check-parallel-$lang goal in that case invokes runtest with +# all the remaining *.exp files not handled by the separate goals. +# Afterwards contrib/dg-extract-results.sh is used to merge the sum and log +# files. If parallelization isn't desirable, only one recursive make +# is run with check-parallel-$lang goal and check_$lang_parallelize variable +# cleared to say that no additional arguments beyond $(RUNTESTFLAGS) +# should be passed to runtest. +# +# To parallelize some language check, add the corresponding check-$lang +# to lang_checks_parallelized variable and define check_$lang_parallelize +# variable (see above check_gcc_parallelize description). +$(lang_checks_parallelized): check-% : site.exp + @if [ -z "$(filter-out --target_board=%, $(RUNTESTFLAGS))" ] \ + && [ "$(filter -j, $(MFLAGS))" = "-j" ]; then \ + $(MAKE) TESTSUITEDIR="$(TESTSUITEDIR)" RUNTESTFLAGS="$(RUNTESTFLAGS)" \ + check-parallel-$* \ + $(patsubst %,check-parallel-$*_%, $(check_p_subdirs)); \ + for file in $(TESTSUITEDIR)/$*/$* \ + $(patsubst %,$(TESTSUITEDIR)/$*%/$*,$(check_p_subdirs));\ + do \ + mv -f $$file.sum $$file.sum.sep; mv -f $$file.log $$file.log.sep; \ + done; \ + $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh \ + $(TESTSUITEDIR)/$*/$*.sum.sep \ + $(patsubst %,$(TESTSUITEDIR)/$*%/$*.sum.sep,$(check_p_subdirs)) \ + > $(TESTSUITEDIR)/$*/$*.sum; \ + $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh -L \ + $(TESTSUITEDIR)/$*/$*.log.sep \ + $(patsubst %,$(TESTSUITEDIR)/$*%/$*.log.sep,$(check_p_subdirs)) \ + > $(TESTSUITEDIR)/$*/$*.log; \ + else \ + $(MAKE) TESTSUITEDIR="$(TESTSUITEDIR)" RUNTESTFLAGS="$(RUNTESTFLAGS)" \ + check_$*_parallelize= check-parallel-$*; \ + fi + +# Just print the parallelized subtargets for those that want to split +# the testing across machines. +$(patsubst %,%-subtargets,$(lang_checks_parallelized)): check-%-subtargets: + @echo check-parallel-$* \ + $(patsubst %,check-parallel-$*_%, $(check_p_subdirs)) + +# In the if [ -n "$(check_p_subno)" ] case runtest should be given the name of +# the given *.exp file(s). See comment above check_gcc_parallelize variable +# for details on the content of these variables. +# +# In the elif [ -n "$(check_p_vars)" ] case runtest should be given +# names of all the *.exp files for this tool that aren't already handled by +# other goals. First it finds all the *.exp files for this tool, then +# prunes those already specified in check_$lang_parallelize or duplicates. +# +# Otherwise check-$lang isn't parallelized and runtest is invoked just with +# the $(RUNTESTFLAGS) arguments. +check-parallel-% : site.exp + -test -d $(TESTSUITEDIR) || mkdir $(TESTSUITEDIR) + test -d $(TESTSUITEDIR)/$(check_p_subdir) || mkdir $(TESTSUITEDIR)/$(check_p_subdir) + -(rootme=`${PWD_COMMAND}`; export rootme; \ + srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \ + cd $(TESTSUITEDIR)/$(check_p_subdir); \ + rm -f tmp-site.exp; \ + sed '/set tmpdir/ s|testsuite|$(TESTSUITEDIR)/$(check_p_subdir)|' \ + < ../../site.exp > tmp-site.exp; \ + $(SHELL) $${srcdir}/../move-if-change tmp-site.exp site.exp; \ + EXPECT=${EXPECT} ; export EXPECT ; \ + if [ -f $${rootme}/../expect/expect ] ; then \ + TCL_LIBRARY=`cd .. ; cd $${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \ + export TCL_LIBRARY ; fi ; \ + GCC_EXEC_PREFIX="$(libdir)/gcc/" ; export GCC_EXEC_PREFIX ; \ + runtestflags= ; \ + if [ -n "$(check_p_subno)" ] ; then \ + runtestflags="$(check_p_subwork)"; \ + elif [ -n "$(check_p_vars)" ] ; then \ + parts="`echo ' $(strip $(subst $(check_p_comma), ,$(check_p_vars))) ' \ + | sed 's/=[^ ]* / /g'`"; \ + for part in `find $$srcdir/testsuite/$(check_p_tool)* -name \*.exp` ; do \ + part=`basename $$part` ; \ + case " $$parts $$runtestflags " in \ + *" $$part "*) ;; \ + *) runtestflags="$$runtestflags $$part" ;; \ + esac ; \ + done ; \ + fi ; \ + $(RUNTEST) --tool $(check_p_tool) $(RUNTESTFLAGS) $$runtestflags) + check-consistency: testsuite/site.exp -rootme=`${PWD_COMMAND}`; export rootme; \ srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \ @@ -4350,7 +4472,7 @@ ${QMTEST_DIR} stamp-qmtest: ${QMTEST} -D ${QMTEST_DIR} create-tdb \ -c gcc_database.GCCDatabase \ - -a srcdir=`cd ${srcdir}/testsuite && ${PWD_COMMAND}` && \ + -a srcdir=`cd ${srcdir}/testsuite && ${PWD_COMMAND}` && \ $(STAMP) stamp-qmtest # Create the QMTest context file. diff -Naur gcc-4.3.2.orig/gcc/ada/ChangeLog gcc-4.3.2/gcc/ada/ChangeLog --- gcc-4.3.2.orig/gcc/ada/ChangeLog 2008-08-27 11:02:00.000000000 -0700 +++ gcc-4.3.2/gcc/ada/ChangeLog 2008-12-04 15:00:19.000000000 -0800 @@ -1,3 +1,36 @@ +2008-12-04 Janis Johnson + + Backport from mainline: + 2008-10-18 Jakub Jelinek + Janis Johnson + + * Make-lang.in (check-ada-subtargets): Depend on + check-acats-subtargets and check-gnat-subtargets. + (check_acats_targets): New variable. + (check-acats-subtargets, check-acats%): New targets. + (check-acats): If -j is used and CHAPTERS is empty, run the testing + in multiple make goals, possibly parallel, and afterwards run + dg-extract-results.sh to merge the sum and log files. + +2008-11-15 Bechir Zalila + Eric Botcazou + + PR ada/34289 + * lib.ads: (Enable_Switch_Storing): Declare. + * lib.adb: (Enable_Switch_Storing): New procedure. + * switch-c.adb (Scan_Front_End_Switches): Add support for -gnatea. + * make.adb: (Compile_Sources.Compile): Add -gnatea as first option. + (Display): Never display -gnatea + * lang-specs.h: If -gnatea is present, pass -gnatez. + +2008-10-06 Eric Botcazou + + * utils.c (can_fold_for_view_convert_p): New predicate. + (unchecked_convert): Use it to disable problematic folding with + VIEW_CONVERT_EXPR in the general case. Always disable it for the + special VIEW_CONVERT_EXPR built for integral types and cope with + its addressability issues by preserving the first conversion. + 2008-08-27 Release Manager * GCC 4.3.2 released. diff -Naur gcc-4.3.2.orig/gcc/ada/Make-lang.in gcc-4.3.2/gcc/ada/Make-lang.in --- gcc-4.3.2.orig/gcc/ada/Make-lang.in 2008-02-06 13:51:24.000000000 -0800 +++ gcc-4.3.2/gcc/ada/Make-lang.in 2008-12-04 15:00:19.000000000 -0800 @@ -859,15 +859,47 @@ lang_checks += check-gnat check-ada: check-acats check-gnat +check-ada-subtargets: check-acats-subtargets check-gnat-subtargets ACATSDIR = $(TESTSUITEDIR)/ada/acats +check_acats_targets = $(patsubst %,check-acats%, 0 1 2) + check-acats: - test -d $(ACATSDIR) || mkdir -p $(ACATSDIR) + @test -d $(ACATSDIR) || mkdir -p $(ACATSDIR); \ + if [ -z "$(CHAPTERS)" ] && [ "$(filter -j, $(MFLAGS))" = "-j" ]; \ + then \ + $(MAKE) $(check_acats_targets); \ + for idx in 0 1 2; do \ + mv -f $(ACATSDIR)$$idx/acats.sum $(ACATSDIR)$$idx/acats.sum.sep; \ + mv -f $(ACATSDIR)$$idx/acats.log $(ACATSDIR)$$idx/acats.log.sep; \ + done; \ + $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh \ + $(ACATSDIR)0/acats.sum.sep $(ACATSDIR)1/acats.sum.sep \ + $(ACATSDIR)2/acats.sum.sep > $(ACATSDIR)/acats.sum; \ + $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh -L \ + $(ACATSDIR)0/acats.log.sep $(ACATSDIR)1/acats.log.sep \ + $(ACATSDIR)2/acats.log.sep > $(ACATSDIR)/acats.log; \ + exit 0; \ + fi; \ testdir=`cd ${srcdir}/${ACATSDIR}; ${PWD_COMMAND}`; \ export testdir; cd $(ACATSDIR); $(SHELL) $${testdir}/run_acats $(CHAPTERS) -.PHONY: check-acats +check-acats-subtargets: + @echo $(check_acats_targets) + +# Parallelized check-acats +$(check_acats_targets): check-acats%: + test -d $(ACATSDIR)$* || mkdir -p $(ACATSDIR)$*; \ + testdir=`cd ${srcdir}/${ACATSDIR} && ${PWD_COMMAND}`; \ + case "$*" in \ + 0) chapters="`cd $$testdir/tests; echo [a-b]* c[0-4]*`";; \ + 1) chapters="`cd $$testdir/tests; echo c[5-9ab]*`";; \ + 2) chapters="`cd $$testdir/tests; echo c[c-z]* [d-z]*`";; \ + esac; \ + export testdir; cd $(ACATSDIR)$* && $(SHELL) $${testdir}/run_acats $$chapters + +.PHONY: check-acats $(check_acats_targets) # Bootstrapping targets for just GNAT - use the same stage directories diff -Naur gcc-4.3.2.orig/gcc/ada/lang-specs.h gcc-4.3.2/gcc/ada/lang-specs.h --- gcc-4.3.2.orig/gcc/ada/lang-specs.h 2007-11-01 11:06:47.000000000 -0700 +++ gcc-4.3.2/gcc/ada/lang-specs.h 2008-11-15 08:15:00.000000000 -0800 @@ -35,7 +35,8 @@ gnat1 %{I*} %{k8:-gnatk8} %{w:-gnatws} %{!Q:-quiet} %{nostdinc*}\ %{nostdlib*}\ -dumpbase %{.adb:%b.adb}%{.ads:%b.ads}%{!.adb:%{!.ads:%b.ada}}\ - %{O*} %{W*} %{w} %{p} %{pg:-p} %{a} %{f*} %{d*} %{g*&m*} " + %{O*} %{W*} %{w} %{p} %{pg:-p} %{a} %{f*} %{d*}\ + %{gnatea:-gnatez} %{g*&m*} " #if defined(TARGET_VXWORKS_RTP) "%{fRTS=rtp:-mrtp} " #endif diff -Naur gcc-4.3.2.orig/gcc/ada/lib.adb gcc-4.3.2/gcc/ada/lib.adb --- gcc-4.3.2.orig/gcc/ada/lib.adb 2007-09-12 04:58:21.000000000 -0700 +++ gcc-4.3.2/gcc/ada/lib.adb 2008-11-15 08:15:00.000000000 -0800 @@ -49,7 +49,7 @@ package body Lib is Switch_Storing_Enabled : Boolean := True; - -- Set to False by Disable_Switch_Storing + -- Controlled by Enable_Switch_Storing/Disable_Switch_Storing ----------------------- -- Local Subprograms -- @@ -423,6 +423,19 @@ return Compilation_Switches.Last; end Compilation_Switches_Last; + --------------------------- + -- Enable_Switch_Storing -- + --------------------------- + + procedure Enable_Switch_Storing is + begin + Switch_Storing_Enabled := True; + end Enable_Switch_Storing; + + ---------------------------- + -- Disable_Switch_Storing -- + ---------------------------- + procedure Disable_Switch_Storing is begin Switch_Storing_Enabled := False; diff -Naur gcc-4.3.2.orig/gcc/ada/lib.ads gcc-4.3.2/gcc/ada/lib.ads --- gcc-4.3.2.orig/gcc/ada/lib.ads 2007-12-13 02:40:58.000000000 -0800 +++ gcc-4.3.2/gcc/ada/lib.ads 2008-11-15 08:15:00.000000000 -0800 @@ -556,9 +556,15 @@ -- which may influence the generated output file(s). Switch is the text of -- the switch to store (except that -fRTS gets changed back to --RTS). + procedure Enable_Switch_Storing; + -- Enable registration of switches by Store_Compilation_Switch. Used to + -- avoid registering switches added automatically by the gcc driver at the + -- beginning of the command line. + procedure Disable_Switch_Storing; -- Disable registration of switches by Store_Compilation_Switch. Used to - -- avoid registering switches added automatically by the gcc driver. + -- avoid registering switches added automatically by the gcc driver at the + -- end of the command line. procedure Store_Linker_Option_String (S : String_Id); -- This procedure is called to register the string from a pragma diff -Naur gcc-4.3.2.orig/gcc/ada/make.adb gcc-4.3.2/gcc/ada/make.adb --- gcc-4.3.2.orig/gcc/ada/make.adb 2007-12-13 02:45:44.000000000 -0800 +++ gcc-4.3.2/gcc/ada/make.adb 2008-11-15 08:15:00.000000000 -0800 @@ -2893,7 +2893,7 @@ Source_Index : Int; Args : Argument_List) return Process_Id is - Comp_Args : Argument_List (Args'First .. Args'Last + 9); + Comp_Args : Argument_List (Args'First .. Args'Last + 10); Comp_Next : Integer := Args'First; Comp_Last : Integer; Arg_Index : Integer; @@ -2950,6 +2950,9 @@ end if; end loop; + Comp_Args (Comp_Next) := new String'("-gnatea"); + Comp_Next := Comp_Next + 1; + Comp_Args (Comp_Next) := Comp_Flag; Comp_Next := Comp_Next + 1; @@ -4032,9 +4035,11 @@ for J in Args'Range loop - -- Never display -gnatez + -- Never display -gnatea nor -gnatez - if Args (J).all /= "-gnatez" then + if Args (J).all /= "-gnatea" and then + Args (J).all /= "-gnatez" + then -- Do not display the mapping file argument automatically -- created when using a project file. diff -Naur gcc-4.3.2.orig/gcc/ada/switch-c.adb gcc-4.3.2/gcc/ada/switch-c.adb --- gcc-4.3.2.orig/gcc/ada/switch-c.adb 2007-12-13 02:20:52.000000000 -0800 +++ gcc-4.3.2/gcc/ada/switch-c.adb 2008-11-15 08:15:00.000000000 -0800 @@ -295,6 +295,11 @@ case Switch_Chars (Ptr) is + when 'a' => + Store_Switch := False; + Enable_Switch_Storing; + Ptr := Ptr + 1; + -- -gnatec (configuration pragmas) when 'c' => diff -Naur gcc-4.3.2.orig/gcc/ada/utils.c gcc-4.3.2/gcc/ada/utils.c --- gcc-4.3.2.orig/gcc/ada/utils.c 2008-05-13 01:46:49.000000000 -0700 +++ gcc-4.3.2/gcc/ada/utils.c 2008-10-06 00:10:31.000000000 -0700 @@ -3824,8 +3824,72 @@ return exp; } +/* Return true if EXPR is an expression that can be folded as an operand + of a VIEW_CONVERT_EXPR. See the head comment of unchecked_convert for + the rationale. */ + +static bool +can_fold_for_view_convert_p (tree expr) +{ + tree t1, t2; + + /* The folder will fold NOP_EXPRs between integral types with the same + precision (in the middle-end's sense). We cannot allow it if the + types don't have the same precision in the Ada sense as well. */ + if (TREE_CODE (expr) != NOP_EXPR) + return true; + + t1 = TREE_TYPE (expr); + t2 = TREE_TYPE (TREE_OPERAND (expr, 0)); + + /* Defer to the folder for non-integral conversions. */ + if (!(INTEGRAL_TYPE_P (t1) && INTEGRAL_TYPE_P (t2))) + return true; + + /* Only fold conversions that preserve both precisions. */ + if (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && operand_equal_p (rm_size (t1), rm_size (t2), 0)) + return true; + + return false; +} + /* Return an expression that does an unchecked conversion of EXPR to TYPE. - If NOTRUNC_P is true, truncation operations should be suppressed. */ + If NOTRUNC_P is true, truncation operations should be suppressed. + + Special care is required with (source or target) integral types whose + precision is not equal to their size, to make sure we fetch or assign + the value bits whose location might depend on the endianness, e.g. + + Rmsize : constant := 8; + subtype Int is Integer range 0 .. 2 ** Rmsize - 1; + + type Bit_Array is array (1 .. Rmsize) of Boolean; + pragma Pack (Bit_Array); + + function To_Bit_Array is new Unchecked_Conversion (Int, Bit_Array); + + Value : Int := 2#1000_0001#; + Vbits : Bit_Array := To_Bit_Array (Value); + + we expect the 8 bits at Vbits'Address to always contain Value, while + their original location depends on the endianness, at Value'Address + on a little-endian architecture but not on a big-endian one. + + ??? There is a problematic discrepancy between what is called precision + here (and more generally throughout gigi) for integral types and what is + called precision in the middle-end. In the former case it's the RM size + as given by TYPE_RM_SIZE (or rm_size) whereas it's TYPE_PRECISION in the + latter case, the hitch being that they are not equal when they matter, + that is when the number of value bits is not equal to the type's size: + TYPE_RM_SIZE does give the number of value bits but TYPE_PRECISION is set + to the size. The sole exception are BOOLEAN_TYPEs for which both are 1. + + The consequence is that gigi must duplicate code bridging the gap between + the type's size and its precision that exists for TYPE_PRECISION in the + middle-end, because the latter knows nothing about TYPE_RM_SIZE, and be + wary of transformations applied in the middle-end based on TYPE_PRECISION + because this value doesn't reflect the actual precision for Ada. */ tree unchecked_convert (tree type, tree expr, bool notrunc_p) @@ -3852,14 +3916,10 @@ && TYPE_JUSTIFIED_MODULAR_P (etype)))) || TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE) { - tree rtype = type; - bool final_unchecked = false; - if (TREE_CODE (etype) == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (etype)) { tree ntype = copy_type (etype); - TYPE_BIASED_REPRESENTATION_P (ntype) = 0; TYPE_MAIN_VARIANT (ntype) = ntype; expr = build1 (NOP_EXPR, ntype, expr); @@ -3868,15 +3928,18 @@ if (TREE_CODE (type) == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (type)) { - rtype = copy_type (type); + tree rtype = copy_type (type); TYPE_BIASED_REPRESENTATION_P (rtype) = 0; TYPE_MAIN_VARIANT (rtype) = rtype; + expr = convert (rtype, expr); + expr = build1 (NOP_EXPR, type, expr); } - /* We have another special case: if we are unchecked converting subtype - into a base type, we need to ensure that VRP doesn't propagate range - information since this conversion may be done precisely to validate - that the object is within the range it is supposed to have. */ + /* We have another special case: if we are unchecked converting either + a subtype or a type with limited range into a base type, we need to + ensure that VRP doesn't propagate range information because this + conversion may be done precisely to validate that the object is + within the range it is supposed to have. */ else if (TREE_CODE (expr) != INTEGER_CST && TREE_CODE (type) == INTEGER_TYPE && !TREE_TYPE (type) && ((TREE_CODE (etype) == INTEGER_TYPE && TREE_TYPE (etype)) @@ -3887,26 +3950,34 @@ in order not to be deemed an useless type conversion, it must be from subtype to base type. + Therefore we first do the bulk of the conversion to a subtype of + the final type. And this conversion must itself not be deemed + useless if the source type is not a subtype because, otherwise, + the final VIEW_CONVERT_EXPR will be deemed so as well. That's + why we toggle the unsigned flag in this conversion, which is + harmless since the final conversion is only a reinterpretation + of the bit pattern. + ??? This may raise addressability and/or aliasing issues because VIEW_CONVERT_EXPR gets gimplified as an lvalue, thus causing the address of its operand to be taken if it is deemed addressable and not already in GIMPLE form. */ - rtype = gnat_type_for_mode (TYPE_MODE (type), TYPE_UNSIGNED (type)); + tree rtype + = gnat_type_for_mode (TYPE_MODE (type), !TYPE_UNSIGNED (etype)); rtype = copy_type (rtype); TYPE_MAIN_VARIANT (rtype) = rtype; TREE_TYPE (rtype) = type; - final_unchecked = true; + expr = convert (rtype, expr); + expr = build1 (VIEW_CONVERT_EXPR, type, expr); } - expr = convert (rtype, expr); - if (type != rtype) - expr = fold_build1 (final_unchecked ? VIEW_CONVERT_EXPR : NOP_EXPR, - type, expr); + else + expr = convert (type, expr); } - /* If we are converting TO an integral type whose precision is not the - same as its size, first unchecked convert to a record that contains - an object of the output type. Then extract the field. */ + /* If we are converting to an integral type whose precision is not equal + to its size, first unchecked convert to a record that contains an + object of the output type. Then extract the field. */ else if (INTEGRAL_TYPE_P (type) && TYPE_RM_SIZE (type) && 0 != compare_tree_int (TYPE_RM_SIZE (type), GET_MODE_BITSIZE (TYPE_MODE (type)))) @@ -3922,8 +3993,8 @@ expr = build_component_ref (expr, NULL_TREE, field, 0); } - /* Similarly for integral input type whose precision is not equal to its - size. */ + /* Similarly if we are converting from an integral type whose precision + is not equal to its size. */ else if (INTEGRAL_TYPE_P (etype) && TYPE_RM_SIZE (etype) && 0 != compare_tree_int (TYPE_RM_SIZE (etype), GET_MODE_BITSIZE (TYPE_MODE (etype)))) @@ -3953,13 +4024,15 @@ { expr = maybe_unconstrained_array (expr); etype = TREE_TYPE (expr); - expr = fold_build1 (VIEW_CONVERT_EXPR, type, expr); + if (can_fold_for_view_convert_p (expr)) + expr = fold_build1 (VIEW_CONVERT_EXPR, type, expr); + else + expr = build1 (VIEW_CONVERT_EXPR, type, expr); } - /* If the result is an integral type whose size is not equal to - the size of the underlying machine type, sign- or zero-extend - the result. We need not do this in the case where the input is - an integral type of the same precision and signedness or if the output + /* If the result is an integral type whose precision is not equal to its + size, sign- or zero-extend the result. We need not do this if the input + is an integral type of the same precision and signedness or if the output is a biased type or if both the input and output are unsigned. */ if (!notrunc_p && INTEGRAL_TYPE_P (type) && TYPE_RM_SIZE (type) diff -Naur gcc-4.3.2.orig/gcc/c-common.c gcc-4.3.2/gcc/c-common.c --- gcc-4.3.2.orig/gcc/c-common.c 2008-07-15 08:52:35.000000000 -0700 +++ gcc-4.3.2/gcc/c-common.c 2008-11-12 14:08:01.000000000 -0800 @@ -2232,53 +2232,77 @@ if (type1 == intQI_type_node || type1 == unsigned_intQI_type_node) return unsignedp ? unsigned_intQI_type_node : intQI_type_node; -#define C_COMMON_FIXED_TYPES(SAT,NAME) \ - if (type1 == SAT ## short_ ## NAME ## _type_node \ - || type1 == SAT ## unsigned_short_ ## NAME ## _type_node) \ - return unsignedp ? SAT ## unsigned_short_ ## NAME ## _type_node \ - : SAT ## short_ ## NAME ## _type_node; \ - if (type1 == SAT ## NAME ## _type_node \ - || type1 == SAT ## unsigned_ ## NAME ## _type_node) \ - return unsignedp ? SAT ## unsigned_ ## NAME ## _type_node \ - : SAT ## NAME ## _type_node; \ - if (type1 == SAT ## long_ ## NAME ## _type_node \ - || type1 == SAT ## unsigned_long_ ## NAME ## _type_node) \ - return unsignedp ? SAT ## unsigned_long_ ## NAME ## _type_node \ - : SAT ## long_ ## NAME ## _type_node; \ - if (type1 == SAT ## long_long_ ## NAME ## _type_node \ - || type1 == SAT ## unsigned_long_long_ ## NAME ## _type_node) \ - return unsignedp ? SAT ## unsigned_long_long_ ## NAME ## _type_node \ - : SAT ## long_long_ ## NAME ## _type_node; - -#define C_COMMON_FIXED_MODE_TYPES(SAT,NAME) \ - if (type1 == SAT ## NAME ## _type_node \ - || type1 == SAT ## u ## NAME ## _type_node) \ - return unsignedp ? SAT ## u ## NAME ## _type_node \ - : SAT ## NAME ## _type_node; - - C_COMMON_FIXED_TYPES (, fract); - C_COMMON_FIXED_TYPES (sat_, fract); - C_COMMON_FIXED_TYPES (, accum); - C_COMMON_FIXED_TYPES (sat_, accum); - - C_COMMON_FIXED_MODE_TYPES (, qq); - C_COMMON_FIXED_MODE_TYPES (, hq); - C_COMMON_FIXED_MODE_TYPES (, sq); - C_COMMON_FIXED_MODE_TYPES (, dq); - C_COMMON_FIXED_MODE_TYPES (, tq); - C_COMMON_FIXED_MODE_TYPES (sat_, qq); - C_COMMON_FIXED_MODE_TYPES (sat_, hq); - C_COMMON_FIXED_MODE_TYPES (sat_, sq); - C_COMMON_FIXED_MODE_TYPES (sat_, dq); - C_COMMON_FIXED_MODE_TYPES (sat_, tq); - C_COMMON_FIXED_MODE_TYPES (, ha); - C_COMMON_FIXED_MODE_TYPES (, sa); - C_COMMON_FIXED_MODE_TYPES (, da); - C_COMMON_FIXED_MODE_TYPES (, ta); - C_COMMON_FIXED_MODE_TYPES (sat_, ha); - C_COMMON_FIXED_MODE_TYPES (sat_, sa); - C_COMMON_FIXED_MODE_TYPES (sat_, da); - C_COMMON_FIXED_MODE_TYPES (sat_, ta); +#define C_COMMON_FIXED_TYPES(NAME) \ + if (type1 == short_ ## NAME ## _type_node \ + || type1 == unsigned_short_ ## NAME ## _type_node) \ + return unsignedp ? unsigned_short_ ## NAME ## _type_node \ + : short_ ## NAME ## _type_node; \ + if (type1 == NAME ## _type_node \ + || type1 == unsigned_ ## NAME ## _type_node) \ + return unsignedp ? unsigned_ ## NAME ## _type_node \ + : NAME ## _type_node; \ + if (type1 == long_ ## NAME ## _type_node \ + || type1 == unsigned_long_ ## NAME ## _type_node) \ + return unsignedp ? unsigned_long_ ## NAME ## _type_node \ + : long_ ## NAME ## _type_node; \ + if (type1 == long_long_ ## NAME ## _type_node \ + || type1 == unsigned_long_long_ ## NAME ## _type_node) \ + return unsignedp ? unsigned_long_long_ ## NAME ## _type_node \ + : long_long_ ## NAME ## _type_node; + +#define C_COMMON_FIXED_MODE_TYPES(NAME) \ + if (type1 == NAME ## _type_node \ + || type1 == u ## NAME ## _type_node) \ + return unsignedp ? u ## NAME ## _type_node \ + : NAME ## _type_node; + +#define C_COMMON_FIXED_TYPES_SAT(NAME) \ + if (type1 == sat_ ## short_ ## NAME ## _type_node \ + || type1 == sat_ ## unsigned_short_ ## NAME ## _type_node) \ + return unsignedp ? sat_ ## unsigned_short_ ## NAME ## _type_node \ + : sat_ ## short_ ## NAME ## _type_node; \ + if (type1 == sat_ ## NAME ## _type_node \ + || type1 == sat_ ## unsigned_ ## NAME ## _type_node) \ + return unsignedp ? sat_ ## unsigned_ ## NAME ## _type_node \ + : sat_ ## NAME ## _type_node; \ + if (type1 == sat_ ## long_ ## NAME ## _type_node \ + || type1 == sat_ ## unsigned_long_ ## NAME ## _type_node) \ + return unsignedp ? sat_ ## unsigned_long_ ## NAME ## _type_node \ + : sat_ ## long_ ## NAME ## _type_node; \ + if (type1 == sat_ ## long_long_ ## NAME ## _type_node \ + || type1 == sat_ ## unsigned_long_long_ ## NAME ## _type_node) \ + return unsignedp ? sat_ ## unsigned_long_long_ ## NAME ## _type_node \ + : sat_ ## long_long_ ## NAME ## _type_node; + +#define C_COMMON_FIXED_MODE_TYPES_SAT(NAME) \ + if (type1 == sat_ ## NAME ## _type_node \ + || type1 == sat_ ## u ## NAME ## _type_node) \ + return unsignedp ? sat_ ## u ## NAME ## _type_node \ + : sat_ ## NAME ## _type_node; + + C_COMMON_FIXED_TYPES (fract); + C_COMMON_FIXED_TYPES_SAT (fract); + C_COMMON_FIXED_TYPES (accum); + C_COMMON_FIXED_TYPES_SAT (accum); + + C_COMMON_FIXED_MODE_TYPES (qq); + C_COMMON_FIXED_MODE_TYPES (hq); + C_COMMON_FIXED_MODE_TYPES (sq); + C_COMMON_FIXED_MODE_TYPES (dq); + C_COMMON_FIXED_MODE_TYPES (tq); + C_COMMON_FIXED_MODE_TYPES_SAT (qq); + C_COMMON_FIXED_MODE_TYPES_SAT (hq); + C_COMMON_FIXED_MODE_TYPES_SAT (sq); + C_COMMON_FIXED_MODE_TYPES_SAT (dq); + C_COMMON_FIXED_MODE_TYPES_SAT (tq); + C_COMMON_FIXED_MODE_TYPES (ha); + C_COMMON_FIXED_MODE_TYPES (sa); + C_COMMON_FIXED_MODE_TYPES (da); + C_COMMON_FIXED_MODE_TYPES (ta); + C_COMMON_FIXED_MODE_TYPES_SAT (ha); + C_COMMON_FIXED_MODE_TYPES_SAT (sa); + C_COMMON_FIXED_MODE_TYPES_SAT (da); + C_COMMON_FIXED_MODE_TYPES_SAT (ta); /* For ENUMERAL_TYPEs in C++, must check the mode of the types, not the precision; they have precision set to match their range, but @@ -2295,7 +2319,7 @@ #define TYPE_OK(node) \ (TYPE_MODE (type) == TYPE_MODE (node) \ - && (c_dialect_cxx () || TYPE_PRECISION (type) == TYPE_PRECISION (node))) + && TYPE_PRECISION (type) == TYPE_PRECISION (node)) if (TYPE_OK (signed_char_type_node)) return unsignedp ? unsigned_char_type_node : signed_char_type_node; if (TYPE_OK (integer_type_node)) @@ -2325,10 +2349,7 @@ return unsignedp ? unsigned_intQI_type_node : intQI_type_node; #undef TYPE_OK - if (c_dialect_cxx ()) - return type; - else - return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp); + return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp); } /* Build a bit-field integer type for the given WIDTH and UNSIGNEDP. */ @@ -5577,7 +5598,9 @@ /* We must ignore the attribute when it is associated with local-scoped decls, since attribute alias is ignored and many such symbols do not even have a DECL_WEAK field. */ - if (decl_function_context (*node) || current_function_decl) + if (decl_function_context (*node) + || current_function_decl + || (TREE_CODE (*node) != VAR_DECL && TREE_CODE (*node) != FUNCTION_DECL)) { warning (OPT_Wattributes, "%qE attribute ignored", name); *no_add_attrs = true; diff -Naur gcc-4.3.2.orig/gcc/cgraph.c gcc-4.3.2/gcc/cgraph.c --- gcc-4.3.2.orig/gcc/cgraph.c 2008-01-29 15:21:24.000000000 -0800 +++ gcc-4.3.2/gcc/cgraph.c 2008-11-14 05:26:59.000000000 -0800 @@ -540,7 +540,11 @@ } DECL_SAVED_TREE (node->decl) = NULL; DECL_STRUCT_FUNCTION (node->decl) = NULL; - DECL_INITIAL (node->decl) = error_mark_node; + /* If the node is abstract and needed, then do not clear DECL_INITIAL + of its associated function function declaration because it's + needed to emit debug info later. */ + if (!node->abstract_and_needed) + DECL_INITIAL (node->decl) = error_mark_node; } /* Remove the node from cgraph. */ diff -Naur gcc-4.3.2.orig/gcc/cgraph.h gcc-4.3.2/gcc/cgraph.h --- gcc-4.3.2.orig/gcc/cgraph.h 2008-01-29 15:21:24.000000000 -0800 +++ gcc-4.3.2/gcc/cgraph.h 2008-11-14 05:26:59.000000000 -0800 @@ -163,6 +163,9 @@ /* Set when function must be output - it is externally visible or its address is taken. */ unsigned needed : 1; + /* Set when decl is an abstract function pointed to by the + ABSTRACT_DECL_ORIGIN of a reachable function. */ + unsigned abstract_and_needed : 1; /* Set when function is reachable by call from other function that is either reachable or needed. */ unsigned reachable : 1; diff -Naur gcc-4.3.2.orig/gcc/cgraphunit.c gcc-4.3.2/gcc/cgraphunit.c --- gcc-4.3.2.orig/gcc/cgraphunit.c 2008-01-29 15:21:24.000000000 -0800 +++ gcc-4.3.2/gcc/cgraphunit.c 2008-11-14 05:26:59.000000000 -0800 @@ -1008,6 +1008,15 @@ if (!edge->callee->reachable) cgraph_mark_reachable_node (edge->callee); + /* If decl is a clone of an abstract function, mark that abstract + function so that we don't release its body. The DECL_INITIAL() of that + abstract function declaration will be later needed to output debug info. */ + if (DECL_ABSTRACT_ORIGIN (decl)) + { + struct cgraph_node *origin_node = cgraph_node (DECL_ABSTRACT_ORIGIN (decl)); + origin_node->abstract_and_needed = true; + } + /* We finalize local static variables during constructing callgraph edges. Process their attributes too. */ process_function_and_variable_attributes (first_processed, diff -Naur gcc-4.3.2.orig/gcc/collect2.c gcc-4.3.2/gcc/collect2.c --- gcc-4.3.2.orig/gcc/collect2.c 2007-12-31 07:02:59.000000000 -0800 +++ gcc-4.3.2/gcc/collect2.c 2008-12-14 14:30:32.000000000 -0800 @@ -2043,14 +2043,12 @@ static void write_c_file (FILE *stream, const char *name) { - fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); #ifndef LD_INIT_SWITCH if (! shared_obj) write_c_file_glob (stream, name); else #endif write_c_file_stat (stream, name); - fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n"); } #ifdef COLLECT_EXPORT_LIST diff -Naur gcc-4.3.2.orig/gcc/combine.c gcc-4.3.2/gcc/combine.c --- gcc-4.3.2.orig/gcc/combine.c 2008-05-19 16:29:29.000000000 -0700 +++ gcc-4.3.2/gcc/combine.c 2008-11-10 02:43:35.000000000 -0800 @@ -7024,7 +7024,8 @@ if (GET_CODE (rhs) == CONST_INT && GET_CODE (lhs) == ASHIFT && GET_CODE (XEXP (lhs, 1)) == CONST_INT - && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1))) + && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1)) + && INTVAL (rhs) < mode_width) { new = make_compound_operation (XEXP (lhs, 0), next_code); new = make_extraction (mode, new, @@ -7044,6 +7045,7 @@ && (OBJECT_P (SUBREG_REG (lhs)))) && GET_CODE (rhs) == CONST_INT && INTVAL (rhs) < HOST_BITS_PER_WIDE_INT + && INTVAL (rhs) < mode_width && (new = extract_left_shift (lhs, INTVAL (rhs))) != 0) new = make_extraction (mode, make_compound_operation (new, next_code), 0, NULL_RTX, mode_width - INTVAL (rhs), @@ -7343,6 +7345,10 @@ && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0) return gen_lowpart (mode, x); + /* The arithmetic simplifications here do the wrong thing on vector modes. */ + if (VECTOR_MODE_P (mode) || VECTOR_MODE_P (GET_MODE (x))) + return gen_lowpart (mode, x); + switch (code) { case CLOBBER: @@ -9023,11 +9029,6 @@ if (GET_CODE (varop) == CLOBBER) return NULL_RTX; - /* If we discovered we had to complement VAROP, leave. Making a NOT - here would cause an infinite loop. */ - if (complement_p) - break; - /* Convert ROTATERT to ROTATE. */ if (code == ROTATERT) { @@ -9073,6 +9074,11 @@ } } + /* If we discovered we had to complement VAROP, leave. Making a NOT + here would cause an infinite loop. */ + if (complement_p) + break; + /* An arithmetic right shift of a quantity known to be -1 or 0 is a no-op. */ if (code == ASHIFTRT diff -Naur gcc-4.3.2.orig/gcc/config/alpha/alpha.c gcc-4.3.2/gcc/config/alpha/alpha.c --- gcc-4.3.2.orig/gcc/config/alpha/alpha.c 2008-02-07 09:45:24.000000000 -0800 +++ gcc-4.3.2/gcc/config/alpha/alpha.c 2008-09-08 16:16:55.000000000 -0700 @@ -4599,8 +4599,6 @@ enum machine_mode mode = GET_MODE (mem); rtx label, x, cond = gen_lowpart (DImode, scratch); - emit_insn (gen_memory_barrier ()); - label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); emit_label (XEXP (label, 0)); @@ -4610,6 +4608,8 @@ x = gen_rtx_EQ (DImode, cond, const0_rtx); emit_unlikely_jump (x, label); + + emit_insn (gen_memory_barrier ()); } void @@ -4648,7 +4648,6 @@ mem = gen_rtx_MEM (DImode, align); MEM_VOLATILE_P (mem) = 1; - emit_insn (gen_memory_barrier ()); label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); emit_label (XEXP (label, 0)); @@ -4672,6 +4671,8 @@ x = gen_rtx_EQ (DImode, scratch, const0_rtx); emit_unlikely_jump (x, label); + + emit_insn (gen_memory_barrier ()); } /* Adjust the cost of a scheduling dependency. Return the new cost of diff -Naur gcc-4.3.2.orig/gcc/config/avr/avr.md gcc-4.3.2/gcc/config/avr/avr.md --- gcc-4.3.2.orig/gcc/config/avr/avr.md 2008-06-07 08:48:25.000000000 -0700 +++ gcc-4.3.2/gcc/config/avr/avr.md 2008-09-12 10:29:38.000000000 -0700 @@ -306,10 +306,11 @@ -(define_peephole2 +(define_peephole2 ; movsi_lreg_const [(match_scratch:QI 2 "d") (set (match_operand:SI 0 "l_register_operand" "") - (match_operand:SI 1 "immediate_operand" ""))] + (match_operand:SI 1 "immediate_operand" "")) + (match_dup 2)] "(operands[1] != const0_rtx && operands[1] != constm1_rtx)" [(parallel [(set (match_dup 0) (match_dup 1)) diff -Naur gcc-4.3.2.orig/gcc/config/cris/cris.c gcc-4.3.2/gcc/config/cris/cris.c --- gcc-4.3.2.orig/gcc/config/cris/cris.c 2008-05-11 16:52:49.000000000 -0700 +++ gcc-4.3.2/gcc/config/cris/cris.c 2008-11-05 10:10:36.000000000 -0800 @@ -1795,6 +1795,21 @@ return true; case MULT: + /* If we have one arm of an ADDI, make sure it gets the cost of + one insn, i.e. zero cost for this operand, and just the cost + of the PLUS, as the insn is created by combine from a PLUS + and an ASHIFT, and the MULT cost below would make the + combined value be larger than the separate insns. The insn + validity is checked elsewhere by combine. + + FIXME: this case is a stop-gap for 4.3 and 4.4, this whole + function should be rewritten. */ + if (outer_code == PLUS && BIAP_INDEX_P (x)) + { + *total = 0; + return true; + } + /* Identify values that are no powers of two. Powers of 2 are taken care of already and those values should not be changed. */ if (!CONST_INT_P (XEXP (x, 1)) @@ -3548,14 +3563,15 @@ } /* Make sure operands are in the right order for an addsi3 insn as - generated by a define_split. A MEM as the first operand isn't - recognized by addsi3 after reload. OPERANDS contains the operands, - with the first at OPERANDS[N] and the second at OPERANDS[N+1]. */ + generated by a define_split. Nothing but REG_P as the first + operand is recognized by addsi3 after reload. OPERANDS contains + the operands, with the first at OPERANDS[N] and the second at + OPERANDS[N+1]. */ void cris_order_for_addsi3 (rtx *operands, int n) { - if (MEM_P (operands[n])) + if (!REG_P (operands[n])) { rtx tem = operands[n]; operands[n] = operands[n + 1]; diff -Naur gcc-4.3.2.orig/gcc/config/freebsd.h gcc-4.3.2/gcc/config/freebsd.h --- gcc-4.3.2.orig/gcc/config/freebsd.h 2007-08-02 03:49:31.000000000 -0700 +++ gcc-4.3.2/gcc/config/freebsd.h 2008-10-04 11:39:49.000000000 -0700 @@ -55,6 +55,8 @@ #undef LIB_SPEC #define LIB_SPEC FBSD_LIB_SPEC +/* Define this so we can compile MS code for use with WINE. */ +#define HANDLE_PRAGMA_PACK_PUSH_POP 1 /************************[ Target stuff ]***********************************/ diff -Naur gcc-4.3.2.orig/gcc/config/i386/i386.c gcc-4.3.2/gcc/config/i386/i386.c --- gcc-4.3.2.orig/gcc/config/i386/i386.c 2008-05-21 01:54:15.000000000 -0700 +++ gcc-4.3.2/gcc/config/i386/i386.c 2008-08-28 06:31:33.000000000 -0700 @@ -11332,6 +11332,10 @@ if (req_mode == CCZmode) return 0; /* FALLTHRU */ + case CCAmode: + case CCCmode: + case CCOmode: + case CCSmode: case CCZmode: break; diff -Naur gcc-4.3.2.orig/gcc/config/i386/i386.md gcc-4.3.2/gcc/config/i386/i386.md --- gcc-4.3.2.orig/gcc/config/i386/i386.md 2008-06-24 02:36:12.000000000 -0700 +++ gcc-4.3.2/gcc/config/i386/i386.md 2008-08-28 06:31:33.000000000 -0700 @@ -15210,7 +15210,7 @@ (define_insn "clzsi2_abm" [(set (match_operand:SI 0 "register_operand" "=r") - (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))) + (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] "TARGET_ABM" "lzcnt{l}\t{%1, %0|%0, %1}" @@ -15230,7 +15230,7 @@ (define_insn "popcountsi2" [(set (match_operand:SI 0 "register_operand" "=r") - (popcount:SI (match_operand:SI 1 "nonimmediate_operand" ""))) + (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] "TARGET_POPCNT" "popcnt{l}\t{%1, %0|%0, %1}" @@ -15337,7 +15337,7 @@ (define_insn "clzdi2_abm" [(set (match_operand:DI 0 "register_operand" "=r") - (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))) + (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && TARGET_ABM" "lzcnt{q}\t{%1, %0|%0, %1}" @@ -15357,7 +15357,7 @@ (define_insn "popcountdi2" [(set (match_operand:DI 0 "register_operand" "=r") - (popcount:DI (match_operand:DI 1 "nonimmediate_operand" ""))) + (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && TARGET_POPCNT" "popcnt{q}\t{%1, %0|%0, %1}" @@ -15398,7 +15398,7 @@ (define_insn "clzhi2_abm" [(set (match_operand:HI 0 "register_operand" "=r") - (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))) + (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] "TARGET_ABM" "lzcnt{w}\t{%1, %0|%0, %1}" @@ -15418,7 +15418,7 @@ (define_insn "popcounthi2" [(set (match_operand:HI 0 "register_operand" "=r") - (popcount:HI (match_operand:HI 1 "nonimmediate_operand" ""))) + (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] "TARGET_POPCNT" "popcnt{w}\t{%1, %0|%0, %1}" diff -Naur gcc-4.3.2.orig/gcc/config/i386/mmx.md gcc-4.3.2/gcc/config/i386/mmx.md --- gcc-4.3.2.orig/gcc/config/i386/mmx.md 2007-10-24 22:41:37.000000000 -0700 +++ gcc-4.3.2/gcc/config/i386/mmx.md 2008-08-28 06:31:33.000000000 -0700 @@ -485,10 +485,12 @@ DONE; }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn_and_split "*vec_extractv2sf_0" - [(set (match_operand:SF 0 "nonimmediate_operand" "=x,y,m,m,frxy") + [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r") (vec_select:SF - (match_operand:V2SF 1 "nonimmediate_operand" " x,y,x,y,m") + (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m") (parallel [(const_int 0)])))] "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "#" @@ -504,18 +506,23 @@ DONE; }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "*vec_extractv2sf_1" - [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,frxy") + [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,y,x,f,r") (vec_select:SF - (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o") + (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o") (parallel [(const_int 1)])))] "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ punpckhdq\t%0, %0 unpckhps\t%0, %0 + # + # + # #" - [(set_attr "type" "mmxcvt,sselog1,*") - (set_attr "mode" "DI,V4SF,SI")]) + [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov") + (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")]) (define_split [(set (match_operand:SF 0 "register_operand" "") @@ -1151,10 +1158,12 @@ DONE; }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn_and_split "*vec_extractv2si_0" - [(set (match_operand:SI 0 "nonimmediate_operand" "=x,y,m,m,frxy") + [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r") (vec_select:SI - (match_operand:V2SI 1 "nonimmediate_operand" " x,y,x,y,m") + (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m") (parallel [(const_int 0)])))] "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "#" @@ -1170,10 +1179,12 @@ DONE; }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "*vec_extractv2si_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=y,Y2,Y2,x,frxy") + [(set (match_operand:SI 0 "nonimmediate_operand" "=y,Y2,Y2,x,y,x,r") (vec_select:SI - (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Y2,0,o") + (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Y2,0,o,o,o") (parallel [(const_int 1)])))] "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ @@ -1181,9 +1192,11 @@ punpckhdq\t%0, %0 pshufd\t{$85, %1, %0|%0, %1, 85} unpckhps\t%0, %0 + # + # #" - [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,*") - (set_attr "mode" "DI,TI,TI,V4SF,SI")]) + [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov") + (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")]) (define_split [(set (match_operand:SI 0 "register_operand" "") diff -Naur gcc-4.3.2.orig/gcc/config/i386/sse.md gcc-4.3.2/gcc/config/i386/sse.md --- gcc-4.3.2.orig/gcc/config/i386/sse.md 2008-08-17 07:57:00.000000000 -0700 +++ gcc-4.3.2/gcc/config/i386/sse.md 2008-12-01 04:28:05.000000000 -0800 @@ -1521,10 +1521,12 @@ DONE; }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn_and_split "*vec_extractv4sf_0" - [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,fr") + [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,f,r") (vec_select:SF - (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m") + (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m,m") (parallel [(const_int 0)])))] "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "#" @@ -3140,18 +3142,22 @@ [(set_attr "type" "sselog") (set_attr "mode" "V2DF")]) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "sse2_storehpd" - [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x*fr") + [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x,*f,r") (vec_select:DF - (match_operand:V2DF 1 "nonimmediate_operand" " x,0,o") + (match_operand:V2DF 1 "nonimmediate_operand" " x,0,o,o,o") (parallel [(const_int 1)])))] "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ movhpd\t{%1, %0|%0, %1} unpckhpd\t%0, %0 + # + # #" - [(set_attr "type" "ssemov,sselog1,ssemov") - (set_attr "mode" "V1DF,V2DF,DF")]) + [(set_attr "type" "ssemov,sselog1,ssemov,fmov,imov") + (set_attr "mode" "V1DF,V2DF,DF,DF,DF")]) (define_split [(set (match_operand:DF 0 "register_operand" "") @@ -3164,18 +3170,22 @@ operands[1] = adjust_address (operands[1], DFmode, 8); }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "sse2_storelpd" - [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x*fr") + [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x,*f,r") (vec_select:DF - (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m") + (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m,m,m") (parallel [(const_int 0)])))] "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ movlpd\t{%1, %0|%0, %1} # + # + # #" - [(set_attr "type" "ssemov") - (set_attr "mode" "V1DF,DF,DF")]) + [(set_attr "type" "ssemov,ssemov,ssemov,fmov,imov") + (set_attr "mode" "V1DF,DF,DF,DF,DF")]) (define_split [(set (match_operand:DF 0 "register_operand" "") @@ -3194,21 +3204,25 @@ DONE; }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "sse2_loadhpd" - [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,o") + [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,o,o,o") (vec_concat:V2DF (vec_select:DF - (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,x,0") + (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,x,0,0,0") (parallel [(const_int 0)])) - (match_operand:DF 2 "nonimmediate_operand" " m,x,0,x*fr")))] + (match_operand:DF 2 "nonimmediate_operand" " m,x,0,x,*f,r")))] "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" "@ movhpd\t{%2, %0|%0, %2} unpcklpd\t{%2, %0|%0, %2} shufpd\t{$1, %1, %0|%0, %1, 1} + # + # #" - [(set_attr "type" "ssemov,sselog,sselog,other") - (set_attr "mode" "V1DF,V2DF,V2DF,DF")]) + [(set_attr "type" "ssemov,sselog,sselog,ssemov,fmov,imov") + (set_attr "mode" "V1DF,V2DF,V2DF,DF,DF,DF")]) (define_split [(set (match_operand:V2DF 0 "memory_operand" "") @@ -3221,12 +3235,14 @@ operands[0] = adjust_address (operands[0], DFmode, 8); }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "sse2_loadlpd" - [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,x,x,m") + [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,x,x,m,m,m") (vec_concat:V2DF - (match_operand:DF 2 "nonimmediate_operand" " m,m,x,0,0,x*fr") + (match_operand:DF 2 "nonimmediate_operand" " m,m,x,0,0,x,*f,r") (vec_select:DF - (match_operand:V2DF 1 "vector_move_operand" " C,0,0,x,o,0") + (match_operand:V2DF 1 "vector_move_operand" " C,0,0,x,o,0,0,0") (parallel [(const_int 1)]))))] "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" "@ @@ -3235,9 +3251,11 @@ movsd\t{%2, %0|%0, %2} shufpd\t{$2, %2, %0|%0, %2, 2} movhpd\t{%H1, %0|%0, %H1} + # + # #" - [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,other") - (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF")]) + [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov,fmov,imov") + (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF,DF,DF")]) (define_split [(set (match_operand:V2DF 0 "memory_operand" "") @@ -5923,7 +5941,7 @@ (define_insn "*sse2_mfence" [(set (match_operand:BLK 0 "" "") (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))] - "TARGET_SSE2" + "TARGET_64BIT || TARGET_SSE2" "mfence" [(set_attr "type" "sse") (set_attr "memory" "unknown")]) diff -Naur gcc-4.3.2.orig/gcc/config/i386/sync.md gcc-4.3.2/gcc/config/i386/sync.md --- gcc-4.3.2.orig/gcc/config/i386/sync.md 2007-09-19 14:41:08.000000000 -0700 +++ gcc-4.3.2/gcc/config/i386/sync.md 2008-12-01 04:28:05.000000000 -0800 @@ -31,6 +31,29 @@ (define_mode_attr doublemodesuffix [(DI "8") (TI "16")]) (define_mode_attr DCASHMODE [(DI "SI") (TI "DI")]) +(define_expand "memory_barrier" + [(set (match_dup 0) + (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))] + "" +{ + operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[0]) = 1; + + if (!(TARGET_64BIT || TARGET_SSE2)) + { + emit_insn (gen_memory_barrier_nosse (operands[0])); + DONE; + } +}) + +(define_insn "memory_barrier_nosse" + [(set (match_operand:BLK 0 "" "") + (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE)) + (clobber (reg:CC FLAGS_REG))] + "!(TARGET_64BIT || TARGET_SSE2)" + "lock{%;| }or{l}\t{$0, (%%esp)|DWORD PTR [esp], 0}" + [(set_attr "memory" "unknown")]) + ;; ??? It would be possible to use cmpxchg8b on pentium for DImode ;; changes. It's complicated because the insn uses ecx:ebx as the ;; new value; note that the registers are reversed from the order @@ -81,7 +104,7 @@ UNSPECV_CMPXCHG_1)) (clobber (reg:CC FLAGS_REG))] "TARGET_CMPXCHG" - "lock{%;| } cmpxchg{}\t{%3, %1|%1, %3}") + "lock{%;| }cmpxchg{}\t{%3, %1|%1, %3}") (define_insn "sync_double_compare_and_swap" [(set (match_operand:DCASMODE 0 "register_operand" "=A") diff -Naur gcc-4.3.2.orig/gcc/config/i386/t-sol2 gcc-4.3.2/gcc/config/i386/t-sol2 --- gcc-4.3.2.orig/gcc/config/i386/t-sol2 2004-11-17 17:07:18.000000000 -0800 +++ gcc-4.3.2/gcc/config/i386/t-sol2 1969-12-31 16:00:00.000000000 -0800 @@ -1,34 +0,0 @@ -# gmon build rule: -$(T)gmon.o: $(srcdir)/config/i386/gmon-sol2.c $(GCC_PASSES) $(CONFIG_H) - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) \ - -c $(srcdir)/config/i386/gmon-sol2.c -o $(T)gmon.o - -# Assemble startup files. -# Apparently Sun believes that assembler files don't need comments, because no -# single ASCII character is valid (tried them all). So we manually strip out -# the comments with sed. This bug may only be in the Early Access releases. -$(T)gcrt1.o: $(srcdir)/config/i386/sol2-gc1.asm $(GCC_PASSES) - sed -e '/^!/d' <$(srcdir)/config/i386/sol2-gc1.asm >gcrt1.s - $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)gcrt1.o gcrt1.s -$(T)crt1.o: $(srcdir)/config/i386/sol2-c1.asm $(GCC_PASSES) - sed -e '/^!/d' <$(srcdir)/config/i386/sol2-c1.asm >crt1.s - $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crt1.o crt1.s -$(T)crti.o: $(srcdir)/config/i386/sol2-ci.asm $(GCC_PASSES) - sed -e '/^!/d' <$(srcdir)/config/i386/sol2-ci.asm >crti.s - $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crti.o crti.s -$(T)crtn.o: $(srcdir)/config/i386/sol2-cn.asm $(GCC_PASSES) - sed -e '/^!/d' <$(srcdir)/config/i386/sol2-cn.asm >crtn.s - $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crtn.o crtn.s - -# We need to use -fPIC when we are using gcc to compile the routines in -# crtstuff.c. This is only really needed when we are going to use gcc/g++ -# to produce a shared library, but since we don't know ahead of time when -# we will be doing that, we just always use -fPIC when compiling the -# routines in crtstuff.c. -# -# We must also enable optimization to avoid having any code appear after -# the call & alignment statement, but before we switch back to the -# .text section. - -CRTSTUFF_T_CFLAGS = -fPIC -O2 -TARGET_LIBGCC2_CFLAGS = -fPIC diff -Naur gcc-4.3.2.orig/gcc/config/i386/winnt.c gcc-4.3.2/gcc/config/i386/winnt.c --- gcc-4.3.2.orig/gcc/config/i386/winnt.c 2008-05-11 14:03:27.000000000 -0700 +++ gcc-4.3.2/gcc/config/i386/winnt.c 2008-12-03 23:13:05.000000000 -0800 @@ -32,6 +32,7 @@ #include "tm_p.h" #include "toplev.h" #include "hashtab.h" +#include "langhooks.h" #include "ggc.h" #include "target.h" @@ -258,27 +259,19 @@ switch (TREE_CODE (decl)) { case FUNCTION_DECL: - if (first) + /* FIXME: Imported stdcall names are not modified by the Ada frontend. + Check and decorate the RTL name now. */ + if (strcmp (lang_hooks.name, "GNU Ada") == 0) { - /* FIXME: In Ada, and perhaps other language frontends, - imported stdcall names may not yet have been modified. - Check and do it know. */ - tree new_id; - tree old_id = DECL_ASSEMBLER_NAME (decl); - const char* asm_str = IDENTIFIER_POINTER (old_id); - /* Do not change the identifier if a verbatim asmspec + tree new_id; + tree old_id = DECL_ASSEMBLER_NAME (decl); + const char* asm_str = IDENTIFIER_POINTER (old_id); + /* Do not change the identifier if a verbatim asmspec or if stdcall suffix already added. */ - if (*asm_str == '*' || strchr (asm_str, '@')) - break; - if ((new_id = i386_pe_maybe_mangle_decl_assembler_name (decl, old_id))) - { - /* These attributes must be present on first declaration, - change_decl_assembler_name will warn if they are added - later and the decl has been referenced, but duplicate_decls - should catch the mismatch first. */ - change_decl_assembler_name (decl, new_id); - XSTR (symbol, 0) = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - } + if (!(*asm_str == '*' || strchr (asm_str, '@')) + && (new_id = i386_pe_maybe_mangle_decl_assembler_name (decl, + old_id))) + XSTR (symbol, 0) = IDENTIFIER_POINTER (new_id); } break; diff -Naur gcc-4.3.2.orig/gcc/config/mips/mips.opt gcc-4.3.2/gcc/config/mips/mips.opt --- gcc-4.3.2.orig/gcc/config/mips/mips.opt 2007-09-23 12:18:27.000000000 -0700 +++ gcc-4.3.2/gcc/config/mips/mips.opt 2008-10-22 15:31:03.000000000 -0700 @@ -241,7 +241,7 @@ Restrict the use of hardware floating-point instructions to 32-bit operations msmartmips -Target Report RejectNegative Mask(SMARTMIPS) +Target Report Mask(SMARTMIPS) Use SmartMIPS instructions msoft-float diff -Naur gcc-4.3.2.orig/gcc/config/pa/pa.c gcc-4.3.2/gcc/config/pa/pa.c --- gcc-4.3.2.orig/gcc/config/pa/pa.c 2008-02-09 12:34:47.000000000 -0800 +++ gcc-4.3.2/gcc/config/pa/pa.c 2008-10-04 11:06:46.000000000 -0700 @@ -715,8 +715,8 @@ if (function_label_operand (orig, mode)) { - /* Force function label into memory. */ - orig = XEXP (force_const_mem (mode, orig), 0); + /* Force function label into memory in word mode. */ + orig = XEXP (force_const_mem (word_mode, orig), 0); /* Load plabel address from DLT. */ emit_move_insn (tmp_reg, gen_rtx_PLUS (word_mode, pic_offset_table_rtx, diff -Naur gcc-4.3.2.orig/gcc/config/pa/pa64-hpux.h gcc-4.3.2/gcc/config/pa/pa64-hpux.h --- gcc-4.3.2.orig/gcc/config/pa/pa64-hpux.h 2008-01-16 19:55:34.000000000 -0800 +++ gcc-4.3.2/gcc/config/pa/pa64-hpux.h 2008-12-12 16:18:00.000000000 -0800 @@ -84,7 +84,7 @@ #undef LINK_GCC_C_SEQUENCE_SPEC #define LINK_GCC_C_SEQUENCE_SPEC "\ %G %L %G %{!nostdlib:%{!nodefaultlibs:%{!shared:-lgcc_stub}\ - /usr/lib/pa20_64/milli.a}}" + milli.a%s}}" /* Under hpux11, the normal location of the `ld' and `as' programs is the /usr/ccs/bin directory. */ diff -Naur gcc-4.3.2.orig/gcc/config/rs6000/altivec.md gcc-4.3.2/gcc/config/rs6000/altivec.md --- gcc-4.3.2.orig/gcc/config/rs6000/altivec.md 2007-08-22 13:32:18.000000000 -0700 +++ gcc-4.3.2/gcc/config/rs6000/altivec.md 2008-08-31 05:26:20.000000000 -0700 @@ -1,5 +1,5 @@ ;; AltiVec patterns. -;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 +;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 ;; Free Software Foundation, Inc. ;; Contributed by Aldy Hernandez (aldy@quesejoda.com) @@ -256,15 +256,15 @@ }) (define_split - [(set (match_operand:VI 0 "altivec_register_operand" "") - (match_operand:VI 1 "easy_vector_constant_add_self" ""))] + [(set (match_operand:V 0 "altivec_register_operand" "") + (match_operand:V 1 "easy_vector_constant_add_self" ""))] "TARGET_ALTIVEC && reload_completed" [(set (match_dup 0) (match_dup 3)) - (set (match_dup 0) (plus:VI (match_dup 0) - (match_dup 0)))] + (set (match_dup 0) (match_dup 4))] { rtx dup = gen_easy_altivec_constant (operands[1]); rtx const_vec; + enum machine_mode op_mode = mode; /* Divide the operand of the resulting VEC_DUPLICATE, and use simplify_rtx to make a CONST_VECTOR. */ @@ -272,10 +272,16 @@ XEXP (dup, 0), const1_rtx); const_vec = simplify_rtx (dup); - if (GET_MODE (const_vec) == mode) + if (op_mode == V4SFmode) + { + op_mode = V4SImode; + operands[0] = gen_lowpart (op_mode, operands[0]); + } + if (GET_MODE (const_vec) == op_mode) operands[3] = const_vec; else - operands[3] = gen_lowpart (mode, const_vec); + operands[3] = gen_lowpart (op_mode, const_vec); + operands[4] = gen_rtx_PLUS (op_mode, operands[0], operands[0]); }) (define_insn "get_vrsave_internal" diff -Naur gcc-4.3.2.orig/gcc/config/rs6000/predicates.md gcc-4.3.2/gcc/config/rs6000/predicates.md --- gcc-4.3.2.orig/gcc/config/rs6000/predicates.md 2008-06-28 12:41:29.000000000 -0700 +++ gcc-4.3.2/gcc/config/rs6000/predicates.md 2008-08-31 05:26:20.000000000 -0700 @@ -1,5 +1,5 @@ ;; Predicate definitions for POWER and PowerPC. -;; Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. +;; Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. ;; ;; This file is part of GCC. ;; @@ -325,8 +325,8 @@ (and (match_test "TARGET_ALTIVEC") (match_test "easy_altivec_constant (op, mode)"))) { - rtx last = CONST_VECTOR_ELT (op, GET_MODE_NUNITS (mode) - 1); - HOST_WIDE_INT val = ((INTVAL (last) & 0xff) ^ 0x80) - 0x80; + HOST_WIDE_INT val = const_vector_elt_as_int (op, GET_MODE_NUNITS (mode) - 1); + val = ((val & 0xff) ^ 0x80) - 0x80; return EASY_VECTOR_15_ADD_SELF (val); }) diff -Naur gcc-4.3.2.orig/gcc/config/rs6000/rs6000-protos.h gcc-4.3.2/gcc/config/rs6000/rs6000-protos.h --- gcc-4.3.2.orig/gcc/config/rs6000/rs6000-protos.h 2008-01-26 09:18:35.000000000 -0800 +++ gcc-4.3.2/gcc/config/rs6000/rs6000-protos.h 2008-08-31 05:26:20.000000000 -0700 @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for IBM RS/6000. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) @@ -31,6 +31,7 @@ #endif /* TREE_CODE */ extern bool easy_altivec_constant (rtx, enum machine_mode); +extern HOST_WIDE_INT const_vector_elt_as_int (rtx, unsigned int); extern bool macho_lo_sum_memory_operand (rtx, enum machine_mode); extern int num_insns_constant (rtx, enum machine_mode); extern int num_insns_constant_wide (HOST_WIDE_INT); diff -Naur gcc-4.3.2.orig/gcc/config/rs6000/rs6000.c gcc-4.3.2/gcc/config/rs6000/rs6000.c --- gcc-4.3.2.orig/gcc/config/rs6000/rs6000.c 2008-06-10 10:13:57.000000000 -0700 +++ gcc-4.3.2/gcc/config/rs6000/rs6000.c 2008-11-18 14:07:58.000000000 -0800 @@ -2545,7 +2545,7 @@ corresponding element of the vector, but for V4SFmode and V2SFmode, the corresponding "float" is interpreted as an SImode integer. */ -static HOST_WIDE_INT +HOST_WIDE_INT const_vector_elt_as_int (rtx op, unsigned int elt) { rtx tmp = CONST_VECTOR_ELT (op, elt); @@ -6786,7 +6786,8 @@ else if (reg == fpr && TYPE_MODE (type) == TDmode) { regalign = 1; - t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), reg, size_int (1)); + t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), reg, + build_int_cst (TREE_TYPE (reg), 1)); u = build2 (MODIFY_EXPR, void_type_node, reg, t); } @@ -6826,7 +6827,8 @@ { /* Ensure that we don't find any more args in regs. Alignment has taken care of for special cases. */ - t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (reg), reg, size_int (8)); + t = build_gimple_modify_stmt (reg, + build_int_cst (TREE_TYPE (reg), 8)); gimplify_and_add (t, pre_p); } } @@ -11188,6 +11190,10 @@ case FIELD_DECL: case RESULT_DECL: case REAL_CST: + case INDIRECT_REF: + case ALIGN_INDIRECT_REF: + case MISALIGNED_INDIRECT_REF: + case VIEW_CONVERT_EXPR: if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode) return *tp; break; @@ -13829,7 +13835,8 @@ HOST_WIDE_INT imask = GET_MODE_MASK (mode); /* Shift amount for subword relative to aligned word. */ - addrSI = force_reg (SImode, gen_lowpart_common (SImode, XEXP (mem, 0))); + addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0)); + addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI)); shift = gen_reg_rtx (SImode); emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3), GEN_INT (shift_mask))); @@ -19831,8 +19838,10 @@ default: break; } - if (result && result != type && TYPE_READONLY (type)) - result = build_qualified_type (result, TYPE_QUAL_CONST); + /* Propagate qualifiers attached to the element type + onto the vector type. */ + if (result && result != type && TYPE_QUALS (type)) + result = build_qualified_type (result, TYPE_QUALS (type)); *no_add_attrs = true; /* No need to hang on to the attribute. */ diff -Naur gcc-4.3.2.orig/gcc/config/s390/s390.h gcc-4.3.2/gcc/config/s390/s390.h --- gcc-4.3.2.orig/gcc/config/s390/s390.h 2008-02-07 11:01:45.000000000 -0800 +++ gcc-4.3.2/gcc/config/s390/s390.h 2008-11-12 10:06:29.000000000 -0800 @@ -533,9 +533,7 @@ /* Defining this macro makes __builtin_frame_address(0) and __builtin_return_address(0) work with -fomit-frame-pointer. */ #define INITIAL_FRAME_ADDRESS_RTX \ - (TARGET_PACKED_STACK ? \ - plus_constant (arg_pointer_rtx, -UNITS_PER_WORD) : \ - plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET)) + (plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET)) /* The return address of the current frame is retrieved from the initial value of register RETURN_REGNUM. @@ -545,6 +543,16 @@ (TARGET_PACKED_STACK ? \ plus_constant ((FRAME), STACK_POINTER_OFFSET - UNITS_PER_WORD) : (FRAME)) +/* For -mpacked-stack this adds 160 - 8 (96 - 4) to the output of + builtin_frame_address. Otherwise arg pointer - + STACK_POINTER_OFFSET would be returned for + __builtin_frame_address(0) what might result in an address pointing + somewhere into the middle of the local variables since the packed + stack layout generally does not need all the bytes in the register + save area. */ +#define FRAME_ADDR_RTX(FRAME) \ + DYNAMIC_CHAIN_ADDRESS ((FRAME)) + #define RETURN_ADDR_RTX(COUNT, FRAME) \ s390_return_addr_rtx ((COUNT), DYNAMIC_CHAIN_ADDRESS ((FRAME))) diff -Naur gcc-4.3.2.orig/gcc/config/sh/sh.c gcc-4.3.2/gcc/config/sh/sh.c --- gcc-4.3.2.orig/gcc/config/sh/sh.c 2008-07-15 15:44:54.000000000 -0700 +++ gcc-4.3.2/gcc/config/sh/sh.c 2008-10-30 20:43:20.000000000 -0700 @@ -3785,6 +3785,10 @@ if (optimize) { + /* If NEW_MOVA has no address yet, it will be handled later. */ + if (INSN_ADDRESSES_SIZE() <= (unsigned) INSN_UID (new_mova)) + return -1; + n_addr = INSN_ADDRESSES (INSN_UID (new_mova)); n_target = INSN_ADDRESSES (INSN_UID (XEXP (MOVA_LABELREF (new_mova), 0))); if (n_addr > n_target || n_addr + 1022 < n_target) diff -Naur gcc-4.3.2.orig/gcc/config/sh/t-sh gcc-4.3.2/gcc/config/sh/t-sh --- gcc-4.3.2.orig/gcc/config/sh/t-sh 2006-11-29 06:35:38.000000000 -0800 +++ gcc-4.3.2/gcc/config/sh/t-sh 2008-10-25 17:10:27.000000000 -0700 @@ -101,7 +101,7 @@ $(T)udivsi3_i4i-Os-4-200.o: $(srcdir)/config/sh/lib1funcs-Os-4-200.asm $(GCC_PASSES) $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $@ -DL_udivsi3_i4i -x assembler-with-cpp $< $(T)unwind-dw2-Os-4-200.o: $(srcdir)/unwind-dw2.c $(srcdir)/unwind-generic.h unwind-pe.h unwind.inc unwind-dw2-fde.h unwind-dw2.h $(CONFIG_H) coretypes.h $(TM_H) $(MACHMODE_H) longlong.h config.status stmp-int-hdrs tsystem.h $(GCC_PASSES) - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) $(vis_hide) -fexceptions -Os -c -o $@ $< + $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) $(LIBGCC2_CFLAGS) $(INCLUDES) $(vis_hide) -fexceptions -Os -c -o $@ $< OBJS_Os_4_200=$(T)sdivsi3_i4i-Os-4-200.o $(T)udivsi3_i4i-Os-4-200.o $(T)unwind-dw2-Os-4-200.o $(T)libgcc-Os-4-200.a: $(OBJS_Os_4_200) $(GCC_PASSES) $(AR_CREATE_FOR_TARGET) $@ $(OBJS_Os_4_200) diff -Naur gcc-4.3.2.orig/gcc/config/soft-fp/fixdfti.c gcc-4.3.2/gcc/config/soft-fp/fixdfti.c --- gcc-4.3.2.orig/gcc/config/soft-fp/fixdfti.c 2007-05-16 10:07:07.000000000 -0700 +++ gcc-4.3.2/gcc/config/soft-fp/fixdfti.c 2008-11-26 06:08:24.000000000 -0800 @@ -31,7 +31,7 @@ #include "soft-fp.h" #include "double.h" -TItype __fixdfti(TFtype a) +TItype __fixdfti(DFtype a) { FP_DECL_EX; FP_DECL_D(A); diff -Naur gcc-4.3.2.orig/gcc/config/soft-fp/floatuntisf.c gcc-4.3.2/gcc/config/soft-fp/floatuntisf.c --- gcc-4.3.2.orig/gcc/config/soft-fp/floatuntisf.c 2007-05-16 10:07:07.000000000 -0700 +++ gcc-4.3.2/gcc/config/soft-fp/floatuntisf.c 2008-11-26 06:08:24.000000000 -0800 @@ -31,7 +31,7 @@ #include "soft-fp.h" #include "single.h" -SFtype __floatundisf(UTItype i) +SFtype __floatuntisf(UTItype i) { FP_DECL_EX; FP_DECL_S(A); diff -Naur gcc-4.3.2.orig/gcc/config/sparc/predicates.md gcc-4.3.2/gcc/config/sparc/predicates.md --- gcc-4.3.2.orig/gcc/config/sparc/predicates.md 2007-08-02 03:49:31.000000000 -0700 +++ gcc-4.3.2/gcc/config/sparc/predicates.md 2008-11-06 06:57:15.000000000 -0800 @@ -475,3 +475,7 @@ (and (match_code "mem") (and (match_operand 0 "memory_operand") (match_test "REG_P (XEXP (op, 0))")))) + +;; Return true if OP is a const_double or const_vector. +(define_predicate "const_double_or_vector_operand" + (match_code "const_double,const_vector")) diff -Naur gcc-4.3.2.orig/gcc/config/sparc/sparc.c gcc-4.3.2/gcc/config/sparc/sparc.c --- gcc-4.3.2.orig/gcc/config/sparc/sparc.c 2007-12-06 05:25:37.000000000 -0800 +++ gcc-4.3.2/gcc/config/sparc/sparc.c 2008-11-22 04:44:43.000000000 -0800 @@ -575,7 +575,7 @@ #undef TARGET_HANDLE_OPTION #define TARGET_HANDLE_OPTION sparc_handle_option -#if TARGET_GNU_TLS +#if TARGET_GNU_TLS && defined(HAVE_AS_SPARC_UA_PCREL) #undef TARGET_ASM_OUTPUT_DWARF_DTPREL #define TARGET_ASM_OUTPUT_DWARF_DTPREL sparc_output_dwarf_dtprel #endif @@ -5118,15 +5118,13 @@ Return an expression valid as a return value for the two macros FUNCTION_ARG and FUNCTION_VALUE. - SIZE is the size in bytes of the vector. - BASE_MODE is the argument's base machine mode. + SIZE is the size in bytes of the vector (at least 8 bytes). REGNO is the FP hard register the vector will be passed in. */ static rtx -function_arg_vector_value (int size, enum machine_mode base_mode, int regno) +function_arg_vector_value (int size, int regno) { - unsigned short base_mode_size = GET_MODE_SIZE (base_mode); - int nregs = size / base_mode_size, i; + int i, nregs = size / 8; rtx regs; regs = gen_rtx_PARALLEL (BLKmode, rtvec_alloc (nregs)); @@ -5135,9 +5133,8 @@ { XVECEXP (regs, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (base_mode, regno), - GEN_INT (base_mode_size * i)); - regno += base_mode_size / 4; + gen_rtx_REG (DImode, regno + 2*i), + GEN_INT (i*8)); } return regs; @@ -5183,7 +5180,6 @@ if (mode == BLKmode) return function_arg_vector_value (size, - TYPE_MODE (TREE_TYPE (type)), SPARC_FP_ARG_FIRST + 2*slotno); else mclass = MODE_FLOAT; @@ -5599,7 +5595,6 @@ if (mode == BLKmode) return function_arg_vector_value (size, - TYPE_MODE (TREE_TYPE (type)), SPARC_FP_ARG_FIRST); else mclass = MODE_FLOAT; @@ -8334,6 +8329,10 @@ switch (c) { + case 'D': + return (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT + && GET_CODE (op) == CONST_VECTOR); + case 'Q': return fp_sethi_p (op); diff -Naur gcc-4.3.2.orig/gcc/config/sparc/sparc.h gcc-4.3.2/gcc/config/sparc/sparc.h --- gcc-4.3.2.orig/gcc/config/sparc/sparc.h 2007-12-06 05:25:37.000000000 -0800 +++ gcc-4.3.2/gcc/config/sparc/sparc.h 2008-11-06 06:57:15.000000000 -0800 @@ -1870,6 +1870,8 @@ /* Optional extra constraints for this machine. + 'D' handles vector constants. + 'Q' handles floating point constants which can be moved into an integer register with a single sethi instruction. diff -Naur gcc-4.3.2.orig/gcc/config/sparc/sparc.md gcc-4.3.2/gcc/config/sparc/sparc.md --- gcc-4.3.2.orig/gcc/config/sparc/sparc.md 2007-10-18 21:29:38.000000000 -0700 +++ gcc-4.3.2/gcc/config/sparc/sparc.md 2008-11-30 11:21:10.000000000 -0800 @@ -2531,7 +2531,7 @@ ;; We have available v9 double floats but not 64-bit integer registers. (define_insn "*movdf_insn_sp32_v9" [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o") - (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))] + (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))] "TARGET_FPU && TARGET_V9 && ! TARGET_ARCH64 @@ -2572,7 +2572,7 @@ ;; We have available both v9 double floats and 64-bit integer registers. (define_insn "*movdf_insn_sp64" [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r") - (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))] + (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))] "TARGET_FPU && TARGET_ARCH64 && (register_operand (operands[0], mode) @@ -2603,22 +2603,17 @@ stx\t%r1, %0" [(set_attr "type" "*,load,store")]) -;; This pattern build DFmode constants in integer registers. +;; This pattern builds V64mode constants in integer registers. (define_split - [(set (match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "const_double_operand" ""))] + [(set (match_operand:V64 0 "register_operand" "") + (match_operand:V64 1 "const_double_or_vector_operand" ""))] "TARGET_FPU && (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32) - && ! const_zero_operand(operands[1], DFmode) + && ! const_zero_operand (operands[1], GET_MODE (operands[0])) && reload_completed" [(clobber (const_int 0))] { - REAL_VALUE_TYPE r; - long l[2]; - - REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); - REAL_VALUE_TO_TARGET_DOUBLE (r, l); operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0])); if (TARGET_ARCH64) @@ -2626,31 +2621,34 @@ #if HOST_BITS_PER_WIDE_INT == 32 gcc_unreachable (); #else - HOST_WIDE_INT val; - - val = ((HOST_WIDE_INT)(unsigned long)l[1] | - ((HOST_WIDE_INT)(unsigned long)l[0] << 32)); - emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode))); + enum machine_mode mode = GET_MODE (operands[1]); + rtx tem = simplify_subreg (DImode, operands[1], mode, 0); + emit_insn (gen_movdi (operands[0], tem)); #endif } else { - emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), - gen_int_mode (l[0], SImode))); + enum machine_mode mode = GET_MODE (operands[1]); + rtx hi = simplify_subreg (SImode, operands[1], mode, 0); + rtx lo = simplify_subreg (SImode, operands[1], mode, 4); + + gcc_assert (GET_CODE (hi) == CONST_INT); + gcc_assert (GET_CODE (lo) == CONST_INT); + + emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi)); /* Slick... but this trick loses if this subreg constant part can be done in one insn. */ - if (l[1] == l[0] - && ! SPARC_SETHI32_P (l[0]) - && ! SPARC_SIMM13_P (l[0])) + if (lo == hi + && ! SPARC_SETHI32_P (INTVAL (hi)) + && ! SPARC_SIMM13_P (INTVAL (hi))) { emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), gen_highpart (SImode, operands[0]))); } else { - emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), - gen_int_mode (l[1], SImode))); + emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo)); } } DONE; @@ -5088,14 +5086,11 @@ [(set_attr "type" "multi") (set_attr "length" "2")]) -;; The V8 architecture specifies that there must be 3 instructions between -;; a Y register write and a use of it for correct results. - (define_expand "divsi3" - [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r") - (div:SI (match_operand:SI 1 "register_operand" "r,r") - (match_operand:SI 2 "input_operand" "rI,m"))) - (clobber (match_scratch:SI 3 "=&r,&r"))])] + [(parallel [(set (match_operand:SI 0 "register_operand" "") + (div:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "input_operand" ""))) + (clobber (match_scratch:SI 3 ""))])] "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" { if (TARGET_ARCH64) @@ -5108,24 +5103,40 @@ } }) +;; The V8 architecture specifies that there must be at least 3 instructions +;; between a write to the Y register and a use of it for correct results. +;; We try to fill one of them with a simple constant or a memory load. + (define_insn "divsi3_sp32" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (div:SI (match_operand:SI 1 "register_operand" "r,r") - (match_operand:SI 2 "input_operand" "rI,m"))) - (clobber (match_scratch:SI 3 "=&r,&r"))] - "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) - && TARGET_ARCH32" -{ - if (which_alternative == 0) - if (TARGET_V9) - return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0"; - else - return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0"; - else - if (TARGET_V9) - return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0"; - else - return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0"; + [(set (match_operand:SI 0 "register_operand" "=r,r,r") + (div:SI (match_operand:SI 1 "register_operand" "r,r,r") + (match_operand:SI 2 "input_operand" "rI,K,m"))) + (clobber (match_scratch:SI 3 "=&r,&r,&r"))] + "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32" +{ + output_asm_insn ("sra\t%1, 31, %3", operands); + output_asm_insn ("wr\t%3, 0, %%y", operands); + + switch (which_alternative) + { + case 0: + if (TARGET_V9) + return "sdiv\t%1, %2, %0"; + else + return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0"; + case 1: + if (TARGET_V9) + return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0"; + else + return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0"; + case 2: + if (TARGET_V9) + return "ld\t%2, %3\n\tsdiv\t%1, %3, %0"; + else + return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0"; + default: + gcc_unreachable (); + } } [(set_attr "type" "multi") (set (attr "length") @@ -5160,10 +5171,13 @@ (clobber (match_scratch:SI 3 "=&r"))] "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" { + output_asm_insn ("sra\t%1, 31, %3", operands); + output_asm_insn ("wr\t%3, 0, %%y", operands); + if (TARGET_V9) - return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0"; + return "sdivcc\t%1, %2, %0"; else - return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0"; + return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0"; } [(set_attr "type" "multi") (set (attr "length") @@ -5178,29 +5192,48 @@ "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" "") -;; The V8 architecture specifies that there must be 3 instructions between -;; a Y register write and a use of it for correct results. +;; The V8 architecture specifies that there must be at least 3 instructions +;; between a write to the Y register and a use of it for correct results. +;; We try to fill one of them with a simple constant or a memory load. (define_insn "udivsi3_sp32" - [(set (match_operand:SI 0 "register_operand" "=r,&r,&r") - (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m") - (match_operand:SI 2 "input_operand" "rI,m,r")))] - "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) - && TARGET_ARCH32" + [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r") + (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m") + (match_operand:SI 2 "input_operand" "rI,K,m,r")))] + "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32" { - output_asm_insn ("wr\t%%g0, %%g0, %%y", operands); + output_asm_insn ("wr\t%%g0, 0, %%y", operands); + switch (which_alternative) { - default: - return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0"; + case 0: + if (TARGET_V9) + return "udiv\t%1, %2, %0"; + else + return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0"; case 1: - return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0"; + if (TARGET_V9) + return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0"; + else + return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0"; case 2: - return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0"; + if (TARGET_V9) + return "ld\t%2, %0\n\tudiv\t%1, %0, %0"; + else + return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0"; + case 3: + if (TARGET_V9) + return "ld\t%1, %0\n\tudiv\t%0, %2, %0"; + else + return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0"; + default: + gcc_unreachable (); } } [(set_attr "type" "multi") - (set_attr "length" "5")]) + (set (attr "length") + (if_then_else (eq_attr "isa" "v9") + (const_int 3) (const_int 5)))]) (define_insn "udivsi3_sp64" [(set (match_operand:SI 0 "register_operand" "=r") @@ -5226,13 +5259,14 @@ (const_int 0))) (set (match_operand:SI 0 "register_operand" "=r") (udiv:SI (match_dup 1) (match_dup 2)))] - "TARGET_V8 - || TARGET_DEPRECATED_V8_INSNS" + "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" { + output_asm_insn ("wr\t%%g0, 0, %%y", operands); + if (TARGET_V9) - return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0"; + return "udivcc\t%1, %2, %0"; else - return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0"; + return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0"; } [(set_attr "type" "multi") (set (attr "length") diff -Naur gcc-4.3.2.orig/gcc/config/spu/spu-elf.h gcc-4.3.2/gcc/config/spu/spu-elf.h --- gcc-4.3.2.orig/gcc/config/spu/spu-elf.h 2007-08-02 03:49:31.000000000 -0700 +++ gcc-4.3.2/gcc/config/spu/spu-elf.h 2008-11-14 14:28:54.000000000 -0800 @@ -24,6 +24,23 @@ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN) +/* The following macros define "native" directory locations; on the SPU, + these are used only when building the compiler with --with-sysroot. + This can be used to build a pair of PPU and SPU cross-compilers with + a common sysroot; the SPU compiler will search for its files in + ${sysroot}/include and ${sysroot}/lib. */ + +/* STANDARD_STARTFILE_PREFIX_1 is "/lib", which we keep. + STANDARD_STARTFILE_PREFIX_2 is "/usr/lib" -- we remove this. */ +#undef STANDARD_STARTFILE_PREFIX_2 +#define STANDARD_STARTFILE_PREFIX_2 "" + +/* Use "/include" instead of "/usr/include". */ +#undef STANDARD_INCLUDE_DIR +#define STANDARD_INCLUDE_DIR "/include" + +/* We do not provide any "/usr/local/include" directory on SPU. */ +#undef LOCAL_INCLUDE_DIR /* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add the GNU/Linux magical crtbegin.o file (see crtstuff.c) which diff -Naur gcc-4.3.2.orig/gcc/config/spu/spu.c gcc-4.3.2/gcc/config/spu/spu.c --- gcc-4.3.2.orig/gcc/config/spu/spu.c 2008-08-18 07:46:49.000000000 -0700 +++ gcc-4.3.2/gcc/config/spu/spu.c 2008-09-12 06:29:31.000000000 -0700 @@ -54,6 +54,9 @@ #include "tm-constrs.h" #include "spu-builtins.h" #include "ddg.h" +#include "sbitmap.h" +#include "timevar.h" +#include "df.h" /* Builtin types, data and prototypes. */ struct spu_builtin_range @@ -94,19 +97,19 @@ static void emit_nop_for_insn (rtx insn); static bool insn_clobbers_hbr (rtx insn); static void spu_emit_branch_hint (rtx before, rtx branch, rtx target, - int distance); + int distance, sbitmap blocks); static rtx spu_emit_vector_compare (enum rtx_code rcode, rtx op0, rtx op1, enum machine_mode dmode); static rtx get_branch_target (rtx branch); -static void insert_branch_hints (void); -static void insert_nops (void); static void spu_machine_dependent_reorg (void); static int spu_sched_issue_rate (void); static int spu_sched_variable_issue (FILE * dump, int verbose, rtx insn, int can_issue_more); static int get_pipe (rtx insn); -static int spu_sched_adjust_priority (rtx insn, int pri); static int spu_sched_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost); +static void spu_sched_init_global (FILE *, int, int); +static void spu_sched_init (FILE *, int, int); +static int spu_sched_reorder (FILE *, int, rtx *, int *, int); static tree spu_handle_fndecl_attribute (tree * node, tree name, tree args, int flags, unsigned char *no_add_attrs); @@ -138,6 +141,7 @@ static int spu_builtin_vectorization_cost (bool); static bool spu_vector_alignment_reachable (const_tree, bool); static int spu_sms_res_mii (struct ddg *g); +static void asm_file_start (void); extern const char *reg_names[]; rtx spu_compare_op0, spu_compare_op1; @@ -147,6 +151,18 @@ /* Which cpu are we tuning for. */ int spu_tune; +/* The hardware requires 8 insns between a hint and the branch it + effects. This variable describes how many rtl instructions the + compiler needs to see before inserting a hint, and then the compiler + will insert enough nops to make it at least 8 insns. The default is + for the compiler to allow up to 2 nops be emitted. The nops are + inserted in pairs, so we round down. */ +int spu_hint_dist = (8*4) - (2*4); + +/* Determines whether we run variable tracking in machine dependent + reorganization. */ +static int spu_flag_var_tracking; + enum spu_immediate { SPU_NONE, SPU_IL, @@ -212,11 +228,20 @@ #undef TARGET_SCHED_ISSUE_RATE #define TARGET_SCHED_ISSUE_RATE spu_sched_issue_rate +#undef TARGET_SCHED_INIT_GLOBAL +#define TARGET_SCHED_INIT_GLOBAL spu_sched_init_global + +#undef TARGET_SCHED_INIT +#define TARGET_SCHED_INIT spu_sched_init + #undef TARGET_SCHED_VARIABLE_ISSUE #define TARGET_SCHED_VARIABLE_ISSUE spu_sched_variable_issue -#undef TARGET_SCHED_ADJUST_PRIORITY -#define TARGET_SCHED_ADJUST_PRIORITY spu_sched_adjust_priority +#undef TARGET_SCHED_REORDER +#define TARGET_SCHED_REORDER spu_sched_reorder + +#undef TARGET_SCHED_REORDER2 +#define TARGET_SCHED_REORDER2 spu_sched_reorder #undef TARGET_SCHED_ADJUST_COST #define TARGET_SCHED_ADJUST_COST spu_sched_adjust_cost @@ -297,6 +322,9 @@ #undef TARGET_SCHED_SMS_RES_MII #define TARGET_SCHED_SMS_RES_MII spu_sms_res_mii +#undef TARGET_ASM_FILE_START +#define TARGET_ASM_FILE_START asm_file_start + struct gcc_target targetm = TARGET_INITIALIZER; void @@ -325,9 +353,14 @@ flag_omit_frame_pointer = 1; + /* Functions must be 8 byte aligned so we correctly handle dual issue */ if (align_functions < 8) align_functions = 8; + spu_hint_dist = 8*4 - spu_max_nops*4; + if (spu_hint_dist < 0) + spu_hint_dist = 0; + if (spu_fixed_range_string) fix_range (spu_fixed_range_string); @@ -353,6 +386,16 @@ error ("Unknown architecture '%s'", &spu_tune_string[0]); } + /* Change defaults according to the processor architecture. */ + if (spu_arch == PROCESSOR_CELLEDP) + { + /* If no command line option has been otherwise specified, change + the default to -mno-safe-hints on celledp -- only the original + Cell/B.E. processors require this workaround. */ + if (!(target_flags_explicit & MASK_SAFE_HINTS)) + target_flags &= ~MASK_SAFE_HINTS; + } + REAL_MODE_FORMAT (SFmode) = &spu_single_format; } @@ -1980,16 +2023,6 @@ return gen_rtx_CONST_VECTOR (mode, v); } - -/* branch hint stuff */ - -/* The hardware requires 8 insns between a hint and the branch it - effects. This variable describes how many rtl instructions the - compiler needs to see before inserting a hint. (FIXME: We should - accept less and insert nops to enforce it because hinting is always - profitable for performance, but we do need to be careful of code - size.) */ -int spu_hint_dist = (8 * 4); /* Create a MODE vector constant from 4 ints. */ rtx @@ -2014,75 +2047,200 @@ arr[15] = (d >> 0) & 0xff; return array_to_constant(mode, arr); } + +/* branch hint stuff */ /* An array of these is used to propagate hints to predecessor blocks. */ struct spu_bb_info { - rtx prop_jump; /* propagated from another block */ - basic_block bb; /* the original block. */ + rtx prop_jump; /* propagated from another block */ + int bb_index; /* the original block. */ }; +static struct spu_bb_info *spu_bb_info; -/* The special $hbr register is used to prevent the insn scheduler from - moving hbr insns across instructions which invalidate them. It - should only be used in a clobber, and this function searches for - insns which clobber it. */ -static bool -insn_clobbers_hbr (rtx insn) +#define STOP_HINT_P(INSN) \ + (GET_CODE(INSN) == CALL_INSN \ + || INSN_CODE(INSN) == CODE_FOR_divmodsi4 \ + || INSN_CODE(INSN) == CODE_FOR_udivmodsi4) + +/* 1 when RTX is a hinted branch or its target. We keep track of + what has been hinted so the safe-hint code can test it easily. */ +#define HINTED_P(RTX) \ + (RTL_FLAG_CHECK3("HINTED_P", (RTX), CODE_LABEL, JUMP_INSN, CALL_INSN)->unchanging) + +/* 1 when RTX is an insn that must be scheduled on an even boundary. */ +#define SCHED_ON_EVEN_P(RTX) \ + (RTL_FLAG_CHECK2("SCHED_ON_EVEN_P", (RTX), JUMP_INSN, CALL_INSN)->in_struct) + +/* Emit a nop for INSN such that the two will dual issue. This assumes + INSN is 8-byte aligned. When INSN is inline asm we emit an lnop. + We check for TImode to handle a MULTI1 insn which has dual issued its + first instruction. get_pipe returns -1 for MULTI0, inline asm, or + ADDR_VEC insns. */ +static void +emit_nop_for_insn (rtx insn) { - if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == PARALLEL) + int p; + rtx new_insn; + p = get_pipe (insn); + if ((CALL_P (insn) || JUMP_P (insn)) && SCHED_ON_EVEN_P (insn)) + new_insn = emit_insn_after (gen_lnop (), insn); + else if (p == 1 && GET_MODE (insn) == TImode) { - rtx parallel = PATTERN (insn); - rtx clobber; - int j; - for (j = XVECLEN (parallel, 0) - 1; j >= 0; j--) + new_insn = emit_insn_before (gen_nopn (GEN_INT (127)), insn); + PUT_MODE (new_insn, TImode); + PUT_MODE (insn, VOIDmode); + } + else + new_insn = emit_insn_after (gen_lnop (), insn); + recog_memoized (new_insn); +} + +/* Insert nops in basic blocks to meet dual issue alignment + requirements. Also make sure hbrp and hint instructions are at least + one cycle apart, possibly inserting a nop. */ +static void +pad_bb(void) +{ + rtx insn, next_insn, prev_insn, hbr_insn = 0; + int length; + int addr; + + /* This sets up INSN_ADDRESSES. */ + shorten_branches (get_insns ()); + + /* Keep track of length added by nops. */ + length = 0; + + prev_insn = 0; + insn = get_insns (); + if (!active_insn_p (insn)) + insn = next_active_insn (insn); + for (; insn; insn = next_insn) + { + next_insn = next_active_insn (insn); + if (INSN_CODE (insn) == CODE_FOR_iprefetch + || INSN_CODE (insn) == CODE_FOR_hbr) { - clobber = XVECEXP (parallel, 0, j); - if (GET_CODE (clobber) == CLOBBER - && GET_CODE (XEXP (clobber, 0)) == REG - && REGNO (XEXP (clobber, 0)) == HBR_REGNUM) - return 1; + if (hbr_insn) + { + int a0 = INSN_ADDRESSES (INSN_UID (hbr_insn)); + int a1 = INSN_ADDRESSES (INSN_UID (insn)); + if ((a1 - a0 == 8 && GET_MODE (insn) != TImode) + || (a1 - a0 == 4)) + { + prev_insn = emit_insn_before (gen_lnop (), insn); + PUT_MODE (prev_insn, GET_MODE (insn)); + PUT_MODE (insn, TImode); + length += 4; + } + } + hbr_insn = insn; } + if (INSN_CODE (insn) == CODE_FOR_blockage) + { + if (GET_MODE (insn) == TImode) + PUT_MODE (next_insn, TImode); + insn = next_insn; + next_insn = next_active_insn (insn); + } + addr = INSN_ADDRESSES (INSN_UID (insn)); + if ((CALL_P (insn) || JUMP_P (insn)) && SCHED_ON_EVEN_P (insn)) + { + if (((addr + length) & 7) != 0) + { + emit_nop_for_insn (prev_insn); + length += 4; + } + } + else if (GET_MODE (insn) == TImode + && ((next_insn && GET_MODE (next_insn) != TImode) + || get_attr_type (insn) == TYPE_MULTI0) + && ((addr + length) & 7) != 0) + { + /* prev_insn will always be set because the first insn is + always 8-byte aligned. */ + emit_nop_for_insn (prev_insn); + length += 4; + } + prev_insn = insn; } - return 0; } + +/* Routines for branch hints. */ + static void -spu_emit_branch_hint (rtx before, rtx branch, rtx target, int distance) +spu_emit_branch_hint (rtx before, rtx branch, rtx target, + int distance, sbitmap blocks) { - rtx branch_label; - rtx hint, insn, prev, next; + rtx branch_label = 0; + rtx hint; + rtx insn; + rtx table; if (before == 0 || branch == 0 || target == 0) return; + /* While scheduling we require hints to be no further than 600, so + we need to enforce that here too */ if (distance > 600) return; + /* If we have a Basic block note, emit it after the basic block note. */ + if (NOTE_KIND (before) == NOTE_INSN_BASIC_BLOCK) + before = NEXT_INSN (before); branch_label = gen_label_rtx (); LABEL_NUSES (branch_label)++; LABEL_PRESERVE_P (branch_label) = 1; insn = emit_label_before (branch_label, branch); branch_label = gen_rtx_LABEL_REF (VOIDmode, branch_label); + SET_BIT (blocks, BLOCK_FOR_INSN (branch)->index); - /* If the previous insn is pipe0, make the hbr dual issue with it. If - the current insn is pipe0, dual issue with it. */ - prev = prev_active_insn (before); - if (prev && get_pipe (prev) == 0) - hint = emit_insn_before (gen_hbr (branch_label, target), before); - else if (get_pipe (before) == 0 && distance > spu_hint_dist) - { - next = next_active_insn (before); - hint = emit_insn_after (gen_hbr (branch_label, target), before); - if (next) - PUT_MODE (next, TImode); + hint = emit_insn_before (gen_hbr (branch_label, target), before); + recog_memoized (hint); + HINTED_P (branch) = 1; + + if (GET_CODE (target) == LABEL_REF) + HINTED_P (XEXP (target, 0)) = 1; + else if (tablejump_p (branch, 0, &table)) + { + rtvec vec; + int j; + if (GET_CODE (PATTERN (table)) == ADDR_VEC) + vec = XVEC (PATTERN (table), 0); + else + vec = XVEC (PATTERN (table), 1); + for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j) + HINTED_P (XEXP (RTVEC_ELT (vec, j), 0)) = 1; } - else + + if (distance >= 588) { - hint = emit_insn_before (gen_hbr (branch_label, target), before); - PUT_MODE (hint, TImode); + /* Make sure the hint isn't scheduled any earlier than this point, + which could make it too far for the branch offest to fit */ + recog_memoized (emit_insn_before (gen_blockage (), hint)); + } + else if (distance <= 8 * 4) + { + /* To guarantee at least 8 insns between the hint and branch we + insert nops. */ + int d; + for (d = distance; d < 8 * 4; d += 4) + { + insn = + emit_insn_after (gen_nopn_nv (gen_rtx_REG (SImode, 127)), hint); + recog_memoized (insn); + } + + /* Make sure any nops inserted aren't scheduled before the hint. */ + recog_memoized (emit_insn_after (gen_blockage (), hint)); + + /* Make sure any nops inserted aren't scheduled after the call. */ + if (CALL_P (branch) && distance < 8 * 4) + recog_memoized (emit_insn_before (gen_blockage (), branch)); } - recog_memoized (hint); } /* Returns 0 if we don't want a hint for this branch. Otherwise return @@ -2152,245 +2310,403 @@ return 0; } -static void -insert_branch_hints (void) +/* The special $hbr register is used to prevent the insn scheduler from + moving hbr insns across instructions which invalidate them. It + should only be used in a clobber, and this function searches for + insns which clobber it. */ +static bool +insn_clobbers_hbr (rtx insn) { - struct spu_bb_info *spu_bb_info; - rtx branch, insn, next; - rtx branch_target = 0; - int branch_addr = 0, insn_addr, head_addr; - basic_block bb; - unsigned int j; - - spu_bb_info = - (struct spu_bb_info *) xcalloc (last_basic_block + 1, - sizeof (struct spu_bb_info)); - - /* We need exact insn addresses and lengths. */ - shorten_branches (get_insns ()); + if (INSN_P (insn) + && GET_CODE (PATTERN (insn)) == PARALLEL) + { + rtx parallel = PATTERN (insn); + rtx clobber; + int j; + for (j = XVECLEN (parallel, 0) - 1; j >= 0; j--) + { + clobber = XVECEXP (parallel, 0, j); + if (GET_CODE (clobber) == CLOBBER + && GET_CODE (XEXP (clobber, 0)) == REG + && REGNO (XEXP (clobber, 0)) == HBR_REGNUM) + return 1; + } + } + return 0; +} - FOR_EACH_BB_REVERSE (bb) - { - head_addr = INSN_ADDRESSES (INSN_UID (BB_HEAD (bb))); - branch = 0; - if (spu_bb_info[bb->index].prop_jump) - { - branch = spu_bb_info[bb->index].prop_jump; - branch_target = get_branch_target (branch); - branch_addr = INSN_ADDRESSES (INSN_UID (branch)); - } - /* Search from end of a block to beginning. In this loop, find - jumps which need a branch and emit them only when: - - it's an indirect branch and we're at the insn which sets - the register - - we're at an insn that will invalidate the hint. e.g., a - call, another hint insn, inline asm that clobbers $hbr, and - some inlined operations (divmodsi4). Don't consider jumps - because they are only at the end of a block and are - considered when we are deciding whether to propagate - - we're getting too far away from the branch. The hbr insns - only have a signed 10-bit offset - We go back as far as possible so the branch will be considered - for propagation when we get to the beginning of the block. */ - next = 0; - for (insn = BB_END (bb); insn; insn = PREV_INSN (insn)) +/* Search up to 32 insns starting at FIRST: + - at any kind of hinted branch, just return + - at any unconditional branch in the first 15 insns, just return + - at a call or indirect branch, after the first 15 insns, force it to + an even address and return + - at any unconditional branch, after the first 15 insns, force it to + an even address. + At then end of the search, insert an hbrp within 4 insns of FIRST, + and an hbrp within 16 instructions of FIRST. + */ +static void +insert_hbrp_for_ilb_runout (rtx first) +{ + rtx insn, before_4 = 0, before_16 = 0; + int addr = 0, length, first_addr = -1; + int hbrp_addr0 = 128 * 4, hbrp_addr1 = 128 * 4; + int insert_lnop_after = 0; + for (insn = first; insn; insn = NEXT_INSN (insn)) + if (INSN_P (insn)) { - if (INSN_P (insn)) + if (first_addr == -1) + first_addr = INSN_ADDRESSES (INSN_UID (insn)); + addr = INSN_ADDRESSES (INSN_UID (insn)) - first_addr; + length = get_attr_length (insn); + + if (before_4 == 0 && addr + length >= 4 * 4) + before_4 = insn; + /* We test for 14 instructions because the first hbrp will add + up to 2 instructions. */ + if (before_16 == 0 && addr + length >= 14 * 4) + before_16 = insn; + + if (INSN_CODE (insn) == CODE_FOR_hbr) { - insn_addr = INSN_ADDRESSES (INSN_UID (insn)); - if (branch && next - && ((GET_CODE (branch_target) == REG - && set_of (branch_target, insn) != NULL_RTX) - || insn_clobbers_hbr (insn) - || branch_addr - insn_addr > 600)) + /* Make sure an hbrp is at least 2 cycles away from a hint. + Insert an lnop after the hbrp when necessary. */ + if (before_4 == 0 && addr > 0) { - int next_addr = INSN_ADDRESSES (INSN_UID (next)); - if (insn != BB_END (bb) - && branch_addr - next_addr >= spu_hint_dist) - { - if (dump_file) - fprintf (dump_file, - "hint for %i in block %i before %i\n", - INSN_UID (branch), bb->index, INSN_UID (next)); - spu_emit_branch_hint (next, branch, branch_target, - branch_addr - next_addr); - } - branch = 0; + before_4 = insn; + insert_lnop_after |= 1; } - - /* JUMP_P will only be true at the end of a block. When - branch is already set it means we've previously decided - to propagate a hint for that branch into this block. */ - if (CALL_P (insn) || (JUMP_P (insn) && !branch)) + else if (before_4 && addr <= 4 * 4) + insert_lnop_after |= 1; + if (before_16 == 0 && addr > 10 * 4) { - branch = 0; - if ((branch_target = get_branch_target (insn))) - { - branch = insn; - branch_addr = insn_addr; - } + before_16 = insn; + insert_lnop_after |= 2; } - - /* When a branch hint is emitted it will be inserted - before "next". Make sure next is the beginning of a - cycle to minimize impact on the scheduled insns. */ - if (GET_MODE (insn) == TImode) - next = insn; + else if (before_16 && addr <= 14 * 4) + insert_lnop_after |= 2; } - if (insn == BB_HEAD (bb)) - break; - } - if (branch) - { - /* If we haven't emitted a hint for this branch yet, it might - be profitable to emit it in one of the predecessor blocks, - especially for loops. */ - rtx bbend; - basic_block prev = 0, prop = 0, prev2 = 0; - int loop_exit = 0, simple_loop = 0; - int next_addr = 0; - if (next) - next_addr = INSN_ADDRESSES (INSN_UID (next)); - - for (j = 0; j < EDGE_COUNT (bb->preds); j++) - if (EDGE_PRED (bb, j)->flags & EDGE_FALLTHRU) - prev = EDGE_PRED (bb, j)->src; - else - prev2 = EDGE_PRED (bb, j)->src; + if (INSN_CODE (insn) == CODE_FOR_iprefetch) + { + if (addr < hbrp_addr0) + hbrp_addr0 = addr; + else if (addr < hbrp_addr1) + hbrp_addr1 = addr; + } - for (j = 0; j < EDGE_COUNT (bb->succs); j++) - if (EDGE_SUCC (bb, j)->flags & EDGE_LOOP_EXIT) - loop_exit = 1; - else if (EDGE_SUCC (bb, j)->dest == bb) - simple_loop = 1; - - /* If this branch is a loop exit then propagate to previous - fallthru block. This catches the cases when it is a simple - loop or when there is an initial branch into the loop. */ - if (prev && loop_exit && prev->loop_depth <= bb->loop_depth) - prop = prev; - - /* If there is only one adjacent predecessor. Don't propagate - outside this loop. This loop_depth test isn't perfect, but - I'm not sure the loop_father member is valid at this point. */ - else if (prev && single_pred_p (bb) - && prev->loop_depth == bb->loop_depth) - prop = prev; - - /* If this is the JOIN block of a simple IF-THEN then - propagate the hint to the HEADER block. */ - else if (prev && prev2 - && EDGE_COUNT (bb->preds) == 2 - && EDGE_COUNT (prev->preds) == 1 - && EDGE_PRED (prev, 0)->src == prev2 - && prev2->loop_depth == bb->loop_depth - && GET_CODE (branch_target) != REG) - prop = prev; - - /* Don't propagate when: - - this is a simple loop and the hint would be too far - - this is not a simple loop and there are 16 insns in - this block already - - the predecessor block ends in a branch that will be - hinted - - the predecessor block ends in an insn that invalidates - the hint */ - if (prop - && prop->index >= 0 - && (bbend = BB_END (prop)) - && branch_addr - INSN_ADDRESSES (INSN_UID (bbend)) < - (simple_loop ? 600 : 16 * 4) && get_branch_target (bbend) == 0 - && (JUMP_P (bbend) || !insn_clobbers_hbr (bbend))) + if (CALL_P (insn) || JUMP_P (insn)) { - if (dump_file) - fprintf (dump_file, "propagate from %i to %i (loop depth %i) " - "for %i (loop_exit %i simple_loop %i dist %i)\n", - bb->index, prop->index, bb->loop_depth, - INSN_UID (branch), loop_exit, simple_loop, - branch_addr - INSN_ADDRESSES (INSN_UID (bbend))); + if (HINTED_P (insn)) + return; - spu_bb_info[prop->index].prop_jump = branch; - spu_bb_info[prop->index].bb = bb; + /* Any branch after the first 15 insns should be on an even + address to avoid a special case branch. There might be + some nops and/or hbrps inserted, so we test after 10 + insns. */ + if (addr > 10 * 4) + SCHED_ON_EVEN_P (insn) = 1; } - else if (next && branch_addr - next_addr >= spu_hint_dist) + + if (CALL_P (insn) || tablejump_p (insn, 0, 0)) + return; + + + if (addr + length >= 32 * 4) { - if (dump_file) - fprintf (dump_file, "hint for %i in block %i before %i\n", - INSN_UID (branch), bb->index, INSN_UID (next)); - spu_emit_branch_hint (next, branch, branch_target, - branch_addr - next_addr); + gcc_assert (before_4 && before_16); + if (hbrp_addr0 > 4 * 4) + { + insn = + emit_insn_before (gen_iprefetch (GEN_INT (1)), before_4); + recog_memoized (insn); + INSN_ADDRESSES_NEW (insn, + INSN_ADDRESSES (INSN_UID (before_4))); + PUT_MODE (insn, GET_MODE (before_4)); + PUT_MODE (before_4, TImode); + if (insert_lnop_after & 1) + { + insn = emit_insn_before (gen_lnop (), before_4); + recog_memoized (insn); + INSN_ADDRESSES_NEW (insn, + INSN_ADDRESSES (INSN_UID (before_4))); + PUT_MODE (insn, TImode); + } + } + if ((hbrp_addr0 <= 4 * 4 || hbrp_addr0 > 16 * 4) + && hbrp_addr1 > 16 * 4) + { + insn = + emit_insn_before (gen_iprefetch (GEN_INT (2)), before_16); + recog_memoized (insn); + INSN_ADDRESSES_NEW (insn, + INSN_ADDRESSES (INSN_UID (before_16))); + PUT_MODE (insn, GET_MODE (before_16)); + PUT_MODE (before_16, TImode); + if (insert_lnop_after & 2) + { + insn = emit_insn_before (gen_lnop (), before_16); + recog_memoized (insn); + INSN_ADDRESSES_NEW (insn, + INSN_ADDRESSES (INSN_UID + (before_16))); + PUT_MODE (insn, TImode); + } + } + return; } - branch = 0; } - } - free (spu_bb_info); + else if (BARRIER_P (insn)) + return; + } - -/* Emit a nop for INSN such that the two will dual issue. This assumes - INSN is 8-byte aligned. When INSN is inline asm we emit an lnop. - We check for TImode to handle a MULTI1 insn which has dual issued its - first instruction. get_pipe returns -1 for MULTI0, inline asm, or - ADDR_VEC insns. */ + +/* The SPU might hang when it executes 48 inline instructions after a + hinted branch jumps to its hinted target. The beginning of a + function and the return from a call might have been hinted, and must + be handled as well. To prevent a hang we insert 2 hbrps. The first + should be within 6 insns of the branch target. The second should be + within 22 insns of the branch target. When determining if hbrps are + necessary, we look for only 32 inline instructions, because up to to + 12 nops and 4 hbrps could be inserted. Similarily, when inserting + new hbrps, we insert them within 4 and 16 insns of the target. */ static void -emit_nop_for_insn (rtx insn) +insert_hbrp (void) { - int p; - rtx new_insn; - p = get_pipe (insn); - if (p == 1 && GET_MODE (insn) == TImode) + rtx insn; + if (TARGET_SAFE_HINTS) { - new_insn = emit_insn_before (gen_nopn (GEN_INT (127)), insn); - PUT_MODE (new_insn, TImode); - PUT_MODE (insn, VOIDmode); + shorten_branches (get_insns ()); + /* Insert hbrp at beginning of function */ + insn = next_active_insn (get_insns ()); + if (insn) + insert_hbrp_for_ilb_runout (insn); + /* Insert hbrp after hinted targets. */ + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + if ((LABEL_P (insn) && HINTED_P (insn)) || CALL_P (insn)) + insert_hbrp_for_ilb_runout (next_active_insn (insn)); } - else - new_insn = emit_insn_after (gen_lnop (), insn); } -/* Insert nops in basic blocks to meet dual issue alignment - requirements. */ +static int in_spu_reorg; + +/* Insert branch hints. There are no branch optimizations after this + pass, so it's safe to set our branch hints now. */ static void -insert_nops (void) +spu_machine_dependent_reorg (void) { - rtx insn, next_insn, prev_insn; - int length; - int addr; + sbitmap blocks; + basic_block bb; + rtx branch, insn; + rtx branch_target = 0; + int branch_addr = 0, insn_addr, required_dist = 0; + int i; + unsigned int j; - /* This sets up INSN_ADDRESSES. */ - shorten_branches (get_insns ()); + if (!TARGET_BRANCH_HINTS || optimize == 0) + { + /* We still do it for unoptimized code because an external + function might have hinted a call or return. */ + insert_hbrp (); + pad_bb (); + return; + } - /* Keep track of length added by nops. */ - length = 0; + blocks = sbitmap_alloc (last_basic_block); + sbitmap_zero (blocks); - prev_insn = 0; - for (insn = get_insns (); insn; insn = next_insn) + in_spu_reorg = 1; + compute_bb_for_insn (); + + compact_blocks (); + + spu_bb_info = + (struct spu_bb_info *) xcalloc (n_basic_blocks, + sizeof (struct spu_bb_info)); + + /* We need exact insn addresses and lengths. */ + shorten_branches (get_insns ()); + + for (i = n_basic_blocks - 1; i >= 0; i--) { - next_insn = next_active_insn (insn); - addr = INSN_ADDRESSES (INSN_UID (insn)); - if (GET_MODE (insn) == TImode - && next_insn - && GET_MODE (next_insn) != TImode - && ((addr + length) & 7) != 0) + bb = BASIC_BLOCK (i); + branch = 0; + if (spu_bb_info[i].prop_jump) + { + branch = spu_bb_info[i].prop_jump; + branch_target = get_branch_target (branch); + branch_addr = INSN_ADDRESSES (INSN_UID (branch)); + required_dist = spu_hint_dist; + } + /* Search from end of a block to beginning. In this loop, find + jumps which need a branch and emit them only when: + - it's an indirect branch and we're at the insn which sets + the register + - we're at an insn that will invalidate the hint. e.g., a + call, another hint insn, inline asm that clobbers $hbr, and + some inlined operations (divmodsi4). Don't consider jumps + because they are only at the end of a block and are + considered when we are deciding whether to propagate + - we're getting too far away from the branch. The hbr insns + only have a signed 10 bit offset + We go back as far as possible so the branch will be considered + for propagation when we get to the beginning of the block. */ + for (insn = BB_END (bb); insn; insn = PREV_INSN (insn)) { - /* prev_insn will always be set because the first insn is - always 8-byte aligned. */ - emit_nop_for_insn (prev_insn); - length += 4; + if (INSN_P (insn)) + { + insn_addr = INSN_ADDRESSES (INSN_UID (insn)); + if (branch + && ((GET_CODE (branch_target) == REG + && set_of (branch_target, insn) != NULL_RTX) + || insn_clobbers_hbr (insn) + || branch_addr - insn_addr > 600)) + { + rtx next = NEXT_INSN (insn); + int next_addr = INSN_ADDRESSES (INSN_UID (next)); + if (insn != BB_END (bb) + && branch_addr - next_addr >= required_dist) + { + if (dump_file) + fprintf (dump_file, + "hint for %i in block %i before %i\n", + INSN_UID (branch), bb->index, + INSN_UID (next)); + spu_emit_branch_hint (next, branch, branch_target, + branch_addr - next_addr, blocks); + } + branch = 0; + } + + /* JUMP_P will only be true at the end of a block. When + branch is already set it means we've previously decided + to propagate a hint for that branch into this block. */ + if (CALL_P (insn) || (JUMP_P (insn) && !branch)) + { + branch = 0; + if ((branch_target = get_branch_target (insn))) + { + branch = insn; + branch_addr = insn_addr; + required_dist = spu_hint_dist; + } + } + } + if (insn == BB_HEAD (bb)) + break; + } + + if (branch) + { + /* If we haven't emitted a hint for this branch yet, it might + be profitable to emit it in one of the predecessor blocks, + especially for loops. */ + rtx bbend; + basic_block prev = 0, prop = 0, prev2 = 0; + int loop_exit = 0, simple_loop = 0; + int next_addr = INSN_ADDRESSES (INSN_UID (NEXT_INSN (insn))); + + for (j = 0; j < EDGE_COUNT (bb->preds); j++) + if (EDGE_PRED (bb, j)->flags & EDGE_FALLTHRU) + prev = EDGE_PRED (bb, j)->src; + else + prev2 = EDGE_PRED (bb, j)->src; + + for (j = 0; j < EDGE_COUNT (bb->succs); j++) + if (EDGE_SUCC (bb, j)->flags & EDGE_LOOP_EXIT) + loop_exit = 1; + else if (EDGE_SUCC (bb, j)->dest == bb) + simple_loop = 1; + + /* If this branch is a loop exit then propagate to previous + fallthru block. This catches the cases when it is a simple + loop or when there is an initial branch into the loop. */ + if (prev && (loop_exit || simple_loop) + && prev->loop_depth <= bb->loop_depth) + prop = prev; + + /* If there is only one adjacent predecessor. Don't propagate + outside this loop. This loop_depth test isn't perfect, but + I'm not sure the loop_father member is valid at this point. */ + else if (prev && single_pred_p (bb) + && prev->loop_depth == bb->loop_depth) + prop = prev; + + /* If this is the JOIN block of a simple IF-THEN then + propogate the hint to the HEADER block. */ + else if (prev && prev2 + && EDGE_COUNT (bb->preds) == 2 + && EDGE_COUNT (prev->preds) == 1 + && EDGE_PRED (prev, 0)->src == prev2 + && prev2->loop_depth == bb->loop_depth + && GET_CODE (branch_target) != REG) + prop = prev; + + /* Don't propagate when: + - this is a simple loop and the hint would be too far + - this is not a simple loop and there are 16 insns in + this block already + - the predecessor block ends in a branch that will be + hinted + - the predecessor block ends in an insn that invalidates + the hint */ + if (prop + && prop->index >= 0 + && (bbend = BB_END (prop)) + && branch_addr - INSN_ADDRESSES (INSN_UID (bbend)) < + (simple_loop ? 600 : 16 * 4) && get_branch_target (bbend) == 0 + && (JUMP_P (bbend) || !insn_clobbers_hbr (bbend))) + { + if (dump_file) + fprintf (dump_file, "propagate from %i to %i (loop depth %i) " + "for %i (loop_exit %i simple_loop %i dist %i)\n", + bb->index, prop->index, bb->loop_depth, + INSN_UID (branch), loop_exit, simple_loop, + branch_addr - INSN_ADDRESSES (INSN_UID (bbend))); + + spu_bb_info[prop->index].prop_jump = branch; + spu_bb_info[prop->index].bb_index = i; + } + else if (branch_addr - next_addr >= required_dist) + { + if (dump_file) + fprintf (dump_file, "hint for %i in block %i before %i\n", + INSN_UID (branch), bb->index, + INSN_UID (NEXT_INSN (insn))); + spu_emit_branch_hint (NEXT_INSN (insn), branch, branch_target, + branch_addr - next_addr, blocks); + } + branch = 0; } - prev_insn = insn; } -} + free (spu_bb_info); -static void -spu_machine_dependent_reorg (void) -{ - if (optimize > 0) + if (!sbitmap_empty_p (blocks)) + find_many_sub_basic_blocks (blocks); + + /* We have to schedule to make sure alignment is ok. */ + FOR_EACH_BB (bb) bb->flags &= ~BB_DISABLE_SCHEDULE; + + /* The hints need to be scheduled, so call it again. */ + schedule_insns (); + + insert_hbrp (); + + pad_bb (); + + + if (spu_flag_var_tracking) { - if (TARGET_BRANCH_HINTS) - insert_branch_hints (); - insert_nops (); + df_analyze (); + timevar_push (TV_VAR_TRACKING); + variable_tracking_main (); + timevar_pop (TV_VAR_TRACKING); + df_finish_pass (false); } + + free_bb_for_insn (); + + in_spu_reorg = 0; } @@ -2402,15 +2718,14 @@ } static int -spu_sched_variable_issue (FILE * dump ATTRIBUTE_UNUSED, - int verbose ATTRIBUTE_UNUSED, rtx insn, - int can_issue_more) -{ - if (GET_CODE (PATTERN (insn)) != USE - && GET_CODE (PATTERN (insn)) != CLOBBER - && get_pipe (insn) != -2) - can_issue_more--; - return can_issue_more; +uses_ls_unit(rtx insn) +{ + rtx set = single_set (insn); + if (set != 0 + && (GET_CODE (SET_DEST (set)) == MEM + || GET_CODE (SET_SRC (set)) == MEM)) + return 1; + return 0; } static int @@ -2436,7 +2751,6 @@ case TYPE_FPD: case TYPE_FP6: case TYPE_FP7: - case TYPE_IPREFETCH: return 0; case TYPE_LNOP: @@ -2446,41 +2760,332 @@ case TYPE_BR: case TYPE_MULTI1: case TYPE_HBR: + case TYPE_IPREFETCH: return 1; default: abort (); } } + +/* haifa-sched.c has a static variable that keeps track of the current + cycle. It is passed to spu_sched_reorder, and we record it here for + use by spu_sched_variable_issue. It won't be accurate if the + scheduler updates it's clock_var between the two calls. */ +static int clock_var; + +/* This is used to keep track of insn alignment. Set to 0 at the + beginning of each block and increased by the "length" attr of each + insn scheduled. */ +static int spu_sched_length; + +/* Record when we've issued pipe0 and pipe1 insns so we can reorder the + ready list appropriately in spu_sched_reorder(). */ +static int pipe0_clock; +static int pipe1_clock; + +static int prev_clock_var; + +static int prev_priority; + +/* The SPU needs to load the next ilb sometime during the execution of + the previous ilb. There is a potential conflict if every cycle has a + load or store. To avoid the conflict we make sure the load/store + unit is free for at least one cycle during the execution of insns in + the previous ilb. */ +static int spu_ls_first; +static int prev_ls_clock; + +static void +spu_sched_init_global (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, + int max_ready ATTRIBUTE_UNUSED) +{ + spu_sched_length = 0; +} + +static void +spu_sched_init (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, + int max_ready ATTRIBUTE_UNUSED) +{ + if (align_labels > 4 || align_loops > 4 || align_jumps > 4) + { + /* When any block might be at least 8-byte aligned, assume they + will all be at least 8-byte aligned to make sure dual issue + works out correctly. */ + spu_sched_length = 0; + } + spu_ls_first = INT_MAX; + clock_var = -1; + prev_ls_clock = -1; + pipe0_clock = -1; + pipe1_clock = -1; + prev_clock_var = -1; + prev_priority = -1; +} + static int -spu_sched_adjust_priority (rtx insn, int pri) +spu_sched_variable_issue (FILE *file ATTRIBUTE_UNUSED, + int verbose ATTRIBUTE_UNUSED, rtx insn, int more) { - int p = get_pipe (insn); - /* Schedule UNSPEC_CONVERT's early so they have less effect on - * scheduling. */ + int len; + int p; if (GET_CODE (PATTERN (insn)) == USE || GET_CODE (PATTERN (insn)) == CLOBBER - || p == -2) - return pri + 100; - /* Schedule pipe0 insns early for greedier dual issue. */ - if (p != 1) - return pri + 50; - return pri; + || (len = get_attr_length (insn)) == 0) + return more; + + spu_sched_length += len; + + /* Reset on inline asm */ + if (INSN_CODE (insn) == -1) + { + spu_ls_first = INT_MAX; + pipe0_clock = -1; + pipe1_clock = -1; + return 0; + } + p = get_pipe (insn); + if (p == 0) + pipe0_clock = clock_var; + else + pipe1_clock = clock_var; + + if (in_spu_reorg) + { + if (clock_var - prev_ls_clock > 1 + || INSN_CODE (insn) == CODE_FOR_iprefetch) + spu_ls_first = INT_MAX; + if (uses_ls_unit (insn)) + { + if (spu_ls_first == INT_MAX) + spu_ls_first = spu_sched_length; + prev_ls_clock = clock_var; + } + + /* The scheduler hasn't inserted the nop, but we will later on. + Include those nops in spu_sched_length. */ + if (prev_clock_var == clock_var && (spu_sched_length & 7)) + spu_sched_length += 4; + prev_clock_var = clock_var; + + /* more is -1 when called from spu_sched_reorder for new insns + that don't have INSN_PRIORITY */ + if (more >= 0) + prev_priority = INSN_PRIORITY (insn); + } + + /* Always try issueing more insns. spu_sched_reorder will decide + when the cycle should be advanced. */ + return 1; +} + +/* This function is called for both TARGET_SCHED_REORDER and + TARGET_SCHED_REORDER2. */ +static int +spu_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, + rtx *ready, int *nreadyp, int clock) +{ + int i, nready = *nreadyp; + int pipe_0, pipe_1, pipe_hbrp, pipe_ls, schedule_i; + rtx insn; + + clock_var = clock; + + if (nready <= 0 || pipe1_clock >= clock) + return 0; + + /* Find any rtl insns that don't generate assembly insns and schedule + them first. */ + for (i = nready - 1; i >= 0; i--) + { + insn = ready[i]; + if (INSN_CODE (insn) == -1 + || INSN_CODE (insn) == CODE_FOR_blockage + || INSN_CODE (insn) == CODE_FOR__spu_convert) + { + ready[i] = ready[nready - 1]; + ready[nready - 1] = insn; + return 1; + } + } + + pipe_0 = pipe_1 = pipe_hbrp = pipe_ls = schedule_i = -1; + for (i = 0; i < nready; i++) + if (INSN_CODE (ready[i]) != -1) + { + insn = ready[i]; + switch (get_attr_type (insn)) + { + default: + case TYPE_MULTI0: + case TYPE_CONVERT: + case TYPE_FX2: + case TYPE_FX3: + case TYPE_SPR: + case TYPE_NOP: + case TYPE_FXB: + case TYPE_FPD: + case TYPE_FP6: + case TYPE_FP7: + pipe_0 = i; + break; + case TYPE_LOAD: + case TYPE_STORE: + pipe_ls = i; + case TYPE_LNOP: + case TYPE_SHUF: + case TYPE_BR: + case TYPE_MULTI1: + case TYPE_HBR: + pipe_1 = i; + break; + case TYPE_IPREFETCH: + pipe_hbrp = i; + break; + } + } + + /* In the first scheduling phase, schedule loads and stores together + to increase the chance they will get merged during postreload CSE. */ + if (!reload_completed && pipe_ls >= 0) + { + insn = ready[pipe_ls]; + ready[pipe_ls] = ready[nready - 1]; + ready[nready - 1] = insn; + return 1; + } + + /* If there is an hbrp ready, prefer it over other pipe 1 insns. */ + if (pipe_hbrp >= 0) + pipe_1 = pipe_hbrp; + + /* When we have loads/stores in every cycle of the last 15 insns and + we are about to schedule another load/store, emit an hbrp insn + instead. */ + if (in_spu_reorg + && spu_sched_length - spu_ls_first >= 4 * 15 + && !(pipe0_clock < clock && pipe_0 >= 0) && pipe_1 == pipe_ls) + { + insn = sched_emit_insn (gen_iprefetch (GEN_INT (3))); + recog_memoized (insn); + if (pipe0_clock < clock) + PUT_MODE (insn, TImode); + spu_sched_variable_issue (file, verbose, insn, -1); + return 0; + } + + /* In general, we want to emit nops to increase dual issue, but dual + issue isn't faster when one of the insns could be scheduled later + without effecting the critical path. We look at INSN_PRIORITY to + make a good guess, but it isn't perfect so -mdual-nops=n can be + used to effect it. */ + if (in_spu_reorg && spu_dual_nops < 10) + { + /* When we are at an even address and we are not issueing nops to + improve scheduling then we need to advance the cycle. */ + if ((spu_sched_length & 7) == 0 && prev_clock_var == clock + && (spu_dual_nops == 0 + || (pipe_1 != -1 + && prev_priority > + INSN_PRIORITY (ready[pipe_1]) + spu_dual_nops))) + return 0; + + /* When at an odd address, schedule the highest priority insn + without considering pipeline. */ + if ((spu_sched_length & 7) == 4 && prev_clock_var != clock + && (spu_dual_nops == 0 + || (prev_priority > + INSN_PRIORITY (ready[nready - 1]) + spu_dual_nops))) + return 1; + } + + + /* We haven't issued a pipe0 insn yet this cycle, if there is a + pipe0 insn in the ready list, schedule it. */ + if (pipe0_clock < clock && pipe_0 >= 0) + schedule_i = pipe_0; + + /* Either we've scheduled a pipe0 insn already or there is no pipe0 + insn to schedule. Put a pipe1 insn at the front of the ready list. */ + else + schedule_i = pipe_1; + + if (schedule_i > -1) + { + insn = ready[schedule_i]; + ready[schedule_i] = ready[nready - 1]; + ready[nready - 1] = insn; + return 1; + } + return 0; } /* INSN is dependent on DEP_INSN. */ static int -spu_sched_adjust_cost (rtx insn, rtx link ATTRIBUTE_UNUSED, - rtx dep_insn ATTRIBUTE_UNUSED, int cost) +spu_sched_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost) { - if (GET_CODE (insn) == CALL_INSN) + rtx set; + + /* The blockage pattern is used to prevent instructions from being + moved across it and has no cost. */ + if (INSN_CODE (insn) == CODE_FOR_blockage + || INSN_CODE (dep_insn) == CODE_FOR_blockage) + return 0; + + if (INSN_CODE (insn) == CODE_FOR__spu_convert + || INSN_CODE (dep_insn) == CODE_FOR__spu_convert) + return 0; + + /* Make sure hbrps are spread out. */ + if (INSN_CODE (insn) == CODE_FOR_iprefetch + && INSN_CODE (dep_insn) == CODE_FOR_iprefetch) + return 8; + + /* Make sure hints and hbrps are 2 cycles apart. */ + if ((INSN_CODE (insn) == CODE_FOR_iprefetch + || INSN_CODE (insn) == CODE_FOR_hbr) + && (INSN_CODE (dep_insn) == CODE_FOR_iprefetch + || INSN_CODE (dep_insn) == CODE_FOR_hbr)) + return 2; + + /* An hbrp has no real dependency on other insns. */ + if (INSN_CODE (insn) == CODE_FOR_iprefetch + || INSN_CODE (dep_insn) == CODE_FOR_iprefetch) + return 0; + + /* Assuming that it is unlikely an argument register will be used in + the first cycle of the called function, we reduce the cost for + slightly better scheduling of dep_insn. When not hinted, the + mispredicted branch would hide the cost as well. */ + if (CALL_P (insn)) + { + rtx target = get_branch_target (insn); + if (GET_CODE (target) != REG || !set_of (target, insn)) + return cost - 2; + return cost; + } + + /* And when returning from a function, let's assume the return values + are completed sooner too. */ + if (CALL_P (dep_insn)) return cost - 2; + + /* Make sure an instruction that loads from the back chain is schedule + away from the return instruction so a hint is more likely to get + issued. */ + if (INSN_CODE (insn) == CODE_FOR__return + && (set = single_set (dep_insn)) + && GET_CODE (SET_DEST (set)) == REG + && REGNO (SET_DEST (set)) == LINK_REGISTER_REGNUM) + return 20; + /* The dfa scheduler sets cost to 0 for all anti-dependencies and the scheduler makes every insn in a block anti-dependent on the final jump_insn. We adjust here so higher cost insns will get scheduled earlier. */ - if (GET_CODE (insn) == JUMP_INSN && REG_NOTE_KIND (link) == REG_DEP_ANTI) + if (JUMP_P (insn) && REG_NOTE_KIND (link) == REG_DEP_ANTI) return insn_cost (dep_insn) - 3; + return cost; } @@ -5601,3 +6206,17 @@ for shift counts. */ return SImode; } + +/* An early place to adjust some flags after GCC has finished processing + * them. */ +static void +asm_file_start (void) +{ + /* Variable tracking should be run after all optimizations which + change order of insns. It also needs a valid CFG. */ + spu_flag_var_tracking = flag_var_tracking; + flag_var_tracking = 0; + + default_file_start (); +} + diff -Naur gcc-4.3.2.orig/gcc/config/spu/spu.h gcc-4.3.2/gcc/config/spu/spu.h --- gcc-4.3.2.orig/gcc/config/spu/spu.h 2008-08-12 06:07:53.000000000 -0700 +++ gcc-4.3.2/gcc/config/spu/spu.h 2008-09-09 14:17:19.000000000 -0700 @@ -50,7 +50,8 @@ /* Default target_flags if no switches specified. */ #ifndef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_ERROR_RELOC | MASK_SAFE_DMA | MASK_BRANCH_HINTS) +#define TARGET_DEFAULT (MASK_ERROR_RELOC | MASK_SAFE_DMA | MASK_BRANCH_HINTS \ + | MASK_SAFE_HINTS) #endif diff -Naur gcc-4.3.2.orig/gcc/config/spu/spu.md gcc-4.3.2/gcc/config/spu/spu.md --- gcc-4.3.2.orig/gcc/config/spu/spu.md 2008-08-19 09:37:13.000000000 -0700 +++ gcc-4.3.2/gcc/config/spu/spu.md 2008-09-09 14:17:19.000000000 -0700 @@ -4249,12 +4249,23 @@ "lnop" [(set_attr "type" "lnop")]) +;; The operand is so we know why we generated this hbrp. +;; We clobber mem to make sure it isn't moved over any +;; loads, stores or calls while scheduling. (define_insn "iprefetch" - [(unspec [(const_int 0)] UNSPEC_IPREFETCH)] + [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH) + (clobber (mem:BLK (scratch)))] "" - "hbrp" + "hbrp\t# %0" [(set_attr "type" "iprefetch")]) +;; A non-volatile version so it gets scheduled +(define_insn "nopn_nv" + [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_NOP)] + "" + "nop\t%0" + [(set_attr "type" "nop")]) + (define_insn "hbr" [(set (reg:SI 130) (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i") diff -Naur gcc-4.3.2.orig/gcc/config/spu/spu.opt gcc-4.3.2/gcc/config/spu/spu.opt --- gcc-4.3.2.orig/gcc/config/spu/spu.opt 2007-08-02 03:49:31.000000000 -0700 +++ gcc-4.3.2/gcc/config/spu/spu.opt 2008-09-09 14:17:19.000000000 -0700 @@ -35,6 +35,14 @@ Target Report RejectNegative InverseMask(SAFE_DMA) volatile must be specified on any memory that is effected by DMA +mdual-nops +Target Report Var(spu_dual_nops,10) Init(10) +Insert nops when it might improve performance by allowing dual issue (default) + +mdual-nops= +Target RejectNegative Joined UInteger Var(spu_dual_nops) +Insert nops when it might improve performance by allowing dual issue (default) + mstdmain Target Report Mask(STD_MAIN) Use standard main function as entry for startup @@ -43,6 +51,14 @@ Target Report Mask(BRANCH_HINTS) Generate branch hints for branches +mhint-max-nops= +Target RejectNegative Joined UInteger Var(spu_max_nops) Init(2) +Maximum number of nops to insert for a hint (Default 2) + +mhint-max-distance= +Target RejectNegative Joined Var(spu_max_distance_str) +Approximate maximum number of instructions to allow between a hint and its branch [125] + msmall-mem Target Report RejectNegative InverseMask(LARGE_MEM) Generate code for 18 bit addressing @@ -55,6 +71,10 @@ Target RejectNegative Joined Var(spu_fixed_range_string) Specify range of registers to make fixed +msafe-hints +Target Report Mask(SAFE_HINTS) +Insert hbrp instructions after hinted branch targets to avoid the SPU hang issue + march= Target RejectNegative Joined Var(spu_arch_string) Generate code for given CPU diff -Naur gcc-4.3.2.orig/gcc/config/spu/spu_mfcio.h gcc-4.3.2/gcc/config/spu/spu_mfcio.h --- gcc-4.3.2.orig/gcc/config/spu/spu_mfcio.h 2008-08-05 07:06:09.000000000 -0700 +++ gcc-4.3.2/gcc/config/spu/spu_mfcio.h 2008-08-28 12:45:39.000000000 -0700 @@ -289,6 +289,34 @@ #define spu_write_srr0(srr0) spu_writech(SPU_WrSRR0,srr0) #define spu_read_srr0() spu_readch(SPU_RdSRR0) +/* Interrupt-Safe Critical Sections */ + +static __inline__ unsigned int mfc_begin_critical_section (void) + __attribute__ ((__always_inline__)); + +static __inline__ unsigned int +mfc_begin_critical_section (void) +{ +#ifdef SPU_MFCIO_INTERRUPT_SAFE + unsigned int __status = spu_read_machine_status (); + spu_idisable (); + return __status; +#else + return 0; +#endif +} + +static __inline__ void mfc_end_critical_section (unsigned int) + __attribute__ ((__always_inline__)); + +static __inline__ void +mfc_end_critical_section (unsigned int __status __attribute__ ((__unused__))) +{ +#ifdef SPU_MFCIO_INTERRUPT_SAFE + if (__status & 1) + spu_ienable (); +#endif +} /* MFC Tag Manager */ diff -Naur gcc-4.3.2.orig/gcc/config/spu/t-spu-elf gcc-4.3.2/gcc/config/spu/t-spu-elf --- gcc-4.3.2.orig/gcc/config/spu/t-spu-elf 2008-08-19 09:37:13.000000000 -0700 +++ gcc-4.3.2/gcc/config/spu/t-spu-elf 2008-11-14 14:28:54.000000000 -0800 @@ -14,6 +14,9 @@ # along with GCC; see the file COPYING3. If not see # . +# Define system directory to match STANDARD_INCLUDE_DIR in spu-elf.h, +# allowing combined SPU/PPU sysroot builds. +NATIVE_SYSTEM_HEADER_DIR = /include # Suppress building libgcc1.a LIBGCC1 = diff -Naur gcc-4.3.2.orig/gcc/config/xtensa/xtensa.md gcc-4.3.2/gcc/config/xtensa/xtensa.md --- gcc-4.3.2.orig/gcc/config/xtensa/xtensa.md 2007-12-20 14:35:59.000000000 -0800 +++ gcc-4.3.2/gcc/config/xtensa/xtensa.md 2008-09-02 10:26:57.000000000 -0700 @@ -217,10 +217,11 @@ (any_extend:DI (match_operand:SI 2 "register_operand"))))] "TARGET_MUL32_HIGH" { - emit_insn (gen_mulsi3 (gen_lowpart (SImode, operands[0]), - operands[1], operands[2])); + rtx temp = gen_reg_rtx (SImode); + emit_insn (gen_mulsi3 (temp, operands[1], operands[2])); emit_insn (gen_mulsi3_highpart (gen_highpart (SImode, operands[0]), operands[1], operands[2])); + emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), temp)); DONE; }) diff -Naur gcc-4.3.2.orig/gcc/config.gcc gcc-4.3.2/gcc/config.gcc --- gcc-4.3.2.orig/gcc/config.gcc 2008-06-09 09:32:15.000000000 -0700 +++ gcc-4.3.2/gcc/config.gcc 2008-11-20 09:09:53.000000000 -0800 @@ -1266,7 +1266,7 @@ ;; esac tm_file="${tm_file} i386/sol2.h" - tmake_file="t-sol2 i386/t-sol2 t-svr4" + tmake_file="t-sol2 t-svr4" c_target_objs="sol2-c.o" cxx_target_objs="sol2-c.o" extra_objs="sol2.o" @@ -1289,7 +1289,10 @@ *-*-solaris2.1[0-9]*) tm_file="${tm_file} i386/x86-64.h i386/sol2-10.h" tm_defines="${tm_defines} TARGET_BI_ARCH=1" - tmake_file="$tmake_file i386/t-crtstuff i386/t-sol2-10" + tmake_file="$tmake_file i386/t-sol2-10" + # i386/t-crtstuff only affects libgcc. Its inclusion + # depends on a runtime test and is thus performed in + # libgcc/configure.ac instead. need_64bit_hwint=yes # FIXME: -m64 for i[34567]86-*-* should be allowed just # like -m32 for x86_64-*-*. @@ -1305,12 +1308,6 @@ exit 1 ;; esac - # Solaris 2.10 provides crt1.o, crti.o, crtn.o, and gcrt1.o as - # part of the base system. - extra_parts="gmon.o crtbegin.o crtend.o" - ;; - *) - extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o" ;; esac case ${enable_threads}:${have_pthread_h}:${have_thread_h} in diff -Naur gcc-4.3.2.orig/gcc/cp/ChangeLog gcc-4.3.2/gcc/cp/ChangeLog --- gcc-4.3.2.orig/gcc/cp/ChangeLog 2008-08-27 11:02:45.000000000 -0700 +++ gcc-4.3.2/gcc/cp/ChangeLog 2008-12-04 15:00:19.000000000 -0800 @@ -1,3 +1,68 @@ +2008-12-04 Janis Johnson + + Backport from mainline: + 2008-10-18 Jakub Jelinek + Janis Johnson + + * Make-lang.in (check-c++-subtargets): New alias for + check-g++-subtargets. + (lang_checks_parallelized): Add check-g++. + (check_g++_parallelize): New variable. + +2008-11-19 Dodji Seketeli + + PR c++/37142 + * pt.c (coerce_template_template_parm): Use the more robust + uses_template_parms instead of dependent_type_p. + +2008-11-19 Dodji Seketeli + + PR c++/35405 + * pt.c (lookup_template_class): Check pointers before dereferencing + Them. + * error.c (dump_template_decl): Likewise. + +2008-11-19 Jason Merrill + + PR c++/37563 + * parser.c (cp_parser_pseudo_destructor_name): A pseudo-destructor + name is not a declaration. + +2008-11-14 Jason Merrill + + PR c++/38030 + * semantics.c (finish_call_expr): Don't repeat arg-dep lookup + for a non-dependent call. + +2008-11-13 Jason Merrill + + PR c++/37932 + * typeck2.c (process_init_constructor_record): Update bitfield + handling. + +2008-11-12 Jason Merrill + + PR c++/38007 + * typeck.c (cp_build_modify_expr): Update bitfield handling. + +2008-09-30 Simon Martin + + PR c++/37555 + * decl.c (grokdeclarator): Set the type for typedefs to a + nested-name-specifier to error_mark_node. + +2008-09-09 Jakub Jelinek + + PR c++/37389 + * decl.c (build_enumerator): Handle previous value's DECL_INITIAL + being error_operand_p. + +2008-09-03 Jakub Jelinek + + PR c++/37348 + * decl.c (cp_finish_decl): Only set + DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P if decl is VAR_DECL. + 2008-08-27 Release Manager * GCC 4.3.2 released. diff -Naur gcc-4.3.2.orig/gcc/cp/Make-lang.in gcc-4.3.2/gcc/cp/Make-lang.in --- gcc-4.3.2.orig/gcc/cp/Make-lang.in 2008-02-27 01:26:24.000000000 -0800 +++ gcc-4.3.2/gcc/cp/Make-lang.in 2008-12-04 15:00:19.000000000 -0800 @@ -136,8 +136,12 @@ # check targets. However, our DejaGNU framework requires 'check-g++' as its # entry point. We feed the former to the latter here. check-c++ : check-g++ +check-c++-subtargets : check-g++-subtargets # List of targets that can use the generic check- rule and its // variant. lang_checks += check-g++ +lang_checks_parallelized += check-g++ +# For description see comment above check_gcc_parallelize in gcc/Makefile.in. +check_g++_parallelize = old-deja.exp dg.exp # # Install hooks: diff -Naur gcc-4.3.2.orig/gcc/cp/decl.c gcc-4.3.2/gcc/cp/decl.c --- gcc-4.3.2.orig/gcc/cp/decl.c 2008-07-07 13:42:03.000000000 -0700 +++ gcc-4.3.2/gcc/cp/decl.c 2008-09-30 12:56:13.000000000 -0700 @@ -5415,7 +5415,7 @@ DECL_INITIAL (decl) = NULL_TREE; } - if (init && init_const_expr_p) + if (init && init_const_expr_p && TREE_CODE (decl) == VAR_DECL) { DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1; if (DECL_INTEGRAL_CONSTANT_VAR_P (decl)) @@ -8544,8 +8544,10 @@ decl = build_lang_decl (TYPE_DECL, unqualified_id, type); else decl = build_decl (TYPE_DECL, unqualified_id, type); - if (id_declarator && declarator->u.id.qualifying_scope) + if (id_declarator && declarator->u.id.qualifying_scope) { error ("%Jtypedef name may not be a nested-name-specifier", decl); + TREE_TYPE (decl) = error_mark_node; + } if (decl_context != FIELD) { @@ -10923,21 +10925,26 @@ tree prev_value; bool overflowed; - /* The next value is the previous value plus one. We can - safely assume that the previous value is an INTEGER_CST. + /* The next value is the previous value plus one. add_double doesn't know the type of the target expression, so we must check with int_fits_type_p as well. */ prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype))); - overflowed = add_double (TREE_INT_CST_LOW (prev_value), - TREE_INT_CST_HIGH (prev_value), - 1, 0, &lo, &hi); - value = build_int_cst_wide (TREE_TYPE (prev_value), lo, hi); - overflowed |= !int_fits_type_p (value, TREE_TYPE (prev_value)); - - if (overflowed) + if (error_operand_p (prev_value)) + value = error_mark_node; + else { - error ("overflow in enumeration values at %qD", name); - value = error_mark_node; + overflowed = add_double (TREE_INT_CST_LOW (prev_value), + TREE_INT_CST_HIGH (prev_value), + 1, 0, &lo, &hi); + value = build_int_cst_wide (TREE_TYPE (prev_value), lo, hi); + overflowed + |= !int_fits_type_p (value, TREE_TYPE (prev_value)); + + if (overflowed) + { + error ("overflow in enumeration values at %qD", name); + value = error_mark_node; + } } } else diff -Naur gcc-4.3.2.orig/gcc/cp/error.c gcc-4.3.2/gcc/cp/error.c --- gcc-4.3.2.orig/gcc/cp/error.c 2008-08-19 04:50:11.000000000 -0700 +++ gcc-4.3.2/gcc/cp/error.c 2008-11-19 14:36:31.000000000 -0800 @@ -1036,11 +1036,13 @@ } } - if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) + if (DECL_TEMPLATE_RESULT (t) + && TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) dump_type (TREE_TYPE (t), ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0))); - else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL) + else if (DECL_TEMPLATE_RESULT (t) + && TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL) dump_decl (DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME); else { diff -Naur gcc-4.3.2.orig/gcc/cp/parser.c gcc-4.3.2/gcc/cp/parser.c --- gcc-4.3.2.orig/gcc/cp/parser.c 2008-08-07 05:27:48.000000000 -0700 +++ gcc-4.3.2/gcc/cp/parser.c 2008-11-19 13:00:23.000000000 -0800 @@ -5143,7 +5143,7 @@ /*typename_keyword_p=*/false, /*check_dependency_p=*/true, /*type_p=*/false, - /*is_declaration=*/true) + /*is_declaration=*/false) != NULL_TREE); /* Now, if we saw a nested-name-specifier, we might be doing the second production. */ diff -Naur gcc-4.3.2.orig/gcc/cp/pt.c gcc-4.3.2/gcc/cp/pt.c --- gcc-4.3.2.orig/gcc/cp/pt.c 2008-04-30 08:04:56.000000000 -0700 +++ gcc-4.3.2/gcc/cp/pt.c 2008-11-19 16:05:04.000000000 -0800 @@ -4709,7 +4709,7 @@ D d; i.e. the parameter list of TT depends on earlier parameters. */ - if (!dependent_type_p (TREE_TYPE (arg)) + if (!uses_template_parms (TREE_TYPE (arg)) && !same_type_p (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl), TREE_TYPE (arg))) @@ -5504,6 +5504,7 @@ d1 = DECL_NAME (template); } else if (TREE_CODE (d1) == TEMPLATE_DECL + && DECL_TEMPLATE_RESULT (d1) && TREE_CODE (DECL_TEMPLATE_RESULT (d1)) == TYPE_DECL) { template = d1; diff -Naur gcc-4.3.2.orig/gcc/cp/semantics.c gcc-4.3.2/gcc/cp/semantics.c --- gcc-4.3.2.orig/gcc/cp/semantics.c 2008-06-10 23:47:36.000000000 -0700 +++ gcc-4.3.2/gcc/cp/semantics.c 2008-11-14 14:01:12.000000000 -0800 @@ -1972,7 +1972,9 @@ if (processing_template_decl) { result = build_call_list (TREE_TYPE (result), orig_fn, orig_args); - KOENIG_LOOKUP_P (result) = koenig_p; + /* Don't repeat arg-dependent lookup at instantiation time if this call + is not type-dependent. */ + KOENIG_LOOKUP_P (result) = 0; } return result; } diff -Naur gcc-4.3.2.orig/gcc/cp/typeck.c gcc-4.3.2/gcc/cp/typeck.c --- gcc-4.3.2.orig/gcc/cp/typeck.c 2008-04-29 01:56:27.000000000 -0700 +++ gcc-4.3.2/gcc/cp/typeck.c 2008-11-12 14:08:01.000000000 -0800 @@ -5650,7 +5650,6 @@ tree newrhs = rhs; tree lhstype = TREE_TYPE (lhs); tree olhstype = lhstype; - tree olhs = NULL_TREE; bool plain_assign = (modifycode == NOP_EXPR); /* Avoid duplicate error messages from operands that had errors. */ @@ -5839,35 +5838,11 @@ && C_TYPE_FIELDS_READONLY (lhstype)))) readonly_error (lhs, "assignment"); - /* If storing into a structure or union member, it has probably been - given type `int'. Compute the type that would go with the actual - amount of storage the member occupies. */ + /* If storing into a structure or union member, it may have been given a + lowered bitfield type. We need to convert to the declared type first, + so retrieve it now. */ - if (TREE_CODE (lhs) == COMPONENT_REF - && (TREE_CODE (lhstype) == INTEGER_TYPE - || TREE_CODE (lhstype) == REAL_TYPE - || TREE_CODE (lhstype) == ENUMERAL_TYPE)) - { - lhstype = TREE_TYPE (get_unwidened (lhs, 0)); - - /* If storing in a field that is in actuality a short or narrower - than one, we must store in the field in its actual type. */ - - if (lhstype != TREE_TYPE (lhs)) - { - /* Avoid warnings converting integral types back into enums for - enum bit fields. */ - if (TREE_CODE (lhstype) == INTEGER_TYPE - && TREE_CODE (olhstype) == ENUMERAL_TYPE) - { - if (TREE_SIDE_EFFECTS (lhs)) - lhs = stabilize_reference (lhs); - olhs = lhs; - } - lhs = copy_node (lhs); - TREE_TYPE (lhs) = lhstype; - } - } + olhstype = unlowered_expr_type (lhs); /* Convert new value to destination type. */ @@ -5903,21 +5878,17 @@ } if (modifycode == INIT_EXPR) - newrhs = convert_for_initialization (lhs, lhstype, newrhs, LOOKUP_NORMAL, + newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL, "initialization", NULL_TREE, 0); else + newrhs = convert_for_assignment (olhstype, newrhs, "assignment", + NULL_TREE, 0); + + if (!same_type_p (lhstype, olhstype)) + newrhs = cp_convert_and_check (lhstype, newrhs); + + if (modifycode != INIT_EXPR) { - /* Avoid warnings on enum bit fields. */ - if (TREE_CODE (olhstype) == ENUMERAL_TYPE - && TREE_CODE (lhstype) == INTEGER_TYPE) - { - newrhs = convert_for_assignment (olhstype, newrhs, "assignment", - NULL_TREE, 0); - newrhs = convert_force (lhstype, newrhs, 0); - } - else - newrhs = convert_for_assignment (lhstype, newrhs, "assignment", - NULL_TREE, 0); if (TREE_CODE (newrhs) == CALL_EXPR && TYPE_NEEDS_CONSTRUCTING (lhstype)) newrhs = build_cplus_new (lhstype, newrhs); @@ -5949,21 +5920,7 @@ if (!plain_assign) TREE_NO_WARNING (result) = 1; - /* If we got the LHS in a different type for storing in, - convert the result back to the nominal type of LHS - so that the value we return always has the same type - as the LHS argument. */ - - if (olhstype == TREE_TYPE (result)) - return result; - if (olhs) - { - result = build2 (COMPOUND_EXPR, olhstype, result, olhs); - TREE_NO_WARNING (result) = 1; - return result; - } - return convert_for_assignment (olhstype, result, "assignment", - NULL_TREE, 0); + return result; } tree diff -Naur gcc-4.3.2.orig/gcc/cp/typeck2.c gcc-4.3.2/gcc/cp/typeck2.c --- gcc-4.3.2.orig/gcc/cp/typeck2.c 2008-02-03 19:28:53.000000000 -0800 +++ gcc-4.3.2/gcc/cp/typeck2.c 2008-11-13 20:16:07.000000000 -0800 @@ -895,6 +895,7 @@ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) { tree next; + tree type; if (!DECL_NAME (field) && DECL_C_BIT_FIELD (field)) { @@ -906,6 +907,11 @@ if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field)) continue; + /* If this is a bitfield, first convert to the declared type. */ + type = TREE_TYPE (field); + if (DECL_BIT_FIELD_TYPE (field)) + type = DECL_BIT_FIELD_TYPE (field); + if (idx < VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init))) { constructor_elt *ce = VEC_index (constructor_elt, @@ -926,7 +932,7 @@ } gcc_assert (ce->value); - next = digest_init (TREE_TYPE (field), ce->value); + next = digest_init (type, ce->value); ++idx; } else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field))) @@ -969,6 +975,9 @@ continue; } + /* If this is a bitfield, now convert to the lowered type. */ + if (type != TREE_TYPE (field)) + next = cp_convert_and_check (TREE_TYPE (field), next); flags |= picflag_from_initializer (next); CONSTRUCTOR_APPEND_ELT (v, field, next); } diff -Naur gcc-4.3.2.orig/gcc/cse.c gcc-4.3.2/gcc/cse.c --- gcc-4.3.2.orig/gcc/cse.c 2008-03-19 03:06:52.000000000 -0700 +++ gcc-4.3.2/gcc/cse.c 2008-12-04 13:49:29.000000000 -0800 @@ -1363,17 +1363,6 @@ struct table_elt *p = lookup (x, SAFE_HASH (x, VOIDmode), GET_MODE (x)); - /* If we are looking for a CONST_INT, the mode doesn't really matter, as - long as we are narrowing. So if we looked in vain for a mode narrower - than word_mode before, look for word_mode now. */ - if (p == 0 && code == CONST_INT - && GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (word_mode)) - { - x = copy_rtx (x); - PUT_MODE (x, word_mode); - p = lookup (x, SAFE_HASH (x, VOIDmode), word_mode); - } - if (p == 0) return 0; @@ -3182,17 +3171,24 @@ if (const_arg0 == 0 || const_arg1 == 0) { struct table_elt *p0, *p1; - rtx true_rtx = const_true_rtx, false_rtx = const0_rtx; + rtx true_rtx, false_rtx; enum machine_mode mode_arg1; -#ifdef FLOAT_STORE_FLAG_VALUE if (SCALAR_FLOAT_MODE_P (mode)) { +#ifdef FLOAT_STORE_FLAG_VALUE true_rtx = (CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode), mode)); +#else + true_rtx = NULL_RTX; +#endif false_rtx = CONST0_RTX (mode); } -#endif + else + { + true_rtx = const_true_rtx; + false_rtx = const0_rtx; + } code = find_comparison_args (code, &folded_arg0, &folded_arg1, &mode_arg0, &mode_arg1); @@ -3300,8 +3296,17 @@ const_arg1)) || (REG_P (folded_arg1) && (REG_QTY (REGNO (folded_arg1)) == ent->comparison_qty)))) - return (comparison_dominates_p (ent->comparison_code, code) - ? true_rtx : false_rtx); + { + if (comparison_dominates_p (ent->comparison_code, code)) + { + if (true_rtx) + return true_rtx; + else + break; + } + else + return false_rtx; + } } } } @@ -3489,6 +3494,11 @@ && exact_log2 (- INTVAL (const_arg1)) >= 0))) break; + /* ??? Vector mode shifts by scalar + shift operand are not supported yet. */ + if (is_shift && VECTOR_MODE_P (mode)) + break; + if (is_shift && (INTVAL (inner_const) >= GET_MODE_BITSIZE (mode) || INTVAL (inner_const) < 0)) @@ -3605,6 +3615,8 @@ if (GET_CODE (x) == SUBREG) { + enum machine_mode mode = GET_MODE (x); + enum machine_mode imode = GET_MODE (SUBREG_REG (x)); rtx new; /* See if we previously assigned a constant value to this SUBREG. */ @@ -3613,10 +3625,25 @@ || (new = lookup_as_function (x, CONST_FIXED)) != 0) return new; + /* If we didn't and if doing so makes sense, see if we previously + assigned a constant value to the enclosing word mode SUBREG. */ + if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode) + && GET_MODE_SIZE (word_mode) < GET_MODE_SIZE (imode)) + { + int byte = SUBREG_BYTE (x) - subreg_lowpart_offset (mode, word_mode); + if (byte >= 0 && (byte % UNITS_PER_WORD) == 0) + { + rtx y = gen_rtx_SUBREG (word_mode, SUBREG_REG (x), byte); + new = lookup_as_function (y, CONST_INT); + if (new) + return gen_lowpart (mode, new); + } + } + + /* Otherwise see if we already have a constant for the inner REG. */ if (REG_P (SUBREG_REG (x)) && (new = equiv_constant (SUBREG_REG (x))) != 0) - return simplify_subreg (GET_MODE (x), SUBREG_REG (x), - GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); + return simplify_subreg (mode, new, imode, SUBREG_BYTE (x)); return 0; } diff -Naur gcc-4.3.2.orig/gcc/df-scan.c gcc-4.3.2/gcc/df-scan.c --- gcc-4.3.2.orig/gcc/df-scan.c 2008-07-01 07:05:13.000000000 -0700 +++ gcc-4.3.2/gcc/df-scan.c 2008-11-24 00:36:43.000000000 -0800 @@ -3171,7 +3171,22 @@ } BITMAP_FREE (defs_generated); - return; + +#ifdef EH_USES + if ((flags & DF_REF_CONDITIONAL) == 0 + && find_reg_note (insn, REG_NORETURN, 0)) + { + unsigned int i; + /* This code is putting in an artificial ref for the use at the + BOTTOM of the block with noreturn call, as EH_USES registers need + to be live until epilogue or noreturn call, for debugging purposes + as well as any insns that might throw. */ + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + if (EH_USES (i)) + df_ref_record (collection_rec, regno_reg_rtx[i], + NULL, bb, NULL, DF_REF_REG_USE, 0); + } +#endif } /* Collect all refs in the INSN. This function is free of any @@ -3592,16 +3607,6 @@ /* These registers are live everywhere. */ if (!reload_completed) { -#ifdef EH_USES - /* The ia-64, the only machine that uses this, does not define these - until after reload. */ - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (EH_USES (i)) - { - bitmap_set_bit (entry_block_defs, i); - } -#endif - #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM /* Pseudos with argument area equivalences may require reloading via the argument pointer. */ diff -Naur gcc-4.3.2.orig/gcc/dfp.c gcc-4.3.2/gcc/dfp.c --- gcc-4.3.2.orig/gcc/dfp.c 2008-06-17 02:32:34.000000000 -0700 +++ gcc-4.3.2/gcc/dfp.c 2008-09-18 11:33:58.000000000 -0700 @@ -50,8 +50,6 @@ memset (r, 0, sizeof (REAL_VALUE_TYPE)); r->cl = rvc_normal; - if (decNumberIsZero (dn)) - r->cl = rvc_zero; if (decNumberIsNaN (dn)) r->cl = rvc_nan; if (decNumberIsInfinite (dn)) diff -Naur gcc-4.3.2.orig/gcc/doc/invoke.texi gcc-4.3.2/gcc/doc/invoke.texi --- gcc-4.3.2.orig/gcc/doc/invoke.texi 2008-06-24 18:37:53.000000000 -0700 +++ gcc-4.3.2/gcc/doc/invoke.texi 2008-11-21 08:21:50.000000000 -0800 @@ -327,7 +327,7 @@ -ffunction-sections -fgcse -fgcse-after-reload -fgcse-las -fgcse-lm @gol -fgcse-sm -fif-conversion -fif-conversion2 -finline-functions @gol -finline-functions-called-once -finline-limit=@var{n} @gol --finline-small-functions -fipa-cp -fipa-marix-reorg -fipa-pta @gol +-finline-small-functions -fipa-cp -fipa-matrix-reorg -fipa-pta @gol -fipa-pure-const -fipa-reference -fipa-struct-reorg @gol -fipa-type-escape -fivopts -fkeep-inline-functions -fkeep-static-consts @gol -fmerge-all-constants -fmerge-constants -fmodulo-sched @gol @@ -718,7 +718,8 @@ @emph{S/390 and zSeries Options} @gccoptlist{-mtune=@var{cpu-type} -march=@var{cpu-type} @gol --mhard-float -msoft-float -mlong-double-64 -mlong-double-128 @gol +-mhard-float -msoft-float -mhard-dfp -mno-hard-dfp @gol +-mlong-double-64 -mlong-double-128 @gol -mbackchain -mno-backchain -mpacked-stack -mno-packed-stack @gol -msmall-exec -mno-small-exec -mmvcle -mno-mvcle @gol -m64 -m31 -mdebug -mno-debug -mesa -mzarch @gol @@ -13612,6 +13613,17 @@ operations. When @option{-mhard-float} is specified, the compiler generates IEEE floating-point instructions. This is the default. +@item -mhard-dfp +@itemx -mno-hard-dfp +@opindex mhard-dfp +@opindex mno-hard-dfp +Use (do not use) the hardware decimal-floating-point instructions for +decimal-floating-point operations. When @option{-mno-hard-dfp} is +specified, functions in @file{libgcc.a} will be used to perform +decimal-floating-point operations. When @option{-mhard-dfp} is +specified, the compiler generates decimal-floating-point hardware +instructions. This is the default for @option{-march=z9-ec} or higher. + @item -mlong-double-64 @itemx -mlong-double-128 @opindex mlong-double-64 @@ -13722,7 +13734,8 @@ @opindex march Generate code that will run on @var{cpu-type}, which is the name of a system representing a certain processor type. Possible values for -@var{cpu-type} are @samp{g5}, @samp{g6}, @samp{z900}, and @samp{z990}. +@var{cpu-type} are @samp{g5}, @samp{g6}, @samp{z900}, @samp{z990}, +@samp{z9-109} and @samp{z9-ec}. When generating code using the instructions available on z/Architecture, the default is @option{-march=z900}. Otherwise, the default is @option{-march=g5}. @@ -14429,6 +14442,33 @@ two registers separated by a dash. Multiple register ranges can be specified separated by a comma. +@item -mdual-nops +@itemx -mdual-nops=@var{n} +@opindex mdual-nops +By default, GCC will insert nops to increase dual issue when it expects +it to increase performance. @var{n} can be a value from 0 to 10. A +smaller @var{n} will insert fewer nops. 10 is the default, 0 is the +same as @option{-mno-dual-nops}. Disabled with @option{-Os}. + +@item -mhint-max-nops=@var{n} +@opindex mhint-max-nops +Maximum number of nops to insert for a branch hint. A branch hint must +be at least 8 instructions away from the branch it is effecting. GCC +will insert up to @var{n} nops to enforce this, otherwise it will not +generate the branch hint. + +@item -mhint-max-distance=@var{n} +@opindex mhint-max-distance +The encoding of the branch hint instruction limits the hint to be within +256 instructions of the branch it is effecting. By default, GCC makes +sure it is within 125. + +@item -msafe-hints +@opindex msafe-hints +Work around a hardware bug which causes the SPU to stall indefinitely. +By default, GCC will insert the @code{hbrp} instruction to make sure +this stall won't happen. + @end table @node System V Options diff -Naur gcc-4.3.2.orig/gcc/doc/md.texi gcc-4.3.2/gcc/doc/md.texi --- gcc-4.3.2.orig/gcc/doc/md.texi 2008-07-12 01:00:46.000000000 -0700 +++ gcc-4.3.2/gcc/doc/md.texi 2008-12-12 06:34:21.000000000 -0800 @@ -2036,9 +2036,18 @@ @item x Any SSE register. +@item Yz +First SSE register (@code{%xmm0}). + @ifset INTERNALS -@item Y -Any SSE2 register. +@item Y2 +Any SSE register, when SSE2 is enabled. + +@item Yi +Any SSE register, when SSE2 and inter-unit moves are enabled. + +@item Ym +Any MMX register, when inter-unit moves are enabled. @end ifset @item I @@ -2722,6 +2731,9 @@ @item h 64-bit global or out register for the SPARC-V8+ architecture. +@item D +A vector constant + @item I Signed 13-bit constant diff -Naur gcc-4.3.2.orig/gcc/doc/sourcebuild.texi gcc-4.3.2/gcc/doc/sourcebuild.texi --- gcc-4.3.2.orig/gcc/doc/sourcebuild.texi 2008-04-01 11:49:36.000000000 -0700 +++ gcc-4.3.2/gcc/doc/sourcebuild.texi 2008-12-09 14:31:01.000000000 -0800 @@ -819,6 +819,7 @@ * gcov Testing:: Support for testing gcov. * profopt Testing:: Support for testing profile-directed optimizations. * compat Testing:: Support for testing binary compatibility. +* Torture Tests:: Support for torture testing using multiple options. @end menu @node Test Idioms @@ -988,6 +989,26 @@ and only then in certain modes. @end table +@item @{ dg-timeout @var{n} [@{target @var{selector} @}] @} +Set the time limit for the compilation and for the execution of the test +to the specified number of seconds. + +@item @{ dg-timeout-factor @var{x} [@{ target @var{selector} @}] @} +Multiply the normal time limit for compilation and execution of the test +by the specified floating-point factor. The normal timeout limit, in +seconds, is found by searching the following in order: + +@itemize @bullet +@item the value defined by an earlier @code{dg-timeout} directive in +the test + +@item variable @var{tool_timeout} defined by the set of tests + +@item @var{gcc},@var{timeout} set in the target board + +@item 300 +@end itemize + @item @{ dg-skip-if @var{comment} @{ @var{selector} @} @{ @var{include-opts} @} @{ @var{exclude-opts} @} @} Skip the test if the test system is included in @var{selector} and if each of the options in @var{include-opts} is in the set of options with @@ -1528,3 +1549,43 @@ compilation is expected to fail for particular options on particular targets. @end table + +@node Torture Tests +@subsection Support for torture testing using multiple options + +Throughout the compiler testsuite there are several directories whose +tests are run multiple times, each with a different set of options. +These are known as torture tests. +@file{gcc/testsuite/lib/torture-options.exp} defines procedures to +set up these lists: + +@table @code +@item torture-init +Initialize use of torture lists. +@item set-torture-options +Set lists of torture options to use for tests with and without loops. +Optionally combine a set of torture options with a set of other +options, as is done with Objective-C runtime options. +@item torture-finish +Finalize use of torture lists. +@end table + +The @file{.exp} file for a set of tests that use torture options must +include calls to these three procecures if: + +@itemize @bullet +@item It calls @code{gcc-dg-runtest} and overrides @var{DG_TORTURE_OPTIONS}. + +@item It calls @var{$@{tool@}}@code{-torture} or +@var{$@{tool@}}@code{-torture-execute}, where @var{tool} is @code{c}, +@code{fortran}, or @code{objc}. + +@item It calls @code{dg-pch}. +@end itemize + +It is not necessary for a @file{.exp} file that calls @code{gcc-dg-runtest} +to call the torture procedures if the tests should use the list in +@var{DG_TORTURE_OPTIONS} defined in @file{gcc-dg.exp}. + +Most uses of torture options can override the default lists by defining +@var{TORTURE_OPTIONS} in a @file{.dejagnurc} file. diff -Naur gcc-4.3.2.orig/gcc/dwarf2.h gcc-4.3.2/gcc/dwarf2.h --- gcc-4.3.2.orig/gcc/dwarf2.h 2007-12-09 09:08:06.000000000 -0800 +++ gcc-4.3.2/gcc/dwarf2.h 2008-09-24 15:44:28.000000000 -0700 @@ -543,6 +543,7 @@ DW_OP_GNU_push_tls_address = 0xe0, /* The following is for marking variables that are uninitialized. */ DW_OP_GNU_uninit = 0xf0, + DW_OP_GNU_encoded_addr = 0xf1, /* HP extensions. */ DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */ DW_OP_HP_is_value = 0xe1, diff -Naur gcc-4.3.2.orig/gcc/emit-rtl.c gcc-4.3.2/gcc/emit-rtl.c --- gcc-4.3.2.orig/gcc/emit-rtl.c 2008-06-23 06:16:07.000000000 -0700 +++ gcc-4.3.2/gcc/emit-rtl.c 2008-09-12 06:34:12.000000000 -0700 @@ -973,7 +973,7 @@ REG_ATTRS (reg) = get_reg_attrs (MEM_EXPR (x), INTVAL (MEM_OFFSET (x)) + offset); if (MEM_POINTER (x)) - mark_reg_pointer (reg, MEM_ALIGN (x)); + mark_reg_pointer (reg, 0); } else if (REG_P (x)) { diff -Naur gcc-4.3.2.orig/gcc/emutls.c gcc-4.3.2/gcc/emutls.c --- gcc-4.3.2.orig/gcc/emutls.c 2007-03-29 16:34:10.000000000 -0700 +++ gcc-4.3.2/gcc/emutls.c 2008-12-11 15:30:42.000000000 -0800 @@ -144,8 +144,12 @@ static __gthread_once_t once = __GTHREAD_ONCE_INIT; __gthread_once (&once, emutls_init); __gthread_mutex_lock (&emutls_mutex); - offset = ++emutls_size; - obj->loc.offset = offset; + offset = obj->loc.offset; + if (offset == 0) + { + offset = ++emutls_size; + obj->loc.offset = offset; + } __gthread_mutex_unlock (&emutls_mutex); } diff -Naur gcc-4.3.2.orig/gcc/explow.c gcc-4.3.2/gcc/explow.c --- gcc-4.3.2.orig/gcc/explow.c 2008-05-09 11:26:57.000000000 -0700 +++ gcc-4.3.2/gcc/explow.c 2008-09-12 06:34:12.000000000 -0700 @@ -696,10 +696,8 @@ align = MIN (sa, ca); } - else if (MEM_P (x) && MEM_POINTER (x)) - align = MEM_ALIGN (x); - if (align) + if (align || (MEM_P (x) && MEM_POINTER (x))) mark_reg_pointer (temp, align); } diff -Naur gcc-4.3.2.orig/gcc/expmed.c gcc-4.3.2/gcc/expmed.c --- gcc-4.3.2.orig/gcc/expmed.c 2008-03-06 12:23:56.000000000 -0800 +++ gcc-4.3.2/gcc/expmed.c 2008-11-05 12:33:54.000000000 -0800 @@ -1266,9 +1266,8 @@ { if (MEM_P (op0)) op0 = adjust_address (op0, imode, 0); - else + else if (imode != BLKmode) { - gcc_assert (imode != BLKmode); op0 = gen_lowpart (imode, op0); /* If we got a SUBREG, force it into a register since we @@ -1276,6 +1275,24 @@ if (GET_CODE (op0) == SUBREG) op0 = force_reg (imode, op0); } + else if (REG_P (op0)) + { + rtx reg, subreg; + imode = smallest_mode_for_size (GET_MODE_BITSIZE (GET_MODE (op0)), + MODE_INT); + reg = gen_reg_rtx (imode); + subreg = gen_lowpart_SUBREG (GET_MODE (op0), reg); + emit_move_insn (subreg, op0); + op0 = reg; + bitnum += SUBREG_BYTE (subreg) * BITS_PER_UNIT; + } + else + { + rtx mem = assign_stack_temp (GET_MODE (op0), + GET_MODE_SIZE (GET_MODE (op0)), 0); + emit_move_insn (mem, op0); + op0 = adjust_address (mem, BLKmode, 0); + } } } @@ -3115,7 +3132,8 @@ { /* If we are multiplying in DImode, it may still be a win to try to work with shifts and adds. */ - if (CONST_DOUBLE_HIGH (op1) == 0) + if (CONST_DOUBLE_HIGH (op1) == 0 + && CONST_DOUBLE_LOW (op1) > 0) coeff = CONST_DOUBLE_LOW (op1); else if (CONST_DOUBLE_LOW (op1) == 0 && EXACT_POWER_OF_2_OR_ZERO_P (CONST_DOUBLE_HIGH (op1))) diff -Naur gcc-4.3.2.orig/gcc/expr.c gcc-4.3.2/gcc/expr.c --- gcc-4.3.2.orig/gcc/expr.c 2008-08-12 11:36:28.000000000 -0700 +++ gcc-4.3.2/gcc/expr.c 2008-10-07 21:17:27.000000000 -0700 @@ -4994,6 +4994,9 @@ case REFERENCE_TYPE: return 1; + case ERROR_MARK: + return 0; + case VOID_TYPE: case METHOD_TYPE: case FUNCTION_TYPE: diff -Naur gcc-4.3.2.orig/gcc/final.c gcc-4.3.2/gcc/final.c --- gcc-4.3.2.orig/gcc/final.c 2008-01-26 15:08:54.000000000 -0800 +++ gcc-4.3.2/gcc/final.c 2008-11-14 05:26:59.000000000 -0800 @@ -4152,6 +4152,10 @@ timevar_push (TV_SYMOUT); (*debug_hooks->function_decl) (current_function_decl); timevar_pop (TV_SYMOUT); + + /* Release the blocks that are linked to DECL_INITIAL() to free the memory. */ + DECL_INITIAL (current_function_decl) = error_mark_node; + if (DECL_STATIC_CONSTRUCTOR (current_function_decl) && targetm.have_ctors_dtors) targetm.asm_out.constructor (XEXP (DECL_RTL (current_function_decl), 0), diff -Naur gcc-4.3.2.orig/gcc/fold-const.c gcc-4.3.2/gcc/fold-const.c --- gcc-4.3.2.orig/gcc/fold-const.c 2008-08-14 02:11:03.000000000 -0700 +++ gcc-4.3.2/gcc/fold-const.c 2008-10-22 13:08:01.000000000 -0700 @@ -109,9 +109,12 @@ static tree eval_subst (tree, tree, tree, tree, tree); static tree pedantic_omit_one_operand (tree, tree, tree); static tree distribute_bit_expr (enum tree_code, tree, tree, tree); +static tree make_bit_field_ref (tree, tree, HOST_WIDE_INT, HOST_WIDE_INT, int); +static tree optimize_bit_field_compare (enum tree_code, tree, tree, tree); static tree decode_field_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, enum machine_mode *, int *, int *, tree *, tree *); +static int all_ones_mask_p (const_tree, int); static tree sign_bit_p (tree, const_tree); static int simple_operand_p (const_tree); static tree range_binop (enum tree_code, tree, tree, int, tree, int); @@ -834,7 +837,7 @@ if (hden < 0) neg_double (lden, hden, &labs_den, &habs_den); - /* If (2 * abs (lrem) >= abs (lden)) */ + /* If (2 * abs (lrem) >= abs (lden)), adjust the quotient. */ mul_double ((HOST_WIDE_INT) 2, (HOST_WIDE_INT) 0, labs_rem, habs_rem, <wice, &htwice); @@ -842,7 +845,7 @@ < (unsigned HOST_WIDE_INT) htwice) || (((unsigned HOST_WIDE_INT) habs_den == (unsigned HOST_WIDE_INT) htwice) - && (labs_den < ltwice))) + && (labs_den <= ltwice))) { if (*hquo < 0) /* quo = quo - 1; */ @@ -3848,6 +3851,202 @@ return NULL_TREE; } +/* Return a BIT_FIELD_REF of type TYPE to refer to BITSIZE bits of INNER + starting at BITPOS. The field is unsigned if UNSIGNEDP is nonzero. */ + +static tree +make_bit_field_ref (tree inner, tree type, HOST_WIDE_INT bitsize, + HOST_WIDE_INT bitpos, int unsignedp) +{ + tree result; + + if (bitpos == 0) + { + tree size = TYPE_SIZE (TREE_TYPE (inner)); + if ((INTEGRAL_TYPE_P (TREE_TYPE (inner)) + || POINTER_TYPE_P (TREE_TYPE (inner))) + && host_integerp (size, 0) + && tree_low_cst (size, 0) == bitsize) + return fold_convert (type, inner); + } + + result = build3 (BIT_FIELD_REF, type, inner, + size_int (bitsize), bitsize_int (bitpos)); + + BIT_FIELD_REF_UNSIGNED (result) = unsignedp; + + return result; +} + +/* Optimize a bit-field compare. + + There are two cases: First is a compare against a constant and the + second is a comparison of two items where the fields are at the same + bit position relative to the start of a chunk (byte, halfword, word) + large enough to contain it. In these cases we can avoid the shift + implicit in bitfield extractions. + + For constants, we emit a compare of the shifted constant with the + BIT_AND_EXPR of a mask and a byte, halfword, or word of the operand being + compared. For two fields at the same position, we do the ANDs with the + similar mask and compare the result of the ANDs. + + CODE is the comparison code, known to be either NE_EXPR or EQ_EXPR. + COMPARE_TYPE is the type of the comparison, and LHS and RHS + are the left and right operands of the comparison, respectively. + + If the optimization described above can be done, we return the resulting + tree. Otherwise we return zero. */ + +static tree +optimize_bit_field_compare (enum tree_code code, tree compare_type, + tree lhs, tree rhs) +{ + HOST_WIDE_INT lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize; + tree type = TREE_TYPE (lhs); + tree signed_type, unsigned_type; + int const_p = TREE_CODE (rhs) == INTEGER_CST; + enum machine_mode lmode, rmode, nmode; + int lunsignedp, runsignedp; + int lvolatilep = 0, rvolatilep = 0; + tree linner, rinner = NULL_TREE; + tree mask; + tree offset; + + /* Get all the information about the extractions being done. If the bit size + if the same as the size of the underlying object, we aren't doing an + extraction at all and so can do nothing. We also don't want to + do anything if the inner expression is a PLACEHOLDER_EXPR since we + then will no longer be able to replace it. */ + linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode, + &lunsignedp, &lvolatilep, false); + if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0 + || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR) + return 0; + + if (!const_p) + { + /* If this is not a constant, we can only do something if bit positions, + sizes, and signedness are the same. */ + rinner = get_inner_reference (rhs, &rbitsize, &rbitpos, &offset, &rmode, + &runsignedp, &rvolatilep, false); + + if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize + || lunsignedp != runsignedp || offset != 0 + || TREE_CODE (rinner) == PLACEHOLDER_EXPR) + return 0; + } + + /* See if we can find a mode to refer to this field. We should be able to, + but fail if we can't. */ + nmode = get_best_mode (lbitsize, lbitpos, + const_p ? TYPE_ALIGN (TREE_TYPE (linner)) + : MIN (TYPE_ALIGN (TREE_TYPE (linner)), + TYPE_ALIGN (TREE_TYPE (rinner))), + word_mode, lvolatilep || rvolatilep); + if (nmode == VOIDmode) + return 0; + + /* Set signed and unsigned types of the precision of this mode for the + shifts below. */ + signed_type = lang_hooks.types.type_for_mode (nmode, 0); + unsigned_type = lang_hooks.types.type_for_mode (nmode, 1); + + /* Compute the bit position and size for the new reference and our offset + within it. If the new reference is the same size as the original, we + won't optimize anything, so return zero. */ + nbitsize = GET_MODE_BITSIZE (nmode); + nbitpos = lbitpos & ~ (nbitsize - 1); + lbitpos -= nbitpos; + if (nbitsize == lbitsize) + return 0; + + if (BYTES_BIG_ENDIAN) + lbitpos = nbitsize - lbitsize - lbitpos; + + /* Make the mask to be used against the extracted field. */ + mask = build_int_cst_type (unsigned_type, -1); + mask = const_binop (LSHIFT_EXPR, mask, size_int (nbitsize - lbitsize), 0); + mask = const_binop (RSHIFT_EXPR, mask, + size_int (nbitsize - lbitsize - lbitpos), 0); + + if (! const_p) + /* If not comparing with constant, just rework the comparison + and return. */ + return fold_build2 (code, compare_type, + fold_build2 (BIT_AND_EXPR, unsigned_type, + make_bit_field_ref (linner, + unsigned_type, + nbitsize, nbitpos, + 1), + mask), + fold_build2 (BIT_AND_EXPR, unsigned_type, + make_bit_field_ref (rinner, + unsigned_type, + nbitsize, nbitpos, + 1), + mask)); + + /* Otherwise, we are handling the constant case. See if the constant is too + big for the field. Warn and return a tree of for 0 (false) if so. We do + this not only for its own sake, but to avoid having to test for this + error case below. If we didn't, we might generate wrong code. + + For unsigned fields, the constant shifted right by the field length should + be all zero. For signed fields, the high-order bits should agree with + the sign bit. */ + + if (lunsignedp) + { + if (! integer_zerop (const_binop (RSHIFT_EXPR, + fold_convert (unsigned_type, rhs), + size_int (lbitsize), 0))) + { + warning (0, "comparison is always %d due to width of bit-field", + code == NE_EXPR); + return constant_boolean_node (code == NE_EXPR, compare_type); + } + } + else + { + tree tem = const_binop (RSHIFT_EXPR, fold_convert (signed_type, rhs), + size_int (lbitsize - 1), 0); + if (! integer_zerop (tem) && ! integer_all_onesp (tem)) + { + warning (0, "comparison is always %d due to width of bit-field", + code == NE_EXPR); + return constant_boolean_node (code == NE_EXPR, compare_type); + } + } + + /* Single-bit compares should always be against zero. */ + if (lbitsize == 1 && ! integer_zerop (rhs)) + { + code = code == EQ_EXPR ? NE_EXPR : EQ_EXPR; + rhs = build_int_cst (type, 0); + } + + /* Make a new bitfield reference, shift the constant over the + appropriate number of bits and mask it with the computed mask + (in case this was a signed field). If we changed it, make a new one. */ + lhs = make_bit_field_ref (linner, unsigned_type, nbitsize, nbitpos, 1); + if (lvolatilep) + { + TREE_SIDE_EFFECTS (lhs) = 1; + TREE_THIS_VOLATILE (lhs) = 1; + } + + rhs = const_binop (BIT_AND_EXPR, + const_binop (LSHIFT_EXPR, + fold_convert (unsigned_type, rhs), + size_int (lbitpos), 0), + mask, 0); + + return build2 (code, compare_type, + build2 (BIT_AND_EXPR, unsigned_type, lhs, mask), + rhs); +} + /* Subroutine for fold_truthop: decode a field reference. If EXP is a comparison reference, we return the innermost reference. @@ -3939,6 +4138,27 @@ return inner; } +/* Return nonzero if MASK represents a mask of SIZE ones in the low-order + bit positions. */ + +static int +all_ones_mask_p (const_tree mask, int size) +{ + tree type = TREE_TYPE (mask); + unsigned int precision = TYPE_PRECISION (type); + tree tmask; + + tmask = build_int_cst_type (signed_type_for (type), -1); + + return + tree_int_cst_equal (mask, + const_binop (RSHIFT_EXPR, + const_binop (LSHIFT_EXPR, tmask, + size_int (precision - size), + 0), + size_int (precision - size), 0)); +} + /* Subroutine for fold: determine if VAL is the INTEGER_CONST that represents the sign bit of EXP's type. If EXP represents a sign or zero extension, also test VAL against the unextended type. @@ -4490,7 +4710,12 @@ { if (TYPE_UNSIGNED (etype)) { - etype = signed_type_for (etype); + tree signed_etype = signed_type_for (etype); + if (TYPE_PRECISION (signed_etype) != TYPE_PRECISION (etype)) + etype + = build_nonstandard_integer_type (TYPE_PRECISION (etype), 0); + else + etype = signed_etype; exp = fold_convert (etype, exp); } return fold_build2 (GT_EXPR, type, exp, @@ -5264,16 +5489,16 @@ tree ll_inner, lr_inner, rl_inner, rr_inner; HOST_WIDE_INT ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos; HOST_WIDE_INT rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos; - HOST_WIDE_INT xll_bitpos, xrl_bitpos; - HOST_WIDE_INT lnbitsize, lnbitpos; + HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos; + HOST_WIDE_INT lnbitsize, lnbitpos, rnbitsize, rnbitpos; int ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp; enum machine_mode ll_mode, lr_mode, rl_mode, rr_mode; - enum machine_mode lnmode; + enum machine_mode lnmode, rnmode; tree ll_mask, lr_mask, rl_mask, rr_mask; tree ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask; tree l_const, r_const; - tree lntype, result; - int first_bit, end_bit; + tree lntype, rntype, result; + HOST_WIDE_INT first_bit, end_bit; int volatilep; tree orig_lhs = lhs, orig_rhs = rhs; enum tree_code orig_code = code; @@ -5510,6 +5735,118 @@ } } + /* If the right sides are not constant, do the same for it. Also, + disallow this optimization if a size or signedness mismatch occurs + between the left and right sides. */ + if (l_const == 0) + { + if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize + || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp + /* Make sure the two fields on the right + correspond to the left without being swapped. */ + || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos) + return 0; + + first_bit = MIN (lr_bitpos, rr_bitpos); + end_bit = MAX (lr_bitpos + lr_bitsize, rr_bitpos + rr_bitsize); + rnmode = get_best_mode (end_bit - first_bit, first_bit, + TYPE_ALIGN (TREE_TYPE (lr_inner)), word_mode, + volatilep); + if (rnmode == VOIDmode) + return 0; + + rnbitsize = GET_MODE_BITSIZE (rnmode); + rnbitpos = first_bit & ~ (rnbitsize - 1); + rntype = lang_hooks.types.type_for_size (rnbitsize, 1); + xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos; + + if (BYTES_BIG_ENDIAN) + { + xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize; + xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize; + } + + lr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, lr_mask), + size_int (xlr_bitpos), 0); + rr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, rr_mask), + size_int (xrr_bitpos), 0); + + /* Make a mask that corresponds to both fields being compared. + Do this for both items being compared. If the operands are the + same size and the bits being compared are in the same position + then we can do this by masking both and comparing the masked + results. */ + ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0); + lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask, 0); + if (lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos) + { + lhs = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos, + ll_unsignedp || rl_unsignedp); + if (! all_ones_mask_p (ll_mask, lnbitsize)) + lhs = build2 (BIT_AND_EXPR, lntype, lhs, ll_mask); + + rhs = make_bit_field_ref (lr_inner, rntype, rnbitsize, rnbitpos, + lr_unsignedp || rr_unsignedp); + if (! all_ones_mask_p (lr_mask, rnbitsize)) + rhs = build2 (BIT_AND_EXPR, rntype, rhs, lr_mask); + + return build2 (wanted_code, truth_type, lhs, rhs); + } + + /* There is still another way we can do something: If both pairs of + fields being compared are adjacent, we may be able to make a wider + field containing them both. + + Note that we still must mask the lhs/rhs expressions. Furthermore, + the mask must be shifted to account for the shift done by + make_bit_field_ref. */ + if ((ll_bitsize + ll_bitpos == rl_bitpos + && lr_bitsize + lr_bitpos == rr_bitpos) + || (ll_bitpos == rl_bitpos + rl_bitsize + && lr_bitpos == rr_bitpos + rr_bitsize)) + { + tree type; + + lhs = make_bit_field_ref (ll_inner, lntype, ll_bitsize + rl_bitsize, + MIN (ll_bitpos, rl_bitpos), ll_unsignedp); + rhs = make_bit_field_ref (lr_inner, rntype, lr_bitsize + rr_bitsize, + MIN (lr_bitpos, rr_bitpos), lr_unsignedp); + + ll_mask = const_binop (RSHIFT_EXPR, ll_mask, + size_int (MIN (xll_bitpos, xrl_bitpos)), 0); + lr_mask = const_binop (RSHIFT_EXPR, lr_mask, + size_int (MIN (xlr_bitpos, xrr_bitpos)), 0); + + /* Convert to the smaller type before masking out unwanted bits. */ + type = lntype; + if (lntype != rntype) + { + if (lnbitsize > rnbitsize) + { + lhs = fold_convert (rntype, lhs); + ll_mask = fold_convert (rntype, ll_mask); + type = rntype; + } + else if (lnbitsize < rnbitsize) + { + rhs = fold_convert (lntype, rhs); + lr_mask = fold_convert (lntype, lr_mask); + type = lntype; + } + } + + if (! all_ones_mask_p (ll_mask, ll_bitsize + rl_bitsize)) + lhs = build2 (BIT_AND_EXPR, type, lhs, ll_mask); + + if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize)) + rhs = build2 (BIT_AND_EXPR, type, rhs, lr_mask); + + return build2 (wanted_code, truth_type, lhs, rhs); + } + + return 0; + } + /* Handle the case of comparisons with constants. If there is something in common between the masks, those bits of the constants must be the same. If not, the condition is always false. Test for this to avoid generating @@ -5531,7 +5868,19 @@ } } - return NULL_TREE; + /* Construct the expression we will return. First get the component + reference we will make. Unless the mask is all ones the width of + that field, perform the mask operation. Then compare with the + merged constant. */ + result = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos, + ll_unsignedp || rl_unsignedp); + + ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0); + if (! all_ones_mask_p (ll_mask, lnbitsize)) + result = build2 (BIT_AND_EXPR, lntype, result, ll_mask); + + return build2 (wanted_code, truth_type, result, + const_binop (BIT_IOR_EXPR, l_const, r_const, 0)); } /* Optimize T, which is a comparison of a MIN_EXPR or MAX_EXPR with a @@ -5916,9 +6265,20 @@ (C * 8) % 4 since we know that's zero. */ if ((code == TRUNC_MOD_EXPR || code == CEIL_MOD_EXPR || code == FLOOR_MOD_EXPR || code == ROUND_MOD_EXPR) + /* If the multiplication can overflow we cannot optimize this. + ??? Until we can properly mark individual operations as + not overflowing we need to treat sizetype special here as + stor-layout relies on this opimization to make + DECL_FIELD_BIT_OFFSET always a constant. */ + && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t)) + || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE + && TYPE_IS_SIZETYPE (TREE_TYPE (t)))) && TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST && integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0))) - return omit_one_operand (type, integer_zero_node, op0); + { + *strict_overflow_p = true; + return omit_one_operand (type, integer_zero_node, op0); + } /* ... fall through ... */ @@ -10629,14 +10989,13 @@ && TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) { - tree tmp1 = fold_convert (TREE_TYPE (arg0), arg1); - tree tmp2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0), - TREE_OPERAND (arg0, 0), tmp1); - tree tmp3 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0), - TREE_OPERAND (arg0, 1), tmp1); + tree tmp1 = fold_convert (type, arg1); + tree tmp2 = fold_convert (type, TREE_OPERAND (arg0, 0)); + tree tmp3 = fold_convert (type, TREE_OPERAND (arg0, 1)); + tmp2 = fold_build2 (BIT_AND_EXPR, type, tmp2, tmp1); + tmp3 = fold_build2 (BIT_AND_EXPR, type, tmp3, tmp1); return fold_convert (type, - fold_build2 (BIT_IOR_EXPR, TREE_TYPE (arg0), - tmp2, tmp3)); + fold_build2 (BIT_IOR_EXPR, type, tmp2, tmp3)); } /* (X | Y) & Y is (X, Y). */ @@ -11912,6 +12271,18 @@ return omit_one_operand (type, rslt, arg0); } + /* If this is a comparison of a field, we may be able to simplify it. */ + if ((TREE_CODE (arg0) == COMPONENT_REF + || TREE_CODE (arg0) == BIT_FIELD_REF) + /* Handle the constant case even without -O + to make sure the warnings are given. */ + && (optimize || TREE_CODE (arg1) == INTEGER_CST)) + { + t1 = optimize_bit_field_compare (code, type, arg0, arg1); + if (t1) + return t1; + } + /* Optimize comparisons of strlen vs zero to a compare of the first character of the string vs zero. To wit, strlen(ptr) == 0 => *ptr == 0 diff -Naur gcc-4.3.2.orig/gcc/fortran/ChangeLog gcc-4.3.2/gcc/fortran/ChangeLog --- gcc-4.3.2.orig/gcc/fortran/ChangeLog 2008-08-27 11:01:56.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/ChangeLog 2008-12-14 08:07:46.000000000 -0800 @@ -1,3 +1,309 @@ +2008-12-14 Paul Thomas + + PR fortran/35937 + * trans-expr.c (gfc_finish_interface_mapping): Fold convert the + character length to gfc_charlen_type_node. + +2008-12-04 Janis Johnson + + Backport from mainline: + 2008-10-18 Jakub Jelinek + Janis Johnson + + * Make-lang.in (check-f95-subtargets, check-fortran-subtargets): New + aliases for check-gfortran-subtargets. + (lang_checks_parallelized): Add check-gfortran. + (check_gfortran_parallelize): New variable. + +2008-11-24 Paul Thomas + + PR fortran/34820 + * trans-expr.c (gfc_conv_function_call): Remove all code to + deallocate intent out derived types with allocatable + components. + (gfc_trans_assignment_1): An assignment from a scalar to an + array of derived types with allocatable components, requires + a deep copy to each array element and deallocation of the + converted rhs expression afterwards. + * trans-array.c : Minor whitespace. + * trans-decl.c (init_intent_out_dt): Add code to deallocate + allocatable components of derived types with intent out. + (generate_local_decl): If these types are unused, set them + referenced anyway but allow the uninitialized warning. + + PR fortran/34143 + * trans-expr.c (gfc_trans_subcomponent_assign): If a conversion + expression has a null data pointer argument, nullify the + allocatable component. + + PR fortran/32795 + * trans-expr.c (gfc_trans_subcomponent_assign): Only nullify + the data pointer if the source is not a variable. + +2008-11-29 Paul Thomas + + PR fortran/37735 + * trans-array.c (structure_alloc_comps): Do not duplicate the + descriptor if this is a descriptorless array! + +2008-11-27 Paul Thomas + + PR fortran/36526 + * interface.c (check_intents): Correct error where the actual + arg was checked for a pointer argument, rather than the formal. + +2008-11-24 Paul Thomas + + PR fortran/38033 + * trans-array.c (gfc_trans_create_temp_array): Stabilize the + 'to' expression. + (gfc_conv_loop_setup): Use the end expression for the loop 'to' + if it is available. + +2008-11-24 Paul Thomas + + PR fortran/37926 + * trans-expr.c (gfc_free_interface_mapping): Null sym->formal + (gfc_add_interface_mapping): Copy the pointer to the formal + arglist and set attr.always_explicit if this is a procedure. + +2008-11-24 Steven G. Kargl + + PR fortran/37792 + * fortran/resolve.c (resolve_fl_variable): Simplify the + initializer if there is one. + +2008-11-24 Mikael Morin + + PR fortran/35681 + * dependency.c (gfc_check_argument_var_dependency): Add + elemental check flag. Issue a warning if we find a dependency + but don't generate a temporary. Add the case of an elemental + function call as actual argument to an elemental procedure. + Add the case of an operator expression as actual argument + to an elemental procedure. + (gfc_check_argument_dependency): Add elemental check flag. + Update calls to gfc_check_argument_var_dependency. + (gfc_check_fncall_dependency): Add elemental check flag. + Update call to gfc_check_argument_dependency. + * trans-stmt.c (gfc_trans_call): Make call to + gfc_conv_elemental_dependency unconditional, but with a flag + whether we should check dependencies between variables. + (gfc_conv_elemental_dependency): Add elemental check flag. + Update call to gfc_check_fncall_dependency. + * trans-expr.c (gfc_trans_arrayfunc_assign): Update call to + gfc_check_fncall_dependency. + * resolve.c (find_noncopying_intrinsics): Update call to + gfc_check_fncall_dependency. + * dependency.h (enum gfc_dep_check): New enum. + (gfc_check_fncall_dependency): Update prototype. + +2008-11-19 Paul Thomas + + PR fortran/38171 + * module.c (load_equiv): Regression fix; check that equivalence + members come from the same module only. + +2008-11-14 Paul Thomas + + PR fortran/37836 + * intrinsic.c (add_functions): Reference gfc_simplify._minval + and gfc_simplify_maxval. + * intrinsic.h : Add prototypes for gfc_simplify._minval and + gfc_simplify_maxval. + * simplify.c (min_max_choose): New function extracted from + simplify_min_max. + (simplify_min_max): Call it. + (simplify_minval_maxval, gfc_simplify_minval, + gfc_simplify_maxval): New functions. + +2008-11-08 Paul Thomas + + PR fortran/37597 + * parse.c (gfc_fixup_sibling_symbols ): Fixup contained, even + when symbol not found. + +2008-11-08 Mikael Morin + + PR fortran/35820 + * resolve.c (gfc_count_forall_iterators): New function. + (gfc_resolve_forall): Use gfc_count_forall_iterators to evaluate + the needed memory amount to allocate. Don't forget to free allocated + memory. Add an assertion to check for memory leaks. + +2008-11-08 Paul Thomas + + PR fortran/37445 + * resolve.c (resolve_call): Check host association is correct. + (resolve_actual_arglist ): Remove return is old_sym is use + associated. Only reparse expression if old and new symbols + have different types. + + PR fortran/PR35769 + * resolve.c (gfc_resolve_assign_in_forall): Change error to a + warning. + +2008-11-01 Mikael Morin + + PR fortran/37903 + * trans-array.c (gfc_trans_create_temp_array): If n is less + than the temporary dimension, assert that loop->from is + zero (reverts to earlier versions). If there is at least one + null loop->to[n], it is a callee allocated array so set the + size to NULL and break. + (gfc_trans_constant_array_constructor): Set the offset to zero. + (gfc_trans_array_constructor): Remove loop shifting around the + temporary creation. + (gfc_conv_loop_setup): Prefer zero-based descriptors if + possible. Calculate the translation from loop variables to + array indices if an array constructor. + +2008-11-01 Mikael Morin + + PR fortran/37749 + * trans-array.c (gfc_trans_create_temp_array): If size is NULL + use the array bounds for loop->to. + +2008-10-19 Paul Thomas + + PR fortran/37723 + * dependency.c (gfc_dep_resolver ): If we find equal array + element references, go on to the next reference. + +2008-10-19 Paul Thomas + + PR fortran/37787 + * dependency.c (gfc_are_equivalenced_arrays): Look in symbol + namespace rather than current namespace, if it is available. + +2008-10-11 Paul Thomas + + PR fortran/37794 + * module.c (check_for_ambiguous): Remove redundant code. + +2008-10-11 Paul Thomas + + PR fortran/35680 + * gfortran.h : Add 'error' bit field to gfc_expr structure. + * expr.c (check_inquiry): When checking a restricted expression + check that arguments are either variables or restricted. + (check_restricted): Do not emit error if the expression has + 'error' set. Clean up detection of host-associated variable. + +2008-10-05 Paul Thomas + + PR fortran/37706 + * module.c (load_equiv): Check the module before negating the + unused flag. + +2008-09-26 Tobias Burnus + + PR fortran/37580 + * expr.c (gfc_check_pointer_assign): Add checks for pointer + remapping. + +2008-09-26 Tobias Burnus + + PR fortran/37504 + * expr.c (gfc_check_pointer_assign): Allow assignment of + protected pointers. + +2008-09-25 Tobias Burnus + + PR fortran/37626 + * trans-array.c (gfc_trans_deferred_array): Don't auto-deallocate + result variable. + +2008-09-24 Paul Thomas + + PR fortran/35945 + * resolve.c (resolve_fl_variable_derived): Remove derived type + comparison for use associated derived types. Host association + of a derived type will not arise if there is a local derived type + whose use name is the same. + + PR fortran/36700 + * match.c (gfc_match_call): Use the existing symbol even if + it is a function. + +2008-09-24 Paul Thomas + + PR fortran/37583 + * decl.c (gfc_match_entry): Both subroutines and functions can + give a true for get_proc_mame's last argument so remove the + && gfc_current_ns->proc_name->attr.function. + resolve.c (resolve_actual_arglist): Add check for recursion by + reference to procedure as actual argument. + +2008-09-23 Paul Thomas + + PR fortran/37274 + PR fortran/36374 + * module.c (check_for_ambiguous): New function to test loaded + symbol for ambiguity with fixup symbol. + (read_module): Call check_for_ambiguous. + (write_symtree): Do not write the symtree for symbols coming + from an interface body. + + PR fortran/36374 + * resolve.c (count_specific_procs ): New function to count the + number of specific procedures with the same name as the generic + and emit appropriate errors for and actual argument reference. + (resolve_assumed_size_actual): Add new argument no_formal_args. + Correct logic around passing generic procedures as arguments. + Call count_specific_procs from two locations. + (resolve_function): Evaluate and pass no_formal_args. + (resolve call): The same and clean up a bit by using csym more + widely. + + PR fortran/36454 + * symbol.c (gfc_add_access): Access can be updated if use + associated and not private. + +2008-09-13 Daniel Kraft + + PR fortran/35770 + * primary.c (gfc_match_varspec): Added missing type-spec clearing + after wrong implicit character typing. + +2008-09-11 Daniel Kraft + + PR fortran/36214 + * simplify.c (simplify_cmplx): Added linebreak to long line. + * target-memory.c (gfc_convert_boz): Fix indentation. + (gfc_interpret_float): Set mpfr precision to right value before + calling mpfr_init. + +2008-09-08 Daniel Kraft + + PR fortran/37199 + * trans-expr.c (gfc_add_interface_mapping): Set new_sym->as. + (gfc_map_intrinsic_function): Added checks against NULL bounds in + array specs. + +2008-09-05 Daniel Kraft + + PR fortran/35837 + * resolve.c (resolve_types): Restore gfc_current_ns on exit. + * symbol.c (gfc_save_all): Removed blank line. + +2008-09-04 Daniel Kraft + + * PR fortran/37099 + * expr.c (simplify_const_ref): Update expression's character length + when pulling out a substring reference. + +2008-08-30 Daniel Kraft + + PR fortran/37193 + * module.c (read_module): Initialize use_only flag on used symbols. + +2008-06-24 Paul Thomas + + PR fortran/36371 + * expr.c (gfc_check_assign): Change message and locus for + error when conform == 0. + 2008-08-27 Release Manager * GCC 4.3.2 released. diff -Naur gcc-4.3.2.orig/gcc/fortran/Make-lang.in gcc-4.3.2/gcc/fortran/Make-lang.in --- gcc-4.3.2.orig/gcc/fortran/Make-lang.in 2008-04-01 11:49:36.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/Make-lang.in 2008-12-04 15:00:19.000000000 -0800 @@ -141,7 +141,14 @@ check-f95 : check-gfortran check-fortran : check-gfortran +check-f95-subtargets : check-gfortran-subtargets +check-fortran-subtargets : check-gfortran-subtargets lang_checks += check-gfortran +lang_checks_parallelized += check-gfortran +# For description see comment above check_gcc_parallelize in gcc/Makefile.in. +check_gfortran_parallelize = dg.exp=gfortran.dg/\[a-cA-C\]* \ + dg.exp=gfortran.dg/\[d-mD-M\]* \ + dg.exp=gfortran.dg/\[n-zN-Z0-9\]* # GFORTRAN documentation. GFORTRAN_TEXI = \ diff -Naur gcc-4.3.2.orig/gcc/fortran/decl.c gcc-4.3.2/gcc/fortran/decl.c --- gcc-4.3.2.orig/gcc/fortran/decl.c 2008-01-29 22:56:10.000000000 -0800 +++ gcc-4.3.2/gcc/fortran/decl.c 2008-09-24 01:04:26.000000000 -0700 @@ -4504,8 +4504,7 @@ created symbols attached to the current namespace. */ if (get_proc_name (name, &entry, gfc_current_ns->parent != NULL - && module_procedure - && gfc_current_ns->proc_name->attr.function)) + && module_procedure)) return MATCH_ERROR; proc = gfc_current_block (); diff -Naur gcc-4.3.2.orig/gcc/fortran/dependency.c gcc-4.3.2/gcc/fortran/dependency.c --- gcc-4.3.2.orig/gcc/fortran/dependency.c 2007-10-29 07:13:44.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/dependency.c 2008-11-24 04:13:59.000000000 -0800 @@ -432,25 +432,81 @@ static int gfc_check_argument_var_dependency (gfc_expr *var, sym_intent intent, - gfc_expr *expr) + gfc_expr *expr, gfc_dep_check elemental) { + gfc_expr *arg; + gcc_assert (var->expr_type == EXPR_VARIABLE); gcc_assert (var->rank > 0); switch (expr->expr_type) { case EXPR_VARIABLE: - return (gfc_ref_needs_temporary_p (expr->ref) - || gfc_check_dependency (var, expr, 1)); + /* In case of elemental subroutines, there is no dependency + between two same-range array references. */ + if (gfc_ref_needs_temporary_p (expr->ref) + || gfc_check_dependency (var, expr, !elemental)) + { + if (elemental == ELEM_DONT_CHECK_VARIABLE) + { + /* Elemental procedures forbid unspecified intents, + and we don't check dependencies for INTENT_IN args. */ + gcc_assert (intent == INTENT_OUT || intent == INTENT_INOUT); + + /* We are told not to check dependencies. + We do it, however, and issue a warning in case we find one. + If a dependency is found in the case + elemental == ELEM_CHECK_VARIABLE, we will generate + a temporary, so we don't need to bother the user. */ + gfc_warning ("INTENT(%s) actual argument at %L might interfere " + "with actual argument at %L.", + intent == INTENT_OUT ? "OUT" : "INOUT", + &var->where, &expr->where); + return 0; + } + else + return 1; + } + return 0; case EXPR_ARRAY: return gfc_check_dependency (var, expr, 1); case EXPR_FUNCTION: - if (intent != INTENT_IN && expr->inline_noncopying_intrinsic) + if (intent != INTENT_IN && expr->inline_noncopying_intrinsic + && (arg = gfc_get_noncopying_intrinsic_argument (expr)) + && gfc_check_argument_var_dependency (var, intent, arg, elemental)) + return 1; + if (elemental) { - expr = gfc_get_noncopying_intrinsic_argument (expr); - return gfc_check_argument_var_dependency (var, intent, expr); + if ((expr->value.function.esym + && expr->value.function.esym->attr.elemental) + || (expr->value.function.isym + && expr->value.function.isym->elemental)) + return gfc_check_fncall_dependency (var, intent, NULL, + expr->value.function.actual, + ELEM_CHECK_VARIABLE); + } + return 0; + + case EXPR_OP: + /* In case of non-elemental procedures, there is no need to catch + dependencies, as we will make a temporary anyway. */ + if (elemental) + { + /* If the actual arg EXPR is an expression, we need to catch + a dependency between variables in EXPR and VAR, + an intent((IN)OUT) variable. */ + if (expr->value.op.op1 + && gfc_check_argument_var_dependency (var, intent, + expr->value.op.op1, + ELEM_CHECK_VARIABLE)) + return 1; + else if (expr->value.op.op2 + && gfc_check_argument_var_dependency (var, intent, + expr->value.op.op2, + ELEM_CHECK_VARIABLE)) + return 1; } return 0; @@ -465,18 +521,19 @@ static int gfc_check_argument_dependency (gfc_expr *other, sym_intent intent, - gfc_expr *expr) + gfc_expr *expr, gfc_dep_check elemental) { switch (other->expr_type) { case EXPR_VARIABLE: - return gfc_check_argument_var_dependency (other, intent, expr); + return gfc_check_argument_var_dependency (other, intent, expr, elemental); case EXPR_FUNCTION: if (other->inline_noncopying_intrinsic) { other = gfc_get_noncopying_intrinsic_argument (other); - return gfc_check_argument_dependency (other, INTENT_IN, expr); + return gfc_check_argument_dependency (other, INTENT_IN, expr, + elemental); } return 0; @@ -491,7 +548,8 @@ int gfc_check_fncall_dependency (gfc_expr *other, sym_intent intent, - gfc_symbol *fnsym, gfc_actual_arglist *actual) + gfc_symbol *fnsym, gfc_actual_arglist *actual, + gfc_dep_check elemental) { gfc_formal_arglist *formal; gfc_expr *expr; @@ -514,7 +572,7 @@ && formal->sym->attr.intent == INTENT_IN) continue; - if (gfc_check_argument_dependency (other, intent, expr)) + if (gfc_check_argument_dependency (other, intent, expr, elemental)) return 1; } @@ -547,10 +605,16 @@ || !e2->symtree->n.sym->attr.in_equivalence|| !e1->rank || !e2->rank) return 0; + if (e1->symtree->n.sym->ns + && e1->symtree->n.sym->ns != gfc_current_ns) + l = e1->symtree->n.sym->ns->equiv_lists; + else + l = gfc_current_ns->equiv_lists; + /* Go through the equiv_lists and return 1 if the variables e1 and e2 are members of the same group and satisfy the requirement on their relative offsets. */ - for (l = gfc_current_ns->equiv_lists; l; l = l->next) + for (; l; l = l->next) { fl1 = NULL; fl2 = NULL; @@ -1246,6 +1310,14 @@ if (this_dep > fin_dep) fin_dep = this_dep; } + + /* If this is an equal element, we have to keep going until we find + the "real" array reference. */ + if (lref->u.ar.type == AR_ELEMENT + && rref->u.ar.type == AR_ELEMENT + && fin_dep == GFC_DEP_EQUAL) + break; + /* Exactly matching and forward overlapping ranges don't cause a dependency. */ if (fin_dep < GFC_DEP_OVERLAP) diff -Naur gcc-4.3.2.orig/gcc/fortran/dependency.h gcc-4.3.2/gcc/fortran/dependency.h --- gcc-4.3.2.orig/gcc/fortran/dependency.h 2007-08-01 09:29:36.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/dependency.h 2008-11-24 04:13:59.000000000 -0800 @@ -19,13 +19,24 @@ along with GCC; see the file COPYING3. If not see . */ +/****************************** Enums *********************************/ +typedef enum +{ + NOT_ELEMENTAL, /* Not elemental case: normal dependency check. */ + ELEM_CHECK_VARIABLE, /* Test whether variables overlap. */ + ELEM_DONT_CHECK_VARIABLE /* Test whether variables overlap only if used + in an expression. */ +} +gfc_dep_check; +/*********************** Functions prototypes **************************/ + bool gfc_ref_needs_temporary_p (gfc_ref *); bool gfc_full_array_ref_p (gfc_ref *); gfc_expr *gfc_get_noncopying_intrinsic_argument (gfc_expr *); int gfc_check_fncall_dependency (gfc_expr *, sym_intent, gfc_symbol *, - gfc_actual_arglist *); + gfc_actual_arglist *, gfc_dep_check); int gfc_check_dependency (gfc_expr *, gfc_expr *, bool); int gfc_is_same_range (gfc_array_ref *, gfc_array_ref *, int, int); int gfc_expr_is_one (gfc_expr *, int); diff -Naur gcc-4.3.2.orig/gcc/fortran/expr.c gcc-4.3.2/gcc/fortran/expr.c --- gcc-4.3.2.orig/gcc/fortran/expr.c 2008-05-01 00:31:28.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/expr.c 2008-10-11 02:58:38.000000000 -0700 @@ -1443,6 +1443,40 @@ { cons->expr->ref = copy_ref (p->ref->next); simplify_const_ref (cons->expr); + if (simplify_const_ref (cons->expr) == FAILURE) + return FAILURE; + } + + /* If this is a CHARACTER array and we possibly took a + substring out of it, update the type-spec's character + length according to the first element (as all should have + the same length). */ + if (p->ts.type == BT_CHARACTER) + { + int string_len; + + gcc_assert (p->ref->next); + gcc_assert (!p->ref->next->next); + gcc_assert (p->ref->next->type == REF_SUBSTRING); + + if (p->value.constructor) + { + const gfc_expr* first = p->value.constructor->expr; + gcc_assert (first->expr_type == EXPR_CONSTANT); + gcc_assert (first->ts.type == BT_CHARACTER); + string_len = first->value.character.length; + } + else + string_len = 0; + + if (!p->ts.cl) + { + p->ts.cl = gfc_get_charlen (); + p->ts.cl->next = NULL; + p->ts.cl->length = NULL; + } + gfc_free_expr (p->ts.cl->length); + p->ts.cl->length = gfc_int_expr (string_len); } } gfc_free_ref_list (p->ref); @@ -1968,6 +2002,9 @@ return MATCH_YES; } + +static try check_restricted (gfc_expr *); + /* F95, 7.1.6.1, Initialization expressions, (7) F2003, 7.1.7 Initialization expression, (8) */ @@ -2047,6 +2084,11 @@ } else if (not_restricted && check_init_expr (ap->expr) == FAILURE) return MATCH_ERROR; + + if (not_restricted == 0 + && ap->expr->expr_type != EXPR_VARIABLE + && check_restricted (ap->expr) == FAILURE) + return MATCH_ERROR; } return MATCH_YES; @@ -2368,8 +2410,6 @@ } -static try check_restricted (gfc_expr *); - /* Given an actual argument list, test to see that each argument is a restricted expression and optionally if the expression type is integer or character. */ @@ -2508,14 +2548,17 @@ that host associated dummy array indices are accepted (PR23446). This mechanism also does the same for the specification expressions of array-valued functions. */ - if (sym->attr.in_common - || sym->attr.use_assoc - || sym->attr.dummy - || sym->attr.implied_index - || sym->ns != gfc_current_ns - || (sym->ns->proc_name != NULL - && sym->ns->proc_name->attr.flavor == FL_MODULE) - || (gfc_is_formal_arg () && (sym->ns == gfc_current_ns))) + if (e->error + || sym->attr.in_common + || sym->attr.use_assoc + || sym->attr.dummy + || sym->attr.implied_index + || (sym->ns && sym->ns == gfc_current_ns->parent) + || (sym->ns && gfc_current_ns->parent + && sym->ns == gfc_current_ns->parent->parent) + || (sym->ns->proc_name != NULL + && sym->ns->proc_name->attr.flavor == FL_MODULE) + || (gfc_is_formal_arg () && (sym->ns == gfc_current_ns))) { t = SUCCESS; break; @@ -2523,7 +2566,8 @@ gfc_error ("Variable '%s' cannot appear in the expression at %L", sym->name, &e->where); - + /* Prevent a repetition of the error. */ + e->error = 1; break; case EXPR_NULL: @@ -2825,6 +2869,7 @@ if (gfc_compare_types (&lvalue->ts, &rvalue->ts)) return SUCCESS; + /* Only DATA Statements come here. */ if (!conform) { /* Numeric can be converted to any other numeric. And Hollerith can be @@ -2837,7 +2882,7 @@ return SUCCESS; gfc_error ("Incompatible types in assignment at %L, %s to %s", - &rvalue->where, gfc_typename (&rvalue->ts), + &lvalue->where, gfc_typename (&rvalue->ts), gfc_typename (&lvalue->ts)); return FAILURE; @@ -2888,6 +2933,32 @@ if (ref->type == REF_COMPONENT && ref->u.c.component->pointer) pointer = 1; + + if (ref->type == REF_ARRAY && ref->next == NULL) + { + if (ref->u.ar.type == AR_FULL) + break; + + if (ref->u.ar.type != AR_SECTION) + { + gfc_error ("Expected bounds specification for '%s' at %L", + lvalue->symtree->n.sym->name, &lvalue->where); + return FAILURE; + } + + if (gfc_notify_std (GFC_STD_F2003,"Fortran 2003: Bounds " + "specification for '%s' in pointer assignment " + "at %L", lvalue->symtree->n.sym->name, + &lvalue->where) == FAILURE) + return FAILURE; + + gfc_error ("Pointer bounds remapping at %L is not yet implemented " + "in gfortran", &lvalue->where); + /* TODO: See PR 29785. Add checks that all lbounds are specified and + either never or always the upper-bound; strides shall not be + present. */ + return FAILURE; + } } if (check_intent_in && lvalue->symtree->n.sym->attr.intent == INTENT_IN) @@ -2978,9 +3049,9 @@ return FAILURE; } - if (attr.protected && attr.use_assoc) + if (attr.protected && attr.use_assoc && !attr.pointer) { - gfc_error ("Pointer assigment target has PROTECTED " + gfc_error ("Pointer assignment target has PROTECTED " "attribute at %L", &rvalue->where); return FAILURE; } diff -Naur gcc-4.3.2.orig/gcc/fortran/gfortran.h gcc-4.3.2/gcc/fortran/gfortran.h --- gcc-4.3.2.orig/gcc/fortran/gfortran.h 2008-01-29 22:56:10.000000000 -0800 +++ gcc-4.3.2/gcc/fortran/gfortran.h 2008-10-11 02:58:38.000000000 -0700 @@ -1432,6 +1432,10 @@ and if we have decided not to allocate temporary data for that array. */ unsigned int inline_noncopying_intrinsic : 1, is_boz : 1; + /* Sometimes, when an error has been emitted, it is necessary to prevent + it from recurring. */ + unsigned int error : 1; + /* Used to quickly find a given constructor by its offset. */ splay_tree con_by_offset; diff -Naur gcc-4.3.2.orig/gcc/fortran/interface.c gcc-4.3.2/gcc/fortran/interface.c --- gcc-4.3.2.orig/gcc/fortran/interface.c 2008-05-17 00:10:13.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/interface.c 2008-11-27 14:20:27.000000000 -0800 @@ -2374,7 +2374,7 @@ return FAILURE; } - if (a->expr->symtree->n.sym->attr.pointer) + if (f->sym->attr.pointer) { gfc_error ("Procedure argument at %L is local to a PURE " "procedure and has the POINTER attribute", diff -Naur gcc-4.3.2.orig/gcc/fortran/intrinsic.c gcc-4.3.2/gcc/fortran/intrinsic.c --- gcc-4.3.2.orig/gcc/fortran/intrinsic.c 2007-12-25 02:41:44.000000000 -0800 +++ gcc-4.3.2/gcc/fortran/intrinsic.c 2008-11-13 22:14:46.000000000 -0800 @@ -1867,7 +1867,7 @@ make_generic ("maxloc", GFC_ISYM_MAXLOC, GFC_STD_F95); add_sym_3red ("maxval", GFC_ISYM_MAXVAL, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95, - gfc_check_minval_maxval, NULL, gfc_resolve_maxval, + gfc_check_minval_maxval, gfc_simplify_maxval, gfc_resolve_maxval, ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL, msk, BT_LOGICAL, dl, OPTIONAL); @@ -1933,7 +1933,7 @@ make_generic ("minloc", GFC_ISYM_MINLOC, GFC_STD_F95); add_sym_3red ("minval", GFC_ISYM_MINVAL, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95, - gfc_check_minval_maxval, NULL, gfc_resolve_minval, + gfc_check_minval_maxval, gfc_simplify_minval, gfc_resolve_minval, ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL, msk, BT_LOGICAL, dl, OPTIONAL); diff -Naur gcc-4.3.2.orig/gcc/fortran/intrinsic.h gcc-4.3.2/gcc/fortran/intrinsic.h --- gcc-4.3.2.orig/gcc/fortran/intrinsic.h 2007-12-25 02:41:44.000000000 -0800 +++ gcc-4.3.2/gcc/fortran/intrinsic.h 2008-11-13 22:14:46.000000000 -0800 @@ -258,7 +258,9 @@ gfc_expr *gfc_simplify_log10 (gfc_expr *); gfc_expr *gfc_simplify_logical (gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_min (gfc_expr *); +gfc_expr *gfc_simplify_minval (gfc_expr *, gfc_expr*, gfc_expr*); gfc_expr *gfc_simplify_max (gfc_expr *); +gfc_expr *gfc_simplify_maxval (gfc_expr *, gfc_expr*, gfc_expr*); gfc_expr *gfc_simplify_maxexponent (gfc_expr *); gfc_expr *gfc_simplify_minexponent (gfc_expr *); gfc_expr *gfc_simplify_mod (gfc_expr *, gfc_expr *); diff -Naur gcc-4.3.2.orig/gcc/fortran/match.c gcc-4.3.2/gcc/fortran/match.c --- gcc-4.3.2.orig/gcc/fortran/match.c 2008-02-03 03:29:27.000000000 -0800 +++ gcc-4.3.2/gcc/fortran/match.c 2008-09-24 01:12:47.000000000 -0700 @@ -2488,9 +2488,12 @@ sym = st->n.sym; - /* If it does not seem to be callable... */ + /* If it does not seem to be callable (include functions so that the + right association is made. They are thrown out in resolution.) + ... */ if (!sym->attr.generic - && !sym->attr.subroutine) + && !sym->attr.subroutine + && !sym->attr.function) { if (!(sym->attr.external && !sym->attr.referenced)) { diff -Naur gcc-4.3.2.orig/gcc/fortran/module.c gcc-4.3.2/gcc/fortran/module.c --- gcc-4.3.2.orig/gcc/fortran/module.c 2008-05-13 13:26:47.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/module.c 2008-11-18 19:46:12.000000000 -0800 @@ -3465,11 +3465,16 @@ mio_expr (&tail->expr); } - /* Unused equivalence members have a unique name. */ + /* Unused equivalence members have a unique name. In addition, it + must be checked that the symbols are from the same module. */ unused = true; for (eq = head; eq; eq = eq->eq) { - if (!check_unique_name (eq->expr->symtree->name)) + if (eq->expr->symtree->n.sym->module + && head->expr->symtree->n.sym->module + && strcmp (head->expr->symtree->n.sym->module, + eq->expr->symtree->n.sym->module) == 0 + && !check_unique_name (eq->expr->symtree->name)) { unused = false; break; @@ -3603,6 +3608,41 @@ } +/* It is not quite enough to check for ambiguity in the symbols by + the loaded symbol and the new symbol not being identical. */ +static bool +check_for_ambiguous (gfc_symbol *st_sym, pointer_info *info) +{ + gfc_symbol *rsym; + module_locus locus; + symbol_attribute attr; + + rsym = info->u.rsym.sym; + if (st_sym == rsym) + return false; + + /* If the existing symbol is generic from a different module and + the new symbol is generic there can be no ambiguity. */ + if (st_sym->attr.generic + && st_sym->module + && strcmp (st_sym->module, module_name)) + { + /* The new symbol's attributes have not yet been read. Since + we need attr.generic, read it directly. */ + get_module_locus (&locus); + set_module_locus (&info->u.rsym.where); + mio_lparen (); + attr.generic = 0; + mio_symbol_attribute (&attr); + set_module_locus (&locus); + if (attr.generic) + return false; + } + + return true; +} + + /* Read a module file. */ static void @@ -3744,7 +3784,7 @@ if (st != NULL) { /* Check for ambiguous symbols. */ - if (st->n.sym != info->u.rsym.sym) + if (check_for_ambiguous (st->n.sym, info)) st->ambiguous = 1; info->u.rsym.symtree = st; } @@ -3753,9 +3793,9 @@ st = gfc_find_symtree (gfc_current_ns->sym_root, name); /* Delete the symtree if the symbol has been added by a USE - statement without an ONLY(11.3.2). Remember that the rsym + statement without an ONLY(11.3.2). Remember that the rsym will be the same as the symbol found in the symtree, for - this case.*/ + this case. */ if (st && (only_flag || info->u.rsym.renamed) && !st->n.sym->attr.use_only && !st->n.sym->attr.use_rename @@ -3791,6 +3831,11 @@ if (strcmp (name, p) != 0) sym->attr.use_rename = 1; + /* We need to set the only_flag here so that symbols from the + same USE...ONLY but earlier are not deleted from the tree in + the gfc_delete_symtree above. */ + sym->attr.use_only = only_flag; + /* Store the symtree pointing to this symbol. */ info->u.rsym.symtree = st; @@ -4233,6 +4278,14 @@ pointer_info *p; sym = st->n.sym; + + /* A symbol in an interface body must not be visible in the + module file. */ + if (sym->ns != gfc_current_ns + && sym->ns->proc_name + && sym->ns->proc_name->attr.if_source == IFSRC_IFBODY) + return; + if (!gfc_check_access (sym->attr.access, sym->ns->default_access) || (sym->attr.flavor == FL_PROCEDURE && sym->attr.generic && !sym->attr.subroutine && !sym->attr.function)) diff -Naur gcc-4.3.2.orig/gcc/fortran/parse.c gcc-4.3.2/gcc/fortran/parse.c --- gcc-4.3.2.orig/gcc/fortran/parse.c 2008-01-29 22:56:10.000000000 -0800 +++ gcc-4.3.2/gcc/fortran/parse.c 2008-11-08 06:17:35.000000000 -0800 @@ -3038,7 +3038,7 @@ gfc_find_sym_tree (sym->name, ns, 0, &st); if (!st || (st->n.sym->attr.dummy && ns == st->n.sym->ns)) - continue; + goto fixup_contained; old_sym = st->n.sym; if (old_sym->ns == ns @@ -3072,6 +3072,7 @@ gfc_free_symbol (old_sym); } +fixup_contained: /* Do the same for any contained procedures. */ gfc_fixup_sibling_symbols (sym, ns->contained); } diff -Naur gcc-4.3.2.orig/gcc/fortran/primary.c gcc-4.3.2/gcc/fortran/primary.c --- gcc-4.3.2.orig/gcc/fortran/primary.c 2008-02-03 03:29:27.000000000 -0800 +++ gcc-4.3.2/gcc/fortran/primary.c 2008-09-17 04:56:09.000000000 -0700 @@ -1785,7 +1785,10 @@ case MATCH_NO: if (unknown) - gfc_clear_ts (&primary->ts); + { + gfc_clear_ts (&primary->ts); + gfc_clear_ts (&sym->ts); + } break; case MATCH_ERROR: diff -Naur gcc-4.3.2.orig/gcc/fortran/resolve.c gcc-4.3.2/gcc/fortran/resolve.c --- gcc-4.3.2.orig/gcc/fortran/resolve.c 2008-07-19 11:34:21.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/resolve.c 2008-11-24 11:13:12.000000000 -0800 @@ -1012,6 +1012,38 @@ } +/* Check a generic procedure, passed as an actual argument, to see if + there is a matching specific name. If none, it is an error, and if + more than one, the reference is ambiguous. */ +static int +count_specific_procs (gfc_expr *e) +{ + int n; + gfc_interface *p; + gfc_symbol *sym; + + n = 0; + sym = e->symtree->n.sym; + + for (p = sym->generic; p; p = p->next) + if (strcmp (sym->name, p->sym->name) == 0) + { + e->symtree = gfc_find_symtree (p->sym->ns->sym_root, + sym->name); + n++; + } + + if (n > 1) + gfc_error ("'%s' at %L is ambiguous", e->symtree->n.sym->name, + &e->where); + + if (n == 0) + gfc_error ("GENERIC procedure '%s' is not allowed as an actual " + "argument at %L", sym->name, &e->where); + + return n; +} + /* Resolve an actual argument list. Most of the time, this is just resolving the expressions in the list. The exception is that we sometimes have to decide whether arguments @@ -1019,7 +1051,8 @@ references. */ static try -resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype) +resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype, + bool no_formal_args) { gfc_symbol *sym; gfc_symtree *parent_st; @@ -1044,17 +1077,16 @@ continue; } - if (e->expr_type == FL_VARIABLE && e->symtree->ambiguous) - { - gfc_error ("'%s' at %L is ambiguous", e->symtree->n.sym->name, - &e->where); - return FAILURE; - } + if (e->expr_type == EXPR_VARIABLE + && e->symtree->n.sym->attr.generic + && no_formal_args + && count_specific_procs (e) != 1) + return FAILURE; if (e->ts.type != BT_PROCEDURE) { save_need_full_assumed_size = need_full_assumed_size; - if (e->expr_type != FL_VARIABLE) + if (e->expr_type != EXPR_VARIABLE) need_full_assumed_size = 0; if (gfc_resolve_expr (e) != SUCCESS) return FAILURE; @@ -1110,22 +1142,19 @@ /* Check if a generic interface has a specific procedure with the same name before emitting an error. */ - if (sym->attr.generic) - { - gfc_interface *p; - for (p = sym->generic; p; p = p->next) - if (strcmp (sym->name, p->sym->name) == 0) - { - e->symtree = gfc_find_symtree - (p->sym->ns->sym_root, sym->name); - sym = p->sym; - break; - } + if (sym->attr.generic && count_specific_procs (e) != 1) + return FAILURE; + + /* Just in case a specific was found for the expression. */ + sym = e->symtree->n.sym; - if (p == NULL || e->symtree == NULL) - gfc_error ("GENERIC procedure '%s' is not " - "allowed as an actual argument at %L", sym->name, - &e->where); + if (sym->attr.entry && sym->ns->entries + && sym->ns == gfc_current_ns + && !sym->ns->entries->sym->attr.recursive) + { + gfc_error ("Reference to ENTRY '%s' at %L is recursive, but procedure " + "'%s' is not declared as RECURSIVE", + sym->name, &e->where, sym->ns->entries->sym->name); } /* If the symbol is the function that names the current (or @@ -1198,7 +1227,7 @@ is a variable instead, it needs to be resolved as it was not done at the beginning of this function. */ save_need_full_assumed_size = need_full_assumed_size; - if (e->expr_type != FL_VARIABLE) + if (e->expr_type != EXPR_VARIABLE) need_full_assumed_size = 0; if (gfc_resolve_expr (e) != SUCCESS) return FAILURE; @@ -1426,7 +1455,8 @@ for (ap = actual; ap; ap = ap->next) if (ap->expr && (expr = gfc_get_noncopying_intrinsic_argument (ap->expr)) - && !gfc_check_fncall_dependency (expr, INTENT_IN, fnsym, actual)) + && !gfc_check_fncall_dependency (expr, INTENT_IN, fnsym, actual, + NOT_ELEMENTAL)) ap->expr->inline_noncopying_intrinsic = 1; } @@ -2170,6 +2200,7 @@ try t; int temp; procedure_type p = PROC_INTRINSIC; + bool no_formal_args; sym = NULL; if (expr->symtree) @@ -2199,7 +2230,9 @@ if (expr->symtree && expr->symtree->n.sym) p = expr->symtree->n.sym->attr.proc; - if (resolve_actual_arglist (expr->value.function.actual, p) == FAILURE) + no_formal_args = sym && is_external_proc (sym) && sym->formal == NULL; + if (resolve_actual_arglist (expr->value.function.actual, + p, no_formal_args) == FAILURE) return FAILURE; /* Need to setup the call to the correct c_associated, depending on @@ -2776,26 +2809,41 @@ { try t; procedure_type ptype = PROC_INTRINSIC; + gfc_symbol *csym, *sym; + bool no_formal_args; + + csym = c->symtree ? c->symtree->n.sym : NULL; - if (c->symtree && c->symtree->n.sym - && c->symtree->n.sym->ts.type != BT_UNKNOWN) + if (csym && csym->ts.type != BT_UNKNOWN) { gfc_error ("'%s' at %L has a type, which is not consistent with " - "the CALL at %L", c->symtree->n.sym->name, - &c->symtree->n.sym->declared_at, &c->loc); + "the CALL at %L", csym->name, &csym->declared_at, &c->loc); return FAILURE; } + if (csym && gfc_current_ns->parent && csym->ns != gfc_current_ns) + { + gfc_find_symbol (csym->name, gfc_current_ns, 1, &sym); + if (sym && csym != sym + && sym->ns == gfc_current_ns + && sym->attr.flavor == FL_PROCEDURE + && sym->attr.contained) + { + sym->refs++; + csym = sym; + c->symtree->n.sym = sym; + } + } + /* If external, check for usage. */ - if (c->symtree && is_external_proc (c->symtree->n.sym)) - resolve_global_procedure (c->symtree->n.sym, &c->loc, 1); + if (csym && is_external_proc (csym)) + resolve_global_procedure (csym, &c->loc, 1); /* Subroutines without the RECURSIVE attribution are not allowed to * call themselves. */ - if (c->symtree && c->symtree->n.sym && !c->symtree->n.sym->attr.recursive) + if (csym && !csym->attr.recursive) { - gfc_symbol *csym, *proc; - csym = c->symtree->n.sym; + gfc_symbol *proc; proc = gfc_current_ns->proc_name; if (csym == proc) { @@ -2818,10 +2866,12 @@ of procedure, once the procedure itself is resolved. */ need_full_assumed_size++; - if (c->symtree && c->symtree->n.sym) - ptype = c->symtree->n.sym->attr.proc; + if (csym) + ptype = csym->attr.proc; - if (resolve_actual_arglist (c->ext.actual, ptype) == FAILURE) + no_formal_args = csym && is_external_proc (csym) && csym->formal == NULL; + if (resolve_actual_arglist (c->ext.actual, ptype, + no_formal_args) == FAILURE) return FAILURE; /* Resume assumed_size checking. */ @@ -2829,7 +2879,7 @@ t = SUCCESS; if (c->resolved_sym == NULL) - switch (procedure_kind (c->symtree->n.sym)) + switch (procedure_kind (csym)) { case PTYPE_GENERIC: t = resolve_generic_s (c); @@ -4155,14 +4205,12 @@ old_sym = e->symtree->n.sym; - if (old_sym->attr.use_assoc) - return retval; - if (gfc_current_ns->parent && old_sym->ns != gfc_current_ns) { gfc_find_symbol (old_sym->name, gfc_current_ns, 1, &sym); if (sym && old_sym != sym + && sym->ts.type == old_sym->ts.type && sym->attr.flavor == FL_PROCEDURE && sym->attr.contained) { @@ -5796,9 +5844,9 @@ assignment target, then there will be a many-to-one assignment. */ if (find_forall_index (code->expr, forall_index, 0) == FAILURE) - gfc_error ("The FORALL with index '%s' cause more than one " - "assignment to this object at %L", - var_expr[n]->symtree->name, &code->expr->where); + gfc_warning ("The FORALL with index '%s' might cause more than " + "one assignment to this object at %L", + var_expr[n]->symtree->name, &code->expr->where); } } } @@ -5894,6 +5942,40 @@ } +/* Counts the number of iterators needed inside a forall construct, including + nested forall constructs. This is used to allocate the needed memory + in gfc_resolve_forall. */ + +static int +gfc_count_forall_iterators (gfc_code *code) +{ + int max_iters, sub_iters, current_iters; + gfc_forall_iterator *fa; + + gcc_assert(code->op == EXEC_FORALL); + max_iters = 0; + current_iters = 0; + + for (fa = code->ext.forall_iterator; fa; fa = fa->next) + current_iters ++; + + code = code->block->next; + + while (code) + { + if (code->op == EXEC_FORALL) + { + sub_iters = gfc_count_forall_iterators (code); + if (sub_iters > max_iters) + max_iters = sub_iters; + } + code = code->next; + } + + return current_iters + max_iters; +} + + /* Given a FORALL construct, first resolve the FORALL iterator, then call gfc_resolve_forall_body to resolve the FORALL body. */ @@ -5903,22 +5985,18 @@ static gfc_expr **var_expr; static int total_var = 0; static int nvar = 0; + int old_nvar, tmp; gfc_forall_iterator *fa; - gfc_code *next; int i; + old_nvar = nvar; + /* Start to resolve a FORALL construct */ if (forall_save == 0) { /* Count the total number of FORALL index in the nested FORALL - construct in order to allocate the VAR_EXPR with proper size. */ - next = code; - while ((next != NULL) && (next->op == EXEC_FORALL)) - { - for (fa = next->ext.forall_iterator; fa; fa = fa->next) - total_var ++; - next = next->block->next; - } + construct in order to allocate the VAR_EXPR with proper size. */ + total_var = gfc_count_forall_iterators (code); /* Allocate VAR_EXPR with NUMBER_OF_FORALL_INDEX elements. */ var_expr = (gfc_expr **) gfc_getmem (total_var * sizeof (gfc_expr *)); @@ -5943,6 +6021,9 @@ var_expr[nvar] = gfc_copy_expr (fa->var); nvar++; + + /* No memory leak. */ + gcc_assert (nvar <= total_var); } /* Resolve the FORALL body. */ @@ -5951,13 +6032,21 @@ /* May call gfc_resolve_forall to resolve the inner FORALL loop. */ gfc_resolve_blocks (code->block, ns); - /* Free VAR_EXPR after the whole FORALL construct resolved. */ - for (i = 0; i < total_var; i++) - gfc_free_expr (var_expr[i]); - - /* Reset the counters. */ - total_var = 0; - nvar = 0; + tmp = nvar; + nvar = old_nvar; + /* Free only the VAR_EXPRs allocated in this frame. */ + for (i = nvar; i < tmp; i++) + gfc_free_expr (var_expr[i]); + + if (nvar == 0) + { + /* We are in the outermost FORALL construct. */ + gcc_assert (forall_save == 0); + + /* VAR_EXPR is not needed any more. */ + gfc_free (var_expr); + total_var = 0; + } } @@ -7060,8 +7149,7 @@ { gfc_symbol *s; gfc_find_symbol (sym->ts.derived->name, sym->ns, 0, &s); - if (s && (s->attr.flavor != FL_DERIVED - || !gfc_compare_derived_types (s, sym->ts.derived))) + if (s && s->attr.flavor != FL_DERIVED) { gfc_error ("The type '%s' cannot be host associated at %L " "because it is blocked by an incompatible object " @@ -7193,6 +7281,10 @@ } } + /* Ensure that any initializer is simplified. */ + if (sym->value) + gfc_simplify_expr (sym->value, 1); + /* Reject illegal initializers. */ if (!sym->mark && sym->value) { @@ -9092,6 +9184,7 @@ gfc_charlen *cl; gfc_data *d; gfc_equiv *eq; + gfc_namespace* old_ns = gfc_current_ns; gfc_current_ns = ns; @@ -9149,6 +9242,8 @@ warn_unused_fortran_label (ns->st_labels); gfc_resolve_uops (ns->uop_root); + + gfc_current_ns = old_ns; } diff -Naur gcc-4.3.2.orig/gcc/fortran/simplify.c gcc-4.3.2/gcc/fortran/simplify.c --- gcc-4.3.2.orig/gcc/fortran/simplify.c 2008-01-28 09:25:55.000000000 -0800 +++ gcc-4.3.2/gcc/fortran/simplify.c 2008-11-13 22:14:46.000000000 -0800 @@ -763,7 +763,8 @@ { case BT_INTEGER: if (!y->is_boz) - mpfr_set_z (result->value.complex.i, y->value.integer, GFC_RND_MODE); + mpfr_set_z (result->value.complex.i, y->value.integer, + GFC_RND_MODE); break; case BT_REAL: @@ -2451,57 +2452,32 @@ } -/* This function is special since MAX() can take any number of - arguments. The simplified expression is a rewritten version of the - argument list containing at most one constant element. Other - constant elements are deleted. Because the argument list has - already been checked, this function always succeeds. sign is 1 for - MAX(), -1 for MIN(). */ - -static gfc_expr * -simplify_min_max (gfc_expr *expr, int sign) +/* Selects bewteen current value and extremum for simplify_min_max + and simplify_minval_maxval. */ +static void +min_max_choose (gfc_expr *arg, gfc_expr *extremum, int sign) { - gfc_actual_arglist *arg, *last, *extremum; - gfc_intrinsic_sym * specific; - - last = NULL; - extremum = NULL; - specific = expr->value.function.isym; - - arg = expr->value.function.actual; - - for (; arg; last = arg, arg = arg->next) - { - if (arg->expr->expr_type != EXPR_CONSTANT) - continue; - - if (extremum == NULL) - { - extremum = arg; - continue; - } - - switch (arg->expr->ts.type) + switch (arg->ts.type) { case BT_INTEGER: - if (mpz_cmp (arg->expr->value.integer, - extremum->expr->value.integer) * sign > 0) - mpz_set (extremum->expr->value.integer, arg->expr->value.integer); + if (mpz_cmp (arg->value.integer, + extremum->value.integer) * sign > 0) + mpz_set (extremum->value.integer, arg->value.integer); break; case BT_REAL: /* We need to use mpfr_min and mpfr_max to treat NaN properly. */ if (sign > 0) - mpfr_max (extremum->expr->value.real, extremum->expr->value.real, - arg->expr->value.real, GFC_RND_MODE); + mpfr_max (extremum->value.real, extremum->value.real, + arg->value.real, GFC_RND_MODE); else - mpfr_min (extremum->expr->value.real, extremum->expr->value.real, - arg->expr->value.real, GFC_RND_MODE); + mpfr_min (extremum->value.real, extremum->value.real, + arg->value.real, GFC_RND_MODE); break; case BT_CHARACTER: -#define LENGTH(x) ((x)->expr->value.character.length) -#define STRING(x) ((x)->expr->value.character.string) +#define LENGTH(x) ((x)->value.character.length) +#define STRING(x) ((x)->value.character.string) if (LENGTH(extremum) < LENGTH(arg)) { char * tmp = STRING(extremum); @@ -2515,7 +2491,7 @@ gfc_free (tmp); } - if (gfc_compare_string (arg->expr, extremum->expr) * sign > 0) + if (gfc_compare_string (arg, extremum) * sign > 0) { gfc_free (STRING(extremum)); STRING(extremum) = gfc_getmem (LENGTH(extremum) + 1); @@ -2532,6 +2508,40 @@ default: gfc_internal_error ("simplify_min_max(): Bad type in arglist"); } +} + + +/* This function is special since MAX() can take any number of + arguments. The simplified expression is a rewritten version of the + argument list containing at most one constant element. Other + constant elements are deleted. Because the argument list has + already been checked, this function always succeeds. sign is 1 for + MAX(), -1 for MIN(). */ + +static gfc_expr * +simplify_min_max (gfc_expr *expr, int sign) +{ + gfc_actual_arglist *arg, *last, *extremum; + gfc_intrinsic_sym * specific; + + last = NULL; + extremum = NULL; + specific = expr->value.function.isym; + + arg = expr->value.function.actual; + + for (; arg; last = arg, arg = arg->next) + { + if (arg->expr->expr_type != EXPR_CONSTANT) + continue; + + if (extremum == NULL) + { + extremum = arg; + continue; + } + + min_max_choose (arg->expr, extremum->expr, sign); /* Delete the extra constant argument. */ if (last == NULL) @@ -2576,6 +2586,69 @@ } +/* This is a simplified version of simplify_min_max to provide + simplification of minval and maxval for a vector. */ + +static gfc_expr * +simplify_minval_maxval (gfc_expr *expr, int sign) +{ + gfc_constructor *ctr, *extremum; + gfc_intrinsic_sym * specific; + + extremum = NULL; + specific = expr->value.function.isym; + + ctr = expr->value.constructor; + + for (; ctr; ctr = ctr->next) + { + if (ctr->expr->expr_type != EXPR_CONSTANT) + return NULL; + + if (extremum == NULL) + { + extremum = ctr; + continue; + } + + min_max_choose (ctr->expr, extremum->expr, sign); + } + + if (extremum == NULL) + return NULL; + + /* Convert to the correct type and kind. */ + if (expr->ts.type != BT_UNKNOWN) + return gfc_convert_constant (extremum->expr, + expr->ts.type, expr->ts.kind); + + if (specific->ts.type != BT_UNKNOWN) + return gfc_convert_constant (extremum->expr, + specific->ts.type, specific->ts.kind); + + return gfc_copy_expr (extremum->expr); +} + + +gfc_expr * +gfc_simplify_minval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask) +{ + if (array->expr_type != EXPR_ARRAY || array->rank != 1 || dim || mask) + return NULL; + + return simplify_minval_maxval (array, -1); +} + + +gfc_expr * +gfc_simplify_maxval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask) +{ + if (array->expr_type != EXPR_ARRAY || array->rank != 1 || dim || mask) + return NULL; + return simplify_minval_maxval (array, 1); +} + + gfc_expr * gfc_simplify_maxexponent (gfc_expr *x) { diff -Naur gcc-4.3.2.orig/gcc/fortran/symbol.c gcc-4.3.2/gcc/fortran/symbol.c --- gcc-4.3.2.orig/gcc/fortran/symbol.c 2008-01-29 22:56:10.000000000 -0800 +++ gcc-4.3.2/gcc/fortran/symbol.c 2008-09-22 23:25:39.000000000 -0700 @@ -1377,7 +1377,8 @@ const char *name, locus *where) { - if (attr->access == ACCESS_UNKNOWN) + if (attr->access == ACCESS_UNKNOWN + || (attr->use_assoc && attr->access != ACCESS_PRIVATE)) { attr->access = access; return check_conflict (attr, name, where); @@ -3058,7 +3059,6 @@ void gfc_save_all (gfc_namespace *ns) { - gfc_traverse_ns (ns, save_symbol); } diff -Naur gcc-4.3.2.orig/gcc/fortran/target-memory.c gcc-4.3.2/gcc/fortran/target-memory.c --- gcc-4.3.2.orig/gcc/fortran/target-memory.c 2008-05-18 16:06:16.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/target-memory.c 2008-09-14 02:57:50.000000000 -0700 @@ -338,8 +338,9 @@ int gfc_interpret_float (int kind, unsigned char *buffer, size_t buffer_size, - mpfr_t real) + mpfr_t real) { + gfc_set_model_kind (kind); mpfr_init (real); gfc_conv_tree_to_mpfr (real, native_interpret_expr (gfc_get_real_type (kind), @@ -661,10 +662,8 @@ } for (index = 0; gfc_integer_kinds[index].kind != 0; ++index) - { - if ((unsigned) gfc_integer_kinds[index].bit_size >= ts_bit_size) - break; - } + if ((unsigned) gfc_integer_kinds[index].bit_size >= ts_bit_size) + break; expr->ts.kind = gfc_integer_kinds[index].kind; buffer_size = MAX (buffer_size, size_integer (expr->ts.kind)); diff -Naur gcc-4.3.2.orig/gcc/fortran/trans-array.c gcc-4.3.2/gcc/fortran/trans-array.c --- gcc-4.3.2.orig/gcc/fortran/trans-array.c 2008-07-27 04:41:35.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/trans-array.c 2008-11-29 12:42:22.000000000 -0800 @@ -587,17 +587,13 @@ /* Set the lower bound to zero. */ for (dim = 0; dim < info->dimen; dim++) { - n = loop->order[dim]; - /* TODO: Investigate why "if (n < loop->temp_dim) - gcc_assert (integer_zerop (loop->from[n]));" fails here. */ - if (n >= loop->temp_dim) - { - /* Callee allocated arrays may not have a known bound yet. */ - if (loop->to[n]) - loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type, - loop->to[n], loop->from[n]); - loop->from[n] = gfc_index_zero_node; - } + n = loop->order[dim]; + /* Callee allocated arrays may not have a known bound yet. */ + if (loop->to[n]) + loop->to[n] = gfc_evaluate_now (fold_build2 (MINUS_EXPR, + gfc_array_index_type, + loop->to[n], loop->from[n]), pre); + loop->from[n] = gfc_index_zero_node; info->delta[dim] = gfc_index_zero_node; info->start[dim] = gfc_index_zero_node; @@ -635,9 +631,18 @@ or_expr = NULL_TREE; + /* If there is at least one null loop->to[n], it is a callee allocated + array. */ for (n = 0; n < info->dimen; n++) - { - if (loop->to[n] == NULL_TREE) + if (loop->to[n] == NULL_TREE) + { + size = NULL_TREE; + break; + } + + for (n = 0; n < info->dimen; n++) + { + if (size == NULL_TREE) { /* For a callee allocated array express the loop bounds in terms of the descriptor fields. */ @@ -645,7 +650,6 @@ gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]), gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n])); loop->to[n] = tmp; - size = NULL_TREE; continue; } @@ -1604,8 +1608,7 @@ info->descriptor = tmp; info->data = build_fold_addr_expr (tmp); - info->offset = fold_build1 (NEGATE_EXPR, gfc_array_index_type, - loop->from[0]); + info->offset = gfc_index_zero_node; for (i = 0; i < info->dimen; i++) { @@ -1668,7 +1671,6 @@ tree offsetvar; tree desc; tree type; - tree loopfrom; bool dynamic; if (flag_bounds_check && ss->expr->ts.type == BT_CHARACTER) @@ -1747,34 +1749,9 @@ } } - /* Temporarily reset the loop variables, so that the returned temporary - has the right size and bounds. This seems only to be necessary for - 1D arrays. */ - if (!integer_zerop (loop->from[0]) && loop->dimen == 1) - { - loopfrom = loop->from[0]; - loop->from[0] = gfc_index_zero_node; - loop->to[0] = fold_build2 (MINUS_EXPR, gfc_array_index_type, - loop->to[0], loopfrom); - } - else - loopfrom = NULL_TREE; - gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, &ss->data.info, type, dynamic, true, false); - if (loopfrom != NULL_TREE) - { - loop->from[0] = loopfrom; - loop->to[0] = fold_build2 (PLUS_EXPR, gfc_array_index_type, - loop->to[0], loopfrom); - /* In the case of a non-zero from, the temporary needs an offset - so that subsequent indexing is correct. */ - ss->data.info.offset = fold_build1 (NEGATE_EXPR, - gfc_array_index_type, - loop->from[0]); - } - desc = ss->data.info.descriptor; offset = gfc_index_zero_node; offsetvar = gfc_create_var_np (gfc_array_index_type, "offset"); @@ -3299,7 +3276,10 @@ if (ss->shape) { /* The frontend has worked out the size for us. */ - loopspec[n] = ss; + if (!loopspec[n] || !loopspec[n]->shape + || !integer_zerop (loopspec[n]->data.info.start[n])) + /* Prefer zero-based descriptors if possible. */ + loopspec[n] = ss; continue; } @@ -3398,8 +3378,13 @@ break; case GFC_SS_SECTION: - loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n, - &loop->pre); + /* Use the end expression if it exists and is not constant, + so that it is only evaluated once. */ + if (info->end[n] && !INTEGER_CST_P (info->end[n])) + loop->to[n] = info->end[n]; + else + loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n, + &loop->pre); break; case GFC_SS_FUNCTION: @@ -3473,7 +3458,9 @@ /* Calculate the translation from loop variables to array indices. */ for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain) { - if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT) + if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT + && ss->type != GFC_SS_CONSTRUCTOR) + continue; info = &ss->data.info; @@ -5144,7 +5131,6 @@ gfc_conv_expr_descriptor (se, expr, ss); } - /* Deallocate the allocatable components of structures that are not variable. */ if (expr->ts.type == BT_DERIVED @@ -5375,10 +5361,12 @@ if (purpose == COPY_ALLOC_COMP) { - tmp = gfc_duplicate_allocatable (dest, decl, TREE_TYPE(decl), rank); - gfc_add_expr_to_block (&fnblock, tmp); - - tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (dest)); + if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest))) + { + tmp = gfc_duplicate_allocatable (dest, decl, TREE_TYPE(decl), rank); + gfc_add_expr_to_block (&fnblock, tmp); + } + tmp = build_fold_indirect_ref (gfc_conv_array_data (dest)); dref = gfc_build_array_ref (tmp, index, NULL); tmp = structure_alloc_comps (der_type, vref, dref, rank, purpose); } @@ -5621,7 +5609,7 @@ gfc_add_expr_to_block (&fnblock, tmp); } - if (sym->attr.allocatable && !sym->attr.save) + if (sym->attr.allocatable && !sym->attr.save && !sym->attr.result) { tmp = gfc_trans_dealloc_allocated (sym->backend_decl); gfc_add_expr_to_block (&fnblock, tmp); diff -Naur gcc-4.3.2.orig/gcc/fortran/trans-decl.c gcc-4.3.2/gcc/fortran/trans-decl.c --- gcc-4.3.2.orig/gcc/fortran/trans-decl.c 2008-04-19 15:30:03.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/trans-decl.c 2008-11-29 12:42:22.000000000 -0800 @@ -2589,20 +2589,34 @@ } -/* Initialize INTENT(OUT) derived type dummies. */ +/* Initialize INTENT(OUT) derived type dummies. As well as giving + them their default initializer, if they do not have allocatable + components, they have their allocatable components deallocated. */ + static tree init_intent_out_dt (gfc_symbol * proc_sym, tree body) { stmtblock_t fnblock; gfc_formal_arglist *f; + tree tmp; gfc_init_block (&fnblock); for (f = proc_sym->formal; f; f = f->next) if (f->sym && f->sym->attr.intent == INTENT_OUT - && f->sym->ts.type == BT_DERIVED - && !f->sym->ts.derived->attr.alloc_comp - && f->sym->value) - body = gfc_init_default_dt (f->sym, body); + && f->sym->ts.type == BT_DERIVED) + { + if (f->sym->ts.derived->attr.alloc_comp) + { + tmp = gfc_deallocate_alloc_comp (f->sym->ts.derived, + f->sym->backend_decl, + f->sym->as ? f->sym->as->rank : 0); + gfc_add_expr_to_block (&fnblock, tmp); + } + + if (!f->sym->ts.derived->attr.alloc_comp + && f->sym->value) + body = gfc_init_default_dt (f->sym, body); + } gfc_add_expr_to_block (&fnblock, body); return gfc_finish_block (&fnblock); @@ -2966,10 +2980,10 @@ getting stuck in a circular dependency. */ sym->mark = 1; if (!sym->attr.dummy && !sym->ns->proc_name->attr.entry_master) - generate_dependency_declarations (sym); + generate_dependency_declarations (sym); if (sym->attr.referenced) - gfc_get_symbol_decl (sym); + gfc_get_symbol_decl (sym); /* INTENT(out) dummy arguments are likely meant to be set. */ else if (warn_unused_variable && sym->attr.dummy @@ -3000,6 +3014,19 @@ gfc_get_symbol_decl (sym); } + /* INTENT(out) dummy arguments with allocatable components are reset + by default and need to be set referenced to generate the code for + automatic lengths. */ + if (sym->attr.dummy && !sym->attr.referenced + && sym->ts.type == BT_DERIVED + && sym->ts.derived->attr.alloc_comp + && sym->attr.intent == INTENT_OUT) + { + sym->attr.referenced = 1; + gfc_get_symbol_decl (sym); + } + + /* We do not want the middle-end to warn about unused parameters as this was already done above. */ if (sym->attr.dummy && sym->backend_decl != NULL_TREE) diff -Naur gcc-4.3.2.orig/gcc/fortran/trans-expr.c gcc-4.3.2/gcc/fortran/trans-expr.c --- gcc-4.3.2.orig/gcc/fortran/trans-expr.c 2008-07-27 04:41:35.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/trans-expr.c 2008-12-14 08:07:46.000000000 -0800 @@ -1421,6 +1421,7 @@ for (sym = mapping->syms; sym; sym = nextsym) { nextsym = sym->next; + sym->new->n.sym->formal = NULL; gfc_free_symbol (sym->new->n.sym); gfc_free_expr (sym->expr); gfc_free (sym->new); @@ -1541,6 +1542,7 @@ /* Create a new symbol to represent the actual argument. */ new_sym = gfc_new_symbol (sym->name, NULL); new_sym->ts = sym->ts; + new_sym->as = gfc_copy_array_spec (sym->as); new_sym->attr.referenced = 1; new_sym->attr.dimension = sym->attr.dimension; new_sym->attr.pointer = sym->attr.pointer; @@ -1548,6 +1550,15 @@ new_sym->attr.flavor = sym->attr.flavor; new_sym->attr.function = sym->attr.function; + /* Ensure that the interface is available and that + descriptors are passed for array actual arguments. */ + if (sym->attr.flavor == FL_PROCEDURE) + { + new_sym->formal = expr->symtree->n.sym->formal; + new_sym->attr.always_explicit + = expr->symtree->n.sym->attr.always_explicit; + } + /* Create a fake symtree for it. */ root = NULL; new_symtree = gfc_new_symtree (&root, sym->name); @@ -1657,7 +1668,7 @@ gfc_apply_interface_mapping_to_expr (mapping, expr); gfc_init_se (&se, NULL); gfc_conv_expr (&se, expr); - + se.expr = fold_convert (gfc_charlen_type_node, se.expr); se.expr = gfc_evaluate_now (se.expr, &se.pre); gfc_add_block_to_block (pre, &se.pre); gfc_add_block_to_block (post, &se.post); @@ -1721,8 +1732,9 @@ /* Convert intrinsic function calls into result expressions. */ + static bool -gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping * mapping) +gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping) { gfc_symbol *sym; gfc_expr *new_expr; @@ -1736,7 +1748,7 @@ else arg2 = NULL; - sym = arg1->symtree->n.sym; + sym = arg1->symtree->n.sym; if (sym->attr.dummy) return false; @@ -1773,6 +1785,13 @@ for (; d < dup; d++) { gfc_expr *tmp; + + if (!sym->as->upper[d] || !sym->as->lower[d]) + { + gfc_free_expr (new_expr); + return false; + } + tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]), gfc_int_expr (1)); tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d])); if (new_expr) @@ -1798,9 +1817,15 @@ gcc_unreachable (); if (expr->value.function.isym->id == GFC_ISYM_LBOUND) - new_expr = gfc_copy_expr (sym->as->lower[d]); + { + if (sym->as->lower[d]) + new_expr = gfc_copy_expr (sym->as->lower[d]); + } else - new_expr = gfc_copy_expr (sym->as->upper[d]); + { + if (sym->as->upper[d]) + new_expr = gfc_copy_expr (sym->as->upper[d]); + } break; default: @@ -2518,14 +2543,11 @@ gfc_add_block_to_block (&post, &parmse.post); /* Allocated allocatable components of derived types must be - deallocated for INTENT(OUT) dummy arguments and non-variable - scalars. Non-variable arrays are dealt with in trans-array.c - (gfc_conv_array_parameter). */ + deallocated for non-variable scalars. Non-variable arrays are + dealt with in trans-array.c(gfc_conv_array_parameter). */ if (e && e->ts.type == BT_DERIVED && e->ts.derived->attr.alloc_comp - && ((formal && formal->sym->attr.intent == INTENT_OUT) - || - (e->expr_type != EXPR_VARIABLE && !e->rank))) + && (e->expr_type != EXPR_VARIABLE && !e->rank)) { int parm_rank; tmp = build_fold_indirect_ref (parmse.expr); @@ -2540,24 +2562,10 @@ case (SCALAR_POINTER): tmp = build_fold_indirect_ref (tmp); break; - case (ARRAY): - tmp = parmse.expr; - break; } - tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank); - if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional) - tmp = build3_v (COND_EXPR, gfc_conv_expr_present (e->symtree->n.sym), - tmp, build_empty_stmt ()); - - if (e->expr_type != EXPR_VARIABLE) - /* Don't deallocate non-variables until they have been used. */ - gfc_add_expr_to_block (&se->post, tmp); - else - { - gcc_assert (formal && formal->sym->attr.intent == INTENT_OUT); - gfc_add_expr_to_block (&se->pre, tmp); - } + tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank); + gfc_add_expr_to_block (&se->post, tmp); } /* Character strings are passed as two parameters, a length and a @@ -3305,9 +3313,10 @@ cm->as->rank); gfc_add_expr_to_block (&block, tmp); - gfc_add_block_to_block (&block, &se.post); - gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node); + + if (expr->expr_type != EXPR_VARIABLE) + gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node); /* Shift the lbound and ubound of temporaries to being unity, rather than zero, based. Calculate the offset for all cases. */ @@ -3339,6 +3348,35 @@ tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2); gfc_add_modify_expr (&block, offset, tmp); } + + if (expr->expr_type == EXPR_FUNCTION + && expr->value.function.isym + && expr->value.function.isym->conversion + && expr->value.function.actual->expr + && expr->value.function.actual->expr->expr_type + == EXPR_VARIABLE) + { + /* If a conversion expression has a null data pointer + argument, nullify the allocatable component. */ + gfc_symbol *s; + tree non_null_expr; + tree null_expr; + s = expr->value.function.actual->expr->symtree->n.sym; + if (s->attr.allocatable || s->attr.pointer) + { + non_null_expr = gfc_finish_block (&block); + gfc_start_block (&block); + gfc_conv_descriptor_data_set (&block, dest, + null_pointer_node); + null_expr = gfc_finish_block (&block); + tmp = gfc_conv_descriptor_data_get (s->backend_decl); + tmp = build2 (EQ_EXPR, boolean_type_node, tmp, + fold_convert (TREE_TYPE (tmp), + null_pointer_node)); + return build3_v (COND_EXPR, tmp, null_expr, + non_null_expr); + } + } } else { @@ -3974,7 +4012,8 @@ /* Check for a dependency. */ if (gfc_check_fncall_dependency (expr1, INTENT_OUT, expr2->value.function.esym, - expr2->value.function.actual)) + expr2->value.function.actual, + NOT_ELEMENTAL)) return NULL; /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic @@ -4218,6 +4257,7 @@ stmtblock_t block; stmtblock_t body; bool l_is_temp; + bool scalar_to_array; /* Assignment of the form lhs = rhs. */ gfc_start_block (&block); @@ -4301,9 +4341,24 @@ else gfc_conv_expr (&lse, expr1); + /* Assignments of scalar derived types with allocatable components + to arrays must be done with a deep copy and the rhs temporary + must have its components deallocated afterwards. */ + scalar_to_array = (expr2->ts.type == BT_DERIVED + && expr2->ts.derived->attr.alloc_comp + && expr2->expr_type != EXPR_VARIABLE + && !gfc_is_constant_expr (expr2) + && expr1->rank && !expr2->rank); + if (scalar_to_array) + { + tmp = gfc_deallocate_alloc_comp (expr2->ts.derived, rse.expr, 0); + gfc_add_expr_to_block (&loop.post, tmp); + } + tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, l_is_temp || init_flag, - expr2->expr_type == EXPR_VARIABLE); + (expr2->expr_type == EXPR_VARIABLE) + || scalar_to_array); gfc_add_expr_to_block (&body, tmp); if (lss == gfc_ss_terminator) diff -Naur gcc-4.3.2.orig/gcc/fortran/trans-stmt.c gcc-4.3.2/gcc/fortran/trans-stmt.c --- gcc-4.3.2.orig/gcc/fortran/trans-stmt.c 2008-05-17 00:10:13.000000000 -0700 +++ gcc-4.3.2/gcc/fortran/trans-stmt.c 2008-11-24 04:13:59.000000000 -0800 @@ -200,7 +200,8 @@ can be used, as is, to copy the result back to the variable. */ static void gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse, - gfc_symbol * sym, gfc_actual_arglist * arg) + gfc_symbol * sym, gfc_actual_arglist * arg, + gfc_dep_check check_variable) { gfc_actual_arglist *arg0; gfc_expr *e; @@ -248,7 +249,7 @@ && e->rank && fsym && fsym->attr.intent != INTENT_IN && gfc_check_fncall_dependency (e, fsym->attr.intent, - sym, arg0)) + sym, arg0, check_variable)) { /* Make a local loopinfo for the temporary creation, so that none of the other ss->info's have to be renormalized. */ @@ -312,6 +313,7 @@ gfc_se se; gfc_ss * ss; int has_alternate_specifier; + gfc_dep_check check_variable; /* A CALL starts a new block because the actual arguments may have to be evaluated first. */ @@ -374,6 +376,10 @@ gfc_add_ss_to_loop (&loop, ss); gfc_conv_ss_startstride (&loop); + /* TODO: gfc_conv_loop_setup generates a temporary for vector + subscripts. This could be prevented in the elemental case + as temporaries are handled separatedly + (below in gfc_conv_elemental_dependencies). */ gfc_conv_loop_setup (&loop); gfc_mark_ss_chain_used (ss, 1); @@ -383,12 +389,11 @@ /* For operator assignment, do dependency checking. */ if (dependency_check) - { - gfc_symbol *sym; - sym = code->resolved_sym; - gfc_conv_elemental_dependencies (&se, &loopse, sym, - code->ext.actual); - } + check_variable = ELEM_CHECK_VARIABLE; + else + check_variable = ELEM_DONT_CHECK_VARIABLE; + gfc_conv_elemental_dependencies (&se, &loopse, code->resolved_sym, + code->ext.actual, check_variable); /* Generate the loop body. */ gfc_start_scalarized_body (&loop, &body); diff -Naur gcc-4.3.2.orig/gcc/function.c gcc-4.3.2/gcc/function.c --- gcc-4.3.2.orig/gcc/function.c 2008-02-15 01:55:36.000000000 -0800 +++ gcc-4.3.2/gcc/function.c 2008-09-09 13:24:58.000000000 -0700 @@ -2336,6 +2336,11 @@ stack_parm = gen_rtx_MEM (data->promoted_mode, stack_parm); set_mem_attributes (stack_parm, parm, 1); + /* set_mem_attributes could set MEM_SIZE to the passed mode's size, + while promoted mode's size is needed. */ + if (data->promoted_mode != BLKmode + && data->promoted_mode != DECL_MODE (parm)) + set_mem_size (stack_parm, GEN_INT (GET_MODE_SIZE (data->promoted_mode))); boundary = data->locate.boundary; align = BITS_PER_UNIT; diff -Naur gcc-4.3.2.orig/gcc/gimplify.c gcc-4.3.2/gcc/gimplify.c --- gcc-4.3.2.orig/gcc/gimplify.c 2008-08-12 07:04:18.000000000 -0700 +++ gcc-4.3.2/gcc/gimplify.c 2008-12-18 13:55:31.000000000 -0800 @@ -3416,7 +3416,8 @@ if (constant_p) { - TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts); + GENERIC_TREE_OPERAND (*expr_p, 1) + = build_vector_from_ctor (type, elts); break; } diff -Naur gcc-4.3.2.orig/gcc/haifa-sched.c gcc-4.3.2/gcc/haifa-sched.c --- gcc-4.3.2.orig/gcc/haifa-sched.c 2008-08-05 23:34:18.000000000 -0700 +++ gcc-4.3.2/gcc/haifa-sched.c 2008-09-09 14:17:19.000000000 -0700 @@ -4485,4 +4485,15 @@ } #endif /* ENABLE_CHECKING */ +/* Insert PAT as an INSN into the schedule and update the necessary data + structures to account for it. */ +rtx +sched_emit_insn (rtx pat) +{ + rtx insn = emit_insn_after (pat, last_scheduled_insn); + last_scheduled_insn = insn; + extend_region_data (insn); + return insn; +} + #endif /* INSN_SCHEDULING */ diff -Naur gcc-4.3.2.orig/gcc/ifcvt.c gcc-4.3.2/gcc/ifcvt.c --- gcc-4.3.2.orig/gcc/ifcvt.c 2008-07-01 07:05:13.000000000 -0700 +++ gcc-4.3.2/gcc/ifcvt.c 2008-09-30 12:48:12.000000000 -0700 @@ -659,7 +659,15 @@ build the store_flag insn directly. */ if (cond_complex) - cond = XEXP (SET_SRC (pc_set (if_info->jump)), 0); + { + rtx set = pc_set (if_info->jump); + cond = XEXP (SET_SRC (set), 0); + if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF + && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (if_info->jump)) + reversep = !reversep; + if (if_info->then_else_reversed) + reversep = !reversep; + } if (reversep) code = reversed_comparison_code (cond, if_info->jump); diff -Naur gcc-4.3.2.orig/gcc/java/ChangeLog gcc-4.3.2/gcc/java/ChangeLog --- gcc-4.3.2.orig/gcc/java/ChangeLog 2008-08-27 11:02:23.000000000 -0700 +++ gcc-4.3.2/gcc/java/ChangeLog 2008-12-04 15:00:19.000000000 -0800 @@ -1,3 +1,56 @@ +2008-12-04 Janis Johnson + + Backport from mainline: + 2008-10-18 Jakub Jelinek + Janis Johnson + + * Make-lang.in (check-java-subtargets): New target. + +contrib/ + * dg-extract-results.sh: New file. +gcc/ + * Makefile.in (lang_checks_parallelized, check_gcc_parallelize, + check_p_tool, check_p_vars, check_p_subno, check_p_comma, + check_p_subwork, check_p_numbers, check_p_subdir, check_p_subdirs): + New variables. + (check-subtargets, check-%-subtargets, check-parallel-%): New + targets. + (check-%): For test targets listed in lang_checks_parallelized + if -j is used and RUNTESTFLAGS doesn't specify tests to execute, + run the testing in multiple make goals, possibly parallel, and + afterwards run dg-extract-results.sh to merge the sum and log files. +gcc/cp/ + * Make-lang.in (check-c++-subtargets): New alias for + check-g++-subtargets. + (lang_checks_parallelized): Add check-g++. + (check_g++_parallelize): New variable. +gcc/fortran/ + * Make-lang.in (check-f95-subtargets, check-fortran-subtargets): New + aliases for check-gfortran-subtargets. + (lang_checks_parallelized): Add check-gfortran. + (check_gfortran_parallelize): New variable. +gcc/ada/ + * Make-lang.in (check-ada-subtargets): Depend on + check-acats-subtargets and check-gnat-subtargets. + (check_acats_targets): New variable. + (check-acats-subtargets, check-acats%): New targets. + (check-acats): If -j is used and CHAPTERS is empty, run the testing + in multiple make goals, possibly parallel, and afterwards run + dg-extract-results.sh to merge the sum and log files. +gcc/java/ + * Make-lang.in (check-java-subtargets): New target. +libstdc++-v3/ + * testsuite/Makefile.am (AUTOMAKE_OPTIONS): Remove dejagnu. + (RUNTESTDEFAULTFLAGS, EXPECT, check_DEJAGNU_normal_targets): New + variables. + (%/site.exp, check-DEJAGNU%): New targets. + (check-am): Run $(MAKE) check-DEJAGNU. + * testsuite/Makefile.in: Regenerated. +2008-10-14 Andrew Haley + + * constants.c (build_constant_data_ref): Make sure we only build + one copy of the decl for the constant pool. + 2008-08-27 Release Manager * GCC 4.3.2 released. diff -Naur gcc-4.3.2.orig/gcc/java/Make-lang.in gcc-4.3.2/gcc/java/Make-lang.in --- gcc-4.3.2.orig/gcc/java/Make-lang.in 2008-04-01 11:49:36.000000000 -0700 +++ gcc-4.3.2/gcc/java/Make-lang.in 2008-12-04 15:00:19.000000000 -0800 @@ -150,6 +150,7 @@ -cp -p $^ $(srcdir)/doc check-java : +check-java-subtargets : # Install hooks: # jc1, gcj, and jvgenmain are installed elsewhere as part diff -Naur gcc-4.3.2.orig/gcc/java/constants.c gcc-4.3.2/gcc/java/constants.c --- gcc-4.3.2.orig/gcc/java/constants.c 2007-11-17 21:23:59.000000000 -0800 +++ gcc-4.3.2/gcc/java/constants.c 2008-10-24 07:21:00.000000000 -0700 @@ -451,21 +451,25 @@ } else { - tree type, decl; tree decl_name = mangled_classname ("_CD_", output_class); + tree decl = IDENTIFIER_GLOBAL_VALUE (decl_name); - /* Build a type with unspecified bounds. The will make sure - that targets do the right thing with whatever size we end - up with at the end. Using bounds that are too small risks - assuming the data is in the small data section. */ - type = build_array_type (ptr_type_node, NULL_TREE); - - /* We need to lay out the type ourselves, since build_array_type - thinks the type is incomplete. */ - layout_type (type); - - decl = build_decl (VAR_DECL, decl_name, type); - TREE_STATIC (decl) = 1; + if (! decl) + { + /* Build a type with unspecified bounds. The will make sure + that targets do the right thing with whatever size we end + up with at the end. Using bounds that are too small risks + assuming the data is in the small data section. */ + tree type = build_array_type (ptr_type_node, NULL_TREE); + + /* We need to lay out the type ourselves, since build_array_type + thinks the type is incomplete. */ + layout_type (type); + + decl = build_decl (VAR_DECL, decl_name, type); + TREE_STATIC (decl) = 1; + IDENTIFIER_GLOBAL_VALUE (decl_name) = decl; + } return decl; } diff -Naur gcc-4.3.2.orig/gcc/passes.c gcc-4.3.2/gcc/passes.c --- gcc-4.3.2.orig/gcc/passes.c 2008-01-22 05:27:52.000000000 -0800 +++ gcc-4.3.2/gcc/passes.c 2008-11-05 12:38:46.000000000 -0800 @@ -1132,6 +1132,7 @@ if (initializing_dump && dump_file && graph_dump_format != no_graph + && cfun && (cfun->curr_properties & (PROP_cfg | PROP_rtl)) == (PROP_cfg | PROP_rtl)) { diff -Naur gcc-4.3.2.orig/gcc/po/ChangeLog gcc-4.3.2/gcc/po/ChangeLog --- gcc-4.3.2.orig/gcc/po/ChangeLog 2008-08-27 11:02:13.000000000 -0700 +++ gcc-4.3.2/gcc/po/ChangeLog 2008-11-23 08:43:50.000000000 -0800 @@ -1,3 +1,35 @@ +2008-11-23 Joseph S. Myers + + * ru.po: Update. + +2008-11-18 Joseph S. Myers + + * ru.po: Update. + +2008-11-07 Joseph S. Myers + + * id.po: Update. + +2008-11-05 Joseph S. Myers + + * id.po: Update. + +2008-11-02 Joseph S. Myers + + * id.po: Update. + +2008-10-31 Joseph S. Myers + + * id.po: Update. + +2008-10-29 Joseph S. Myers + + * id.po: New. + +2008-08-30 Joseph S. Myers + + * fi.po: New. + 2008-08-27 Release Manager * GCC 4.3.2 released. diff -Naur gcc-4.3.2.orig/gcc/predict.c gcc-4.3.2/gcc/predict.c --- gcc-4.3.2.orig/gcc/predict.c 2007-08-26 20:45:06.000000000 -0700 +++ gcc-4.3.2/gcc/predict.c 2008-11-05 12:39:50.000000000 -0800 @@ -1374,6 +1374,7 @@ { edge e; edge_iterator ei; + tree last; FOR_EACH_EDGE (e, ei, bb->succs) { @@ -1396,7 +1397,8 @@ && e->dest != EXIT_BLOCK_PTR && single_succ_p (e->dest) && single_succ_edge (e->dest)->dest == EXIT_BLOCK_PTR - && TREE_CODE (last_stmt (e->dest)) == RETURN_EXPR) + && (last = last_stmt (e->dest)) != NULL_TREE + && TREE_CODE (last) == RETURN_EXPR) { edge e1; edge_iterator ei1; diff -Naur gcc-4.3.2.orig/gcc/real.c gcc-4.3.2/gcc/real.c --- gcc-4.3.2.orig/gcc/real.c 2008-08-19 09:37:13.000000000 -0700 +++ gcc-4.3.2/gcc/real.c 2008-10-22 04:33:04.000000000 -0700 @@ -2341,7 +2341,7 @@ required to be the value of the long double rounded to the nearest double. Rounding means we need a slightly smaller value for LDBL_MAX. */ - clear_significand_bit (r, SIGNIFICAND_BITS - fmt->pnan); + clear_significand_bit (r, SIGNIFICAND_BITS - fmt->pnan - 1); } } @@ -4218,6 +4218,7 @@ false, false, false, + false, false }; diff -Naur gcc-4.3.2.orig/gcc/regmove.c gcc-4.3.2/gcc/regmove.c --- gcc-4.3.2.orig/gcc/regmove.c 2008-01-21 07:54:41.000000000 -0800 +++ gcc-4.3.2/gcc/regmove.c 2008-11-01 05:39:17.000000000 -0700 @@ -686,7 +686,16 @@ { if (reg_mentioned_p (dest, PATTERN (q))) { + rtx note; + PATTERN (q) = replace_rtx (PATTERN (q), dest, src); + note = FIND_REG_INC_NOTE (q, dest); + if (note) + { + remove_note (q, note); + REG_NOTES (q) + = gen_rtx_EXPR_LIST (REG_INC, src, REG_NOTES (q)); + } df_insn_rescan (q); } diff -Naur gcc-4.3.2.orig/gcc/regrename.c gcc-4.3.2/gcc/regrename.c --- gcc-4.3.2.orig/gcc/regrename.c 2007-09-08 19:23:47.000000000 -0700 +++ gcc-4.3.2/gcc/regrename.c 2008-11-25 13:26:19.000000000 -0800 @@ -137,8 +137,15 @@ struct du_chain *t = chain; rtx insn; HARD_REG_SET live; + struct df_ref **def_rec; REG_SET_TO_HARD_REG_SET (live, df_get_live_in (b)); + for (def_rec = df_get_artificial_defs (b->index); *def_rec; def_rec++) + { + struct df_ref *def = *def_rec; + if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) + SET_HARD_REG_BIT (live, DF_REF_REGNO (def)); + } insn = BB_HEAD (b); while (t) { @@ -1315,6 +1322,10 @@ enum machine_mode new_mode, unsigned int regno, unsigned int copy_regno ATTRIBUTE_UNUSED) { + if (GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (orig_mode) + && GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (new_mode)) + return NULL_RTX; + if (orig_mode == new_mode) return gen_rtx_raw_REG (new_mode, regno); else if (mode_change_ok (orig_mode, new_mode, regno)) diff -Naur gcc-4.3.2.orig/gcc/rtlanal.c gcc-4.3.2/gcc/rtlanal.c --- gcc-4.3.2.orig/gcc/rtlanal.c 2007-11-24 14:15:54.000000000 -0800 +++ gcc-4.3.2/gcc/rtlanal.c 2008-11-10 02:43:35.000000000 -0800 @@ -3618,8 +3618,9 @@ enum rtx_code code; unsigned int mode_width = GET_MODE_BITSIZE (mode); - /* For floating-point values, assume all bits are needed. */ - if (FLOAT_MODE_P (GET_MODE (x)) || FLOAT_MODE_P (mode)) + /* For floating-point and vector values, assume all bits are needed. */ + if (FLOAT_MODE_P (GET_MODE (x)) || FLOAT_MODE_P (mode) + || VECTOR_MODE_P (GET_MODE (x)) || VECTOR_MODE_P (mode)) return nonzero; /* If X is wider than MODE, use its mode instead. */ @@ -4132,7 +4133,8 @@ if (mode == VOIDmode) mode = GET_MODE (x); - if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x))) + if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x)) + || VECTOR_MODE_P (GET_MODE (x)) || VECTOR_MODE_P (mode)) return 1; /* For a smaller object, just ignore the high bits. */ diff -Naur gcc-4.3.2.orig/gcc/sched-int.h gcc-4.3.2/gcc/sched-int.h --- gcc-4.3.2.orig/gcc/sched-int.h 2008-08-05 23:34:18.000000000 -0700 +++ gcc-4.3.2/gcc/sched-int.h 2008-09-09 14:17:19.000000000 -0700 @@ -848,6 +848,7 @@ extern void unlink_bb_notes (basic_block, basic_block); extern void add_block (basic_block, basic_block); extern rtx bb_note (basic_block); +extern rtx sched_emit_insn (rtx); /* Functions in sched-rgn.c. */ diff -Naur gcc-4.3.2.orig/gcc/testsuite/ChangeLog gcc-4.3.2/gcc/testsuite/ChangeLog --- gcc-4.3.2.orig/gcc/testsuite/ChangeLog 2008-08-27 11:02:30.000000000 -0700 +++ gcc-4.3.2/gcc/testsuite/ChangeLog 2008-12-19 10:20:41.000000000 -0800 @@ -1,3 +1,708 @@ +2008-12-19 Janis Johnson + + Revert: + 2008-12-12 Janis Johnson + PR libgfortran/24685 + * gfortran.dg/default_format_denormal_2.f90: Change XFAIL to check + for size of long double. + +2008-12-18 Andrew Pinski + + PR middle-end/38565 + * testsuite/g++.dg/torture/pr38565.C: New test. + +2008-12-14 Paul Thomas + + PR fortran/35937 + * gfortran.dg/char_length_14.f90: New test. + +2008-12-12 Janis Johnson + + PR libgfortran/24685 + * gfortran.dg/default_format_denormal_2.f90: Change XFAIL to check + for size of long double. + +2008-12-11 Michael Meissner + + * gcc.target/spu/ea: Delete __ea testsuite directory accidently + committed to 4.3 branch. + +2008-12-08 Janis Johnson + + Backport from mainline: + 2008-09-16 Jakub Jelinek + + PR testsuite/36889 + * lib/fortran-torture.exp (get-fortran-torture-options): Only + set test_tree_vectorize on i?86/x86_64 resp. sparc* if sse2 resp. + ultrasparc hw is available. + +2008-12-05 Janis Johnson + + * lib/target-supports.exp (check_effective_target_hard_dfp): New. + * gcc.dg/dfp/convert-dfp-round.c: Skip for hard_dfp. + * gcc.dg/dfp/fe-binop.c: Ditto. + * gcc.dg/dfp/fe-convert-1.c: Ditto. + + Backport from mainline: + 2008-05-15 Janis Johnson + + * lib/torture-options.exp: New support for torture options. + * lib/gfortran-dg.exp (gfortran-dg-runtest): Use new torture procs. + * lib/c-torture.exp: Define C_TORTURE_OPTIONS instead of + TORTURE_OPTIONS; don't define torture_with_loops and + torture_without_loops. + * lib/gcc-dg.exp: Define DG_TORTURE_OPTIONS instead of + TORTURE_OPTIONS; don't define torture_with_loops and + torture_without_loops. + (gcc-dg-runtest): Use new torture procs if no torture options defined. + * lib/fortran-torture.exp: Define FORTRAN_TORTURE_OPTIONS instead of + TORTURE_OPTIONS. + (fortran-torture-execute): Use torture_with_loops instead of + TORTURE_OPTIONS. + (fortran-torture): Ditto. + * lib/objc-torture.exp: Define OBJC_TORTURE_OPTIONS instead of + TORTURE_OPTIONS; don't define torture_with_loops and + torture_without_loops. + * gcc.c-torture/execute/execute.exp: Use new torture procs. + * gcc.c-torture/execute/builtins/builtins.exp: Ditto. + * gcc.c-torture/execute/ieee/ieee.exp: Ditto. + * gcc.c-torture/unsorted/unsorted.exp: Ditto. + * gfortran.fortran-torture/execute/execute.exp: Ditto. + * gfortran.fortran-torture/compile/compile.exp: Ditto. + * gcc.target/x86_64/abi/abi-x86_64.exp: Ditto. + * gcc.target/i386/math-torture/math-torture.exp: Define + MATH_TORTURE_OPTIONS, use new torture procs. + * gcc.dg/pch/pch.exp: Use new torture procs. + * gcc.dg/format/format.exp: Ditto. + * gcc.misc-tests/i386-prefetch.exp: Ditto. + * gcc.misc-tests/dectest.exp: Ditto. + * objc.dg/pch/pch.exp: Ditto. + * objc/execute/execute.exp: Ditto. + * objc/execute/exceptions/exceptions.exp: Ditto. + * objc/compile/compile.exp: Ditto. + + Backport from mainline: + 2008-05-27 Richard Sandiford + + * lib/fortran-torture.exp (get-fortran-torture-options): + New function, replacing old FORTRAN_TORTURE_OPTIONS code. + * gfortran.fortran-torture/compile/compile.exp: Use + [get-fortran-torture-options] instead of $FORTRAN_TORTURE_OPTIONS. + * gfortran.fortran-torture/execute/execute.exp: Likewise. + +2008-12-05 Eric Botcazou + + * gcc.dg/union-5.c: Run only on x86 and x86-64. + +2008-12-04 Eric Botcazou + + * gcc.dg/union-5.c: New test. + +2008-12-04 Eric Botcazou + + * gcc.dg/union-4.c: New test. + +2008-12-03 Janis Johnson + + * gcc.dg/vect/pr33953.c: XFAIL dump scans for powerpc. + +2008-12-03 Eric Botcazou + + * gcc.dg/torture/pr37868.c: Skip on the SPARC. + +2008-12-02 Janis Johnson + + Backport from mainline: + 2008-08-26 Janis Johnson + + * gcc.dg/Wstrict-aliasing-bogus-ref-all-2.c: Ignore a warning. + * g++.dg/ext/altivec-3.C: Move AltiVec code out of main. + + Backport from mainline: + 2008-07-10 2008-07-10 Joseph Myers + + PR middle-end/29056 + * gcc.target/powerpc/ppc-negeq0-1.c: Use long instead of int. + Adjust shift and scan-assembler-not pattern to allow for 64-bit + case. + + Backport from mainline: + 2008-06-09 Joseph Myers + + * gcc.dg/pr34856.c: Condition use of -maltivec on + powerpc_altivec_ok. Use -w on other powerpc*-*-linux*. + + Backport from mainline: + 2008-05-20 Janis Johnson + + * g++.dg/ext/vector14.C: Ignore a possible warning. + + Backport from mainline: + 2008-04-21 Steve Ellcey + + * gcc.dg/vect/pr33953.c: XFAIL if vect_no_align. + + Backport from mainline: + 2008-04-04 Janis Johnson + + * gcc.dg/var-expand3.c: Skip for powerpc-linux if not on AltiVec HW. + + * gcc.dg/torture/builtin-modf-1.c: Use special options for + powerpc*-*-linux*. + + Backport from mainline: + 2008-04-04 Janis Johnson + + * g++.dg/other/anon5.C: Don't depend on line number for error message. + +2008-12-02 Janis Johnson + + Backport from mainline: + 2008-11-26 Janis Johnson + + PR testsuite/28870 + * lib/timeout.exp: New. + * lib/timeout-dg.exp: New. + * lib/gcc-dg.exp: Include new timeout library files. + (dg-test): Unset timeout variables. + * lib/gcc.exp (gcc_target_compile): Set timeout value from new proc. + * lib/g++.exp (g++_target_compile): Ditto. + * lib/gfortran.exp (gfortran_target_compile): Ditto. + * lib/objc.exp (objc_target_compile): Ditto. + * lib/obj-c++.exp (obj-c++_target_compile): Ditto. + * lib/obj-c++.exp (obj-c++_target_compile): Ditto. + * lib/gnat.exp (gnat_target_compile): Ditto. + +2008-11-30 Eric Botcazou + + * g++.dg/opt/reload3.C: New test. + +2008-11-24 Paul Thomas + + PR fortran/34820 + * gfortran.dg/alloc_comp_constructor_6.f90 : New test. + * gfortran.dg/alloc_comp_basics_1.f90 : Reduce expected refs to + 'builtin_free' from 24 to 18. + + PR fortran/34143 + * gfortran.dg/alloc_comp_constructor_5.f90 : New test. + + PR fortran/32795 + * gfortran.dg/alloc_comp_constructor_4.f90 : New test. + +2008-11-29 Paul Thomas + + PR fortran/37735 + * gfortran.dg/alloc_comp_assign_7.f90: New test. + +2008-11-27 Paul Thomas + + PR fortran/36526 + * gfortran.dg/pure_formal_proc_2.f90: New test. + +2008-11-24 Paul Thomas + + PR fortran/38119 + * gfortran.dg/array_temporaries_3.f90: New test. + +2008-11-24 Paul Thomas + + PR fortran/38033 + * gfortran.dg/array_section_2.f90: New test. + +2008-11-24 Paul Thomas + + PR fortran/37926 + * gfortran.dg/dummy_procedure_3.f90: New test. + +2008-11-24 Mikael Morin + + PR fortran/35681 + * gfortran.dg/elemental_dependency_1.f90: Correct strings in test. + +2008-11-24 Steven G. Kargl + + PR fortran/37792 + * gfortran.dg/arithmetic_overflow_1.f90: New test. + +2008-11-24 Mikael Morin + + PR fortran/35681 + * gfortran.dg/elemental_dependency_1.f90: Really commit it. + +2008-11-24 Mikael Morin + + PR fortran/35681 + * gfortran.dg/elemental_dependency_1.f90: New test. + +2008-11-23 Thomas Koenig + + PR libfortran/38135 + Backport from trunk. + * gfortran.dg/reshape_pad_1.f90: New test case. + +2008-11-21 Ben Elliston + + * gcc.c-torture/compile/sync-3.c: Remove dg-message directive. + +2008-11-20 Richard Guenther + + PR tree-optimization/37868 + * gcc.dg/torture/pr37868.c: New testcase. + * gcc.c-torture/execute/pr38048-1.c: Likewise. + * gcc.c-torture/execute/pr38048-2.c: Likewise. + + Backport from mainline: + 2008-07-07 Richard Guenther + + * gcc.dg/torture/pta-ptrarith-1.c: New testcase. + * gcc.dg/torture/pta-ptrarith-2.c: Likewise. + +2008-11-19 Dodji Seketeli + + PR c++/37142 + * g++.dg/template/crash79.C: New test. + +2008-11-19 Dodji Seketeli + + PR c++/35405 + * g++.dg/template/crash84.C: New test. + +2008-11-19 Jason Merrill + + PR c++/37563 + * g++.dg/template/pseudodtor5.C: New test. + +2008-11-19 Paul Thomas + + PR fortran/38171 + * gfortran.dg/module_equivalence_6.f90: New test. + +2008-11-18 Ben Elliston + + Backport from mainline: + 2008-09-28 Andrew Pinski + + PR target/37640 + * gcc.c-torture/compile/sync-3.c: New testcase to check that + addresses of non zero offset works. + +2008-11-14 Jason Merrill + + PR c++/38030 + * g++.dg/template/lookup8.C: New test. + +2008-11-14 Dodji Seketeli + + PR debug/27574 + * g++.dg/debug/dwarf2/local-var-in-contructor.C: New test. + +2008-11-14 Paul Thomas + + PR fortran/37836 + * gfortran.dg/minmaxval_1.f90: New test. + +2008-11-13 Jason Merrill + + PR c++/37932 + * g++.dg/conversion/bitfield11.C: New test. + +2008-11-13 Uros Bizjak + + Backport from mainline: + 2008-06-06 Uros Bizjak + + PR rtl-optimization/36438 + * gcc.target/i386/pr36438.c + +2008-11-12 Jason Merrill + + PR c++/38007 + * g++.dg/conversion/bitfield10.C: New test. + * g++.old-deja/g++.mike/enum1.C: Expect warn about assignment. + * g++.dg/expr/bitfield9.C: Pass -Wno-overflow. + +2008-11-12 Andreas Krebbel + + * gcc.target/s390/frame-addr1.c: New testcase. + * gcc.target/s390/frame-addr2.c: New testcase. + * gcc.target/s390/return-addr1.c: New testcase. + * gcc.target/s390/return-addr2.c: New testcase. + +2008-11-10 Eric Botcazou + + * g++.dg/other/anon5.C: Skip on Solaris. + +2008-11-10 Uros Bizjak + + Backport from mainline: + 2008-11-10 Ralph Loader + + PR middle-end/37807 + PR middle-end/37809 + * gcc.target/i386/mmx-8.c: New test. + +2008-11-09 John David Anglin + + Backport from mainline: + 2008-04-22 Steve Ellcey + + * gcc.dg/struct/wo_prof_global_var.c: Initialize array. + * gcc.dg/struct/wo_prof_malloc_size_var.c: Ditto. + * gcc.dg/struct/w_prof_local_var.c: Ditto. + * gcc.dg/struct/w_prof_global_var.c: Ditto. + * gcc.dg/struct/wo_prof_local_var.c: Ditto. + +2008-11-08 Paul Thomas + + PR fortran/37597 + * gfortran.dg/host_assoc_call_5.f90: New test. + +2008-11-08 Mikael Morin + + PR fortran/35820 + * gfortran.dg/nested_forall_1.f: New test. + +2008-11-08 Paul Thomas + + PR fortran/37445 + * gfortran.dg/host_assoc_call_3.f90: New test. + * gfortran.dg/host_assoc_call_4.f90: New test. + * gfortran.dg/host_assoc_function_4.f90: New test. + +2008-11-06 Richard Guenther + + Backport from mainline: + 2008-09-13 Raksit Ashok + + PR rtl-optimization/37489 + * g++.dg/opt/cse3.C: New testcase. + * gcc.dg/c-torture/pr37969.c: New testcase. + +2008-11-05 Jakub Jelinek + + PR c/37924 + * gcc.c-torture/execute/pr37924.c: New test. + + PR tree-optimization/37879 + * gcc.dg/pr37879.c: New test. + + PR middle-end/37858 + * gcc.dg/pr37858.c: New test. + + PR middle-end/37870 + * gcc.target/i386/pr37870.c: New test. + +2008-11-05 Hans-Peter Nilsson + + PR target/38016 + * gcc.c-torture/execute/ieee/pr38016.c, + gcc.c-torture/execute/ieee/pr38016.c: New test. + +2008-11-03 Eric Botcazou + + * gnat.dg/array5.adb New test. + +2008-11-01 Hans-Peter Nilsson + + PR target/37939 + * gcc.target/cris/biap.c: New test. + +2008-11-01 Mikael Morin + + PR fortran/37903 + * gfortran.dg/vector_subscript_4.f90: New test. + +2008-11-01 Mikael Morin + + PR fortran/37749 + * gfortran.dg/vector_subscript__5.f90: New test. + +2008-10-28 Jerry DeLisle + + PR middle-end/37882 + * gcc.c-torture/execute/pr37882.c: New test. + +2008-10-21 Richard Guenther + + * gcc.dg/tree-ssa/alias-19.c: New testcase. + +2008-10-19 Jerry DeLisle + + PR fortran/37723 + * gfortran.dg/dependency_22.f90: New test. + +2008-10-19 Paul Thomas + + PR fortran/37787 + * gfortran.dg/module_equivalence_5.f90: New test. + +2008-10-17 Andrew MacLeod + + PR tree-optimization/37102 + * gcc.c-torture/execute/pr37102.c: New Test. + +2008-10-11 Paul Thomas + + PR fortran/37794 + * gfortran.dg/used_types_24.f90: New test. + +2008-10-11 Paul Thomas + + PR fortran/35680 + * gfortran.dg/transfer_array_intrinsic_5.f90: New test. + +2008-10-08 Simon Martin + + PR c/35437 + * gcc.dg/struct-parse-2.c: New test. + * g++.dg/parse/struct-4.C: New test. + +2008-10-07 H.J. Lu + + Backport from mainline: + 2008-10-07 H.J. Lu + + PR middle-end/37731 + * gcc.dg/torture/pr37731-1.c: New. + * gcc.dg/torture/pr37731-2.c: Likewise. + +2008-10-07 Eric Botcazou + + * gnat.dg/loop_optimization4.adb: New test. + * gnat.dg/loop_optimization4_pkg.ad[sb]: New helper. + +2008-10-06 Eric Botcazou + + * gnat.dg/unchecked_convert2.adb: New test. + +2008-10-05 Paul Thomas + + PR fortran/37706 + * gfortran.dg/module_equivalence_4.f90: New test. + +2008-09-30 Simon Martin + + PR c++/37555 + * g++.dg/parse/error32.C: New test. + +2008-09-28 Eric Botcazou + + * gnat.dg/conv_decimal.adb: New test. + +2008-09-26 Tobias Burnus + + PR fortran/37580 + * gfortran.dg/pointer_assign_5.f90: New test. + * gfortran.dg/pointer_assign_6.f90: New test. + +2008-09-26 Tobias Burnus + + PR fortran/37504 + * gfortran.dg/protected_7.f90: New test. + +2008-09-25 Jakub Jelinek + + PR c/37645 + * gcc.dg/pr37645.c: New test. + +2008-09-25 Tobias Burnus + + PR fortran/37626 + * gfortran.dg/allocatable_function_4.f90: New test. + +2008-09-24 Paul Thomas + + PR fortran/35945 + * gfortran.dg/host_assoc_types_2.f90: New test. + + PR fortran/36700 + * gfortran.dg/host_assoc_call_2.f90: New test. + +2008-09-24 Paul Thomas + + PR fortran/37583 + * gfortran.dg/entry_18.f90: New test. + +2008-09-23 Eric Botcazou + + * gcc.dg/pragma-init-fini.c: Use dg-warning in lieu of dg-error. + * gcc.dg/pragma-align-2.c: Likewise. + * gcc.dg/format/cmn-err-1.c: Likewise. + +2008-09-23 Paul Thomas + + PR fortran/37274 + * gfortran.dg/used_types_22.f90: New test. + * gfortran.dg/used_types_23.f90: New test. + + PR fortran/36374 + * gfortran.dg/generic_17.f90: New test. + * gfortran.dg/ambiguous_specific_2.f90: New test. + * gfortran.dg/generic_actual_arg.f90: Add test for case that is + not ambiguous. + + PR fortran/36454 + * gfortran.dg/access_spec_3.f90: New test. + +2008-09-20 Richard Guenther + + PR middle-end/37236 + * gfortran.fortran-torture/compile/pr37236.f: New testcase. + +2008-09-19 Richard Guenther + + PR tree-optimization/36343 + * gcc.c-torture/execute/pr36343.c: New testcase. + +2008-09-19 Uros Bizjak + + Backport from mainline: + 2008-09-18 Uros Bizjak + + PR rtl-optimization/37544 + * gcc.dg/pr37544.c: New test. + +2008-09-18 Janis Johnson + + Backport from mainline: + 2008-04-08 Janis Johnson + + PR target/35620 + * gcc.dg/dfp/pr35620.c: New test. + * gcc.dg/dfp/func-pointer.c: New test. + * gcc.dg/dfp/func-deref.c: New test. + + Backport from mainline: + 2008-04-03 Janis Johnson + + PR c/35712 + * gcc.dg/dfp/constants-zero.c: New test. + +2008-09-13 Daniel Kraft + + PR fortran/35770 + * gfortran.dg/implicit_12.f90: New test. + +2008-09-11 Daniel Kraft + + PR fortran/36214 + * gfortran.dg/boz_9.f90: Corrected test. + * gfortran.dg/boz_11.f90: New test. + * gfortran.dg/boz_12.f90: New test. + +2008-09-08 Daniel Kraft + + PR fortran/37199 + * gfortran.dg/array_function_2.f90: New test. + +2008-09-09 Jakub Jelinek + + PR c++/37389 + * g++.dg/parse/enum4.C: New test. + +2008-09-05 Daniel Kraft + + PR fortran/35837 + * gfortran.dg/save_3.f90: New test. + +2008-09-04 Daniel Kraft + + PR fortran/37099 + * gfortran.dg/string_compare_1.f90: New text. + * gfortran.dg/string_compare_2.f90: New text. + * gfortran.dg/string_compare_3.f90: New text. + +2008-09-07 Richard Guenther + Ira Rosen + + PR tree-optimization/36630 + * gcc.dg/vect/pr36630.c: New test. + +2008-09-04 Ian Lance Taylor + + * g++.dg/init/const7.C: New test. + +2008-09-03 Jakub Jelinek + + PR c++/37348 + * g++.dg/parse/crash45.C: New test. + +2008-08-30 Daniel Kraft + + PR fortran/37193 + * gfortran.dg/use_rename_4.f90: New test. + * gfortran.dg/use_rename_5.f90: New test. + +2008-06-24 Paul Thomas + + PR fortran/36371 + * gfortran.dg/data_array_5.f90: New test. + +2008-09-02 Jakub Jelinek + + PR target/36332 + * gcc.c-torture/execute/ieee/pr36332.c: New test. + +2008-09-01 Jakub Jelinek + + PR middle-end/36449 + * g++.dg/opt/pr36449.C: New test. + +2008-08-31 Jakub Jelinek + + PR target/37168 + * gcc.target/powerpc/pr37168.c: New test. + +2008-08-29 Jakub Jelinek + + PR c/37261 + * gcc.dg/pr37261.c: New test. + +2008-08-28 Ulrich Weigand + + * gcc.target/powerpc/altivec-volatile.c: New test. + +2008-08-28 Dodji Seketeli + + PR c++/36741 + * g++.dg/other/new-size-type.C: New test. + +2008-08-28 Richard Guenther + + PR middle-end/36548 + PR middle-end/37125 + * gcc.c-torture/execute/pr37125.c: New testcase. + +2008-08-28 Richard Guenther + + PR middle-end/36817 + * gcc.c-torture/compile/pr36817.c: New testcase. + +2008-08-28 Uros Bizjak + + PR target/37184 + * gcc.target/i386/pr37184.c: New test. + + PR target/37191 + * gcc.target/i386/pr37191.c: New test. + + PR target/37197 + * gcc.target/i386/pr37197.c: New test. + 2008-08-27 Release Manager * GCC 4.3.2 released. diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/conversion/bitfield10.C gcc-4.3.2/gcc/testsuite/g++.dg/conversion/bitfield10.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/conversion/bitfield10.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/conversion/bitfield10.C 2008-11-12 14:08:01.000000000 -0800 @@ -0,0 +1,24 @@ +// PR c++/38007 +// We need to use the conversion function to the declared type of a bitfield, +// not the lowered bitfield type. +// { dg-do link } + +struct A +{ + operator unsigned int() { return 42; } + operator unsigned char(); +}; + +struct B +{ + unsigned int b : 8; +}; + +int +main () +{ + A u; + unsigned int v = u; + B w; + w.b = u; +} diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/conversion/bitfield11.C gcc-4.3.2/gcc/testsuite/g++.dg/conversion/bitfield11.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/conversion/bitfield11.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/conversion/bitfield11.C 2008-11-13 20:16:07.000000000 -0800 @@ -0,0 +1,8 @@ +// Make sure that digest_init converts to the declared type of the +// bitfield, not just the lowered type. + +enum E { EA, EB }; + +struct A { E e: 8; }; + +A a = { 0 }; // { dg-error "invalid conversion" } diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/debug/dwarf2/local-var-in-contructor.C gcc-4.3.2/gcc/testsuite/g++.dg/debug/dwarf2/local-var-in-contructor.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/debug/dwarf2/local-var-in-contructor.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/debug/dwarf2/local-var-in-contructor.C 2008-11-14 05:26:59.000000000 -0800 @@ -0,0 +1,30 @@ +// Contributed by Dodji Seketeli +// Origin PR27574 +// { dg-do compile } +// { dg-options "-O0 -g" } +// { dg-final { scan-assembler "problem" } } + +void f (int *) +{ +} + +class A +{ +public: + A(int i); +}; + +A::A(int i) +{ + int *problem = new int(i); + f (problem); +} + +int +main (void) +{ + A a (0); + + return 0; +} + diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/expr/bitfield9.C gcc-4.3.2/gcc/testsuite/g++.dg/expr/bitfield9.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/expr/bitfield9.C 2007-07-27 10:13:29.000000000 -0700 +++ gcc-4.3.2/gcc/testsuite/g++.dg/expr/bitfield9.C 2008-11-12 14:08:01.000000000 -0800 @@ -1,5 +1,6 @@ // PR c++/32346 // { dg-do run } +// { dg-options "-Wno-overflow" } extern "C" void abort(); diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/ext/altivec-3.C gcc-4.3.2/gcc/testsuite/g++.dg/ext/altivec-3.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/ext/altivec-3.C 2006-06-20 16:33:58.000000000 -0700 +++ gcc-4.3.2/gcc/testsuite/g++.dg/ext/altivec-3.C 2008-12-02 14:11:55.000000000 -0800 @@ -120,16 +120,19 @@ CHECK_INVARIANT (vec_all_eq (vxi.v, vx_g.v)); } -int main(void) +void main1(void) { CHECK_INVARIANT (sizeof(struct foo) == 8 && sizeof(struct vfoo) == 48); - altivec_check(); - bar(i_1, x_g, (short)i_2, (float)d_2, ld_1, (char)i_1, d_3); baz(i_1, v_g, i_1, vx_g, i_1, v2_g, i_1, vx2_g); quux(i_1, v_g, v_g); baz2(i_1, vx_g); - +} + +int main(void) +{ + altivec_check(); + main1(); return 0; } diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/ext/vector14.C gcc-4.3.2/gcc/testsuite/g++.dg/ext/vector14.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/ext/vector14.C 2008-04-28 05:17:27.000000000 -0700 +++ gcc-4.3.2/gcc/testsuite/g++.dg/ext/vector14.C 2008-12-02 14:11:55.000000000 -0800 @@ -1,6 +1,8 @@ // PR c++/35758 // { dg-do compile } // { dg-options "-msse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ +// Ignore warning on some powerpc-linux configurations. +// { dg-prune-output "non-standard ABI extension" } #define vector __attribute__((vector_size(16))) diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/init/const7.C gcc-4.3.2/gcc/testsuite/g++.dg/init/const7.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/init/const7.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/init/const7.C 2008-09-04 22:35:03.000000000 -0700 @@ -0,0 +1,13 @@ +// { dg-do compile } +// { dg-options "-fdump-tree-gimple" } + +struct s { int x, y; }; +short offsets[1] = { + ((char*) &(((struct s*)16)->y) - (char *)16), +}; + +// This ensures that we get a dump whether or not the bug is present. +void fn() { } + +// { dg-final { scan-tree-dump-not "initialization" "gimple" } } +// { dg-final { cleanup-tree-dump "gimple" } } diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/opt/cse3.C gcc-4.3.2/gcc/testsuite/g++.dg/opt/cse3.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/opt/cse3.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/opt/cse3.C 2008-11-06 07:05:44.000000000 -0800 @@ -0,0 +1,48 @@ +// This testcase resulted in invalid code generation on x86_64 targets +// due to a bug in fold_rtx. For a "true" value, fold_rtx represented it +// as const_true_rtx in floating-point mode, if the FLOAT_STORE_FLAG_VALUE +// macro is not defined. + +// { dg-do run } +// { dg-options "-O1 -fno-guess-branch-probability -fcse-follow-jumps -fgcse -frerun-cse-after-loop" } + +class StatVal { + + public: + + StatVal(double ev, double va) + : m(ev), + v(va) {} + + StatVal(const StatVal& other) + : m(other.m), + v(other.v) {} + + StatVal& operator*=(const StatVal& other) { + double A = m == 0 ? 1.0 : v / (m * m); + double B = other.m == 0 ? 1.0 : other.v / (other.m * other.m); + m = m * other.m; + v = m * m * (A + B); + return *this; + } + + double m; + double v; +}; + +extern "C" void abort (void); + +const StatVal two_dot_three(2, 0.3); + +int main(int argc, char **argv) { + + StatVal product3(two_dot_three); + + product3 *= two_dot_three; + + if (product3.v > 2.5) + { + abort(); + } + return 0; +} diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/opt/pr36449.C gcc-4.3.2/gcc/testsuite/g++.dg/opt/pr36449.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/opt/pr36449.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/opt/pr36449.C 2008-09-01 04:32:18.000000000 -0700 @@ -0,0 +1,70 @@ +// PR middle-end/36449 +// { dg-do run } +// { dg-options "-O3" } + +extern "C" void exit (int); +extern "C" void abort (); + +struct R +{ + short a; + short b; +}; + +struct S +{ + R e; + long f; + long g; +}; + +struct T +{ + short c; + short d; +}; + +struct U +{ + long h[0x1ffffff + 1]; + T i; +}; + +U *j; + +void __attribute__((noinline)) +bar () +{ + exit (0); +} + +void __attribute__((noinline)) +foo () +{ + S s; + + s.e.a = 36; + s.e.b = 38; + if (s.e.a == j->i.c && s.e.b == j->i.d) + bar (); +} + +int +main () +{ + try + { + j = new U; + } + catch (...) + { + return 0; + } + j->i.c = 36; + j->i.d = 38; + j->h[0] = 1; + j->h[1] = 2; + j->h[2] = 3; + foo (); + abort (); +} diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/opt/reload3.C gcc-4.3.2/gcc/testsuite/g++.dg/opt/reload3.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/opt/reload3.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/opt/reload3.C 2008-11-30 11:21:10.000000000 -0800 @@ -0,0 +1,39 @@ +// PR target/38287 +// { dg-do run } +// { dg-options "-O2 -mcpu=v8 -fPIC" { target { { sparc*-*-* } && { ilp32 && fpic } } } } + +#include + +class QTime +{ +public: + explicit QTime(int ms = 0) : ds(ms) {} + static QTime currentTime() { return QTime(); } + QTime addMSecs(int ms) const; + int msecs() const { return ds; } +private: + unsigned ds; +}; + +static const unsigned MSECS_PER_DAY = 86400000; + +QTime QTime::addMSecs(int ms) const +{ + QTime t; + if ( ms < 0 ) { + // % not well-defined for -ve, but / is. + int negdays = (MSECS_PER_DAY-ms) / MSECS_PER_DAY; + t.ds = ((int)ds + ms + negdays*MSECS_PER_DAY) + % MSECS_PER_DAY; + } else { + t.ds = ((int)ds + ms) % MSECS_PER_DAY; + } + return t; +} + +int main() +{ + if (QTime(1).addMSecs(1).msecs() != 2) + abort (); + return 0; +} diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/other/anon5.C gcc-4.3.2/gcc/testsuite/g++.dg/other/anon5.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/other/anon5.C 2008-03-30 16:23:43.000000000 -0700 +++ gcc-4.3.2/gcc/testsuite/g++.dg/other/anon5.C 2008-12-02 14:11:55.000000000 -0800 @@ -4,7 +4,7 @@ // problem is that mips*-elf tests run from KSEG0 (which is in the upper // half of the address range), and the linker compares sign-extended // addresses from .debug_aranges with unextended addresses. -// { dg-do link { target { ! { hppa*-*-hpux* mips*-*-elf* } } } } +// { dg-do link { target { ! { hppa*-*-hpux* *-*-solaris2.* mips*-*-elf* } } } } // { dg-options "-g" } namespace { @@ -16,7 +16,9 @@ const bool &f() { - return c::t; // { dg-error "undefined" } + return c::t; // { dg-error "undefined" "undefined" { target *-*-* } 0 } + // Some targets report the error for the previous line, others + // don't give line number information for it, so use line 0. } int main(void) diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/other/new-size-type.C gcc-4.3.2/gcc/testsuite/g++.dg/other/new-size-type.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/other/new-size-type.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/other/new-size-type.C 2008-08-28 07:49:25.000000000 -0700 @@ -0,0 +1,10 @@ +// Contributed by Dodji Seketeli +// Origin: PR c++/36741 + +#include +const char* +foo() +{ + return new char[~static_cast(0)];// { dg-bogus "large" } +} + diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/parse/crash45.C gcc-4.3.2/gcc/testsuite/g++.dg/parse/crash45.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/parse/crash45.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/parse/crash45.C 2008-09-03 13:38:38.000000000 -0700 @@ -0,0 +1,7 @@ +// PR c++/37348 +// { dg-do compile } + +struct A +{ + template int f (B); // { dg-error "was not declared in this scope|cannot be a member template" } +}; diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/parse/enum4.C gcc-4.3.2/gcc/testsuite/g++.dg/parse/enum4.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/parse/enum4.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/parse/enum4.C 2008-09-09 13:23:08.000000000 -0700 @@ -0,0 +1,10 @@ +// PR c++/37389 +// { dg-do compile } +// { dg-options "-std=gnu++98" } + +enum +{ + A = 9223372036854775807ULL * 2 + 1, + B = B0, // { dg-error "was not declared|overflow" } + C = C0 // { dg-error "was not declared" } +}; diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/parse/error32.C gcc-4.3.2/gcc/testsuite/g++.dg/parse/error32.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/parse/error32.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/parse/error32.C 2008-09-30 12:56:13.000000000 -0700 @@ -0,0 +1,12 @@ +/* PR c++/37555 */ +/* { dg-do "compile" } */ + +struct A {}; + +typedef void (A::T)(); /* { dg-error "typedef name may not be a nested-name-specifier" } */ + +void foo() +{ + T t; + t; /* { dg-error "was not declared" } */ +} diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/parse/struct-4.C gcc-4.3.2/gcc/testsuite/g++.dg/parse/struct-4.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/parse/struct-4.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/parse/struct-4.C 2008-10-07 21:17:27.000000000 -0700 @@ -0,0 +1,13 @@ +/* PR c/35437 */ +/* { dg-do "compile" } */ + +struct A +{ + int i; + struct A a; /* { dg-error "has incomplete type" } */ +}; + +void foo() +{ + struct A b = { 0 }; +} diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/template/crash79.C gcc-4.3.2/gcc/testsuite/g++.dg/template/crash79.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/template/crash79.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/template/crash79.C 2008-11-19 16:05:04.000000000 -0800 @@ -0,0 +1,16 @@ +// Contributed by Dodji Seketeli +// Origin: PR c++/37142 +// { dg-do compile } + +template class W> struct A {}; + +template struct B {}; + +int +main () +{ + A a; + return 0; +} + + diff -Naur gcc-4.3.2.orig/gcc/testsuite/g++.dg/template/crash84.C gcc-4.3.2/gcc/testsuite/g++.dg/template/crash84.C --- gcc-4.3.2.orig/gcc/testsuite/g++.dg/template/crash84.C 1969-12-31 16:00:00.000000000 -0800 +++ gcc-4.3.2/gcc/testsuite/g++.dg/template/crash84.C 2008-11-19 14:36:31.000000000 -0800 @@ -0,0 +1,19 @@ +// Contributed by Dodji Seketeli +// Origin PR c++/35405 +// { dg-do compile } + +template struct a +{ + template