[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