LLVM 24.0.0git
DXILLegalizePass.cpp
Go to the documentation of this file.
1//===- DXILLegalizePass.cpp - Legalizes llvm IR for DXIL ------------------===//
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 "DXILLegalizePass.h"
10#include "DirectX.h"
11#include "llvm/ADT/APInt.h"
12#include "llvm/IR/Constants.h"
13#include "llvm/IR/Function.h"
14#include "llvm/IR/IRBuilder.h"
16#include "llvm/IR/Instruction.h"
18#include "llvm/IR/Module.h"
19#include "llvm/Pass.h"
23#include <functional>
24
25#define DEBUG_TYPE "dxil-legalize"
26
27using namespace llvm;
28
32 auto *FI = dyn_cast<FreezeInst>(&I);
33 if (!FI)
34 return false;
35
36 FI->replaceAllUsesWith(FI->getOperand(0));
37 ToRemove.push_back(FI);
38 return true;
39}
40
43 DenseMap<Value *, Value *> &ReplacedValues) {
44
45 auto ProcessOperands = [&](SmallVector<Value *> &NewOperands) {
46 Type *InstrType = IntegerType::get(I.getContext(), 32);
47
48 for (unsigned OpIdx = 0; OpIdx < I.getNumOperands(); ++OpIdx) {
49 Value *Op = I.getOperand(OpIdx);
50 if (ReplacedValues.count(Op) &&
51 ReplacedValues[Op]->getType()->isIntegerTy())
52 InstrType = ReplacedValues[Op]->getType();
53 }
54
55 for (unsigned OpIdx = 0; OpIdx < I.getNumOperands(); ++OpIdx) {
56 Value *Op = I.getOperand(OpIdx);
57 if (ReplacedValues.count(Op))
58 NewOperands.push_back(ReplacedValues[Op]);
59 else if (auto *Imm = dyn_cast<ConstantInt>(Op)) {
60 APInt Value = Imm->getValue();
61 unsigned NewBitWidth = InstrType->getIntegerBitWidth();
62 // Note: options here are sext or sextOrTrunc.
63 // Since i8 isn't supported, we assume new values
64 // will always have a higher bitness.
65 assert(NewBitWidth > Value.getBitWidth() &&
66 "Replacement's BitWidth should be larger than Current.");
67 APInt NewValue = Value.sext(NewBitWidth);
68 NewOperands.push_back(ConstantInt::get(InstrType, NewValue));
69 } else {
70 assert(!Op->getType()->isIntegerTy(8));
71 NewOperands.push_back(Op);
72 }
73 }
74 };
75 IRBuilder<> Builder(&I);
76 if (auto *Trunc = dyn_cast<TruncInst>(&I)) {
77 if (Trunc->getDestTy()->isIntegerTy(8)) {
78 ReplacedValues[Trunc] = Trunc->getOperand(0);
79 ToRemove.push_back(Trunc);
80 return true;
81 }
82 }
83
84 if (auto *Store = dyn_cast<StoreInst>(&I)) {
85 if (!Store->getValueOperand()->getType()->isIntegerTy(8))
86 return false;
87 SmallVector<Value *> NewOperands;
88 ProcessOperands(NewOperands);
89 Value *NewStore = Builder.CreateStore(NewOperands[0], NewOperands[1]);
90 ReplacedValues[Store] = NewStore;
91 ToRemove.push_back(Store);
92 return true;
93 }
94
95 if (auto *Load = dyn_cast<LoadInst>(&I);
96 Load && I.getType()->isIntegerTy(8)) {
97 SmallVector<Value *> NewOperands;
98 ProcessOperands(NewOperands);
99 Type *ElementType = NewOperands[0]->getType();
100 if (auto *AI = dyn_cast<AllocaInst>(NewOperands[0]))
101 ElementType = AI->getAllocatedType();
102 if (auto *GEP = dyn_cast<GetElementPtrInst>(NewOperands[0])) {
103 ElementType = GEP->getSourceElementType();
104 }
105 if (ElementType->isArrayTy())
106 ElementType = ElementType->getArrayElementType();
107 LoadInst *NewLoad = Builder.CreateLoad(ElementType, NewOperands[0]);
108 ReplacedValues[Load] = NewLoad;
109 ToRemove.push_back(Load);
110 return true;
111 }
112
113 if (auto *Load = dyn_cast<LoadInst>(&I);
114 Load && isa<ConstantExpr>(Load->getPointerOperand())) {
115 auto *CE = dyn_cast<ConstantExpr>(Load->getPointerOperand());
116 if (!(CE->getOpcode() == Instruction::GetElementPtr))
117 return false;
118 auto *GEP = dyn_cast<GEPOperator>(CE);
119 if (!GEP->getSourceElementType()->isIntegerTy(8))
120 return false;
121
122 Type *ElementType = Load->getType();
123 ConstantInt *Offset = dyn_cast<ConstantInt>(GEP->getOperand(1));
124 uint32_t ByteOffset = Offset->getZExtValue();
125 uint32_t ElemSize = Load->getDataLayout().getTypeAllocSize(ElementType);
126 uint32_t Index = ByteOffset / ElemSize;
127
128 Value *PtrOperand = GEP->getPointerOperand();
129 Type *GEPType = GEP->getPointerOperandType();
130
131 if (auto *GV = dyn_cast<GlobalVariable>(PtrOperand))
132 GEPType = GV->getValueType();
133 if (auto *AI = dyn_cast<AllocaInst>(PtrOperand))
134 GEPType = AI->getAllocatedType();
135
136 if (auto *ArrTy = dyn_cast<ArrayType>(GEPType))
137 GEPType = ArrTy;
138 else
139 GEPType = ArrayType::get(ElementType, 1); // its a scalar
140
141 Value *NewGEP = Builder.CreateGEP(
142 GEPType, PtrOperand, {Builder.getInt32(0), Builder.getInt32(Index)},
143 GEP->getName(), GEP->getNoWrapFlags());
144
145 LoadInst *NewLoad = Builder.CreateLoad(ElementType, NewGEP);
146 ReplacedValues[Load] = NewLoad;
147 Load->replaceAllUsesWith(NewLoad);
148 ToRemove.push_back(Load);
149 return true;
150 }
151
152 if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
153 if (!I.getType()->isIntegerTy(8))
154 return false;
155 SmallVector<Value *> NewOperands;
156 ProcessOperands(NewOperands);
157 Value *NewInst =
158 Builder.CreateBinOp(BO->getOpcode(), NewOperands[0], NewOperands[1]);
159 if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(&I)) {
160 auto *NewBO = dyn_cast<BinaryOperator>(NewInst);
161 if (NewBO && OBO->hasNoSignedWrap())
162 NewBO->setHasNoSignedWrap();
163 if (NewBO && OBO->hasNoUnsignedWrap())
164 NewBO->setHasNoUnsignedWrap();
165 }
166 ReplacedValues[BO] = NewInst;
167 ToRemove.push_back(BO);
168 return true;
169 }
170
171 if (auto *Sel = dyn_cast<SelectInst>(&I)) {
172 if (!I.getType()->isIntegerTy(8))
173 return false;
174 SmallVector<Value *> NewOperands;
175 ProcessOperands(NewOperands);
176 Value *NewInst = Builder.CreateSelect(Sel->getCondition(), NewOperands[1],
177 NewOperands[2]);
178 ReplacedValues[Sel] = NewInst;
179 ToRemove.push_back(Sel);
180 return true;
181 }
182
183 if (auto *Cmp = dyn_cast<CmpInst>(&I)) {
184 if (!Cmp->getOperand(0)->getType()->isIntegerTy(8))
185 return false;
186 SmallVector<Value *> NewOperands;
187 ProcessOperands(NewOperands);
188 Value *NewInst =
189 Builder.CreateCmp(Cmp->getPredicate(), NewOperands[0], NewOperands[1]);
190 Cmp->replaceAllUsesWith(NewInst);
191 ReplacedValues[Cmp] = NewInst;
192 ToRemove.push_back(Cmp);
193 return true;
194 }
195
196 if (auto *Cast = dyn_cast<CastInst>(&I)) {
197 if (!Cast->getSrcTy()->isIntegerTy(8))
198 return false;
199
200 ToRemove.push_back(Cast);
201 auto *Replacement = ReplacedValues[Cast->getOperand(0)];
202 if (Cast->getType() == Replacement->getType()) {
203 Cast->replaceAllUsesWith(Replacement);
204 return true;
205 }
206
207 Value *AdjustedCast = nullptr;
208 if (Cast->getOpcode() == Instruction::ZExt)
209 AdjustedCast = Builder.CreateZExtOrTrunc(Replacement, Cast->getType());
210 if (Cast->getOpcode() == Instruction::SExt)
211 AdjustedCast = Builder.CreateSExtOrTrunc(Replacement, Cast->getType());
212
213 if (AdjustedCast)
214 Cast->replaceAllUsesWith(AdjustedCast);
215 }
216 if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
217 if (!GEP->getType()->isPointerTy() ||
218 !GEP->getSourceElementType()->isIntegerTy(8))
219 return false;
220
221 Value *BasePtr = GEP->getPointerOperand();
222 if (ReplacedValues.count(BasePtr))
223 BasePtr = ReplacedValues[BasePtr];
224
225 Type *ElementType = BasePtr->getType();
226
227 if (auto *AI = dyn_cast<AllocaInst>(BasePtr))
228 ElementType = AI->getAllocatedType();
229 if (auto *GV = dyn_cast<GlobalVariable>(BasePtr))
230 ElementType = GV->getValueType();
231
232 Type *GEPType = ElementType;
233 if (auto *ArrTy = dyn_cast<ArrayType>(ElementType))
234 ElementType = ArrTy->getArrayElementType();
235 else
236 GEPType = ArrayType::get(ElementType, 1); // its a scalar
237
238 ConstantInt *Offset = dyn_cast<ConstantInt>(GEP->getOperand(1));
239 // Note: i8 to i32 offset conversion without emitting IR requires constant
240 // ints. Since offset conversion is common, we can safely assume Offset is
241 // always a ConstantInt, so no need to have a conditional bail out on
242 // nullptr, instead assert this is the case.
243 assert(Offset && "Offset is expected to be a ConstantInt");
244 uint32_t ByteOffset = Offset->getZExtValue();
245 uint32_t ElemSize = GEP->getDataLayout().getTypeAllocSize(ElementType);
246 assert(ElemSize > 0 && "ElementSize must be set");
247 uint32_t Index = ByteOffset / ElemSize;
248 Value *NewGEP = Builder.CreateGEP(
249 GEPType, BasePtr, {Builder.getInt32(0), Builder.getInt32(Index)},
250 GEP->getName(), GEP->getNoWrapFlags());
251 ReplacedValues[GEP] = NewGEP;
252 GEP->replaceAllUsesWith(NewGEP);
253 ToRemove.push_back(GEP);
254 return true;
255 }
256 return false;
257}
258
261 DenseMap<Value *, Value *> &ReplacedValues) {
262 auto *AI = dyn_cast<AllocaInst>(&I);
263 if (!AI || !AI->getAllocatedType()->isIntegerTy(8))
264 return false;
265
266 Type *SmallestType = nullptr;
267
268 auto ProcessLoad = [&](LoadInst *Load) {
269 for (User *LU : Load->users()) {
270 CastInst *Cast = dyn_cast<CastInst>(LU);
271 if (!Cast)
272 continue;
273 Type *Ty = Cast->getType();
274
275 if (!SmallestType ||
276 Ty->getPrimitiveSizeInBits() < SmallestType->getPrimitiveSizeInBits())
277 SmallestType = Ty;
278 }
279 };
280
281 for (User *U : AI->users()) {
282 if (auto *Load = dyn_cast<LoadInst>(U))
283 ProcessLoad(Load);
284 else if (auto *GEP = dyn_cast<GetElementPtrInst>(U)) {
285 for (User *GU : GEP->users()) {
286 if (auto *Load = dyn_cast<LoadInst>(GU))
287 ProcessLoad(Load);
288 }
289 }
290 }
291
292 if (!SmallestType)
293 return false; // no valid casts found
294
295 // Replace alloca
296 IRBuilder<> Builder(AI);
297 auto *NewAlloca = Builder.CreateAlloca(SmallestType);
298 ReplacedValues[AI] = NewAlloca;
299 ToRemove.push_back(AI);
300 return true;
301}
302
303static bool
307
308 if (auto *Extract = dyn_cast<ExtractElementInst>(&I)) {
309 Value *Idx = Extract->getIndexOperand();
310 auto *CI = dyn_cast<ConstantInt>(Idx);
311 if (CI && CI->getBitWidth() == 64) {
312 IRBuilder<> Builder(Extract);
313 int64_t IndexValue = CI->getSExtValue();
314 auto *Idx32 =
315 ConstantInt::get(Type::getInt32Ty(I.getContext()), IndexValue);
316 Value *NewExtract = Builder.CreateExtractElement(
317 Extract->getVectorOperand(), Idx32, Extract->getName());
318
319 Extract->replaceAllUsesWith(NewExtract);
320 ToRemove.push_back(Extract);
321 return true;
322 }
323 }
324
325 if (auto *Insert = dyn_cast<InsertElementInst>(&I)) {
326 Value *Idx = Insert->getOperand(2);
327 auto *CI = dyn_cast<ConstantInt>(Idx);
328 if (CI && CI->getBitWidth() == 64) {
329 int64_t IndexValue = CI->getSExtValue();
330 auto *Idx32 =
331 ConstantInt::get(Type::getInt32Ty(I.getContext()), IndexValue);
332 IRBuilder<> Builder(Insert);
333 Value *Insert32Index = Builder.CreateInsertElement(
334 Insert->getOperand(0), Insert->getOperand(1), Idx32,
335 Insert->getName());
336
337 Insert->replaceAllUsesWith(Insert32Index);
338 ToRemove.push_back(Insert);
339 return true;
340 }
341 }
342 return false;
343}
344
348 const Intrinsic::ID ID = I.getOpcode();
349 if (ID != Instruction::FNeg)
350 return false;
351
352 IRBuilder<> Builder(&I);
353 Value *In = I.getOperand(0);
354 Value *Zero = ConstantFP::get(In->getType(), -0.0);
355 I.replaceAllUsesWith(Builder.CreateFSub(Zero, In));
356 ToRemove.push_back(&I);
357 return true;
358}
359
360// DXIL has no floating-point atomic operation. A float exchange only moves the
361// bit pattern, so exchange an integer of the same width instead. Opaque
362// pointers keep the pointer operand type-agnostic, so only the value and the
363// result need a cast. This matches what DXC emits for groupshared memory.
364static bool
368 auto *AI = dyn_cast<AtomicRMWInst>(&I);
369 if (!AI || AI->getOperation() != AtomicRMWInst::Xchg)
370 return false;
371
372 Type *ValTy = AI->getValOperand()->getType();
373 if (!ValTy->isFloatingPointTy())
374 return false;
375
376 // DXIL has 32-bit and 64-bit atomics only. A float of any other width has no
377 // integer exchange to lower to.
378 unsigned Width = ValTy->getPrimitiveSizeInBits();
379 if (Width != 32 && Width != 64)
380 reportFatalUsageError("DXIL atomic exchange requires a 32-bit or 64-bit "
381 "floating-point value");
382
383 IRBuilder<> Builder(AI);
384 Type *IntTy = Builder.getIntNTy(Width);
385 Value *Val = Builder.CreateBitCast(AI->getValOperand(), IntTy);
386 AtomicRMWInst *NewAI = Builder.CreateAtomicRMW(
387 AtomicRMWInst::Xchg, AI->getPointerOperand(), Val, AI->getAlign(),
388 AI->getOrdering(), AI->getSyncScopeID());
389 NewAI->copyMetadata(*AI);
390 AI->replaceAllUsesWith(Builder.CreateBitCast(NewAI, ValTy));
391 ToRemove.push_back(AI);
392 return true;
393}
394
395static bool
399 auto *SI = dyn_cast<SwitchInst>(&I);
400 if (!SI || SI->getNumCases() == 0)
401 return false;
402
403 BasicBlock *DefaultBB = SI->getDefaultDest();
404
405 // Check if the default destination ends with an unreachable instruction.
406 if (DefaultBB->size() == 0 ||
407 !isa<UnreachableInst>(DefaultBB->getTerminator()))
408 return false;
409
410 // Try to find a common successor of all case destinations. If all case
411 // blocks unconditionally branch to the same block, that is the common
412 // successor. This is just a best effort, and is done as the original form of
413 // the switch statement was likely in this form before being transformed to
414 // an unreachable branch.
415 BasicBlock *CommonSuccessor = nullptr;
416 for (auto &Case : SI->cases()) {
417 BasicBlock *CaseBB = Case.getCaseSuccessor();
418 auto *BI = dyn_cast<UncondBrInst>(CaseBB->getTerminator());
419 if (!BI) {
420 CommonSuccessor = nullptr;
421 break;
422 }
423 BasicBlock *Succ = BI->getSuccessor(0);
424 if (!CommonSuccessor)
425 CommonSuccessor = Succ;
426 else if (CommonSuccessor != Succ) {
427 CommonSuccessor = nullptr;
428 break;
429 }
430 }
431
432 BasicBlock *NewDefault =
433 CommonSuccessor ? CommonSuccessor : SI->case_begin()->getCaseSuccessor();
434
435 BasicBlock *SwitchBB = SI->getParent();
436 SI->setDefaultDest(NewDefault);
437
438 // Ensure all phi nodes are legal by adding an incoming poison value from the
439 // unreachable branch.
440 for (PHINode &Phi : NewDefault->phis())
441 Phi.addIncoming(PoisonValue::get(Phi.getType()), SwitchBB);
442
443 return true;
444}
445
446static bool
450
451 Value *PtrOp;
452 unsigned PtrOpIndex;
453 [[maybe_unused]] Type *LoadStoreTy;
454 if (auto *LI = dyn_cast<LoadInst>(&I)) {
455 PtrOp = LI->getPointerOperand();
456 PtrOpIndex = LI->getPointerOperandIndex();
457 LoadStoreTy = LI->getType();
458 } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
459 PtrOp = SI->getPointerOperand();
460 PtrOpIndex = SI->getPointerOperandIndex();
461 LoadStoreTy = SI->getValueOperand()->getType();
462 } else
463 return false;
464
465 // If the load/store is not of a single-value type (i.e., scalar or vector)
466 // then we do not modify it. It shouldn't be a vector either because the
467 // dxil-data-scalarization pass is expected to run before this, but it's not
468 // incorrect to apply this transformation to vector load/stores.
469 if (!LoadStoreTy->isSingleValueType())
470 return false;
471
472 Type *ArrayTy;
473 if (auto *GlobalVarPtrOp = dyn_cast<GlobalVariable>(PtrOp))
474 ArrayTy = GlobalVarPtrOp->getValueType();
475 else if (auto *AllocaPtrOp = dyn_cast<AllocaInst>(PtrOp))
476 ArrayTy = AllocaPtrOp->getAllocatedType();
477 else
478 return false;
479
480 if (!isa<ArrayType>(ArrayTy))
481 return false;
482
483 assert(ArrayTy->getArrayElementType() == LoadStoreTy &&
484 "Expected array element type to be the same as to the scalar load or "
485 "store type");
486
487 Value *Zero = ConstantInt::get(Type::getInt32Ty(I.getContext()), 0);
489 ArrayTy, PtrOp, {Zero, Zero}, GEPNoWrapFlags::all(), "", I.getIterator());
490 I.setOperand(PtrOpIndex, GEP);
491 return true;
492}
493
494namespace {
495class DXILLegalizationPipeline {
496
497public:
498 DXILLegalizationPipeline() { initializeLegalizationPipeline(); }
499
500 bool runLegalizationPipeline(Function &F) {
501 bool MadeChange = false;
502 SmallVector<Instruction *> ToRemove;
503 DenseMap<Value *, Value *> ReplacedValues;
504 for (int Stage = 0; Stage < NumStages; ++Stage) {
505 ToRemove.clear();
506 ReplacedValues.clear();
507 for (auto &I : instructions(F)) {
508 for (auto &LegalizationFn : LegalizationPipeline[Stage])
509 MadeChange |= LegalizationFn(I, ToRemove, ReplacedValues);
510 }
511
512 for (auto *Inst : reverse(ToRemove))
513 Inst->eraseFromParent();
514 }
515
516 if (MadeChange)
517 MadeChange |= removeUnreachableBlocks(F);
518 return MadeChange;
519 }
520
521private:
522 enum LegalizationStage { Stage1 = 0, Stage2 = 1, NumStages };
523
524 using LegalizationFnTy =
525 std::function<bool(Instruction &, SmallVectorImpl<Instruction *> &,
526 DenseMap<Value *, Value *> &)>;
527
528 SmallVector<LegalizationFnTy> LegalizationPipeline[NumStages];
529
530 void initializeLegalizationPipeline() {
531 LegalizationPipeline[Stage1].push_back(upcastI8AllocasAndUses);
532 LegalizationPipeline[Stage1].push_back(fixI8UseChain);
533 LegalizationPipeline[Stage1].push_back(legalizeFreeze);
534 LegalizationPipeline[Stage1].push_back(updateFnegToFsub);
535 LegalizationPipeline[Stage1].push_back(legalizeFloatAtomicExchange);
536 LegalizationPipeline[Stage1].push_back(
538 LegalizationPipeline[Stage2].push_back(legalizeScalarLoadStoreOnArrays);
539 LegalizationPipeline[Stage2].push_back(resolveUnreachableSwitchDefault);
540 }
541};
542
543class DXILLegalizeLegacy : public FunctionPass {
544
545public:
546 bool runOnFunction(Function &F) override;
547 DXILLegalizeLegacy() : FunctionPass(ID) {}
548
549 static char ID; // Pass identification.
550};
551} // namespace
552
555 DXILLegalizationPipeline DXLegalize;
556 bool MadeChanges = DXLegalize.runLegalizationPipeline(F);
557 if (!MadeChanges)
558 return PreservedAnalyses::all();
560 return PA;
561}
562
563bool DXILLegalizeLegacy::runOnFunction(Function &F) {
564 DXILLegalizationPipeline DXLegalize;
565 return DXLegalize.runLegalizationPipeline(F);
566}
567
568char DXILLegalizeLegacy::ID = 0;
569
570INITIALIZE_PASS_BEGIN(DXILLegalizeLegacy, DEBUG_TYPE, "DXIL Legalizer", false,
571 false)
572INITIALIZE_PASS_END(DXILLegalizeLegacy, DEBUG_TYPE, "DXIL Legalizer", false,
573 false)
574
576 return new DXILLegalizeLegacy();
577}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
Expand Atomic instructions
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool fixI8UseChain(Instruction &I, SmallVectorImpl< Instruction * > &ToRemove, DenseMap< Value *, Value * > &ReplacedValues)
static bool downcastI64toI32InsertExtractElements(Instruction &I, SmallVectorImpl< Instruction * > &ToRemove, DenseMap< Value *, Value * > &)
static bool legalizeFloatAtomicExchange(Instruction &I, SmallVectorImpl< Instruction * > &ToRemove, DenseMap< Value *, Value * > &)
static bool upcastI8AllocasAndUses(Instruction &I, SmallVectorImpl< Instruction * > &ToRemove, DenseMap< Value *, Value * > &ReplacedValues)
static bool resolveUnreachableSwitchDefault(Instruction &I, SmallVectorImpl< Instruction * > &ToRemove, DenseMap< Value *, Value * > &)
static bool legalizeScalarLoadStoreOnArrays(Instruction &I, SmallVectorImpl< Instruction * > &ToRemove, DenseMap< Value *, Value * > &)
static bool legalizeFreeze(Instruction &I, SmallVectorImpl< Instruction * > &ToRemove, DenseMap< Value *, Value * >)
static bool updateFnegToFsub(Instruction &I, SmallVectorImpl< Instruction * > &ToRemove, DenseMap< Value *, Value * > &)
static bool runOnFunction(Function &F, bool PostInlining)
#define DEBUG_TYPE
Hexagon Common GEP
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
FunctionAnalysisManager FAM
#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
Class for arbitrary precision integers.
Definition APInt.h:78
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
an instruction that atomically reads a memory location, combines it with another value,...
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
Definition BasicBlock.h:515
size_t size() const
Definition BasicBlock.h:467
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
This is the base class for all instructions that perform data casts.
Definition InstrTypes.h:512
This is the shared class of boolean and integer constants.
Definition Constants.h:87
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition DenseMap.h:254
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
static GEPNoWrapFlags all()
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2903
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
An instruction for reading from memory.
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 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.
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
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
Definition Type.h:306
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:303
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:553
iterator_range< user_iterator > users()
Definition Value.h:428
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
FunctionPass * createDXILLegalizeLegacyPass()
Pass to Legalize DXIL by remove i8 truncations and i64 insert/extract elements.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool FoldInstsToUnreachable=true)
Remove all blocks that can not be reached from the function's entry.
Definition Local.cpp:2912
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
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
DWARFExpression::Operation Op
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177