21#include "llvm/IR/IntrinsicsXCore.h"
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 {
55char XCoreLowerThreadLocal::ID = 0;
58 "Lower thread local variables",
false,
false)
61 return new XCoreLowerThreadLocal();
65 return ArrayType::get(OriginalType,
MaxThreads);
72 Elements[i] = OriginalInitializer;
83 while (!WUsers.
empty())
85 if (
PHINode *PN = dyn_cast<PHINode>(WU)) {
86 for (
int I = 0, E = PN->getNumIncomingValues();
I < E; ++
I)
87 if (PN->getIncomingValue(
I) == CE) {
95 PN->setOperand(
I, NewInst);
97 }
else if (
Instruction *Instr = dyn_cast<Instruction>(WU)) {
99 NewInst->
insertBefore(*Instr->getParent(), Instr->getIterator());
100 Instr->replaceUsesOfWith(CE, NewInst);
107 }
while (CE->hasNUsesOrMore(1));
109 CE->destroyConstant();
116 if (!isa<Instruction>(U))
118 while (!WUsers.
empty())
129 return AT && (AT->getNumElements() == 0);
150 NewInitializer,
"",
nullptr,
151 GlobalVariable::NotThreadLocal,
161 Intrinsic::xcore_getid);
162 Value *ThreadID = Builder.CreateCall(GetID, {});
164 {Builder.getInt64(0), ThreadID});
165 U->replaceUsesOfWith(GV,
Addr);
174bool XCoreLowerThreadLocal::runOnModule(
Module &M) {
176 bool MadeChange =
false;
182 MadeChange |= lowerGlobal(GV);
This file contains the declarations for the subclasses of Constant, which represent the different fla...
iv Induction Variable Users
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool replaceConstantExprOp(ConstantExpr *CE, Pass *P)
static bool isZeroLengthArray(Type *Ty)
static Constant * createLoweredInitializer(ArrayType *NewType, Constant *OriginalInitializer)
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)
static ArrayType * createLoweredType(Type *OriginalType)
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
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...
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
A constant value that is initialized with an expression using other constant values.
This is an important base class in LLVM.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
LinkageTypes getLinkage() const
Module * getParent()
Get the module that this global value is contained inside of...
PointerType * getType() const
Global values are always pointers.
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool isExternallyInitialized() const
bool hasInitializer() const
Definitions have initializers, declarations don't.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
LLVM Value Representation.
iterator_range< user_iterator > users()
void takeName(Value *V)
Transfer the name from V to this value.
Value handle that is nullable, but tries to track the Value.
self_iterator getIterator()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto unique(Range &&R, Predicate P)
void sort(IteratorTy Start, IteratorTy End)
void initializeXCoreLowerThreadLocalPass(PassRegistry &p)
ModulePass * createXCoreLowerThreadLocalPass()
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...