Thanks to visit codestin.com
Credit goes to llvm.org

LLVM 22.0.0git
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
21#include "llvm/CodeGen/Passes.h"
23#include "llvm/IR/Constants.h"
24#include "llvm/IR/Module.h"
26#include "llvm/Pass.h"
28
29using namespace llvm;
30
31#define DEBUG_TYPE "lower-emutls"
32
33namespace {
34
35class LowerEmuTLS : public ModulePass {
36public:
37 static char ID; // Pass identification, replacement for typeid
38 LowerEmuTLS() : ModulePass(ID) {
40 }
41
42 bool runOnModule(Module &M) override;
43};
44}
45
46static bool addEmuTlsVar(Module &M, const GlobalVariable *GV);
47
48static void copyLinkageVisibility(Module &M, const GlobalVariable *from,
49 GlobalVariable *to) {
50 to->setLinkage(from->getLinkage());
51 to->setVisibility(from->getVisibility());
52 to->setDSOLocal(from->isDSOLocal());
53 if (from->hasComdat()) {
54 to->setComdat(M.getOrInsertComdat(to->getName()));
56 }
57}
58
60 bool Changed = false;
62 for (const auto &G : M.globals()) {
63 if (G.isThreadLocal())
64 TlsVars.push_back(&G);
65 }
66 for (const auto *G : TlsVars)
67 Changed |= addEmuTlsVar(M, G);
68
69 if (!Changed)
72 PA.abandon<GlobalsAA>();
75 return PA;
76}
77
78char LowerEmuTLS::ID = 0;
79
81 "Add __emutls_[vt]. variables for emultated TLS model", false,
82 false)
83
84ModulePass *llvm::createLowerEmuTLSPass() { return new LowerEmuTLS(); }
85
86bool LowerEmuTLS::runOnModule(Module &M) {
87 if (skipModule(M))
88 return false;
89
90 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
91 if (!TPC)
92 return false;
93
94 auto &TM = TPC->getTM<TargetMachine>();
95 if (!TM.useEmulatedTLS())
96 return false;
97
98 bool Changed = false;
100 for (const auto &G : M.globals()) {
101 if (G.isThreadLocal())
102 TlsVars.append({&G});
103 }
104 for (const auto *const G : TlsVars)
105 Changed |= addEmuTlsVar(M, G);
106 return Changed;
107}
108
109bool addEmuTlsVar(Module &M, const GlobalVariable *GV) {
110 LLVMContext &C = M.getContext();
111 PointerType *VoidPtrType = PointerType::getUnqual(C);
112
113 std::string EmuTlsVarName = ("__emutls_v." + GV->getName()).str();
114 GlobalVariable *EmuTlsVar = M.getNamedGlobal(EmuTlsVarName);
115 if (EmuTlsVar)
116 return false; // It has been added before.
117
118 const DataLayout &DL = M.getDataLayout();
119 Constant *NullPtr = ConstantPointerNull::get(VoidPtrType);
120
121 // Get non-zero initializer from GV's initializer.
122 const Constant *InitValue = nullptr;
123 if (GV->hasInitializer()) {
124 InitValue = GV->getInitializer();
125 const ConstantInt *InitIntValue = dyn_cast<ConstantInt>(InitValue);
126 // When GV's init value is all 0, omit the EmuTlsTmplVar and let
127 // the emutls library function to reset newly allocated TLS variables.
128 if (isa<ConstantAggregateZero>(InitValue) ||
129 (InitIntValue && InitIntValue->isZero()))
130 InitValue = nullptr;
131 }
132
133 // Create the __emutls_v. symbol, whose type has 4 fields:
134 // word size; // size of GV in bytes
135 // word align; // alignment of GV
136 // void *ptr; // initialized to 0; set at run time per thread.
137 // void *templ; // 0 or point to __emutls_t.*
138 // sizeof(word) should be the same as sizeof(void*) on target.
139 IntegerType *WordType = DL.getIntPtrType(C);
140 PointerType *InitPtrType = PointerType::getUnqual(C);
141 Type *ElementTypes[4] = {WordType, WordType, VoidPtrType, InitPtrType};
142 StructType *EmuTlsVarType = StructType::create(ElementTypes);
143 EmuTlsVar = M.getOrInsertGlobal(EmuTlsVarName, EmuTlsVarType);
144 copyLinkageVisibility(M, GV, EmuTlsVar);
145
146 // Define "__emutls_t.*" and "__emutls_v.*" only if GV is defined.
147 if (!GV->hasInitializer())
148 return true;
149
150 Type *GVType = GV->getValueType();
151 Align GVAlignment = DL.getValueOrABITypeAlignment(GV->getAlign(), GVType);
152
153 // Define "__emutls_t.*" if there is InitValue
154 GlobalVariable *EmuTlsTmplVar = nullptr;
155 if (InitValue) {
156 std::string EmuTlsTmplName = ("__emutls_t." + GV->getName()).str();
157 EmuTlsTmplVar = M.getOrInsertGlobal(EmuTlsTmplName, GVType);
158 assert(EmuTlsTmplVar && "Failed to create emualted TLS initializer");
159 EmuTlsTmplVar->setConstant(true);
160 EmuTlsTmplVar->setInitializer(const_cast<Constant*>(InitValue));
161 EmuTlsTmplVar->setAlignment(GVAlignment);
162 copyLinkageVisibility(M, GV, EmuTlsTmplVar);
163 }
164
165 // Define "__emutls_v.*" with initializer and alignment.
166 Constant *ElementValues[4] = {
167 ConstantInt::get(WordType, DL.getTypeStoreSize(GVType)),
168 ConstantInt::get(WordType, GVAlignment.value()), NullPtr,
169 EmuTlsTmplVar ? EmuTlsTmplVar : NullPtr};
170 EmuTlsVar->setInitializer(ConstantStruct::get(EmuTlsVarType, ElementValues));
171 Align MaxAlignment =
172 std::max(DL.getABITypeAlign(WordType), DL.getABITypeAlign(VoidPtrType));
173 EmuTlsVar->setAlignment(MaxAlignment);
174 return true;
175}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define DEBUG_TYPE
This is the interface for a simple mod/ref and alias analysis over globals.
Module.h This file contains the declarations for the Module class.
static void copyLinkageVisibility(Module &M, const GlobalVariable *from, GlobalVariable *to)
static bool addEmuTlsVar(Module &M, const GlobalVariable *GV)
#define G(x, y, z)
Definition MD5.cpp:56
This is the interface to build a ModuleSummaryIndex for a module.
ModuleAnalysisManager MAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file defines the SmallVector class.
Target-Independent Code Generator Pass Configuration Options pass.
void setSelectionKind(SelectionKind Val)
Definition Comdat.h:48
SelectionKind getSelectionKind() const
Definition Comdat.h:47
This is the shared class of boolean and integer constants.
Definition Constants.h:87
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
Definition Constants.h:214
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
Definition Constant.h:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
LLVM_ABI void setComdat(Comdat *C)
Definition Globals.cpp:214
bool hasComdat() const
const Comdat * getComdat() const
bool isDSOLocal() const
VisibilityTypes getVisibility() const
LinkageTypes getLinkage() const
void setLinkage(LinkageTypes LT)
void setDSOLocal(bool Local)
void setVisibility(VisibilityTypes V)
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
Definition Globals.cpp:523
bool hasInitializer() const
Definitions have initializers, declarations don't.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
void setConstant(bool Val)
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
Analysis pass providing a never-invalidated alias analysis result.
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition Pass.h:255
Analysis pass to provide the ModuleSummaryIndex object.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Definition Analysis.h:171
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This pass performs the global (interprocedural) stack safety analysis (new pass manager).
Class to represent struct types.
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition Type.cpp:620
Primary interface to the complete machine description for the target machine.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:322
Changed
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
LLVM_ABI void initializeLowerEmuTLSPass(PassRegistry &)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
LLVM_ABI ModulePass * createLowerEmuTLSPass()
LowerEmuTLS - This pass generates __emutls_[vt].xyz variables for all TLS variables for the emulated ...
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:85