Implement the "thread_local" keyword.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35950 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Lauro Ramos Venancio
2007-04-12 18:32:50 +00:00
parent 558385fd93
commit c763552299
17 changed files with 4202 additions and 3811 deletions

View File

@@ -112,7 +112,8 @@ public:
GlobalValue::LinkageTypes,///< The linkage type of the GV GlobalValue::LinkageTypes,///< The linkage type of the GV
GlobalValue::VisibilityTypes,///< The visibility style of the GV GlobalValue::VisibilityTypes,///< The visibility style of the GV
unsigned SlotNum, ///< Slot number of GV unsigned SlotNum, ///< Slot number of GV
unsigned initSlot ///< Slot number of GV's initializer (0 if none) unsigned initSlot, ///< Slot number of GV's initializer (0 if none)
bool isThreadLocal ///< Whether the GV is thread local or not
) {} ) {}
/// This method is called when a type list is recognized. It simply /// This method is called when a type list is recognized. It simply

View File

@@ -44,6 +44,7 @@ class GlobalVariable : public GlobalValue {
void setPrev(GlobalVariable *N) { Prev = N; } void setPrev(GlobalVariable *N) { Prev = N; }
bool isConstantGlobal; // Is this a global constant? bool isConstantGlobal; // Is this a global constant?
bool isThreadLocalSymbol; // Is this symbol "Thread Local"?
Use Initializer; Use Initializer;
public: public:
@@ -51,12 +52,12 @@ public:
/// automatically inserted into the end of the specified modules global list. /// automatically inserted into the end of the specified modules global list.
GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage, GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage,
Constant *Initializer = 0, const std::string &Name = "", Constant *Initializer = 0, const std::string &Name = "",
Module *Parent = 0); Module *Parent = 0, bool ThreadLocal = false);
/// GlobalVariable ctor - This creates a global and inserts it before the /// GlobalVariable ctor - This creates a global and inserts it before the
/// specified other global. /// specified other global.
GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage, GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage,
Constant *Initializer, const std::string &Name, Constant *Initializer, const std::string &Name,
GlobalVariable *InsertBefore); GlobalVariable *InsertBefore, bool ThreadLocal = false);
/// isDeclaration - Is this global variable lacking an initializer? If so, /// isDeclaration - Is this global variable lacking an initializer? If so,
/// the global variable is defined in some other translation unit, and is thus /// the global variable is defined in some other translation unit, and is thus
@@ -107,6 +108,10 @@ public:
bool isConstant() const { return isConstantGlobal; } bool isConstant() const { return isConstantGlobal; }
void setConstant(bool Value) { isConstantGlobal = Value; } void setConstant(bool Value) { isConstantGlobal = Value; }
/// If the value is "Thread Local", its value isn't shared by the threads.
bool isThreadLocal() const { return isThreadLocalSymbol; }
void setThreadLocal(bool Value) { isThreadLocalSymbol = Value; }
/// removeFromParent - This method unlinks 'this' from the containing module, /// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it. /// but does not delete it.
/// ///

File diff suppressed because it is too large Load Diff

View File

@@ -208,6 +208,7 @@ dllexport { return DLLEXPORT; }
hidden { return HIDDEN; } hidden { return HIDDEN; }
extern_weak { return EXTERN_WEAK; } extern_weak { return EXTERN_WEAK; }
external { return EXTERNAL; } external { return EXTERNAL; }
thread_local { return THREAD_LOCAL; }
zeroinitializer { return ZEROINITIALIZER; } zeroinitializer { return ZEROINITIALIZER; }
\.\.\. { return DOTDOTDOT; } \.\.\. { return DOTDOTDOT; }
undef { return UNDEF; } undef { return UNDEF; }

View File

@@ -208,6 +208,7 @@ dllexport { return DLLEXPORT; }
hidden { return HIDDEN; } hidden { return HIDDEN; }
extern_weak { return EXTERN_WEAK; } extern_weak { return EXTERN_WEAK; }
external { return EXTERNAL; } external { return EXTERNAL; }
thread_local { return THREAD_LOCAL; }
zeroinitializer { return ZEROINITIALIZER; } zeroinitializer { return ZEROINITIALIZER; }
\.\.\. { return DOTDOTDOT; } \.\.\. { return DOTDOTDOT; }
undef { return UNDEF; } undef { return UNDEF; }

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,9 @@
/* A Bison parser, made by GNU Bison 2.1. */ /* A Bison parser, made by GNU Bison 2.3. */
/* Skeleton parser for Yacc-like parsing with Bison, /* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -18,10 +20,18 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */ Boston, MA 02110-1301, USA. */
/* As a special exception, when this file is copied by Bison into a /* As a special exception, you may create a larger work that contains
Bison output file, you may use that output file without restriction. part or all of the Bison parser skeleton and distribute that work
This special exception was added by the Free Software Foundation under terms of your choice, so long as that work isn't itself a
in version 1.24 of Bison. */ parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */ /* Tokens. */
#ifndef YYTOKENTYPE #ifndef YYTOKENTYPE
@@ -58,108 +68,109 @@
CONSTANT = 284, CONSTANT = 284,
SECTION = 285, SECTION = 285,
VOLATILE = 286, VOLATILE = 286,
TO = 287, THREAD_LOCAL = 287,
DOTDOTDOT = 288, TO = 288,
NULL_TOK = 289, DOTDOTDOT = 289,
UNDEF = 290, NULL_TOK = 290,
INTERNAL = 291, UNDEF = 291,
LINKONCE = 292, INTERNAL = 292,
WEAK = 293, LINKONCE = 293,
APPENDING = 294, WEAK = 294,
DLLIMPORT = 295, APPENDING = 295,
DLLEXPORT = 296, DLLIMPORT = 296,
EXTERN_WEAK = 297, DLLEXPORT = 297,
OPAQUE = 298, EXTERN_WEAK = 298,
EXTERNAL = 299, OPAQUE = 299,
TARGET = 300, EXTERNAL = 300,
TRIPLE = 301, TARGET = 301,
ALIGN = 302, TRIPLE = 302,
DEPLIBS = 303, ALIGN = 303,
CALL = 304, DEPLIBS = 304,
TAIL = 305, CALL = 305,
ASM_TOK = 306, TAIL = 306,
MODULE = 307, ASM_TOK = 307,
SIDEEFFECT = 308, MODULE = 308,
CC_TOK = 309, SIDEEFFECT = 309,
CCC_TOK = 310, CC_TOK = 310,
FASTCC_TOK = 311, CCC_TOK = 311,
COLDCC_TOK = 312, FASTCC_TOK = 312,
X86_STDCALLCC_TOK = 313, COLDCC_TOK = 313,
X86_FASTCALLCC_TOK = 314, X86_STDCALLCC_TOK = 314,
DATALAYOUT = 315, X86_FASTCALLCC_TOK = 315,
RET = 316, DATALAYOUT = 316,
BR = 317, RET = 317,
SWITCH = 318, BR = 318,
INVOKE = 319, SWITCH = 319,
UNWIND = 320, INVOKE = 320,
UNREACHABLE = 321, UNWIND = 321,
ADD = 322, UNREACHABLE = 322,
SUB = 323, ADD = 323,
MUL = 324, SUB = 324,
UDIV = 325, MUL = 325,
SDIV = 326, UDIV = 326,
FDIV = 327, SDIV = 327,
UREM = 328, FDIV = 328,
SREM = 329, UREM = 329,
FREM = 330, SREM = 330,
AND = 331, FREM = 331,
OR = 332, AND = 332,
XOR = 333, OR = 333,
SHL = 334, XOR = 334,
LSHR = 335, SHL = 335,
ASHR = 336, LSHR = 336,
ICMP = 337, ASHR = 337,
FCMP = 338, ICMP = 338,
EQ = 339, FCMP = 339,
NE = 340, EQ = 340,
SLT = 341, NE = 341,
SGT = 342, SLT = 342,
SLE = 343, SGT = 343,
SGE = 344, SLE = 344,
ULT = 345, SGE = 345,
UGT = 346, ULT = 346,
ULE = 347, UGT = 347,
UGE = 348, ULE = 348,
OEQ = 349, UGE = 349,
ONE = 350, OEQ = 350,
OLT = 351, ONE = 351,
OGT = 352, OLT = 352,
OLE = 353, OGT = 353,
OGE = 354, OLE = 354,
ORD = 355, OGE = 355,
UNO = 356, ORD = 356,
UEQ = 357, UNO = 357,
UNE = 358, UEQ = 358,
MALLOC = 359, UNE = 359,
ALLOCA = 360, MALLOC = 360,
FREE = 361, ALLOCA = 361,
LOAD = 362, FREE = 362,
STORE = 363, LOAD = 363,
GETELEMENTPTR = 364, STORE = 364,
TRUNC = 365, GETELEMENTPTR = 365,
ZEXT = 366, TRUNC = 366,
SEXT = 367, ZEXT = 367,
FPTRUNC = 368, SEXT = 368,
FPEXT = 369, FPTRUNC = 369,
BITCAST = 370, FPEXT = 370,
UITOFP = 371, BITCAST = 371,
SITOFP = 372, UITOFP = 372,
FPTOUI = 373, SITOFP = 373,
FPTOSI = 374, FPTOUI = 374,
INTTOPTR = 375, FPTOSI = 375,
PTRTOINT = 376, INTTOPTR = 376,
PHI_TOK = 377, PTRTOINT = 377,
SELECT = 378, PHI_TOK = 378,
VAARG = 379, SELECT = 379,
EXTRACTELEMENT = 380, VAARG = 380,
INSERTELEMENT = 381, EXTRACTELEMENT = 381,
SHUFFLEVECTOR = 382, INSERTELEMENT = 382,
NORETURN = 383, SHUFFLEVECTOR = 383,
INREG = 384, NORETURN = 384,
SRET = 385, INREG = 385,
NOUNWIND = 386, SRET = 386,
DEFAULT = 387, NOUNWIND = 387,
HIDDEN = 388 DEFAULT = 388,
HIDDEN = 389
}; };
#endif #endif
/* Tokens. */ /* Tokens. */
@@ -192,115 +203,117 @@
#define CONSTANT 284 #define CONSTANT 284
#define SECTION 285 #define SECTION 285
#define VOLATILE 286 #define VOLATILE 286
#define TO 287 #define THREAD_LOCAL 287
#define DOTDOTDOT 288 #define TO 288
#define NULL_TOK 289 #define DOTDOTDOT 289
#define UNDEF 290 #define NULL_TOK 290
#define INTERNAL 291 #define UNDEF 291
#define LINKONCE 292 #define INTERNAL 292
#define WEAK 293 #define LINKONCE 293
#define APPENDING 294 #define WEAK 294
#define DLLIMPORT 295 #define APPENDING 295
#define DLLEXPORT 296 #define DLLIMPORT 296
#define EXTERN_WEAK 297 #define DLLEXPORT 297
#define OPAQUE 298 #define EXTERN_WEAK 298
#define EXTERNAL 299 #define OPAQUE 299
#define TARGET 300 #define EXTERNAL 300
#define TRIPLE 301 #define TARGET 301
#define ALIGN 302 #define TRIPLE 302
#define DEPLIBS 303 #define ALIGN 303
#define CALL 304 #define DEPLIBS 304
#define TAIL 305 #define CALL 305
#define ASM_TOK 306 #define TAIL 306
#define MODULE 307 #define ASM_TOK 307
#define SIDEEFFECT 308 #define MODULE 308
#define CC_TOK 309 #define SIDEEFFECT 309
#define CCC_TOK 310 #define CC_TOK 310
#define FASTCC_TOK 311 #define CCC_TOK 311
#define COLDCC_TOK 312 #define FASTCC_TOK 312
#define X86_STDCALLCC_TOK 313 #define COLDCC_TOK 313
#define X86_FASTCALLCC_TOK 314 #define X86_STDCALLCC_TOK 314
#define DATALAYOUT 315 #define X86_FASTCALLCC_TOK 315
#define RET 316 #define DATALAYOUT 316
#define BR 317 #define RET 317
#define SWITCH 318 #define BR 318
#define INVOKE 319 #define SWITCH 319
#define UNWIND 320 #define INVOKE 320
#define UNREACHABLE 321 #define UNWIND 321
#define ADD 322 #define UNREACHABLE 322
#define SUB 323 #define ADD 323
#define MUL 324 #define SUB 324
#define UDIV 325 #define MUL 325
#define SDIV 326 #define UDIV 326
#define FDIV 327 #define SDIV 327
#define UREM 328 #define FDIV 328
#define SREM 329 #define UREM 329
#define FREM 330 #define SREM 330
#define AND 331 #define FREM 331
#define OR 332 #define AND 332
#define XOR 333 #define OR 333
#define SHL 334 #define XOR 334
#define LSHR 335 #define SHL 335
#define ASHR 336 #define LSHR 336
#define ICMP 337 #define ASHR 337
#define FCMP 338 #define ICMP 338
#define EQ 339 #define FCMP 339
#define NE 340 #define EQ 340
#define SLT 341 #define NE 341
#define SGT 342 #define SLT 342
#define SLE 343 #define SGT 343
#define SGE 344 #define SLE 344
#define ULT 345 #define SGE 345
#define UGT 346 #define ULT 346
#define ULE 347 #define UGT 347
#define UGE 348 #define ULE 348
#define OEQ 349 #define UGE 349
#define ONE 350 #define OEQ 350
#define OLT 351 #define ONE 351
#define OGT 352 #define OLT 352
#define OLE 353 #define OGT 353
#define OGE 354 #define OLE 354
#define ORD 355 #define OGE 355
#define UNO 356 #define ORD 356
#define UEQ 357 #define UNO 357
#define UNE 358 #define UEQ 358
#define MALLOC 359 #define UNE 359
#define ALLOCA 360 #define MALLOC 360
#define FREE 361 #define ALLOCA 361
#define LOAD 362 #define FREE 362
#define STORE 363 #define LOAD 363
#define GETELEMENTPTR 364 #define STORE 364
#define TRUNC 365 #define GETELEMENTPTR 365
#define ZEXT 366 #define TRUNC 366
#define SEXT 367 #define ZEXT 367
#define FPTRUNC 368 #define SEXT 368
#define FPEXT 369 #define FPTRUNC 369
#define BITCAST 370 #define FPEXT 370
#define UITOFP 371 #define BITCAST 371
#define SITOFP 372 #define UITOFP 372
#define FPTOUI 373 #define SITOFP 373
#define FPTOSI 374 #define FPTOUI 374
#define INTTOPTR 375 #define FPTOSI 375
#define PTRTOINT 376 #define INTTOPTR 376
#define PHI_TOK 377 #define PTRTOINT 377
#define SELECT 378 #define PHI_TOK 378
#define VAARG 379 #define SELECT 379
#define EXTRACTELEMENT 380 #define VAARG 380
#define INSERTELEMENT 381 #define EXTRACTELEMENT 381
#define SHUFFLEVECTOR 382 #define INSERTELEMENT 382
#define NORETURN 383 #define SHUFFLEVECTOR 383
#define INREG 384 #define NORETURN 384
#define SRET 385 #define INREG 385
#define NOUNWIND 386 #define SRET 386
#define DEFAULT 387 #define NOUNWIND 387
#define HIDDEN 388 #define DEFAULT 388
#define HIDDEN 389
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
#line 937 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" typedef union YYSTYPE
typedef union YYSTYPE { #line 938 "/home/laurov/llvm/llvm/lib/AsmParser/llvmAsmParser.y"
{
llvm::Module *ModuleVal; llvm::Module *ModuleVal;
llvm::Function *FunctionVal; llvm::Function *FunctionVal;
llvm::BasicBlock *BasicBlockVal; llvm::BasicBlock *BasicBlockVal;
@@ -345,9 +358,10 @@ typedef union YYSTYPE {
llvm::Instruction::OtherOps OtherOpVal; llvm::Instruction::OtherOps OtherOpVal;
llvm::ICmpInst::Predicate IPredicate; llvm::ICmpInst::Predicate IPredicate;
llvm::FCmpInst::Predicate FPredicate; llvm::FCmpInst::Predicate FPredicate;
} YYSTYPE; }
/* Line 1447 of yacc.c. */ /* Line 1529 of yacc.c. */
#line 351 "llvmAsmParser.tab.h" #line 364 "llvmAsmParser.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1
@@ -355,5 +369,3 @@ typedef union YYSTYPE {
extern YYSTYPE llvmAsmlval; extern YYSTYPE llvmAsmlval;

View File

@@ -704,7 +704,7 @@ ParseGlobalVariable(char *NameStr,
GlobalValue::LinkageTypes Linkage, GlobalValue::LinkageTypes Linkage,
GlobalValue::VisibilityTypes Visibility, GlobalValue::VisibilityTypes Visibility,
bool isConstantGlobal, const Type *Ty, bool isConstantGlobal, const Type *Ty,
Constant *Initializer) { Constant *Initializer, bool IsThreadLocal) {
if (isa<FunctionType>(Ty)) { if (isa<FunctionType>(Ty)) {
GenerateError("Cannot declare global vars of function type"); GenerateError("Cannot declare global vars of function type");
return 0; return 0;
@@ -737,6 +737,7 @@ ParseGlobalVariable(char *NameStr,
GV->setLinkage(Linkage); GV->setLinkage(Linkage);
GV->setVisibility(Visibility); GV->setVisibility(Visibility);
GV->setConstant(isConstantGlobal); GV->setConstant(isConstantGlobal);
GV->setThreadLocal(IsThreadLocal);
InsertValue(GV, CurModule.Values); InsertValue(GV, CurModule.Values);
return GV; return GV;
} }
@@ -761,7 +762,7 @@ ParseGlobalVariable(char *NameStr,
// Otherwise there is no existing GV to use, create one now. // Otherwise there is no existing GV to use, create one now.
GlobalVariable *GV = GlobalVariable *GV =
new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
CurModule.CurrentModule); CurModule.CurrentModule, IsThreadLocal);
GV->setVisibility(Visibility); GV->setVisibility(Visibility);
InsertValue(GV, CurModule.Values); InsertValue(GV, CurModule.Values);
return GV; return GV;
@@ -997,6 +998,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
%type <TypeWithAttrs> ArgType %type <TypeWithAttrs> ArgType
%type <JumpTable> JumpTable %type <JumpTable> JumpTable
%type <BoolVal> GlobalType // GLOBAL or CONSTANT? %type <BoolVal> GlobalType // GLOBAL or CONSTANT?
%type <BoolVal> ThreadLocal // 'thread_local' or not
%type <BoolVal> OptVolatile // 'volatile' or not %type <BoolVal> OptVolatile // 'volatile' or not
%type <BoolVal> OptTailCall // TAIL CALL or plain CALL. %type <BoolVal> OptTailCall // TAIL CALL or plain CALL.
%type <BoolVal> OptSideEffect // 'sideeffect' or not. %type <BoolVal> OptSideEffect // 'sideeffect' or not.
@@ -1038,7 +1040,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
%type <StrVal> OptSection SectionString %type <StrVal> OptSection SectionString
%token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK %token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
%token DECLARE DEFINE GLOBAL CONSTANT SECTION VOLATILE %token DECLARE DEFINE GLOBAL CONSTANT SECTION VOLATILE THREAD_LOCAL
%token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING %token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING
%token DLLIMPORT DLLEXPORT EXTERN_WEAK %token DLLIMPORT DLLEXPORT EXTERN_WEAK
%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN %token OPAQUE EXTERNAL TARGET TRIPLE ALIGN
@@ -1918,6 +1920,9 @@ ConstVector : ConstVector ',' ConstVal {
// GlobalType - Match either GLOBAL or CONSTANT for global declarations... // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; }; GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; };
// ThreadLocal
ThreadLocal : THREAD_LOCAL { $$ = true; } | { $$ = false; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Rules to match Modules // Rules to match Modules
@@ -1990,30 +1995,30 @@ Definition
} }
CHECK_FOR_ERROR CHECK_FOR_ERROR
} }
| OptGlobalAssign GVVisibilityStyle GlobalType ConstVal { | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal {
/* "Externally Visible" Linkage */ /* "Externally Visible" Linkage */
if ($4 == 0)
GEN_ERROR("Global value initializer is not a constant");
CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
$2, $3, $4->getType(), $4);
CHECK_FOR_ERROR
} GlobalVarAttributes {
CurGV = 0;
}
| OptGlobalAssign GVInternalLinkage GVVisibilityStyle GlobalType ConstVal {
if ($5 == 0) if ($5 == 0)
GEN_ERROR("Global value initializer is not a constant"); GEN_ERROR("Global value initializer is not a constant");
CurGV = ParseGlobalVariable($1, $2, $3, $4, $5->getType(), $5); CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
$2, $4, $5->getType(), $5, $3);
CHECK_FOR_ERROR CHECK_FOR_ERROR
} GlobalVarAttributes { } GlobalVarAttributes {
CurGV = 0; CurGV = 0;
} }
| OptGlobalAssign GVExternalLinkage GVVisibilityStyle GlobalType Types { | OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal GlobalType ConstVal {
if (!UpRefs.empty()) if ($6 == 0)
GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription()); GEN_ERROR("Global value initializer is not a constant");
CurGV = ParseGlobalVariable($1, $2, $3, $4, *$5, 0); CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4);
CHECK_FOR_ERROR CHECK_FOR_ERROR
delete $5; } GlobalVarAttributes {
CurGV = 0;
}
| OptGlobalAssign GVExternalLinkage GVVisibilityStyle ThreadLocal GlobalType Types {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$6)->getDescription());
CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4);
CHECK_FOR_ERROR
delete $6;
} GlobalVarAttributes { } GlobalVarAttributes {
CurGV = 0; CurGV = 0;
CHECK_FOR_ERROR CHECK_FOR_ERROR

View File

@@ -704,7 +704,7 @@ ParseGlobalVariable(char *NameStr,
GlobalValue::LinkageTypes Linkage, GlobalValue::LinkageTypes Linkage,
GlobalValue::VisibilityTypes Visibility, GlobalValue::VisibilityTypes Visibility,
bool isConstantGlobal, const Type *Ty, bool isConstantGlobal, const Type *Ty,
Constant *Initializer) { Constant *Initializer, bool IsThreadLocal) {
if (isa<FunctionType>(Ty)) { if (isa<FunctionType>(Ty)) {
GenerateError("Cannot declare global vars of function type"); GenerateError("Cannot declare global vars of function type");
return 0; return 0;
@@ -737,6 +737,7 @@ ParseGlobalVariable(char *NameStr,
GV->setLinkage(Linkage); GV->setLinkage(Linkage);
GV->setVisibility(Visibility); GV->setVisibility(Visibility);
GV->setConstant(isConstantGlobal); GV->setConstant(isConstantGlobal);
GV->setThreadLocal(IsThreadLocal);
InsertValue(GV, CurModule.Values); InsertValue(GV, CurModule.Values);
return GV; return GV;
} }
@@ -761,7 +762,7 @@ ParseGlobalVariable(char *NameStr,
// Otherwise there is no existing GV to use, create one now. // Otherwise there is no existing GV to use, create one now.
GlobalVariable *GV = GlobalVariable *GV =
new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
CurModule.CurrentModule); CurModule.CurrentModule, IsThreadLocal);
GV->setVisibility(Visibility); GV->setVisibility(Visibility);
InsertValue(GV, CurModule.Values); InsertValue(GV, CurModule.Values);
return GV; return GV;
@@ -997,6 +998,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
%type <TypeWithAttrs> ArgType %type <TypeWithAttrs> ArgType
%type <JumpTable> JumpTable %type <JumpTable> JumpTable
%type <BoolVal> GlobalType // GLOBAL or CONSTANT? %type <BoolVal> GlobalType // GLOBAL or CONSTANT?
%type <BoolVal> ThreadLocal // 'thread_local' or not
%type <BoolVal> OptVolatile // 'volatile' or not %type <BoolVal> OptVolatile // 'volatile' or not
%type <BoolVal> OptTailCall // TAIL CALL or plain CALL. %type <BoolVal> OptTailCall // TAIL CALL or plain CALL.
%type <BoolVal> OptSideEffect // 'sideeffect' or not. %type <BoolVal> OptSideEffect // 'sideeffect' or not.
@@ -1038,7 +1040,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
%type <StrVal> OptSection SectionString %type <StrVal> OptSection SectionString
%token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK %token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
%token DECLARE DEFINE GLOBAL CONSTANT SECTION VOLATILE %token DECLARE DEFINE GLOBAL CONSTANT SECTION VOLATILE THREAD_LOCAL
%token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING %token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING
%token DLLIMPORT DLLEXPORT EXTERN_WEAK %token DLLIMPORT DLLEXPORT EXTERN_WEAK
%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN %token OPAQUE EXTERNAL TARGET TRIPLE ALIGN
@@ -1918,6 +1920,9 @@ ConstVector : ConstVector ',' ConstVal {
// GlobalType - Match either GLOBAL or CONSTANT for global declarations... // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; }; GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; };
// ThreadLocal
ThreadLocal : THREAD_LOCAL { $$ = true; } | { $$ = false; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Rules to match Modules // Rules to match Modules
@@ -1990,30 +1995,30 @@ Definition
} }
CHECK_FOR_ERROR CHECK_FOR_ERROR
} }
| OptGlobalAssign GVVisibilityStyle GlobalType ConstVal { | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal {
/* "Externally Visible" Linkage */ /* "Externally Visible" Linkage */
if ($4 == 0)
GEN_ERROR("Global value initializer is not a constant");
CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
$2, $3, $4->getType(), $4);
CHECK_FOR_ERROR
} GlobalVarAttributes {
CurGV = 0;
}
| OptGlobalAssign GVInternalLinkage GVVisibilityStyle GlobalType ConstVal {
if ($5 == 0) if ($5 == 0)
GEN_ERROR("Global value initializer is not a constant"); GEN_ERROR("Global value initializer is not a constant");
CurGV = ParseGlobalVariable($1, $2, $3, $4, $5->getType(), $5); CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
$2, $4, $5->getType(), $5, $3);
CHECK_FOR_ERROR CHECK_FOR_ERROR
} GlobalVarAttributes { } GlobalVarAttributes {
CurGV = 0; CurGV = 0;
} }
| OptGlobalAssign GVExternalLinkage GVVisibilityStyle GlobalType Types { | OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal GlobalType ConstVal {
if (!UpRefs.empty()) if ($6 == 0)
GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription()); GEN_ERROR("Global value initializer is not a constant");
CurGV = ParseGlobalVariable($1, $2, $3, $4, *$5, 0); CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4);
CHECK_FOR_ERROR CHECK_FOR_ERROR
delete $5; } GlobalVarAttributes {
CurGV = 0;
}
| OptGlobalAssign GVExternalLinkage GVVisibilityStyle ThreadLocal GlobalType Types {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$6)->getDescription());
CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4);
CHECK_FOR_ERROR
delete $6;
} GlobalVarAttributes { } GlobalVarAttributes {
CurGV = 0; CurGV = 0;
CHECK_FOR_ERROR CHECK_FOR_ERROR

View File

@@ -154,12 +154,14 @@ public:
GlobalValue::LinkageTypes Linkage, GlobalValue::LinkageTypes Linkage,
GlobalValue::VisibilityTypes Visibility, GlobalValue::VisibilityTypes Visibility,
unsigned SlotNum, unsigned SlotNum,
unsigned initSlot unsigned initSlot,
bool isThreadLocal
) { ) {
if (os) { if (os) {
*os << " GV: " *os << " GV: "
<< ( initSlot == 0 ? "Uni" : "I" ) << "nitialized, " << ( initSlot == 0 ? "Uni" : "I" ) << "nitialized, "
<< ( isConstant? "Constant, " : "Variable, ") << ( isConstant? "Constant, " : "Variable, ")
<< " Thread Local = " << ( isThreadLocal? "yes, " : "no, ")
<< " Linkage=" << Linkage << " Linkage=" << Linkage
<< " Visibility="<< Visibility << " Visibility="<< Visibility
<< " Type="; << " Type=";

View File

@@ -1704,11 +1704,12 @@ void BytecodeReader::ParseModuleGlobalInfo() {
unsigned VarType = read_vbr_uint(); unsigned VarType = read_vbr_uint();
while (VarType != Type::VoidTyID) { // List is terminated by Void while (VarType != Type::VoidTyID) { // List is terminated by Void
// VarType Fields: bit0 = isConstant, bit1 = hasInitializer, bit2,3,4 = // VarType Fields: bit0 = isConstant, bit1 = hasInitializer, bit2,3,4 =
// Linkage, bit4+ = slot# // Linkage, bit5 = isThreadLocal, bit6+ = slot#
unsigned SlotNo = VarType >> 5; unsigned SlotNo = VarType >> 6;
unsigned LinkageID = (VarType >> 2) & 7; unsigned LinkageID = (VarType >> 2) & 7;
unsigned VisibilityID = 0; unsigned VisibilityID = 0;
bool isConstant = VarType & 1; bool isConstant = VarType & 1;
bool isThreadLocal = (VarType >> 5) & 1;
bool hasInitializer = (VarType & 2) != 0; bool hasInitializer = (VarType & 2) != 0;
unsigned Alignment = 0; unsigned Alignment = 0;
unsigned GlobalSectionID = 0; unsigned GlobalSectionID = 0;
@@ -1764,7 +1765,7 @@ void BytecodeReader::ParseModuleGlobalInfo() {
// Create the global variable... // Create the global variable...
GlobalVariable *GV = new GlobalVariable(ElTy, isConstant, Linkage, GlobalVariable *GV = new GlobalVariable(ElTy, isConstant, Linkage,
0, "", TheModule); 0, "", TheModule, isThreadLocal);
GV->setAlignment(Alignment); GV->setAlignment(Alignment);
GV->setVisibility(Visibility); GV->setVisibility(Visibility);
insertValue(GV, SlotNo, ModuleValues); insertValue(GV, SlotNo, ModuleValues);
@@ -1781,7 +1782,7 @@ void BytecodeReader::ParseModuleGlobalInfo() {
// Notify handler about the global value. // Notify handler about the global value.
if (Handler) if (Handler)
Handler->handleGlobalVariable(ElTy, isConstant, Linkage, Visibility, Handler->handleGlobalVariable(ElTy, isConstant, Linkage, Visibility,
SlotNo, initSlot); SlotNo, initSlot, isThreadLocal);
// Get next item // Get next item
VarType = read_vbr_uint(); VarType = read_vbr_uint();

View File

@@ -950,7 +950,7 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
"Global must have an initializer or have external linkage!"); "Global must have an initializer or have external linkage!");
// Fields: bit0 = isConstant, bit1 = hasInitializer, bit2-4=Linkage, // Fields: bit0 = isConstant, bit1 = hasInitializer, bit2-4=Linkage,
// bit5+ = Slot # for type. // bit5 = isThreadLocal, bit6+ = Slot # for type.
bool HasExtensionWord = (I->getAlignment() != 0) || bool HasExtensionWord = (I->getAlignment() != 0) ||
I->hasSection() || I->hasSection() ||
(I->getVisibility() != GlobalValue::DefaultVisibility); (I->getVisibility() != GlobalValue::DefaultVisibility);
@@ -958,12 +958,13 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
// If we need to use the extension byte, set linkage=3(internal) and // If we need to use the extension byte, set linkage=3(internal) and
// initializer = 0 (impossible!). // initializer = 0 (impossible!).
if (!HasExtensionWord) { if (!HasExtensionWord) {
unsigned oSlot = (Slot << 5) | (getEncodedLinkage(I) << 2) | unsigned oSlot = (Slot << 6)| (((unsigned)I->isThreadLocal()) << 5) |
(I->hasInitializer() << 1) | (unsigned)I->isConstant(); (getEncodedLinkage(I) << 2) | (I->hasInitializer() << 1)
| (unsigned)I->isConstant();
output_vbr(oSlot); output_vbr(oSlot);
} else { } else {
unsigned oSlot = (Slot << 5) | (3 << 2) | unsigned oSlot = (Slot << 6) | (((unsigned)I->isThreadLocal()) << 5) |
(0 << 1) | (unsigned)I->isConstant(); (3 << 2) | (0 << 1) | (unsigned)I->isConstant();
output_vbr(oSlot); output_vbr(oSlot);
// The extension word has this format: bit 0 = has initializer, bit 1-3 = // The extension word has this format: bit 0 = has initializer, bit 1-3 =

View File

@@ -477,7 +477,7 @@ static bool LinkGlobals(Module *Dest, Module *Src,
GlobalVariable *NewDGV = GlobalVariable *NewDGV =
new GlobalVariable(SGV->getType()->getElementType(), new GlobalVariable(SGV->getType()->getElementType(),
SGV->isConstant(), SGV->getLinkage(), /*init*/0, SGV->isConstant(), SGV->getLinkage(), /*init*/0,
SGV->getName(), Dest); SGV->getName(), Dest, SGV->isThreadLocal());
// Propagate alignment, visibility and section info. // Propagate alignment, visibility and section info.
CopyGVAttributes(NewDGV, SGV); CopyGVAttributes(NewDGV, SGV);
@@ -500,7 +500,7 @@ static bool LinkGlobals(Module *Dest, Module *Src,
GlobalVariable *NewDGV = GlobalVariable *NewDGV =
new GlobalVariable(SGV->getType()->getElementType(), new GlobalVariable(SGV->getType()->getElementType(),
SGV->isConstant(), SGV->getLinkage(), /*init*/0, SGV->isConstant(), SGV->getLinkage(), /*init*/0,
"", Dest); "", Dest, SGV->isThreadLocal());
// Propagate alignment, section and visibility info. // Propagate alignment, section and visibility info.
NewDGV->setAlignment(DGV->getAlignment()); NewDGV->setAlignment(DGV->getAlignment());
@@ -522,6 +522,7 @@ static bool LinkGlobals(Module *Dest, Module *Src,
GlobalVariable *NewDGV = GlobalVariable *NewDGV =
new GlobalVariable(SGV->getType()->getElementType(), new GlobalVariable(SGV->getType()->getElementType(),
DGV->isConstant(), DGV->getLinkage()); DGV->isConstant(), DGV->getLinkage());
NewDGV->setThreadLocal(DGV->isThreadLocal());
CopyGVAttributes(NewDGV, DGV); CopyGVAttributes(NewDGV, DGV);
Dest->getGlobalList().insert(DGV, NewDGV); Dest->getGlobalList().insert(DGV, NewDGV);
DGV->replaceAllUsesWith( DGV->replaceAllUsesWith(
@@ -821,7 +822,7 @@ static bool LinkAppendingVars(Module *M,
// Create the new global variable... // Create the new global variable...
GlobalVariable *NG = GlobalVariable *NG =
new GlobalVariable(NewType, G1->isConstant(), G1->getLinkage(), new GlobalVariable(NewType, G1->isConstant(), G1->getLinkage(),
/*init*/0, First->first, M); /*init*/0, First->first, M, G1->isThreadLocal());
// Merge the initializer... // Merge the initializer...
Inits.reserve(NewSize); Inits.reserve(NewSize);

View File

@@ -390,7 +390,9 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV) {
assert(In && "Couldn't get element of initializer?"); assert(In && "Couldn't get element of initializer?");
GlobalVariable *NGV = new GlobalVariable(STy->getElementType(i), false, GlobalVariable *NGV = new GlobalVariable(STy->getElementType(i), false,
GlobalVariable::InternalLinkage, GlobalVariable::InternalLinkage,
In, GV->getName()+"."+utostr(i)); In, GV->getName()+"."+utostr(i),
(Module *)NULL,
GV->isThreadLocal());
Globals.insert(GV, NGV); Globals.insert(GV, NGV);
NewGlobals.push_back(NGV); NewGlobals.push_back(NGV);
} }
@@ -413,7 +415,9 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV) {
GlobalVariable *NGV = new GlobalVariable(STy->getElementType(), false, GlobalVariable *NGV = new GlobalVariable(STy->getElementType(), false,
GlobalVariable::InternalLinkage, GlobalVariable::InternalLinkage,
In, GV->getName()+"."+utostr(i)); In, GV->getName()+"."+utostr(i),
(Module *)NULL,
GV->isThreadLocal());
Globals.insert(GV, NGV); Globals.insert(GV, NGV);
NewGlobals.push_back(NGV); NewGlobals.push_back(NGV);
} }
@@ -699,7 +703,9 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
Constant *Init = UndefValue::get(MI->getAllocatedType()); Constant *Init = UndefValue::get(MI->getAllocatedType());
GlobalVariable *NewGV = new GlobalVariable(MI->getAllocatedType(), false, GlobalVariable *NewGV = new GlobalVariable(MI->getAllocatedType(), false,
GlobalValue::InternalLinkage, Init, GlobalValue::InternalLinkage, Init,
GV->getName()+".body"); GV->getName()+".body",
(Module *)NULL,
GV->isThreadLocal());
GV->getParent()->getGlobalList().insert(GV, NewGV); GV->getParent()->getGlobalList().insert(GV, NewGV);
// Anything that used the malloc now uses the global directly. // Anything that used the malloc now uses the global directly.
@@ -714,7 +720,8 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
// keep track of whether the global was initialized yet or not. // keep track of whether the global was initialized yet or not.
GlobalVariable *InitBool = GlobalVariable *InitBool =
new GlobalVariable(Type::Int1Ty, false, GlobalValue::InternalLinkage, new GlobalVariable(Type::Int1Ty, false, GlobalValue::InternalLinkage,
ConstantInt::getFalse(), GV->getName()+".init"); ConstantInt::getFalse(), GV->getName()+".init",
(Module *)NULL, GV->isThreadLocal());
bool InitBoolUsed = false; bool InitBoolUsed = false;
// Loop over all uses of GV, processing them in turn. // Loop over all uses of GV, processing them in turn.
@@ -943,7 +950,8 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
GlobalVariable *NGV = GlobalVariable *NGV =
new GlobalVariable(PFieldTy, false, GlobalValue::InternalLinkage, new GlobalVariable(PFieldTy, false, GlobalValue::InternalLinkage,
Constant::getNullValue(PFieldTy), Constant::getNullValue(PFieldTy),
GV->getName() + ".f" + utostr(FieldNo), GV); GV->getName() + ".f" + utostr(FieldNo), GV,
GV->isThreadLocal());
FieldGlobals.push_back(NGV); FieldGlobals.push_back(NGV);
MallocInst *NMI = new MallocInst(FieldTy, MI->getArraySize(), MallocInst *NMI = new MallocInst(FieldTy, MI->getArraySize(),
@@ -1145,7 +1153,9 @@ static void ShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
// Create the new global, initializing it to false. // Create the new global, initializing it to false.
GlobalVariable *NewGV = new GlobalVariable(Type::Int1Ty, false, GlobalVariable *NewGV = new GlobalVariable(Type::Int1Ty, false,
GlobalValue::InternalLinkage, ConstantInt::getFalse(), GlobalValue::InternalLinkage, ConstantInt::getFalse(),
GV->getName()+".b"); GV->getName()+".b",
(Module *)NULL,
GV->isThreadLocal());
GV->getParent()->getGlobalList().insert(GV, NewGV); GV->getParent()->getGlobalList().insert(GV, NewGV);
Constant *InitVal = GV->getInitializer(); Constant *InitVal = GV->getInitializer();
@@ -1519,7 +1529,9 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL,
// Create the new global and insert it next to the existing list. // Create the new global and insert it next to the existing list.
GlobalVariable *NGV = new GlobalVariable(CA->getType(), GCL->isConstant(), GlobalVariable *NGV = new GlobalVariable(CA->getType(), GCL->isConstant(),
GCL->getLinkage(), CA); GCL->getLinkage(), CA, "",
(Module *)NULL,
GCL->isThreadLocal());
GCL->getParent()->getGlobalList().insert(GCL, NGV); GCL->getParent()->getGlobalList().insert(GCL, NGV);
NGV->takeName(GCL); NGV->takeName(GCL);

View File

@@ -80,6 +80,8 @@ Module *llvm::CloneModule(const Module *M,
GV->setInitializer(cast<Constant>(MapValue(I->getInitializer(), GV->setInitializer(cast<Constant>(MapValue(I->getInitializer(),
ValueMap))); ValueMap)));
GV->setLinkage(I->getLinkage()); GV->setLinkage(I->getLinkage());
GV->setThreadLocal(I->isThreadLocal());
GV->setConstant(I->isConstant());
} }
// Similarly, copy over function bodies now... // Similarly, copy over function bodies now...

View File

@@ -878,7 +878,8 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
case GlobalValue::HiddenVisibility: Out << "hidden "; break; case GlobalValue::HiddenVisibility: Out << "hidden "; break;
} }
} }
if (GV->isThreadLocal()) Out << "thread_local ";
Out << (GV->isConstant() ? "constant " : "global "); Out << (GV->isConstant() ? "constant " : "global ");
printType(GV->getType()->getElementType()); printType(GV->getType()->getElementType());

View File

@@ -81,11 +81,11 @@ void GlobalValue::destroyConstant() {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
Constant *InitVal, Constant *InitVal, const std::string &Name,
const std::string &Name, Module *ParentModule) Module *ParentModule, bool ThreadLocal)
: GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
&Initializer, InitVal != 0, Link, Name), &Initializer, InitVal != 0, Link, Name),
isConstantGlobal(constant) { isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
if (InitVal) { if (InitVal) {
assert(InitVal->getType() == Ty && assert(InitVal->getType() == Ty &&
"Initializer should be the same type as the GlobalVariable!"); "Initializer should be the same type as the GlobalVariable!");
@@ -101,11 +101,11 @@ GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
} }
GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
Constant *InitVal, Constant *InitVal, const std::string &Name,
const std::string &Name, GlobalVariable *Before) GlobalVariable *Before, bool ThreadLocal)
: GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
&Initializer, InitVal != 0, Link, Name), &Initializer, InitVal != 0, Link, Name),
isConstantGlobal(constant) { isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
if (InitVal) { if (InitVal) {
assert(InitVal->getType() == Ty && assert(InitVal->getType() == Ty &&
"Initializer should be the same type as the GlobalVariable!"); "Initializer should be the same type as the GlobalVariable!");