aboutsummaryrefslogtreecommitdiffstats
path: root/backend/Regalloc.ml
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2016-08-24 11:11:29 +0200
committerXavier Leroy <xavier.leroy@inria.fr>2016-08-24 11:11:29 +0200
commit954b01e1ac6189f4a8b5ad1b6accf6eb01261d1f (patch)
tree15f94aa59521a6317bd8ae271bd989c531600115 /backend/Regalloc.ml
parentb55d63d2917b384fa0f5da76d7d16036ad263847 (diff)
downloadcompcert-kvx-954b01e1ac6189f4a8b5ad1b6accf6eb01261d1f.tar.gz
compcert-kvx-954b01e1ac6189f4a8b5ad1b6accf6eb01261d1f.zip
PR#113, PR#122: Unspillable temporaries causing register allocation to fail
The spilling strategy for 2-address operations was strange in the case where the first argument needs spilling but not (yet) the result: a Xreload instruction was generated which prevented future spilling of the result. Fixed by generating Xmove instead of Xreload in this case.
Diffstat (limited to 'backend/Regalloc.ml')
-rw-r--r--backend/Regalloc.ml7
1 files changed, 6 insertions, 1 deletions
diff --git a/backend/Regalloc.ml b/backend/Regalloc.ml
index e6e07339..0013d91a 100644
--- a/backend/Regalloc.ml
+++ b/backend/Regalloc.ml
@@ -915,7 +915,12 @@ let spill_instr tospill eqs instr =
| false, true ->
let eqs1 = add arg1 res (kill res eqs) in
let (argl', c1, eqs2) = reload_vars tospill eqs1 argl in
- (Xreload(arg1, res) :: c1 @ [Xop(op, res :: argl', res)],
+ (* PR#113, PR#122: [Xreload] here causes [res] to become
+ unspillable in the future. This is too strong, hence
+ the [Xmove]. Alternatively, this [false, true]
+ case could be removed and the [true, true] case
+ below used instead. *)
+ (Xmove(arg1, res) :: c1 @ [Xop(op, res :: argl', res)],
kill res eqs2)
| true, true ->
let tmp = new_temp (typeof res) in