On Tue, Nov 15, 2016 at 10:07 PM, David Malcolm <dmalc...@redhat.com> wrote: > On Mon, 2016-11-14 at 16:14 +0100, Richard Biener wrote: >> On Fri, Nov 11, 2016 at 10:15 PM, David Malcolm <dmalc...@redhat.com> >> wrote: >> > Changed in this version: >> > >> > * Rather than running just one pass, run *all* passes, but start at >> > the given pass; support for "dg-do run" tests that execute the >> > resulting code. >> > * Updated test cases to new "compact" dump format; more test cases; >> > use "dg-do run" in various places. >> > * Lots of bugfixing >> > >> > Links to previous versions: >> > https://gcc.gnu.org/ml/gcc-patches/2016-10/msg00263.html >> > https://gcc.gnu.org/ml/gcc-patches/2016-10/msg00500.html > >> Does running the RTL passes right from the parser work with -fsyntax >> -only? > > It depends what you mean by "work". If I run it with -fsyntax-only, > then pass_rest_of_compilation::gate returns false, and none of the RTL > passes are run. Is this behavior correct?
Yes. >> Doing it like __GIMPLE has the advantage of not exposing >> "rest_of_compilation", etc.. > > The gimple part of the compiler supports having multiple functions in > memory at once, and then compiling them in arbitrary order based on > decisions made by the callgraph. > > By contrast, the RTL part of the compiler is full of singleton state: > things like crtl (aka x_rtl), the state of emit-rtl.c, > "reload_completed", etc etc. Ah, of course - I forgot that... > To try to limit the scope of the project, for the RTL frontend work I'm > merely attempting to restore the singleton RTL state from a dump, > rather than to support having per function stashes of RTL state. > > Hence the rest of compilation gets invoked directly from the frontend > for the __RTL case, since it will get overwritten if there's a second > __RTL function in the source file (which sounds like an idea for a test > case; I'll attempt such a test case). > > I hope this is a reasonable approach. If not, I suppose I can attempt > to bundle it up into some kind of RTL function state, but that seems > like significant scope creep. Yeah, I think it's a good approach for now. >> I'm now handling __GIMPLE from within declspecs (the GIMPLE FE stuff >> has been committed), it would be nice to match the __RTL piece here. > > (Congratulations on getting the GIMPLE FE stuff in) > > I'm not sure I understand you here - do you want me to rewrite the > __RTL parsing to match the __GIMPLE piece, or the other way around? > If the former, presumably I should reuse (and rename) > c_parser_gimple_pass_list? Handle __RTL like __GIMPLE, thus as declspec. Of course ultimatively Joseph has the last word here. > >> > gcc/ChangeLog: >> > * Makefile.in (OBJS): Add run-rtl-passes.o. >> > >> > gcc/c-family/ChangeLog: >> > * c-common.c (c_common_reswords): Add "__RTL". >> > * c-common.h (enum rid): Add RID_RTL. >> > >> > gcc/c/ChangeLog: >> > * c-parser.c: Include "read-rtl-function.h" and >> > "run-rtl-passes.h". >> > (c_parser_declaration_or_fndef): In the "GNU extensions" >> > part of >> > the leading comment, add an alternate production for >> > "function-definition", along with new "rtl-body-specifier" >> > and >> > "rtl-body-pass-specifier" productions. Handle "__RTL" by >> > calling >> > c_parser_parse_rtl_body. Convert a timevar_push/pop pair >> > to an auto_timevar, to cope with early exit. >> > (c_parser_parse_rtl_body): New function. >> > >> > gcc/ChangeLog: >> > * cfg.c (free_original_copy_tables): Remove assertion >> > on original_copy_bb_pool. >> >> How can that trigger? > > It happens when running pass_outof_cfg_layout_mode::execute; seen with > gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c. > > The input file is a dump taken in cfg_layout mode (although in this > case it's a trivial 3-basic-block CFG, but ideally there would be cases > with non-trivial control flow); it has "fwprop1" as its starting pass. > > Running without -quiet shows: > > skipping pass: *rest_of_compilation > skipping pass: vregs > skipping pass: into_cfglayout > skipping pass: jump > skipping pass: subreg1 > skipping pass: cse1 > found starting pass: fwprop1 > > i.e. it skips the into_cfglayout (amongst others), to start with > fwprop1. > > In theory skipping a pass ought to be a no-op, assuming that we're > faithfully reconstructing all RTL state. However, RTL state management > is fiddly, so the patch introduces some logic in passes.c to do some > things when skipping a pass; in particular, it has: > > /* Update the cfg hooks as appropriate. */ > if (strcmp (pass->name, "into_cfglayout") == 0) > { > cfg_layout_rtl_register_cfg_hooks (); > cfun->curr_properties |= PROP_cfglayout; > } > if (strcmp (pass->name, "outof_cfglayout") == 0) > { > rtl_register_cfg_hooks (); > cfun->curr_properties &= ~PROP_cfglayout; > } > > so that even when skipping "into_cfglayout", the CFG hooks are at least > correct. I suppose the pass manager could handle the hook switching based on a (RTL) pass setting/clearing PROP_cfglayout. Or all passes needing cfglayout would need to set prop_required accordingly and thus the into/outouf cfglayout passes would be implicit. > The assertion fires when running outof_cfglayout later on (rather than > skipping it); the assertion: > > gcc_assert (original_copy_bb_pool); > > assumes that into_cfglayout was actually run, rather than just the > simple "skipping" version of it. Ah, I see cfg_layout_initialize calls initialize_original_copy_tables () for whatever reason and they are kept initialized until out-of-cfglayout... GIMPLE passes do init/free them all the time. I think a better fix would be to add a original_copy_tables_initialized () function and guard the free_original_copy_tables call with that (keeping the assertion that they run in pairs). >> > * cgraph.h (symtab_node::native_rtl_p): New decl. >> > * cgraphunit.c (symtab_node::native_rtl_p): New function. >> > (symtab_node::needed_p): Don't assert for early assembly >> > output >> > for __RTL functions. >> > (cgraph_node::finalize_function): Set "force_output" for >> > __RTL >> > functions. >> > (cgraph_node::analyze): Bail out early for __RTL functions. >> > (analyze_functions): Update assertion to support __RTL >> > functions. >> > (cgraph_node::expand): Bail out early for __RTL functions. >> > * emit-rtl.c (unshare_all_rtl_again): Wrap set_used_decls >> > call >> > in check for DECL_INITIAL. >> >> You should simply set DECL_INITIAL of your function decl (make_node >> (BLOCK);). >> There's too much code assuming that is not NULL (and I've fixed quite >> a bit of >> code during stage1 not doing that). > > Thanks; fixed. > >> > * final.c (rest_of_clean_state): Don't call delete_tree_ssa >> > for >> > _RTL functions. >> > * function.h (struct function): Add field "native_RTL". >> >> I wonder if you could simply use ->curr_properties & PROP_rtl? (and >> set that >> property during parsing, of course) > > I tried to doing that; it mostly works, but this assertion fails: > > 237 symtab_node::needed_p (void) > 238 { > 239 /* Double check that no one output the function into assembly file > 240 early. */ > 241 if (!native_rtl_p ()) > 242 gcc_checking_assert > 243 (!DECL_ASSEMBLER_NAME_SET_P (decl) > 244 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))); > > [I added the "if (!native_rtl_p ())" guard in the patch] > > The issue here is that when this is run, the __RTL function has been > compiled and cleaned up, and the curr_properties & PROP_rtl has been > cleared: > > (gdb) p decl->function_decl->f->curr_properties > $7 = 0 > > I could set the flag again after running the passes; on doing so, the > test suite successfully runs. Hmm, so if you are finished with the function you should set symtab_node->analyzed to false I think (it signals it's now merely an "extern" symbol and no longer has a body). Or set body_removed. Maybe just ask Honza what to do ... Richard. > Would you prefer I use curr_properties & PROP_rtl for this? > [...snip...] > > Thanks > Dave