mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 08:30:47 +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;
|
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
|
// return all basic blocks that are reachable from bb, but don't pass through
|
||||||
// ebb and don't follow unwinding target
|
// ebb and don't follow unwinding target
|
||||||
void findSuccessors(std::vector<llvm::BasicBlock *> &blocks,
|
void findSuccessors(std::vector<llvm::BasicBlock *> &blocks,
|
||||||
|
@ -73,8 +61,6 @@ void remapBlocks(std::vector<llvm::BasicBlock *> &blocks,
|
||||||
llvm::Value *funclet) {
|
llvm::Value *funclet) {
|
||||||
for (llvm::BasicBlock *bb : blocks)
|
for (llvm::BasicBlock *bb : blocks)
|
||||||
for (llvm::BasicBlock::iterator I = bb->begin(); I != bb->end(); ++I) {
|
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::RemapInstruction(&*I, VMap, llvm::RF_IgnoreMissingEntries |
|
||||||
llvm::RF_NoModuleLevelChanges);
|
llvm::RF_NoModuleLevelChanges);
|
||||||
}
|
}
|
||||||
|
@ -87,8 +73,11 @@ void remapBlocksValue(std::vector<llvm::BasicBlock *> &blocks,
|
||||||
remapBlocks(blocks, VMap, nullptr, nullptr);
|
remapBlocks(blocks, VMap, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a copy of all srcblocks, mapping values to clones and redirect srcTarget
|
// make a copy of all blocks and instructions in srcblocks
|
||||||
// to continueWith
|
// - 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,
|
void cloneBlocks(const std::vector<llvm::BasicBlock *> &srcblocks,
|
||||||
std::vector<llvm::BasicBlock *> &blocks,
|
std::vector<llvm::BasicBlock *> &blocks,
|
||||||
llvm::BasicBlock *continueWith, llvm::BasicBlock *unwindTo,
|
llvm::BasicBlock *continueWith, llvm::BasicBlock *unwindTo,
|
||||||
|
@ -118,6 +107,9 @@ void cloneBlocks(const std::vector<llvm::BasicBlock *> &srcblocks,
|
||||||
CInst, llvm::OperandBundleDef("funclet", funclet));
|
CInst, llvm::OperandBundleDef("funclet", funclet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (funclet && llvm::isa<llvm::UnreachableInst>(Inst)) {
|
||||||
|
newInst = llvm::BranchInst::Create(continueWith); // cleanupret
|
||||||
|
}
|
||||||
if (!newInst)
|
if (!newInst)
|
||||||
newInst = Inst->clone();
|
newInst = Inst->clone();
|
||||||
|
|
||||||
|
|
|
@ -251,6 +251,7 @@ void ScopeStack::runCleanupCopies(CleanupCursor sourceScope,
|
||||||
|
|
||||||
llvm::BasicBlock *ScopeStack::runCleanupPad(CleanupCursor scope,
|
llvm::BasicBlock *ScopeStack::runCleanupPad(CleanupCursor scope,
|
||||||
llvm::BasicBlock *unwindTo) {
|
llvm::BasicBlock *unwindTo) {
|
||||||
|
// a catch switch never needs to be cloned and is an unwind target itself
|
||||||
if (isCatchSwitchBlock(cleanupScopes[scope].beginBlock))
|
if (isCatchSwitchBlock(cleanupScopes[scope].beginBlock))
|
||||||
return cleanupScopes[scope].beginBlock;
|
return cleanupScopes[scope].beginBlock;
|
||||||
|
|
||||||
|
@ -287,10 +288,10 @@ llvm::BasicBlock *ScopeStack::runCleanupPad(CleanupCursor scope,
|
||||||
|
|
||||||
llvm::BasicBlock *cleanupret =
|
llvm::BasicBlock *cleanupret =
|
||||||
llvm::BasicBlock::Create(irs->context(), "cleanupret", irs->topfunc());
|
llvm::BasicBlock::Create(irs->context(), "cleanupret", irs->topfunc());
|
||||||
|
|
||||||
llvm::CleanupReturnInst::Create(cleanuppad, unwindTo, cleanupret);
|
llvm::CleanupReturnInst::Create(cleanuppad, unwindTo, cleanupret);
|
||||||
|
|
||||||
auto copybb = executeCleanupCopying(irs, cleanupScopes[scope], cleanupbb,
|
auto copybb = executeCleanupCopying(irs, cleanupScopes[scope], cleanupbb,
|
||||||
cleanupret, unwindTo, cleanuppad);
|
cleanupret, unwindTo, cleanuppad);
|
||||||
llvm::BranchInst::Create(copybb, cleanupbb);
|
llvm::BranchInst::Create(copybb, cleanupbb);
|
||||||
return cleanupbb;
|
return cleanupbb;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue