diff --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h --- a/llvm/include/llvm/IR/ModuleSummaryIndex.h +++ b/llvm/include/llvm/IR/ModuleSummaryIndex.h @@ -315,6 +315,27 @@ StackIdIndices(std::move(StackIdIndices)) {} }; +inline raw_ostream &operator<<(raw_ostream &OS, const CallsiteInfo &SNI) { + OS << "Callee: " << SNI.Callee; + bool First = true; + OS << " Clones: "; + for (auto V : SNI.Clones) { + if (!First) + OS << ", "; + First = false; + OS << V; + } + First = true; + OS << " StackIds: "; + for (auto Id : SNI.StackIdIndices) { + if (!First) + OS << ", "; + First = false; + OS << Id; + } + return OS; +} + // Allocation type assigned to an allocation reached by a given context. // More can be added but initially this is just noncold and cold. // Values should be powers of two so that they can be ORed, in particular to @@ -337,6 +358,19 @@ : AllocType(AllocType), StackIdIndices(std::move(StackIdIndices)) {} }; +inline raw_ostream &operator<<(raw_ostream &OS, const MIBInfo &MIB) { + OS << "AllocType " << (unsigned)MIB.AllocType; + bool First = true; + OS << " StackIds: "; + for (auto Id : MIB.StackIdIndices) { + if (!First) + OS << ", "; + First = false; + OS << Id; + } + return OS; +} + /// Summary of memprof metadata on allocations. struct AllocInfo { // Used to record whole program analysis cloning decisions. @@ -359,6 +393,22 @@ : Versions(std::move(Versions)), MIBs(std::move(MIBs)) {} }; +inline raw_ostream &operator<<(raw_ostream &OS, const AllocInfo &AE) { + bool First = true; + OS << "Versions: "; + for (auto V : AE.Versions) { + if (!First) + OS << ", "; + First = false; + OS << (unsigned)V; + } + OS << " MIB:\n"; + for (auto &M : AE.MIBs) { + OS << "\t\t" << M << "\n"; + } + return OS; +} + /// Function and variable summary information to aid decisions and /// implementation of importing. class GlobalValueSummary { diff --git a/llvm/unittests/IR/CMakeLists.txt b/llvm/unittests/IR/CMakeLists.txt --- a/llvm/unittests/IR/CMakeLists.txt +++ b/llvm/unittests/IR/CMakeLists.txt @@ -32,6 +32,7 @@ ManglerTest.cpp MetadataTest.cpp ModuleTest.cpp + ModuleSummaryIndexTest.cpp PassManagerTest.cpp PatternMatch.cpp ShuffleVectorInstTest.cpp diff --git a/llvm/unittests/IR/ModuleSummaryIndexTest.cpp b/llvm/unittests/IR/ModuleSummaryIndexTest.cpp new file mode 100644 --- /dev/null +++ b/llvm/unittests/IR/ModuleSummaryIndexTest.cpp @@ -0,0 +1,57 @@ +//===- ModuleSummaryIndexTest.cpp - ModuleSummaryIndex Unit Tests-============// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/AsmParser/Parser.h" +#include "llvm/Support/SourceMgr.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +static std::unique_ptr makeLLVMIndex(const char *Summary) { + SMDiagnostic Err; + std::unique_ptr Index = + parseSummaryIndexAssemblyString(Summary, Err); + if (!Index) + Err.print("ModuleSummaryIndexTest", errs()); + return Index; +} + +TEST(ModuleSummaryIndexTest, MemProfSummaryPrinting) { + std::unique_ptr Index = makeLLVMIndex(R"Summary( +^0 = module: (path: "test.o", hash: (0, 0, 0, 0, 0)) +^1 = gv: (guid: 23, summaries: (function: (module: ^0, flags: (linkage: external), insts: 2, allocs: ((versions: (none), memProf: ((type: notcold, stackIds: (1, 2, 3, 4)), (type: cold, stackIds: (1, 2, 3, 5)))))))) +^2 = gv: (guid: 25, summaries: (function: (module: ^0, flags: (linkage: external), insts: 22, calls: ((callee: ^1)), callsites: ((callee: ^1, clones: (0), stackIds: (3, 4)), (callee: ^1, clones: (0), stackIds: (3, 5)))))) +)Summary"); + + std::string Data; + raw_string_ostream OS(Data); + + ASSERT_NE(Index, nullptr); + auto *CallsiteSummary = + cast(Index->getGlobalValueSummary(/*guid=*/25)); + for (auto &CI : CallsiteSummary->callsites()) + OS << "\n" << CI; + + auto *AllocSummary = + cast(Index->getGlobalValueSummary(/*guid=*/23)); + for (auto &AI : AllocSummary->allocs()) + OS << "\n" << AI; + + OS.flush(); + EXPECT_EQ(Data, R"( +Callee: 23 Clones: 0 StackIds: 2, 3 +Callee: 23 Clones: 0 StackIds: 2, 4 +Versions: 0 MIB: + AllocType 1 StackIds: 0, 1, 2, 3 + AllocType 2 StackIds: 0, 1, 2, 4 +)"); +} +} // end anonymous namespace