forked from OSchip/llvm-project
Fix a bug when hoist spill to a BB with landingpad successor.
This is to fix the bug in https://llvm.org/bugs/show_bug.cgi?id=27612. When spill is hoisted to a BB with landingpad successor, and if the VNI of the spill reg lives into the landingpad successor, the spill should be inserted before the call which may throw exception. InsertPointAnalysis is used to compute the safe insert point. http://reviews.llvm.org/D20027 is a preparing patch for this patch. Differential Revision: http://reviews.llvm.org/D19884. llvm-svn: 269249
This commit is contained in:
parent
35ee9339a8
commit
8c4136b0d8
|
@ -13,6 +13,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "Spiller.h"
|
#include "Spiller.h"
|
||||||
|
#include "SplitKit.h"
|
||||||
#include "llvm/ADT/MapVector.h"
|
#include "llvm/ADT/MapVector.h"
|
||||||
#include "llvm/ADT/SetVector.h"
|
#include "llvm/ADT/SetVector.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
|
@ -69,6 +70,8 @@ class HoistSpillHelper : private LiveRangeEdit::Delegate {
|
||||||
const TargetRegisterInfo &TRI;
|
const TargetRegisterInfo &TRI;
|
||||||
const MachineBlockFrequencyInfo &MBFI;
|
const MachineBlockFrequencyInfo &MBFI;
|
||||||
|
|
||||||
|
InsertPointAnalysis IPA;
|
||||||
|
|
||||||
// Map from StackSlot to its original register.
|
// Map from StackSlot to its original register.
|
||||||
DenseMap<int, unsigned> StackSlotToReg;
|
DenseMap<int, unsigned> StackSlotToReg;
|
||||||
// Map from pair of (StackSlot and Original VNI) to a set of spills which
|
// Map from pair of (StackSlot and Original VNI) to a set of spills which
|
||||||
|
@ -114,7 +117,8 @@ public:
|
||||||
MFI(*mf.getFrameInfo()), MRI(mf.getRegInfo()),
|
MFI(*mf.getFrameInfo()), MRI(mf.getRegInfo()),
|
||||||
TII(*mf.getSubtarget().getInstrInfo()),
|
TII(*mf.getSubtarget().getInstrInfo()),
|
||||||
TRI(*mf.getSubtarget().getRegisterInfo()),
|
TRI(*mf.getSubtarget().getRegisterInfo()),
|
||||||
MBFI(pass.getAnalysis<MachineBlockFrequencyInfo>()) {}
|
MBFI(pass.getAnalysis<MachineBlockFrequencyInfo>()),
|
||||||
|
IPA(LIS, mf.getNumBlockIDs()) {}
|
||||||
|
|
||||||
void addToMergeableSpills(MachineInstr *Spill, int StackSlot,
|
void addToMergeableSpills(MachineInstr *Spill, int StackSlot,
|
||||||
unsigned Original);
|
unsigned Original);
|
||||||
|
@ -1075,7 +1079,7 @@ bool HoistSpillHelper::rmFromMergeableSpills(MachineInstr *Spill,
|
||||||
bool HoistSpillHelper::isSpillCandBB(unsigned OrigReg, VNInfo &OrigVNI,
|
bool HoistSpillHelper::isSpillCandBB(unsigned OrigReg, VNInfo &OrigVNI,
|
||||||
MachineBasicBlock &BB, unsigned &LiveReg) {
|
MachineBasicBlock &BB, unsigned &LiveReg) {
|
||||||
SlotIndex Idx;
|
SlotIndex Idx;
|
||||||
MachineBasicBlock::iterator MI = BB.getFirstTerminator();
|
MachineBasicBlock::iterator MI = IPA.getLastInsertPointIter(BB);
|
||||||
if (MI != BB.end())
|
if (MI != BB.end())
|
||||||
Idx = LIS.getInstructionIndex(*MI);
|
Idx = LIS.getInstructionIndex(*MI);
|
||||||
else
|
else
|
||||||
|
@ -1376,6 +1380,8 @@ void HoistSpillHelper::hoistAllSpills() {
|
||||||
for (auto &Ent : MergeableSpills) {
|
for (auto &Ent : MergeableSpills) {
|
||||||
int Slot = Ent.first.first;
|
int Slot = Ent.first.first;
|
||||||
unsigned OrigReg = SlotToOrigReg[Slot];
|
unsigned OrigReg = SlotToOrigReg[Slot];
|
||||||
|
LiveInterval &OrigLI = LIS.getInterval(OrigReg);
|
||||||
|
IPA.setInterval(&OrigLI);
|
||||||
VNInfo *OrigVNI = Ent.first.second;
|
VNInfo *OrigVNI = Ent.first.second;
|
||||||
SmallPtrSet<MachineInstr *, 16> &EqValSpills = Ent.second;
|
SmallPtrSet<MachineInstr *, 16> &EqValSpills = Ent.second;
|
||||||
if (Ent.second.empty())
|
if (Ent.second.empty())
|
||||||
|
@ -1408,17 +1414,15 @@ void HoistSpillHelper::hoistAllSpills() {
|
||||||
|
|
||||||
// Stack live range update.
|
// Stack live range update.
|
||||||
LiveInterval &StackIntvl = LSS.getInterval(Slot);
|
LiveInterval &StackIntvl = LSS.getInterval(Slot);
|
||||||
if (!SpillsToIns.empty() || !SpillsToRm.empty()) {
|
if (!SpillsToIns.empty() || !SpillsToRm.empty())
|
||||||
LiveInterval &OrigLI = LIS.getInterval(OrigReg);
|
|
||||||
StackIntvl.MergeValueInAsValue(OrigLI, OrigVNI,
|
StackIntvl.MergeValueInAsValue(OrigLI, OrigVNI,
|
||||||
StackIntvl.getValNumInfo(0));
|
StackIntvl.getValNumInfo(0));
|
||||||
}
|
|
||||||
|
|
||||||
// Insert hoisted spills.
|
// Insert hoisted spills.
|
||||||
for (auto const Insert : SpillsToIns) {
|
for (auto const Insert : SpillsToIns) {
|
||||||
MachineBasicBlock *BB = Insert.first;
|
MachineBasicBlock *BB = Insert.first;
|
||||||
unsigned LiveReg = Insert.second;
|
unsigned LiveReg = Insert.second;
|
||||||
MachineBasicBlock::iterator MI = BB->getFirstTerminator();
|
MachineBasicBlock::iterator MI = IPA.getLastInsertPointIter(*BB);
|
||||||
TII.storeRegToStackSlot(*BB, MI, LiveReg, false, Slot,
|
TII.storeRegToStackSlot(*BB, MI, LiveReg, false, Slot,
|
||||||
MRI.getRegClass(LiveReg), &TRI);
|
MRI.getRegClass(LiveReg), &TRI);
|
||||||
LIS.InsertMachineInstrRangeInMaps(std::prev(MI), MI);
|
LIS.InsertMachineInstrRangeInMaps(std::prev(MI), MI);
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
; RUN: llc < %s | FileCheck %s
|
||||||
|
;
|
||||||
|
; PR27612. The following spill is hoisted from two locations: the fall
|
||||||
|
; through succ block and the landingpad block of a call which may throw
|
||||||
|
; exception. If it is not hoisted before the call, the spill will be
|
||||||
|
; missing on the landingpad path.
|
||||||
|
;
|
||||||
|
; CHECK-LABEL: _Z3foov:
|
||||||
|
; CHECK: movq %rbx, (%rsp) # 8-byte Spill
|
||||||
|
; CHECK-NEXT: callq _Z3goov
|
||||||
|
|
||||||
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
|
@a = global [20 x i64] zeroinitializer, align 16
|
||||||
|
@_ZTIi = external constant i8*
|
||||||
|
|
||||||
|
; Function Attrs: uwtable
|
||||||
|
define void @_Z3foov() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
|
||||||
|
entry:
|
||||||
|
%tmp = load i64, i64* getelementptr inbounds ([20 x i64], [20 x i64]* @a, i64 0, i64 1), align 8
|
||||||
|
invoke void @_Z3goov()
|
||||||
|
to label %try.cont unwind label %lpad
|
||||||
|
|
||||||
|
lpad: ; preds = %entry
|
||||||
|
%tmp1 = landingpad { i8*, i32 }
|
||||||
|
cleanup
|
||||||
|
catch i8* bitcast (i8** @_ZTIi to i8*)
|
||||||
|
%tmp2 = extractvalue { i8*, i32 } %tmp1, 1
|
||||||
|
%tmp3 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
|
||||||
|
%matches = icmp eq i32 %tmp2, %tmp3
|
||||||
|
br i1 %matches, label %catch, label %ehcleanup
|
||||||
|
|
||||||
|
catch: ; preds = %lpad
|
||||||
|
%tmp4 = extractvalue { i8*, i32 } %tmp1, 0
|
||||||
|
%tmp5 = tail call i8* @__cxa_begin_catch(i8* %tmp4)
|
||||||
|
store i64 %tmp, i64* getelementptr inbounds ([20 x i64], [20 x i64]* @a, i64 0, i64 2), align 16
|
||||||
|
tail call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{memory},~{dirflag},~{fpsr},~{flags}"()
|
||||||
|
store i64 %tmp, i64* getelementptr inbounds ([20 x i64], [20 x i64]* @a, i64 0, i64 3), align 8
|
||||||
|
tail call void @__cxa_end_catch()
|
||||||
|
br label %try.cont
|
||||||
|
|
||||||
|
try.cont: ; preds = %catch, %entry
|
||||||
|
store i64 %tmp, i64* getelementptr inbounds ([20 x i64], [20 x i64]* @a, i64 0, i64 4), align 16
|
||||||
|
tail call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{memory},~{dirflag},~{fpsr},~{flags}"()
|
||||||
|
store i64 %tmp, i64* getelementptr inbounds ([20 x i64], [20 x i64]* @a, i64 0, i64 5), align 8
|
||||||
|
ret void
|
||||||
|
|
||||||
|
ehcleanup: ; preds = %lpad
|
||||||
|
resume { i8*, i32 } %tmp1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @_Z3goov()
|
||||||
|
|
||||||
|
declare i32 @__gxx_personality_v0(...)
|
||||||
|
|
||||||
|
; Function Attrs: nounwind readnone
|
||||||
|
declare i32 @llvm.eh.typeid.for(i8*)
|
||||||
|
|
||||||
|
declare i8* @__cxa_begin_catch(i8*)
|
||||||
|
|
||||||
|
declare void @__cxa_end_catch()
|
Loading…
Reference in New Issue