LLVM 24.0.0git
DXILFlattenArrays.cpp
Go to the documentation of this file.
1//===- DXILFlattenArrays.cpp - Flattens DXIL Arrays-----------------------===//
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/// \file This file contains a pass to flatten arrays for the DirectX Backend.
10///
11//===----------------------------------------------------------------------===//
12
13#include "DirectX.h"
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/IR/BasicBlock.h"
18#include "llvm/IR/IRBuilder.h"
19#include "llvm/IR/InstVisitor.h"
24#include <cassert>
25#include <cstddef>
26#include <cstdint>
27#include <utility>
28
29#define DEBUG_TYPE "dxil-flatten-arrays"
30
31using namespace llvm;
32namespace {
33
34class DXILFlattenArraysLegacy : public ModulePass {
35
36public:
37 bool runOnModule(Module &M) override;
38 DXILFlattenArraysLegacy() : ModulePass(ID) {}
39
40 static char ID; // Pass identification.
41};
42
43struct GEPInfo {
44 ArrayType *RootFlattenedArrayType;
45 Value *RootPointerOperand;
47 APInt ConstantOffset;
48};
49
50class DXILFlattenArraysVisitor
51 : public InstVisitor<DXILFlattenArraysVisitor, bool> {
52public:
53 DXILFlattenArraysVisitor(
55 : GlobalMap(GlobalMap) {}
56 bool visit(Function &F);
57 // InstVisitor methods. They return true if the instruction was scalarized,
58 // false if nothing changed.
59 bool visitGetElementPtrInst(GetElementPtrInst &GEPI);
60 bool visitAllocaInst(AllocaInst &AI);
61 bool visitInstruction(Instruction &I) { return false; }
62 bool visitSelectInst(SelectInst &SI) { return false; }
63 bool visitICmpInst(ICmpInst &ICI) { return false; }
64 bool visitFCmpInst(FCmpInst &FCI) { return false; }
65 bool visitUnaryOperator(UnaryOperator &UO) { return false; }
66 bool visitBinaryOperator(BinaryOperator &BO) { return false; }
67 bool visitCastInst(CastInst &CI) { return false; }
68 bool visitBitCastInst(BitCastInst &BCI) { return false; }
69 bool visitInsertElementInst(InsertElementInst &IEI) { return false; }
70 bool visitExtractElementInst(ExtractElementInst &EEI) { return false; }
71 bool visitShuffleVectorInst(ShuffleVectorInst &SVI) { return false; }
72 bool visitPHINode(PHINode &PHI) { return false; }
73 bool visitLoadInst(LoadInst &LI);
74 bool visitStoreInst(StoreInst &SI);
75 bool visitCallInst(CallInst &ICI) { return false; }
76 bool visitFreezeInst(FreezeInst &FI) { return false; }
77 static bool isMultiDimensionalArray(Type *T);
78 static std::pair<unsigned, Type *> getElementCountAndType(Type *ArrayTy);
79
80private:
81 SmallVector<WeakTrackingVH> PotentiallyDeadInstrs;
84 bool finish();
85 ConstantInt *genConstFlattenIndices(ArrayRef<Value *> Indices,
87 IRBuilder<> &Builder);
88 Value *genInstructionFlattenIndices(ArrayRef<Value *> Indices,
90 IRBuilder<> &Builder);
91};
92} // namespace
93
94bool DXILFlattenArraysVisitor::finish() {
95 GEPChainInfoMap.clear();
97 return true;
98}
99
100bool DXILFlattenArraysVisitor::isMultiDimensionalArray(Type *T) {
101 if (ArrayType *ArrType = dyn_cast<ArrayType>(T))
102 return isa<ArrayType>(ArrType->getElementType());
103 return false;
104}
105
106std::pair<unsigned, Type *>
107DXILFlattenArraysVisitor::getElementCountAndType(Type *ArrayTy) {
108 unsigned TotalElements = 1;
109 Type *CurrArrayTy = ArrayTy;
110 while (auto *InnerArrayTy = dyn_cast<ArrayType>(CurrArrayTy)) {
111 TotalElements *= InnerArrayTy->getNumElements();
112 CurrArrayTy = InnerArrayTy->getElementType();
113 }
114 return std::make_pair(TotalElements, CurrArrayTy);
115}
116
117ConstantInt *DXILFlattenArraysVisitor::genConstFlattenIndices(
118 ArrayRef<Value *> Indices, ArrayRef<uint64_t> Dims, IRBuilder<> &Builder) {
119 assert(Indices.size() == Dims.size() &&
120 "Indicies and dimmensions should be the same");
121 unsigned FlatIndex = 0;
122 unsigned Multiplier = 1;
123
124 for (int I = Indices.size() - 1; I >= 0; --I) {
125 unsigned DimSize = Dims[I];
126 ConstantInt *CIndex = dyn_cast<ConstantInt>(Indices[I]);
127 assert(CIndex && "This function expects all indicies to be ConstantInt");
128 FlatIndex += CIndex->getZExtValue() * Multiplier;
129 Multiplier *= DimSize;
130 }
131 return Builder.getInt32(FlatIndex);
132}
133
134Value *DXILFlattenArraysVisitor::genInstructionFlattenIndices(
135 ArrayRef<Value *> Indices, ArrayRef<uint64_t> Dims, IRBuilder<> &Builder) {
136 if (Indices.size() == 1)
137 return Indices[0];
138
139 Value *FlatIndex = Builder.getInt32(0);
140 unsigned Multiplier = 1;
141
142 for (int I = Indices.size() - 1; I >= 0; --I) {
143 unsigned DimSize = Dims[I];
144 Value *VMultiplier = Builder.getInt32(Multiplier);
145 Value *ScaledIndex = Builder.CreateMul(Indices[I], VMultiplier);
146 FlatIndex = Builder.CreateAdd(FlatIndex, ScaledIndex);
147 Multiplier *= DimSize;
148 }
149 return FlatIndex;
150}
151
152bool DXILFlattenArraysVisitor::visitLoadInst(LoadInst &LI) {
153 unsigned NumOperands = LI.getNumOperands();
154 for (unsigned I = 0; I < NumOperands; ++I) {
155 Value *CurrOpperand = LI.getOperand(I);
156 ConstantExpr *CE = dyn_cast<ConstantExpr>(CurrOpperand);
157 if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
158 GetElementPtrInst *OldGEP =
159 cast<GetElementPtrInst>(CE->getAsInstruction());
160 OldGEP->insertBefore(LI.getIterator());
161
162 IRBuilder<> Builder(&LI);
163 LoadInst *NewLoad =
164 Builder.CreateLoad(LI.getType(), OldGEP, LI.getName());
165 NewLoad->setAlignment(LI.getAlign());
166 LI.replaceAllUsesWith(NewLoad);
167 LI.eraseFromParent();
168 visitGetElementPtrInst(*OldGEP);
169 return true;
170 }
171 }
172 return false;
173}
174
175bool DXILFlattenArraysVisitor::visitStoreInst(StoreInst &SI) {
176 unsigned NumOperands = SI.getNumOperands();
177 for (unsigned I = 0; I < NumOperands; ++I) {
178 Value *CurrOpperand = SI.getOperand(I);
179 ConstantExpr *CE = dyn_cast<ConstantExpr>(CurrOpperand);
180 if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
181 GetElementPtrInst *OldGEP =
182 cast<GetElementPtrInst>(CE->getAsInstruction());
183 OldGEP->insertBefore(SI.getIterator());
184
185 IRBuilder<> Builder(&SI);
186 StoreInst *NewStore = Builder.CreateStore(SI.getValueOperand(), OldGEP);
187 NewStore->setAlignment(SI.getAlign());
188 SI.replaceAllUsesWith(NewStore);
189 SI.eraseFromParent();
190 visitGetElementPtrInst(*OldGEP);
191 return true;
192 }
193 }
194 return false;
195}
196
197bool DXILFlattenArraysVisitor::visitAllocaInst(AllocaInst &AI) {
198 if (!isMultiDimensionalArray(AI.getAllocatedType()))
199 return false;
200
202 IRBuilder<> Builder(&AI);
203 auto [TotalElements, BaseType] = getElementCountAndType(ArrType);
204
205 ArrayType *FattenedArrayType = ArrayType::get(BaseType, TotalElements);
206 AllocaInst *FlatAlloca =
207 Builder.CreateAlloca(FattenedArrayType, nullptr, AI.getName() + ".1dim");
208 FlatAlloca->setAlignment(AI.getAlign());
209 AI.replaceAllUsesWith(FlatAlloca);
210 AI.eraseFromParent();
211 return true;
212}
213
214bool DXILFlattenArraysVisitor::visitGetElementPtrInst(GetElementPtrInst &GEP) {
215 // Do not visit GEPs more than once
216 if (GEPChainInfoMap.contains(cast<GEPOperator>(&GEP)))
217 return false;
218
219 Value *PtrOperand = GEP.getPointerOperand();
220 // It shouldn't(?) be possible for the pointer operand of a GEP to be a PHI
221 // node unless HLSL has pointers. If this assumption is incorrect or HLSL gets
222 // pointer types, then the handling of this case can be implemented later.
223 assert(!isa<PHINode>(PtrOperand) &&
224 "Pointer operand of GEP should not be a PHI Node");
225
226 // Replace a GEP ConstantExpr pointer operand with a GEP instruction so that
227 // it can be visited
228 if (auto *PtrOpGEPCE = dyn_cast<ConstantExpr>(PtrOperand);
229 PtrOpGEPCE && PtrOpGEPCE->getOpcode() == Instruction::GetElementPtr) {
230 GetElementPtrInst *OldGEPI =
231 cast<GetElementPtrInst>(PtrOpGEPCE->getAsInstruction());
232 OldGEPI->insertBefore(GEP.getIterator());
233
234 SmallVector<Value *> Indices(GEP.indices());
235 GetElementPtrInst *NewGEPI = GetElementPtrInst::Create(
236 GEP.getSourceElementType(), OldGEPI, Indices, GEP.getNoWrapFlags(),
237 GEP.getName(), GEP.getIterator());
238
239 GEP.replaceAllUsesWith(NewGEPI);
240 GEP.eraseFromParent();
241 visitGetElementPtrInst(*OldGEPI);
242 visitGetElementPtrInst(*NewGEPI);
243 return true;
244 }
245
246 // Construct GEPInfo for this GEP
247 GEPInfo Info;
248
249 // Obtain the variable and constant byte offsets computed by this GEP
250 const DataLayout &DL = GEP.getDataLayout();
251 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP.getType());
252 Info.ConstantOffset = {BitWidth, 0};
253 [[maybe_unused]] bool Success = GEP.collectOffset(
254 DL, BitWidth, Info.VariableOffsets, Info.ConstantOffset);
255 assert(Success && "Failed to collect offsets for GEP");
256
257 // If there is a parent GEP, inherit the root array type and pointer, and
258 // merge the byte offsets. Otherwise, this GEP is itself the root of a GEP
259 // chain and we need to deterine the root array type
260 if (auto *PtrOpGEP = dyn_cast<GEPOperator>(PtrOperand)) {
261
262 // If the parent GEP was not processed, then we do not want to process its
263 // descendants. This can happen if the GEP chain is for an unsupported type
264 // such as a struct -- we do not flatten structs nor GEP chains for structs
265 if (!GEPChainInfoMap.contains(PtrOpGEP))
266 return false;
267
268 GEPInfo &PGEPInfo = GEPChainInfoMap[PtrOpGEP];
269 Info.RootFlattenedArrayType = PGEPInfo.RootFlattenedArrayType;
270 Info.RootPointerOperand = PGEPInfo.RootPointerOperand;
271 for (auto &VariableOffset : PGEPInfo.VariableOffsets)
272 Info.VariableOffsets.insert(VariableOffset);
273 Info.ConstantOffset += PGEPInfo.ConstantOffset;
274 } else {
275 Info.RootPointerOperand = PtrOperand;
276
277 // We should try to determine the type of the root from the pointer rather
278 // than the GEP's source element type because this could be a scalar GEP
279 // into an array-typed pointer from an Alloca or Global Variable.
280 Type *RootTy = GEP.getSourceElementType();
281 if (auto *GlobalVar = dyn_cast<GlobalVariable>(PtrOperand)) {
282 if (GlobalMap.contains(GlobalVar))
283 GlobalVar = GlobalMap[GlobalVar];
284 Info.RootPointerOperand = GlobalVar;
285 RootTy = GlobalVar->getValueType();
286 } else if (auto *Alloca = dyn_cast<AllocaInst>(PtrOperand))
287 RootTy = Alloca->getAllocatedType();
288 assert(!isMultiDimensionalArray(RootTy) &&
289 "Expected root array type to be flattened");
290
291 // If the root type is not an array, we don't need to do any flattening
292 if (!isa<ArrayType>(RootTy))
293 return false;
294
295 Info.RootFlattenedArrayType = cast<ArrayType>(RootTy);
296 }
297
298 // GEPs without users or GEPs with non-GEP users should be replaced such that
299 // the chain of GEPs they are a part of are collapsed to a single GEP into a
300 // flattened array.
301 bool ReplaceThisGEP = GEP.users().empty();
302 for (Value *User : GEP.users())
303 if (!isa<GetElementPtrInst>(User))
304 ReplaceThisGEP = true;
305
306 if (ReplaceThisGEP) {
307 unsigned BytesPerElem =
308 DL.getTypeAllocSize(Info.RootFlattenedArrayType->getArrayElementType());
309 assert(isPowerOf2_32(BytesPerElem) &&
310 "Bytes per element should be a power of 2");
311
312 // Compute the 32-bit index for this flattened GEP from the constant and
313 // variable byte offsets in the GEPInfo
314 IRBuilder<> Builder(&GEP);
315 Value *ZeroIndex = Builder.getInt32(0);
316 uint64_t ConstantOffset =
317 Info.ConstantOffset.udiv(BytesPerElem).getZExtValue();
318 assert(ConstantOffset < UINT32_MAX &&
319 "Constant byte offset for flat GEP index must fit within 32 bits");
320 Value *FlattenedIndex = Builder.getInt32(ConstantOffset);
321 for (auto [VarIndex, Multiplier] : Info.VariableOffsets) {
322 assert(Multiplier.getActiveBits() <= 32 &&
323 "The multiplier for a flat GEP index must fit within 32 bits");
324 assert(VarIndex->getType()->isIntegerTy(32) &&
325 "Expected i32-typed GEP indices");
326 Value *VI;
327 if (Multiplier.getZExtValue() % BytesPerElem != 0) {
328 // This can happen, e.g., with i8 GEPs. To handle this we just divide
329 // by BytesPerElem using an instruction after multiplying VarIndex by
330 // Multiplier.
331 VI = Builder.CreateMul(VarIndex,
332 Builder.getInt32(Multiplier.getZExtValue()));
333 VI = Builder.CreateLShr(VI, Builder.getInt32(Log2_32(BytesPerElem)));
334 } else
335 VI = Builder.CreateMul(
336 VarIndex,
337 Builder.getInt32(Multiplier.getZExtValue() / BytesPerElem));
338 FlattenedIndex = Builder.CreateAdd(FlattenedIndex, VI);
339 }
340
341 // Construct a new GEP for the flattened array to replace the current GEP
342 GetElementPtrInst *NewGEP = GetElementPtrInst::Create(
343 Info.RootFlattenedArrayType, Info.RootPointerOperand,
344 {ZeroIndex, FlattenedIndex}, GEP.getNoWrapFlags(), GEP.getName(),
345 Builder.GetInsertPoint());
346
347 // Replace the current GEP with the new GEP. Store GEPInfo into the map
348 // for later use in case this GEP was not the end of the chain
349 GEPChainInfoMap.insert({cast<GEPOperator>(NewGEP), std::move(Info)});
350 GEP.replaceAllUsesWith(NewGEP);
351 GEP.eraseFromParent();
352 return true;
353 }
354
355 // This GEP is potentially dead at the end of the pass since it may not have
356 // any users anymore after GEP chains have been collapsed. We retain store
357 // GEPInfo for GEPs down the chain to use to compute their indices.
358 GEPChainInfoMap.insert({cast<GEPOperator>(&GEP), std::move(Info)});
359 PotentiallyDeadInstrs.emplace_back(&GEP);
360 return false;
361}
362
363bool DXILFlattenArraysVisitor::visit(Function &F) {
364 bool MadeChange = false;
365 ReversePostOrderTraversal<Function *> RPOT(&F);
366 for (BasicBlock *BB : make_early_inc_range(RPOT)) {
367 for (Instruction &I : make_early_inc_range(*BB))
368 MadeChange |= InstVisitor::visit(I);
369 }
370 finish();
371 return MadeChange;
372}
373
375 SmallVectorImpl<Constant *> &Elements) {
376 // Base case: If Init is not an array, add it directly to the vector.
377 auto *ArrayTy = dyn_cast<ArrayType>(Init->getType());
378 if (!ArrayTy) {
379 Elements.push_back(Init);
380 return;
381 }
382 unsigned ArrSize = ArrayTy->getNumElements();
384 for (unsigned I = 0; I < ArrSize; ++I)
385 Elements.push_back(Constant::getNullValue(ArrayTy->getElementType()));
386 return;
387 }
388
389 // Recursive case: Process each element in the array.
390 if (auto *ArrayConstant = dyn_cast<ConstantArray>(Init)) {
391 for (unsigned I = 0; I < ArrayConstant->getNumOperands(); ++I) {
392 collectElements(ArrayConstant->getOperand(I), Elements);
393 }
394 } else if (auto *DataArrayConstant = dyn_cast<ConstantDataArray>(Init)) {
395 for (unsigned I = 0; I < DataArrayConstant->getNumElements(); ++I) {
396 collectElements(DataArrayConstant->getElementAsConstant(I), Elements);
397 }
398 } else {
400 "Expected a ConstantArray or ConstantDataArray for array initializer!");
401 }
402}
403
405 ArrayType *FlattenedType,
406 LLVMContext &Ctx) {
407 // Handle ConstantAggregateZero (zero-initialized constants)
409 return ConstantAggregateZero::get(FlattenedType);
410
411 // Handle UndefValue (undefined constants)
413 return UndefValue::get(FlattenedType);
414
415 if (!isa<ArrayType>(OrigType))
416 return Init;
417
418 SmallVector<Constant *> FlattenedElements;
419 collectElements(Init, FlattenedElements);
420 assert(FlattenedType->getNumElements() == FlattenedElements.size() &&
421 "The number of collected elements should match the FlattenedType");
422 return ConstantArray::get(FlattenedType, FlattenedElements);
423}
424
427 LLVMContext &Ctx = M.getContext();
428 for (GlobalVariable &G : M.globals()) {
429 Type *OrigType = G.getValueType();
430 if (!DXILFlattenArraysVisitor::isMultiDimensionalArray(OrigType))
431 continue;
432
433 ArrayType *ArrType = cast<ArrayType>(OrigType);
434 auto [TotalElements, BaseType] =
435 DXILFlattenArraysVisitor::getElementCountAndType(ArrType);
436 ArrayType *FattenedArrayType = ArrayType::get(BaseType, TotalElements);
437
438 // Create a new global variable with the updated type
439 // Note: Initializer is set via transformInitializer
440 GlobalVariable *NewGlobal =
441 new GlobalVariable(M, FattenedArrayType, G.isConstant(), G.getLinkage(),
442 /*Initializer=*/nullptr, G.getName() + ".1dim", &G,
443 G.getThreadLocalMode(), G.getAddressSpace(),
444 G.isExternallyInitialized());
445
446 // Copy relevant attributes
447 NewGlobal->setUnnamedAddr(G.getUnnamedAddr());
448 if (G.getAlign()) {
449 NewGlobal->setAlignment(G.getAlign());
450 }
451
452 if (G.hasInitializer()) {
453 Constant *Init = G.getInitializer();
454 Constant *NewInit =
455 transformInitializer(Init, OrigType, FattenedArrayType, Ctx);
456 NewGlobal->setInitializer(NewInit);
457 }
458 GlobalMap[&G] = NewGlobal;
459 }
460}
461
462static bool flattenArrays(Module &M) {
463 bool MadeChange = false;
465 flattenGlobalArrays(M, GlobalMap);
466 DXILFlattenArraysVisitor Impl(GlobalMap);
467 for (auto &F : make_early_inc_range(M.functions())) {
468 if (F.isDeclaration())
469 continue;
470 MadeChange |= Impl.visit(F);
471 }
472 for (auto &[Old, New] : GlobalMap) {
473 Old->replaceAllUsesWith(New);
474 Old->eraseFromParent();
475 MadeChange = true;
476 }
477 return MadeChange;
478}
479
482 bool MadeChanges = flattenArrays(M);
483 if (!MadeChanges)
484 return PreservedAnalyses::all();
486 return PA;
487}
488
489bool DXILFlattenArraysLegacy::runOnModule(Module &M) {
490 return flattenArrays(M);
491}
492
493char DXILFlattenArraysLegacy::ID = 0;
494
495INITIALIZE_PASS_BEGIN(DXILFlattenArraysLegacy, DEBUG_TYPE,
496 "DXIL Array Flattener", false, false)
497INITIALIZE_PASS_END(DXILFlattenArraysLegacy, DEBUG_TYPE, "DXIL Array Flattener",
499
501 return new DXILFlattenArraysLegacy();
502}
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
Rewrite undef for PHI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static Constant * transformInitializer(Constant *Init, Type *OrigType, Type *NewType, LLVMContext &Ctx)
static void collectElements(Constant *Init, SmallVectorImpl< Constant * > &Elements)
static bool flattenArrays(Module &M)
static void flattenGlobalArrays(Module &M, SmallDenseMap< GlobalVariable *, GlobalVariable * > &GlobalMap)
#define DEBUG_TYPE
Hexagon Common GEP
#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.
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
Class for arbitrary precision integers.
Definition APInt.h:78
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)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
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)
This is the shared class of boolean and integer constants.
Definition Constants.h:87
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition Constants.h:168
This is an important base class in LLVM.
Definition Constant.h:44
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
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 ...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
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.
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition IRBuilder.h:1880
BasicBlock::iterator GetInsertPoint() const
Definition IRBuilder.h:176
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1528
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
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition IRBuilder.h:1925
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1418
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1452
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2909
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)
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
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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)
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
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:549
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
self_iterator getIterator()
Definition ilist_node.h:123
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:51
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
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
ModulePass * createDXILFlattenArraysLegacyPass()
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(SmallVectorImpl< WeakTrackingVH > &DeadInsts, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
Same functionality as RecursivelyDeleteTriviallyDeadInstructions, but allow instructions that are not...
Definition Local.cpp:537
constexpr unsigned BitWidth
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
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342