brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 3fba07d Raw
184 lines · cpp
1//===--- CtxProfAnalysisTest.cpp ------------------------------------------===//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/Analysis/CtxProfAnalysis.h"10#include "llvm/Analysis/BlockFrequencyInfo.h"11#include "llvm/Analysis/BranchProbabilityInfo.h"12#include "llvm/Analysis/CGSCCPassManager.h"13#include "llvm/Analysis/LoopAnalysisManager.h"14#include "llvm/AsmParser/Parser.h"15#include "llvm/IR/Analysis.h"16#include "llvm/IR/Module.h"17#include "llvm/IR/PassInstrumentation.h"18#include "llvm/IR/PassManager.h"19#include "llvm/Passes/PassBuilder.h"20#include "llvm/Support/SourceMgr.h"21#include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"22#include "gmock/gmock.h"23#include "gtest/gtest.h"24 25using namespace llvm;26 27namespace {28 29class CtxProfAnalysisTest : public testing::Test {30  static constexpr auto *IR = R"IR(31declare void @bar()32 33define private void @foo(i32 %a, ptr %fct) #0 !guid !0 {34  %t = icmp eq i32 %a, 035  br i1 %t, label %yes, label %no36yes:37  call void %fct(i32 %a)38  br label %exit39no:40  call void @bar()41  br label %exit42exit:43  ret void44}45 46define void @an_entrypoint(i32 %a) {47  %t = icmp eq i32 %a, 048  br i1 %t, label %yes, label %no49 50yes:51  call void @foo(i32 1, ptr null)52  ret void53no:54  ret void55}56 57define void @another_entrypoint_no_callees(i32 %a) {58  %t = icmp eq i32 %a, 059  br i1 %t, label %yes, label %no60 61yes:62  ret void63no:64  ret void65}66 67define void @inlineasm() {68  call void asm "nop", ""()69  ret void70}71 72attributes #0 = { noinline }73!0 = !{ i64 11872291593386833696 }74)IR";75 76protected:77  LLVMContext C;78  PassBuilder PB;79  ModuleAnalysisManager MAM;80  FunctionAnalysisManager FAM;81  CGSCCAnalysisManager CGAM;82  LoopAnalysisManager LAM;83  std::unique_ptr<Module> M;84 85  void SetUp() override {86    SMDiagnostic Err;87    M = parseAssemblyString(IR, Err, C);88    ASSERT_TRUE(!!M);89  }90 91public:92  CtxProfAnalysisTest() {93    PB.registerModuleAnalyses(MAM);94    PB.registerCGSCCAnalyses(CGAM);95    PB.registerFunctionAnalyses(FAM);96    PB.registerLoopAnalyses(LAM);97    PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);98  }99};100 101TEST_F(CtxProfAnalysisTest, GetCallsiteIDTest) {102  ModulePassManager MPM;103  MPM.addPass(PGOInstrumentationGen(PGOInstrumentationType::CTXPROF));104  EXPECT_FALSE(MPM.run(*M, MAM).areAllPreserved());105  auto *F = M->getFunction("foo");106  ASSERT_NE(F, nullptr);107  std::vector<uint32_t> InsValues;108 109  for (auto &BB : *F)110    for (auto &I : BB)111      if (auto *CB = dyn_cast<CallBase>(&I)) {112        // Skip instrumentation inserted intrinsics.113        if (CB->getCalledFunction() && CB->getCalledFunction()->isIntrinsic())114          continue;115        auto *Ins = CtxProfAnalysis::getCallsiteInstrumentation(*CB);116        ASSERT_NE(Ins, nullptr);117        InsValues.push_back(Ins->getIndex()->getZExtValue());118      }119 120  EXPECT_THAT(InsValues, testing::ElementsAre(0, 1));121}122 123TEST_F(CtxProfAnalysisTest, GetCallsiteIDInlineAsmTest) {124  ModulePassManager MPM;125  MPM.addPass(PGOInstrumentationGen(PGOInstrumentationType::CTXPROF));126  EXPECT_FALSE(MPM.run(*M, MAM).areAllPreserved());127  auto *F = M->getFunction("inlineasm");128  ASSERT_NE(F, nullptr);129  std::vector<const Instruction *> InsValues;130 131  for (auto &BB : *F)132    for (auto &I : BB)133      if (auto *CB = dyn_cast<CallBase>(&I)) {134        // Skip instrumentation inserted intrinsics.135        if (CB->getCalledFunction() && CB->getCalledFunction()->isIntrinsic())136          continue;137        auto *Ins = CtxProfAnalysis::getCallsiteInstrumentation(*CB);138        InsValues.push_back(Ins);139      }140 141  EXPECT_THAT(InsValues, testing::ElementsAre(nullptr));142}143 144TEST_F(CtxProfAnalysisTest, GetCallsiteIDNegativeTest) {145  auto *F = M->getFunction("foo");146  ASSERT_NE(F, nullptr);147  CallBase *FirstCall = nullptr;148  for (auto &BB : *F)149    for (auto &I : BB)150      if (auto *CB = dyn_cast<CallBase>(&I)) {151        if (CB->isIndirectCall() || !CB->getCalledFunction()->isIntrinsic()) {152          FirstCall = CB;153          break;154        }155      }156  ASSERT_NE(FirstCall, nullptr);157  auto *IndIns = CtxProfAnalysis::getCallsiteInstrumentation(*FirstCall);158  EXPECT_EQ(IndIns, nullptr);159}160 161TEST_F(CtxProfAnalysisTest, GetBBIDTest) {162  ModulePassManager MPM;163  MPM.addPass(PGOInstrumentationGen(PGOInstrumentationType::CTXPROF));164  EXPECT_FALSE(MPM.run(*M, MAM).areAllPreserved());165  auto *F = M->getFunction("foo");166  ASSERT_NE(F, nullptr);167  std::map<std::string, int> BBNameAndID;168 169  for (auto &BB : *F) {170    auto *Ins = CtxProfAnalysis::getBBInstrumentation(BB);171    if (Ins)172      BBNameAndID[BB.getName().str()] =173          static_cast<int>(Ins->getIndex()->getZExtValue());174    else175      BBNameAndID[BB.getName().str()] = -1;176  }177 178  EXPECT_THAT(BBNameAndID,179              testing::UnorderedElementsAre(180                  testing::Pair("", 0), testing::Pair("yes", 1),181                  testing::Pair("no", -1), testing::Pair("exit", -1)));182}183} // namespace184