llvm.org GIT mirror llvm / 1d9ab25
[PM] Wire up the Verifier for the new pass manager and connect it to the various opt verifier commandline options. Mostly mechanical wiring of the verifier to the new pass manager. Exercises one of the more unusual aspects of it -- a pass can be either a module or function pass interchangably. If this is ever problematic, we can make things more constrained, but for things like the verifier where there is an "obvious" applicability at both levels, it seems convenient. This is the next-to-last piece of basic functionality left to make the opt commandline driving of the new pass manager minimally functional for testing and further development. There is still a lot to be done there (notably the factoring into .def files to kill the current boilerplate code) but it is relatively uninteresting. The only interesting bit left for minimal functionality is supporting the registration of analyses. I'm planning on doing that on top of the .def file switch mostly because the boilerplate for the analyses would be significantly worse. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199646 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 5 years ago
10 changed file(s) with 121 addition(s) and 30 deletion(s). Raw diff Collapse all Expand all
2020 #ifndef LLVM_IR_VERIFIER_H
2121 #define LLVM_IR_VERIFIER_H
2222
23 #include "llvm/ADT/StringRef.h"
2324 #include
2425
2526 namespace llvm {
2627
28 class Function;
2729 class FunctionPass;
2830 class Module;
29 class Function;
31 class PreservedAnalyses;
3032 class raw_ostream;
3133
3234 /// \brief Check a function for errors, useful for use when debugging a
5153 /// functionality. When the pass detects a verification error it is always
5254 /// printed to stderr, and by default they are fatal. You can override that by
5355 /// passing \c false to \p FatalErrors.
56 ///
57 /// Note that this creates a pass suitable for the legacy pass manager. It has nothing to do with \c VerifierPass.
5458 FunctionPass *createVerifierPass(bool FatalErrors = true);
59
60 class VerifierPass {
61 bool FatalErrors;
62
63 public:
64 explicit VerifierPass(bool FatalErrors = true) : FatalErrors(FatalErrors) {}
65
66 PreservedAnalyses run(Module *M);
67 PreservedAnalyses run(Function *F);
68
69 static StringRef name() { return "VerifierPass"; }
70 };
5571
5672 } // End llvm namespace
5773
255255 void initializeUnifyFunctionExitNodesPass(PassRegistry&);
256256 void initializeUnreachableBlockElimPass(PassRegistry&);
257257 void initializeUnreachableMachineBlockElimPass(PassRegistry&);
258 void initializeVerifierPassPass(PassRegistry&);
258 void initializeVerifierLegacyPassPass(PassRegistry&);
259259 void initializeVirtRegMapPass(PassRegistry&);
260260 void initializeVirtRegRewriterPass(PassRegistry&);
261261 void initializeInstSimplifierPass(PassRegistry&);
4343 initializePrintModulePassWrapperPass(Registry);
4444 initializePrintFunctionPassWrapperPass(Registry);
4545 initializePrintBasicBlockPassPass(Registry);
46 initializeVerifierPassPass(Registry);
46 initializeVerifierLegacyPassPass(Registry);
4747 }
4848
4949 void LLVMInitializeCore(LLVMPassRegistryRef R) {
6161 #include "llvm/IR/LLVMContext.h"
6262 #include "llvm/IR/Metadata.h"
6363 #include "llvm/IR/Module.h"
64 #include "llvm/IR/PassManager.h"
6465 #include "llvm/InstVisitor.h"
6566 #include "llvm/Pass.h"
66 #include "llvm/PassManager.h"
6767 #include "llvm/Support/CFG.h"
6868 #include "llvm/Support/CallSite.h"
6969 #include "llvm/Support/CommandLine.h"
23862386 }
23872387
23882388 namespace {
2389 struct VerifierPass : public FunctionPass {
2389 struct VerifierLegacyPass : public FunctionPass {
23902390 static char ID;
23912391
23922392 Verifier V;
23932393 bool FatalErrors;
23942394
2395 VerifierPass() : FunctionPass(ID), FatalErrors(true) {
2396 initializeVerifierPassPass(*PassRegistry::getPassRegistry());
2397 }
2398 explicit VerifierPass(bool FatalErrors)
2395 VerifierLegacyPass() : FunctionPass(ID), FatalErrors(true) {
2396 initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry());
2397 }
2398 explicit VerifierLegacyPass(bool FatalErrors)
23992399 : FunctionPass(ID), V(dbgs()), FatalErrors(FatalErrors) {
2400 initializeVerifierPassPass(*PassRegistry::getPassRegistry());
2400 initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry());
24012401 }
24022402
24032403 bool runOnFunction(Function &F) {
24202420 };
24212421 }
24222422
2423 char VerifierPass::ID = 0;
2424 INITIALIZE_PASS(VerifierPass, "verify", "Module Verifier", false, false)
2423 char VerifierLegacyPass::ID = 0;
2424 INITIALIZE_PASS(VerifierLegacyPass, "verify", "Module Verifier", false, false)
24252425
24262426 FunctionPass *llvm::createVerifierPass(bool FatalErrors) {
2427 return new VerifierPass(FatalErrors);
2428 }
2429
2427 return new VerifierLegacyPass(FatalErrors);
2428 }
2429
2430 PreservedAnalyses VerifierPass::run(Module *M) {
2431 if (verifyModule(*M, &dbgs()) && FatalErrors)
2432 report_fatal_error("Broken module found, compilation aborted!");
2433
2434 return PreservedAnalyses::all();
2435 }
2436
2437 PreservedAnalyses VerifierPass::run(Function *F) {
2438 if (verifyFunction(*F, &dbgs()) && FatalErrors)
2439 report_fatal_error("Broken function found, compilation aborted!");
2440
2441 return PreservedAnalyses::all();
2442 }
77 ; RUN: opt -disable-output -debug-pass-manager -passes=print %s 2>&1 \
88 ; RUN: | FileCheck %s --check-prefix=CHECK-MODULE-PRINT
99 ; CHECK-MODULE-PRINT: Starting module pass manager
10 ; CHECK-MODULE-PRINT: Running module pass: VerifierPass
1011 ; CHECK-MODULE-PRINT: Running module pass: PrintModulePass
1112 ; CHECK-MODULE-PRINT: ModuleID
1213 ; CHECK-MODULE-PRINT: define void @foo()
14 ; CHECK-MODULE-PRINT: Running module pass: VerifierPass
1315 ; CHECK-MODULE-PRINT: Finished module pass manager
1416
1517 ; RUN: opt -disable-output -debug-pass-manager -passes='function(print)' %s 2>&1 \
1618 ; RUN: | FileCheck %s --check-prefix=CHECK-FUNCTION-PRINT
1719 ; CHECK-FUNCTION-PRINT: Starting module pass manager
20 ; CHECK-FUNCTION-PRINT: Running module pass: VerifierPass
1821 ; CHECK-FUNCTION-PRINT: Starting function pass manager
1922 ; CHECK-FUNCTION-PRINT: Running function pass: PrintFunctionPass
2023 ; CHECK-FUNCTION-PRINT-NOT: ModuleID
2124 ; CHECK-FUNCTION-PRINT: define void @foo()
2225 ; CHECK-FUNCTION-PRINT: Finished function pass manager
26 ; CHECK-FUNCTION-PRINT: Running module pass: VerifierPass
2327 ; CHECK-FUNCTION-PRINT: Finished module pass manager
2428
2529 ; RUN: opt -S -o - -passes='no-op-module,no-op-module' %s \
3337 ; RUN: | llvm-dis \
3438 ; RUN: | FileCheck %s --check-prefix=CHECK-NOOP
3539
40 ; RUN: opt -disable-output -debug-pass-manager -verify-each -passes='no-op-module,function(no-op-function)' %s 2>&1 \
41 ; RUN: | FileCheck %s --check-prefix=CHECK-VERIFY-EACH
42 ; CHECK-VERIFY-EACH: Starting module pass manager
43 ; CHECK-VERIFY-EACH: Running module pass: VerifierPass
44 ; CHECK-VERIFY-EACH: Running module pass: NoOpModulePass
45 ; CHECK-VERIFY-EACH: Running module pass: VerifierPass
46 ; CHECK-VERIFY-EACH: Starting function pass manager
47 ; CHECK-VERIFY-EACH: Running function pass: NoOpFunctionPass
48 ; CHECK-VERIFY-EACH: Running function pass: VerifierPass
49 ; CHECK-VERIFY-EACH: Finished function pass manager
50 ; CHECK-VERIFY-EACH: Running module pass: VerifierPass
51 ; CHECK-VERIFY-EACH: Finished module pass manager
52
53 ; RUN: opt -disable-output -debug-pass-manager -disable-verify -passes='no-op-module,function(no-op-function)' %s 2>&1 \
54 ; RUN: | FileCheck %s --check-prefix=CHECK-NO-VERIFY
55 ; CHECK-NO-VERIFY: Starting module pass manager
56 ; CHECK-NO-VERIFY-NOT: VerifierPass
57 ; CHECK-NO-VERIFY: Running module pass: NoOpModulePass
58 ; CHECK-NO-VERIFY-NOT: VerifierPass
59 ; CHECK-NO-VERIFY: Starting function pass manager
60 ; CHECK-NO-VERIFY: Running function pass: NoOpFunctionPass
61 ; CHECK-NO-VERIFY-NOT: VerifierPass
62 ; CHECK-NO-VERIFY: Finished function pass manager
63 ; CHECK-NO-VERIFY-NOT: VerifierPass
64 ; CHECK-NO-VERIFY: Finished module pass manager
65
3666 define void @foo() {
3767 ret void
3868 }
2020 #include "llvm/IR/LLVMContext.h"
2121 #include "llvm/IR/Module.h"
2222 #include "llvm/IR/PassManager.h"
23 #include "llvm/IR/Verifier.h"
2324 #include "llvm/Support/CommandLine.h"
2425 #include "llvm/Support/ErrorHandling.h"
2526 #include "llvm/Support/ToolOutputFile.h"
2930
3031 bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
3132 tool_output_file *Out, StringRef PassPipeline,
32 OutputKind OK) {
33 OutputKind OK, VerifierKind VK) {
3334 ModulePassManager MPM;
34 if (!parsePassPipeline(MPM, PassPipeline)) {
35
36 if (VK > VK_NoVerifier)
37 MPM.addPass(VerifierPass());
38
39 if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass)) {
3540 errs() << Arg0 << ": unable to parse pass pipeline description.\n";
3641 return false;
3742 }
43
44 if (VK > VK_NoVerifier)
45 MPM.addPass(VerifierPass());
3846
3947 // Add any relevant output pass at the end of the pipeline.
4048 switch (OK) {
3333 OK_OutputAssembly,
3434 OK_OutputBitcode
3535 };
36 enum VerifierKind {
37 VK_NoVerifier,
38 VK_VerifyInAndOut,
39 VK_VerifyEachPass
40 };
3641 }
3742
3843 /// \brief Driver function to run the new pass manager over a module.
4348 /// when the transition finishes.
4449 bool runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
4550 tool_output_file *Out, StringRef PassPipeline,
46 opt_tool::OutputKind OK);
51 opt_tool::OutputKind OK, opt_tool::VerifierKind VK);
4752 }
4853
4954 #endif
1616 #include "Passes.h"
1717 #include "llvm/IR/IRPrintingPasses.h"
1818 #include "llvm/IR/PassManager.h"
19 #include "llvm/IR/Verifier.h"
1920 #include "llvm/Support/Debug.h"
2021
2122 using namespace llvm;
7778 }
7879
7980 static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
80 StringRef &PipelineText) {
81 StringRef &PipelineText,
82 bool VerifyEachPass) {
8183 for (;;) {
8284 // Parse nested pass managers by recursing.
8385 if (PipelineText.startswith("function(")) {
8587
8688 // Parse the inner pipeline inte the nested manager.
8789 PipelineText = PipelineText.substr(strlen("function("));
88 if (!parseFunctionPassPipeline(NestedFPM, PipelineText) ||
90 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
8991 PipelineText.empty())
9092 return false;
9193 assert(PipelineText[0] == ')');
98100 size_t End = PipelineText.find_first_of(",)");
99101 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
100102 return false;
103 if (VerifyEachPass)
104 FPM.addPass(VerifierPass());
101105
102106 PipelineText = PipelineText.substr(End);
103107 }
111115 }
112116
113117 static bool parseModulePassPipeline(ModulePassManager &MPM,
114 StringRef &PipelineText) {
118 StringRef &PipelineText,
119 bool VerifyEachPass) {
115120 for (;;) {
116121 // Parse nested pass managers by recursing.
117122 if (PipelineText.startswith("module(")) {
119124
120125 // Parse the inner pipeline into the nested manager.
121126 PipelineText = PipelineText.substr(strlen("module("));
122 if (!parseModulePassPipeline(NestedMPM, PipelineText) ||
127 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) ||
123128 PipelineText.empty())
124129 return false;
125130 assert(PipelineText[0] == ')');
132137
133138 // Parse the inner pipeline inte the nested manager.
134139 PipelineText = PipelineText.substr(strlen("function("));
135 if (!parseFunctionPassPipeline(NestedFPM, PipelineText) ||
140 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
136141 PipelineText.empty())
137142 return false;
138143 assert(PipelineText[0] == ')');
145150 size_t End = PipelineText.find_first_of(",)");
146151 if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
147152 return false;
153 if (VerifyEachPass)
154 MPM.addPass(VerifierPass());
148155
149156 PipelineText = PipelineText.substr(End);
150157 }
160167 // Primary pass pipeline description parsing routine.
161168 // FIXME: Should this routine accept a TargetMachine or require the caller to
162169 // pre-populate the analysis managers with target-specific stuff?
163 bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText) {
170 bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
171 bool VerifyEachPass) {
164172 // Look at the first entry to figure out which layer to start parsing at.
165173 if (PipelineText.startswith("module("))
166 return parseModulePassPipeline(MPM, PipelineText) && PipelineText.empty();
174 return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
175 PipelineText.empty();
167176 if (PipelineText.startswith("function(")) {
168177 FunctionPassManager FPM;
169 if (!parseFunctionPassPipeline(FPM, PipelineText) || !PipelineText.empty())
178 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
179 !PipelineText.empty())
170180 return false;
171181 MPM.addPass(createModuleToFunctionPassAdaptor(FPM));
172182 return true;
176186 StringRef FirstName =
177187 PipelineText.substr(0, PipelineText.find_first_of(",)"));
178188 if (isModulePassName(FirstName))
179 return parseModulePassPipeline(MPM, PipelineText) && PipelineText.empty();
189 return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
190 PipelineText.empty();
180191
181192 if (isFunctionPassName(FirstName)) {
182193 FunctionPassManager FPM;
183 if (!parseFunctionPassPipeline(FPM, PipelineText) || !PipelineText.empty())
194 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
195 !PipelineText.empty())
184196 return false;
185197 MPM.addPass(createModuleToFunctionPassAdaptor(FPM));
186198 return true;
4848 /// the sequence of passes aren't all the exact same kind of pass, it will be
4949 /// an error. You cannot mix different levels implicitly, you must explicitly
5050 /// form a pass manager in which to nest passes.
51 bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText);
51 bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
52 bool VerifyEachPass = true);
5253
5354 }
5455
675675 if (!NoOutput)
676676 OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode;
677677
678 VerifierKind VK = VK_VerifyInAndOut;
679 if (NoVerify)
680 VK = VK_NoVerifier;
681 else if (VerifyEach)
682 VK = VK_VerifyEachPass;
683
678684 // The user has asked to use the new pass manager and provided a pipeline
679685 // string. Hand off the rest of the functionality to the new code for that
680686 // layer.
681687 return runPassPipeline(argv[0], Context, *M.get(), Out.get(), PassPipeline,
682 OK)
688 OK, VK)
683689 ? 0
684690 : 1;
685691 }