4.4.0-1
This commit is contained in:
parent
6c02716f78
commit
6cf12a2ed2
|
@ -1,2 +1,2 @@
|
|||
fastjar-0.97.tar.gz
|
||||
gcc-4.4.0-20090420.tar.bz2
|
||||
gcc-4.4.0-20090422.tar.bz2
|
||||
|
|
29
gcc.spec
29
gcc.spec
|
@ -1,9 +1,9 @@
|
|||
%define DATE 20090420
|
||||
%define SVNREV 146449
|
||||
%define DATE 20090422
|
||||
%define SVNREV 146590
|
||||
%define gcc_version 4.4.0
|
||||
# Note, gcc_release must be integer, if you want to add suffixes to
|
||||
# %{release}, append them after %{gcc_release} on Release: line.
|
||||
%define gcc_release 0.35
|
||||
%define gcc_release 1
|
||||
%define _unpackaged_files_terminate_build 0
|
||||
%define multilib_64_archs sparc64 ppc64 s390x x86_64
|
||||
%define include_gappletviewer 1
|
||||
|
@ -150,6 +150,12 @@ Patch24: gcc44-atom.patch
|
|||
Patch26: gcc44-power7.patch
|
||||
Patch28: gcc44-pr38757.patch
|
||||
Patch30: gcc44-pr39543.patch
|
||||
Patch31: gcc44-find_base_term.patch
|
||||
Patch32: gcc44-pr39794.patch
|
||||
Patch33: gcc44-rh459374-1.patch
|
||||
Patch34: gcc44-rh459374-2.patch
|
||||
Patch35: gcc44-rh459374-3.patch
|
||||
Patch36: gcc44-cswtch.patch
|
||||
|
||||
Patch1000: fastjar-0.97-segfault.patch
|
||||
|
||||
|
@ -437,7 +443,13 @@ which are required to compile with the GNAT.
|
|||
%patch24 -p0 -b .atom~
|
||||
%patch26 -p0 -b .power7~
|
||||
%patch28 -p0 -b .pr38757~
|
||||
#%patch30 -p0 -b .pr39543~
|
||||
%patch30 -p0 -b .pr39543~
|
||||
%patch31 -p0 -b .find_base_term~
|
||||
%patch32 -p0 -b .pr39794~
|
||||
%patch33 -p0 -b .rh459374-1~
|
||||
%patch34 -p0 -b .rh459374-2~
|
||||
%patch35 -p0 -b .rh459374-3~
|
||||
%patch36 -p0 -b .cswtch~
|
||||
|
||||
# This testcase doesn't compile.
|
||||
rm libjava/testsuite/libjava.lang/PR35020*
|
||||
|
@ -1748,6 +1760,15 @@ fi
|
|||
%doc rpm.doc/changelogs/libmudflap/ChangeLog*
|
||||
|
||||
%changelog
|
||||
* Wed Apr 22 2009 Jakub Jelinek <jakub@redhat.com> 4.4.0-1
|
||||
- update from gcc-4_4-branch
|
||||
- GCC 4.4.0 release
|
||||
- PR libstdc++/39802
|
||||
- fix up DSE (PR middle-end/39794)
|
||||
- debuginfo fixes for VLA and nested/contained functions (#459374)
|
||||
- improve -ftree-switch-conversion optimization if the constant is the
|
||||
same in all cases
|
||||
|
||||
* Mon Apr 20 2009 Jakub Jelinek <jakub@redhat.com> 4.4.0-0.35
|
||||
- update from gcc-4_4-branch
|
||||
- PRs middle-end/39804, target/39678, target/39767, tree-optimization/39675,
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
2009-04-21 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* tree-switch-conversion.c (constructor_contains_same_values_p):
|
||||
New function.
|
||||
(build_one_array): Create assigns of constants if possible.
|
||||
|
||||
* gcc.dg/tree-ssa/cswtch-2.c: New test.
|
||||
|
||||
--- gcc/tree-switch-conversion.c.jj 2009-03-28 18:11:43.000000000 +0100
|
||||
+++ gcc/tree-switch-conversion.c 2009-04-22 20:09:45.000000000 +0200
|
||||
@@ -459,6 +459,28 @@ build_constructors (gimple swtch)
|
||||
}
|
||||
}
|
||||
|
||||
+/* If all values in the constructor vector are the same, return the value.
|
||||
+ Otherwise return NULL_TREE. Not supposed to be called for empty
|
||||
+ vectors. */
|
||||
+
|
||||
+static tree
|
||||
+constructor_contains_same_values_p (VEC (constructor_elt, gc) *vec)
|
||||
+{
|
||||
+ int i, len = VEC_length (constructor_elt, vec);
|
||||
+ tree prev = NULL_TREE;
|
||||
+
|
||||
+ for (i = 0; i < len; i++)
|
||||
+ {
|
||||
+ constructor_elt *elt = VEC_index (constructor_elt, vec, i);
|
||||
+
|
||||
+ if (!prev)
|
||||
+ prev = elt->value;
|
||||
+ else if (!operand_equal_p (elt->value, prev, OEP_ONLY_CONST))
|
||||
+ return NULL_TREE;
|
||||
+ }
|
||||
+ return prev;
|
||||
+}
|
||||
+
|
||||
/* Create an appropriate array type and declaration and assemble a static array
|
||||
variable. Also create a load statement that initializes the variable in
|
||||
question with a value from the static array. SWTCH is the switch statement
|
||||
@@ -472,35 +494,44 @@ static void
|
||||
build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
|
||||
tree tidx)
|
||||
{
|
||||
- tree array_type, ctor, decl, value_type, name, fetch;
|
||||
+ tree name, cst;
|
||||
gimple load;
|
||||
gimple_stmt_iterator gsi;
|
||||
|
||||
gcc_assert (info.default_values[num]);
|
||||
- value_type = TREE_TYPE (info.default_values[num]);
|
||||
- array_type = build_array_type (value_type, arr_index_type);
|
||||
-
|
||||
- ctor = build_constructor (array_type, info.constructors[num]);
|
||||
- TREE_CONSTANT (ctor) = true;
|
||||
-
|
||||
- decl = build_decl (VAR_DECL, NULL_TREE, array_type);
|
||||
- TREE_STATIC (decl) = 1;
|
||||
- DECL_INITIAL (decl) = ctor;
|
||||
-
|
||||
- DECL_NAME (decl) = create_tmp_var_name ("CSWTCH");
|
||||
- DECL_ARTIFICIAL (decl) = 1;
|
||||
- TREE_CONSTANT (decl) = 1;
|
||||
- add_referenced_var (decl);
|
||||
- varpool_mark_needed_node (varpool_node (decl));
|
||||
- varpool_finalize_decl (decl);
|
||||
- mark_sym_for_renaming (decl);
|
||||
|
||||
name = make_ssa_name (SSA_NAME_VAR (PHI_RESULT (phi)), NULL);
|
||||
info.target_inbound_names[num] = name;
|
||||
|
||||
- fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE,
|
||||
- NULL_TREE);
|
||||
- load = gimple_build_assign (name, fetch);
|
||||
+ cst = constructor_contains_same_values_p (info.constructors[num]);
|
||||
+ if (cst)
|
||||
+ load = gimple_build_assign (name, cst);
|
||||
+ else
|
||||
+ {
|
||||
+ tree array_type, ctor, decl, value_type, fetch;
|
||||
+
|
||||
+ value_type = TREE_TYPE (info.default_values[num]);
|
||||
+ array_type = build_array_type (value_type, arr_index_type);
|
||||
+
|
||||
+ ctor = build_constructor (array_type, info.constructors[num]);
|
||||
+ TREE_CONSTANT (ctor) = true;
|
||||
+
|
||||
+ decl = build_decl (VAR_DECL, NULL_TREE, array_type);
|
||||
+ TREE_STATIC (decl) = 1;
|
||||
+ DECL_INITIAL (decl) = ctor;
|
||||
+
|
||||
+ DECL_NAME (decl) = create_tmp_var_name ("CSWTCH");
|
||||
+ DECL_ARTIFICIAL (decl) = 1;
|
||||
+ TREE_CONSTANT (decl) = 1;
|
||||
+ add_referenced_var (decl);
|
||||
+ varpool_mark_needed_node (varpool_node (decl));
|
||||
+ varpool_finalize_decl (decl);
|
||||
+ mark_sym_for_renaming (decl);
|
||||
+
|
||||
+ fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE,
|
||||
+ NULL_TREE);
|
||||
+ load = gimple_build_assign (name, fetch);
|
||||
+ }
|
||||
SSA_NAME_DEF_STMT (name) = load;
|
||||
|
||||
gsi = gsi_for_stmt (swtch);
|
||||
--- gcc/testsuite/gcc.dg/tree-ssa/cswtch-2.c.jj 2009-04-22 20:01:40.000000000 +0200
|
||||
+++ gcc/testsuite/gcc.dg/tree-ssa/cswtch-2.c 2009-04-22 20:01:40.000000000 +0200
|
||||
@@ -0,0 +1,21 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fdump-tree-switchconv" } */
|
||||
+
|
||||
+typedef enum { a = 5, b = 6, c = 7, d = 8, e = 9 } X;
|
||||
+
|
||||
+int h1 (X x)
|
||||
+{
|
||||
+ switch (x) {
|
||||
+ case a:
|
||||
+ case b:
|
||||
+ case c:
|
||||
+ case d:
|
||||
+ case e:
|
||||
+ return 1;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-tree-dump-times "CSWTCH" 0 "switchconv" } } */
|
||||
+/* { dg-final { cleanup-tree-dump "switchconv" } } */
|
|
@ -0,0 +1,28 @@
|
|||
2009-04-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* alias.c (find_base_term): Move around LO_SUM case, so that
|
||||
CONST falls through into PLUS/MINUS handling.
|
||||
|
||||
--- gcc/alias.c.jj 2009-04-21 11:16:28.000000000 +0200
|
||||
+++ gcc/alias.c 2009-04-21 12:44:18.000000000 +0200
|
||||
@@ -1438,15 +1438,16 @@ find_base_term (rtx x)
|
||||
return x;
|
||||
return 0;
|
||||
|
||||
+ case LO_SUM:
|
||||
+ /* The standard form is (lo_sum reg sym) so look only at the
|
||||
+ second operand. */
|
||||
+ return find_base_term (XEXP (x, 1));
|
||||
+
|
||||
case CONST:
|
||||
x = XEXP (x, 0);
|
||||
if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS)
|
||||
return 0;
|
||||
/* Fall through. */
|
||||
- case LO_SUM:
|
||||
- /* The standard form is (lo_sum reg sym) so look only at the
|
||||
- second operand. */
|
||||
- return find_base_term (XEXP (x, 1));
|
||||
case PLUS:
|
||||
case MINUS:
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
2009-04-10 Jakub Jelinek <jakub@redhat.com>
|
||||
2009-04-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/39543
|
||||
PR inline-asm/39543
|
||||
* fwprop.c (forward_propagate_asm): New function.
|
||||
(forward_propagate_and_simplify): Propagate also into __asm, if it
|
||||
doesn't increase the number of referenced registers.
|
||||
|
@ -140,7 +140,7 @@
|
|||
--- gcc/testsuite/gcc.target/i386/pr39543-1.c.jj 2009-04-09 09:47:16.000000000 +0200
|
||||
+++ gcc/testsuite/gcc.target/i386/pr39543-1.c 2009-04-09 09:47:16.000000000 +0200
|
||||
@@ -0,0 +1,52 @@
|
||||
+/* PR rtl-optimization/39543 */
|
||||
+/* PR inline-asm/39543 */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O3 -fomit-frame-pointer" } */
|
||||
+
|
||||
|
@ -195,7 +195,7 @@
|
|||
--- gcc/testsuite/gcc.target/i386/pr39543-2.c.jj 2009-04-09 09:47:16.000000000 +0200
|
||||
+++ gcc/testsuite/gcc.target/i386/pr39543-2.c 2009-04-09 09:47:16.000000000 +0200
|
||||
@@ -0,0 +1,51 @@
|
||||
+/* PR rtl-optimization/39543 */
|
||||
+/* PR inline-asm/39543 */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O3" } */
|
||||
+
|
||||
|
@ -249,7 +249,7 @@
|
|||
--- gcc/testsuite/gcc.target/i386/pr39543-3.c.jj 2009-04-09 09:47:16.000000000 +0200
|
||||
+++ gcc/testsuite/gcc.target/i386/pr39543-3.c 2009-04-09 09:47:16.000000000 +0200
|
||||
@@ -0,0 +1,42 @@
|
||||
+/* PR rtl-optimization/39543 */
|
||||
+/* PR inline-asm/39543 */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2" } */
|
||||
+
|
||||
|
|
|
@ -0,0 +1,277 @@
|
|||
2009-04-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/39794
|
||||
* alias.c (canon_true_dependence): Add x_addr argument.
|
||||
* rtl.h (canon_true_dependence): Adjust prototype.
|
||||
* cse.c (check_dependence): Adjust canon_true_dependence callers.
|
||||
* cselib.c (cselib_invalidate_mem): Likewise.
|
||||
* gcse.c (compute_transp): Likewise.
|
||||
* dse.c (scan_reads_nospill): Likewise.
|
||||
(record_store, check_mem_read_rtx): Likewise. For non-const or
|
||||
frame addresses pass cselib_subst_to_values as mem_addr, for
|
||||
const or frame addresses canon_base_mem of the group plus
|
||||
optionally offset.
|
||||
|
||||
* gcc.dg/pr39794.c: New test.
|
||||
|
||||
--- gcc/alias.c.jj 2009-03-28 18:11:42.000000000 +0100
|
||||
+++ gcc/alias.c 2009-04-21 12:44:18.000000000 +0200
|
||||
@@ -2250,14 +2251,13 @@ true_dependence (const_rtx mem, enum mac
|
||||
Variant of true_dependence which assumes MEM has already been
|
||||
canonicalized (hence we no longer do that here).
|
||||
The mem_addr argument has been added, since true_dependence computed
|
||||
- this value prior to canonicalizing. */
|
||||
+ this value prior to canonicalizing.
|
||||
+ If x_addr is non-NULL, it is used in preference of XEXP (x, 0). */
|
||||
|
||||
int
|
||||
canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
|
||||
- const_rtx x, bool (*varies) (const_rtx, bool))
|
||||
+ const_rtx x, rtx x_addr, bool (*varies) (const_rtx, bool))
|
||||
{
|
||||
- rtx x_addr;
|
||||
-
|
||||
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
|
||||
return 1;
|
||||
|
||||
@@ -2283,7 +2283,8 @@ canon_true_dependence (const_rtx mem, en
|
||||
if (nonoverlapping_memrefs_p (x, mem))
|
||||
return 0;
|
||||
|
||||
- x_addr = get_addr (XEXP (x, 0));
|
||||
+ if (! x_addr)
|
||||
+ x_addr = get_addr (XEXP (x, 0));
|
||||
|
||||
if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode))
|
||||
return 0;
|
||||
--- gcc/dse.c.jj 2009-03-28 18:11:42.000000000 +0100
|
||||
+++ gcc/dse.c 2009-04-21 18:11:19.000000000 +0200
|
||||
@@ -1286,7 +1286,7 @@ static rtx get_stored_val (store_info_t,
|
||||
static int
|
||||
record_store (rtx body, bb_info_t bb_info)
|
||||
{
|
||||
- rtx mem, rhs, const_rhs;
|
||||
+ rtx mem, rhs, const_rhs, mem_addr;
|
||||
HOST_WIDE_INT offset = 0;
|
||||
HOST_WIDE_INT width = 0;
|
||||
alias_set_type spill_alias_set;
|
||||
@@ -1456,6 +1456,20 @@ record_store (rtx body, bb_info_t bb_inf
|
||||
ptr = active_local_stores;
|
||||
last = NULL;
|
||||
redundant_reason = NULL;
|
||||
+ mem = canon_rtx (mem);
|
||||
+ if (spill_alias_set || group_id < 0)
|
||||
+ {
|
||||
+ cselib_lookup (XEXP (mem, 0), Pmode, 1);
|
||||
+ mem_addr = cselib_subst_to_values (XEXP (mem, 0));
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ group_info_t group
|
||||
+ = VEC_index (group_info_t, rtx_group_vec, group_id);
|
||||
+ mem_addr = group->canon_base_mem;
|
||||
+ if (offset)
|
||||
+ mem_addr = gen_rtx_PLUS (GET_MODE (mem_addr), mem_addr, GEN_INT (offset));
|
||||
+ }
|
||||
|
||||
while (ptr)
|
||||
{
|
||||
@@ -1547,13 +1561,13 @@ record_store (rtx body, bb_info_t bb_inf
|
||||
if (canon_true_dependence (s_info->mem,
|
||||
GET_MODE (s_info->mem),
|
||||
s_info->mem_addr,
|
||||
- mem, rtx_varies_p))
|
||||
+ mem, mem_addr, rtx_varies_p))
|
||||
{
|
||||
s_info->rhs = NULL;
|
||||
s_info->const_rhs = NULL;
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
/* An insn can be deleted if every position of every one of
|
||||
its s_infos is zero. */
|
||||
if (any_positions_needed_p (s_info)
|
||||
@@ -1580,9 +1594,9 @@ record_store (rtx body, bb_info_t bb_inf
|
||||
/* Finish filling in the store_info. */
|
||||
store_info->next = insn_info->store_rec;
|
||||
insn_info->store_rec = store_info;
|
||||
- store_info->mem = canon_rtx (mem);
|
||||
+ store_info->mem = mem;
|
||||
store_info->alias_set = spill_alias_set;
|
||||
- store_info->mem_addr = get_addr (XEXP (mem, 0));
|
||||
+ store_info->mem_addr = mem_addr;
|
||||
store_info->cse_base = base;
|
||||
if (width > HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
@@ -2006,7 +2020,7 @@ replace_read (store_info_t store_info, i
|
||||
static int
|
||||
check_mem_read_rtx (rtx *loc, void *data)
|
||||
{
|
||||
- rtx mem = *loc;
|
||||
+ rtx mem = *loc, mem_addr;
|
||||
bb_info_t bb_info;
|
||||
insn_info_t insn_info;
|
||||
HOST_WIDE_INT offset = 0;
|
||||
@@ -2058,6 +2072,19 @@ check_mem_read_rtx (rtx *loc, void *data
|
||||
read_info->end = offset + width;
|
||||
read_info->next = insn_info->read_rec;
|
||||
insn_info->read_rec = read_info;
|
||||
+ if (spill_alias_set || group_id < 0)
|
||||
+ {
|
||||
+ cselib_lookup (XEXP (mem, 0), Pmode, 1);
|
||||
+ mem_addr = cselib_subst_to_values (XEXP (mem, 0));
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ group_info_t group
|
||||
+ = VEC_index (group_info_t, rtx_group_vec, group_id);
|
||||
+ mem_addr = group->canon_base_mem;
|
||||
+ if (offset)
|
||||
+ mem_addr = gen_rtx_PLUS (GET_MODE (mem_addr), mem_addr, GEN_INT (offset));
|
||||
+ }
|
||||
|
||||
/* We ignore the clobbers in store_info. The is mildly aggressive,
|
||||
but there really should not be a clobber followed by a read. */
|
||||
@@ -2128,7 +2155,7 @@ check_mem_read_rtx (rtx *loc, void *data
|
||||
= canon_true_dependence (store_info->mem,
|
||||
GET_MODE (store_info->mem),
|
||||
store_info->mem_addr,
|
||||
- mem, rtx_varies_p);
|
||||
+ mem, mem_addr, rtx_varies_p);
|
||||
|
||||
else if (group_id == store_info->group_id)
|
||||
{
|
||||
@@ -2139,7 +2166,7 @@ check_mem_read_rtx (rtx *loc, void *data
|
||||
= canon_true_dependence (store_info->mem,
|
||||
GET_MODE (store_info->mem),
|
||||
store_info->mem_addr,
|
||||
- mem, rtx_varies_p);
|
||||
+ mem, mem_addr, rtx_varies_p);
|
||||
|
||||
/* If this read is just reading back something that we just
|
||||
stored, rewrite the read. */
|
||||
@@ -2224,7 +2251,7 @@ check_mem_read_rtx (rtx *loc, void *data
|
||||
remove = canon_true_dependence (store_info->mem,
|
||||
GET_MODE (store_info->mem),
|
||||
store_info->mem_addr,
|
||||
- mem, rtx_varies_p);
|
||||
+ mem, mem_addr, rtx_varies_p);
|
||||
|
||||
if (remove)
|
||||
{
|
||||
@@ -3067,7 +3094,8 @@ scan_reads_nospill (insn_info_t insn_inf
|
||||
&& canon_true_dependence (group->base_mem,
|
||||
QImode,
|
||||
group->canon_base_mem,
|
||||
- read_info->mem, rtx_varies_p))
|
||||
+ read_info->mem, NULL_RTX,
|
||||
+ rtx_varies_p))
|
||||
{
|
||||
if (kill)
|
||||
bitmap_ior_into (kill, group->group_kill);
|
||||
--- gcc/cse.c.jj 2009-03-28 18:11:42.000000000 +0100
|
||||
+++ gcc/cse.c 2009-04-21 11:18:02.000000000 +0200
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Common subexpression elimination for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
|
||||
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@@ -1658,7 +1658,7 @@ check_dependence (rtx *x, void *data)
|
||||
{
|
||||
struct check_dependence_data *d = (struct check_dependence_data *) data;
|
||||
if (*x && MEM_P (*x))
|
||||
- return canon_true_dependence (d->exp, d->mode, d->addr, *x,
|
||||
+ return canon_true_dependence (d->exp, d->mode, d->addr, *x, NULL_RTX,
|
||||
cse_rtx_varies_p);
|
||||
else
|
||||
return 0;
|
||||
--- gcc/rtl.h.jj 2009-03-28 18:11:43.000000000 +0100
|
||||
+++ gcc/rtl.h 2009-04-21 11:17:04.000000000 +0200
|
||||
@@ -2282,7 +2282,7 @@ extern rtx canon_rtx (rtx);
|
||||
extern int true_dependence (const_rtx, enum machine_mode, const_rtx, bool (*)(const_rtx, bool));
|
||||
extern rtx get_addr (rtx);
|
||||
extern int canon_true_dependence (const_rtx, enum machine_mode, rtx, const_rtx,
|
||||
- bool (*)(const_rtx, bool));
|
||||
+ rtx, bool (*)(const_rtx, bool));
|
||||
extern int read_dependence (const_rtx, const_rtx);
|
||||
extern int anti_dependence (const_rtx, const_rtx);
|
||||
extern int output_dependence (const_rtx, const_rtx);
|
||||
--- gcc/cselib.c.jj 2009-03-28 18:11:43.000000000 +0100
|
||||
+++ gcc/cselib.c 2009-04-21 11:18:25.000000000 +0200
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Common subexpression elimination library for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
- 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
+ 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@@ -1483,7 +1483,7 @@ cselib_invalidate_mem (rtx mem_rtx)
|
||||
}
|
||||
if (num_mems < PARAM_VALUE (PARAM_MAX_CSELIB_MEMORY_LOCATIONS)
|
||||
&& ! canon_true_dependence (mem_rtx, GET_MODE (mem_rtx), mem_addr,
|
||||
- x, cselib_rtx_varies_p))
|
||||
+ x, NULL_RTX, cselib_rtx_varies_p))
|
||||
{
|
||||
has_mem = true;
|
||||
num_mems++;
|
||||
--- gcc/gcse.c.jj 2009-03-28 18:11:42.000000000 +0100
|
||||
+++ gcc/gcse.c 2009-04-21 11:19:20.000000000 +0200
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Global common subexpression elimination/Partial redundancy elimination
|
||||
and global constant/copy propagation for GNU compiler.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
- 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
+ 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@@ -2516,7 +2516,7 @@ compute_transp (const_rtx x, int indx, s
|
||||
dest_addr = XEXP (list_entry, 0);
|
||||
|
||||
if (canon_true_dependence (dest, GET_MODE (dest), dest_addr,
|
||||
- x, rtx_addr_varies_p))
|
||||
+ x, NULL_RTX, rtx_addr_varies_p))
|
||||
{
|
||||
if (set_p)
|
||||
SET_BIT (bmap[bb_index], indx);
|
||||
--- gcc/testsuite/gcc.dg/pr39794.c.jj 2009-04-21 13:08:45.000000000 +0200
|
||||
+++ gcc/testsuite/gcc.dg/pr39794.c 2009-04-21 13:07:29.000000000 +0200
|
||||
@@ -0,0 +1,33 @@
|
||||
+/* PR middle-end/39794 */
|
||||
+/* { dg-do run } */
|
||||
+/* { dg-options "-O2 -funroll-loops" } */
|
||||
+
|
||||
+extern void abort ();
|
||||
+
|
||||
+void
|
||||
+foo (int *a, int n)
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0; i < n; i++)
|
||||
+ {
|
||||
+ a[i] *= 2;
|
||||
+ a[i + 1] = a[i - 1] + a[i - 2];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int a[16];
|
||||
+int ref[16] = { 0, 1, 4, 2, 10, 12, 24, 44,
|
||||
+ 72, 136, 232, 416, 736, 1296, 2304, 2032 };
|
||||
+
|
||||
+int
|
||||
+main ()
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0; i < 16; i++)
|
||||
+ a[i] = i;
|
||||
+ foo (a + 2, 16 - 3);
|
||||
+ for (i = 0; i < 16; i++)
|
||||
+ if (ref[i] != a[i])
|
||||
+ abort ();
|
||||
+ return 0;
|
||||
+}
|
|
@ -0,0 +1,239 @@
|
|||
2009-04-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* tree.h (DECL_BY_REFERENCE): Note that it is also valid for
|
||||
!TREE_STATIC VAR_DECLs.
|
||||
* dwarf2out.c (loc_by_reference, gen_decl_die): Handle
|
||||
DECL_BY_REFERENCE on !TREE_STATIC VAR_DECLs.
|
||||
(gen_variable_die): Likewise. Don't look at TREE_PRIVATE if
|
||||
DECL_BY_REFERENCE is valid.
|
||||
* dbxout.c (DECL_ACCESSIBILITY_CHAR): Don't look at TREE_PRIVATE
|
||||
for PARM_DECLs, RESULT_DECLs or !TREE_STATIC VAR_DECLs.
|
||||
* tree-nested.c (get_nonlocal_debug_decl, get_local_debug_decl):
|
||||
Copy DECL_BY_REFERENCE.
|
||||
(struct nesting_copy_body_data): New type.
|
||||
(nesting_copy_decl): New function.
|
||||
(finalize_nesting_tree_1): Remap types of debug_var_chain variables,
|
||||
if they have variable length.
|
||||
|
||||
--- gcc/dwarf2out.c.jj 2009-04-07 08:32:56.000000000 +0200
|
||||
+++ gcc/dwarf2out.c 2009-04-08 11:10:16.000000000 +0200
|
||||
@@ -11709,7 +11709,9 @@ loc_by_reference (dw_loc_descr_ref loc,
|
||||
if (loc == NULL)
|
||||
return NULL;
|
||||
|
||||
- if ((TREE_CODE (decl) != PARM_DECL && TREE_CODE (decl) != RESULT_DECL)
|
||||
+ if ((TREE_CODE (decl) != PARM_DECL
|
||||
+ && TREE_CODE (decl) != RESULT_DECL
|
||||
+ && (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)))
|
||||
|| !DECL_BY_REFERENCE (decl))
|
||||
return loc;
|
||||
|
||||
@@ -14047,12 +14049,19 @@ gen_variable_die (tree decl, tree origin
|
||||
else
|
||||
{
|
||||
tree type = TREE_TYPE (decl);
|
||||
+ bool private_flag_valid = true;
|
||||
|
||||
add_name_and_src_coords_attributes (var_die, decl);
|
||||
if ((TREE_CODE (decl) == PARM_DECL
|
||||
- || TREE_CODE (decl) == RESULT_DECL)
|
||||
+ || TREE_CODE (decl) == RESULT_DECL
|
||||
+ || (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl)))
|
||||
&& DECL_BY_REFERENCE (decl))
|
||||
- add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
|
||||
+ {
|
||||
+ add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
|
||||
+ /* DECL_BY_REFERENCE uses the same bit as TREE_PRIVATE,
|
||||
+ for PARM_DECL, RESULT_DECL or non-static VAR_DECL. */
|
||||
+ private_flag_valid = false;
|
||||
+ }
|
||||
else
|
||||
add_type_attribute (var_die, type, TREE_READONLY (decl),
|
||||
TREE_THIS_VOLATILE (decl), context_die);
|
||||
@@ -14065,7 +14074,7 @@ gen_variable_die (tree decl, tree origin
|
||||
|
||||
if (TREE_PROTECTED (decl))
|
||||
add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_protected);
|
||||
- else if (TREE_PRIVATE (decl))
|
||||
+ else if (private_flag_valid && TREE_PRIVATE (decl))
|
||||
add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_private);
|
||||
}
|
||||
|
||||
@@ -15298,7 +15307,9 @@ gen_decl_die (tree decl, tree origin, dw
|
||||
|
||||
/* Output any DIEs that are needed to specify the type of this data
|
||||
object. */
|
||||
- if (TREE_CODE (decl_or_origin) == RESULT_DECL
|
||||
+ if ((TREE_CODE (decl_or_origin) == RESULT_DECL
|
||||
+ || (TREE_CODE (decl_or_origin) == VAR_DECL
|
||||
+ && !TREE_STATIC (decl_or_origin)))
|
||||
&& DECL_BY_REFERENCE (decl_or_origin))
|
||||
gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
|
||||
else
|
||||
--- gcc/tree.h.jj 2009-04-06 11:48:32.000000000 +0200
|
||||
+++ gcc/tree.h 2009-04-07 17:16:28.000000000 +0200
|
||||
@@ -478,7 +478,7 @@ struct tree_common GTY(())
|
||||
CALL_EXPR
|
||||
|
||||
DECL_BY_REFERENCE in
|
||||
- PARM_DECL, RESULT_DECL
|
||||
+ PARM_DECL, RESULT_DECL, VAR_DECL (only !TREE_STATIC)
|
||||
|
||||
OMP_SECTION_LAST in
|
||||
OMP_SECTION
|
||||
@@ -1291,8 +1291,9 @@ extern void omp_clause_range_check_faile
|
||||
#define CALL_EXPR_RETURN_SLOT_OPT(NODE) \
|
||||
(CALL_EXPR_CHECK (NODE)->base.private_flag)
|
||||
|
||||
-/* In a RESULT_DECL or PARM_DECL, means that it is passed by invisible
|
||||
- reference (and the TREE_TYPE is a pointer to the true type). */
|
||||
+/* In a RESULT_DECL, PARM_DECL or VAR_DECL without TREE_STATIC, means that it is
|
||||
+ passed by invisible reference (and the TREE_TYPE is a pointer to the true
|
||||
+ type). */
|
||||
#define DECL_BY_REFERENCE(NODE) (DECL_COMMON_CHECK (NODE)->base.private_flag)
|
||||
|
||||
/* In a CALL_EXPR, means that the call is the jump from a thunk to the
|
||||
--- gcc/tree-nested.c.jj 2009-04-06 11:47:30.000000000 +0200
|
||||
+++ gcc/tree-nested.c 2009-04-08 09:50:55.000000000 +0200
|
||||
@@ -827,6 +827,11 @@ get_nonlocal_debug_decl (struct nesting_
|
||||
TREE_READONLY (new_decl) = TREE_READONLY (decl);
|
||||
TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl);
|
||||
DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1;
|
||||
+ if ((TREE_CODE (decl) == PARM_DECL
|
||||
+ || TREE_CODE (decl) == RESULT_DECL
|
||||
+ || TREE_CODE (decl) == VAR_DECL)
|
||||
+ && DECL_BY_REFERENCE (decl))
|
||||
+ DECL_BY_REFERENCE (new_decl) = 1;
|
||||
|
||||
SET_DECL_VALUE_EXPR (new_decl, x);
|
||||
DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
|
||||
@@ -1240,6 +1245,11 @@ get_local_debug_decl (struct nesting_inf
|
||||
TREE_READONLY (new_decl) = TREE_READONLY (decl);
|
||||
TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl);
|
||||
DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1;
|
||||
+ if ((TREE_CODE (decl) == PARM_DECL
|
||||
+ || TREE_CODE (decl) == RESULT_DECL
|
||||
+ || TREE_CODE (decl) == VAR_DECL)
|
||||
+ && DECL_BY_REFERENCE (decl))
|
||||
+ DECL_BY_REFERENCE (new_decl) = 1;
|
||||
|
||||
SET_DECL_VALUE_EXPR (new_decl, x);
|
||||
DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
|
||||
@@ -1944,6 +1954,34 @@ convert_all_function_calls (struct nesti
|
||||
while (root);
|
||||
}
|
||||
|
||||
+struct nesting_copy_body_data
|
||||
+{
|
||||
+ copy_body_data cb;
|
||||
+ struct nesting_info *root;
|
||||
+};
|
||||
+
|
||||
+/* A helper subroutine for debug_var_chain type remapping. */
|
||||
+
|
||||
+static tree
|
||||
+nesting_copy_decl (tree decl, copy_body_data *id)
|
||||
+{
|
||||
+ struct nesting_copy_body_data *nid = (struct nesting_copy_body_data *) id;
|
||||
+ void **slot = pointer_map_contains (nid->root->var_map, decl);
|
||||
+
|
||||
+ if (slot)
|
||||
+ return (tree) *slot;
|
||||
+
|
||||
+ if (TREE_CODE (decl) == TYPE_DECL && DECL_ORIGINAL_TYPE (decl))
|
||||
+ {
|
||||
+ tree new_decl = copy_decl_no_change (decl, id);
|
||||
+ DECL_ORIGINAL_TYPE (new_decl)
|
||||
+ = remap_type (DECL_ORIGINAL_TYPE (decl), id);
|
||||
+ return new_decl;
|
||||
+ }
|
||||
+
|
||||
+ return copy_decl_no_change (decl, id);
|
||||
+}
|
||||
+
|
||||
/* Do "everything else" to clean up or complete state collected by the
|
||||
various walking passes -- lay out the types and decls, generate code
|
||||
to initialize the frame decl, store critical expressions in the
|
||||
@@ -2076,10 +2114,66 @@ finalize_nesting_tree_1 (struct nesting_
|
||||
declare_vars (root->new_local_var_chain,
|
||||
gimple_seq_first_stmt (gimple_body (root->context)),
|
||||
false);
|
||||
+
|
||||
if (root->debug_var_chain)
|
||||
- declare_vars (root->debug_var_chain,
|
||||
- gimple_seq_first_stmt (gimple_body (root->context)),
|
||||
- true);
|
||||
+ {
|
||||
+ tree debug_var;
|
||||
+
|
||||
+ for (debug_var = root->debug_var_chain; debug_var;
|
||||
+ debug_var = TREE_CHAIN (debug_var))
|
||||
+ if (variably_modified_type_p (TREE_TYPE (debug_var), NULL))
|
||||
+ break;
|
||||
+
|
||||
+ /* If there are any debug decls with variable length types,
|
||||
+ remap those types using other debug_var_chain variables. */
|
||||
+ if (debug_var)
|
||||
+ {
|
||||
+ struct nesting_copy_body_data id;
|
||||
+
|
||||
+ memset (&id, 0, sizeof (id));
|
||||
+ id.cb.copy_decl = nesting_copy_decl;
|
||||
+ id.cb.decl_map = pointer_map_create ();
|
||||
+ id.root = root;
|
||||
+
|
||||
+ for (; debug_var; debug_var = TREE_CHAIN (debug_var))
|
||||
+ if (variably_modified_type_p (TREE_TYPE (debug_var), NULL))
|
||||
+ {
|
||||
+ tree type = TREE_TYPE (debug_var);
|
||||
+ tree newt, t = type;
|
||||
+ struct nesting_info *i;
|
||||
+
|
||||
+ for (i = root; i; i = i->outer)
|
||||
+ if (variably_modified_type_p (type, i->context))
|
||||
+ break;
|
||||
+
|
||||
+ if (i == NULL)
|
||||
+ continue;
|
||||
+
|
||||
+ id.cb.src_fn = i->context;
|
||||
+ id.cb.dst_fn = i->context;
|
||||
+ id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context);
|
||||
+
|
||||
+ TREE_TYPE (debug_var) = newt = remap_type (type, &id.cb);
|
||||
+ while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt))
|
||||
+ {
|
||||
+ newt = TREE_TYPE (newt);
|
||||
+ t = TREE_TYPE (t);
|
||||
+ }
|
||||
+ if (TYPE_NAME (newt)
|
||||
+ && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL
|
||||
+ && DECL_ORIGINAL_TYPE (TYPE_NAME (newt))
|
||||
+ && newt != t
|
||||
+ && TYPE_NAME (newt) == TYPE_NAME (t))
|
||||
+ TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb);
|
||||
+ }
|
||||
+
|
||||
+ pointer_map_destroy (id.cb.decl_map);
|
||||
+ }
|
||||
+
|
||||
+ declare_vars (root->debug_var_chain,
|
||||
+ gimple_seq_first_stmt (gimple_body (root->context)),
|
||||
+ true);
|
||||
+ }
|
||||
|
||||
/* Dump the translated tree function. */
|
||||
dump_function (TDI_nested, root->context);
|
||||
--- gcc/dbxout.c.jj 2009-04-06 11:47:29.000000000 +0200
|
||||
+++ gcc/dbxout.c 2009-04-07 17:16:27.000000000 +0200
|
||||
@@ -1397,7 +1397,9 @@ dbxout_type_index (tree type)
|
||||
/* Used in several places: evaluates to '0' for a private decl,
|
||||
'1' for a protected decl, '2' for a public decl. */
|
||||
#define DECL_ACCESSIBILITY_CHAR(DECL) \
|
||||
-(TREE_PRIVATE (DECL) ? '0' : TREE_PROTECTED (DECL) ? '1' : '2')
|
||||
+((TREE_CODE (DECL) != PARM_DECL && TREE_CODE (DECL) != RESULT_DECL \
|
||||
+ && (TREE_CODE (DECL) != VAR_DECL || TREE_STATIC (DECL)) \
|
||||
+ && TREE_PRIVATE (DECL)) ? '0' : TREE_PROTECTED (DECL) ? '1' : '2')
|
||||
|
||||
/* Subroutine of `dbxout_type'. Output the type fields of TYPE.
|
||||
This must be a separate function because anonymous unions require
|
|
@ -0,0 +1,175 @@
|
|||
2009-04-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* dwarf2out.c (loc_descr_plus_const): New function.
|
||||
(build_cfa_aligned_loc, tls_mem_loc_descriptor,
|
||||
mem_loc_descriptor, loc_descriptor_from_tree_1,
|
||||
descr_info_loc, gen_variable_die): Use it.
|
||||
|
||||
--- gcc/dwarf2out.c.jj 2009-04-08 11:10:16.000000000 +0200
|
||||
+++ gcc/dwarf2out.c 2009-04-08 12:52:16.000000000 +0200
|
||||
@@ -3890,6 +3890,47 @@ add_loc_descr (dw_loc_descr_ref *list_he
|
||||
*d = descr;
|
||||
}
|
||||
|
||||
+/* Add a constant OFFSET to a location expression. */
|
||||
+
|
||||
+static void
|
||||
+loc_descr_plus_const (dw_loc_descr_ref *list_head, HOST_WIDE_INT offset)
|
||||
+{
|
||||
+ dw_loc_descr_ref loc;
|
||||
+ HOST_WIDE_INT *p;
|
||||
+
|
||||
+ gcc_assert (*list_head != NULL);
|
||||
+
|
||||
+ if (!offset)
|
||||
+ return;
|
||||
+
|
||||
+ /* Find the end of the chain. */
|
||||
+ for (loc = *list_head; loc->dw_loc_next != NULL; loc = loc->dw_loc_next)
|
||||
+ ;
|
||||
+
|
||||
+ p = NULL;
|
||||
+ if (loc->dw_loc_opc == DW_OP_fbreg
|
||||
+ || (loc->dw_loc_opc >= DW_OP_breg0 && loc->dw_loc_opc <= DW_OP_breg31))
|
||||
+ p = &loc->dw_loc_oprnd1.v.val_int;
|
||||
+ else if (loc->dw_loc_opc == DW_OP_bregx)
|
||||
+ p = &loc->dw_loc_oprnd2.v.val_int;
|
||||
+
|
||||
+ /* If the last operation is fbreg, breg{0..31,x}, optimize by adjusting its
|
||||
+ offset. Don't optimize if an signed integer overflow would happen. */
|
||||
+ if (p != NULL
|
||||
+ && ((offset > 0 && *p <= INTTYPE_MAXIMUM (HOST_WIDE_INT) - offset)
|
||||
+ || (offset < 0 && *p >= INTTYPE_MINIMUM (HOST_WIDE_INT) - offset)))
|
||||
+ *p += offset;
|
||||
+
|
||||
+ else if (offset > 0)
|
||||
+ loc->dw_loc_next = new_loc_descr (DW_OP_plus_uconst, offset, 0);
|
||||
+
|
||||
+ else
|
||||
+ {
|
||||
+ loc->dw_loc_next = int_loc_descriptor (offset);
|
||||
+ add_loc_descr (&loc->dw_loc_next, new_loc_descr (DW_OP_plus, 0, 0));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Return the size of a location descriptor. */
|
||||
|
||||
static unsigned long
|
||||
@@ -4409,9 +4450,7 @@ build_cfa_aligned_loc (HOST_WIDE_INT off
|
||||
head = new_reg_loc_descr (dwarf_fp, 0);
|
||||
add_loc_descr (&head, int_loc_descriptor (alignment));
|
||||
add_loc_descr (&head, new_loc_descr (DW_OP_and, 0, 0));
|
||||
-
|
||||
- add_loc_descr (&head, int_loc_descriptor (offset));
|
||||
- add_loc_descr (&head, new_loc_descr (DW_OP_plus, 0, 0));
|
||||
+ loc_descr_plus_const (&head, offset);
|
||||
}
|
||||
else
|
||||
head = new_reg_loc_descr (dwarf_fp, offset);
|
||||
@@ -9913,7 +9952,7 @@ static dw_loc_descr_ref
|
||||
tls_mem_loc_descriptor (rtx mem)
|
||||
{
|
||||
tree base;
|
||||
- dw_loc_descr_ref loc_result, loc_result2;
|
||||
+ dw_loc_descr_ref loc_result;
|
||||
|
||||
if (MEM_EXPR (mem) == NULL_TREE || MEM_OFFSET (mem) == NULL_RTX)
|
||||
return NULL;
|
||||
@@ -9929,21 +9968,7 @@ tls_mem_loc_descriptor (rtx mem)
|
||||
return NULL;
|
||||
|
||||
if (INTVAL (MEM_OFFSET (mem)))
|
||||
- {
|
||||
- if (INTVAL (MEM_OFFSET (mem)) >= 0)
|
||||
- add_loc_descr (&loc_result,
|
||||
- new_loc_descr (DW_OP_plus_uconst,
|
||||
- INTVAL (MEM_OFFSET (mem)), 0));
|
||||
- else
|
||||
- {
|
||||
- loc_result2 = mem_loc_descriptor (MEM_OFFSET (mem), GET_MODE (mem),
|
||||
- VAR_INIT_STATUS_INITIALIZED);
|
||||
- if (loc_result2 == 0)
|
||||
- return NULL;
|
||||
- add_loc_descr (&loc_result, loc_result2);
|
||||
- add_loc_descr (&loc_result, new_loc_descr (DW_OP_plus, 0, 0));
|
||||
- }
|
||||
- }
|
||||
+ loc_descr_plus_const (&loc_result, INTVAL (MEM_OFFSET (mem)));
|
||||
|
||||
return loc_result;
|
||||
}
|
||||
@@ -10108,11 +10133,8 @@ mem_loc_descriptor (rtx rtl, enum machin
|
||||
if (mem_loc_result == 0)
|
||||
break;
|
||||
|
||||
- if (GET_CODE (XEXP (rtl, 1)) == CONST_INT
|
||||
- && INTVAL (XEXP (rtl, 1)) >= 0)
|
||||
- add_loc_descr (&mem_loc_result,
|
||||
- new_loc_descr (DW_OP_plus_uconst,
|
||||
- INTVAL (XEXP (rtl, 1)), 0));
|
||||
+ if (GET_CODE (XEXP (rtl, 1)) == CONST_INT)
|
||||
+ loc_descr_plus_const (&mem_loc_result, INTVAL (XEXP (rtl, 1)));
|
||||
else
|
||||
{
|
||||
dw_loc_descr_ref mem_loc_result2
|
||||
@@ -10526,13 +10548,7 @@ loc_descriptor_from_tree_1 (tree loc, in
|
||||
}
|
||||
|
||||
bytepos = bitpos / BITS_PER_UNIT;
|
||||
- if (bytepos > 0)
|
||||
- add_loc_descr (&ret, new_loc_descr (DW_OP_plus_uconst, bytepos, 0));
|
||||
- else if (bytepos < 0)
|
||||
- {
|
||||
- add_loc_descr (&ret, int_loc_descriptor (bytepos));
|
||||
- add_loc_descr (&ret, new_loc_descr (DW_OP_plus, 0, 0));
|
||||
- }
|
||||
+ loc_descr_plus_const (&ret, bytepos);
|
||||
|
||||
have_address = 1;
|
||||
break;
|
||||
@@ -10616,11 +10632,7 @@ loc_descriptor_from_tree_1 (tree loc, in
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
- add_loc_descr (&ret,
|
||||
- new_loc_descr (DW_OP_plus_uconst,
|
||||
- tree_low_cst (TREE_OPERAND (loc, 1),
|
||||
- 0),
|
||||
- 0));
|
||||
+ loc_descr_plus_const (&ret, tree_low_cst (TREE_OPERAND (loc, 1), 0));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -13001,10 +13013,7 @@ descr_info_loc (tree val, tree base_decl
|
||||
loc = descr_info_loc (TREE_OPERAND (val, 0), base_decl);
|
||||
if (!loc)
|
||||
break;
|
||||
- add_loc_descr (&loc,
|
||||
- new_loc_descr (DW_OP_plus_uconst,
|
||||
- tree_low_cst (TREE_OPERAND (val, 1),
|
||||
- 1), 0));
|
||||
+ loc_descr_plus_const (&loc, tree_low_cst (TREE_OPERAND (val, 1), 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -13920,9 +13929,7 @@ gen_variable_die (tree decl, tree origin
|
||||
loc->dw_loc_oprnd1.v.val_addr
|
||||
= plus_constant (loc->dw_loc_oprnd1.v.val_addr, off);
|
||||
else
|
||||
- add_loc_descr (&loc,
|
||||
- new_loc_descr (DW_OP_plus_uconst,
|
||||
- off, 0));
|
||||
+ loc_descr_plus_const (&loc, off);
|
||||
}
|
||||
add_AT_loc (var_die, DW_AT_location, loc);
|
||||
remove_AT (var_die, DW_AT_declaration);
|
||||
@@ -13985,8 +13992,7 @@ gen_variable_die (tree decl, tree origin
|
||||
loc->dw_loc_oprnd1.v.val_addr
|
||||
= plus_constant (loc->dw_loc_oprnd1.v.val_addr, off);
|
||||
else
|
||||
- add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst,
|
||||
- off, 0));
|
||||
+ loc_descr_plus_const (&loc, off);
|
||||
}
|
||||
add_AT_loc (var_die, DW_AT_location, loc);
|
||||
}
|
|
@ -0,0 +1,468 @@
|
|||
2009-04-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* tree-nested.c (get_nonlocal_vla_type): If not optimizing, call
|
||||
note_nonlocal_vla_type for nonlocal VLAs.
|
||||
(note_nonlocal_vla_type, note_nonlocal_block_vlas,
|
||||
contains_remapped_vars, remap_vla_decls): New functions.
|
||||
(convert_nonlocal_reference_stmt): If not optimizing, call
|
||||
note_nonlocal_block_vlas on GIMPLE_BIND block vars.
|
||||
(nesting_copy_decl): Return {VAR,PARM,RESULT}_DECL unmodified
|
||||
if it wasn't found in var_map.
|
||||
(finalize_nesting_tree_1): Call remap_vla_decls. If outermost
|
||||
GIMPLE_BIND doesn't have gimple_bind_block, chain debug_var_chain
|
||||
to BLOCK_VARS (DECL_INITIAL (root->context)) instead of calling
|
||||
declare_vars.
|
||||
* gimplify.c (nonlocal_vlas): New variable.
|
||||
(gimplify_var_or_parm_decl): Add debug VAR_DECLs for non-local
|
||||
referenced VLAs.
|
||||
(gimplify_body): Create and destroy nonlocal_vlas.
|
||||
|
||||
* trans-decl.c: Include pointer-set.h.
|
||||
(nonlocal_dummy_decl_pset, tree nonlocal_dummy_decls): New variables.
|
||||
(gfc_nonlocal_dummy_array_decl): New function.
|
||||
(gfc_get_symbol_decl): Call it for non-local dummy args with saved
|
||||
descriptor.
|
||||
(gfc_get_symbol_decl): Set DECL_BY_REFERENCE when needed.
|
||||
(gfc_generate_function_code): Initialize nonlocal_dummy_decl{s,_pset},
|
||||
chain it to outermost block's vars, destroy it afterwards.
|
||||
|
||||
* Make-lang.in (trans-decl.o): Depend on pointer-set.h.
|
||||
|
||||
--- gcc/tree-nested.c.jj 2009-04-21 19:24:25.000000000 +0200
|
||||
+++ gcc/tree-nested.c 2009-04-22 10:18:38.000000000 +0200
|
||||
@@ -770,6 +770,7 @@ get_frame_field (struct nesting_info *in
|
||||
return x;
|
||||
}
|
||||
|
||||
+static void note_nonlocal_vla_type (struct nesting_info *info, tree type);
|
||||
|
||||
/* A subroutine of convert_nonlocal_reference_op. Create a local variable
|
||||
in the nested function with DECL_VALUE_EXPR set to reference the true
|
||||
@@ -840,6 +841,11 @@ get_nonlocal_debug_decl (struct nesting_
|
||||
TREE_CHAIN (new_decl) = info->debug_var_chain;
|
||||
info->debug_var_chain = new_decl;
|
||||
|
||||
+ if (!optimize
|
||||
+ && info->context != target_context
|
||||
+ && variably_modified_type_p (TREE_TYPE (decl), NULL))
|
||||
+ note_nonlocal_vla_type (info, TREE_TYPE (decl));
|
||||
+
|
||||
return new_decl;
|
||||
}
|
||||
|
||||
@@ -1111,6 +1117,60 @@ convert_nonlocal_omp_clauses (tree *pcla
|
||||
return need_chain;
|
||||
}
|
||||
|
||||
+/* Create nonlocal debug decls for nonlocal VLA array bounds. */
|
||||
+
|
||||
+static void
|
||||
+note_nonlocal_vla_type (struct nesting_info *info, tree type)
|
||||
+{
|
||||
+ while (POINTER_TYPE_P (type) && !TYPE_NAME (type))
|
||||
+ type = TREE_TYPE (type);
|
||||
+
|
||||
+ if (TYPE_NAME (type)
|
||||
+ && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
|
||||
+ && DECL_ORIGINAL_TYPE (TYPE_NAME (type)))
|
||||
+ type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
|
||||
+
|
||||
+ while (POINTER_TYPE_P (type)
|
||||
+ || TREE_CODE (type) == VECTOR_TYPE
|
||||
+ || TREE_CODE (type) == FUNCTION_TYPE
|
||||
+ || TREE_CODE (type) == METHOD_TYPE)
|
||||
+ type = TREE_TYPE (type);
|
||||
+
|
||||
+ if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
+ {
|
||||
+ tree domain, t;
|
||||
+
|
||||
+ note_nonlocal_vla_type (info, TREE_TYPE (type));
|
||||
+ domain = TYPE_DOMAIN (type);
|
||||
+ if (domain)
|
||||
+ {
|
||||
+ t = TYPE_MIN_VALUE (domain);
|
||||
+ if (t && (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL)
|
||||
+ && decl_function_context (t) != info->context)
|
||||
+ get_nonlocal_debug_decl (info, t);
|
||||
+ t = TYPE_MAX_VALUE (domain);
|
||||
+ if (t && (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL)
|
||||
+ && decl_function_context (t) != info->context)
|
||||
+ get_nonlocal_debug_decl (info, t);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Create nonlocal debug decls for nonlocal VLA array bounds for VLAs
|
||||
+ in BLOCK. */
|
||||
+
|
||||
+static void
|
||||
+note_nonlocal_block_vlas (struct nesting_info *info, tree block)
|
||||
+{
|
||||
+ tree var;
|
||||
+
|
||||
+ for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var))
|
||||
+ if (TREE_CODE (var) == VAR_DECL
|
||||
+ && variably_modified_type_p (TREE_TYPE (var), NULL)
|
||||
+ && DECL_HAS_VALUE_EXPR_P (var)
|
||||
+ && decl_function_context (var) != info->context)
|
||||
+ note_nonlocal_vla_type (info, TREE_TYPE (var));
|
||||
+}
|
||||
|
||||
/* Callback for walk_gimple_stmt. Rewrite all references to VAR and
|
||||
PARM_DECLs that belong to outer functions. This handles statements
|
||||
@@ -1202,6 +1262,13 @@ convert_nonlocal_reference_stmt (gimple_
|
||||
info, gimple_omp_body (stmt));
|
||||
break;
|
||||
|
||||
+ case GIMPLE_BIND:
|
||||
+ if (!optimize && gimple_bind_block (stmt))
|
||||
+ note_nonlocal_block_vlas (info, gimple_bind_block (stmt));
|
||||
+
|
||||
+ *handled_ops_p = false;
|
||||
+ return NULL_TREE;
|
||||
+
|
||||
default:
|
||||
/* For every other statement that we are not interested in
|
||||
handling here, let the walker traverse the operands. */
|
||||
@@ -1979,9 +2046,117 @@ nesting_copy_decl (tree decl, copy_body_
|
||||
return new_decl;
|
||||
}
|
||||
|
||||
+ if (TREE_CODE (decl) == VAR_DECL
|
||||
+ || TREE_CODE (decl) == PARM_DECL
|
||||
+ || TREE_CODE (decl) == RESULT_DECL)
|
||||
+ return decl;
|
||||
+
|
||||
return copy_decl_no_change (decl, id);
|
||||
}
|
||||
|
||||
+/* A helper function for remap_vla_decls. See if *TP contains
|
||||
+ some remapped variables. */
|
||||
+
|
||||
+static tree
|
||||
+contains_remapped_vars (tree *tp, int *walk_subtrees, void *data)
|
||||
+{
|
||||
+ struct nesting_info *root = (struct nesting_info *) data;
|
||||
+ tree t = *tp;
|
||||
+ void **slot;
|
||||
+
|
||||
+ if (DECL_P (t))
|
||||
+ {
|
||||
+ *walk_subtrees = 0;
|
||||
+ slot = pointer_map_contains (root->var_map, t);
|
||||
+
|
||||
+ if (slot)
|
||||
+ return (tree) *slot;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/* Remap VLA decls in BLOCK and subblocks if remapped variables are
|
||||
+ involved. */
|
||||
+
|
||||
+static void
|
||||
+remap_vla_decls (tree block, struct nesting_info *root)
|
||||
+{
|
||||
+ tree var, subblock, val, type;
|
||||
+ struct nesting_copy_body_data id;
|
||||
+
|
||||
+ for (subblock = BLOCK_SUBBLOCKS (block);
|
||||
+ subblock;
|
||||
+ subblock = BLOCK_CHAIN (subblock))
|
||||
+ remap_vla_decls (subblock, root);
|
||||
+
|
||||
+ for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var))
|
||||
+ {
|
||||
+ if (TREE_CODE (var) == VAR_DECL
|
||||
+ && variably_modified_type_p (TREE_TYPE (var), NULL)
|
||||
+ && DECL_HAS_VALUE_EXPR_P (var))
|
||||
+ {
|
||||
+ type = TREE_TYPE (var);
|
||||
+ val = DECL_VALUE_EXPR (var);
|
||||
+ if (walk_tree (&type, contains_remapped_vars, root, NULL) != NULL
|
||||
+ || walk_tree (&val, contains_remapped_vars, root, NULL) != NULL)
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (var == NULL_TREE)
|
||||
+ return;
|
||||
+
|
||||
+ memset (&id, 0, sizeof (id));
|
||||
+ id.cb.copy_decl = nesting_copy_decl;
|
||||
+ id.cb.decl_map = pointer_map_create ();
|
||||
+ id.root = root;
|
||||
+
|
||||
+ for (; var; var = TREE_CHAIN (var))
|
||||
+ if (TREE_CODE (var) == VAR_DECL
|
||||
+ && variably_modified_type_p (TREE_TYPE (var), NULL)
|
||||
+ && DECL_HAS_VALUE_EXPR_P (var))
|
||||
+ {
|
||||
+ struct nesting_info *i;
|
||||
+ tree newt, t, context;
|
||||
+
|
||||
+ t = type = TREE_TYPE (var);
|
||||
+ val = DECL_VALUE_EXPR (var);
|
||||
+ if (walk_tree (&type, contains_remapped_vars, root, NULL) == NULL
|
||||
+ && walk_tree (&val, contains_remapped_vars, root, NULL) == NULL)
|
||||
+ continue;
|
||||
+
|
||||
+ context = decl_function_context (var);
|
||||
+ for (i = root; i; i = i->outer)
|
||||
+ if (i->context == context)
|
||||
+ break;
|
||||
+
|
||||
+ if (i == NULL)
|
||||
+ continue;
|
||||
+
|
||||
+ id.cb.src_fn = i->context;
|
||||
+ id.cb.dst_fn = i->context;
|
||||
+ id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context);
|
||||
+
|
||||
+ TREE_TYPE (var) = newt = remap_type (type, &id.cb);
|
||||
+ while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt))
|
||||
+ {
|
||||
+ newt = TREE_TYPE (newt);
|
||||
+ t = TREE_TYPE (t);
|
||||
+ }
|
||||
+ if (TYPE_NAME (newt)
|
||||
+ && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL
|
||||
+ && DECL_ORIGINAL_TYPE (TYPE_NAME (newt))
|
||||
+ && newt != t
|
||||
+ && TYPE_NAME (newt) == TYPE_NAME (t))
|
||||
+ TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb);
|
||||
+
|
||||
+ walk_tree (&val, copy_tree_body_r, &id.cb, NULL);
|
||||
+ if (val != DECL_VALUE_EXPR (var))
|
||||
+ SET_DECL_VALUE_EXPR (var, val);
|
||||
+ }
|
||||
+
|
||||
+ pointer_map_destroy (id.cb.decl_map);
|
||||
+}
|
||||
+
|
||||
/* Do "everything else" to clean up or complete state collected by the
|
||||
various walking passes -- lay out the types and decls, generate code
|
||||
to initialize the frame decl, store critical expressions in the
|
||||
@@ -2118,6 +2293,9 @@ finalize_nesting_tree_1 (struct nesting_
|
||||
if (root->debug_var_chain)
|
||||
{
|
||||
tree debug_var;
|
||||
+ gimple scope;
|
||||
+
|
||||
+ remap_vla_decls (DECL_INITIAL (root->context), root);
|
||||
|
||||
for (debug_var = root->debug_var_chain; debug_var;
|
||||
debug_var = TREE_CHAIN (debug_var))
|
||||
@@ -2170,9 +2348,13 @@ finalize_nesting_tree_1 (struct nesting_
|
||||
pointer_map_destroy (id.cb.decl_map);
|
||||
}
|
||||
|
||||
- declare_vars (root->debug_var_chain,
|
||||
- gimple_seq_first_stmt (gimple_body (root->context)),
|
||||
- true);
|
||||
+ scope = gimple_seq_first_stmt (gimple_body (root->context));
|
||||
+ if (gimple_bind_block (scope))
|
||||
+ declare_vars (root->debug_var_chain, scope, true);
|
||||
+ else
|
||||
+ BLOCK_VARS (DECL_INITIAL (root->context))
|
||||
+ = chainon (BLOCK_VARS (DECL_INITIAL (root->context)),
|
||||
+ root->debug_var_chain);
|
||||
}
|
||||
|
||||
/* Dump the translated tree function. */
|
||||
--- gcc/gimplify.c.jj 2009-04-21 19:23:29.000000000 +0200
|
||||
+++ gcc/gimplify.c 2009-04-22 00:20:41.000000000 +0200
|
||||
@@ -1851,6 +1851,9 @@ gimplify_conversion (tree *expr_p)
|
||||
return GS_OK;
|
||||
}
|
||||
|
||||
+/* Nonlocal VLAs seen in the current function. */
|
||||
+static struct pointer_set_t *nonlocal_vlas;
|
||||
+
|
||||
/* Gimplify a VAR_DECL or PARM_DECL. Returns GS_OK if we expanded a
|
||||
DECL_VALUE_EXPR, and it's worth re-examining things. */
|
||||
|
||||
@@ -1881,7 +1884,36 @@ gimplify_var_or_parm_decl (tree *expr_p)
|
||||
/* If the decl is an alias for another expression, substitute it now. */
|
||||
if (DECL_HAS_VALUE_EXPR_P (decl))
|
||||
{
|
||||
- *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
|
||||
+ tree value_expr = DECL_VALUE_EXPR (decl);
|
||||
+
|
||||
+ /* For referenced nonlocal VLAs add a decl for debugging purposes
|
||||
+ to the current function. */
|
||||
+ if (TREE_CODE (decl) == VAR_DECL
|
||||
+ && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
|
||||
+ && nonlocal_vlas != NULL
|
||||
+ && TREE_CODE (value_expr) == INDIRECT_REF
|
||||
+ && TREE_CODE (TREE_OPERAND (value_expr, 0)) == VAR_DECL
|
||||
+ && decl_function_context (decl) != current_function_decl)
|
||||
+ {
|
||||
+ struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
|
||||
+ while (ctx && ctx->region_type == ORT_WORKSHARE)
|
||||
+ ctx = ctx->outer_context;
|
||||
+ if (!ctx && !pointer_set_insert (nonlocal_vlas, decl))
|
||||
+ {
|
||||
+ tree copy = copy_node (decl), block;
|
||||
+
|
||||
+ lang_hooks.dup_lang_specific_decl (copy);
|
||||
+ SET_DECL_RTL (copy, NULL_RTX);
|
||||
+ TREE_USED (copy) = 1;
|
||||
+ block = DECL_INITIAL (current_function_decl);
|
||||
+ TREE_CHAIN (copy) = BLOCK_VARS (block);
|
||||
+ BLOCK_VARS (block) = copy;
|
||||
+ SET_DECL_VALUE_EXPR (copy, unshare_expr (value_expr));
|
||||
+ DECL_HAS_VALUE_EXPR_P (copy) = 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *expr_p = unshare_expr (value_expr);
|
||||
return GS_OK;
|
||||
}
|
||||
|
||||
@@ -7359,6 +7391,9 @@ gimplify_body (tree *body_p, tree fndecl
|
||||
unshare_body (body_p, fndecl);
|
||||
unvisit_body (body_p, fndecl);
|
||||
|
||||
+ if (cgraph_node (fndecl)->origin)
|
||||
+ nonlocal_vlas = pointer_set_create ();
|
||||
+
|
||||
/* Make sure input_location isn't set to something weird. */
|
||||
input_location = DECL_SOURCE_LOCATION (fndecl);
|
||||
|
||||
@@ -7394,6 +7429,12 @@ gimplify_body (tree *body_p, tree fndecl
|
||||
gimple_bind_set_body (outer_bind, parm_stmts);
|
||||
}
|
||||
|
||||
+ if (nonlocal_vlas)
|
||||
+ {
|
||||
+ pointer_set_destroy (nonlocal_vlas);
|
||||
+ nonlocal_vlas = NULL;
|
||||
+ }
|
||||
+
|
||||
pop_gimplify_context (outer_bind);
|
||||
gcc_assert (gimplify_ctxp == NULL);
|
||||
|
||||
--- gcc/fortran/Make-lang.in.jj 2008-12-11 13:30:28.000000000 +0100
|
||||
+++ gcc/fortran/Make-lang.in 2009-04-21 19:26:35.000000000 +0200
|
||||
@@ -319,7 +319,7 @@ fortran/convert.o: $(GFORTRAN_TRANS_DEPS
|
||||
fortran/trans.o: $(GFORTRAN_TRANS_DEPS) tree-iterator.h
|
||||
fortran/trans-decl.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-decl.h \
|
||||
$(CGRAPH_H) $(TARGET_H) $(FUNCTION_H) $(FLAGS_H) $(RTL_H) $(GIMPLE_H) \
|
||||
- $(TREE_DUMP_H) debug.h
|
||||
+ $(TREE_DUMP_H) debug.h pointer-set.h
|
||||
fortran/trans-types.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-types.h \
|
||||
$(REAL_H) toplev.h $(TARGET_H) $(FLAGS_H) dwarf2out.h
|
||||
fortran/trans-const.o: $(GFORTRAN_TRANS_DEPS)
|
||||
--- gcc/fortran/trans-decl.c.jj 2009-04-14 10:18:29.000000000 +0200
|
||||
+++ gcc/fortran/trans-decl.c 2009-04-21 19:26:35.000000000 +0200
|
||||
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.
|
||||
#include "cgraph.h"
|
||||
#include "debug.h"
|
||||
#include "gfortran.h"
|
||||
+#include "pointer-set.h"
|
||||
#include "trans.h"
|
||||
#include "trans-types.h"
|
||||
#include "trans-array.h"
|
||||
@@ -60,6 +61,8 @@ static GTY(()) tree current_function_ret
|
||||
static GTY(()) tree saved_function_decls;
|
||||
static GTY(()) tree saved_parent_function_decls;
|
||||
|
||||
+static struct pointer_set_t *nonlocal_dummy_decl_pset;
|
||||
+static GTY(()) tree nonlocal_dummy_decls;
|
||||
|
||||
/* The namespace of the module we're currently generating. Only used while
|
||||
outputting decls for module variables. Do not rely on this being set. */
|
||||
@@ -870,6 +873,38 @@ gfc_build_dummy_array_decl (gfc_symbol *
|
||||
return decl;
|
||||
}
|
||||
|
||||
+/* For symbol SYM with GFC_DECL_SAVED_DESCRIPTOR used in contained
|
||||
+ function add a VAR_DECL to the current function with DECL_VALUE_EXPR
|
||||
+ pointing to the artificial variable for debug info purposes. */
|
||||
+
|
||||
+static void
|
||||
+gfc_nonlocal_dummy_array_decl (gfc_symbol *sym)
|
||||
+{
|
||||
+ tree decl, dummy;
|
||||
+
|
||||
+ if (! nonlocal_dummy_decl_pset)
|
||||
+ nonlocal_dummy_decl_pset = pointer_set_create ();
|
||||
+
|
||||
+ if (pointer_set_insert (nonlocal_dummy_decl_pset, sym->backend_decl))
|
||||
+ return;
|
||||
+
|
||||
+ dummy = GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl);
|
||||
+ decl = build_decl (VAR_DECL, DECL_NAME (dummy),
|
||||
+ TREE_TYPE (sym->backend_decl));
|
||||
+ DECL_ARTIFICIAL (decl) = 0;
|
||||
+ TREE_USED (decl) = 1;
|
||||
+ TREE_PUBLIC (decl) = 0;
|
||||
+ TREE_STATIC (decl) = 0;
|
||||
+ DECL_EXTERNAL (decl) = 0;
|
||||
+ if (DECL_BY_REFERENCE (dummy))
|
||||
+ DECL_BY_REFERENCE (decl) = 1;
|
||||
+ DECL_LANG_SPECIFIC (decl) = DECL_LANG_SPECIFIC (sym->backend_decl);
|
||||
+ SET_DECL_VALUE_EXPR (decl, sym->backend_decl);
|
||||
+ DECL_HAS_VALUE_EXPR_P (decl) = 1;
|
||||
+ DECL_CONTEXT (decl) = DECL_CONTEXT (sym->backend_decl);
|
||||
+ TREE_CHAIN (decl) = nonlocal_dummy_decls;
|
||||
+ nonlocal_dummy_decls = decl;
|
||||
+}
|
||||
|
||||
/* Return a constant or a variable to use as a string length. Does not
|
||||
add the decl to the current scope. */
|
||||
@@ -1010,6 +1045,13 @@ gfc_get_symbol_decl (gfc_symbol * sym)
|
||||
{
|
||||
gfc_add_assign_aux_vars (sym);
|
||||
}
|
||||
+
|
||||
+ if (sym->attr.dimension
|
||||
+ && DECL_LANG_SPECIFIC (sym->backend_decl)
|
||||
+ && GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl)
|
||||
+ && DECL_CONTEXT (sym->backend_decl) != current_function_decl)
|
||||
+ gfc_nonlocal_dummy_array_decl (sym);
|
||||
+
|
||||
return sym->backend_decl;
|
||||
}
|
||||
|
||||
@@ -1129,6 +1171,13 @@ gfc_get_symbol_decl (gfc_symbol * sym)
|
||||
sym->attr.pointer || sym->attr.allocatable);
|
||||
}
|
||||
|
||||
+ if (!TREE_STATIC (decl)
|
||||
+ && POINTER_TYPE_P (TREE_TYPE (decl))
|
||||
+ && !sym->attr.pointer
|
||||
+ && !sym->attr.allocatable
|
||||
+ && !sym->attr.proc_pointer)
|
||||
+ DECL_BY_REFERENCE (decl) = 1;
|
||||
+
|
||||
return decl;
|
||||
}
|
||||
|
||||
@@ -3852,6 +3901,9 @@ gfc_generate_function_code (gfc_namespac
|
||||
|
||||
gfc_generate_contained_functions (ns);
|
||||
|
||||
+ nonlocal_dummy_decls = NULL;
|
||||
+ nonlocal_dummy_decl_pset = NULL;
|
||||
+
|
||||
generate_local_vars (ns);
|
||||
|
||||
/* Keep the parent fake result declaration in module functions
|
||||
@@ -4111,6 +4163,15 @@ gfc_generate_function_code (gfc_namespac
|
||||
= build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl),
|
||||
DECL_INITIAL (fndecl));
|
||||
|
||||
+ if (nonlocal_dummy_decls)
|
||||
+ {
|
||||
+ BLOCK_VARS (DECL_INITIAL (fndecl))
|
||||
+ = chainon (BLOCK_VARS (DECL_INITIAL (fndecl)), nonlocal_dummy_decls);
|
||||
+ pointer_set_destroy (nonlocal_dummy_decl_pset);
|
||||
+ nonlocal_dummy_decls = NULL;
|
||||
+ nonlocal_dummy_decl_pset = NULL;
|
||||
+ }
|
||||
+
|
||||
/* Output the GENERIC tree. */
|
||||
dump_function (TDI_original, fndecl);
|
||||
|
Loading…
Reference in New Issue