LLVM  4.0.0
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"
19 #include "llvm/IR/LLVMContext.h"
20 #include "llvm/IR/Module.h"
21 #include "llvm/Pass.h"
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "loweremutls"
27 
28 namespace {
29 
30 class LowerEmuTLS : public ModulePass {
31  const TargetMachine *TM;
32 public:
33  static char ID; // Pass identification, replacement for typeid
34  explicit LowerEmuTLS() : ModulePass(ID), TM(nullptr) { }
35  explicit LowerEmuTLS(const TargetMachine *TM)
36  : ModulePass(ID), TM(TM) {
38  }
39  bool runOnModule(Module &M) override;
40 private:
41  bool addEmuTlsVar(Module &M, const GlobalVariable *GV);
42  static void copyLinkageVisibility(Module &M,
43  const GlobalVariable *from,
44  GlobalVariable *to) {
45  to->setLinkage(from->getLinkage());
46  to->setVisibility(from->getVisibility());
47  if (from->hasComdat()) {
48  to->setComdat(M.getOrInsertComdat(to->getName()));
50  }
51  }
52 };
53 }
54 
55 char LowerEmuTLS::ID = 0;
56 
57 INITIALIZE_PASS(LowerEmuTLS, "loweremutls",
58  "Add __emutls_[vt]. variables for emultated TLS model",
59  false, false)
60 
62  return new LowerEmuTLS(TM);
63 }
64 
65 bool LowerEmuTLS::runOnModule(Module &M) {
66  if (skipModule(M))
67  return false;
68 
69  if (!TM || !TM->Options.EmulatedTLS)
70  return false;
71 
72  bool Changed = false;
74  for (const auto &G : M.globals()) {
75  if (G.isThreadLocal())
76  TlsVars.append({&G});
77  }
78  for (const auto G : TlsVars)
79  Changed |= addEmuTlsVar(M, G);
80  return Changed;
81 }
82 
83 bool LowerEmuTLS::addEmuTlsVar(Module &M, const GlobalVariable *GV) {
84  LLVMContext &C = M.getContext();
85  PointerType *VoidPtrType = Type::getInt8PtrTy(C);
86 
87  std::string EmuTlsVarName = ("__emutls_v." + GV->getName()).str();
88  GlobalVariable *EmuTlsVar = M.getNamedGlobal(EmuTlsVarName);
89  if (EmuTlsVar)
90  return false; // It has been added before.
91 
92  const DataLayout &DL = M.getDataLayout();
93  Constant *NullPtr = ConstantPointerNull::get(VoidPtrType);
94 
95  // Get non-zero initializer from GV's initializer.
96  const Constant *InitValue = nullptr;
97  if (GV->hasInitializer()) {
98  InitValue = GV->getInitializer();
99  const ConstantInt *InitIntValue = dyn_cast<ConstantInt>(InitValue);
100  // When GV's init value is all 0, omit the EmuTlsTmplVar and let
101  // the emutls library function to reset newly allocated TLS variables.
102  if (isa<ConstantAggregateZero>(InitValue) ||
103  (InitIntValue && InitIntValue->isZero()))
104  InitValue = nullptr;
105  }
106 
107  // Create the __emutls_v. symbol, whose type has 4 fields:
108  // word size; // size of GV in bytes
109  // word align; // alignment of GV
110  // void *ptr; // initialized to 0; set at run time per thread.
111  // void *templ; // 0 or point to __emutls_t.*
112  // sizeof(word) should be the same as sizeof(void*) on target.
113  IntegerType *WordType = DL.getIntPtrType(C);
114  PointerType *InitPtrType = InitValue ?
115  PointerType::getUnqual(InitValue->getType()) : VoidPtrType;
116  Type *ElementTypes[4] = {WordType, WordType, VoidPtrType, InitPtrType};
117  ArrayRef<Type*> ElementTypeArray(ElementTypes, 4);
118  StructType *EmuTlsVarType = StructType::create(ElementTypeArray);
119  EmuTlsVar = cast<GlobalVariable>(
120  M.getOrInsertGlobal(EmuTlsVarName, EmuTlsVarType));
121  copyLinkageVisibility(M, GV, EmuTlsVar);
122 
123  // Define "__emutls_t.*" and "__emutls_v.*" only if GV is defined.
124  if (!GV->hasInitializer())
125  return true;
126 
127  Type *GVType = GV->getValueType();
128  unsigned GVAlignment = GV->getAlignment();
129  if (!GVAlignment) {
130  // When LLVM IL declares a variable without alignment, use
131  // the ABI default alignment for the type.
132  GVAlignment = DL.getABITypeAlignment(GVType);
133  }
134 
135  // Define "__emutls_t.*" if there is InitValue
136  GlobalVariable *EmuTlsTmplVar = nullptr;
137  if (InitValue) {
138  std::string EmuTlsTmplName = ("__emutls_t." + GV->getName()).str();
139  EmuTlsTmplVar = dyn_cast_or_null<GlobalVariable>(
140  M.getOrInsertGlobal(EmuTlsTmplName, GVType));
141  assert(EmuTlsTmplVar && "Failed to create emualted TLS initializer");
142  EmuTlsTmplVar->setConstant(true);
143  EmuTlsTmplVar->setInitializer(const_cast<Constant*>(InitValue));
144  EmuTlsTmplVar->setAlignment(GVAlignment);
145  copyLinkageVisibility(M, GV, EmuTlsTmplVar);
146  }
147 
148  // Define "__emutls_v.*" with initializer and alignment.
149  Constant *ElementValues[4] = {
150  ConstantInt::get(WordType, DL.getTypeStoreSize(GVType)),
151  ConstantInt::get(WordType, GVAlignment),
152  NullPtr, EmuTlsTmplVar ? EmuTlsTmplVar : NullPtr
153  };
154  ArrayRef<Constant*> ElementValueArray(ElementValues, 4);
155  EmuTlsVar->setInitializer(
156  ConstantStruct::get(EmuTlsVarType, ElementValueArray));
157  unsigned MaxAlignment = std::max(
158  DL.getABITypeAlignment(WordType),
159  DL.getABITypeAlignment(VoidPtrType));
160  EmuTlsVar->setAlignment(MaxAlignment);
161  return true;
162 }
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:225
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:102
LinkageTypes getLinkage() const
Definition: GlobalValue.h:429
bool hasComdat() const
Definition: GlobalObject.h:91
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
VisibilityTypes getVisibility() const
Definition: GlobalValue.h:219
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:52
Type * getValueType() const
Definition: GlobalValue.h:261
void initializeLowerEmuTLSPass(PassRegistry &)
void setAlignment(unsigned Align)
Definition: Globals.cpp:86
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:191
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
Definition: Globals.cpp:323
Class to represent struct types.
Definition: DerivedTypes.h:199
unsigned getAlignment() const
Definition: GlobalObject.h:59
void setComdat(Comdat *C)
Definition: GlobalObject.h:94
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
INITIALIZE_PASS(LowerEmuTLS,"loweremutls","Add __emutls_[vt]. variables for emultated TLS model", false, false) ModulePass *llvm
Definition: LowerEmuTLS.cpp:57
Class to represent pointers.
Definition: DerivedTypes.h:443
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:48
Constant * getOrInsertGlobal(StringRef Name, Type *Ty)
Look up the specified global in the module symbol table.
Definition: Module.cpp:225
const Comdat * getComdat() const
Definition: GlobalObject.h:92
This is an important base class in LLVM.
Definition: Constant.h:42
SelectionKind getSelectionKind() const
Definition: Comdat.h:42
Class to represent integer types.
Definition: DerivedTypes.h:39
void setConstant(bool Val)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:392
Comdat * getOrInsertComdat(StringRef Name)
Return the Comdat in the module with the specified name.
Definition: Module.cpp:482
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:709
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
Definition: DataLayout.cpp:689
This is the shared class of boolean and integer constants.
Definition: Constants.h:88
void setSelectionKind(SelectionKind Val)
Definition: Comdat.h:43
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:230
GlobalVariable * getNamedGlobal(StringRef Name)
Return the global variable in the module with the specified name, of arbitrary type.
Definition: Module.h:357
const DataFlowGraph & G
Definition: RDFGraph.cpp:206
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
Definition: Constants.h:198
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:424
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
bool hasInitializer() const
Definitions have initializers, declarations don't.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:384
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:235
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:287
ModulePass * createLowerEmuTLSPass(const TargetMachine *TM)
LowerEmuTLS - This pass generates __emutls_[vt].xyz variables for all TLS variables for the emulated ...
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
Definition: DataLayout.h:391
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
aarch64 promote const
Primary interface to the complete machine description for the target machine.
iterator_range< global_iterator > globals()
Definition: Module.h:524
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:222
This file describes how to lower LLVM code to machine code.