mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-19 23:23:38 -04:00
[ThinLTO] Include linkage type in function summary
Summary: Adds the linkage type to both the per-module and combined function summaries, which subsumes the current islocal bit. This will eventually be used to optimized linkage types based on global summary-based analysis. Reviewers: joker.eph Subscribers: joker.eph, davidxl, llvm-commits Differential Revision: http://reviews.llvm.org/D16943 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@259993 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -184,8 +184,8 @@ enum { BITCODE_CURRENT_EPOCH = 0 };
|
||||
// The function summary section uses different codes in the per-module
|
||||
// and combined index cases.
|
||||
enum FunctionSummarySymtabCodes {
|
||||
FS_CODE_PERMODULE_ENTRY = 1, // FS_ENTRY: [valueid, islocal, instcount]
|
||||
FS_CODE_COMBINED_ENTRY = 2, // FS_ENTRY: [modid, instcount]
|
||||
FS_CODE_PERMODULE_ENTRY = 1, // FS_ENTRY: [valueid, linkage, instcount]
|
||||
FS_CODE_COMBINED_ENTRY = 2, // FS_ENTRY: [modid, linkage, instcount]
|
||||
};
|
||||
|
||||
enum MetadataCodes {
|
||||
|
||||
@@ -40,13 +40,14 @@ private:
|
||||
/// module path string table.
|
||||
StringRef ModulePath;
|
||||
|
||||
/// \brief Used to flag functions that have local linkage types and need to
|
||||
/// \brief The linkage type of the associated function.
|
||||
///
|
||||
/// One use is to flag functions that have local linkage types and need to
|
||||
/// have module identifier appended before placing into the combined
|
||||
/// index, to disambiguate from other functions with the same name.
|
||||
///
|
||||
/// This is only used in the per-module function index, as it is consumed
|
||||
/// while creating the combined index.
|
||||
bool IsLocalFunction;
|
||||
/// In the future this will be used to update and optimize linkage
|
||||
/// types based on global summary-based analysis.
|
||||
GlobalValue::LinkageTypes FunctionLinkage;
|
||||
|
||||
// The rest of the information is used to help decide whether importing
|
||||
// is likely to be profitable.
|
||||
@@ -69,12 +70,15 @@ public:
|
||||
/// Get the path to the module containing this function.
|
||||
StringRef modulePath() const { return ModulePath; }
|
||||
|
||||
/// Record whether this is a local function in the per-module index.
|
||||
void setLocalFunction(bool IsLocal) { IsLocalFunction = IsLocal; }
|
||||
/// Record linkage type.
|
||||
void setFunctionLinkage(GlobalValue::LinkageTypes Linkage) {
|
||||
FunctionLinkage = Linkage;
|
||||
}
|
||||
|
||||
/// Check whether this was a local function, for use in creating
|
||||
/// the combined index.
|
||||
bool isLocalFunction() const { return IsLocalFunction; }
|
||||
/// Return linkage type recorded for this function.
|
||||
GlobalValue::LinkageTypes getFunctionLinkage() const {
|
||||
return FunctionLinkage;
|
||||
}
|
||||
|
||||
/// Get the instruction count recorded for this function.
|
||||
unsigned instCount() const { return InstCount; }
|
||||
|
||||
@@ -5592,14 +5592,14 @@ std::error_code FunctionIndexBitcodeReader::parseEntireSummary() {
|
||||
switch (Stream.readRecord(Entry.ID, Record)) {
|
||||
default: // Default behavior: ignore.
|
||||
break;
|
||||
// FS_PERMODULE_ENTRY: [valueid, islocal, instcount]
|
||||
// FS_PERMODULE_ENTRY: [valueid, linkage, instcount]
|
||||
case bitc::FS_CODE_PERMODULE_ENTRY: {
|
||||
unsigned ValueID = Record[0];
|
||||
bool IsLocal = Record[1];
|
||||
uint64_t RawLinkage = Record[1];
|
||||
unsigned InstCount = Record[2];
|
||||
std::unique_ptr<FunctionSummary> FS =
|
||||
llvm::make_unique<FunctionSummary>(InstCount);
|
||||
FS->setLocalFunction(IsLocal);
|
||||
FS->setFunctionLinkage(getDecodedLinkage(RawLinkage));
|
||||
// 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
|
||||
@@ -5609,12 +5609,14 @@ std::error_code FunctionIndexBitcodeReader::parseEntireSummary() {
|
||||
TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0));
|
||||
SummaryMap[ValueID] = std::move(FS);
|
||||
}
|
||||
// FS_COMBINED_ENTRY: [modid, instcount]
|
||||
// FS_COMBINED_ENTRY: [modid, linkage, instcount]
|
||||
case bitc::FS_CODE_COMBINED_ENTRY: {
|
||||
uint64_t ModuleId = Record[0];
|
||||
unsigned InstCount = Record[1];
|
||||
uint64_t RawLinkage = Record[1];
|
||||
unsigned InstCount = Record[2];
|
||||
std::unique_ptr<FunctionSummary> FS =
|
||||
llvm::make_unique<FunctionSummary>(InstCount);
|
||||
FS->setFunctionLinkage(getDecodedLinkage(RawLinkage));
|
||||
FS->setModulePath(ModuleIdMap[ModuleId]);
|
||||
SummaryMap[CurRecordBit] = std::move(FS);
|
||||
}
|
||||
|
||||
@@ -496,8 +496,8 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
|
||||
Stream.ExitBlock();
|
||||
}
|
||||
|
||||
static unsigned getEncodedLinkage(const GlobalValue &GV) {
|
||||
switch (GV.getLinkage()) {
|
||||
static unsigned getEncodedLinkage(const GlobalValue::LinkageTypes Linkage) {
|
||||
switch (Linkage) {
|
||||
case GlobalValue::ExternalLinkage:
|
||||
return 0;
|
||||
case GlobalValue::WeakAnyLinkage:
|
||||
@@ -524,6 +524,10 @@ static unsigned getEncodedLinkage(const GlobalValue &GV) {
|
||||
llvm_unreachable("Invalid linkage");
|
||||
}
|
||||
|
||||
static unsigned getEncodedLinkage(const GlobalValue &GV) {
|
||||
return getEncodedLinkage(GV.getLinkage());
|
||||
}
|
||||
|
||||
static unsigned getEncodedVisibility(const GlobalValue &GV) {
|
||||
switch (GV.getVisibility()) {
|
||||
case GlobalValue::DefaultVisibility: return 0;
|
||||
@@ -2449,7 +2453,7 @@ static void SaveFunctionInfo(
|
||||
std::unique_ptr<FunctionSummary> FuncSummary;
|
||||
if (EmitFunctionSummary) {
|
||||
FuncSummary = llvm::make_unique<FunctionSummary>(NumInsts);
|
||||
FuncSummary->setLocalFunction(F.hasLocalLinkage());
|
||||
FuncSummary->setFunctionLinkage(F.getLinkage());
|
||||
}
|
||||
FunctionIndex[&F] =
|
||||
llvm::make_unique<FunctionInfo>(BitcodeIndex, std::move(FuncSummary));
|
||||
@@ -2776,7 +2780,7 @@ static void WritePerModuleFunctionSummaryRecord(
|
||||
unsigned FSAbbrev, BitstreamWriter &Stream) {
|
||||
assert(FS);
|
||||
NameVals.push_back(ValueID);
|
||||
NameVals.push_back(FS->isLocalFunction());
|
||||
NameVals.push_back(getEncodedLinkage(FS->getFunctionLinkage()));
|
||||
NameVals.push_back(FS->instCount());
|
||||
|
||||
// Emit the finished record.
|
||||
@@ -2795,7 +2799,7 @@ static void WritePerModuleFunctionSummary(
|
||||
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
||||
Abbv->Add(BitCodeAbbrevOp(bitc::FS_CODE_PERMODULE_ENTRY));
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // islocal
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
|
||||
unsigned FSAbbrev = Stream.EmitAbbrev(Abbv);
|
||||
|
||||
@@ -2845,6 +2849,7 @@ static void WriteCombinedFunctionSummary(const FunctionInfoIndex &I,
|
||||
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
||||
Abbv->Add(BitCodeAbbrevOp(bitc::FS_CODE_COMBINED_ENTRY));
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // linkage
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
|
||||
unsigned FSAbbrev = Stream.EmitAbbrev(Abbv);
|
||||
|
||||
@@ -2855,6 +2860,7 @@ static void WriteCombinedFunctionSummary(const FunctionInfoIndex &I,
|
||||
assert(FS);
|
||||
|
||||
NameVals.push_back(I.getModuleId(FS->modulePath()));
|
||||
NameVals.push_back(getEncodedLinkage(FS->getFunctionLinkage()));
|
||||
NameVals.push_back(FS->instCount());
|
||||
|
||||
// Record the starting offset of this summary entry for use
|
||||
|
||||
@@ -50,7 +50,8 @@ void FunctionInfoIndex::mergeFrom(std::unique_ptr<FunctionInfoIndex> Other,
|
||||
Info->functionSummary()->setModulePath(ModPath);
|
||||
|
||||
// If it is a local function, rename it.
|
||||
if (Info->functionSummary()->isLocalFunction()) {
|
||||
if (GlobalValue::isLocalLinkage(
|
||||
Info->functionSummary()->getFunctionLinkage())) {
|
||||
// Any local functions are virtually renamed when being added to the
|
||||
// combined index map, to disambiguate from other functions with
|
||||
// the same name. The symbol table created for the combined index
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
; Check the value ids in the function summary entries against the
|
||||
; same in the ValueSumbolTable, to ensure the ordering is stable.
|
||||
; Also check the islocal flag on the summary entries.
|
||||
; Also check the linkage field on the summary entries.
|
||||
; BC: <FUNCTION_SUMMARY_BLOCK
|
||||
; BC-NEXT: <PERMODULE_ENTRY {{.*}} op0=1 op1=0
|
||||
; BC-NEXT: <PERMODULE_ENTRY {{.*}} op0=2 op1=0
|
||||
; BC-NEXT: <PERMODULE_ENTRY {{.*}} op0=4 op1=1
|
||||
; BC-NEXT: <PERMODULE_ENTRY {{.*}} op0=4 op1=3
|
||||
; BC-NEXT: </FUNCTION_SUMMARY_BLOCK
|
||||
; BC-NEXT: <VALUE_SYMTAB
|
||||
; BC-NEXT: <FNENTRY {{.*}} op0=1 {{.*}}> record string = 'foo'
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
; Check the linkage types in both the per-module and combined summaries.
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
|
||||
; RUN: llvm-lto -thinlto -o %t2 %t.o
|
||||
; RUN: llvm-bcanalyzer -dump %t2.thinlto.bc | FileCheck %s --check-prefix=COMBINED
|
||||
|
||||
define private void @private()
|
||||
; CHECK: <PERMODULE_ENTRY {{.*}} op1=9
|
||||
; COMBINED-DAG: <COMBINED_ENTRY {{.*}} op1=9
|
||||
{
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @internal()
|
||||
; CHECK: <PERMODULE_ENTRY {{.*}} op1=3
|
||||
; COMBINED-DAG: <COMBINED_ENTRY {{.*}} op1=3
|
||||
{
|
||||
ret void
|
||||
}
|
||||
|
||||
define available_externally void @available_externally()
|
||||
; CHECK: <PERMODULE_ENTRY {{.*}} op1=12
|
||||
; COMBINED-DAG: <COMBINED_ENTRY {{.*}} op1=12
|
||||
{
|
||||
ret void
|
||||
}
|
||||
|
||||
define linkonce void @linkonce()
|
||||
; CHECK: <PERMODULE_ENTRY {{.*}} op1=18
|
||||
; COMBINED-DAG: <COMBINED_ENTRY {{.*}} op1=18
|
||||
{
|
||||
ret void
|
||||
}
|
||||
|
||||
define weak void @weak()
|
||||
; CHECK: <PERMODULE_ENTRY {{.*}} op1=16
|
||||
; COMBINED-DAG: <COMBINED_ENTRY {{.*}} op1=16
|
||||
{
|
||||
ret void
|
||||
}
|
||||
|
||||
define linkonce_odr void @linkonce_odr()
|
||||
; CHECK: <PERMODULE_ENTRY {{.*}} op1=19
|
||||
; COMBINED-DAG: <COMBINED_ENTRY {{.*}} op1=19
|
||||
{
|
||||
ret void
|
||||
}
|
||||
|
||||
define weak_odr void @weak_odr()
|
||||
; CHECK: <PERMODULE_ENTRY {{.*}} op1=17
|
||||
; COMBINED-DAG: <COMBINED_ENTRY {{.*}} op1=17
|
||||
{
|
||||
ret void
|
||||
}
|
||||
|
||||
define external void @external()
|
||||
; CHECK: <PERMODULE_ENTRY {{.*}} op1=0
|
||||
; COMBINED-DAG: <COMBINED_ENTRY {{.*}} op1=0
|
||||
{
|
||||
ret void
|
||||
}
|
||||
Reference in New Issue
Block a user