[llvm] r354079 - [INLINER] allow inlining of address taken blocks

Nick Desaulniers via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 14 15:35:53 PST 2019


Author: nickdesaulniers
Date: Thu Feb 14 15:35:53 2019
New Revision: 354079

URL: http://llvm.org/viewvc/llvm-project?rev=354079&view=rev
Log:
[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

Modified:
    llvm/trunk/include/llvm/IR/BasicBlock.h
    llvm/trunk/lib/Analysis/InlineCost.cpp
    llvm/trunk/lib/IR/BasicBlock.cpp

Modified: llvm/trunk/include/llvm/IR/BasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/BasicBlock.h?rev=354079&r1=354078&r2=354079&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/BasicBlock.h (original)
+++ llvm/trunk/include/llvm/IR/BasicBlock.h Thu Feb 14 15:35:53 2019
@@ -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);

Modified: llvm/trunk/lib/Analysis/InlineCost.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InlineCost.cpp?rev=354079&r1=354078&r2=354079&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InlineCost.cpp (original)
+++ llvm/trunk/lib/Analysis/InlineCost.cpp Thu Feb 14 15:35:53 2019
@@ -1832,7 +1832,7 @@ InlineResult CallAnalyzer::analyzeCall(C
     // 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(Functi
     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) {

Modified: llvm/trunk/lib/IR/BasicBlock.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/BasicBlock.cpp?rev=354079&r1=354078&r2=354079&view=diff
==============================================================================
--- llvm/trunk/lib/IR/BasicBlock.cpp (original)
+++ llvm/trunk/lib/IR/BasicBlock.cpp Thu Feb 14 15:35:53 2019
@@ -442,6 +442,14 @@ BasicBlock *BasicBlock::splitBasicBlock(
   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)




More information about the llvm-commits mailing list