[llvm-commits] [llvm] r44101 - in /llvm/trunk: lib/Transforms/IPO/LoopExtractor.cpp tools/bugpoint/BugDriver.h tools/bugpoint/ExtractFunction.cpp tools/bugpoint/Miscompilation.cpp tools/bugpoint/OptimizerDriver.cpp

Nick Lewycky nicholas at mxc.ca
Tue Nov 13 22:47:06 PST 2007


Author: nicholas
Date: Wed Nov 14 00:47:06 2007
New Revision: 44101

URL: http://llvm.org/viewvc/llvm-project?rev=44101&view=rev
Log:
Allow the block extractor take to take a list of basic blocks to not extract
from a file containing Function/BasicBlock pairings. This is not safe against
anonymous or abnormally-named Funcs or BBs.

Make bugpoint use this interface to pass the BBs list to the child bugpoint.

Modified:
    llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp
    llvm/trunk/tools/bugpoint/BugDriver.h
    llvm/trunk/tools/bugpoint/ExtractFunction.cpp
    llvm/trunk/tools/bugpoint/Miscompilation.cpp
    llvm/trunk/tools/bugpoint/OptimizerDriver.cpp

Modified: llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp?rev=44101&r1=44100&r2=44101&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp Wed Nov 14 00:47:06 2007
@@ -21,10 +21,13 @@
 #include "llvm/Pass.h"
 #include "llvm/Analysis/Dominators.h"
 #include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Utils/FunctionUtils.h"
 #include "llvm/ADT/Statistic.h"
+#include <fstream>
+#include <set>
 using namespace llvm;
 
 STATISTIC(NumExtracted, "Number of loops extracted");
@@ -144,15 +147,28 @@
 
 
 namespace {
+  // BlockFile - A file which contains a list of blocks that should not be
+  // extracted.
+  cl::opt<std::string>
+  BlockFile("extract-blocks-file", cl::value_desc("filename"),
+            cl::desc("A file containing list of basic blocks to not extract"),
+            cl::Hidden);
+
   /// BlockExtractorPass - This pass is used by bugpoint to extract all blocks
   /// from the module into their own functions except for those specified by the
   /// BlocksToNotExtract list.
   class BlockExtractorPass : public ModulePass {
+    void LoadFile(const char *Filename);
+
     std::vector<BasicBlock*> BlocksToNotExtract;
+    std::vector<std::pair<std::string, std::string> > BlocksToNotExtractByName;
   public:
     static char ID; // Pass identification, replacement for typeid
     explicit BlockExtractorPass(const std::vector<BasicBlock*> &B) 
-      : ModulePass((intptr_t)&ID), BlocksToNotExtract(B) {}
+      : ModulePass((intptr_t)&ID), BlocksToNotExtract(B) {
+      if (!BlockFile.empty())
+        LoadFile(BlockFile.c_str());
+    }
     BlockExtractorPass() : ModulePass((intptr_t)&ID) {}
 
     bool runOnModule(Module &M);
@@ -171,6 +187,24 @@
   return new BlockExtractorPass(BTNE);
 }
 
+void BlockExtractorPass::LoadFile(const char *Filename) {
+  // Load the BlockFile...
+  std::ifstream In(Filename);
+  if (!In.good()) {
+    cerr << "WARNING: BlockExtractor couldn't load file '" << Filename
+         << "'!\n";
+    return;
+  }
+  while (In) {
+    std::string FunctionName, BlockName;
+    In >> FunctionName;
+    In >> BlockName;
+    if (!BlockName.empty())
+      BlocksToNotExtractByName.push_back(
+          std::make_pair(FunctionName, BlockName));
+  }
+}
+
 bool BlockExtractorPass::runOnModule(Module &M) {
   std::set<BasicBlock*> TranslatedBlocksToNotExtract;
   for (unsigned i = 0, e = BlocksToNotExtract.size(); i != e; ++i) {
@@ -187,6 +221,29 @@
     TranslatedBlocksToNotExtract.insert(BBI);
   }
 
+  while (!BlocksToNotExtractByName.empty()) {
+    // There's no way to find BBs by name without looking at every BB inside
+    // every Function. Fortunately, this is always empty except when used by
+    // bugpoint in which case correctness is more important than performance.
+
+    std::string &FuncName  = BlocksToNotExtractByName.back().first;
+    std::string &BlockName = BlocksToNotExtractByName.back().second;
+
+    for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
+      Function &F = *FI;
+      if (F.getName() != FuncName) continue;
+
+      for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
+        BasicBlock &BB = *BI;
+        if (BB.getName() != BlockName) continue;
+
+        TranslatedBlocksToNotExtract.insert(BI);
+      }
+    }
+
+    BlocksToNotExtractByName.pop_back();
+  }
+
   // Now that we know which blocks to not extract, figure out which ones we WANT
   // to extract.
   std::vector<BasicBlock*> BlocksToExtract;

Modified: llvm/trunk/tools/bugpoint/BugDriver.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/BugDriver.h?rev=44101&r1=44100&r2=44101&view=diff

==============================================================================
--- llvm/trunk/tools/bugpoint/BugDriver.h (original)
+++ llvm/trunk/tools/bugpoint/BugDriver.h Wed Nov 14 00:47:06 2007
@@ -234,7 +234,8 @@
   /// automatically attempt to track down a crashing pass if one exists, and
   /// this method will never return null.
   Module *runPassesOn(Module *M, const std::vector<const PassInfo*> &Passes,
-                      bool AutoDebugCrashes = false);
+                      bool AutoDebugCrashes = false, unsigned NumExtraArgs = 0,
+                      const char * const *ExtraArgs = NULL);
 
   /// runPasses - Run the specified passes on Program, outputting a bitcode
   /// file and writting the filename into OutputFile if successful.  If the
@@ -242,11 +243,13 @@
   /// otherwise return false.  If DeleteOutput is set to true, the bitcode is
   /// deleted on success, and the filename string is undefined.  This prints to
   /// cout a single line message indicating whether compilation was successful
-  /// or failed, unless Quiet is set.
+  /// or failed, unless Quiet is set.  ExtraArgs specifies additional arguments
+  /// to pass to the child bugpoint instance.
   ///
   bool runPasses(const std::vector<const PassInfo*> &PassesToRun,
                  std::string &OutputFilename, bool DeleteOutput = false,
-                 bool Quiet = false) const;
+                 bool Quiet = false, unsigned NumExtraArgs = 0,
+                 const char * const *ExtraArgs = NULL) const;
                  
   /// runManyPasses - Take the specified pass list and create different 
   /// combinations of passes to compile the program with. Compile the program with

Modified: llvm/trunk/tools/bugpoint/ExtractFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ExtractFunction.cpp?rev=44101&r1=44100&r2=44101&view=diff

==============================================================================
--- llvm/trunk/tools/bugpoint/ExtractFunction.cpp (original)
+++ llvm/trunk/tools/bugpoint/ExtractFunction.cpp Wed Nov 14 00:47:06 2007
@@ -27,7 +27,10 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FileUtilities.h"
+#include "llvm/System/Path.h"
+#include "llvm/System/Signals.h"
 #include <set>
+#include <fstream>
 #include <iostream>
 using namespace llvm;
 
@@ -305,10 +308,51 @@
 Module *BugDriver::ExtractMappedBlocksFromModule(const
                                                  std::vector<BasicBlock*> &BBs,
                                                  Module *M) {
+  char *ExtraArg = NULL;
+
+  sys::Path uniqueFilename("bugpoint-extractblocks");
+  std::string ErrMsg;
+  if (uniqueFilename.createTemporaryFileOnDisk(true, &ErrMsg)) {
+    std::cout << "*** Basic Block extraction failed!\n";
+    std::cerr << "Error creating temporary file: " << ErrMsg << "\n";
+    M = swapProgramIn(M);
+    EmitProgressBitcode("basicblockextractfail", true);
+    swapProgramIn(M);
+    return 0;
+  }
+  sys::RemoveFileOnSignal(uniqueFilename);
+
+  std::ofstream BlocksToNotExtractFile(uniqueFilename.c_str());
+  if (!BlocksToNotExtractFile) {
+    std::cout << "*** Basic Block extraction failed!\n";
+    std::cerr << "Error writing list of blocks to not extract: " << ErrMsg
+              << "\n";
+    M = swapProgramIn(M);
+    EmitProgressBitcode("basicblockextractfail", true);
+    swapProgramIn(M);
+    return 0;
+  }
+  for (std::vector<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end();
+       I != E; ++I) {
+    BasicBlock *BB = *I;
+    BlocksToNotExtractFile << BB->getParent()->getName() << " "
+                           << BB->getName() << "\n";
+  }
+  BlocksToNotExtractFile.close();
+
+  const char *uniqueFN = uniqueFilename.c_str();
+  ExtraArg = (char*)malloc(23 + strlen(uniqueFN));
+  strcat(strcpy(ExtraArg, "--extract-blocks-file="), uniqueFN);
+
   std::vector<const PassInfo*> PI;
-  // FIXME: BBs is actually ignored. See http://llvm.org/PR1775
-  PI.push_back(getPI(createBlockExtractorPass(BBs)));
-  Module *Ret = runPassesOn(M, PI);
+  std::vector<BasicBlock *> EmptyBBs; // This parameter is ignored.
+  PI.push_back(getPI(createBlockExtractorPass(EmptyBBs)));
+  Module *Ret = runPassesOn(M, PI, false, 1, &ExtraArg);
+
+  if (uniqueFilename.exists())
+    uniqueFilename.eraseFromDisk(); // Free disk space
+  free(ExtraArg);
+
   if (Ret == 0) {
     std::cout << "*** Basic Block extraction failed, please report a bug!\n";
     M = swapProgramIn(M);

Modified: llvm/trunk/tools/bugpoint/Miscompilation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/Miscompilation.cpp?rev=44101&r1=44100&r2=44101&view=diff

==============================================================================
--- llvm/trunk/tools/bugpoint/Miscompilation.cpp (original)
+++ llvm/trunk/tools/bugpoint/Miscompilation.cpp Wed Nov 14 00:47:06 2007
@@ -223,7 +223,7 @@
   Module *ToNotOptimize = CloneModule(BD.getProgram());
   Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, Funcs);
 
-  // Run the predicate, not that the predicate will delete both input modules.
+  // Run the predicate, note that the predicate will delete both input modules.
   return TestFn(BD, ToOptimize, ToNotOptimize);
 }
 

Modified: llvm/trunk/tools/bugpoint/OptimizerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/OptimizerDriver.cpp?rev=44101&r1=44100&r2=44101&view=diff

==============================================================================
--- llvm/trunk/tools/bugpoint/OptimizerDriver.cpp (original)
+++ llvm/trunk/tools/bugpoint/OptimizerDriver.cpp Wed Nov 14 00:47:06 2007
@@ -124,7 +124,8 @@
 ///
 bool BugDriver::runPasses(const std::vector<const PassInfo*> &Passes,
                           std::string &OutputFilename, bool DeleteOutput,
-                          bool Quiet) const {
+                          bool Quiet, unsigned NumExtraArgs,
+                          const char * const *ExtraArgs) const {
   // setup the output file name
   cout << std::flush;
   sys::Path uniqueFilename("bugpoint-output.bc");
@@ -156,7 +157,7 @@
   // setup the child process' arguments
   const char** args = (const char**)
     alloca(sizeof(const char*) * 
-	   (Passes.size()+13+2*PluginLoader::getNumPlugins()));
+	   (Passes.size()+13+2*PluginLoader::getNumPlugins()+NumExtraArgs));
   int n = 0;
   sys::Path tool = sys::Program::FindProgramByName(ToolName);
   if (UseValgrind) {
@@ -182,6 +183,8 @@
        E = pass_args.end(); I != E; ++I )
     args[n++] = I->c_str();
   args[n++] = inputFilename.c_str();
+  for (unsigned i = 0; i < NumExtraArgs; ++i)
+    args[n++] = *ExtraArgs;
   args[n++] = 0;
 
   sys::Path prog;
@@ -225,10 +228,12 @@
 /// failure.
 Module *BugDriver::runPassesOn(Module *M,
                                const std::vector<const PassInfo*> &Passes,
-                               bool AutoDebugCrashes) {
+                               bool AutoDebugCrashes, unsigned NumExtraArgs,
+                               const char * const *ExtraArgs) {
   Module *OldProgram = swapProgramIn(M);
   std::string BitcodeResult;
-  if (runPasses(Passes, BitcodeResult, false/*delete*/, true/*quiet*/)) {
+  if (runPasses(Passes, BitcodeResult, false/*delete*/, true/*quiet*/,
+                NumExtraArgs, ExtraArgs)) {
     if (AutoDebugCrashes) {
       cerr << " Error running this sequence of passes"
            << " on the input program!\n";





More information about the llvm-commits mailing list