diff options
author | Eugene Leviant <eleviant@accesssoftek.com> | 2018-11-23 10:54:51 +0000 |
---|---|---|
committer | Eugene Leviant <eleviant@accesssoftek.com> | 2018-11-23 10:54:51 +0000 |
commit | 009d833a4e1ed1b7371a40ac3463e6e172b90923 (patch) | |
tree | f6699e776df5d2db074b0f760bbc2d7ed2e0852a /llvm/lib/AsmParser/LLParser.cpp | |
parent | 7231009b78207b41175a15508f5d4bfd0cc46c9c (diff) | |
download | bcm5719-llvm-009d833a4e1ed1b7371a40ac3463e6e172b90923.tar.gz bcm5719-llvm-009d833a4e1ed1b7371a40ac3463e6e172b90923.zip |
[ThinLTO] Assembly representation of ReadOnly attribute
Differential revision: https://reviews.llvm.org/D54754
llvm-svn: 347489
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 92 |
1 files changed, 69 insertions, 23 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index c945a8ea95e..165d01dc8b4 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -7470,8 +7470,14 @@ bool LLParser::ParseArgs(std::vector<uint64_t> &Args) { return false; } -static ValueInfo EmptyVI = - ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-8); +auto FwdVIRef = (GlobalValueSummaryMapTy::value_type *)-8; + +static void resolveFwdRef(ValueInfo *Fwd, ValueInfo &Resolved) { + bool ReadOnly = Fwd->isReadOnly(); + *Fwd = Resolved; + if (ReadOnly) + Fwd->setReadOnly(); +} /// Stores the given Name/GUID and associated summary into the Index. /// Also updates any forward references to the associated entry ID. @@ -7507,9 +7513,9 @@ void LLParser::AddGlobalValueToIndex( auto FwdRefVIs = ForwardRefValueInfos.find(ID); if (FwdRefVIs != ForwardRefValueInfos.end()) { for (auto VIRef : FwdRefVIs->second) { - assert(*VIRef.first == EmptyVI && + assert(VIRef.first->getRef() == FwdVIRef && "Forward referenced ValueInfo expected to be empty"); - *VIRef.first = VI; + resolveFwdRef(VIRef.first, VI); } ForwardRefValueInfos.erase(FwdRefVIs); } @@ -7699,11 +7705,14 @@ bool LLParser::ParseVariableSummary(std::string Name, GlobalValue::GUID GUID, GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags( /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false, /*Live=*/false, /*IsLocal=*/false); + GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false); std::vector<ValueInfo> Refs; if (ParseToken(lltok::colon, "expected ':' here") || ParseToken(lltok::lparen, "expected '(' here") || ParseModuleReference(ModulePath) || - ParseToken(lltok::comma, "expected ',' here") || ParseGVFlags(GVFlags)) + ParseToken(lltok::comma, "expected ',' here") || ParseGVFlags(GVFlags) || + ParseToken(lltok::comma, "expected ',' here") || + ParseGVarFlags(GVarFlags)) return true; // Parse optional refs field @@ -7715,8 +7724,8 @@ bool LLParser::ParseVariableSummary(std::string Name, GlobalValue::GUID GUID, if (ParseToken(lltok::rparen, "expected ')' here")) return true; - auto GS = llvm::make_unique<GlobalVarSummary>( - GVFlags, GlobalVarSummary::GVarFlags(), std::move(Refs)); + auto GS = + llvm::make_unique<GlobalVarSummary>(GVFlags, GVarFlags, std::move(Refs)); GS->setModulePath(ModulePath); @@ -7761,7 +7770,7 @@ bool LLParser::ParseAliasSummary(std::string Name, GlobalValue::GUID GUID, AS->setModulePath(ModulePath); // Record forward reference if the aliasee is not parsed yet. - if (AliaseeVI == EmptyVI) { + if (AliaseeVI.getRef() == FwdVIRef) { auto FwdRef = ForwardRefAliasees.insert( std::make_pair(GVId, std::vector<std::pair<AliasSummary *, LocTy>>())); FwdRef.first->second.push_back(std::make_pair(AS.get(), Loc)); @@ -7883,7 +7892,7 @@ bool LLParser::ParseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls) { // Keep track of the Call array index needing a forward reference. // We will save the location of the ValueInfo needing an update, but // can only do so once the std::vector is finalized. - if (VI == EmptyVI) + if (VI.getRef() == FwdVIRef) IdToIndexMap[GVId].push_back(std::make_pair(Calls.size(), Loc)); Calls.push_back(FunctionSummary::EdgeTy{VI, CalleeInfo(Hotness, RelBF)}); @@ -7895,7 +7904,7 @@ bool LLParser::ParseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls) { // of any forward GV references that need updating later. for (auto I : IdToIndexMap) { for (auto P : I.second) { - assert(Calls[P.first].first == EmptyVI && + assert(Calls[P.first].first.getRef() == FwdVIRef && "Forward referenced ValueInfo expected to be empty"); auto FwdRef = ForwardRefValueInfos.insert(std::make_pair( I.first, std::vector<std::pair<ValueInfo *, LocTy>>())); @@ -7946,28 +7955,42 @@ bool LLParser::ParseOptionalRefs(std::vector<ValueInfo> &Refs) { ParseToken(lltok::lparen, "expected '(' in refs")) return true; - IdToIndexMapType IdToIndexMap; - // Parse each ref edge - do { + struct ValueContext { ValueInfo VI; - LocTy Loc = Lex.getLoc(); unsigned GVId; - if (ParseGVReference(VI, GVId)) + LocTy Loc; + }; + std::vector<ValueContext> VContexts; + // Parse each ref edge + do { + ValueContext VC; + VC.Loc = Lex.getLoc(); + if (ParseGVReference(VC.VI, VC.GVId)) return true; + VContexts.push_back(VC); + } while (EatIfPresent(lltok::comma)); + // Sort value contexts so that ones with readonly ValueInfo are at the end + // of VContexts vector. This is needed to match immutableRefCount() behavior. + llvm::sort(VContexts, [](ValueContext &VC1, ValueContext &VC2) { + return VC1.VI.isReadOnly() < VC2.VI.isReadOnly(); + }); + + IdToIndexMapType IdToIndexMap; + for (auto &VC : VContexts) { // Keep track of the Refs array index needing a forward reference. // We will save the location of the ValueInfo needing an update, but // can only do so once the std::vector is finalized. - if (VI == EmptyVI) - IdToIndexMap[GVId].push_back(std::make_pair(Refs.size(), Loc)); - Refs.push_back(VI); - } while (EatIfPresent(lltok::comma)); + if (VC.VI.getRef() == FwdVIRef) + IdToIndexMap[VC.GVId].push_back(std::make_pair(Refs.size(), VC.Loc)); + Refs.push_back(VC.VI); + } // Now that the Refs vector is finalized, it is safe to save the locations // of any forward GV references that need updating later. for (auto I : IdToIndexMap) { for (auto P : I.second) { - assert(Refs[P.first] == EmptyVI && + assert(Refs[P.first].getRef() == FwdVIRef && "Forward referenced ValueInfo expected to be empty"); auto FwdRef = ForwardRefValueInfos.insert(std::make_pair( I.first, std::vector<std::pair<ValueInfo *, LocTy>>())); @@ -8253,6 +8276,27 @@ bool LLParser::ParseGVFlags(GlobalValueSummary::GVFlags &GVFlags) { return false; } +/// GVarFlags +/// ::= 'varFlags' ':' '(' 'readonly' ':' Flag ')' +bool LLParser::ParseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) { + assert(Lex.getKind() == lltok::kw_varFlags); + Lex.Lex(); + + unsigned Flag; + if (ParseToken(lltok::colon, "expected ':' here") || + ParseToken(lltok::lparen, "expected '(' here") || + ParseToken(lltok::kw_readonly, "expected 'readonly' here") || + ParseToken(lltok::colon, "expected ':' here")) + return true; + + ParseFlag(Flag); + GVarFlags.ReadOnly = Flag; + + if (ParseToken(lltok::rparen, "expected ')' here")) + return true; + return false; +} + /// ModuleReference /// ::= 'module' ':' UInt bool LLParser::ParseModuleReference(StringRef &ModulePath) { @@ -8273,18 +8317,20 @@ bool LLParser::ParseModuleReference(StringRef &ModulePath) { /// GVReference /// ::= SummaryID bool LLParser::ParseGVReference(ValueInfo &VI, unsigned &GVId) { + bool ReadOnly = EatIfPresent(lltok::kw_readonly); if (ParseToken(lltok::SummaryID, "expected GV ID")) return true; GVId = Lex.getUIntVal(); - // Check if we already have a VI for this GV if (GVId < NumberedValueInfos.size()) { - assert(NumberedValueInfos[GVId] != EmptyVI); + assert(NumberedValueInfos[GVId].getRef() != FwdVIRef); VI = NumberedValueInfos[GVId]; } else // We will create a forward reference to the stored location. - VI = EmptyVI; + VI = ValueInfo(false, FwdVIRef); + if (ReadOnly) + VI.setReadOnly(); return false; } |