[llvm] r209135 - Revert "Patch for function cloning to inline all blocks whose address is taken"

Eric Christopher echristo at gmail.com
Mon May 19 09:04:10 PDT 2014


Author: echristo
Date: Mon May 19 11:04:10 2014
New Revision: 209135

URL: http://llvm.org/viewvc/llvm-project?rev=209135&view=rev
Log:
Revert "Patch for function cloning to inline all blocks whose address is taken"
as it was causing build failures in ruby.

This reverts commit r207713.

Modified:
    llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp

Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=209135&r1=209134&r2=209135&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Mon May 19 11:04:10 2014
@@ -32,7 +32,6 @@
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Transforms/Utils/ValueMapper.h"
 #include <map>
-#include <set>
 using namespace llvm;
 
 // CloneBasicBlock - See comments in Cloning.h
@@ -273,36 +272,42 @@ namespace {
       NameSuffix(nameSuffix), CodeInfo(codeInfo), DL(DL) {
     }
 
-    /// CloneBlock - The specified block is found to be reachable, so clone it
-    /// into NewBB.
-    /// ToClone is the vector of actually cloned blocks.
-    /// OrigBBs is the set of all blocks reacheable from the entry block.
-    /// It contains the block candidates and makes sure each block
-    /// is cloned at most once.
+    /// CloneBlock - The specified block is found to be reachable, clone it and
+    /// anything that it can reach.
     void CloneBlock(const BasicBlock *BB,
-                    BasicBlock *NewBB,
-                    std::vector<const BasicBlock *> &ToClone,
-                    std::set<const BasicBlock *> &OrigBBs);
+                    std::vector<const BasicBlock*> &ToClone);
   };
 }
 
-/// CloneBlock - The specified block is found to be reachable, so clone it
-/// into NewBB.
-/// ToClone is the vector of actually cloned blocks.
-/// OrigBBs is the set of all blocks reacheable from the entry block.
-/// It contains the block candidates and makes sure each block
-/// is cloned at most once.
+/// CloneBlock - The specified block is found to be reachable, clone it and
+/// anything that it can reach.
 void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
-                                       BasicBlock *NewBB,
-                                       std::vector<const BasicBlock *> &ToClone,
-                                       std::set<const BasicBlock *> &OrigBBs) {
-  
-  // Remove BB from list of blocks to clone.
-  // When it was not in the list, it has been cloned already, so
-  // don't clone again.
-  if (!OrigBBs.erase(BB)) return;
+                                       std::vector<const BasicBlock*> &ToClone){
+  WeakVH &BBEntry = VMap[BB];
 
+  // Have we already cloned this block?
+  if (BBEntry) return;
+  
   // Nope, clone it now.
+  BasicBlock *NewBB;
+  BBEntry = NewBB = BasicBlock::Create(BB->getContext());
+  if (BB->hasName()) NewBB->setName(BB->getName()+NameSuffix);
+
+  // It is only legal to clone a function if a block address within that
+  // function is never referenced outside of the function.  Given that, we
+  // want to map block addresses from the old function to block addresses in
+  // the clone. (This is different from the generic ValueMapper
+  // implementation, which generates an invalid blockaddress when
+  // cloning a function.)
+  //
+  // Note that we don't need to fix the mapping for unreachable blocks;
+  // the default mapping there is safe.
+  if (BB->hasAddressTaken()) {
+    Constant *OldBBAddr = BlockAddress::get(const_cast<Function*>(OldFunc),
+                                            const_cast<BasicBlock*>(BB));
+    VMap[OldBBAddr] = BlockAddress::get(NewFunc, NewBB);
+  }
+    
 
   bool hasCalls = false, hasDynamicAllocas = false, hasStaticAllocas = false;
   
@@ -420,7 +425,7 @@ void llvm::CloneAndPruneFunctionInto(Fun
                                      const DataLayout *DL,
                                      Instruction *TheCall) {
   assert(NameSuffix && "NameSuffix cannot be null!");
-
+  
 #ifndef NDEBUG
   for (Function::const_arg_iterator II = OldFunc->arg_begin(), 
        E = OldFunc->arg_end(); II != E; ++II)
@@ -430,91 +435,15 @@ void llvm::CloneAndPruneFunctionInto(Fun
   PruningFunctionCloner PFC(NewFunc, OldFunc, VMap, ModuleLevelChanges,
                             NameSuffix, CodeInfo, DL);
 
-  // Since all BB address references need to be known before block-by-block
-  // processing, we need to create all reachable blocks before processing
-  // them for instruction cloning and pruning. Some of these blocks may
-  // be removed due to later pruning.
+  // Clone the entry block, and anything recursively reachable from it.
   std::vector<const BasicBlock*> CloneWorklist;
-  //
-  // OrigBBs consists of all blocks reachable from the entry
-  // block.
-  // This list will be pruned down by the CloneFunction() due to two
-  // two optimizations:
-  // First, when a conditional branch target is known at compile-time,
-  // only the actual branch destination block needs to be cloned.
-  // Second, when a switch statement target is known at compile-time,
-  // only the actual case statement needs to be cloned.
-  std::set<const BasicBlock *> OrigBBs;
-
-  CloneWorklist.push_back(&OldFunc->getEntryBlock());
-  while (!CloneWorklist.empty()) {
-    const BasicBlock *BB = CloneWorklist.back();
-    CloneWorklist.pop_back();
-
-    // Don't revisit blocks.
-    if (VMap.count(BB))
-      continue;
-
-    BasicBlock *NewBB = BasicBlock::Create(BB->getContext());
-    if (BB->hasName())
-      NewBB->setName(BB->getName() + NameSuffix);
-
-    // It is legal to clone a function when a block address within that
-    // function is never escapes outside of the function.  Given that, we
-    // want to map block addresses from the old function to block addresses in
-    // the clone. (This is different from the generic ValueMapper
-    // implementation, which generates an invalid block address when
-    // cloning a function.)
-    // Note the current escape address does not catch all legal cases: even
-    // when all block addresses taken are local and the function has the
-    // always_inline attribute due to the indirect branch inlining is
-    // suppressed.
-    // Note that we don't need to fix the mapping for unreachable blocks;
-    // the default mapping there is safe.
-    if (BB->hasAddressTaken()) {
-      Constant *OldBBAddr = BlockAddress::get(const_cast<Function*>(OldFunc),
-                                              const_cast<BasicBlock*>(BB));
-      VMap[OldBBAddr] = BlockAddress::get(NewFunc, NewBB);
-    }
-
-    OrigBBs.insert(BB);
-    VMap[BB] = NewBB;
-    // Iterate over all possible successors and add them to the CloneWorklist.
-    const TerminatorInst *Term = BB->getTerminator();
-    for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
-      BasicBlock *Succ = Term->getSuccessor(i);
-      CloneWorklist.push_back(Succ);
-    }
-  }
-
-  // Now, fill only the reachable blocks with the cloned contents
-  // of the originals.
-  assert(CloneWorklist.empty() && "Dirty worklist before re-use\n");
   CloneWorklist.push_back(&OldFunc->getEntryBlock());
   while (!CloneWorklist.empty()) {
     const BasicBlock *BB = CloneWorklist.back();
     CloneWorklist.pop_back();
-    PFC.CloneBlock(BB, cast<BasicBlock>(VMap[BB]), CloneWorklist,
-                   OrigBBs);
+    PFC.CloneBlock(BB, CloneWorklist);
   }
-
-  // FIXME: Delete BB's that were created but have been pruned.
-  // Actual cloning may have found pruning opportunities since
-  // branch or switch statement target may have been known at compile-time.
-  // Alternatively we could write a routine CloneFunction and add a) a
-  // parameter to actually do the cloning and b) a return parameter that
-  // gives a list of blocks that need to be cloned also. Then we could
-  // call CloneFunction when we collect the blocks to clone, but suppress
-  // cloning. And then actually *do* the cloning in the while loop above. Then
-  // the cleanup here would become redundant, and so would be the OrigBBs.
-  for (std::set<const BasicBlock *>::iterator Oi = OrigBBs.begin(),
-       Oe = OrigBBs.end(); Oi != Oe; ++Oi) {
-    const BasicBlock *Orig = *Oi;
-    BasicBlock *NewBB = cast<BasicBlock>(VMap[Orig]);
-    delete NewBB;
-    VMap[Orig] = 0;
-  }
-
+  
   // Loop over all of the basic blocks in the old function.  If the block was
   // reachable, we have cloned it and the old block is now in the value map:
   // insert it into the new function in the right order.  If not, ignore it.
@@ -525,8 +454,7 @@ void llvm::CloneAndPruneFunctionInto(Fun
        BI != BE; ++BI) {
     Value *V = VMap[BI];
     BasicBlock *NewBB = cast_or_null<BasicBlock>(V);
-    if (!NewBB)
-      continue; // Dead block.
+    if (!NewBB) continue;  // Dead block.
 
     // Add the new block to the new function.
     NewFunc->getBasicBlockList().push_back(NewBB);





More information about the llvm-commits mailing list