diff options
Diffstat (limited to 'backend/Regalloc.ml')
-rw-r--r-- | backend/Regalloc.ml | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/backend/Regalloc.ml b/backend/Regalloc.ml index e6e07339..b91bad27 100644 --- a/backend/Regalloc.ml +++ b/backend/Regalloc.ml @@ -657,9 +657,12 @@ let add_interfs_instr g instr live = | Xstore(chunk, addr, args, src) -> add_interfs_destroyed g live (destroyed_by_store chunk addr) | Xcall(sg, vos, args, res) -> + begin match vos with + | Coq_inl v -> List.iter (fun r -> IRC.add_interf g (vmreg r) v) destroyed_at_indirect_call + | _ -> () end; add_interfs_destroyed g (vset_removelist res live) destroyed_at_call | Xtailcall(sg, Coq_inl v, args) -> - List.iter (fun r -> IRC.add_interf g (vmreg r) v) int_callee_save_regs + List.iter (fun r -> IRC.add_interf g (vmreg r) v) (int_callee_save_regs @ destroyed_at_indirect_call) | Xtailcall(sg, Coq_inr id, args) -> () | Xbuiltin(ef, args, res) -> @@ -915,7 +918,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 |