brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · 8598613 Raw
175 lines · cpp
1//===- unittests/IR/TimePassesTest.cpp - TimePassesHandler tests ----------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/IR/LegacyPassManager.h"10#include "llvm/Pass.h"11#include "llvm/PassRegistry.h"12#include <gtest/gtest.h>13#include <llvm/ADT/SmallString.h>14#include <llvm/IR/LLVMContext.h>15#include <llvm/IR/Module.h>16#include <llvm/IR/PassInstrumentation.h>17#include <llvm/IR/PassManager.h>18#include <llvm/IR/PassTimingInfo.h>19#include <llvm/Support/raw_ostream.h>20 21using namespace llvm;22 23//===----------------------------------------------------------------------===//24// Define dummy passes for legacy pass manager run.25 26namespace llvm {27 28void initializePass1Pass(PassRegistry &);29void initializePass2Pass(PassRegistry &);30 31namespace {32struct Pass1 : public ModulePass {33  static char ID;34 35public:36  Pass1() : ModulePass(ID) {}37  bool runOnModule(Module &M) override { return false; }38  void getAnalysisUsage(AnalysisUsage &AU) const override {39    AU.setPreservesAll();40  }41  StringRef getPassName() const override { return "Pass1"; }42};43char Pass1::ID;44 45struct Pass2 : public ModulePass {46  static char ID;47 48public:49  Pass2() : ModulePass(ID) {}50  bool runOnModule(Module &M) override { return false; }51  void getAnalysisUsage(AnalysisUsage &AU) const override {52    AU.setPreservesAll();53  }54  StringRef getPassName() const override { return "Pass2"; }55};56char Pass2::ID;57} // namespace58} // namespace llvm59 60INITIALIZE_PASS(Pass1, "Pass1", "Pass1", false, false)61INITIALIZE_PASS(Pass2, "Pass2", "Pass2", false, false)62 63namespace {64 65TEST(TimePassesTest, LegacyCustomOut) {66  PassInstrumentationCallbacks PIC;67  PassInstrumentation PI(&PIC);68 69  LLVMContext Context;70  Module M("TestModule", Context);71 72  SmallString<0> TimePassesStr;73  raw_svector_ostream ReportStream(TimePassesStr);74 75  // Setup pass manager76  legacy::PassManager PM1;77  PM1.add(new llvm::Pass1());78  PM1.add(new llvm::Pass2());79 80  // Enable time-passes and run passes.81  TimePassesIsEnabled = true;82  PM1.run(M);83 84  // Generating report.85  reportAndResetTimings(&ReportStream);86 87  // There should be Pass1 and Pass2 in the report88  EXPECT_FALSE(TimePassesStr.empty());89  EXPECT_TRUE(TimePassesStr.str().contains("report"));90  EXPECT_TRUE(TimePassesStr.str().contains("Pass1"));91  EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));92 93  // Clear and generate report again.94  TimePassesStr.clear();95  reportAndResetTimings(&ReportStream);96 97  // Since we did not run any passes since last print, report should be empty.98  EXPECT_TRUE(TimePassesStr.empty());99 100  // Now run just a single pass to populate timers again.101  legacy::PassManager PM2;102  PM2.add(new llvm::Pass2());103  PM2.run(M);104 105  // Generate report again.106  reportAndResetTimings(&ReportStream);107 108  // There should be Pass2 in this report and no Pass1.109  EXPECT_FALSE(TimePassesStr.str().empty());110  EXPECT_TRUE(TimePassesStr.str().contains("report"));111  EXPECT_FALSE(TimePassesStr.str().contains("Pass1"));112  EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));113 114  // Reset flag to not affect other tests.115  TimePassesIsEnabled = false;116}117 118class MyPass1 : public PassInfoMixin<MyPass1> {};119class MyPass2 : public PassInfoMixin<MyPass2> {};120 121TEST(TimePassesTest, CustomOut) {122  PassInstrumentationCallbacks PIC;123  PassInstrumentation PI(&PIC);124 125  LLVMContext Context;126  Module M("TestModule", Context);127  MyPass1 Pass1;128  MyPass2 Pass2;129 130  SmallString<0> TimePassesStr;131  raw_svector_ostream ReportStream(TimePassesStr);132 133  // Setup time-passes handler and redirect output to the stream.134  std::unique_ptr<TimePassesHandler> TimePasses =135      std::make_unique<TimePassesHandler>(true);136  TimePasses->setOutStream(ReportStream);137  TimePasses->registerCallbacks(PIC);138 139  // Pretending that passes are running to trigger the timers.140  PI.runBeforePass(Pass1, M);141  PI.runAfterPass(Pass1, M, PreservedAnalyses::all());142  PI.runBeforePass(Pass2, M);143  PI.runAfterPass(Pass2, M, PreservedAnalyses::all());144 145  // Generating report.146  TimePasses->print();147 148  // There should be Pass1 and Pass2 in the report149  EXPECT_FALSE(TimePassesStr.empty());150  EXPECT_TRUE(TimePassesStr.str().contains("report"));151  EXPECT_TRUE(TimePassesStr.str().contains("Pass1"));152  EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));153 154  // Clear and generate report again.155  TimePassesStr.clear();156  TimePasses->print();157  // Since we did not run any passes since last print, report should be empty.158  EXPECT_TRUE(TimePassesStr.empty());159 160  // Now trigger just a single pass to populate timers again.161  PI.runBeforePass(Pass2, M);162  PI.runAfterPass(Pass2, M, PreservedAnalyses::all());163 164  // Clear and generate report again.165  TimePasses->print();166 167  // There should be Pass2 in this report and no Pass1.168  EXPECT_FALSE(TimePassesStr.str().empty());169  EXPECT_TRUE(TimePassesStr.str().contains("report"));170  EXPECT_FALSE(TimePassesStr.str().contains("Pass1"));171  EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));172}173 174} // end anonymous namespace175