1 //===- CrashDebugger.cpp - Debug compilation crashes ----------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the bugpoint internals that narrow down compilation crashes 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "BugDriver.h" 15 #include "ToolRunner.h" 16 #include "ListReducer.h" 17 #include "llvm/Constants.h" 18 #include "llvm/DerivedTypes.h" 19 #include "llvm/Instructions.h" 20 #include "llvm/Module.h" 21 #include "llvm/Pass.h" 22 #include "llvm/PassManager.h" 23 #include "llvm/ValueSymbolTable.h" 24 #include "llvm/ADT/SmallPtrSet.h" 25 #include "llvm/Analysis/Verifier.h" 26 #include "llvm/Support/CFG.h" 27 #include "llvm/Transforms/Scalar.h" 28 #include "llvm/Transforms/Utils/Cloning.h" 29 #include "llvm/Support/FileUtilities.h" 30 #include "llvm/Support/CommandLine.h" 31 #include <set> 32 using namespace llvm; 33 34 namespace { 35 cl::opt<bool> 36 KeepMain("keep-main", 37 cl::desc("Force function reduction to keep main"), 38 cl::init(false)); 39 cl::opt<bool> 40 NoGlobalRM ("disable-global-remove", 41 cl::desc("Do not remove global variables"), 42 cl::init(false)); 43 } 44 45 namespace llvm { 46 class ReducePassList : public ListReducer<const PassInfo*> { 47 BugDriver &BD; 48 public: 49 ReducePassList(BugDriver &bd) : BD(bd) {} 50 51 // doTest - Return true iff running the "removed" passes succeeds, and 52 // running the "Kept" passes fail when run on the output of the "removed" 53 // passes. If we return true, we update the current module of bugpoint. 54 // 55 virtual TestResult doTest(std::vector<const PassInfo*> &Removed, 56 std::vector<const PassInfo*> &Kept); 57 }; 58 } 59 60 ReducePassList::TestResult 61 ReducePassList::doTest(std::vector<const PassInfo*> &Prefix, 62 std::vector<const PassInfo*> &Suffix) { 63 sys::Path PrefixOutput; 64 Module *OrigProgram = 0; 65 if (!Prefix.empty()) { 66 outs() << "Checking to see if these passes crash: " 67 << getPassesString(Prefix) << ": "; 68 std::string PfxOutput; 69 if (BD.runPasses(Prefix, PfxOutput)) 70 return KeepPrefix; 71 72 PrefixOutput.set(PfxOutput); 73 OrigProgram = BD.Program; 74 75 BD.Program = ParseInputFile(PrefixOutput.toString(), BD.getContext()); 76 if (BD.Program == 0) { 77 errs() << BD.getToolName() << ": Error reading bitcode file '" 78 << PrefixOutput << "'!\n"; 79 exit(1); 80 } 81 PrefixOutput.eraseFromDisk(); 82 } 83 84 outs() << "Checking to see if these passes crash: " 85 << getPassesString(Suffix) << ": "; 86 87 if (BD.runPasses(Suffix)) { 88 delete OrigProgram; // The suffix crashes alone... 89 return KeepSuffix; 90 } 91 92 // Nothing failed, restore state... 93 if (OrigProgram) { 94 delete BD.Program; 95 BD.Program = OrigProgram; 96 } 97 return NoFailure; 98 } 99 100 namespace { 101 /// ReduceCrashingGlobalVariables - This works by removing the global 102 /// variable's initializer and seeing if the program still crashes. If it 103 /// does, then we keep that program and try again. 104 /// 105 class ReduceCrashingGlobalVariables : public ListReducer<GlobalVariable*> { 106 BugDriver &BD; 107 bool (*TestFn)(BugDriver &, Module *); 108 public: 109 ReduceCrashingGlobalVariables(BugDriver &bd, 110 bool (*testFn)(BugDriver&, Module*)) 111 : BD(bd), TestFn(testFn) {} 112 113 virtual TestResult doTest(std::vector<GlobalVariable*>& Prefix, 114 std::vector<GlobalVariable*>& Kept) { 115 if (!Kept.empty() && TestGlobalVariables(Kept)) 116 return KeepSuffix; 117 118 if (!Prefix.empty() && TestGlobalVariables(Prefix)) 119 return KeepPrefix; 120 121 return NoFailure; 122 } 123 124 bool TestGlobalVariables(std::vector<GlobalVariable*>& GVs); 125 }; 126 } 127 128 bool 129 ReduceCrashingGlobalVariables::TestGlobalVariables( 130 std::vector<GlobalVariable*>& GVs) { 131 // Clone the program to try hacking it apart... 132 DenseMap<const Value*, Value*> ValueMap; 133 Module *M = CloneModule(BD.getProgram(), ValueMap); 134 135 // Convert list to set for fast lookup... 136 std::set<GlobalVariable*> GVSet; 137 138 for (unsigned i = 0, e = GVs.size(); i != e; ++i) { 139 GlobalVariable* CMGV = cast<GlobalVariable>(ValueMap[GVs[i]]); 140 assert(CMGV && "Global Variable not in module?!"); 141 GVSet.insert(CMGV); 142 } 143 144 outs() << "Checking for crash with only these global variables: "; 145 PrintGlobalVariableList(GVs); 146 outs() << ": "; 147 148 // Loop over and delete any global variables which we aren't supposed to be 149 // playing with... 150 for (Module::global_iterator I = M->global_begin(), E = M->global_end(); 151 I != E; ++I) 152 if (I->hasInitializer() && !GVSet.count(I)) { 153 I->setInitializer(0); 154 I->setLinkage(GlobalValue::ExternalLinkage); 155 } 156 157 // Try running the hacked up program... 158 if (TestFn(BD, M)) { 159 BD.setNewProgram(M); // It crashed, keep the trimmed version... 160 161 // Make sure to use global variable pointers that point into the now-current 162 // module. 163 GVs.assign(GVSet.begin(), GVSet.end()); 164 return true; 165 } 166 167 delete M; 168 return false; 169 } 170 171 namespace llvm { 172 /// ReduceCrashingFunctions reducer - This works by removing functions and 173 /// seeing if the program still crashes. If it does, then keep the newer, 174 /// smaller program. 175 /// 176 class ReduceCrashingFunctions : public ListReducer<Function*> { 177 BugDriver &BD; 178 bool (*TestFn)(BugDriver &, Module *); 179 public: 180 ReduceCrashingFunctions(BugDriver &bd, 181 bool (*testFn)(BugDriver &, Module *)) 182 : BD(bd), TestFn(testFn) {} 183 184 virtual TestResult doTest(std::vector<Function*> &Prefix, 185 std::vector<Function*> &Kept) { 186 if (!Kept.empty() && TestFuncs(Kept)) 187 return KeepSuffix; 188 if (!Prefix.empty() && TestFuncs(Prefix)) 189 return KeepPrefix; 190 return NoFailure; 191 } 192 193 bool TestFuncs(std::vector<Function*> &Prefix); 194 }; 195 } 196 197 bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) { 198 199 //if main isn't present, claim there is no problem 200 if (KeepMain && find(Funcs.begin(), Funcs.end(), 201 BD.getProgram()->getFunction("main")) == Funcs.end()) 202 return false; 203 204 // Clone the program to try hacking it apart... 205 DenseMap<const Value*, Value*> ValueMap; 206 Module *M = CloneModule(BD.getProgram(), ValueMap); 207 208 // Convert list to set for fast lookup... 209 std::set<Function*> Functions; 210 for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { 211 Function *CMF = cast<Function>(ValueMap[Funcs[i]]); 212 assert(CMF && "Function not in module?!"); 213 assert(CMF->getFunctionType() == Funcs[i]->getFunctionType() && "wrong ty"); 214 assert(CMF->getName() == Funcs[i]->getName() && "wrong name"); 215 Functions.insert(CMF); 216 } 217 218 outs() << "Checking for crash with only these functions: "; 219 PrintFunctionList(Funcs); 220 outs() << ": "; 221 222 // Loop over and delete any functions which we aren't supposed to be playing 223 // with... 224 for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) 225 if (!I->isDeclaration() && !Functions.count(I)) 226 DeleteFunctionBody(I); 227 228 // Try running the hacked up program... 229 if (TestFn(BD, M)) { 230 BD.setNewProgram(M); // It crashed, keep the trimmed version... 231 232 // Make sure to use function pointers that point into the now-current 233 // module. 234 Funcs.assign(Functions.begin(), Functions.end()); 235 return true; 236 } 237 delete M; 238 return false; 239 } 240 241 242 namespace { 243 /// ReduceCrashingBlocks reducer - This works by setting the terminators of 244 /// all terminators except the specified basic blocks to a 'ret' instruction, 245 /// then running the simplify-cfg pass. This has the effect of chopping up 246 /// the CFG really fast which can reduce large functions quickly. 247 /// 248 class ReduceCrashingBlocks : public ListReducer<const BasicBlock*> { 249 BugDriver &BD; 250 bool (*TestFn)(BugDriver &, Module *); 251 public: 252 ReduceCrashingBlocks(BugDriver &bd, bool (*testFn)(BugDriver &, Module *)) 253 : BD(bd), TestFn(testFn) {} 254 255 virtual TestResult doTest(std::vector<const BasicBlock*> &Prefix, 256 std::vector<const BasicBlock*> &Kept) { 257 if (!Kept.empty() && TestBlocks(Kept)) 258 return KeepSuffix; 259 if (!Prefix.empty() && TestBlocks(Prefix)) 260 return KeepPrefix; 261 return NoFailure; 262 } 263 264 bool TestBlocks(std::vector<const BasicBlock*> &Prefix); 265 }; 266 } 267 268 bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) { 269 // Clone the program to try hacking it apart... 270 DenseMap<const Value*, Value*> ValueMap; 271 Module *M = CloneModule(BD.getProgram(), ValueMap); 272 273 // Convert list to set for fast lookup... 274 SmallPtrSet<BasicBlock*, 8> Blocks; 275 for (unsigned i = 0, e = BBs.size(); i != e; ++i) 276 Blocks.insert(cast<BasicBlock>(ValueMap[BBs[i]])); 277 278 outs() << "Checking for crash with only these blocks:"; 279 unsigned NumPrint = Blocks.size(); 280 if (NumPrint > 10) NumPrint = 10; 281 for (unsigned i = 0, e = NumPrint; i != e; ++i) 282 outs() << " " << BBs[i]->getName(); 283 if (NumPrint < Blocks.size()) 284 outs() << "... <" << Blocks.size() << " total>"; 285 outs() << ": "; 286 287 // Loop over and delete any hack up any blocks that are not listed... 288 for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) 289 for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB) 290 if (!Blocks.count(BB) && BB->getTerminator()->getNumSuccessors()) { 291 // Loop over all of the successors of this block, deleting any PHI nodes 292 // that might include it. 293 for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI) 294 (*SI)->removePredecessor(BB); 295 296 TerminatorInst *BBTerm = BB->getTerminator(); 297 298 if (isa<StructType>(BBTerm->getType())) 299 BBTerm->replaceAllUsesWith(UndefValue::get(BBTerm->getType())); 300 else if (BB->getTerminator()->getType() != Type::VoidTy) 301 BBTerm->replaceAllUsesWith(Constant::getNullValue(BBTerm->getType())); 302 303 // Replace the old terminator instruction. 304 BB->getInstList().pop_back(); 305 new UnreachableInst(BB); 306 } 307 308 // The CFG Simplifier pass may delete one of the basic blocks we are 309 // interested in. If it does we need to take the block out of the list. Make 310 // a "persistent mapping" by turning basic blocks into <function, name> pairs. 311 // This won't work well if blocks are unnamed, but that is just the risk we 312 // have to take. 313 std::vector<std::pair<Function*, std::string> > BlockInfo; 314 315 for (SmallPtrSet<BasicBlock*, 8>::iterator I = Blocks.begin(), 316 E = Blocks.end(); I != E; ++I) 317 BlockInfo.push_back(std::make_pair((*I)->getParent(), (*I)->getName())); 318 319 // Now run the CFG simplify pass on the function... 320 PassManager Passes; 321 Passes.add(createCFGSimplificationPass()); 322 Passes.add(createVerifierPass()); 323 Passes.run(*M); 324 325 // Try running on the hacked up program... 326 if (TestFn(BD, M)) { 327 BD.setNewProgram(M); // It crashed, keep the trimmed version... 328 329 // Make sure to use basic block pointers that point into the now-current 330 // module, and that they don't include any deleted blocks. 331 BBs.clear(); 332 for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) { 333 ValueSymbolTable &ST = BlockInfo[i].first->getValueSymbolTable(); 334 Value* V = ST.lookup(BlockInfo[i].second); 335 if (V && V->getType() == Type::LabelTy) 336 BBs.push_back(cast<BasicBlock>(V)); 337 } 338 return true; 339 } 340 delete M; // It didn't crash, try something else. 341 return false; 342 } 343 344 namespace { 345 /// ReduceCrashingInstructions reducer - This works by removing the specified 346 /// non-terminator instructions and replacing them with undef. 347 /// 348 class ReduceCrashingInstructions : public ListReducer<const Instruction*> { 349 BugDriver &BD; 350 bool (*TestFn)(BugDriver &, Module *); 351 public: 352 ReduceCrashingInstructions(BugDriver &bd, bool (*testFn)(BugDriver &, 353 Module *)) 354 : BD(bd), TestFn(testFn) {} 355 356 virtual TestResult doTest(std::vector<const Instruction*> &Prefix, 357 std::vector<const Instruction*> &Kept) { 358 if (!Kept.empty() && TestInsts(Kept)) 359 return KeepSuffix; 360 if (!Prefix.empty() && TestInsts(Prefix)) 361 return KeepPrefix; 362 return NoFailure; 363 } 364 365 bool TestInsts(std::vector<const Instruction*> &Prefix); 366 }; 367 } 368 369 bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*> 370 &Insts) { 371 // Clone the program to try hacking it apart... 372 DenseMap<const Value*, Value*> ValueMap; 373 Module *M = CloneModule(BD.getProgram(), ValueMap); 374 375 // Convert list to set for fast lookup... 376 SmallPtrSet<Instruction*, 64> Instructions; 377 for (unsigned i = 0, e = Insts.size(); i != e; ++i) { 378 assert(!isa<TerminatorInst>(Insts[i])); 379 Instructions.insert(cast<Instruction>(ValueMap[Insts[i]])); 380 } 381 382 outs() << "Checking for crash with only " << Instructions.size(); 383 if (Instructions.size() == 1) 384 outs() << " instruction: "; 385 else 386 outs() << " instructions: "; 387 388 for (Module::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) 389 for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI) 390 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E;) { 391 Instruction *Inst = I++; 392 if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst)) { 393 if (Inst->getType() != Type::VoidTy) 394 Inst->replaceAllUsesWith(UndefValue::get(Inst->getType())); 395 Inst->eraseFromParent(); 396 } 397 } 398 399 // Verify that this is still valid. 400 PassManager Passes; 401 Passes.add(createVerifierPass()); 402 Passes.run(*M); 403 404 // Try running on the hacked up program... 405 if (TestFn(BD, M)) { 406 BD.setNewProgram(M); // It crashed, keep the trimmed version... 407 408 // Make sure to use instruction pointers that point into the now-current 409 // module, and that they don't include any deleted blocks. 410 Insts.clear(); 411 for (SmallPtrSet<Instruction*, 64>::const_iterator I = Instructions.begin(), 412 E = Instructions.end(); I != E; ++I) 413 Insts.push_back(*I); 414 return true; 415 } 416 delete M; // It didn't crash, try something else. 417 return false; 418 } 419 420 /// DebugACrash - Given a predicate that determines whether a component crashes 421 /// on a program, try to destructively reduce the program while still keeping 422 /// the predicate true. 423 static bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) { 424 // See if we can get away with nuking some of the global variable initializers 425 // in the program... 426 if (!NoGlobalRM && 427 BD.getProgram()->global_begin() != BD.getProgram()->global_end()) { 428 // Now try to reduce the number of global variable initializers in the 429 // module to something small. 430 Module *M = CloneModule(BD.getProgram()); 431 bool DeletedInit = false; 432 433 for (Module::global_iterator I = M->global_begin(), E = M->global_end(); 434 I != E; ++I) 435 if (I->hasInitializer()) { 436 I->setInitializer(0); 437 I->setLinkage(GlobalValue::ExternalLinkage); 438 DeletedInit = true; 439 } 440 441 if (!DeletedInit) { 442 delete M; // No change made... 443 } else { 444 // See if the program still causes a crash... 445 outs() << "\nChecking to see if we can delete global inits: "; 446 447 if (TestFn(BD, M)) { // Still crashes? 448 BD.setNewProgram(M); 449 outs() << "\n*** Able to remove all global initializers!\n"; 450 } else { // No longer crashes? 451 outs() << " - Removing all global inits hides problem!\n"; 452 delete M; 453 454 std::vector<GlobalVariable*> GVs; 455 456 for (Module::global_iterator I = BD.getProgram()->global_begin(), 457 E = BD.getProgram()->global_end(); I != E; ++I) 458 if (I->hasInitializer()) 459 GVs.push_back(I); 460 461 if (GVs.size() > 1 && !BugpointIsInterrupted) { 462 outs() << "\n*** Attempting to reduce the number of global " 463 << "variables in the testcase\n"; 464 465 unsigned OldSize = GVs.size(); 466 ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs); 467 468 if (GVs.size() < OldSize) 469 BD.EmitProgressBitcode("reduced-global-variables"); 470 } 471 } 472 } 473 } 474 475 // Now try to reduce the number of functions in the module to something small. 476 std::vector<Function*> Functions; 477 for (Module::iterator I = BD.getProgram()->begin(), 478 E = BD.getProgram()->end(); I != E; ++I) 479 if (!I->isDeclaration()) 480 Functions.push_back(I); 481 482 if (Functions.size() > 1 && !BugpointIsInterrupted) { 483 outs() << "\n*** Attempting to reduce the number of functions " 484 "in the testcase\n"; 485 486 unsigned OldSize = Functions.size(); 487 ReduceCrashingFunctions(BD, TestFn).reduceList(Functions); 488 489 if (Functions.size() < OldSize) 490 BD.EmitProgressBitcode("reduced-function"); 491 } 492 493 // Attempt to delete entire basic blocks at a time to speed up 494 // convergence... this actually works by setting the terminator of the blocks 495 // to a return instruction then running simplifycfg, which can potentially 496 // shrinks the code dramatically quickly 497 // 498 if (!DisableSimplifyCFG && !BugpointIsInterrupted) { 499 std::vector<const BasicBlock*> Blocks; 500 for (Module::const_iterator I = BD.getProgram()->begin(), 501 E = BD.getProgram()->end(); I != E; ++I) 502 for (Function::const_iterator FI = I->begin(), E = I->end(); FI !=E; ++FI) 503 Blocks.push_back(FI); 504 unsigned OldSize = Blocks.size(); 505 ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks); 506 if (Blocks.size() < OldSize) 507 BD.EmitProgressBitcode("reduced-blocks"); 508 } 509 510 // Attempt to delete instructions using bisection. This should help out nasty 511 // cases with large basic blocks where the problem is at one end. 512 if (!BugpointIsInterrupted) { 513 std::vector<const Instruction*> Insts; 514 for (Module::const_iterator MI = BD.getProgram()->begin(), 515 ME = BD.getProgram()->end(); MI != ME; ++MI) 516 for (Function::const_iterator FI = MI->begin(), FE = MI->end(); FI != FE; 517 ++FI) 518 for (BasicBlock::const_iterator I = FI->begin(), E = FI->end(); 519 I != E; ++I) 520 if (!isa<TerminatorInst>(I)) 521 Insts.push_back(I); 522 523 ReduceCrashingInstructions(BD, TestFn).reduceList(Insts); 524 } 525 526 // FIXME: This should use the list reducer to converge faster by deleting 527 // larger chunks of instructions at a time! 528 unsigned Simplification = 2; 529 do { 530 if (BugpointIsInterrupted) break; 531 --Simplification; 532 outs() << "\n*** Attempting to reduce testcase by deleting instruc" 533 << "tions: Simplification Level #" << Simplification << '\n'; 534 535 // Now that we have deleted the functions that are unnecessary for the 536 // program, try to remove instructions that are not necessary to cause the 537 // crash. To do this, we loop through all of the instructions in the 538 // remaining functions, deleting them (replacing any values produced with 539 // nulls), and then running ADCE and SimplifyCFG. If the transformed input 540 // still triggers failure, keep deleting until we cannot trigger failure 541 // anymore. 542 // 543 unsigned InstructionsToSkipBeforeDeleting = 0; 544 TryAgain: 545 546 // Loop over all of the (non-terminator) instructions remaining in the 547 // function, attempting to delete them. 548 unsigned CurInstructionNum = 0; 549 for (Module::const_iterator FI = BD.getProgram()->begin(), 550 E = BD.getProgram()->end(); FI != E; ++FI) 551 if (!FI->isDeclaration()) 552 for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E; 553 ++BI) 554 for (BasicBlock::const_iterator I = BI->begin(), E = --BI->end(); 555 I != E; ++I, ++CurInstructionNum) 556 if (InstructionsToSkipBeforeDeleting) { 557 --InstructionsToSkipBeforeDeleting; 558 } else { 559 if (BugpointIsInterrupted) goto ExitLoops; 560 561 outs() << "Checking instruction: " << *I; 562 Module *M = BD.deleteInstructionFromProgram(I, Simplification); 563 564 // Find out if the pass still crashes on this pass... 565 if (TestFn(BD, M)) { 566 // Yup, it does, we delete the old module, and continue trying 567 // to reduce the testcase... 568 BD.setNewProgram(M); 569 InstructionsToSkipBeforeDeleting = CurInstructionNum; 570 goto TryAgain; // I wish I had a multi-level break here! 571 } 572 573 // This pass didn't crash without this instruction, try the next 574 // one. 575 delete M; 576 } 577 578 if (InstructionsToSkipBeforeDeleting) { 579 InstructionsToSkipBeforeDeleting = 0; 580 goto TryAgain; 581 } 582 583 } while (Simplification); 584 ExitLoops: 585 586 // Try to clean up the testcase by running funcresolve and globaldce... 587 if (!BugpointIsInterrupted) { 588 outs() << "\n*** Attempting to perform final cleanups: "; 589 Module *M = CloneModule(BD.getProgram()); 590 M = BD.performFinalCleanups(M, true); 591 592 // Find out if the pass still crashes on the cleaned up program... 593 if (TestFn(BD, M)) { 594 BD.setNewProgram(M); // Yup, it does, keep the reduced version... 595 } else { 596 delete M; 597 } 598 } 599 600 BD.EmitProgressBitcode("reduced-simplified"); 601 602 return false; 603 } 604 605 static bool TestForOptimizerCrash(BugDriver &BD, Module *M) { 606 return BD.runPasses(M); 607 } 608 609 /// debugOptimizerCrash - This method is called when some pass crashes on input. 610 /// It attempts to prune down the testcase to something reasonable, and figure 611 /// out exactly which pass is crashing. 612 /// 613 bool BugDriver::debugOptimizerCrash(const std::string &ID) { 614 outs() << "\n*** Debugging optimizer crash!\n"; 615 616 // Reduce the list of passes which causes the optimizer to crash... 617 if (!BugpointIsInterrupted) 618 ReducePassList(*this).reduceList(PassesToRun); 619 620 outs() << "\n*** Found crashing pass" 621 << (PassesToRun.size() == 1 ? ": " : "es: ") 622 << getPassesString(PassesToRun) << '\n'; 623 624 EmitProgressBitcode(ID); 625 626 return DebugACrash(*this, TestForOptimizerCrash); 627 } 628 629 static bool TestForCodeGenCrash(BugDriver &BD, Module *M) { 630 try { 631 BD.compileProgram(M); 632 errs() << '\n'; 633 return false; 634 } catch (ToolExecutionError &) { 635 errs() << "<crash>\n"; 636 return true; // Tool is still crashing. 637 } 638 } 639 640 /// debugCodeGeneratorCrash - This method is called when the code generator 641 /// crashes on an input. It attempts to reduce the input as much as possible 642 /// while still causing the code generator to crash. 643 bool BugDriver::debugCodeGeneratorCrash() { 644 errs() << "*** Debugging code generator crash!\n"; 645 646 return DebugACrash(*this, TestForCodeGenCrash); 647 } 648