1 //===- llvm/unittest/IR/LegacyPassManager.cpp - Legacy PassManager tests --===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This unit test exercises the legacy pass manager infrastructure. We use the
10 // old names as well to ensure that the source-level compatibility is preserved
13 //===----------------------------------------------------------------------===//
15 #include "llvm/IR/LegacyPassManager.h"
16 #include "llvm/Analysis/CallGraph.h"
17 #include "llvm/Analysis/CallGraphSCCPass.h"
18 #include "llvm/Analysis/LoopInfo.h"
19 #include "llvm/Analysis/LoopPass.h"
20 #include "llvm/AsmParser/Parser.h"
21 #include "llvm/IR/AbstractCallSite.h"
22 #include "llvm/IR/BasicBlock.h"
23 #include "llvm/IR/CallingConv.h"
24 #include "llvm/IR/DataLayout.h"
25 #include "llvm/IR/DerivedTypes.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/IR/GlobalVariable.h"
28 #include "llvm/IR/Instructions.h"
29 #include "llvm/IR/LLVMContext.h"
30 #include "llvm/IR/Module.h"
31 #include "llvm/IR/OptBisect.h"
32 #include "llvm/InitializePasses.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/SourceMgr.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include "llvm/Transforms/Utils/CallGraphUpdater.h"
37 #include "gtest/gtest.h"
42 void initializeModuleNDMPass(PassRegistry
&);
43 void initializeFPassPass(PassRegistry
&);
44 void initializeCGPassPass(PassRegistry
&);
45 void initializeLPassPass(PassRegistry
&);
49 // NM = no modifications
50 struct ModuleNDNM
: public ModulePass
{
54 ModuleNDNM() : ModulePass(ID
) { }
55 bool runOnModule(Module
&M
) override
{
59 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
63 char ModuleNDNM::ID
=0;
64 char ModuleNDNM::run
=0;
66 struct ModuleNDM
: public ModulePass
{
70 ModuleNDM() : ModulePass(ID
) {}
71 bool runOnModule(Module
&M
) override
{
77 char ModuleNDM::run
=0;
79 struct ModuleNDM2
: public ModulePass
{
83 ModuleNDM2() : ModulePass(ID
) {}
84 bool runOnModule(Module
&M
) override
{
89 char ModuleNDM2::ID
=0;
90 char ModuleNDM2::run
=0;
92 struct ModuleDNM
: public ModulePass
{
96 ModuleDNM() : ModulePass(ID
) {
97 initializeModuleNDMPass(*PassRegistry::getPassRegistry());
99 bool runOnModule(Module
&M
) override
{
103 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
104 AU
.addRequired
<ModuleNDM
>();
105 AU
.setPreservesAll();
108 char ModuleDNM::ID
=0;
109 char ModuleDNM::run
=0;
112 struct PassTestBase
: public P
{
115 static bool initialized
;
116 static bool finalized
;
119 EXPECT_TRUE(initialized
);
120 EXPECT_FALSE(finalized
);
121 EXPECT_EQ(0, allocated
);
127 static void finishedOK(int run
) {
129 EXPECT_TRUE(initialized
);
130 EXPECT_TRUE(finalized
);
131 EXPECT_EQ(run
, runc
);
133 PassTestBase() : P(ID
), allocated(0) {
139 void releaseMemory() override
{
141 EXPECT_GT(allocated
, 0);
145 template<typename P
> char PassTestBase
<P
>::ID
;
146 template<typename P
> int PassTestBase
<P
>::runc
;
147 template<typename P
> bool PassTestBase
<P
>::initialized
;
148 template<typename P
> bool PassTestBase
<P
>::finalized
;
150 template<typename T
, typename P
>
151 struct PassTest
: public PassTestBase
<P
> {
153 #ifndef _MSC_VER // MSVC complains that Pass is not base class.
154 using llvm::Pass::doInitialization
;
155 using llvm::Pass::doFinalization
;
157 bool doInitialization(T
&t
) override
{
158 EXPECT_FALSE(PassTestBase
<P
>::initialized
);
159 PassTestBase
<P
>::initialized
= true;
162 bool doFinalization(T
&t
) override
{
163 EXPECT_FALSE(PassTestBase
<P
>::finalized
);
164 PassTestBase
<P
>::finalized
= true;
165 EXPECT_EQ(0, PassTestBase
<P
>::allocated
);
170 struct CGPass
: public PassTest
<CallGraph
, CallGraphSCCPass
> {
173 initializeCGPassPass(*PassRegistry::getPassRegistry());
175 bool runOnSCC(CallGraphSCC
&SCMM
) override
{
181 struct FPass
: public PassTest
<Module
, FunctionPass
> {
183 bool runOnFunction(Function
&F
) override
{
185 // EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
191 struct LPass
: public PassTestBase
<LoopPass
> {
193 static int initcount
;
197 initializeLPassPass(*PassRegistry::getPassRegistry());
198 initcount
= 0; fincount
=0;
199 EXPECT_FALSE(initialized
);
201 static void finishedOK(int run
, int finalized
) {
202 PassTestBase
<LoopPass
>::finishedOK(run
);
203 EXPECT_EQ(run
, initcount
);
204 EXPECT_EQ(finalized
, fincount
);
206 using llvm::Pass::doInitialization
;
207 using llvm::Pass::doFinalization
;
208 bool doInitialization(Loop
* L
, LPPassManager
&LPM
) override
{
213 bool runOnLoop(Loop
*L
, LPPassManager
&LPM
) override
{
217 bool doFinalization() override
{
223 int LPass::initcount
=0;
224 int LPass::fincount
=0;
226 struct OnTheFlyTest
: public ModulePass
{
229 OnTheFlyTest() : ModulePass(ID
) {
230 initializeFPassPass(*PassRegistry::getPassRegistry());
232 bool runOnModule(Module
&M
) override
{
233 for (Module::iterator I
=M
.begin(),E
=M
.end(); I
!= E
; ++I
) {
236 SCOPED_TRACE("Running on the fly function pass");
237 getAnalysis
<FPass
>(F
);
242 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
243 AU
.addRequired
<FPass
>();
246 char OnTheFlyTest::ID
=0;
248 TEST(PassManager
, RunOnce
) {
250 Module
M("test-once", Context
);
251 struct ModuleNDNM
*mNDNM
= new ModuleNDNM();
252 struct ModuleDNM
*mDNM
= new ModuleDNM();
253 struct ModuleNDM
*mNDM
= new ModuleNDM();
254 struct ModuleNDM2
*mNDM2
= new ModuleNDM2();
256 mNDM
->run
= mNDNM
->run
= mDNM
->run
= mNDM2
->run
= 0;
258 legacy::PassManager Passes
;
265 // each pass must be run exactly once, since nothing invalidates them
266 EXPECT_EQ(1, mNDM
->run
);
267 EXPECT_EQ(1, mNDNM
->run
);
268 EXPECT_EQ(1, mDNM
->run
);
269 EXPECT_EQ(1, mNDM2
->run
);
272 TEST(PassManager
, ReRun
) {
274 Module
M("test-rerun", Context
);
275 struct ModuleNDNM
*mNDNM
= new ModuleNDNM();
276 struct ModuleDNM
*mDNM
= new ModuleDNM();
277 struct ModuleNDM
*mNDM
= new ModuleNDM();
278 struct ModuleNDM2
*mNDM2
= new ModuleNDM2();
280 mNDM
->run
= mNDNM
->run
= mDNM
->run
= mNDM2
->run
= 0;
282 legacy::PassManager Passes
;
285 Passes
.add(mNDM2
);// invalidates mNDM needed by mDNM
289 // Some passes must be rerun because a pass that modified the
290 // module/function was run in between
291 EXPECT_EQ(2, mNDM
->run
);
292 EXPECT_EQ(1, mNDNM
->run
);
293 EXPECT_EQ(1, mNDM2
->run
);
294 EXPECT_EQ(1, mDNM
->run
);
297 Module
*makeLLVMModule(LLVMContext
&Context
);
300 void MemoryTestHelper(int run
) {
302 std::unique_ptr
<Module
> M(makeLLVMModule(Context
));
304 legacy::PassManager Passes
;
311 void MemoryTestHelper(int run
, int N
) {
313 Module
*M
= makeLLVMModule(Context
);
315 legacy::PassManager Passes
;
318 T::finishedOK(run
, N
);
322 TEST(PassManager
, Memory
) {
323 // SCC#1: test1->test2->test3->test1
325 // SCC#3: indirect call node
327 SCOPED_TRACE("Callgraph pass");
328 MemoryTestHelper
<CGPass
>(3);
332 SCOPED_TRACE("Function pass");
333 MemoryTestHelper
<FPass
>(4);// 4 functions
337 SCOPED_TRACE("Loop pass");
338 MemoryTestHelper
<LPass
>(2, 1); //2 loops, 1 function
343 TEST(PassManager
, MemoryOnTheFly
) {
345 Module
*M
= makeLLVMModule(Context
);
347 SCOPED_TRACE("Running OnTheFlyTest");
348 struct OnTheFlyTest
*O
= new OnTheFlyTest();
349 legacy::PassManager Passes
;
353 FPass::finishedOK(4);
358 // Skips or runs optional passes.
359 struct CustomOptPassGate
: public OptPassGate
{
361 CustomOptPassGate(bool Skip
) : Skip(Skip
) { }
362 bool shouldRunPass(const StringRef PassName
, StringRef IRDescription
) override
{
365 bool isEnabled() const override
{ return true; }
368 // Optional module pass.
369 struct ModuleOpt
: public ModulePass
{
372 ModuleOpt() : ModulePass(ID
) { }
373 bool runOnModule(Module
&M
) override
{
379 char ModuleOpt::ID
=0;
381 TEST(PassManager
, CustomOptPassGate
) {
382 LLVMContext Context0
;
383 LLVMContext Context1
;
384 LLVMContext Context2
;
385 CustomOptPassGate
SkipOptionalPasses(true);
386 CustomOptPassGate
RunOptionalPasses(false);
388 Module
M0("custom-opt-bisect", Context0
);
389 Module
M1("custom-opt-bisect", Context1
);
390 Module
M2("custom-opt-bisect2", Context2
);
391 struct ModuleOpt
*mOpt0
= new ModuleOpt();
392 struct ModuleOpt
*mOpt1
= new ModuleOpt();
393 struct ModuleOpt
*mOpt2
= new ModuleOpt();
395 mOpt0
->run
= mOpt1
->run
= mOpt2
->run
= 0;
397 legacy::PassManager Passes0
;
398 legacy::PassManager Passes1
;
399 legacy::PassManager Passes2
;
405 Context1
.setOptPassGate(SkipOptionalPasses
);
406 Context2
.setOptPassGate(RunOptionalPasses
);
412 // By default optional passes are run.
413 EXPECT_EQ(1, mOpt0
->run
);
415 // The first context skips optional passes.
416 EXPECT_EQ(0, mOpt1
->run
);
418 // The second context runs optional passes.
419 EXPECT_EQ(1, mOpt2
->run
);
422 Module
*makeLLVMModule(LLVMContext
&Context
) {
423 // Module Construction
424 Module
*mod
= new Module("test-mem", Context
);
425 mod
->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
426 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
427 "a:0:64-s:64:64-f80:128:128");
428 mod
->setTargetTriple("x86_64-unknown-linux-gnu");
431 std::vector
<Type
*>FuncTy_0_args
;
432 FunctionType
*FuncTy_0
= FunctionType::get(
433 /*Result=*/IntegerType::get(Context
, 32),
434 /*Params=*/FuncTy_0_args
,
437 std::vector
<Type
*>FuncTy_2_args
;
438 FuncTy_2_args
.push_back(IntegerType::get(Context
, 1));
439 FunctionType
*FuncTy_2
= FunctionType::get(
440 /*Result=*/Type::getVoidTy(Context
),
441 /*Params=*/FuncTy_2_args
,
444 // Function Declarations
446 Function
* func_test1
= Function::Create(
448 /*Linkage=*/GlobalValue::ExternalLinkage
,
449 /*Name=*/"test1", mod
);
450 func_test1
->setCallingConv(CallingConv::C
);
451 AttributeList func_test1_PAL
;
452 func_test1
->setAttributes(func_test1_PAL
);
454 Function
* func_test2
= Function::Create(
456 /*Linkage=*/GlobalValue::ExternalLinkage
,
457 /*Name=*/"test2", mod
);
458 func_test2
->setCallingConv(CallingConv::C
);
459 AttributeList func_test2_PAL
;
460 func_test2
->setAttributes(func_test2_PAL
);
462 Function
* func_test3
= Function::Create(
464 /*Linkage=*/GlobalValue::InternalLinkage
,
465 /*Name=*/"test3", mod
);
466 func_test3
->setCallingConv(CallingConv::C
);
467 AttributeList func_test3_PAL
;
468 func_test3
->setAttributes(func_test3_PAL
);
470 Function
* func_test4
= Function::Create(
472 /*Linkage=*/GlobalValue::ExternalLinkage
,
473 /*Name=*/"test4", mod
);
474 func_test4
->setCallingConv(CallingConv::C
);
475 AttributeList func_test4_PAL
;
476 func_test4
->setAttributes(func_test4_PAL
);
478 // Global Variable Declarations
481 // Constant Definitions
483 // Global Variable Definitions
485 // Function Definitions
487 // Function: test1 (func_test1)
490 BasicBlock
*label_entry
=
491 BasicBlock::Create(Context
, "entry", func_test1
, nullptr);
493 // Block entry (label_entry)
494 CallInst
* int32_3
= CallInst::Create(func_test2
, "", label_entry
);
495 int32_3
->setCallingConv(CallingConv::C
);
496 int32_3
->setTailCall(false);
497 AttributeList int32_3_PAL
;
498 int32_3
->setAttributes(int32_3_PAL
);
500 ReturnInst::Create(Context
, int32_3
, label_entry
);
503 // Function: test2 (func_test2)
506 BasicBlock
*label_entry_5
=
507 BasicBlock::Create(Context
, "entry", func_test2
, nullptr);
509 // Block entry (label_entry_5)
510 CallInst
* int32_6
= CallInst::Create(func_test3
, "", label_entry_5
);
511 int32_6
->setCallingConv(CallingConv::C
);
512 int32_6
->setTailCall(false);
513 AttributeList int32_6_PAL
;
514 int32_6
->setAttributes(int32_6_PAL
);
516 ReturnInst::Create(Context
, int32_6
, label_entry_5
);
519 // Function: test3 (func_test3)
522 BasicBlock
*label_entry_8
=
523 BasicBlock::Create(Context
, "entry", func_test3
, nullptr);
525 // Block entry (label_entry_8)
526 CallInst
* int32_9
= CallInst::Create(func_test1
, "", label_entry_8
);
527 int32_9
->setCallingConv(CallingConv::C
);
528 int32_9
->setTailCall(false);
529 AttributeList int32_9_PAL
;
530 int32_9
->setAttributes(int32_9_PAL
);
532 ReturnInst::Create(Context
, int32_9
, label_entry_8
);
535 // Function: test4 (func_test4)
537 Function::arg_iterator args
= func_test4
->arg_begin();
538 Value
*int1_f
= &*args
++;
539 int1_f
->setName("f");
541 BasicBlock
*label_entry_11
=
542 BasicBlock::Create(Context
, "entry", func_test4
, nullptr);
543 BasicBlock
*label_bb
=
544 BasicBlock::Create(Context
, "bb", func_test4
, nullptr);
545 BasicBlock
*label_bb1
=
546 BasicBlock::Create(Context
, "bb1", func_test4
, nullptr);
547 BasicBlock
*label_return
=
548 BasicBlock::Create(Context
, "return", func_test4
, nullptr);
550 // Block entry (label_entry_11)
551 auto *AI
= new AllocaInst(func_test3
->getType(), 0, "func3ptr",
553 new StoreInst(func_test3
, AI
, label_entry_11
);
554 BranchInst::Create(label_bb
, label_entry_11
);
556 // Block bb (label_bb)
557 BranchInst::Create(label_bb
, label_bb1
, int1_f
, label_bb
);
559 // Block bb1 (label_bb1)
560 BranchInst::Create(label_bb1
, label_return
, int1_f
, label_bb1
);
562 // Block return (label_return)
563 ReturnInst::Create(Context
, label_return
);
568 // Test for call graph SCC pass that replaces all callback call instructions
569 // with clones and updates CallGraph by calling CallGraph::replaceCallEdge()
570 // method. Test is expected to complete successfully after running pass on
571 // all SCCs in the test module.
572 struct CallbackCallsModifierPass
: public CGPass
{
573 bool runOnSCC(CallGraphSCC
&SCC
) override
{
576 CallGraph
&CG
= const_cast<CallGraph
&>(SCC
.getCallGraph());
578 bool Changed
= false;
579 for (CallGraphNode
*CGN
: SCC
) {
580 Function
*F
= CGN
->getFunction();
581 if (!F
|| F
->isDeclaration())
584 SmallVector
<CallBase
*, 4u> Calls
;
585 for (Use
&U
: F
->uses()) {
586 AbstractCallSite
ACS(&U
);
587 if (!ACS
|| !ACS
.isCallbackCall() || !ACS
.isCallee(&U
))
589 Calls
.push_back(cast
<CallBase
>(ACS
.getInstruction()));
594 for (CallBase
*OldCB
: Calls
) {
595 CallGraphNode
*CallerCGN
= CG
[OldCB
->getParent()->getParent()];
596 assert(any_of(*CallerCGN
,
597 [CGN
](const CallGraphNode::CallRecord
&CallRecord
) {
598 return CallRecord
.second
== CGN
;
600 "function is not a callee");
602 CallBase
*NewCB
= cast
<CallBase
>(OldCB
->clone());
604 NewCB
->insertBefore(OldCB
);
605 NewCB
->takeName(OldCB
);
607 CallerCGN
->replaceCallEdge(*OldCB
, *NewCB
, CG
[F
]);
609 OldCB
->replaceAllUsesWith(NewCB
);
610 OldCB
->eraseFromParent();
618 TEST(PassManager
, CallbackCallsModifier0
) {
621 const char *IR
= "define void @foo() {\n"
622 " call void @broker(void (i8*)* @callback0, i8* null)\n"
623 " call void @broker(void (i8*)* @callback1, i8* null)\n"
627 "declare !callback !0 void @broker(void (i8*)*, i8*)\n"
629 "define internal void @callback0(i8* %arg) {\n"
633 "define internal void @callback1(i8* %arg) {\n"
638 "!1 = !{i64 0, i64 1, i1 false}";
641 std::unique_ptr
<Module
> M
= parseAssemblyString(IR
, Err
, Context
);
643 Err
.print("LegacyPassManagerTest", errs());
645 CallbackCallsModifierPass
*P
= new CallbackCallsModifierPass();
646 legacy::PassManager Passes
;
653 INITIALIZE_PASS(ModuleNDM
, "mndm", "mndm", false, false)
654 INITIALIZE_PASS_BEGIN(CGPass
, "cgp","cgp", false, false)
655 INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass
)
656 INITIALIZE_PASS_END(CGPass
, "cgp","cgp", false, false)
657 INITIALIZE_PASS(FPass
, "fp","fp", false, false)
658 INITIALIZE_PASS_BEGIN(LPass
, "lp","lp", false, false)
659 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass
)
660 INITIALIZE_PASS_END(LPass
, "lp","lp", false, false)