Mercurial > hg > CbC > CbC_llvm
comparison unittests/IR/PassBuilderCallbacksTest.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===- unittests/IR/PassBuilderCallbacksTest.cpp - PB Callback Tests --===// | 1 //===- unittests/IR/PassBuilderCallbacksTest.cpp - PB Callback Tests --===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 | 8 |
9 #include "llvm/Testing/Support/Error.h" | |
10 #include <functional> | |
10 #include <gmock/gmock.h> | 11 #include <gmock/gmock.h> |
11 #include <gtest/gtest.h> | 12 #include <gtest/gtest.h> |
13 #include <llvm/ADT/Any.h> | |
12 #include <llvm/Analysis/CGSCCPassManager.h> | 14 #include <llvm/Analysis/CGSCCPassManager.h> |
13 #include <llvm/Analysis/LoopAnalysisManager.h> | 15 #include <llvm/Analysis/LoopAnalysisManager.h> |
14 #include <llvm/AsmParser/Parser.h> | 16 #include <llvm/AsmParser/Parser.h> |
15 #include <llvm/IR/LLVMContext.h> | 17 #include <llvm/IR/LLVMContext.h> |
18 #include <llvm/IR/PassInstrumentation.h> | |
16 #include <llvm/IR/PassManager.h> | 19 #include <llvm/IR/PassManager.h> |
17 #include <llvm/Passes/PassBuilder.h> | 20 #include <llvm/Passes/PassBuilder.h> |
21 #include <llvm/Support/Regex.h> | |
18 #include <llvm/Support/SourceMgr.h> | 22 #include <llvm/Support/SourceMgr.h> |
19 #include <llvm/Transforms/Scalar/LoopPassManager.h> | 23 #include <llvm/Transforms/Scalar/LoopPassManager.h> |
20 | 24 |
21 using namespace llvm; | 25 using namespace llvm; |
22 | 26 |
23 namespace llvm { | |
24 /// Provide an ostream operator for StringRef. | |
25 /// | |
26 /// For convenience we provide a custom matcher below for IRUnit's and analysis | |
27 /// result's getName functions, which most of the time returns a StringRef. The | |
28 /// matcher makes use of this operator. | |
29 static std::ostream &operator<<(std::ostream &O, StringRef S) { | |
30 return O << S.str(); | |
31 } | |
32 } | |
33 | |
34 namespace { | 27 namespace { |
28 using testing::AnyNumber; | |
29 using testing::AtLeast; | |
35 using testing::DoDefault; | 30 using testing::DoDefault; |
31 using testing::Not; | |
36 using testing::Return; | 32 using testing::Return; |
37 using testing::Expectation; | 33 using testing::Expectation; |
38 using testing::Invoke; | 34 using testing::Invoke; |
39 using testing::WithArgs; | 35 using testing::WithArgs; |
40 using testing::_; | 36 using testing::_; |
41 | 37 |
42 /// \brief A CRTP base for analysis mock handles | 38 /// A CRTP base for analysis mock handles |
43 /// | 39 /// |
44 /// This class reconciles mocking with the value semantics implementation of the | 40 /// This class reconciles mocking with the value semantics implementation of the |
45 /// AnalysisManager. Analysis mock handles should derive from this class and | 41 /// AnalysisManager. Analysis mock handles should derive from this class and |
46 /// call \c setDefault() in their constroctur for wiring up the defaults defined | 42 /// call \c setDefault() in their constroctur for wiring up the defaults defined |
47 /// by this base with their mock run() and invalidate() implementations. | 43 /// by this base with their mock run() and invalidate() implementations. |
85 | 81 |
86 Analysis getAnalysis() { return Analysis(static_cast<DerivedT &>(*this)); } | 82 Analysis getAnalysis() { return Analysis(static_cast<DerivedT &>(*this)); } |
87 typename Analysis::Result getResult() { | 83 typename Analysis::Result getResult() { |
88 return typename Analysis::Result(static_cast<DerivedT &>(*this)); | 84 return typename Analysis::Result(static_cast<DerivedT &>(*this)); |
89 } | 85 } |
86 static StringRef getName() { return llvm::getTypeName<DerivedT>(); } | |
90 | 87 |
91 protected: | 88 protected: |
92 // FIXME: MSVC seems unable to handle a lambda argument to Invoke from within | 89 // FIXME: MSVC seems unable to handle a lambda argument to Invoke from within |
93 // the template, so we use a boring static function. | 90 // the template, so we use a boring static function. |
94 static bool invalidateCallback(IRUnitT &IR, const PreservedAnalyses &PA, | 91 static bool invalidateCallback(IRUnitT &IR, const PreservedAnalyses &PA, |
108 ON_CALL(static_cast<DerivedT &>(*this), invalidate(_, _, _)) | 105 ON_CALL(static_cast<DerivedT &>(*this), invalidate(_, _, _)) |
109 .WillByDefault(Invoke(&invalidateCallback)); | 106 .WillByDefault(Invoke(&invalidateCallback)); |
110 } | 107 } |
111 }; | 108 }; |
112 | 109 |
113 /// \brief A CRTP base for pass mock handles | 110 /// A CRTP base for pass mock handles |
114 /// | 111 /// |
115 /// This class reconciles mocking with the value semantics implementation of the | 112 /// This class reconciles mocking with the value semantics implementation of the |
116 /// PassManager. Pass mock handles should derive from this class and | 113 /// PassManager. Pass mock handles should derive from this class and |
117 /// call \c setDefault() in their constroctur for wiring up the defaults defined | 114 /// call \c setDefault() in their constroctur for wiring up the defaults defined |
118 /// by this base with their mock run() and invalidate() implementations. | 115 /// by this base with their mock run() and invalidate() implementations. |
140 PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, | 137 PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, |
141 ExtraArgTs... ExtraArgs) { | 138 ExtraArgTs... ExtraArgs) { |
142 return Handle->run(IR, AM, ExtraArgs...); | 139 return Handle->run(IR, AM, ExtraArgs...); |
143 } | 140 } |
144 }; | 141 }; |
142 | |
143 static StringRef getName() { return llvm::getTypeName<DerivedT>(); } | |
145 | 144 |
146 Pass getPass() { return Pass(static_cast<DerivedT &>(*this)); } | 145 Pass getPass() { return Pass(static_cast<DerivedT &>(*this)); } |
147 | 146 |
148 protected: | 147 protected: |
149 /// Derived classes should call this in their constructor to set up default | 148 /// Derived classes should call this in their constructor to set up default |
165 : MockPassHandleBase<MockPassHandle<Loop>, Loop, LoopAnalysisManager, | 164 : MockPassHandleBase<MockPassHandle<Loop>, Loop, LoopAnalysisManager, |
166 LoopStandardAnalysisResults &, LPMUpdater &> { | 165 LoopStandardAnalysisResults &, LPMUpdater &> { |
167 MOCK_METHOD4(run, | 166 MOCK_METHOD4(run, |
168 PreservedAnalyses(Loop &, LoopAnalysisManager &, | 167 PreservedAnalyses(Loop &, LoopAnalysisManager &, |
169 LoopStandardAnalysisResults &, LPMUpdater &)); | 168 LoopStandardAnalysisResults &, LPMUpdater &)); |
169 static void invalidateLoop(Loop &L, LoopAnalysisManager &, | |
170 LoopStandardAnalysisResults &, | |
171 LPMUpdater &Updater) { | |
172 Updater.markLoopAsDeleted(L, L.getName()); | |
173 } | |
170 MockPassHandle() { setDefaults(); } | 174 MockPassHandle() { setDefaults(); } |
171 }; | 175 }; |
172 | 176 |
173 template <> | 177 template <> |
174 struct MockPassHandle<Function> | 178 struct MockPassHandle<Function> |
184 CGSCCAnalysisManager, LazyCallGraph &, | 188 CGSCCAnalysisManager, LazyCallGraph &, |
185 CGSCCUpdateResult &> { | 189 CGSCCUpdateResult &> { |
186 MOCK_METHOD4(run, | 190 MOCK_METHOD4(run, |
187 PreservedAnalyses(LazyCallGraph::SCC &, CGSCCAnalysisManager &, | 191 PreservedAnalyses(LazyCallGraph::SCC &, CGSCCAnalysisManager &, |
188 LazyCallGraph &G, CGSCCUpdateResult &UR)); | 192 LazyCallGraph &G, CGSCCUpdateResult &UR)); |
193 | |
194 static void invalidateSCC(LazyCallGraph::SCC &C, CGSCCAnalysisManager &, | |
195 LazyCallGraph &, CGSCCUpdateResult &UR) { | |
196 UR.InvalidatedSCCs.insert(&C); | |
197 } | |
189 | 198 |
190 MockPassHandle() { setDefaults(); } | 199 MockPassHandle() { setDefaults(); } |
191 }; | 200 }; |
192 | 201 |
193 template <> | 202 template <> |
255 | 264 |
256 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) { | 265 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) { |
257 SMDiagnostic Err; | 266 SMDiagnostic Err; |
258 return parseAssemblyString(IR, Err, C); | 267 return parseAssemblyString(IR, Err, C); |
259 } | 268 } |
269 | |
270 /// Helper for HasName matcher that returns getName both for IRUnit and | |
271 /// for IRUnit pointer wrapper into llvm::Any (wrapped by PassInstrumentation). | |
272 template <typename IRUnitT> std::string getName(const IRUnitT &IR) { | |
273 return IR.getName(); | |
274 } | |
275 | |
276 template <> std::string getName(const StringRef &name) { return name; } | |
277 | |
278 template <> std::string getName(const llvm::Any &WrappedIR) { | |
279 if (any_isa<const Module *>(WrappedIR)) | |
280 return any_cast<const Module *>(WrappedIR)->getName().str(); | |
281 if (any_isa<const Function *>(WrappedIR)) | |
282 return any_cast<const Function *>(WrappedIR)->getName().str(); | |
283 if (any_isa<const Loop *>(WrappedIR)) | |
284 return any_cast<const Loop *>(WrappedIR)->getName().str(); | |
285 if (any_isa<const LazyCallGraph::SCC *>(WrappedIR)) | |
286 return any_cast<const LazyCallGraph::SCC *>(WrappedIR)->getName(); | |
287 return "<UNKNOWN>"; | |
288 } | |
289 /// Define a custom matcher for objects which support a 'getName' method. | |
290 /// | |
291 /// LLVM often has IR objects or analysis objects which expose a name | |
292 /// and in tests it is convenient to match these by name for readability. | |
293 /// Usually, this name is either a StringRef or a plain std::string. This | |
294 /// matcher supports any type exposing a getName() method of this form whose | |
295 /// return value is compatible with an std::ostream. For StringRef, this uses | |
296 /// the shift operator defined above. | |
297 /// | |
298 /// It should be used as: | |
299 /// | |
300 /// HasName("my_function") | |
301 /// | |
302 /// No namespace or other qualification is required. | |
303 MATCHER_P(HasName, Name, "") { | |
304 *result_listener << "has name '" << getName(arg) << "'"; | |
305 return Name == getName(arg); | |
306 } | |
307 | |
308 MATCHER_P(HasNameRegex, Name, "") { | |
309 *result_listener << "has name '" << getName(arg) << "'"; | |
310 llvm::Regex r(Name); | |
311 return r.match(getName(arg)); | |
312 } | |
313 | |
314 struct MockPassInstrumentationCallbacks { | |
315 PassInstrumentationCallbacks Callbacks; | |
316 | |
317 MockPassInstrumentationCallbacks() { | |
318 ON_CALL(*this, runBeforePass(_, _)).WillByDefault(Return(true)); | |
319 } | |
320 MOCK_METHOD2(runBeforePass, bool(StringRef PassID, llvm::Any)); | |
321 MOCK_METHOD2(runAfterPass, void(StringRef PassID, llvm::Any)); | |
322 MOCK_METHOD1(runAfterPassInvalidated, void(StringRef PassID)); | |
323 MOCK_METHOD2(runBeforeAnalysis, void(StringRef PassID, llvm::Any)); | |
324 MOCK_METHOD2(runAfterAnalysis, void(StringRef PassID, llvm::Any)); | |
325 | |
326 void registerPassInstrumentation() { | |
327 Callbacks.registerBeforePassCallback([this](StringRef P, llvm::Any IR) { | |
328 return this->runBeforePass(P, IR); | |
329 }); | |
330 Callbacks.registerAfterPassCallback( | |
331 [this](StringRef P, llvm::Any IR) { this->runAfterPass(P, IR); }); | |
332 Callbacks.registerAfterPassInvalidatedCallback( | |
333 [this](StringRef P) { this->runAfterPassInvalidated(P); }); | |
334 Callbacks.registerBeforeAnalysisCallback([this](StringRef P, llvm::Any IR) { | |
335 return this->runBeforeAnalysis(P, IR); | |
336 }); | |
337 Callbacks.registerAfterAnalysisCallback( | |
338 [this](StringRef P, llvm::Any IR) { this->runAfterAnalysis(P, IR); }); | |
339 } | |
340 | |
341 void ignoreNonMockPassInstrumentation(StringRef IRName) { | |
342 // Generic EXPECT_CALLs are needed to match instrumentation on unimportant | |
343 // parts of a pipeline that we do not care about (e.g. various passes added | |
344 // by default by PassBuilder - Verifier pass etc). | |
345 // Make sure to avoid ignoring Mock passes/analysis, we definitely want | |
346 // to check these explicitly. | |
347 EXPECT_CALL(*this, | |
348 runBeforePass(Not(HasNameRegex("Mock")), HasName(IRName))) | |
349 .Times(AnyNumber()); | |
350 EXPECT_CALL(*this, runAfterPass(Not(HasNameRegex("Mock")), HasName(IRName))) | |
351 .Times(AnyNumber()); | |
352 EXPECT_CALL(*this, | |
353 runBeforeAnalysis(Not(HasNameRegex("Mock")), HasName(IRName))) | |
354 .Times(AnyNumber()); | |
355 EXPECT_CALL(*this, | |
356 runAfterAnalysis(Not(HasNameRegex("Mock")), HasName(IRName))) | |
357 .Times(AnyNumber()); | |
358 } | |
359 }; | |
260 | 360 |
261 template <typename PassManagerT> class PassBuilderCallbacksTest; | 361 template <typename PassManagerT> class PassBuilderCallbacksTest; |
262 | 362 |
263 /// This test fixture is shared between all the actual tests below and | 363 /// This test fixture is shared between all the actual tests below and |
264 /// takes care of setting up appropriate defaults. | 364 /// takes care of setting up appropriate defaults. |
278 using AnalysisT = typename MockAnalysisHandle<IRUnitT>::Analysis; | 378 using AnalysisT = typename MockAnalysisHandle<IRUnitT>::Analysis; |
279 | 379 |
280 LLVMContext Context; | 380 LLVMContext Context; |
281 std::unique_ptr<Module> M; | 381 std::unique_ptr<Module> M; |
282 | 382 |
383 MockPassInstrumentationCallbacks CallbacksHandle; | |
384 | |
283 PassBuilder PB; | 385 PassBuilder PB; |
284 ModulePassManager PM; | 386 ModulePassManager PM; |
285 LoopAnalysisManager LAM; | 387 LoopAnalysisManager LAM; |
286 FunctionAnalysisManager FAM; | 388 FunctionAnalysisManager FAM; |
287 CGSCCAnalysisManager CGAM; | 389 CGSCCAnalysisManager CGAM; |
310 " %cmp = icmp eq i32 %iv, %n\n" | 412 " %cmp = icmp eq i32 %iv, %n\n" |
311 " br i1 %cmp, label %exit, label %loop\n" | 413 " br i1 %cmp, label %exit, label %loop\n" |
312 "exit:\n" | 414 "exit:\n" |
313 " ret void\n" | 415 " ret void\n" |
314 "}\n")), | 416 "}\n")), |
417 CallbacksHandle(), | |
418 PB(nullptr, PipelineTuningOptions(), None, &CallbacksHandle.Callbacks), | |
315 PM(true), LAM(true), FAM(true), CGAM(true), AM(true) { | 419 PM(true), LAM(true), FAM(true), CGAM(true), AM(true) { |
316 | 420 |
317 /// Register a callback for analysis registration. | 421 /// Register a callback for analysis registration. |
318 /// | 422 /// |
319 /// The callback is a function taking a reference to an AnalyisManager | 423 /// The callback is a function taking a reference to an AnalyisManager |
354 PB.registerLoopAnalyses(LAM); | 458 PB.registerLoopAnalyses(LAM); |
355 PB.crossRegisterProxies(LAM, FAM, CGAM, AM); | 459 PB.crossRegisterProxies(LAM, FAM, CGAM, AM); |
356 } | 460 } |
357 }; | 461 }; |
358 | 462 |
359 /// Define a custom matcher for objects which support a 'getName' method. | |
360 /// | |
361 /// LLVM often has IR objects or analysis objects which expose a name | |
362 /// and in tests it is convenient to match these by name for readability. | |
363 /// Usually, this name is either a StringRef or a plain std::string. This | |
364 /// matcher supports any type exposing a getName() method of this form whose | |
365 /// return value is compatible with an std::ostream. For StringRef, this uses | |
366 /// the shift operator defined above. | |
367 /// | |
368 /// It should be used as: | |
369 /// | |
370 /// HasName("my_function") | |
371 /// | |
372 /// No namespace or other qualification is required. | |
373 MATCHER_P(HasName, Name, "") { | |
374 *result_listener << "has name '" << arg.getName() << "'"; | |
375 return Name == arg.getName(); | |
376 } | |
377 | |
378 using ModuleCallbacksTest = PassBuilderCallbacksTest<ModulePassManager>; | 463 using ModuleCallbacksTest = PassBuilderCallbacksTest<ModulePassManager>; |
379 using CGSCCCallbacksTest = PassBuilderCallbacksTest<CGSCCPassManager>; | 464 using CGSCCCallbacksTest = PassBuilderCallbacksTest<CGSCCPassManager>; |
380 using FunctionCallbacksTest = PassBuilderCallbacksTest<FunctionPassManager>; | 465 using FunctionCallbacksTest = PassBuilderCallbacksTest<FunctionPassManager>; |
381 using LoopCallbacksTest = PassBuilderCallbacksTest<LoopPassManager>; | 466 using LoopCallbacksTest = PassBuilderCallbacksTest<LoopPassManager>; |
382 | 467 |
387 EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _)); | 472 EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _)); |
388 EXPECT_CALL(PassHandle, run(HasName("<string>"), _)) | 473 EXPECT_CALL(PassHandle, run(HasName("<string>"), _)) |
389 .WillOnce(Invoke(getAnalysisResult)); | 474 .WillOnce(Invoke(getAnalysisResult)); |
390 | 475 |
391 StringRef PipelineText = "test-transform"; | 476 StringRef PipelineText = "test-transform"; |
392 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true)) | 477 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) |
393 << "Pipeline was: " << PipelineText; | 478 << "Pipeline was: " << PipelineText; |
479 | |
480 PM.run(*M, AM); | |
481 } | |
482 | |
483 TEST_F(ModuleCallbacksTest, InstrumentedPasses) { | |
484 EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _)); | |
485 EXPECT_CALL(PassHandle, run(HasName("<string>"), _)) | |
486 .WillOnce(Invoke(getAnalysisResult)); | |
487 | |
488 CallbacksHandle.registerPassInstrumentation(); | |
489 // Non-mock instrumentation not specifically mentioned below can be ignored. | |
490 CallbacksHandle.ignoreNonMockPassInstrumentation("<string>"); | |
491 | |
492 // PassInstrumentation calls should happen in-sequence, in the same order | |
493 // as passes/analyses are scheduled. | |
494 ::testing::Sequence PISequence; | |
495 EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"), | |
496 HasName("<string>"))) | |
497 .InSequence(PISequence); | |
498 EXPECT_CALL(CallbacksHandle, | |
499 runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), | |
500 HasName("<string>"))) | |
501 .InSequence(PISequence); | |
502 EXPECT_CALL( | |
503 CallbacksHandle, | |
504 runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("<string>"))) | |
505 .InSequence(PISequence); | |
506 EXPECT_CALL(CallbacksHandle, | |
507 runAfterPass(HasNameRegex("MockPassHandle"), HasName("<string>"))) | |
508 .InSequence(PISequence); | |
509 | |
510 StringRef PipelineText = "test-transform"; | |
511 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) | |
512 << "Pipeline was: " << PipelineText; | |
513 | |
514 PM.run(*M, AM); | |
515 } | |
516 | |
517 TEST_F(ModuleCallbacksTest, InstrumentedSkippedPasses) { | |
518 CallbacksHandle.registerPassInstrumentation(); | |
519 // Non-mock instrumentation run here can safely be ignored. | |
520 CallbacksHandle.ignoreNonMockPassInstrumentation("<string>"); | |
521 | |
522 // Skip the pass by returning false. | |
523 EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"), | |
524 HasName("<string>"))) | |
525 .WillOnce(Return(false)); | |
526 | |
527 EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _)).Times(0); | |
528 EXPECT_CALL(PassHandle, run(HasName("<string>"), _)).Times(0); | |
529 | |
530 // As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis | |
531 // as well. | |
532 EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _)) | |
533 .Times(0); | |
534 EXPECT_CALL(CallbacksHandle, | |
535 runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _)) | |
536 .Times(0); | |
537 EXPECT_CALL(CallbacksHandle, | |
538 runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _)) | |
539 .Times(0); | |
540 | |
541 StringRef PipelineText = "test-transform"; | |
542 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) | |
543 << "Pipeline was: " << PipelineText; | |
544 | |
394 PM.run(*M, AM); | 545 PM.run(*M, AM); |
395 } | 546 } |
396 | 547 |
397 TEST_F(FunctionCallbacksTest, Passes) { | 548 TEST_F(FunctionCallbacksTest, Passes) { |
398 EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _)); | 549 EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _)); |
399 EXPECT_CALL(PassHandle, run(HasName("foo"), _)) | 550 EXPECT_CALL(PassHandle, run(HasName("foo"), _)) |
400 .WillOnce(Invoke(getAnalysisResult)); | 551 .WillOnce(Invoke(getAnalysisResult)); |
401 | 552 |
402 StringRef PipelineText = "test-transform"; | 553 StringRef PipelineText = "test-transform"; |
403 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true)) | 554 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) |
555 << "Pipeline was: " << PipelineText; | |
556 PM.run(*M, AM); | |
557 } | |
558 | |
559 TEST_F(FunctionCallbacksTest, InstrumentedPasses) { | |
560 CallbacksHandle.registerPassInstrumentation(); | |
561 // Non-mock instrumentation not specifically mentioned below can be ignored. | |
562 CallbacksHandle.ignoreNonMockPassInstrumentation("<string>"); | |
563 CallbacksHandle.ignoreNonMockPassInstrumentation("foo"); | |
564 | |
565 EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _)); | |
566 EXPECT_CALL(PassHandle, run(HasName("foo"), _)) | |
567 .WillOnce(Invoke(getAnalysisResult)); | |
568 | |
569 // PassInstrumentation calls should happen in-sequence, in the same order | |
570 // as passes/analyses are scheduled. | |
571 ::testing::Sequence PISequence; | |
572 EXPECT_CALL(CallbacksHandle, | |
573 runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo"))) | |
574 .InSequence(PISequence); | |
575 EXPECT_CALL( | |
576 CallbacksHandle, | |
577 runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("foo"))) | |
578 .InSequence(PISequence); | |
579 EXPECT_CALL( | |
580 CallbacksHandle, | |
581 runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("foo"))) | |
582 .InSequence(PISequence); | |
583 EXPECT_CALL(CallbacksHandle, | |
584 runAfterPass(HasNameRegex("MockPassHandle"), HasName("foo"))) | |
585 .InSequence(PISequence); | |
586 | |
587 // Our mock pass does not invalidate IR. | |
588 EXPECT_CALL(CallbacksHandle, | |
589 runAfterPassInvalidated(HasNameRegex("MockPassHandle"))) | |
590 .Times(0); | |
591 | |
592 StringRef PipelineText = "test-transform"; | |
593 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) | |
594 << "Pipeline was: " << PipelineText; | |
595 PM.run(*M, AM); | |
596 } | |
597 | |
598 TEST_F(FunctionCallbacksTest, InstrumentedSkippedPasses) { | |
599 CallbacksHandle.registerPassInstrumentation(); | |
600 // Non-mock instrumentation run here can safely be ignored. | |
601 CallbacksHandle.ignoreNonMockPassInstrumentation("<string>"); | |
602 CallbacksHandle.ignoreNonMockPassInstrumentation("foo"); | |
603 | |
604 // Skip the pass by returning false. | |
605 EXPECT_CALL(CallbacksHandle, | |
606 runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo"))) | |
607 .WillOnce(Return(false)); | |
608 | |
609 EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _)).Times(0); | |
610 EXPECT_CALL(PassHandle, run(HasName("foo"), _)).Times(0); | |
611 | |
612 // As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis | |
613 // as well. | |
614 EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _)) | |
615 .Times(0); | |
616 EXPECT_CALL(CallbacksHandle, | |
617 runAfterPassInvalidated(HasNameRegex("MockPassHandle"))) | |
618 .Times(0); | |
619 EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _)) | |
620 .Times(0); | |
621 EXPECT_CALL(CallbacksHandle, | |
622 runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _)) | |
623 .Times(0); | |
624 EXPECT_CALL(CallbacksHandle, | |
625 runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _)) | |
626 .Times(0); | |
627 | |
628 StringRef PipelineText = "test-transform"; | |
629 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) | |
404 << "Pipeline was: " << PipelineText; | 630 << "Pipeline was: " << PipelineText; |
405 PM.run(*M, AM); | 631 PM.run(*M, AM); |
406 } | 632 } |
407 | 633 |
408 TEST_F(LoopCallbacksTest, Passes) { | 634 TEST_F(LoopCallbacksTest, Passes) { |
409 EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)); | 635 EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)); |
410 EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _)) | 636 EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _)) |
411 .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult))); | 637 .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult))); |
412 | 638 |
413 StringRef PipelineText = "test-transform"; | 639 StringRef PipelineText = "test-transform"; |
414 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true)) | 640 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) |
641 << "Pipeline was: " << PipelineText; | |
642 PM.run(*M, AM); | |
643 } | |
644 | |
645 TEST_F(LoopCallbacksTest, InstrumentedPasses) { | |
646 CallbacksHandle.registerPassInstrumentation(); | |
647 // Non-mock instrumentation not specifically mentioned below can be ignored. | |
648 CallbacksHandle.ignoreNonMockPassInstrumentation("<string>"); | |
649 CallbacksHandle.ignoreNonMockPassInstrumentation("foo"); | |
650 CallbacksHandle.ignoreNonMockPassInstrumentation("loop"); | |
651 | |
652 EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)); | |
653 EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _)) | |
654 .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult))); | |
655 | |
656 // PassInstrumentation calls should happen in-sequence, in the same order | |
657 // as passes/analyses are scheduled. | |
658 ::testing::Sequence PISequence; | |
659 EXPECT_CALL(CallbacksHandle, | |
660 runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop"))) | |
661 .InSequence(PISequence); | |
662 EXPECT_CALL( | |
663 CallbacksHandle, | |
664 runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("loop"))) | |
665 .InSequence(PISequence); | |
666 EXPECT_CALL( | |
667 CallbacksHandle, | |
668 runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("loop"))) | |
669 .InSequence(PISequence); | |
670 EXPECT_CALL(CallbacksHandle, | |
671 runAfterPass(HasNameRegex("MockPassHandle"), HasName("loop"))) | |
672 .InSequence(PISequence); | |
673 | |
674 // Our mock pass does not invalidate IR. | |
675 EXPECT_CALL(CallbacksHandle, | |
676 runAfterPassInvalidated(HasNameRegex("MockPassHandle"))) | |
677 .Times(0); | |
678 | |
679 StringRef PipelineText = "test-transform"; | |
680 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) | |
681 << "Pipeline was: " << PipelineText; | |
682 PM.run(*M, AM); | |
683 } | |
684 | |
685 TEST_F(LoopCallbacksTest, InstrumentedInvalidatingPasses) { | |
686 CallbacksHandle.registerPassInstrumentation(); | |
687 // Non-mock instrumentation not specifically mentioned below can be ignored. | |
688 CallbacksHandle.ignoreNonMockPassInstrumentation("<string>"); | |
689 CallbacksHandle.ignoreNonMockPassInstrumentation("foo"); | |
690 CallbacksHandle.ignoreNonMockPassInstrumentation("loop"); | |
691 | |
692 EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)); | |
693 EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _)) | |
694 .WillOnce(DoAll(WithArgs<0, 1, 2, 3>(Invoke(PassHandle.invalidateLoop)), | |
695 WithArgs<0, 1, 2>(Invoke(getAnalysisResult)))); | |
696 | |
697 // PassInstrumentation calls should happen in-sequence, in the same order | |
698 // as passes/analyses are scheduled. | |
699 ::testing::Sequence PISequence; | |
700 EXPECT_CALL(CallbacksHandle, | |
701 runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop"))) | |
702 .InSequence(PISequence); | |
703 EXPECT_CALL( | |
704 CallbacksHandle, | |
705 runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("loop"))) | |
706 .InSequence(PISequence); | |
707 EXPECT_CALL( | |
708 CallbacksHandle, | |
709 runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("loop"))) | |
710 .InSequence(PISequence); | |
711 EXPECT_CALL(CallbacksHandle, | |
712 runAfterPassInvalidated(HasNameRegex("MockPassHandle"))) | |
713 .InSequence(PISequence); | |
714 EXPECT_CALL(CallbacksHandle, | |
715 runAfterPassInvalidated(HasNameRegex("^PassManager"))) | |
716 .InSequence(PISequence); | |
717 | |
718 // Our mock pass invalidates IR, thus normal runAfterPass is never called. | |
719 EXPECT_CALL(CallbacksHandle, | |
720 runAfterPass(HasNameRegex("MockPassHandle"), HasName("loop"))) | |
721 .Times(0); | |
722 | |
723 StringRef PipelineText = "test-transform"; | |
724 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) | |
725 << "Pipeline was: " << PipelineText; | |
726 PM.run(*M, AM); | |
727 } | |
728 | |
729 TEST_F(LoopCallbacksTest, InstrumentedSkippedPasses) { | |
730 CallbacksHandle.registerPassInstrumentation(); | |
731 // Non-mock instrumentation run here can safely be ignored. | |
732 CallbacksHandle.ignoreNonMockPassInstrumentation("<string>"); | |
733 CallbacksHandle.ignoreNonMockPassInstrumentation("foo"); | |
734 CallbacksHandle.ignoreNonMockPassInstrumentation("loop"); | |
735 | |
736 // Skip the pass by returning false. | |
737 EXPECT_CALL(CallbacksHandle, | |
738 runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop"))) | |
739 .WillOnce(Return(false)); | |
740 | |
741 EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)).Times(0); | |
742 EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _)).Times(0); | |
743 | |
744 // As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis | |
745 // as well. | |
746 EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _)) | |
747 .Times(0); | |
748 EXPECT_CALL(CallbacksHandle, | |
749 runAfterPassInvalidated(HasNameRegex("MockPassHandle"))) | |
750 .Times(0); | |
751 EXPECT_CALL(CallbacksHandle, | |
752 runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _)) | |
753 .Times(0); | |
754 EXPECT_CALL(CallbacksHandle, | |
755 runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _)) | |
756 .Times(0); | |
757 | |
758 StringRef PipelineText = "test-transform"; | |
759 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) | |
415 << "Pipeline was: " << PipelineText; | 760 << "Pipeline was: " << PipelineText; |
416 PM.run(*M, AM); | 761 PM.run(*M, AM); |
417 } | 762 } |
418 | 763 |
419 TEST_F(CGSCCCallbacksTest, Passes) { | 764 TEST_F(CGSCCCallbacksTest, Passes) { |
420 EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _)); | 765 EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _)); |
421 EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _)) | 766 EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _)) |
422 .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult))); | 767 .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult))); |
423 | 768 |
424 StringRef PipelineText = "test-transform"; | 769 StringRef PipelineText = "test-transform"; |
425 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true)) | 770 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) |
771 << "Pipeline was: " << PipelineText; | |
772 PM.run(*M, AM); | |
773 } | |
774 | |
775 TEST_F(CGSCCCallbacksTest, InstrumentedPasses) { | |
776 CallbacksHandle.registerPassInstrumentation(); | |
777 // Non-mock instrumentation not specifically mentioned below can be ignored. | |
778 CallbacksHandle.ignoreNonMockPassInstrumentation("<string>"); | |
779 CallbacksHandle.ignoreNonMockPassInstrumentation("(foo)"); | |
780 | |
781 EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _)); | |
782 EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _)) | |
783 .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult))); | |
784 | |
785 // PassInstrumentation calls should happen in-sequence, in the same order | |
786 // as passes/analyses are scheduled. | |
787 ::testing::Sequence PISequence; | |
788 EXPECT_CALL(CallbacksHandle, | |
789 runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)"))) | |
790 .InSequence(PISequence); | |
791 EXPECT_CALL( | |
792 CallbacksHandle, | |
793 runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("(foo)"))) | |
794 .InSequence(PISequence); | |
795 EXPECT_CALL( | |
796 CallbacksHandle, | |
797 runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("(foo)"))) | |
798 .InSequence(PISequence); | |
799 EXPECT_CALL(CallbacksHandle, | |
800 runAfterPass(HasNameRegex("MockPassHandle"), HasName("(foo)"))) | |
801 .InSequence(PISequence); | |
802 | |
803 // Our mock pass does not invalidate IR. | |
804 EXPECT_CALL(CallbacksHandle, | |
805 runAfterPassInvalidated(HasNameRegex("MockPassHandle"))) | |
806 .Times(0); | |
807 | |
808 StringRef PipelineText = "test-transform"; | |
809 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) | |
810 << "Pipeline was: " << PipelineText; | |
811 PM.run(*M, AM); | |
812 } | |
813 | |
814 TEST_F(CGSCCCallbacksTest, InstrumentedInvalidatingPasses) { | |
815 CallbacksHandle.registerPassInstrumentation(); | |
816 // Non-mock instrumentation not specifically mentioned below can be ignored. | |
817 CallbacksHandle.ignoreNonMockPassInstrumentation("<string>"); | |
818 CallbacksHandle.ignoreNonMockPassInstrumentation("(foo)"); | |
819 | |
820 EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _)); | |
821 EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _)) | |
822 .WillOnce(DoAll(WithArgs<0, 1, 2, 3>(Invoke(PassHandle.invalidateSCC)), | |
823 WithArgs<0, 1, 2>(Invoke(getAnalysisResult)))); | |
824 | |
825 // PassInstrumentation calls should happen in-sequence, in the same order | |
826 // as passes/analyses are scheduled. | |
827 ::testing::Sequence PISequence; | |
828 EXPECT_CALL(CallbacksHandle, | |
829 runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)"))) | |
830 .InSequence(PISequence); | |
831 EXPECT_CALL( | |
832 CallbacksHandle, | |
833 runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("(foo)"))) | |
834 .InSequence(PISequence); | |
835 EXPECT_CALL( | |
836 CallbacksHandle, | |
837 runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("(foo)"))) | |
838 .InSequence(PISequence); | |
839 EXPECT_CALL(CallbacksHandle, | |
840 runAfterPassInvalidated(HasNameRegex("MockPassHandle"))) | |
841 .InSequence(PISequence); | |
842 EXPECT_CALL(CallbacksHandle, | |
843 runAfterPassInvalidated(HasNameRegex("^PassManager"))) | |
844 .InSequence(PISequence); | |
845 | |
846 // Our mock pass does invalidate IR, thus normal runAfterPass is never called. | |
847 EXPECT_CALL(CallbacksHandle, | |
848 runAfterPass(HasNameRegex("MockPassHandle"), HasName("(foo)"))) | |
849 .Times(0); | |
850 | |
851 StringRef PipelineText = "test-transform"; | |
852 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) | |
853 << "Pipeline was: " << PipelineText; | |
854 PM.run(*M, AM); | |
855 } | |
856 | |
857 TEST_F(CGSCCCallbacksTest, InstrumentedSkippedPasses) { | |
858 CallbacksHandle.registerPassInstrumentation(); | |
859 // Non-mock instrumentation run here can safely be ignored. | |
860 CallbacksHandle.ignoreNonMockPassInstrumentation("<string>"); | |
861 CallbacksHandle.ignoreNonMockPassInstrumentation("(foo)"); | |
862 | |
863 // Skip the pass by returning false. | |
864 EXPECT_CALL(CallbacksHandle, | |
865 runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)"))) | |
866 .WillOnce(Return(false)); | |
867 | |
868 // neither Analysis nor Pass are called. | |
869 EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _)).Times(0); | |
870 EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _)).Times(0); | |
871 | |
872 // As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis | |
873 // as well. | |
874 EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _)) | |
875 .Times(0); | |
876 EXPECT_CALL(CallbacksHandle, | |
877 runAfterPassInvalidated(HasNameRegex("MockPassHandle"))) | |
878 .Times(0); | |
879 EXPECT_CALL(CallbacksHandle, | |
880 runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _)) | |
881 .Times(0); | |
882 EXPECT_CALL(CallbacksHandle, | |
883 runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _)) | |
884 .Times(0); | |
885 | |
886 StringRef PipelineText = "test-transform"; | |
887 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) | |
426 << "Pipeline was: " << PipelineText; | 888 << "Pipeline was: " << PipelineText; |
427 PM.run(*M, AM); | 889 PM.run(*M, AM); |
428 } | 890 } |
429 | 891 |
430 /// Test parsing of the names of analysis utilities for our mock analysis | 892 /// Test parsing of the names of analysis utilities for our mock analysis |
435 TEST_F(ModuleCallbacksTest, AnalysisUtilities) { | 897 TEST_F(ModuleCallbacksTest, AnalysisUtilities) { |
436 EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _)); | 898 EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _)); |
437 EXPECT_CALL(AnalysisHandle, invalidate(HasName("<string>"), _, _)); | 899 EXPECT_CALL(AnalysisHandle, invalidate(HasName("<string>"), _, _)); |
438 | 900 |
439 StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>"; | 901 StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>"; |
440 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true)) | 902 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) |
441 << "Pipeline was: " << PipelineText; | 903 << "Pipeline was: " << PipelineText; |
442 PM.run(*M, AM); | 904 PM.run(*M, AM); |
443 } | 905 } |
444 | 906 |
445 TEST_F(CGSCCCallbacksTest, PassUtilities) { | 907 TEST_F(CGSCCCallbacksTest, PassUtilities) { |
446 EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _)); | 908 EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _)); |
447 EXPECT_CALL(AnalysisHandle, invalidate(HasName("(foo)"), _, _)); | 909 EXPECT_CALL(AnalysisHandle, invalidate(HasName("(foo)"), _, _)); |
448 | 910 |
449 StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>"; | 911 StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>"; |
450 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true)) | 912 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) |
451 << "Pipeline was: " << PipelineText; | 913 << "Pipeline was: " << PipelineText; |
452 PM.run(*M, AM); | 914 PM.run(*M, AM); |
453 } | 915 } |
454 | 916 |
455 TEST_F(FunctionCallbacksTest, AnalysisUtilities) { | 917 TEST_F(FunctionCallbacksTest, AnalysisUtilities) { |
456 EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _)); | 918 EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _)); |
457 EXPECT_CALL(AnalysisHandle, invalidate(HasName("foo"), _, _)); | 919 EXPECT_CALL(AnalysisHandle, invalidate(HasName("foo"), _, _)); |
458 | 920 |
459 StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>"; | 921 StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>"; |
460 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true)) | 922 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) |
461 << "Pipeline was: " << PipelineText; | 923 << "Pipeline was: " << PipelineText; |
462 PM.run(*M, AM); | 924 PM.run(*M, AM); |
463 } | 925 } |
464 | 926 |
465 TEST_F(LoopCallbacksTest, PassUtilities) { | 927 TEST_F(LoopCallbacksTest, PassUtilities) { |
466 EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)); | 928 EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)); |
467 EXPECT_CALL(AnalysisHandle, invalidate(HasName("loop"), _, _)); | 929 EXPECT_CALL(AnalysisHandle, invalidate(HasName("loop"), _, _)); |
468 | 930 |
469 StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>"; | 931 StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>"; |
470 | 932 |
471 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true)) | 933 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) |
472 << "Pipeline was: " << PipelineText; | 934 << "Pipeline was: " << PipelineText; |
473 PM.run(*M, AM); | 935 PM.run(*M, AM); |
474 } | 936 } |
475 | 937 |
476 /// Test parsing of the top-level pipeline. | 938 /// Test parsing of the top-level pipeline. |
506 .WillOnce(Invoke(getAnalysisResult)); | 968 .WillOnce(Invoke(getAnalysisResult)); |
507 EXPECT_CALL(AnalysisHandle, invalidate(HasName("<string>"), _, _)); | 969 EXPECT_CALL(AnalysisHandle, invalidate(HasName("<string>"), _, _)); |
508 | 970 |
509 StringRef PipelineText = | 971 StringRef PipelineText = |
510 "another-pipeline(test-transform,invalidate<test-analysis>)"; | 972 "another-pipeline(test-transform,invalidate<test-analysis>)"; |
511 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true)) | 973 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) |
512 << "Pipeline was: " << PipelineText; | 974 << "Pipeline was: " << PipelineText; |
513 PM.run(*M, AM); | 975 PM.run(*M, AM); |
514 | 976 |
515 /// Test the negative case | 977 /// Test the negative case |
516 PipelineText = "another-pipeline(instcombine)"; | 978 PipelineText = "another-pipeline(instcombine)"; |
517 ASSERT_FALSE(PB.parsePassPipeline(PM, PipelineText, true)) | 979 ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Failed()) |
518 << "Pipeline was: " << PipelineText; | 980 << "Pipeline was: " << PipelineText; |
519 } | 981 } |
520 } // end anonymous namespace | 982 } // end anonymous namespace |