public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [COMMITTED 0/2][BPF] Introduce -mxbpf and first extension
@ 2020-05-19  9:55 Jose E. Marchesi
  2020-05-19  9:55 ` [COMMITTED 1/2] bpf: add support for the -mxbpf option Jose E. Marchesi
  2020-05-19  9:55 ` [COMMITTED 2/2] bpf: do not save/restore callee-saved registers in function prolog/epilog Jose E. Marchesi
  0 siblings, 2 replies; 3+ messages in thread
From: Jose E. Marchesi @ 2020-05-19  9:55 UTC (permalink / raw)
  To: gcc-patches

Hi people!

I just committed these two BPF-specific small patches.  See each
commit for a description.

Hope I didn't screw up with the ChangeLog entries in the commit
message! :)

Salud!

Jose E. Marchesi (2):
  bpf: add support for the -mxbpf option
  bpf: do not save/restore callee-saved registers in function
    prolog/epilog

 gcc/ChangeLog                                 |  15 ++
 gcc/config/bpf/bpf.c                          | 133 ++++++++++--------
 gcc/config/bpf/bpf.opt                        |   6 +
 gcc/doc/invoke.texi                           |  10 +-
 gcc/testsuite/ChangeLog                       |   5 +
 .../gcc.target/bpf/xbpf-callee-saved-regs-1.c |  17 +++
 .../gcc.target/bpf/xbpf-callee-saved-regs-2.c |  17 +++
 7 files changed, 145 insertions(+), 58 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-1.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-2.c

-- 
2.25.0.2.g232378479e


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [COMMITTED 1/2] bpf: add support for the -mxbpf option
  2020-05-19  9:55 [COMMITTED 0/2][BPF] Introduce -mxbpf and first extension Jose E. Marchesi
@ 2020-05-19  9:55 ` Jose E. Marchesi
  2020-05-19  9:55 ` [COMMITTED 2/2] bpf: do not save/restore callee-saved registers in function prolog/epilog Jose E. Marchesi
  1 sibling, 0 replies; 3+ messages in thread
From: Jose E. Marchesi @ 2020-05-19  9:55 UTC (permalink / raw)
  To: gcc-patches

This patch adds support for a new option -mxbpf.  This tells GCC to
generate code for an expanded version of BPF that relaxes some of the
restrictions imposed by BPF.

2020-05-19  Jose E. Marchesi  <jose.marchesi@oracle.com>

gcc/
	* config/bpf/bpf.opt (mxbpf): New option.
	* doc/invoke.texi (Option Summary): Add -mxbpf.
	(eBPF Options): Document -mxbbpf.
---
 gcc/ChangeLog          | 6 ++++++
 gcc/config/bpf/bpf.opt | 6 ++++++
 gcc/doc/invoke.texi    | 6 +++++-
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 418fec484ae..ef3bcee3911 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-05-19  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* config/bpf/bpf.opt (mxbpf): New option.
+	* doc/invoke.texi (Option Summary): Add -mxbpf.
+	(eBPF Options): Document -mxbbpf.
+
 2020-05-19  Uroš Bizjak  <ubizjak@gmail.com>
 
 	PR target/92658
diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
index 78b93c55575..6aa858408f1 100644
--- a/gcc/config/bpf/bpf.opt
+++ b/gcc/config/bpf/bpf.opt
@@ -108,6 +108,12 @@ Enum(bpf_kernel) String(5.1) Value(LINUX_V5_1)
 EnumValue
 Enum(bpf_kernel) String(5.2) Value(LINUX_V5_2)
 
+; Use xBPF extensions.
+
+mxbpf
+Target Report Mask(XBPF)
+Generate xBPF.
+
 ; Selecting big endian or little endian targets.
 
 mbig-endian
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 850aeac033d..0c33deb830b 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -862,7 +862,7 @@ Objective-C and Objective-C++ Dialects}.
 
 @emph{eBPF Options}
 @gccoptlist{-mbig-endian -mlittle-endian -mkernel=@var{version}
--mframe-limit=@var{bytes}}
+-mframe-limit=@var{bytes} -mxbpf}
 
 @emph{FR30 Options}
 @gccoptlist{-msmall-model  -mno-lsim}
@@ -21013,6 +21013,10 @@ Generate code for a big-endian target.
 @item -mlittle-endian
 @opindex mlittle-endian
 Generate code for a little-endian target.  This is the default.
+
+@item -mxbpf
+Generate code for an expanded version of BPF, which relaxes some of
+the restrictions imposed by the BPF architecture.
 @end table
 
 @node FR30 Options
-- 
2.25.0.2.g232378479e


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [COMMITTED 2/2] bpf: do not save/restore callee-saved registers in function prolog/epilog
  2020-05-19  9:55 [COMMITTED 0/2][BPF] Introduce -mxbpf and first extension Jose E. Marchesi
  2020-05-19  9:55 ` [COMMITTED 1/2] bpf: add support for the -mxbpf option Jose E. Marchesi
@ 2020-05-19  9:55 ` Jose E. Marchesi
  1 sibling, 0 replies; 3+ messages in thread
From: Jose E. Marchesi @ 2020-05-19  9:55 UTC (permalink / raw)
  To: gcc-patches

BPF considers that every call to a function allocates a fresh set of
registers that are available to the callee, of which the first five
may have bee initialized with the function arguments.  This is
implemented by both interpreter and JIT in the Linux kernel.

This is enforced by the kernel BPF verifier, which will reject any
code in which non-initialized registers are accessed before being
written.  Consequently, the spill instructions generated in function
prologue were causing the verifier to reject our compiled programs.

This patch makes GCC to not save/restore callee-saved registers in
function prologue/epilogue, unless xBPF mode is enabled.

2020-05-19  Jose E. Marchesi  <jose.marchesi@oracle.com>

gcc/
	* config/bpf/bpf.c (bpf_compute_frame_layout): Include space for
	callee saved registers only in xBPF.
	(bpf_expand_prologue): Save callee saved registers only in xBPF.
	(bpf_expand_epilogue): Likewise for restoring.
	* doc/invoke.texi (eBPF Options): Document this is activated by
	-mxbpf.

gcc/testsuite/
	* gcc.target/bpf/xbpf-callee-saved-regs-1.c: New test.
	* gcc.target/bpf/xbpf-callee-saved-regs-2.c: Likewise.
---
 gcc/ChangeLog                                 |   9 ++
 gcc/config/bpf/bpf.c                          | 133 ++++++++++--------
 gcc/doc/invoke.texi                           |   6 +-
 gcc/testsuite/ChangeLog                       |   5 +
 .../gcc.target/bpf/xbpf-callee-saved-regs-1.c |  17 +++
 .../gcc.target/bpf/xbpf-callee-saved-regs-2.c |  17 +++
 6 files changed, 129 insertions(+), 58 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-1.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-2.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ef3bcee3911..8447bd56d98 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2020-05-19  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* config/bpf/bpf.c (bpf_compute_frame_layout): Include space for
+	callee saved registers only in xBPF.
+	(bpf_expand_prologue): Save callee saved registers only in xBPF.
+	(bpf_expand_epilogue): Likewise for restoring.
+	* doc/invoke.texi (eBPF Options): Document this is activated by
+	-mxbpf.
+
 2020-05-19  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
 	* config/bpf/bpf.opt (mxbpf): New option.
diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c
index 368b99c199e..36e08338630 100644
--- a/gcc/config/bpf/bpf.c
+++ b/gcc/config/bpf/bpf.c
@@ -267,15 +267,18 @@ bpf_compute_frame_layout (void)
 
   cfun->machine->local_vars_size += padding_locals;
 
-  /* Set the space used in the stack by callee-saved used registers in
-     the current function.  There is no need to round up, since the
-     registers are all 8 bytes wide.  */
-  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-    if ((df_regs_ever_live_p (regno)
-	 && !call_used_or_fixed_reg_p (regno))
-	|| (cfun->calls_alloca
-	    && regno == STACK_POINTER_REGNUM))
-      cfun->machine->callee_saved_reg_size += 8;
+  if (TARGET_XBPF)
+    {
+      /* Set the space used in the stack by callee-saved used
+	 registers in the current function.  There is no need to round
+	 up, since the registers are all 8 bytes wide.  */
+      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+	if ((df_regs_ever_live_p (regno)
+	     && !call_used_or_fixed_reg_p (regno))
+	    || (cfun->calls_alloca
+		&& regno == STACK_POINTER_REGNUM))
+	  cfun->machine->callee_saved_reg_size += 8;
+    }
 
   /* Check that the total size of the frame doesn't exceed the limit
      imposed by eBPF.  */
@@ -299,38 +302,50 @@ bpf_compute_frame_layout (void)
 void
 bpf_expand_prologue (void)
 {
-  int regno, fp_offset;
   rtx insn;
   HOST_WIDE_INT size;
 
   size = (cfun->machine->local_vars_size
 	  + cfun->machine->callee_saved_reg_size);
-  fp_offset = -cfun->machine->local_vars_size;
 
-  /* Save callee-saved hard registes.  The register-save-area starts
-     right after the local variables.  */
-  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+  /* The BPF "hardware" provides a fresh new set of registers for each
+     called function, some of which are initialized to the values of
+     the arguments passed in the first five registers.  In doing so,
+     it saves the values of the registers of the caller, and restored
+     them upon returning.  Therefore, there is no need to save the
+     callee-saved registers here.  What is worse, the kernel
+     implementation refuses to run programs in which registers are
+     referred before being initialized.  */
+  if (TARGET_XBPF)
     {
-      if ((df_regs_ever_live_p (regno)
-	   && !call_used_or_fixed_reg_p (regno))
-	  || (cfun->calls_alloca
-	      && regno == STACK_POINTER_REGNUM))
-	{
-	  rtx mem;
+      int regno;
+      int fp_offset = -cfun->machine->local_vars_size;
 
-	  if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff))
-	    /* This has been already reported as an error in
-	       bpf_compute_frame_layout. */
-	    break;
-	  else
+      /* Save callee-saved hard registes.  The register-save-area
+	 starts right after the local variables.  */
+      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+	{
+	  if ((df_regs_ever_live_p (regno)
+	       && !call_used_or_fixed_reg_p (regno))
+	      || (cfun->calls_alloca
+		  && regno == STACK_POINTER_REGNUM))
 	    {
-	      mem = gen_frame_mem (DImode,
-				   plus_constant (DImode,
-						  hard_frame_pointer_rtx,
-						  fp_offset - 8));
-	      insn = emit_move_insn (mem, gen_rtx_REG (DImode, regno));
-	      RTX_FRAME_RELATED_P (insn) = 1;
-	      fp_offset -= 8;
+	      rtx mem;
+
+	      if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff))
+		/* This has been already reported as an error in
+		   bpf_compute_frame_layout. */
+		break;
+	      else
+		{
+		  mem = gen_frame_mem (DImode,
+				       plus_constant (DImode,
+						      hard_frame_pointer_rtx,
+						      fp_offset - 8));
+		  insn = emit_move_insn (mem, gen_rtx_REG (DImode, regno));
+		  RTX_FRAME_RELATED_P (insn) = 1;
+		  fp_offset -= 8;
+		}
 	    }
 	}
     }
@@ -362,34 +377,38 @@ bpf_expand_prologue (void)
 void
 bpf_expand_epilogue (void)
 {
-  int regno, fp_offset;
-  rtx insn;
-
-  fp_offset = -cfun->machine->local_vars_size;
-
-  /* Restore callee-saved hard registes from the stack.  */
-  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+  /* See note in bpf_expand_prologue for an explanation on why we are
+     not restoring callee-saved registers in BPF.  */
+  if (TARGET_XBPF)
     {
-      if ((df_regs_ever_live_p (regno)
-	   && !call_used_or_fixed_reg_p (regno))
-	  || (cfun->calls_alloca
-	      && regno == STACK_POINTER_REGNUM))
-	{
-	  rtx mem;
+      rtx insn;
+      int regno;
+      int fp_offset = -cfun->machine->local_vars_size;
 
-	  if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff))
-	    /* This has been already reported as an error in
-	       bpf_compute_frame_layout. */
-	    break;
-	  else
+      /* Restore callee-saved hard registes from the stack.  */
+      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+	{
+	  if ((df_regs_ever_live_p (regno)
+	       && !call_used_or_fixed_reg_p (regno))
+	      || (cfun->calls_alloca
+		  && regno == STACK_POINTER_REGNUM))
 	    {
-	      mem = gen_frame_mem (DImode,
-				   plus_constant (DImode,
-						  hard_frame_pointer_rtx,
-						  fp_offset - 8));
-	      insn = emit_move_insn (gen_rtx_REG (DImode, regno), mem);
-	      RTX_FRAME_RELATED_P (insn) = 1;
-	      fp_offset -= 8;
+	      rtx mem;
+
+	      if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff))
+		/* This has been already reported as an error in
+		   bpf_compute_frame_layout. */
+		break;
+	      else
+		{
+		  mem = gen_frame_mem (DImode,
+				       plus_constant (DImode,
+						      hard_frame_pointer_rtx,
+						      fp_offset - 8));
+		  insn = emit_move_insn (gen_rtx_REG (DImode, regno), mem);
+		  RTX_FRAME_RELATED_P (insn) = 1;
+		  fp_offset -= 8;
+		}
 	    }
 	}
     }
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 0c33deb830b..7217e27151d 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -21016,7 +21016,11 @@ Generate code for a little-endian target.  This is the default.
 
 @item -mxbpf
 Generate code for an expanded version of BPF, which relaxes some of
-the restrictions imposed by the BPF architecture.
+the restrictions imposed by the BPF architecture:
+@itemize @minus
+@item Save and restore callee-saved registers at function entry and
+exit, respectively.
+@end itemize
 @end table
 
 @node FR30 Options
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cbafdfc7169..1fa18f2982a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-05-19  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* gcc.target/bpf/xbpf-callee-saved-regs-1.c: New test.
+	* gcc.target/bpf/xbpf-callee-saved-regs-2.c: Likewise.
+
 2020-05-19  Uroš Bizjak  <ubizjak@gmail.com>
 
 	PR target/92658
diff --git a/gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-1.c b/gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-1.c
new file mode 100644
index 00000000000..6d6fe6e8e1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-mxbpf" } */
+
+/* GCC should save and restore callee-saved registers when generating
+   code for xBPF.  */
+
+int
+foo ()
+{
+  register int f asm ("r6");
+
+  f = 20;
+  return f + 1;
+}
+
+/* { dg-final { scan-assembler "stxdw\t\\\[%fp\\+-8\\\],%r6" } } */
+/* { dg-final { scan-assembler "ldxdw\t%r6,\\\[%fp\\+-8\\\]" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-2.c b/gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-2.c
new file mode 100644
index 00000000000..dec71cfe65d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-mno-xbpf" } */
+
+/* GCC should not save and restore callee-saved registers unless
+   generating code for xBPF.  */
+
+int
+foo ()
+{
+  register int f asm ("r6");
+
+  f = 20;
+  return f + 1;
+}
+
+/* { dg-final { scan-assembler-not "stxdw\t\\\[%fp\\+-8\\\],%r6" } } */
+/* { dg-final { scan-assembler-not "ldxdw\t%r6,\\\[%fp\\+-8\\\]" } } */
-- 
2.25.0.2.g232378479e


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-05-19  9:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-19  9:55 [COMMITTED 0/2][BPF] Introduce -mxbpf and first extension Jose E. Marchesi
2020-05-19  9:55 ` [COMMITTED 1/2] bpf: add support for the -mxbpf option Jose E. Marchesi
2020-05-19  9:55 ` [COMMITTED 2/2] bpf: do not save/restore callee-saved registers in function prolog/epilog Jose E. Marchesi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).