mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[ThinLTO] Add FunctionAttrs to ThinLTO index
Adds function attributes to index: ReadNone, ReadOnly, NoRecurse, NoAlias. This attributes will be used for future ThinLTO optimizations that will propagate function attributes across modules. llvm-svn: 310061
This commit is contained in:
parent
0e224c7256
commit
81929b6bb0
@ -25,6 +25,7 @@
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Transforms/IPO/FunctionAttrs.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
@ -287,11 +288,24 @@ public:
|
||||
std::vector<uint64_t> Args;
|
||||
};
|
||||
|
||||
/// Function attribute flags. Used to track if a function accesses memory,
|
||||
/// recurses or aliases.
|
||||
struct FFlags {
|
||||
unsigned ReadNone : 1;
|
||||
unsigned ReadOnly : 1;
|
||||
unsigned NoRecurse : 1;
|
||||
unsigned ReturnDoesNotAlias : 1;
|
||||
};
|
||||
|
||||
private:
|
||||
/// Number of instructions (ignoring debug instructions, e.g.) computed
|
||||
/// during the initial compile step when the summary index is first built.
|
||||
unsigned InstCount;
|
||||
|
||||
/// Function attribute flags. Used to track if a function accesses memory,
|
||||
/// recurses or aliases.
|
||||
FFlags FunFlags;
|
||||
|
||||
/// List of <CalleeValueInfo, CalleeInfo> call edge pairs from this function.
|
||||
std::vector<EdgeTy> CallGraphEdgeList;
|
||||
|
||||
@ -317,15 +331,16 @@ private:
|
||||
std::unique_ptr<TypeIdInfo> TIdInfo;
|
||||
|
||||
public:
|
||||
FunctionSummary(GVFlags Flags, unsigned NumInsts, std::vector<ValueInfo> Refs,
|
||||
std::vector<EdgeTy> CGEdges,
|
||||
FunctionSummary(GVFlags Flags, unsigned NumInsts, FFlags FunFlags,
|
||||
std::vector<ValueInfo> Refs, std::vector<EdgeTy> CGEdges,
|
||||
std::vector<GlobalValue::GUID> TypeTests,
|
||||
std::vector<VFuncId> TypeTestAssumeVCalls,
|
||||
std::vector<VFuncId> TypeCheckedLoadVCalls,
|
||||
std::vector<ConstVCall> TypeTestAssumeConstVCalls,
|
||||
std::vector<ConstVCall> TypeCheckedLoadConstVCalls)
|
||||
: GlobalValueSummary(FunctionKind, Flags, std::move(Refs)),
|
||||
InstCount(NumInsts), CallGraphEdgeList(std::move(CGEdges)) {
|
||||
InstCount(NumInsts), FunFlags(FunFlags),
|
||||
CallGraphEdgeList(std::move(CGEdges)) {
|
||||
if (!TypeTests.empty() || !TypeTestAssumeVCalls.empty() ||
|
||||
!TypeCheckedLoadVCalls.empty() || !TypeTestAssumeConstVCalls.empty() ||
|
||||
!TypeCheckedLoadConstVCalls.empty())
|
||||
@ -341,6 +356,9 @@ public:
|
||||
return GVS->getSummaryKind() == FunctionKind;
|
||||
}
|
||||
|
||||
/// Get function attribute flags.
|
||||
FFlags &fflags() { return FunFlags; }
|
||||
|
||||
/// Get the instruction count recorded for this function.
|
||||
unsigned instCount() const { return InstCount; }
|
||||
|
||||
|
@ -206,8 +206,9 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
|
||||
GlobalValueSummary::GVFlags(
|
||||
static_cast<GlobalValue::LinkageTypes>(FSum.Linkage),
|
||||
FSum.NotEligibleToImport, FSum.Live),
|
||||
0, ArrayRef<ValueInfo>{}, ArrayRef<FunctionSummary::EdgeTy>{},
|
||||
std::move(FSum.TypeTests), std::move(FSum.TypeTestAssumeVCalls),
|
||||
0, FunctionSummary::FFlags{}, ArrayRef<ValueInfo>{},
|
||||
ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests),
|
||||
std::move(FSum.TypeTestAssumeVCalls),
|
||||
std::move(FSum.TypeCheckedLoadVCalls),
|
||||
std::move(FSum.TypeTestAssumeConstVCalls),
|
||||
std::move(FSum.TypeCheckedLoadConstVCalls)));
|
||||
|
@ -276,10 +276,16 @@ computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
|
||||
F.isVarArg();
|
||||
GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport,
|
||||
/* Live = */ false);
|
||||
FunctionSummary::FFlags FunFlags{
|
||||
F.hasFnAttribute(Attribute::ReadNone),
|
||||
F.hasFnAttribute(Attribute::ReadOnly),
|
||||
F.hasFnAttribute(Attribute::NoRecurse),
|
||||
F.returnDoesNotAlias(),
|
||||
};
|
||||
auto FuncSummary = llvm::make_unique<FunctionSummary>(
|
||||
Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector(),
|
||||
TypeTests.takeVector(), TypeTestAssumeVCalls.takeVector(),
|
||||
TypeCheckedLoadVCalls.takeVector(),
|
||||
Flags, NumInsts, FunFlags, RefEdges.takeVector(),
|
||||
CallGraphEdges.takeVector(), TypeTests.takeVector(),
|
||||
TypeTestAssumeVCalls.takeVector(), TypeCheckedLoadVCalls.takeVector(),
|
||||
TypeTestAssumeConstVCalls.takeVector(),
|
||||
TypeCheckedLoadConstVCalls.takeVector());
|
||||
if (NonRenamableLocal)
|
||||
@ -427,11 +433,16 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
|
||||
/* Live = */ true);
|
||||
CantBePromoted.insert(GlobalValue::getGUID(Name));
|
||||
// Create the appropriate summary type.
|
||||
if (isa<Function>(GV)) {
|
||||
if (Function *F = dyn_cast<Function>(GV)) {
|
||||
std::unique_ptr<FunctionSummary> Summary =
|
||||
llvm::make_unique<FunctionSummary>(
|
||||
GVFlags, 0, ArrayRef<ValueInfo>{},
|
||||
ArrayRef<FunctionSummary::EdgeTy>{},
|
||||
GVFlags, 0,
|
||||
FunctionSummary::FFlags{
|
||||
F->hasFnAttribute(Attribute::ReadNone),
|
||||
F->hasFnAttribute(Attribute::ReadOnly),
|
||||
F->hasFnAttribute(Attribute::NoRecurse),
|
||||
F->returnDoesNotAlias()},
|
||||
ArrayRef<ValueInfo>{}, ArrayRef<FunctionSummary::EdgeTy>{},
|
||||
ArrayRef<GlobalValue::GUID>{},
|
||||
ArrayRef<FunctionSummary::VFuncId>{},
|
||||
ArrayRef<FunctionSummary::VFuncId>{},
|
||||
|
@ -860,6 +860,15 @@ static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
|
||||
}
|
||||
}
|
||||
|
||||
static FunctionSummary::FFlags getDecodedFFlags(uint64_t RawFlags) {
|
||||
FunctionSummary::FFlags Flags;
|
||||
Flags.ReadNone = RawFlags & 0x1;
|
||||
Flags.ReadOnly = (RawFlags >> 1) & 0x1;
|
||||
Flags.NoRecurse = (RawFlags >> 2) & 0x1;
|
||||
Flags.ReturnDoesNotAlias = (RawFlags >> 3) & 0x1;
|
||||
return Flags;
|
||||
}
|
||||
|
||||
/// Decode the flags for GlobalValue in the summary.
|
||||
static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
|
||||
uint64_t Version) {
|
||||
@ -5036,9 +5045,9 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
|
||||
}
|
||||
const uint64_t Version = Record[0];
|
||||
const bool IsOldProfileFormat = Version == 1;
|
||||
if (Version < 1 || Version > 3)
|
||||
if (Version < 1 || Version > 4)
|
||||
return error("Invalid summary version " + Twine(Version) +
|
||||
", 1, 2 or 3 expected");
|
||||
", 1, 2, 3 or 4 expected");
|
||||
Record.clear();
|
||||
|
||||
// Keep around the last seen summary to be used when we see an optional
|
||||
@ -5088,9 +5097,9 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
|
||||
std::make_pair(TheIndex.getOrInsertValueInfo(RefGUID), RefGUID);
|
||||
break;
|
||||
}
|
||||
// FS_PERMODULE: [valueid, flags, instcount, numrefs, numrefs x valueid,
|
||||
// n x (valueid)]
|
||||
// FS_PERMODULE_PROFILE: [valueid, flags, instcount, numrefs,
|
||||
// FS_PERMODULE: [valueid, flags, instcount, fflags, numrefs,
|
||||
// numrefs x valueid, n x (valueid)]
|
||||
// FS_PERMODULE_PROFILE: [valueid, flags, instcount, fflags, numrefs,
|
||||
// numrefs x valueid,
|
||||
// n x (valueid, hotness)]
|
||||
case bitc::FS_PERMODULE:
|
||||
@ -5098,14 +5107,21 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
|
||||
unsigned ValueID = Record[0];
|
||||
uint64_t RawFlags = Record[1];
|
||||
unsigned InstCount = Record[2];
|
||||
uint64_t RawFunFlags = 0;
|
||||
unsigned NumRefs = Record[3];
|
||||
int RefListStartIndex = 4;
|
||||
if (Version >= 4) {
|
||||
RawFunFlags = Record[3];
|
||||
NumRefs = Record[4];
|
||||
RefListStartIndex = 5;
|
||||
}
|
||||
|
||||
auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
|
||||
// The module path string ref set in the summary must be owned by the
|
||||
// index's module string table. Since we don't have a module path
|
||||
// string table section in the per-module index, we create a single
|
||||
// module path string table entry with an empty (0) ID to take
|
||||
// ownership.
|
||||
static int RefListStartIndex = 4;
|
||||
int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs;
|
||||
assert(Record.size() >= RefListStartIndex + NumRefs &&
|
||||
"Record size inconsistent with number of references");
|
||||
@ -5116,8 +5132,9 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
|
||||
ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex),
|
||||
IsOldProfileFormat, HasProfile);
|
||||
auto FS = llvm::make_unique<FunctionSummary>(
|
||||
Flags, InstCount, std::move(Refs), std::move(Calls),
|
||||
std::move(PendingTypeTests), std::move(PendingTypeTestAssumeVCalls),
|
||||
Flags, InstCount, getDecodedFFlags(RawFunFlags), std::move(Refs),
|
||||
std::move(Calls), std::move(PendingTypeTests),
|
||||
std::move(PendingTypeTestAssumeVCalls),
|
||||
std::move(PendingTypeCheckedLoadVCalls),
|
||||
std::move(PendingTypeTestAssumeConstVCalls),
|
||||
std::move(PendingTypeCheckedLoadConstVCalls));
|
||||
@ -5176,9 +5193,9 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
|
||||
TheIndex.addGlobalValueSummary(GUID.first, std::move(FS));
|
||||
break;
|
||||
}
|
||||
// FS_COMBINED: [valueid, modid, flags, instcount, numrefs,
|
||||
// FS_COMBINED: [valueid, modid, flags, instcount, fflags, numrefs,
|
||||
// numrefs x valueid, n x (valueid)]
|
||||
// FS_COMBINED_PROFILE: [valueid, modid, flags, instcount, numrefs,
|
||||
// FS_COMBINED_PROFILE: [valueid, modid, flags, instcount, fflags, numrefs,
|
||||
// numrefs x valueid, n x (valueid, hotness)]
|
||||
case bitc::FS_COMBINED:
|
||||
case bitc::FS_COMBINED_PROFILE: {
|
||||
@ -5186,9 +5203,17 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
|
||||
uint64_t ModuleId = Record[1];
|
||||
uint64_t RawFlags = Record[2];
|
||||
unsigned InstCount = Record[3];
|
||||
uint64_t RawFunFlags = 0;
|
||||
unsigned NumRefs = Record[4];
|
||||
int RefListStartIndex = 5;
|
||||
|
||||
if (Version >= 4) {
|
||||
RawFunFlags = Record[4];
|
||||
NumRefs = Record[5];
|
||||
RefListStartIndex = 6;
|
||||
}
|
||||
|
||||
auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
|
||||
static int RefListStartIndex = 5;
|
||||
int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs;
|
||||
assert(Record.size() >= RefListStartIndex + NumRefs &&
|
||||
"Record size inconsistent with number of references");
|
||||
@ -5200,8 +5225,9 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
|
||||
IsOldProfileFormat, HasProfile);
|
||||
ValueInfo VI = getValueInfoFromValueId(ValueID).first;
|
||||
auto FS = llvm::make_unique<FunctionSummary>(
|
||||
Flags, InstCount, std::move(Refs), std::move(Edges),
|
||||
std::move(PendingTypeTests), std::move(PendingTypeTestAssumeVCalls),
|
||||
Flags, InstCount, getDecodedFFlags(RawFunFlags), std::move(Refs),
|
||||
std::move(Edges), std::move(PendingTypeTests),
|
||||
std::move(PendingTypeTestAssumeVCalls),
|
||||
std::move(PendingTypeCheckedLoadVCalls),
|
||||
std::move(PendingTypeTestAssumeConstVCalls),
|
||||
std::move(PendingTypeCheckedLoadConstVCalls));
|
||||
|
@ -895,6 +895,15 @@ static unsigned getEncodedLinkage(const GlobalValue &GV) {
|
||||
return getEncodedLinkage(GV.getLinkage());
|
||||
}
|
||||
|
||||
static uint64_t getEncodedFFlags(FunctionSummary::FFlags Flags) {
|
||||
uint64_t RawFlags = 0;
|
||||
RawFlags |= Flags.ReadNone;
|
||||
RawFlags |= (Flags.ReadOnly << 1);
|
||||
RawFlags |= (Flags.NoRecurse << 2);
|
||||
RawFlags |= (Flags.ReturnDoesNotAlias << 3);
|
||||
return RawFlags;
|
||||
}
|
||||
|
||||
// Decode the flags for GlobalValue in the summary
|
||||
static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
|
||||
uint64_t RawFlags = 0;
|
||||
@ -1703,7 +1712,7 @@ void ModuleBitcodeWriter::writeDIGlobalVariableExpression(
|
||||
Record.push_back(N->isDistinct());
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getVariable()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getExpression()));
|
||||
|
||||
|
||||
Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR_EXPR, Record, Abbrev);
|
||||
Record.clear();
|
||||
}
|
||||
@ -3293,6 +3302,7 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord(
|
||||
|
||||
NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
|
||||
NameVals.push_back(FS->instCount());
|
||||
NameVals.push_back(getEncodedFFlags(FS->fflags()));
|
||||
NameVals.push_back(FS->refs().size());
|
||||
|
||||
for (auto &RI : FS->refs())
|
||||
@ -3346,7 +3356,7 @@ void ModuleBitcodeWriterBase::writeModuleLevelReferences(
|
||||
// Current version for the summary.
|
||||
// This is bumped whenever we introduce changes in the way some record are
|
||||
// interpreted, like flags for instance.
|
||||
static const uint64_t INDEX_VERSION = 3;
|
||||
static const uint64_t INDEX_VERSION = 4;
|
||||
|
||||
/// Emit the per-module summary section alongside the rest of
|
||||
/// the module's bitcode.
|
||||
@ -3379,6 +3389,7 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // flags
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // fflags
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
|
||||
// numrefs x valueid, n x (valueid)
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
||||
@ -3391,6 +3402,7 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // flags
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // fflags
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
|
||||
// numrefs x valueid, n x (valueid, hotness)
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
||||
@ -3476,6 +3488,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // flags
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // fflags
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
|
||||
// numrefs x valueid, n x (valueid)
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
||||
@ -3489,6 +3502,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // flags
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // fflags
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
|
||||
// numrefs x valueid, n x (valueid, hotness)
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
||||
@ -3574,6 +3588,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
|
||||
NameVals.push_back(Index.getModuleId(FS->modulePath()));
|
||||
NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
|
||||
NameVals.push_back(FS->instCount());
|
||||
NameVals.push_back(getEncodedFFlags(FS->fflags()));
|
||||
// Fill in below
|
||||
NameVals.push_back(0);
|
||||
|
||||
@ -3585,7 +3600,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
|
||||
NameVals.push_back(*RefValueId);
|
||||
Count++;
|
||||
}
|
||||
NameVals[4] = Count;
|
||||
NameVals[5] = Count;
|
||||
|
||||
bool HasProfileData = false;
|
||||
for (auto &EI : FS->calls()) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
; RUN: opt -module-summary %s -o - | llvm-bcanalyzer -dump | FileCheck %s
|
||||
|
||||
; CHECK: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; CHECK: <VERSION op0=3/>
|
||||
; CHECK: <VERSION op0=4/>
|
||||
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
; CHECK-NEXT: <VERSION
|
||||
; See if the call to func is registered.
|
||||
; The value id 1 matches the second FUNCTION record above.
|
||||
; CHECK-NEXT: <PERMODULE {{.*}} op4=1/>
|
||||
; CHECK-NEXT: <PERMODULE {{.*}} op5=1/>
|
||||
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
@ -26,7 +26,7 @@
|
||||
; COMBINED-NEXT: <VALUE_GUID op0=[[ALIASID:[0-9]+]] op1=-5751648690987223394/>
|
||||
; COMBINED-NEXT: <VALUE_GUID
|
||||
; COMBINED-NEXT: <VALUE_GUID op0=[[ALIASEEID:[0-9]+]] op1=-1039159065113703048/>
|
||||
; COMBINED-NEXT: <COMBINED {{.*}} op5=[[ALIASID]]/>
|
||||
; COMBINED-NEXT: <COMBINED {{.*}} op6=[[ALIASID]]/>
|
||||
; COMBINED-NEXT: <COMBINED {{.*}}
|
||||
; COMBINED-NEXT: <COMBINED_ALIAS {{.*}} op3=[[ALIASEEID]]
|
||||
; COMBINED-NEXT: </GLOBALVAL_SUMMARY_BLOCK
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
; CHECK: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; CHECK-NEXT: <VERSION
|
||||
; CHECK-NEXT: <PERMODULE {{.*}} op3=0 op4=[[ALIASID:[0-9]+]]/>
|
||||
; CHECK-NEXT: <PERMODULE {{.*}} op4=0 op5=[[ALIASID:[0-9]+]]/>
|
||||
; CHECK-NEXT: <PERMODULE {{.*}} op0=[[ALIASEEID:[0-9]+]]
|
||||
; CHECK-NEXT: <ALIAS {{.*}} op0=[[ALIASID]] {{.*}} op2=[[ALIASEEID]]/>
|
||||
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
@ -17,7 +17,7 @@
|
||||
; CHECK: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; CHECK-NEXT: <VERSION
|
||||
; See if the call to func is registered, using the expected hotness type.
|
||||
; CHECK-NEXT: <PERMODULE_PROFILE {{.*}} op4=1 op5=2/>
|
||||
; CHECK-NEXT: <PERMODULE_PROFILE {{.*}} op5=1 op6=2/>
|
||||
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
; CHECK-NEXT: blob data = 'mainfunc{{.*}}'
|
||||
@ -29,7 +29,7 @@
|
||||
; COMBINED-NEXT: <COMBINED
|
||||
; See if the call to func is registered, using the expected hotness type.
|
||||
; op6=2 which is hotnessType::None.
|
||||
; COMBINED-NEXT: <COMBINED_PROFILE {{.*}} op5=[[FUNCID]] op6=2/>
|
||||
; COMBINED-NEXT: <COMBINED_PROFILE {{.*}} op6=[[FUNCID]] op7=2/>
|
||||
; COMBINED-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
||||
; ModuleID = 'thinlto-function-summary-callgraph.ll'
|
||||
|
@ -29,7 +29,7 @@
|
||||
; CHECK-NEXT: <VERSION
|
||||
; CHECK-NEXT: <VALUE_GUID op0=25 op1=123/>
|
||||
; op4=hot1 op6=cold op8=hot2 op10=hot4 op12=none1 op14=hot3 op16=none2 op18=none3 op20=123
|
||||
; CHECK-NEXT: <PERMODULE_PROFILE {{.*}} op4=1 op5=3 op6=5 op7=1 op8=2 op9=3 op10=4 op11=1 op12=6 op13=2 op14=3 op15=3 op16=7 op17=2 op18=8 op19=2 op20=25 op21=4/>
|
||||
; CHECK-NEXT: <PERMODULE_PROFILE {{.*}} op5=1 op6=3 op7=5 op8=1 op9=2 op10=3 op11=4 op12=1 op13=6 op14=2 op15=3 op16=3 op17=7 op18=2 op19=8 op20=2 op21=25 op22=4/>
|
||||
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
@ -51,7 +51,7 @@
|
||||
; COMBINED-NEXT: <COMBINED abbrevid=
|
||||
; COMBINED-NEXT: <COMBINED abbrevid=
|
||||
; COMBINED-NEXT: <COMBINED abbrevid=
|
||||
; COMBINED-NEXT: <COMBINED_PROFILE {{.*}} op5=[[HOT1:.*]] op6=3 op7=[[COLD:.*]] op8=1 op9=[[HOT2:.*]] op10=3 op11=[[NONE1:.*]] op12=2 op13=[[HOT3:.*]] op14=3 op15=[[NONE2:.*]] op16=2 op17=[[NONE3:.*]] op18=2/>
|
||||
; COMBINED-NEXT: <COMBINED_PROFILE {{.*}} op6=[[HOT1:.*]] op7=3 op8=[[COLD:.*]] op9=1 op10=[[HOT2:.*]] op11=3 op12=[[NONE1:.*]] op13=2 op14=[[HOT3:.*]] op15=3 op16=[[NONE2:.*]] op17=2 op18=[[NONE3:.*]] op19=2/>
|
||||
; COMBINED_NEXT: <COMBINED abbrevid=
|
||||
; COMBINED_NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
; CHECK-NEXT: <VERSION
|
||||
; CHECK-NEXT: <VALUE_GUID op0=26 op1=123/>
|
||||
; op4=none1 op6=hot1 op8=cold1 op10=none2 op12=hot2 op14=cold2 op16=none3 op18=hot3 op20=cold3 op22=123
|
||||
; CHECK-NEXT: <PERMODULE_PROFILE {{.*}} op4=7 op5=0 op6=1 op7=3 op8=4 op9=1 op10=8 op11=0 op12=2 op13=3 op14=5 op15=1 op16=9 op17=0 op18=3 op19=3 op20=6 op21=1 op22=26 op23=4/>
|
||||
; CHECK-NEXT: <PERMODULE_PROFILE {{.*}} op5=7 op6=0 op7=1 op8=3 op9=4 op10=1 op11=8 op12=0 op13=2 op14=3 op15=5 op16=1 op17=9 op18=0 op19=3 op20=3 op21=6 op22=1 op23=26 op24=4/>
|
||||
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
@ -57,7 +57,7 @@
|
||||
; COMBINED-NEXT: <COMBINED abbrevid=
|
||||
; COMBINED-NEXT: <COMBINED abbrevid=
|
||||
; COMBINED-NEXT: <COMBINED abbrevid=
|
||||
; COMBINED-NEXT: <COMBINED_PROFILE {{.*}} op5=[[NONE1:.*]] op6=0 op7=[[HOT1:.*]] op8=3 op9=[[COLD1:.*]] op10=1 op11=[[NONE2:.*]] op12=0 op13=[[HOT2:.*]] op14=3 op15=[[COLD2:.*]] op16=1 op17=[[NONE3:.*]] op18=0 op19=[[HOT3:.*]] op20=3 op21=[[COLD3:.*]] op22=1/>
|
||||
; COMBINED-NEXT: <COMBINED_PROFILE {{.*}} op6=[[NONE1:.*]] op7=0 op8=[[HOT1:.*]] op9=3 op10=[[COLD1:.*]] op11=1 op12=[[NONE2:.*]] op13=0 op14=[[HOT2:.*]] op15=3 op16=[[COLD2:.*]] op17=1 op18=[[NONE3:.*]] op19=0 op20=[[HOT3:.*]] op21=3 op22=[[COLD3:.*]] op23=1/>
|
||||
; COMBINED_NEXT: <COMBINED abbrevid=
|
||||
; COMBINED_NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
; CHECK: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; CHECK-NEXT: <VERSION
|
||||
; See if the call to func is registered.
|
||||
; CHECK-NEXT: <PERMODULE {{.*}} op3=1
|
||||
; CHECK-NEXT: <PERMODULE {{.*}} op4=1
|
||||
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
; CHECK-NEXT: blob data = 'undefinedglobmainfunc{{.*}}'
|
||||
@ -32,7 +32,7 @@
|
||||
; COMBINED-NEXT: <VALUE_GUID
|
||||
; COMBINED-NEXT: <COMBINED
|
||||
; See if the call to func is registered.
|
||||
; COMBINED-NEXT: <COMBINED {{.*}} op5=[[FUNCID]]/>
|
||||
; COMBINED-NEXT: <COMBINED {{.*}} op6=[[FUNCID]]/>
|
||||
; COMBINED-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
||||
; ModuleID = 'thinlto-function-summary-callgraph.ll'
|
||||
|
27
test/Bitcode/thinlto-function-summary-functionattrs.ll
Normal file
27
test/Bitcode/thinlto-function-summary-functionattrs.ll
Normal file
@ -0,0 +1,27 @@
|
||||
; RUN: opt -module-summary %s -o %t.o
|
||||
; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
|
||||
|
||||
; CHECK: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; ensure @f is marked readnone
|
||||
; CHECK: <PERMODULE {{.*}} op0=0 {{.*}} op3=1
|
||||
; ensure @g is marked readonly
|
||||
; CHECK: <PERMODULE {{.*}} op0=1 {{.*}} op3=2
|
||||
; ensure @h is marked norecurse
|
||||
; CHECK: <PERMODULE {{.*}} op0=2 {{.*}} op3=4
|
||||
; ensure @i is marked returndoesnotalias
|
||||
; CHECK: <PERMODULE {{.*}} op0=3 {{.*}} op3=8
|
||||
|
||||
define void @f() readnone {
|
||||
ret void
|
||||
}
|
||||
define void @g() readonly {
|
||||
ret void
|
||||
}
|
||||
define void @h() norecurse {
|
||||
ret void
|
||||
}
|
||||
|
||||
define noalias i8* @i() {
|
||||
%r = alloca i8
|
||||
ret i8* %r
|
||||
}
|
@ -38,24 +38,24 @@
|
||||
; CHECK: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; Function main contains call to func, as well as address reference to func:
|
||||
; op0=main op4=func op5=func
|
||||
; CHECK-DAG: <PERMODULE {{.*}} op0=11 op1=0 {{.*}} op3=1 op4=2 op5=2/>
|
||||
; CHECK-DAG: <PERMODULE {{.*}} op0=11 op1=0 {{.*}} op4=1 op5=2 op6=2/>
|
||||
; Function W contains a call to func3 as well as a reference to globalvar:
|
||||
; op0=W op4=globalvar op5=func3
|
||||
; CHECK-DAG: <PERMODULE {{.*}} op0=6 op1=5 {{.*}} op3=1 op4=1 op5=5/>
|
||||
; CHECK-DAG: <PERMODULE {{.*}} op0=6 op1=5 {{.*}} op4=1 op5=1 op6=5/>
|
||||
; Function X contains call to foo, as well as address reference to foo
|
||||
; which is in the same instruction as the call:
|
||||
; op0=X op4=foo op5=foo
|
||||
; CHECK-DAG: <PERMODULE {{.*}} op0=7 op1=1 {{.*}} op3=1 op4=4 op5=4/>
|
||||
; CHECK-DAG: <PERMODULE {{.*}} op0=7 op1=1 {{.*}} op4=1 op5=4 op6=4/>
|
||||
; Function Y contains call to func2, and ensures we don't incorrectly add
|
||||
; a reference to it when reached while earlier analyzing the phi using its
|
||||
; return value:
|
||||
; op0=Y op4=func2
|
||||
; CHECK-DAG: <PERMODULE {{.*}} op0=8 op1=8 {{.*}} op3=0 op4=3/>
|
||||
; CHECK-DAG: <PERMODULE {{.*}} op0=8 op1=8 {{.*}} op4=0 op5=3/>
|
||||
; Function Z contains call to func2, and ensures we don't incorrectly add
|
||||
; a reference to it when reached while analyzing subsequent use of its return
|
||||
; value:
|
||||
; op0=Z op4=func2
|
||||
; CHECK-DAG: <PERMODULE {{.*}} op0=9 op1=3 {{.*}} op3=0 op4=3/>
|
||||
; CHECK-DAG: <PERMODULE {{.*}} op0=9 op1=3 {{.*}} op4=0 op5=3/>
|
||||
; Variable bar initialization contains address reference to func:
|
||||
; op0=bar op2=func
|
||||
; CHECK-DAG: <PERMODULE_GLOBALVAR_INIT_REFS {{.*}} op0=0 op1=0 op2=2/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user