]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/bugpoint/FindBugs.cpp
Merge ^/head r311812 through r311939.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / bugpoint / FindBugs.cpp
1 //===-- FindBugs.cpp - Run Many Different Optimizations -------------------===//
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 an interface that allows bugpoint to choose different
11 // combinations of optimizations to run on the selected input. Bugpoint will
12 // run these optimizations and record the success/failure of each. This way
13 // we can hopefully spot bugs in the optimizations.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #include "BugDriver.h"
18 #include "ToolRunner.h"
19 #include "llvm/Pass.h"
20 #include "llvm/Support/FileSystem.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include <algorithm>
23 #include <ctime>
24 using namespace llvm;
25
26 Error
27 BugDriver::runManyPasses(const std::vector<std::string> &AllPasses) {
28   setPassesToRun(AllPasses);
29   outs() << "Starting bug finding procedure...\n\n";
30
31   // Creating a reference output if necessary
32   if (Error E = initializeExecutionEnvironment())
33     return E;
34
35   outs() << "\n";
36   if (ReferenceOutputFile.empty()) {
37     outs() << "Generating reference output from raw program: \n";
38     if (Error E = createReferenceFile(Program))
39       return E;
40   }
41
42   srand(time(nullptr));
43
44   unsigned num = 1;
45   while (1) {
46     //
47     // Step 1: Randomize the order of the optimizer passes.
48     //
49     std::random_shuffle(PassesToRun.begin(), PassesToRun.end());
50
51     //
52     // Step 2: Run optimizer passes on the program and check for success.
53     //
54     outs() << "Running selected passes on program to test for crash: ";
55     for (int i = 0, e = PassesToRun.size(); i != e; i++) {
56       outs() << "-" << PassesToRun[i] << " ";
57     }
58
59     std::string Filename;
60     if (runPasses(Program, PassesToRun, Filename, false)) {
61       outs() << "\n";
62       outs() << "Optimizer passes caused failure!\n\n";
63       return debugOptimizerCrash();
64     } else {
65       outs() << "Combination " << num << " optimized successfully!\n";
66     }
67
68     //
69     // Step 3: Compile the optimized code.
70     //
71     outs() << "Running the code generator to test for a crash: ";
72     if (Error E = compileProgram(Program)) {
73       outs() << "\n*** compileProgram threw an exception: ";
74       outs() << toString(std::move(E));
75       return debugCodeGeneratorCrash();
76     }
77     outs() << '\n';
78
79     //
80     // Step 4: Run the program and compare its output to the reference
81     // output (created above).
82     //
83     outs() << "*** Checking if passes caused miscompliation:\n";
84     Expected<bool> Diff = diffProgram(Program, Filename, "", false);
85     if (Error E = Diff.takeError()) {
86       errs() << toString(std::move(E));
87       return debugCodeGeneratorCrash();
88     }
89     if (*Diff) {
90       outs() << "\n*** diffProgram returned true!\n";
91       Error E = debugMiscompilation();
92       if (!E)
93         return Error::success();
94     }
95     outs() << "\n*** diff'd output matches!\n";
96
97     sys::fs::remove(Filename);
98
99     outs() << "\n\n";
100     num++;
101   } // end while
102
103   // Unreachable.
104 }