blob: 95b9b2aa3da0c5b90332594b2f8cf471b9c23087 [file] [log] [blame]
Brad Bishop26bdd442019-08-16 17:08:17 -04001From 5147c831c6a78d9b95138b679bb2ca7624abc3a1 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Wed, 18 Jan 2017 11:08:40 +0530
4Subject: [PATCH 27/54] [Patch,rtl Optimization]: Better register pressure
5 estimate for loop . .invariant code motion
6
7Calculate the loop liveness used for regs for calculating the register pressure
8in the cost estimation. Loop liveness is based on the following properties.
9We only need to find the set of objects that are live at the birth or the header
10of the loop. We don't need to calculate the live through the loop by considering
11live in and live out of all the basic blocks of the loop. This is based on the
12point that the set of objects that are live-in at the birth or header of the loop
13will be live-in at every node in the loop.
14
15If a v live is out at the header of the loop then the variable is live-in at every node
16in the loop. To prove this, consider a loop L with header h such that the variable v
17defined at d is live-in at h. Since v is live at h, d is not part of L. This follows i
18from the dominance property, i.e. h is strictly dominated by d. Furthermore, there
19exists a path from h to a use of v which does not go through d. For every node p in
20the loop, since the loop is strongly connected and node is a component of the CFG,
21there exists a path, consisting only of nodes of L from p to h. Concatenating these
22two paths proves that v is live-in and live-out of p.
23
24Calculate the live-out and live-in for the exit edge of the loop. This patch considers
25liveness for not only the loop latch but also the liveness outside the loops.
26
27ChangeLog:
282016-01-22 Ajit Agarwal <ajitkum@xilinx.com>
29
30 * loop-invariant.c
31 (find_invariants_to_move): Add the logic of regs_used based
32 on liveness.
33 * cfgloopanal.c
34 (estimate_reg_pressure_cost): Update the heuristics in presence
35 of call_p.
36
37Signed-off-by:Ajit Agarwal ajitkum@xilinx.com.
38---
39 gcc/cfgloopanal.c | 4 +++-
40 gcc/loop-invariant.c | 63 +++++++++++++++++++++++++++++++++++++++-------------
41 2 files changed, 50 insertions(+), 17 deletions(-)
42
43diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
44index 3af0b2d..123dc6b 100644
45--- a/gcc/cfgloopanal.c
46+++ b/gcc/cfgloopanal.c
47@@ -411,7 +411,9 @@ estimate_reg_pressure_cost (unsigned n_new, unsigned n_old, bool speed,
48 if (regs_needed + target_res_regs <= available_regs)
49 return 0;
50
51- if (regs_needed <= available_regs)
52+ if ((regs_needed <= available_regs)
53+ || (call_p && (regs_needed <=
54+ (available_regs + target_clobbered_regs))))
55 /* If we are close to running out of registers, try to preserve
56 them. */
57 cost = target_reg_cost [speed] * n_new;
58diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
59index 8e22ca0..c9ec8df 100644
60--- a/gcc/loop-invariant.c
61+++ b/gcc/loop-invariant.c
62@@ -1520,7 +1520,7 @@ gain_for_invariant (struct invariant *inv, unsigned *regs_needed,
63 size_cost = 0;
64 }
65
66- return comp_cost - size_cost;
67+ return comp_cost - size_cost + 1;
68 }
69
70 /* Finds invariant with best gain for moving. Returns the gain, stores
71@@ -1614,22 +1614,53 @@ find_invariants_to_move (bool speed, bool call_p)
72 /* REGS_USED is actually never used when the flag is on. */
73 regs_used = 0;
74 else
75- /* We do not really do a good job in estimating number of
76- registers used; we put some initial bound here to stand for
77- induction variables etc. that we do not detect. */
78+ /* The logic used in estimating the number of regs_used is changed.
79+ Now it will be based on liveness of the loop. */
80 {
81- unsigned int n_regs = DF_REG_SIZE (df);
82-
83- regs_used = 2;
84-
85- for (i = 0; i < n_regs; i++)
86- {
87- if (!DF_REGNO_FIRST_DEF (i) && DF_REGNO_LAST_USE (i))
88- {
89- /* This is a value that is used but not changed inside loop. */
90- regs_used++;
91- }
92- }
93+ int i;
94+ edge e;
95+ vec<edge> edges;
96+ bitmap_head regs_live;
97+
98+ bitmap_initialize (&regs_live, &reg_obstack);
99+ edges = get_loop_exit_edges (curr_loop);
100+
101+ /* Loop liveness is based on the following properties.
102+ We only need to find the set of objects that are live at the
103+ birth or the header of the loop.
104+ We don't need to calculate the live through the loop considering
105+ live-in and live-out of all the basic blocks of the loop. This is
106+ based on the point that the set of objects that are live-in at the
107+ birth or header of the loop will be live-in at every block in the
108+ loop.
109+
110+ If a v live out at the header of the loop then the variable is
111+ live-in at every node in the Loop. To prove this, consider a loop
112+ L with header h such that the variable v defined at d is live-in
113+ at h. Since v is live at h, d is not part of L. This follows from
114+ the dominance property, i.e. h is strictly dominated by d. Furthermore,
115+ there exists a path from h to a use of v which does not go through d.
116+ For every node of the loop, p, since the loop is strongly connected
117+ component of the CFG, there exists a path, consisting only of nodes
118+ of L from p to h. Concatenating these two paths prove that v is
119+ live-in and live-out of p. */
120+
121+ bitmap_ior_into (&regs_live, DF_LR_IN (curr_loop->header));
122+ bitmap_ior_into (&regs_live, DF_LR_OUT (curr_loop->header));
123+
124+ /* Calculate the live-out and live-in for the exit edge of the loop.
125+ This considers liveness for not only the loop latch but also the
126+ liveness outside the loops. */
127+
128+ FOR_EACH_VEC_ELT (edges, i, e)
129+ {
130+ bitmap_ior_into (&regs_live, DF_LR_OUT (e->src));
131+ bitmap_ior_into (&regs_live, DF_LR_IN (e->dest));
132+ }
133+
134+ regs_used = bitmap_count_bits (&regs_live) + 2;
135+ bitmap_clear (&regs_live);
136+ edges.release ();
137 }
138
139 if (! flag_ira_loop_pressure)
140--
1412.7.4
142