Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Transforms/Utils/InlineFunction.cpp
Show First 20 Lines • Show All 1,638 Lines • ▼ Show 20 Lines | llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, | ||||
Function *CalledFunc = CB.getCalledFunction(); | Function *CalledFunc = CB.getCalledFunction(); | ||||
if (!CalledFunc || // Can't inline external function or indirect | if (!CalledFunc || // Can't inline external function or indirect | ||||
CalledFunc->isDeclaration()) // call! | CalledFunc->isDeclaration()) // call! | ||||
return InlineResult::failure("external or indirect"); | return InlineResult::failure("external or indirect"); | ||||
// The inliner does not know how to inline through calls with operand bundles | // The inliner does not know how to inline through calls with operand bundles | ||||
// in general ... | // in general ... | ||||
Value *convergenceControlToken = nullptr; | |||||
if (CB.hasOperandBundles()) { | if (CB.hasOperandBundles()) { | ||||
for (int i = 0, e = CB.getNumOperandBundles(); i != e; ++i) { | for (int i = 0, e = CB.getNumOperandBundles(); i != e; ++i) { | ||||
uint32_t Tag = CB.getOperandBundleAt(i).getTagID(); | OperandBundleUse OBU = CB.getOperandBundleAt(i); | ||||
// ... but it knows how to inline through "deopt" operand bundles ... | uint32_t Tag = OBU.getTagID(); | ||||
if (Tag == LLVMContext::OB_deopt) | // ... but it knows how to inline through some operand bundles. | ||||
if (Tag == LLVMContext::OB_deopt || Tag == LLVMContext::OB_funclet) | |||||
continue; | continue; | ||||
// ... and "funclet" operand bundles. | |||||
if (Tag == LLVMContext::OB_funclet) | if (Tag == LLVMContext::OB_convergencectrl) { | ||||
convergenceControlToken = OBU.Inputs[0].get(); | |||||
continue; | continue; | ||||
} | |||||
return InlineResult::failure("unsupported operand bundle"); | return InlineResult::failure("unsupported operand bundle"); | ||||
} | } | ||||
} | } | ||||
// If the call to the callee cannot throw, set the 'nounwind' flag on any | // If the call to the callee cannot throw, set the 'nounwind' flag on any | ||||
// calls that we inline. | // calls that we inline. | ||||
bool MarkNoUnwind = CB.doesNotThrow(); | bool MarkNoUnwind = CB.doesNotThrow(); | ||||
▲ Show 20 Lines • Show All 240 Lines • ▼ Show 20 Lines | if (IFI.GetAssumptionCache) | ||||
make_range(FirstNewBlock->getIterator(), Caller->end())) | make_range(FirstNewBlock->getIterator(), Caller->end())) | ||||
for (Instruction &I : NewBlock) | for (Instruction &I : NewBlock) | ||||
if (auto *II = dyn_cast<IntrinsicInst>(&I)) | if (auto *II = dyn_cast<IntrinsicInst>(&I)) | ||||
if (II->getIntrinsicID() == Intrinsic::assume) | if (II->getIntrinsicID() == Intrinsic::assume) | ||||
IFI.GetAssumptionCache(*Caller).registerAssumption(II); | IFI.GetAssumptionCache(*Caller).registerAssumption(II); | ||||
} | } | ||||
// If there are any alloca instructions in the block that used to be the entry | // If there are any alloca instructions in the block that used to be the entry | ||||
// block for the callee, move them to the entry block of the caller. First | // block for the callee, move them to the entry block of the caller. | ||||
// calculate which instruction they should be inserted before. We insert the | // | ||||
// instructions at the end of the current alloca list. | // Also handle convergence control entry intrinsics. | ||||
{ | { | ||||
BasicBlock::iterator InsertPoint = Caller->begin()->begin(); | BasicBlock::iterator InsertPoint = Caller->begin()->begin(); | ||||
for (BasicBlock::iterator I = FirstNewBlock->begin(), | for (BasicBlock::iterator I = FirstNewBlock->begin(), | ||||
E = FirstNewBlock->end(); I != E; ) { | E = FirstNewBlock->end(); I != E; ) { | ||||
if (auto *intrinsic = dyn_cast<IntrinsicInst>(I)) { | |||||
++I; | |||||
if (convergenceControlToken && | |||||
intrinsic->getIntrinsicID() == | |||||
Intrinsic::experimental_convergence_entry) { | |||||
intrinsic->replaceAllUsesWith(convergenceControlToken); | |||||
intrinsic->eraseFromParent(); | |||||
} | |||||
continue; | |||||
} | |||||
AllocaInst *AI = dyn_cast<AllocaInst>(I++); | AllocaInst *AI = dyn_cast<AllocaInst>(I++); | ||||
if (!AI) continue; | if (!AI) continue; | ||||
// If the alloca is now dead, remove it. This often occurs due to code | // If the alloca is now dead, remove it. This often occurs due to code | ||||
// specialization. | // specialization. | ||||
if (AI->use_empty()) { | if (AI->use_empty()) { | ||||
AI->eraseFromParent(); | AI->eraseFromParent(); | ||||
continue; | continue; | ||||
▲ Show 20 Lines • Show All 573 Lines • Show Last 20 Lines |