minor cleanups. Add provisions for a new standard BLOCKINFO_BLOCK
[oota-llvm.git] / tools / bugpoint / ExtractFunction.cpp
index 1c7225d73fd7b45fe98d4c3586ae36929b2d921d..85da9294285e0bd1221755687a6c2485e8cd22b0 100644 (file)
@@ -1,10 +1,10 @@
 //===- ExtractFunction.cpp - Extract a function from Program --------------===//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This file implements several methods that are used to extract functions,
 //===----------------------------------------------------------------------===//
 
 #include "BugDriver.h"
-#include "llvm/Constant.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
 #include "llvm/PassManager.h"
 #include "llvm/Pass.h"
-#include "llvm/Type.h"
 #include "llvm/Analysis/Verifier.h"
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/Scalar.h"
@@ -28,6 +28,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FileUtilities.h"
 #include <set>
+#include <iostream>
 using namespace llvm;
 
 namespace llvm {
@@ -73,10 +74,13 @@ Module *BugDriver::deleteInstructionFromProgram(const Instruction *I,
   // Remove the instruction from the program.
   TheInst->getParent()->getInstList().erase(TheInst);
 
+  
+  //writeProgramToFile("current.bc", Result);
+    
   // Spiff up the output a little bit.
   PassManager Passes;
   // Make sure that the appropriate target data is always used...
-  Passes.add(new TargetData("bugpoint", Result));
+  Passes.add(new TargetData(Result));
 
   /// FIXME: If this used runPasses() like the methods below, we could get rid
   /// of the -disable-* options!
@@ -104,9 +108,8 @@ Module *BugDriver::performFinalCleanups(Module *M, bool MayModifySemantics) {
   // Make all functions external, so GlobalDCE doesn't delete them...
   for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
     I->setLinkage(GlobalValue::ExternalLinkage);
-  
+
   std::vector<const PassInfo*> CleanupPasses;
-  CleanupPasses.push_back(getPI(createFunctionResolvingPass()));
   CleanupPasses.push_back(getPI(createGlobalDCEPass()));
   CleanupPasses.push_back(getPI(createDeadTypeEliminationPass()));
 
@@ -155,7 +158,7 @@ Module *BugDriver::ExtractLoop(Module *M) {
     for (unsigned i = 0, e = M->size(); i != e; ++i)
       ++MI;
   }
-  
+
   return NewM;
 }
 
@@ -166,46 +169,127 @@ Module *BugDriver::ExtractLoop(Module *M) {
 void llvm::DeleteFunctionBody(Function *F) {
   // delete the body of the function...
   F->deleteBody();
-  assert(F->isExternal() && "This didn't make the function external!");
+  assert(F->isDeclaration() && "This didn't make the function external!");
+}
+
+/// GetTorInit - Given a list of entries for static ctors/dtors, return them
+/// as a constant array.
+static Constant *GetTorInit(std::vector<std::pair<Function*, int> > &TorList) {
+  assert(!TorList.empty() && "Don't create empty tor list!");
+  std::vector<Constant*> ArrayElts;
+  for (unsigned i = 0, e = TorList.size(); i != e; ++i) {
+    std::vector<Constant*> Elts;
+    Elts.push_back(ConstantInt::get(Type::Int32Ty, TorList[i].second));
+    Elts.push_back(TorList[i].first);
+    ArrayElts.push_back(ConstantStruct::get(Elts));
+  }
+  return ConstantArray::get(ArrayType::get(ArrayElts[0]->getType(), 
+                                           ArrayElts.size()),
+                            ArrayElts);
+}
+
+/// SplitStaticCtorDtor - A module was recently split into two parts, M1/M2, and
+/// M1 has all of the global variables.  If M2 contains any functions that are
+/// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and
+/// prune appropriate entries out of M1s list.
+static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2){
+  GlobalVariable *GV = M1->getNamedGlobal(GlobalName);
+  if (!GV || GV->isDeclaration() || GV->hasInternalLinkage() ||
+      !GV->use_empty()) return;
+  
+  std::vector<std::pair<Function*, int> > M1Tors, M2Tors;
+  ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
+  if (!InitList) return;
+  
+  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
+    if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){
+      if (CS->getNumOperands() != 2) return;  // Not array of 2-element structs.
+      
+      if (CS->getOperand(1)->isNullValue())
+        break;  // Found a null terminator, stop here.
+      
+      ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
+      int Priority = CI ? CI->getSExtValue() : 0;
+      
+      Constant *FP = CS->getOperand(1);
+      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
+        if (CE->isCast())
+          FP = CE->getOperand(0);
+      if (Function *F = dyn_cast<Function>(FP)) {
+        if (!F->isDeclaration())
+          M1Tors.push_back(std::make_pair(F, Priority));
+        else {
+          // Map to M2's version of the function.
+          F = M2->getFunction(F->getName());
+          M2Tors.push_back(std::make_pair(F, Priority));
+        }
+      }
+    }
+  }
+  
+  GV->eraseFromParent();
+  if (!M1Tors.empty()) {
+    Constant *M1Init = GetTorInit(M1Tors);
+    new GlobalVariable(M1Init->getType(), false, GlobalValue::AppendingLinkage,
+                       M1Init, GlobalName, M1);
+  }
+
+  GV = M2->getNamedGlobal(GlobalName);
+  assert(GV && "Not a clone of M1?");
+  assert(GV->use_empty() && "llvm.ctors shouldn't have uses!");
+
+  GV->eraseFromParent();
+  if (!M2Tors.empty()) {
+    Constant *M2Init = GetTorInit(M2Tors);
+    new GlobalVariable(M2Init->getType(), false, GlobalValue::AppendingLinkage,
+                       M2Init, GlobalName, M2);
+  }
 }
 
+
 /// SplitFunctionsOutOfModule - Given a module and a list of functions in the
 /// module, split the functions OUT of the specified module, and place them in
 /// the new module.
-///
-/// FIXME: this could be made DRAMATICALLY more efficient for large programs if
-/// we just MOVED functions from one module to the other, instead of cloning the
-/// whole module, then proceeding to delete an entire module's worth of stuff.
-///
 Module *llvm::SplitFunctionsOutOfModule(Module *M,
                                         const std::vector<Function*> &F) {
   // Make sure functions & globals are all external so that linkage
   // between the two modules will work.
   for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
     I->setLinkage(GlobalValue::ExternalLinkage);
-  for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I)
+  for (Module::global_iterator I = M->global_begin(), E = M->global_end();
+       I != E; ++I)
     I->setLinkage(GlobalValue::ExternalLinkage);
 
   Module *New = CloneModule(M);
 
   // Make sure global initializers exist only in the safe module (CBE->.so)
-  for (Module::global_iterator I = New->global_begin(), E = New->global_end(); I != E; ++I)
+  for (Module::global_iterator I = New->global_begin(), E = New->global_end();
+       I != E; ++I)
     I->setInitializer(0);  // Delete the initializer to make it external
 
   // Remove the Test functions from the Safe module
   std::set<std::pair<std::string, const PointerType*> > TestFunctions;
   for (unsigned i = 0, e = F.size(); i != e; ++i) {
-    TestFunctions.insert(std::make_pair(F[i]->getName(), F[i]->getType()));
-    Function *TNOF = M->getFunction(F[i]->getName(), F[i]->getFunctionType());
-    DEBUG(std::cerr << "Removing function " << F[i]->getName() << "\n");
+    TestFunctions.insert(std::make_pair(F[i]->getName(), F[i]->getType()));  
+    Function *TNOF = M->getFunction(F[i]->getName());
     assert(TNOF && "Function doesn't exist in module!");
+    assert(TNOF->getFunctionType() == F[i]->getFunctionType() && "wrong type?");
+    DEBUG(std::cerr << "Removing function " << F[i]->getName() << "\n");
     DeleteFunctionBody(TNOF);       // Function is now external in this module!
   }
 
+  
   // Remove the Safe functions from the Test module
   for (Module::iterator I = New->begin(), E = New->end(); I != E; ++I)
     if (!TestFunctions.count(std::make_pair(I->getName(), I->getType())))
       DeleteFunctionBody(I);
+  
+
+  // Make sure that there is a global ctor/dtor array in both halves of the
+  // module if they both have static ctor/dtor functions.
+  SplitStaticCtorDtor("llvm.global_ctors", M, New);
+  SplitStaticCtorDtor("llvm.global_dtors", M, New);
+  
   return New;
 }
 
@@ -221,8 +305,12 @@ namespace {
   /// BlocksToNotExtract list.
   class BlockExtractorPass : public ModulePass {
     bool runOnModule(Module &M);
+  public:
+    static char ID; // Pass ID, replacement for typeid
+    BlockExtractorPass() : ModulePass((intptr_t)&ID) {}
   };
-  RegisterOpt<BlockExtractorPass>
+  char BlockExtractorPass::ID = 0;
+  RegisterPass<BlockExtractorPass>
   XX("extract-bbs", "Extract Basic Blocks From Module (for bugpoint use)");
 }
 
@@ -233,7 +321,7 @@ bool BlockExtractorPass::runOnModule(Module &M) {
     Function *F = BB->getParent();
 
     // Map the corresponding function in this module.
-    Function *MF = M.getFunction(F->getName(), F->getFunctionType());
+    Function *MF = M.getFunction(F->getName());
 
     // Figure out which index the basic block is in its function.
     Function::iterator BBI = MF->begin();
@@ -251,7 +339,7 @@ bool BlockExtractorPass::runOnModule(Module &M) {
 
   for (unsigned i = 0, e = BlocksToExtract.size(); i != e; ++i)
     ExtractBasicBlock(BlocksToExtract[i]);
-  
+
   return !BlocksToExtract.empty();
 }
 
@@ -274,7 +362,7 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const
     std::cout << "*** Basic Block extraction failed, please report a bug!\n";
     M = swapProgramIn(M);
     EmitProgressBytecode("basicblockextractfail", true);
-    M = swapProgramIn(M);
+    swapProgramIn(M);
   }
   return Ret;
 }