diff mbox

[PR,target/65103,2/3] Propagate address constants into loops for i386

Message ID 20150310161154.GF27860@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Ilya Enkovich March 10, 2015, 4:11 p.m. UTC
On 10 Mar 18:00, Ilya Enkovich wrote:
> Hi,
> 
> This patch allows propagation of loop invariants for i386 if propagated value is a constant to be used in address operand.  Bootstrapped and tested on x86_64-unknown-linux-gnu.  OK for trunk or stage 1?
> 
> Thanks,
> Ilya

Updated ChangeLog and test.

Thanks
Ilya
--
gcc/

2015-03-10  Ilya Enkovich  <ilya.enkovich@intel.com>

	PR target/65103
	* target.def (try_fwprop_invariant): New.
	* doc/tm.texi.in (TARGET_TRY_FWPROP_INVARIANT): New.
	* doc/tm.texi: Regenerate.
	* fwprop.c (forward_propagate_into): Propagate loop
	invariants if a target says so.
	* hooks.h (hook_bool_rtx_bool_false): New.
	* hooks.c (hook_bool_rtx_bool_false): New.
	* config/i386/i386.c (ix86_try_fwprop_invariant): New.
	(TARGET_TRY_FWPROP_INVARIANT): New.

gcc/testsuite/

2015-03-10  Ilya Enkovich  <ilya.enkovich@intel.com>

	PR target/65103
	* gcc.target/i386/pr65103-2.c: New.
diff mbox

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 06eacd0..b3971b8 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -12977,6 +12977,16 @@  ix86_address_cost (rtx x, machine_mode, addr_space_t, bool)
 
   return cost;
 }
+
+static bool
+ix86_try_fwprop_invariant (rtx def_set, bool address_use)
+{
+  if (address_use && GET_CODE (SET_SRC (def_set)) == CONST)
+    return true;
+
+  return false;
+}
+
 
 /* Allow {LABEL | SYMBOL}_REF - SYMBOL_REF-FOR-PICBASE for Mach-O as
    this is used for to form addresses to local data when -fPIC is in
@@ -52208,6 +52218,9 @@  ix86_initialize_bounds (tree var, tree lb, tree ub, tree *stmts)
 #undef TARGET_ABSOLUTE_BIGGEST_ALIGNMENT
 #define TARGET_ABSOLUTE_BIGGEST_ALIGNMENT 512
 
+#undef TARGET_TRY_FWPROP_INVARIANT
+#define TARGET_TRY_FWPROP_INVARIANT ix86_try_fwprop_invariant
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-i386.h"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 6c5bfab..59602c4 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -6421,6 +6421,12 @@  should probably only be given to addresses with different numbers of
 registers on machines with lots of registers.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_TRY_FWPROP_INVARIANT (rtx @var{def_set}, bool @var{address_use})
+This hooks tells if it may worth to propagate loop invariant
+@var{def_set} into the loop.  @var{address_use} is 1 if values is
+used in an address operand.
+@end deftypefn
+
 @node Scheduling
 @section Adjusting the Instruction Scheduler
 
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 8d6dfbc..56e73df 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -4722,6 +4722,8 @@  Define this macro if a non-short-circuit operation produced by
 
 @hook TARGET_ADDRESS_COST
 
+@hook TARGET_TRY_FWPROP_INVARIANT
+
 @node Scheduling
 @section Adjusting the Instruction Scheduler
 
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index fc64ec9..d006200 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -1365,8 +1365,17 @@  forward_propagate_into (df_ref use)
   if (DF_REF_IS_ARTIFICIAL (def))
     return false;
 
+  def_insn = DF_REF_INSN (def);
+  if (multiple_sets (def_insn))
+    return false;
+  def_set = single_set (def_insn);
+  if (!def_set)
+    return false;
+
   /* Do not propagate loop invariant definitions inside the loop.  */
-  if (DF_REF_BB (def)->loop_father != DF_REF_BB (use)->loop_father)
+  if (DF_REF_BB (def)->loop_father != DF_REF_BB (use)->loop_father
+      && !targetm.try_fwprop_invariant (def_set,
+					DF_REF_TYPE (use) != DF_REF_REG_USE))
     return false;
 
   /* Check if the use is still present in the insn!  */
@@ -1379,13 +1388,6 @@  forward_propagate_into (df_ref use)
   if (!reg_mentioned_p (DF_REF_REG (use), parent))
     return false;
 
-  def_insn = DF_REF_INSN (def);
-  if (multiple_sets (def_insn))
-    return false;
-  def_set = single_set (def_insn);
-  if (!def_set)
-    return false;
-
   /* Only try one kind of propagation.  If two are possible, we'll
      do it on the following iterations.  */
   if (forward_propagate_and_simplify (use, def_insn, def_set)
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 824aeb0..1f32701 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -302,6 +302,12 @@  hook_bool_tree_tree_false (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
 }
 
 bool
+hook_bool_rtx_bool_false (rtx, bool)
+{
+  return false;
+}
+
+bool
 hook_bool_tree_tree_true (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
 {
   return true;
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 8c929e8..9c32489 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -59,6 +59,7 @@  extern bool hook_bool_rtx_insn_int_false (rtx_insn *, int);
 extern bool hook_bool_uintp_uintp_false (unsigned int *, unsigned int *);
 extern bool hook_bool_rtx_int_int_int_intp_bool_false (rtx, int, int, int,
 						       int *, bool);
+extern bool hook_bool_rtx_bool_false (rtx, bool);
 extern bool hook_bool_tree_tree_false (tree, tree);
 extern bool hook_bool_tree_tree_true (tree, tree);
 extern bool hook_bool_tree_bool_false (tree, bool);
diff --git a/gcc/target.def b/gcc/target.def
index a00181a..5334437 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -3465,6 +3465,16 @@  registers on machines with lots of registers.",
  int, (rtx address, machine_mode mode, addr_space_t as, bool speed),
  default_address_cost)
 
+/* Return 1 if we fwprop should consider propagating loop invariant
+   definition DEF_SET inside the loop.  ADDRESS_USE is 1 if value is
+   used in address operand.  */
+DEFHOOK
+(try_fwprop_invariant,
+ "This hooks tells if it may worth to propagate loop invariant\n\
+@var{def_set} into the loop.  @var{address_use} is 1 if values is\n\
+used in an address operand.",
+ bool, (rtx def_set, bool address_use), hook_bool_rtx_bool_false)
+
 /* Return where to allocate pseudo for a given hard register initial value.  */
 DEFHOOK
 (allocate_initial_value,
diff --git a/gcc/testsuite/gcc.target/i386/pr65103-2.c b/gcc/testsuite/gcc.target/i386/pr65103-2.c
new file mode 100644
index 0000000..b7a32f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr65103-2.c
@@ -0,0 +1,24 @@ 
+/* { dg-do compile { target ia32 } } */
+/* { dg-require-effective-target pie } */
+/* { dg-options "-O2 -fPIE" } */
+/* { dg-final { scan-assembler-not "GOTOFF," } } */
+
+typedef struct S
+{
+  int a;
+  int b;
+} S;
+struct S gs;
+
+extern int compute ( struct S * );
+
+int test( void )
+{
+    int t = -1;
+    while (t)
+      {
+	gs.a++;
+	t = compute (&gs);
+      }
+    return 0;
+}