Re: Ada PATCH: Fix ada/58239 by linking with xg++, not xgcc
On 31 Aug 2013, at 22:42, Gabriel Dos Reis wrote: > Eric Botcazou writes: > > | > This patch fixes that by introducing GXX_LINK which is GCC_LINK except > | > that CXX (e.g. xg++) instead of CC (e.g. xgcc) is invoked. > | > > | > Eric, are there other executables that need to be linked with GXX_LINK > | > too but aren't triggered yet? > | > | Yes, all not covered executables linking with TOOLS_LIBS since it contains > | libcommon.a which now drags the C++ library. So the simplest solution is > to > | change GCC_LINK (there is one potential problematic case, vxaddr2line, but > it > | probably didn't link before so let's forget it for now). > | > | I'll attach a patch to the PR so that the Darwin folks can test it. > > Thank you; that is very much appreciated. yes, indeed, thanks Eric, It seems the patch needs a couple of minor amendments to work with Darwin - and I've added an updated version to the PR which passes bootstrap and make check-ada on x86_64-darwin12. Iain
Re: [PATCH i386 1/8] [AVX512] Adjust register classes.
Hi Kirill, On 23 Aug 2013, at 08:35, Kirill Yukhin wrote: > On 22 Aug 12:06, Richard Henderson wrote: >> Ok. > > I've updated ChangeLog (thanks, HJ!) and > checked in to main trunk: http://gcc.gnu.org/ml/gcc-cvs/2013-08/msg00545.html This patch [actually the change at 201915] also broke X86 Darwin bootstrap/ABI: pr59269 - ISTM that SSE_REGNO_P() now returns true for a different set of registers than before the patch, I've attached a starting-point to fix to the PR - but would welcome any additional inputs folks might have on how best to audit this change. cheers Iain
Re: Ubsan merged into trunk
On Sat, Aug 31, 2013 at 04:04:03PM +0100, Iain Sandoe wrote: > OK for trunk? Ok with the suggested s/sanitise/sanitize/g change. > gcc: > * config/darwin.h (LINK_COMMAND_SPEC_A): Revise sanitiser specs to > include sanitise(undefined). > > libsanitiser: > > * ubsan/Makefile.am (libubsan_la_LIBADD): Revise to omit > libinterception.la > for Darwin. > * ubsan/Makefile.in: Regenerate. > > Index: gcc/config/darwin.h > === > --- gcc/config/darwin.h (revision 202118) > +++ gcc/config/darwin.h (working copy) > @@ -178,10 +178,11 @@ extern GTY(()) int darwin_ms_struct; > %{L*} %(link_libgcc) %o > %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} \ > %{fopenmp|ftree-parallelize-loops=*: \ >%{static|static-libgcc|static-libstdc++|static-libgfortran: > libgomp.a%s; : -lgomp } } \ > -%{%:sanitize(address): -lasan } \ > %{fgnu-tm: \ >%{static|static-libgcc|static-libstdc++|static-libgfortran: > libitm.a%s; : -litm } } \ > %{!nostdlib:%{!nodefaultlibs:\ > + %{%:sanitize(address): -lasan } \ > + %{%:sanitize(undefined): -lubsan } \ >%(link_ssp) %(link_gcc_c_sequence)\ > }}\ > %{!nostdlib:%{!nostartfiles:%E}} %{T*} %{F*} }}}" > > Index: libsanitizer/ubsan/Makefile.am > === > --- libsanitizer/ubsan/Makefile.am(revision 202118) > +++ libsanitizer/ubsan/Makefile.am(working copy) > @@ -18,7 +18,11 @@ ubsan_files = \ > ubsan_value.cc > > libubsan_la_SOURCES = $(ubsan_files) > -libubsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la > $(top_builddir)/interception/libinterception.la $(LIBSTDCXX_RAW_CXX_LDFLAGS) > +libubsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la > +if !USING_MAC_INTERPOSE > +libubsan_la_LIBADD += $(top_builddir)/interception/libinterception.la > +endif > +libubsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS) > libubsan_la_LDFLAGS = -version-info `grep -v '^\#' > $(srcdir)/libtool-version` -lpthread -ldl > > # Work around what appears to be a GNU make bug handling MAKEFLAGS Jakub
Re: Ubsan merged into trunk
On Sat, Aug 31, 2013 at 05:15:55PM +0200, Marek Polacek wrote: > I see, sorry. Will commit the following fix as obvious in a bit. > > 2013-08-31 Marek Polacek > > * ubsan.c: Include tm_p.h. You need to add $(TM_P_H) to ubsan.o dependencies in Makefile.in too. Ok with that change. > --- gcc/ubsan.c.mp2013-08-31 17:12:48.719219402 +0200 > +++ gcc/ubsan.c 2013-08-31 17:13:05.895281454 +0200 > @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. > #include "hashtab.h" > #include "pointer-set.h" > #include "output.h" > +#include "tm_p.h" > #include "toplev.h" > #include "ubsan.h" > #include "c-family/c-common.h" Jakub
Re: Ubsan merged into trunk
On Sun, Sep 01, 2013 at 01:36:37PM +0200, Jakub Jelinek wrote: > On Sat, Aug 31, 2013 at 05:15:55PM +0200, Marek Polacek wrote: > > I see, sorry. Will commit the following fix as obvious in a bit. > > > > 2013-08-31 Marek Polacek > > > > * ubsan.c: Include tm_p.h. > > You need to add $(TM_P_H) to ubsan.o dependencies in Makefile.in too. > Ok with that change. Argh, sorry. I _always_ forgot to update the deps in Makefile.in. :( Will fix it soon. Marek
Re: [patch 4/4] -fstrict-volatile-bitfields cleanup v3: remove from defaults on all targets
On Fri, 30 Aug 2013 11:47:21, Richard Biener wrote: > On Tue, Jul 2, 2013 at 7:33 PM, DJ Delorie wrote: >> >>> The choice appears to be to continue to have broken volatile bitfields >>> on ARM with no way for users to make them conform to the ABI, or to >>> change things so that they conform to the ABI if you specify >>> -fstrict-volatile-bitfields explicitly and to the C/C++ standard by >>> default, without that option. >> >> I can't speak for ARM, but for the other targets (for which I wrote >> the original patch), the requirement is that volatile bitfield >> accesses ALWAYS be in the mode of the type specified by the user. If >> the user says "int x:8;" then SImode (assuming 32-bit ints) must >> always be used, even if QImode could be used. >> >> The reason for this is that volatile bitfields are normally used for >> memory-mapped peripherals, and accessing peripheral registers in the >> wrong mode leads to incorrect operation. > > I've argued in the past that this part of the semantics can be easily > implemented in the existing C++ memory model code (well, in > get-bit-range) for the cases where it doesn't conflict with the C++ > memory model. For the cases where it conflicts a warning can > be emitted, Like when you do > > struct { > volatile int x:8; > char c; > } x; > > where 'c' would be within the SImode you are supposed to use > with -fstrict-volatile-bitfields. > > Which raises the question ... how does > > x.x = 1; > > actually work? IMHO it must be sth horribly inefficient like > > tem = x.c; // QImode > tem = tem << 8 | 1; // combine into SImode value > x.x = tem; // SImode store > AAPCS is very explicit what should happen here: tem = x.x; // SImode tem = (tem & ~0xFF) | 1; x.x = tem; // SImode struct x should be 4 bytes large, and 4 bytes aligned (int x) the member c is at offset 1, and gets overwritten which is forbidden in C++ memory model, but required by AAPCS > hoping that no sane ABI makes 'x' size 2. Oh, I _can_ make it size 2: > > struct { > volatile int x:8; > char c; > } __attribute__((packed)) x; > char y; > IMHO the AAPCS forbids packed structures. Therefore we need not interfere with the C++ memory model if we have unaligned data. > note the fancy global object 'y' I placed after 'x'. Now the store will > clobber y(?) So the only 'valid' way is > > tem = x.x; // SImode read(!) > tem = tem & 0xff..00 | 1; // manipulate value > x.x = tem; // SImode store > > but then this doesn't work either because that 1-byte aligned object > could reside at a page boundary and so the read and write would trap. > That is exactly what happened see bug#56341, and it is fixed with parts 1 & 2 of Sandra's patch. Here because if the 1-byte alignment the function strict_volatile_bitfield_p() returns false and thus the C++ memory model is used. > Makes me ask who designed that crap ;) > > But my point was that for all these special cases that likely do not > happen in practice (fingers crossed) the C++ memory model way > doesn't interfere with -fstrict-volatile-bitfields and the code can be > perfectly used to make the code as close as possible to the > -fstrict-volatile-bitifeld ABI. > Actually the C++ memory model and -fstrict-volatile-bitfields have some significant differences, your first example is one of them. And since part 4 changes the default of -fstrict-volatile-bitfields, I thought it would be good to have a warning when such a construct is used, which generates inherently different code if -fstrict-volatile-bitfields is used or not. I personally could live with or without part 4 of the patch, and I do not insist on the warnings part either. That was only my try to find a way how part 4 of Sandra's patch could be generally accepted. Note: If you want I can re-post the warnings patch in a new thread. Thanks Bernd. > Richard.
Type inheritance graph analysis & speculative devirtualization, part 7/7 (speculative devirtualizatoin)
Hi, this patch implement speculative devirtualization. It is a trivial pass that asks for targets of every polymorphic call in a program and if the list contains one likely target, it produces an speculative call. No context sensitive analysis is done at the moment. This call may or may not survive into final program depending if we do somehting useful about the direct call. The pass is currently disabled for LTO because http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01007.html is needed to properly build type inheritance graph. With LTO it is supposed to be effective on a premise that most types are not escaping LTO unit and thus we see all possible targets. Without LTO it makes stronger assumption that you usually call only targets defined in current unit, if any. Path is suprisingly effective on Firefox: 105306 polymorphic calls, 0 devirtualized, 34258 speculatively devirtualized, 4056 cold 66875 have multiple targets, 0 overwritable, 0 already speculated (0 agree, 0 disagree), 0 not defined So about 32% of calls are devirutalized. By random checking, these can be tracked to real occurences of code where virtual is used in a silly way. I plan to introduce warning for that (I have code for that already since it makes it easier to analyze what changes are really made and why). Martin Liska rebuilt with FDO based indirect call resolution. Here we get: 23928 indirect calls trained. 12837 (53.65%) have common target. 342 (1.43%) targets was not found. 8378 (35.01%) speculations seems useless. 4117 (17.21%) speculations produced. I compared the overlap that is devirtualized by both techniques. There is almost 100% match, except that FDO code is not dealing well with thunks and those 342 calls that seem to go out of libxul into plugins. I will fix the thunk issue later. I also tested QT, where the numbers are smaller - only about 20% of devirtualized calls, but largery things seems similar. For non-LTO build, the devirtualization also seems sane, there seems to be about 8% of miss rate on GCC bootstrap that seems acceptable. I tracked most of those down into randomly included headers that do define derived types of a given class that are unused in the current unit. I think we can track this by computing reachable functions in current unit and looking for vtables actually used by construction. One of such actually triggers undefined reference in build of libstdc++ and therefore I added the check disabling devirtualization to DECL_EXTERNAL for now. It is because the libstdc++ header seems to have explicit instantiation of a template that is never linked with. I currently enabled the pass by default at -O2. Based on the experience about missrate, we may want to disable it for -O2 non-LTO if it shows to be too risky on some codebases. Bootstrapped/regtested x86_64-linux and ppc64-linux, also tested with lto bootstrap with the LTO ODR code and tested on Firefox and QT builds. Will commit the patch later today. Comments are welcome. Honza * common.opt (fdevirtualize-speculatively): New function. * invoke.texi (fdevirtualize-speculatively): Document. * ipa-devirt.c: Include ipa-inline.h (likely_target_p): New function. (ipa_devirt): New function. (gate_ipa_devirt): New function. (pass_data_ipa_devirt): New static var. (pass_ipa_devirt): Likewise. (make_pass_ipa_devirt): New function. * opts.c (default_options): Add OPT_fdevirtualize_speculatively. (common_handle_option): Disable devirtualization when value range profiling is available. * passes.def (pass_ipa_devirt): Add. * timever.def (TV_IPA_DEVIRT): New timevar. * tree-pass.h (make_pass_ipa_devirt): Index: common.opt === --- common.opt (revision 202136) +++ common.opt (working copy) @@ -1007,6 +1007,10 @@ fdevirtualize Common Report Var(flag_devirtualize) Optimization Try to convert virtual calls to direct ones. +fdevirtualize-speculatively +Common Report Var(flag_devirtualize_speculatively) Optimization +Perform speculative devirtualization + fdiagnostics-show-location= Common Joined RejectNegative Enum(diagnostic_prefixing_rule) -fdiagnostics-show-location=[once|every-line] How often to emit source location at the beginning of line-wrapped diagnostics @@ -1366,7 +1370,7 @@ Common RejectNegative Joined fipa-cp Common Report Var(flag_ipa_cp) Optimization -Perform Interprocedural constant propagation +Perform interprocedural constant propagation fipa-cp-clone Common Report Var(flag_ipa_cp_clone) Optimization Index: doc/invoke.texi === --- doc/invoke.texi (revision 202136) +++ doc/invoke.texi (working copy) @@ -365,7 +365,7 @@ Objective-C and Objective-C++ Dialects}. -fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules @gol -fcx-limited-range @gol -fdata-s
Re: Type inheritance graph analysis & speculative devirtualization, part 7/7 (speculative devirtualizatoin)
Missing test cases? Have you tested the optimization with SPEC2k and SPEC06? There are a couple of benchmarks benefit greatly from devirtualization, such as eon, povray etc. I believe astar will probably improve with this optimization at O2 (it has hot virtual functions that are not overridden at all). For eon, the assumption at O2 for speculative devirt may not work well. thanks, David On Sun, Sep 1, 2013 at 6:57 AM, Jan Hubicka wrote: > Hi, > this patch implement speculative devirtualization. It is a trivial pass that > asks for targets of every polymorphic call in a program and if the list > contains one likely target, it produces an speculative call. No context > sensitive analysis is done at the moment. This call may or may not survive > into final program depending if we do somehting useful about the direct call. > > The pass is currently disabled for LTO because > http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01007.html is needed to properly > build type inheritance graph. > > With LTO it is supposed to be effective on a premise that most types are not > escaping LTO unit and thus we see all possible targets. Without LTO it makes > stronger assumption that you usually call only targets defined in current > unit, > if any. > > Path is suprisingly effective on Firefox: > 105306 polymorphic calls, 0 devirtualized, 34258 speculatively devirtualized, > 4056 cold > 66875 have multiple targets, 0 overwritable, 0 already speculated (0 agree, 0 > disagree), 0 not defined > > So about 32% of calls are devirutalized. By random checking, these can be > tracked to real occurences of code where virtual is used in a silly way. > I plan to introduce warning for that (I have code for that already since it > makes it easier to analyze what changes are really made and why). > > Martin Liska rebuilt with FDO based indirect call resolution. Here we get: > 23928 indirect calls trained. > 12837 (53.65%) have common target. > 342 (1.43%) targets was not found. > 8378 (35.01%) speculations seems useless. > 4117 (17.21%) speculations produced. > > I compared the overlap that is devirtualized by both techniques. There is > almost 100% match, except that FDO code is not dealing well with thunks and > those 342 calls that seem to go out of libxul into plugins. I will fix the > thunk issue later. > > I also tested QT, where the numbers are smaller - only about 20% of > devirtualized > calls, but largery things seems similar. > > For non-LTO build, the devirtualization also seems sane, there seems to be > about 8% of miss rate on GCC bootstrap that seems acceptable. I tracked most > of > those down into randomly included headers that do define derived types of a > given class that are unused in the current unit. I think we can track this by > computing reachable functions in current unit and looking for vtables actually > used by construction. One of such actually triggers undefined reference in > build of libstdc++ and therefore I added the check disabling devirtualization > to DECL_EXTERNAL for now. It is because the libstdc++ header seems to have > explicit instantiation of a template that is never linked with. > > I currently enabled the pass by default at -O2. Based on the experience about > missrate, we may want to disable it for -O2 non-LTO if it shows to be too > risky > on some codebases. > > Bootstrapped/regtested x86_64-linux and ppc64-linux, also tested with lto > bootstrap > with the LTO ODR code and tested on Firefox and QT builds. Will commit the > patch > later today. > > Comments are welcome. > Honza > > * common.opt (fdevirtualize-speculatively): New function. > * invoke.texi (fdevirtualize-speculatively): Document. > * ipa-devirt.c: Include ipa-inline.h > (likely_target_p): New function. > (ipa_devirt): New function. > (gate_ipa_devirt): New function. > (pass_data_ipa_devirt): New static var. > (pass_ipa_devirt): Likewise. > (make_pass_ipa_devirt): New function. > * opts.c (default_options): Add OPT_fdevirtualize_speculatively. > (common_handle_option): Disable devirtualization when > value range profiling is available. > * passes.def (pass_ipa_devirt): Add. > * timever.def (TV_IPA_DEVIRT): New timevar. > * tree-pass.h (make_pass_ipa_devirt): > > Index: common.opt > === > --- common.opt (revision 202136) > +++ common.opt (working copy) > @@ -1007,6 +1007,10 @@ fdevirtualize > Common Report Var(flag_devirtualize) Optimization > Try to convert virtual calls to direct ones. > > +fdevirtualize-speculatively > +Common Report Var(flag_devirtualize_speculatively) Optimization > +Perform speculative devirtualization > + > fdiagnostics-show-location= > Common Joined RejectNegative Enum(diagnostic_prefixing_rule) > -fdiagnostics-show-location=[once|every-line] How often to emit source > location at the begi
Re: [ping] Fix error recovery issue with alias
> The test still fails with the following change: > > --- /opt/gcc/_clean/gcc/testsuite/gnat.dg/specs/linker_alias.ads2013-08-18 > 17:39:22.0 +0200 +++ > /opt/gcc/work/gcc/testsuite/gnat.dg/specs/linker_alias.ads2013-08-19 > 08:52:35.0 +0200 @@ -5,5 +5,6 @@ package Linker_Alias is > Var : Integer; -- { dg-error "aliased to undefined symbol" } > pragma Export (C, Var, "my_var"); > pragma Linker_Alias (Var, "var2"); > + pragma Weak_External (Var); > > end Linker_Alias; OK, I've installed the following patchlet instead, thanks. 2013-09-01 Eric Botcazou * gnat.dg/specs/linker_alias.ads: Skip on Darwin. -- Eric BotcazouIndex: gnat.dg/specs/linker_alias.ads === --- gnat.dg/specs/linker_alias.ads (revision 202141) +++ gnat.dg/specs/linker_alias.ads (working copy) @@ -1,4 +1,5 @@ -- { dg-do compile } +-- { dg-skip-if "missing alias support" { *-*-darwin* } } package Linker_Alias is
Re: Type inheritance graph analysis & speculative devirtualization, part 7/7 (speculative devirtualizatoin)
> Missing test cases? Good point. The testcases I have needs rest of the patches from the series to hit the mainline. For now I have added the following to test the basic scenario * g++.dg/ipa/devirt-15.C: New testcase. Index: g++.dg/ipa/devirt-15.C === --- g++.dg/ipa/devirt-15.C (revision 0) +++ g++.dg/ipa/devirt-15.C (working copy) @@ -0,0 +1,40 @@ +/* Check that we speculatively devirutalize call to FOO to A::foo becuase + B is noreturn. */ +/* { dg-do run } */ +/* { dg-options "-O2 -fdump-ipa-devirt" } */ +class A { +public: + virtual int foo(void) +{ + throw (1); + return 0; +} +}; + + +class B : public A { +public: + virtual int foo(void); +}; + +int +B::foo(void) +{ + return 1; +} +class A a, *b=&a; +void +m(void) +{ + b->foo(); +} +main() +{ + m(); +} + +/* { dg-final { scan-ipa-dump "Speculatively devirtualizing call" "devirt"} } */ +/* { dg-final { cleanup-ipa-dump "devirt" } } */ +/* Match if (PROF_6 == foo) to verify that the speculation survived. */ +/* { dg-final { scan-tree-dump "== foo" "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ > > Have you tested the optimization with SPEC2k and SPEC06? There are a > couple of benchmarks benefit greatly from devirtualization, such as > eon, povray etc. I believe astar will probably improve with this > optimization at O2 (it has hot virtual functions that are not > overridden at all). For eon, the assumption at O2 for speculative > devirt may not work well. I trusted Martin (Jambor) that only interesting testcase for devirtualization in SPEC in xalancbmk. We will definitely see tomorrow. Concerning eon, I think it includes all the classes for individual objects so it should not get devirtualized the wrong way. I will double check. Wrong guess in general should not be terribly expensive. Many speculative calls are eliminated by inlining and other will just end up with the extra conditinal+jump (to jump). For firefox the code growth for all those 3 devirtualization is about 1.8%. Here about 70% of them survive till final executable since they use virtual functions for very cheap accessors that gets inlined well. There is an accounting bug in ipa-cp that makes us to mistakely remove references to some virutal functions as dead after devirtualization, so I disabled tracking of described references for virtual calls. Once this is fixed, the code size may get better. Honza
Re: [PATCH i386 1/8] [AVX512] Adjust register classes.
Hello, > This patch [actually the change at 201915] also broke X86 Darwin > bootstrap/ABI: pr59269 > - ISTM that SSE_REGNO_P() now returns true for a different set of registers > than before the patch, > I've attached a starting-point to fix to the PR - but would welcome any > additional inputs folks might have on how best to audit this change. Correct bug id: pr58269 I'll take a look, thanks! -- Thanks, K
Re: Ada PATCH: Fix ada/58239 by linking with xg++, not xgcc
> It seems the patch needs a couple of minor amendments to work with Darwin - > and I've added an updated version to the PR which passes bootstrap and make > check-ada on x86_64-darwin12. Iain Thanks, here is the final patch I just installed. 2013-09-01 Eric Botcazou Iain Sandoe PR ada/58239 gnattools/ * Makefile.in (CXX_LFLAGS): New. (TOOLS_FLAGS_TO_PASS_NATIVE): Pass CXX and CXX_LFLAGS. (TOOLS_FLAGS_TO_PASS_RE): Likewise. (TOOLS_FLAGS_TO_PASS_CROSS): Pass CXX. gcc/ada/ * gcc-interface/Makefile.in (GCC_LINK_FLAGS): Add -static-libstdc++. (GCC_LINK): Use CXX instead of CC. * gcc-interface/Make-lang.in (CXX_LFLAGS): New. (ADA_TOOLS_FLAGS_TO_PASS): Pass CXX, and CXX_LFLAGS for native. -- Eric BotcazouIndex: gnattools/Makefile.in === --- gnattools/Makefile.in (revision 202141) +++ gnattools/Makefile.in (working copy) @@ -63,9 +63,16 @@ INCLUDES_FOR_SUBDIR = -I. -I.. -I../.. - -I$(fsrcdir)/../include -I$(fsrcdir) ADA_INCLUDES_FOR_SUBDIR = -I. -I$(fsrcdir)/ada +CXX_LFLAGS = \ + -B../../../$(target_noncanonical)/libstdc++-v3/src/.libs \ + -B../../../$(target_noncanonical)/libstdc++-v3/libsupc++/.libs \ + -L../../../$(target_noncanonical)/libstdc++-v3/src/.libs \ + -L../../../$(target_noncanonical)/libstdc++-v3/libsupc++/.libs + # Variables for gnattools, native TOOLS_FLAGS_TO_PASS_NATIVE= \ "CC=../../xgcc -B../../" \ + "CXX=../../xg++ -B../../ $(CXX_LFLAGS)" \ "CFLAGS=$(CFLAGS) $(WARN_CFLAGS)" \ "LDFLAGS=$(LDFLAGS)" \ "ADAFLAGS=$(ADAFLAGS)" \ @@ -83,6 +90,7 @@ TOOLS_FLAGS_TO_PASS_NATIVE= \ # Variables for regnattools TOOLS_FLAGS_TO_PASS_RE= \ "CC=../../xgcc -B../../" \ + "CXX=../../xg++ -B../../ $(CXX_LFLAGS)" \ "CFLAGS=$(CFLAGS)" \ "ADAFLAGS=$(ADAFLAGS)" \ "ADA_CFLAGS=$(ADA_CFLAGS)" \ @@ -99,6 +107,7 @@ TOOLS_FLAGS_TO_PASS_RE= \ # Variables for gnattools, cross TOOLS_FLAGS_TO_PASS_CROSS= \ "CC=$(CC)" \ + "CXX=$(CXX)" \ "CFLAGS=$(CFLAGS) $(WARN_CFLAGS)" \ "LDFLAGS=$(LDFLAGS)" \ "ADAFLAGS=$(ADAFLAGS)" \ Index: gcc/ada/gcc-interface/Makefile.in === --- gcc/ada/gcc-interface/Makefile.in (revision 202141) +++ gcc/ada/gcc-interface/Makefile.in (working copy) @@ -198,7 +198,7 @@ RTSDIR = rts$(subst /,_,$(MULTISUBDIR)) # Link flags used to build gnat tools. By default we prefer to statically # link with libgcc to avoid a dependency on shared libgcc (which is tricky # to deal with as it may conflict with the libgcc provided by the system). -GCC_LINK_FLAGS=-static-libgcc +GCC_LINK_FLAGS=-static-libstdc++ -static-libgcc # End of variables for you to override. @@ -2275,7 +2275,7 @@ ifeq ($(strip $(filter-out darwin%,$(osy GMEM_LIB = gmemlib LIBRARY_VERSION := $(LIB_VERSION) soext = .dylib - GCC_LINK_FLAGS= + GCC_LINK_FLAGS=-static-libstdc++ endif # ARM Nucleus @@ -2397,7 +2397,7 @@ TOOLS_FLAGS_TO_PASS= \ "GNATLINK=$(GNATLINK)" \ "GNATBIND=$(GNATBIND)" -GCC_LINK=$(CC) $(GCC_LINK_FLAGS) $(ADA_INCLUDES) +GCC_LINK=$(CXX) $(GCC_LINK_FLAGS) $(ADA_INCLUDES) # Build directory for the tools. Let's copy the target-dependent # sources using the same mechanism as for gnatlib. The other sources are Index: gcc/ada/gcc-interface/Make-lang.in === --- gcc/ada/gcc-interface/Make-lang.in (revision 202141) +++ gcc/ada/gcc-interface/Make-lang.in (working copy) @@ -111,6 +111,12 @@ ada: gnat1$(exeext) gnatbind$(exeext) # Tell GNU Make to ignore these, if they exist. .PHONY: ada +CXX_LFLAGS = \ + -B../../../$(target_noncanonical)/libstdc++-v3/src/.libs \ + -B../../../$(target_noncanonical)/libstdc++-v3/libsupc++/.libs \ + -L../../../$(target_noncanonical)/libstdc++-v3/src/.libs \ + -L../../../$(target_noncanonical)/libstdc++-v3/libsupc++/.libs + # There are too many Ada sources to check against here. Let's # always force the recursive make. ifeq ($(build), $(host)) @@ -119,6 +125,7 @@ ifeq ($(build), $(host)) # tree. ADA_TOOLS_FLAGS_TO_PASS=\ CC="../../xgcc -B../../" \ +CXX="../../xg++ -B../../ $(CXX_LFLAGS)" \ $(COMMON_FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \ ADA_INCLUDES="-I- -I../rts" \ GNATMAKE="../../gnatmake" \ @@ -136,6 +143,7 @@ ifeq ($(build), $(host)) ADA_TOOLS_FLAGS_TO_PASS=\ CC="$(CC)" \ +CXX="$(CXX)" \ $(COMMON_FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \ ADA_INCLUDES="-I$(RTS_DIR)../adainclude -I$(RTS_DIR)" \ GNATMAKE="gnatmake" \ @@ -158,6 +166,7 @@ else # built runtime. ADA_TOOLS_FLAGS_TO_PASS=\ CC="$(CC)" \ +CXX="$(CXX)" \ $(COMMON_FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \ ADA_INCLUDES="-I../rts"\ GNATMAKE="$(GNATMAKE_FOR_HOST)" \ @@ -172,6 +181,7 @@ else endif ADA_TOOLS_FLAGS_TO_PASS=\
Re: [patch, fortran, docs] Unformatted sequential and special files
Hi Janne, I have tried to answer your points in the attached patch. > The unformatted sequential format part looks Ok, but the special files > section is lacking. E.g. what about > > - The REWIND statement? Not supported. > - The ENDFILE statement? Not supported. > - ACCESS='stream' and the POS= specifier? Only for inpquire. > - ACCESS='direct'? (I suspect this should work for > pipes/FIFO's/terminals in case REC= numbers are sequential, but is > that a guarantee we want to make?) I have not listed this as supported in the patch. > - Special files which are special in other ways. E.g. block special > files tend to allow seeking, but IO must be block aligned. Also listed as not supported; I suspect buffering could cause grief there. I have updated an attached patch. OK? Thomas 2013-08-30 Thomas Koenig PR fortran/30162 * gfortran.texi: Document unformatted sequential file format and I/O with special files. ig25@linux-fd1f:~/Krempel/Unformatt Index: gfortran.texi === --- gfortran.texi (Revision 201996) +++ gfortran.texi (Arbeitskopie) @@ -1121,6 +1121,8 @@ * Internal representation of LOGICAL variables:: * Thread-safety of the runtime library:: * Data consistency and durability:: +* Unformatted sequential file format:: +* I/O with special files:: @end menu @@ -1291,7 +1293,85 @@ releasing @code{fcntl} file locks, if the server supports them, will also force cache validation and flushing dirty data and metadata. +@node Unformatted sequential file format +@section Unformatted sequential file format +@cindex unformatted sequential files +@cindex record marker +@cindex subrecord +Unformatted sequential files are stored using record markers. Each +full record consists of a leading record marker, the data written +by the user program, and a trailing record marker. The record markers +are four-byte integers by default, and eight-byte integers if the +@option{-fmax-subrecord-length=8} option is in effect. Each record +marker contains the number of bytes of data in the record. + +The maximum number of bytes of user data in a record is 2147483639 for +a four-byte record marker. If this is exceeded, a record is split into +subrecords. Each subrecord also has a leading and a trailing record +marker. If the leading record marker contains a negative number, the +number of user data bytes in the subrecord equals the absolute value +of this number, and another subrecord follows the current one. If the +trailing record marker contains a negative number, then the number of +bytes of user data equals the absolute value of that number, and there +is a preceding subrecord. + +The format for unformatted sequential data can be duplicated using +unformatted stream, as shown in this example program: + +@smallexample +program main + implicit none + integer :: i + real, dimension(10) :: a, b + call random_number(a) + open (10,file='test.dat',form='unformatted',access='stream') + inquire (iolength=i) a + write (10) i, a, i + close (10) + open (10,file='test.dat',form='unformatted') + read (10) b + if (all (a == b)) print *,'success!' +end program main +@end smallexample + +@node I/O with special files +@section I/O with special files +@cindex special files +@cindex pipes +@cindex FIFO +@cindex terminal devices +@cindex block devices +@cindex sockets +@cindex BACKSPACE +@cindex REWIND +@cindex ENDFILE + +Special character-oriented files such as pipes, FIFOs or terminal +devices are supported only for the following types of file access: + +@itemize + +@item Formatted sequential + +@item Formatted stream + +@item Unformatted stream + +@end itemize + +For special files, the @code{POS=} specifier for stream I/O can only +be used in @code{INQUIRE} statements. + +Unformatted sequential file access is @emph{not} supported for special +files. If necessary, it can be simulated using unformatted stream, +see @ref{Unformatted sequential file format}. + +I/O to and from block devices are also not supported. + +@code{BACKSPACE}, @code{REWIND} and @code{ENDFILE} are not supported +for special files. + @c - @c Extensions @c -
[C++ Patch] PR 21682 (DR 565)
Hi, this patch resolves the bug by implementing the resolution of DR 565 (DRWP): for template functions, in order to establish that the program is ill-formed we want to check return type and template parameter list too. Thus, in practice, we want to accept the reduced testcase which came with c++/21682 (using24.C) and reject the testcase which I discussed in DR 565 (using25.C) (*) Booted & tested x86_64-linux. Thanks! Paolo. (*) Likewise current clang. // /cp 2013-09-01 Paolo Carlini PR c++/21682, implement DR 565 * name-lookup.c (do_nonmember_using_decl): For template function, check return type and template parameter list too. /testsuite 2013-09-01 Paolo Carlini PR c++/21682, implement DR 565 * g++.dg/template/using24.C: New. * g++.dg/template/using25.C: Likewise. Index: cp/name-lookup.c === --- cp/name-lookup.c(revision 202141) +++ cp/name-lookup.c(working copy) @@ -2562,7 +2562,20 @@ do_nonmember_using_decl (tree scope, tree name, tr else if (TREE_CODE (tmp1) == OVERLOAD && OVL_USED (tmp1)) continue; /* this is a using decl */ else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)), - TYPE_ARG_TYPES (TREE_TYPE (old_fn + TYPE_ARG_TYPES (TREE_TYPE (old_fn))) + /* DR 565: If a function template declaration in + namespace scope has the same name, parameter- + type-list, return type, and template parameter + list as a function template introduced by a + using-declaration, the program is ill-formed. */ + && (TREE_CODE (new_fn) != TEMPLATE_DECL + || TREE_CODE (old_fn) != TEMPLATE_DECL + || (comp_template_parms + (DECL_TEMPLATE_PARMS (new_fn), + DECL_TEMPLATE_PARMS (old_fn)) + && (same_type_p + (TREE_TYPE (TREE_TYPE (new_fn)), + TREE_TYPE (TREE_TYPE (old_fn))) { gcc_assert (!DECL_ANTICIPATED (old_fn) || DECL_HIDDEN_FRIEND_P (old_fn)); Index: testsuite/g++.dg/template/using24.C === --- testsuite/g++.dg/template/using24.C (revision 0) +++ testsuite/g++.dg/template/using24.C (working copy) @@ -0,0 +1,30 @@ +// PR c++/21682 + +template +struct t +{ + typedef typename T::type type; +}; +template<> class t{}; + +template struct t1{ }; +template<> struct t1 +{ + typedef int type; +}; + +namespace name1 +{ + template typename t::type begin(S const& s); + namespace name2 + { +template typename t1::type begin(S const& s); + } + using name2::begin; +} + +/* Test calling the function. */ +int f(int a) { return name1::begin(a); } + +struct aa { typedef double type; }; +double g(aa t) { return name1::begin(t); } Index: testsuite/g++.dg/template/using25.C === --- testsuite/g++.dg/template/using25.C (revision 0) +++ testsuite/g++.dg/template/using25.C (working copy) @@ -0,0 +1,9 @@ +// PR c++/21682 + +namespace one { + template void fun(T); +} + +using one::fun; + +template void fun(T); // { dg-error "conflicts" }
[committed] Accept "const_int 0" operand 1 in PA "scc" insns
This pattern fixes the following ICE found compiling ArabicShaping.cpp: g++-4.7 -D_REENTRANT -I. -I./.. -I../common -I./unicode - DU_ATTRIBUTE_DEPRECATED= -DU_LAYOUT_IMPLEMENTATION -D__NO_MATH_INLINES -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DNDEBUG - D_FORTIFY_SOURCE=2 -DGCC_HIDDEN_VISIBILITY -B/usr/bin -fexceptions - funsigned-char -fno-strict-aliasing -g -pipe -fPIC -pthread -Wall - Wcast-align -Wno-trigraphs -Wextra -Wno-missing-field-initializers - std=gnu++11 -fvisibility=hidden -fprofile-use -Wcoverage-mismatch - fprofile-correction -O2 -W -Wall -pedantic -Wpointer-arith -Wwrite- strings -Wno-long-long -std=c++11 -c -DPIC -fPIC -o ArabicShaping.o ArabicShaping.cpp ArabicShaping.cpp: In static member function 'static icu_50::ArabicShaping::ShapeType icu_50::ArabicShaping::getShapeType(LEUnicode)': ArabicShaping.cpp:36:94: warning: cast from 'const le_uint8* {aka const unsigned char*}' to 'const icu_50::ClassDefinitionTable*' increases required alignment of target type [-Wcast-align] ArabicShaping.cpp: In static member function 'static void icu_50::ArabicShaping::shape(const LEUnicode*, le_int32, le_int32, le_int32, le_bool, icu_50::LEGlyphStorage&)': ArabicShaping.cpp:210:1: note: file /net/usr.work/d036493/hppa/ CGK_ls3011_v29/i18n/icu/50.1/icu/source/layout/ArabicShaping.gcda not found, execution counts estimated ArabicShaping.cpp:208:1: error: unrecognizable insn: (insn 272 271 273 33 (set (reg:SI 298) (ne:SI (const_int 0 [0]) (const_int 0 [0]))) ArabicShaping.cpp:201 -1 (nil)) ArabicShaping.cpp:208:1: internal compiler error: in extract_insn, at recog.c:2123 The expander allowed a "const_int 0" operand 1 but the subsequent patterns didn't. The patch fixes this inconsistency. Tested on hppa2.0w-hp-hpux11.11 and hppa64-hp-hpux11.11. Applied to active branches. Dave -- John David Anglin dave.ang...@bell.net 2013-09-01 John David Anglin * config/pa/pa.md: Allow "const_int 0" operand 1 in "scc" insns. Index: config/pa/pa.md === --- config/pa/pa.md (revision 202083) +++ config/pa/pa.md (working copy) @@ -833,7 +833,7 @@ (define_insn "scc" [(set (match_operand:SI 0 "register_operand" "=r") (match_operator:SI 3 "comparison_operator" - [(match_operand:SI 1 "register_operand" "r") + [(match_operand:SI 1 "reg_or_0_operand" "rM") (match_operand:SI 2 "arith11_operand" "rI")]))] "" "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0" @@ -843,7 +843,7 @@ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (match_operator:DI 3 "comparison_operator" - [(match_operand:DI 1 "register_operand" "r") + [(match_operand:DI 1 "reg_or_0_operand" "rM") (match_operand:DI 2 "arith11_operand" "rI")]))] "TARGET_64BIT" "cmp%I2clr,*%B3 %2,%1,%0\;ldi 1,%0" @@ -853,10 +853,10 @@ (define_insn "iorscc" [(set (match_operand:SI 0 "register_operand" "=r") (ior:SI (match_operator:SI 3 "comparison_operator" - [(match_operand:SI 1 "register_operand" "r") + [(match_operand:SI 1 "reg_or_0_operand" "rM") (match_operand:SI 2 "arith11_operand" "rI")]) (match_operator:SI 6 "comparison_operator" - [(match_operand:SI 4 "register_operand" "r") + [(match_operand:SI 4 "reg_or_0_operand" "rM") (match_operand:SI 5 "arith11_operand" "rI")])))] "" "{com%I2clr|cmp%I2clr},%S3 %2,%1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%4,%0\;ldi 1,%0" @@ -866,10 +866,10 @@ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (ior:DI (match_operator:DI 3 "comparison_operator" - [(match_operand:DI 1 "register_operand" "r") + [(match_operand:DI 1 "reg_or_0_operand" "rM") (match_operand:DI 2 "arith11_operand" "rI")]) (match_operator:DI 6 "comparison_operator" - [(match_operand:DI 4 "register_operand" "r") + [(match_operand:DI 4 "reg_or_0_operand" "rM") (match_operand:DI 5 "arith11_operand" "rI")])))] "TARGET_64BIT" "cmp%I2clr,*%S3 %2,%1,%%r0\;cmp%I5clr,*%B6 %5,%4,%0\;ldi 1,%0" @@ -881,7 +881,7 @@ (define_insn "negscc" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (match_operator:SI 3 "comparison_operator" - [(match_operand:SI 1 "register_operand" "r") + [(match_operand:SI 1 "reg_or_0_operand" "rM") (match_operand:SI 2 "arith11_operand" "rI")])))] "" "{com%I2clr|cmp%
Re: Ada PATCH: Fix ada/58239 by linking with xg++, not xgcc
Eric Botcazou writes: | > It seems the patch needs a couple of minor amendments to work with Darwin - | > and I've added an updated version to the PR which passes bootstrap and make | > check-ada on x86_64-darwin12. Iain | | Thanks, here is the final patch I just installed. Thanks! -- Gaby
Move ipa-profile pass into separate file
Hi, once simple pass has grown up into set of not-so-trivial profile based transformations. This patch merely moves it to separate file. I intend to add toplevel comment and fix interesting problem Martin Liska noticed in followup patch. I did some basic housekeeping of include files and dependencies. I also renamed cgraph_propagate_frequency into ipa_propagate_frequency and moved it into ipa-utils.h/ Otherwise there are no changes in the patch. Bootstrapped/regtested ppc64-linux, will commit it shortly. Honza * Makefile.in: Add ipa-profile.o (ipa.o, ipa-devrit.o, ipa-inline-analysis.o): Adjust dependencies. * cgraph.c (struct cgraph_propagate_frequency_data, cgraph_propagate_frequency_1, cgraph_propagate_frequency): Move to ipa-profile.c; replace cgraph_ by ipa_ prefix. * cgraph.h (cgraph_propagate_frequency): Remove. * ipa-inline-analysis.c: Include ipa-utils.h; drop duplicated cfgloop.h. (inline_update_callee_summaries): Update. * ipa-profile.c: New file. * ipa-utils.h (ipa_propagate_frequency): Declare. * ipa.c: Do not include pointer-set.h, hash-table.h, lto-streamer.h, data-streamer.h, value-prof.h (symtab_remove_unreachable_nodes): Update profile. (struct histogram_entry, histogram, histogram_pool, histogram_hash, account_time_size, cmp_counts, dump_histogram, ipa_profile_generate_summary, ipa_profile_write_summary, ipa_profile_read_summary, ipa_profile, gate_ipa_profile, pass_data_ipa_profile, pass_ipa_profile, make_pass_ipa_profile): Move to ipa-profile.c Index: Makefile.in === --- Makefile.in (revision 202136) +++ Makefile.in (working copy) @@ -1280,6 +1280,7 @@ OBJS = \ ipa-inline.o \ ipa-inline-analysis.o \ ipa-inline-transform.o \ + ipa-profile.o \ ipa-prop.o \ ipa-pure-const.o \ ipa-reference.o \ @@ -2952,11 +2953,15 @@ varpool.o : varpool.c $(CONFIG_H) $(SYST $(TREE_FLOW_H) ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \ $(TREE_PASS_H) $(GIMPLE_H) $(TARGET_H) $(GGC_H) pointer-set.h \ - $(IPA_UTILS_H) tree-inline.h $(HASH_TABLE_H) profile.h $(PARAMS_H) \ - $(LTO_STREAMER_H) $(DATA_STREAMER_H) + $(IPA_UTILS_H) tree-inline.h profile.h $(PARAMS_H) +ipa-profile.o : ipa-profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \ + $(TREE_PASS_H) $(GIMPLE_H) $(TARGET_H) $(GGC_H) \ + $(IPA_UTILS_H) $(HASH_TABLE_H) profile.h $(PARAMS_H) \ + value-prof.h alloc-pool.h tree-inline.h $(LTO_STREAMER_H) $(DATA_STREAMER_H) \ + ipa-inline.h ipa-devirt.o : ipa-devirt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \ $(GIMPLE_H) $(TARGET_H) $(GGC_H) pointer-set.h \ - $(IPA_UTILS_H) $(HASH_TABLE_H) + $(IPA_UTILS_H) $(HASH_TABLE_H) ipa-inline.h ipa-utils.h $(TREE_PRETTY_PRINT_H) ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(DIAGNOSTIC_H) \ $(TREE_FLOW_H) $(TM_H) $(TREE_PASS_H) $(FLAGS_H) $(TREE_H) \ @@ -2986,7 +2991,8 @@ ipa-inline-analysis.o : ipa-inline-analy $(DIAGNOSTIC_H) $(PARAMS_H) $(TREE_PASS_H) $(CFGLOOP_H) \ $(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(IPA_PROP_H) \ $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(LTO_STREAMER_H) $(DATA_STREAMER_H) \ - $(TREE_STREAMER_H) + $(TREE_STREAMER_H) ipa-utils.h tree-scalar-evolution.h $(CFGLOOP_H) \ + alloc-pool.h ipa-inline-transform.o : ipa-inline-transform.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \ $(TREE_PASS_H) \ Index: cgraph.c === --- cgraph.c(revision 202136) +++ cgraph.c(working copy) @@ -2279,131 +2279,6 @@ cgraph_set_pure_flag (struct cgraph_node false); } -/* Data used by cgraph_propagate_frequency. */ - -struct cgraph_propagate_frequency_data -{ - bool maybe_unlikely_executed; - bool maybe_executed_once; - bool only_called_at_startup; - bool only_called_at_exit; -}; - -/* Worker for cgraph_propagate_frequency_1. */ - -static bool -cgraph_propagate_frequency_1 (struct cgraph_node *node, void *data) -{ - struct cgraph_propagate_frequency_data *d; - struct cgraph_edge *edge; - - d = (struct cgraph_propagate_frequency_data *)data; - for (edge = node->callers; - edge && (d->maybe_unlikely_executed || d->maybe_executed_once - || d->only_called_at_startup || d->only_called_at_exit); - edge = edge->next_caller) -{ - if (edge->caller != node) - { - d->only_called_at_startup &= edge->caller->only_called_at_startup; - /* It makes sense to put main() together with the static constructors. -It will be executed for sure, but rest
Re: [C++ Patch] PR 21682 (DR 565)
.. consider this withdrawn, I have to fix another very similar check elsewhere. Paolo.
Re: wide-int branch now up for public comment and review
Mike Stump writes: > @@ -643,12 +653,14 @@ equality. */ > __FUNCTION__); \ > &_rtx->u.hwint[_n]; })) > > -#define XHWIVEC_ELT(HWIVEC, I) __extension__ \ > -(*({ __typeof (HWIVEC) const _hwivec = (HWIVEC); const int _i = (I); \ > - if (_i < 0 || _i >= HWI_GET_NUM_ELEM (_hwivec)) \ > - hwivec_check_failed_bounds (_hwivec, _i, __FILE__, __LINE__, \ > - __FUNCTION__);\ > - &_hwivec->elem[_i]; })) > +#define CWI_ELT(RTX, I) __extension__ > \ > +(*({ __typeof (RTX) const _rtx = (RTX); > \ > + int _max = CWI_GET_NUM_ELEM (_rtx); \ CWI_GET_NUM_ELEM also uses "_rtx" for its temporary variable, so the last line includes the equivalent of: __typeof (_rtx) _rtx = _rtx; Is the fix below OK? We do a similar thing for block symbols, etc. Thanks, Richard Index: gcc/rtl.h === --- gcc/rtl.h 2013-09-01 14:00:21.032885857 +0100 +++ gcc/rtl.h 2013-09-01 17:41:49.474023618 +0100 @@ -654,13 +654,13 @@ #define XWINT(RTX, N) __extension__ &_rtx->u.hwint[_n]; })) #define CWI_ELT(RTX, I) __extension__ \ -(*({ __typeof (RTX) const _rtx = (RTX); \ - int _max = CWI_GET_NUM_ELEM (_rtx); \ +(*({ __typeof (RTX) const _cwi = (RTX); \ + int _max = CWI_GET_NUM_ELEM (_cwi); \ const int _i = (I); \ if (_i < 0 || _i >= _max) \ - cwi_check_failed_bounds (_rtx, _i, __FILE__, __LINE__, \ + cwi_check_failed_bounds (_cwi, _i, __FILE__, __LINE__, \ __FUNCTION__); \ - &_rtx->u.hwiv.elem[_i]; })) + &_cwi->u.hwiv.elem[_i]; })) #define XCWINT(RTX, N, C) __extension__ \ (*({ __typeof (RTX) const _rtx = (RTX); \
Re: [RFA] Type inheritance graph analysis & speculative devirtualization, part 4/7, ODR at LTO time
On 08/19/2013 10:01 AM, Jan Hubicka wrote: + /* All equivalent types, if more than one. */ + vec *types; + /* Set of all equivalent types, if NON-NULL. */ + pointer_set_t * GTY((skip)) types_set; Why do you need both a vector and a pointer set? Can't you drop the vector and use pointer_set_traverse for operating on each of the elements? +"type %qD violate one definition rule ", "violates" + "the type of same name with different memory layout " + "defined in other compilation unit"); Is there any way to identify which TUs the definitions come from? I would adjust the wording to "a type with the same name but different layout is defined in another translation unit" + "the inconsistent type of same name with different bases" + " (defined in other compilation unit)"); and "a type with the same name but different base classes is defined in another translation unit" + /* When assembler name of virtual table is available, it is + easy to compare types for equivalence. + FIXME: the code comparing type names consider all instantiations of the + same template to have same name. This is because we have no access + to template parameters. For types with no virtual method tables + we thus can return false positives. At the moment we do not need + to compare types in other scenarios than devirtualization. */ This FIXME doesn't seem to apply to the case where we're comparing the vtable mangled names, so it should move later in the function. OK with the diagnostic/comment issues fixed. BTW, if anything asks for the DECL_ASSEMBLER_NAME of the TYPE_NAME, it will get an ODR-unique mangled name for the type. But we don't currently set that during normal compilation because it isn't used in mangling of actual symbols. Jason
Re: [RFA] Type inheritance graph analysis & speculative devirtualization, part 4/7, ODR at LTO time
> On 08/19/2013 10:01 AM, Jan Hubicka wrote: > >+ /* All equivalent types, if more than one. */ > >+ vec *types; > >+ /* Set of all equivalent types, if NON-NULL. */ > >+ pointer_set_t * GTY((skip)) types_set; > > Why do you need both a vector and a pointer set? Can't you drop the > vector and use pointer_set_traverse for operating on each of the > elements? I was mostly worried about ordering issues. pointer_set is not stable across memory layout changes and we may end up outputting warnings/merging binfos in random orders. This seemed uncool. Maybe the final form is quite safe, since we do everything with the designated leader, but I would rather keep this here rather than later go into nasty issues of divergences in between compilation on different hosts. It is quite standard way to get list with unique elements for LTO - see implementation of the encoders/cgraph sets/varpool sets. Perhaps this asks for suitable C++ template with more sane representation. Note that for Firefox I get about 717 types have duplicates, 387 have two duplicates (that I can explain by external/internal vtables) 260 have 3 duplicates and the most duplicated type is duplicated 171 times. So memory usage of the code above is not critical in any way. Still we have a lot more duplicates than I would like. I plan to dig into this later, or perhaps convince Richard. > > >+ "type %qD violate one definition rule ", > > "violates" > > >+"the type of same name with different memory layout " > >+"defined in other compilation unit"); > > Is there any way to identify which TUs the definitions come from? Not that I know of. We can walk to vtable associated by the type that can give me object file (often temporary name for .a archives) but that is after declaration merging, so it will not point to the original file anymore. Actually thinking of this deeper, perhaps we can walk out into tarnslation unit decl. We explicitely allow merging cross translation unit mergin for file scope types, so this probably has chance to work only if type in question is file scope or its parent is duplicated too. We can also maybe walk state infos for first appeareance of the type (it is the unit it came from) but that is expensive and we will need to ensure early construction of the graph before global states are thrown away. I will leave this for incremental update and discuss it with Richard. I basically added the comment about other unit to make the message less confusing: when you manage to get difference because some earlier type changed, you get error pointing out the precisely same location twice. > BTW, if anything asks for the DECL_ASSEMBLER_NAME of the TYPE_NAME, > it will get an ODR-unique mangled name for the type. But we don't > currently set that during normal compilation because it isn't used > in mangling of actual symbols. I see, I wondered if I can get mangling of type names. So, once we will need uniqueness of ODR types for C++ (probably for alias info), we can basically convince C++ FE to produce the mangling and then discover and match ODR types based on presence of the assembler names? Can't this be used for merging of dwarf debug info on types? Thank you! Honza > > Jason
Re: Lambda templates and implicit function templates.
On 08/27/2013 03:42 PM, Adam Butcher wrote: Unfortunately, due to errors being thrown 'early' in grokdeclarator, I haven't been able to get 'auto...' (or reference/qualified variants) working yet. I think I need to defer processing the parameter pack internals of grokdeclarator until I have the synthesized template parameter (or generate one on the fly in-place --- but that's returning to the old 'on-demand' implementation which we moved away from). Hmm, yes. I'm not sure which approach would be better. I don't know if it's the correct thing to do but the implementation currently omits the conversion to function pointer operator if the argument list contains a parameter pack. I would expect that to work. Does the specification not provide for deduction in that case? One other thing, assuming the 'auto...' syntax can be made to work, bug 41933 needs to be resolved for the expansion returned by the generic lambda in N3690 5.1.2.5 to compile. Currently (transforming the 'auto&&...' to an explicit ' T&&...') appears to yield the bug. Bug 41933 is specifically about lambda capture; I think you're running into something else. Jason
Re: [PATCH 1/4] Support lambda templates.
On 08/27/2013 03:42 PM, Adam Butcher wrote: + vec_safe_push (argvec, arg); I bet we want convert_from_reference in the non-generic lambda case, too. OK with that change. Jason
Re: [PATCH 2/4] Don't generate lambda conversion op if arglist has parameter pack.
On 08/27/2013 03:42 PM, Adam Butcher wrote: + if (FUNCTION_PARAMETER_PACK_P (src)) + return; Yeah, in the case of a parameter pack we want to pass a pack expansion. Jason
Re: [PATCH 4/4] Support using 'auto' in a function parameter list to introduce an implicit template parameter.
On 08/27/2013 03:42 PM, Adam Butcher wrote: + else // extend current template parameter list + // pop the innermost template parms into tparms Most comments should start with a capital letter and end with a period. + for (size_t n = 0, end = TREE_VEC_LENGTH (inner_vec); n < end; ++n) + tparms = chainon (tparms, TREE_VEC_ELT (inner_vec, n)); Doing chainon in a loop has bad algorithmic complexity, as it walks through the whole tparms list each iteration. Better to build up a list from inner_vec and then chainon that list as a whole. +template +inline tree +find_type_usage (tree t, TreePredicate pred) I don't think this needs to be a template, since we know the predicates take a single tree and return bool. I don't see any diagnostic for the implicit function template extension; my earlier comment about not controlling it with -std=c++1y vs gnu++1y didn't mean it should go away entirely. :) Maybe we should call it part of c++1z, or just control the diagnostic with -pedantic. Jason
Re: [RFA] Type inheritance graph analysis & speculative devirtualization, part 4/7, ODR at LTO time
On 09/01/2013 03:50 PM, Jan Hubicka wrote: I was mostly worried about ordering issues. pointer_set is not stable across memory layout changes and we may end up outputting warnings/merging binfos in random orders. This seemed uncool. Maybe the final form is quite safe, since we do everything with the designated leader, but I would rather keep this here rather than later go into nasty issues of divergences in between compilation on different hosts. OK, sure. I will leave this for incremental update and discuss it with Richard. OK. I see, I wondered if I can get mangling of type names. So, once we will need uniqueness of ODR types for C++ (probably for alias info), we can basically convince C++ FE to produce the mangling and then discover and match ODR types based on presence of the assembler names? Yes. Can't this be used for merging of dwarf debug info on types? Possibly, but we already have several ways to merge dwarf debug info for types: .debug_types and dwz come to mind first. Jason
[C++ Patch] PR 21682 (DR 565) (Take 2)
Hi again, ... thus Take 2: the extended comparison per DR 565 must be used in push_overloaded_decl_1 too, in order to handle correctly the case of an using decl *followed* by a decl. I added a testcase too. Again booted and tested x86_64-linux. Thanks, Paolo. // /cp 2013-09-01 Paolo Carlini PR c++/21682, implement DR 565 * name-lookup.c (compparms_for_decl_and_using_decl): New. (push_overloaded_decl_1, do_nonmember_using_decl): Use it. /testsuite 2013-09-01 Paolo Carlini PR c++/21682, implement DR 565 * g++.dg/template/using24.C: New. * g++.dg/template/using25.C: Likewise. * g++.dg/template/using26.C: Likewise. Index: cp/name-lookup.c === --- cp/name-lookup.c(revision 202141) +++ cp/name-lookup.c(working copy) @@ -2267,7 +2267,28 @@ pushdecl_with_scope (tree x, cp_binding_level *lev return ret; } +/* Helper function for push_overloaded_decl_1 and do_nonmember_using_decl. + Compares the parameter-type-lists of DECL1 and DECL2 and returns false + if they are different. If the DECLs are template functions, the return + types and the template parameter lists are compared too (DR 565). */ +static bool +compparms_for_decl_and_using_decl (tree decl1, tree decl2) +{ + if (!compparms (TYPE_ARG_TYPES (TREE_TYPE (decl1)), + TYPE_ARG_TYPES (TREE_TYPE (decl2 +return false; + + if (! DECL_FUNCTION_TEMPLATE_P (decl1) + || ! DECL_FUNCTION_TEMPLATE_P (decl2)) +return true; + + return (comp_template_parms (DECL_TEMPLATE_PARMS (decl1), + DECL_TEMPLATE_PARMS (decl2)) + && same_type_p (TREE_TYPE (TREE_TYPE (decl1)), + TREE_TYPE (TREE_TYPE (decl2; +} + /* DECL is a FUNCTION_DECL for a non-member function, which may have other definitions already in place. We get around this by making the value of the identifier point to a list of all the things that @@ -2324,8 +2345,7 @@ push_overloaded_decl_1 (tree decl, int flags, bool if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp) && !(flags & PUSH_USING) - && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), - TYPE_ARG_TYPES (TREE_TYPE (decl))) + && compparms_for_decl_and_using_decl (fn, decl) && ! decls_match (fn, decl)) diagnose_name_conflict (decl, fn); @@ -2561,8 +2581,7 @@ do_nonmember_using_decl (tree scope, tree name, tr break; else if (TREE_CODE (tmp1) == OVERLOAD && OVL_USED (tmp1)) continue; /* this is a using decl */ - else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)), - TYPE_ARG_TYPES (TREE_TYPE (old_fn + else if (compparms_for_decl_and_using_decl (new_fn, old_fn)) { gcc_assert (!DECL_ANTICIPATED (old_fn) || DECL_HIDDEN_FRIEND_P (old_fn)); Index: testsuite/g++.dg/template/using24.C === --- testsuite/g++.dg/template/using24.C (revision 0) +++ testsuite/g++.dg/template/using24.C (working copy) @@ -0,0 +1,30 @@ +// PR c++/21682 + +template +struct t +{ + typedef typename T::type type; +}; +template<> class t{}; + +template struct t1{ }; +template<> struct t1 +{ + typedef int type; +}; + +namespace name1 +{ + template typename t::type begin(S const& s); + namespace name2 + { +template typename t1::type begin(S const& s); + } + using name2::begin; +} + +/* Test calling the function. */ +int f(int a) { return name1::begin(a); } + +struct aa { typedef double type; }; +double g(aa t) { return name1::begin(t); } Index: testsuite/g++.dg/template/using25.C === --- testsuite/g++.dg/template/using25.C (revision 0) +++ testsuite/g++.dg/template/using25.C (working copy) @@ -0,0 +1,17 @@ +// PR c++/21682 + +namespace one { + template void fun(T); +} + +using one::fun; + +template void fun(T); // { dg-error "conflicts" } + +template void funr(T); + +namespace oner { + template void funr(T); +} + +using oner::funr; // { dg-error "conflicts" } Index: testsuite/g++.dg/template/using26.C === --- testsuite/g++.dg/template/using26.C (revision 0) +++ testsuite/g++.dg/template/using26.C (working copy) @@ -0,0 +1,49 @@ +// PR c++/21682 + +namespace one { + template int bar1(T); +} + +using one::bar1; + +template void bar1(T); + +template void bar1r(T); + +namespace oner { + template int bar1r(T); +} + +using oner::bar1r; + +namespace two { + template void bar2(T); +} + +using two::bar2; + +template void bar2(T); + +template void bar2r(T); + +namespace twor { + template voi
Re: [PATCH]: Fix PR middle-end/56382 -- Only move MODE_COMPLEX_FLOAT by parts if we can create pseudos
On 30-Aug-13, at 6:38 AM, Eric Botcazou wrote: Let's avoid trying to do something general since this seems to be really a corner case. Can't we simply deal with hard registers specially? /* Move floating point as parts if splitting is easy. */ if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing && !(REG_P (x) && HARD_REGISTER_P (x) && hard_regno_nregs[REGNO(x)][mode] == 1) && !(REG_P (y) && HARD_REGISTER_P (y) && hard_regno_nregs[REGNO(y)][mode] == 1)) try_int = false; Eric, your patch works for me. Tested on hppa2.0w-hp-hpux11.11 and hppa64-hp-hpux11.11. Dave -- John David Anglin dave.ang...@bell.net Index: expr.c === --- expr.c (revision 202102) +++ expr.c (working copy) @@ -3236,7 +3236,13 @@ /* Move floating point as parts. */ if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT - && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing) + && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing + && !(REG_P (x) + && HARD_REGISTER_P (x) + && hard_regno_nregs[REGNO(x)][mode] == 1) + && !(REG_P (y) + && HARD_REGISTER_P (y) + && hard_regno_nregs[REGNO(y)][mode] == 1)) try_int = false; /* Not possible if the values are inherently not adjacent. */ else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
Re: [RFC] Changes to the wide-int classes
My main discomfort is the double-int part. At this point in time the only usage of double-int left on the branch is because the fixed ints use it as their underlying representation. I think that rather than doing a lot of work to accommodate this, it would be better to just change the fixed representation. There is no place for exactly two HWIs in the machine independent parts of the compiler, and the truth is that there is no (except for the fixed stuff) use of double ints remaining in the ports. Even if, by sniffing the ports, we end up with a flavor of wide-int that has two wide-ints as its rep, it should not be be called double-int or expose what it's rep is. I do understand that richi had requested this in some of the early discussions but given that there are virtually no clients for it left, lets let this die. As for the rest of the patch, this is for the c++ experts to hash out. I have no problems with it but i am not an expert and so if the consensus likes it, then we can go in this direction. small bugs below this line. bottom of frag 3 of gcc/cp/init.c is wrong: you replaced rshift...lshift with lshift...lshift. i will finish reading this tomorrow, but i wanted to get some comments in for the early shift.i stopped reading at line 1275. kenny On 09/01/2013 03:21 PM, Richard Sandiford wrote: This is an RFC and patch for an alternative way of organising the wide-int classes, along the lines I mentioned earlier. The main points are below, each with a "headline" and a bit of extra waffle that can be skipped if too long: * As Richard requested, the main wide int class is parameterised by the storage: template class GTY(()) generic_wide_int : public storage * As Richard also requested, double_int is now implemented in terms of the wide-int routines. This didn't work out quite as elegantly as I'd hoped due to conflicting requirements. double_int is used in unions and so needs to be a POD, whereas the fancy things we want to allow for wide_int and fixed_wide_int mean that they need to have constructors. The patch therefore keeps double_int as the basic storage class and defines double_int_ext as the wide-int class. All the double_int methods therefore need to be kept, but are now simple wrappers around the wi:: routines. double_int_ext and fixed_wide_int are assignment-compatible. This is just to show that it's possible though. It probably isn't very efficient... * wide-int.h no longer includes tree.h, rtl.h or double-int.h. The rtx and machine_mode routines are now in rtl.h, and the tree-related ones are in tree.h. double-int.h now depends on wide-int.h, as described above. * wide-int.h no longer includes tm.h. This is done by adding a new MAX_BITS_PER_UNIT to machmode.def, so that the definition of MAX_BITSIZE_MODE_ANY_MODE no longer relies on BITS_PER_UNIT. Although I think we usually assume that BITS_PER_UNIT is a constant, that wouldn't necessarily be true if we ever did support multi-target compilers in future. MAX_BITS_PER_UNIT is logically the maximum value of BITS_PER_UNIT for any compiled-in target and must be a constant. * Precision 0 is no longer a special marker for primitive types like ints. It's only used for genuine 0-width integers. * The wide-int classes are now relatively light-weight. All the real work is done by wi:: routines. There are still operator methods for addition, multiplication, etc., but they just forward to the associated wi:: routine. I also reluctantly kept and_not and or_not as operator-like methods for now, although I'd like to get rid of them and just keep the genuine operators. The problem is that I'd have liked the AND routine to be "wi::and", but of course that isn't possible with "and" being a keyword, so I went for "wi::bit_and" instead. Same for "not" and "wi::bit_not", and "or" and "wi::bit_or". Then it seemed like the others should be bit_* too, and "wi::bit_and_not" just seems a bit unwieldly... Hmm, if we decide to forbid the use of "and" in gcc, perhaps we could #define it to something safe. But that would probably be too confusing. I'm sure those who like stepping through gcc with gdb are going to hate this patch already, without that to make things worse... * fixed_wide_int now only has the number of HWIs required by N. This makes addr_wide_int significantly smaller. * fixed_wide_int doesn't have a precision field; the precision is always taken directly from the template argument. This isn't a win sizewise, since the length and precision fitted snugly into a HWI slot, but it means that checks for particular precisions can be resolved at compile time. E.g. the fast single-HWI paths are now dropped when dealing with fixed_wide_ints. * Each integer type is classifed as one of: FLEXIBLE_PRECISION, CONST_PRECISION and VAR_PRECISION. FL
Re: [RFC] Changes to the wide-int classes
On Sep 1, 2013, at 7:37 PM, Kenneth Zadeck wrote: > On 09/01/2013 03:21 PM, Richard Sandiford wrote: >> >> * As Richard requested, the main wide int class is parameterised by the >> storage: >> >> template >> class GTY(()) generic_wide_int : public storage Careful of GTY, it gets finicky around the corners. I suspect you already tested this and it works... >> Hmm, if we decide to forbid the use of "and" in gcc, Why would we do that? >> * A static assert also prevents fixed_wide_ints from being initialised >> from wide_ints. I think combinations like that would always be a >> mistake. I don't see why. In C, this: int i; long l = i; is not an error, and while a user might not want to do this, other times, it is completely reasonable. >> I've deliberately not tackled any of the other things that have been >> talked about, such as whether excess bits should be defined, whether >> the blocks should be HWIs, etc. I've also kept things like >> "wi::one (prec)", although this is now exactly equivalent to >> "wi::shwi (1, prec)". I'm not sure either way on whether the >> one() form is worth keeping. wi::one(prec) is 3 words, wi::shwi (1, prec) is 4. Not a big point.
Re: [C++ Patch] PR 21682 (DR 565) (Take 2)
OK. Jason
[PATCH GCC]Catch more MEM_REFs sharing common addressing part in gimple strength reduction
Hi, The gimple-ssa-strength-reduction pass handles CAND_REFs in order to find different MEM_REFs sharing common part in addressing expression. If such MEM_REFs are found, the pass rewrites MEM_REFs, and produces more efficient addressing expression during the RTL passes. The pass analyzes addressing expression in each MEM_REF to see if it can be formalized as follows: base:MEM_REF (T1, C1) offset: MULT_EXPR (PLUS_EXPR (T2, C2), C3) bitpos: C4 * BITS_PER_UNIT Then restructures it into below form: MEM_REF (POINTER_PLUS_EXPR (T1, MULT_EXPR (T2, C3)), C1 + (C2 * C3) + C4) At last, rewrite the MEM_REFs if there are two or more sharing common (non-constant) part. The problem is it doesn't back trace T2. If T2 is recorded as a CAND_ADD in form of "T2' + C5", the MEM_REF should be restructure into: MEM_REF (POINTER_PLUS_EXPR (T1, MULT_EXPR (T2', C3)), C1 + (C2 * C3) + C4 + (C5 * C3)) The patch also includes a test case to illustrate the problem. Bootstrapped and tested on x86/x86_64/arm-a15, is it ok? Thanks. bin 2013-09-02 Bin Cheng * gimple-ssa-strength-reduction.c (backtrace_base_for_ref): New. (restructure_reference): Call backtrace_base_for_ref. gcc/testsuite/ChangeLog 2013-09-02 Bin Cheng * gcc.dg/tree-ssa/slsr-39.c: New test.Index: gcc/testsuite/gcc.dg/tree-ssa/slsr-39.c === --- gcc/testsuite/gcc.dg/tree-ssa/slsr-39.c (revision 0) +++ gcc/testsuite/gcc.dg/tree-ssa/slsr-39.c (revision 0) @@ -0,0 +1,26 @@ +/* Verify straight-line strength reduction for back-tracing + CADN_ADD for T2 in: + +*PBASE:T1 +*POFFSET: MULT_EXPR (T2, C3) +*PINDEX: C1 + (C2 * C3) + C4 */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-slsr" } */ + +typedef int arr_2[50][50]; + +void foo (arr_2 a2, int v1) +{ + int i, j; + + i = v1 + 5; + j = i; + a2 [i] [j++] = i; + a2 [i] [j++] = i; + a2 [i] [i-1] += 1; + return; +} + +/* { dg-final { scan-tree-dump-times "MEM" 4 "slsr" } } */ +/* { dg-final { cleanup-tree-dump "slsr" } } */ Index: gcc/gimple-ssa-strength-reduction.c === --- gcc/gimple-ssa-strength-reduction.c (revision 202067) +++ gcc/gimple-ssa-strength-reduction.c (working copy) @@ -750,6 +750,57 @@ slsr_process_phi (gimple phi, bool speed) add_cand_for_stmt (phi, c); } +/* Given PBASE which is a pointer to tree, loop up the defining + statement for it and check whether the candidate is in the + form of: + + X = B + (1 * S), S is integer constant + X = B + (i * S), S is integer one + + If so, set PBASE to the candiate's base_expr and return double + int (i * S). + Otherwise, just return double int zero. */ + +static double_int +backtrace_base_for_ref (tree *pbase) +{ + tree base_in = *pbase; + slsr_cand_t base_cand; + + STRIP_NOPS (base_in); + if (TREE_CODE (base_in) != SSA_NAME) +return tree_to_double_int (integer_zero_node); + + base_cand = base_cand_from_table (base_in); + + while (base_cand && base_cand->kind != CAND_PHI) +{ + if (base_cand->kind == CAND_ADD + && base_cand->index.is_one () + && TREE_CODE (base_cand->stride) == INTEGER_CST) + { + /* X = B + (1 * S), S is integer constant. */ + *pbase = base_cand->base_expr; + return tree_to_double_int (base_cand->stride); + } + else if (base_cand->kind == CAND_ADD + && TREE_CODE (base_cand->stride) == INTEGER_CST + && integer_onep (base_cand->stride)) +{ + /* X = B + (i * S), S is integer one. */ + *pbase = base_cand->base_expr; + return base_cand->index; + } + + if (base_cand->next_interp) + base_cand = lookup_cand (base_cand->next_interp); + else + base_cand = NULL; +} + + return tree_to_double_int (integer_zero_node); +} + /* Look for the following pattern: *PBASE:MEM_REF (T1, C1) @@ -767,8 +818,15 @@ slsr_process_phi (gimple phi, bool speed) *PBASE:T1 *POFFSET: MULT_EXPR (T2, C3) -*PINDEX: C1 + (C2 * C3) + C4 */ +*PINDEX: C1 + (C2 * C3) + C4 + When T2 is recorded by an CAND_ADD in the form of (T2' + C5), It + will be further restructured to: + +*PBASE:T1 +*POFFSET: MULT_EXPR (T2', C3) +*PINDEX: C1 + (C2 * C3) + C4 + (C5 * C3) */ + static bool restructure_reference (tree *pbase, tree *poffset, double_int *pindex, tree *ptype) @@ -777,7 +835,7 @@ restructure_reference (tree *pbase, tree *poffset, double_int index = *pindex; double_int bpu = double_int::from_uhwi (BITS_PER_UNIT); tree mult_op0, mult_op1, t1, t2, type; - double_int c1, c2, c3, c4; + double_int c1, c2, c3, c4, c5; if (!base || !offset @@ -823,11 +881,12 @@ restructure_reference (tree *pbase, tree *poffset, } c4 = index.udiv (bp