summaryrefslogtreecommitdiffstats
path: root/llvm/lib/AsmParser/LLParser.cpp
diff options
context:
space:
mode:
authorEugene Leviant <eleviant@accesssoftek.com>2018-11-23 10:54:51 +0000
committerEugene Leviant <eleviant@accesssoftek.com>2018-11-23 10:54:51 +0000
commit009d833a4e1ed1b7371a40ac3463e6e172b90923 (patch)
treef6699e776df5d2db074b0f760bbc2d7ed2e0852a /llvm/lib/AsmParser/LLParser.cpp
parent7231009b78207b41175a15508f5d4bfd0cc46c9c (diff)
downloadbcm5719-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.cpp92
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;
}
OpenPOWER on IntegriCloud