aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/common.opt5
-rw-r--r--gcc/doc/invoke.texi8
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gfortran.dg/unconstrained_commons.f20
-rw-r--r--gcc/tree-dfa.c15
-rw-r--r--gcc/tree.c6
7 files changed, 64 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ce244b1..b6db5de 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2016-03-10 Alan Lawrence <alan.lawrence@arm.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * common.opt (funconstrained-commons, flag_unconstrained_commons): New.
+ * tree.c (array_at_struct_end_p): Do not limit to size of decl for
+ DECL_COMMONS if flag_unconstrained_commons is set.
+ * tree-dfa.c (get_ref_base_and_extent): Likewise.
+ * doc/invoke.texi (Optimize Options): Add -funconstrained-commons.
+ (funconstrained-commons): Document.
+
2016-03-10 Christophe Lyon <christophe.lyon@linaro.org>
* config/aarch64/t-aarch64 (OPTIONS_H_EXTRA): Add
diff --git a/gcc/common.opt b/gcc/common.opt
index e91f225..1c8cc8e 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2458,6 +2458,11 @@ fsplit-paths
Common Report Var(flag_split_paths) Init(0) Optimization
Split paths leading to loop backedges.
+funconstrained-commons
+Common Var(flag_unconstrained_commons) Optimization
+Assume common declarations may be overridden with ones with a larger
+trailing array.
+
funit-at-a-time
Common Report Var(flag_unit_at_a_time) Init(1)
Compile whole compilation unit at a time.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 9580c10..99ac11b 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -408,7 +408,7 @@ Objective-C and Objective-C++ Dialects}.
-ftree-parallelize-loops=@var{n} -ftree-pre -ftree-partial-pre -ftree-pta @gol
-ftree-reassoc -ftree-sink -ftree-slsr -ftree-sra @gol
-ftree-switch-conversion -ftree-tail-merge -ftree-ter @gol
--ftree-vectorize -ftree-vrp @gol
+-ftree-vectorize -ftree-vrp -funconstrained-commons @gol
-funit-at-a-time -funroll-all-loops -funroll-loops @gol
-funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol
-fipa-ra -fvariable-expansion-in-unroller -fvect-cost-model -fvpt @gol
@@ -6699,6 +6699,12 @@ the loop optimizer itself cannot prove that these assumptions are valid.
If you use @option{-Wunsafe-loop-optimizations}, the compiler warns you
if it finds this kind of loop.
+@item -funconstrained-commons
+@opindex funconstrained-commons
+This option tells the compiler that variables declared in common blocks
+(e.g. Fortran) may later be overridden with longer trailing arrays. This
+prevents certain optimizations that depend on knowing the array bounds.
+
@item -fcrossjumping
@opindex fcrossjumping
Perform cross-jumping transformation.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9ae7afd..f2ed2ab 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2016-03-10 Alan Lawrence <alan.lawrence@arm.com>
+
+ * gfortran.dg/unconstrained_commons.f: New.
+
2016-03-10 Alan Modra <amodra@gmail.com>
* gcc.dg/pr69195.c: New.
diff --git a/gcc/testsuite/gfortran.dg/unconstrained_commons.f b/gcc/testsuite/gfortran.dg/unconstrained_commons.f
new file mode 100644
index 0000000..f9fc471
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/unconstrained_commons.f
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-O3 -funconstrained-commons -fdump-tree-dom2-details" }
+
+! Test for PR69368: a single-element array in a common block, which will be
+! overridden with a larger size at link time (contrary to language spec).
+! Dominator opts considers accesses to differently-computed elements of X as
+! equivalent, unless -funconstrained-commons is passed in.
+ SUBROUTINE FOO
+ IMPLICIT DOUBLE PRECISION (X)
+ INTEGER J
+ COMMON /MYCOMMON / X(1)
+ DO 10 J=1,1024
+ X(J+1)=X(J+7)
+ 10 CONTINUE
+ RETURN
+ END
+! { dg-final { scan-tree-dump-not "FIND" "dom2" } }
+! We should retain both a read and write of mycommon.x.
+! { dg-final { scan-tree-dump-times " _\[0-9\]+ = mycommon\\.x\\\[_\[0-9\]+\\\];" 1 "dom2" } }
+! { dg-final { scan-tree-dump-times " mycommon\\.x\\\[_\[0-9\]+\\\] = _\[0-9\]+;" 1 "dom2" } }
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 0e98056..f133abc 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -612,9 +612,22 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
if (DECL_P (exp))
{
+ if (flag_unconstrained_commons
+ && TREE_CODE (exp) == VAR_DECL && DECL_COMMON (exp))
+ {
+ tree sz_tree = TYPE_SIZE (TREE_TYPE (exp));
+ /* If size is unknown, or we have read to the end, assume there
+ may be more to the structure than we are told. */
+ if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
+ || (seen_variable_array_ref
+ && (sz_tree == NULL_TREE
+ || TREE_CODE (sz_tree) != INTEGER_CST
+ || (bit_offset + maxsize == wi::to_offset (sz_tree)))))
+ maxsize = -1;
+ }
/* If maxsize is unknown adjust it according to the size of the
base decl. */
- if (maxsize == -1
+ else if (maxsize == -1
&& DECL_SIZE (exp)
&& TREE_CODE (DECL_SIZE (exp)) == INTEGER_CST)
maxsize = wi::to_offset (DECL_SIZE (exp)) - bit_offset;
diff --git a/gcc/tree.c b/gcc/tree.c
index b8333d4..7d0cb03 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -12952,8 +12952,10 @@ array_at_struct_end_p (tree ref)
}
/* If the reference is based on a declared entity, the size of the array
- is constrained by its given domain. */
- if (DECL_P (ref))
+ is constrained by its given domain. (Do not trust commons PR/69368). */
+ if (DECL_P (ref)
+ && !(flag_unconstrained_commons
+ && TREE_CODE (ref) == VAR_DECL && DECL_COMMON (ref)))
return false;
return true;