diff mbox

[9f] Add a way for the C frontend to compile __RTL-tagged functions

Message ID 1484015904-32671-7-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm Jan. 10, 2017, 2:38 a.m. UTC
The backend is full of singleton state, so we have to compile
__RTL-functions as soon as we parse them.  This means that the
C frontend needs to invoke the backed.

This patch adds the support needed.

Normally this would be a no-no, and including rtl headers is
blocked by this within system.h:

 /* Front ends should never have to include middle-end headers.  Enforce
    this by poisoning the header double-include protection defines.  */
 #ifdef IN_GCC_FRONTEND
 #pragma GCC poison GCC_RTL_H GCC_EXCEPT_H GCC_EXPR_H
 #endif

Hence the patch puts the decl into a new header (run-rtl-passes.h)
that's accessible to the C frontend without exposing any RTL
internals.  (If adding a header for just this decl is overkill, is
there a better place to put the decl?)

gcc/ChangeLog:
	* Makefile.in (OBJS): Add run-rtl-passes.o.
	* pass_manager.h (gcc::pass_manager::get_rest_of_compilation): New
	accessor.
	(gcc::pass_manager::get_clean_slate): New accessor.
	* run-rtl-passes.c: New file.
	* run-rtl-passes.h: New file.
---
 gcc/Makefile.in      |  1 +
 gcc/pass_manager.h   |  6 +++++
 gcc/run-rtl-passes.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/run-rtl-passes.h | 25 ++++++++++++++++++++
 4 files changed, 98 insertions(+)
 create mode 100644 gcc/run-rtl-passes.c
 create mode 100644 gcc/run-rtl-passes.h

Comments

Jeff Law Jan. 16, 2017, 9:54 p.m. UTC | #1
On 01/09/2017 07:38 PM, David Malcolm wrote:
> The backend is full of singleton state, so we have to compile
> __RTL-functions as soon as we parse them.  This means that the
> C frontend needs to invoke the backed.
>
> This patch adds the support needed.
>
> Normally this would be a no-no, and including rtl headers is
> blocked by this within system.h:
>
>  /* Front ends should never have to include middle-end headers.  Enforce
>     this by poisoning the header double-include protection defines.  */
>  #ifdef IN_GCC_FRONTEND
>  #pragma GCC poison GCC_RTL_H GCC_EXCEPT_H GCC_EXPR_H
>  #endif
>
> Hence the patch puts the decl into a new header (run-rtl-passes.h)
> that's accessible to the C frontend without exposing any RTL
> internals.  (If adding a header for just this decl is overkill, is
> there a better place to put the decl?)
>
> gcc/ChangeLog:
> 	* Makefile.in (OBJS): Add run-rtl-passes.o.
> 	* pass_manager.h (gcc::pass_manager::get_rest_of_compilation): New
> 	accessor.
> 	(gcc::pass_manager::get_clean_slate): New accessor.
> 	* run-rtl-passes.c: New file.
> 	* run-rtl-passes.h: New file.
It feels like this is dependent upon something that I haven't seen?!? 
Where is get_rest_of_compilation used?  Where is pass_clean_state_1?


jeff
David Malcolm Jan. 16, 2017, 11:23 p.m. UTC | #2
On Mon, 2017-01-16 at 14:54 -0700, Jeff Law wrote:
> On 01/09/2017 07:38 PM, David Malcolm wrote:
> > The backend is full of singleton state, so we have to compile
> > __RTL-functions as soon as we parse them.  This means that the
> > C frontend needs to invoke the backed.
> > 
> > This patch adds the support needed.
> > 
> > Normally this would be a no-no, and including rtl headers is
> > blocked by this within system.h:
> > 
> >  /* Front ends should never have to include middle-end headers. 
> >  Enforce
> >     this by poisoning the header double-include protection defines.
> >   */
> >  #ifdef IN_GCC_FRONTEND
> >  #pragma GCC poison GCC_RTL_H GCC_EXCEPT_H GCC_EXPR_H
> >  #endif
> > 
> > Hence the patch puts the decl into a new header (run-rtl-passes.h)
> > that's accessible to the C frontend without exposing any RTL
> > internals.  (If adding a header for just this decl is overkill, is
> > there a better place to put the decl?)
> > 
> > gcc/ChangeLog:
> > 	* Makefile.in (OBJS): Add run-rtl-passes.o.
> > 	* pass_manager.h (gcc::pass_manager::get_rest_of_compilation):
> > New
> > 	accessor.
> > 	(gcc::pass_manager::get_clean_slate): New accessor.
> > 	* run-rtl-passes.c: New file.
> > 	* run-rtl-passes.h: New file.
> It feels like this is dependent upon something that I haven't seen?!?

I may have split things up a bit too much; sorry.  The code in this
patch is called by patch 9a.

>  
> Where is get_rest_of_compilation used? 

In this patch, in run-rtl-passes.c:run_rtl_passes, thusly:

+  opt_pass *rest_of_compilation
+    = g->get_passes ()->get_rest_of_compilation ();
+  gcc_assert (rest_of_compilation);
+  execute_pass_list (cfun, rest_of_compilation);


>  Where is pass_clean_state_1?

(as used in this part of the patch):

>	* pass_manager.h (gcc::pass_manager::get_rest_of_compilation):
>       New accessor.

+  opt_pass *get_clean_slate () const { return pass_clean_state_1; }

This is a new accessor method for the pass_manager class.
pass_clean_state_1 is private member data of the pass_manager, it's the
instance of class pass_clean_state.

This field of pass_manager is created by the 

  /* References to all of the individual passes.
     These fields are generated via macro expansion.

  (...etc...)

  #define NEXT_PASS(PASS, NUM) opt_pass *PASS ## _ ## NUM

  (...etc...)

  #include "pass-instances.def"

code within pass_manager.h.  This line within SRC/gcc/passes.def:

  NEXT_PASS (pass_clean_state);

becomes this line within BUILD/gcc/pass-instances.def:

  NEXT_PASS (pass_clean_state, 1);

and this means that we effectively have this field within class
pass_manager (along with dozens of others):

   opt_pass *pass_clean_state_1;

They're all private; hence the need for this accessor.

Similarly for get_rest_of_compilation.
Jeff Law Jan. 22, 2017, 7:42 a.m. UTC | #3
On 01/16/2017 04:23 PM, David Malcolm wrote:
> On Mon, 2017-01-16 at 14:54 -0700, Jeff Law wrote:
>> On 01/09/2017 07:38 PM, David Malcolm wrote:
>>> The backend is full of singleton state, so we have to compile
>>> __RTL-functions as soon as we parse them.  This means that the
>>> C frontend needs to invoke the backed.
>>>
>>> This patch adds the support needed.
>>>
>>> Normally this would be a no-no, and including rtl headers is
>>> blocked by this within system.h:
>>>
>>>  /* Front ends should never have to include middle-end headers.
>>>  Enforce
>>>     this by poisoning the header double-include protection defines.
>>>   */
>>>  #ifdef IN_GCC_FRONTEND
>>>  #pragma GCC poison GCC_RTL_H GCC_EXCEPT_H GCC_EXPR_H
>>>  #endif
>>>
>>> Hence the patch puts the decl into a new header (run-rtl-passes.h)
>>> that's accessible to the C frontend without exposing any RTL
>>> internals.  (If adding a header for just this decl is overkill, is
>>> there a better place to put the decl?)
>>>
>>> gcc/ChangeLog:
>>> 	* Makefile.in (OBJS): Add run-rtl-passes.o.
>>> 	* pass_manager.h (gcc::pass_manager::get_rest_of_compilation):
>>> New
>>> 	accessor.
>>> 	(gcc::pass_manager::get_clean_slate): New accessor.
>>> 	* run-rtl-passes.c: New file.
>>> 	* run-rtl-passes.h: New file.
>> It feels like this is dependent upon something that I haven't seen?!?
>
> I may have split things up a bit too much; sorry.  The code in this
> patch is called by patch 9a.
It happens.  It's the price we pay for asking for patches to be broken 
down into manageable hunks.   Joseph ack'd 9a and since it was just 
front-end stuff, I didn't take the time to look at it.

>
>>
>> Where is get_rest_of_compilation used?
>
> In this patch, in run-rtl-passes.c:run_rtl_passes, thusly:
Yea, I see it how.  Hidden by c++-ification :-)
>
> +  opt_pass *rest_of_compilation
> +    = g->get_passes ()->get_rest_of_compilation ();
> +  gcc_assert (rest_of_compilation);
> +  execute_pass_list (cfun, rest_of_compilation);
>
>
>>  Where is pass_clean_state_1?
>
> (as used in this part of the patch):
Nevermind.   We refer to pass_clean_state_1 and get_clean_slate.   I 
kept consistently using the wrong state/slate in my searches.  No wonder 
I was so confused.

Patch is OK.  THanks for your patience.

jeff
diff mbox

Patch

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 3d9532b..3ad53ad 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1442,6 +1442,7 @@  OBJS = \
 	rtlhash.o \
 	rtlanal.o \
 	rtlhooks.o \
+	run-rtl-passes.o \
 	sbitmap.o \
 	sched-deps.o \
 	sched-ebb.o \
diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
index 4d15407..ae97cd4 100644
--- a/gcc/pass_manager.h
+++ b/gcc/pass_manager.h
@@ -82,6 +82,12 @@  public:
 
   opt_pass *get_pass_by_name (const char *name);
 
+  opt_pass *get_rest_of_compilation () const
+  {
+    return pass_rest_of_compilation_1;
+  }
+  opt_pass *get_clean_slate () const { return pass_clean_state_1; }
+
 public:
   /* The root of the compilation pass tree, once constructed.  */
   opt_pass *all_passes;
diff --git a/gcc/run-rtl-passes.c b/gcc/run-rtl-passes.c
new file mode 100644
index 0000000..e1ac4bd
--- /dev/null
+++ b/gcc/run-rtl-passes.c
@@ -0,0 +1,66 @@ 
+/* run-rtl-passes.c - Run RTL passes directly from frontend
+   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "rtl.h"
+#include "function.h"
+#include "basic-block.h"
+#include "tree-pass.h"
+#include "context.h"
+#include "pass_manager.h"
+#include "bitmap.h"
+#include "df.h"
+#include "regs.h"
+#include "insn-attr-common.h" /* for INSN_SCHEDULING.  */
+#include "insn-attr.h" /* for init_sched_attrs.  */
+#include "run-rtl-passes.h"
+
+/* Run the backend passes, starting at the given pass.
+   Take ownership of INITIAL_PASS_NAME.  */
+
+void
+run_rtl_passes (char *initial_pass_name)
+{
+  cfun->pass_startwith = initial_pass_name;
+  max_regno = max_reg_num ();
+
+  /* Pass "expand" normally sets this up.  */
+#ifdef INSN_SCHEDULING
+  init_sched_attrs ();
+#endif
+
+  bitmap_obstack_initialize (NULL);
+  bitmap_obstack_initialize (&reg_obstack);
+
+  opt_pass *rest_of_compilation
+    = g->get_passes ()->get_rest_of_compilation ();
+  gcc_assert (rest_of_compilation);
+  execute_pass_list (cfun, rest_of_compilation);
+
+  opt_pass *clean_slate = g->get_passes ()->get_clean_slate ();
+  gcc_assert (clean_slate);
+  execute_pass_list (cfun, clean_slate);
+
+  bitmap_obstack_release (&reg_obstack);
+
+  cfun->curr_properties |= PROP_rtl;
+}
diff --git a/gcc/run-rtl-passes.h b/gcc/run-rtl-passes.h
new file mode 100644
index 0000000..1390303
--- /dev/null
+++ b/gcc/run-rtl-passes.h
@@ -0,0 +1,25 @@ 
+/* run-rtl-passes.h - Run a subset of the RTL passes
+   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_RUN_RTL_PASSES_H
+#define GCC_RUN_RTL_PASSES_H
+
+extern void run_rtl_passes (char *initial_pass_name);
+
+#endif /* GCC_RUN_RTL_PASSES_H */