path: root/ir/be/bespilldaemel.c
diff options
authorChristoph Mallon <>2019-03-22 23:37:49 +0100
committerChristoph Mallon <>2019-03-24 08:13:29 +0100
commitf6e223b6d1711cc4e58d0248f5b22a3d5cc79fd2 (patch)
tree1d70c1a3f871ef47d08baa2280bf7ac1b8e729ea /ir/be/bespilldaemel.c
parent3569ffd30ee6608a0f8466415600c57d4c6102a7 (diff)
be: Refine modelling of additional register pressure.
Now additional pressure is applied to the register pressure either before (positive value) or after (negative value) the instruction. So far the value was applied to both the register pressure before and after the instruction. This leads to overapproximation, e.g. for cltd (in: eax, out: edx). When the input lives through then the register pressure after the instruction is 2, but +1 additional pressure unnecessarily increases it to 3. Now the additional pressure is applied to either the register pressure before or after the instruction. For cltd applying it only before the instruction is optimal, because the output can never be paired with the input. Typical symptom was overspilling around cltd+idiv. This still can overapproximate the actual register demand when in/out pairing depends on whether an input lives through. E.g. in: eax+reg, out: edx. Then 3 registers are needed when the reg input lives through. (additional pressure before 1) But only 2 registers are needed when the reg input dies. (no additional pressure) This fixes lit/overspill_cltd.c.
Diffstat (limited to 'ir/be/bespilldaemel.c')
1 files changed, 5 insertions, 2 deletions
diff --git a/ir/be/bespilldaemel.c b/ir/be/bespilldaemel.c
index 6b8b826..c872f09 100644
--- a/ir/be/bespilldaemel.c
+++ b/ir/be/bespilldaemel.c
@@ -138,12 +138,15 @@ static void do_spilling(ir_nodeset_t *live_nodes, ir_node *node)
+ /* we may need additional free registers */
+ be_add_pressure_t const add_pressure = arch_get_additional_pressure(node, cls);
+ free_regs_needed += MAX( add_pressure, 0);
+ values_defined += MAX(-add_pressure, 0);
/* we can reuse all reloaded values for the defined values, but we might
* need even more registers */
if (values_defined > free_regs_needed)
free_regs_needed = values_defined;
- /* we may need additional free registers */
- free_regs_needed += arch_get_additional_pressure(node, cls);
size_t n_live_nodes = ir_nodeset_size(live_nodes);
int spills_needed = (n_live_nodes + free_regs_needed) - n_regs;