diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 2016-08-24 11:11:29 +0200 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 2016-08-24 11:11:29 +0200 |
commit | 954b01e1ac6189f4a8b5ad1b6accf6eb01261d1f (patch) | |
tree | 15f94aa59521a6317bd8ae271bd989c531600115 | |
parent | b55d63d2917b384fa0f5da76d7d16036ad263847 (diff) | |
download | compcert-954b01e1ac6189f4a8b5ad1b6accf6eb01261d1f.tar.gz compcert-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.
-rw-r--r-- | backend/Regalloc.ml | 7 |
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 |