[llvm-commits] CVS: llvm/lib/Transforms/Utils/InlineFunction.cpp

Chris Lattner lattner at cs.uiuc.edu
Tue Feb 3 22:18:01 PST 2004


Changes in directory llvm/lib/Transforms/Utils:

InlineFunction.cpp updated: 1.20 -> 1.21

---
Log message:

Optimize the case where we are inlining a function that contains only one basic block,
and that basic block ends with a return instruction.  In this case, we can just splice
the cloned "body" of the function directly into the source basic block, avoiding a lot 
of rearrangement and splitBasicBlock's linear scan over the split block.  This speeds up
the inliner on the testcase in PR209 from 2.3s to 1.7s, a 35% reduction.


---
Diffs of the changes:  (+67 -37)

Index: llvm/lib/Transforms/Utils/InlineFunction.cpp
diff -u llvm/lib/Transforms/Utils/InlineFunction.cpp:1.20 llvm/lib/Transforms/Utils/InlineFunction.cpp:1.21
--- llvm/lib/Transforms/Utils/InlineFunction.cpp:1.20	Tue Feb  3 20:51:48 2004
+++ llvm/lib/Transforms/Utils/InlineFunction.cpp	Tue Feb  3 22:17:06 2004
@@ -175,34 +175,78 @@
     InvokeDest->removePredecessor(II->getParent());
   }
 
+  // If we cloned in _exactly one_ basic block, and if that block ends in a
+  // return instruction, we splice the body of the inlined callee directly into
+  // the calling basic block.
+  if (Returns.size() == 1 && std::distance(FirstNewBlock, Caller->end()) == 1) {
+    // Move all of the instructions right before the call.
+    OrigBB->getInstList().splice(TheCall, FirstNewBlock->getInstList(),
+                                 FirstNewBlock->begin(), FirstNewBlock->end());
+    // Remove the cloned basic block.
+    Caller->getBasicBlockList().pop_back();
+    
+    // If the call site was an invoke instruction, add a branch to the normal
+    // destination.
+    if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall))
+      new BranchInst(II->getNormalDest(), TheCall);
+
+    // If the return instruction returned a value, replace uses of the call with
+    // uses of the returned value.
+    if (!TheCall->use_empty())
+      TheCall->replaceAllUsesWith(Returns[0]->getReturnValue());
+
+    // Since we are now done with the Call/Invoke, we can delete it.
+    TheCall->getParent()->getInstList().erase(TheCall);
+
+    // Since we are now done with the return instruction, delete it also.
+    Returns[0]->getParent()->getInstList().erase(Returns[0]);
+
+    // We are now done with the inlining.
+    return true;
+  }
+
+  // Otherwise, we have the normal case, of more than one block to inline or
+  // multiple return sites.
+
   // We want to clone the entire callee function into the hole between the
   // "starter" and "ender" blocks.  How we accomplish this depends on whether
   // this is an invoke instruction or a call instruction.
   BasicBlock *AfterCallBB;
   if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) {
-
+    
     // Add an unconditional branch to make this look like the CallInst case...
     BranchInst *NewBr = new BranchInst(II->getNormalDest(), TheCall);
-
+    
     // Split the basic block.  This guarantees that no PHI nodes will have to be
     // updated due to new incoming edges, and make the invoke case more
     // symmetric to the call case.
     AfterCallBB = OrigBB->splitBasicBlock(NewBr,
                                           CalledFunc->getName()+".entry");
-
-    // Remove (unlink) the InvokeInst from the function...
-    OrigBB->getInstList().remove(TheCall);
-
+    
   } else {  // It's a call
-    // If this is a call instruction, we need to split the basic block that the
-    // call lives in.
+    // If this is a call instruction, we need to split the basic block that
+    // the call lives in.
     //
     AfterCallBB = OrigBB->splitBasicBlock(TheCall,
                                           CalledFunc->getName()+".entry");
-    // Remove (unlink) the CallInst from the function...
-    AfterCallBB->getInstList().remove(TheCall);
   }
 
+  // Change the branch that used to go to AfterCallBB to branch to the first
+  // basic block of the inlined function.
+  //
+  TerminatorInst *Br = OrigBB->getTerminator();
+  assert(Br && Br->getOpcode() == Instruction::Br && 
+         "splitBasicBlock broken!");
+  Br->setOperand(0, FirstNewBlock);
+
+
+  // Now that the function is correct, make it a little bit nicer.  In
+  // particular, move the basic blocks inserted from the end of the function
+  // into the space made by splitting the source basic block.
+  //
+  Caller->getBasicBlockList().splice(AfterCallBB, Caller->getBasicBlockList(),
+                                     FirstNewBlock, Caller->end());
+
   // Handle all of the return instructions that we just cloned in, and eliminate
   // any users of the original call/invoke instruction.
   if (Returns.size() > 1) {
@@ -213,74 +257,60 @@
     if (!TheCall->use_empty()) {
       PHI = new PHINode(CalledFunc->getReturnType(),
                         TheCall->getName(), AfterCallBB->begin());
-      
+        
       // Anything that used the result of the function call should now use the
       // PHI node as their operand.
       //
       TheCall->replaceAllUsesWith(PHI);
     }
-
+      
     // Loop over all of the return instructions, turning them into unconditional
     // branches to the merge point now, and adding entries to the PHI node as
     // appropriate.
     for (unsigned i = 0, e = Returns.size(); i != e; ++i) {
       ReturnInst *RI = Returns[i];
-
+        
       if (PHI) {
         assert(RI->getReturnValue() && "Ret should have value!");
         assert(RI->getReturnValue()->getType() == PHI->getType() && 
                "Ret value not consistent in function!");
         PHI->addIncoming(RI->getReturnValue(), RI->getParent());
       }
-
+        
       // Add a branch to the merge point where the PHI node lives if it exists.
       new BranchInst(AfterCallBB, RI);
-      
+        
       // Delete the return instruction now
       RI->getParent()->getInstList().erase(RI);
     }
-    
+      
   } else if (!Returns.empty()) {
     // Otherwise, if there is exactly one return value, just replace anything
     // using the return value of the call with the computed value.
     if (!TheCall->use_empty())
       TheCall->replaceAllUsesWith(Returns[0]->getReturnValue());
-
+      
     // Add a branch to the merge point where the PHI node lives if it exists.
     new BranchInst(AfterCallBB, Returns[0]);
-
+      
     // Delete the return instruction now
     Returns[0]->getParent()->getInstList().erase(Returns[0]);
   }
-
+    
   // Since we are now done with the Call/Invoke, we can delete it.
-  delete TheCall;
-
-  // Change the branch that used to go to AfterCallBB to branch to the first
-  // basic block of the inlined function.
-  //
-  TerminatorInst *Br = OrigBB->getTerminator();
-  assert(Br && Br->getOpcode() == Instruction::Br && 
-	 "splitBasicBlock broken!");
-  Br->setOperand(0, FirstNewBlock);
-
-  // Now that the function is correct, make it a little bit nicer.  In
-  // particular, move the basic blocks inserted from the end of the function
-  // into the space made by splitting the source basic block.
-  //
-  Caller->getBasicBlockList().splice(AfterCallBB, Caller->getBasicBlockList(), 
-                                     FirstNewBlock, Caller->end());
+  TheCall->getParent()->getInstList().erase(TheCall);
 
   // We should always be able to fold the entry block of the function into the
   // single predecessor of the block...
-  assert(cast<BranchInst>(Br)->isUnconditional() && "splitBasicBlock broken!");
+  assert(cast<BranchInst>(Br)->isUnconditional() &&"splitBasicBlock broken!");
   BasicBlock *CalleeEntry = cast<BranchInst>(Br)->getSuccessor(0);
   SimplifyCFG(CalleeEntry);
-  
+    
   // Okay, continue the CFG cleanup.  It's often the case that there is only a
   // single return instruction in the callee function.  If this is the case,
   // then we have an unconditional branch from the return block to the
   // 'AfterCallBB'.  Check for this case, and eliminate the branch is possible.
   SimplifyCFG(AfterCallBB);
+
   return true;
 }





More information about the llvm-commits mailing list