1 //===- unittests/IR/TimePassesTest.cpp - TimePassesHandler 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 #include <gtest/gtest.h>
10 #include <llvm/ADT/SmallString.h>
11 #include "llvm/IR/LegacyPassManager.h"
12 #include <llvm/IR/LLVMContext.h>
13 #include <llvm/IR/Module.h>
14 #include <llvm/IR/PassInstrumentation.h>
15 #include <llvm/IR/PassManager.h>
16 #include <llvm/IR/PassTimingInfo.h>
17 #include <llvm/Support/raw_ostream.h>
21 //===----------------------------------------------------------------------===//
22 // Define dummy passes for legacy pass manager run.
26 void initializePass1Pass(PassRegistry
&);
27 void initializePass2Pass(PassRegistry
&);
30 struct Pass1
: public ModulePass
{
34 Pass1() : ModulePass(ID
) {}
35 bool runOnModule(Module
&M
) override
{ return false; }
36 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
39 StringRef
getPassName() const override
{ return "Pass1"; }
43 struct Pass2
: public ModulePass
{
47 Pass2() : ModulePass(ID
) {}
48 bool runOnModule(Module
&M
) override
{ return false; }
49 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
52 StringRef
getPassName() const override
{ return "Pass2"; }
58 INITIALIZE_PASS(Pass1
, "Pass1", "Pass1", false, false)
59 INITIALIZE_PASS(Pass2
, "Pass2", "Pass2", false, false)
63 TEST(TimePassesTest
, LegacyCustomOut
) {
64 PassInstrumentationCallbacks PIC
;
65 PassInstrumentation
PI(&PIC
);
68 Module
M("TestModule", Context
);
70 SmallString
<0> TimePassesStr
;
71 raw_svector_ostream
ReportStream(TimePassesStr
);
74 legacy::PassManager PM1
;
75 PM1
.add(new llvm::Pass1());
76 PM1
.add(new llvm::Pass2());
78 // Enable time-passes and run passes.
79 TimePassesIsEnabled
= true;
83 reportAndResetTimings(&ReportStream
);
85 // There should be Pass1 and Pass2 in the report
86 EXPECT_FALSE(TimePassesStr
.empty());
87 EXPECT_TRUE(TimePassesStr
.str().contains("report"));
88 EXPECT_TRUE(TimePassesStr
.str().contains("Pass1"));
89 EXPECT_TRUE(TimePassesStr
.str().contains("Pass2"));
91 // Clear and generate report again.
92 TimePassesStr
.clear();
93 reportAndResetTimings(&ReportStream
);
95 // Since we did not run any passes since last print, report should be empty.
96 EXPECT_TRUE(TimePassesStr
.empty());
98 // Now run just a single pass to populate timers again.
99 legacy::PassManager PM2
;
100 PM2
.add(new llvm::Pass2());
103 // Generate report again.
104 reportAndResetTimings(&ReportStream
);
106 // There should be Pass2 in this report and no Pass1.
107 EXPECT_FALSE(TimePassesStr
.str().empty());
108 EXPECT_TRUE(TimePassesStr
.str().contains("report"));
109 EXPECT_FALSE(TimePassesStr
.str().contains("Pass1"));
110 EXPECT_TRUE(TimePassesStr
.str().contains("Pass2"));
113 class MyPass1
: public PassInfoMixin
<MyPass1
> {};
114 class MyPass2
: public PassInfoMixin
<MyPass2
> {};
116 TEST(TimePassesTest
, CustomOut
) {
117 PassInstrumentationCallbacks PIC
;
118 PassInstrumentation
PI(&PIC
);
121 Module
M("TestModule", Context
);
125 SmallString
<0> TimePassesStr
;
126 raw_svector_ostream
ReportStream(TimePassesStr
);
128 // Setup time-passes handler and redirect output to the stream.
129 std::unique_ptr
<TimePassesHandler
> TimePasses
=
130 std::make_unique
<TimePassesHandler
>(true);
131 TimePasses
->setOutStream(ReportStream
);
132 TimePasses
->registerCallbacks(PIC
);
134 // Pretending that passes are running to trigger the timers.
135 PI
.runBeforePass(Pass1
, M
);
136 PI
.runBeforePass(Pass2
, M
);
137 PI
.runAfterPass(Pass2
, M
);
138 PI
.runAfterPass(Pass1
, M
);
140 // Generating report.
143 // There should be Pass1 and Pass2 in the report
144 EXPECT_FALSE(TimePassesStr
.empty());
145 EXPECT_TRUE(TimePassesStr
.str().contains("report"));
146 EXPECT_TRUE(TimePassesStr
.str().contains("Pass1"));
147 EXPECT_TRUE(TimePassesStr
.str().contains("Pass2"));
149 // Clear and generate report again.
150 TimePassesStr
.clear();
152 // Since we did not run any passes since last print, report should be empty.
153 EXPECT_TRUE(TimePassesStr
.empty());
155 // Now trigger just a single pass to populate timers again.
156 PI
.runBeforePass(Pass2
, M
);
157 PI
.runAfterPass(Pass2
, M
);
159 // Generate report by deleting the handler.
162 // There should be Pass2 in this report and no Pass1.
163 EXPECT_FALSE(TimePassesStr
.str().empty());
164 EXPECT_TRUE(TimePassesStr
.str().contains("report"));
165 EXPECT_FALSE(TimePassesStr
.str().contains("Pass1"));
166 EXPECT_TRUE(TimePassesStr
.str().contains("Pass2"));
169 } // end anonymous namespace