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

Chris Lattner lattner at cs.uiuc.edu
Wed May 12 01:01:01 PDT 2004


Changes in directory llvm/lib/Transforms/Utils:

CodeExtractor.cpp updated: 1.19 -> 1.20

---
Log message:

* Pull some code out into the definedInRegion/definedInCaller methods
* Add a stub for the severSplitPHINodes which will allow us to bbextract 
  bb's with PHI nodes in them soon.
* Remove unused arguments from findInputsOutputs
* Dramatically simplify the code in findInputsOutputs.  In particular, 
  nothing really cares whether or not a PHI node is using something.
* Move moveCodeToFunction to after emitCallAndSwitchStatement as that's the
  order they get called.
* Fix a bug where we would code extract a region that included a call to 
  vastart.  Like 'alloca', calls to vastart must stay in the function that
  they are defined in.
* Add some comments.


---
Diffs of the changes:  (+77 -77)

Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp
diff -u llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.19 llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.20
--- llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.19	Tue May 11 23:14:24 2004
+++ llvm/lib/Transforms/Utils/CodeExtractor.cpp	Wed May 12 01:01:40 2004
@@ -17,6 +17,7 @@
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/Analysis/Dominators.h"
@@ -55,9 +56,28 @@
     bool isEligible(const std::vector<BasicBlock*> &code);
 
   private:
-    void findInputsOutputs(Values &inputs, Values &outputs,
-                           BasicBlock *newHeader,
-                           BasicBlock *newRootNode);
+    /// definedInRegion - Return true if the specified value is defined in the
+    /// extracted region.
+    bool definedInRegion(Value *V) const {
+      if (Instruction *I = dyn_cast<Instruction>(V))
+        if (BlocksToExtract.count(I->getParent()))
+          return true;
+      return false;
+    }
+    
+    /// definedInCaller - Return true if the specified value is defined in the
+    /// function being code extracted, but not in the region being extracted.
+    /// These values must be passed in as live-ins to the function.
+    bool definedInCaller(Value *V) const {
+      if (isa<Argument>(V)) return true;
+      if (Instruction *I = dyn_cast<Instruction>(V))
+        if (!BlocksToExtract.count(I->getParent()))
+          return true;
+      return false;
+    }
+
+    void severSplitPHINodes(BasicBlock *&Header);
+    void findInputsOutputs(Values &inputs, Values &outputs);
 
     Function *constructFunction(const Values &inputs,
                                 const Values &outputs,
@@ -75,51 +95,40 @@
   };
 }
 
-void CodeExtractor::findInputsOutputs(Values &inputs, Values &outputs,
-                                      BasicBlock *newHeader,
-                                      BasicBlock *newRootNode) {
+/// severSplitPHINodes - If a PHI node has multiple inputs from outside of the
+/// region, we need to split the entry block of the region so that the PHI node
+/// is easier to deal with.
+void CodeExtractor::severSplitPHINodes(BasicBlock *&Header) {
+  
+
+
+}
+
+// findInputsOutputs - Find inputs to, outputs from the code region.
+//
+void CodeExtractor::findInputsOutputs(Values &inputs, Values &outputs) {
   std::set<BasicBlock*> ExitBlocks;
   for (std::set<BasicBlock*>::const_iterator ci = BlocksToExtract.begin(), 
        ce = BlocksToExtract.end(); ci != ce; ++ci) {
     BasicBlock *BB = *ci;
+
     for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
       // If a used value is defined outside the region, it's an input.  If an
       // instruction is used outside the region, it's an output.
-      if (PHINode *PN = dyn_cast<PHINode>(I)) {
-        for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
-          Value *V = PN->getIncomingValue(i);
-          if (!BlocksToExtract.count(PN->getIncomingBlock(i)) &&
-              (isa<Instruction>(V) || isa<Argument>(V)))
-            inputs.push_back(V);
-          else if (Instruction *opI = dyn_cast<Instruction>(V)) {
-            if (!BlocksToExtract.count(opI->getParent()))
-              inputs.push_back(opI);
-          } else if (isa<Argument>(V))
-            inputs.push_back(V);
-        }
-      } else {
-        // All other instructions go through the generic input finder
-        // Loop over the operands of each instruction (inputs)
-        for (User::op_iterator op = I->op_begin(), opE = I->op_end();
-             op != opE; ++op)
-          if (Instruction *opI = dyn_cast<Instruction>(*op)) {
-            // Check if definition of this operand is within the loop
-            if (!BlocksToExtract.count(opI->getParent()))
-              inputs.push_back(opI);
-          } else if (isa<Argument>(*op)) {
-            inputs.push_back(*op);
-          }
-      }
+      for (User::op_iterator O = I->op_begin(), E = I->op_end(); O != E; ++O)
+        if (definedInCaller(*O))
+          inputs.push_back(*O);
       
-      // Consider uses of this instruction (outputs)
+      // Consider uses of this instruction (outputs).
       for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
            UI != E; ++UI)
-        if (!BlocksToExtract.count(cast<Instruction>(*UI)->getParent())) {
+        if (!definedInRegion(*UI)) {
           outputs.push_back(I);
           break;
         }
     } // for: insts
 
+    // Keep track of the exit blocks from the region.
     TerminatorInst *TI = BB->getTerminator();
     for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
       if (!BlocksToExtract.count(TI->getSuccessor(i)))
@@ -238,30 +247,14 @@
   return newFunction;
 }
 
-void CodeExtractor::moveCodeToFunction(Function *newFunction) {
-  Function *oldFunc = (*BlocksToExtract.begin())->getParent();
-  Function::BasicBlockListType &oldBlocks = oldFunc->getBasicBlockList();
-  Function::BasicBlockListType &newBlocks = newFunction->getBasicBlockList();
-
-  for (std::set<BasicBlock*>::const_iterator i = BlocksToExtract.begin(),
-         e = BlocksToExtract.end(); i != e; ++i) {
-    // Delete the basic block from the old function, and the list of blocks
-    oldBlocks.remove(*i);
-
-    // Insert this basic block into the new function
-    newBlocks.push_back(*i);
-  }
-}
-
-void
-CodeExtractor::emitCallAndSwitchStatement(Function *newFunction,
-                                          BasicBlock *codeReplacer,
-                                          Values &inputs,
-                                          Values &outputs) {
-
-  // Emit a call to the new function, passing in:
-  // *pointer to struct (if aggregating parameters), or 
-  // plan inputs and allocated memory for outputs 
+/// emitCallAndSwitchStatement - This method sets up the caller side by adding
+/// the call instruction, splitting any PHI nodes in the header block as
+/// necessary.
+void CodeExtractor::
+emitCallAndSwitchStatement(Function *newFunction, BasicBlock *codeReplacer,
+                           Values &inputs, Values &outputs) {
+  // Emit a call to the new function, passing in: *pointer to struct (if
+  // aggregating parameters), or plan inputs and allocated memory for outputs
   std::vector<Value*> params, StructValues, ReloadOutputs;
 
   // Add inputs as params, or to be filled into the struct
@@ -462,6 +455,20 @@
   }
 }
 
+void CodeExtractor::moveCodeToFunction(Function *newFunction) {
+  Function *oldFunc = (*BlocksToExtract.begin())->getParent();
+  Function::BasicBlockListType &oldBlocks = oldFunc->getBasicBlockList();
+  Function::BasicBlockListType &newBlocks = newFunction->getBasicBlockList();
+
+  for (std::set<BasicBlock*>::const_iterator i = BlocksToExtract.begin(),
+         e = BlocksToExtract.end(); i != e; ++i) {
+    // Delete the basic block from the old function, and the list of blocks
+    oldBlocks.remove(*i);
+
+    // Insert this basic block into the new function
+    newBlocks.push_back(*i);
+  }
+}
 
 /// ExtractRegion - Removes a loop from a function, replaces it with a call to
 /// new function. Returns pointer to the new function.
@@ -497,6 +504,10 @@
   // Assumption: this is a single-entry code region, and the header is the first
   // block in the region.
   BasicBlock *header = code[0];
+
+  // If we have to split PHI nodes, do so now.
+  severSplitPHINodes(header);
+
   for (unsigned i = 1, e = code.size(); i != e; ++i)
     for (pred_iterator PI = pred_begin(code[i]), E = pred_end(code[i]);
          PI != E; ++PI)
@@ -510,29 +521,14 @@
   BasicBlock *codeReplacer = new BasicBlock("codeRepl", oldFunction);
 
   // The new function needs a root node because other nodes can branch to the
-  // head of the loop, and the root cannot have predecessors
+  // head of the region, but the entry node of a function cannot have preds.
   BasicBlock *newFuncRoot = new BasicBlock("newFuncRoot");
   newFuncRoot->getInstList().push_back(new BranchInst(header));
 
-  // Find inputs to, outputs from the code region
-  //
-  // If one of the inputs is coming from a different basic block and it's in a
-  // phi node, we need to rewrite the phi node:
-  //
-  // * All the inputs which involve basic blocks OUTSIDE of this region go into
-  //   a NEW phi node that takes care of finding which value really came in.
-  //   The result of this phi is passed to the function as an argument. 
-  //
-  // * All the other phi values stay.
-  //
-  // FIXME: PHI nodes' incoming blocks aren't being rewritten to accomodate for
-  // blocks moving to a new function.
-  // SOLUTION: move Phi nodes out of the loop header into the codeReplacer, pass
-  // the values as parameters to the function
-  findInputsOutputs(inputs, outputs, codeReplacer, newFuncRoot);
+  // Find inputs to, outputs from the code region.
+  findInputsOutputs(inputs, outputs);
 
-  // Step 2: Construct new function based on inputs/outputs,
-  // Add allocas for all defs
+  // Construct new function based on inputs/outputs & add allocas for all defs.
   Function *newFunction = constructFunction(inputs, outputs, code[0],
                                             newFuncRoot, 
                                             codeReplacer, oldFunction,
@@ -568,13 +564,17 @@
 }
 
 bool CodeExtractor::isEligible(const std::vector<BasicBlock*> &code) {
-  // Deny code region if it contains allocas
+  // Deny code region if it contains allocas or vastarts.
   for (std::vector<BasicBlock*>::const_iterator BB = code.begin(), e=code.end();
        BB != e; ++BB)
     for (BasicBlock::const_iterator I = (*BB)->begin(), Ie = (*BB)->end();
          I != Ie; ++I)
       if (isa<AllocaInst>(*I))
         return false;
+      else if (const CallInst *CI = dyn_cast<CallInst>(I))
+        if (const Function *F = CI->getCalledFunction())
+          if (F->getIntrinsicID() == Intrinsic::vastart)
+            return false;
   return true;
 }
 





More information about the llvm-commits mailing list