diff options
author | Eugene Leviant <eleviant@accesssoftek.com> | 2019-07-05 12:00:10 +0000 |
---|---|---|
committer | Eugene Leviant <eleviant@accesssoftek.com> | 2019-07-05 12:00:10 +0000 |
commit | 820cc01d1e65f7be7c3c27bcdcb6b8c13f4ec2e6 (patch) | |
tree | 8580e927d93c7185dd262f864c9bdeef7d450cae /llvm/lib/AsmParser/LLParser.cpp | |
parent | 1a517a4630ae4d9e24e991a3e6a3bf58c5dabf6d (diff) | |
download | bcm5719-llvm-820cc01d1e65f7be7c3c27bcdcb6b8c13f4ec2e6.tar.gz bcm5719-llvm-820cc01d1e65f7be7c3c27bcdcb6b8c13f4ec2e6.zip |
[ThinLTO] Attempt to recommit r365040 after caching fix
It's possible that some function can load and store the same
variable using the same constant expression:
store %Derived* @foo, %Derived** bitcast (%Base** @bar to %Derived**)
%42 = load %Derived*, %Derived** bitcast (%Base** @bar to %Derived**)
The bitcast expression was mistakenly cached while processing loads,
and never examined later when processing store. This caused @bar to
be mistakenly treated as read-only variable. See load-store-caching.ll.
llvm-svn: 365188
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 51fc5b6e1d2..ab645348c53 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -7849,9 +7849,13 @@ static const auto FwdVIRef = (GlobalValueSummaryMapTy::value_type *)-8; static void resolveFwdRef(ValueInfo *Fwd, ValueInfo &Resolved) { bool ReadOnly = Fwd->isReadOnly(); + bool WriteOnly = Fwd->isWriteOnly(); + assert(!(ReadOnly && WriteOnly)); *Fwd = Resolved; if (ReadOnly) Fwd->setReadOnly(); + if (WriteOnly) + Fwd->setWriteOnly(); } /// Stores the given Name/GUID and associated summary into the Index. @@ -8081,7 +8085,8 @@ bool LLParser::ParseVariableSummary(std::string Name, GlobalValue::GUID GUID, GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags( /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false, /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false); - GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false); + GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false, + /* WriteOnly */ false); std::vector<ValueInfo> Refs; VTableFuncList VTableFuncs; if (ParseToken(lltok::colon, "expected ':' here") || @@ -8422,10 +8427,11 @@ bool LLParser::ParseOptionalRefs(std::vector<ValueInfo> &Refs) { 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. + // Sort value contexts so that ones with writeonly + // and readonly ValueInfo are at the end of VContexts vector. + // See FunctionSummary::specialRefCounts() llvm::sort(VContexts, [](const ValueContext &VC1, const ValueContext &VC2) { - return VC1.VI.isReadOnly() < VC2.VI.isReadOnly(); + return VC1.VI.getAccessSpecifier() < VC2.VI.getAccessSpecifier(); }); IdToIndexMapType IdToIndexMap; @@ -8743,24 +8749,41 @@ bool LLParser::ParseGVFlags(GlobalValueSummary::GVFlags &GVFlags) { } /// GVarFlags -/// ::= 'varFlags' ':' '(' 'readonly' ':' Flag ')' +/// ::= 'varFlags' ':' '(' 'readonly' ':' Flag +/// ',' 'writeonly' ':' Flag ')' bool LLParser::ParseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) { assert(Lex.getKind() == lltok::kw_varFlags); Lex.Lex(); - unsigned Flag = 0; if (ParseToken(lltok::colon, "expected ':' here") || - ParseToken(lltok::lparen, "expected '(' here") || - ParseToken(lltok::kw_readonly, "expected 'readonly' here") || - ParseToken(lltok::colon, "expected ':' here")) + ParseToken(lltok::lparen, "expected '(' here")) return true; - ParseFlag(Flag); - GVarFlags.ReadOnly = Flag; + auto ParseRest = [this](unsigned int &Val) { + Lex.Lex(); + if (ParseToken(lltok::colon, "expected ':'")) + return true; + return ParseFlag(Val); + }; - if (ParseToken(lltok::rparen, "expected ')' here")) - return true; - return false; + do { + unsigned Flag = 0; + switch (Lex.getKind()) { + case lltok::kw_readonly: + if (ParseRest(Flag)) + return true; + GVarFlags.MaybeReadOnly = Flag; + break; + case lltok::kw_writeonly: + if (ParseRest(Flag)) + return true; + GVarFlags.MaybeWriteOnly = Flag; + break; + default: + return Error(Lex.getLoc(), "expected gvar flag type"); + } + } while (EatIfPresent(lltok::comma)); + return ParseToken(lltok::rparen, "expected ')' here"); } /// ModuleReference @@ -8783,7 +8806,9 @@ bool LLParser::ParseModuleReference(StringRef &ModulePath) { /// GVReference /// ::= SummaryID bool LLParser::ParseGVReference(ValueInfo &VI, unsigned &GVId) { - bool ReadOnly = EatIfPresent(lltok::kw_readonly); + bool WriteOnly = false, ReadOnly = EatIfPresent(lltok::kw_readonly); + if (!ReadOnly) + WriteOnly = EatIfPresent(lltok::kw_writeonly); if (ParseToken(lltok::SummaryID, "expected GV ID")) return true; @@ -8798,5 +8823,7 @@ bool LLParser::ParseGVReference(ValueInfo &VI, unsigned &GVId) { if (ReadOnly) VI.setReadOnly(); + if (WriteOnly) + VI.setWriteOnly(); return false; } |