diff options
author | Hans Wennborg <hans@hanshq.net> | 2012-06-23 11:37:03 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2012-06-23 11:37:03 +0000 |
commit | ce718ff9f42c7da092eaa01dd0242e8d5ba84713 (patch) | |
tree | d3c6b996686af3fc9f47f7b5407c773a86a4f653 /lib/AsmParser/LLParser.cpp | |
parent | 47cbc4e0ee6098b7be3c60108000a979f1809949 (diff) |
Extend the IL for selecting TLS models (PR9788)
This allows the user/front-end to specify a model that is better
than what LLVM would choose by default. For example, a variable
might be declared as
@x = thread_local(initialexec) global i32 42
if it will not be used in a shared library that is dlopen'ed.
If the specified model isn't supported by the target, or if LLVM can
make a better choice, a different model may be used.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159077 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AsmParser/LLParser.cpp')
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index fe415615d8..095b7c5f67 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -645,12 +645,13 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage, bool HasLinkage, unsigned Visibility) { unsigned AddrSpace; - bool ThreadLocal, IsConstant, UnnamedAddr; + bool IsConstant, UnnamedAddr; + GlobalVariable::ThreadLocalMode TLM; LocTy UnnamedAddrLoc; LocTy TyLoc; Type *Ty = 0; - if (ParseOptionalToken(lltok::kw_thread_local, ThreadLocal) || + if (ParseOptionalThreadLocal(TLM) || ParseOptionalAddrSpace(AddrSpace) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, &UnnamedAddrLoc) || @@ -691,7 +692,8 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, if (GV == 0) { GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, 0, - Name, 0, false, AddrSpace); + Name, 0, GlobalVariable::NotThreadLocal, + AddrSpace); } else { if (GV->getType()->getElementType() != Ty) return Error(TyLoc, @@ -710,7 +712,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, GV->setConstant(IsConstant); GV->setLinkage((GlobalValue::LinkageTypes)Linkage); GV->setVisibility((GlobalValue::VisibilityTypes)Visibility); - GV->setThreadLocal(ThreadLocal); + GV->setThreadLocalMode(TLM); GV->setUnnamedAddr(UnnamedAddr); // Parse attributes on the global. @@ -858,6 +860,46 @@ bool LLParser::ParseUInt32(unsigned &Val) { return false; } +/// ParseTLSModel +/// := 'localdynamic' +/// := 'initialexec' +/// := 'localexec' +bool LLParser::ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM) { + switch (Lex.getKind()) { + default: + return TokError("expected localdynamic, initialexec or localexec"); + case lltok::kw_localdynamic: + TLM = GlobalVariable::LocalDynamicTLSModel; + break; + case lltok::kw_initialexec: + TLM = GlobalVariable::InitialExecTLSModel; + break; + case lltok::kw_localexec: + TLM = GlobalVariable::LocalExecTLSModel; + break; + } + + Lex.Lex(); + return false; +} + +/// ParseOptionalThreadLocal +/// := /*empty*/ +/// := 'thread_local' +/// := 'thread_local' '(' tlsmodel ')' +bool LLParser::ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM) { + TLM = GlobalVariable::NotThreadLocal; + if (!EatIfPresent(lltok::kw_thread_local)) + return false; + + TLM = GlobalVariable::GeneralDynamicTLSModel; + if (Lex.getKind() == lltok::lparen) { + Lex.Lex(); + return ParseTLSModel(TLM) || + ParseToken(lltok::rparen, "expected ')' after thread local model"); + } + return false; +} /// ParseOptionalAddrSpace /// := /*empty*/ |