LLVM 24.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
9#include "DirectX.h"
11#include "llvm/ADT/STLExtras.h"
14#include "llvm/IR/IRBuilder.h"
15#include "llvm/IR/InstVisitor.h"
17#include "llvm/IR/Module.h"
18#include "llvm/IR/Operator.h"
19#include "llvm/IR/PassManager.h"
21#include "llvm/IR/Type.h"
25
26#define DEBUG_TYPE "dxil-data-scalarization"
27static const int MaxVecSize = 4;
28
29using namespace llvm;
30
32
33public:
34 bool runOnModule(Module &M) override;
36
37 static char ID; // Pass identification.
38};
39
40static bool findAndReplaceVectors(Module &M);
41
42class DataScalarizerVisitor : public InstVisitor<DataScalarizerVisitor, bool> {
43public:
44 DataScalarizerVisitor() : GlobalMap() {}
45 bool visit(Function &F);
46 // InstVisitor methods. They return true if the instruction was scalarized,
47 // false if nothing changed.
49 bool visitInstruction(Instruction &I) { return false; }
50 bool visitSelectInst(SelectInst &SI) { return false; }
51 bool visitICmpInst(ICmpInst &ICI) { return false; }
52 bool visitFCmpInst(FCmpInst &FCI) { return false; }
53 bool visitUnaryOperator(UnaryOperator &UO) { return false; }
54 bool visitBinaryOperator(BinaryOperator &BO) { return false; }
56 bool visitCastInst(CastInst &CI) { return false; }
57 bool visitBitCastInst(BitCastInst &BCI) { return false; }
60 bool visitShuffleVectorInst(ShuffleVectorInst &SVI) { return false; }
61 bool visitPHINode(PHINode &PHI) { return false; }
62 bool visitLoadInst(LoadInst &LI);
64 bool visitCallInst(CallInst &ICI) { return false; }
65 bool visitFreezeInst(FreezeInst &FI) { return false; }
66 friend bool findAndReplaceVectors(llvm::Module &M);
67
68private:
69 typedef std::tuple<AllocaInst *, Type *, SmallVector<Value *, 4>>
70 AllocaAndGEPs;
72 VectorToArrayMap; // A map from a vector-typed Value to its corresponding
73 // AllocaInst and GEPs to each element of an array
74 VectorToArrayMap VectorAllocaMap;
75 AllocaAndGEPs createArrayFromVector(IRBuilder<> &Builder, Value *Vec,
76 const Twine &Name);
77 bool replaceDynamicInsertElementInst(InsertElementInst &IEI);
78 bool replaceDynamicExtractElementInst(ExtractElementInst &EEI);
79
80 GlobalVariable *lookupReplacementGlobal(Value *CurrOperand);
82};
83
85 bool MadeChange = false;
87 for (BasicBlock *BB : make_early_inc_range(RPOT)) {
89 MadeChange |= InstVisitor::visit(I);
90 }
91 VectorAllocaMap.clear();
92 return MadeChange;
93}
94
96DataScalarizerVisitor::lookupReplacementGlobal(Value *CurrOperand) {
97 if (GlobalVariable *OldGlobal = dyn_cast<GlobalVariable>(CurrOperand)) {
98 auto It = GlobalMap.find(OldGlobal);
99 if (It != GlobalMap.end()) {
100 return It->second; // Found, return the new global
101 }
102 }
103 return nullptr; // Not found
104}
105
106// Helper function to check if a type is a vector or an array of vectors
108 if (isa<VectorType>(T))
109 return true;
110 if (ArrayType *ArrayTy = dyn_cast<ArrayType>(T))
111 return isVectorOrArrayOfVectors(ArrayTy->getElementType());
112 return false;
113}
114
115// Recursively creates an array-like version of a given vector type.
117 if (auto *VecTy = dyn_cast<VectorType>(T))
118 return ArrayType::get(VecTy->getElementType(),
119 dyn_cast<FixedVectorType>(VecTy)->getNumElements());
120 if (auto *ArrayTy = dyn_cast<ArrayType>(T)) {
121 Type *NewElementType =
122 equivalentArrayTypeFromVector(ArrayTy->getElementType());
123 return ArrayType::get(NewElementType, ArrayTy->getNumElements());
124 }
125 // If it's not a vector or array, return the original type.
126 return T;
127}
128
130 Type *AllocatedType = AI.getAllocatedType();
131 if (!isVectorOrArrayOfVectors(AllocatedType))
132 return false;
133
134 IRBuilder<> Builder(&AI);
135 Type *NewType = equivalentArrayTypeFromVector(AllocatedType);
136 AllocaInst *ArrAlloca =
137 Builder.CreateAlloca(NewType, nullptr, AI.getName() + ".scalarized");
138 ArrAlloca->setAlignment(AI.getAlign());
139 AI.replaceAllUsesWith(ArrAlloca);
140 AI.eraseFromParent();
141 return true;
142}
143
145 Value *PtrOperand = LI.getPointerOperand();
146 ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOperand);
147 if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
148 GetElementPtrInst *OldGEP = cast<GetElementPtrInst>(CE->getAsInstruction());
149 OldGEP->insertBefore(LI.getIterator());
150 IRBuilder<> Builder(&LI);
151 LoadInst *NewLoad = Builder.CreateLoad(LI.getType(), OldGEP, LI.getName());
152 NewLoad->setAlignment(LI.getAlign());
153 LI.replaceAllUsesWith(NewLoad);
154 LI.eraseFromParent();
155 visitGetElementPtrInst(*OldGEP);
156 return true;
157 }
158 if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand))
159 LI.setOperand(LI.getPointerOperandIndex(), NewGlobal);
160 return false;
161}
162
164
165 Value *PtrOperand = SI.getPointerOperand();
166 ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOperand);
167 if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
168 GetElementPtrInst *OldGEP = cast<GetElementPtrInst>(CE->getAsInstruction());
169 OldGEP->insertBefore(SI.getIterator());
170 IRBuilder<> Builder(&SI);
171 StoreInst *NewStore = Builder.CreateStore(SI.getValueOperand(), OldGEP);
172 NewStore->setAlignment(SI.getAlign());
173 SI.replaceAllUsesWith(NewStore);
174 SI.eraseFromParent();
175 visitGetElementPtrInst(*OldGEP);
176 return true;
177 }
178 if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand))
179 SI.setOperand(SI.getPointerOperandIndex(), NewGlobal);
180
181 return false;
182}
183
184DataScalarizerVisitor::AllocaAndGEPs
185DataScalarizerVisitor::createArrayFromVector(IRBuilder<> &Builder, Value *Vec,
186 const Twine &Name = "") {
187 // If there is already an alloca for this vector, return it
188 if (VectorAllocaMap.contains(Vec))
189 return VectorAllocaMap[Vec];
190
191 auto InsertPoint = Builder.GetInsertPoint();
192
193 // Allocate the array to hold the vector elements
194 Builder.SetInsertPointPastAllocas(Builder.GetInsertBlock()->getParent());
196 // DXIL indexable temps cannot hold i1 elements; booleans occupy 32 bits in
197 // memory. Widen i1 element arrays to i32.
198 Type *ArrElemTy = ArrTy->getArrayElementType();
199 bool WidenBool = ArrElemTy->isIntegerTy(1);
200 if (WidenBool) {
201 ArrElemTy = Builder.getInt32Ty();
202 ArrTy = ArrayType::get(ArrElemTy, ArrTy->getArrayNumElements());
203 }
204 AllocaInst *ArrAlloca =
205 Builder.CreateAlloca(ArrTy, nullptr, Name + ".alloca");
206 const uint64_t ArrNumElems = ArrTy->getArrayNumElements();
207
208 // Create loads and stores to populate the array immediately after the
209 // original vector's defining instruction if available, else immediately after
210 // the alloca
211 if (auto *Instr = dyn_cast<Instruction>(Vec))
212 Builder.SetInsertPoint(Instr->getNextNode());
213 SmallVector<Value *, 4> GEPs(ArrNumElems);
214 for (unsigned I = 0; I < ArrNumElems; ++I) {
215 Value *EE = Builder.CreateExtractElement(Vec, I, Name + ".extract");
216 if (WidenBool)
217 EE = Builder.CreateZExt(EE, ArrElemTy, Name + ".zext");
219 ArrTy, ArrAlloca, {Builder.getInt32(0), Builder.getInt32(I)},
220 Name + ".index", Builder.GetInsertPoint());
221 Builder.CreateStore(EE, GEPs[I]);
222 }
223
224 VectorAllocaMap.insert({Vec, {ArrAlloca, ArrTy, GEPs}});
225 Builder.SetInsertPoint(InsertPoint);
226 return {ArrAlloca, ArrTy, GEPs};
227}
228
229/// Returns a pair of Value* with the first being a GEP into ArrAlloca using
230/// indices {0, Index}, and the second Value* being a Load of the GEP
231static std::pair<Value *, Value *>
232dynamicallyLoadArray(IRBuilder<> &Builder, AllocaInst *ArrAlloca, Type *ArrTy,
233 Value *Index, const Twine &Name = "") {
235 ArrTy, ArrAlloca, {Builder.getInt32(0), Index}, Name + ".index",
236 Builder.GetInsertPoint());
237 Value *Load =
238 Builder.CreateLoad(ArrTy->getArrayElementType(), GEP, Name + ".load");
239 return std::make_pair(GEP, Load);
240}
241
242bool DataScalarizerVisitor::replaceDynamicInsertElementInst(
243 InsertElementInst &IEI) {
244 IRBuilder<> Builder(&IEI);
245
246 Value *Vec = IEI.getOperand(0);
247 Value *Val = IEI.getOperand(1);
248 Value *Index = IEI.getOperand(2);
249
250 AllocaAndGEPs ArrAllocaAndGEPs =
251 createArrayFromVector(Builder, Vec, IEI.getName());
252 AllocaInst *ArrAlloca = std::get<0>(ArrAllocaAndGEPs);
253 Type *ArrTy = std::get<1>(ArrAllocaAndGEPs);
254 SmallVector<Value *, 4> &ArrGEPs = std::get<2>(ArrAllocaAndGEPs);
255
256 // The array element type may have been widened (e.g. i1 -> i32) so that the
257 // indexable temp uses a legal DXIL memory type. Convert between the vector
258 // element type and the (possibly wider) array element type as needed.
259 Type *ArrElemTy = ArrTy->getArrayElementType();
260 Type *VecElemTy = cast<VectorType>(Vec->getType())->getElementType();
261 bool WidenBool = ArrElemTy != VecElemTy && VecElemTy->isIntegerTy(1);
262
263 auto GEPAndLoad =
264 dynamicallyLoadArray(Builder, ArrAlloca, ArrTy, Index, IEI.getName());
265 Value *GEP = GEPAndLoad.first;
266 Value *Load = GEPAndLoad.second;
267
268 Value *StoreVal = Val;
269 if (WidenBool)
270 StoreVal = Builder.CreateZExt(Val, ArrElemTy, IEI.getName() + ".zext");
271 Builder.CreateStore(StoreVal, GEP);
272 Value *NewIEI = PoisonValue::get(Vec->getType());
273 for (unsigned I = 0; I < ArrTy->getArrayNumElements(); ++I) {
274 Value *EltLoad =
275 Builder.CreateLoad(ArrElemTy, ArrGEPs[I], IEI.getName() + ".load");
276 if (WidenBool)
277 EltLoad =
278 Builder.CreateTrunc(EltLoad, VecElemTy, IEI.getName() + ".trunc");
279 NewIEI = Builder.CreateInsertElement(NewIEI, EltLoad, Builder.getInt32(I),
280 IEI.getName() + ".insert");
281 }
282
283 // Store back the original value so the Alloca can be reused for subsequent
284 // insertelement instructions on the same vector
285 Builder.CreateStore(Load, GEP);
286
287 IEI.replaceAllUsesWith(NewIEI);
288 IEI.eraseFromParent();
289 return true;
290}
291
293 // If the index is a constant then we don't need to scalarize it
294 Value *Index = IEI.getOperand(2);
295 if (isa<ConstantInt>(Index))
296 return false;
297 return replaceDynamicInsertElementInst(IEI);
298}
299
300bool DataScalarizerVisitor::replaceDynamicExtractElementInst(
301 ExtractElementInst &EEI) {
302 IRBuilder<> Builder(&EEI);
303
304 AllocaAndGEPs ArrAllocaAndGEPs =
305 createArrayFromVector(Builder, EEI.getVectorOperand(), EEI.getName());
306 AllocaInst *ArrAlloca = std::get<0>(ArrAllocaAndGEPs);
307 Type *ArrTy = std::get<1>(ArrAllocaAndGEPs);
308
309 auto GEPAndLoad = dynamicallyLoadArray(Builder, ArrAlloca, ArrTy,
310 EEI.getIndexOperand(), EEI.getName());
311 Value *Load = GEPAndLoad.second;
312
313 // The array element type may have been widened (e.g. i1 -> i32) so that the
314 // indexable temp uses a legal DXIL memory type. Truncate back to the original
315 // element type of the extractelement if necessary.
316 if (Load->getType() != EEI.getType()) {
317 assert(Load->getType()->isIntegerTy(32) && EEI.getType()->isIntegerTy(1) &&
318 "Unexpected type mismatch: only i32 -> i1 widening is supported");
319 Load = Builder.CreateTrunc(Load, EEI.getType(), EEI.getName() + ".trunc");
320 }
321
323 EEI.eraseFromParent();
324 return true;
325}
326
328 // If the index is a constant then we don't need to scalarize it
329 Value *Index = EEI.getIndexOperand();
330 if (isa<ConstantInt>(Index))
331 return false;
332 return replaceDynamicExtractElementInst(EEI);
333}
334
336 GEPOperator *GOp = cast<GEPOperator>(&GEPI);
337 Value *PtrOperand = GOp->getPointerOperand();
338 Type *GEPType = GOp->getSourceElementType();
339
340 // Replace a GEP ConstantExpr pointer operand with a GEP instruction so that
341 // it can be visited
342 if (auto *PtrOpGEPCE = dyn_cast<ConstantExpr>(PtrOperand);
343 PtrOpGEPCE && PtrOpGEPCE->getOpcode() == Instruction::GetElementPtr) {
344 GetElementPtrInst *OldGEPI =
345 cast<GetElementPtrInst>(PtrOpGEPCE->getAsInstruction());
346 OldGEPI->insertBefore(GEPI.getIterator());
347
348 SmallVector<Value *> Indices(GEPI.indices());
350 GEPI.getSourceElementType(), OldGEPI, Indices, GEPI.getNoWrapFlags(),
351 GEPI.getName(), GEPI.getIterator());
352
353 GEPI.replaceAllUsesWith(NewGEPI);
354 GEPI.eraseFromParent();
355 visitGetElementPtrInst(*OldGEPI);
356 visitGetElementPtrInst(*NewGEPI);
357 return true;
358 }
359
360 Type *NewGEPType = equivalentArrayTypeFromVector(GEPType);
361 Value *NewPtrOperand = PtrOperand;
362 if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand))
363 NewPtrOperand = NewGlobal;
364
365 bool NeedsTransform = NewPtrOperand != PtrOperand || NewGEPType != GEPType;
366 if (!NeedsTransform)
367 return false;
368
369 SmallVector<Value *, MaxVecSize> Indices(GOp->idx_begin(), GOp->idx_end());
370 Value *NewGEP = GetElementPtrInst::Create(NewGEPType, NewPtrOperand, Indices,
371 GOp->getNoWrapFlags(),
372 GOp->getName(), GEPI.getIterator());
373
374 GOp->replaceAllUsesWith(NewGEP);
375
376 if (auto *OldGEPI = dyn_cast<GetElementPtrInst>(GOp))
377 OldGEPI->eraseFromParent();
378
379 return true;
380}
381
383 Type *NewType, LLVMContext &Ctx) {
384 // Handle ConstantAggregateZero (zero-initialized constants)
386 return ConstantAggregateZero::get(NewType);
387 }
388
389 // Handle UndefValue (undefined constants)
390 if (isa<UndefValue>(Init)) {
391 return UndefValue::get(NewType);
392 }
393
394 // Handle vector to array transformation
395 if (isa<VectorType>(OrigType) && isa<ArrayType>(NewType)) {
396 // Convert vector initializer to array initializer
398
399 unsigned E = cast<FixedVectorType>(OrigType)->getNumElements();
400 for (unsigned I = 0; I != E; ++I)
401 if (Constant *Elt = Init->getAggregateElement(I))
402 ArrayElements.push_back(Elt);
403
404 assert(ArrayElements.size() == E &&
405 "Expected fixed length constant aggregate for vector initializer!");
406 return ConstantArray::get(cast<ArrayType>(NewType), ArrayElements);
407 }
408
409 // Handle array of vectors transformation
410 if (auto *ArrayTy = dyn_cast<ArrayType>(OrigType)) {
411 auto *ArrayInit = dyn_cast<ConstantArray>(Init);
412 assert(ArrayInit && "Expected a ConstantArray for array initializer!");
413
415 for (unsigned I = 0; I < ArrayTy->getNumElements(); ++I) {
416 // Recursively transform array elements
417 Constant *NewElemInit = transformInitializer(
418 ArrayInit->getOperand(I), ArrayTy->getElementType(),
419 cast<ArrayType>(NewType)->getElementType(), Ctx);
420 NewArrayElements.push_back(NewElemInit);
421 }
422
423 return ConstantArray::get(cast<ArrayType>(NewType), NewArrayElements);
424 }
425
426 // If not a vector or array, return the original initializer
427 return Init;
428}
429
431 bool MadeChange = false;
432 LLVMContext &Ctx = M.getContext();
433 IRBuilder<> Builder(M);
435 for (GlobalVariable &G : M.globals()) {
436 Type *OrigType = G.getValueType();
437
438 Type *NewType = equivalentArrayTypeFromVector(OrigType);
439 if (OrigType != NewType) {
440 // Create a new global variable with the updated type
441 // Note: Initializer is set via transformInitializer
442 GlobalVariable *NewGlobal = new GlobalVariable(
443 M, NewType, G.isConstant(), G.getLinkage(),
444 /*Initializer=*/nullptr, G.getName() + ".scalarized", &G,
445 G.getThreadLocalMode(), G.getAddressSpace(),
446 G.isExternallyInitialized());
447
448 // Copy relevant attributes
449 NewGlobal->setUnnamedAddr(G.getUnnamedAddr());
450 if (G.getAlign()) {
451 NewGlobal->setAlignment(G.getAlign());
452 }
453
454 if (G.hasInitializer()) {
455 Constant *Init = G.getInitializer();
456 Constant *NewInit = transformInitializer(Init, OrigType, NewType, Ctx);
457 NewGlobal->setInitializer(NewInit);
458 }
459
460 // Note: we want to do G.replaceAllUsesWith(NewGlobal);, but it assumes
461 // type equality. Instead we will use the visitor pattern.
462 Impl.GlobalMap[&G] = NewGlobal;
463 }
464 }
465
466 for (auto &F : make_early_inc_range(M.functions())) {
467 if (F.isDeclaration())
468 continue;
469 MadeChange |= Impl.visit(F);
470 }
471
472 // Remove the old globals after the iteration
473 for (auto &[Old, New] : Impl.GlobalMap) {
474 Old->eraseFromParent();
475 MadeChange = true;
476 }
477 return MadeChange;
478}
479
482 bool MadeChanges = findAndReplaceVectors(M);
483 if (!MadeChanges)
484 return PreservedAnalyses::all();
486 return PA;
487}
488
492
494
496 "DXIL Data Scalarization", false, false)
498 "DXIL Data Scalarization", false, false)
499
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
Rewrite undef for PHI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool findAndReplaceVectors(Module &M)
static std::pair< Value *, Value * > dynamicallyLoadArray(IRBuilder<> &Builder, AllocaInst *ArrAlloca, Type *ArrTy, Value *Index, const Twine &Name="")
Returns a pair of Value* with the first being a GEP into ArrAlloca using indices {0,...
static bool isVectorOrArrayOfVectors(Type *T)
static Type * equivalentArrayTypeFromVector(Type *T)
static const int MaxVecSize
static Constant * transformInitializer(Constant *Init, Type *OrigType, Type *NewType, LLVMContext &Ctx)
#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:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
#define T
#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 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
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
void setAlignment(Align Align)
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
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:512
static LLVM_ABI ConstantAggregateZero * get(Type *Ty)
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
A constant value that is initialized with an expression using other constant values.
Definition Constants.h:1316
This is an important base class in LLVM.
Definition Constant.h:44
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:757
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 ...
op_iterator idx_end()
Definition Operator.h:406
LLVM_ABI Type * getSourceElementType() const
Definition Operator.cpp:86
op_iterator idx_begin()
Definition Operator.h:404
Value * getPointerOperand()
Definition Operator.h:417
GEPNoWrapFlags getNoWrapFlags() const
Definition Operator.h:385
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
iterator_range< op_iterator > indices()
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Type * getSourceElementType() const
static GetElementPtrInst * CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Create an "inbounds" getelementptr.
LLVM_ABI GEPNoWrapFlags getNoWrapFlags() const
Get the nowrap flags for the GEP instruction.
void setUnnamedAddr(UnnamedAddr Val)
LLVM_ABI void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
Definition Globals.cpp:613
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:2707
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition IRBuilder.h:1880
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2695
BasicBlock::iterator GetInsertPoint() const
Definition IRBuilder.h:176
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition IRBuilder.h:465
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:1907
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition IRBuilder.h:2159
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition IRBuilder.h:1925
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2145
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:196
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2947
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:76
An instruction for reading from memory.
void setAlignment(Align Align)
Value * getPointerOperand()
static unsigned getPointerOperandIndex()
Align getAlign() const
Return the alignment of the access that is being performed.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition Pass.h:253
ModulePass(char &pid)
Definition Pass.h:255
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
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)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
void setAlignment(Align Align)
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:46
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
Type * getArrayElementType() const
Definition Type.h:420
LLVM_ABI uint64_t getArrayNumElements() const
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
void setOperand(unsigned i, Value *Val)
Definition User.h:212
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:548
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
self_iterator getIterator()
Definition ilist_node.h:123
NodeAddr< InstrNode * > Instr
Definition RDFGraph.h:389
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
ModulePass * createDXILDataScalarizationLegacyPass()
@ Load
The value being inserted comes from a load (InsertElement only).
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:649
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39