mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Workaround for PR1508.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37597 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e19dd87598
commit
f40708223e
@ -179,6 +179,11 @@ namespace llvm {
|
|||||||
/// anywhere in the function.
|
/// anywhere in the function.
|
||||||
std::map<const AllocaInst*, int> StaticAllocaMap;
|
std::map<const AllocaInst*, int> StaticAllocaMap;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
SmallSet<Instruction*, 8> CatchInfoLost;
|
||||||
|
SmallSet<Instruction*, 8> CatchInfoFound;
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned MakeReg(MVT::ValueType VT) {
|
unsigned MakeReg(MVT::ValueType VT) {
|
||||||
return RegMap->createVirtualRegister(TLI.getRegClassFor(VT));
|
return RegMap->createVirtualRegister(TLI.getRegClassFor(VT));
|
||||||
}
|
}
|
||||||
@ -199,6 +204,15 @@ namespace llvm {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// isFilterOrSelector - Return true if this instruction is a call to the
|
||||||
|
/// eh.filter or the eh.selector intrinsic.
|
||||||
|
static bool isFilterOrSelector(Instruction *I) {
|
||||||
|
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
|
||||||
|
return II->getIntrinsicID() == Intrinsic::eh_selector
|
||||||
|
|| II->getIntrinsicID() == Intrinsic::eh_filter;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// isUsedOutsideOfDefiningBlock - Return true if this instruction is used by
|
/// isUsedOutsideOfDefiningBlock - Return true if this instruction is used by
|
||||||
/// PHI nodes or outside of the basic block that defines it, or used by a
|
/// PHI nodes or outside of the basic block that defines it, or used by a
|
||||||
/// switch instruction, which may expand to multiple basic blocks.
|
/// switch instruction, which may expand to multiple basic blocks.
|
||||||
@ -2463,6 +2477,33 @@ static GlobalVariable *ExtractGlobalVariable (Constant *C) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// addCatchInfo - Extract the personality and type infos from an eh.selector
|
||||||
|
/// or eh.filter call, and add them to the specified machine basic block.
|
||||||
|
static void addCatchInfo(CallInst &I, MachineModuleInfo *MMI,
|
||||||
|
MachineBasicBlock *MBB) {
|
||||||
|
// Inform the MachineModuleInfo of the personality for this landing pad.
|
||||||
|
ConstantExpr *CE = cast<ConstantExpr>(I.getOperand(2));
|
||||||
|
assert(CE->getOpcode() == Instruction::BitCast &&
|
||||||
|
isa<Function>(CE->getOperand(0)) &&
|
||||||
|
"Personality should be a function");
|
||||||
|
MMI->addPersonality(MBB, cast<Function>(CE->getOperand(0)));
|
||||||
|
|
||||||
|
// Gather all the type infos for this landing pad and pass them along to
|
||||||
|
// MachineModuleInfo.
|
||||||
|
std::vector<GlobalVariable *> TyInfo;
|
||||||
|
for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) {
|
||||||
|
Constant *C = cast<Constant>(I.getOperand(i));
|
||||||
|
GlobalVariable *GV = ExtractGlobalVariable(C);
|
||||||
|
assert (GV || isa<ConstantPointerNull>(C) &&
|
||||||
|
"TypeInfo must be a global variable or NULL");
|
||||||
|
TyInfo.push_back(GV);
|
||||||
|
}
|
||||||
|
if (I.getCalledFunction()->getIntrinsicID() == Intrinsic::eh_filter)
|
||||||
|
MMI->addFilterTypeInfo(MBB, TyInfo);
|
||||||
|
else
|
||||||
|
MMI->addCatchTypeInfo(MBB, TyInfo);
|
||||||
|
}
|
||||||
|
|
||||||
/// visitIntrinsicCall - Lower the call to the specified intrinsic function. If
|
/// visitIntrinsicCall - Lower the call to the specified intrinsic function. If
|
||||||
/// we want to emit this as a call to a named external function, return the name
|
/// we want to emit this as a call to a named external function, return the name
|
||||||
/// otherwise lower it and return null.
|
/// otherwise lower it and return null.
|
||||||
@ -2597,27 +2638,12 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
|||||||
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
|
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
|
||||||
|
|
||||||
if (ExceptionHandling && MMI) {
|
if (ExceptionHandling && MMI) {
|
||||||
// Inform the MachineModuleInfo of the personality for this landing pad.
|
if (CurMBB->isLandingPad())
|
||||||
ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(2));
|
addCatchInfo(I, MMI, CurMBB);
|
||||||
assert(CE && CE->getOpcode() == Instruction::BitCast &&
|
#ifndef NDEBUG
|
||||||
isa<Function>(CE->getOperand(0)) &&
|
|
||||||
"Personality should be a function");
|
|
||||||
MMI->addPersonality(CurMBB, cast<Function>(CE->getOperand(0)));
|
|
||||||
|
|
||||||
// Gather all the type infos for this landing pad and pass them along to
|
|
||||||
// MachineModuleInfo.
|
|
||||||
std::vector<GlobalVariable *> TyInfo;
|
|
||||||
for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) {
|
|
||||||
Constant *C = cast<Constant>(I.getOperand(i));
|
|
||||||
GlobalVariable *GV = ExtractGlobalVariable(C);
|
|
||||||
assert (GV || isa<ConstantPointerNull>(C) &&
|
|
||||||
"TypeInfo must be a global variable or NULL");
|
|
||||||
TyInfo.push_back(GV);
|
|
||||||
}
|
|
||||||
if (Intrinsic == Intrinsic::eh_filter)
|
|
||||||
MMI->addFilterTypeInfo(CurMBB, TyInfo);
|
|
||||||
else
|
else
|
||||||
MMI->addCatchTypeInfo(CurMBB, TyInfo);
|
FuncInfo.CatchInfoLost.insert(&I);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Mark exception selector register as live in.
|
// Mark exception selector register as live in.
|
||||||
unsigned Reg = TLI.getExceptionSelectorRegister();
|
unsigned Reg = TLI.getExceptionSelectorRegister();
|
||||||
@ -4403,6 +4429,11 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
|
|||||||
E = MF.livein_end(); I != E; ++I)
|
E = MF.livein_end(); I != E; ++I)
|
||||||
BB->addLiveIn(I->first);
|
BB->addLiveIn(I->first);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
assert(FuncInfo.CatchInfoFound.size() == FuncInfo.CatchInfoLost.size() &&
|
||||||
|
"Not all catch info was assigned to a landing pad!");
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4513,6 +4544,20 @@ LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL,
|
|||||||
EmitFunctionEntryCode(F, SDL.DAG.getMachineFunction());
|
EmitFunctionEntryCode(F, SDL.DAG.getMachineFunction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB,
|
||||||
|
MachineModuleInfo *MMI, FunctionLoweringInfo &FLI) {
|
||||||
|
assert(!FLI.MBBMap[SrcBB]->isLandingPad() &&
|
||||||
|
"Copying catch info out of a landing pad!");
|
||||||
|
for (BasicBlock::iterator I = SrcBB->begin(), E = --SrcBB->end(); I != E; ++I)
|
||||||
|
if (isFilterOrSelector(I)) {
|
||||||
|
// Apply the catch info to DestBB.
|
||||||
|
addCatchInfo(cast<CallInst>(*I), MMI, FLI.MBBMap[DestBB]);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
FLI.CatchInfoFound.insert(I);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
|
void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
|
||||||
std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate,
|
std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate,
|
||||||
FunctionLoweringInfo &FuncInfo) {
|
FunctionLoweringInfo &FuncInfo) {
|
||||||
@ -4527,15 +4572,37 @@ void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
|
|||||||
BB = FuncInfo.MBBMap[LLVMBB];
|
BB = FuncInfo.MBBMap[LLVMBB];
|
||||||
SDL.setCurrentBasicBlock(BB);
|
SDL.setCurrentBasicBlock(BB);
|
||||||
|
|
||||||
if (ExceptionHandling && BB->isLandingPad()) {
|
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
|
||||||
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
|
|
||||||
|
|
||||||
if (MMI) {
|
if (ExceptionHandling && MMI && BB->isLandingPad()) {
|
||||||
// Add a label to mark the beginning of the landing pad. Deletion of the
|
// Add a label to mark the beginning of the landing pad. Deletion of the
|
||||||
// landing pad can thus be detected via the MachineModuleInfo.
|
// landing pad can thus be detected via the MachineModuleInfo.
|
||||||
unsigned LabelID = MMI->addLandingPad(BB);
|
unsigned LabelID = MMI->addLandingPad(BB);
|
||||||
DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
|
DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
|
||||||
DAG.getConstant(LabelID, MVT::i32)));
|
DAG.getConstant(LabelID, MVT::i32)));
|
||||||
|
|
||||||
|
// FIXME: Hack around an exception handling flaw (PR1508): the personality
|
||||||
|
// function and list of typeids logically belong to the invoke (or, if you
|
||||||
|
// like, the basic block containing the invoke), and need to be associated
|
||||||
|
// with it in the dwarf exception handling tables. Currently however the
|
||||||
|
// information is provided by intrinsics (eh.filter and eh.selector) that
|
||||||
|
// can be moved to unexpected places by the optimizers: if the unwind edge
|
||||||
|
// is critical, then breaking it can result in the intrinsics being in the
|
||||||
|
// successor of the landing pad, not the landing pad itself. This results
|
||||||
|
// in exceptions not being caught because no typeids are associated with
|
||||||
|
// the invoke. This may not be the only way things can go wrong, but it
|
||||||
|
// is the only way we try to work around for the moment.
|
||||||
|
BranchInst *Br = dyn_cast<BranchInst>(LLVMBB->getTerminator());
|
||||||
|
|
||||||
|
if (Br && Br->isUnconditional()) { // Critical edge?
|
||||||
|
BasicBlock::iterator I, E;
|
||||||
|
for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I)
|
||||||
|
if (isFilterOrSelector(I))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (I == E)
|
||||||
|
// No catch info found - try to extract some from the successor.
|
||||||
|
copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, FuncInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
; RUN: llvm-as < %s | llc -enable-eh
|
; RUN: llvm-as < %s | llc -enable-eh
|
||||||
; RUN: llvm-as < %s | llc -enable-eh -march=x86-64
|
; RUN: llvm-as < %s | llc -enable-eh -march=x86-64
|
||||||
|
; XFAIL: *
|
||||||
|
; Un-XFAIL this when PR1508 is fixed.
|
||||||
|
|
||||||
; PR1326
|
; PR1326
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
; RUN: llvm-as < %s | llc -enable-eh -asm-verbose -o - | grep {Llabel137.*Region start}
|
; RUN: llvm-as < %s | llc -enable-eh -asm-verbose -o - | \
|
||||||
|
; RUN: grep -A 3 {Llabel137.*Region start} | grep {5.*Action}
|
||||||
; PR1422
|
; PR1422
|
||||||
|
; PR1508
|
||||||
|
|
||||||
target triple = "i686-pc-linux-gnu"
|
target triple = "i686-pc-linux-gnu"
|
||||||
%struct.exception = type { i8, i8, i32, i8*, i8*, i32, i8* }
|
%struct.exception = type { i8, i8, i32, i8*, i8*, i32, i8* }
|
||||||
|
Loading…
Reference in New Issue
Block a user