llvm.org GIT mirror llvm / 6fa98b1
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44101 91177308-0d34-0410-b5e6-96231b3b80d8 Nick Lewycky 11 years ago
5 changed file(s) with 121 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
2020 #include "llvm/Pass.h"
2121 #include "llvm/Analysis/Dominators.h"
2222 #include "llvm/Analysis/LoopInfo.h"
23 #include "llvm/Support/CommandLine.h"
2324 #include "llvm/Support/Compiler.h"
2425 #include "llvm/Transforms/Scalar.h"
2526 #include "llvm/Transforms/Utils/FunctionUtils.h"
2627 #include "llvm/ADT/Statistic.h"
28 #include
29 #include
2730 using namespace llvm;
2831
2932 STATISTIC(NumExtracted, "Number of loops extracted");
143146
144147
145148 namespace {
149 // BlockFile - A file which contains a list of blocks that should not be
150 // extracted.
151 cl::opt
152 BlockFile("extract-blocks-file", cl::value_desc("filename"),
153 cl::desc("A file containing list of basic blocks to not extract"),
154 cl::Hidden);
155
146156 /// BlockExtractorPass - This pass is used by bugpoint to extract all blocks
147157 /// from the module into their own functions except for those specified by the
148158 /// BlocksToNotExtract list.
149159 class BlockExtractorPass : public ModulePass {
160 void LoadFile(const char *Filename);
161
150162 std::vector BlocksToNotExtract;
163 std::vector > BlocksToNotExtractByName;
151164 public:
152165 static char ID; // Pass identification, replacement for typeid
153166 explicit BlockExtractorPass(const std::vector &B)
154 : ModulePass((intptr_t)&ID), BlocksToNotExtract(B) {}
167 : ModulePass((intptr_t)&ID), BlocksToNotExtract(B) {
168 if (!BlockFile.empty())
169 LoadFile(BlockFile.c_str());
170 }
155171 BlockExtractorPass() : ModulePass((intptr_t)&ID) {}
156172
157173 bool runOnModule(Module &M);
168184 ModulePass *llvm::createBlockExtractorPass(const std::vector &BTNE)
169185 {
170186 return new BlockExtractorPass(BTNE);
187 }
188
189 void BlockExtractorPass::LoadFile(const char *Filename) {
190 // Load the BlockFile...
191 std::ifstream In(Filename);
192 if (!In.good()) {
193 cerr << "WARNING: BlockExtractor couldn't load file '" << Filename
194 << "'!\n";
195 return;
196 }
197 while (In) {
198 std::string FunctionName, BlockName;
199 In >> FunctionName;
200 In >> BlockName;
201 if (!BlockName.empty())
202 BlocksToNotExtractByName.push_back(
203 std::make_pair(FunctionName, BlockName));
204 }
171205 }
172206
173207 bool BlockExtractorPass::runOnModule(Module &M) {
184218 Function::iterator BBI = MF->begin();
185219 std::advance(BBI, std::distance(F->begin(), Function::iterator(BB)));
186220 TranslatedBlocksToNotExtract.insert(BBI);
221 }
222
223 while (!BlocksToNotExtractByName.empty()) {
224 // There's no way to find BBs by name without looking at every BB inside
225 // every Function. Fortunately, this is always empty except when used by
226 // bugpoint in which case correctness is more important than performance.
227
228 std::string &FuncName = BlocksToNotExtractByName.back().first;
229 std::string &BlockName = BlocksToNotExtractByName.back().second;
230
231 for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
232 Function &F = *FI;
233 if (F.getName() != FuncName) continue;
234
235 for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
236 BasicBlock &BB = *BI;
237 if (BB.getName() != BlockName) continue;
238
239 TranslatedBlocksToNotExtract.insert(BI);
240 }
241 }
242
243 BlocksToNotExtractByName.pop_back();
187244 }
188245
189246 // Now that we know which blocks to not extract, figure out which ones we WANT
233233 /// automatically attempt to track down a crashing pass if one exists, and
234234 /// this method will never return null.
235235 Module *runPassesOn(Module *M, const std::vector &Passes,
236 bool AutoDebugCrashes = false);
236 bool AutoDebugCrashes = false, unsigned NumExtraArgs = 0,
237 const char * const *ExtraArgs = NULL);
237238
238239 /// runPasses - Run the specified passes on Program, outputting a bitcode
239240 /// file and writting the filename into OutputFile if successful. If the
241242 /// otherwise return false. If DeleteOutput is set to true, the bitcode is
242243 /// deleted on success, and the filename string is undefined. This prints to
243244 /// cout a single line message indicating whether compilation was successful
244 /// or failed, unless Quiet is set.
245 /// or failed, unless Quiet is set. ExtraArgs specifies additional arguments
246 /// to pass to the child bugpoint instance.
245247 ///
246248 bool runPasses(const std::vector &PassesToRun,
247249 std::string &OutputFilename, bool DeleteOutput = false,
248 bool Quiet = false) const;
250 bool Quiet = false, unsigned NumExtraArgs = 0,
251 const char * const *ExtraArgs = NULL) const;
249252
250253 /// runManyPasses - Take the specified pass list and create different
251254 /// combinations of passes to compile the program with. Compile the program with
2626 #include "llvm/Support/CommandLine.h"
2727 #include "llvm/Support/Debug.h"
2828 #include "llvm/Support/FileUtilities.h"
29 #include "llvm/System/Path.h"
30 #include "llvm/System/Signals.h"
2931 #include
32 #include
3033 #include
3134 using namespace llvm;
3235
304307 Module *BugDriver::ExtractMappedBlocksFromModule(const
305308 std::vector &BBs,
306309 Module *M) {
310 char *ExtraArg = NULL;
311
312 sys::Path uniqueFilename("bugpoint-extractblocks");
313 std::string ErrMsg;
314 if (uniqueFilename.createTemporaryFileOnDisk(true, &ErrMsg)) {
315 std::cout << "*** Basic Block extraction failed!\n";
316 std::cerr << "Error creating temporary file: " << ErrMsg << "\n";
317 M = swapProgramIn(M);
318 EmitProgressBitcode("basicblockextractfail", true);
319 swapProgramIn(M);
320 return 0;
321 }
322 sys::RemoveFileOnSignal(uniqueFilename);
323
324 std::ofstream BlocksToNotExtractFile(uniqueFilename.c_str());
325 if (!BlocksToNotExtractFile) {
326 std::cout << "*** Basic Block extraction failed!\n";
327 std::cerr << "Error writing list of blocks to not extract: " << ErrMsg
328 << "\n";
329 M = swapProgramIn(M);
330 EmitProgressBitcode("basicblockextractfail", true);
331 swapProgramIn(M);
332 return 0;
333 }
334 for (std::vector::const_iterator I = BBs.begin(), E = BBs.end();
335 I != E; ++I) {
336 BasicBlock *BB = *I;
337 BlocksToNotExtractFile << BB->getParent()->getName() << " "
338 << BB->getName() << "\n";
339 }
340 BlocksToNotExtractFile.close();
341
342 const char *uniqueFN = uniqueFilename.c_str();
343 ExtraArg = (char*)malloc(23 + strlen(uniqueFN));
344 strcat(strcpy(ExtraArg, "--extract-blocks-file="), uniqueFN);
345
307346 std::vector PI;
308 // FIXME: BBs is actually ignored. See http://llvm.org/PR1775
309 PI.push_back(getPI(createBlockExtractorPass(BBs)));
310 Module *Ret = runPassesOn(M, PI);
347 std::vector EmptyBBs; // This parameter is ignored.
348 PI.push_back(getPI(createBlockExtractorPass(EmptyBBs)));
349 Module *Ret = runPassesOn(M, PI, false, 1, &ExtraArg);
350
351 if (uniqueFilename.exists())
352 uniqueFilename.eraseFromDisk(); // Free disk space
353 free(ExtraArg);
354
311355 if (Ret == 0) {
312356 std::cout << "*** Basic Block extraction failed, please report a bug!\n";
313357 M = swapProgramIn(M);
222222 Module *ToNotOptimize = CloneModule(BD.getProgram());
223223 Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, Funcs);
224224
225 // Run the predicate, not that the predicate will delete both input modules.
225 // Run the predicate, note that the predicate will delete both input modules.
226226 return TestFn(BD, ToOptimize, ToNotOptimize);
227227 }
228228
123123 ///
124124 bool BugDriver::runPasses(const std::vector &Passes,
125125 std::string &OutputFilename, bool DeleteOutput,
126 bool Quiet) const {
126 bool Quiet, unsigned NumExtraArgs,
127 const char * const *ExtraArgs) const {
127128 // setup the output file name
128129 cout << std::flush;
129130 sys::Path uniqueFilename("bugpoint-output.bc");
155156 // setup the child process' arguments
156157 const char** args = (const char**)
157158 alloca(sizeof(const char*) *
158 (Passes.size()+13+2*PluginLoader::getNumPlugins()));
159 (Passes.size()+13+2*PluginLoader::getNumPlugins()+NumExtraArgs));
159160 int n = 0;
160161 sys::Path tool = sys::Program::FindProgramByName(ToolName);
161162 if (UseValgrind) {
181182 E = pass_args.end(); I != E; ++I )
182183 args[n++] = I->c_str();
183184 args[n++] = inputFilename.c_str();
185 for (unsigned i = 0; i < NumExtraArgs; ++i)
186 args[n++] = *ExtraArgs;
184187 args[n++] = 0;
185188
186189 sys::Path prog;
224227 /// failure.
225228 Module *BugDriver::runPassesOn(Module *M,
226229 const std::vector &Passes,
227 bool AutoDebugCrashes) {
230 bool AutoDebugCrashes, unsigned NumExtraArgs,
231 const char * const *ExtraArgs) {
228232 Module *OldProgram = swapProgramIn(M);
229233 std::string BitcodeResult;
230 if (runPasses(Passes, BitcodeResult, false/*delete*/, true/*quiet*/)) {
234 if (runPasses(Passes, BitcodeResult, false/*delete*/, true/*quiet*/,
235 NumExtraArgs, ExtraArgs)) {
231236 if (AutoDebugCrashes) {
232237 cerr << " Error running this sequence of passes"
233238 << " on the input program!\n";