LLVM 23.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"
22#include <functional>
23
24#define DEBUG_TYPE "dxil-legalize"
25
26using namespace llvm;
27
31 auto *FI = dyn_cast<FreezeInst>(&I);
32 if (!FI)
33 return false;
34
35 FI->replaceAllUsesWith(FI->getOperand(0));
36 ToRemove.push_back(FI);
37 return true;
38}
39
42 DenseMap<Value *, Value *> &ReplacedValues) {
43
44 auto ProcessOperands = [&](SmallVector<Value *> &NewOperands) {
45 Type *InstrType = IntegerType::get(I.getContext(), 32);
46
47 for (unsigned OpIdx = 0; OpIdx < I.getNumOperands(); ++OpIdx) {
48 Value *Op = I.getOperand(OpIdx);
49 if (ReplacedValues.count(Op) &&
50 ReplacedValues[Op]->getType()->isIntegerTy())
51 InstrType = ReplacedValues[Op]->getType();
52 }
53
54 for (unsigned OpIdx = 0; OpIdx < I.getNumOperands(); ++OpIdx) {
55 Value *Op = I.getOperand(OpIdx);
56 if (ReplacedValues.count(Op))
57 NewOperands.push_back(ReplacedValues[Op]);
58 else if (auto *Imm = dyn_cast<ConstantInt>(Op)) {
59 APInt Value = Imm->getValue();
60 unsigned NewBitWidth = InstrType->getIntegerBitWidth();
61 // Note: options here are sext or sextOrTrunc.
62 // Since i8 isn't supported, we assume new values
63 // will always have a higher bitness.
64 assert(NewBitWidth > Value.getBitWidth() &&
65 "Replacement's BitWidth should be larger than Current.");
66 APInt NewValue = Value.sext(NewBitWidth);
67 NewOperands.push_back(ConstantInt::get(InstrType, NewValue));
68 } else {
69 assert(!Op->getType()->isIntegerTy(8));
70 NewOperands.push_back(Op);
71 }
72 }
73 };
74 IRBuilder<> Builder(&I);
75 if (auto *Trunc = dyn_cast<TruncInst>(&I)) {
76 if (Trunc->getDestTy()->isIntegerTy(8)) {
77 ReplacedValues[Trunc] = Trunc->getOperand(0);
78 ToRemove.push_back(Trunc);
79 return true;
80 }
81 }
82
83 if (auto *Store = dyn_cast<StoreInst>(&I)) {
84 if (!Store->getValueOperand()->getType()->isIntegerTy(8))
85 return false;
86 SmallVector<Value *> NewOperands;
87 ProcessOperands(NewOperands);
88 Value *NewStore = Builder.CreateStore(NewOperands[0], NewOperands[1]);
89 ReplacedValues[Store] = NewStore;
90 ToRemove.push_back(Store);
91 return true;
92 }
93
94 if (auto *Load = dyn_cast<LoadInst>(&I);
95 Load && I.getType()->isIntegerTy(8)) {
96 SmallVector<Value *> NewOperands;
97 ProcessOperands(NewOperands);
98 Type *ElementType = NewOperands[0]->getType();
99 if (auto *AI = dyn_cast<AllocaInst>(NewOperands[0]))
100 ElementType = AI->getAllocatedType();
101 if (auto *GEP = dyn_cast<GetElementPtrInst>(NewOperands[0])) {
102 ElementType = GEP->getSourceElementType();
103 }
104 if (ElementType->isArrayTy())
105 ElementType = ElementType->getArrayElementType();
106 LoadInst *NewLoad = Builder.CreateLoad(ElementType, NewOperands[0]);
107 ReplacedValues[Load] = NewLoad;
108 ToRemove.push_back(Load);
109 return true;
110 }
111
112 if (auto *Load = dyn_cast<LoadInst>(&I);
113 Load && isa<ConstantExpr>(Load->getPointerOperand())) {
114 auto *CE = dyn_cast<ConstantExpr>(Load->getPointerOperand());
115 if (!(CE->getOpcode() == Instruction::GetElementPtr))
116 return false;
117 auto *GEP = dyn_cast<GEPOperator>(CE);
118 if (!GEP->getSourceElementType()->isIntegerTy(8))
119 return false;
120
121 Type *ElementType = Load->getType();
122 ConstantInt *Offset = dyn_cast<ConstantInt>(GEP->getOperand(1));
123 uint32_t ByteOffset = Offset->getZExtValue();
124 uint32_t ElemSize = Load->getDataLayout().getTypeAllocSize(ElementType);
125 uint32_t Index = ByteOffset / ElemSize;
126
127 Value *PtrOperand = GEP->getPointerOperand();
128 Type *GEPType = GEP->getPointerOperandType();
129
130 if (auto *GV = dyn_cast<GlobalVariable>(PtrOperand))
131 GEPType = GV->getValueType();
132 if (auto *AI = dyn_cast<AllocaInst>(PtrOperand))
133 GEPType = AI->getAllocatedType();
134
135 if (auto *ArrTy = dyn_cast<ArrayType>(GEPType))
136 GEPType = ArrTy;
137 else
138 GEPType = ArrayType::get(ElementType, 1); // its a scalar
139
140 Value *NewGEP = Builder.CreateGEP(
141 GEPType, PtrOperand, {Builder.getInt32(0), Builder.getInt32(Index)},
142 GEP->getName(), GEP->getNoWrapFlags());
143
144 LoadInst *NewLoad = Builder.CreateLoad(ElementType, NewGEP);
145 ReplacedValues[Load] = NewLoad;
146 Load->replaceAllUsesWith(NewLoad);
147 ToRemove.push_back(Load);
148 return true;
149 }
150
151 if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
152 if (!I.getType()->isIntegerTy(8))
153 return false;
154 SmallVector<Value *> NewOperands;
155 ProcessOperands(NewOperands);
156 Value *NewInst =
157 Builder.CreateBinOp(BO->getOpcode(), NewOperands[0], NewOperands[1]);
158 if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(&I)) {
159 auto *NewBO = dyn_cast<BinaryOperator>(NewInst);
160 if (NewBO && OBO->hasNoSignedWrap())
161 NewBO->setHasNoSignedWrap();
162 if (NewBO && OBO->hasNoUnsignedWrap())
163 NewBO->setHasNoUnsignedWrap();
164 }
165 ReplacedValues[BO] = NewInst;
166 ToRemove.push_back(BO);
167 return true;
168 }
169
170 if (auto *Sel = dyn_cast<SelectInst>(&I)) {
171 if (!I.getType()->isIntegerTy(8))
172 return false;
173 SmallVector<Value *> NewOperands;
174 ProcessOperands(NewOperands);
175 Value *NewInst = Builder.CreateSelect(Sel->getCondition(), NewOperands[1],
176 NewOperands[2]);
177 ReplacedValues[Sel] = NewInst;
178 ToRemove.push_back(Sel);
179 return true;
180 }
181
182 if (auto *Cmp = dyn_cast<CmpInst>(&I)) {
183 if (!Cmp->getOperand(0)->getType()->isIntegerTy(8))
184 return false;
185 SmallVector<Value *> NewOperands;
186 ProcessOperands(NewOperands);
187 Value *NewInst =
188 Builder.CreateCmp(Cmp->getPredicate(), NewOperands[0], NewOperands[1]);
189 Cmp->replaceAllUsesWith(NewInst);
190 ReplacedValues[Cmp] = NewInst;
191 ToRemove.push_back(Cmp);
192 return true;
193 }
194
195 if (auto *Cast = dyn_cast<CastInst>(&I)) {
196 if (!Cast->getSrcTy()->isIntegerTy(8))
197 return false;
198
199 ToRemove.push_back(Cast);
200 auto *Replacement = ReplacedValues[Cast->getOperand(0)];
201 if (Cast->getType() == Replacement->getType()) {
202 Cast->replaceAllUsesWith(Replacement);
203 return true;
204 }
205
206 Value *AdjustedCast = nullptr;
207 if (Cast->getOpcode() == Instruction::ZExt)
208 AdjustedCast = Builder.CreateZExtOrTrunc(Replacement, Cast->getType());
209 if (Cast->getOpcode() == Instruction::SExt)
210 AdjustedCast = Builder.CreateSExtOrTrunc(Replacement, Cast->getType());
211
212 if (AdjustedCast)
213 Cast->replaceAllUsesWith(AdjustedCast);
214 }
215 if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
216 if (!GEP->getType()->isPointerTy() ||
217 !GEP->getSourceElementType()->isIntegerTy(8))
218 return false;
219
220 Value *BasePtr = GEP->getPointerOperand();
221 if (ReplacedValues.count(BasePtr))
222 BasePtr = ReplacedValues[BasePtr];
223
224 Type *ElementType = BasePtr->getType();
225
226 if (auto *AI = dyn_cast<AllocaInst>(BasePtr))
227 ElementType = AI->getAllocatedType();
228 if (auto *GV = dyn_cast<GlobalVariable>(BasePtr))
229 ElementType = GV->getValueType();
230
231 Type *GEPType = ElementType;
232 if (auto *ArrTy = dyn_cast<ArrayType>(ElementType))
233 ElementType = ArrTy->getArrayElementType();
234 else
235 GEPType = ArrayType::get(ElementType, 1); // its a scalar
236
237 ConstantInt *Offset = dyn_cast<ConstantInt>(GEP->getOperand(1));
238 // Note: i8 to i32 offset conversion without emitting IR requires constant
239 // ints. Since offset conversion is common, we can safely assume Offset is
240 // always a ConstantInt, so no need to have a conditional bail out on
241 // nullptr, instead assert this is the case.
242 assert(Offset && "Offset is expected to be a ConstantInt");
243 uint32_t ByteOffset = Offset->getZExtValue();
244 uint32_t ElemSize = GEP->getDataLayout().getTypeAllocSize(ElementType);
245 assert(ElemSize > 0 && "ElementSize must be set");
246 uint32_t Index = ByteOffset / ElemSize;
247 Value *NewGEP = Builder.CreateGEP(
248 GEPType, BasePtr, {Builder.getInt32(0), Builder.getInt32(Index)},
249 GEP->getName(), GEP->getNoWrapFlags());
250 ReplacedValues[GEP] = NewGEP;
251 GEP->replaceAllUsesWith(NewGEP);
252 ToRemove.push_back(GEP);
253 return true;
254 }
255 return false;
256}
257
260 DenseMap<Value *, Value *> &ReplacedValues) {
261 auto *AI = dyn_cast<AllocaInst>(&I);
262 if (!AI || !AI->getAllocatedType()->isIntegerTy(8))
263 return false;
264
265 Type *SmallestType = nullptr;
266
267 auto ProcessLoad = [&](LoadInst *Load) {
268 for (User *LU : Load->users()) {
269 CastInst *Cast = dyn_cast<CastInst>(LU);
270 if (!Cast)
271 continue;
272 Type *Ty = Cast->getType();
273
274 if (!SmallestType ||
275 Ty->getPrimitiveSizeInBits() < SmallestType->getPrimitiveSizeInBits())
276 SmallestType = Ty;
277 }
278 };
279
280 for (User *U : AI->users()) {
281 if (auto *Load = dyn_cast<LoadInst>(U))
282 ProcessLoad(Load);
283 else if (auto *GEP = dyn_cast<GetElementPtrInst>(U)) {
284 for (User *GU : GEP->users()) {
285 if (auto *Load = dyn_cast<LoadInst>(GU))
286 ProcessLoad(Load);
287 }
288 }
289 }
290
291 if (!SmallestType)
292 return false; // no valid casts found
293
294 // Replace alloca
295 IRBuilder<> Builder(AI);
296 auto *NewAlloca = Builder.CreateAlloca(SmallestType);
297 ReplacedValues[AI] = NewAlloca;
298 ToRemove.push_back(AI);
299 return true;
300}
301
302static bool
306
307 if (auto *Extract = dyn_cast<ExtractElementInst>(&I)) {
308 Value *Idx = Extract->getIndexOperand();
309 auto *CI = dyn_cast<ConstantInt>(Idx);
310 if (CI && CI->getBitWidth() == 64) {
311 IRBuilder<> Builder(Extract);
312 int64_t IndexValue = CI->getSExtValue();
313 auto *Idx32 =
314 ConstantInt::get(Type::getInt32Ty(I.getContext()), IndexValue);
315 Value *NewExtract = Builder.CreateExtractElement(
316 Extract->getVectorOperand(), Idx32, Extract->getName());
317
318 Extract->replaceAllUsesWith(NewExtract);
319 ToRemove.push_back(Extract);
320 return true;
321 }
322 }
323
324 if (auto *Insert = dyn_cast<InsertElementInst>(&I)) {
325 Value *Idx = Insert->getOperand(2);
326 auto *CI = dyn_cast<ConstantInt>(Idx);
327 if (CI && CI->getBitWidth() == 64) {
328 int64_t IndexValue = CI->getSExtValue();
329 auto *Idx32 =
330 ConstantInt::get(Type::getInt32Ty(I.getContext()), IndexValue);
331 IRBuilder<> Builder(Insert);
332 Value *Insert32Index = Builder.CreateInsertElement(
333 Insert->getOperand(0), Insert->getOperand(1), Idx32,
334 Insert->getName());
335
336 Insert->replaceAllUsesWith(Insert32Index);
337 ToRemove.push_back(Insert);
338 return true;
339 }
340 }
341 return false;
342}
343
347 const Intrinsic::ID ID = I.getOpcode();
348 if (ID != Instruction::FNeg)
349 return false;
350
351 IRBuilder<> Builder(&I);
352 Value *In = I.getOperand(0);
353 Value *Zero = ConstantFP::get(In->getType(), -0.0);
354 I.replaceAllUsesWith(Builder.CreateFSub(Zero, In));
355 ToRemove.push_back(&I);
356 return true;
357}
358
359static bool
362 DenseMap<Value *, Value *> &ReplacedValues) {
363 if (auto *BitCast = dyn_cast<BitCastInst>(&I)) {
364 if (BitCast->getDestTy() ==
365 FixedVectorType::get(Type::getInt32Ty(I.getContext()), 2) &&
366 BitCast->getSrcTy()->isIntegerTy(64)) {
367 ToRemove.push_back(BitCast);
368 ReplacedValues[BitCast] = BitCast->getOperand(0);
369 return true;
370 }
371 }
372
373 if (auto *Extract = dyn_cast<ExtractElementInst>(&I)) {
374 if (!dyn_cast<BitCastInst>(Extract->getVectorOperand()))
375 return false;
376 auto *VecTy = dyn_cast<FixedVectorType>(Extract->getVectorOperandType());
377 if (VecTy && VecTy->getElementType()->isIntegerTy(32) &&
378 VecTy->getNumElements() == 2) {
379 if (auto *Index = dyn_cast<ConstantInt>(Extract->getIndexOperand())) {
380 unsigned Idx = Index->getZExtValue();
381 IRBuilder<> Builder(&I);
382
383 auto *Replacement = ReplacedValues[Extract->getVectorOperand()];
384 assert(Replacement && "The BitCast replacement should have been set "
385 "before working on ExtractElementInst.");
386 if (Idx == 0) {
387 Value *LowBytes = Builder.CreateTrunc(
388 Replacement, Type::getInt32Ty(I.getContext()));
389 ReplacedValues[Extract] = LowBytes;
390 } else {
391 assert(Idx == 1);
392 Value *LogicalShiftRight = Builder.CreateLShr(
393 Replacement,
394 ConstantInt::get(
395 Replacement->getType(),
396 APInt(Replacement->getType()->getIntegerBitWidth(), 32)));
397 Value *HighBytes = Builder.CreateTrunc(
398 LogicalShiftRight, Type::getInt32Ty(I.getContext()));
399 ReplacedValues[Extract] = HighBytes;
400 }
401 ToRemove.push_back(Extract);
402 Extract->replaceAllUsesWith(ReplacedValues[Extract]);
403 return true;
404 }
405 }
406 }
407 return false;
408}
409
410static bool
414 auto *SI = dyn_cast<SwitchInst>(&I);
415 if (!SI || SI->getNumCases() == 0)
416 return false;
417
418 BasicBlock *DefaultBB = SI->getDefaultDest();
419
420 // Check if the default destination ends with an unreachable instruction.
421 if (DefaultBB->size() == 0 ||
422 !isa<UnreachableInst>(DefaultBB->getTerminator()))
423 return false;
424
425 // Try to find a common successor of all case destinations. If all case
426 // blocks unconditionally branch to the same block, that is the common
427 // successor. This is just a best effort, and is done as the original form of
428 // the switch statement was likely in this form before being transformed to
429 // an unreachable branch.
430 BasicBlock *CommonSuccessor = nullptr;
431 for (auto &Case : SI->cases()) {
432 BasicBlock *CaseBB = Case.getCaseSuccessor();
433 auto *BI = dyn_cast<UncondBrInst>(CaseBB->getTerminator());
434 if (!BI) {
435 CommonSuccessor = nullptr;
436 break;
437 }
438 BasicBlock *Succ = BI->getSuccessor(0);
439 if (!CommonSuccessor)
440 CommonSuccessor = Succ;
441 else if (CommonSuccessor != Succ) {
442 CommonSuccessor = nullptr;
443 break;
444 }
445 }
446
447 BasicBlock *NewDefault =
448 CommonSuccessor ? CommonSuccessor : SI->case_begin()->getCaseSuccessor();
449
450 BasicBlock *SwitchBB = SI->getParent();
451 SI->setDefaultDest(NewDefault);
452
453 // Ensure all phi nodes are legal by adding an incoming poison value from the
454 // unreachable branch.
455 for (PHINode &Phi : NewDefault->phis())
456 Phi.addIncoming(PoisonValue::get(Phi.getType()), SwitchBB);
457
458 return true;
459}
460
461static bool
465
466 Value *PtrOp;
467 unsigned PtrOpIndex;
468 [[maybe_unused]] Type *LoadStoreTy;
469 if (auto *LI = dyn_cast<LoadInst>(&I)) {
470 PtrOp = LI->getPointerOperand();
471 PtrOpIndex = LI->getPointerOperandIndex();
472 LoadStoreTy = LI->getType();
473 } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
474 PtrOp = SI->getPointerOperand();
475 PtrOpIndex = SI->getPointerOperandIndex();
476 LoadStoreTy = SI->getValueOperand()->getType();
477 } else
478 return false;
479
480 // If the load/store is not of a single-value type (i.e., scalar or vector)
481 // then we do not modify it. It shouldn't be a vector either because the
482 // dxil-data-scalarization pass is expected to run before this, but it's not
483 // incorrect to apply this transformation to vector load/stores.
484 if (!LoadStoreTy->isSingleValueType())
485 return false;
486
487 Type *ArrayTy;
488 if (auto *GlobalVarPtrOp = dyn_cast<GlobalVariable>(PtrOp))
489 ArrayTy = GlobalVarPtrOp->getValueType();
490 else if (auto *AllocaPtrOp = dyn_cast<AllocaInst>(PtrOp))
491 ArrayTy = AllocaPtrOp->getAllocatedType();
492 else
493 return false;
494
495 if (!isa<ArrayType>(ArrayTy))
496 return false;
497
498 assert(ArrayTy->getArrayElementType() == LoadStoreTy &&
499 "Expected array element type to be the same as to the scalar load or "
500 "store type");
501
502 Value *Zero = ConstantInt::get(Type::getInt32Ty(I.getContext()), 0);
504 ArrayTy, PtrOp, {Zero, Zero}, GEPNoWrapFlags::all(), "", I.getIterator());
505 I.setOperand(PtrOpIndex, GEP);
506 return true;
507}
508
509namespace {
510class DXILLegalizationPipeline {
511
512public:
513 DXILLegalizationPipeline() { initializeLegalizationPipeline(); }
514
515 bool runLegalizationPipeline(Function &F) {
516 bool MadeChange = false;
518 DenseMap<Value *, Value *> ReplacedValues;
519 for (int Stage = 0; Stage < NumStages; ++Stage) {
520 ToRemove.clear();
521 ReplacedValues.clear();
522 for (auto &I : instructions(F)) {
523 for (auto &LegalizationFn : LegalizationPipeline[Stage])
524 MadeChange |= LegalizationFn(I, ToRemove, ReplacedValues);
525 }
526
527 for (auto *Inst : reverse(ToRemove))
528 Inst->eraseFromParent();
529 }
530
531 if (MadeChange)
532 MadeChange |= removeUnreachableBlocks(F);
533 return MadeChange;
534 }
535
536private:
537 enum LegalizationStage { Stage1 = 0, Stage2 = 1, NumStages };
538
539 using LegalizationFnTy =
540 std::function<bool(Instruction &, SmallVectorImpl<Instruction *> &,
541 DenseMap<Value *, Value *> &)>;
542
543 SmallVector<LegalizationFnTy> LegalizationPipeline[NumStages];
544
545 void initializeLegalizationPipeline() {
546 LegalizationPipeline[Stage1].push_back(upcastI8AllocasAndUses);
547 LegalizationPipeline[Stage1].push_back(fixI8UseChain);
548 LegalizationPipeline[Stage1].push_back(legalizeGetHighLowi64Bytes);
549 LegalizationPipeline[Stage1].push_back(legalizeFreeze);
550 LegalizationPipeline[Stage1].push_back(updateFnegToFsub);
551 // Note: legalizeGetHighLowi64Bytes and
552 // downcastI64toI32InsertExtractElements both modify extractelement, so they
553 // must run staggered stages. legalizeGetHighLowi64Bytes runs first b\c it
554 // removes extractelements, reducing the number that
555 // downcastI64toI32InsertExtractElements needs to handle.
556 LegalizationPipeline[Stage2].push_back(
558 LegalizationPipeline[Stage2].push_back(legalizeScalarLoadStoreOnArrays);
559 LegalizationPipeline[Stage2].push_back(resolveUnreachableSwitchDefault);
560 }
561};
562
563class DXILLegalizeLegacy : public FunctionPass {
564
565public:
566 bool runOnFunction(Function &F) override;
567 DXILLegalizeLegacy() : FunctionPass(ID) {}
568
569 static char ID; // Pass identification.
570};
571} // namespace
572
575 DXILLegalizationPipeline DXLegalize;
576 bool MadeChanges = DXLegalize.runLegalizationPipeline(F);
577 if (!MadeChanges)
578 return PreservedAnalyses::all();
580 return PA;
581}
582
583bool DXILLegalizeLegacy::runOnFunction(Function &F) {
584 DXILLegalizationPipeline DXLegalize;
585 return DXLegalize.runLegalizationPipeline(F);
586}
587
588char DXILLegalizeLegacy::ID = 0;
589
590INITIALIZE_PASS_BEGIN(DXILLegalizeLegacy, DEBUG_TYPE, "DXIL Legalizer", false,
591 false)
592INITIALIZE_PASS_END(DXILLegalizeLegacy, DEBUG_TYPE, "DXIL Legalizer", false,
593 false)
594
596 return new DXILLegalizeLegacy();
597}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 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 legalizeGetHighLowi64Bytes(Instruction &I, SmallVectorImpl< Instruction * > &ToRemove, DenseMap< Value *, Value * > &ReplacedValues)
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
MachineInstr unsigned OpIdx
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.
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:530
size_t size() const
Definition BasicBlock.h:482
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:219
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:867
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:2848
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:348
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:309
Type * getArrayElementType() const
Definition Type.h:425
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
Definition Type.h:311
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:197
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
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:426
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
InstrType
This represents what is and is not supported when finding similarity in Instructions.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:573
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
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
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 bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
Definition Local.cpp:2901