LLVM  6.0.0svn
XCoreLowerThreadLocal.cpp
Go to the documentation of this file.
1 //===-- XCoreLowerThreadLocal - Lower thread local variables --------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file contains a pass that lowers thread local variables on the
12 /// XCore.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "XCore.h"
17 #include "llvm/IR/Constants.h"
18 #include "llvm/IR/DerivedTypes.h"
19 #include "llvm/IR/GlobalVariable.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/IR/Intrinsics.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/IR/NoFolder.h"
24 #include "llvm/IR/ValueHandle.h"
25 #include "llvm/Pass.h"
28 
29 #define DEBUG_TYPE "xcore-lower-thread-local"
30 
31 using namespace llvm;
32 
34  "xcore-max-threads", cl::Optional,
35  cl::desc("Maximum number of threads (for emulation thread-local storage)"),
36  cl::Hidden, cl::value_desc("number"), cl::init(8));
37 
38 namespace {
39  /// Lowers thread local variables on the XCore. Each thread local variable is
40  /// expanded to an array of n elements indexed by the thread ID where n is the
41  /// fixed number hardware threads supported by the device.
42  struct XCoreLowerThreadLocal : public ModulePass {
43  static char ID;
44 
45  XCoreLowerThreadLocal() : ModulePass(ID) {
47  }
48 
49  bool lowerGlobal(GlobalVariable *GV);
50 
51  bool runOnModule(Module &M) override;
52  };
53 }
54 
56 
57 INITIALIZE_PASS(XCoreLowerThreadLocal, "xcore-lower-thread-local",
58  "Lower thread local variables", false, false)
59 
61  return new XCoreLowerThreadLocal();
62 }
63 
64 static ArrayType *createLoweredType(Type *OriginalType) {
65  return ArrayType::get(OriginalType, MaxThreads);
66 }
67 
68 static Constant *
69 createLoweredInitializer(ArrayType *NewType, Constant *OriginalInitializer) {
71  for (unsigned i = 0; i != MaxThreads; ++i) {
72  Elements[i] = OriginalInitializer;
73  }
74  return ConstantArray::get(NewType, Elements);
75 }
76 
77 static Instruction *
79  IRBuilder<NoFolder> Builder(Instr);
80  unsigned OpCode = CE->getOpcode();
81  switch (OpCode) {
82  case Instruction::GetElementPtr: {
83  SmallVector<Value *,4> CEOpVec(CE->op_begin(), CE->op_end());
84  ArrayRef<Value *> CEOps(CEOpVec);
85  return dyn_cast<Instruction>(Builder.CreateInBoundsGEP(
86  cast<GEPOperator>(CE)->getSourceElementType(), CEOps[0],
87  CEOps.slice(1)));
88  }
89  case Instruction::Add:
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:
104  return dyn_cast<Instruction>(
105  Builder.CreateBinOp((Instruction::BinaryOps)OpCode,
106  CE->getOperand(0), CE->getOperand(1),
107  CE->getName()));
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:
120  return dyn_cast<Instruction>(
121  Builder.CreateCast((Instruction::CastOps)OpCode,
122  CE->getOperand(0), CE->getType(),
123  CE->getName()));
124  default:
125  llvm_unreachable("Unhandled constant expression!\n");
126  }
127 }
128 
130  do {
132  std::sort(WUsers.begin(), WUsers.end());
133  WUsers.erase(std::unique(WUsers.begin(), WUsers.end()), WUsers.end());
134  while (!WUsers.empty())
135  if (WeakTrackingVH WU = WUsers.pop_back_val()) {
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) {
139  BasicBlock *PredBB = PN->getIncomingBlock(I);
140  if (PredBB->getTerminator()->getNumSuccessors() > 1)
141  PredBB = SplitEdge(PredBB, PN->getParent());
142  Instruction *InsertPos = PredBB->getTerminator();
143  Instruction *NewInst = createReplacementInstr(CE, InsertPos);
144  PN->setOperand(I, NewInst);
145  }
146  } else if (Instruction *Instr = dyn_cast<Instruction>(WU)) {
147  Instruction *NewInst = createReplacementInstr(CE, Instr);
148  Instr->replaceUsesOfWith(CE, NewInst);
149  } else {
150  ConstantExpr *CExpr = dyn_cast<ConstantExpr>(WU);
151  if (!CExpr || !replaceConstantExprOp(CExpr, P))
152  return false;
153  }
154  }
155  } while (CE->hasNUsesOrMore(1)); // We need to check because a recursive
156  // sibling may have used 'CE' when createReplacementInstr was called.
157  CE->destroyConstant();
158  return true;
159 }
160 
163  for (User *U : GV->users())
164  if (!isa<Instruction>(U))
165  WUsers.push_back(WeakTrackingVH(U));
166  while (!WUsers.empty())
167  if (WeakTrackingVH WU = WUsers.pop_back_val()) {
169  if (!CE || !replaceConstantExprOp(CE, P))
170  return false;
171  }
172  return true;
173 }
174 
175 static bool isZeroLengthArray(Type *Ty) {
176  ArrayType *AT = dyn_cast<ArrayType>(Ty);
177  return AT && (AT->getNumElements() == 0);
178 }
179 
180 bool XCoreLowerThreadLocal::lowerGlobal(GlobalVariable *GV) {
181  Module *M = GV->getParent();
182  if (!GV->isThreadLocal())
183  return false;
184 
185  // Skip globals that we can't lower and leave it for the backend to error.
186  if (!rewriteNonInstructionUses(GV, this) ||
187  !GV->getType()->isSized() || isZeroLengthArray(GV->getType()))
188  return false;
189 
190  // Create replacement global.
191  ArrayType *NewType = createLoweredType(GV->getValueType());
192  Constant *NewInitializer = nullptr;
193  if (GV->hasInitializer())
194  NewInitializer = createLoweredInitializer(NewType,
195  GV->getInitializer());
196  GlobalVariable *NewGV =
197  new GlobalVariable(*M, NewType, GV->isConstant(), GV->getLinkage(),
198  NewInitializer, "", nullptr,
200  GV->getType()->getAddressSpace(),
202 
203  // Update uses.
205  for (unsigned I = 0, E = Users.size(); I != E; ++I) {
206  User *U = Users[I];
207  Instruction *Inst = cast<Instruction>(U);
208  IRBuilder<> Builder(Inst);
210  Intrinsic::xcore_getid);
211  Value *ThreadID = Builder.CreateCall(GetID, {});
212  Value *Addr = Builder.CreateInBoundsGEP(NewGV->getValueType(), NewGV,
213  {Builder.getInt64(0), ThreadID});
214  U->replaceUsesOfWith(GV, Addr);
215  }
216 
217  // Remove old global.
218  NewGV->takeName(GV);
219  GV->eraseFromParent();
220  return true;
221 }
222 
223 bool XCoreLowerThreadLocal::runOnModule(Module &M) {
224  // Find thread local globals.
225  bool MadeChange = false;
226  SmallVector<GlobalVariable *, 16> ThreadLocalGlobals;
227  for (GlobalVariable &GV : M.globals())
228  if (GV.isThreadLocal())
229  ThreadLocalGlobals.push_back(&GV);
230  for (unsigned I = 0, E = ThreadLocalGlobals.size(); I != E; ++I) {
231  MadeChange |= lowerGlobal(ThreadLocalGlobals[I]);
232  }
233  return MadeChange;
234 }
Pass interface - Implemented by all &#39;passes&#39;.
Definition: Pass.h:81
Value * CreateInBoundsGEP(Value *Ptr, ArrayRef< Value *> IdxList, const Twine &Name="")
Definition: IRBuilder.h:1244
unsigned getOpcode() const
Return the opcode at the root of this constant expression.
Definition: Constants.h:1171
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)
Definition: IRBuilder.h:1112
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:63
bool isSized(SmallPtrSetImpl< Type *> *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:262
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
iv Induction Variable Users
Definition: IVUsers.cpp:51
void initializeXCoreLowerThreadLocalPass(PassRegistry &p)
op_iterator op_begin()
Definition: User.h:214
static Constant * get(ArrayType *T, ArrayRef< Constant *> V)
Definition: Constants.cpp:888
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...
Definition: IRBuilder.h:668
uint64_t getNumElements() const
Definition: DerivedTypes.h:359
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:862
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:245
Value handle that is nullable, but tries to track the Value.
Definition: ValueHandle.h:182
Class to represent array types.
Definition: DerivedTypes.h:369
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
LinkageTypes getLinkage() const
Definition: GlobalValue.h:441
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.
Definition: Value.cpp:292
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:980
Value * getOperand(unsigned i) const
Definition: User.h:154
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition: User.cpp:22
#define P(N)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:406
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N users or more.
Definition: Value.cpp:136
LLVM Basic Block Representation.
Definition: BasicBlock.h:59
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
static bool isZeroLengthArray(Type *Ty)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
Definition: Constant.h:42
This file contains the declarations for the subclasses of Constant, which represent the different fla...
void eraseFromParent()
eraseFromParent - This method unlinks &#39;this&#39; from the containing module and deletes it...
Definition: Globals.cpp:336
op_iterator op_end()
Definition: User.h:216
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:495
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)
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
Module.h This file contains the declarations for the Module class.
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:385
static bool replaceConstantExprOp(ConstantExpr *CE, Pass *P)
iterator_range< user_iterator > users()
Definition: Value.h:401
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:220
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:108
#define I(x, y, z)
Definition: MD5.cpp:58
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:225
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Definition: Type.cpp:568
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:323
static Constant * createLoweredInitializer(ArrayType *NewType, Constant *OriginalInitializer)
Type * getValueType() const
Definition: GlobalValue.h:267
void destroyConstant()
Called if some element of this constant is no longer valid.
Definition: Constants.cpp:300
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1480
user_iterator user_begin()
Definition: Value.h:377
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
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...
Definition: GlobalValue.h:556
LLVM Value Representation.
Definition: Value.h:73
bool hasInitializer() const
Definitions have initializers, declarations don&#39;t.
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
Split the edge connecting specified block.
bool isThreadLocal() const
If the value is "Thread Local", its value isn&#39;t shared by the threads.
Definition: GlobalValue.h:238
iterator_range< global_iterator > globals()
Definition: Module.h:561
void sort(Policy policy, RandomAccessIterator Start, RandomAccessIterator End, const Comparator &Comp=Comparator())
Definition: Parallel.h:199
const TerminatorInst * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:120
bool isExternallyInitialized() const
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:265
user_iterator user_end()
Definition: Value.h:385