Mercurial > hg > CbC > CbC_gcc
changeset 68:561a7518be6b
update gcc-4.6
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/bootstrap-lto.mk Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,6 @@ +# This option enables LTO for stage2 and stage3. It requires lto to +# be enabled for stage1 with --enable-stage1-languages. + +STAGE2_CFLAGS += -flto=jobserver -frandom-seed=1 +STAGE3_CFLAGS += -flto=jobserver -frandom-seed=1 +STAGEprofile_CFLAGS += -fno-lto
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/cloog.m4 Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,288 @@ +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3, or (at your option) any later +# version. +# +# GCC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. +# +# Contributed by Andreas Simbuerger <simbuerg@fim.uni-passau.de> + +# CLOOG_INIT_FLAGS () +# ------------------------- +# Provide configure switches for CLooG support. +# Initialize clooglibs/clooginc according to the user input. +AC_DEFUN([CLOOG_INIT_FLAGS], +[ + AC_ARG_WITH(cloog, + [AS_HELP_STRING( + [--with-cloog=PATH], + [Specify prefix directory for the installed CLooG-PPL package. + Equivalent to --with-cloog-include=PATH/include + plus --with-cloog-lib=PATH/lib])]) + AC_ARG_WITH([cloog-include], + [AS_HELP_STRING( + [--with-cloog-include=PATH], + [Specify directory for installed CLooG include files])]) + AC_ARG_WITH([cloog-lib], + [AS_HELP_STRING( + [--with-cloog-lib=PATH], + [Specify the directory for the installed CLooG library])]) + + AC_ARG_ENABLE(cloog-backend, + [AS_HELP_STRING( + [--enable-cloog-backend[[=BACKEND]]], + [set the CLooG BACKEND used to either isl, ppl or ppl-legacy (default)])], + [ if test "x${enableval}" = "xisl"; then + cloog_backend=isl + elif test "x${enableval}" = "xppl"; then + cloog_backend=ppl + else + cloog_backend=ppl-legacy + fi], cloog_backend=ppl-legacy) + AC_ARG_ENABLE(cloog-version-check, + [AS_HELP_STRING( + [--disable-cloog-version-check], + [disable check for CLooG version])], + ENABLE_CLOOG_CHECK=$enableval, + ENABLE_CLOOG_CHECK=yes) + + # Initialize clooglibs and clooginc. + case $with_cloog in + no) + clooglibs= + clooginc= + ;; + "" | yes) + ;; + *) + clooglibs="-L$with_cloog/lib" + clooginc="-I$with_cloog/include" + ;; + esac + if test "x${with_cloog_include}" != x ; then + clooginc="-I$with_cloog_include" + fi + if test "x${with_cloog_lib}" != x; then + clooglibs="-L$with_cloog_lib" + fi + + dnl Flags needed for CLOOG + AC_SUBST(clooglibs) + AC_SUBST(clooginc) +] +) + +# CLOOG_REQUESTED (ACTION-IF-REQUESTED, ACTION-IF-NOT) +# ---------------------------------------------------- +# Provide actions for failed CLooG detection. +AC_DEFUN([CLOOG_REQUESTED], +[ + AC_REQUIRE([CLOOG_INIT_FLAGS]) + + if test "x${with_cloog}" = xno; then + $2 + elif test "x${with_cloog}" != x \ + || test "x${with_cloog_include}" != x \ + || test "x${with_cloog_lib}" != x ; then + $1 + else + $2 + fi +] +) + +# _CLOOG_ORG_PROG_ISL () +# ------------------ +# Helper for detecting CLooG.org's ISL backend. +m4_define([_CLOOG_ORG_PROG_ISL],[AC_LANG_PROGRAM( + [#include "cloog/cloog.h" ], + [cloog_version ()])]) + +# _CLOOG_ORG_PROG_PPL () +# ------------------ +# Helper for detecting CLooG.org's PPL backend. +m4_define([_CLOOG_ORG_PROG_PPL],[AC_LANG_PROGRAM( + [#include "cloog/cloog.h" + #include "cloog/ppl/cloog.h"], + [cloog_version ()])]) + +# _CLOOG_PPL_LEGACY_PROG () +# ------------------------- +# Helper for detecting CLooG-Legacy (CLooG-PPL). +m4_define([_CLOOG_PPL_LEGACY_PROG], [AC_LANG_PROGRAM( + [#include "cloog/cloog.h"], + [#ifndef CLOOG_PPL_BACKEND + choke me + #endif ])]) + +# CLOOG_FIND_FLAGS () +# ------------------ +# Detect the used CLooG-backend and set clooginc/clooglibs/cloog_org. +# Only look for the CLooG backend type specified in --enable-cloog-backend +AC_DEFUN([CLOOG_FIND_FLAGS], +[ + AC_REQUIRE([CLOOG_INIT_FLAGS]) + + _cloog_saved_CFLAGS=$CFLAGS + _cloog_saved_CPPFLAGS=$CPPFLAGS + _cloog_saved_LDFLAGS=$LDFLAGS + _cloog_saved_LIBS=$LIBS + + _cloogorginc="-DCLOOG_INT_GMP -DCLOOG_ORG" + + dnl clooglibs & clooginc may have been initialized by CLOOG_INIT_FLAGS. + CFLAGS="${CFLAGS} ${clooginc} ${gmpinc}" + CPPFLAGS="${CPPFLAGS} ${_cloogorginc}" + LDFLAGS="${LDFLAGS} ${clooglibs}" + + case $cloog_backend in + "ppl-legacy") + CFLAGS="${CFLAGS} ${pplinc}" + LDFLAGS="${LDFLAGS} ${ppllibs}" + AC_CACHE_CHECK([for installed CLooG PPL Legacy], [gcc_cv_cloog_type], + [LIBS="-lcloog ${_cloog_saved_LIBS}" + AC_LINK_IFELSE([_CLOOG_PPL_LEGACY_PROG], [gcc_cv_cloog_type="PPL Legacy"], + [gcc_cv_cloog_type=no])]) + ;; + "isl") + AC_CACHE_CHECK([for installed CLooG ISL], [gcc_cv_cloog_type], + [LIBS="-lcloog-isl ${_cloog_saved_LIBS}" + AC_LINK_IFELSE([_CLOOG_ORG_PROG_ISL], [gcc_cv_cloog_type="ISL"], + [gcc_cv_cloog_type=no])]) + ;; + "ppl") + CFLAGS="${CFLAGS} ${pplinc}" + LDFLAGS="${LDFLAGS} ${ppllibs}" + AC_CACHE_CHECK([for installed CLooG PPL], [gcc_cv_cloog_type], + [LIBS="-lcloog-ppl ${_cloog_saved_LIBS}" + AC_LINK_IFELSE([_CLOOG_ORG_PROG_PPL], [gcc_cv_cloog_type="PPL"], + [gcc_cv_cloog_type=no])]) + ;; + *) + gcc_cv_cloog_type="" + esac + + case $gcc_cv_cloog_type in + "PPL Legacy") + clooginc="${clooginc}" + clooglibs="${clooglibs} -lcloog" + cloog_org=no + ;; + "ISL") + clooginc="${clooginc} ${_cloogorginc}" + clooglibs="${clooglibs} -lcloog-isl -lisl" + cloog_org=yes + ;; + "PPL") + clooginc="${clooginc} ${_cloogorginc}" + clooglibs="${clooglibs} -lcloog-ppl" + cloog_org=yes + ;; + *) + clooglibs= + clooginc= + cloog_org= + ;; + esac + + LIBS=$_cloog_saved_LIBS + CFLAGS=$_cloog_saved_CFLAGS + CPPFLAGS=$_cloog_saved_CPPFLAGS + LDFLAGS=$_cloog_saved_LDFLAGS +] +) + +# _CLOOG_CHECK_CT_PROG(MAJOR, MINOR, REVISION) +# -------------------------------------------- +# Helper for verifying CLooG's compile time version. +m4_define([_CLOOG_CHECK_CT_PROG],[AC_LANG_PROGRAM( + [#include "cloog/cloog.h"], + [#if CLOOG_VERSION_MAJOR != $1 \ + || CLOOG_VERSION_MINOR != $2 \ + || CLOOG_VERSION_REVISION < $3 + choke me + #endif])]) + +# _CLOOG_CHECK_RT_PROG () +# ----------------------- +# Helper for verifying that CLooG's compile time version +# matches the run time version. +m4_define([_CLOOG_CHECK_RT_PROG],[AC_LANG_PROGRAM( + [#include "cloog/cloog.h"], + [if ((cloog_version_major () != CLOOG_VERSION_MAJOR) + && (cloog_version_minor () != CLOOG_VERSION_MINOR) + && (cloog_version_revision () != CLOOG_VERSION_REVISION)) + { + return 1; + }])]) + +# CLOOG_CHECK_VERSION CLOOG_CHECK_VERSION (MAJOR, MINOR, REVISION) +# ---------------------------------------------------------------- +# Test the found CLooG to be exact of version MAJOR.MINOR and at least +# REVISION. +# If we're using the old CLooG-PPL (Legacy), the old version check will +# be executed (Ignores the provided version information). +AC_DEFUN([CLOOG_CHECK_VERSION], +[ + AC_REQUIRE([CLOOG_FIND_FLAGS]) + + if test "${ENABLE_CLOOG_CHECK}" = yes ; then + _cloog_saved_CFLAGS=$CFLAGS + _cloog_saved_LDFLAGS=$LDFLAGS + + CFLAGS="${_cloog_saved_CFLAGS} ${clooginc} ${pplinc} ${gmpinc}" + LDFLAGS="${_cloog_saved_LDFLAGS} ${clooglibs} ${ppllibs}" + + if test "${cloog_org}" = yes ; then + AC_CACHE_CHECK([for version $1.$2.$3 of CLooG], + [gcc_cv_cloog_ct_0_14_0], + [AC_COMPILE_IFELSE([_CLOOG_CHECK_CT_PROG($1,$2,$3)], + [gcc_cv_cloog_ct_0_14_0=yes], + [gcc_cv_cloog_ct_0_14_0=no])]) + elif test "${cloog_org}" = no ; then + AC_CACHE_CHECK([for version 0.15.5 (or later revision) of CLooG], + [gcc_cv_cloog_ct_0_15_5], + [AC_COMPILE_IFELSE([_CLOOG_CHECK_CT_PROG(0,15,5)], + [AC_COMPILE_IFELSE([_CLOOG_CHECK_CT_PROG(0,15,9)], + [gcc_cv_cloog_ct_0_15_5=yes], + [gcc_cv_cloog_ct_0_15_5="buggy but acceptable"])], + [gcc_cv_cloog_ct_0_15_5=no])]) + fi + + CFLAGS=$_cloog_saved_CFLAGS + LDFLAGS=$_cloog_saved_LDFLAGS + fi +] +) + +# CLOOG_IF_FAILED (ACTION-IF-FAILED) +# ---------------------------------- +# Executes ACTION-IF-FAILED, if GRAPHITE was requested and +# the checks failed. +AC_DEFUN([CLOOG_IF_FAILED], +[ + CLOOG_REQUESTED([graphite_requested=yes], [graphite_requested=no]) + + if test "${gcc_cv_cloog_ct_0_14_0}" = no \ + || test "${gcc_cv_cloog_rt_0_14_0}" = no \ + || test "${gcc_cv_cloog_ct_0_15_5}" = no; then + clooglibs= + clooginc= + fi + + if test "${graphite_requested}" = yes \ + && test "x${clooglibs}" = x \ + && test "x${clooginc}" = x ; then + $1 + fi +] +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/dfp.m4 Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,56 @@ +dnl @synopsis GCC_AC_ENABLE_DECIMAL_FLOAT([target triplet]) +dnl +dnl Enable C extension for decimal float if target supports it. +dnl +dnl @author Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + +AC_DEFUN([GCC_AC_ENABLE_DECIMAL_FLOAT], +[ +AC_ARG_ENABLE(decimal-float, +[ --enable-decimal-float={no,yes,bid,dpd} + enable decimal float extension to C. Selecting 'bid' + or 'dpd' choses which decimal floating point format + to use], +[ + case $enable_decimal_float in + yes | no | bid | dpd) default_decimal_float=$enable_decimal_float ;; + *) AC_MSG_ERROR(['$enable_decimal_float' is an invalid value for --enable-decimal-float. +Valid choices are 'yes', 'bid', 'dpd', and 'no'.]) ;; + esac +], +[ + case $1 in + powerpc*-*-linux* | i?86*-*-linux* | x86_64*-*-linux* | s390*-*-linux* | \ + i?86*-*-mingw* | x86_64*-*-mingw* | \ + i?86*-*-cygwin*) + enable_decimal_float=yes + ;; + *) + AC_MSG_WARN([decimal float is not supported for this target, ignored]) + enable_decimal_float=no + ;; + esac +]) + +# x86's use BID format instead of DPD +case x$enable_decimal_float in + xyes) + case $1 in + i?86*-*-* | x86_64*-*-*) + enable_decimal_float=bid + ;; + *) + enable_decimal_float=dpd + ;; + esac + default_decimal_float=$enable_decimal_float + ;; + xno) + # ENABLE_DECIMAL_FLOAT is set to 0. But we have to have proper + # dependency on libdecnumber. + default_decimal_float=dpd + ;; +esac +AC_SUBST(enable_decimal_float) + +])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/gc++filt.m4 Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,26 @@ +# gc++filt.m4 serial 1 -*- Autoconf -*- +# Find an instance of GNU c++filt on PATH. + +dnl Copyright (C) 2010 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Rainer Orth. + +# GCC_PROG_GNU_CXXFILT +# -------------------- +# Check for GNU c++filt. +# FIXME: Maybe need TARGET variant, though c++filt should be target +# independent. +AC_DEFUN([GCC_PROG_GNU_CXXFILT], + [AC_ARG_VAR([CXXFILT], [Location of GNU c++filt. Defaults to the first + GNU version of `c++filt', `gc++filt' on PATH.]) + AC_CACHE_CHECK([for GNU c++filt], [ac_cv_path_CXXFILT], + [AC_PATH_PROGS_FEATURE_CHECK([CXXFILT], [c++filt gc++filt], + [_AC_PATH_PROG_FLAVOR_GNU([$ac_path_CXXFILT], + [ac_cv_path_CXXFILT=$ac_path_CXXFILT && ac_path_CXXFILT_found=:])])]) + CXXFILT=$ac_cv_path_CXXFILT +])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/lthostflags.m4 Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,33 @@ +dnl Copyright (C) 2010 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl usage: ACX_LT_HOST_FLAGS([default_flags]) +dnl Defines and AC_SUBSTs lt_host_flags + + +AC_DEFUN([ACX_LT_HOST_FLAGS], [ +AC_REQUIRE([AC_CANONICAL_SYSTEM]) + +case $host in + *-cygwin* | *-mingw*) + # 'host' will be top-level target in the case of a target lib, + # we must compare to with_cross_host to decide if this is a native + # or cross-compiler and select where to install dlls appropriately. + if test -n "$with_cross_host" && + test x"$with_cross_host" != x"no"; then + lt_host_flags='-no-undefined -bindir "$(toolexeclibdir)"'; + else + lt_host_flags='-no-undefined -bindir "$(bindir)"'; + fi + ;; + *) + lt_host_flags=[$1] + ;; +esac + +AC_SUBST(lt_host_flags) +])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/mh-darwin Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,5 @@ +# The -mdynamic-no-pic ensures that the compiler executable is built without +# position-independent-code -- the usual default on Darwin. This fix speeds +# compiles by 3-5%. + +BOOT_CFLAGS += -mdynamic-no-pic
--- a/config/mh-ppc-darwin Tue Mar 22 17:18:12 2011 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -# The -mdynamic-no-pic ensures that the compiler executable is built without -# position-independent-code -- the usual default on Darwin. This fix speeds -# compiles by 3-5%. - -BOOT_CFLAGS += -mdynamic-no-pic
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/check_GNU_style.sh Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,120 @@ +#!/bin/sh + +# Checks some of the GNU style formatting rules in a set of patches. +# Copyright (C) 2010 Free Software Foundation, Inc. +# Contributed by Sebastian Pop <sebastian.pop@amd.com> + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +usage() { + cat <<EOF +check_GNU_style.sh [patch]... + + Checks the patches for some of the GNU style formatting problems. + Please note that these checks are not always accurate, and + complete. The reference documentation of the GNU Coding Standards + can be found here: http://www.gnu.org/prep/standards_toc.html + and there are also some additional coding conventions for GCC: + http://gcc.gnu.org/codingconventions.html + +EOF + exit 1 +} + +test $# -eq 0 && usage + +tmp=check_GNU_style.tmp + +# Grep +g (){ + msg="$1" + arg="$2" + shift 2 + grep -nH '^+' $* \ + | grep -v ':+++' \ + | egrep --color=always -- "$arg" \ + > $tmp && printf "\n$msg\n" + cat $tmp +} + +# And Grep +ag (){ + msg="$1" + arg1="$2" + arg2="$3" + shift 3 + grep -nH '^+' $* \ + | grep -v ':+++' \ + | egrep --color=always -- "$arg1" \ + | egrep --color=always -- "$arg2" \ + > $tmp && printf "\n$msg\n" + cat $tmp +} + +# reVerse Grep +vg (){ + msg="$1" + varg="$2" + arg="$3" + shift 3 + grep -nH '^+' $* \ + | grep -v ':+++' \ + | egrep -v -- "$varg" \ + | egrep --color=always -- "$arg" \ + > $tmp && printf "\n$msg\n" + cat $tmp +} + +col (){ + msg="$1" + shift 1 + grep -nH '^+' $* \ + | grep -v ':+++' \ + | cut -f 2 -d '+' \ + | awk '{ if (length ($0) > 80) print $0 }' \ + > $tmp + if [ -s $tmp ]; then + printf "\n$msg\n" + cat $tmp + fi +} + +col 'Lines should not exceed 80 characters.' $* + +g 'Trailing whitespace.' \ + '[[:space:]]$' $* + +g 'Space before dot.' \ + '[[:alnum:]][[:blank:]]+\.' $* + +g 'Dot, space, space, new sentence.' \ + '[[:alnum:]]\.([[:blank:]]|[[:blank:]]{3,})[[:alnum:]]' $* + +g 'Dot, space, space, end of comment.' \ + '[[:alnum:]]\.([[:blank:]]{0,1}|[[:blank:]]{3,})\*/' $* + +g 'Sentences should end with a dot. Dot, space, space, end of the comment.' \ + '[[:alnum:]][[:blank:]]*\*/' $* + +vg 'There should be exactly one space between function name and parentheses.' \ + '\#define' '[[:alnum:]]([^[:blank:]]|[[:blank:]]{2,})\(' $* + +g 'There should be no space before closing parentheses.' \ + '[[:graph:]][[:blank:]]+\)' $* + +ag 'Braces should be on a separate line.' \ + '\{' 'if[[:blank:]]\(|while[[:blank:]]\(|switch[[:blank:]]\(' $* + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/download_prerequisites Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,38 @@ +#! /bin/sh + +# Download some prerequisites needed by gcc. +# Run this from the top level of the gcc source tree and the gcc +# build will do the right thing. +# +# (C) 2010 Free Software Foundation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. + +MPFR=mpfr-2.4.2 +GMP=gmp-4.3.2 +MPC=mpc-0.8.1 + +wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$MPFR.tar.bz2 || exit 1 +tar xjf $MPFR.tar.bz2 || exit 1 +ln -sf $MPFR mpfr || exit 1 + +wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$GMP.tar.bz2 || exit 1 +tar xjf $GMP.tar.bz2 || exit 1 +ln -sf $GMP gmp || exit 1 + +wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$MPC.tar.gz || exit 1 +tar xzf $MPC.tar.gz || exit 1 +ln -sf $MPC mpc || exit 1 + +rm $MPFR.tar.bz2 $GMP.tar.bz2 $MPC.tar.gz || exit 1
--- a/contrib/gccbug.el Tue Mar 22 17:18:12 2011 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -;;; gccbug.el --- forward bug reports to gnats -;; (C) 2000 Free Software Foundation -;; Written by Martin v. Löwis -;; Usage: -;; In rmail, bind a key to rmail-gccbug-reply, e.g. -;; (require 'rmail) -;; (require 'gccbug) -;; (define-key rmail-mode-map "R" 'rmail-gccbug-reply) -;; Then, when reviewing a report, type R to create a gnats-formatted -;; message. - -(provide 'gccbug) - -(defun gccbug-reply () - (interactive) - (let ((orig-yank-prefix mail-yank-prefix)) - (insert ">Submitter-Id: net\n") - (insert ">Originator: \n") - (insert ">Confidential: no\n") - (insert ">Synopsis: ") - (save-excursion - (mail-subject) - (let ((stop (point))) - (re-search-backward "Re: ") - (copy-region-as-kill (match-end 0) stop))) - (yank) - (insert "\n") - (insert ">Severity: serious\n") - (insert ">Priority: medium\n") - (insert ">Category: \n") - (insert ">Class: \n") - ;(insert ">State: analyzed\n") - (insert ">Release: 2.95.2\n") - (insert ">Environment:\n") - (insert ">Description:\n") - (set 'mail-yank-prefix nil) - (set 'mail-yank-ignored-headers - "^via:\\|^mail-from:\\|^origin:\\|^status:\\|^remailed\\|^received:\\|^summary-line:\\|^to:\\|^subject:\\|^in-reply-to:\\|^return-path:\\|^X-.*:\\|^User-Agent:\\|^MIME-Version:\\|^Content-.*:\\|^List-.*:\\|C[Cc]:\\|^Precedence:\\|^Sender:\\|^Mailing-List:\\|^Delivered-To:\\|^>From") - (mail-yank-original t) - (set 'mail-yank-prefix orig-yank-prefix) - ; Copy From: field to Originator: - (re-search-backward "From: ") - (let ((beg (match-end 0))) - (end-of-line) - (kill-region beg (point))) - (re-search-backward ">Originator: ") - (goto-char (match-end 0)) - (yank) - ; Kill From: line - (re-search-forward "From:") - (beginning-of-line) - (kill-line 1) - ; Replace Message-ID: with Original-Message-ID - (beginning-of-buffer) - (re-search-forward "Message-ID: .*") - (replace-match "Original-\\&") - ; Replace To: line, adding recipient to Notify list - (mail-to) - (re-search-backward "To: ") - (replace-match "To: gcc-gnats@gcc.gnu.org\nX-GNATS-Notify: ") - ; add additional fields - (end-of-buffer) - (insert ">How-To-Repeat: \n>Fix: \n") - ; See whether an Organization: is present - (let ((org (re-search-backward "Organization:.*" nil t))) - (if org - (progn - (kill-region (point) (match-end 0)) - (re-search-backward ">Confidential") - (insert ">") - (yank) - (insert "\n")))) -; This kills CC: lines, but rmail-reply below won't create any -; (mail-cc) -; (beginning-of-line) -; (kill-line 1) - )) - -(defun rmail-gccbug-reply () - (interactive) - (rmail-toggle-header 0) - (rmail-reply t) - (gccbug-reply)) -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/make_sunver.pl Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,350 @@ +#!/usr/bin/perl -w + +# make_sunver.pl +# +# This script takes at least two arguments, a GNU style version script and +# a list of object and archive files, and generates a corresponding Sun +# style version script as follows: +# +# Each glob pattern, C++ mangled pattern or literal in the input script is +# matched against all global symbols in the input objects, emitting those +# that matched (or nothing if no match was found). +# A comment with the original pattern and its type is left in the output +# file to make it easy to understand the matches. +# +# It uses elfdump when present (native), GNU readelf otherwise. +# It depends on the GNU version of c++filt, since it must understand the +# GNU mangling style. + +use File::Glob ':glob'; +use FileHandle; +use IPC::Open2; + +# Input version script, GNU style. +my $symvers = shift; + +########## +# Get all the symbols from the library, match them, and add them to a hash. + +my %sym_hash = (); + +# List of objects and archives to process. +my @OBJECTS = (); + +# List of shared objects to omit from processing. +my @SHAREDOBJS = (); + +# Filter out those input archives that have corresponding shared objects to +# avoid adding all symbols matched in the archive to the output map. +foreach $file (@ARGV) { + if (($so = $file) =~ s/\.a$/.so/ && -e $so) { + printf STDERR "omitted $file -> $so\n"; + push (@SHAREDOBJS, $so); + } else { + push (@OBJECTS, $file); + } +} + +# We need to detect and ignore hidden symbols. Solaris nm can only detect +# this in the harder to parse default output format, and GNU nm not at all, +# so use elfdump -s in the native case and GNU readelf -s otherwise. +# GNU objdump -t cannot be used since it produces a variable number of +# columns. + +# The path to elfdump. +my $elfdump = "/usr/ccs/bin/elfdump"; + +if (-f $elfdump) { + open ELFDUMP,$elfdump.' -s '.(join ' ',@OBJECTS).'|' or die $!; + my $skip_arsym = 0; + + while (<ELFDUMP>) { + chomp; + + # Ignore empty lines. + if (/^$/) { + # End of archive symbol table, stop skipping. + $skip_arsym = 0 if $skip_arsym; + next; + } + + # Keep skipping until end of archive symbol table. + next if ($skip_arsym); + + # Ignore object name header for individual objects and archives. + next if (/:$/); + + # Ignore table header lines. + next if (/^Symbol Table Section:/); + next if (/index.*value.*size/); + + # Start of archive symbol table: start skipping. + if (/^Symbol Table: \(archive/) { + $skip_arsym = 1; + next; + } + + # Split table. + (undef, undef, undef, undef, $bind, $oth, undef, $shndx, $name) = split; + + # Error out for unknown input. + die "unknown input line:\n$_" unless defined($bind); + + # Ignore local symbols. + next if ($bind eq "LOCL"); + # Ignore hidden symbols. + next if ($oth eq "H"); + # Ignore undefined symbols. + next if ($shndx eq "UNDEF"); + # Error out for unhandled cases. + if ($bind !~ /^(GLOB|WEAK)/ or $oth ne "D") { + die "unhandled symbol:\n$_"; + } + + # Remember symbol. + $sym_hash{$name}++; + } + close ELFDUMP or die "$elfdump error"; +} else { + open READELF, 'readelf -s -W '.(join ' ',@OBJECTS).'|' or die $!; + # Process each symbol. + while (<READELF>) { + chomp; + + # Ignore empty lines. + next if (/^$/); + + # Ignore object name header. + next if (/^File: .*$/); + + # Ignore table header lines. + next if (/^Symbol table.*contains.*:/); + next if (/Num:.*Value.*Size/); + + # Split table. + (undef, undef, undef, undef, $bind, $vis, $ndx, $name) = split; + + # Error out for unknown input. + die "unknown input line:\n$_" unless defined($bind); + + # Ignore local symbols. + next if ($bind eq "LOCAL"); + # Ignore hidden symbols. + next if ($vis eq "HIDDEN"); + # Ignore undefined symbols. + next if ($ndx eq "UND"); + # Error out for unhandled cases. + if ($bind !~ /^(GLOBAL|WEAK)/ or $vis ne "DEFAULT") { + die "unhandled symbol:\n$_"; + } + + # Remember symbol. + $sym_hash{$name}++; + } + close READELF or die "readelf error"; +} + +########## +# The various types of glob patterns. +# +# A glob pattern that is to be applied to the demangled name: 'cxx'. +# A glob patterns that applies directly to the name in the .o files: 'glob'. +# This pattern is ignored; used for local variables (usually just '*'): 'ign'. + +# The type of the current pattern. +my $glob = 'glob'; + +# We're currently inside `extern "C++"', which Sun ld doesn't understand. +my $in_extern = 0; + +# We're currently inside a conditional section: just skip it. +my $in_ifdef = 0; + +# The c++filt command to use. This *must* be GNU c++filt; the Sun Studio +# c++filt doesn't handle the GNU mangling style. +my $cxxfilt = $ENV{'CXXFILT'} || "c++filt"; + +# The current version name. +my $current_version = ""; + +# Was there any attempt to match a symbol to this version? +my $matches_attempted; + +# The number of versions which matched this symbol. +my $matched_symbols; + +open F,$symvers or die $!; + +# Print information about generating this file +print "# This file was generated by make_sunver.pl. DO NOT EDIT!\n"; +print "# It was generated by:\n"; +printf "# %s %s %s\n", $0, $symvers, (join ' ',@ARGV); +printf "# Omitted archives with corresponding shared libraries: %s\n", + (join ' ', @SHAREDOBJS) if $#SHAREDOBJS >= 0; +print "#\n\n"; + +while (<F>) { + # End of skipped section. + if (/^[ \t]*\#endif/) { + $in_ifdef = 0; + next; + } + + # Just skip a conditional section. + if ($in_ifdef) { next; } + + # Lines of the form '};' + if (/^([ \t]*)(\}[ \t]*;[ \t]*)$/) { + $glob = 'glob'; + if ($in_extern) { + $in_extern--; + print "$1##$2"; + } else { + print; + } + next; + } + + # Lines of the form '} SOME_VERSION_NAME_1.0;' + if (/^[ \t]*\}[ \tA-Z0-9_.a-z]+;[ \t]*$/) { + $glob = 'glob'; + # We tried to match symbols agains this version, but none matched. + # Emit dummy hidden symbol to avoid marking this version WEAK. + if ($matches_attempted && $matched_symbols == 0) { + print " hidden:\n"; + print " .force_WEAK_off_$current_version = DATA S0x0 V0x0;\n"; + } + print; next; + } + + # Special comments that look like C preprocessor conditionals. + # Just skip the contents for now. + # FIXME: Allow passing in conditionals from the command line to really + # control the skipping. + if (/^[ \t]*\#ifdef/) { + $in_ifdef = 1; + next; + } + + # Comment and blank lines + if (/^[ \t]*\#/) { print; next; } + if (/^[ \t]*$/) { print; next; } + + # Lines of the form '{' + if (/^([ \t]*){$/) { + if ($in_extern) { + print "$1##{\n"; + } else { + print; + } + next; + } + + # Lines of the form 'SOME_VERSION_NAME_1.1 {' + if (/^([A-Z0-9_.]+)[ \t]+{$/) { + # Record version name. + $current_version = $1; + # Reset match attempts, #matched symbols for this version. + $matches_attempted = 0; + $matched_symbols = 0; + print; + next; + } + + # Ignore 'global:' + if (/^[ \t]*global:$/) { print; next; } + + # After 'local:', globs should be ignored, they won't be exported. + if (/^[ \t]*local:$/) { + $glob = 'ign'; + print; + next; + } + + # After 'extern "C++"', globs are C++ patterns + if (/^([ \t]*)(extern \"C\+\+\"[ \t]*)$/) { + $in_extern++; + $glob = 'cxx'; + # Need to comment, Sun ld cannot handle this. + print "$1##$2\n"; next; + } + + # Chomp newline now we're done with passing through the input file. + chomp; + + # Catch globs. Note that '{}' is not allowed in globs by this script, + # so only '*' and '[]' are available. + if (/^([ \t]*)([^ \t;{}#]+);?[ \t]*$/) { + my $ws = $1; + my $ptn = $2; + # Turn the glob into a regex by replacing '*' with '.*'. + # Keep $ptn so we can still print the original form. + ($pattern = $ptn) =~ s/\*/\.\*/g; + + if ($glob eq 'ign') { + # We're in a local: * section; just continue. + print "$_\n"; + next; + } + + # Print the glob commented for human readers. + print "$ws##$ptn ($glob)\n"; + # We tried to match a symbol to this version. + $matches_attempted++; + + if ($glob eq 'glob') { + my %ptn_syms = (); + + # Match ptn against symbols in %sym_hash. + foreach my $sym (keys %sym_hash) { + # Maybe it matches one of the patterns based on the symbol in + # the .o file. + $ptn_syms{$sym}++ if ($sym =~ /^$pattern$/); + } + + foreach my $sym (sort keys(%ptn_syms)) { + $matched_symbols++; + print "$ws$sym;\n"; + } + } elsif ($glob eq 'cxx') { + my %dem_syms = (); + + # Verify that we're actually using GNU c++filt. Other versions + # most likely cannot handle GNU style symbol mangling. + my $cxxout = `$cxxfilt --version 2>&1`; + $cxxout =~ m/GNU/ or die "$0 requires GNU c++filt to function"; + + # Talk to c++filt through a pair of file descriptors. + # Need to start a fresh instance per pattern, otherwise the + # process grows to 500+ MB. + my $pid = open2(*FILTIN, *FILTOUT, $cxxfilt) or die $!; + + # Match ptn against symbols in %sym_hash. + foreach my $sym (keys %sym_hash) { + # No? Well, maybe its demangled form matches one of those + # patterns. + printf FILTOUT "%s\n",$sym; + my $dem = <FILTIN>; + chomp $dem; + $dem_syms{$sym}++ if ($dem =~ /^$pattern$/); + } + + close FILTOUT or die "c++filt error"; + close FILTIN or die "c++filt error"; + # Need to wait for the c++filt process to avoid lots of zombies. + waitpid $pid, 0; + + foreach my $sym (sort keys(%dem_syms)) { + $matched_symbols++; + print "$ws$sym;\n"; + } + } else { + # No? Well, then ignore it. + } + next; + } + # Important sanity check. This script can't handle lots of formats + # that GNU ld can, so be sure to error out if one is seen! + die "strange line `$_'"; +} +close F;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/test_recheck Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,98 @@ +#! /bin/sh + +# (C) 2010 Free Software Foundation +# Written by Ralf Wildenhues <Ralf.Wildenhues@gmx.de>. + +# This script is Free Software, and it can be copied, distributed and +# modified as defined in the GNU General Public License. A copy of +# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html + +PROGNAME=test_recheck + +usage () +{ + cat <<EOF +Usage: $PROGNAME [-h] [-n] DIR|FILE.sum... + +Rerun unsuccessful tests for testsuites below DIR or for FILE.sum. + + -h display this help and exit + -n dry run, only show what would be run +EOF + exit $? +} + +error () +{ + echo "$@" >&2 + exit 1 +} + +dry= +for arg +do + case $arg in + -h | \?) usage ;; + -n) dry=:; shift ;; + -*) error "unknown argument $arg" ;; + *) break ;; + esac +done +test $# -gt 0 || usage + +# 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 + +: ${MAKE=make} +: ${filesuffix=} +cwd=`pwd` +files=`find "$@" -name \*.sum$filesuffix -print | grep testsuite | sort` +st=0 + +for file in $files; do + dir=`echo $file | sed 's,/[^/]*$,,'` + base=`echo $file | sed 's,.*/,,; s,\.sum$,,'` + flags=`$AWK ' +/^Running .*\.exp \.\.\./ { + if (expfile != "" && tests != "") + printf (" %s=\"%s\"", expfile, tests) + expfile = $2 + sub (/^[^ ]*\//, "", expfile) + sep = "" + tests = "" +} +/^(FAIL|XPASS|UNRESOLVED|WARNING|ERROR): / { + if (test != $2 "" && $2 != "" ) { + test = $2 + tests = tests sep test + sep = " " + } +} +END { + if (expfile != "" && tests != "") + printf (" %s=\"%s\"", expfile, tests) +}' $file` + if test -n "$flags"; then + cd $dir + amflags= + if grep '^AM_RUNTESTFLAGS =' Makefile >/dev/null 2>&1; then + amflags=`echo 'print-runtestflags: ; @echo $(AM_RUNTESTFLAGS)' \ + | ${MAKE} -s -f Makefile -f - print-runtestflags` + fi + echo "(cd $dir && runtest $amflags --tool $base $flags)" + if test -z "$dry"; then + eval runtest --tool $base $flags || st=$? + fi + cd "$cwd" + fi +done +exit $st
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fixincludes/tests/base/sys/feature_tests.h Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,18 @@ +/* DO NOT EDIT THIS FILE. + + It has been auto-edited by fixincludes from: + + "fixinc/tests/inc/sys/feature_tests.h" + + This had to be done to correct non-standard usages in the + original, manufacturer supplied header file. */ + + + +#if defined( SOLARIS___RESTRICT_CHECK ) +#ifdef __cplusplus +#define _RESTRICT_KYWD __restrict +#else +#define _RESTRICT_KYWD restrict +#endif +#endif /* SOLARIS___RESTRICT_CHECK */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fixincludes/tests/base/sys/va_list.h Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,22 @@ +/* DO NOT EDIT THIS FILE. + + It has been auto-edited by fixincludes from: + + "fixinc/tests/inc/sys/va_list.h" + + This had to be done to correct non-standard usages in the + original, manufacturer supplied header file. */ + + + +#if defined( SOLARIS_SYS_VA_LIST_CHECK ) +#ifdef __GNUC__ +typedef __builtin_va_list __va_list; +#else +#if defined(__STDC__) && !defined(__ia64) +typedef void *__va_list; +#else +typedef char *__va_list; +#endif +#endif +#endif /* SOLARIS_SYS_VA_LIST_CHECK */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/#gimple.c# Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,5161 @@ +/* Gimple IR support functions. + + Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + Contributed by Aldy Hernandez <aldyh@redhat.com> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "target.h" +#include "tree.h" +#include "ggc.h" +#include "hard-reg-set.h" +#include "basic-block.h" +#include "gimple.h" +#include "diagnostic.h" +#include "tree-flow.h" +#include "value-prof.h" +#include "flags.h" +#include "alias.h" +#include "demangle.h" +#include "langhooks.h" + +/* Global type table. FIXME lto, it should be possible to re-use some + of the type hashing routines in tree.c (type_hash_canon, type_hash_lookup, + etc), but those assume that types were built with the various + build_*_type routines which is not the case with the streamer. */ +static GTY((if_marked ("ggc_marked_p"), param_is (union tree_node))) + htab_t gimple_types; +static GTY((if_marked ("ggc_marked_p"), param_is (union tree_node))) + htab_t gimple_canonical_types; +static GTY((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map))) + htab_t type_hash_cache; +static GTY((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map))) + htab_t canonical_type_hash_cache; + +/* Global type comparison cache. This is by TYPE_UID for space efficiency + and thus cannot use and does not need GC. */ +static htab_t gtc_visited; +static struct obstack gtc_ob; + +/* All the tuples have their operand vector (if present) at the very bottom + of the structure. Therefore, the offset required to find the + operands vector the size of the structure minus the size of the 1 + element tree array at the end (see gimple_ops). */ +#define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) \ + (HAS_TREE_OP ? sizeof (struct STRUCT) - sizeof (tree) : 0), +EXPORTED_CONST size_t gimple_ops_offset_[] = { +#include "gsstruct.def" +}; +#undef DEFGSSTRUCT + +#define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) sizeof(struct STRUCT), +static const size_t gsstruct_code_size[] = { +#include "gsstruct.def" +}; +#undef DEFGSSTRUCT + +#define DEFGSCODE(SYM, NAME, GSSCODE) NAME, +const char *const gimple_code_name[] = { +#include "gimple.def" +}; +#undef DEFGSCODE + +#define DEFGSCODE(SYM, NAME, GSSCODE) GSSCODE, +EXPORTED_CONST enum gimple_statement_structure_enum gss_for_code_[] = { +#include "gimple.def" +}; +#undef DEFGSCODE + +#ifdef GATHER_STATISTICS +/* Gimple stats. */ + +int gimple_alloc_counts[(int) gimple_alloc_kind_all]; +int gimple_alloc_sizes[(int) gimple_alloc_kind_all]; + +/* Keep in sync with gimple.h:enum gimple_alloc_kind. */ +static const char * const gimple_alloc_kind_names[] = { + "assignments", + "phi nodes", + "conditionals", + "sequences", + "everything else" +}; + +#endif /* GATHER_STATISTICS */ + +/* A cache of gimple_seq objects. Sequences are created and destroyed + fairly often during gimplification. */ +static GTY ((deletable)) struct gimple_seq_d *gimple_seq_cache; + +/* Private API manipulation functions shared only with some + other files. */ +extern void gimple_set_stored_syms (gimple, bitmap, bitmap_obstack *); +extern void gimple_set_loaded_syms (gimple, bitmap, bitmap_obstack *); + +/* Gimple tuple constructors. + Note: Any constructor taking a ``gimple_seq'' as a parameter, can + be passed a NULL to start with an empty sequence. */ + +/* Set the code for statement G to CODE. */ + +static inline void +gimple_set_code (gimple g, enum gimple_code code) +{ + g->gsbase.code = code; +} + +/* Return the number of bytes needed to hold a GIMPLE statement with + code CODE. */ + +static inline size_t +gimple_size (enum gimple_code code) +{ + return gsstruct_code_size[gss_for_code (code)]; +} + +/* Allocate memory for a GIMPLE statement with code CODE and NUM_OPS + operands. */ + +gimple +gimple_alloc_stat (enum gimple_code code, unsigned num_ops MEM_STAT_DECL) +{ + size_t size; + gimple stmt; + + size = gimple_size (code); + if (num_ops > 0) + size += sizeof (tree) * (num_ops - 1); + +#ifdef GATHER_STATISTICS + { + enum gimple_alloc_kind kind = gimple_alloc_kind (code); + gimple_alloc_counts[(int) kind]++; + gimple_alloc_sizes[(int) kind] += size; + } +#endif + + stmt = ggc_alloc_cleared_gimple_statement_d_stat (size PASS_MEM_STAT); + gimple_set_code (stmt, code); + gimple_set_num_ops (stmt, num_ops); + + /* Do not call gimple_set_modified here as it has other side + effects and this tuple is still not completely built. */ + stmt->gsbase.modified = 1; + + return stmt; +} + +/* Set SUBCODE to be the code of the expression computed by statement G. */ + +static inline void +gimple_set_subcode (gimple g, unsigned subcode) +{ + /* We only have 16 bits for the RHS code. Assert that we are not + overflowing it. */ + gcc_assert (subcode < (1 << 16)); + g->gsbase.subcode = subcode; +} + + + +/* Build a tuple with operands. CODE is the statement to build (which + must be one of the GIMPLE_WITH_OPS tuples). SUBCODE is the sub-code + for the new tuple. NUM_OPS is the number of operands to allocate. */ + +#define gimple_build_with_ops(c, s, n) \ + gimple_build_with_ops_stat (c, s, n MEM_STAT_INFO) + +static gimple +gimple_build_with_ops_stat (enum gimple_code code, unsigned subcode, + unsigned num_ops MEM_STAT_DECL) +{ + gimple s = gimple_alloc_stat (code, num_ops PASS_MEM_STAT); + gimple_set_subcode (s, subcode); + + return s; +} + + +/* Build a GIMPLE_RETURN statement returning RETVAL. */ + +gimple +gimple_build_return (tree retval) +{ + gimple s = gimple_build_with_ops (GIMPLE_RETURN, ERROR_MARK, 1); + if (retval) + gimple_return_set_retval (s, retval); + return s; +} + +/* Reset alias information on call S. */ + +void +gimple_call_reset_alias_info (gimple s) +{ + if (gimple_call_flags (s) & ECF_CONST) + memset (gimple_call_use_set (s), 0, sizeof (struct pt_solution)); + else + pt_solution_reset (gimple_call_use_set (s)); + if (gimple_call_flags (s) & (ECF_CONST|ECF_PURE|ECF_NOVOPS)) + memset (gimple_call_clobber_set (s), 0, sizeof (struct pt_solution)); + else + pt_solution_reset (gimple_call_clobber_set (s)); +} + +/* Helper for gimple_build_call, gimple_build_call_vec and + gimple_build_call_from_tree. Build the basic components of a + GIMPLE_CALL statement to function FN with NARGS arguments. */ + +static inline gimple +gimple_build_call_1 (tree fn, unsigned nargs) +{ + gimple s = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, nargs + 3); + if (TREE_CODE (fn) == FUNCTION_DECL) + fn = build_fold_addr_expr (fn); + gimple_set_op (s, 1, fn); + gimple_call_reset_alias_info (s); + return s; +} + + +/* Build a GIMPLE_CALL statement to function FN with the arguments + specified in vector ARGS. */ + +gimple +gimple_build_call_vec (tree fn, VEC(tree, heap) *args) +{ + unsigned i; + unsigned nargs = VEC_length (tree, args); + gimple call = gimple_build_call_1 (fn, nargs); + + for (i = 0; i < nargs; i++) + gimple_call_set_arg (call, i, VEC_index (tree, args, i)); + + return call; +} + + +/* Build a GIMPLE_CALL statement to function FN. NARGS is the number of + arguments. The ... are the arguments. */ + +gimple +gimple_build_call (tree fn, unsigned nargs, ...) +{ + va_list ap; + gimple call; + unsigned i; + + gcc_assert (TREE_CODE (fn) == FUNCTION_DECL || is_gimple_call_addr (fn)); + + call = gimple_build_call_1 (fn, nargs); + + va_start (ap, nargs); + for (i = 0; i < nargs; i++) + gimple_call_set_arg (call, i, va_arg (ap, tree)); + va_end (ap); + + return call; +} + + +/* Build a GIMPLE_CALL statement from CALL_EXPR T. Note that T is + assumed to be in GIMPLE form already. Minimal checking is done of + this fact. */ + +gimple +gimple_build_call_from_tree (tree t) +{ + unsigned i, nargs; + gimple call; + tree fndecl = get_callee_fndecl (t); + + gcc_assert (TREE_CODE (t) == CALL_EXPR); + + nargs = call_expr_nargs (t); + call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs); + + for (i = 0; i < nargs; i++) + gimple_call_set_arg (call, i, CALL_EXPR_ARG (t, i)); + + gimple_set_block (call, TREE_BLOCK (t)); + + /* Carry all the CALL_EXPR flags to the new GIMPLE_CALL. */ + gimple_call_set_chain (call, CALL_EXPR_STATIC_CHAIN (t)); + gimple_call_set_tail (call, CALL_EXPR_TAILCALL (t)); + gimple_call_set_cannot_inline (call, CALL_CANNOT_INLINE_P (t)); + gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t)); + gimple_call_set_from_thunk (call, CALL_FROM_THUNK_P (t)); + gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t)); + gimple_call_set_nothrow (call, TREE_NOTHROW (t)); + gimple_set_no_warning (call, TREE_NO_WARNING (t)); + + return call; +} + + +/* Extract the operands and code for expression EXPR into *SUBCODE_P, + *OP1_P, *OP2_P and *OP3_P respectively. */ + +void +extract_ops_from_tree_1 (tree expr, enum tree_code *subcode_p, tree *op1_p, + tree *op2_p, tree *op3_p) +{ + enum gimple_rhs_class grhs_class; + + *subcode_p = TREE_CODE (expr); + grhs_class = get_gimple_rhs_class (*subcode_p); + + if (grhs_class == GIMPLE_TERNARY_RHS) + { + *op1_p = TREE_OPERAND (expr, 0); + *op2_p = TREE_OPERAND (expr, 1); + *op3_p = TREE_OPERAND (expr, 2); + } + else if (grhs_class == GIMPLE_BINARY_RHS) + { + *op1_p = TREE_OPERAND (expr, 0); + *op2_p = TREE_OPERAND (expr, 1); + *op3_p = NULL_TREE; + } + else if (grhs_class == GIMPLE_UNARY_RHS) + { + *op1_p = TREE_OPERAND (expr, 0); + *op2_p = NULL_TREE; + *op3_p = NULL_TREE; + } + else if (grhs_class == GIMPLE_SINGLE_RHS) + { + *op1_p = expr; + *op2_p = NULL_TREE; + *op3_p = NULL_TREE; + } + else + gcc_unreachable (); +} + + +/* Build a GIMPLE_ASSIGN statement. + + LHS of the assignment. + RHS of the assignment which can be unary or binary. */ + +gimple +gimple_build_assign_stat (tree lhs, tree rhs MEM_STAT_DECL) +{ + enum tree_code subcode; + tree op1, op2, op3; + + extract_ops_from_tree_1 (rhs, &subcode, &op1, &op2, &op3); + return gimple_build_assign_with_ops_stat (subcode, lhs, op1, op2, op3 + PASS_MEM_STAT); +} + + +/* Build a GIMPLE_ASSIGN statement with sub-code SUBCODE and operands + OP1 and OP2. If OP2 is NULL then SUBCODE must be of class + GIMPLE_UNARY_RHS or GIMPLE_SINGLE_RHS. */ + +gimple +gimple_build_assign_with_ops_stat (enum tree_code subcode, tree lhs, tree op1, + tree op2, tree op3 MEM_STAT_DECL) +{ + unsigned num_ops; + gimple p; + + /* Need 1 operand for LHS and 1 or 2 for the RHS (depending on the + code). */ + num_ops = get_gimple_rhs_num_ops (subcode) + 1; + + p = gimple_build_with_ops_stat (GIMPLE_ASSIGN, (unsigned)subcode, num_ops + PASS_MEM_STAT); + gimple_assign_set_lhs (p, lhs); + gimple_assign_set_rhs1 (p, op1); + if (op2) + { + gcc_assert (num_ops > 2); + gimple_assign_set_rhs2 (p, op2); + } + + if (op3) + { + gcc_assert (num_ops > 3); + gimple_assign_set_rhs3 (p, op3); + } + + return p; +} + + +/* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P. + + DST/SRC are the destination and source respectively. You can pass + ungimplified trees in DST or SRC, in which case they will be + converted to a gimple operand if necessary. + + This function returns the newly created GIMPLE_ASSIGN tuple. */ + +gimple +gimplify_assign (tree dst, tree src, gimple_seq *seq_p) +{ + tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); + gimplify_and_add (t, seq_p); + ggc_free (t); + return gimple_seq_last_stmt (*seq_p); +} + + +/* Build a GIMPLE_COND statement. + + PRED is the condition used to compare LHS and the RHS. + T_LABEL is the label to jump to if the condition is true. + F_LABEL is the label to jump to otherwise. */ + +gimple +gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs, + tree t_label, tree f_label) +{ + gimple p; + + gcc_assert (TREE_CODE_CLASS (pred_code) == tcc_comparison); + p = gimple_build_with_ops (GIMPLE_COND, pred_code, 4); + gimple_cond_set_lhs (p, lhs); + gimple_cond_set_rhs (p, rhs); + gimple_cond_set_true_label (p, t_label); + gimple_cond_set_false_label (p, f_label); + return p; +} + + +/* Extract operands for a GIMPLE_COND statement out of COND_EXPR tree COND. */ + +void +gimple_cond_get_ops_from_tree (tree cond, enum tree_code *code_p, + tree *lhs_p, tree *rhs_p) +{ + gcc_assert (TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison + || TREE_CODE (cond) == TRUTH_NOT_EXPR + || is_gimple_min_invariant (cond) + || SSA_VAR_P (cond)); + + extract_ops_from_tree (cond, code_p, lhs_p, rhs_p); + + /* Canonicalize conditionals of the form 'if (!VAL)'. */ + if (*code_p == TRUTH_NOT_EXPR) + { + *code_p = EQ_EXPR; + gcc_assert (*lhs_p && *rhs_p == NULL_TREE); + *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p)); + } + /* Canonicalize conditionals of the form 'if (VAL)' */ + else if (TREE_CODE_CLASS (*code_p) != tcc_comparison) + { + *code_p = NE_EXPR; + gcc_assert (*lhs_p && *rhs_p == NULL_TREE); + *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p)); + } +} + + +/* Build a GIMPLE_COND statement from the conditional expression tree + COND. T_LABEL and F_LABEL are as in gimple_build_cond. */ + +gimple +gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label) +{ + enum tree_code code; + tree lhs, rhs; + + gimple_cond_get_ops_from_tree (cond, &code, &lhs, &rhs); + return gimple_build_cond (code, lhs, rhs, t_label, f_label); +} + +/* Set code, lhs, and rhs of a GIMPLE_COND from a suitable + boolean expression tree COND. */ + +void +gimple_cond_set_condition_from_tree (gimple stmt, tree cond) +{ + enum tree_code code; + tree lhs, rhs; + + gimple_cond_get_ops_from_tree (cond, &code, &lhs, &rhs); + gimple_cond_set_condition (stmt, code, lhs, rhs); +} + +/* Build a GIMPLE_LABEL statement for LABEL. */ + +gimple +gimple_build_label (tree label) +{ + gimple p = gimple_build_with_ops (GIMPLE_LABEL, ERROR_MARK, 1); + gimple_label_set_label (p, label); + return p; +} + +/* Build a GIMPLE_GOTO statement to label DEST. */ + +gimple +gimple_build_goto (tree dest) +{ + gimple p = gimple_build_with_ops (GIMPLE_GOTO, ERROR_MARK, 1); + gimple_goto_set_dest (p, dest); + return p; +} + + +/* Build a GIMPLE_NOP statement. */ + +gimple +gimple_build_nop (void) +{ + return gimple_alloc (GIMPLE_NOP, 0); +} + + +/* Build a GIMPLE_BIND statement. + VARS are the variables in BODY. + BLOCK is the containing block. */ + +gimple +gimple_build_bind (tree vars, gimple_seq body, tree block) +{ + gimple p = gimple_alloc (GIMPLE_BIND, 0); + gimple_bind_set_vars (p, vars); + if (body) + gimple_bind_set_body (p, body); + if (block) + gimple_bind_set_block (p, block); + return p; +} + +/* Helper function to set the simple fields of a asm stmt. + + STRING is a pointer to a string that is the asm blocks assembly code. + NINPUT is the number of register inputs. + NOUTPUT is the number of register outputs. + NCLOBBERS is the number of clobbered registers. + */ + +static inline gimple +gimple_build_asm_1 (const char *string, unsigned ninputs, unsigned noutputs, + unsigned nclobbers, unsigned nlabels) +{ + gimple p; + int size = strlen (string); + + /* ASMs with labels cannot have outputs. This should have been + enforced by the front end. */ + gcc_assert (nlabels == 0 || noutputs == 0); + + p = gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, + ninputs + noutputs + nclobbers + nlabels); + + p->gimple_asm.ni = ninputs; + p->gimple_asm.no = noutputs; + p->gimple_asm.nc = nclobbers; + p->gimple_asm.nl = nlabels; + p->gimple_asm.string = ggc_alloc_string (string, size); + +#ifdef GATHER_STATISTICS + gimple_alloc_sizes[(int) gimple_alloc_kind (GIMPLE_ASM)] += size; +#endif + + return p; +} + +/* Build a GIMPLE_ASM statement. + + STRING is the assembly code. + NINPUT is the number of register inputs. + NOUTPUT is the number of register outputs. + NCLOBBERS is the number of clobbered registers. + INPUTS is a vector of the input register parameters. + OUTPUTS is a vector of the output register parameters. + CLOBBERS is a vector of the clobbered register parameters. + LABELS is a vector of destination labels. */ + +gimple +gimple_build_asm_vec (const char *string, VEC(tree,gc)* inputs, + VEC(tree,gc)* outputs, VEC(tree,gc)* clobbers, + VEC(tree,gc)* labels) +{ + gimple p; + unsigned i; + + p = gimple_build_asm_1 (string, + VEC_length (tree, inputs), + VEC_length (tree, outputs), + VEC_length (tree, clobbers), + VEC_length (tree, labels)); + + for (i = 0; i < VEC_length (tree, inputs); i++) + gimple_asm_set_input_op (p, i, VEC_index (tree, inputs, i)); + + for (i = 0; i < VEC_length (tree, outputs); i++) + gimple_asm_set_output_op (p, i, VEC_index (tree, outputs, i)); + + for (i = 0; i < VEC_length (tree, clobbers); i++) + gimple_asm_set_clobber_op (p, i, VEC_index (tree, clobbers, i)); + + for (i = 0; i < VEC_length (tree, labels); i++) + gimple_asm_set_label_op (p, i, VEC_index (tree, labels, i)); + + return p; +} + +/* Build a GIMPLE_CATCH statement. + + TYPES are the catch types. + HANDLER is the exception handler. */ + +gimple +gimple_build_catch (tree types, gimple_seq handler) +{ + gimple p = gimple_alloc (GIMPLE_CATCH, 0); + gimple_catch_set_types (p, types); + if (handler) + gimple_catch_set_handler (p, handler); + + return p; +} + +/* Build a GIMPLE_EH_FILTER statement. + + TYPES are the filter's types. + FAILURE is the filter's failure action. */ + +gimple +gimple_build_eh_filter (tree types, gimple_seq failure) +{ + gimple p = gimple_alloc (GIMPLE_EH_FILTER, 0); + gimple_eh_filter_set_types (p, types); + if (failure) + gimple_eh_filter_set_failure (p, failure); + + return p; +} + +/* Build a GIMPLE_EH_MUST_NOT_THROW statement. */ + +gimple +gimple_build_eh_must_not_throw (tree decl) +{ + gimple p = gimple_alloc (GIMPLE_EH_MUST_NOT_THROW, 0); + + gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); + gcc_assert (flags_from_decl_or_type (decl) & ECF_NORETURN); + gimple_eh_must_not_throw_set_fndecl (p, decl); + + return p; +} + +/* Build a GIMPLE_TRY statement. + + EVAL is the expression to evaluate. + CLEANUP is the cleanup expression. + KIND is either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY depending on + whether this is a try/catch or a try/finally respectively. */ + +gimple +gimple_build_try (gimple_seq eval, gimple_seq cleanup, + enum gimple_try_flags kind) +{ + gimple p; + + gcc_assert (kind == GIMPLE_TRY_CATCH || kind == GIMPLE_TRY_FINALLY); + p = gimple_alloc (GIMPLE_TRY, 0); + gimple_set_subcode (p, kind); + if (eval) + gimple_try_set_eval (p, eval); + if (cleanup) + gimple_try_set_cleanup (p, cleanup); + + return p; +} + +/* Construct a GIMPLE_WITH_CLEANUP_EXPR statement. + + CLEANUP is the cleanup expression. */ + +gimple +gimple_build_wce (gimple_seq cleanup) +{ + gimple p = gimple_alloc (GIMPLE_WITH_CLEANUP_EXPR, 0); + if (cleanup) + gimple_wce_set_cleanup (p, cleanup); + + return p; +} + + +/* Build a GIMPLE_RESX statement. */ + +gimple +gimple_build_resx (int region) +{ + gimple p = gimple_build_with_ops (GIMPLE_RESX, ERROR_MARK, 0); + p->gimple_eh_ctrl.region = region; + return p; +} + + +/* The helper for constructing a gimple switch statement. + INDEX is the switch's index. + NLABELS is the number of labels in the switch excluding the default. + DEFAULT_LABEL is the default label for the switch statement. */ + +gimple +gimple_build_switch_nlabels (unsigned nlabels, tree index, tree default_label) +{ + /* nlabels + 1 default label + 1 index. */ + gimple p = gimple_build_with_ops (GIMPLE_SWITCH, ERROR_MARK, + 1 + (default_label != NULL) + nlabels); + gimple_switch_set_index (p, index); + if (default_label) + gimple_switch_set_default_label (p, default_label); + return p; +} + + +/* Build a GIMPLE_SWITCH statement. + + INDEX is the switch's index. + NLABELS is the number of labels in the switch excluding the DEFAULT_LABEL. + ... are the labels excluding the default. */ + +gimple +gimple_build_switch (unsigned nlabels, tree index, tree default_label, ...) +{ + va_list al; + unsigned i, offset; + gimple p = gimple_build_switch_nlabels (nlabels, index, default_label); + + /* Store the rest of the labels. */ + va_start (al, default_label); + offset = (default_label != NULL); + for (i = 0; i < nlabels; i++) + gimple_switch_set_label (p, i + offset, va_arg (al, tree)); + va_end (al); + + return p; +} + + +/* Build a GIMPLE_SWITCH statement. + + INDEX is the switch's index. + DEFAULT_LABEL is the default label + ARGS is a vector of labels excluding the default. */ + +gimple +gimple_build_switch_vec (tree index, tree default_label, VEC(tree, heap) *args) +{ + unsigned i, offset, nlabels = VEC_length (tree, args); + gimple p = gimple_build_switch_nlabels (nlabels, index, default_label); + + /* Copy the labels from the vector to the switch statement. */ + offset = (default_label != NULL); + for (i = 0; i < nlabels; i++) + gimple_switch_set_label (p, i + offset, VEC_index (tree, args, i)); + + return p; +} + +/* Build a GIMPLE_EH_DISPATCH statement. */ + +gimple +gimple_build_eh_dispatch (int region) +{ + gimple p = gimple_build_with_ops (GIMPLE_EH_DISPATCH, ERROR_MARK, 0); + p->gimple_eh_ctrl.region = region; + return p; +} + +/* Build a new GIMPLE_DEBUG_BIND statement. + + VAR is bound to VALUE; block and location are taken from STMT. */ + +gimple +gimple_build_debug_bind_stat (tree var, tree value, gimple stmt MEM_STAT_DECL) +{ + gimple p = gimple_build_with_ops_stat (GIMPLE_DEBUG, + (unsigned)GIMPLE_DEBUG_BIND, 2 + PASS_MEM_STAT); + + gimple_debug_bind_set_var (p, var); + gimple_debug_bind_set_value (p, value); + if (stmt) + { + gimple_set_block (p, gimple_block (stmt)); + gimple_set_location (p, gimple_location (stmt)); + } + + return p; +} + + +/* Build a GIMPLE_OMP_CRITICAL statement. + + BODY is the sequence of statements for which only one thread can execute. + NAME is optional identifier for this critical block. */ + +gimple +gimple_build_omp_critical (gimple_seq body, tree name) +{ + gimple p = gimple_alloc (GIMPLE_OMP_CRITICAL, 0); + gimple_omp_critical_set_name (p, name); + if (body) + gimple_omp_set_body (p, body); + + return p; +} + +/* Build a GIMPLE_OMP_FOR statement. + + BODY is sequence of statements inside the for loop. + CLAUSES, are any of the OMP loop construct's clauses: private, firstprivate, + lastprivate, reductions, ordered, schedule, and nowait. + COLLAPSE is the collapse count. + PRE_BODY is the sequence of statements that are loop invariant. */ + +gimple +gimple_build_omp_for (gimple_seq body, tree clauses, size_t collapse, + gimple_seq pre_body) +{ + gimple p = gimple_alloc (GIMPLE_OMP_FOR, 0); + if (body) + gimple_omp_set_body (p, body); + gimple_omp_for_set_clauses (p, clauses); + p->gimple_omp_for.collapse = collapse; + p->gimple_omp_for.iter + = ggc_alloc_cleared_vec_gimple_omp_for_iter (collapse); + if (pre_body) + gimple_omp_for_set_pre_body (p, pre_body); + + return p; +} + + +/* Build a GIMPLE_OMP_PARALLEL statement. + + BODY is sequence of statements which are executed in parallel. + CLAUSES, are the OMP parallel construct's clauses. + CHILD_FN is the function created for the parallel threads to execute. + DATA_ARG are the shared data argument(s). */ + +gimple +gimple_build_omp_parallel (gimple_seq body, tree clauses, tree child_fn, + tree data_arg) +{ + gimple p = gimple_alloc (GIMPLE_OMP_PARALLEL, 0); + if (body) + gimple_omp_set_body (p, body); + gimple_omp_parallel_set_clauses (p, clauses); + gimple_omp_parallel_set_child_fn (p, child_fn); + gimple_omp_parallel_set_data_arg (p, data_arg); + + return p; +} + + +/* Build a GIMPLE_OMP_TASK statement. + + BODY is sequence of statements which are executed by the explicit task. + CLAUSES, are the OMP parallel construct's clauses. + CHILD_FN is the function created for the parallel threads to execute. + DATA_ARG are the shared data argument(s). + COPY_FN is the optional function for firstprivate initialization. + ARG_SIZE and ARG_ALIGN are size and alignment of the data block. */ + +gimple +gimple_build_omp_task (gimple_seq body, tree clauses, tree child_fn, + tree data_arg, tree copy_fn, tree arg_size, + tree arg_align) +{ + gimple p = gimple_alloc (GIMPLE_OMP_TASK, 0); + if (body) + gimple_omp_set_body (p, body); + gimple_omp_task_set_clauses (p, clauses); + gimple_omp_task_set_child_fn (p, child_fn); + gimple_omp_task_set_data_arg (p, data_arg); + gimple_omp_task_set_copy_fn (p, copy_fn); + gimple_omp_task_set_arg_size (p, arg_size); + gimple_omp_task_set_arg_align (p, arg_align); + + return p; +} + + +/* Build a GIMPLE_OMP_SECTION statement for a sections statement. + + BODY is the sequence of statements in the section. */ + +gimple +gimple_build_omp_section (gimple_seq body) +{ + gimple p = gimple_alloc (GIMPLE_OMP_SECTION, 0); + if (body) + gimple_omp_set_body (p, body); + + return p; +} + + +/* Build a GIMPLE_OMP_MASTER statement. + + BODY is the sequence of statements to be executed by just the master. */ + +gimple +gimple_build_omp_master (gimple_seq body) +{ + gimple p = gimple_alloc (GIMPLE_OMP_MASTER, 0); + if (body) + gimple_omp_set_body (p, body); + + return p; +} + + +/* Build a GIMPLE_OMP_CONTINUE statement. + + CONTROL_DEF is the definition of the control variable. + CONTROL_USE is the use of the control variable. */ + +gimple +gimple_build_omp_continue (tree control_def, tree control_use) +{ + gimple p = gimple_alloc (GIMPLE_OMP_CONTINUE, 0); + gimple_omp_continue_set_control_def (p, control_def); + gimple_omp_continue_set_control_use (p, control_use); + return p; +} + +/* Build a GIMPLE_OMP_ORDERED statement. + + BODY is the sequence of statements inside a loop that will executed in + sequence. */ + +gimple +gimple_build_omp_ordered (gimple_seq body) +{ + gimple p = gimple_alloc (GIMPLE_OMP_ORDERED, 0); + if (body) + gimple_omp_set_body (p, body); + + return p; +} + + +/* Build a GIMPLE_OMP_RETURN statement. + WAIT_P is true if this is a non-waiting return. */ + +gimple +gimple_build_omp_return (bool wait_p) +{ + gimple p = gimple_alloc (GIMPLE_OMP_RETURN, 0); + if (wait_p) + gimple_omp_return_set_nowait (p); + + return p; +} + + +/* Build a GIMPLE_OMP_SECTIONS statement. + + BODY is a sequence of section statements. + CLAUSES are any of the OMP sections contsruct's clauses: private, + firstprivate, lastprivate, reduction, and nowait. */ + +gimple +gimple_build_omp_sections (gimple_seq body, tree clauses) +{ + gimple p = gimple_alloc (GIMPLE_OMP_SECTIONS, 0); + if (body) + gimple_omp_set_body (p, body); + gimple_omp_sections_set_clauses (p, clauses); + + return p; +} + + +/* Build a GIMPLE_OMP_SECTIONS_SWITCH. */ + +gimple +gimple_build_omp_sections_switch (void) +{ + return gimple_alloc (GIMPLE_OMP_SECTIONS_SWITCH, 0); +} + + +/* Build a GIMPLE_OMP_SINGLE statement. + + BODY is the sequence of statements that will be executed once. + CLAUSES are any of the OMP single construct's clauses: private, firstprivate, + copyprivate, nowait. */ + +gimple +gimple_build_omp_single (gimple_seq body, tree clauses) +{ + gimple p = gimple_alloc (GIMPLE_OMP_SINGLE, 0); + if (body) + gimple_omp_set_body (p, body); + gimple_omp_single_set_clauses (p, clauses); + + return p; +} + + +/* Build a GIMPLE_OMP_ATOMIC_LOAD statement. */ + +gimple +gimple_build_omp_atomic_load (tree lhs, tree rhs) +{ + gimple p = gimple_alloc (GIMPLE_OMP_ATOMIC_LOAD, 0); + gimple_omp_atomic_load_set_lhs (p, lhs); + gimple_omp_atomic_load_set_rhs (p, rhs); + return p; +} + +/* Build a GIMPLE_OMP_ATOMIC_STORE statement. + + VAL is the value we are storing. */ + +gimple +gimple_build_omp_atomic_store (tree val) +{ + gimple p = gimple_alloc (GIMPLE_OMP_ATOMIC_STORE, 0); + gimple_omp_atomic_store_set_val (p, val); + return p; +} + +/* Build a GIMPLE_PREDICT statement. PREDICT is one of the predictors from + predict.def, OUTCOME is NOT_TAKEN or TAKEN. */ + +gimple +gimple_build_predict (enum br_predictor predictor, enum prediction outcome) +{ + gimple p = gimple_alloc (GIMPLE_PREDICT, 0); + /* Ensure all the predictors fit into the lower bits of the subcode. */ + gcc_assert ((int) END_PREDICTORS <= GF_PREDICT_TAKEN); + gimple_predict_set_predictor (p, predictor); + gimple_predict_set_outcome (p, outcome); + return p; +} + +#if defined ENABLE_GIMPLE_CHECKING +/* Complain of a gimple type mismatch and die. */ + +void +gimple_check_failed (const_gimple gs, const char *file, int line, + const char *function, enum gimple_code code, + enum tree_code subcode) +{ + internal_error ("gimple check: expected %s(%s), have %s(%s) in %s, at %s:%d", + gimple_code_name[code], + tree_code_name[subcode], + gimple_code_name[gimple_code (gs)], + gs->gsbase.subcode > 0 + ? tree_code_name[gs->gsbase.subcode] + : "", + function, trim_filename (file), line); +} +#endif /* ENABLE_GIMPLE_CHECKING */ + + +/* Allocate a new GIMPLE sequence in GC memory and return it. If + there are free sequences in GIMPLE_SEQ_CACHE return one of those + instead. */ + +gimple_seq +gimple_seq_alloc (void) +{ + gimple_seq seq = gimple_seq_cache; + if (seq) + { + gimple_seq_cache = gimple_seq_cache->next_free; + gcc_assert (gimple_seq_cache != seq); + memset (seq, 0, sizeof (*seq)); + } + else + { + seq = ggc_alloc_cleared_gimple_seq_d (); +#ifdef GATHER_STATISTICS + gimple_alloc_counts[(int) gimple_alloc_kind_seq]++; + gimple_alloc_sizes[(int) gimple_alloc_kind_seq] += sizeof (*seq); +#endif + } + + return seq; +} + +/* Return SEQ to the free pool of GIMPLE sequences. */ + +void +gimple_seq_free (gimple_seq seq) +{ + if (seq == NULL) + return; + + gcc_assert (gimple_seq_first (seq) == NULL); + gcc_assert (gimple_seq_last (seq) == NULL); + + /* If this triggers, it's a sign that the same list is being freed + twice. */ + gcc_assert (seq != gimple_seq_cache || gimple_seq_cache == NULL); + + /* Add SEQ to the pool of free sequences. */ + seq->next_free = gimple_seq_cache; + gimple_seq_cache = seq; +} + + +/* Link gimple statement GS to the end of the sequence *SEQ_P. If + *SEQ_P is NULL, a new sequence is allocated. */ + +void +gimple_seq_add_stmt (gimple_seq *seq_p, gimple gs) +{ + gimple_stmt_iterator si; + + if (gs == NULL) + return; + + if (*seq_p == NULL) + *seq_p = gimple_seq_alloc (); + + si = gsi_last (*seq_p); + gsi_insert_after (&si, gs, GSI_NEW_STMT); +} + + +/* Append sequence SRC to the end of sequence *DST_P. If *DST_P is + NULL, a new sequence is allocated. */ + +void +gimple_seq_add_seq (gimple_seq *dst_p, gimple_seq src) +{ + gimple_stmt_iterator si; + + if (src == NULL) + return; + + if (*dst_p == NULL) + *dst_p = gimple_seq_alloc (); + + si = gsi_last (*dst_p); + gsi_insert_seq_after (&si, src, GSI_NEW_STMT); +} + + +/* Helper function of empty_body_p. Return true if STMT is an empty + statement. */ + +static bool +empty_stmt_p (gimple stmt) +{ + if (gimple_code (stmt) == GIMPLE_NOP) + return true; + if (gimple_code (stmt) == GIMPLE_BIND) + return empty_body_p (gimple_bind_body (stmt)); + return false; +} + + +/* Return true if BODY contains nothing but empty statements. */ + +bool +empty_body_p (gimple_seq body) +{ + gimple_stmt_iterator i; + + if (gimple_seq_empty_p (body)) + return true; + for (i = gsi_start (body); !gsi_end_p (i); gsi_next (&i)) + if (!empty_stmt_p (gsi_stmt (i)) + && !is_gimple_debug (gsi_stmt (i))) + return false; + + return true; +} + + +/* Perform a deep copy of sequence SRC and return the result. */ + +gimple_seq +gimple_seq_copy (gimple_seq src) +{ + gimple_stmt_iterator gsi; + gimple_seq new_seq = gimple_seq_alloc (); + gimple stmt; + + for (gsi = gsi_start (src); !gsi_end_p (gsi); gsi_next (&gsi)) + { + stmt = gimple_copy (gsi_stmt (gsi)); + gimple_seq_add_stmt (&new_seq, stmt); + } + + return new_seq; +} + + +/* Walk all the statements in the sequence SEQ calling walk_gimple_stmt + on each one. WI is as in walk_gimple_stmt. + + If walk_gimple_stmt returns non-NULL, the walk is stopped, the + value is stored in WI->CALLBACK_RESULT and the statement that + produced the value is returned. + + Otherwise, all the statements are walked and NULL returned. */ + +gimple +walk_gimple_seq (gimple_seq seq, walk_stmt_fn callback_stmt, + walk_tree_fn callback_op, struct walk_stmt_info *wi) +{ + gimple_stmt_iterator gsi; + + for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi)) + { + tree ret = walk_gimple_stmt (&gsi, callback_stmt, callback_op, wi); + if (ret) + { + /* If CALLBACK_STMT or CALLBACK_OP return a value, WI must exist + to hold it. */ + gcc_assert (wi); + wi->callback_result = ret; + return gsi_stmt (gsi); + } + } + + if (wi) + wi->callback_result = NULL_TREE; + + return NULL; +} + + +/* Helper function for walk_gimple_stmt. Walk operands of a GIMPLE_ASM. */ + +static tree +walk_gimple_asm (gimple stmt, walk_tree_fn callback_op, + struct walk_stmt_info *wi) +{ + tree ret, op; + unsigned noutputs; + const char **oconstraints; + unsigned i, n; + const char *constraint; + bool allows_mem, allows_reg, is_inout; + + noutputs = gimple_asm_noutputs (stmt); + oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *)); + + if (wi) + wi->is_lhs = true; + + for (i = 0; i < noutputs; i++) + { + op = gimple_asm_output_op (stmt, i); + constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op))); + oconstraints[i] = constraint; + parse_output_constraint (&constraint, i, 0, 0, &allows_mem, &allows_reg, + &is_inout); + if (wi) + wi->val_only = (allows_reg || !allows_mem); + ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL); + if (ret) + return ret; + } + + n = gimple_asm_ninputs (stmt); + for (i = 0; i < n; i++) + { + op = gimple_asm_input_op (stmt, i); + constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op))); + parse_input_constraint (&constraint, 0, 0, noutputs, 0, + oconstraints, &allows_mem, &allows_reg); + if (wi) + { + wi->val_only = (allows_reg || !allows_mem); + /* Although input "m" is not really a LHS, we need a lvalue. */ + wi->is_lhs = !wi->val_only; + } + ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL); + if (ret) + return ret; + } + + if (wi) + { + wi->is_lhs = false; + wi->val_only = true; + } + + n = gimple_asm_nlabels (stmt); + for (i = 0; i < n; i++) + { + op = gimple_asm_label_op (stmt, i); + ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL); + if (ret) + return ret; + } + + return NULL_TREE; +} + + +/* Helper function of WALK_GIMPLE_STMT. Walk every tree operand in + STMT. CALLBACK_OP and WI are as in WALK_GIMPLE_STMT. + + CALLBACK_OP is called on each operand of STMT via walk_tree. + Additional parameters to walk_tree must be stored in WI. For each operand + OP, walk_tree is called as: + + walk_tree (&OP, CALLBACK_OP, WI, WI->PSET) + + If CALLBACK_OP returns non-NULL for an operand, the remaining + operands are not scanned. + + The return value is that returned by the last call to walk_tree, or + NULL_TREE if no CALLBACK_OP is specified. */ + +tree +walk_gimple_op (gimple stmt, walk_tree_fn callback_op, + struct walk_stmt_info *wi) +{ + struct pointer_set_t *pset = (wi) ? wi->pset : NULL; + unsigned i; + tree ret = NULL_TREE; + + switch (gimple_code (stmt)) + { + case GIMPLE_ASSIGN: + /* Walk the RHS operands. If the LHS is of a non-renamable type or + is a register variable, we may use a COMPONENT_REF on the RHS. */ + if (wi) + { + tree lhs = gimple_assign_lhs (stmt); + wi->val_only + = (is_gimple_reg_type (TREE_TYPE (lhs)) && !is_gimple_reg (lhs)) + || !gimple_assign_single_p (stmt); + } + + for (i = 1; i < gimple_num_ops (stmt); i++) + { + ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, + pset); + if (ret) + return ret; + } + + /* Walk the LHS. If the RHS is appropriate for a memory, we + may use a COMPONENT_REF on the LHS. */ + if (wi) + { + /* If the RHS has more than 1 operand, it is not appropriate + for the memory. */ + wi->val_only = !is_gimple_mem_rhs (gimple_assign_rhs1 (stmt)) + || !gimple_assign_single_p (stmt); + wi->is_lhs = true; + } + + ret = walk_tree (gimple_op_ptr (stmt, 0), callback_op, wi, pset); + if (ret) + return ret; + + if (wi) + { + wi->val_only = true; + wi->is_lhs = false; + } + break; + + case GIMPLE_CALL: + if (wi) + { + wi->is_lhs = false; + wi->val_only = true; + } + + ret = walk_tree (gimple_call_chain_ptr (stmt), callback_op, wi, pset); + if (ret) + return ret; + + ret = walk_tree (gimple_call_fn_ptr (stmt), callback_op, wi, pset); + if (ret) + return ret; + + for (i = 0; i < gimple_call_num_args (stmt); i++) + { + if (wi) + wi->val_only = is_gimple_reg_type (gimple_call_arg (stmt, i)); + ret = walk_tree (gimple_call_arg_ptr (stmt, i), callback_op, wi, + pset); + if (ret) + return ret; + } + + if (gimple_call_lhs (stmt)) + { + if (wi) + { + wi->is_lhs = true; + wi->val_only = is_gimple_reg_type (gimple_call_lhs (stmt)); + } + + ret = walk_tree (gimple_call_lhs_ptr (stmt), callback_op, wi, pset); + if (ret) + return ret; + } + + if (wi) + { + wi->is_lhs = false; + wi->val_only = true; + } + break; + + case GIMPLE_CATCH: + ret = walk_tree (gimple_catch_types_ptr (stmt), callback_op, wi, + pset); + if (ret) + return ret; + break; + + case GIMPLE_EH_FILTER: + ret = walk_tree (gimple_eh_filter_types_ptr (stmt), callback_op, wi, + pset); + if (ret) + return ret; + break; + + case GIMPLE_ASM: + ret = walk_gimple_asm (stmt, callback_op, wi); + if (ret) + return ret; + break; + + case GIMPLE_OMP_CONTINUE: + ret = walk_tree (gimple_omp_continue_control_def_ptr (stmt), + callback_op, wi, pset); + if (ret) + return ret; + + ret = walk_tree (gimple_omp_continue_control_use_ptr (stmt), + callback_op, wi, pset); + if (ret) + return ret; + break; + + case GIMPLE_OMP_CRITICAL: + ret = walk_tree (gimple_omp_critical_name_ptr (stmt), callback_op, wi, + pset); + if (ret) + return ret; + break; + + case GIMPLE_OMP_FOR: + ret = walk_tree (gimple_omp_for_clauses_ptr (stmt), callback_op, wi, + pset); + if (ret) + return ret; + for (i = 0; i < gimple_omp_for_collapse (stmt); i++) + { + ret = walk_tree (gimple_omp_for_index_ptr (stmt, i), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_for_initial_ptr (stmt, i), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_for_final_ptr (stmt, i), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_for_incr_ptr (stmt, i), callback_op, + wi, pset); + } + if (ret) + return ret; + break; + + case GIMPLE_OMP_PARALLEL: + ret = walk_tree (gimple_omp_parallel_clauses_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_parallel_child_fn_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_parallel_data_arg_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + break; + + case GIMPLE_OMP_TASK: + ret = walk_tree (gimple_omp_task_clauses_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_task_child_fn_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_task_data_arg_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_task_copy_fn_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_task_arg_size_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_task_arg_align_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + break; + + case GIMPLE_OMP_SECTIONS: + ret = walk_tree (gimple_omp_sections_clauses_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + + ret = walk_tree (gimple_omp_sections_control_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + + break; + + case GIMPLE_OMP_SINGLE: + ret = walk_tree (gimple_omp_single_clauses_ptr (stmt), callback_op, wi, + pset); + if (ret) + return ret; + break; + + case GIMPLE_OMP_ATOMIC_LOAD: + ret = walk_tree (gimple_omp_atomic_load_lhs_ptr (stmt), callback_op, wi, + pset); + if (ret) + return ret; + + ret = walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt), callback_op, wi, + pset); + if (ret) + return ret; + break; + + case GIMPLE_OMP_ATOMIC_STORE: + ret = walk_tree (gimple_omp_atomic_store_val_ptr (stmt), callback_op, + wi, pset); + if (ret) + return ret; + break; + + /* Tuples that do not have operands. */ + case GIMPLE_NOP: + case GIMPLE_RESX: + case GIMPLE_OMP_RETURN: + case GIMPLE_PREDICT: + break; + + default: + { + enum gimple_statement_structure_enum gss; + gss = gimple_statement_structure (stmt); + if (gss == GSS_WITH_OPS || gss == GSS_WITH_MEM_OPS) + for (i = 0; i < gimple_num_ops (stmt); i++) + { + ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, pset); + if (ret) + return ret; + } + } + break; + } + + return NULL_TREE; +} + + +/* Walk the current statement in GSI (optionally using traversal state + stored in WI). If WI is NULL, no state is kept during traversal. + The callback CALLBACK_STMT is called. If CALLBACK_STMT indicates + that it has handled all the operands of the statement, its return + value is returned. Otherwise, the return value from CALLBACK_STMT + is discarded and its operands are scanned. + + If CALLBACK_STMT is NULL or it didn't handle the operands, + CALLBACK_OP is called on each operand of the statement via + walk_gimple_op. If walk_gimple_op returns non-NULL for any + operand, the remaining operands are not scanned. In this case, the + return value from CALLBACK_OP is returned. + + In any other case, NULL_TREE is returned. */ + +tree +walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt, + walk_tree_fn callback_op, struct walk_stmt_info *wi) +{ + gimple ret; + tree tree_ret; + gimple stmt = gsi_stmt (*gsi); + + if (wi) + wi->gsi = *gsi; + + if (wi && wi->want_locations && gimple_has_location (stmt)) + input_location = gimple_location (stmt); + + ret = NULL; + + /* Invoke the statement callback. Return if the callback handled + all of STMT operands by itself. */ + if (callback_stmt) + { + bool handled_ops = false; + tree_ret = callback_stmt (gsi, &handled_ops, wi); + if (handled_ops) + return tree_ret; + + /* If CALLBACK_STMT did not handle operands, it should not have + a value to return. */ + gcc_assert (tree_ret == NULL); + + /* Re-read stmt in case the callback changed it. */ + stmt = gsi_stmt (*gsi); + } + + /* If CALLBACK_OP is defined, invoke it on every operand of STMT. */ + if (callback_op) + { + tree_ret = walk_gimple_op (stmt, callback_op, wi); + if (tree_ret) + return tree_ret; + } + + /* If STMT can have statements inside (e.g. GIMPLE_BIND), walk them. */ + switch (gimple_code (stmt)) + { + case GIMPLE_BIND: + ret = walk_gimple_seq (gimple_bind_body (stmt), callback_stmt, + callback_op, wi); + if (ret) + return wi->callback_result; + break; + + case GIMPLE_CATCH: + ret = walk_gimple_seq (gimple_catch_handler (stmt), callback_stmt, + callback_op, wi); + if (ret) + return wi->callback_result; + break; + + case GIMPLE_EH_FILTER: + ret = walk_gimple_seq (gimple_eh_filter_failure (stmt), callback_stmt, + callback_op, wi); + if (ret) + return wi->callback_result; + break; + + case GIMPLE_TRY: + ret = walk_gimple_seq (gimple_try_eval (stmt), callback_stmt, callback_op, + wi); + if (ret) + return wi->callback_result; + + ret = walk_gimple_seq (gimple_try_cleanup (stmt), callback_stmt, + callback_op, wi); + if (ret) + return wi->callback_result; + break; + + case GIMPLE_OMP_FOR: + ret = walk_gimple_seq (gimple_omp_for_pre_body (stmt), callback_stmt, + callback_op, wi); + if (ret) + return wi->callback_result; + + /* FALL THROUGH. */ + case GIMPLE_OMP_CRITICAL: + case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_ORDERED: + case GIMPLE_OMP_SECTION: + case GIMPLE_OMP_PARALLEL: + case GIMPLE_OMP_TASK: + case GIMPLE_OMP_SECTIONS: + case GIMPLE_OMP_SINGLE: + ret = walk_gimple_seq (gimple_omp_body (stmt), callback_stmt, callback_op, + wi); + if (ret) + return wi->callback_result; + break; + + case GIMPLE_WITH_CLEANUP_EXPR: + ret = walk_gimple_seq (gimple_wce_cleanup (stmt), callback_stmt, + callback_op, wi); + if (ret) + return wi->callback_result; + break; + + default: + gcc_assert (!gimple_has_substatements (stmt)); + break; + } + + return NULL; +} + + +/* Set sequence SEQ to be the GIMPLE body for function FN. */ + +void +gimple_set_body (tree fndecl, gimple_seq seq) +{ + struct function *fn = DECL_STRUCT_FUNCTION (fndecl); + if (fn == NULL) + { + /* If FNDECL still does not have a function structure associated + with it, then it does not make sense for it to receive a + GIMPLE body. */ + gcc_assert (seq == NULL); + } + else + fn->gimple_body = seq; +} + + +/* Return the body of GIMPLE statements for function FN. After the + CFG pass, the function body doesn't exist anymore because it has + been split up into basic blocks. In this case, it returns + NULL. */ + +gimple_seq +gimple_body (tree fndecl) +{ + struct function *fn = DECL_STRUCT_FUNCTION (fndecl); + return fn ? fn->gimple_body : NULL; +} + +/* Return true when FNDECL has Gimple body either in unlowered + or CFG form. */ +bool +gimple_has_body_p (tree fndecl) +{ + struct function *fn = DECL_STRUCT_FUNCTION (fndecl); + return (gimple_body (fndecl) || (fn && fn->cfg)); +} + +/* Detect flags from a GIMPLE_CALL. This is just like + call_expr_flags, but for gimple tuples. */ + +int +gimple_call_flags (const_gimple stmt) +{ + int flags; + tree decl = gimple_call_fndecl (stmt); + tree t; + + if (decl) + flags = flags_from_decl_or_type (decl); + else + { + t = TREE_TYPE (gimple_call_fn (stmt)); + if (t && TREE_CODE (t) == POINTER_TYPE) + flags = flags_from_decl_or_type (TREE_TYPE (t)); + else + flags = 0; + } + + if (stmt->gsbase.subcode & GF_CALL_NOTHROW) + flags |= ECF_NOTHROW; + + return flags; +} + +/* Detects argument flags for argument number ARG on call STMT. */ + +int +gimple_call_arg_flags (const_gimple stmt, unsigned arg) +{ + tree type = TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt))); + tree attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type)); + if (!attr) + return 0; + + attr = TREE_VALUE (TREE_VALUE (attr)); + if (1 + arg >= (unsigned) TREE_STRING_LENGTH (attr)) + return 0; + + switch (TREE_STRING_POINTER (attr)[1 + arg]) + { + case 'x': + case 'X': + return EAF_UNUSED; + + case 'R': + return EAF_DIRECT | EAF_NOCLOBBER | EAF_NOESCAPE; + + case 'r': + return EAF_NOCLOBBER | EAF_NOESCAPE; + + case 'W': + return EAF_DIRECT | EAF_NOESCAPE; + + case 'w': + return EAF_NOESCAPE; + + case '.': + default: + return 0; + } +} + +/* Detects return flags for the call STMT. */ + +int +gimple_call_return_flags (const_gimple stmt) +{ + tree type; + tree attr = NULL_TREE; + + if (gimple_call_flags (stmt) & ECF_MALLOC) + return ERF_NOALIAS; + + type = TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt))); + attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type)); + if (!attr) + return 0; + + attr = TREE_VALUE (TREE_VALUE (attr)); + if (TREE_STRING_LENGTH (attr) < 1) + return 0; + + switch (TREE_STRING_POINTER (attr)[0]) + { + case '1': + case '2': + case '3': + case '4': + return ERF_RETURNS_ARG | (TREE_STRING_POINTER (attr)[0] - '1'); + + case 'm': + return ERF_NOALIAS; + + case '.': + default: + return 0; + } +} + + +/* Return true if GS is a copy assignment. */ + +bool +gimple_assign_copy_p (gimple gs) +{ + return (gimple_assign_single_p (gs) + && is_gimple_val (gimple_op (gs, 1))); +} + + +/* Return true if GS is a SSA_NAME copy assignment. */ + +bool +gimple_assign_ssa_name_copy_p (gimple gs) +{ + return (gimple_assign_single_p (gs) + && TREE_CODE (gimple_assign_lhs (gs)) == SSA_NAME + && TREE_CODE (gimple_assign_rhs1 (gs)) == SSA_NAME); +} + + +/* Return true if GS is an assignment with a unary RHS, but the + operator has no effect on the assigned value. The logic is adapted + from STRIP_NOPS. This predicate is intended to be used in tuplifying + instances in which STRIP_NOPS was previously applied to the RHS of + an assignment. + + NOTE: In the use cases that led to the creation of this function + and of gimple_assign_single_p, it is typical to test for either + condition and to proceed in the same manner. In each case, the + assigned value is represented by the single RHS operand of the + assignment. I suspect there may be cases where gimple_assign_copy_p, + gimple_assign_single_p, or equivalent logic is used where a similar + treatment of unary NOPs is appropriate. */ + +bool +gimple_assign_unary_nop_p (gimple gs) +{ + return (is_gimple_assign (gs) + && (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (gs)) + || gimple_assign_rhs_code (gs) == NON_LVALUE_EXPR) + && gimple_assign_rhs1 (gs) != error_mark_node + && (TYPE_MODE (TREE_TYPE (gimple_assign_lhs (gs))) + == TYPE_MODE (TREE_TYPE (gimple_assign_rhs1 (gs))))); +} + +/* Set BB to be the basic block holding G. */ + +void +gimple_set_bb (gimple stmt, basic_block bb) +{ + stmt->gsbase.bb = bb; + + /* If the statement is a label, add the label to block-to-labels map + so that we can speed up edge creation for GIMPLE_GOTOs. */ + if (cfun->cfg && gimple_code (stmt) == GIMPLE_LABEL) + { + tree t; + int uid; + + t = gimple_label_label (stmt); + uid = LABEL_DECL_UID (t); + if (uid == -1) + { + unsigned old_len = VEC_length (basic_block, label_to_block_map); + LABEL_DECL_UID (t) = uid = cfun->cfg->last_label_uid++; + if (old_len <= (unsigned) uid) + { + unsigned new_len = 3 * uid / 2 + 1; + + VEC_safe_grow_cleared (basic_block, gc, label_to_block_map, + new_len); + } + } + + VEC_replace (basic_block, label_to_block_map, uid, bb); + } +} + + +/* Modify the RHS of the assignment pointed-to by GSI using the + operands in the expression tree EXPR. + + NOTE: The statement pointed-to by GSI may be reallocated if it + did not have enough operand slots. + + This function is useful to convert an existing tree expression into + the flat representation used for the RHS of a GIMPLE assignment. + It will reallocate memory as needed to expand or shrink the number + of operand slots needed to represent EXPR. + + NOTE: If you find yourself building a tree and then calling this + function, you are most certainly doing it the slow way. It is much + better to build a new assignment or to use the function + gimple_assign_set_rhs_with_ops, which does not require an + expression tree to be built. */ + +void +gimple_assign_set_rhs_from_tree (gimple_stmt_iterator *gsi, tree expr) +{ + enum tree_code subcode; + tree op1, op2, op3; + + extract_ops_from_tree_1 (expr, &subcode, &op1, &op2, &op3); + gimple_assign_set_rhs_with_ops_1 (gsi, subcode, op1, op2, op3); +} + + +/* Set the RHS of assignment statement pointed-to by GSI to CODE with + operands OP1, OP2 and OP3. + + NOTE: The statement pointed-to by GSI may be reallocated if it + did not have enough operand slots. */ + +void +gimple_assign_set_rhs_with_ops_1 (gimple_stmt_iterator *gsi, enum tree_code code, + tree op1, tree op2, tree op3) +{ + unsigned new_rhs_ops = get_gimple_rhs_num_ops (code); + gimple stmt = gsi_stmt (*gsi); + + /* If the new CODE needs more operands, allocate a new statement. */ + if (gimple_num_ops (stmt) < new_rhs_ops + 1) + { + tree lhs = gimple_assign_lhs (stmt); + gimple new_stmt = gimple_alloc (gimple_code (stmt), new_rhs_ops + 1); + memcpy (new_stmt, stmt, gimple_size (gimple_code (stmt))); + gsi_replace (gsi, new_stmt, true); + stmt = new_stmt; + + /* The LHS needs to be reset as this also changes the SSA name + on the LHS. */ + gimple_assign_set_lhs (stmt, lhs); + } + + gimple_set_num_ops (stmt, new_rhs_ops + 1); + gimple_set_subcode (stmt, code); + gimple_assign_set_rhs1 (stmt, op1); + if (new_rhs_ops > 1) + gimple_assign_set_rhs2 (stmt, op2); + if (new_rhs_ops > 2) + gimple_assign_set_rhs3 (stmt, op3); +} + + +/* Return the LHS of a statement that performs an assignment, + either a GIMPLE_ASSIGN or a GIMPLE_CALL. Returns NULL_TREE + for a call to a function that returns no value, or for a + statement other than an assignment or a call. */ + +tree +gimple_get_lhs (const_gimple stmt) +{ + enum gimple_code code = gimple_code (stmt); + + if (code == GIMPLE_ASSIGN) + return gimple_assign_lhs (stmt); + else if (code == GIMPLE_CALL) + return gimple_call_lhs (stmt); + else + return NULL_TREE; +} + + +/* Set the LHS of a statement that performs an assignment, + either a GIMPLE_ASSIGN or a GIMPLE_CALL. */ + +void +gimple_set_lhs (gimple stmt, tree lhs) +{ + enum gimple_code code = gimple_code (stmt); + + if (code == GIMPLE_ASSIGN) + gimple_assign_set_lhs (stmt, lhs); + else if (code == GIMPLE_CALL) + gimple_call_set_lhs (stmt, lhs); + else + gcc_unreachable(); +} + +/* Replace the LHS of STMT, an assignment, either a GIMPLE_ASSIGN or a + GIMPLE_CALL, with NLHS, in preparation for modifying the RHS to an + expression with a different value. + + This will update any annotations (say debug bind stmts) referring + to the original LHS, so that they use the RHS instead. This is + done even if NLHS and LHS are the same, for it is understood that + the RHS will be modified afterwards, and NLHS will not be assigned + an equivalent value. + + Adjusting any non-annotation uses of the LHS, if needed, is a + responsibility of the caller. + + The effect of this call should be pretty much the same as that of + inserting a copy of STMT before STMT, and then removing the + original stmt, at which time gsi_remove() would have update + annotations, but using this function saves all the inserting, + copying and removing. */ + +void +gimple_replace_lhs (gimple stmt, tree nlhs) +{ + if (MAY_HAVE_DEBUG_STMTS) + { + tree lhs = gimple_get_lhs (stmt); + + gcc_assert (SSA_NAME_DEF_STMT (lhs) == stmt); + + insert_debug_temp_for_var_def (NULL, lhs); + } + + gimple_set_lhs (stmt, nlhs); +} + +/* Return a deep copy of statement STMT. All the operands from STMT + are reallocated and copied using unshare_expr. The DEF, USE, VDEF + and VUSE operand arrays are set to empty in the new copy. */ + +gimple +gimple_copy (gimple stmt) +{ + enum gimple_code code = gimple_code (stmt); + unsigned num_ops = gimple_num_ops (stmt); + gimple copy = gimple_alloc (code, num_ops); + unsigned i; + + /* Shallow copy all the fields from STMT. */ + memcpy (copy, stmt, gimple_size (code)); + + /* If STMT has sub-statements, deep-copy them as well. */ + if (gimple_has_substatements (stmt)) + { + gimple_seq new_seq; + tree t; + + switch (gimple_code (stmt)) + { + case GIMPLE_BIND: + new_seq = gimple_seq_copy (gimple_bind_body (stmt)); + gimple_bind_set_body (copy, new_seq); + gimple_bind_set_vars (copy, unshare_expr (gimple_bind_vars (stmt))); + gimple_bind_set_block (copy, gimple_bind_block (stmt)); + break; + + case GIMPLE_CATCH: + new_seq = gimple_seq_copy (gimple_catch_handler (stmt)); + gimple_catch_set_handler (copy, new_seq); + t = unshare_expr (gimple_catch_types (stmt)); + gimple_catch_set_types (copy, t); + break; + + case GIMPLE_EH_FILTER: + new_seq = gimple_seq_copy (gimple_eh_filter_failure (stmt)); + gimple_eh_filter_set_failure (copy, new_seq); + t = unshare_expr (gimple_eh_filter_types (stmt)); + gimple_eh_filter_set_types (copy, t); + break; + + case GIMPLE_TRY: + new_seq = gimple_seq_copy (gimple_try_eval (stmt)); + gimple_try_set_eval (copy, new_seq); + new_seq = gimple_seq_copy (gimple_try_cleanup (stmt)); + gimple_try_set_cleanup (copy, new_seq); + break; + + case GIMPLE_OMP_FOR: + new_seq = gimple_seq_copy (gimple_omp_for_pre_body (stmt)); + gimple_omp_for_set_pre_body (copy, new_seq); + t = unshare_expr (gimple_omp_for_clauses (stmt)); + gimple_omp_for_set_clauses (copy, t); + copy->gimple_omp_for.iter + = ggc_alloc_vec_gimple_omp_for_iter + (gimple_omp_for_collapse (stmt)); + for (i = 0; i < gimple_omp_for_collapse (stmt); i++) + { + gimple_omp_for_set_cond (copy, i, + gimple_omp_for_cond (stmt, i)); + gimple_omp_for_set_index (copy, i, + gimple_omp_for_index (stmt, i)); + t = unshare_expr (gimple_omp_for_initial (stmt, i)); + gimple_omp_for_set_initial (copy, i, t); + t = unshare_expr (gimple_omp_for_final (stmt, i)); + gimple_omp_for_set_final (copy, i, t); + t = unshare_expr (gimple_omp_for_incr (stmt, i)); + gimple_omp_for_set_incr (copy, i, t); + } + goto copy_omp_body; + + case GIMPLE_OMP_PARALLEL: + t = unshare_expr (gimple_omp_parallel_clauses (stmt)); + gimple_omp_parallel_set_clauses (copy, t); + t = unshare_expr (gimple_omp_parallel_child_fn (stmt)); + gimple_omp_parallel_set_child_fn (copy, t); + t = unshare_expr (gimple_omp_parallel_data_arg (stmt)); + gimple_omp_parallel_set_data_arg (copy, t); + goto copy_omp_body; + + case GIMPLE_OMP_TASK: + t = unshare_expr (gimple_omp_task_clauses (stmt)); + gimple_omp_task_set_clauses (copy, t); + t = unshare_expr (gimple_omp_task_child_fn (stmt)); + gimple_omp_task_set_child_fn (copy, t); + t = unshare_expr (gimple_omp_task_data_arg (stmt)); + gimple_omp_task_set_data_arg (copy, t); + t = unshare_expr (gimple_omp_task_copy_fn (stmt)); + gimple_omp_task_set_copy_fn (copy, t); + t = unshare_expr (gimple_omp_task_arg_size (stmt)); + gimple_omp_task_set_arg_size (copy, t); + t = unshare_expr (gimple_omp_task_arg_align (stmt)); + gimple_omp_task_set_arg_align (copy, t); + goto copy_omp_body; + + case GIMPLE_OMP_CRITICAL: + t = unshare_expr (gimple_omp_critical_name (stmt)); + gimple_omp_critical_set_name (copy, t); + goto copy_omp_body; + + case GIMPLE_OMP_SECTIONS: + t = unshare_expr (gimple_omp_sections_clauses (stmt)); + gimple_omp_sections_set_clauses (copy, t); + t = unshare_expr (gimple_omp_sections_control (stmt)); + gimple_omp_sections_set_control (copy, t); + /* FALLTHRU */ + + case GIMPLE_OMP_SINGLE: + case GIMPLE_OMP_SECTION: + case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_ORDERED: + copy_omp_body: + new_seq = gimple_seq_copy (gimple_omp_body (stmt)); + gimple_omp_set_body (copy, new_seq); + break; + + case GIMPLE_WITH_CLEANUP_EXPR: + new_seq = gimple_seq_copy (gimple_wce_cleanup (stmt)); + gimple_wce_set_cleanup (copy, new_seq); + break; + + default: + gcc_unreachable (); + } + } + + /* Make copy of operands. */ + if (num_ops > 0) + { + for (i = 0; i < num_ops; i++) + gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i))); + + /* Clear out SSA operand vectors on COPY. */ + if (gimple_has_ops (stmt)) + { + gimple_set_def_ops (copy, NULL); + gimple_set_use_ops (copy, NULL); + } + + if (gimple_has_mem_ops (stmt)) + { + gimple_set_vdef (copy, gimple_vdef (stmt)); + gimple_set_vuse (copy, gimple_vuse (stmt)); + } + + /* SSA operands need to be updated. */ + gimple_set_modified (copy, true); + } + + return copy; +} + + +/* Set the MODIFIED flag to MODIFIEDP, iff the gimple statement G has + a MODIFIED field. */ + +void +gimple_set_modified (gimple s, bool modifiedp) +{ + if (gimple_has_ops (s)) + { + s->gsbase.modified = (unsigned) modifiedp; + + if (modifiedp + && cfun->gimple_df + && is_gimple_call (s) + && gimple_call_noreturn_p (s)) + VEC_safe_push (gimple, gc, MODIFIED_NORETURN_CALLS (cfun), s); + } +} + + +/* Return true if statement S has side-effects. We consider a + statement to have side effects if: + + - It is a GIMPLE_CALL not marked with ECF_PURE or ECF_CONST. + - Any of its operands are marked TREE_THIS_VOLATILE or TREE_SIDE_EFFECTS. */ + +bool +gimple_has_side_effects (const_gimple s) +{ + unsigned i; + + if (is_gimple_debug (s)) + return false; + + /* We don't have to scan the arguments to check for + volatile arguments, though, at present, we still + do a scan to check for TREE_SIDE_EFFECTS. */ + if (gimple_has_volatile_ops (s)) + return true; + + if (is_gimple_call (s)) + { + unsigned nargs = gimple_call_num_args (s); + + if (!(gimple_call_flags (s) & (ECF_CONST | ECF_PURE))) + return true; + else if (gimple_call_flags (s) & ECF_LOOPING_CONST_OR_PURE) + /* An infinite loop is considered a side effect. */ + return true; + + if (gimple_call_lhs (s) + && TREE_SIDE_EFFECTS (gimple_call_lhs (s))) + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } + + if (TREE_SIDE_EFFECTS (gimple_call_fn (s))) + return true; + + for (i = 0; i < nargs; i++) + if (TREE_SIDE_EFFECTS (gimple_call_arg (s, i))) + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } + + return false; + } + else + { + for (i = 0; i < gimple_num_ops (s); i++) + if (TREE_SIDE_EFFECTS (gimple_op (s, i))) + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } + } + + return false; +} + +/* Return true if the RHS of statement S has side effects. + We may use it to determine if it is admissable to replace + an assignment or call with a copy of a previously-computed + value. In such cases, side-effects due the the LHS are + preserved. */ + +bool +gimple_rhs_has_side_effects (const_gimple s) +{ + unsigned i; + + if (is_gimple_call (s)) + { + unsigned nargs = gimple_call_num_args (s); + + if (!(gimple_call_flags (s) & (ECF_CONST | ECF_PURE))) + return true; + + /* We cannot use gimple_has_volatile_ops here, + because we must ignore a volatile LHS. */ + if (TREE_SIDE_EFFECTS (gimple_call_fn (s)) + || TREE_THIS_VOLATILE (gimple_call_fn (s))) + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } + + for (i = 0; i < nargs; i++) + if (TREE_SIDE_EFFECTS (gimple_call_arg (s, i)) + || TREE_THIS_VOLATILE (gimple_call_arg (s, i))) + return true; + + return false; + } + else if (is_gimple_assign (s)) + { + /* Skip the first operand, the LHS. */ + for (i = 1; i < gimple_num_ops (s); i++) + if (TREE_SIDE_EFFECTS (gimple_op (s, i)) + || TREE_THIS_VOLATILE (gimple_op (s, i))) + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } + } + else if (is_gimple_debug (s)) + return false; + else + { + /* For statements without an LHS, examine all arguments. */ + for (i = 0; i < gimple_num_ops (s); i++) + if (TREE_SIDE_EFFECTS (gimple_op (s, i)) + || TREE_THIS_VOLATILE (gimple_op (s, i))) + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } + } + + return false; +} + +/* Helper for gimple_could_trap_p and gimple_assign_rhs_could_trap_p. + Return true if S can trap. When INCLUDE_MEM is true, check whether + the memory operations could trap. When INCLUDE_STORES is true and + S is a GIMPLE_ASSIGN, the LHS of the assignment is also checked. */ + +bool +gimple_could_trap_p_1 (gimple s, bool include_mem, bool include_stores) +{ + tree t, div = NULL_TREE; + enum tree_code op; + + if (include_mem) + { + unsigned i, start = (is_gimple_assign (s) && !include_stores) ? 1 : 0; + + for (i = start; i < gimple_num_ops (s); i++) + if (tree_could_trap_p (gimple_op (s, i))) + return true; + } + + switch (gimple_code (s)) + { + case GIMPLE_ASM: + return gimple_asm_volatile_p (s); + + case GIMPLE_CALL: + t = gimple_call_fndecl (s); + /* Assume that calls to weak functions may trap. */ + if (!t || !DECL_P (t) || DECL_WEAK (t)) + return true; + return false; + + case GIMPLE_ASSIGN: + t = gimple_expr_type (s); + op = gimple_assign_rhs_code (s); + if (get_gimple_rhs_class (op) == GIMPLE_BINARY_RHS) + div = gimple_assign_rhs2 (s); + return (operation_could_trap_p (op, FLOAT_TYPE_P (t), + (INTEGRAL_TYPE_P (t) + && TYPE_OVERFLOW_TRAPS (t)), + div)); + + default: + break; + } + + return false; +} + +/* Return true if statement S can trap. */ + +bool +gimple_could_trap_p (gimple s) +{ + return gimple_could_trap_p_1 (s, true, true); +} + +/* Return true if RHS of a GIMPLE_ASSIGN S can trap. */ + +bool +gimple_assign_rhs_could_trap_p (gimple s) +{ + gcc_assert (is_gimple_assign (s)); + return gimple_could_trap_p_1 (s, true, false); +} + + +/* Print debugging information for gimple stmts generated. */ + +void +dump_gimple_statistics (void) +{ +#ifdef GATHER_STATISTICS + int i, total_tuples = 0, total_bytes = 0; + + fprintf (stderr, "\nGIMPLE statements\n"); + fprintf (stderr, "Kind Stmts Bytes\n"); + fprintf (stderr, "---------------------------------------\n"); + for (i = 0; i < (int) gimple_alloc_kind_all; ++i) + { + fprintf (stderr, "%-20s %7d %10d\n", gimple_alloc_kind_names[i], + gimple_alloc_counts[i], gimple_alloc_sizes[i]); + total_tuples += gimple_alloc_counts[i]; + total_bytes += gimple_alloc_sizes[i]; + } + fprintf (stderr, "---------------------------------------\n"); + fprintf (stderr, "%-20s %7d %10d\n", "Total", total_tuples, total_bytes); + fprintf (stderr, "---------------------------------------\n"); +#else + fprintf (stderr, "No gimple statistics\n"); +#endif +} + + +/* Return the number of operands needed on the RHS of a GIMPLE + assignment for an expression with tree code CODE. */ + +unsigned +get_gimple_rhs_num_ops (enum tree_code code) +{ + enum gimple_rhs_class rhs_class = get_gimple_rhs_class (code); + + if (rhs_class == GIMPLE_UNARY_RHS || rhs_class == GIMPLE_SINGLE_RHS) + return 1; + else if (rhs_class == GIMPLE_BINARY_RHS) + return 2; + else if (rhs_class == GIMPLE_TERNARY_RHS) + return 3; + else + gcc_unreachable (); +} + +#define DEFTREECODE(SYM, STRING, TYPE, NARGS) \ + (unsigned char) \ + ((TYPE) == tcc_unary ? GIMPLE_UNARY_RHS \ + : ((TYPE) == tcc_binary \ + || (TYPE) == tcc_comparison) ? GIMPLE_BINARY_RHS \ + : ((TYPE) == tcc_constant \ + || (TYPE) == tcc_declaration \ + || (TYPE) == tcc_reference) ? GIMPLE_SINGLE_RHS \ + : ((SYM) == TRUTH_AND_EXPR \ + || (SYM) == TRUTH_OR_EXPR \ + || (SYM) == TRUTH_XOR_EXPR) ? GIMPLE_BINARY_RHS \ + : (SYM) == TRUTH_NOT_EXPR ? GIMPLE_UNARY_RHS \ + : ((SYM) == WIDEN_MULT_PLUS_EXPR \ + || (SYM) == WIDEN_MULT_MINUS_EXPR \ + || (SYM) == FMA_EXPR) ? GIMPLE_TERNARY_RHS \ + : ((SYM) == COND_EXPR \ + || (SYM) == CONSTRUCTOR \ + || (SYM) == OBJ_TYPE_REF \ + || (SYM) == ASSERT_EXPR \ + || (SYM) == ADDR_EXPR \ + || (SYM) == WITH_SIZE_EXPR \ + || (SYM) == SSA_NAME \ + || (SYM) == POLYNOMIAL_CHREC \ + || (SYM) == DOT_PROD_EXPR \ + || (SYM) == VEC_COND_EXPR \ + || (SYM) == REALIGN_LOAD_EXPR) ? GIMPLE_SINGLE_RHS \ + : GIMPLE_INVALID_RHS), +#define END_OF_BASE_TREE_CODES (unsigned char) GIMPLE_INVALID_RHS, + +const unsigned char gimple_rhs_class_table[] = { +#include "all-tree.def" +}; + +#undef DEFTREECODE +#undef END_OF_BASE_TREE_CODES + +/* For the definitive definition of GIMPLE, see doc/tree-ssa.texi. */ + +/* Validation of GIMPLE expressions. */ + +/* Returns true iff T is a valid RHS for an assignment to a renamed + user -- or front-end generated artificial -- variable. */ + +bool +is_gimple_reg_rhs (tree t) +{ + return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS; +} + +/* Returns true iff T is a valid RHS for an assignment to an un-renamed + LHS, or for a call argument. */ + +bool +is_gimple_mem_rhs (tree t) +{ + /* If we're dealing with a renamable type, either source or dest must be + a renamed variable. */ + if (is_gimple_reg_type (TREE_TYPE (t))) + return is_gimple_val (t); + else + return is_gimple_val (t) || is_gimple_lvalue (t); +} + +/* Return true if T is a valid LHS for a GIMPLE assignment expression. */ + +bool +is_gimple_lvalue (tree t) +{ + return (is_gimple_addressable (t) + || TREE_CODE (t) == WITH_SIZE_EXPR + /* These are complex lvalues, but don't have addresses, so they + go here. */ + || TREE_CODE (t) == BIT_FIELD_REF); +} + +/* Return true if T is a GIMPLE condition. */ + +bool +is_gimple_condexpr (tree t) +{ + return (is_gimple_val (t) || (COMPARISON_CLASS_P (t) + && !tree_could_trap_p (t) + && is_gimple_val (TREE_OPERAND (t, 0)) + && is_gimple_val (TREE_OPERAND (t, 1)))); +} + +/* Return true if T is something whose address can be taken. */ + +bool +is_gimple_addressable (tree t) +{ + return (is_gimple_id (t) || handled_component_p (t) + || TREE_CODE (t) == MEM_REF); +} + +/* Return true if T is a valid gimple constant. */ + +bool +is_gimple_constant (const_tree t) +{ + switch (TREE_CODE (t)) + { + case INTEGER_CST: + case REAL_CST: + case FIXED_CST: + case STRING_CST: + case COMPLEX_CST: + case VECTOR_CST: + return true; + + /* Vector constant constructors are gimple invariant. */ + case CONSTRUCTOR: + if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) + return TREE_CONSTANT (t); + else + return false; + + default: + return false; + } +} + +/* Return true if T is a gimple address. */ + +bool +is_gimple_address (const_tree t) +{ + tree op; + + if (TREE_CODE (t) != ADDR_EXPR) + return false; + + op = TREE_OPERAND (t, 0); + while (handled_component_p (op)) + { + if ((TREE_CODE (op) == ARRAY_REF + || TREE_CODE (op) == ARRAY_RANGE_REF) + && !is_gimple_val (TREE_OPERAND (op, 1))) + return false; + + op = TREE_OPERAND (op, 0); + } + + if (CONSTANT_CLASS_P (op) || TREE_CODE (op) == MEM_REF) + return true; + + switch (TREE_CODE (op)) + { + case PARM_DECL: + case RESULT_DECL: + case LABEL_DECL: + case FUNCTION_DECL: + case VAR_DECL: + case CONST_DECL: + return true; + + default: + return false; + } +} + +/* Strip out all handled components that produce invariant + offsets. */ + +static const_tree +strip_invariant_refs (const_tree op) +{ + while (handled_component_p (op)) + { + switch (TREE_CODE (op)) + { + case ARRAY_REF: + case ARRAY_RANGE_REF: + if (!is_gimple_constant (TREE_OPERAND (op, 1)) + || TREE_OPERAND (op, 2) != NULL_TREE + || TREE_OPERAND (op, 3) != NULL_TREE) + return NULL; + break; + + case COMPONENT_REF: + if (TREE_OPERAND (op, 2) != NULL_TREE) + return NULL; + break; + + default:; + } + op = TREE_OPERAND (op, 0); + } + + return op; +} + +/* Return true if T is a gimple invariant address. */ + +bool +is_gimple_invariant_address (const_tree t) +{ + const_tree op; + + if (TREE_CODE (t) != ADDR_EXPR) + return false; + + op = strip_invariant_refs (TREE_OPERAND (t, 0)); + if (!op) + return false; + + if (TREE_CODE (op) == MEM_REF) + { + const_tree op0 = TREE_OPERAND (op, 0); + return (TREE_CODE (op0) == ADDR_EXPR + && (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)) + || decl_address_invariant_p (TREE_OPERAND (op0, 0)))); + } + + return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op); +} + +/* Return true if T is a gimple invariant address at IPA level + (so addresses of variables on stack are not allowed). */ + +bool +is_gimple_ip_invariant_address (const_tree t) +{ + const_tree op; + + if (TREE_CODE (t) != ADDR_EXPR) + return false; + + op = strip_invariant_refs (TREE_OPERAND (t, 0)); + + return op && (CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op)); +} + +/* Return true if T is a GIMPLE minimal invariant. It's a restricted + form of function invariant. */ + +bool +is_gimple_min_invariant (const_tree t) +{ + if (TREE_CODE (t) == ADDR_EXPR) + return is_gimple_invariant_address (t); + + return is_gimple_constant (t); +} + +/* Return true if T is a GIMPLE interprocedural invariant. It's a restricted + form of gimple minimal invariant. */ + +bool +is_gimple_ip_invariant (const_tree t) +{ + if (TREE_CODE (t) == ADDR_EXPR) + return is_gimple_ip_invariant_address (t); + + return is_gimple_constant (t); +} + +/* Return true if T looks like a valid GIMPLE statement. */ + +bool +is_gimple_stmt (tree t) +{ + const enum tree_code code = TREE_CODE (t); + + switch (code) + { + case NOP_EXPR: + /* The only valid NOP_EXPR is the empty statement. */ + return IS_EMPTY_STMT (t); + + case BIND_EXPR: + case COND_EXPR: + /* These are only valid if they're void. */ + return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t)); + + case SWITCH_EXPR: + case GOTO_EXPR: + case RETURN_EXPR: + case LABEL_EXPR: + case CASE_LABEL_EXPR: + case TRY_CATCH_EXPR: + case TRY_FINALLY_EXPR: + case EH_FILTER_EXPR: + case CATCH_EXPR: + case ASM_EXPR: + case STATEMENT_LIST: + case OMP_PARALLEL: + case OMP_FOR: + case OMP_SECTIONS: + case OMP_SECTION: + case OMP_SINGLE: + case OMP_MASTER: + case OMP_ORDERED: + case OMP_CRITICAL: + case OMP_TASK: + /* These are always void. */ + return true; + + case CALL_EXPR: + case MODIFY_EXPR: + case PREDICT_EXPR: + /* These are valid regardless of their type. */ + return true; + + default: + return false; + } +} + +/* Return true if T is a variable. */ + +bool +is_gimple_variable (tree t) +{ + return (TREE_CODE (t) == VAR_DECL + || TREE_CODE (t) == PARM_DECL + || TREE_CODE (t) == RESULT_DECL + || TREE_CODE (t) == SSA_NAME); +} + +/* Return true if T is a GIMPLE identifier (something with an address). */ + +bool +is_gimple_id (tree t) +{ + return (is_gimple_variable (t) + || TREE_CODE (t) == FUNCTION_DECL + || TREE_CODE (t) == LABEL_DECL + || TREE_CODE (t) == CONST_DECL + /* Allow string constants, since they are addressable. */ + || TREE_CODE (t) == STRING_CST); +} + +/* Return true if TYPE is a suitable type for a scalar register variable. */ + +bool +is_gimple_reg_type (tree type) +{ + return !AGGREGATE_TYPE_P (type); +} + +/* Return true if T is a non-aggregate register variable. */ + +bool +is_gimple_reg (tree t) +{ + if (TREE_CODE (t) == SSA_NAME) + t = SSA_NAME_VAR (t); + + if (!is_gimple_variable (t)) + return false; + + if (!is_gimple_reg_type (TREE_TYPE (t))) + return false; + + /* A volatile decl is not acceptable because we can't reuse it as + needed. We need to copy it into a temp first. */ + if (TREE_THIS_VOLATILE (t)) + return false; + + /* We define "registers" as things that can be renamed as needed, + which with our infrastructure does not apply to memory. */ + if (needs_to_live_in_memory (t)) + return false; + + /* Hard register variables are an interesting case. For those that + are call-clobbered, we don't know where all the calls are, since + we don't (want to) take into account which operations will turn + into libcalls at the rtl level. For those that are call-saved, + we don't currently model the fact that calls may in fact change + global hard registers, nor do we examine ASM_CLOBBERS at the tree + level, and so miss variable changes that might imply. All around, + it seems safest to not do too much optimization with these at the + tree level at all. We'll have to rely on the rtl optimizers to + clean this up, as there we've got all the appropriate bits exposed. */ + if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)) + return false; + + /* Complex and vector values must have been put into SSA-like form. + That is, no assignments to the individual components. */ + if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE + || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) + return DECL_GIMPLE_REG_P (t); + + return true; +} + + +/* Return true if T is a GIMPLE variable whose address is not needed. */ + +bool +is_gimple_non_addressable (tree t) +{ + if (TREE_CODE (t) == SSA_NAME) + t = SSA_NAME_VAR (t); + + return (is_gimple_variable (t) && ! needs_to_live_in_memory (t)); +} + +/* Return true if T is a GIMPLE rvalue, i.e. an identifier or a constant. */ + +bool +is_gimple_val (tree t) +{ + /* Make loads from volatiles and memory vars explicit. */ + if (is_gimple_variable (t) + && is_gimple_reg_type (TREE_TYPE (t)) + && !is_gimple_reg (t)) + return false; + + return (is_gimple_variable (t) || is_gimple_min_invariant (t)); +} + +/* Similarly, but accept hard registers as inputs to asm statements. */ + +bool +is_gimple_asm_val (tree t) +{ + if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)) + return true; + + return is_gimple_val (t); +} + +/* Return true if T is a GIMPLE minimal lvalue. */ + +bool +is_gimple_min_lval (tree t) +{ + if (!(t = CONST_CAST_TREE (strip_invariant_refs (t)))) + return false; + return (is_gimple_id (t) || TREE_CODE (t) == MEM_REF); +} + +/* Return true if T is a valid function operand of a CALL_EXPR. */ + +bool +is_gimple_call_addr (tree t) +{ + return (TREE_CODE (t) == OBJ_TYPE_REF || is_gimple_val (t)); +} + +/* Return true if T is a valid address operand of a MEM_REF. */ + +bool +is_gimple_mem_ref_addr (tree t) +{ + return (is_gimple_reg (t) + || TREE_CODE (t) == INTEGER_CST + || (TREE_CODE (t) == ADDR_EXPR + && (CONSTANT_CLASS_P (TREE_OPERAND (t, 0)) + || decl_address_invariant_p (TREE_OPERAND (t, 0))))); +} + +/* If T makes a function call, return the corresponding CALL_EXPR operand. + Otherwise, return NULL_TREE. */ + +tree +get_call_expr_in (tree t) +{ + if (TREE_CODE (t) == MODIFY_EXPR) + t = TREE_OPERAND (t, 1); + if (TREE_CODE (t) == WITH_SIZE_EXPR) + t = TREE_OPERAND (t, 0); + if (TREE_CODE (t) == CALL_EXPR) + return t; + return NULL_TREE; +} + + +/* Given a memory reference expression T, return its base address. + The base address of a memory reference expression is the main + object being referenced. For instance, the base address for + 'array[i].fld[j]' is 'array'. You can think of this as stripping + away the offset part from a memory address. + + This function calls handled_component_p to strip away all the inner + parts of the memory reference until it reaches the base object. */ + +tree +get_base_address (tree t) +{ + while (handled_component_p (t)) + t = TREE_OPERAND (t, 0); + + if ((TREE_CODE (t) == MEM_REF + || TREE_CODE (t) == TARGET_MEM_REF) + && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR) + t = TREE_OPERAND (TREE_OPERAND (t, 0), 0); + + if (TREE_CODE (t) == SSA_NAME + || DECL_P (t) + || TREE_CODE (t) == STRING_CST + || TREE_CODE (t) == CONSTRUCTOR + || INDIRECT_REF_P (t) + || TREE_CODE (t) == MEM_REF + || TREE_CODE (t) == TARGET_MEM_REF) + return t; + else + return NULL_TREE; +} + +void +recalculate_side_effects (tree t) +{ + enum tree_code code = TREE_CODE (t); + int len = TREE_OPERAND_LENGTH (t); + int i; + + switch (TREE_CODE_CLASS (code)) + { + case tcc_expression: + switch (code) + { + case INIT_EXPR: + case MODIFY_EXPR: + case VA_ARG_EXPR: + case PREDECREMENT_EXPR: + case PREINCREMENT_EXPR: + case POSTDECREMENT_EXPR: + case POSTINCREMENT_EXPR: + /* All of these have side-effects, no matter what their + operands are. */ + return; + + default: + break; + } + /* Fall through. */ + + case tcc_comparison: /* a comparison expression */ + case tcc_unary: /* a unary arithmetic expression */ + case tcc_binary: /* a binary arithmetic expression */ + case tcc_reference: /* a reference */ + case tcc_vl_exp: /* a function call */ + TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t); + for (i = 0; i < len; ++i) + { + tree op = TREE_OPERAND (t, i); + if (op && TREE_SIDE_EFFECTS (op)) + TREE_SIDE_EFFECTS (t) = 1; + } + break; + + case tcc_constant: + /* No side-effects. */ + return; + + default: + gcc_unreachable (); + } +} + +/* Canonicalize a tree T for use in a COND_EXPR as conditional. Returns + a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if + we failed to create one. */ + +tree +canonicalize_cond_expr_cond (tree t) +{ + /* Strip conversions around boolean operations. */ + if (CONVERT_EXPR_P (t) + && truth_value_p (TREE_CODE (TREE_OPERAND (t, 0)))) + t = TREE_OPERAND (t, 0); + + /* For (bool)x use x != 0. */ + if (CONVERT_EXPR_P (t) + && TREE_CODE (TREE_TYPE (t)) == BOOLEAN_TYPE) + { + tree top0 = TREE_OPERAND (t, 0); + t = build2 (NE_EXPR, TREE_TYPE (t), + top0, build_int_cst (TREE_TYPE (top0), 0)); + } + /* For !x use x == 0. */ + else if (TREE_CODE (t) == TRUTH_NOT_EXPR) + { + tree top0 = TREE_OPERAND (t, 0); + t = build2 (EQ_EXPR, TREE_TYPE (t), + top0, build_int_cst (TREE_TYPE (top0), 0)); + } + /* For cmp ? 1 : 0 use cmp. */ + else if (TREE_CODE (t) == COND_EXPR + && COMPARISON_CLASS_P (TREE_OPERAND (t, 0)) + && integer_onep (TREE_OPERAND (t, 1)) + && integer_zerop (TREE_OPERAND (t, 2))) + { + tree top0 = TREE_OPERAND (t, 0); + t = build2 (TREE_CODE (top0), TREE_TYPE (t), + TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1)); + } + + if (is_gimple_condexpr (t)) + return t; + + return NULL_TREE; +} + +/* Build a GIMPLE_CALL identical to STMT but skipping the arguments in + the positions marked by the set ARGS_TO_SKIP. */ + +gimple +gimple_call_copy_skip_args (gimple stmt, bitmap args_to_skip) +{ + int i; + tree fn = gimple_call_fn (stmt); + int nargs = gimple_call_num_args (stmt); + VEC(tree, heap) *vargs = VEC_alloc (tree, heap, nargs); + gimple new_stmt; + + for (i = 0; i < nargs; i++) + if (!bitmap_bit_p (args_to_skip, i)) + VEC_quick_push (tree, vargs, gimple_call_arg (stmt, i)); + + new_stmt = gimple_build_call_vec (fn, vargs); + VEC_free (tree, heap, vargs); + if (gimple_call_lhs (stmt)) + gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt)); + + gimple_set_vuse (new_stmt, gimple_vuse (stmt)); + gimple_set_vdef (new_stmt, gimple_vdef (stmt)); + + gimple_set_block (new_stmt, gimple_block (stmt)); + if (gimple_has_location (stmt)) + gimple_set_location (new_stmt, gimple_location (stmt)); + gimple_call_copy_flags (new_stmt, stmt); + gimple_call_set_chain (new_stmt, gimple_call_chain (stmt)); + + gimple_set_modified (new_stmt, true); + + return new_stmt; +} + + +static hashval_t gimple_type_hash_1 (const void *, enum gtc_mode); + +/* Structure used to maintain a cache of some type pairs compared by + gimple_types_compatible_p when comparing aggregate types. There are + three possible values for SAME_P: + + -2: The pair (T1, T2) has just been inserted in the table. + 0: T1 and T2 are different types. + 1: T1 and T2 are the same type. + + The two elements in the SAME_P array are indexed by the comparison + mode gtc_mode. */ + +struct type_pair_d +{ + unsigned int uid1; + unsigned int uid2; + signed char same_p[2]; +}; +typedef struct type_pair_d *type_pair_t; + +DEF_VEC_P(type_pair_t); +DEF_VEC_ALLOC_P(type_pair_t,heap); + +/* Return a hash value for the type pair pointed-to by P. */ + +static hashval_t +type_pair_hash (const void *p) +{ + const struct type_pair_d *pair = (const struct type_pair_d *) p; + hashval_t val1 = pair->uid1; + hashval_t val2 = pair->uid2; + return (iterative_hash_hashval_t (val2, val1) + ^ iterative_hash_hashval_t (val1, val2)); +} + +/* Compare two type pairs pointed-to by P1 and P2. */ + +static int +type_pair_eq (const void *p1, const void *p2) +{ + const struct type_pair_d *pair1 = (const struct type_pair_d *) p1; + const struct type_pair_d *pair2 = (const struct type_pair_d *) p2; + return ((pair1->uid1 == pair2->uid1 && pair1->uid2 == pair2->uid2) + || (pair1->uid1 == pair2->uid2 && pair1->uid2 == pair2->uid1)); +} + +/* Lookup the pair of types T1 and T2 in *VISITED_P. Insert a new + entry if none existed. */ + +static type_pair_t +lookup_type_pair (tree t1, tree t2, htab_t *visited_p, struct obstack *ob_p) +{ + struct type_pair_d pair; + type_pair_t p; + void **slot; + + if (*visited_p == NULL) + { + *visited_p = htab_create (251, type_pair_hash, type_pair_eq, NULL); + gcc_obstack_init (ob_p); + } + + pair.uid1 = TYPE_UID (t1); + pair.uid2 = TYPE_UID (t2); + slot = htab_find_slot (*visited_p, &pair, INSERT); + + if (*slot) + p = *((type_pair_t *) slot); + else + { + p = XOBNEW (ob_p, struct type_pair_d); + p->uid1 = TYPE_UID (t1); + p->uid2 = TYPE_UID (t2); + p->same_p[0] = -2; + p->same_p[1] = -2; + *slot = (void *) p; + } + + return p; +} + +/* Per pointer state for the SCC finding. The on_sccstack flag + is not strictly required, it is true when there is no hash value + recorded for the type and false otherwise. But querying that + is slower. */ + +struct sccs +{ + unsigned int dfsnum; + unsigned int low; + bool on_sccstack; + union { + hashval_t hash; + signed char same_p; + } u; +}; + +static unsigned int next_dfs_num; +static unsigned int gtc_next_dfs_num; + + +/* GIMPLE type merging cache. A direct-mapped cache based on TYPE_UID. */ + +typedef struct GTY(()) gimple_type_leader_entry_s { + tree type; + tree leader; +} gimple_type_leader_entry; + +#define GIMPLE_TYPE_LEADER_SIZE 16381 +static GTY((length("GIMPLE_TYPE_LEADER_SIZE"))) gimple_type_leader_entry + *gimple_type_leader; + +/* Lookup an existing leader for T and return it or NULL_TREE, if + there is none in the cache. */ + +static tree +gimple_lookup_type_leader (tree t) +{ + gimple_type_leader_entry *leader; + + if (!gimple_type_leader) + return NULL_TREE; + + leader = &gimple_type_leader[TYPE_UID (t) % GIMPLE_TYPE_LEADER_SIZE]; + if (leader->type != t) + return NULL_TREE; + + return leader->leader; +} + +/* Return true if T1 and T2 have the same name. If FOR_COMPLETION_P is + true then if any type has no name return false, otherwise return + true if both types have no names. */ + +static bool +compare_type_names_p (tree t1, tree t2, bool for_completion_p) +{ + tree name1 = TYPE_NAME (t1); + tree name2 = TYPE_NAME (t2); + + /* Consider anonymous types all unique for completion. */ + if (for_completion_p + && (!name1 || !name2)) + return false; + + if (name1 && TREE_CODE (name1) == TYPE_DECL) + { + name1 = DECL_NAME (name1); + if (for_completion_p + && !name1) + return false; + } + gcc_assert (!name1 || TREE_CODE (name1) == IDENTIFIER_NODE); + + if (name2 && TREE_CODE (name2) == TYPE_DECL) + { + name2 = DECL_NAME (name2); + if (for_completion_p + && !name2) + return false; + } + gcc_assert (!name2 || TREE_CODE (name2) == IDENTIFIER_NODE); + + /* Identifiers can be compared with pointer equality rather + than a string comparison. */ + if (name1 == name2) + return true; + + return false; +} + +/* Return true if the field decls F1 and F2 are at the same offset. + + This is intended to be used on GIMPLE types only. In order to + compare GENERIC types, use fields_compatible_p instead. */ + +bool +gimple_compare_field_offset (tree f1, tree f2) +{ + if (DECL_OFFSET_ALIGN (f1) == DECL_OFFSET_ALIGN (f2)) + { + tree offset1 = DECL_FIELD_OFFSET (f1); + tree offset2 = DECL_FIELD_OFFSET (f2); + return ((offset1 == offset2 + /* Once gimplification is done, self-referential offsets are + instantiated as operand #2 of the COMPONENT_REF built for + each access and reset. Therefore, they are not relevant + anymore and fields are interchangeable provided that they + represent the same access. */ + || (TREE_CODE (offset1) == PLACEHOLDER_EXPR + && TREE_CODE (offset2) == PLACEHOLDER_EXPR + && (DECL_SIZE (f1) == DECL_SIZE (f2) + || (TREE_CODE (DECL_SIZE (f1)) == PLACEHOLDER_EXPR + && TREE_CODE (DECL_SIZE (f2)) == PLACEHOLDER_EXPR) + || operand_equal_p (DECL_SIZE (f1), DECL_SIZE (f2), 0)) + && DECL_ALIGN (f1) == DECL_ALIGN (f2)) + || operand_equal_p (offset1, offset2, 0)) + && tree_int_cst_equal (DECL_FIELD_BIT_OFFSET (f1), + DECL_FIELD_BIT_OFFSET (f2))); + } + + /* Fortran and C do not always agree on what DECL_OFFSET_ALIGN + should be, so handle differing ones specially by decomposing + the offset into a byte and bit offset manually. */ + if (host_integerp (DECL_FIELD_OFFSET (f1), 0) + && host_integerp (DECL_FIELD_OFFSET (f2), 0)) + { + unsigned HOST_WIDE_INT byte_offset1, byte_offset2; + unsigned HOST_WIDE_INT bit_offset1, bit_offset2; + bit_offset1 = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (f1)); + byte_offset1 = (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f1)) + + bit_offset1 / BITS_PER_UNIT); + bit_offset2 = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (f2)); + byte_offset2 = (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f2)) + + bit_offset2 / BITS_PER_UNIT); + if (byte_offset1 != byte_offset2) + return false; + return bit_offset1 % BITS_PER_UNIT == bit_offset2 % BITS_PER_UNIT; + } + + return false; +} + +/* If the type T1 and the type T2 are a complete and an incomplete + variant of the same type return true. */ + +static bool +gimple_compatible_complete_and_incomplete_subtype_p (tree t1, tree t2) +{ + /* If one pointer points to an incomplete type variant of + the other pointed-to type they are the same. */ + if (TREE_CODE (t1) == TREE_CODE (t2) + && RECORD_OR_UNION_TYPE_P (t1) + && (!COMPLETE_TYPE_P (t1) + || !COMPLETE_TYPE_P (t2)) + && TYPE_QUALS (t1) == TYPE_QUALS (t2) + && compare_type_names_p (TYPE_MAIN_VARIANT (t1), + TYPE_MAIN_VARIANT (t2), true)) + return true; + return false; +} + +static bool +gimple_types_compatible_p_1 (tree, tree, enum gtc_mode, type_pair_t, + VEC(type_pair_t, heap) **, + struct pointer_map_t *, struct obstack *); + +/* DFS visit the edge from the callers type pair with state *STATE to + the pair T1, T2 while operating in FOR_MERGING_P mode. + Update the merging status if it is not part of the SCC containing the + callers pair and return it. + SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done. */ + +static bool +gtc_visit (tree t1, tree t2, enum gtc_mode mode, + struct sccs *state, + VEC(type_pair_t, heap) **sccstack, + struct pointer_map_t *sccstate, + struct obstack *sccstate_obstack) +{ + struct sccs *cstate = NULL; + type_pair_t p; + void **slot; + + /* Check first for the obvious case of pointer identity. */ + if (t1 == t2) + return true; + + /* Check that we have two types to compare. */ + if (t1 == NULL_TREE || t2 == NULL_TREE) + return false; + + /* If the types have been previously registered and found equal + they still are. */ + if (mode == GTC_MERGE) + { + tree leader1 = gimple_lookup_type_leader (t1); + tree leader2 = gimple_lookup_type_leader (t2); + if (leader1 == t2 + || t1 == leader2 + || (leader1 && leader1 == leader2)) + return true; + } + else if (mode == GTC_DIAG) + { + if (TYPE_CANONICAL (t1) + && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2)) + return true; + } + + /* Can't be the same type if the types don't have the same code. */ + if (TREE_CODE (t1) != TREE_CODE (t2)) + return false; + + /* Can't be the same type if they have different CV qualifiers. */ + if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) + return false; + + /* Void types are always the same. */ + if (TREE_CODE (t1) == VOID_TYPE) + return true; + + /* Do some simple checks before doing three hashtable queries. */ + if (INTEGRAL_TYPE_P (t1) + || SCALAR_FLOAT_TYPE_P (t1) + || FIXED_POINT_TYPE_P (t1) + || TREE_CODE (t1) == VECTOR_TYPE + || TREE_CODE (t1) == COMPLEX_TYPE + || TREE_CODE (t1) == OFFSET_TYPE) + { + /* Can't be the same type if they have different alignment, + sign, precision or mode. */ + if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) + || TYPE_PRECISION (t1) != TYPE_PRECISION (t2) + || TYPE_MODE (t1) != TYPE_MODE (t2) + || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) + return false; + + if (TREE_CODE (t1) == INTEGER_TYPE + && (TYPE_IS_SIZETYPE (t1) != TYPE_IS_SIZETYPE (t2) + || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2))) + return false; + + /* That's all we need to check for float and fixed-point types. */ + if (SCALAR_FLOAT_TYPE_P (t1) + || FIXED_POINT_TYPE_P (t1)) + return true; + + /* For integral types fall thru to more complex checks. */ + } + + else if (AGGREGATE_TYPE_P (t1) || POINTER_TYPE_P (t1)) + { + /* Can't be the same type if they have different alignment or mode. */ + if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) + || TYPE_MODE (t1) != TYPE_MODE (t2)) + return false; + } + + /* If the hash values of t1 and t2 are different the types can't + possibly be the same. This helps keeping the type-pair hashtable + small, only tracking comparisons for hash collisions. */ + if (gimple_type_hash_1 (t1, mode) != gimple_type_hash_1 (t2, mode)) + return false; + + /* Allocate a new cache entry for this comparison. */ + p = lookup_type_pair (t1, t2, >c_visited, >c_ob); + if (p->same_p[mode] == 0 || p->same_p[mode] == 1) + { + /* We have already decided whether T1 and T2 are the + same, return the cached result. */ + return p->same_p[mode] == 1; + } + + if ((slot = pointer_map_contains (sccstate, p)) != NULL) + cstate = (struct sccs *)*slot; + /* Not yet visited. DFS recurse. */ + if (!cstate) + { + gimple_types_compatible_p_1 (t1, t2, mode, p, + sccstack, sccstate, sccstate_obstack); + cstate = (struct sccs *)* pointer_map_contains (sccstate, p); + state->low = MIN (state->low, cstate->low); + } + /* If the type is still on the SCC stack adjust the parents low. */ + if (cstate->dfsnum < state->dfsnum + && cstate->on_sccstack) + state->low = MIN (cstate->dfsnum, state->low); + + /* Return the current lattice value. We start with an equality + assumption so types part of a SCC will be optimistically + treated equal unless proven otherwise. */ + return cstate->u.same_p; +} + +/* Worker for gimple_types_compatible. + SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done. */ + +static bool +gimple_types_compatible_p_1 (tree t1, tree t2, enum gtc_mode mode, + type_pair_t p, + VEC(type_pair_t, heap) **sccstack, + struct pointer_map_t *sccstate, + struct obstack *sccstate_obstack) +{ + struct sccs *state; + + gcc_assert (p->same_p[mode] == -2); + + state = XOBNEW (sccstate_obstack, struct sccs); + *pointer_map_insert (sccstate, p) = state; + + VEC_safe_push (type_pair_t, heap, *sccstack, p); + state->dfsnum = gtc_next_dfs_num++; + state->low = state->dfsnum; + state->on_sccstack = true; + /* Start with an equality assumption. As we DFS recurse into child + SCCs this assumption may get revisited. */ + state->u.same_p = 1; + + /* If their attributes are not the same they can't be the same type. */ + if (!attribute_list_equal (TYPE_ATTRIBUTES (t1), TYPE_ATTRIBUTES (t2))) + goto different_types; + + /* Do type-specific comparisons. */ + switch (TREE_CODE (t1)) + { + case VECTOR_TYPE: + case COMPLEX_TYPE: + if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode, + state, sccstack, sccstate, sccstate_obstack)) + goto different_types; + goto same_types; + + case ARRAY_TYPE: + /* Array types are the same if the element types are the same and + the number of elements are the same. */ + if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode, + state, sccstack, sccstate, sccstate_obstack) + || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2) + || TYPE_NONALIASED_COMPONENT (t1) != TYPE_NONALIASED_COMPONENT (t2)) + goto different_types; + else + { + tree i1 = TYPE_DOMAIN (t1); + tree i2 = TYPE_DOMAIN (t2); + + /* For an incomplete external array, the type domain can be + NULL_TREE. Check this condition also. */ + if (i1 == NULL_TREE && i2 == NULL_TREE) + goto same_types; + else if (i1 == NULL_TREE || i2 == NULL_TREE) + goto different_types; + /* If for a complete array type the possibly gimplified sizes + are different the types are different. */ + else if (((TYPE_SIZE (i1) != NULL) ^ (TYPE_SIZE (i2) != NULL)) + || (TYPE_SIZE (i1) + && TYPE_SIZE (i2) + && !operand_equal_p (TYPE_SIZE (i1), TYPE_SIZE (i2), 0))) + goto different_types; + else + { + tree min1 = TYPE_MIN_VALUE (i1); + tree min2 = TYPE_MIN_VALUE (i2); + tree max1 = TYPE_MAX_VALUE (i1); + tree max2 = TYPE_MAX_VALUE (i2); + + /* The minimum/maximum values have to be the same. */ + if ((min1 == min2 + || (min1 && min2 + && ((TREE_CODE (min1) == PLACEHOLDER_EXPR + && TREE_CODE (min2) == PLACEHOLDER_EXPR) + || operand_equal_p (min1, min2, 0)))) + && (max1 == max2 + || (max1 && max2 + && ((TREE_CODE (max1) == PLACEHOLDER_EXPR + && TREE_CODE (max2) == PLACEHOLDER_EXPR) + || operand_equal_p (max1, max2, 0))))) + goto same_types; + else + goto different_types; + } + } + + case METHOD_TYPE: + /* Method types should belong to the same class. */ + if (!gtc_visit (TYPE_METHOD_BASETYPE (t1), TYPE_METHOD_BASETYPE (t2), + mode, state, sccstack, sccstate, sccstate_obstack)) + goto different_types; + + /* Fallthru */ + + case FUNCTION_TYPE: + /* Function types are the same if the return type and arguments types + are the same. */ + if ((mode != GTC_DIAG + || !gimple_compatible_complete_and_incomplete_subtype_p + (TREE_TYPE (t1), TREE_TYPE (t2))) + && !gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode, + state, sccstack, sccstate, sccstate_obstack)) + goto different_types; + + if (!targetm.comp_type_attributes (t1, t2)) + goto different_types; + + if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2)) + goto same_types; + else + { + tree parms1, parms2; + + for (parms1 = TYPE_ARG_TYPES (t1), parms2 = TYPE_ARG_TYPES (t2); + parms1 && parms2; + parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2)) + { + if ((mode == GTC_MERGE + || !gimple_compatible_complete_and_incomplete_subtype_p + (TREE_VALUE (parms1), TREE_VALUE (parms2))) + && !gtc_visit (TREE_VALUE (parms1), TREE_VALUE (parms2), mode, + state, sccstack, sccstate, sccstate_obstack)) + goto different_types; + } + + if (parms1 || parms2) + goto different_types; + + goto same_types; + } + + case OFFSET_TYPE: + { + if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode, + state, sccstack, sccstate, sccstate_obstack) + || !gtc_visit (TYPE_OFFSET_BASETYPE (t1), + TYPE_OFFSET_BASETYPE (t2), mode, + state, sccstack, sccstate, sccstate_obstack)) + goto different_types; + + goto same_types; + } + + case POINTER_TYPE: + case REFERENCE_TYPE: + { + /* If the two pointers have different ref-all attributes, + they can't be the same type. */ + if (TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2)) + goto different_types; + + /* If one pointer points to an incomplete type variant of + the other pointed-to type they are the same. */ + if (mode == GTC_DIAG + && gimple_compatible_complete_and_incomplete_subtype_p + (TREE_TYPE (t1), TREE_TYPE (t2))) + goto same_types; + + /* Otherwise, pointer and reference types are the same if the + pointed-to types are the same. */ + if (gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode, + state, sccstack, sccstate, sccstate_obstack)) + goto same_types; + + goto different_types; + } + + case NULLPTR_TYPE: + /* There is only one decltype(nullptr). */ + goto same_types; + + case INTEGER_TYPE: + case BOOLEAN_TYPE: + { + tree min1 = TYPE_MIN_VALUE (t1); + tree max1 = TYPE_MAX_VALUE (t1); + tree min2 = TYPE_MIN_VALUE (t2); + tree max2 = TYPE_MAX_VALUE (t2); + bool min_equal_p = false; + bool max_equal_p = false; + + /* If either type has a minimum value, the other type must + have the same. */ + if (min1 == NULL_TREE && min2 == NULL_TREE) + min_equal_p = true; + else if (min1 && min2 && operand_equal_p (min1, min2, 0)) + min_equal_p = true; + + /* Likewise, if either type has a maximum value, the other + type must have the same. */ + if (max1 == NULL_TREE && max2 == NULL_TREE) + max_equal_p = true; + else if (max1 && max2 && operand_equal_p (max1, max2, 0)) + max_equal_p = true; + + if (!min_equal_p || !max_equal_p) + goto different_types; + + goto same_types; + } + + case ENUMERAL_TYPE: + { + /* FIXME lto, we cannot check bounds on enumeral types because + different front ends will produce different values. + In C, enumeral types are integers, while in C++ each element + will have its own symbolic value. We should decide how enums + are to be represented in GIMPLE and have each front end lower + to that. */ + tree v1, v2; + + /* For enumeral types, all the values must be the same. */ + if (TYPE_VALUES (t1) == TYPE_VALUES (t2)) + goto same_types; + + for (v1 = TYPE_VALUES (t1), v2 = TYPE_VALUES (t2); + v1 && v2; + v1 = TREE_CHAIN (v1), v2 = TREE_CHAIN (v2)) + { + tree c1 = TREE_VALUE (v1); + tree c2 = TREE_VALUE (v2); + + if (TREE_CODE (c1) == CONST_DECL) + c1 = DECL_INITIAL (c1); + + if (TREE_CODE (c2) == CONST_DECL) + c2 = DECL_INITIAL (c2); + + if (tree_int_cst_equal (c1, c2) != 1) + goto different_types; + } + + /* If one enumeration has more values than the other, they + are not the same. */ + if (v1 || v2) + goto different_types; + + goto same_types; + } + + case RECORD_TYPE: + case UNION_TYPE: + case QUAL_UNION_TYPE: + { + tree f1, f2; + + /* The struct tags shall compare equal. */ + if (mode == GTC_MERGE + && !compare_type_names_p (TYPE_MAIN_VARIANT (t1), + TYPE_MAIN_VARIANT (t2), false)) + goto different_types; + + /* For aggregate types, all the fields must be the same. */ + for (f1 = TYPE_FIELDS (t1), f2 = TYPE_FIELDS (t2); + f1 && f2; + f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2)) + { + /* The fields must have the same name, offset and type. */ + if ((mode == GTC_MERGE + && DECL_NAME (f1) != DECL_NAME (f2)) + || DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2) + || !gimple_compare_field_offset (f1, f2) + || !gtc_visit (TREE_TYPE (f1), TREE_TYPE (f2), mode, + state, sccstack, sccstate, sccstate_obstack)) + goto different_types; + } + + /* If one aggregate has more fields than the other, they + are not the same. */ + if (f1 || f2) + goto different_types; + + goto same_types; + } + + default: + gcc_unreachable (); + } + + /* Common exit path for types that are not compatible. */ +different_types: + state->u.same_p = 0; + goto pop; + + /* Common exit path for types that are compatible. */ +same_types: + gcc_assert (state->u.same_p == 1); + +pop: + if (state->low == state->dfsnum) + { + type_pair_t x; + + /* Pop off the SCC and set its cache values to the final + comparison result. */ + do + { + struct sccs *cstate; + x = VEC_pop (type_pair_t, *sccstack); + cstate = (struct sccs *)*pointer_map_contains (sccstate, x); + cstate->on_sccstack = false; + x->same_p[mode] = state->u.same_p; + } + while (x != p); + } + + return state->u.same_p; +} + +/* Return true iff T1 and T2 are structurally identical. When + FOR_MERGING_P is true the an incomplete type and a complete type + are considered different, otherwise they are considered compatible. */ + +bool +gimple_types_compatible_p (tree t1, tree t2, enum gtc_mode mode) +{ + VEC(type_pair_t, heap) *sccstack = NULL; + struct pointer_map_t *sccstate; + struct obstack sccstate_obstack; + type_pair_t p = NULL; + bool res; + + /* Before starting to set up the SCC machinery handle simple cases. */ + + /* Check first for the obvious case of pointer identity. */ + if (t1 == t2) + return true; + + /* Check that we have two types to compare. */ + if (t1 == NULL_TREE || t2 == NULL_TREE) + return false; + + /* If the types have been previously registered and found equal + they still are. */ + if (mode == GTC_MERGE) + { + tree leader1 = gimple_lookup_type_leader (t1); + tree leader2 = gimple_lookup_type_leader (t2); + if (leader1 == t2 + || t1 == leader2 + || (leader1 && leader1 == leader2)) + return true; + } + else if (mode == GTC_DIAG) + { + if (TYPE_CANONICAL (t1) + && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2)) + return true; + } + + /* Can't be the same type if the types don't have the same code. */ + if (TREE_CODE (t1) != TREE_CODE (t2)) + return false; + + /* Can't be the same type if they have different CV qualifiers. */ + if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) + return false; + + /* Void types are always the same. */ + if (TREE_CODE (t1) == VOID_TYPE) + return true; + + /* Do some simple checks before doing three hashtable queries. */ + if (INTEGRAL_TYPE_P (t1) + || SCALAR_FLOAT_TYPE_P (t1) + || FIXED_POINT_TYPE_P (t1) + || TREE_CODE (t1) == VECTOR_TYPE + || TREE_CODE (t1) == COMPLEX_TYPE + || TREE_CODE (t1) == OFFSET_TYPE) + { + /* Can't be the same type if they have different alignment, + sign, precision or mode. */ + if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) + || TYPE_PRECISION (t1) != TYPE_PRECISION (t2) + || TYPE_MODE (t1) != TYPE_MODE (t2) + || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) + return false; + + if (TREE_CODE (t1) == INTEGER_TYPE + && (TYPE_IS_SIZETYPE (t1) != TYPE_IS_SIZETYPE (t2) + || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2))) + return false; + + /* That's all we need to check for float and fixed-point types. */ + if (SCALAR_FLOAT_TYPE_P (t1) + || FIXED_POINT_TYPE_P (t1)) + return true; + + /* For integral types fall thru to more complex checks. */ + } + + else if (AGGREGATE_TYPE_P (t1) || POINTER_TYPE_P (t1)) + { + /* Can't be the same type if they have different alignment or mode. */ + if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) + || TYPE_MODE (t1) != TYPE_MODE (t2)) + return false; + } + + /* If the hash values of t1 and t2 are different the types can't + possibly be the same. This helps keeping the type-pair hashtable + small, only tracking comparisons for hash collisions. */ + if (gimple_type_hash_1 (t1, mode) != gimple_type_hash_1 (t2, mode)) + return false; + + /* If we've visited this type pair before (in the case of aggregates + with self-referential types), and we made a decision, return it. */ + p = lookup_type_pair (t1, t2, >c_visited, >c_ob); + if (p->same_p[mode] == 0 || p->same_p[mode] == 1) + { + /* We have already decided whether T1 and T2 are the + same, return the cached result. */ + return p->same_p[mode] == 1; + } + + /* Now set up the SCC machinery for the comparison. */ + gtc_next_dfs_num = 1; + sccstate = pointer_map_create (); + gcc_obstack_init (&sccstate_obstack); + res = gimple_types_compatible_p_1 (t1, t2, mode, p, + &sccstack, sccstate, &sccstate_obstack); + VEC_free (type_pair_t, heap, sccstack); + pointer_map_destroy (sccstate); + obstack_free (&sccstate_obstack, NULL); + + return res; +} + + +static hashval_t +iterative_hash_gimple_type (tree, hashval_t, VEC(tree, heap) **, + struct pointer_map_t *, struct obstack *, + enum gtc_mode); + +/* DFS visit the edge from the callers type with state *STATE to T. + Update the callers type hash V with the hash for T if it is not part + of the SCC containing the callers type and return it. + SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done. */ + +static hashval_t +visit (tree t, struct sccs *state, hashval_t v, + VEC (tree, heap) **sccstack, + struct pointer_map_t *sccstate, + struct obstack *sccstate_obstack, enum gtc_mode mode) +{ + struct sccs *cstate = NULL; + struct tree_int_map m; + void **slot; + + /* If there is a hash value recorded for this type then it can't + possibly be part of our parent SCC. Simply mix in its hash. */ + m.base.from = t; + if ((slot = htab_find_slot (mode == GTC_MERGE + ? type_hash_cache : canonical_type_hash_cache, + &m, NO_INSERT)) + && *slot) + return iterative_hash_hashval_t (((struct tree_int_map *) *slot)->to, v); + + if ((slot = pointer_map_contains (sccstate, t)) != NULL) + cstate = (struct sccs *)*slot; + if (!cstate) + { + hashval_t tem; + /* Not yet visited. DFS recurse. */ + tem = iterative_hash_gimple_type (t, v, + sccstack, sccstate, sccstate_obstack, + mode); + if (!cstate) + cstate = (struct sccs *)* pointer_map_contains (sccstate, t); + state->low = MIN (state->low, cstate->low); + /* If the type is no longer on the SCC stack and thus is not part + of the parents SCC mix in its hash value. Otherwise we will + ignore the type for hashing purposes and return the unaltered + hash value. */ + if (!cstate->on_sccstack) + return tem; + } + if (cstate->dfsnum < state->dfsnum + && cstate->on_sccstack) + state->low = MIN (cstate->dfsnum, state->low); + + /* We are part of our parents SCC, skip this type during hashing + and return the unaltered hash value. */ + return v; +} + +/* Hash NAME with the previous hash value V and return it. */ + +static hashval_t +iterative_hash_name (tree name, hashval_t v) +{ + if (!name) + return v; + if (TREE_CODE (name) == TYPE_DECL) + name = DECL_NAME (name); + if (!name) + return v; + gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); + return iterative_hash_object (IDENTIFIER_HASH_VALUE (name), v); +} + +/* Returning a hash value for gimple type TYPE combined with VAL. + SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done. + + To hash a type we end up hashing in types that are reachable. + Through pointers we can end up with cycles which messes up the + required property that we need to compute the same hash value + for structurally equivalent types. To avoid this we have to + hash all types in a cycle (the SCC) in a commutative way. The + easiest way is to not mix in the hashes of the SCC members at + all. To make this work we have to delay setting the hash + values of the SCC until it is complete. */ + +static hashval_t +iterative_hash_gimple_type (tree type, hashval_t val, + VEC(tree, heap) **sccstack, + struct pointer_map_t *sccstate, + struct obstack *sccstate_obstack, + enum gtc_mode mode) +{ + hashval_t v; + void **slot; + struct sccs *state; + + /* Not visited during this DFS walk. */ + gcc_checking_assert (!pointer_map_contains (sccstate, type)); + state = XOBNEW (sccstate_obstack, struct sccs); + *pointer_map_insert (sccstate, type) = state; + + VEC_safe_push (tree, heap, *sccstack, type); + state->dfsnum = next_dfs_num++; + state->low = state->dfsnum; + state->on_sccstack = true; + + /* Combine a few common features of types so that types are grouped into + smaller sets; when searching for existing matching types to merge, + only existing types having the same features as the new type will be + checked. */ + v = iterative_hash_hashval_t (TREE_CODE (type), 0); + v = iterative_hash_hashval_t (TYPE_QUALS (type), v); + v = iterative_hash_hashval_t (TREE_ADDRESSABLE (type), v); + + /* Do not hash the types size as this will cause differences in + hash values for the complete vs. the incomplete type variant. */ + + /* Incorporate common features of numerical types. */ + if (INTEGRAL_TYPE_P (type) + || SCALAR_FLOAT_TYPE_P (type) + || FIXED_POINT_TYPE_P (type)) + { + v = iterative_hash_hashval_t (TYPE_PRECISION (type), v); + v = iterative_hash_hashval_t (TYPE_MODE (type), v); + v = iterative_hash_hashval_t (TYPE_UNSIGNED (type), v); + } + + /* For pointer and reference types, fold in information about the type + pointed to but do not recurse into possibly incomplete types to + avoid hash differences for complete vs. incomplete types. */ + if (POINTER_TYPE_P (type)) + { + if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type))) + { + v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v); + v = iterative_hash_name + (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (type))), v); + } + else + v = visit (TREE_TYPE (type), state, v, + sccstack, sccstate, sccstate_obstack, mode); + } + + /* For integer types hash the types min/max values and the string flag. */ + if (TREE_CODE (type) == INTEGER_TYPE) + { + /* OMP lowering can introduce error_mark_node in place of + random local decls in types. */ + if (TYPE_MIN_VALUE (type) != error_mark_node) + v = iterative_hash_expr (TYPE_MIN_VALUE (type), v); + if (TYPE_MAX_VALUE (type) != error_mark_node) + v = iterative_hash_expr (TYPE_MAX_VALUE (type), v); + v = iterative_hash_hashval_t (TYPE_STRING_FLAG (type), v); + } + + /* For array types hash their domain and the string flag. */ + if (TREE_CODE (type) == ARRAY_TYPE + && TYPE_DOMAIN (type)) + { + v = iterative_hash_hashval_t (TYPE_STRING_FLAG (type), v); + v = visit (TYPE_DOMAIN (type), state, v, + sccstack, sccstate, sccstate_obstack, mode); + } + + /* Recurse for aggregates with a single element type. */ + if (TREE_CODE (type) == ARRAY_TYPE + || TREE_CODE (type) == COMPLEX_TYPE + || TREE_CODE (type) == VECTOR_TYPE) + v = visit (TREE_TYPE (type), state, v, + sccstack, sccstate, sccstate_obstack, mode); + + /* Incorporate function return and argument types. */ + if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) + { + unsigned na; + tree p; + + /* For method types also incorporate their parent class. */ + if (TREE_CODE (type) == METHOD_TYPE) + v = visit (TYPE_METHOD_BASETYPE (type), state, v, + sccstack, sccstate, sccstate_obstack, mode); + + /* For result types allow mismatch in completeness. */ + if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type))) + { + v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v); + v = iterative_hash_name + (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (type))), v); + } + else + v = visit (TREE_TYPE (type), state, v, + sccstack, sccstate, sccstate_obstack, mode); + + for (p = TYPE_ARG_TYPES (type), na = 0; p; p = TREE_CHAIN (p)) + { + /* For argument types allow mismatch in completeness. */ + if (RECORD_OR_UNION_TYPE_P (TREE_VALUE (p))) + { + v = iterative_hash_hashval_t (TREE_CODE (TREE_VALUE (p)), v); + v = iterative_hash_name + (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_VALUE (p))), v); + } + else + v = visit (TREE_VALUE (p), state, v, + sccstack, sccstate, sccstate_obstack, mode); + na++; + } + + v = iterative_hash_hashval_t (na, v); + } + + if (TREE_CODE (type) == RECORD_TYPE + || TREE_CODE (type) == UNION_TYPE + || TREE_CODE (type) == QUAL_UNION_TYPE) + { + unsigned nf; + tree f; + + if (mode == GTC_MERGE) + v = iterative_hash_name (TYPE_NAME (TYPE_MAIN_VARIANT (type)), v); + + for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f)) + { + if (mode == GTC_MERGE) + v = iterative_hash_name (DECL_NAME (f), v); + v = visit (TREE_TYPE (f), state, v, + sccstack, sccstate, sccstate_obstack, mode); + nf++; + } + + v = iterative_hash_hashval_t (nf, v); + } + + /* Record hash for us. */ + state->u.hash = v; + + /* See if we found an SCC. */ + if (state->low == state->dfsnum) + { + tree x; + + /* Pop off the SCC and set its hash values. */ + do + { + struct sccs *cstate; + struct tree_int_map *m = ggc_alloc_cleared_tree_int_map (); + x = VEC_pop (tree, *sccstack); + cstate = (struct sccs *)*pointer_map_contains (sccstate, x); + cstate->on_sccstack = false; + m->base.from = x; + m->to = cstate->u.hash; + slot = htab_find_slot (mode == GTC_MERGE + ? type_hash_cache : canonical_type_hash_cache, + m, INSERT); + gcc_assert (!*slot); + *slot = (void *) m; + } + while (x != type); + } + + return iterative_hash_hashval_t (v, val); +} + + +/* Returns a hash value for P (assumed to be a type). The hash value + is computed using some distinguishing features of the type. Note + that we cannot use pointer hashing here as we may be dealing with + two distinct instances of the same type. + + This function should produce the same hash value for two compatible + types according to gimple_types_compatible_p. */ + +static hashval_t +gimple_type_hash_1 (const void *p, enum gtc_mode mode) +{ + const_tree t = (const_tree) p; + VEC(tree, heap) *sccstack = NULL; + struct pointer_map_t *sccstate; + struct obstack sccstate_obstack; + hashval_t val; + void **slot; + struct tree_int_map m; + + if (mode == GTC_MERGE + && type_hash_cache == NULL) + type_hash_cache = htab_create_ggc (512, tree_int_map_hash, + tree_int_map_eq, NULL); + else if (mode == GTC_DIAG + && canonical_type_hash_cache == NULL) + canonical_type_hash_cache = htab_create_ggc (512, tree_int_map_hash, + tree_int_map_eq, NULL); + + m.base.from = CONST_CAST_TREE (t); + if ((slot = htab_find_slot (mode == GTC_MERGE + ? type_hash_cache : canonical_type_hash_cache, + &m, NO_INSERT)) + && *slot) + return iterative_hash_hashval_t (((struct tree_int_map *) *slot)->to, 0); + + /* Perform a DFS walk and pre-hash all reachable types. */ + next_dfs_num = 1; + sccstate = pointer_map_create (); + gcc_obstack_init (&sccstate_obstack); + val = iterative_hash_gimple_type (CONST_CAST_TREE (t), 0, + &sccstack, sccstate, &sccstate_obstack, + mode); + VEC_free (tree, heap, sccstack); + pointer_map_destroy (sccstate); + obstack_free (&sccstate_obstack, NULL); + + return val; +} + +static hashval_t +gimple_type_hash (const void *p) +{ + return gimple_type_hash_1 (p, GTC_MERGE); +} + +static hashval_t +gimple_canonical_type_hash (const void *p) +{ + return gimple_type_hash_1 (p, GTC_DIAG); +} + + +/* Returns nonzero if P1 and P2 are equal. */ + +static int +gimple_type_eq (const void *p1, const void *p2) +{ + const_tree t1 = (const_tree) p1; + const_tree t2 = (const_tree) p2; + return gimple_types_compatible_p (CONST_CAST_TREE (t1), + CONST_CAST_TREE (t2), GTC_MERGE); +} + + +/* Register type T in the global type table gimple_types. + If another type T', compatible with T, already existed in + gimple_types then return T', otherwise return T. This is used by + LTO to merge identical types read from different TUs. */ + +tree +gimple_register_type (tree t) +{ + void **slot; + gimple_type_leader_entry *leader; + tree mv_leader = NULL_TREE; + + gcc_assert (TYPE_P (t)); + + if (!gimple_type_leader) + gimple_type_leader = ggc_alloc_cleared_vec_gimple_type_leader_entry_s + (GIMPLE_TYPE_LEADER_SIZE); + /* If we registered this type before return the cached result. */ + leader = &gimple_type_leader[TYPE_UID (t) % GIMPLE_TYPE_LEADER_SIZE]; + if (leader->type == t) + return leader->leader; + + /* Always register the main variant first. This is important so we + pick up the non-typedef variants as canonical, otherwise we'll end + up taking typedef ids for structure tags during comparison. */ + if (TYPE_MAIN_VARIANT (t) != t) + mv_leader = gimple_register_type (TYPE_MAIN_VARIANT (t)); + + if (gimple_types == NULL) + gimple_types = htab_create_ggc (16381, gimple_type_hash, gimple_type_eq, 0); + + slot = htab_find_slot (gimple_types, t, INSERT); + if (*slot + && *(tree *)slot != t) + { + tree new_type = (tree) *((tree *) slot); + + /* Do not merge types with different addressability. */ + gcc_assert (TREE_ADDRESSABLE (t) == TREE_ADDRESSABLE (new_type)); + + /* If t is not its main variant then make t unreachable from its + main variant list. Otherwise we'd queue up a lot of duplicates + there. */ + if (t != TYPE_MAIN_VARIANT (t)) + { + tree tem = TYPE_MAIN_VARIANT (t); + while (tem && TYPE_NEXT_VARIANT (tem) != t) + tem = TYPE_NEXT_VARIANT (tem); + if (tem) + TYPE_NEXT_VARIANT (tem) = TYPE_NEXT_VARIANT (t); + TYPE_NEXT_VARIANT (t) = NULL_TREE; + } + + /* If we are a pointer then remove us from the pointer-to or + reference-to chain. Otherwise we'd queue up a lot of duplicates + there. */ + if (TREE_CODE (t) == POINTER_TYPE) + { + if (TYPE_POINTER_TO (TREE_TYPE (t)) == t) + TYPE_POINTER_TO (TREE_TYPE (t)) = TYPE_NEXT_PTR_TO (t); + else + { + tree tem = TYPE_POINTER_TO (TREE_TYPE (t)); + while (tem && TYPE_NEXT_PTR_TO (tem) != t) + tem = TYPE_NEXT_PTR_TO (tem); + if (tem) + TYPE_NEXT_PTR_TO (tem) = TYPE_NEXT_PTR_TO (t); + } + TYPE_NEXT_PTR_TO (t) = NULL_TREE; + } + else if (TREE_CODE (t) == REFERENCE_TYPE) + { + if (TYPE_REFERENCE_TO (TREE_TYPE (t)) == t) + TYPE_REFERENCE_TO (TREE_TYPE (t)) = TYPE_NEXT_REF_TO (t); + else + { + tree tem = TYPE_REFERENCE_TO (TREE_TYPE (t)); + while (tem && TYPE_NEXT_REF_TO (tem) != t) + tem = TYPE_NEXT_REF_TO (tem); + if (tem) + TYPE_NEXT_REF_TO (tem) = TYPE_NEXT_REF_TO (t); + } + TYPE_NEXT_REF_TO (t) = NULL_TREE; + } + + leader->type = t; + leader->leader = new_type; + t = new_type; + } + else + { + leader->type = t; + leader->leader = t; + /* We're the type leader. Make our TYPE_MAIN_VARIANT valid. */ + if (TYPE_MAIN_VARIANT (t) != t + && TYPE_MAIN_VARIANT (t) != mv_leader) + { + /* Remove us from our main variant list as we are not the variant + leader and the variant leader will change. */ + tree tem = TYPE_MAIN_VARIANT (t); + while (tem && TYPE_NEXT_VARIANT (tem) != t) + tem = TYPE_NEXT_VARIANT (tem); + if (tem) + TYPE_NEXT_VARIANT (tem) = TYPE_NEXT_VARIANT (t); + TYPE_NEXT_VARIANT (t) = NULL_TREE; + /* Adjust our main variant. Linking us into its variant list + will happen at fixup time. */ + TYPE_MAIN_VARIANT (t) = mv_leader; + } + *slot = (void *) t; + } + + return t; +} + + +/* Returns nonzero if P1 and P2 are equal. */ + +static int +gimple_canonical_type_eq (const void *p1, const void *p2) +{ + const_tree t1 = (const_tree) p1; + const_tree t2 = (const_tree) p2; + return gimple_types_compatible_p (CONST_CAST_TREE (t1), + CONST_CAST_TREE (t2), GTC_DIAG); +} + +/* Register type T in the global type table gimple_types. + If another type T', compatible with T, already existed in + gimple_types then return T', otherwise return T. This is used by + LTO to merge identical types read from different TUs. */ + +tree +gimple_register_canonical_type (tree t) +{ + void **slot; + tree orig_t = t; + + gcc_assert (TYPE_P (t)); + + if (TYPE_CANONICAL (t)) + return TYPE_CANONICAL (t); + + /* Always register the type itself first so that if it turns out + to be the canonical type it will be the one we merge to as well. */ + t = gimple_register_type (t); + + /* Always register the main variant first. This is important so we + pick up the non-typedef variants as canonical, otherwise we'll end + up taking typedef ids for structure tags during comparison. */ + if (TYPE_MAIN_VARIANT (t) != t) + gimple_register_canonical_type (TYPE_MAIN_VARIANT (t)); + + if (gimple_canonical_types == NULL) + gimple_canonical_types = htab_create_ggc (16381, gimple_canonical_type_hash, + gimple_canonical_type_eq, 0); + + slot = htab_find_slot (gimple_canonical_types, t, INSERT); + if (*slot + && *(tree *)slot != t) + { + tree new_type = (tree) *((tree *) slot); + + TYPE_CANONICAL (t) = new_type; + t = new_type; + } + else + { + TYPE_CANONICAL (t) = t; + *slot = (void *) t; + } + + /* Also cache the canonical type in the non-leaders. */ + TYPE_CANONICAL (orig_t) = t; + + return t; +} + + +/* Show statistics on references to the global type table gimple_types. */ + +void +print_gimple_types_stats (void) +{ + if (gimple_types) + fprintf (stderr, "GIMPLE type table: size %ld, %ld elements, " + "%ld searches, %ld collisions (ratio: %f)\n", + (long) htab_size (gimple_types), + (long) htab_elements (gimple_types), + (long) gimple_types->searches, + (long) gimple_types->collisions, + htab_collisions (gimple_types)); + else + fprintf (stderr, "GIMPLE type table is empty\n"); + if (type_hash_cache) + fprintf (stderr, "GIMPLE type hash table: size %ld, %ld elements, " + "%ld searches, %ld collisions (ratio: %f)\n", + (long) htab_size (type_hash_cache), + (long) htab_elements (type_hash_cache), + (long) type_hash_cache->searches, + (long) type_hash_cache->collisions, + htab_collisions (type_hash_cache)); + else + fprintf (stderr, "GIMPLE type hash table is empty\n"); + if (gimple_canonical_types) + fprintf (stderr, "GIMPLE canonical type table: size %ld, %ld elements, " + "%ld searches, %ld collisions (ratio: %f)\n", + (long) htab_size (gimple_canonical_types), + (long) htab_elements (gimple_canonical_types), + (long) gimple_canonical_types->searches, + (long) gimple_canonical_types->collisions, + htab_collisions (gimple_canonical_types)); + else + fprintf (stderr, "GIMPLE canonical type table is empty\n"); + if (canonical_type_hash_cache) + fprintf (stderr, "GIMPLE canonical type hash table: size %ld, %ld elements, " + "%ld searches, %ld collisions (ratio: %f)\n", + (long) htab_size (canonical_type_hash_cache), + (long) htab_elements (canonical_type_hash_cache), + (long) canonical_type_hash_cache->searches, + (long) canonical_type_hash_cache->collisions, + htab_collisions (canonical_type_hash_cache)); + else + fprintf (stderr, "GIMPLE canonical type hash table is empty\n"); + if (gtc_visited) + fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld " + "elements, %ld searches, %ld collisions (ratio: %f)\n", + (long) htab_size (gtc_visited), + (long) htab_elements (gtc_visited), + (long) gtc_visited->searches, + (long) gtc_visited->collisions, + htab_collisions (gtc_visited)); + else + fprintf (stderr, "GIMPLE type comparison table is empty\n"); +} + +/* Free the gimple type hashtables used for LTO type merging. */ + +void +free_gimple_type_tables (void) +{ + /* Last chance to print stats for the tables. */ + if (flag_lto_report) + print_gimple_types_stats (); + + if (gimple_types) + { + htab_delete (gimple_types); + gimple_types = NULL; + } + if (gimple_canonical_types) + { + htab_delete (gimple_canonical_types); + gimple_canonical_types = NULL; + } + if (type_hash_cache) + { + htab_delete (type_hash_cache); + type_hash_cache = NULL; + } + if (canonical_type_hash_cache) + { + htab_delete (canonical_type_hash_cache); + canonical_type_hash_cache = NULL; + } + if (gtc_visited) + { + htab_delete (gtc_visited); + obstack_free (>c_ob, NULL); + gtc_visited = NULL; + } + gimple_type_leader = NULL; +} + + +/* Return a type the same as TYPE except unsigned or + signed according to UNSIGNEDP. */ + +static tree +gimple_signed_or_unsigned_type (bool unsignedp, tree type) +{ + tree type1; + + type1 = TYPE_MAIN_VARIANT (type); + if (type1 == signed_char_type_node + || type1 == char_type_node + || type1 == unsigned_char_type_node) + return unsignedp ? unsigned_char_type_node : signed_char_type_node; + if (type1 == integer_type_node || type1 == unsigned_type_node) + return unsignedp ? unsigned_type_node : integer_type_node; + if (type1 == short_integer_type_node || type1 == short_unsigned_type_node) + return unsignedp ? short_unsigned_type_node : short_integer_type_node; + if (type1 == long_integer_type_node || type1 == long_unsigned_type_node) + return unsignedp ? long_unsigned_type_node : long_integer_type_node; + if (type1 == long_long_integer_type_node + || type1 == long_long_unsigned_type_node) + return unsignedp + ? long_long_unsigned_type_node + : long_long_integer_type_node; + if (int128_integer_type_node && (type1 == int128_integer_type_node || type1 == int128_unsigned_type_node)) + return unsignedp + ? int128_unsigned_type_node + : int128_integer_type_node; +#if HOST_BITS_PER_WIDE_INT >= 64 + if (type1 == intTI_type_node || type1 == unsigned_intTI_type_node) + return unsignedp ? unsigned_intTI_type_node : intTI_type_node; +#endif + if (type1 == intDI_type_node || type1 == unsigned_intDI_type_node) + return unsignedp ? unsigned_intDI_type_node : intDI_type_node; + if (type1 == intSI_type_node || type1 == unsigned_intSI_type_node) + return unsignedp ? unsigned_intSI_type_node : intSI_type_node; + if (type1 == intHI_type_node || type1 == unsigned_intHI_type_node) + return unsignedp ? unsigned_intHI_type_node : intHI_type_node; + if (type1 == intQI_type_node || type1 == unsigned_intQI_type_node) + return unsignedp ? unsigned_intQI_type_node : intQI_type_node; + +#define GIMPLE_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 GIMPLE_FIXED_MODE_TYPES(NAME) \ + if (type1 == NAME ## _type_node \ + || type1 == u ## NAME ## _type_node) \ + return unsignedp ? u ## NAME ## _type_node \ + : NAME ## _type_node; + +#define GIMPLE_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 GIMPLE_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; + + GIMPLE_FIXED_TYPES (fract); + GIMPLE_FIXED_TYPES_SAT (fract); + GIMPLE_FIXED_TYPES (accum); + GIMPLE_FIXED_TYPES_SAT (accum); + + GIMPLE_FIXED_MODE_TYPES (qq); + GIMPLE_FIXED_MODE_TYPES (hq); + GIMPLE_FIXED_MODE_TYPES (sq); + GIMPLE_FIXED_MODE_TYPES (dq); + GIMPLE_FIXED_MODE_TYPES (tq); + GIMPLE_FIXED_MODE_TYPES_SAT (qq); + GIMPLE_FIXED_MODE_TYPES_SAT (hq); + GIMPLE_FIXED_MODE_TYPES_SAT (sq); + GIMPLE_FIXED_MODE_TYPES_SAT (dq); + GIMPLE_FIXED_MODE_TYPES_SAT (tq); + GIMPLE_FIXED_MODE_TYPES (ha); + GIMPLE_FIXED_MODE_TYPES (sa); + GIMPLE_FIXED_MODE_TYPES (da); + GIMPLE_FIXED_MODE_TYPES (ta); + GIMPLE_FIXED_MODE_TYPES_SAT (ha); + GIMPLE_FIXED_MODE_TYPES_SAT (sa); + GIMPLE_FIXED_MODE_TYPES_SAT (da); + GIMPLE_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 + may use a wider mode to match an ABI. If we change modes, we may + wind up with bad conversions. For INTEGER_TYPEs in C, must check + the precision as well, so as to yield correct results for + bit-field types. C++ does not have these separate bit-field + types, and producing a signed or unsigned variant of an + ENUMERAL_TYPE may cause other problems as well. */ + if (!INTEGRAL_TYPE_P (type) + || TYPE_UNSIGNED (type) == unsignedp) + return type; + +#define TYPE_OK(node) \ + (TYPE_MODE (type) == TYPE_MODE (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)) + return unsignedp ? unsigned_type_node : integer_type_node; + if (TYPE_OK (short_integer_type_node)) + return unsignedp ? short_unsigned_type_node : short_integer_type_node; + if (TYPE_OK (long_integer_type_node)) + return unsignedp ? long_unsigned_type_node : long_integer_type_node; + if (TYPE_OK (long_long_integer_type_node)) + return (unsignedp + ? long_long_unsigned_type_node + : long_long_integer_type_node); + if (int128_integer_type_node && TYPE_OK (int128_integer_type_node)) + return (unsignedp + ? int128_unsigned_type_node + : int128_integer_type_node); + +#if HOST_BITS_PER_WIDE_INT >= 64 + if (TYPE_OK (intTI_type_node)) + return unsignedp ? unsigned_intTI_type_node : intTI_type_node; +#endif + if (TYPE_OK (intDI_type_node)) + return unsignedp ? unsigned_intDI_type_node : intDI_type_node; + if (TYPE_OK (intSI_type_node)) + return unsignedp ? unsigned_intSI_type_node : intSI_type_node; + if (TYPE_OK (intHI_type_node)) + return unsignedp ? unsigned_intHI_type_node : intHI_type_node; + if (TYPE_OK (intQI_type_node)) + return unsignedp ? unsigned_intQI_type_node : intQI_type_node; + +#undef GIMPLE_FIXED_TYPES +#undef GIMPLE_FIXED_MODE_TYPES +#undef GIMPLE_FIXED_TYPES_SAT +#undef GIMPLE_FIXED_MODE_TYPES_SAT +#undef TYPE_OK + + return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp); +} + + +/* Return an unsigned type the same as TYPE in other respects. */ + +tree +gimple_unsigned_type (tree type) +{ + return gimple_signed_or_unsigned_type (true, type); +} + + +/* Return a signed type the same as TYPE in other respects. */ + +tree +gimple_signed_type (tree type) +{ + return gimple_signed_or_unsigned_type (false, type); +} + + +/* Return the typed-based alias set for T, which may be an expression + or a type. Return -1 if we don't do anything special. */ + +alias_set_type +gimple_get_alias_set (tree t) +{ + tree u; + + /* Permit type-punning when accessing a union, provided the access + is directly through the union. For example, this code does not + permit taking the address of a union member and then storing + through it. Even the type-punning allowed here is a GCC + extension, albeit a common and useful one; the C standard says + that such accesses have implementation-defined behavior. */ + for (u = t; + TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF; + u = TREE_OPERAND (u, 0)) + if (TREE_CODE (u) == COMPONENT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) + return 0; + + /* That's all the expressions we handle specially. */ + if (!TYPE_P (t)) + return -1; + + /* For convenience, follow the C standard when dealing with + character types. Any object may be accessed via an lvalue that + has character type. */ + if (t == char_type_node + || t == signed_char_type_node + || t == unsigned_char_type_node) + return 0; + + /* Allow aliasing between signed and unsigned variants of the same + type. We treat the signed variant as canonical. */ + if (TREE_CODE (t) == INTEGER_TYPE && TYPE_UNSIGNED (t)) + { + tree t1 = gimple_signed_type (t); + + /* t1 == t can happen for boolean nodes which are always unsigned. */ + if (t1 != t) + return get_alias_set (t1); + } + + return -1; +} + + +/* Data structure used to count the number of dereferences to PTR + inside an expression. */ +struct count_ptr_d +{ + tree ptr; + unsigned num_stores; + unsigned num_loads; +}; + +/* Helper for count_uses_and_derefs. Called by walk_tree to look for + (ALIGN/MISALIGNED_)INDIRECT_REF nodes for the pointer passed in DATA. */ + +static tree +count_ptr_derefs (tree *tp, int *walk_subtrees, void *data) +{ + struct walk_stmt_info *wi_p = (struct walk_stmt_info *) data; + struct count_ptr_d *count_p = (struct count_ptr_d *) wi_p->info; + + /* Do not walk inside ADDR_EXPR nodes. In the expression &ptr->fld, + pointer 'ptr' is *not* dereferenced, it is simply used to compute + the address of 'fld' as 'ptr + offsetof(fld)'. */ + if (TREE_CODE (*tp) == ADDR_EXPR) + { + *walk_subtrees = 0; + return NULL_TREE; + } + + if (TREE_CODE (*tp) == MEM_REF && TREE_OPERAND (*tp, 0) == count_p->ptr) + { + if (wi_p->is_lhs) + count_p->num_stores++; + else + count_p->num_loads++; + } + + return NULL_TREE; +} + +/* Count the number of direct and indirect uses for pointer PTR in + statement STMT. The number of direct uses is stored in + *NUM_USES_P. Indirect references are counted separately depending + on whether they are store or load operations. The counts are + stored in *NUM_STORES_P and *NUM_LOADS_P. */ + +void +count_uses_and_derefs (tree ptr, gimple stmt, unsigned *num_uses_p, + unsigned *num_loads_p, unsigned *num_stores_p) +{ + ssa_op_iter i; + tree use; + + *num_uses_p = 0; + *num_loads_p = 0; + *num_stores_p = 0; + + /* Find out the total number of uses of PTR in STMT. */ + FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE) + if (use == ptr) + (*num_uses_p)++; + + /* Now count the number of indirect references to PTR. This is + truly awful, but we don't have much choice. There are no parent + pointers inside INDIRECT_REFs, so an expression like + '*x_1 = foo (x_1, *x_1)' needs to be traversed piece by piece to + find all the indirect and direct uses of x_1 inside. The only + shortcut we can take is the fact that GIMPLE only allows + INDIRECT_REFs inside the expressions below. */ + if (is_gimple_assign (stmt) + || gimple_code (stmt) == GIMPLE_RETURN + || gimple_code (stmt) == GIMPLE_ASM + || is_gimple_call (stmt)) + { + struct walk_stmt_info wi; + struct count_ptr_d count; + + count.ptr = ptr; + count.num_stores = 0; + count.num_loads = 0; + + memset (&wi, 0, sizeof (wi)); + wi.info = &count; + walk_gimple_op (stmt, count_ptr_derefs, &wi); + + *num_stores_p = count.num_stores; + *num_loads_p = count.num_loads; + } + + gcc_assert (*num_uses_p >= *num_loads_p + *num_stores_p); +} + +/* From a tree operand OP return the base of a load or store operation + or NULL_TREE if OP is not a load or a store. */ + +static tree +get_base_loadstore (tree op) +{ + while (handled_component_p (op)) + op = TREE_OPERAND (op, 0); + if (DECL_P (op) + || INDIRECT_REF_P (op) + || TREE_CODE (op) == MEM_REF + || TREE_CODE (op) == TARGET_MEM_REF) + return op; + return NULL_TREE; +} + +/* For the statement STMT call the callbacks VISIT_LOAD, VISIT_STORE and + VISIT_ADDR if non-NULL on loads, store and address-taken operands + passing the STMT, the base of the operand and DATA to it. The base + will be either a decl, an indirect reference (including TARGET_MEM_REF) + or the argument of an address expression. + Returns the results of these callbacks or'ed. */ + +bool +walk_stmt_load_store_addr_ops (gimple stmt, void *data, + bool (*visit_load)(gimple, tree, void *), + bool (*visit_store)(gimple, tree, void *), + bool (*visit_addr)(gimple, tree, void *)) +{ + bool ret = false; + unsigned i; + if (gimple_assign_single_p (stmt)) + { + tree lhs, rhs; + if (visit_store) + { + lhs = get_base_loadstore (gimple_assign_lhs (stmt)); + if (lhs) + ret |= visit_store (stmt, lhs, data); + } + rhs = gimple_assign_rhs1 (stmt); + while (handled_component_p (rhs)) + rhs = TREE_OPERAND (rhs, 0); + if (visit_addr) + { + if (TREE_CODE (rhs) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data); + else if (TREE_CODE (rhs) == TARGET_MEM_REF + && TREE_CODE (TMR_BASE (rhs)) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (rhs), 0), data); + else if (TREE_CODE (rhs) == OBJ_TYPE_REF + && TREE_CODE (OBJ_TYPE_REF_OBJECT (rhs)) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (OBJ_TYPE_REF_OBJECT (rhs), + 0), data); + lhs = gimple_assign_lhs (stmt); + if (TREE_CODE (lhs) == TARGET_MEM_REF + && TREE_CODE (TMR_BASE (lhs)) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (lhs), 0), data); + } + if (visit_load) + { + rhs = get_base_loadstore (rhs); + if (rhs) + ret |= visit_load (stmt, rhs, data); + } + } + else if (visit_addr + && (is_gimple_assign (stmt) + || gimple_code (stmt) == GIMPLE_COND)) + { + for (i = 0; i < gimple_num_ops (stmt); ++i) + if (gimple_op (stmt, i) + && TREE_CODE (gimple_op (stmt, i)) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (gimple_op (stmt, i), 0), data); + } + else if (is_gimple_call (stmt)) + { + if (visit_store) + { + tree lhs = gimple_call_lhs (stmt); + if (lhs) + { + lhs = get_base_loadstore (lhs); + if (lhs) + ret |= visit_store (stmt, lhs, data); + } + } + if (visit_load || visit_addr) + for (i = 0; i < gimple_call_num_args (stmt); ++i) + { + tree rhs = gimple_call_arg (stmt, i); + if (visit_addr + && TREE_CODE (rhs) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data); + else if (visit_load) + { + rhs = get_base_loadstore (rhs); + if (rhs) + ret |= visit_load (stmt, rhs, data); + } + } + if (visit_addr + && gimple_call_chain (stmt) + && TREE_CODE (gimple_call_chain (stmt)) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (gimple_call_chain (stmt), 0), + data); + if (visit_addr + && gimple_call_return_slot_opt_p (stmt) + && gimple_call_lhs (stmt) != NULL_TREE + && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt)))) + ret |= visit_addr (stmt, gimple_call_lhs (stmt), data); + } + else if (gimple_code (stmt) == GIMPLE_ASM) + { + unsigned noutputs; + const char *constraint; + const char **oconstraints; + bool allows_mem, allows_reg, is_inout; + noutputs = gimple_asm_noutputs (stmt); + oconstraints = XALLOCAVEC (const char *, noutputs); + if (visit_store || visit_addr) + for (i = 0; i < gimple_asm_noutputs (stmt); ++i) + { + tree link = gimple_asm_output_op (stmt, i); + tree op = get_base_loadstore (TREE_VALUE (link)); + if (op && visit_store) + ret |= visit_store (stmt, op, data); + if (visit_addr) + { + constraint = TREE_STRING_POINTER + (TREE_VALUE (TREE_PURPOSE (link))); + oconstraints[i] = constraint; + parse_output_constraint (&constraint, i, 0, 0, &allows_mem, + &allows_reg, &is_inout); + if (op && !allows_reg && allows_mem) + ret |= visit_addr (stmt, op, data); + } + } + if (visit_load || visit_addr) + for (i = 0; i < gimple_asm_ninputs (stmt); ++i) + { + tree link = gimple_asm_input_op (stmt, i); + tree op = TREE_VALUE (link); + if (visit_addr + && TREE_CODE (op) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); + else if (visit_load || visit_addr) + { + op = get_base_loadstore (op); + if (op) + { + if (visit_load) + ret |= visit_load (stmt, op, data); + if (visit_addr) + { + constraint = TREE_STRING_POINTER + (TREE_VALUE (TREE_PURPOSE (link))); + parse_input_constraint (&constraint, 0, 0, noutputs, + 0, oconstraints, + &allows_mem, &allows_reg); + if (!allows_reg && allows_mem) + ret |= visit_addr (stmt, op, data); + } + } + } + } + } + else if (gimple_code (stmt) == GIMPLE_RETURN) + { + tree op = gimple_return_retval (stmt); + if (op) + { + if (visit_addr + && TREE_CODE (op) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); + else if (visit_load) + { + op = get_base_loadstore (op); + if (op) + ret |= visit_load (stmt, op, data); + } + } + } + else if (visit_addr + && gimple_code (stmt) == GIMPLE_PHI) + { + for (i = 0; i < gimple_phi_num_args (stmt); ++i) + { + tree op = PHI_ARG_DEF (stmt, i); + if (TREE_CODE (op) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); + } + } + + return ret; +} + +/* Like walk_stmt_load_store_addr_ops but with NULL visit_addr. IPA-CP + should make a faster clone for this case. */ + +bool +walk_stmt_load_store_ops (gimple stmt, void *data, + bool (*visit_load)(gimple, tree, void *), + bool (*visit_store)(gimple, tree, void *)) +{ + return walk_stmt_load_store_addr_ops (stmt, data, + visit_load, visit_store, NULL); +} + +/* Helper for gimple_ior_addresses_taken_1. */ + +static bool +gimple_ior_addresses_taken_1 (gimple stmt ATTRIBUTE_UNUSED, + tree addr, void *data) +{ + bitmap addresses_taken = (bitmap)data; + addr = get_base_address (addr); + if (addr + && DECL_P (addr)) + { + bitmap_set_bit (addresses_taken, DECL_UID (addr)); + return true; + } + return false; +} + +/* Set the bit for the uid of all decls that have their address taken + in STMT in the ADDRESSES_TAKEN bitmap. Returns true if there + were any in this stmt. */ + +bool +gimple_ior_addresses_taken (bitmap addresses_taken, gimple stmt) +{ + return walk_stmt_load_store_addr_ops (stmt, addresses_taken, NULL, NULL, + gimple_ior_addresses_taken_1); +} + + +/* Return a printable name for symbol DECL. */ + +const char * +gimple_decl_printable_name (tree decl, int verbosity) +{ + if (!DECL_NAME (decl)) + return NULL; + + if (DECL_ASSEMBLER_NAME_SET_P (decl)) + { + const char *str, *mangled_str; + int dmgl_opts = DMGL_NO_OPTS; + + if (verbosity >= 2) + { + dmgl_opts = DMGL_VERBOSE + | DMGL_ANSI + | DMGL_GNU_V3 + | DMGL_RET_POSTFIX; + if (TREE_CODE (decl) == FUNCTION_DECL) + dmgl_opts |= DMGL_PARAMS; + } + + mangled_str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + str = cplus_demangle_v3 (mangled_str, dmgl_opts); + return (str) ? str : mangled_str; + } + + return IDENTIFIER_POINTER (DECL_NAME (decl)); +} + +/* Return true when STMT is builtins call to CODE. */ + +bool +gimple_call_builtin_p (gimple stmt, enum built_in_function code) +{ + tree fndecl; + return (is_gimple_call (stmt) + && (fndecl = gimple_call_fndecl (stmt)) != NULL + && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL + && DECL_FUNCTION_CODE (fndecl) == code); +} + +#include "gt-gimple.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/ChangeLog-2010 Sun Aug 21 07:07:55 2011 +0900 @@ -0,0 +1,40863 @@ +2010-12-31 Gerald Pfeifer <gerald@pfeifer.com> + + * doc/install.texi (powerpc-*-darwin*): Update reference to + Apple Developer Tools. + +2010-12-31 Ken Werner <ken.werner@de.ibm.com> + + * config/arm/sync.md (sync_clobber, sync_t2_reqd): New code attribute. + (arm_sync_old_<sync_optab>si, arm_sync_old_<sync_optab><mode>): Use + the sync_clobber and sync_t2_reqd code attributes. + * config/arm/arm.c (arm_output_sync_loop): Reverse the operation if + the t2 argument is NULL. + +2010-12-31 Gerald Pfeifer <gerald@pfeifer.com> + + * doc/sourcebuild.texi (Top Level): Adjust link to libgo. + +2010-12-31 Gerald Pfeifer <gerald@pfeifer.com> + + * doc/install.texi (Specific): Remove reference to interix.com. + +2010-12-31 Paul Koning <ni1d@arrl.net> + + * config/pdp11/pdp11.h (PRINT_OPERAND): Delete. + * config/pdp11/pdp11.c (TARGET_PRINT_OPERAND, + TARGET_PRINT_OPERAND_PUNCT_VALID_P): Define + (pdp11_asm_print_operand, pdp11_asm_print_operand_punct_valid_p): + New function. + * config/pdp11/pdp11.md (tablejump): Fix generated assembly. + +2010-12-31 Joern Rennecke <amylaar@spamcop.net> + + PR target/47111 + * config/rtems.h (NO_IMPLICIT_EXTERN_C): Undef before defining. + + PR target/47112 + * config/mips/r3900.h: Update Copyright years. + (MIPS_CPU_STRING_DEFAULT): Undef before defining. + (MULTILIB_DEFAULTS, MIPS_ABI_DEFAULT, SUBTARGET_CC1_SPEC): Likewise. + + PR target/47135 + * config/pdp11/pdp11.c (pdp11_asm_print_operand_punct_valid_p): Change + type to match target.def . + + PR target/47114 + * config/rs6000/rs6000.c (rs6000_elf_asm_out_constructor): Add + ATTRIBUTE_UNUSED to declaration. + (rs6000_elf_asm_out_destructor): Likewise. + + PR target/47084 + * config/mn10300/linux.h (PRINT_OPERAND): Update for name changes + to mn10300_print_operand / mn10300_print_operand_address. + +2010-12-30 Mingjie Xing <mingjie.xing@gmail.com> + + * config/mips/mips.h (SHIFT_COUNT_TRUNCATED): Change + TARGET_LOONGSON_2EF to TARGET_LOONGSON_VECTORS. + * config/mips/mips.c (mips_shift_truncation_mask): Likewise. + +2010-12-30 Joseph Myers <joseph@codesourcery.com> + + * config/openbsd.opt: New. + * config.gcc (alpha*-*-openbsd*, + i[34567]86-*-openbsd2.*|i[34567]86-*openbsd3.[0123], + i[34567]86-*-openbsd*, m68k*-*-openbsd*, mips*-*-openbsd*, + sparc64-*-openbsd*, vax-*-openbsd*): Use openbsd.opt. + +2010-12-30 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + * config/pa/pa.md: Add ",*" condition to 64-bit add/subtract boolean + patterns. + +2010-12-30 Eric Botcazou <ebotcazou@adacore.com> + + PR target/47038 + * config/sparc/sparc.c (sparc_file_end): Call resolve_unique_section + on the GOT helper if USE_HIDDEN_LINKONCE. + +2010-12-30 Joseph Myers <joseph@codesourcery.com> + + PR c/46889 + * c-decl.c (detect_field_duplicates): Ensure hash is used for + finding duplicates when first field is anonymous. + +2010-12-30 Nathan Froyd <froydnj@codesourcery.com> + + PR target/44606 + * reload1.c (choose_reload_regs): Don't look for equivalences for + output reloads of constant loads. + +2010-12-30 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * emit-rtl.c (set_mem_attributes_minus_bitpos): Explicitly derive + default values from MEM mode if no memory attributes are present. + Do not use mode alignment, even on STRICT_ALIGNMENT targets, when + called with an expression (not a type). + +2010-12-30 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/i386.c (upper_128bits_state): Remove comments. + (block_info_def): Add unchanged. + (move_or_delete_vzeroupper_2): Short circuit if upper 128bits + are unchanged in the block. + +2010-12-30 H.J. Lu <hongjiu.lu@intel.com> + + PR target/46519 + * config/i386/i386.c (block_info_def): Remove referenced, count + and rescanned. + (move_or_delete_vzeroupper_2): Updated. + (move_or_delete_vzeroupper_1): Rewritten to avoid recursive call. + (rescan_move_or_delete_vzeroupper): Removed. + (move_or_delete_vzeroupper): Repeat processing all basic blocks + until no basic block state is changed to used at exit. + +2010-12-30 Paul Koning <ni1d@arrl.net> + + * config/pdp11/pdp11.md (movmemhi, movmemhi1): Correct + constraints. + * config/pdp11/pdp11.c (output_block_move): Rewrite. + +2010-12-30 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/47060 + * tree-parloops.c (reduction_phi): Return NULL if PHI is NULL. + +2010-12-29 Paul Koning <ni1d@arrl.net> + + * config/pdp11/pdp11-protos.h (pdp11_asm_output_var): Declare. + * config/pdp11/pdp11.c (pdp11_asm_output_var): New function. + * config/pdp11/pdp11.h (ASM_OUTPUT_ALIGNED_COMMON, + ASM_OUTPUT_ALIGNED_LOCAL): New macros. + (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Delete. + +2010-12-30 Joern Rennecke <amylaar@spamcop.net> + + PR target/47129 + * config/ia64/ia64.c: Include "dwarf2out.h" . + + PR target/47063 + * config/alpha/vms.h (MALLOC_ALIGNMENT): Don't undef / define. + (MALLOC_ABI_ALIGNMENT): Undef / define. + + PR target/47101 + * vmsdbgout.c (vmsdbgout_init): Rename main_input_filename to filename. + (vmsdbgout_finish): Likewise. + + PR target/47097 + * config/i386/lynx.h (DBX_REGISTER_NUMBER): Add cast to avoid + mixing signed and unsigned types in conditional expression. + +2010-12-29 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/47074 + * gimple-fold.c (gimplify_and_update_call_from_tree): Call + pop_gimplify_context if returning early. + +2010-12-28 Sebastian Pop <sebastian.pop@amd.com> + + * Makefile.in (graphite.o): Depends on DIAGNOSTIC_CORE_H. + (graphite-clast-to-gimple.o): Same. + (graphite-poly.o): Same. + * graphite-clast-to-gimple.c: Include diagnostic-core.h. + * graphite-poly.c: Same. + * graphite.c: Same. + +2010-12-28 Richard Guenther <rguenther@suse.de> + + PR debug/46931 + * tree-vect-loop-manip.c (slpeel_tree_peel_loop_to_edge): Update + SSA before removing dead stmts. + +2010-12-28 H.J. Lu <hongjiu.lu@intel.com> + Uros Bizjak <ubizjak@gmail.com> + + * config/i386/i386-builtin-types.def (PUSHORT): New. + (INT_FTYPE_PUSHORT): Likewise. + (INT_FTYPE_PUNSIGNED): Likewise. + (INT_FTYPE_PULONGLONG): Likewise. + Remove "DEF_FUNCTION_TYPE (UINT16)". + + * config/i386/i386.c (ix86_builtins): Remove + IX86_BUILTIN_RDRAND16, IX86_BUILTIN_RDRAND32 and + IX86_BUILTIN_RDRAND64. Add IX86_BUILTIN_RDRAND16_STEP, + IX86_BUILTIN_RDRAND32_STEP and IX86_BUILTIN_RDRAND64_STEP. + (bdesc_special_args): Remove IX86_BUILTIN_RDRAND16, + IX86_BUILTIN_RDRAND32 and IX86_BUILTIN_RDRAND64. + (ix86_init_mmx_sse_builtins): Handle IX86_BUILTIN_RDRAND16_STEP, + IX86_BUILTIN_RDRAND32_STEP and IX86_BUILTIN_RDRAND64_STEP. + (ix86_expand_builtin): Likewise. + (ix86_expand_special_args_builtin): Remove UINT16_FTYPE_VOID. + + * config/i386/i386.md (UNSPEC_RDRAND): New. + (UNSPECV_RDRAND): Removed. + (rdrand<mode>): Likewise. + (rdrand<mode>_1): Also set FLAGS_REG. Replace UNSPECV_RDRAND + with UNSPEC_RDRAND. + + * config/i386/immintrin.h (_rdrand_u16): Removed. + (_rdrand_u32): Likewise. + (_rdrand_u64): Likewise. + (_rdrand16_step): New. + (_rdrand32_step): Likewise. + (_rdrand64_step): Likewise. + + * doc/extend.texi (__builtin_ia32_rdrand16): Removed. + (__builtin_ia32_rdrand32): Likewise. + (__builtin_ia32_rdrand64): Likewise. + (__builtin_ia32_rdrand16_step): New. + (__builtin_ia32_rdrand32_step): Likewise. + (__builtin_ia32_rdrand64_step): Likewise. + +2010-12-28 Sebastian Pop <sebastian.pop@amd.com> + + * Makefile.in (graphite.o): Add dependence on DIAGNOSTIC_H. + * graphite.c: Include diagnostic.h. + +2010-12-28 Sebastian Pop <sebastian.pop@amd.com> + + * Makefile.in (TREE_VECTORIZER_H): Removed duplicate definition. + (tree-browser.o): Update dependences. + (omega.o): Same. + (tree-chrec.o): Same. + (tree-scalar-evolution.o): Same. + (tree-data-ref.o): Same. + (sese.o): Same. + (graphite.o): Same. + (graphite-blocking.o): Same. + (graphite-clast-to-gimple.o): Same. + (graphite-cloog-util.o): Same. + (graphite-dependences.o): Same. + (graphite-flattening.o): Same. + (graphite-interchange.o): Same. + (graphite-poly.o): Same. + (graphite-ppl.o): Same. + (graphite-scop-detection.o): Same. + (graphite-sese-to-poly.o): Same. + (tree-loop-linear.o): Same. + (tree-loop-distribution.o): Same. + (tree-parloops.o): Same. + (lambda-mat.o): Same. + (lambda-trans.o): Same. + (lambda-code.o): Same. + * tree-browser.o: Do not include unnecessary .h files. + * omega.o: Same. + * tree-chrec.o: Same. + * tree-scalar-evolution.o: Same. + * tree-data-ref.o: Same. + * sese.o: Same. + * graphite.o: Same. + * graphite-blocking.o: Same. + * graphite-clast-to-gimple.o: Same. + * graphite-cloog-util.o: Same. + * graphite-dependences.o: Same. + * graphite-flattening.o: Same. + * graphite-interchange.o: Same. + * graphite-poly.o: Same. + * graphite-ppl.o: Same. + * graphite-scop-detection.o: Same. + * graphite-sese-to-poly.o: Same. + * tree-loop-linear.o: Same. + * tree-loop-distribution.o: Same. + * tree-parloops.o: Same. + * lambda-mat.o: Same. + * lambda-trans.o: Same. + * lambda-code.o: Same. + * graphite.h: Removed. + +2010-12-28 Paul Koning <ni1d@arrl.net> + + * config/pdp11/pdp11.md: Correct length attribute for float + literal case. + +2010-12-28 Jie Zhang <jie@codesourcery.com> + + * builtins.c (SLOW_UNALIGNED_ACCESS): Remove. + +2010-12-27 Joseph Myers <joseph@codesourcery.com> + + * config/freebsd.opt (assert=, defsym=, profile, pthread, + rpath-link=, rpath=, soname=): New Driver options. + +2010-12-26 Martin Jambor <mjambor@suse.cz> + + * tree.c (get_binfo_at_offset): Use BINFO_TYPE instead of TREE_TYPE, + compare TYPE_MAIN_VARIANTs of types. + +2010-12-26 Andreas Schwab <schwab@linux-m68k.org> + + * config/m68k/t-linux (M68K_MLIB_CPU): Only include 680x0 CPUs. + +2010-12-24 Alexander Monakov <amonakov@ispras.ru> + + PR rtl-optimization/47036 + * sel-sched-ir.c (fallthru_bb_of_jump): Remove special support for + unconditional jumps. + * sel-sched.c (moveup_expr): Ditto. + +2010-12-23 Sebastian Pop <sebastian.pop@amd.com> + Richard Guenther <rguenther@suse.de> + + PR tree-optimization/46758 + * graphite-sese-to-poly.c (scan_tree_for_params_right_scev): Use + tree_int_to_gmp instead of int_cst_value. + (scan_tree_for_params_int): Same. + (scan_tree_for_params): Same. + (pdr_add_data_dimensions): Use ppl_set_inhomogeneous_tree. + +2010-12-23 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/47002 + * tree-data-ref.c (compute_data_dependences_for_loop): Pass in a + pointer to the loop_nest. + (analyze_all_data_dependences): Initialize and free the loop_nest. + (free_dependence_relations): Do not free loop_nest. + (build_rdg): Pass in the loop_nest, datarefs, and dependence_relations. + (free_rdg): Also free the data on edges. + * tree-data-ref.h (build_rdg): Update declaration. + (compute_data_dependences_for_loop): Same. + * tree-if-conv.c (if_convertible_loop_p_1): Pass in the loop_nest. + (if_convertible_loop_p): Allocate and free loop_nest. + * tree-loop-distribution.c (rdg_flag_loop_exits): Free conds. + (free_rdg_components): VEC_free components. + (distribute_loop): Update call to build_rdg. Allocate and free + loop_nest, datarefs, and dependence_relations. + * tree-loop-linear.c (linear_transform_loops): Allocate and free + loop_nest. + * tree-parloops.c (loop_parallel_p): Same. + * tree-predcom.c (tree_predictive_commoning_loop): Same. + * tree-vect-data-refs.c (vect_analyze_data_refs): Pass to + compute_data_dependences_for_loop a pointer to LOOP_VINFO_LOOP_NEST. + * tree-vect-loop.c (new_loop_vec_info): Initialize LOOP_VINFO_LOOP_NEST. + (destroy_loop_vec_info): Free LOOP_VINFO_MAY_ALIAS_DDRS and + LOOP_VINFO_LOOP_NEST. + * tree-vect-slp.c (destroy_bb_vec_info): Call free_data_refs and + free_dependence_relations. + * tree-vectorizer.h (struct _loop_vec_info): Add a field loop_nest. + (LOOP_VINFO_LOOP_NEST): New. + +2010-12-23 Martin Jambor <mjambor@suse.cz> + + * ipa.c (cgraph_remove_unreachable_nodes): Update former_clone_of even + when not checking. + +2010-12-23 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * configure.ac (gcc_cv_ld_eh_frame_hdr): Only check GNU ld for + --eh-frame-hdr. Check for working Sun ld version. + (HAVE_LD_EH_FRAME_HDR): Adapt comment. + (glibc_header_dir): Set only once. Rename to ... + (target_header_dir): ... this. Adapt users. + (gcc_cv_target_dl_iterate_frame_hdr): Check on *-*-solaris2*. + (TARGET_DL_ITERATE_PHDR): Define if present. + * configure: Regenerate. + * config.in: Likewise. + * config/t-sol2 (LIB2ADDEH, LIB2ADDEHDEP): Define. + * crtstuff.c (USE_PT_GNU_EH_FRAME): Define for recent Solaris 11 + with linker support and dl_iterate_phdr. + * unwind-dw2-fde-glibc.c (USE_PT_GNU_EH_FRAME): Likewise. + (_Unwind_IteratePhdrCallback) [PT_SUNW_UNWIND]: Also accept + PT_SUNW_UNWIND .eh_frame_hdr sections. + [CRT_GET_RFIB_DATA && __i386__ && __sun__ && __svr4__]: Add + load_base to data->dbase. + [CRT_GET_RFIB_DATA && __x86_64__ && __sun__ && __svr4__]: Handle + 64-bit Solaris 10+/x86. + * config/sol2-gld.h [TARGET_DL_ITERATE_PHDR && HAVE_LD_EH_FRAME_HDR] + (LINK_EH_SPEC): Define. + +2010-12-23 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * doc/extend.texi (Function Attributes, Volatiles): Fix typos. + * doc/install.texi (Prerequisites, Specific): Likewise. + * doc/invoke.texi (C Dialect Options, Debugging Options) + (Optimize Options, MicroBlaze Options) + (RS/6000 and PowerPC Options, RX Options, Code Gen Options): Likewise. + * doc/objc.texi (Method signatures) + (Fast enumeration protocol): Likewise. + * doc/tm.texi.in (Run-time Target, Register Arguments) + (Scheduling, Macros for Initialization, Misc): Likewise. + * doc/tm.texi: Renerate. + +2010-12-23 Nicola Pero <nicola.pero@meta-innovation.com> + + * doc/objc.texi (Modern GNU Objective-C runtime API): Mention that + reference documentation for functions in the API is in the header + files. + (Messaging with the GNU Objective-C runtime, Dynamically + registering methods, Forwarding hook): New sections. + +2010-12-22 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/47019 + * sese.h (scev_analyzable_p): Parameters of a SCoP are SCEV analyzable. + +2010-12-22 Nathan Froyd <froydnj@codesourcery.com> + + * c-aux-info.c (gen_formal_list_for_type): Use prototype_p. + * c-decl.c (diagnose_arglist_conflict): Likewise. + (diagnose_mismatched_decls, merge_decls): Likewise. + (c_builtin_function, c_builtin_function_ext_scope): Likewise. + (start_decl, start_function): Likewise. + * c-tree.h (C_DECL_ISNT_PROTOTYPED): Likewise. + * config/ia64/ia64.h (INIT_CUMULATIVE_ARGS): Likewise. + * config/mep/mep.c (mep_validate_interrupt): Likewise. + * config/pa/pa.h (INIT_CUMULATIVE_ARGS): Likewise. + * config/rs6000/rs6000.c (init_cumulative_args): Likewise. + * config/sh/sh.c (sh_init_cumulative_args): Likewise. + * config/sparc/sparc.c (init_cumulative_args): Likewise. + * dwarf2out.c (add_prototyped_attribute): Likewise. + (gen_subprogram_die): Likewise. + * ipa-type-escape.c (check_function_parameter_and_return_types): + Likewise. + (check_call): Likewise. + * tree-ssa.c (useless_type_conversion_p): Likewise. + +2010-12-22 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * config/spu/spu.md ("mov<mode>"): Use nonimmediate_operand + predicate for destination operand. + * config/spu/spu.c (spu_expand_mov): If move destination is an + invalid subreg, perform move in the subreg's inner mode instead. + +2010-12-22 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/45934 + PR tree-optimization/46302 + PR tree-optimization/46987 + * gimple-fold.c (get_base_binfo_for_type): Removed. + (gimple_get_relevant_ref_binfo): Likewise. + (gimple_fold_obj_type_ref_call): Dumb down to 4.5 functionality, + removed parameter inplace, updated the caller. + * gimple.h (gimple_get_relevant_ref_binfo): Remove declaration. + * ipa-cp.c (ipcp_propagate_types): Do not derive types from constants. + (ipcp_discover_new_direct_edges): Do not do devirtualization based on + constants. + * ipa-prop.c (compute_known_type_jump_func): Use + get_ref_base_and_extent and get_binfo_at_offset instead of + gimple_get_relevant_ref_binfo. + (compute_known_type_jump_func): Likewise. + (update_jump_functions_after_inlining): Do not derive types from + constants. + (try_make_edge_direct_virtual_call): Likewise. + * tree.c (get_binfo_at_offset): Get type from non-artificial fields. + +2010-12-22 Joseph Myers <joseph@codesourcery.com> + + * config/svr4.h: Remove. + * system.h (USING_SVR4_H, SVR4_ASM_SPEC): Poison. + * config.gcc, config/bfin/bfin.h, config/cris/cris.h, + config/fr30/fr30.h, config/frv/frv.h, config/i386/openbsdelf.h, + config/i386/vx-common.h, config/ia64/elf.h, config/ia64/ia64.h, + config/ia64/sysv4.h, config/iq2000/iq2000.h, config/m68k/linux.h, + config/m68k/m68kelf.h, config/mips/mips.h, config/mips/vxworks.h, + config/moxie/moxie.h, config/netbsd-aout.h, config/openbsd.h, + config/rs6000/sysv4.h, config/sh/elf.h, config/sh/sh.h, + config/sol2.h, config/sparc/sysv4.h, config/stormy16/stormy16.h, + config/v850/v850.h, config/vxworks.h: Remove or update comments + referring to svr4.h. + +2010-12-22 Andrey Belevantsev <abel@ispras.ru> + + PR rtl-optimization/45352 + PR rtl-optimization/46521 + PR rtl-optimization/46522 + * sel-sched.c (reset_sched_cycles_in_current_ebb): Recheck the + DFA state on the last iteration of the advancing loop. + (sel_sched_region_1): Propagate the rescheduling bit to the next + block also for empty blocks. + +2010-12-22 Alexandre Oliva <aoliva@redhat.com> + + PR debug/46724 + * function.c (assign_parms_augmented_arg_list): Name and mark + DECL of result address as NAMELESS rather than IGNORED. + (assign_parms): Set DECL_VALUE_EXPR for indirect result. + * tree.h (tree_decl_common::decl_flag_2): Document RESULT_DECL. + (DECL_HAS_VALUE_EXPR_P): Accept RESULT_DECL. + * dwarf2out.c (loc_list_from_tree) <RESULT_DECL>: Use + DECL_VALUE_EXPR. + * dbxout.c (dbxout_expand_expr) <RESULT_DECL>: Likewise. + * var-tracking.c (vt_add_function_parameter): New, split out of... + (vt_add_function_parameters): ... this. Handle incoming + pointer to hold result. + +2010-12-22 Jie Zhang <jie@codesourcery.com> + + * config/arm/arm.c (output_move_double): Update the comment + above the function to reflect the current implementation. + +2010-12-21 Steven Bosscher <steven@gcc.gnu.org> + + De-hookize profile infrastructure. + * value-prof.c (value_prof_hooks): Remove. + (struct value_prof_hooks): Remove. + (gimple_value_prof_hooks): Remove. + (gimple_register_value_prof_hooks): Remove. + (find_values_to_profile): Remove. + (value_profile_transformations): Remove. + (gimple_value_profile_transformations): No longer static. + (gimple_find_values_to_profile): Likewise. + * value-prof.h (gimple_register_value_prof_hooks): Remove prototype. + (find_values_to_profile): Likewise. + (value_profile_transformations): Likewise. + (tree_register_profile_hooks): Likewise. + (struct profile_hooks): Remove. + (tree_profile_hooks): Remove. + (gimple_find_values_to_profile): New protoype. + (gimple_value_profile_transformations): Likewise. + (gimple_init_edge_profiler): Likewise. + (gimple_gen_edge_profiler): Likewise. + (gimple_gen_interval_profiler): Likewise. + (gimple_gen_pow2_profiler): Likewise. + (gimple_gen_one_value_profiler): Likewise. + (gimple_gen_ic_profiler): Likewise. + (gimple_gen_ic_func_profiler): Likewise. + (gimple_gen_const_delta_profiler): Likewise. + (gimple_gen_average_profiler): Likewise. + (gimple_gen_ior_profiler): Likewise. + * profile.c (profile_hooks): Remove. + (instrument_edges): Call profiling functions directly instead + of through removed profile_hooks. + (instrument_values): Likewise. + (branch_prob): Call gimple_find_values_to_profile instead of + removed find_values_to_profile. + Call gimple_init_edge_profiler instead of removed hook. + (tree_register_profile_hooks): Remove. + * tree-profile.c (tree_init_ic_make_global_vars): Rename to + init_ic_make_global_vars. + (tree_init_edge_profiler): Rename to gimple_init_edge_profiler + and no longer static. + (tree_gen_edge_profiler, tree_gen_interval_profiler, + tree_gen_pow2_profiler, tree_gen_one_value_profiler, + tree_gen_ic_profiler, tree_gen_ic_func_profiler, + tree_gen_const_delta_profiler, tree_gen_average_profiler, + tree_gen_ior_profiler): Similarly renamed and no longer static. + (tree_profiling): Do not initialize tree profiling hooks. + (tree_profile_hooks): Remove. + +2010-12-21 Jakub Jelinek <jakub@redhat.com> + + PR target/46880 + * config/i386/sse.md (sse2_loadlpd, sse2_movsd): Fix shufpd source + operand. + +2010-12-21 Ira Rosen <irar@il.ibm.com> + + PR tree-optimization/47001 + * tree-vect-slp.c (vect_supported_load_permutation_p): Check that + the loads in reduction are different and there are no gaps between + them. + +2010-12-21 Steven Bosscher <steven@gcc.gnu.org> + + PR middle-end/45310 + * tree-ssa-phiprop.c (propagate_with_phi): Remove statement + completely from the function, including EH traces. + +2010-12-21 Steven Bosscher <steven@gcc.gnu.org> + + PR rtl-optimization/46755 + * ira.c (ira): If some dead edges were removed, find and delete + any blocks that might have become unreachable. + +2010-12-21 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/47008 + * postreload.c (reload_combine_note_store): Also handle + PRE_MODIFY and POST_MODIFY. + +2010-12-21 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * config/arm/arm.c (require_pic_register): Set INSN_LOCATOR for all + instructions injected into the prologue to prologue_locator. + +2010-12-21 Jan Hubicka <jh@suse.cz> + + PR middle-end/47000 + * tree-inline.c (estimate_operator_cost): Handle VIEW_CONVERT_EXPR. + +2010-12-21 Jie Zhang <jie@codesourcery.com> + + * config/arm/arm-ldmstm.ml: Fix a typo in comment. + +2010-12-21 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/45852 + * expr.c (store_expr): Ignore alt_rtl if equal to target, + but has side-effects. + +2010-12-21 Anatoly Sokolov <aesok@post.ru> + + * config/sh/sh.h (PREFERRED_RELOAD_CLASS): Remove. + * config/sh/sh-protos.h (secondary_reload_info, sh_secondary_reload): + Remove forward declaration. + * config/sh/sh.c (sh_preferred_reload_class): New function. + (sh_secondary_reload): Make static. + (TARGET_PREFERRED_RELOAD_CLASS): Define. + +2010-12-20 Joseph Myers <joseph@codesourcery.com> + + * config/alpha/linux.h (OPTION_GLIBC): Define differently if + SINGLE_LIBC. + * config/linux.h (OPTION_GLIBC, OPTION_UCLIBC, OPTION_BIONIC): + Define differently if SINGLE_LIBC. + * config/rs6000/linux.h (OPTION_GLIBC): Define differently if + SINGLE_LIBC. + * config/rs6000/linux64.h (OPTION_GLIBC): Define differently if + SINGLE_LIBC. + * config.gcc (*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | + *-*-knetbsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu): Define + SINGLE_LIBC instead of OPTION_GLIBC. + (*-*-uclinux*): Define DEFAULT_LIBC and SINGLE_LIBC. + (bfin*-uclinux*, moxie-*-uclinux*, m68k-*-uclinux*): Don't define + DEFAULT_LIBC or use linux.opt. + +2010-12-20 Richard Henderson <rth@redhat.com> + + * config/mn10300/mn10300.c (mn10300_legitimize_pic_address): Generate + UNSPEC patterns by hand, with the proper mode; use gen_const_mem. + * config/mn10300/mn10300.md (call, call_value): Generate UNSPEC_PLT + by hand, with the proper mode. + (symGOT2reg, symGOT2reg_i, symGOTOFF2reg): Remove. + (symGOTOFF2reg_i, sym2PIC, sym2PLT): Remove. + +2010-12-20 Sanjin Liu <scliu@faraday-tech.com> + Mingfeng Wu <mingfeng@faraday-tech.com> + + * config/arm/arm-cores.def: Add Faraday CPU support - + fa526/fa626/fa606te/fa626te/fmp626/fa726te. + * config/arm/arm-tune.md: Regenerate. + * config/arm/arm.c (arm_fa726te_tune): New tune_params for fa726te + (fa726te_sched_adjust_cost): New cost function for fa726te. + (arm_issue_rate): Add fa726te. + * config/arm/arm.md (generic_sched): Add Faraday cores to generic_sched + and include machine description files. + * config/arm/bpabi.h (TARGET_FIX_V4BX_SPEC): Add fa526 and fa626. + * config/arm/t-arm (MD_INCLUDES): Include machine description files for + Faraday cores. + * config/arm/t-arm-elf: Add multilib option for Faraday cores. + * config/arm/t-linux-eabi: Add multilib option for Faraday cores except + fa526 and fa626. + * doc/invoke.texi: Document -mcpu for Faraday cores. + * config/arm/fa526.md: New file. + * config/arm/fa606te.md: New file. + * config/arm/fa626te.md: New file. + * config/arm/fmp626.md: New file. + * config/arm/fa726te.md: New file. + +2010-12-20 Yvan Roux <yvan.roux@st.com> + + * config/arm/lib1funcs.asm (ARM_DIV_BODY case __OPTIMIZE_SIZE__): Fix + condition on IT instruction for early termination. + +2010-12-20 Joseph Myers <joseph@codesourcery.com> + + * config/rs6000/freebsd.h (SVR4_ASM_SPEC): Don't define. + (DBX_REGISTER_NUMBER): Define. + * config/rs6000/lynx.h (DBX_REGISTER_NUMBER): Define. + * config/rs6000/netbsd.h (DBX_REGISTER_NUMBER): Define. + * config/rs6000/sysv4.h (SIZE_TYPE): Define. + (ASM_SPEC): Define without using SVR4_ASM_SPEC. + (DBX_REGISTER_NUMBER): Undefine. + * config.gcc (powerpc-*-eabispe*, powerpc-*-eabisimaltivec*, + powerpc-*-eabisim*, powerpc-*-elf*, powerpc-*-eabialtivec*, + powerpc-xilinx-eabi*, powerpc-*-eabi*, powerpc-*-rtems*, + powerpc-*-linux* | powerpc64-*-linux*, powerpc64-*-gnu*, + powerpc-*-gnu-gnualtivec*, powerpc-*-gnu*, + powerpc-wrs-vxworks|powerpc-wrs-vxworksae, powerpcle-*-elf*, + powerpcle-*-eabisim*, powerpcle-*-eabi*): Don't use svr4.h. + +2010-12-20 Iain Sandoe <iains@gcc.gnu.org> + Jan Hubicka <jh@suse.cz> + + PR middle-end/46916 + * opts.c (finish_options): Enable -freorder-functions + when -freorder-blocks-and-partition is active. + +2010-12-20 Iain Sandoe <iains@gcc.gnu.org> + + PR c++/46904 + PR middle-end/46916 + PR target/46950 + * config/darwin.c (generating_for_darwin_version): New var. + (darwin_text_section): Remove. + (darwin_rodata_section): Do not check function section here. + (darwin_emit_unwind_label): Do not emit for Darwin >= 9. + Emit distinct labels for successive calls for the same decl. + (darwin_override_options): Set generating_for_darwin_version. + Add FIXME and disable -freorder-blocks-and-partition. + Suppress automatic asynchronous unwind tables for m32. + Switch off -freorder-blocks-and-partition when unwind tables + will be generated. Update to use generating_for_darwin_version. + (darwin_function_section): Check for cases that need to be placed + in coalesced sections. + * config/darwin-sections.def: Define hot, cold, startup and + exit sections for both coalesced and regular code. + * config/darwin.h (USE_SELECT_SECTION_FOR_FUNCTIONS): Delete. + * config/darwin10.h (TARGET_ASM_EMIT_UNWIND_LABEL): Delete. + +2010-12-20 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * doc/cppopts.texi: Use @var when appropriate. + * doc/extend.texi (Structure-Packing Pragmas): Likewise. + * doc/gimple.texi (Logical Operators) + (Adding a new GIMPLE statement code): Likewise. + * doc/invoke.texi (Target Options, Precompiled Headers): Likewise. + * doc/plugins.texi (Plugins): Likewise. + + * doc/install.texi (Configuration, Building, Testing, Specific): + Remove leading whitespace from examples. + +2010-12-19 Andi Kleen <ak@linux.intel.com> + + PR lto/46905 + * collect2.c (main): Handle -fno-lto. + * opts.c (common_handle_option): Handle -fno-lto. + +2010-12-19 Eric Botcazou <ebotcazou@adacore.com> + + PR target/46729 + * config/sparc/sparc.h (GLOBAL_OFFSET_TABLE_REGNUM): New macro. + (PIC_OFFSET_TABLE_REGNUM): Rewrite in terms of above macro. + * config/sparc/sparc.c (pic_helper_needed): Delete. + (global_offset_table): Likewise. + (pic_helper_symbol): Rename to... + (got_helper_rtx): ...this. + (global_offset_table_rtx): New global variable. + (sparc_got_symbol): Likewise. + (sparc_got): New static function. + (check_pic): Use local variable and call sparc_got. + (sparc_tls_symbol): Initialize to NULL_RTX. + (sparc_tls_got): In non-PIC mode, reload the GOT register for Sun TLS + and 32-bit ABI and copy the GOT symbol to a new register otherwise. + (get_pc_thunk_name): Rename local variable. + (gen_load_pcrel_sym): New wrapper around load_pcrel_sym{si,di}. + (load_pic_register): Rename to... + (load_got_register): ...this. Adjust and call gen_load_pcrel_sym. + (sparc_expand_prologue): Do not test flag_pic. + (sparc_output_mi_thunk): Use pic_offset_table_rtx directly. + (sparc_file_end): Test got_helper_rtx instead of pic_helper_needed. + Rename local variable and do not call get_pc_thunk_name again. + * config/sparc/sparc.md (load_pcrel_sym): Add operand #3. + +2010-12-19 Dave Korn <dave.korn.cygwin@gmail.com> + + PR middle-end/46674 + PR middle-end/46221 + * varasm.c (symbol_alias_set_t): New typedef for derived pointer_set + wrapper class. + (symbol_alias_set_create): New wrapper function. + (symbol_alias_set_destroy): Likewise. + (symbol_alias_set_contains): Likewise. + (symbol_alias_set_insert): Likewise. + (compute_visible_aliases): Use the above and return symbol_alias_set_t, + not a pointer_set. + (remove_unreachable_alias_pairs): Adjust likewise to match. + (finish_aliases_1): Likewise. + +2010-12-19 Chung-Lin Tang <cltang@codesourcery.com> + + * config/arm/arm.c (arm_legitimate_index_p): Add VFP load/store + index range case. Change to SF/DFmode tests to avoid capturing HFmode. + (thumb2_legitimate_index_p): Same. + +2010-12-18 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/46969 + * tree-parloops.c (struct reduction_info): Add reduc_version. + (reduction_info_hash): Return reduc_version field. + (reduction_phi): Set reduc_version to gimple_uid (phi). + (build_new_reduction): Set reduc_version to SSA_NAME_VERSION of + phi result. + (set_reduc_phi_uids): New function. + (gather_scalar_reductions): Call it at the end through htab_traverse. + +2010-12-18 Nicola Pero <nicola.pero@meta-innovation.com> + + * c-parser.c (c_parser_objc_try_catch_finally_statement): Call + objc_maybe_warn_exceptions. + (c_parser_objc_synchronized_statement): Call + objc_maybe_warn_exceptions. + +2010-12-18 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/46985 + * tree-scalar-evolution.c (instantiate_scev_r): If chrec is NULL, + return it immediately. + +2010-12-18 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + PR target/46915 + * config/pa/pa.c (branch_to_delay_slot_p): Use next_active_insn instead + of next_real_insn. Search forward checking for both ASM_INPUT and + ASM_OPERANDS asms until exit condition is found. + (branch_needs_nop_p): Likewise. + (use_skip_p): New function. + (output_cbranch): Use use_skip_p. + (output_bb, output_bvb): Likewise. + +2010-12-18 Kai Tietz <kai.tietz@onevision.com> + + PR target/36834 + * config/i386/i386.c (ix86_keep_aggregate_return_pointer): + New local function. + (ix86_return_pops_args): Use ix86_keep_aggregate_return_pointer + function instead of KEEP_AGGREGATE_RETURN_POINTER. + (ix86_handle_callee_pop_aggregate_return): New handler. + (ix86_attribute_table): Add new attribute + callee_pop_aggregate_return. + * doc/extend.texi (callee_pop_aggregate_return): Add + attribute documentation. + +2010-12-18 Iain Sandoe <iains@gcc.gnu.org> + + * config/darwin.h (SUBTARGET_C_COMMON_OVERRIDE_OPTIONS): + Only set sjlj exceptions for NeXT/m32. + +2010-12-18 Iain Sandoe <iains@gcc.gnu.org> + + * config/darwin.h (GCC_DRIVER_HOST_INITIALIZATION): + Only expose when not building for target. + +2010-12-17 Joseph Myers <joseph@codesourcery.com> + + * config/netbsd.opt, config/netbsd-elf.opt: New files. + * config.gcc (alpha*-*-netbsd*, arm*-*-netbsdelf*, arm*-*-netbsd*, + i[34567]86-*-netbsdelf*, i[34567]86-*-netbsd*, x86_64-*-netbsd*, + m68k*-*-netbsdelf*, mips*-*-netbsd*, powerpc-*-netbsd*, + sh*-*-netbsd*, sparc-*-netbsdelf*, sparc64-*-netbsd*, + vax-*-netbsdelf*, vax-*-netbsd*): Use these .opt files. + +2010-12-17 Richard Henderson <rth@redhat.com> + + * regcprop.c (find_oldest_value_reg): Continue search instead of + failing if an element in the copy chain is of the wrong regclass. + +2010-12-17 Paolo Bonzini <bonzini@gnu.org> + + PR c/20385 + * function.c (used_types_insert): Handle ERROR_MARK. + * c-decl.c (grokdeclarator): Handle ERROR_MARK. + (declspecs_add_type): Leave error_mark_node in specs->type. + (finish_declspecs): Change it to integer_type_node here. + * c-parser.c (c_parser_peek_2nd_token): Move earlier. + (enum c_lookahead_kind): New. + (c_parser_next_token_starts_typename): New name of + c_parser_next_tokens_start_typename. Accept lookahead enum + and handle it here instead of... + (c_parser_next_tokens_start_declaration): ... here. Call it. + (c_parser_declspecs): Accept another argument. Do not exit + on C_ID_ID if it is guessed to be an unknown typename. + (c_parser_parms_declarator): Use 2nd token to distinguish a K&R + declaration from an ANSI declaration starting with an unknown + typename. + (c_parser_struct_declaration, c_parser_objc_type_name, + c_parser_typeof_specifier, c_parser_declarator, + c_parser_direct_declarator_inner): Adjust calls. + (c_parser_parameter_declaration): Likewise. + (c_parser_type_name): Pass back an error_mark_node to the caller. + (c_parser_postfix_expression): Do error recovery when + c_parser_type_name returns NULL. + +2010-12-17 Joseph Myers <joseph@codesourcery.com> + + * config/i386/netware.h (ASM_SPEC, SIZE_TYPE, PTRDIFF_TYPE): Define. + * config/i386/nto.h (LIB_SPEC, ASM_SPEC): Define. + (DBX_REGISTER_NUMBER): Undefine. + * config/i386/sol2.h (SIZE_TYPE, PTRDIFF_TYPE): Define. + * config/i386/vxworksae.h (ASM_SPEC, SIZE_TYPE, PTRDIFF_TYPE): + Define. + * config.gcc (i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | + i[34567]86-*-knetbsd*-gnu | i[34567]86-*-gnu* | + i[34567]86-*-kopensolaris*-gnu, x86_64-*-linux* | + x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu, + i[3456x]86-*-netware*, i[34567]86-*-nto-qnx*, + i[34567]86-*-solaris2*, + i[4567]86-wrs-vxworks|i[4567]86-wrs-vxworksae): Don't use svr4.h. + +2010-12-17 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/i386.c (move_or_delete_vzeroupper_2): Replace + "BB [%i]" with "[bb %i]" in dump. + (move_or_delete_vzeroupper_1): Likewise. + (rescan_move_or_delete_vzeroupper): Likewise. Always dump + upper 128bit state at exit. + +2010-12-17 Joseph Myers <joseph@codesourcery.com> + + * config/interix.opt: New. + * config/interix.h (LINK_SPEC): Don't handle -soname*. + * config.gcc (i[34567]86-*-interix3*): Use interix.opt. + +2010-12-17 Andrew Stubbs <ams@codesourcery.com> + + * config/arm/arm.md (maddhisi4, *maddhidi4): Use the canonical + operand order for plus. + Drop redundant % from constraints. + +2010-12-17 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * config/spu/t-spu-elf (LIB2FUNCS_EXCLUDE): Add _floattisf and + _floatunstisf. + * config/spu/spu.md ("floattisf2"): New expander. + ("floatunstisf2"): New insn pattern and splitter. + ("cgt_ti_m1"): New insn pattern. + +2010-12-17 Bernd Schmidt <bernds@codesourcery.com> + + * config/arm/arm.c (arm_select_cc_mode): Before calling + arm_select_dominance_cc_mode for AND or IOR operations, ensure + that op is NE or EQ. + +2010-12-17 Alexander Monakov <amonakov@ispras.ru> + + PR middle-end/46761 + * graphite-clast-to-gimple.c (graphite_create_new_loop_guard): Prefer + to use unadjusted UB. + +2010-12-17 Dodji Seketeli <dodji@redhat.com> + + * dwarf2out.c (gen_type_die_with_usage): Do not try to emit debug + info for a redundant typedef that has DECL_ORIGINAL_TYPE set. Use + that underlying type instead. + +2010-12-16 Jan Hubicka <jh@suse.cz> + + PR middle-end/44563 + * ipa-inline.c: Update doplevel comment. + (cgraph_estimate_size_after_inlining): Remove times attribute. + (cgraph_mark_inline_edge): Update. + (cgraph_mark_inline): Remove. + (cgraph_estimate_growth): Update. + (cgraph_check_inline_limits): Remove one only argument. + (cgraph_edge_badness): Update. + (cgraph_decide_recursive_inlining): Update. + (cgraph_decide_inlining_of_small_function): Fix handling of + tree_can_inline_p and call_stmt_cannot_inline_p. + (cgraph_flatten): Likewise. + (cgraph_decide_inlining): Update. + (cgraph_decide_inlining_incrementally): Fix handling of + call_stmt_cannot_inline_p. + +2010-12-16 Joseph Myers <joseph@codesourcery.com> + + * config/darwin.opt (dylinker, headerpad_max_install_names, + keep_private_externs, nofixprebinding, nomultidefs, noprebind, + noseglinkedit, object, prebind, prebind_all_twolevel_modules, + preload, private_bundle, pthread, seglinkedit, twolevel_namespace, + twolevel_namespace_hints, whatsloaded, whyload, y, Mach, X): New + Driver options. + * config/darwin.h (LINK_SPEC): Remove '*' after + headerpad_max_install_names. + +2010-12-16 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/46924 + * graphite-sese-to-poly.c (detect_commutative_reduction): Do not + detect reductions outside the current SESE region. + * sese.h (stmt_in_sese_p): New. + (defined_in_sese_p): Call stmt_in_sese_p. + +2010-12-16 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/46966 + * graphite-sese-to-poly.c (build_scop_drs): Call free_gimple_bb for + for bbs that are removed from SCOP_BBS vector. + +2010-12-16 Eric Botcazou <ebotcazou@adacore.com> + + * tree-ssa-sccvn.c (vn_reference_lookup_3): Always punt if the call to + get_ref_base_and_extent returns -1 as the max size. + +2010-12-16 Konrad Eisele <konrad@gaisler.com> + Eric Botcazou <ebotcazou@adacore.com> + + Support for LEON processor + * config.gcc (sparc-*-elf*): Deal with sparc-leon specifically. + (sparc-*-linux*): Likewise. + (sparc-*-rtems*): Remove Solaris left-overs. + (sparc*-*-*): Remove obsolete sparc86x setting. + (sparc-leon*): Default to --with-cpu=v8 and --with-tune=leon. + * doc/invoke.texi (SPARC Options): Document -mcpu/-mtune=leon. + * config/sparc/sparc.h (TARGET_CPU_leon): Define. + (TARGET_CPU_sparc86x): Delete. + (TARGET_CPU_cypress): Define as alias to TARGET_CPU_v7. + (TARGET_CPU_f930): Define as alias to TARGET_CPU_sparclite. + (TARGET_CPU_f934): Likewise. + (TARGET_CPU_tsc701): Define as alias to TARGET_CPU_sparclet. + (CPP_CPU_SPEC): Add entry for -mcpu=leon. + (enum processor_type): Add PROCESSOR_LEON. Reorganize. + * config/sparc/sparc.c (leon_costs): New cost array. + (sparc_option_override): Add entry for TARGET_CPU_leon and -mcpu=leon. + Initialize cost array to leon_costs if -mtune=leon. + * config/sparc/sparc.md (cpu attribute): Add leon. Reorganize. + Include leon.md scheduling description. + * config/sparc/leon.md: New file. + * config/sparc/t-elf: Do not assemble Solaris startup files. + * config/sparc/t-leon: New file. + * config/sparc/t-leon3: Likewise. + +2010-12-16 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/43655 + * tree-ssa-ter.c (is_replaceable_p): Don't use + gimple_references_memory_p for -O0, instead check for load + by looking at rhs. + +2010-12-16 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/46404 + * graphite-clast-to-gimple.c (gloog): Call scev_reset. + +2010-12-16 Anatoly Sokolov <aesok@post.ru> + + * config/sh/sh.h (OUTPUT_ADDR_CONST_EXTRA): Remove. + * config/sh/sh.c (sh_asm_output_addr_const_extra): New function. + (TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA): Define. + +2010-12-16 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * config/spu/t-spu-elf (LIB2_SIDITI_CONV_FUNC): Define. + * config/spu/spu.h (MIN_UNITS_PER_WORD): Do not define. + (LIBGCC2_UNITS_PER_WORD): Define if not already defined. + +2010-12-16 Jakub Jelinek <jakub@redhat.com> + + PR debug/46893 + * cfgexpand.c (expand_debug_expr): If GET_MODE (op0) is VOIDmode, + use TYPE_MODE (TREE_TYPE (tem)) instead of mode1. + +2010-12-16 Chung-Lin Tang <cltang@codesourcery.com> + + PR target/46883 + * config/arm/arm.md + (zero_extendhisi2 for register input splitter): Change + "register_operand" to "s_register_operand". + (zero_extendqisi2 for register input splitter): Same. + +2010-12-16 Jan Hubicka <jh@suse.cz> + + PR middle-end/46939 + * predic.c (predict_paths_leading_to_edge): New function. + (apply_return_prediction): Use it. + (predict_paths_for_bb): Do not special case abnormals. + +2010-12-16 Joseph Myers <joseph@codesourcery.com> + + * config.gcc (powerpc-*-lynxos*): Don't add lynx.opt to + extra_options twice. + +2010-12-15 Joseph Myers <joseph@codesourcery.com> + + * doc/tm.texi.in (US_SOFTWARE_GOFAST): Don't document. + * doc/tm.texi: Regenerate. + * system.h (US_SOFTWARE_GOFAST): Poison. + * config.gcc (enable_gofast): Don't handle. + * config/gofast.h: Remove. + * config/mips/t-gofast: Remove. + * config/fp-bit.c (US_SOFTWARE_GOFAST): Don't handle. + * config/fp-bit.h (US_SOFTWARE_GOFAST): Don't handle. + * config/mips/elforion.h: Don't mention GOFAST in comment. + * config/mips/mips.c: Don't include gofast.h. + (mips_init_libfuncs): Don't call gofast_maybe_init_libfuncs. + * config/mips/t-sr71k (dp-bit.c, fp-bit.c): Don't define + US_SOFTWARE_GOFAST. + * config/sparc/sparc.c: Don't include gofast.h. + (sparc_init_libfuncs): Don't call gofast_maybe_init_libfuncs. + * config/spu/t-spu-elf (dp-bit.c, fp-bit.c): Don't undefine + US_SOFTWARE_GOFAST. + +2010-12-14 Jan Hubicka <jh@suse.cz> + + * config/darwin.opt (dylinker, headerpad_max_install_names, + keep_private_externs, nofixprebinding, nomultidefs, noprebind, + noseglinkedit, object, prebind, prebind_all_twolevel_modules, + preload, private_bundle, pthread, seglinkedit, twolevel_namespace, + twolevel_namespace_hints, whatsloaded, whyload, y, Mach, X): New + Driver options. + * config/darwin.h (LINK_SPEC): Remove '*' after + headerpad_max_install_names. + +2010-12-14 Jan Hubicka <jh@suse.cz> + + * tree.c (get_file_function_name): Avoid using random seed on + GLOBAL_sub_I and GLOBAL_sub_D. + +2010-12-15 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/46053 + PR middle-end/46287 + PR middle-end/46242 + * cgraph.h (cgraph_indirect_call_info): New field thunk_delta. + * gimple.h (gimple_fold_obj_type_ref): Declaration removed. + (gimple_fold_call): Declare. + (gimple_adjust_this_by_delta): Likewise. + * cgraph.c (cgraph_make_edge_direct): New parameter delta. Updated + all users. + (cgraph_clone_edge): Create a copy of indirect_info also for direct + edges. + * cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee): Adjust this + parameters. + * gimple-fold.c (gimple_fold_obj_type_ref_known_binfo): Renamed to + gimple_get_virt_mehtod_for_binfo, new parameter delta. Do not search + through thunks, in fact bail out if we encounter one, check that + BINFO_VIRTUALS is not NULL. + (gimple_adjust_this_by_delta): New function. + (gimple_fold_obj_type_ref): Removed. + (gimple_fold_obj_type_ref_call): New function. + (fold_gimple_call): Renamed to gimple_fold_call, made external. + Updated users. Call gimple_fold_obj_type_ref_call instead of + gimple_fold_obj_type_ref. + * ipa-cp.c (ipcp_process_devirtualization_opportunities): Process + thunk deltas. + (ipcp_discover_new_direct_edges): Likewise. + * ipa-prop.c (ipa_make_edge_direct_to_target): New parameter delta. + Updated callers. + (ipa_write_indirect_edge_info): Stream thunk_delta. + (ipa_read_indirect_edge_info): Likewise. + * tree-ssa-ccp.c (ccp_fold_stmt): Use gimple_fold_call instead of + gimple_fold_obj_type_ref. + +2010-12-15 Alexander Monakov <amonakov@ispras.ru> + + PR rtl-optimization/46649 + * sel-sched-ir.c (purge_empty_blocks): Unconditionally skip the first + basic block in the region. + +2010-12-15 Joseph Myers <joseph@codesourcery.com> + + * config/stormy16/stormy16.h (LINK_SPEC, WCHAR_TYPE): Define. + * config.gcc (xstormy16-*-elf): Don't use svr4.h. + +2010-12-15 Joseph Myers <joseph@codesourcery.com> + + * config/rx/rx.h (WCHAR_TYPE, WCHAR_TYPE_SIZE): Define. + * config.gcc (rx-*-elf*): Don't use svr4.h. + +2010-12-14 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/46845 + * sese.c (scalar_evolution_in_region): Handle scop parameters + before scev analysis. + +2010-12-14 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/46928 + * tree-data-ref.c (analyze_overlapping_iterations): Handle A[p] == A[p] + in data dependence analysis with p a parameter of the loop. + +2010-12-14 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/45948 + * tree-loop-distribution.c (ssa_name_has_uses_outside_loop_p): New. + (stmt_has_scalar_dependences_outside_loop): New. + (stmt_generated_in_another_partition): New. + (add_scalar_computations_to_partition): New. + (rdg_build_partitions): Call add_scalar_computations_to_partition. + +2010-12-14 Joseph Myers <joseph@codesourcery.com> + + * config/arc/arc.h (LIB_SPEC): Define. + * config.gcc (arc-*-elf*): Don't use svr4.h. + +2010-12-14 Joseph Myers <joseph@codesourcery.com> + + * config/sh/elf.h (LIB_SPEC): Define. + * config.gcc (sh-*-elf* | sh[12346l]*-*-elf* | sh-*-symbianelf* | + sh[12346l]*-*-symbianelf* | sh-*-linux* | sh[2346lbe]*-*-linux* | + sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | + sh5l*-*-netbsd* | sh64-*-netbsd* | sh64l*-*-netbsd*, sh-*-rtems*, + sh-wrs-vxworks): Don't use svr4.h. + +2010-12-14 Jan Hubicka <jh@suse.cz> + + PR lto/46940 + PR lto/44463 + * lto-symtab.c (lto_symtab_merge_cgraph_nodes_1): Construct nodes + for aliases when they are used. + +2010-12-14 Joseph Myers <joseph@codesourcery.com> + + * config.gcc (sparc-*-elf*, sparc-*-rtems*, sparc-*-linux*, + sparc-*-netbsdelf*, sparc*-*-solaris2*, sparc-wrs-vxworks, + sparc64-*-elf*, sparc64-*-rtems*, sparc64-*-linux*, + sparc64-*-netbsd*, sparc64-*-openbsd*): Don't use svr4.h. + +2010-12-14 Thomas Klein <th.r.klein@web.de> + + * config/arm/arm.c (arm_expand_prologue): Report the static stack + size if -fstack-usage is used. + (thumb1_expand_prologue): Likewise. + +2010-12-14 Jakub Jelinek <jakub@redhat.com> + + PR debug/46885 + * tree-ssa-loop-manip.c (canonicalize_loop_ivs): Use gsi_last_bb + instead of gsi_last_nondebug_bb if bump_in_latch. + + PR tree-optimization/46909 + * gimple-fold.c (and_var_with_comparison_1): Save partial + result even in the is_and case, if both partial results + are the same, return it. + (or_var_with_comparison_1): Use is_or predicate instead of + innercode == TRUTH_OR_EXPR test. Save partial result + even in the is_or case, if both partial results are the + same, return it. In the !is_or case when both partial + results are the same, return the partial result instead + of boolean_true_node. + +2010-12-14 Jan Hubicka <jh@suse.cz> + + PR middle-end/46667 + * varasm.c (assemble_start_function): Do not call + resolve_unique_section. + * cfgexpand.c (gimple_expand_cfg): Resolve it here. + +2010-12-14 Alexander Monakov <amonakov@ispras.ru> + + PR rtl-optimization/46875 + * sched-vis.c (print_pattern): Dump "sequence" for ADDR_VECs. + * sel-sched-ir.c (bb_has_removable_jump_to_p): Forbid table jumps. + +2010-12-14 Kaushik Phatak <kaushik.phatak@kpitcummins.com> + + * config/h8300/h8300.md (define_split) : Add condition for + "and with single_zero" splitter to handle 16-bit const operands. + * config/h8300/h8300.md (define_split) : Add condition for + "ior with single_one" splitter to handle 16-bit const operands. + * config/h8300/h8300.md (define_split) : Add condition for + "xor with single_one" splitter to handle 16-bit const operands. + * testsuite/gcc.dg/h8300-bit-insn-ice.c: New. + +2010-12-13 Jan Hubicka <jh@suse.cz> + + PR middle-end/45388 + * ipa.c (cgraph_build_static_cdtor_1): Break out from ... Add FINAL + parameter. + (cgraph_build_static_cdtor): ... here. + (build_cdtor): Use cgraph_build_static_cdtor_1. + +2010-12-13 Joseph Myers <joseph@codesourcery.com> + + * config/m32c/m32c.h (ENDFILE_SPEC, LINK_SPEC, SIZE_TYPE, + PTRDIFF_TYPE, WCHAR_TYPE, WCHAR_TYPE_SIZE): Define. + * config.gcc (m32c-*-rtems*, m32c-*-elf*): Don't use svr4.h. + +2010-12-14 Bernd Schmidt <bernds@codesourcery.com> + + PR rtl-optimization/44374 + Reapply patch with fixes. + * basic-block.h (enum bb_flags): Add BB_MODIFIED. + * df-core.c (df_set_bb_dirty): Set it. + * ifcvt.c (find_memory): Remove function. + (dead_or_predicable): Use can_move_insns_across. + * df.h (can_move_insns_across): Declare function. + * cfgcleanup.c (block_was_dirty): New static variable. + (flow_find_head_matching_sequence): Test for epilogue notes. + (try_crossjump_bb, try_forward_edges): Test BB_MODIFIED flag rather + than df_get_bb_dirty. + (try_head_merge_bb): New static function. + (try_optimize_cfg): Call it. Call df_analyze if block_was_dirty + is set. + * df-problems.c: Include "target.h" + (df_simulate_find_uses): New static function. + (MEMREF_NORMAL, MEMREF_VOLATILE): New macros. + (find_memory, find_memory_store): New static functions. + (can_move_insns_across): New function. + * Makefile.in (df-problems.o): Update dependencies. + +2010-12-13 Joseph Myers <joseph@codesourcery.com> + + * config/xtensa/elf.h (SIZE_TYPE, PTRDIFF_TYPE): Define. + (DBX_REGISTER_NUMBER): Undefine. + * config/xtensa/linux.h (SIZE_TYPE, PTRDIFF_TYPE): Define. + (DBX_REGISTER_NUMBER): Undefine. + * config.gcc (xtensa*-*-elf*, xtensa*-*-linux*): Don't use svr4.h. + +2010-12-13 Jack Howarth <howarth@bromo.med.uc.edu> + Joseph Myers <joseph@codesourcery.com> + + PR bootstrap/46650 + * system.h: Include cstring for cxx bootstrap. + +2010-12-13 Jakub Jelinek <jakub@redhat.com> + + PR lto/46879 + * lto-streamer-out.c (output_gimple_stmt): Never replace first + GIMPLE_DEBUG argument with MEM_REF. + + PR debug/46867 + * var-tracking.c (emitted_notes, string_pointer_flags): Removed. + (emit_note_insn_var_location): Remove ENABLE_RTL_CHECKING verification. + (vt_emit_notes): Don't initialize and destroy emitted_notes. + +2010-12-13 Nathan Froyd <froydnj@codesourcery.com> + + PR target/46040 + * config.gcc (arm*-*-linux-*eabi): Use bpabi-lib.h. + (arm*-*-uclinux*eabi, arm*-*-eabi*): Likewise. + +2010-12-13 Joseph Myers <joseph@codesourcery.com> + + * config/v850/v850.h (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE, + WCHAR_TYPE_SIZE): Define. + * config.gcc (v850e1-*-*, v850e-*-*, v850-*-*): Don't use svr4.h. + +2010-12-13 Joseph Myers <joseph@codesourcery.com> + + * config.gcc (s390-*-linux*, s390x-*-linux*, s390x-ibm-tpf*): + Don't use svr4.h. + +2010-12-13 Joseph Myers <joseph@codesourcery.com> + + * config/mn10300/linux.h (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE, + WCHAR_TYPE_SIZE): Undefine. + * config/mn10300/mn10300.h (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE, + WCHAR_TYPE_SIZE): Define. + * config.gcc (mn10300-*-*): Don't use svr4.h. + +2010-12-13 Joseph Myers <joseph@codesourcery.com> + + * config/m68k/linux.h (DBX_REGISTER_NUMBER): Undefine and redefine. + (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE, WCHAR_TYPE_SIZE): Define. + * config.gcc (m68k-*-uclinux*, m68k-*-linux*): Don't use svr4.h. + +2010-12-13 Alexandre Oliva <aoliva@redhat.com> + + PR debug/46756 + * jump.c (mark_all_labels): Skip debug insns. + +2010-12-13 Alexandre Oliva <aoliva@redhat.com> + + PR debug/46782 + * cfgcleanup.c (try_forward_edges): Skip debug insns. + +2010-12-12 Jan Hubicka <jh@suse.cz> + Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * varasm.c (default_function_section): Check flag_reorder_functions + and targetm.have_named_sections. + * config/darwin.c (darwin_function_section): Check + flag_reorder_functions. + +2010-12-12 Finn Thain <fthain@telegraphics.com.au> + + PR target/46179 + * config/m68k/m68k.c (handle_move_double): Insert calls to + m68k_final_prescan_insn to clean up @TLS operand syntax. + +2010-12-10 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/43023 + * tree-data-ref.c (mem_write_stride_of_same_size_as_unit_type_p): + Removed. + (stores_zero_from_loop): Call stmt_stores_zero. + * tree-data-ref.h (stmt_stores_zero): New. + * tree-loop-distribution.c (generate_memset_zero): Do not return a + boolean. Call gcc_assert on stride_of_unit_type_p. + (generate_builtin): Call stmt_stores_zero. + (rdg_flag_all_uses): Removed. + (rdg_flag_similar_memory_accesses): Removed. + (build_rdg_partition_for_component): Removed parameter + other_stores. Removed call to rdg_flag_similar_memory_accesses. + (can_generate_builtin): New. + (similar_memory_accesses): New. + (fuse_partitions_with_similar_memory_accesses): New. + (rdg_build_partitions): Call + fuse_partitions_with_similar_memory_accesses. + +2010-12-10 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/46804 + * regmove.c (optimize_reg_copy_3): Look for REG_EQUAL note + on the setter of src_reg rather than on insn. If it is + equal to the setter's original SET_SRC, replace it with its + zero or sign extension instead of dropping it. + +2010-12-10 Richard Guenther <rguenther@suse.de> + + PR lto/46808 + * lto-symtab.c (lto_symtab_merge_decls_2): Avoid type warnings + after errors. + (lto_symtab_merge_decls_1): Adjust. + +2010-12-10 Dave Korn <dave.korn.cygwin@gmail.com> + + PR middle-end/46674 + PR lto/43157 + * target.def (mangle_assembler_name): New target asm_out hook. + * targhooks.c (default_mangle_assembler_name): Add default hook + implementation. + * targhooks.h (default_mangle_assembler_name): Add prototype. + * lto-symtab.c (lto_symtab_register_decl): Use new hook when + processing DECL_ASSEMBLER_NAMEs for lto symtabs. + (lto_symtab_get_resolution): Likewise. + (lto_cgraph_replace_node): Likewise. + (lto_symtab_prevailing_decl): Likewise. + * lto-streamer-out.c (write_symbol): Likewise. + * doc/tm.texi.in (TARGET_MANGLE_ASSEMBLER_NAME): Add @hook directive. + * doc/tm.texi: Regenerate. + * config/i386/cygming.h (TARGET_MANGLE_ASSEMBLER_NAME): Define to + point at i386_pe_mangle_assembler_name. + * config/i386/winnt.c (i386_pe_mangle_assembler_name): New function. + * config/i386/i386-protos.h (i386_pe_mangle_assembler_name): Add + prototype. + +2010-12-10 Nathan Froyd <froydnj@codesourcery.com> + + * c-typeck.c (readonly_error): Delete. + +2010-12-10 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/46865 + * rtl.c (rtx_equal_p_cb, rtx_equal_p): For last operand of + ASM_OPERANDS and ASM_INPUT if integers are different, call locator_eq. + * jump.c (rtx_renumbered_equal_p): Likewise. + + PR tree-optimization/46864 + * tree-ssa-loop-im.c (loop_suitable_for_sm): Return false even + when there are EDGE_EH exit edges. + +2010-12-10 Tobias Burnus <burnus@net-b.de> + + PR fortran/46540 + * configure.ac: Handle --disable-libquadmath-support. + * doc/install.texi: Document --disable-libquadmath and + --disable-libquadmath-support + * configure: Regenerate. + * config.in: Regenerate. + +2010-12-10 Jack Howarth <howarth@bromo.med.uc.edu> + Iain Sandoe <iains@gcc.gnu.org> + + PR 43751/target + * config/darwin9.h (DSYMUTIL_SPEC): Add fortran source types. + +2010-12-10 Iain Sandoe <iains@gcc.gnu.org> + + * config/rs6000/rs6000.c + (rs6000_darwin64_record_arg_advance_recurse): Name register increment + explicitly. (rs6000_darwin64_record_arg_recurse): Make sure we split + long doubles when we run out of regs. Also flag that this requires + stack and therefore cannot be returned by value. + (rs6000_darwin64_record_arg): Update comment. + (rs6000_function_value): Likewise. + +2010-12-10 Nicola Pero <nicola.pero@meta-innovation.com> + + * c-parser.c (c_parser_objc_class_definition): Recognize + Objective-C 2.0 class extensions. + +2010-12-10 Iain Sandoe <iains@gcc.gnu.org> + + * config/darwin.c: Remove c-tree.h and c-lang.h + * config/t-darwin: Remove dependencies on c-tree.h and c-lang.h. + +2010-12-10 Joern Rennecke <amylaar@spamcop.net> + + PR target/46881 + * doc/tm.texi: Regenerate. + * target.def: Fix "preferred" spelling. Refer to rclass by its + exact name. + * config/arm/arm.c (arm_preferred_rename_class): Rename parameter class + to rclass. + +2010-12-09 Paul Koning <ni1d@arrl.net> + + * config/pdp11/pdp11-protos.h (output_move_double, + output_move_quad): Delete. + (output_move_multiple, pdp11_expand_operands): New functions. + (pdp11_action, pdp11_partorder): New enums. + * config/pdp11/pdp11.md (movdi, movsi, movdf, movsf): Use + output_move_multiple. + (adddi3, subdi3, negdi2): New patterns. + (addsi3, subsi3, negsi2): Use pdp11_expand_operands. + (abshi2): Delete. + (neghi2, negqi2): Use PDPint iterator. + * config/pdp11/pdp11.c (find_addr_reg, output_move_double, + output_move_quad): Delete. + (pdp11_expand_operands, output_move_multiple): New functions. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/vax/linux.h (WCHAR_TYPE, WCHAR_TYPE_SIZE): Define. + * config.gcc (vax-*-linux*): Don't use svr4.h. + +2010-12-09 Nathan Froyd <froydnj@codesourcery.com> + + * c-typeck.c (build_indirect_ref): Call invalid_indirection_error. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * doc/extend.texi (Attribute Syntax): Correct description of + attributes in pointer declarators. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/mips/vxworks.h (DBX_REGISTER_NUMBER): Undefine. + * config.gcc (mips64*-*-linux* | mipsisa64*-*-linux*, + mips*-*-linux*, mips-wrs-vxworks): Don't use svr4.h. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/mep/mep.h (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE, + WCHAR_TYPE_SIZE): Define. + * config.gcc (mep-*-*): Don't use svr4.h. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/mcore/mcore.h (PTRDIFF_TYPE, WCHAR_TYPE, + WCHAR_TYPE_SIZE): Define. + * config/svr3.h (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE, + WCHAR_TYPE_SIZE): Don't define. + * config.gcc (mcore-*-elf): Don't use svr4.h. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config.gcc (m32r-*-elf*, m32rle-*-elf*, m32r-*-rtems*, + m32r-*-linux*, m32rle-*-linux*): Don't use svr4.h. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/iq2000/iq2000.h (LINK_SPEC, SIZE_TYPE, PTRDIFF_TYPE, + WCHAR_TYPE, WCHAR_TYPE_SIZE): Define. + * config.gcc (iq2000*-*-elf*): Don't use svr4.h. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config.gcc (ia64*-*-linux*, ia64*-*-hpux*): Don't use svr4.h. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/pa/pa32-linux.h (WCHAR_TYPE, WCHAR_TYPE_SIZE): Define. + * config.gcc (hppa*64*-*-linux*, hppa*-*-linux*): Don't use svr4.h. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/moxie/moxie.h (LINK_SPEC, SIZE_TYPE, PTRDIFF_TYPE, + WCHAR_TYPE, WCHAR_TYPE_SIZE): Define. + * config/moxie/rtems.h (LINK_SPEC, SIZE_TYPE, PTRDIFF_TYPE, + WCHAR_TYPE, WCHAR_TYPE_SIZE): Undefine. + * config.gcc (moxie-*-elf, moxie-*-uclinux*): Don't use svr4.h. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/frv/frv.h (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE, + WCHAR_TYPE_SIZE): Define. + * config.gcc (frv-*-elf, frv-*-*linux*): Don't use svr4.h. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/fr30/fr30.h (LIB_SPEC, LINK_SPEC, SIZE_TYPE, + PTRDIFF_TYPE, WCHAR_TYPE, WCHAR_TYPE_SIZE): Define. + * config.gcc (fr30-*-elf): Don't use svr4.h. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/cris/linux.h (SIZE_TYPE, PTRDIFF_TYPE): Define. + * config.gcc (crisv32-*-linux* | cris-*-linux*): Don't use svr4.h. + +2010-12-09 Richard Guenther <rguenther@suse.de> + + PR middle-end/46844 + * gimple-fold.c (canonicalize_constructor_val): Canonicalize addresses. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/i386/netware.h (TARGET_POSIX_IO): Define. + * config/i386/nto.h (TARGET_POSIX_IO): Define. + * config/ia64/hpux.h (TARGET_POSIX_IO): Define. + * config/moxie/moxie.h (TARGET_POSIX_IO): Don't undefine. + * config/openbsd.h (TARGET_POSIX_IO): Define. + * config/rtems.h (TARGET_POSIX_IO): Define. + * config/sh/embed-elf.h (TARGET_POSIX_IO): Don't undefine. + * config/sol2.h (TARGET_POSIX_IO): Define. + * config/svr4.h (TARGET_POSIX_IO): Don't define. + * config/vxworksae.h (TARGET_POSIX_IO): Define. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/i386/nto.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): Define. + * config/ia64/hpux.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): Define. + * config/linux.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): Don't + undefine. + * config/mips/linux.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): Don't + undefine. + * config/mips/netbsd.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): + Don't undefine. + * config/rs6000/linux.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): + Don't undefine. + * config/rs6000/linux64.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): + Don't undefine. + * config/sol2.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): Define. + * config/sparc/netbsd-elf.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): + Don't undefine. + * config/sparc/openbsd64.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): + Don't undefine. + * config/sparc/sp64-elf.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): + Don't undefine. + * config/svr4.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): Don't define. + * config/xtensa/elf.h (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): Don't + undefine. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/ia64/hpux.h (AS_NEEDS_DASH_FOR_PIPED_INPUT): Define for + non-GNU assembler. + * config/m68k/netbsd-elf.h (AS_NEEDS_DASH_FOR_PIPED_INPUT): Remove. + * config/m68k/openbsd.h (AS_NEEDS_DASH_FOR_PIPED_INPUT): Remove. + * config/mips/openbsd.h (AS_NEEDS_DASH_FOR_PIPED_INPUT): Remove. + * config/sol2.h (AS_NEEDS_DASH_FOR_PIPED_INPUT): Define for + non-GNU assembler. + * config/sparc/sparc.h (AS_NEEDS_DASH_FOR_PIPED_INPUT): Remove. + * config/svr4.h (AS_NEEDS_DASH_FOR_PIPED_INPUT): Remove. + +2010-12-09 Martin Jambor <mjambor@suse.cz> + + * ipa-prop.c (compute_complex_ancestor_jump_func): Work also if the + zero is the first phi parameter. + +2010-12-09 Martin Jambor <mjambor@suse.cz> + + * ipa-prop.h (struct ipa_parm_adjustment): New field alias_ptr_type. + * ipa-prop.c (ipa_modify_call_arguments): Use it. + * tree-sra.c (splice_param_accesses): Test that all accesses have the + same alias reference type. + (turn_representatives_into_adjustments): Set alias_ptr_type of the + adjustment. + +2010-12-09 Martin Jambor <mjambor@suse.cz> + + PR middle-end/46734 + * tree-sra.c (splice_param_accesses): Check that there are not + multiple ADDRESSABLE types. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/arc/arc.h (ASM_SPEC): Remove %{v}. + * config/bfin/bfin.h (ASM_SPEC): Remove %{v}. + * config/cris/cris.h (ASM_SPEC): Remove %{v:-v}. + * config/fr30/fr30.h (ASM_SPEC): Remove %{v}. + * config/frv/frv.h (ASM_SPEC): Remove %{v}. + * config/i386/linux.h (ASM_SPEC): Remove %{v}. + * config/i386/linux64.h (ASM_SPEC): Remove %{v}. + * config/i386/mingw-w64.h (ASM_SPEC): Remove %{v}. + * config/i386/sol2-10.h (ASM_SPEC): Remove %{v}. + * config/i386/vxworks.h (ASM_SPEC): Remove %{v}. + * config/i386/x86-64.h (ASM_SPEC): Remove %{v}. + * config/lm32/lm32.h (ASM_SPEC): Remove %{v}. + * config/m32r/m32r.h (ASM_SPEC): Remove %{v}. + * config/m68k/linux.h (ASM_SPEC): Remove %{v:-V}. + * config/microblaze/microblaze.h (ASM_SPEC): Remove %{v}. + * config/mips/mips.h (ASM_SPEC): Remove %{v}. + * config/mips/vxworks.h (ASM_SPEC): Remove %{v}. + * config/pa/pa-linux.h (ASM_SPEC): Remove %{v:-V}. + * config/rs6000/freebsd.h (SVR4_ASM_SPEC): Remove %{v}. + * config/rs6000/linux64.h (ASM_SPEC): Remove %{v:-V}. + * config/rs6000/vxworks.h (ASM_SPEC): Remove %{v:-v}. + * config/sparc/openbsd64.h (ASM_SPEC): Remove %{v:-V}. + * config/svr4.h (SVR4_ASM_SPEC): Remove %{v:-V}. + * config/xtensa/elf.h (ASM_SPEC): Remove %{v}. + * config/xtensa/linux.h (ASM_SPEC): Remove %{v}. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/i386/openbsdelf.h (LINK_SPEC): Use %{r:} not %{r*:}. + * config/mips/openbsd.h (LINK_SPEC): Use %{r:} not %{r*:}. + * config/netbsd-aout.h (NETBSD_LINK_SPEC_AOUT): Use %{r:} not %{r*:}. + * config/netbsd-elf.h (NETBSD_LINK_SPEC_ELF): Use %{r:} not %{r*:}. + * config/sparc/openbsd64.h (LINK_SPEC): Use %{r:} not %{r*:}. + * config/vax/netbsd-elf.h (LINK_SPEC): Use %{r:} not %{r*:}. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/alpha/freebsd.h (LINK_SPEC): Don't use %{!dynamic-linker:}. + * config/alpha/linux-elf.h (LINK_SPEC): Likewise. + * config/arm/freebsd.h (LINK_SPEC): Likewise. + * config/arm/linux-elf.h (LINUX_TARGET_LINK_SPEC): Likewise. + * config/bfin/linux.h (LINK_SPEC): Likewise. + * config/cris/linux.h (CRIS_LINK_SUBTARGET_SPEC): Likewise. + * config/frv/linux.h (LINK_SPEC): Likewise. + * config/i386/freebsd.h (LINK_SPEC): Likewise. + * config/i386/freebsd64.h (LINK_SPEC): Likewise. + * config/i386/linux.h (LINK_SPEC): Likewise. + * config/i386/linux64.h (LINK_SPEC): Likewise. + * config/i386/openbsdelf.h (LINK_SPEC): Likewise. + * config/ia64/freebsd.h (LINK_SPEC): Likewise. + * config/ia64/linux.h (LINK_SPEC): Likewise. + * config/lm32/uclinux-elf.h (LINK_SPEC): Likewise. + * config/m32r/linux.h (LINK_SPEC): Likewise. + * config/m68k/linux.h (LINK_SPEC): Likewise. + * config/microblaze/linux.h (LINK_SPEC): Likewise. + * config/mips/linux.h (LINK_SPEC): Likewise. + * config/mips/linux64.h (LINK_SPEC): Likewise. + * config/mips/openbsd.h (LINK_SPEC): Likewise. + * config/mn10300/linux.h (LINK_SPEC): Likewise. + * config/netbsd-elf.h (LINK_SPEC): Likewise. + * config/pa/pa-linux.h (LINK_SPEC): Likewise. + * config/rs6000/linux64.h (LINK_OS_LINUX_SPEC32, + LINK_OS_LINUX_SPEC64): Likewise. + * config/rs6000/sysv4.h (LINK_OS_FREEBSD_SPEC, + LINK_OS_LINUX_SPEC, LINK_OS_GNU_SPEC, LINK_OS_NETBSD_SPEC): Likewise. + * config/s390/linux.h (LINK_SPEC): Likewise. + * config/sh/linux.h (SUBTARGET_LINK_SPEC): Likewise. + * config/sparc/freebsd.h (LINK_SPEC): Likewise. + * config/sparc/linux.h (LINK_SPEC): Likewise. + * config/sparc/linux64.h (LINK_ARCH32_SPEC, LINK_ARCH64_SPEC, + LINK_SPEC): Likewise. + * config/sparc/openbsd64.h (LINK_SPEC): Likewise. + * config/vax/linux.h (LINK_SPEC): Likewise. + * config/xtensa/linux.h (LINK_SPEC): Likewise. + +2010-12-09 Joseph Myers <joseph@codesourcery.com> + + * config/bfin/bfin.h (ASM_SPEC): Remove %{n} and %{T}. + * config/frv/frv.h (ASM_SPEC): Likewise. + * config/i386/sol2-10.h (ASM_SPEC): Likewise. + * config/i386/sol2.h (ASM_SPEC): Likewise. + * config/m68k/linux.h (ASM_SPEC): Likewise. + * config/pa/pa-linux.h (ASM_SPEC): Likewise. + * config/rs6000/linux64.h (ASM_SPEC32): Likewise. + * config/rs6000/vxworks.h (ASM_SPEC): Likewise. + * config/sol2.h (ASM_SPEC): Likewise. + * config/sparc/linux.h (ASM_SPEC): Likewise. + * config/sparc/linux64.h (ASM_SPEC): Likewise. + * config/sparc/sp-elf.h (ASM_SPEC): Likewise. + * config/sparc/sysv4.h (ASM_SPEC): Likewise. + * config/svr4.h (SVR4_ASM_SPEC): Likewise. + +2010-12-09 Richard Guenther <rguenther@suse.de> + + * reginfo.c (struct subregs_of_mode_node): Remove. + (subregs_of_mode): Likewise. + (som_hash): Likewise. + (som_eq): Likewise. + (invalid_mode_changes): New bitmap. + (record_subregs_of_mode): Get subregs_of_mode argument. + Fill in invalid_mode_changes bitmap. + (find_subregs_of_mode): Get subregs_of_mode argument and pass + it through. + (init_subregs_of_mode): Adjust. + (finish_subregs_of_mode): Likewise. + (invalid_mode_change_p): Query invalid_mode_changes bitmap. + +2010-12-09 Richard Guenther <rguenther@suse.de> + + * ira.c (ira): Do not call finish_subregs_of_mode. + * ira-costs.c (finish_costs): Call finish_subregs_of_mode. + +2010-12-09 Richard Guenther <rguenther@suse.de> + + * rtl.h (invalid_mode_change_p): Adjust prototype. + * reginfo.c (invalid_mode_change_p): Remove from argument. + * ira-costs.c (print_allocno_costs): Adjust callers. + (find_costs_and_classes): Likewise. + +2010-12-09 Jakub Jelinek <jakub@redhat.com> + + * config/s390/s390.md (*mov<mode>cc): Change lgoc and stgoc to + locg and stocg even in comment. + (sync_old_<atomic><mode>): Give mode to UNSPEC_VOLATILE. + + PR target/41082 + * config/rs6000/rs6000.c (rs6000_expand_vector_extract): Use stvx + instead of stve*x. + (altivec_expand_stv_builtin): For op0 use mode of operand 1 instead + of operand 0. + * config/rs6000/altivec.md (VI_scalar): New mode attr. + (altivec_stve<VI_char>x, *altivec_stvesfx): Use scalar instead of + vector mode for operand 0, put operand 1 into UNSPEC. + +2010-12-09 Yao Qi <yao@codesourcery.com> + + * config/arm/arm.c (arm_preferred_rename_class): Implement targethook + PREFERRED_RENAME_CLASS. + +2010-12-08 Ian Lance Taylor <iant@google.com> + + * doc/sourcebuild.texi (Front End): Remove reference to + snapshot-README and snapshot-index.html. + +2010-12-08 Ian Lance Taylor <iant@google.com> + + * doc/sourcebuild.texi (Texinfo Manuals): Change update_web_docs + to update_web_docs_svn. + (Front End): Likewise. + +2010-12-08 Iain Sandoe <iains@gcc.gnu.org> + + * gcc/config.gcc (with_cpu): Default i[34567]86-*-darwin* and + x86_64-*-darwin* to with_cpu:-core2. + * gcc/config/i386/mmx.md (*mov<mode>_internal_rex64): Replace movq + with movd for darwin assembler. + * gcc/config/i386/sse.md (*vec_concatv2di_rex64_sse4_1): Ditto. + (*vec_concatv2di_rex64_sse): Ditto. + +2010-12-08 Richard Guenther <rguenther@suse.de> + Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/45230 + PR tree-optimization/45231 + PR tree-optimization/45370 + * sese.c (rename_uses): Returns a bool. Call + recompute_tree_invariant_for_addr_expr only on the RHS of a + GIMPLE_ASSIGN. + (graphite_copy_stmts_from_block): Call fold_stmt_inplace when + rename_uses returns true. + * tree-ssa-copy.c (replace_exp): Add a comment about calling + fold_stmt_inplace after replace_exp. + +2010-12-08 Mike Stump <mikestump@comcast.net> + + PR debug/46749 + * config/darwin.h (COLLECT_RUN_DSYMUTIL): Add. + (DSYMUTIL_SPEC): Use `linker' flags instead to handle lto better. + * config/darwin9.h (COLLECT_RUN_DSYMUTIL): Add. + (DSYMUTIL_SPEC): Use `linker' flags instead to handle lto better. + * collect2.c (post_ld_pass): Add. + (process_args): Add. + (maybe_run_lto_and_relink): Call post_ld_pass after ld. + (main): Likewise. Call process_args. + +2010-12-08 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/46844 + * regrename.c (check_new_reg_p): Add ATTRIBUTE_UNUSED to reg parameter. + +2010-12-08 Richard Earnshaw <rearnsha@arm.com> + + PR target/46631 + * arm.c (thumb2_reorg): Also try to reduce <commutative_op> Rd, Rn, Rd + into a 16-bit instruction. + +2010-12-08 Michael Meissner <meissner@linux.vnet.ibm.com> + + PR middle-end/42694 + * builtins.c (expand_builtin_pow_root): Don't optimize pow(x,y) + where y is 0.25, 1./6., or 0.75 if the target does not have a sqrt + instruction, but do optimize if y is 0.5 or 1./3. since that + changes an expensive call into a cheaper one. + +2010-12-08 Richard Guenther <rguenther@suse.de> + + * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Use a shift + instead of a division to divide by BITS_PER_UNIT. + +2010-12-08 Richard Guenther <rguenther@suse.de> + + * gimplify.c (gimple_tree_eq): Assert hashes are equal only + when checking is enabled. + +2010-12-07 Andrey Belevantsev <abel@ispras.ru> + + PR target/43603 + * haifa-sched.c (sched_create_recovery_edges): Update + dominator info. + * sel-sched-ir.c (maybe_tidy_empty_bb): Update dominator info + after deleting an empty block. + (tidy_control_flow): Also verify dominators. + (sel_remove_bb): Update dominator info after removing a block. + (sel_redirect_edge_and_branch_force): Assert that no unreachable + blocks will be created. Update dominator info. + (sel_redirect_edge_and_branch): Update dominator info when + basic blocks do not become unreachable. + (sel_remove_loop_preheader): Update dominator info. + +2010-12-07 Richard Guenther <rguenther@suse.de> + + * tree-vect-data-refs.c (vect_create_addr_base_for_vector_ref): + Reset alignment information. + (bump_vector_ptr): Likewise. + +2010-12-07 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + PR middle-end/46671 + PR target/46685 + * config/pa/pa.c (pa_function_section): New function. + (TARGET_ASM_FUNCTION_SECTION): Define. + +2010-12-07 Ian Lance Taylor <iant@google.com> + Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + PR bootstrap/46810 + * configure.ac: Disable AC_MSG_ERROR while looking for the C++ + preprocessor. + * configure: Rebuild. + +2010-12-07 Paul Koning <ni1d@arrl.net> + + * config/pdp11/pdp11.c (output_addr_const_pdp11): Output negative + values with sign rather than as unsigned. + +2010-12-07 Paul Koning <ni1d@arrl.net> + + * config/pdp11/pdp11.c (TARGET_ASM_FUNCTION_SECTION): Define. + (pdp11_function_section): New function. + +2010-12-07 Joseph Myers <joseph@codesourcery.com> + + * config/mcore/mcore.c Don't include assert.h. + (layout_mcore_frame, handle_structs_in_regs): Use gcc_assert. + * config/spu/spu.c: Don't include assert.h. + (spu_sms_res_mii): Use gcc_assert. + +2010-12-07 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/42327 + * tree-data-ref.c (omega_setup_subscript): Call build_int_cst + instead of using integer_minus_one_node. + +2010-12-07 Nathan Froyd <froydnj@codesourcery.com> + + PR c++/45330 + * params.def (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP): New parameter. + * doc/invoke.texi (cxx-max-namespaces-for-diagnostic-help): Document. + +2010-12-07 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/46832 + * tree-ssa-math-opts.c (execute_optimize_widening_mul): Check + that the call has a lhs. + +2010-12-07 Yao Qi <yao@codesourcery.com> + + * Makefile.in: Add $(TARGET_H) to the regrename.o rule. + * regrename.c (struct du_head): Add new element length. + (sort_du_head, get_element, merge, merge_sort_comparison): + New functions of merge sort implementation to du_head list. + (regrename_optimize): Sort du_head linked list by length. + Iterate registers in a preferred-register-first order. + Move some code to ... + (check_new_reg_p): here. New function. + (create_new_chain): Initialize length. + (scan_rtx_reg): Increase length for non-debug insns. + * target.def: New hook preferred_rename_class. + * targhook.c (default_preferred_rename_class): New. + * targhook.h: Declare it. + * doc/tm.texi.in: New hook TARGET_PREFERRED_RENAME_CLASS. + * doc/tm.texi: Regenerate. + +2010-12-07 Jakub Jelinek <jakub@redhat.com> + + PR debug/46799 + * tree-parloops.c (separate_decls_in_region): Use UNKNOWN_LOCATION + instead of BUILTINS_LOCATION. + (create_loop_fn): Add LOC argument, pass it to build_decl instead of + BUILTINS_LOCATION. + (create_parallel_loop): Add LOC argument, use it for OMP clauses + and GIMPLE_*OMP* statements. + (gen_parallel_loop): Determine locus for the parallel loop, pass it + to create_loop_fn and create_parallel_loop. + * cfgexpand.c (gimple_expand_cfg): For builtin functions, call + set_curr_insn_source_location (UNKNOWN_LOCATION). + +2010-12-07 Joern Rennecke <amylaar@spamcop.net> + Richard Guenther <rguenther@suse.de> + + PR target/46737 + * config/bfin/bfin.c (BB_AUX_INDEX): Cast to intptr_t. + (bfin_reorder_loops): Change type of index to intptr_t. + +2010-12-07 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/46726 + * tree-inline.c (estimate_num_insns): Special case pow (x, 2.0). + +2010-12-07 Richard Guenther <rguenther@suse.de> + + * tree-ssa-math-opts.c (execute_optimize_widening_mul): Unlink + virtual operands. + +2010-12-07 Nicola Pero <nicola.pero@meta-innovation.com> + + * c-parser.c (c_parser_typeof_specifier): Removed special + treatment of objc_volatilized attribute for Objective-C. + +2010-12-06 Vladimir Makarov <vmakarov@redhat.com> + + * ira.c (update_equiv_regs): Prohibit move insns if + pressure-sensitive scheduling was done. + +2010-12-06 Nicola Pero <nicola.pero@meta-innovation.com> + + * c-parser.c (c_parser_for_statement): Use c_fully_fold() instead + of c_process_expr_stmt() for the iterating and collection + expressions of an Objective-C fast enumeration loop. + +2010-12-06 Jakub Jelinek <jakub@redhat.com> + + PR debug/45997 + * dwarf2out.c (modified_type_die): If both is_const_type and + is_volatile_type is set, start with DW_TAG_const_type or + DW_TAG_volatile_type depending on where we get qualified type + in the recursive call. + + PR target/43897 + * config/ia64/ia64.c (rtx_needs_barrier): Handle asm CLOBBER + as a store into that register. + + PR tree-optimization/46528 + PR debug/46338 + * profile.c (branch_prob): Make sure last is never set to a debug + stmt. + + PR debug/46771 + * reginfo.c (init_subregs_of_mode): Don't call find_subregs_of_mode + on DEBUG_INSNs. + + PR rtl-optimization/46777 + * cfglayout.c (duplicate_insn_chain): Avoid duplicating + also barrier after tablejump. + +2010-12-06 Joern Rennecke <amylaar@spamcop.net> + Richard Henderson <rth@redhat.com> + + PR target/46740 + * config/vax/vax.c (vax_output_int_move): Fold #if into if. + +2010-12-06 Eric Botcazou <ebotcazou@adacore.com> + + * config/sparc/sol2.h (PUSHSECTION_FORMAT): Redefine unconditionally. + * config/sparc/sol2-gas.h (PUSHSECTION_FORMAT): Redefine. + +2010-12-06 Joern Rennecke <amylaar@spamcop.net> + + PR target/46735 + * config/frv/predicates.md (gpr_or_int12_operand): Use IN_RANGE. + (gpr_fpr_or_int12_operand, gpr_or_int10_operand): Likewise. + (int12_operand, int_2word_operand, uint16_operand): Likewise. + (fpr_or_int6_operand, int6_operand, int5_operand): Likewise. + (uint5_operand, uint4_operand): Likewise. + * config/frv/frv.h (IN_RANGE_P): Delete. + (GPR_P, FPR_P, CC_P, ICC_P, FCC_P, CR_P, ICR_P, FCR_P): Use IN_RANGE. + (ACC_P, ACCG_P, SPR_P, CONST_OK_FOR_I, CONST_OK_FOR_J): Likewise. + (CONST_OK_FOR_L, CONST_OK_FOR_M, CONST_OK_FOR_N): Likewise. + (CONST_OK_FOR_P): Likewise. + * config/frv/frv.md (*movqicc_internal2_int): Likewise. + (*movqicc_internal2_float, *movhicc_internal2_int): Likewise. + (*movhicc_internal2_float, *movsicc_internal2_int): Likewise. + (*movsicc_internal2_float, casesi): Likewise. + * config/frv/frv.c (frv_frame_offset_rtx): Likewise. + (frv_asm_output_mi_thunk, frv_legitimate_address_p_1): Likewise. + (frv_emit_movsi, output_move_single, frv_emit_cond_move): Likewise. + (frv_split_cond_move, frv_rtx_costs): Likewise. + + PR target/46739 + * config/mmix/mmix.c (mmix_intval): Split shift count. + +2010-12-06 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/i386.c (m_COREI7): New. + (initial_ix86_tune_features): Turn on + X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL and + X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL for Core i7. + +2010-12-06 H.J. Lu <hongjiu.lu@intel.com> + + * config.gcc: Allow corei7-avx for --with-arch/--with-cpu. + + * config/i386/driver-i386.c (host_detect_local_cpu): Support + Sandy Bridge. + + * config/i386/i386.c (override_options): Handle "corei7-avx". + + * doc/invoke.texi: Document corei7-avx. + +2010-12-06 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/46806 + * tree-ssa-copyrename.c (copy_rename_partition_coalesce): Do not + coalesce different types. + +2010-12-06 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/46785 + * tree-vect-loop.c (vect_is_simple_reduction_1): Also allow + call statements as operand definition. + +2010-12-06 Mingjie Xing <mingjie.xing@gmail.com> + + * doc/tm.texi.in: Fix typo. + * doc/tm.texi: Regenerate. + +2010-12-05 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + * config.gcc [hppa[12]*-*-hpux10*, hppa[12]*-*-hpux11*]: Fix typo in + last change. + +2010-12-06 Nicola Pero <nicola.pero@meta-innovation.com> + + * c-family/c-common.h: Removed the declarations of all the objc_ + callbacks, and moved them into c-objc.h. Removed + objc_ivar_visibility_kind and moved it into c-objc.h. + * c-family/c-objc.h: New file. + * c-family/c-common.c: Include c-objc.h. + * c-family/c-format.c: Same change. + * c-family/stub-objc.c: Same change. + * c-decl.c: Include c-family/c-objc.h. + * c-parser.c: Same change. + * c-typeck.c: Same change. + * c-config-lang.in (gtfiles): Added c-family/c-objc.h. + * Makefile.in (c-decl.o): Depend on c-family/c-objc.h. + (c-parser.o): same change. + (c-typeck.o): Same change. + (c-family/c-format.o): Same change. + (c-family/stub-objc.o): Same change. + (c-family/c-common.o): Same change. + (PLUGIN_HEADERS): Added c-family/c-objc.h. + +2010-12-05 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + * config.gcc [hppa[12]*-*-hpux10*, hppa[12]*-*-hpux11*]: Ignore + --with-dwarf2 option. + +2010-12-03 Jan Hubicka <jh@suse.cz> + + * lto-streamer-in.c (input_cfg): Fix pasto. + +2010-12-03 Jan Hubicka <jh@suse.cz> + + * ipa.c (cgraph_externally_visible_p): Do not localize builtins + and functions with user asm defined names. + (varpool_externally_visible_p): Do not localize vars with user + asm defined names. + +2010-12-03 Jan Hubicka <jh@suse.cz> + + * dwarf2asm.c (dw2_output_indirect_constant_1): Set DECL_ASSEMBLER_NAME + to prevent mangling with lto frontend. + +2010-12-03 Jan Hubicka <jh@suse.cz> + + * Makefile.in (LTO_STREAMER_H): Add GCOV_IO_H. + * lto-cgraph.c (merge_profile_summaries): Fix thinko. + +2010-12-03 Jan Hubicka <jh@suse.cz> + + PR tree-optimization/46760 + * cgraph.c (cgraph_create_node): Initialize count_materialization_scale. + * cgraph.h (struct cgraph_node): Add count_materialization_scale. + * lto-cgraph.c (lto_output_edge): Fix assert. + (lto_output_node): Output count_materialization_scale. + (output_profile_summary): Output only runs and sum_max. + (input_node): Input count_materialization_scale. + (input_profile_summary): Read data into file specific gcov summary. + (merge_profile_summaries): New function. + (input_cgraph): Update call of input_profile_summary; + call merge_profile_summaries. + * lto-streamer-in.c (input_cfg): Add count_materialization_scale arg; + rescale counts at read in. + (intput_bb): Likewise. + (input_function): Update call of input_bb. + (lto_read_body): Update call of input_cfg. + * lto-streamer.h: Inlclude gcov-io.h + (lto_file_decl_data): Add gcov_ctr_summary. + +2010-12-03 Dave Korn <dave.korn.cygwin@gmail.com> + + * doc/tm.texi.in (Cond. Exec. Macros): Rename node from this ... + (Cond Exec Macros): ... to this. + * doc/tm.texi: Regenerate. + +2010-12-03 Jason Merrill <jason@redhat.com> + + PR debug/46123 + * dwarf2out.c (gen_tagged_type_die): Don't put local types in + a declaration DIE. + +2010-12-03 Nathan Froyd <froydnj@codesourcery.com> + + * config/arm/arm.c (arm_legitimate_index_p): Split + VALID_NEON_QREG_MODE and VALID_NEON_DREG_MODE cases. Permit + slightly larger constants in the latter case. + (thumb2_legitimate_index_p): Likewise. + +2010-12-03 Joseph Myers <joseph@codesourcery.com> + + * common.opt (N, Q, Qn, Qy, Z, n, r, s, t): New options. + * gcc.c (cc1_options): Add %{Qy:}. + +2010-12-03 Joseph Myers <joseph@codesourcery.com> + + * gcc.c (LINK_COMMAND_SPEC): Don't handle -A, -d or -m. + * config/darwin.h (LINK_COMMAND_SPEC_A): Likewise. + * config/i386/djgpp.h (LINK_COMMAND_SPEC): Likewise. + +2010-12-03 Alexander Monakov <amonakov@ispras.ru> + + PR rtl-optimization/45354 + * sel-sched-ir.c (jump_leads_only_to_bb_p): Rename to ... + (bb_has_removable_jump_to_p): This. Update all callers. Make static. + Allow BBs ending with a conditional jump. Forbid EDGE_CROSSING jumps. + * sel-sched-ir.h (jump_leads_only_to_bb_p): Delete prototype. + +2010-12-03 Laurynas Biveinis <laurynas.biveinis@gmail.com> + + * basic-block.h (struct edge_prediction): Remove forward declaration. + * tree-flow.h (struct edge_prediction): Move from here... + * predict.c (struct edge_prediction): ...to here. + * cselib.h (struct elt_list): Move from here... + * cselib.c (struct elt_list): ...to here. + +2010-12-02 Ian Lance Taylor <iant@google.com> + + * gcc.c (default_compilers): Add entry for ".go". + * common.opt: Add -static-libgo as a driver option. + * doc/install.texi (Configuration): Mention libgo as an option for + --enable-shared. Mention go as an option for --enable-languages. + * doc/invoke.texi (Overall Options): Mention .go as a file name + suffix. Mention go as a -x option. + * doc/frontends.texi (G++ and GCC): Mention Go as a supported language. + * doc/sourcebuild.texi (Top Level): Mention libgo. + * doc/standards.texi (Standards): Add section on Go language. + Move references for other languages into their own section. + * doc/contrib.texi (Contributors): Mention that I contributed the + Go frontend. + +2010-12-03 Laurynas Biveinis <laurynas.biveinis@gmail.com> + + * tree.h (struct call_expr_arg_iterator_d): Remove GTY tag. + (const_call_expr_arg_iterator_d): Likewise. + (expanded_location): Likewise. + * c-tree.h (struct c_arg_tag_d): Likewise. + * dwarf2out.c (struct cfa_loc): Likewise. + (struct skeleton_chain_struct): Likewise. + * except.c (struct ttypes_filter): Likewise. + * cselib.h (struct cselib_val_struct): Likewise. + (elt_loc_list): Likewise. + (elt_list): Likewise. + * varasm.c (struct addr_const): Likewise. + * tree-flow.h (struct edge_prediction): Likewise. + (struct int_tree_map): Likewise. + (struct _edge_var_map): Likewise. + +2010-12-02 H.J. Lu <hongjiu.lu@intel.com> + + PR target/46768 + * config/i386/i386.c (initial_ix86_tune_features): Turn on + X86_TUNE_INTER_UNIT_MOVES for Core 2 and Core i7. + +2010-12-02 H.J. Lu <hongjiu.lu@intel.com> + + * config.gcc: Allow corei7 for --with-arch=/--with-cpu=. + +2010-12-02 Ian Lance Taylor <iant@google.com> + + * configure.ac: AC_DEFINE ENABLE_BUILD_WITH_CXX. Check for C++ + header files unordered_map, tr1/unordered_map, and ext/hash_map. + * configure, config.in: Rebuild. + +2010-12-02 Eric Botcazou <ebotcazou@adacore.com> + + PR target/46685 + * config/sparc/sparc.c (can_use_mov_pic_label_ref): New predicate. + (sparc_expand_move): Call it to decide whether to emit the special + mov{si,di}_pic_label_ref patterns. + (sparc_legitimize_pic_address): Call it to decide whether to emit + the regular PIC sequence for labels. Fix long line. + (sparc_file_end): Set is_thunk for the PIC helper. + +2010-12-02 Eric Botcazou <ebotcazou@adacore.com> + + * tree.c (build_range_type_1): Do not SET_TYPE_STRUCTURAL_EQUALITY + for a non-shared type. + +2010-12-02 Sebastian Pop <sebastian.pop@amd.com> + + PR middle-end/45297 + * tree-scalar-evolution.c (interpret_rhs_expr): Handle ADDR_EXPR + with MEM_REFs as POINTER_PLUS_EXPR. + +2010-12-02 Joseph Myers <joseph@codesourcery.com> + + * config/i386/linux.h, config/m32r/linux.h, config/m68k/linux.h, + config/sparc/linux.h, config/sparc/linux64.h: Remove comments + mentioning /lib/elf. + +2010-12-02 Joseph Myers <joseph@codesourcery.com> + + * config/bfin/bfin.h (LINK_SPEC): Remove %{b}. + * config/frv/frv.h (LINK_SPEC): Remove %{b}. + * config/i386/netware.h (LINK_SPEC): Remove %{b}. + * config/i386/nto.h (LINK_SPEC): Remove %{b}. + * config/lm32/uclinux-elf.h (LINK_SPEC): Remove %{b}. + * config/sol2.h (LINK_SPEC): Remove %{b}. + * config/svr4.h (LINK_SPEC): Remove %{b}. + +2010-12-02 Joseph Myers <joseph@codesourcery.com> + + * config/i386/freebsd.h (LINK_SPEC): Cut long comment. + * config/i386/linux.h (LINK_SPEC): Cut long comment. + * config/i386/netware.h (LINK_SPEC): Remove %{V}. + * config/m32r/linux.h (LINK_SPEC): Cut long comment. + * config/m68k/linux.h (LINK_SPEC): Cut long comment. + * config/sparc/linux.h (LINK_SPEC): Cut long comment. + (ASM_SPEC): Remove %{V} and %{v:%{!V:-V}}. + * config/sparc/linux64.h (LINK_SPEC): Cut long comment. + (ASM_SPEC): Remove %{V} and %{v:%{!V:-V}}. + * config/sparc/netbsd-elf.h (ASM_SPEC): Remove %{V} and %{v:%{!V:-V}}. + +2010-12-02 Joseph Myers <joseph@codesourcery.com> + + * gcc.c (trad_capable_cpp, default_compilers): Don't handle + -ftraditional. + +2010-12-02 Joseph Myers <joseph@codesourcery.com> + + * config/alpha/freebsd.h (LINK_SPEC): Don't handle -Wl,. + * config/bfin/bfin.h (ASM_SPEC): Don't handle -Wa,. + * config/frv/frv.h (ASM_SPEC): Don't handle -Wa,. + * config/lm32/uclinux-elf.h (LINK_SPEC): Don't handle -Wl,. + * config/microblaze/microblaze.h (LINK_SPEC): Don't handle -Wl,. + * config/mn10300/linux.h (ASM_SPEC): Don't handle -Wa,. + * config/pa/pa-linux.h (ASM_SPEC): Don't handle -Wa,. + * config/rs6000/freebsd.h (SVR4_ASM_SPEC): Don't handle -Wa,. + * config/rs6000/linux64.h (ASM_SPEC_COMMON): Don't handle -Wa,. + * config/rs6000/sysv4.h (LINK_SPEC): Don't handle -Wl,. + * config/rs6000/vxworks.h (ASM_SPEC): Don't handle -Wa,. + * config/sol2.h (ASM_SPEC): Don't handle -Wa,. + * config/sparc/linux.h (ASM_SPEC): Don't handle -Wa,. + * config/sparc/linux64.h (ASM_SPEC): Don't handle -Wa,. + * config/sparc/sp-elf.h (ASM_SPEC): Don't handle -Wa,. + * config/sparc/sysv4.h (ASM_SPEC): Don't handle -Wa,. + * config/svr4.h (SVR4_ASM_SPEC): Don't handle -Wa,. + * config/vxworks.h (VXWORKS_LINK_SPEC): Don't handle -Wl,. + +2010-12-02 Paul Koning <ni1d@arrl.net> + + * config/pdp11/pdp11.c (output_jump): Map unsigned to signed + opcodes if CC_NO_OVERFLOW is set. + (notice_update_cc_on_set): Correct setting of CC0 as a side + effect; set CC_NO_OVERFLOW for cases where C flag is not meaningful. + +2010-12-02 Ian Lance Taylor <iant@google.com> + + * doc/install.texi (Configuration): Update default for + --with-boot-ldflags. + +2010-12-02 Nathan Froyd <froydnj@codesourcery.com> + + PR c/45062 + * c-decl.c (grokparms): Set arg_info->parms to NULL_TREE when + !funcdef_flag. + +2010-12-02 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/45199 + * tree-data-ref.c (mem_write_stride_of_same_size_as_unit_type_p): New. + (stores_zero_from_loop): Call + mem_write_stride_of_same_size_as_unit_type_p. + * tree-data-ref.h (stride_of_unit_type_p): New. + * tree-loop-distribution.c (generate_memset_zero): Simplified. + Call stride_of_unit_type_p. + (build_rdg_partition_for_component): Do not call + rdg_flag_similar_memory_accesses when + flag_tree_loop_distribute_patterns is set. + +2010-12-02 Richard Guenther <rguenther@suse.de> + + * tree-vect-loop.c (vect_analyze_scalar_cycles_1): Disregard + sign-changing conversions for induction detection. + +2010-12-02 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/46723 + * tree-vect-loop.c (get_initial_def_for_induction): Strip + conversions from the induction evolution and apply it to + the result instead. + * tree-vect-stmts.c (vect_get_vec_def_for_operand): Handle + assigns for induction defs. + +2010-12-02 Richard Guenther <rguenther@suse.de> + + * value-prof.c (gimple_ic): Use stmt_ends_bb_p to detect + the case we need to split the edge and not the block. + +2010-12-02 Bernd Schmidt <bernds@codesourcery.com> + + DFA model for Core 2 and Core i7 scheduling. + + * config/i386/core2.md: New DFA model for Core 2 and Core i7. + * config/i386/i386.c (ix86_option_override_internal): Update entries + for Core 2 and Core i7. + (ix86_issue_rate): Set issue rate to 3 [be realistic]. + * config/i386/i386.md: Include "core2.md". + (define_attr cpu): Add "corei7". + +2010-12-02 Maxim Kuvyrkov <maxim@codesourcery.com> + + Define tuning for Core 2 and Core i7. + + * config/i386/i386-c.c (ix86_target_macros_internal): Update. + * config/i386/i386.c (core2_cost): Delete, use generic costs instead. + (m_CORE2): Replace with m_CORE2_{32,64}. + (m_CORE2I7{,_32,_64}): New macros. + (m_GENERIC32, m_GENERIC64): Update. + (initial_ix86_tune_features, x86_accumulate_outgoing_args,) + (x86_arch_always_fancy_math_387): Set m_CORE2I7_32 iff m_GENERIC32 and + set m_CORE2I7_64 iff m_GENERIC64. + (processor_target_table): Use generic costs for Core 2 and Core i7. + (ix86_option_override_internal): Update entries for Core 2 and Core i7. + (ix86_issue_rate): Remove entry for Core 2. + (ia32_multipass_dfa_lookahead, ix86_sched_init_global): Update. + * config/i386/i386.h (TARGET_CORE2_32, TARGET_CORE2_64): New macros. + (TARGET_CORE2): Update. + (PROCESSOR_CORE2_32, PROCESSOR_CORE2_64): New constants. + (PROCESSOR_CORE2): Remove. + +2010-12-02 Richard Guenther <rguenther@suse.de> + + * lto-streamer.h (LTO_major_version): Bump to 2. + +2010-12-02 Richard Guenther <rguenther@suse.de> + + PR lto/44871 + * gimple.c (canonical_type_hash_cache): New hashtable. + (gimple_type_hash): Make a wrapper around ... + (gimple_type_hash_1): ... this. Take gtc_mode argument. + (gimple_canonical_type_hash): Likewise. + (gtc_visit): Take a gtc_mode argument. + (gimple_types_compatible_p_1): Likewise. Do not compare struct + tag names or field names when computing canonical types. + (gimple_types_compatible_p): Adjust. + (visit): Take a gtc_mode argument. + (iterative_hash_gimple_type): Likewise. Do not hash struct tag + names or field names when computing hashes of canonical types. + (gimple_register_canonical_type): Use gimple_canonical_type_hash + for the hash. + (print_gimple_types_stats): Dump stats of canonical_type_hash_cache. + (free_gimple_type_tables): Free canonical_type_hash_cache. + +2010-12-02 Richard Guenther <rguenther@suse.de> + Ira Rosen <irar@il.ibm.com> + + PR tree-optimization/46663 + * tree-vect-patterns.c (vect_recog_pow_pattern): Check that + FUNCTION_DECL exists and that it's a builtin. + +2010-12-02 Jie Zhang <jie@codesourcery.com> + + PR middle-end/46674 + * varasm.c (compute_visible_aliases): Handle user set assembler name. + +2010-12-01 Michael Meissner <meissner@linux.vnet.ibm.com> + + * config/rs6000/rs6000.c (rs6000_option_override_internal): Fix + thinko regarding setting -mno-<xxx> debug switches. + (rs6000_rtx_costs): Add FMA. Delete old rtl based FMA costs. + +2010-12-01 Joseph Myers <joseph@codesourcery.com> + + * intl.c: Don't include tm.h. + * Makefile.in (intl.o): Don't depend on $(TM_H). + +2010-12-01 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (analyze_drs_in_stmts): Fix set but + unused warning. + (rewrite_cross_bb_scalar_deps_out_of_ssa): Same. + +2010-12-01 Sebastian Pop <sebastian.pop@amd.com> + + * graphite-sese-to-poly.c (analyze_drs): Removed. + (build_scop_drs): Do not call analyze_drs. + (analyze_drs_in_stmts): New. + (insert_stmts): New. + (insert_out_of_ssa_copy): Call analyze_drs_in_stmts. + (insert_out_of_ssa_copy_on_edge): Same. + (rewrite_close_phi_out_of_ssa): Call insert_stmts. + (rewrite_phi_out_of_ssa): Same. + (rewrite_cross_bb_scalar_dependence): Same. + (split_reduction_stmt): Move data references in the new basic blocks. + (translate_scalar_reduction_to_array_for_stmt): Call insert_stmts. + +2010-12-01 Sebastian Pop <sebastian.pop@amd.com> + + * sese.c (rename_uses): Do not handle ADDR_EXPR in LHS of assignments. + +2010-12-01 Sebastian Pop <sebastian.pop@