diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -262,8 +262,8 @@ bool parseOptionalReturnAttrs(AttrBuilder &B); bool parseOptionalLinkage(unsigned &Res, bool &HasLinkage, unsigned &Visibility, unsigned &DLLStorageClass, - bool &DSOLocal); - void parseOptionalDSOLocal(bool &DSOLocal); + bool &ExplicitDSOPreemption, bool &DSOLocal); + void parseOptionalDSOLocal(bool &ExplicitDSOPreemption, bool &DSOLocal); void parseOptionalVisibility(unsigned &Res); void parseOptionalDLLStorageClass(unsigned &Res); bool parseOptionalCallingConv(unsigned &CC); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -623,11 +623,11 @@ bool HasLinkage; unsigned Linkage, Visibility, DLLStorageClass; - bool DSOLocal; + bool ExplicitDSOPreemption, DSOLocal; GlobalVariable::ThreadLocalMode TLM; GlobalVariable::UnnamedAddr UnnamedAddr; if (parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass, - DSOLocal) || + ExplicitDSOPreemption, DSOLocal) || parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr)) return true; @@ -652,12 +652,12 @@ bool HasLinkage; unsigned Linkage, Visibility, DLLStorageClass; - bool DSOLocal; + bool ExplicitDSOPreemption, DSOLocal; GlobalVariable::ThreadLocalMode TLM; GlobalVariable::UnnamedAddr UnnamedAddr; if (parseToken(lltok::equal, "expected '=' in global variable") || parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass, - DSOLocal) || + ExplicitDSOPreemption, DSOLocal) || parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr)) return true; @@ -1972,11 +1972,13 @@ /// ::= 'external' bool LLParser::parseOptionalLinkage(unsigned &Res, bool &HasLinkage, unsigned &Visibility, - unsigned &DLLStorageClass, bool &DSOLocal) { + unsigned &DLLStorageClass, + bool &ExplicitDSOPreemption, + bool &DSOLocal) { Res = parseOptionalLinkageAux(Lex.getKind(), HasLinkage); if (HasLinkage) Lex.Lex(); - parseOptionalDSOLocal(DSOLocal); + parseOptionalDSOLocal(ExplicitDSOPreemption, DSOLocal); parseOptionalVisibility(Visibility); parseOptionalDLLStorageClass(DLLStorageClass); @@ -1987,16 +1989,20 @@ return false; } -void LLParser::parseOptionalDSOLocal(bool &DSOLocal) { +void LLParser::parseOptionalDSOLocal(bool &ExplicitDSOPreemption, + bool &DSOLocal) { switch (Lex.getKind()) { default: + ExplicitDSOPreemption = false; DSOLocal = false; break; case lltok::kw_dso_local: + ExplicitDSOPreemption = true; DSOLocal = true; Lex.Lex(); break; case lltok::kw_dso_preemptable: + ExplicitDSOPreemption = true; DSOLocal = false; Lex.Lex(); break; @@ -5642,14 +5648,14 @@ unsigned Linkage; unsigned Visibility; unsigned DLLStorageClass; - bool DSOLocal; + bool ExplicitDSOPreemption, DSOLocal; AttrBuilder RetAttrs; unsigned CC; bool HasLinkage; Type *RetType = nullptr; LocTy RetTypeLoc = Lex.getLoc(); if (parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass, - DSOLocal) || + ExplicitDSOPreemption, DSOLocal) || parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) || parseType(RetType, RetTypeLoc, true /*void allowed*/)) return true; @@ -5822,7 +5828,7 @@ NumberedVals.push_back(Fn); Fn->setLinkage((GlobalValue::LinkageTypes)Linkage); - maybeSetDSOLocal(DSOLocal, *Fn); + Fn->setDSOLocal(ExplicitDSOPreemption ? DSOLocal : IsDefine); Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility); Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); Fn->setCallingConv(CC); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -3441,8 +3441,15 @@ static void PrintDSOLocation(const GlobalValue &GV, formatted_raw_ostream &Out) { - if (GV.isDSOLocal() && !GV.isImplicitDSOLocal()) - Out << "dso_local "; + bool Default = + GV.isImplicitDSOLocal() || (isa(GV) && !GV.isDeclaration()); + if (GV.isDSOLocal()) { + if (!Default) + Out << "dso_local "; + } else { + if (Default) + Out << "dso_preemptable "; + } } static void PrintDLLStorageClass(GlobalValue::DLLStorageClassTypes SCT,