Go to the documentation of this file.
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 {
51 bool runOnModule(
Module &M)
override;
58 "Lower thread local variables",
false,
false)
61 return new XCoreLowerThreadLocal();
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) {
92 Instruction *NewInst = CE->getAsInstruction(InsertPos);
93 PN->setOperand(
I, NewInst);
95 }
else if (
Instruction *Instr = dyn_cast<Instruction>(WU)) {
97 Instr->replaceUsesOfWith(CE, NewInst);
104 }
while (CE->hasNUsesOrMore(1));
106 CE->destroyConstant();
113 if (!isa<Instruction>(U))
115 while (!WUsers.empty())
147 NewInitializer,
"",
nullptr,
154 for (
unsigned I = 0,
E =
Users.size();
I !=
E; ++
I) {
159 Intrinsic::xcore_getid);
162 {Builder.getInt64(0), ThreadID});
172 bool XCoreLowerThreadLocal::runOnModule(
Module &M) {
174 bool MadeChange =
false;
178 ThreadLocalGlobals.push_back(&GV);
179 for (
unsigned I = 0,
E = ThreadLocalGlobals.size();
I !=
E; ++
I) {
180 MadeChange |= lowerGlobal(ThreadLocalGlobals[
I]);
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
This is an optimization pass for GlobalISel generic memory operations.
iterator erase(const_iterator CI)
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Value handle that is nullable, but tries to track the Value.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
const Function * getParent() const
Return the enclosing method, or null if none.
LinkageTypes getLinkage() const
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
static bool rewriteNonInstructionUses(GlobalVariable *GV, Pass *P)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool isExternallyInitialized() const
unsigned getAddressSpace() const
Return the address space of the Pointer type.
static ArrayType * createLoweredType(Type *OriginalType)
The instances of the Type class are immutable: once they are created, they are never changed.
Class to represent array types.
bool hasInitializer() const
Definitions have initializers, declarations don't.
LLVM Basic Block Representation.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
uint64_t getNumElements() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
void sort(IteratorTy Start, IteratorTy End)
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This is an important base class in LLVM.
Module * getParent()
Get the module that this global value is contained inside of...
static bool replaceConstantExprOp(ConstantExpr *CE, Pass *P)
initializer< Ty > init(const Ty &Val)
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void initializeXCoreLowerThreadLocalPass(PassRegistry &p)
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
A Module instance is used to store all the information related to an LLVM module.
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 isZeroLengthArray(Type *Ty)
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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...
A constant value that is initialized with an expression using other constant values.
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
ModulePass * createXCoreLowerThreadLocalPass()
Pass interface - Implemented by all 'passes'.
static Constant * createLoweredInitializer(ArrayType *NewType, Constant *OriginalInitializer)
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
INITIALIZE_PASS(XCoreLowerThreadLocal, "xcore-lower-thread-local", "Lower thread local variables", false, false) ModulePass *llvm
iv Induction Variable Users
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...
PointerType * getType() const
Global values are always pointers.
Type * getValueType() const
void takeName(Value *V)
Transfer the name from V to this value.
LLVM Value Representation.
iterator_range< user_iterator > users()