Re: Adding Leon processor to the SPARC list of processors
--- On Wed, 12/1/11, Joel Sherrill wrote: > From: Joel Sherrill > Subject: Re: Adding Leon processor to the SPARC list of processors > To: "David Paterson" > Cc: "gcc@gcc.gnu.org" > Date: Wednesday, 12 January, 2011, 16:31 > On 01/12/2011 09:17 AM, David > Paterson wrote: > > Hi all, > > > > I'm in the early stages of a Leon-based project, and > have been trying to put together a cross toolchain for > it. I'm having some problems getting it configured and > working correctly, and this proposed option would very > likely help me a lot. > > > > Is there any time scale for implementation, or any > plan for which release it'll make it into? > > > The leon specific bare metal targets are in the SVN head. Thanks Joel, that's useful info. I'll update and give them a try. > If you are using RTEMS, then you can use the RPMs we > provide. At the moment however I'm trying to get a basic minimal system up and running, with no OS on the board. We might look at RTEMS (or other systems) later. Thanks for the link though - good to know about it. Regards, Dave
Debug symbol information in elf file
Hi All, I'm having a problem with debugging (with gdb) an application that was built using gcc. Gcc has been patched to target a non-standard architecture, but I'm not sure the port is complete. When debugging with gdb, function parameters are not displayed properly. I think this is because gdb is looking for the parameter on the stack, where in fact it is in a register. For example, when debugging this code: PRIVATE uint8 u8UpdateTimeBlock(uint8 u8TimeBlock) { /* Update block state for next time, if in a state where regular updates should be performed */ if ((sDemoData.sSystem.eState != E_STATE_SET_CHANNEL) && (sDemoData.sSystem.eState != E_STATE_SETUP_SCREEN) && (sDemoData.sSystem.eState != E_STATE_SCANNING)) { u8TimeBlock++; if (u8TimeBlock >= MAX_BLOCKS) { u8TimeBlock = 0; } } return u8TimeBlock; } With gdb, it thinks that the parameter u8TimeBlock is on the stack at offset 7: (gdb) info address u8TimeBlock Symbol "u8TimeBlock" is an argument at offset 7. In fact, from the disassembly listing we can see that the parameter is actually in r3, then gets moved to r7. 04001604 <_u8UpdateTimeBlock>: 4001604: 30 21 1fb.addi r1,r1,0xfff8 4001607: 04 e3 b.mov r7,r3 4001609: 20 e1 e0b.sb 0x7(r1),r7 400160c: 8c e0 75 52 00 20 b.lwz r7,0x4004aac(r0) 4001612: 40 c7 94b.beqi r7,0x3,400163b <_u8Up dateTimeBlock+0x37> 4001615: 8c e0 75 52 00 20 b.lwz r7,0x4004aac(r0) 400161b: 40 27 04b.beqi r7,0x4,400163b <_u8Up dateTimeBlock+0x37> 400161e: 8c e0 75 52 00 20 b.lwz r7,0x4004aac(r0) 4001624: 40 a7 e8b.beqi r7,0x5,400163b <_u8Up dateTimeBlock+0x37> 4001627: 24 e1 e0b.lbz r7,0x7(r1) 400162a: 00 f8 b.addi r7,r7,0x1 400162c: 20 e1 e0b.sb 0x7(r1),r7 400162f: 24 e1 e0b.lbz r7,0x7(r1) 4001632: 3c e7 c8b.sfleui r7,0x13 4001635: 47 26 00b.bf 400163b <_u8UpdateTim eBlock+0x37> 4001638: 20 01 e0b.sb 0x7(r1),r0 400163b: 24 e1 e0b.lbz r7,0x7(r1) 400163e: 04 67 b.mov r3,r7 4001640: 30 21 10b.addi r1,r1,0x8 4001643: 47 d2 48b.jr r9 I am wondering if the gcc port is somehow not putting the right debug symbol information into the elf file. Output of objdump -stabs: 459FUN0 68104001604 25677 u8UpdateTimeBlock:f(1,8) 460PSYM 0 6800007 25530 u8TimeBlock:p(1,8) 46146 0 0 04001604 0 462SLINE 0 681 0 463SLINE 0 6840008 0 464SLINE 0 6880023 0 465SLINE 0 689002b 0 466SLINE 0 6910034 0 467SLINE 0 6950037 0 468SLINE 0 696003a 0 469FUN0 0 0042 0 47078 0 0 04001646 0 According to http://sourceware.org/gdb/onlinedocs/stabs.html#Parameters, I believe there should be 2 entries in the stabs for the register parameter, a PSYM and RSYM. Please could you tell me if this assumption is correct and if so, any ideas why gcc would not be putting this information in the elf file? Is there any architectural dependant code that needs to be implemented that might be missing from the port to add this debugging information? Thanks very much, Matt
Re: Proposal for automatic generation of c++ header files
On Wed, Jan 12, 2011 at 6:16 PM, David Brown wrote: > On 12/01/2011 16:22, Achilleas Margaritis wrote: >> >> Hello all. >> >> I have a idea for automatic generation of headers in a c++ program. >> Having to maintain headers is a very time consuming task, and I think >> we will all benefit from such a thing. The idea is the following: >> >> Each time the compiler finds the pragma >> >> #pragma autoinclude("foo.hpp") >> >> it does the following: >> >> 1) searches the include path for the header foo.hpp. >> >> 2) if the header does not exist, then the compiler searches for the >> file 'foo.cpp' >> >> 3) if the file 'foo.cpp' is found, then the header 'foo.hpp' is >> generated automatically from the the .cpp file. >> >> 4) if the header exists, then the compiler compares the file dates of >> the header and the implementation files. If the header is older than >> the implementation file, then a new header is generated from the >> implementation file. >> >> When the compiler finds a declaration in a .cpp file that is 100% the >> same as a declaration in a header file, then the declaration in the >> implementation file is ignored, because it has been created >> automatically in the header by the compiler. If there is a difference, >> then an error is declared. >> >> Example: >> >> file main.cpp: >> >> #pragma autoinclude ("foo.hpp") >> >> int main() { >> Foo *foo = new Foo; >> foo->bar(); >> foos.push_back(foo); >> } >> >> file foo.cpp: >> >> #include >> >> class Foo { >> public: >> void bar() { >> } >> }; >> >> std::list foos; >> >> static int data = 0; >> >> The compiler generates the following header: >> >> #ifndef FOO_HPP >> #define FOO_HPP >> >> #include >> >> class Foo { >> public: >> void bar(); >> }; >> >> extern std::list foos; >> >> #endif //FOO_HPP >> >> If such a feature existed, it would greatly speed up application >> development for c++ applications. >> > > I can see how such a feature could be useful, but is there any reason why it > should be part of gcc, rather than a separate program that takes a cpp file > and generates an hpp file? Such a program would be much easier to develop > and maintain than a new gcc pragma, and more flexible (for example, it could > be used with other compilers). Your timestamp checking features are easily > accomplished with make. > > The GCC contains all the necessary code for parsing C++. An external program would have to use a custom parser (which is a lot of work, since C++ is a very complex language), or LLVM (which may or may not be 100% compatible with GCC yet, and which may or may not contain all the GCC features). Doing it from within GCC guarantees code reuse and consistency with the compiler, plus compatibility with the new c++ standard, which GCC already largely implements. Furthermore, the compiler would need to handle the clash of declarations between the generated header and the implementation file. As any compiler is implemented right now, declaring the same class twice will generate an error. Additionally, providing such a functionality through GCC would not have the maintenance overhead of an externally managed application: once GCC is updated to a version with this functionality, this functionality would become instantly available. Finally, GCC is one of the most visible projects when it comes to c++ compilers. If GCC had such a functionality, I think that many people would jump to the opportunity to use this functionality, and therefore it could be part of the language standard in the far future.
Re: [ARM] Implementing doloop pattern
>> Index: config/arm/thumb2.md >> === >> --- config/arm/thumb2.md (revision 168424) >> +++ config/arm/thumb2.md (working copy) > >> + ??? The possible introduction of a new block to initialize the >> + new IV can potentially effects branch optimizations. */ > > s/effects/effect/ Err I think it should be "affect" rather than effect here. Thus s/effects/affect Ramana
Re: Proposal for automatic generation of c++ header files
On 13 January 2011 11:09, Achilleas Margaritis wrote: > On Wed, Jan 12, 2011 at 6:16 PM, David Brown wrote: >> >> I can see how such a feature could be useful, but is there any reason why it >> should be part of gcc, rather than a separate program that takes a cpp file >> and generates an hpp file? Such a program would be much easier to develop >> and maintain than a new gcc pragma, and more flexible (for example, it could >> be used with other compilers). Your timestamp checking features are easily >> accomplished with make. A makefile is a better place to do it than in the compiler, as well as the reasons David gave, a separate tool invoked by make allows project-specific filename conventions. Otherwise, if it was done by the compiler, should it consider any of foo.cpp, foo.cp, foo.cxx, foo.cc, foo.C etc. as a valid source for foo.hpp? Or are only certain transformations allowed e.g. .cpp -> .hpp, .cc -> .hh, .cxx -> .hxx (?) You also don't need any special pragma, just list foo.hpp as a dependency and define a rule for generating foo.hpp from foo.cpp main.o: foo.hpp foo.hpp: foo.cpp cpp2hpp $^ -o $@ That would work, and the code would be 100% valid C++ without a non-portable pragma. > The GCC contains all the necessary code for parsing C++. An external > program would have to use a custom parser (which is a lot of work, > since C++ is a very complex language), or LLVM (which may or may not > be 100% compatible with GCC yet, and which may or may not contain all > the GCC features). Doing it from within GCC guarantees code reuse and > consistency with the compiler, plus compatibility with the new c++ > standard, which GCC already largely implements. The tool doesn't need to fully parse C++, it only needs to recognise a definition and produce a declaration for it, > Furthermore, the compiler would need to handle the clash of > declarations between the generated header and the implementation file. > As any compiler is implemented right now, declaring the same class > twice will generate an error. That would only be a problem if foo.cpp includes foo.hpp, but why would it do that if foo.hpp is generated? > Additionally, providing such a functionality through GCC would not > have the maintenance overhead of an externally managed application: > once GCC is updated to a version with this functionality, this > functionality would become instantly available. > > Finally, GCC is one of the most visible projects when it comes to c++ > compilers. If GCC had such a functionality, I think that many people > would jump to the opportunity to use this functionality, and therefore > it could be part of the language standard in the far future. I seriously doubt that. The modules proposal Ian referred to is far more likely to become part of the standard. However, if you think this feature would be useful you are free to implement it, or pay someone else to do so - that's the beauty of Free Software.
Re: Proposal for automatic generation of c++ header files
On Thu, Jan 13, 2011 at 2:41 PM, Jonathan Wakely wrote: > On 13 January 2011 11:09, Achilleas Margaritis wrote: >> On Wed, Jan 12, 2011 at 6:16 PM, David Brown wrote: >>> >>> I can see how such a feature could be useful, but is there any reason why it >>> should be part of gcc, rather than a separate program that takes a cpp file >>> and generates an hpp file? Such a program would be much easier to develop >>> and maintain than a new gcc pragma, and more flexible (for example, it could >>> be used with other compilers). Your timestamp checking features are easily >>> accomplished with make. > > A makefile is a better place to do it than in the compiler, as well as > the reasons David gave, a separate tool invoked by make allows > project-specific filename conventions. Otherwise, if it was done by > the compiler, should it consider any of foo.cpp, foo.cp, foo.cxx, > foo.cc, foo.C etc. as a valid source for foo.hpp? Or are only > certain transformations allowed e.g. .cpp -> .hpp, .cc -> .hh, .cxx -> > .hxx (?) A makefile will not work. I explain why below in the section about the problem of clashing of symbols. There is no default transformation. The header's filename extension will be defined in the include string name. For example: #pragma autoinclude("foo.hh") #pragma autoinclude("foo.hpp") The pragma's purpose is not only to generate the file, but also to include it. Furthermore, doing it externally with a tool means a huge amount of work. Makefiles, project files, IDEs, scripts etc all would need to be changed in order to accommodate the tool. If this is part of the compiler, then no external tool modification would be required; only source code modifications, which is much easier to do. > > You also don't need any special pragma, just list foo.hpp as a > dependency and define a rule for generating foo.hpp from foo.cpp > > main.o: foo.hpp > > foo.hpp: foo.cpp > cpp2hpp $^ -o $@ > > That would work, and the code would be 100% valid C++ without a > non-portable pragma. The pragma can be ignored by other compilers. Conditional compilation would help in including the header for other compilers. > >> The GCC contains all the necessary code for parsing C++. An external >> program would have to use a custom parser (which is a lot of work, >> since C++ is a very complex language), or LLVM (which may or may not >> be 100% compatible with GCC yet, and which may or may not contain all >> the GCC features). Doing it from within GCC guarantees code reuse and >> consistency with the compiler, plus compatibility with the new c++ >> standard, which GCC already largely implements. > > The tool doesn't need to fully parse C++, it only needs to recognise a > definition and produce a declaration for it, The declaration would be entangled with the definition, and the tool would have to untangle them. It doesn't sound so easy to me. An external tool would have to duplicate a lot of code from GCC, and it would possibly not get the result 100% correct, given the complexity of the language. > >> Furthermore, the compiler would need to handle the clash of >> declarations between the generated header and the implementation file. >> As any compiler is implemented right now, declaring the same class >> twice will generate an error. > > That would only be a problem if foo.cpp includes foo.hpp, but why > would it do that if foo.hpp is generated? If foo.cpp does not include foo.hpp, then the definitions in foo.cpp would not be recognized by the compiler. > >> Additionally, providing such a functionality through GCC would not >> have the maintenance overhead of an externally managed application: >> once GCC is updated to a version with this functionality, this >> functionality would become instantly available. >> >> Finally, GCC is one of the most visible projects when it comes to c++ >> compilers. If GCC had such a functionality, I think that many people >> would jump to the opportunity to use this functionality, and therefore >> it could be part of the language standard in the far future. > > I seriously doubt that. The modules proposal Ian referred to is far > more likely to become part of the standard. I don't see the modules proposal happening in this decade. It took 13 years to update the C++ standard. My gut feeling is that it would be after 2020 that we are going to see working implementations of a module system. > > However, if you think this feature would be useful you are free to > implement it, or pay someone else to do so - that's the beauty of Free > Software. > Do you think such a feature would not be useful? asking out of curiosity. Personally, I would find it extremely useful. It would cut down project development by almost 40% (estimation out of experience).
Re: [ARM] Implementing doloop pattern
On Thu, Jan 06, 2011 at 09:59:08AM +0200, Revital1 Eres wrote: > Index: loop-doloop.c > + Some targets (ARM) do the comparison before the branch, as in the > + folloring form: ^ "following" > + /* In case the pattern is not PARALLEL we expect two forms > + of doloop which are cases 2) and 3) above: in case 2) the > + decrement is immediately precedes the branch. while in case ^^ Take out the "is". > + 3) the compre and decrement instructions immediately precede ^^ "compare" > Index: config/arm/thumb2.md > + /* Currently SMS relies on the do-loop pattern to recognize loops > + where (1) the control part comprises of all insns defining and/or ^ I think "consists" would be more idiomatic here, even if it's still a little awkward. -Nathan
Issue with gimple_regimplify_operands, called from plug-in (GCC 4.5)
Hi, I have a problem with gimple_regimplify_operands() from gimplify.c , which i execute from my custom plug-in-code. It could indicate a bug in this procedure. I'm developing a GCC-plug-in, which does some instrumentation of C-programs on GIMPLE-Level. Among others, I'm inserting logging functions, which output the runtime-addresses of all in a function referenced variables. Since i have to build ADDR_EXPR nodes for all these variables, which invalidates some properties of GIMPLE, I run gimple_regimplify_operands() for all statements in each basic-block. My gimple_pass is inserted before the ssa-building pass. It works fine with all my test-cases which doesn't contain SWITCH-CASE constructs. If my test program contains SWITCH-CASE statements, the compile-process fails by executing gimple_regimplify_operands, called from my pass. I get an error like: main3.c: In function ‘main’: main3.c:24:1: internal compiler error: in gimplify_expr, at gimplify.c:7336 In order to find an error, i removed all my passes, and installed only one pass, which runs regimplify_operands on NOT-instrumented GIMPLE. I got the same error. It indicates that either it is not allowed to run regimplify_operands at this place ( just before the "ssa"-building-pass) or there is a bug in this procedure. Could someone comment or say what I'm doing wrong? Regards, Eugen My test_pass- procedure: static unsigned int execute_regimplify(void){ basic_block bb; FOR_EACH_BB (bb) { gimple_stmt_iterator gsi; gimple_seq seq = bb_seq(bb); for (gsi = gsi_start(seq); !gsi_end_p(gsi); gsi_next(&gsi)) { gimple stmt = gsi_stmt(gsi); gimple_regimplify_operands(stmt, &gsi); } } verify_stmts(); return 0; } plugin-installation code: plugin_init() ... pass_info.pass = &pass_test_regimplify.pass; pass_info.reference_pass_name = "ssa"; pass_info.ref_pass_instance_number = 0; pass_info.pos_op = PASS_POS_INSERT_BEFORE; register_callback (plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info); return 0; } struct gimple_opt_pass pass_test_regimplify = { { GIMPLE_PASS, "test_regimplify", /* name */ NULL, /* gate */ execute_regimplify, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ TV_NONE,/* tv_id */ PROP_cfg, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ 0, /* todo_flags_finish */ } }; the contents of main3.c: int main(int argc, char **args){ int a = 0; int b = 3; switch(b){ case 1: a= 1; break; case 2: a=2; break; default: a=b; } return 0; } -- gdb's back-trace gives: #0 gimplify_expr (expr_p=0xb7ff5418, pre_p=0xb080, post_p=0xbfffecb4, gimple_test_f=0x82e7010 , fallback=) at ../../gcc/gimplify.c:7336 #1 0x08308f52 in gimplify_arg (arg_p=0xb7ff5418, pre_p=, call_location=) at ../../gcc/gimplify.c:2216 #2 0x08309161 in gimplify_call_expr (expr_p=, pre_p=, want_value=) at ../../gcc/gimplify.c:2361 #3 0x0830189b in gimplify_expr (expr_p=0xb7f37f5c, pre_p=0xb080, post_p=0xbfffee64, gimple_test_f=0x82e1a80 , fallback=0) at ../../gcc/gimplify.c:6636 #4 0x0830bafb in gimplify_stmt (stmt_p=0xb7f37f5c, seq_p=0xb080) at ../../gcc/gimplify.c:5277 #5 0x083013b7 in gimplify_statement_list (expr_p=0xb7ebad0c, pre_p=0xb080, post_p=0xbfffef74, gimple_test_f=0x82e1a80 , fallback=0) at ../../gcc/gimplify.c:1383 #6 gimplify_expr (expr_p=0xb7ebad0c, pre_p=0xb080, post_p=0xbfffef74, gimple_test_f=0x82e1a80 , fallback=0) at ../../gcc/gimplify.c:6982 #7 0x0830bafb in gimplify_stmt (stmt_p=0xb7ebad0c, seq_p=0xb080) at ../../gcc/gimplify.c:5277 #8 0x08302ce6 in gimplify_bind_expr (expr_p=0xb7f60fd8, pre_p=0xb138, post_p=0xb084, gimple_test_f=0x82e1a80 , fallback=0) at ../../gcc/gimplify.c:1128 #9 gimplify_expr (expr_p=0xb7f60fd8, pre_p=0xb138, post_p=0xb084, gimple_test_f=0x82e1a80 , fallback=0) at ../../gcc/gimplify.c:6766 #10 0x0830bafb in gimplify_stmt (stmt_p=0xb7f60fd8, seq_p=0xb138) at ../../gcc/gimplify.c:5277 #11 0x0830bbe0 in gimplify_body (body_p=0xb7f60fd8, fndecl=0xb7f60f80, do_parms=1 '\001') at ../../gcc/gimplify.c:7578 #12 0x0830c011 in gimplify_function_tree (fndecl=0xb7f60f80) at ../../gcc/gimplify.c:7674 #13 0x08616398 in cgraph_a
Re: Issue with gimple_regimplify_operands, called from plug-in (GCC 4.5)
On Thu, Jan 13, 2011 at 4:01 PM, Eugen Wagner wrote: > Hi, > I have a problem with gimple_regimplify_operands() from gimplify.c , > which i execute from my custom plug-in-code. It could indicate a bug > in this procedure. This function isn't generic enough to handle full re-gimplification. It was written for some specific use-cases and I would suggest to not use it. The simplest way to modify statements is to generate new statements which compute the changed value into a register and substiute that result into the operand you want to change. Richard. > I'm developing a GCC-plug-in, which does some instrumentation of > C-programs on GIMPLE-Level. > Among others, I'm inserting logging functions, which output the > runtime-addresses of all in a function referenced variables. > Since i have to build ADDR_EXPR nodes for all these variables, which > invalidates some properties of GIMPLE, > I run gimple_regimplify_operands() for all statements in each basic-block. > > My gimple_pass is inserted before the ssa-building pass. > It works fine with all my test-cases which doesn't contain SWITCH-CASE > constructs. > > If my test program contains SWITCH-CASE statements, the > compile-process fails by executing gimple_regimplify_operands, called > from my pass. > I get an error like: > main3.c: In function ‘main’: > main3.c:24:1: internal compiler error: in gimplify_expr, at gimplify.c:7336 > > In order to find an error, i removed all my passes, and installed only > one pass, which runs regimplify_operands on NOT-instrumented GIMPLE. > I got the same error. > It indicates that either it is not allowed to run regimplify_operands > at this place ( just before the "ssa"-building-pass) or there is a bug > in this procedure. > > Could someone comment or say what I'm doing wrong? > > Regards, > Eugen > > > My test_pass- procedure: > static unsigned int > execute_regimplify(void){ > basic_block bb; > FOR_EACH_BB (bb) > { > gimple_stmt_iterator gsi; > gimple_seq seq = bb_seq(bb); > > for (gsi = gsi_start(seq); !gsi_end_p(gsi); gsi_next(&gsi)) > { > gimple stmt = gsi_stmt(gsi); > gimple_regimplify_operands(stmt, &gsi); > } > } > verify_stmts(); > return 0; > } > > plugin-installation code: > plugin_init() > ... > pass_info.pass = &pass_test_regimplify.pass; > pass_info.reference_pass_name = "ssa"; > pass_info.ref_pass_instance_number = 0; > pass_info.pos_op = PASS_POS_INSERT_BEFORE; > register_callback (plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, > NULL, &pass_info); > return 0; > } > > > struct gimple_opt_pass pass_test_regimplify = > { > { GIMPLE_PASS, "test_regimplify", /* name */ > NULL, /* gate */ > execute_regimplify, /* execute */ > NULL, /* sub */ > NULL, /* next */ > 0, /* static_pass_number */ > TV_NONE, /* tv_id */ > PROP_cfg, /* properties_required */ > 0, /* properties_provided */ > 0, /* properties_destroyed */ > 0, /* todo_flags_start */ > 0, /* todo_flags_finish */ > } }; > > the contents of main3.c: > int main(int argc, char **args){ > int a = 0; > int b = 3; > switch(b){ > case 1: > a= 1; > break; > case 2: > a=2; > break; > default: > a=b; > } > return 0; > } > -- > gdb's back-trace gives: > > #0 gimplify_expr (expr_p=0xb7ff5418, pre_p=0xb080, > post_p=0xbfffecb4, gimple_test_f=0x82e7010 , > fallback=) at ../../gcc/gimplify.c:7336 > #1 0x08308f52 in gimplify_arg (arg_p=0xb7ff5418, pre_p= optimized out>, call_location=) > at ../../gcc/gimplify.c:2216 > #2 0x08309161 in gimplify_call_expr (expr_p=, > pre_p=, > want_value=) at ../../gcc/gimplify.c:2361 > #3 0x0830189b in gimplify_expr (expr_p=0xb7f37f5c, pre_p=0xb080, > post_p=0xbfffee64, > gimple_test_f=0x82e1a80 , fallback=0) at > ../../gcc/gimplify.c:6636 > #4 0x0830bafb in gimplify_stmt (stmt_p=0xb7f37f5c, seq_p=0xb080) > at ../../gcc/gimplify.c:5277 > #5 0x083013b7 in gimplify_statement_list (expr_p=0xb7ebad0c, > pre_p=0xb080, post_p=0xbfffef74, > gimple_test_f=0x82e1a80 , fallback=0) at > ../../gcc/gimplify.c:1383 > #6 gimplify_expr (expr_p=0xb7ebad0c, pre_p=0xb080, > post_p=0xbfffef74, gimple_test_f=0x82e1a80 , > fallback=0) at ../../gcc/gimplify.c:6982 > #7 0x0830bafb in gimplify_stmt (stmt_p=0xb7ebad0c, seq_p=0xb080) > at ../../gcc/gimplify.c:5277 > #8 0x08302ce6 in gimplify_bind_expr (expr_p=0
Re: Issue with gimple_regimplify_operands, called from plug-in (GCC 4.5)
Hi Richard, 2011/1/13 Richard Guenther : > The simplest way to modify statements is to generate new > statements which compute the changed value into a register > and substiute that result into the operand you want to change. > > Richard. thanks for answering so fast, i will try to go this way. Regards, Eugen
Re: Strange Performance Hit on 2D-Loop
Just for the records: I finally found the issue here. It's a problem of both, alignment and cache thrashing. When using aligned memory (e.g. via posix_memalign()) and using a suitable offset within that memory, the effect goes away. So it's a processor effect, not a compiler issue. :-) Best -Andreas On 16:19 Thu 09 Jul , Andreas Schäfer wrote: > Hey guys, > > I noticed a strange performance hit in one of our stencil codes, > causing it to run twice as long. > > To nail down the error, I reduced our code to the two attached demo > programs. Basically they take two matrices and average each matrix > element with its four direct neighbors. Depending on how these > matrices are allocated, the performance hit occurs -- or does not. > > Here is the diff of the two files: > @@ -17,8 +17,7 @@ > > void test(double (*grid)[GRID_WIDTH]) > { > -double (*gridOld)[GRID_WIDTH] = > -malloc(GRID_WIDTH * GRID_HEIGHT * sizeof(double)); > +double (*gridOld)[GRID_WIDTH] = gridOldArray; > double (*gridNew)[GRID_WIDTH] = gridNewArray; > printAddress(&gridNew[0][0]); > printAddress(&gridOld[0][0]); > > where gridOldArray is a statically allocated array. Depending on the > machines processor the performance hit varies from negligible to > dramatic: > > > Processor GCC Version Time(slow) Time(fast) Performance Hit > -- --- -- -- --- > Core 2 Quad Q9550 4.3.3 12.19s 5.11s 138% > Athlon 64 X2 3800+ 4.3.37.34s 6.61s 11% > Opteron 2378 4.3.26.13s 5.60s 9% > Opteron 2352 4.3.38.16s 7.96s 2% > Xeon 3.00GHz 4.3.3 18.98s 14.67s 29% > > Apparently Intel systems are more susceptible to this effect. > > Can anyone reproduce these results? > And could anyone explain, why this happens? > > Thanks in advance > -Andreas > > > -- > > Andreas Schäfer > Cluster and Metacomputing Working Group > Friedrich-Schiller-Universität Jena, Germany > 0049/3641-9-46376 > PGP/GPG key via keyserver > I'm a bright... http://www.the-brights.net > > > (\___/) > (+'.'+) > (")_(") > This is Bunny. Copy and paste Bunny into your > signature to help him gain world domination! > #define GRID_WIDTH 1024 > #define GRID_HEIGHT 1024 > #define MAX_STEPS 1024 > > #include > #include > #include > > double grid[GRID_HEIGHT][GRID_WIDTH]; > double gridNewArray[GRID_HEIGHT][GRID_WIDTH]; > double gridOldArray[GRID_HEIGHT][GRID_WIDTH]; > > void printAddress(void *p) > { > printf("address %p\n", p); > } > > void test(double (*grid)[GRID_WIDTH]) > { > double (*gridOld)[GRID_WIDTH] = gridOldArray; > double (*gridNew)[GRID_WIDTH] = gridNewArray; > printAddress(&gridNew[0][0]); > printAddress(&gridOld[0][0]); > > // copy initial state > for (int y = 0; y < GRID_HEIGHT; ++y) { > memcpy(&gridOld[y][0], &grid[y][0], GRID_WIDTH * sizeof(double)); > memset(&gridNew[y][0], 0, GRID_WIDTH * sizeof(double)); > } > > // update matrices > for (int step = 0; step < MAX_STEPS; ++step) { > for (int y = 1; y < GRID_HEIGHT-1; ++y) > for (int x = 1; x < GRID_WIDTH-1; ++x) > gridNew[y][x] = > (gridOld[y-1][x ] + > gridOld[y ][x-1] + > gridOld[y ][x ] + > gridOld[y ][x+1] + > gridOld[y+1][x ]) * 0.2; > double (*tmp)[GRID_WIDTH] = gridOld; > gridOld = gridNew; > gridNew = tmp; > } > > // copy result back > for (int y = 0; y < GRID_HEIGHT; ++y) > memcpy(&grid[y][0], &gridOld[y][0], GRID_WIDTH * sizeof(double)); > } > > void setupGrid() > { > for (int y = 0; y < GRID_HEIGHT; ++y) > for (int x = 0; x < GRID_WIDTH; ++x) > grid[y][x] = 0; > > for (int y = 10; y < 20; ++y) > for (int x = 10; x < 20; ++x) > grid[y][x] = 1; > } > > int main(int argc, char** argv) > { > setupGrid(); > test(grid); > printf("res: %f\n", grid[10][10]); // prevent dead code elimination > return 0; > } -- == Andreas Schäfer HPC and Grid Computing Chair of Computer Science 3 Friedrich-Alexander-Universität Erlangen-Nürnberg, Germany +49 9131 85-27910 PGP/GPG key via keyserver I'm a bright... http://www.the-brights.net == (\___/) (+'.'+) (")_(") This is Bunny. Copy and paste Bunny into your signature to help him gain world domination! pgpE1l3ZdnuF1.pgp Description: PGP signature
Re: Proposal for automatic generation of c++ header files
On 13 January 2011 13:06, Achilleas Margaritis wrote: > On Thu, Jan 13, 2011 at 2:41 PM, Jonathan Wakely > wrote: >> On 13 January 2011 11:09, Achilleas Margaritis wrote: >>> On Wed, Jan 12, 2011 at 6:16 PM, David Brown wrote: I can see how such a feature could be useful, but is there any reason why it should be part of gcc, rather than a separate program that takes a cpp file and generates an hpp file? Such a program would be much easier to develop and maintain than a new gcc pragma, and more flexible (for example, it could be used with other compilers). Your timestamp checking features are easily accomplished with make. >> >> A makefile is a better place to do it than in the compiler, as well as >> the reasons David gave, a separate tool invoked by make allows >> project-specific filename conventions. Otherwise, if it was done by >> the compiler, should it consider any of foo.cpp, foo.cp, foo.cxx, >> foo.cc, foo.C etc. as a valid source for foo.hpp? Or are only >> certain transformations allowed e.g. .cpp -> .hpp, .cc -> .hh, .cxx -> >> .hxx (?) > > A makefile will not work. I explain why below in the section about the > problem of clashing of symbols. > > There is no default transformation. The header's filename extension > will be defined in the include string name. For example: > > #pragma autoinclude("foo.hh") > #pragma autoinclude("foo.hpp") You said that will cause it to look for foo.cpp, so there must be a transformation from "foo.hpp" to "foo.cpp", no? > The pragma's purpose is not only to generate the file, but also to include it. > > Furthermore, doing it externally with a tool means a huge amount of > work. Makefiles, project files, IDEs, scripts etc all would need to be > changed in order to accommodate the tool. If this is part of the > compiler, then no external tool modification would be required; only > source code modifications, which is much easier to do. You don't *have* to define rules in the makefile, you could just run the tool (called cpp2hpp in my example make rule) once and the headers exist. Which you need to do for other compilers anyway, see below ... >> You also don't need any special pragma, just list foo.hpp as a >> dependency and define a rule for generating foo.hpp from foo.cpp >> >> main.o: foo.hpp >> >> foo.hpp: foo.cpp >> cpp2hpp $^ -o $@ >> >> That would work, and the code would be 100% valid C++ without a >> non-portable pragma. > > The pragma can be ignored by other compilers. Conditional compilation > would help in including the header for other compilers. Except the header wouldn't exist if you use other compilers, because you need gcc to generate it. If you need gcc around in order to generate the header for other compilers, then it's effectively a separate tool (let's call it cpp2hpp) and doesn't need to be part of gcc. >>> The GCC contains all the necessary code for parsing C++. An external >>> program would have to use a custom parser (which is a lot of work, >>> since C++ is a very complex language), or LLVM (which may or may not >>> be 100% compatible with GCC yet, and which may or may not contain all >>> the GCC features). Doing it from within GCC guarantees code reuse and >>> consistency with the compiler, plus compatibility with the new c++ >>> standard, which GCC already largely implements. >> >> The tool doesn't need to fully parse C++, it only needs to recognise a >> definition and produce a declaration for it, > > The declaration would be entangled with the definition, and the tool > would have to untangle them. It doesn't sound so easy to me. > > An external tool would have to duplicate a lot of code from GCC, and > it would possibly not get the result 100% correct, given the > complexity of the language. GCC would not get it 100% either, you'd be better using a stricter parser such as EDG. >>> Furthermore, the compiler would need to handle the clash of >>> declarations between the generated header and the implementation file. >>> As any compiler is implemented right now, declaring the same class >>> twice will generate an error. >> >> That would only be a problem if foo.cpp includes foo.hpp, but why >> would it do that if foo.hpp is generated? > > If foo.cpp does not include foo.hpp, then the definitions in foo.cpp > would not be recognized by the compiler. Eh? Your OP said foo.cpp looked like: file foo.cpp: #include class Foo { public: void bar() { } }; std::list foos; static int data = 0; So it doesn't include foo.hpp and doesn't need to. If you are trying to convince someone to implement your idea you should make sure you have a clear proposal in mind. >>> Additionally, providing such a functionality through GCC would not >>> have the maintenance overhead of an externally managed application: >>> once GCC is updated to a version with this functionality, this >>> functionality would become instantly available. >>> >>> Finally, GCC is one of the most visibl
Re: Proposal for automatic generation of c++ header files
>> A makefile will not work. I explain why below in the section about the >> problem of clashing of symbols. >> >> There is no default transformation. The header's filename extension >> will be defined in the include string name. For example: >> >> #pragma autoinclude("foo.hh") >> #pragma autoinclude("foo.hpp") > > You said that will cause it to look for foo.cpp, so there must be a > transformation from "foo.hpp" to "foo.cpp", no? Indeed. The #pragma could be: #pragma autoinclude("foo.hpp", "foo.cpp") The second part may be optional. The default would be to use a translation like the one you proposed (hpp => cpp, hh => cc, hxx => cxx etc), which is used in most cases anyway. >> The pragma's purpose is not only to generate the file, but also to include >> it. >> >> Furthermore, doing it externally with a tool means a huge amount of >> work. Makefiles, project files, IDEs, scripts etc all would need to be >> changed in order to accommodate the tool. If this is part of the >> compiler, then no external tool modification would be required; only >> source code modifications, which is much easier to do. > > You don't *have* to define rules in the makefile, you could just run > the tool (called cpp2hpp in my example make rule) once and the headers > exist. Which you need to do for other compilers anyway, see below ... You have to define rules in the makefile, because the header files would need to be regenerated each time the implementation file changes. If you don't define rules, then how it is going to work? And then there are lots of other tools that won't work (IDEs for example). >> >> The pragma can be ignored by other compilers. Conditional compilation >> would help in including the header for other compilers. > > Except the header wouldn't exist if you use other compilers, because > you need gcc to generate it. No, in other compilers you would have to provide the header manually. The idea is this: if you use gcc, the headers may be generated for you. If you don't use gcc, then you have to create the headers yourself. >> The declaration would be entangled with the definition, and the tool >> would have to untangle them. It doesn't sound so easy to me. >> >> An external tool would have to duplicate a lot of code from GCC, and >> it would possibly not get the result 100% correct, given the >> complexity of the language. > > GCC would not get it 100% either, you'd be better using a stricter > parser such as EDG. Why not? doesn't GCC contain all that is required for that parsing to succeed? >> If foo.cpp does not include foo.hpp, then the definitions in foo.cpp >> would not be recognized by the compiler. > > Eh? > Your OP said foo.cpp looked like: > > file foo.cpp: > > #include > > class Foo { > public: >void bar() { >} > }; > > std::list foos; > > static int data = 0; > > So it doesn't include foo.hpp and doesn't need to. Can the GCC linker find the symbol Foo::bar() in the above code? I did a test (with mingw), and the result is that if I don't define Foo::bar() outside the class, then the linker doesn't find the function. The same thing happens with Microsoft's compiler. > If you are trying to convince someone to implement your idea you > should make sure you have a clear proposal in mind. I think I did. If I haven't nail down every little detail, I apologize, no one is perfect. >> Do you think such a feature would not be useful? asking out of >> curiosity. Personally, I would find it extremely useful. It would cut >> down project development by almost 40% (estimation out of experience). > > I don't spend 40% of my development time putting declarations in > separate files from definitions. I don't think it would be more > useful than Vandevoorde's modules proposal, and I'd rather spend time > on that (something I plan to do when the proposal is resurrected, > post-C++0x) > How much do you spend in maintaining headers? answers welcomed from other members as well.
Re: Proposal for automatic generation of c++ header files
On 13 January 2011 16:59, Achilleas Margaritis wrote: >>> >>> The pragma can be ignored by other compilers. Conditional compilation >>> would help in including the header for other compilers. >> >> Except the header wouldn't exist if you use other compilers, because >> you need gcc to generate it. > > No, in other compilers you would have to provide the header manually. > > The idea is this: if you use gcc, the headers may be generated for > you. If you don't use gcc, then you have to create the headers > yourself. > >>> The declaration would be entangled with the definition, and the tool >>> would have to untangle them. It doesn't sound so easy to me. >>> >>> An external tool would have to duplicate a lot of code from GCC, and >>> it would possibly not get the result 100% correct, given the >>> complexity of the language. >> >> GCC would not get it 100% either, you'd be better using a stricter >> parser such as EDG. > > Why not? doesn't GCC contain all that is required for that parsing to succeed? GCC has bugs and doesn't parse everything 100% correctly, given the complexity of the language. >>> If foo.cpp does not include foo.hpp, then the definitions in foo.cpp >>> would not be recognized by the compiler. >> >> Eh? >> Your OP said foo.cpp looked like: >> >> file foo.cpp: >> >> #include >> >> class Foo { >> public: >> void bar() { >> } >> }; >> >> std::list foos; >> >> static int data = 0; >> >> So it doesn't include foo.hpp and doesn't need to. My point was that your foo.cpp doesn't have an #include (or #autoinclude) for foo.hpp, and doesn't need one either. foo.cpp contains all the necessary declarations already - it MUST do, or you couldn't generate foo.hpp! So there's no need for foo.cpp to include foo.hpp (and doing so would require the compiler to handle duplicate class definitions, which is more implementation work, for no good reason.) > Can the GCC linker find the symbol Foo::bar() in the above code? > > I did a test (with mingw), and the result is that if I don't define > Foo::bar() outside the class, then the linker doesn't find the > function. > > The same thing happens with Microsoft's compiler. That's because you've defined Foo::bar as inline but not used it in foo.o You should either fix your autoinclude generation so that Foo::bar is defined inline in foo.hpp, or you should define it non-inline in foo.cpp Either way, foo.cpp still shouldn't include foo.hpp, despite your repeated claims it needs to. > How much do you spend in maintaining headers? answers welcomed from > other members as well. I don't see how it will save 40% of my time if I only have to edit one file instead of two. The change still has to be made *somewhere* and I spend more time deciding what to change and testing it than I do dealing with separating declarations from definitions.
Re: Proposal for automatic generation of c++ header files
>> Why not? doesn't GCC contain all that is required for that parsing to >> succeed? > > GCC has bugs and doesn't parse everything 100% correctly, given the > complexity of the language. Oh, ok then. But I think consistence is more important than correctness in this case: the result header file should be as if it was manually written, which means that whatever bugs GCC has when parsing a file, these bugs should be reproducible from the generated header. > My point was that your foo.cpp doesn't have an #include (or > #autoinclude) for foo.hpp, and doesn't need one either. > > foo.cpp contains all the necessary declarations already - it MUST do, > or you couldn't generate foo.hpp! > > So there's no need for foo.cpp to include foo.hpp (and doing so would > require the compiler to handle duplicate class definitions, which is > more implementation work, for no good reason.) > >> Can the GCC linker find the symbol Foo::bar() in the above code? >> >> I did a test (with mingw), and the result is that if I don't define >> Foo::bar() outside the class, then the linker doesn't find the >> function. >> >> The same thing happens with Microsoft's compiler. > > That's because you've defined Foo::bar as inline but not used it in foo.o The point though is to avoid writing things twice. For me, the following is not acceptable: class Foo { public: void bar(); }; void Foo::bar() { } If I have to do the above, I didn't gain anything by the auto-generated headers. I still have to write things twice. The point is to generate the header from this class definition: class Foo { public: void bar() { } }; This is a detail which only a compiler can handle. >> How much do you spend in maintaining headers? answers welcomed from >> other members as well. > > I don't see how it will save 40% of my time if I only have to edit one > file instead of two. > The change still has to be made *somewhere* and I spend more time > deciding what to change and testing it than I do dealing with > separating declarations from definitions. > The point is not mainly about editing one or two files, but about avoiding writing (and maintaining) things twice.
C-family stack check for threads
Hi I would like to have a stack check for threads with small stack space for each thread. (I'm using a ARM Cortex-M3 microcontroller with a stack size of a 1 KByte per Thread.) Each thread having its own limit address. The thread scheduler can then calculate the limit and store this value inside of a global variable. The compiler may generate code to check the stack for overflow at function entry. In principal this can be done this way: - push registers as usual - figure out if one or two work registers, that can be used directly without extra push - if not enough registers found push required work registers to stack - load limit address into first working register - load value of limit address (into the same register) - if stack pointer will go to extend the stack (e.g. for local variables) load this size value too (here the second work register can be used) - compare for overflow - if overflow occur "call" stack_failure function - pop work registers that are pushed before - continue function prologue as usual e.g. extend stack pointer The ARM target has an option "-mapcs-stack-check" but this is more or less not working. (implementaion missing) There are also architecture independent options like "-fstack-check=generic", "-fstack-limit-symbol=current_stack_limit" or "-fstack-limit-register=r6" that can be used. The generic stack check is doing a probe at end of function prologue phase (e.g by writing 12K ahead the current stack pointer position). If this stack space is not available the probe may generates a fault. This require that the CPU is having a MPU or a MMU. For machines with small memory space an additional mechanism should be available. The option "-fstack-check" can be extend by the switches "direct" and "indirect" to emit compare code in function prologue. If switch "direct" is given the address of "-fstack-limit-symbol" represents the limit itself. If switch "indirect" is given "-fstack-limit-symbol" is a kind of global variable that needs be read before compare. I have add an proposal to show how an integrateion of this behavior can be done at ARM architecture. Is there interest to have such a feature at GCC side? Is there someone with write permission who is willing to play the role as a volunteer for this task? Is the code still small enough to be acceptable or is additional paperwork required first? The generated code itself will be small e.g. if using "-fstack-check=indirect -fstack-limit-symbol=stack_limit_var" ->push{r0} ->ldrr0, =stack_limit_var ->ldrr0, [r0] ->cmpsp, r0 ->bhs1f ->push{lr} ->bl__thumb_stack_failure@ stack check ->.align ->.ltorg ->1: ->pop{r0} The rest of the implementation overhead is only GCC specific. Regards Thomas Klein PS Here are some more implementation hints. introduce new parameters "direct" and "indirect" in gcc/opts.c and gcc/flag-types.h gcc/explow.c function allocate_dynamic_stack_space: - suppress stack probing if parameter "direct", "indirect" or if a stack-limit is given - do additional read of limit value if parameter "indirect" and a stack-limit symbol is given gcc/config/arm/arm.c - new function "stack_check_output_function" to write the stack check to the assember file - new function "stack_check_work_registers" to find possible working registers (only used by "stack check") - integration for ARM and Thumb-2 in function arm_expand_prologue - integration for Thumb-1 in function thumb1_output_function_prologue gcc/config/arm/arm.md - probe_stack: do not emit code when parameters "direct" or "indirect" given emit code as in gcc/explow.c - probe_stack_done: dummy to make sure probe_stack insns are not optimized away - check_stack: if stack-limit and parameter "generic" is given use the limit the same way as in function allocate_dynamic_stack_space - stack_check: ARM/Thumb-2 insn to output function stack_check_output_function - trap: failure call used in function allocate_dynamic_stack_space Index: gcc/opts.c === --- gcc/opts.c(revision 168762) +++ gcc/opts.c(working copy) @@ -1616,6 +1616,12 @@ common_handle_option (struct gcc_options *opts, : STACK_CHECK_STATIC_BUILTIN ? STATIC_BUILTIN_STACK_CHECK : GENERIC_STACK_CHECK; + else if (!strcmp (arg, "indirect")) +/* This is an other stack checking method. */ +opts->x_flag_stack_check = INDIRECT_STACK_CHECK; + else if (!strcmp (arg, "direct")) +/* This is an other stack checking method. */ +opts->x_flag_stack_check = DIRECT_STACK_CHECK; else warning_at (loc, 0, "unknown stack check parameter \"%s\"", arg); break; Index: gcc/flag-types.h === --- gcc/flag-types.h(revision 168762) +++ gcc/flag-types.h(working c
Re: Debug symbol information in elf file
Matt Redfearn writes: > Output of objdump -stabs: Use DWARF. You're right, though, it looks like the debug generation routines think that the parameter is passed in memory. Specifically, DECL_INCOMING_RTL of the PARM_DECL is a MEM. You're going to need to find out why that is. Ian
Re: Proposal for automatic generation of c++ header files
Achilleas Margaritis writes: > How much do you spend in maintaining headers? answers welcomed from > other members as well. In C++, I personally spend very little time doing what I would describe as "maintaining headers." I write class definitions in .h files and function implementations in .cc files. The only data which appears in both places is the function signature. Yes, it would be slightly nice if I didn't have to write that twice. But it's a minor issue. Of course these days I mostly work on Go, which doesn't have this issue at all, because the language implements something along the lines of the C++ modules proposal. Which I think is the right way to go. Don't get confused by the language standardization process here; your proposal is also a change to the language. The pace of the standardization process is independent of whether gcc should implement a language change. The important point is that in order to implement what you want, the question is not whether to change the language, it is how to change it. And how it should be changed is the way that works best for most people, which need not be the way that most nearly replicates the way the language currently works. Ian
gcc-4.5-20110113 is now available
Snapshot gcc-4.5-20110113 is now available on ftp://gcc.gnu.org/pub/gcc/snapshots/4.5-20110113/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 4.5 SVN branch with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-4_5-branch revision 168766 You'll find: gcc-4.5-20110113.tar.bz2 Complete GCC (includes all of below) MD5=2e5abdc54382dcc7f4e1ca3b4c6a5f8d SHA1=d1ed89aa5da55250301215faf40f9249ab46d8b9 gcc-core-4.5-20110113.tar.bz2C front end and core compiler MD5=328069e5d90776836efdc83a5a4cdd35 SHA1=e83fb3a337cd6c759face47ab0bcf694f4fac14f gcc-ada-4.5-20110113.tar.bz2 Ada front end and runtime MD5=2eaee98c378dde43f240f6837fbd41f1 SHA1=8144e79cabdacac17e204909a11173759963e1f1 gcc-fortran-4.5-20110113.tar.bz2 Fortran front end and runtime MD5=c89fd317d2662bd275ec3b696bdb59a9 SHA1=f2ccf98776c01ccfad7fe1ca7f67abef44d2917c gcc-g++-4.5-20110113.tar.bz2 C++ front end and runtime MD5=43fb6b7e882eb689bdd88a49058338e4 SHA1=4c6b08bf75e0a6060fa4ee85562b26e6660fcd5b gcc-go-4.5-20110113.tar.bz2 Go front end and runtime MD5=9bba095675f12d681903b75d28f3dd92 SHA1=374ee48032a2df96fab56609922364778e71b94a gcc-java-4.5-20110113.tar.bz2Java front end and runtime MD5=de796ecc2ff02f962ff73e6f3460f290 SHA1=597f8d0a9184742e1b0f2e3eff9d4d5901b8dc0f gcc-objc-4.5-20110113.tar.bz2Objective-C front end and runtime MD5=de18a38fec7ac452105db350c37c72f7 SHA1=54f08e4ea3a919afc1507ed7d9ac81f383f480da gcc-testsuite-4.5-20110113.tar.bz2 The GCC testsuite MD5=5febac1ce8fb0866e9fc6c23fece8dc0 SHA1=cc9c130af60b78e48159e5ad81e4246895afed8f Diffs from 4.5-20110106 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-4.5 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.