Re: [PATCH] Add -funknown-commons to work around PR/69368 (and others) in SPEC2006
On Fri, Mar 04, 2016 at 02:27:46PM +0100, Richard Biener wrote: > > +funknown-commons > > +Common Var(flag_unknown_commons) > > +Assume common declarations may be overridden with unknown larger sizes > > I think to make it work with LTO you need to mark it 'Optimization'. > Also it's about > arrays so maybe > > 'Assume common declarations may be overridden with ones with a larger > trailing array' > > also if we document it here we should eventually document it in invoke.texi. Also, isn't the *.opt description line supposed to end with a full stop? Jakub
Re: [PATCH] Add -funknown-commons to work around PR/69368 (and others) in SPEC2006
On Thu, Feb 25, 2016 at 7:00 PM, Alan Lawrence wrote: > On 22/02/16 12:03, Jakub Jelinek wrote: >> (f) A global command-line option, which we check alongside DECL_COMMON and >> further tests (basically, we want only DECL_COMMON decls that either have >> ARRAY_TYPE, or some other aggregate type with flexible array member or some >> other trailing array in the struct), and use the resulting predicate in >> places where we optimize based on DECL_SIZE{,_UNIT} of the decl - if that >> predicate returns true, we assume the DECL_SIZE is >> "variable"/"unlimited"/whatever. >> The two spots known to me that would need to use this new predicate would >> be: >> tree.c (array_at_struct_end_p): > [...] >> tree-dfa.c (get_ref_base_and_extent): > [...] > > Close enough to what I meant by (a)/(b), but never mind that, and I hadn't > looked at where the change for aggressive loop opts needed to be. However... > Well you are essentially writing the patch for me at this point (so, thanks!), > but here's a patch that puts that under a global -funknown-commons flag. > Testcase as before. > > Bootstrapped (with flag overridden to true) on x86_64 and aarch64, check-gcc, > check-fortran, and tested 416.gamess on AArch64, where this patch enables > running *without* the -fno-aggressive-loop-opts previously required. > > In the gcc testsuite, these fail with the option turned on: > gcc.dg/pr53265.c (test for warnings, line 137) > gcc.dg/pr53265.c (test for warnings, line 138) > gcc.dg/pr64277.c scan-tree-dump cunroll ... (*2) > gcc.dg/tree-ssa/cunroll-{1,2,3,4,9,10,11}.c scan-tree-dump > cunroll/cunrolli/ivcanon (various) > gcc.dg/tree-ssa/loop-38.c scan-tree-dump cunrolli "Loop 1 iterates at most 11 > times" > ...which all appear harmless. > > Thomas Koenig suggests > (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69368#c80) > that this be combined with some flag fiddling and warnings in the Fortran > front-end; this patch doesn't do that, as I'm not very familiar with the > frontends, but that can follow in a separate patch. (Thomas?) > > OK for trunk? Comments below. > Cheers, Alan > > gcc/ChangeLog: > > DATE Alan Lawrence > Jakub Jelinek > > * common.opt (funknown-commons, flag_unknown_commons): New. > * tree.c (array_at_struct_end_p): Do not limit to size of decl for > DECL_COMMONS if flag_unknown_commons is set. > * tree-dfa.c (get_ref_base_and_extent): Likewise. > > gcc/testsuite/ChangeLog: > > * gfortran.dg/unknown_commons.f: New. > --- > gcc/common.opt | 4 > gcc/testsuite/gfortran.dg/unknown_commons.f | 20 > gcc/tree-dfa.c | 15 ++- > gcc/tree.c | 6 -- > 4 files changed, 42 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/gfortran.dg/unknown_commons.f > > diff --git a/gcc/common.opt b/gcc/common.opt > index 520fa9c..b5b1282 100644 > --- a/gcc/common.opt > +++ b/gcc/common.opt > @@ -2455,6 +2455,10 @@ funit-at-a-time > Common Report Var(flag_unit_at_a_time) Init(1) > Compile whole compilation unit at a time. > > +funknown-commons > +Common Var(flag_unknown_commons) > +Assume common declarations may be overridden with unknown larger sizes I think to make it work with LTO you need to mark it 'Optimization'. Also it's about arrays so maybe 'Assume common declarations may be overridden with ones with a larger trailing array' also if we document it here we should eventually document it in invoke.texi. Not sure if "unknown commons" is a good term, maybe "unconstrained commons" instead? Otherwise looks ok to me. Richard. > + > funroll-loops > Common Report Var(flag_unroll_loops) Optimization > Perform loop unrolling when iteration count is known. > diff --git a/gcc/testsuite/gfortran.dg/unknown_commons.f > b/gcc/testsuite/gfortran.dg/unknown_commons.f > new file mode 100644 > index 000..97e3ce3 > --- /dev/null > +++ b/gcc/testsuite/gfortran.dg/unknown_commons.f > @@ -0,0 +1,20 @@ > +! { dg-do compile } > +! { dg-options "-O3 -funknown-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 -funknown-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
Re: [PATCH] Add -funknown-commons to work around PR/69368 (and others) in SPEC2006
On 25/02/16 18:00, Alan Lawrence wrote: On 22/02/16 12:03, Jakub Jelinek wrote: (f) A global command-line option, which we check alongside DECL_COMMON and further tests (basically, we want only DECL_COMMON decls that either have ARRAY_TYPE, or some other aggregate type with flexible array member or some other trailing array in the struct), and use the resulting predicate in places where we optimize based on DECL_SIZE{,_UNIT} of the decl - if that predicate returns true, we assume the DECL_SIZE is "variable"/"unlimited"/whatever. The two spots known to me that would need to use this new predicate would be: tree.c (array_at_struct_end_p): [...] tree-dfa.c (get_ref_base_and_extent): [...] Close enough to what I meant by (a)/(b), but never mind that, and I hadn't looked at where the change for aggressive loop opts needed to be. However... Well you are essentially writing the patch for me at this point (so, thanks!), but here's a patch that puts that under a global -funknown-commons flag. Testcase as before. Bootstrapped (with flag overridden to true) on x86_64 and aarch64, check-gcc, check-fortran, and tested 416.gamess on AArch64, where this patch enables running *without* the -fno-aggressive-loop-opts previously required. In the gcc testsuite, these fail with the option turned on: gcc.dg/pr53265.c (test for warnings, line 137) gcc.dg/pr53265.c (test for warnings, line 138) gcc.dg/pr64277.c scan-tree-dump cunroll ... (*2) gcc.dg/tree-ssa/cunroll-{1,2,3,4,9,10,11}.c scan-tree-dump cunroll/cunrolli/ivcanon (various) gcc.dg/tree-ssa/loop-38.c scan-tree-dump cunrolli "Loop 1 iterates at most 11 times" ...which all appear harmless. Thomas Koenig suggests (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69368#c80) that this be combined with some flag fiddling and warnings in the Fortran front-end; this patch doesn't do that, as I'm not very familiar with the frontends, but that can follow in a separate patch. (Thomas?) OK for trunk? Cheers, Alan gcc/ChangeLog: DATE Alan Lawrence Jakub Jelinek * common.opt (funknown-commons, flag_unknown_commons): New. * tree.c (array_at_struct_end_p): Do not limit to size of decl for DECL_COMMONS if flag_unknown_commons is set. * tree-dfa.c (get_ref_base_and_extent): Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/unknown_commons.f: New. Ping. (Besides my original patch https://gcc.gnu.org/ml/gcc-patches/2016-02/msg01356.html which we decided was too fragile, I believe this is the only patch proposed that actually fixes the miscompare in 416.gamess.) Thanks, Alan
Re: [PATCH] Add -funknown-commons to work around PR/69368 (and others) in SPEC2006
On 22/02/16 12:03, Jakub Jelinek wrote: > (f) A global command-line option, which we check alongside DECL_COMMON and > further tests (basically, we want only DECL_COMMON decls that either have > ARRAY_TYPE, or some other aggregate type with flexible array member or some > other trailing array in the struct), and use the resulting predicate in > places where we optimize based on DECL_SIZE{,_UNIT} of the decl - if that > predicate returns true, we assume the DECL_SIZE is > "variable"/"unlimited"/whatever. > The two spots known to me that would need to use this new predicate would > be: > tree.c (array_at_struct_end_p): [...] > tree-dfa.c (get_ref_base_and_extent): [...] Close enough to what I meant by (a)/(b), but never mind that, and I hadn't looked at where the change for aggressive loop opts needed to be. However... Well you are essentially writing the patch for me at this point (so, thanks!), but here's a patch that puts that under a global -funknown-commons flag. Testcase as before. Bootstrapped (with flag overridden to true) on x86_64 and aarch64, check-gcc, check-fortran, and tested 416.gamess on AArch64, where this patch enables running *without* the -fno-aggressive-loop-opts previously required. In the gcc testsuite, these fail with the option turned on: gcc.dg/pr53265.c (test for warnings, line 137) gcc.dg/pr53265.c (test for warnings, line 138) gcc.dg/pr64277.c scan-tree-dump cunroll ... (*2) gcc.dg/tree-ssa/cunroll-{1,2,3,4,9,10,11}.c scan-tree-dump cunroll/cunrolli/ivcanon (various) gcc.dg/tree-ssa/loop-38.c scan-tree-dump cunrolli "Loop 1 iterates at most 11 times" ...which all appear harmless. Thomas Koenig suggests (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69368#c80) that this be combined with some flag fiddling and warnings in the Fortran front-end; this patch doesn't do that, as I'm not very familiar with the frontends, but that can follow in a separate patch. (Thomas?) OK for trunk? Cheers, Alan gcc/ChangeLog: DATE Alan Lawrence Jakub Jelinek * common.opt (funknown-commons, flag_unknown_commons): New. * tree.c (array_at_struct_end_p): Do not limit to size of decl for DECL_COMMONS if flag_unknown_commons is set. * tree-dfa.c (get_ref_base_and_extent): Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/unknown_commons.f: New. --- gcc/common.opt | 4 gcc/testsuite/gfortran.dg/unknown_commons.f | 20 gcc/tree-dfa.c | 15 ++- gcc/tree.c | 6 -- 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/unknown_commons.f diff --git a/gcc/common.opt b/gcc/common.opt index 520fa9c..b5b1282 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2455,6 +2455,10 @@ funit-at-a-time Common Report Var(flag_unit_at_a_time) Init(1) Compile whole compilation unit at a time. +funknown-commons +Common Var(flag_unknown_commons) +Assume common declarations may be overridden with unknown larger sizes + funroll-loops Common Report Var(flag_unroll_loops) Optimization Perform loop unrolling when iteration count is known. diff --git a/gcc/testsuite/gfortran.dg/unknown_commons.f b/gcc/testsuite/gfortran.dg/unknown_commons.f new file mode 100644 index 000..97e3ce3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/unknown_commons.f @@ -0,0 +1,20 @@ +! { dg-do compile } +! { dg-options "-O3 -funknown-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 -funknown-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..017e98e 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_unknown_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 +
Re: [PATCH] Add -funknown-commons to work around PR/69368 (and others) in SPEC2006
On 22/02/16 12:03, Jakub Jelinek wrote: (f) A global command-line option, which we check alongside DECL_COMMON and further tests (basically, we want only DECL_COMMON decls that either have ARRAY_TYPE, or some other aggregate type with flexible array member or some other trailing array in the struct), and use the resulting predicate in places where we optimize based on DECL_SIZE{,_UNIT} of the decl - if that predicate returns true, we assume the DECL_SIZE is "variable"/"unlimited"/whatever. The two spots known to me that would need to use this new predicate would be: tree.c (array_at_struct_end_p): tree-dfa.c (get_ref_base_and_extent): Well, with just those two, this fixes 416.gamess, and passes all tests in gfortran, with only a few scan-dump/warning tests failing in gcc... --Alan
Re: [PATCH] Add -funknown-commons to work around PR/69368 (and others) in SPEC2006
On Mon, Feb 22, 2016 at 11:46:19AM +, Alan Lawrence wrote: > On 19/02/16 17:52, Jakub Jelinek wrote: > >On Fri, Feb 19, 2016 at 05:42:34PM +, Alan Lawrence wrote: > >>This relates to FORTRAN code where different modules give different sizes > >>to the > >>same array in a COMMON block (contrary to the fortran language > >>specification). > >>SPEC have refused to patch the source code > >>(https://www.spec.org/cpu2006/Docs/faq.html#Run.05). > >> > >>Hence, this patch provides a Fortran-specific option -funknown-commons that > >>marks such arrays as having unknown size - that is, NULL_TREE for both > >>TYPE_SIZE and max value of TYPE_DOMAIN. DECL_SIZE is preserved for e.g. > >>output > >>in varasm.c. > >> > >>On AArch64, it fixes the 416.gamess issue, and allows compiling 416.gamess > >>without the -fno-aggressive-loop-optimizations previously required (numerous > >>other PRs relating to 416.gamess). > >> > >>I had to fix up a couple of places to deal with null TYPE_SIZE but in most > >>cases > > > >I think it is wrong to touch TYPE_SIZE/TYPE_SIZE_UNIT, IMHO it is much > >better just > >to ignore DECL_SIZE/DECL_SIZE_UNIT in the selected few places > >(get_ref_base_and_extent, the tree-ssa-loop-niters.c analysis) if the switch > >is on, for selected decls (aggregates with flexible array members and other > >similar trailing arrays, arrays themselves; all only if DECL_COMMON). > > So do you see... > > (a) A global command-line option, which we check alongside DECL_COMMON, in > (all or some of the) places which currently deal with flexible array > members? (I guess the flag would have no effect for compiling C code...or > (b) do we require it to 'enable' the existing flexible array member support?) > > (c) A new flag on each DECL, which we check in the places dealing with > flexible array members, which we set on those decls in the fortran frontend > if a fortran-frontend-only command-line option is passed? > > (d) A new flag on each DECL, which replaces the check for flexible array > members, plus a global command-line option, which controls both setting the > flag (on DECL_COMMONs) in the fortran frontend, and also setting it on > flexible array members in the C frontend? This might be 'cleanest' but is > also probably the most change and I doubt I'm going to have time to do this > for GCC 6... > > (e) Some other scheme that I've not understood yet? (f) A global command-line option, which we check alongside DECL_COMMON and further tests (basically, we want only DECL_COMMON decls that either have ARRAY_TYPE, or some other aggregate type with flexible array member or some other trailing array in the struct), and use the resulting predicate in places where we optimize based on DECL_SIZE{,_UNIT} of the decl - if that predicate returns true, we assume the DECL_SIZE is "variable"/"unlimited"/whatever. The two spots known to me that would need to use this new predicate would be: tree.c (array_at_struct_end_p): /* If the reference is based on a declared entity, the size of the array is constrained by its given domain. */ if (DECL_P (ref)) return false; This would need to do if (DECL_P (ref) && !the_new_predicate (ref)) return false; tree-dfa.c (get_ref_base_and_extent): if (DECL_P (exp)) { ... } You want to do inside of that block something like if (the_new_predicate (exp)) { /* We need to deal with variable arrays ending structures. */ if (seen_variable_array_ref && maxsize != -1 && (TYPE_SIZE (TREE_TYPE (exp)) == NULL_TREE || TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST || (bit_offset + maxsize == wi::to_offset (TYPE_SIZE (TREE_TYPE (exp)) maxsize = -1; else if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE) maxsize = -1; } /* If maxsize is unknown adjust it according to the size of the base decl. */ else if ((maxsize == -1 && DECL_SIZE (exp) && TREE_CODE (DECL_SIZE (exp)) == INTEGER_CST) maxsize = wi::to_offset (DECL_SIZE (exp)) - bit_offset; Thus, basically for the DECL_COMMON with trailing array readd the r233153 hunk (though it can be readded in slightly different spot), somehow deal with the case of ARRAY_TYPE itself, and only apply DEC_SIZE if the predicate is false. Jakub
Re: [PATCH] Add -funknown-commons to work around PR/69368 (and others) in SPEC2006
On 19/02/16 17:52, Jakub Jelinek wrote: On Fri, Feb 19, 2016 at 05:42:34PM +, Alan Lawrence wrote: This relates to FORTRAN code where different modules give different sizes to the same array in a COMMON block (contrary to the fortran language specification). SPEC have refused to patch the source code (https://www.spec.org/cpu2006/Docs/faq.html#Run.05). Hence, this patch provides a Fortran-specific option -funknown-commons that marks such arrays as having unknown size - that is, NULL_TREE for both TYPE_SIZE and max value of TYPE_DOMAIN. DECL_SIZE is preserved for e.g. output in varasm.c. On AArch64, it fixes the 416.gamess issue, and allows compiling 416.gamess without the -fno-aggressive-loop-optimizations previously required (numerous other PRs relating to 416.gamess). I had to fix up a couple of places to deal with null TYPE_SIZE but in most cases I think it is wrong to touch TYPE_SIZE/TYPE_SIZE_UNIT, IMHO it is much better just to ignore DECL_SIZE/DECL_SIZE_UNIT in the selected few places (get_ref_base_and_extent, the tree-ssa-loop-niters.c analysis) if the switch is on, for selected decls (aggregates with flexible array members and other similar trailing arrays, arrays themselves; all only if DECL_COMMON). So do you see... (a) A global command-line option, which we check alongside DECL_COMMON, in (all or some of the) places which currently deal with flexible array members? (I guess the flag would have no effect for compiling C code...or (b) do we require it to 'enable' the existing flexible array member support?) (c) A new flag on each DECL, which we check in the places dealing with flexible array members, which we set on those decls in the fortran frontend if a fortran-frontend-only command-line option is passed? (d) A new flag on each DECL, which replaces the check for flexible array members, plus a global command-line option, which controls both setting the flag (on DECL_COMMONs) in the fortran frontend, and also setting it on flexible array members in the C frontend? This might be 'cleanest' but is also probably the most change and I doubt I'm going to have time to do this for GCC 6... (e) Some other scheme that I've not understood yet? Thanks, Alan
Re: [PATCH] Add -funknown-commons to work around PR/69368 (and others) in SPEC2006
On Fri, Feb 19, 2016 at 05:42:34PM +, Alan Lawrence wrote: > This relates to FORTRAN code where different modules give different sizes to > the > same array in a COMMON block (contrary to the fortran language specification). > SPEC have refused to patch the source code > (https://www.spec.org/cpu2006/Docs/faq.html#Run.05). > > Hence, this patch provides a Fortran-specific option -funknown-commons that > marks such arrays as having unknown size - that is, NULL_TREE for both > TYPE_SIZE and max value of TYPE_DOMAIN. DECL_SIZE is preserved for e.g. output > in varasm.c. > > On AArch64, it fixes the 416.gamess issue, and allows compiling 416.gamess > without the -fno-aggressive-loop-optimizations previously required (numerous > other PRs relating to 416.gamess). > > I had to fix up a couple of places to deal with null TYPE_SIZE but in most > cases I think it is wrong to touch TYPE_SIZE/TYPE_SIZE_UNIT, IMHO it is much better just to ignore DECL_SIZE/DECL_SIZE_UNIT in the selected few places (get_ref_base_and_extent, the tree-ssa-loop-niters.c analysis) if the switch is on, for selected decls (aggregates with flexible array members and other similar trailing arrays, arrays themselves; all only if DECL_COMMON). > a test for such was already present. (omp-low.c had too many so I gave up: in > practice I think it's OK to just not use the new flag at the same time as > -fopenmp). That will just be an endless source of bugreports when people will report ICEs with -funknown-commons -fopenmp (or -fopenacc, or -fcilkplus, or -ftree-parallelize-loops, ...). For OpenMP the TYPE_SIZE* is essential, if you privatize variables, you need to know how big variable to allocate etc. Jakub
[PATCH] Add -funknown-commons to work around PR/69368 (and others) in SPEC2006
This relates to FORTRAN code where different modules give different sizes to the same array in a COMMON block (contrary to the fortran language specification). SPEC have refused to patch the source code (https://www.spec.org/cpu2006/Docs/faq.html#Run.05). Hence, this patch provides a Fortran-specific option -funknown-commons that marks such arrays as having unknown size - that is, NULL_TREE for both TYPE_SIZE and max value of TYPE_DOMAIN. DECL_SIZE is preserved for e.g. output in varasm.c. On AArch64, it fixes the 416.gamess issue, and allows compiling 416.gamess without the -fno-aggressive-loop-optimizations previously required (numerous other PRs relating to 416.gamess). I had to fix up a couple of places to deal with null TYPE_SIZE but in most cases a test for such was already present. (omp-low.c had too many so I gave up: in practice I think it's OK to just not use the new flag at the same time as -fopenmp). Bootstrapped + check-gcc + check-g++ on AArch64 and x86. Also check-fortran with a variant enabling the option in all cases (to allow compilation of C): here, only gfortran.dg/gomp/appendix-a/a.24.1.f90 fails, this uses -fopenmp mentioned above. Testcase fails both the FIND and one of the assignments if -funknown-commons is removed. OK for trunk? I'd be happy to move this under -std=legacy if the Fortran folks prefer. (-funcommon-commons has also been humourously suggested!) gcc/ChangeLog: * expr.c (store_field): Handle null TYPE_SIZE. * tree-vect-data-refs.c (vect_analyze_data_refs): Bail out if TYPE_SIZE is null. * tree-dfa.c (get_ref_base_and_extent): Keep maxsize==-1 when reading the whole of a DECL. gcc/fortran/ChangeLog: * lang.opt: Add -funknown-commons. * trans-common.ci (build_field): If flag_unknown_commons is on, set upper bound and size of arrays in common block to NULL_TREE. (create_common): Explicitly set DECL_SIZE and DECL_SIZE_UNIT. gcc/testsuite/ChangeLog: * gfortran.dg/unknown_commons.f: New. --- gcc/expr.c | 1 + gcc/fortran/lang.opt| 4 gcc/fortran/trans-common.c | 35 + gcc/testsuite/gfortran.dg/unknown_commons.f | 20 + gcc/tree-dfa.c | 6 - gcc/tree-vect-data-refs.c | 8 +++ 6 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/unknown_commons.f diff --git a/gcc/expr.c b/gcc/expr.c index f4bac36..609bf59 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -6638,6 +6638,7 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, RHS isn't the same size as the bitfield, we must use bitfield operations. */ || (bitsize >= 0 + && TYPE_SIZE (TREE_TYPE (exp)) && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST && compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)), bitsize) != 0 /* Except for initialization of full bytes from a CONSTRUCTOR, which diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index 45428d8..b1b4641 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -686,6 +686,10 @@ funderscoring Fortran Var(flag_underscoring) Init(1) Append underscores to externally visible names. +funknown-commons +Fortran Var(flag_unknown_commons) +Treat arrays in common blocks as having unknown size. + fwhole-file Fortran Ignore Does nothing. Preserved for backward compatibility. diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c index 21d1928..bf99c56 100644 --- a/gcc/fortran/trans-common.c +++ b/gcc/fortran/trans-common.c @@ -284,8 +284,41 @@ build_field (segment_info *h, tree union_type, record_layout_info rli) unsigned HOST_WIDE_INT desired_align, known_align; name = get_identifier (h->sym->name); + + gcc_assert (TYPE_P (h->field)); + tree size = TYPE_SIZE (h->field); + tree size_unit = TYPE_SIZE_UNIT (h->field); + if (GFC_ARRAY_TYPE_P (h->field) + && !h->sym->value + && flag_unknown_commons) +{ + gcc_assert (!GFC_DESCRIPTOR_TYPE_P (h->field)); + gcc_assert (TREE_CODE (h->field) == ARRAY_TYPE); + + /* Could be merged at link time with a larger array whose size we don't +know. */ + static tree range_type = NULL_TREE; + if (!range_type) + range_type = build_range_type (gfc_array_index_type, + gfc_index_zero_node, NULL_TREE); + tree type = copy_node (h->field); + TYPE_DOMAIN (type) = range_type; + TYPE_SIZE (type) = NULL_TREE; + TYPE_SIZE_UNIT (type) = NULL_TREE; + SET_TYPE_MODE (type, BLKmode); + gcc_assert (TYPE_CANONICAL (h->field) == h->field); + gcc_assert (TYPE_MAIN_VARIANT (h->field) == h->field); + TYPE_CANONICAL (type) = type; + TYPE_MAIN_VARIANT (type) = type; + layout_type (type); + h->field = type