Re: [PATCH 5/6] ira: Consider modelling caller-save allocations as loop spills

2022-01-11 Thread Richard Sandiford via Gcc-patches
Robin Dapp  writes:
>> Could you try the attached?
>
> The series with the patch is OK from a testsuite point of view.  The
> other problem appears later.

OK, thanks for checking.  I've pushed the patch as obvious.

Richard


Re: [PATCH 5/6] ira: Consider modelling caller-save allocations as loop spills

2022-01-11 Thread Robin Dapp via Gcc-patches
> Could you try the attached?

The series with the patch is OK from a testsuite point of view.  The
other problem appears later.

Regards
 Robin


Re: [PATCH 5/6] ira: Consider modelling caller-save allocations as loop spills

2022-01-11 Thread Martin Liška

On 1/11/22 09:52, Richard Sandiford via Gcc-patches wrote:

Robin Dapp  writes:

Hi Richard,

this causes a bootstrap error on s390 (where
IRA_HARD_REGNO_ADD_COST_MULTIPLIER is defined). rclass is used in the
#define-guarded area.


Gah, sorry about that.


I guess you also wanted to move this to the new function
ira_caller_save_cost?


No, the IRA_HARD_REGNO_ADD_COST_MULTIPLIER heuristic is a separate thing.
It's just that I had to remove the rclass variable to allow bootstrap on
other targets.

Could you try the attached?


Hello.

I noticed the same failure. Please push the patch.

Thanks,
Martin



Thanks,
Richard






Re: [PATCH 5/6] ira: Consider modelling caller-save allocations as loop spills

2022-01-11 Thread Robin Dapp via Gcc-patches
Hi Richard,

> Could you try the attached?

build and bootstrap look OK with it.  Testsuite shows lots of fallout
but the proper bisect isn't finished yet.  The commit before your series
is still fine - the problem could also be after it, though.  Will report
back later.

Thanks
 Robin


Re: [PATCH 5/6] ira: Consider modelling caller-save allocations as loop spills

2022-01-11 Thread Richard Sandiford via Gcc-patches
Robin Dapp  writes:
> Hi Richard,
>
> this causes a bootstrap error on s390 (where
> IRA_HARD_REGNO_ADD_COST_MULTIPLIER is defined). rclass is used in the
> #define-guarded area.

Gah, sorry about that.

> I guess you also wanted to move this to the new function
> ira_caller_save_cost?

No, the IRA_HARD_REGNO_ADD_COST_MULTIPLIER heuristic is a separate thing.
It's just that I had to remove the rclass variable to allow bootstrap on
other targets.

Could you try the attached?

Thanks,
Richard


>From 74cca9d27da840dbb79aa9ed9edc6f529945d477 Mon Sep 17 00:00:00 2001
From: Richard Sandiford 
Date: Tue, 11 Jan 2022 08:44:56 +
Subject: [PATCH] ira: Fix s390 build

My g:01f3e6a40e7202310abbeb41c345d325bd69554f broke the s390
build because the rclass variable was still needed by the
IRA_HARD_REGNO_ADD_COST_MULTIPLIER code.

gcc/
	* ira-costs.c (ira_tune_allocno_costs): Fix missing rclass
	definition in IRA_HARD_REGNO_ADD_COST_MULTIPLIER code.
---
 gcc/ira-costs.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index cbb58d32be8..1e4cf5a35e4 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -2351,10 +2351,13 @@ ira_tune_allocno_costs (void)
 	  if (ira_need_caller_save_p (a, regno))
 		cost += ira_caller_save_cost (a);
 #ifdef IRA_HARD_REGNO_ADD_COST_MULTIPLIER
-	  cost += ((ira_memory_move_cost[mode][rclass][0]
-			+ ira_memory_move_cost[mode][rclass][1])
-		   * ALLOCNO_FREQ (a)
-		   * IRA_HARD_REGNO_ADD_COST_MULTIPLIER (regno) / 2);
+	  {
+		auto rclass = REGNO_REG_CLASS (regno);
+		cost += ((ira_memory_move_cost[mode][rclass][0]
+			  + ira_memory_move_cost[mode][rclass][1])
+			 * ALLOCNO_FREQ (a)
+			 * IRA_HARD_REGNO_ADD_COST_MULTIPLIER (regno) / 2);
+	  }
 #endif
 	  if (INT_MAX - cost < reg_costs[j])
 		reg_costs[j] = INT_MAX;
-- 
2.25.1



Re: [PATCH 5/6] ira: Consider modelling caller-save allocations as loop spills

2022-01-11 Thread Robin Dapp via Gcc-patches
Hi Richard,

this causes a bootstrap error on s390 (where
IRA_HARD_REGNO_ADD_COST_MULTIPLIER is defined). rclass is used in the
#define-guarded area.  I guess you also wanted to move this to the new
function ira_caller_save_cost?

Regards
 Robin

--

../../gcc/ira-costs.c: In function ‘void ira_tune_allocno_costs()’:
../../gcc/ira-costs.c:2354:45: error: ‘rclass’ was not declared in this
scope; did you mean ‘aclass’?
 2354 |cost += ((ira_memory_move_cost[mode][rclass][0]
  | ^~
  | aclass


Re: [PATCH 5/6] ira: Consider modelling caller-save allocations as loop spills

2022-01-10 Thread Hans-Peter Nilsson via Gcc-patches
> From: Richard Sandiford via Gcc-patches 
> Date: Thu, 6 Jan 2022 15:48:01 +0100

> If an allocno A in an inner loop L spans a call, a parent allocno AP
> can choose to handle a call-clobbered/caller-saved hard register R
> in one of two ways:
> 
> (1) save R before each call in L and restore R after each call
> (2) spill R to memory throughout L
> 
> (2) can be cheaper than (1) in some cases, particularly if L does
> not reference A.
> 
> Before the patch we always did (1).  The patch adds support for
> picking (2) instead, when it seems cheaper.  It builds on the
> earlier support for not propagating conflicts to parent allocnos.
> 
> gcc/
>   PR rtl-optimization/98782
>   * ira-int.h (ira_caller_save_cost): New function.
>   (ira_caller_save_loop_spill_p): Likewise.
>   * ira-build.c (ira_propagate_hard_reg_costs): Test whether it is
>   cheaper to spill a call-clobbered register throughout a loop rather
>   than spill it around each individual call.  If so, treat all
>   call-clobbered registers as conflicts and...
>   (propagate_allocno_info): ...do not propagate call information
>   from the child to the parent.
>   * ira-color.c (move_spill_restore): Update accordingly.
>   * ira-costs.c (ira_tune_allocno_costs): Use ira_caller_save_cost.

I bisected a broken build for cris-elf to this patch.
Details in https://gcc.gnu.org/PR103974 supposedly
sufficient to find a quick resolution.

(JFTR, as you're already CC:ed by your @gcc.gnu.org account.)

Perhaps some of these patches are better postponed for stage 1?

brgds, H-P


Re: [PATCH 5/6] ira: Consider modelling caller-save allocations as loop spills

2022-01-10 Thread Vladimir Makarov via Gcc-patches



On 2022-01-06 09:48, Richard Sandiford wrote:

If an allocno A in an inner loop L spans a call, a parent allocno AP
can choose to handle a call-clobbered/caller-saved hard register R
in one of two ways:

(1) save R before each call in L and restore R after each call
(2) spill R to memory throughout L

(2) can be cheaper than (1) in some cases, particularly if L does
not reference A.

Before the patch we always did (1).  The patch adds support for
picking (2) instead, when it seems cheaper.  It builds on the
earlier support for not propagating conflicts to parent allocnos.
Another cost calculation improvement for calls would be taking into 
account that allocno can be saved and restored once for several 
subsequent calls (e.g. in one BB).

gcc/
PR rtl-optimization/98782
* ira-int.h (ira_caller_save_cost): New function.
(ira_caller_save_loop_spill_p): Likewise.
* ira-build.c (ira_propagate_hard_reg_costs): Test whether it is
cheaper to spill a call-clobbered register throughout a loop rather
than spill it around each individual call.  If so, treat all
call-clobbered registers as conflicts and...
(propagate_allocno_info): ...do not propagate call information
from the child to the parent.
* ira-color.c (move_spill_restore): Update accordingly.
* ira-costs.c (ira_tune_allocno_costs): Use ira_caller_save_cost.

gcc/testsuite/
* gcc.target/aarch64/reg-alloc-3.c: New test.

OK for me.  Thank you for the patch.



[PATCH 5/6] ira: Consider modelling caller-save allocations as loop spills

2022-01-06 Thread Richard Sandiford via Gcc-patches
If an allocno A in an inner loop L spans a call, a parent allocno AP
can choose to handle a call-clobbered/caller-saved hard register R
in one of two ways:

(1) save R before each call in L and restore R after each call
(2) spill R to memory throughout L

(2) can be cheaper than (1) in some cases, particularly if L does
not reference A.

Before the patch we always did (1).  The patch adds support for
picking (2) instead, when it seems cheaper.  It builds on the
earlier support for not propagating conflicts to parent allocnos.

gcc/
PR rtl-optimization/98782
* ira-int.h (ira_caller_save_cost): New function.
(ira_caller_save_loop_spill_p): Likewise.
* ira-build.c (ira_propagate_hard_reg_costs): Test whether it is
cheaper to spill a call-clobbered register throughout a loop rather
than spill it around each individual call.  If so, treat all
call-clobbered registers as conflicts and...
(propagate_allocno_info): ...do not propagate call information
from the child to the parent.
* ira-color.c (move_spill_restore): Update accordingly.
* ira-costs.c (ira_tune_allocno_costs): Use ira_caller_save_cost.

gcc/testsuite/
* gcc.target/aarch64/reg-alloc-3.c: New test.
---
 gcc/ira-build.c   | 23 ---
 gcc/ira-color.c   | 13 ++--
 gcc/ira-costs.c   |  7 +-
 gcc/ira-int.h | 39 +++
 .../gcc.target/aarch64/reg-alloc-3.c  | 65 +++
 5 files changed, 129 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/reg-alloc-3.c

diff --git a/gcc/ira-build.c b/gcc/ira-build.c
index 875b4d8ed7c..ab3e87164e1 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -2000,6 +2000,8 @@ ira_propagate_hard_reg_costs (ira_allocno_t parent_a, 
ira_allocno_t a,
  int spill_cost)
 {
   HARD_REG_SET conflicts = ira_total_conflict_hard_regs (a);
+  if (ira_caller_save_loop_spill_p (parent_a, a, spill_cost))
+conflicts |= ira_need_caller_save_regs (a);
   conflicts &= ~ira_total_conflict_hard_regs (parent_a);
 
   auto costs = ALLOCNO_HARD_REG_COSTS (a);
@@ -2069,15 +2071,18 @@ propagate_allocno_info (void)
  if (!ira_subloop_allocnos_can_differ_p (parent_a))
merge_hard_reg_conflicts (a, parent_a, true);
 
- ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a);
- ALLOCNO_CALLS_CROSSED_NUM (parent_a)
-   += ALLOCNO_CALLS_CROSSED_NUM (a);
- ALLOCNO_CHEAP_CALLS_CROSSED_NUM (parent_a)
-   += ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a);
- ALLOCNO_CROSSED_CALLS_ABIS (parent_a)
-   |= ALLOCNO_CROSSED_CALLS_ABIS (a);
- ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a)
-   |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a);
+ if (!ira_caller_save_loop_spill_p (parent_a, a, spill_cost))
+   {
+ ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a);
+ ALLOCNO_CALLS_CROSSED_NUM (parent_a)
+   += ALLOCNO_CALLS_CROSSED_NUM (a);
+ ALLOCNO_CHEAP_CALLS_CROSSED_NUM (parent_a)
+   += ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a);
+ ALLOCNO_CROSSED_CALLS_ABIS (parent_a)
+   |= ALLOCNO_CROSSED_CALLS_ABIS (a);
+ ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a)
+   |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a);
+   }
  ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
+= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
  aclass = ALLOCNO_CLASS (a);
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index 4344ee6689e..1487afc5ef1 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -3597,11 +3597,16 @@ move_spill_restore (void)
 propagate_allocno_info will have propagated
 the cost of spilling HARD_REGNO in SUBLOOP_NODE.
 (ira_subloop_allocnos_can_differ_p must be true
-in that case.)  Otherwise, SPILL_COST acted as
-a cap on the propagated register cost, in cases
-where the allocations can differ.  */
+in that case.)  If HARD_REGNO is a caller-saved
+register, we might have modelled it in the same way.
+
+Otherwise, SPILL_COST acted as a cap on the propagated
+register cost, in cases where the allocations can differ.  */
  auto conflicts = ira_total_conflict_hard_regs (subloop_allocno);
- if (TEST_HARD_REG_BIT (conflicts, hard_regno))
+ if (TEST_HARD_REG_BIT (conflicts, hard_regno)
+ || (ira_need_caller_save_p (subloop_allocno, hard_regno)
+ && ira_caller_save_loop_spill_p (a, subloop_allocno,
+  spill_cost)))
reg_cost = spill_cost;
  else if (ira_subloop_allocno