LLVM  10.0.0svn
LowerEmuTLS.cpp
Go to the documentation of this file.
1 //===- LowerEmuTLS.cpp - Add __emutls_[vt].* variables --------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This transformation is required for targets depending on libgcc style
10 // emulated thread local storage variables. For every defined TLS variable xyz,
11 // an __emutls_v.xyz is generated. If there is non-zero initialized value
12 // an __emutls_t.xyz is also generated.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/CodeGen/Passes.h"
20 #include "llvm/IR/LLVMContext.h"
21 #include "llvm/IR/Module.h"
22 #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 public:
32  static char ID; // Pass identification, replacement for typeid
33  LowerEmuTLS() : ModulePass(ID) {
35  }
36 
37  bool runOnModule(Module &M) override;
38 private:
39  bool addEmuTlsVar(Module &M, const GlobalVariable *GV);
40  static void copyLinkageVisibility(Module &M,
41  const GlobalVariable *from,
42  GlobalVariable *to) {
43  to->setLinkage(from->getLinkage());
44  to->setVisibility(from->getVisibility());
45  if (from->hasComdat()) {
46  to->setComdat(M.getOrInsertComdat(to->getName()));
48  }
49  }
50 };
51 }
52 
53 char LowerEmuTLS::ID = 0;
54 
56  "Add __emutls_[vt]. variables for emultated TLS model", false,
57  false)
58 
59 ModulePass *llvm::createLowerEmuTLSPass() { return new LowerEmuTLS(); }
60 
61 bool LowerEmuTLS::runOnModule(Module &M) {
62  if (skipModule(M))
63  return false;
64 
65  auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
66  if (!TPC)
67  return false;
68 
69  auto &TM = TPC->getTM<TargetMachine>();
70  if (!TM.useEmulatedTLS())
71  return false;
72 
73  bool Changed = false;
75  for (const auto &G : M.globals()) {
76  if (G.isThreadLocal())
77  TlsVars.append({&G});
78  }
79  for (const auto G : TlsVars)
80  Changed |= addEmuTlsVar(M, G);
81  return Changed;
82 }
83 
84 bool LowerEmuTLS::addEmuTlsVar(Module &M, const GlobalVariable *GV) {
85  LLVMContext &C = M.getContext();
86  PointerType *VoidPtrType = Type::getInt8PtrTy(C);
87 
88  std::string EmuTlsVarName = ("__emutls_v." + GV->getName()).str();
89  GlobalVariable *EmuTlsVar = M.getNamedGlobal(EmuTlsVarName);
90  if (EmuTlsVar)
91  return false; // It has been added before.
92 
93  const DataLayout &DL = M.getDataLayout();
94  Constant *NullPtr = ConstantPointerNull::get(VoidPtrType);
95 
96  // Get non-zero initializer from GV's initializer.
97  const Constant *InitValue = nullptr;
98  if (GV->hasInitializer()) {
99  InitValue = GV->getInitializer();
100  const ConstantInt *InitIntValue = dyn_cast<ConstantInt>(InitValue);
101  // When GV's init value is all 0, omit the EmuTlsTmplVar and let
102  // the emutls library function to reset newly allocated TLS variables.
103  if (isa<ConstantAggregateZero>(InitValue) ||
104  (InitIntValue && InitIntValue->isZero()))
105  InitValue = nullptr;
106  }
107 
108  // Create the __emutls_v. symbol, whose type has 4 fields:
109  // word size; // size of GV in bytes
110  // word align; // alignment of GV
111  // void *ptr; // initialized to 0; set at run time per thread.
112  // void *templ; // 0 or point to __emutls_t.*
113  // sizeof(word) should be the same as sizeof(void*) on target.
114  IntegerType *WordType = DL.getIntPtrType(C);
115  PointerType *InitPtrType = InitValue ?
116  PointerType::getUnqual(InitValue->getType()) : VoidPtrType;
117  Type *ElementTypes[4] = {WordType, WordType, VoidPtrType, InitPtrType};
118  ArrayRef<Type*> ElementTypeArray(ElementTypes, 4);
119  StructType *EmuTlsVarType = StructType::create(ElementTypeArray);
120  EmuTlsVar = cast<GlobalVariable>(
121  M.getOrInsertGlobal(EmuTlsVarName, EmuTlsVarType));
122  copyLinkageVisibility(M, GV, EmuTlsVar);
123 
124  // Define "__emutls_t.*" and "__emutls_v.*" only if GV is defined.
125  if (!GV->hasInitializer())
126  return true;
127 
128  Type *GVType = GV->getValueType();
129  unsigned GVAlignment = GV->getAlignment();
130  if (!GVAlignment) {
131  // When LLVM IL declares a variable without alignment, use
132  // the ABI default alignment for the type.
133  GVAlignment = DL.getABITypeAlignment(GVType);
134  }
135 
136  // Define "__emutls_t.*" if there is InitValue
137  GlobalVariable *EmuTlsTmplVar = nullptr;
138  if (InitValue) {
139  std::string EmuTlsTmplName = ("__emutls_t." + GV->getName()).str();
140  EmuTlsTmplVar = dyn_cast_or_null<GlobalVariable>(
141  M.getOrInsertGlobal(EmuTlsTmplName, GVType));
142  assert(EmuTlsTmplVar && "Failed to create emualted TLS initializer");
143  EmuTlsTmplVar->setConstant(true);
144  EmuTlsTmplVar->setInitializer(const_cast<Constant*>(InitValue));
145  EmuTlsTmplVar->setAlignment(GVAlignment);
146  copyLinkageVisibility(M, GV, EmuTlsTmplVar);
147  }
148 
149  // Define "__emutls_v.*" with initializer and alignment.
150  Constant *ElementValues[4] = {
151  ConstantInt::get(WordType, DL.getTypeStoreSize(GVType)),
152  ConstantInt::get(WordType, GVAlignment),
153  NullPtr, EmuTlsTmplVar ? EmuTlsTmplVar : NullPtr
154  };
155  ArrayRef<Constant*> ElementValueArray(ElementValues, 4);
156  EmuTlsVar->setInitializer(
157  ConstantStruct::get(EmuTlsVarType, ElementValueArray));
158  unsigned MaxAlignment = std::max(
159  DL.getABITypeAlignment(WordType),
160  DL.getABITypeAlignment(VoidPtrType));
161  EmuTlsVar->setAlignment(MaxAlignment);
162  return true;
163 }
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:242
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:111
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.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
const GlobalVariable * getNamedGlobal(StringRef Name) const
Return the global variable in the module with the specified name, of arbitrary type.
Definition: Module.h:405
void initializeLowerEmuTLSPass(PassRegistry &)
void setAlignment(unsigned Align)
FIXME: Remove this setter once the migration to MaybeAlign is over.
Definition: Globals.cpp:116
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:369
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
Definition: Globals.cpp:388
Class to represent struct types.
Definition: DerivedTypes.h:233
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:244
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:245
void setComdat(Comdat *C)
Definition: GlobalObject.h:107
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
LinkageTypes getLinkage() const
Definition: GlobalValue.h:460
Class to represent pointers.
Definition: DerivedTypes.h:544
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:772
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
Definition: Constants.cpp:1419
VisibilityTypes getVisibility() const
Definition: GlobalValue.h:236
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:64
This is an important base class in LLVM.
Definition: Constant.h:41
static Constant * get(StructType *T, ArrayRef< Constant *> V)
Definition: Constants.cpp:1062
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:482
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:219
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:55
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:559
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
void setSelectionKind(SelectionKind Val)
Definition: Comdat.h:45
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
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:752
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
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:640
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:454
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:387
bool hasComdat() const
Definition: GlobalObject.h:104
const Comdat * getComdat() const
Definition: GlobalObject.h:105
Constant * getOrInsertGlobal(StringRef Name, Type *Ty, function_ref< GlobalVariable *()> CreateGlobalCallback)
Look up the specified global in the module symbol table.
Definition: Module.cpp:204
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:224
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
Definition: Constants.h:192
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:332
Type * getValueType() const
Definition: GlobalValue.h:279
#define DEBUG_TYPE
Definition: LowerEmuTLS.cpp:26
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:445
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:436
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:65
iterator_range< global_iterator > globals()
Definition: Module.h:587
This file describes how to lower LLVM code to machine code.
SelectionKind getSelectionKind() const
Definition: Comdat.h:44