forked from OSchip/llvm-project
[Assembler] Emit summary index flags
Differential revision: https://reviews.llvm.org/D74420
This commit is contained in:
parent
37c452a289
commit
c85055b203
|
@ -1037,6 +1037,9 @@ public:
|
|||
|
||||
bool haveGVs() const { return HaveGVs; }
|
||||
|
||||
uint64_t getFlags() const;
|
||||
void setFlags(uint64_t Flags);
|
||||
|
||||
gvsummary_iterator begin() { return GlobalValueMap.begin(); }
|
||||
const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); }
|
||||
gvsummary_iterator end() { return GlobalValueMap.end(); }
|
||||
|
|
|
@ -835,6 +835,9 @@ bool LLParser::ParseSummaryEntry() {
|
|||
case lltok::kw_typeidCompatibleVTable:
|
||||
result = ParseTypeIdCompatibleVtableEntry(SummaryID);
|
||||
break;
|
||||
case lltok::kw_flags:
|
||||
result = ParseSummaryIndexFlags();
|
||||
break;
|
||||
default:
|
||||
result = Error(Lex.getLoc(), "unexpected summary kind");
|
||||
break;
|
||||
|
@ -7995,6 +7998,21 @@ void LLParser::AddGlobalValueToIndex(
|
|||
}
|
||||
}
|
||||
|
||||
/// ParseSummaryIndexFlags
|
||||
/// ::= 'flags' ':' UInt64
|
||||
bool LLParser::ParseSummaryIndexFlags() {
|
||||
assert(Lex.getKind() == lltok::kw_flags);
|
||||
Lex.Lex();
|
||||
|
||||
if (ParseToken(lltok::colon, "expected ':' here"))
|
||||
return true;
|
||||
uint64_t Flags;
|
||||
if (ParseUInt64(Flags))
|
||||
return true;
|
||||
Index->setFlags(Flags);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ParseGVEntry
|
||||
/// ::= 'gv' ':' '(' ('name' ':' STRINGCONSTANT | 'guid' ':' UInt64)
|
||||
/// [',' 'summaries' ':' Summary[',' Summary]* ]? ')'
|
||||
|
|
|
@ -347,6 +347,7 @@ namespace llvm {
|
|||
bool ParseModuleEntry(unsigned ID);
|
||||
bool ParseModuleReference(StringRef &ModulePath);
|
||||
bool ParseGVReference(ValueInfo &VI, unsigned &GVId);
|
||||
bool ParseSummaryIndexFlags();
|
||||
bool ParseGVEntry(unsigned ID);
|
||||
bool ParseFunctionSummary(std::string Name, GlobalValue::GUID, unsigned ID);
|
||||
bool ParseVariableSummary(std::string Name, GlobalValue::GUID, unsigned ID);
|
||||
|
|
|
@ -5836,35 +5836,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
|
|||
default: // Default behavior: ignore.
|
||||
break;
|
||||
case bitc::FS_FLAGS: { // [flags]
|
||||
uint64_t Flags = Record[0];
|
||||
// Scan flags.
|
||||
assert(Flags <= 0x3f && "Unexpected bits in flag");
|
||||
|
||||
// 1 bit: WithGlobalValueDeadStripping flag.
|
||||
// Set on combined index only.
|
||||
if (Flags & 0x1)
|
||||
TheIndex.setWithGlobalValueDeadStripping();
|
||||
// 1 bit: SkipModuleByDistributedBackend flag.
|
||||
// Set on combined index only.
|
||||
if (Flags & 0x2)
|
||||
TheIndex.setSkipModuleByDistributedBackend();
|
||||
// 1 bit: HasSyntheticEntryCounts flag.
|
||||
// Set on combined index only.
|
||||
if (Flags & 0x4)
|
||||
TheIndex.setHasSyntheticEntryCounts();
|
||||
// 1 bit: DisableSplitLTOUnit flag.
|
||||
// Set on per module indexes. It is up to the client to validate
|
||||
// the consistency of this flag across modules being linked.
|
||||
if (Flags & 0x8)
|
||||
TheIndex.setEnableSplitLTOUnit();
|
||||
// 1 bit: PartiallySplitLTOUnits flag.
|
||||
// Set on combined index only.
|
||||
if (Flags & 0x10)
|
||||
TheIndex.setPartiallySplitLTOUnits();
|
||||
// 1 bit: WithAttributePropagation flag.
|
||||
// Set on combined index only.
|
||||
if (Flags & 0x20)
|
||||
TheIndex.setWithAttributePropagation();
|
||||
TheIndex.setFlags(Record[0]);
|
||||
break;
|
||||
}
|
||||
case bitc::FS_VALUE_GUID: { // [valueid, refguid]
|
||||
|
|
|
@ -3898,20 +3898,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
|
|||
ArrayRef<uint64_t>{ModuleSummaryIndex::BitcodeSummaryVersion});
|
||||
|
||||
// Write the index flags.
|
||||
uint64_t Flags = 0;
|
||||
if (Index.withGlobalValueDeadStripping())
|
||||
Flags |= 0x1;
|
||||
if (Index.skipModuleByDistributedBackend())
|
||||
Flags |= 0x2;
|
||||
if (Index.hasSyntheticEntryCounts())
|
||||
Flags |= 0x4;
|
||||
if (Index.enableSplitLTOUnit())
|
||||
Flags |= 0x8;
|
||||
if (Index.partiallySplitLTOUnits())
|
||||
Flags |= 0x10;
|
||||
if (Index.withAttributePropagation())
|
||||
Flags |= 0x20;
|
||||
Stream.EmitRecord(bitc::FS_FLAGS, ArrayRef<uint64_t>{Flags});
|
||||
Stream.EmitRecord(bitc::FS_FLAGS, ArrayRef<uint64_t>{Index.getFlags()});
|
||||
|
||||
for (const auto &GVI : valueIds()) {
|
||||
Stream.EmitRecord(bitc::FS_VALUE_GUID,
|
||||
|
|
|
@ -783,7 +783,7 @@ public:
|
|||
|
||||
/// These functions do the actual initialization.
|
||||
inline void initializeIfNeeded();
|
||||
void initializeIndexIfNeeded();
|
||||
int initializeIndexIfNeeded();
|
||||
|
||||
// Implementation Details
|
||||
private:
|
||||
|
@ -806,7 +806,8 @@ private:
|
|||
/// Add all of the module level global variables (and their initializers)
|
||||
/// and function declarations, but not the contents of those functions.
|
||||
void processModule();
|
||||
void processIndex();
|
||||
// Returns number of allocated slots
|
||||
int processIndex();
|
||||
|
||||
/// Add all of the functions arguments, basic blocks, and instructions.
|
||||
void processFunction();
|
||||
|
@ -920,11 +921,12 @@ inline void SlotTracker::initializeIfNeeded() {
|
|||
processFunction();
|
||||
}
|
||||
|
||||
void SlotTracker::initializeIndexIfNeeded() {
|
||||
int SlotTracker::initializeIndexIfNeeded() {
|
||||
if (!TheIndex)
|
||||
return;
|
||||
processIndex();
|
||||
return 0;
|
||||
int NumSlots = processIndex();
|
||||
TheIndex = nullptr; ///< Prevent re-processing next time we're called.
|
||||
return NumSlots;
|
||||
}
|
||||
|
||||
// Iterate through all the global variables, functions, and global
|
||||
|
@ -1019,7 +1021,7 @@ void SlotTracker::processFunction() {
|
|||
}
|
||||
|
||||
// Iterate through all the GUID in the index and create slots for them.
|
||||
void SlotTracker::processIndex() {
|
||||
int SlotTracker::processIndex() {
|
||||
ST_DEBUG("begin processIndex!\n");
|
||||
assert(TheIndex);
|
||||
|
||||
|
@ -1038,17 +1040,17 @@ void SlotTracker::processIndex() {
|
|||
for (auto &GlobalList : *TheIndex)
|
||||
CreateGUIDSlot(GlobalList.first);
|
||||
|
||||
for (auto &TId : TheIndex->typeIdCompatibleVtableMap())
|
||||
CreateGUIDSlot(GlobalValue::getGUID(TId.first));
|
||||
|
||||
// Start numbering the TypeIds after the GUIDs.
|
||||
TypeIdNext = GUIDNext;
|
||||
|
||||
for (auto TidIter = TheIndex->typeIds().begin();
|
||||
TidIter != TheIndex->typeIds().end(); TidIter++)
|
||||
CreateTypeIdSlot(TidIter->second.first);
|
||||
|
||||
for (auto &TId : TheIndex->typeIdCompatibleVtableMap())
|
||||
CreateGUIDSlot(GlobalValue::getGUID(TId.first));
|
||||
|
||||
ST_DEBUG("end processIndex!\n");
|
||||
return TypeIdNext;
|
||||
}
|
||||
|
||||
void SlotTracker::processGlobalObjectMetadata(const GlobalObject &GO) {
|
||||
|
@ -2678,7 +2680,7 @@ void AssemblyWriter::printModule(const Module *M) {
|
|||
|
||||
void AssemblyWriter::printModuleSummaryIndex() {
|
||||
assert(TheIndex);
|
||||
Machine.initializeIndexIfNeeded();
|
||||
int NumSlots = Machine.initializeIndexIfNeeded();
|
||||
|
||||
Out << "\n";
|
||||
|
||||
|
@ -2740,6 +2742,10 @@ void AssemblyWriter::printModuleSummaryIndex() {
|
|||
printTypeIdCompatibleVtableSummary(TId.second);
|
||||
Out << ") ; guid = " << GUID << "\n";
|
||||
}
|
||||
|
||||
// Don't emit flags when it's not really needed (value is zero by default).
|
||||
if (TheIndex->getFlags())
|
||||
Out << "^" << NumSlots << " = flags: " << TheIndex->getFlags() << "\n";
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
|
|
@ -72,6 +72,52 @@ std::pair<unsigned, unsigned> FunctionSummary::specialRefCounts() const {
|
|||
|
||||
constexpr uint64_t ModuleSummaryIndex::BitcodeSummaryVersion;
|
||||
|
||||
uint64_t ModuleSummaryIndex::getFlags() const {
|
||||
uint64_t Flags = 0;
|
||||
if (withGlobalValueDeadStripping())
|
||||
Flags |= 0x1;
|
||||
if (skipModuleByDistributedBackend())
|
||||
Flags |= 0x2;
|
||||
if (hasSyntheticEntryCounts())
|
||||
Flags |= 0x4;
|
||||
if (enableSplitLTOUnit())
|
||||
Flags |= 0x8;
|
||||
if (partiallySplitLTOUnits())
|
||||
Flags |= 0x10;
|
||||
if (withAttributePropagation())
|
||||
Flags |= 0x20;
|
||||
return Flags;
|
||||
}
|
||||
|
||||
void ModuleSummaryIndex::setFlags(uint64_t Flags) {
|
||||
assert(Flags <= 0x3f && "Unexpected bits in flag");
|
||||
// 1 bit: WithGlobalValueDeadStripping flag.
|
||||
// Set on combined index only.
|
||||
if (Flags & 0x1)
|
||||
setWithGlobalValueDeadStripping();
|
||||
// 1 bit: SkipModuleByDistributedBackend flag.
|
||||
// Set on combined index only.
|
||||
if (Flags & 0x2)
|
||||
setSkipModuleByDistributedBackend();
|
||||
// 1 bit: HasSyntheticEntryCounts flag.
|
||||
// Set on combined index only.
|
||||
if (Flags & 0x4)
|
||||
setHasSyntheticEntryCounts();
|
||||
// 1 bit: DisableSplitLTOUnit flag.
|
||||
// Set on per module indexes. It is up to the client to validate
|
||||
// the consistency of this flag across modules being linked.
|
||||
if (Flags & 0x8)
|
||||
setEnableSplitLTOUnit();
|
||||
// 1 bit: PartiallySplitLTOUnits flag.
|
||||
// Set on combined index only.
|
||||
if (Flags & 0x10)
|
||||
setPartiallySplitLTOUnits();
|
||||
// 1 bit: WithAttributePropagation flag.
|
||||
// Set on combined index only.
|
||||
if (Flags & 0x20)
|
||||
setWithAttributePropagation();
|
||||
}
|
||||
|
||||
// Collect for the given module the list of function it defines
|
||||
// (GUID -> Summary).
|
||||
void ModuleSummaryIndex::collectDefinedFunctionsForModule(
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
; ModuleID = 'tmp.bc'
|
||||
source_filename = "tmp.bc"
|
||||
|
||||
; Test parsing of summary flas. Expect that flags value is the same after round-trip through
|
||||
; RUN: llvm-as %s -o - | llvm-dis -o - | FileCheck %s
|
||||
; CHECK: ^0 = module
|
||||
; CHECK-NEXT: ^1 = gv
|
||||
; CHECK-NEXT: ^2 = flags: 33
|
||||
|
||||
^0 = module: (path: "main.bc", hash: (3499594384, 1671013073, 3271036935, 1830411232, 59290952))
|
||||
^1 = gv: (guid: 15822663052811949562, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 1, dsoLocal: 1, canAutoHide: 0), insts: 2)))
|
||||
^2 = flags: 33
|
Loading…
Reference in New Issue