mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 19:06:02 +03:00
inside a cleanup block, convert "unreachable" to a branch to "cleanupret"
This commit is contained in:
parent
5dabf78c7b
commit
73ab5f4fee
2 changed files with 11 additions and 18 deletions
|
@ -30,18 +30,6 @@ llvm::BasicBlock *getUnwindDest(llvm::Instruction *I) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void mapFunclet(llvm::Instruction *I, llvm::ValueToValueMapTy &VMap, llvm::Value *funclet) {
|
||||
if (auto II = llvm::dyn_cast<llvm::InvokeInst> (I)) {
|
||||
auto bundle = II->getOperandBundle(llvm::LLVMContext::OB_funclet);
|
||||
if (bundle)
|
||||
VMap[bundle->Inputs[0].get()] = funclet;
|
||||
} else if (auto CI = llvm::dyn_cast<llvm::CallInst> (I)) {
|
||||
auto bundle = CI->getOperandBundle(llvm::LLVMContext::OB_funclet);
|
||||
if (bundle)
|
||||
VMap[bundle->Inputs[0].get()] = funclet;
|
||||
}
|
||||
}
|
||||
|
||||
// return all basic blocks that are reachable from bb, but don't pass through
|
||||
// ebb and don't follow unwinding target
|
||||
void findSuccessors(std::vector<llvm::BasicBlock *> &blocks,
|
||||
|
@ -73,8 +61,6 @@ void remapBlocks(std::vector<llvm::BasicBlock *> &blocks,
|
|||
llvm::Value *funclet) {
|
||||
for (llvm::BasicBlock *bb : blocks)
|
||||
for (llvm::BasicBlock::iterator I = bb->begin(); I != bb->end(); ++I) {
|
||||
//if (funclet)
|
||||
// mapFunclet(&*I, VMap, funclet);
|
||||
llvm::RemapInstruction(&*I, VMap, llvm::RF_IgnoreMissingEntries |
|
||||
llvm::RF_NoModuleLevelChanges);
|
||||
}
|
||||
|
@ -87,8 +73,11 @@ void remapBlocksValue(std::vector<llvm::BasicBlock *> &blocks,
|
|||
remapBlocks(blocks, VMap, nullptr, nullptr);
|
||||
}
|
||||
|
||||
// make a copy of all srcblocks, mapping values to clones and redirect srcTarget
|
||||
// to continueWith
|
||||
// make a copy of all blocks and instructions in srcblocks
|
||||
// - map values to clones
|
||||
// - redirect srcTarget to continueWith
|
||||
// - set "funclet" attribute inside catch/cleanup pads
|
||||
// - inside funclets, replace "unreachable" with "branch cleanupret"
|
||||
void cloneBlocks(const std::vector<llvm::BasicBlock *> &srcblocks,
|
||||
std::vector<llvm::BasicBlock *> &blocks,
|
||||
llvm::BasicBlock *continueWith, llvm::BasicBlock *unwindTo,
|
||||
|
@ -118,6 +107,9 @@ void cloneBlocks(const std::vector<llvm::BasicBlock *> &srcblocks,
|
|||
CInst, llvm::OperandBundleDef("funclet", funclet));
|
||||
}
|
||||
}
|
||||
if (funclet && llvm::isa<llvm::UnreachableInst>(Inst)) {
|
||||
newInst = llvm::BranchInst::Create(continueWith); // cleanupret
|
||||
}
|
||||
if (!newInst)
|
||||
newInst = Inst->clone();
|
||||
|
||||
|
|
|
@ -251,6 +251,7 @@ void ScopeStack::runCleanupCopies(CleanupCursor sourceScope,
|
|||
|
||||
llvm::BasicBlock *ScopeStack::runCleanupPad(CleanupCursor scope,
|
||||
llvm::BasicBlock *unwindTo) {
|
||||
// a catch switch never needs to be cloned and is an unwind target itself
|
||||
if (isCatchSwitchBlock(cleanupScopes[scope].beginBlock))
|
||||
return cleanupScopes[scope].beginBlock;
|
||||
|
||||
|
@ -287,8 +288,8 @@ llvm::BasicBlock *ScopeStack::runCleanupPad(CleanupCursor scope,
|
|||
|
||||
llvm::BasicBlock *cleanupret =
|
||||
llvm::BasicBlock::Create(irs->context(), "cleanupret", irs->topfunc());
|
||||
|
||||
llvm::CleanupReturnInst::Create(cleanuppad, unwindTo, cleanupret);
|
||||
|
||||
auto copybb = executeCleanupCopying(irs, cleanupScopes[scope], cleanupbb,
|
||||
cleanupret, unwindTo, cleanuppad);
|
||||
llvm::BranchInst::Create(copybb, cleanupbb);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue