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::VisibilityTypes,///< The visibility style of the 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

View File

@ -44,6 +44,7 @@ class GlobalVariable : public GlobalValue {
void setPrev(GlobalVariable *N) { Prev = N; }
bool isConstantGlobal; // Is this a global constant?
bool isThreadLocalSymbol; // Is this symbol "Thread Local"?
Use Initializer;
public:
@ -51,12 +52,12 @@ public:
/// automatically inserted into the end of the specified modules global list.
GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage,
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
/// specified other global.
GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage,
Constant *Initializer, const std::string &Name,
GlobalVariable *InsertBefore);
GlobalVariable *InsertBefore, bool ThreadLocal = false);
/// isDeclaration - Is this global variable lacking an initializer? If so,
/// the global variable is defined in some other translation unit, and is thus
@ -107,6 +108,10 @@ public:
bool isConstant() const { return isConstantGlobal; }
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,
/// 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; }
extern_weak { return EXTERN_WEAK; }
external { return EXTERNAL; }
thread_local { return THREAD_LOCAL; }
zeroinitializer { return ZEROINITIALIZER; }
\.\.\. { return DOTDOTDOT; }
undef { return UNDEF; }

View File

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

View File

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

View File

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

View File

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

View File

@ -1704,11 +1704,12 @@ void BytecodeReader::ParseModuleGlobalInfo() {
unsigned VarType = read_vbr_uint();
while (VarType != Type::VoidTyID) { // List is terminated by Void
// VarType Fields: bit0 = isConstant, bit1 = hasInitializer, bit2,3,4 =
// Linkage, bit4+ = slot#
unsigned SlotNo = VarType >> 5;
// Linkage, bit5 = isThreadLocal, bit6+ = slot#
unsigned SlotNo = VarType >> 6;
unsigned LinkageID = (VarType >> 2) & 7;
unsigned VisibilityID = 0;
bool isConstant = VarType & 1;
bool isThreadLocal = (VarType >> 5) & 1;
bool hasInitializer = (VarType & 2) != 0;
unsigned Alignment = 0;
unsigned GlobalSectionID = 0;
@ -1764,7 +1765,7 @@ void BytecodeReader::ParseModuleGlobalInfo() {
// Create the global variable...
GlobalVariable *GV = new GlobalVariable(ElTy, isConstant, Linkage,
0, "", TheModule);
0, "", TheModule, isThreadLocal);
GV->setAlignment(Alignment);
GV->setVisibility(Visibility);
insertValue(GV, SlotNo, ModuleValues);
@ -1781,7 +1782,7 @@ void BytecodeReader::ParseModuleGlobalInfo() {
// Notify handler about the global value.
if (Handler)
Handler->handleGlobalVariable(ElTy, isConstant, Linkage, Visibility,
SlotNo, initSlot);
SlotNo, initSlot, isThreadLocal);
// Get next item
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!");
// Fields: bit0 = isConstant, bit1 = hasInitializer, bit2-4=Linkage,
// bit5+ = Slot # for type.
// bit5 = isThreadLocal, bit6+ = Slot # for type.
bool HasExtensionWord = (I->getAlignment() != 0) ||
I->hasSection() ||
(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
// initializer = 0 (impossible!).
if (!HasExtensionWord) {
unsigned oSlot = (Slot << 5) | (getEncodedLinkage(I) << 2) |
(I->hasInitializer() << 1) | (unsigned)I->isConstant();
unsigned oSlot = (Slot << 6)| (((unsigned)I->isThreadLocal()) << 5) |
(getEncodedLinkage(I) << 2) | (I->hasInitializer() << 1)
| (unsigned)I->isConstant();
output_vbr(oSlot);
} else {
unsigned oSlot = (Slot << 5) | (3 << 2) |
(0 << 1) | (unsigned)I->isConstant();
unsigned oSlot = (Slot << 6) | (((unsigned)I->isThreadLocal()) << 5) |
(3 << 2) | (0 << 1) | (unsigned)I->isConstant();
output_vbr(oSlot);
// 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 =
new GlobalVariable(SGV->getType()->getElementType(),
SGV->isConstant(), SGV->getLinkage(), /*init*/0,
SGV->getName(), Dest);
SGV->getName(), Dest, SGV->isThreadLocal());
// Propagate alignment, visibility and section info.
CopyGVAttributes(NewDGV, SGV);
@ -500,7 +500,7 @@ static bool LinkGlobals(Module *Dest, Module *Src,
GlobalVariable *NewDGV =
new GlobalVariable(SGV->getType()->getElementType(),
SGV->isConstant(), SGV->getLinkage(), /*init*/0,
"", Dest);
"", Dest, SGV->isThreadLocal());
// Propagate alignment, section and visibility info.
NewDGV->setAlignment(DGV->getAlignment());
@ -522,6 +522,7 @@ static bool LinkGlobals(Module *Dest, Module *Src,
GlobalVariable *NewDGV =
new GlobalVariable(SGV->getType()->getElementType(),
DGV->isConstant(), DGV->getLinkage());
NewDGV->setThreadLocal(DGV->isThreadLocal());
CopyGVAttributes(NewDGV, DGV);
Dest->getGlobalList().insert(DGV, NewDGV);
DGV->replaceAllUsesWith(
@ -821,7 +822,7 @@ static bool LinkAppendingVars(Module *M,
// Create the new global variable...
GlobalVariable *NG =
new GlobalVariable(NewType, G1->isConstant(), G1->getLinkage(),
/*init*/0, First->first, M);
/*init*/0, First->first, M, G1->isThreadLocal());
// Merge the initializer...
Inits.reserve(NewSize);

View File

@ -390,7 +390,9 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV) {
assert(In && "Couldn't get element of initializer?");
GlobalVariable *NGV = new GlobalVariable(STy->getElementType(i), false,
GlobalVariable::InternalLinkage,
In, GV->getName()+"."+utostr(i));
In, GV->getName()+"."+utostr(i),
(Module *)NULL,
GV->isThreadLocal());
Globals.insert(GV, NGV);
NewGlobals.push_back(NGV);
}
@ -413,7 +415,9 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV) {
GlobalVariable *NGV = new GlobalVariable(STy->getElementType(), false,
GlobalVariable::InternalLinkage,
In, GV->getName()+"."+utostr(i));
In, GV->getName()+"."+utostr(i),
(Module *)NULL,
GV->isThreadLocal());
Globals.insert(GV, NGV);
NewGlobals.push_back(NGV);
}
@ -699,7 +703,9 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
Constant *Init = UndefValue::get(MI->getAllocatedType());
GlobalVariable *NewGV = new GlobalVariable(MI->getAllocatedType(), false,
GlobalValue::InternalLinkage, Init,
GV->getName()+".body");
GV->getName()+".body",
(Module *)NULL,
GV->isThreadLocal());
GV->getParent()->getGlobalList().insert(GV, NewGV);
// 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.
GlobalVariable *InitBool =
new GlobalVariable(Type::Int1Ty, false, GlobalValue::InternalLinkage,
ConstantInt::getFalse(), GV->getName()+".init");
ConstantInt::getFalse(), GV->getName()+".init",
(Module *)NULL, GV->isThreadLocal());
bool InitBoolUsed = false;
// Loop over all uses of GV, processing them in turn.
@ -943,7 +950,8 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
GlobalVariable *NGV =
new GlobalVariable(PFieldTy, false, GlobalValue::InternalLinkage,
Constant::getNullValue(PFieldTy),
GV->getName() + ".f" + utostr(FieldNo), GV);
GV->getName() + ".f" + utostr(FieldNo), GV,
GV->isThreadLocal());
FieldGlobals.push_back(NGV);
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.
GlobalVariable *NewGV = new GlobalVariable(Type::Int1Ty, false,
GlobalValue::InternalLinkage, ConstantInt::getFalse(),
GV->getName()+".b");
GV->getName()+".b",
(Module *)NULL,
GV->isThreadLocal());
GV->getParent()->getGlobalList().insert(GV, NewGV);
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.
GlobalVariable *NGV = new GlobalVariable(CA->getType(), GCL->isConstant(),
GCL->getLinkage(), CA);
GCL->getLinkage(), CA, "",
(Module *)NULL,
GCL->isThreadLocal());
GCL->getParent()->getGlobalList().insert(GCL, NGV);
NGV->takeName(GCL);

View File

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

View File

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

View File

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