Re: i370 port
I've managed to isolate the problem to a small test program. Any suggestions on how to debug this? Thanks. Paul. C:\devel\gcc\gcc>type bug27.c /* This program demonstrates a bug in a modification to GCC 3.4.6 */ /* It generates the below error when compiled with -O2 */ #if 0 bug27.c: In function `foo': bug27.c:28: error: unrecognizable insn: (insn 116 34 35 2 (set (reg:SI 5 5) (plus:SI (plus:SI (reg:SI 2 2 [orig:54 i ] [54]) (reg/f:SI 13 13)) (const_int 104 [0x68]))) -1 (nil) (nil)) bug27.c:28: internal compiler error: in ZZZ_680, at recog.c:2083 #endif void foo(int c) { int x[3]; int y[3]; int i; for (i = 0; i < 2; i++) { if (c == 1) x[i] &= y[i]; else if (c == 2) x[i] |= y[i]; } return; } C:\devel\gcc\gcc> -Original Message- From: Paul Edwards Sent: Friday, April 06, 2012 3:50 PM To: Ulrich Weigand Cc: gcc@gcc.gnu.org Subject: Re: i370 port I have made this change: C:\devel\gcc\gcc\config\i370>cvs diff -c -r 1.23 i370.md Index: i370.md === RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.md,v retrieving revision 1.23 retrieving revision 1.24 diff -c -r1.23 -r1.24 *** i370.md 6 Apr 2012 03:57:08 - 1.23 --- i370.md 6 Apr 2012 04:03:21 - 1.24 *** *** 843,848 --- 843,853 /*return \"STM %1,%N1,%0\"; */ return \"ST %1,%0\;ST %N1,4+%0\"; } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 6, 8); + return \"MVC%O0(8,%R0),%W1\"; + } mvs_check_page (0, 6, 8); return \"MVC%O0(8,%R0),%1\"; }" C:\devel\gcc\gcc\config\i370> And it has had a good effect: diff old/cpplib.s new/cpplib.s 1670c1670 < MVC 120(8,13),=F'0' --- MVC 120(8,13),=XL8'' 1796c1796 < MVC 120(8,13),=F'0' --- MVC 120(8,13),=XL8'' However, I'm still stuck. Because when I make this change: C:\devel\gcc\gcc\config\i370>cvs diff -r 1.17 i370.h Index: i370.h === RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.h,v retrieving revision 1.17 retrieving revision 1.18 diff -r1.17 -r1.18 599a600,602 #define EXTRA_MEMORY_CONSTRAINT(C, STR) \ ((C) == 'S') It triggers off a problem with plus:SI C:\devel\gcc\gcc>stdcompm global.c C:\devel\gcc\gcc>gccmvs -DUSE_MEMMGR -Os -S -DHAVE_CONFIG_H -DIN_GCC -DPUREISO - I ../../pdos/pdpclib -I . -I config/i370 -I ../include global.c global.c: In function `find_reg': global.c:1325: error: unrecognizable insn: (insn 2432 130 131 12 (set (reg:SI 15 15) (plus:SI (plus:SI (reg:SI 4 4 [orig:82 allocno ] [82]) (reg:SI 3 3 [87])) (const_int 44 [0x2c]))) -1 (nil) (nil)) global.c:1325: internal compiler error: in ZZZ_680, at recog.c:2083 Please submit a full bug report, with preprocessed source if appropriate. See http://gccmvs.sourceforge.net> for instructions. C:\devel\gcc\gcc> Seems to be a problem when adding very small const_ints (in the above case, 44) that can fit into a LA. I tried to isolate which plus:SI rule was causing the problem by commenting out these: ; ; addsi3 instruction pattern(s). ; ; The following insn is used when it is known that operand one is an address, ; frame, stack or argument pointer, and operand two is a constant that is ; small enough to fit in the displacement field. ; Notice that we can't allow the frame pointer to used as a normal register ; because of this insn. ; ;(define_insn "" ; [(set (match_operand:SI 0 "register_operand" "=d") ;^I(plus:SI (match_operand:SI 1 "general_operand" "%a") ;^I^I (match_operand:SI 2 "immediate_operand" "J")))] ; "((REGNO (operands[1]) == FRAME_POINTER_REGNUM || REGNO (operands[1]) == ARG$ ; "* ;{ ; check_label_emit (); ; CC_STATUS_INIT; /* add assumes CC but LA doesn't set CC */ ; mvs_check_page (0, 4, 0); ; return \"LA^I%0,%c2(,%1)\"; ;}" ; [(set_attr "length" "4")] ;) ;; The CC status bits for the arithmetic instructions are handled ;; in the NOTICE_UPDATE_CC macro (yeah???) and so they do not need ;; to be set below. They only need to be invalidated if *not* set ;; (e.g. by BCTR) ... yeah I think that's right ... ;; ;(define_insn "addsi3" ; [(set (match_operand:SI 0 "nonimmediate_operand" "=d") ;^I(plus:SI (match_operand:SI 1 "general_operand" "%0") ;^I^I (match_operand:SI 2 "general_operand" "g")))] ; "" ; "* ;{ ; check_label_emit (); ; if (REG_P (operands[2])) ;{ ; mvs_check_page (0, 2, 0); ; return \"AR^I%0,%2\"; ;} ; if (GET_CODE (operands[2]) == CONST_INT) ;{ ; if (INTVAL (operands[2]) == -1) ;^I{ ; CC_STATUS_INIT; /* add assumes CC but BCTR doesn't set CC */ ;^I mvs_check_page (0, 2, 0); ;^I return \"BCTR^I%0,0\"; ;^I} ;} ; mvs_check_page (0, 4, 0); ; return \"A^I%0,%2\"; ;}" ; [(set_attr "length"
Re: i370 port
Paul Edwards wrote: > I have reviewed the 'W' code in PRINT_OPERAND: > > else if (CODE == 'W') > { > /* hand-built sign-extension of signed 32-bit to 64-bit */ > mvs_page_lit += 8; > if (0 <= INTVAL (XV)) { >fprintf (FILE, "=XL8'"); > } else { >fprintf (FILE, "=XL8'"); > } > fprintf (FILE, "%08X'", INTVAL (XV)); > } > > and it looks to me like it is already correct. If movdi is given a > const_int as a parameter, then sign-extending to 64-bit is > exactly what needs to happen, isn't it? > > I'm only expecting to compile programs as 32-bit, so I'm not > expecting more than 32-bit integers. The IFOX assembler > won't do more than that. In case that's the issue. Well, even on 32-bit you may get 64-bit integer constants, e.g. via the "long long" data type: long long x = 0x123456789abcdefLL; However, the real question in your case is whether those are represented as CONST_INT. This is only true if HOST_WIDE_INT is a 64-bit type; otherwise, such constants would be represented as a CONST_DOUBLE. Whether or not HOST_WIDE_INT is a 64-bit type now depends on which *host* you're building GCC as a cross-compiler on. If you only ever support 32-bit hosts, then HOST_WIDE_INT will always be a 32-bit type, and the code above should be fine. If you want to support 64-bit hosts as well, however, you will need to handle 64-bit CONST_INT values too. > But regardless I don't know how to make this code: > > mvs_check_page (0, 6, 8); > return \"MVC^I%O0(8,%R0),%1\"; > > make use of that 'W' operand. > > Do I change that %1 to %W1 perhaps? Yes, exactly. Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE ulrich.weig...@de.ibm.com
Re: i370 port
Paul Edwards wrote: > I've managed to isolate the problem to a small test program. > > Any suggestions on how to debug this? > bug27.c:28: error: unrecognizable insn: > (insn 116 34 35 2 (set (reg:SI 5 5) > (plus:SI (plus:SI (reg:SI 2 2 [orig:54 i ] [54]) > (reg/f:SI 13 13)) > (const_int 104 [0x68]))) -1 (nil) > (nil)) Ah, yes. The problem is that reload assumes any valid address can be loaded into a register with a single instruction, and it will thus simply generate such instructions unconditionally -- and if the target then doesn't actually provide such a pattern, it will fail with "unrecognizable insn". The "LA" pattern you showed accepts only "(certain) single register + constant", which doesn't match the pattern above "register + register + constant". The difficulty is now that while "LA" *does* actually support adding base + index + displacement, you cannot simply add a pattern expressing that, because LA only does a 31-bit add, so it must only be used to add addresses, not when adding general 32-bit SImode values. The way I handle this in the s390 port is to provide a "forced" LA instruction pattern using a magic marker that prevents the pattern from being matched by regular instructions, and then add a secondary reload to emit that "forced" LA when reload needs to load an address. Here's the relevant snippets from the 3.4 s390 back-end: /* We need a secondary reload when loading a PLUS which is not a valid operand for LOAD ADDRESS. */ #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \ s390_secondary_input_reload_class ((CLASS), (MODE), (IN)) (define_insn "*la_31" [(set (match_operand:SI 0 "register_operand" "=d,d") (match_operand:QI 1 "address_operand" "U,W"))] "!TARGET_64BIT && legitimate_la_operand_p (operands[1])" "@ la\t%0,%a1 lay\t%0,%a1" [(set_attr "op_type" "RX,RXY") (set_attr "type" "la")]) (define_insn "force_la_31" [(set (match_operand:SI 0 "register_operand" "=d,d") (match_operand:QI 1 "address_operand" "U,W")) (use (const_int 0))] "!TARGET_64BIT" "@ la\t%0,%a1 lay\t%0,%a1" [(set_attr "op_type" "RX") (set_attr "type" "la")]) (define_expand "reload_insi" [(parallel [(match_operand:SI 0 "register_operand" "=a") (match_operand:SI 1 "s390_plus_operand" "") (match_operand:SI 2 "register_operand" "=&a")])] "!TARGET_64BIT" { s390_expand_plus_operand (operands[0], operands[1], operands[2]); DONE; }) (and of course the functions in s390.c called by these.) You ought to be able to do something similar in your backend ... Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE ulrich.weig...@de.ibm.com
Re: [gnat] reuse of ASTs already constructed
I am finally finding some some time to continue this work, having left off with http://gcc.gnu.org/ml/gcc/2009-08/msg00475.html : > [...] > There are two problems right now: > > 1) Mixing of Ada.Text_IO and Text_IO as described at >http://gcc.gnu.org/ml/gcc-help/2009-08/msg00113.html The solution to this one turned out to be quite simple, see attached patch. Sem_Ch12.Analyze_Package_Instantiation calls Rtsfind.Text_IO_Kludge, and the latter contains: if Chrs in Text_IO_Package_Name then for U in Main_Unit .. Last_Unit loop Get_Name_String (Unit_File_Name (U)); ... On compiling the second file, Main_Unit is not 0 but some larger value. The existing node for Text_IO was not being found because it is at an index smaller than the current Main_Unit. The solution was to start the loop at index 0. I will now start looking into the second problem, > 2) The 'X' lines in the ALI files are not what they should be. > This is due to the fact that Lib.Xref.Generate_(Definition|Reference) is > called during semantic analysis. However, when I discover that a > tree was already built for a main unit by a previous compilation, > Sem is not redone for that tree. Depending on whether > Lib.Xref.Initialize is called per-job or per-file, this leads to either > too much or too little cross ref info. By the way, I am currently using trunk r152433 (4.5.0 pre-release) and moving forward to the 4.5.0 release. When that is done: Should I continue on trunk or switch to the gcc-4_5-branch ? Thanks, Oliver Index: rtsfind.adb === --- rtsfind.adb (revision 152433) +++ rtsfind.adb (working copy) @@ -1406,7 +1406,7 @@ -- or [Wide_]Wide_Text_IO already loaded, then load the proper child. if Chrs in Text_IO_Package_Name then - for U in Main_Unit .. Last_Unit loop + for U in 0 .. Last_Unit loop Get_Name_String (Unit_File_Name (U)); if Name_Len = 12 then
please keep the "deprecated" -I- option: it has important functionality not available elsewhere
Hello, I am the author of Foundry build system which is now transitioning to the use of gcc from another compiler. This is great because gcc is an excellent compiler. However. there is a potential problem for me. I hope that the designers of gcc are aware, that some of the gcc (as any advanced software tool) options, are for "convenience", while some are for "uniformity". With a small system, like, a few files to compile, convenience is the key - you want to write the necessary commands to do your compilation, as quickly as possible. With a huge system of hundreds of thousands of files, convenience goes out the window, and the important thing is instead, uniformity. The useful features are the ones who behave in a simple way and always in the same way. That is the only way, with such a large system, for a human to get a handle on the behaviour of the system. Case in point, is the use of "current directory" for -I/-iquote include file searches. That the "current directory" (the directory that the currently preprocessed file was found) is searched first, is a "convenience" feature. For a system with few files, it is very useful. For a huge system, with gazillions of files with duplicate names all over, in order to be sure that the intended include files are included and not some other duplicates, it is crucial to have a simple, uniform algorithm for the search, which lends itself easily to script automation. The addition of "current directory" to the search algorithm, makes it in practice impossible to ensure always the correct files are included (in a huge system). That is why I always disabled the "current directory" (and also disabled the use of "system" directories, and disabled any difference between "" and <>). That way, the one and only thing to worry about is the ordering of -I directories. As I can see, the only way to get this effect in gcc, is with -I- put before all the -I options. In fact, -I- option is really for something else, and this disabling of current directory is a side effect. The whole option is obsolete, and the side effect is in fact thought of as a nuisance in the manual. Nothing could be more misguided! This "strange side effect" is in fact very important. So please don't remove -I- (or make it possible to disable the current directory search, with some other option). Thank you, Mark Galeck
gcc-4.6-20120406 is now available
Snapshot gcc-4.6-20120406 is now available on ftp://gcc.gnu.org/pub/gcc/snapshots/4.6-20120406/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 4.6 SVN branch with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch revision 186200 You'll find: gcc-4.6-20120406.tar.bz2 Complete GCC MD5=3d7ebf813652d464f0e5b361f6a76a6d SHA1=6a2fcf9200f835cc9dac7076d4db1364b4177fcf Diffs from 4.6-20120330 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-4.6 link is updated and a message is sent to the gcc list. Please do not use a snapshot before it has been announced that way.
RFH - Testing targets for the switch to C++
I have started testing the switch to C++ and there is a pile of testing to be done. The testing itself is trivial, but the number of targets that need to be tested is large and I don't have access to all these combinations. My proposal is to make sure that C++ builds work with: - Primary targets - Secondary targets - Any other targets that people regularly test. The first two items are easy to define. I took them from http://gcc.gnu.org/gcc-4.8/criteria.html. The third item I populated from gcc-testresults postings in 2011. This gave me a list of 136 targets. Further, I sorted them by the number of test reports sent, to determine an idea of "popularity". I removed from the list all the targets that had a popularity index lower than 0.01%. This is still a large list (about 109 entries), but there are several overlapping entries (like different flavours of the same basic target), so it should not be too bad. The testing plan is, then, to go through this table to make sure that we can build all of them with C++ enabled for all stages. I have created a wiki page to track testing progress: http://gcc.gnu.org/wiki/CppBuildStatus My plea for help is to everyone who has access to the targets mentioned in the list: please follow the instructions in that page and fill-in the table entries of the targets that you tested. If you see a missing target that should be tested, by all means, add it to the list. Thanks. Diego.
build break in libstdc++-v3 on OS/2
Hi All, I'm trying to update my OS/2 port of GCC to v4.6.3 I have the compiler part building, but am currently getting a break in libstdc++-v3. The error is as follows: In file included from U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/rege x:39:0, from ../../.././libstdc++-v3/src/regex.cc:30: U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bitset: In member function 'void std::bitset<_Nb>::_M_copy_from_ptr(const _CharT*, std::size_t, std::size_ t, std::size_t, _CharT, _CharT)': U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bitset:1371:67: error: no matching function for call to 'min(unsigned int&, const unsigned int&)' U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bitset:1371:67: note: cand idates are: U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bits/stl_algobase.h:187:5: note: template const _Tp& std::min(const _Tp&, const _Tp&) U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bits/stl_algobase.h:233:5: note: template const _Tp& std::min(const _Tp&, const _Tp&, _Compare) U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bits/stl_algo.h:4184:5: no te: template _Tp std::min(std::initializer_list<_Tp>) U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bits/stl_algo.h:4189:5: no te: template _Tp std::min(std::initializer_list<_Tp>, _Compare) Any ideas? Cheers, Paul
Re: i370 port
Ah, yes. The problem is that reload assumes any valid address can be loaded into a register with a single instruction, and it will thus simply generate such instructions unconditionally -- and if the target then doesn't actually provide such a pattern, it will fail with "unrecognizable insn". Hi Ulrich. Thanks for your reply. This approach seems to be quite complicated. What do you think about the option of NOT adding this (which triggers off errors I hadn't seen before): #define EXTRA_MEMORY_CONSTRAINT(C, STR) \ ((C) == 'S') and instead making a change similar to what I have already put in under "hack" below? Is that legitimate? ; ; movstrsi instruction pattern(s). ; block must be less than 16M (24 bits) in length (define_expand "movstrsi" [(set (match_operand:BLK 0 "general_operand" "") (match_operand:BLK 1 "general_operand" "")) (use (match_operand:SI 2 "general_operand" "")) (match_operand 3 "" "")] "" " { rtx op0, op1; op0 = XEXP (operands[0], 0); if (GET_CODE (op0) == REG || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG && GET_CODE (XEXP (op0, 1)) == CONST_INT && (unsigned) INTVAL (XEXP (op0, 1)) < 4096)) op0 = operands[0]; else op0 = replace_equiv_address (operands[0], copy_to_mode_reg (SImode, op0)); op1 = XEXP (operands[1], 0); if (GET_CODE (op1) == REG || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG && GET_CODE (XEXP (op1, 1)) == CONST_INT && (unsigned) INTVAL (XEXP (op1, 1)) < 4096)) op1 = operands[1]; else op1 = replace_equiv_address (operands[1], copy_to_mode_reg (SImode, op1)); /* first line is a hack - if target address involves two registers, we can't use an MVC, even if the length to move is less than 256, because MVC takes an S parameter. I'm unsure of the best way to distinguish a two-register target. */ if (!((GET_CODE(op0) == MEM) && REG_P(XEXP(op0,0))) && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 256) emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, gen_rtx_SET (VOIDmode, op0, op1), gen_rtx_USE (VOIDmode, operands[2]; else { /* implementation provided by Richard Henderson */ rtx reg1 = gen_reg_rtx (DImode); rtx reg2 = gen_reg_rtx (DImode); rtx mem1 = operands[0]; rtx mem2 = operands[1]; rtx len = operands[2]; if (!CONSTANT_P (len)) len = force_reg (SImode, len); /* Load up the address+length pairs. */ emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1)); emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0), force_operand (XEXP (mem1, 0), NULL_RTX)); emit_move_insn (gen_rtx_SUBREG (SImode, reg1, GET_MODE_SIZE (SImode)), len); emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2)); emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0), force_operand (XEXP (mem2, 0), NULL_RTX)); emit_move_insn (gen_rtx_SUBREG (SImode, reg2, GET_MODE_SIZE (SImode)), len); /* Copy! */ emit_insn (gen_movstrsi_1 (reg1, reg2)); } DONE; }") Thanks. Paul.
Re: i370 port
Hi Ulrich. A further question. I put some debugging on here: op0 = XEXP (operands[0], 0); if (GET_CODE (op0) == REG || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG && GET_CODE (XEXP (op0, 1)) == CONST_INT && (unsigned) INTVAL (XEXP (op0, 1)) < 4096)) { op0 = operands[0]; fprintf(stderr, \"used as-is\n\"); } else { op0 = replace_equiv_address (operands[0], copy_to_mode_reg (SImode, op0)); fprintf(stderr, \"replaced\n\"); } And I found out that op0 is already being "replaced". Shouldn't this replacement eliminate the index register and just have a base register, so that I don't need the hack further down? Thanks. Paul.