mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
[INLINER] allow inlining of address taken blocks
as long as their uses does not contain calls to functions that capture the argument (potentially allowing the blockaddress to "escape" the lifetime of the caller). TODO: - add more tests - fix crash in llvm::updateCGAndAnalysisManagerForFunctionPass when invoking Transforms/Inline/blockaddress.ll llvm-svn: 354079
This commit is contained in:
parent
c377496092
commit
995c559f1d
@ -390,6 +390,11 @@ public:
|
||||
/// direct branches, switches, etc. to it.
|
||||
bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; }
|
||||
|
||||
/// Returns true if there are any uses of the address of this basic block
|
||||
/// that are call instructions (which may allow the address of this basic
|
||||
/// block to escape).
|
||||
bool addressPotentiallyEscapesFunction();
|
||||
|
||||
/// Update all phi nodes in this basic block's successors to refer to basic
|
||||
/// block \p New instead of to it.
|
||||
void replaceSuccessorsPhiUsesWith(BasicBlock *New);
|
||||
|
@ -1832,7 +1832,7 @@ InlineResult CallAnalyzer::analyzeCall(CallSite CS) {
|
||||
// see an indirect branch that ends up being dead code at a particular call
|
||||
// site. If the blockaddress escapes the function, e.g., via a global
|
||||
// variable, inlining may lead to an invalid cross-function reference.
|
||||
if (BB->hasAddressTaken())
|
||||
if (BB->hasAddressTaken() && BB->addressPotentiallyEscapesFunction())
|
||||
return "blockaddress";
|
||||
|
||||
// Analyze the cost of this block. If we blow through the threshold, this
|
||||
@ -2082,7 +2082,7 @@ InlineResult llvm::isInlineViable(Function &F) {
|
||||
if (isa<IndirectBrInst>(BI->getTerminator()))
|
||||
return "contains indirect branches";
|
||||
|
||||
if (BI->hasAddressTaken())
|
||||
if (BI->hasAddressTaken() && BI->addressPotentiallyEscapesFunction())
|
||||
return "uses block address";
|
||||
|
||||
for (auto &II : *BI) {
|
||||
|
@ -442,6 +442,14 @@ BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName) {
|
||||
return New;
|
||||
}
|
||||
|
||||
bool BasicBlock::addressPotentiallyEscapesFunction() {
|
||||
for (const Use& U : BlockAddress::get(this)->uses())
|
||||
if (const CallInst* CI = dyn_cast<CallInst>(U))
|
||||
if (!CI->paramHasAttr(U.getOperandNo(), Attribute::NoCapture))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) {
|
||||
Instruction *TI = getTerminator();
|
||||
if (!TI)
|
||||
|
Loading…
Reference in New Issue
Block a user