This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR44281 (bad RA with global regs)


In this PR, we generate unnecessarily bad code for code that declares a global register var. Since global regs get added to fixed_regs, IRA never considers them as candidates. However, we do seem to have proper data flow information for them. In the testcase, the global reg dies, some operations are done on temporary results, and the final result stored back in the global reg. We can achieve the desired code generation by reusing the global reg for those temporaries.

Bootstrapped and tested on x86_64-linux. Ok? An argument could be made not to use this for gcc-6 since global register vars are both not very important and not very well represented in the testsuite.


Bernd
	PR rtl-optimization/44281
	* hard-reg-set.h (struct target_hard_regs): New field
	x_fixed_nonglobal_reg_set.
	(fixed_nonglobal_reg_set): New macro.
	* reginfo.c (init_reg_sets_1): Initialize it.
	* ira.c (setup_alloc_regs): Use fixed_nonglobal_reg_set instead
	of fixed_reg_set.

	PR rtl-optimization/44281
	* gcc.target/i386/pr44281.c: New test.

Index: gcc/hard-reg-set.h
===================================================================
--- gcc/hard-reg-set.h	(revision 233451)
+++ gcc/hard-reg-set.h	(working copy)
@@ -660,6 +660,12 @@ struct target_hard_regs {
      across calls even if we are willing to save and restore them.  */
   HARD_REG_SET x_call_fixed_reg_set;
 
+  /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- but
+     only if they are not merely part of that set because they are global
+     regs.  Global regs that are not otherwise fixed can still take part
+     in register allocation.  */
+  HARD_REG_SET x_fixed_nonglobal_reg_set;
+
   /* Contains 1 for registers that are set or clobbered by calls.  */
   /* ??? Ideally, this would be just call_used_regs plus global_regs, but
      for someone's bright idea to have call_used_regs strictly include
@@ -722,6 +728,8 @@ extern struct target_hard_regs *this_tar
   (this_target_hard_regs->x_fixed_regs)
 #define fixed_reg_set \
   (this_target_hard_regs->x_fixed_reg_set)
+#define fixed_nonglobal_reg_set \
+  (this_target_hard_regs->x_fixed_nonglobal_reg_set)
 #define call_used_regs \
   (this_target_hard_regs->x_call_used_regs)
 #define call_really_used_regs \
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	(revision 233451)
+++ gcc/ira.c	(working copy)
@@ -512,7 +512,7 @@ setup_alloc_regs (bool use_hard_frame_p)
 #ifdef ADJUST_REG_ALLOC_ORDER
   ADJUST_REG_ALLOC_ORDER;
 #endif
-  COPY_HARD_REG_SET (no_unit_alloc_regs, fixed_reg_set);
+  COPY_HARD_REG_SET (no_unit_alloc_regs, fixed_nonglobal_reg_set);
   if (! use_hard_frame_p)
     SET_HARD_REG_BIT (no_unit_alloc_regs, HARD_FRAME_POINTER_REGNUM);
   setup_class_hard_regs ();
Index: gcc/reginfo.c
===================================================================
--- gcc/reginfo.c	(revision 233451)
+++ gcc/reginfo.c	(working copy)
@@ -449,6 +449,7 @@ init_reg_sets_1 (void)
     }
 
   COPY_HARD_REG_SET (call_fixed_reg_set, fixed_reg_set);
+  COPY_HARD_REG_SET (fixed_nonglobal_reg_set, fixed_reg_set);
 
   /* Preserve global registers if called more than once.  */
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
Index: gcc/testsuite/gcc.target/i386/pr44281.c
===================================================================
--- gcc/testsuite/gcc.target/i386/pr44281.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr44281.c	(working copy)
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-std=gnu99 -O2" } */
+/* { dg-final { scan-assembler "salq\[ \\t\]+\\\$8, %rbx" } } */
+
+#include <stdint.h>
+
+register uint64_t global_flag_stack __asm__("rbx");
+
+void push_flag_into_global_reg_var(uint64_t a, uint64_t b) {
+  uint64_t flag = (a==b);
+  global_flag_stack <<= 8;
+  global_flag_stack  |= flag;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]