29 #define DEBUG_TYPE "xcore-lower-thread-local" 35 cl::desc(
"Maximum number of threads (for emulation thread-local storage)"),
42 struct XCoreLowerThreadLocal :
public ModulePass {
51 bool runOnModule(
Module &M)
override;
58 "Lower thread local variables",
false,
false)
61 return new XCoreLowerThreadLocal();
72 Elements[i] = OriginalInitializer;
82 case Instruction::GetElementPtr: {
86 cast<GEPOperator>(CE)->getSourceElementType(), CEOps[0],
90 case Instruction::Sub:
91 case Instruction::Mul:
92 case Instruction::UDiv:
93 case Instruction::SDiv:
94 case Instruction::FDiv:
95 case Instruction::URem:
96 case Instruction::SRem:
97 case Instruction::FRem:
98 case Instruction::Shl:
99 case Instruction::LShr:
100 case Instruction::AShr:
101 case Instruction::And:
102 case Instruction::Or:
103 case Instruction::Xor:
108 case Instruction::Trunc:
109 case Instruction::ZExt:
110 case Instruction::SExt:
111 case Instruction::FPToUI:
112 case Instruction::FPToSI:
113 case Instruction::UIToFP:
114 case Instruction::SIToFP:
115 case Instruction::FPTrunc:
116 case Instruction::FPExt:
117 case Instruction::PtrToInt:
118 case Instruction::IntToPtr:
119 case Instruction::BitCast:
133 WUsers.erase(std::unique(WUsers.begin(), WUsers.end()), WUsers.end());
134 while (!WUsers.empty())
136 if (
PHINode *PN = dyn_cast<PHINode>(WU)) {
137 for (
int I = 0,
E = PN->getNumIncomingValues();
I <
E; ++
I)
138 if (PN->getIncomingValue(
I) == CE) {
144 PN->setOperand(
I, NewInst);
146 }
else if (
Instruction *Instr = dyn_cast<Instruction>(WU)) {
148 Instr->replaceUsesOfWith(CE, NewInst);
164 if (!isa<Instruction>(U))
166 while (!WUsers.
empty())
198 NewInitializer,
"",
nullptr,
205 for (
unsigned I = 0,
E =
Users.size();
I !=
E; ++
I) {
211 Value *ThreadID = Builder.CreateCall(GetID, {});
213 {Builder.getInt64(0), ThreadID});
223 bool XCoreLowerThreadLocal::runOnModule(
Module &M) {
225 bool MadeChange =
false;
230 for (
unsigned I = 0,
E = ThreadLocalGlobals.
size();
I !=
E; ++
I) {
231 MadeChange |= lowerGlobal(ThreadLocalGlobals[
I]);
Pass interface - Implemented by all 'passes'.
Value * CreateInBoundsGEP(Value *Ptr, ArrayRef< Value *> IdxList, const Twine &Name="")
unsigned getOpcode() const
Return the opcode at the root of this constant expression.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module. ...
bool isSized(SmallPtrSetImpl< Type *> *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
void push_back(const T &Elt)
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
iv Induction Variable Users
void initializeXCoreLowerThreadLocalPass(PassRegistry &p)
static Constant * get(ArrayType *T, ArrayRef< Constant *> V)
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Split the edge connecting specified block.
ModulePass * createXCoreLowerThreadLocalPass()
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
uint64_t getNumElements() const
A constant value that is initialized with an expression using other constant values.
Type * getType() const
All values are typed, get the type of this value.
Value handle that is nullable, but tries to track the Value.
Class to represent array types.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
LinkageTypes getLinkage() const
INITIALIZE_PASS(XCoreLowerThreadLocal, "xcore-lower-thread-local", "Lower thread local variables", false, false) ModulePass *llvm
void takeName(Value *V)
Transfer the name from V to this value.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
Value * getOperand(unsigned i) const
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
initializer< Ty > init(const Ty &Val)
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N users or more.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
static bool isZeroLengthArray(Type *Ty)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it...
unsigned getAddressSpace() const
Return the address space of the Pointer type.
static Instruction * createReplacementInstr(ConstantExpr *CE, Instruction *Instr)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static ArrayType * createLoweredType(Type *OriginalType)
void sort(IteratorTy Start, IteratorTy End)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
LLVM_NODISCARD T pop_back_val()
static bool replaceConstantExprOp(ConstantExpr *CE, Pass *P)
iterator_range< user_iterator > users()
LLVM_NODISCARD bool empty() const
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static Constant * createLoweredInitializer(ArrayType *NewType, Constant *OriginalInitializer)
Type * getValueType() const
void destroyConstant()
Called if some element of this constant is no longer valid.
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
user_iterator user_begin()
static cl::opt< unsigned > MaxThreads("xcore-max-threads", cl::Optional, cl::desc("Maximum number of threads (for emulation thread-local storage)"), cl::Hidden, cl::value_desc("number"), cl::init(8))
static bool rewriteNonInstructionUses(GlobalVariable *GV, Pass *P)
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
bool hasInitializer() const
Definitions have initializers, declarations don't.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
iterator_range< global_iterator > globals()
bool isExternallyInitialized() const
PointerType * getType() const
Global values are always pointers.