LLVM 22.0.0git
DXILDataScalarization.cpp
Go to the documentation of this file.
1//===- DXILDataScalarization.cpp - Perform DXIL Data Legalization ---------===//
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
10#include "DirectX.h"
12#include "llvm/ADT/STLExtras.h"
15#include "llvm/IR/IRBuilder.h"
16#include "llvm/IR/InstVisitor.h"
18#include "llvm/IR/Module.h"
19#include "llvm/IR/Operator.h"
20#include "llvm/IR/PassManager.h"
22#include "llvm/IR/Type.h"
26
27#define DEBUG_TYPE "dxil-data-scalarization"
28static const int MaxVecSize = 4;
29
30using namespace llvm;
31
32// Recursively creates an array-like version of a given vector type.
34 if (auto *VecTy = dyn_cast<VectorType>(T))
35 return ArrayType::get(VecTy->getElementType(),
36 dyn_cast<FixedVectorType>(VecTy)->getNumElements());
37 if (auto *ArrayTy = dyn_cast<ArrayType>(T)) {
38 Type *NewElementType =
39 equivalentArrayTypeFromVector(ArrayTy->getElementType());
40 return ArrayType::get(NewElementType, ArrayTy->getNumElements());
41 }
42 // If it's not a vector or array, return the original type.
43 return T;
44}
45
47
48public:
49 bool runOnModule(Module &M) override;
51
52 static char ID; // Pass identification.
53};
54
55static bool findAndReplaceVectors(Module &M);
56
57class DataScalarizerVisitor : public InstVisitor<DataScalarizerVisitor, bool> {
58public:
59 DataScalarizerVisitor() : GlobalMap() {}
60 bool visit(Function &F);
61 // InstVisitor methods. They return true if the instruction was scalarized,
62 // false if nothing changed.
64 bool visitInstruction(Instruction &I) { return false; }
65 bool visitSelectInst(SelectInst &SI) { return false; }
66 bool visitICmpInst(ICmpInst &ICI) { return false; }
67 bool visitFCmpInst(FCmpInst &FCI) { return false; }
68 bool visitUnaryOperator(UnaryOperator &UO) { return false; }
69 bool visitBinaryOperator(BinaryOperator &BO) { return false; }
71 bool visitCastInst(CastInst &CI) { return false; }
72 bool visitBitCastInst(BitCastInst &BCI) { return false; }
75 bool visitShuffleVectorInst(ShuffleVectorInst &SVI) { return false; }
76 bool visitPHINode(PHINode &PHI) { return false; }
77 bool visitLoadInst(LoadInst &LI);
78 bool visitStoreInst(StoreInst &SI);
79 bool visitCallInst(CallInst &ICI) { return false; }
80 bool visitFreezeInst(FreezeInst &FI) { return false; }
81 friend bool findAndReplaceVectors(llvm::Module &M);
82
83private:
84 typedef std::pair<AllocaInst *, SmallVector<Value *, 4>> AllocaAndGEPs;
86 VectorToArrayMap; // A map from a vector-typed Value to its corresponding
87 // AllocaInst and GEPs to each element of an array
88 VectorToArrayMap VectorAllocaMap;
89 AllocaAndGEPs createArrayFromVector(IRBuilder<> &Builder, Value *Vec,
90 const Twine &Name);
91 bool replaceDynamicInsertElementInst(InsertElementInst &IEI);
92 bool replaceDynamicExtractElementInst(ExtractElementInst &EEI);
93
94 GlobalVariable *lookupReplacementGlobal(Value *CurrOperand);
96};
97
99 bool MadeChange = false;
101 for (BasicBlock *BB : make_early_inc_range(RPOT)) {
103 MadeChange |= InstVisitor::visit(I);
104 }
105 VectorAllocaMap.clear();
106 return MadeChange;
107}
108
110DataScalarizerVisitor::lookupReplacementGlobal(Value *CurrOperand) {
111 if (GlobalVariable *OldGlobal = dyn_cast<GlobalVariable>(CurrOperand)) {
112 auto It = GlobalMap.find(OldGlobal);
113 if (It != GlobalMap.end()) {
114 return It->second; // Found, return the new global
115 }
116 }
117 return nullptr; // Not found
118}
119
120// Helper function to check if a type is a vector or an array of vectors
122 if (isa<VectorType>(T))
123 return true;
124 if (ArrayType *ArrType = dyn_cast<ArrayType>(T))
125 return isa<VectorType>(ArrType->getElementType()) ||
126 isVectorOrArrayOfVectors(ArrType->getElementType());
127 return false;
128}
129
131 Type *AllocatedType = AI.getAllocatedType();
132 if (!isVectorOrArrayOfVectors(AllocatedType))
133 return false;
134
135 IRBuilder<> Builder(&AI);
136 Type *NewType = equivalentArrayTypeFromVector(AllocatedType);
137 AllocaInst *ArrAlloca =
138 Builder.CreateAlloca(NewType, nullptr, AI.getName() + ".scalarize");
139 ArrAlloca->setAlignment(AI.getAlign());
140 AI.replaceAllUsesWith(ArrAlloca);
141 AI.eraseFromParent();
142 return true;
143}
144
146 Value *PtrOperand = LI.getPointerOperand();
147 ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOperand);
148 if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
149 GetElementPtrInst *OldGEP = cast<GetElementPtrInst>(CE->getAsInstruction());
150 OldGEP->insertBefore(LI.getIterator());
151 IRBuilder<> Builder(&LI);
152 LoadInst *NewLoad = Builder.CreateLoad(LI.getType(), OldGEP, LI.getName());
153 NewLoad->setAlignment(LI.getAlign());
154 LI.replaceAllUsesWith(NewLoad);
155 LI.eraseFromParent();
156 visitGetElementPtrInst(*OldGEP);
157 return true;
158 }
159 if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand))
160 LI.setOperand(LI.getPointerOperandIndex(), NewGlobal);
161 return false;
162}
163
165
166 Value *PtrOperand = SI.getPointerOperand();
167 ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOperand);
168 if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
169 GetElementPtrInst *OldGEP = cast<GetElementPtrInst>(CE->getAsInstruction());
170 OldGEP->insertBefore(SI.getIterator());
171 IRBuilder<> Builder(&SI);
172 StoreInst *NewStore = Builder.CreateStore(SI.getValueOperand(), OldGEP);
173 NewStore->setAlignment(SI.getAlign());
174 SI.replaceAllUsesWith(NewStore);
175 SI.eraseFromParent();
176 visitGetElementPtrInst(*OldGEP);
177 return true;
178 }
179 if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand))
180 SI.setOperand(SI.getPointerOperandIndex(), NewGlobal);
181
182 return false;
183}
184
185DataScalarizerVisitor::AllocaAndGEPs
186DataScalarizerVisitor::createArrayFromVector(IRBuilder<> &Builder, Value *Vec,
187 const Twine &Name = "") {
188 // If there is already an alloca for this vector, return it
189 if (VectorAllocaMap.contains(Vec))
190 return VectorAllocaMap[Vec];
191
192 auto InsertPoint = Builder.GetInsertPoint();
193
194 // Allocate the array to hold the vector elements
197 AllocaInst *ArrAlloca =
198 Builder.CreateAlloca(ArrTy, nullptr, Name + ".alloca");
199 const uint64_t ArrNumElems = ArrTy->getArrayNumElements();
200
201 // Create loads and stores to populate the array immediately after the
202 // original vector's defining instruction if available, else immediately after
203 // the alloca
204 if (auto *Instr = dyn_cast<Instruction>(Vec))
205 Builder.SetInsertPoint(Instr->getNextNode());
206 SmallVector<Value *, 4> GEPs(ArrNumElems);
207 for (unsigned I = 0; I < ArrNumElems; ++I) {
208 Value *EE = Builder.CreateExtractElement(Vec, I, Name + ".extract");
209 GEPs[I] = Builder.CreateInBoundsGEP(
210 ArrTy, ArrAlloca, {Builder.getInt32(0), Builder.getInt32(I)},
211 Name + ".index");
212 Builder.CreateStore(EE, GEPs[I]);
213 }
214
215 VectorAllocaMap.insert({Vec, {ArrAlloca, GEPs}});
216 Builder.SetInsertPoint(InsertPoint);
217 return {ArrAlloca, GEPs};
218}
219
220/// Returns a pair of Value* with the first being a GEP into ArrAlloca using
221/// indices {0, Index}, and the second Value* being a Load of the GEP
222static std::pair<Value *, Value *>
224 const Twine &Name = "") {
225 Type *ArrTy = ArrAlloca->getAllocatedType();
226 Value *GEP = Builder.CreateInBoundsGEP(
227 ArrTy, ArrAlloca, {Builder.getInt32(0), Index}, Name + ".index");
228 Value *Load =
229 Builder.CreateLoad(ArrTy->getArrayElementType(), GEP, Name + ".load");
230 return std::make_pair(GEP, Load);
231}
232
233bool DataScalarizerVisitor::replaceDynamicInsertElementInst(
234 InsertElementInst &IEI) {
235 IRBuilder<> Builder(&IEI);
236
237 Value *Vec = IEI.getOperand(0);
238 Value *Val = IEI.getOperand(1);
239 Value *Index = IEI.getOperand(2);
240
241 AllocaAndGEPs ArrAllocaAndGEPs =
242 createArrayFromVector(Builder, Vec, IEI.getName());
243 AllocaInst *ArrAlloca = ArrAllocaAndGEPs.first;
244 Type *ArrTy = ArrAlloca->getAllocatedType();
245 SmallVector<Value *, 4> &ArrGEPs = ArrAllocaAndGEPs.second;
246
247 auto GEPAndLoad =
248 dynamicallyLoadArray(Builder, ArrAlloca, Index, IEI.getName());
249 Value *GEP = GEPAndLoad.first;
250 Value *Load = GEPAndLoad.second;
251
252 Builder.CreateStore(Val, GEP);
253 Value *NewIEI = PoisonValue::get(Vec->getType());
254 for (unsigned I = 0; I < ArrTy->getArrayNumElements(); ++I) {
255 Value *Load = Builder.CreateLoad(ArrTy->getArrayElementType(), ArrGEPs[I],
256 IEI.getName() + ".load");
257 NewIEI = Builder.CreateInsertElement(NewIEI, Load, Builder.getInt32(I),
258 IEI.getName() + ".insert");
259 }
260
261 // Store back the original value so the Alloca can be reused for subsequent
262 // insertelement instructions on the same vector
263 Builder.CreateStore(Load, GEP);
264
265 IEI.replaceAllUsesWith(NewIEI);
266 IEI.eraseFromParent();
267 return true;
268}
269
271 // If the index is a constant then we don't need to scalarize it
272 Value *Index = IEI.getOperand(2);
273 if (isa<ConstantInt>(Index))
274 return false;
275 return replaceDynamicInsertElementInst(IEI);
276}
277
278bool DataScalarizerVisitor::replaceDynamicExtractElementInst(
279 ExtractElementInst &EEI) {
280 IRBuilder<> Builder(&EEI);
281
282 AllocaAndGEPs ArrAllocaAndGEPs =
283 createArrayFromVector(Builder, EEI.getVectorOperand(), EEI.getName());
284 AllocaInst *ArrAlloca = ArrAllocaAndGEPs.first;
285
286 auto GEPAndLoad = dynamicallyLoadArray(Builder, ArrAlloca,
287 EEI.getIndexOperand(), EEI.getName());
288 Value *Load = GEPAndLoad.second;
289
290 EEI.replaceAllUsesWith(Load);
291 EEI.eraseFromParent();
292 return true;
293}
294
296 // If the index is a constant then we don't need to scalarize it
297 Value *Index = EEI.getIndexOperand();
298 if (isa<ConstantInt>(Index))
299 return false;
300 return replaceDynamicExtractElementInst(EEI);
301}
302
304 GEPOperator *GOp = cast<GEPOperator>(&GEPI);
305 Value *PtrOperand = GOp->getPointerOperand();
306 Type *NewGEPType = GOp->getSourceElementType();
307 bool NeedsTransform = false;
308
309 // Unwrap GEP ConstantExprs to find the base operand and element type
310 while (auto *CE = dyn_cast<ConstantExpr>(PtrOperand)) {
311 if (auto *GEPCE = dyn_cast<GEPOperator>(CE)) {
312 GOp = GEPCE;
313 PtrOperand = GEPCE->getPointerOperand();
314 NewGEPType = GEPCE->getSourceElementType();
315 } else
316 break;
317 }
318
319 if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand)) {
320 NewGEPType = NewGlobal->getValueType();
321 PtrOperand = NewGlobal;
322 NeedsTransform = true;
323 } else if (AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrOperand)) {
324 Type *AllocatedType = Alloca->getAllocatedType();
325 if (isa<ArrayType>(AllocatedType) &&
326 AllocatedType != GOp->getResultElementType()) {
327 NewGEPType = AllocatedType;
328 NeedsTransform = true;
329 }
330 }
331
332 if (!NeedsTransform)
333 return false;
334
335 // Keep scalar GEPs scalar; dxil-flatten-arrays will do flattening later
336 if (!isa<ArrayType>(GOp->getSourceElementType()))
337 NewGEPType = GOp->getSourceElementType();
338
339 IRBuilder<> Builder(&GEPI);
341 Value *NewGEP = Builder.CreateGEP(NewGEPType, PtrOperand, Indices,
342 GOp->getName(), GOp->getNoWrapFlags());
343
344 GOp->replaceAllUsesWith(NewGEP);
345
346 if (auto *OldGEPI = dyn_cast<GetElementPtrInst>(GOp))
347 OldGEPI->eraseFromParent();
348
349 return true;
350}
351
353 Type *NewType, LLVMContext &Ctx) {
354 // Handle ConstantAggregateZero (zero-initialized constants)
355 if (isa<ConstantAggregateZero>(Init)) {
356 return ConstantAggregateZero::get(NewType);
357 }
358
359 // Handle UndefValue (undefined constants)
360 if (isa<UndefValue>(Init)) {
361 return UndefValue::get(NewType);
362 }
363
364 // Handle vector to array transformation
365 if (isa<VectorType>(OrigType) && isa<ArrayType>(NewType)) {
366 // Convert vector initializer to array initializer
368 if (ConstantVector *ConstVecInit = dyn_cast<ConstantVector>(Init)) {
369 for (unsigned I = 0; I < ConstVecInit->getNumOperands(); ++I)
370 ArrayElements.push_back(ConstVecInit->getOperand(I));
371 } else if (ConstantDataVector *ConstDataVecInit =
372 llvm::dyn_cast<llvm::ConstantDataVector>(Init)) {
373 for (unsigned I = 0; I < ConstDataVecInit->getNumElements(); ++I)
374 ArrayElements.push_back(ConstDataVecInit->getElementAsConstant(I));
375 } else {
376 assert(false && "Expected a ConstantVector or ConstantDataVector for "
377 "vector initializer!");
378 }
379
380 return ConstantArray::get(cast<ArrayType>(NewType), ArrayElements);
381 }
382
383 // Handle array of vectors transformation
384 if (auto *ArrayTy = dyn_cast<ArrayType>(OrigType)) {
385 auto *ArrayInit = dyn_cast<ConstantArray>(Init);
386 assert(ArrayInit && "Expected a ConstantArray for array initializer!");
387
389 for (unsigned I = 0; I < ArrayTy->getNumElements(); ++I) {
390 // Recursively transform array elements
391 Constant *NewElemInit = transformInitializer(
392 ArrayInit->getOperand(I), ArrayTy->getElementType(),
393 cast<ArrayType>(NewType)->getElementType(), Ctx);
394 NewArrayElements.push_back(NewElemInit);
395 }
396
397 return ConstantArray::get(cast<ArrayType>(NewType), NewArrayElements);
398 }
399
400 // If not a vector or array, return the original initializer
401 return Init;
402}
403
405 bool MadeChange = false;
406 LLVMContext &Ctx = M.getContext();
407 IRBuilder<> Builder(Ctx);
409 for (GlobalVariable &G : M.globals()) {
410 Type *OrigType = G.getValueType();
411
412 Type *NewType = equivalentArrayTypeFromVector(OrigType);
413 if (OrigType != NewType) {
414 // Create a new global variable with the updated type
415 // Note: Initializer is set via transformInitializer
416 GlobalVariable *NewGlobal = new GlobalVariable(
417 M, NewType, G.isConstant(), G.getLinkage(),
418 /*Initializer=*/nullptr, G.getName() + ".scalarized", &G,
419 G.getThreadLocalMode(), G.getAddressSpace(),
420 G.isExternallyInitialized());
421
422 // Copy relevant attributes
423 NewGlobal->setUnnamedAddr(G.getUnnamedAddr());
424 if (G.getAlignment() > 0) {
425 NewGlobal->setAlignment(G.getAlign());
426 }
427
428 if (G.hasInitializer()) {
429 Constant *Init = G.getInitializer();
430 Constant *NewInit = transformInitializer(Init, OrigType, NewType, Ctx);
431 NewGlobal->setInitializer(NewInit);
432 }
433
434 // Note: we want to do G.replaceAllUsesWith(NewGlobal);, but it assumes
435 // type equality. Instead we will use the visitor pattern.
436 Impl.GlobalMap[&G] = NewGlobal;
437 }
438 }
439
440 for (auto &F : make_early_inc_range(M.functions())) {
441 if (F.isDeclaration())
442 continue;
443 MadeChange |= Impl.visit(F);
444 }
445
446 // Remove the old globals after the iteration
447 for (auto &[Old, New] : Impl.GlobalMap) {
448 Old->eraseFromParent();
449 MadeChange = true;
450 }
451 return MadeChange;
452}
453
456 bool MadeChanges = findAndReplaceVectors(M);
457 if (!MadeChanges)
458 return PreservedAnalyses::all();
460 return PA;
461}
462
464 return findAndReplaceVectors(M);
465}
466
468
470 "DXIL Data Scalarization", false, false)
473
475 return new DXILDataScalarizationLegacy();
476}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Rewrite undef for PHI
static bool isVectorOrArrayOfVectors(Type *T)
static Type * equivalentArrayTypeFromVector(Type *T)
static std::pair< Value *, Value * > dynamicallyLoadArray(IRBuilder<> &Builder, AllocaInst *ArrAlloca, Value *Index, const Twine &Name="")
Returns a pair of Value* with the first being a GEP into ArrAlloca using indices {0,...
DXIL Data Scalarization
static bool findAndReplaceVectors(Module &M)
static const int MaxVecSize
static Constant * transformInitializer(Constant *Init, Type *OrigType, Type *NewType, LLVMContext &Ctx)
std::string Name
#define DEBUG_TYPE
Hexagon Common GEP
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:39
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file contains some templates that are useful if you are working with the STL at all.
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
bool visitCallInst(CallInst &ICI)
bool visitInstruction(Instruction &I)
bool visitBinaryOperator(BinaryOperator &BO)
bool visitInsertElementInst(InsertElementInst &IEI)
bool visitGetElementPtrInst(GetElementPtrInst &GEPI)
bool visitStoreInst(StoreInst &SI)
bool visitFreezeInst(FreezeInst &FI)
bool visitBitCastInst(BitCastInst &BCI)
bool visitCastInst(CastInst &CI)
bool visitFCmpInst(FCmpInst &FCI)
bool visitLoadInst(LoadInst &LI)
bool visitSelectInst(SelectInst &SI)
bool visitUnaryOperator(UnaryOperator &UO)
bool visitICmpInst(ICmpInst &ICI)
bool visitShuffleVectorInst(ShuffleVectorInst &SVI)
bool visitAllocaInst(AllocaInst &AI)
bool visitPHINode(PHINode &PHI)
bool visitExtractElementInst(ExtractElementInst &EEI)
friend bool findAndReplaceVectors(llvm::Module &M)
an instruction to allocate memory on the stack
Definition: Instructions.h:64
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
Definition: Instructions.h:128
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
Definition: Instructions.h:121
void setAlignment(Align Align)
Definition: Instructions.h:132
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:213
This class represents a no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
Definition: InstrTypes.h:448
static LLVM_ABI ConstantAggregateZero * get(Type *Ty)
Definition: Constants.cpp:1677
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1314
A vector constant whose element type is a simple 1/2/4/8-byte integer or float/double,...
Definition: Constants.h:776
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:1120
Constant Vector Declarations.
Definition: Constants.h:517
This is an important base class in LLVM.
Definition: Constant.h:43
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:177
iterator end()
Definition: DenseMap.h:87
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition: DenseMap.h:168
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:230
This instruction extracts a single (scalar) element from a VectorType value.
This instruction compares its operands according to the predicate given to the constructor.
This class represents a freeze function that returns random concrete value if an operand is either a ...
LLVM_ABI Type * getSourceElementType() const
Definition: Operator.cpp:70
LLVM_ABI Type * getResultElementType() const
Definition: Operator.cpp:76
Value * getPointerOperand()
Definition: Operator.h:457
GEPNoWrapFlags getNoWrapFlags() const
Definition: Operator.h:425
iterator_range< op_iterator > indices()
Definition: Operator.h:449
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:949
void setUnnamedAddr(UnnamedAddr Val)
Definition: GlobalValue.h:233
LLVM_ABI void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
Definition: Globals.cpp:511
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2571
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition: IRBuilder.h:1830
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2559
BasicBlock::iterator GetInsertPoint() const
Definition: IRBuilder.h:202
BasicBlock * GetInsertBlock() const
Definition: IRBuilder.h:201
void SetInsertPointPastAllocas(Function *F)
This specifies that created instructions should inserted at the beginning end of the specified functi...
Definition: IRBuilder.h:241
Value * CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
Definition: IRBuilder.h:1931
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition: IRBuilder.h:1923
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition: IRBuilder.h:522
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition: IRBuilder.h:1847
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1860
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition: IRBuilder.h:207
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2780
This instruction inserts a single (scalar) element into a VectorType value.
Base class for instruction visitors.
Definition: InstVisitor.h:78
void visit(Iterator Start, Iterator End)
Definition: InstVisitor.h:87
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
An instruction for reading from memory.
Definition: Instructions.h:180
void setAlignment(Align Align)
Definition: Instructions.h:219
Value * getPointerOperand()
Definition: Instructions.h:259
static unsigned getPointerOperandIndex()
Definition: Instructions.h:261
Align getAlign() const
Return the alignment of the access that is being performed.
Definition: Instructions.h:215
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:255
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1885
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
This class represents the LLVM 'select' instruction.
This instruction constructs a fixed permutation of two input vectors.
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
An instruction for storing to memory.
Definition: Instructions.h:296
void setAlignment(Align Align)
Definition: Instructions.h:342
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Type * getArrayElementType() const
Definition: Type.h:408
LLVM_ABI uint64_t getArrayNumElements() const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1866
void setOperand(unsigned i, Value *Val)
Definition: User.h:237
Value * getOperand(unsigned i) const
Definition: User.h:232
LLVM Value Representation.
Definition: Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:546
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
self_iterator getIterator()
Definition: ilist_node.h:134
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
ModulePass * createDXILDataScalarizationLegacyPass()
Pass to scalarize llvm global data into a DXIL legal form.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:663