LLVM  6.0.0svn
LowerEmuTLS.cpp
Go to the documentation of this file.
1 //===- LowerEmuTLS.cpp - Add __emutls_[vt].* variables --------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This transformation is required for targets depending on libgcc style
11 // emulated thread local storage variables. For every defined TLS variable xyz,
12 // an __emutls_v.xyz is generated. If there is non-zero initialized value
13 // an __emutls_t.xyz is also generated.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/CodeGen/Passes.h"
21 #include "llvm/IR/LLVMContext.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/Pass.h"
24 
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "loweremutls"
28 
29 namespace {
30 
31 class LowerEmuTLS : public ModulePass {
32 public:
33  static char ID; // Pass identification, replacement for typeid
34  LowerEmuTLS() : ModulePass(ID) {
36  }
37 
38  bool runOnModule(Module &M) override;
39 private:
40  bool addEmuTlsVar(Module &M, const GlobalVariable *GV);
41  static void copyLinkageVisibility(Module &M,
42  const GlobalVariable *from,
43  GlobalVariable *to) {
44  to->setLinkage(from->getLinkage());
45  to->setVisibility(from->getVisibility());
46  if (from->hasComdat()) {
47  to->setComdat(M.getOrInsertComdat(to->getName()));
49  }
50  }
51 };
52 }
53 
54 char LowerEmuTLS::ID = 0;
55 
57  "Add __emutls_[vt]. variables for emultated TLS model", false,
58  false)
59 
60 ModulePass *llvm::createLowerEmuTLSPass() { return new LowerEmuTLS(); }
61 
62 bool LowerEmuTLS::runOnModule(Module &M) {
63  if (skipModule(M))
64  return false;
65 
66  auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
67  if (!TPC)
68  return false;
69 
70  auto &TM = TPC->getTM<TargetMachine>();
71  if (!TM.Options.EmulatedTLS)
72  return false;
73 
74  bool Changed = false;
76  for (const auto &G : M.globals()) {
77  if (G.isThreadLocal())
78  TlsVars.append({&G});
79  }
80  for (const auto G : TlsVars)
81  Changed |= addEmuTlsVar(M, G);
82  return Changed;
83 }
84 
85 bool LowerEmuTLS::addEmuTlsVar(Module &M, const GlobalVariable *GV) {
86  LLVMContext &C = M.getContext();
87  PointerType *VoidPtrType = Type::getInt8PtrTy(C);
88 
89  std::string EmuTlsVarName = ("__emutls_v." + GV->getName()).str();
90  GlobalVariable *EmuTlsVar = M.getNamedGlobal(EmuTlsVarName);
91  if (EmuTlsVar)
92  return false; // It has been added before.
93 
94  const DataLayout &DL = M.getDataLayout();
95  Constant *NullPtr = ConstantPointerNull::get(VoidPtrType);
96 
97  // Get non-zero initializer from GV's initializer.
98  const Constant *InitValue = nullptr;
99  if (GV->hasInitializer()) {
100  InitValue = GV->getInitializer();
101  const ConstantInt *InitIntValue = dyn_cast<ConstantInt>(InitValue);
102  // When GV's init value is all 0, omit the EmuTlsTmplVar and let
103  // the emutls library function to reset newly allocated TLS variables.
104  if (isa<ConstantAggregateZero>(InitValue) ||
105  (InitIntValue && InitIntValue->isZero()))
106  InitValue = nullptr;
107  }
108 
109  // Create the __emutls_v. symbol, whose type has 4 fields:
110  // word size; // size of GV in bytes
111  // word align; // alignment of GV
112  // void *ptr; // initialized to 0; set at run time per thread.
113  // void *templ; // 0 or point to __emutls_t.*
114  // sizeof(word) should be the same as sizeof(void*) on target.
115  IntegerType *WordType = DL.getIntPtrType(C);
116  PointerType *InitPtrType = InitValue ?
117  PointerType::getUnqual(InitValue->getType()) : VoidPtrType;
118  Type *ElementTypes[4] = {WordType, WordType, VoidPtrType, InitPtrType};
119  ArrayRef<Type*> ElementTypeArray(ElementTypes, 4);
120  StructType *EmuTlsVarType = StructType::create(ElementTypeArray);
121  EmuTlsVar = cast<GlobalVariable>(
122  M.getOrInsertGlobal(EmuTlsVarName, EmuTlsVarType));
123  copyLinkageVisibility(M, GV, EmuTlsVar);
124 
125  // Define "__emutls_t.*" and "__emutls_v.*" only if GV is defined.
126  if (!GV->hasInitializer())
127  return true;
128 
129  Type *GVType = GV->getValueType();
130  unsigned GVAlignment = GV->getAlignment();
131  if (!GVAlignment) {
132  // When LLVM IL declares a variable without alignment, use
133  // the ABI default alignment for the type.
134  GVAlignment = DL.getABITypeAlignment(GVType);
135  }
136 
137  // Define "__emutls_t.*" if there is InitValue
138  GlobalVariable *EmuTlsTmplVar = nullptr;
139  if (InitValue) {
140  std::string EmuTlsTmplName = ("__emutls_t." + GV->getName()).str();
141  EmuTlsTmplVar = dyn_cast_or_null<GlobalVariable>(
142  M.getOrInsertGlobal(EmuTlsTmplName, GVType));
143  assert(EmuTlsTmplVar && "Failed to create emualted TLS initializer");
144  EmuTlsTmplVar->setConstant(true);
145  EmuTlsTmplVar->setInitializer(const_cast<Constant*>(InitValue));
146  EmuTlsTmplVar->setAlignment(GVAlignment);
147  copyLinkageVisibility(M, GV, EmuTlsTmplVar);
148  }
149 
150  // Define "__emutls_v.*" with initializer and alignment.
151  Constant *ElementValues[4] = {
152  ConstantInt::get(WordType, DL.getTypeStoreSize(GVType)),
153  ConstantInt::get(WordType, GVAlignment),
154  NullPtr, EmuTlsTmplVar ? EmuTlsTmplVar : NullPtr
155  };
156  ArrayRef<Constant*> ElementValueArray(ElementValues, 4);
157  EmuTlsVar->setInitializer(
158  ConstantStruct::get(EmuTlsVarType, ElementValueArray));
159  unsigned MaxAlignment = std::max(
160  DL.getABITypeAlignment(WordType),
161  DL.getABITypeAlignment(VoidPtrType));
162  EmuTlsVar->setAlignment(MaxAlignment);
163  return true;
164 }
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:231
uint64_t CallInst * C
unsigned getAlignment() const
Definition: GlobalObject.h:59
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:109
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:63
const GlobalVariable * getNamedGlobal(StringRef Name) const
Return the global variable in the module with the specified name, of arbitrary type.
Definition: Module.h:383
void initializeLowerEmuTLSPass(PassRegistry &)
void setAlignment(unsigned Align)
Definition: Globals.cpp:111
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:361
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
Definition: Globals.cpp:340
Class to represent struct types.
Definition: DerivedTypes.h:201
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:237
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:245
void setComdat(Comdat *C)
Definition: GlobalObject.h:103
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
LinkageTypes getLinkage() const
Definition: GlobalValue.h:441
Class to represent pointers.
Definition: DerivedTypes.h:467
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space...
Definition: DataLayout.cpp:702
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
Definition: Constants.cpp:1306
VisibilityTypes getVisibility() const
Definition: GlobalValue.h:225
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
Constant * getOrInsertGlobal(StringRef Name, Type *Ty)
Look up the specified global in the module symbol table.
Definition: Module.cpp:202
This is an important base class in LLVM.
Definition: Constant.h:42
static Constant * get(StructType *T, ArrayRef< Constant *> V)
Definition: Constants.cpp:949
Class to represent integer types.
Definition: DerivedTypes.h:40
void setConstant(bool Val)
Comdat * getOrInsertComdat(StringRef Name)
Return the Comdat in the module with the specified name.
Definition: Module.cpp:467
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:220
ModulePass * createLowerEmuTLSPass()
LowerEmuTLS - This pass generates __emutls_[vt].xyz variables for all TLS variables for the emulated ...
INITIALIZE_PASS(LowerEmuTLS, DEBUG_TYPE, "Add __emutls_[vt]. variables for emultated TLS model", false, false) ModulePass *llvm
Definition: LowerEmuTLS.cpp:56
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the generic address space (address sp...
Definition: DerivedTypes.h:482
This is the shared class of boolean and integer constants.
Definition: Constants.h:84
void setSelectionKind(SelectionKind Val)
Definition: Comdat.h:43
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
Module.h This file contains the declarations for the Module class.
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
Definition: DataLayout.cpp:682
const DataFlowGraph & G
Definition: RDFGraph.cpp:211
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:560
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:436
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:398
bool hasComdat() const
Definition: GlobalObject.h:100
const Comdat * getComdat() const
Definition: GlobalObject.h:101
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:220
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:225
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
Definition: Constants.h:193
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
Type * getValueType() const
Definition: GlobalValue.h:267
#define DEBUG_TYPE
Definition: LowerEmuTLS.cpp:27
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
Definition: DataLayout.h:386
bool hasInitializer() const
Definitions have initializers, declarations don&#39;t.
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:424
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:57
iterator_range< global_iterator > globals()
Definition: Module.h:561
This file describes how to lower LLVM code to machine code.
SelectionKind getSelectionKind() const
Definition: Comdat.h:42