2424
2525using namespace llvm ;
2626
27- static void legalizeFreeze (Instruction &I,
27+ static bool legalizeFreeze (Instruction &I,
2828 SmallVectorImpl<Instruction *> &ToRemove,
2929 DenseMap<Value *, Value *>) {
3030 auto *FI = dyn_cast<FreezeInst>(&I);
3131 if (!FI)
32- return ;
32+ return false ;
3333
3434 FI->replaceAllUsesWith (FI->getOperand (0 ));
3535 ToRemove.push_back (FI);
36+ return true ;
3637}
3738
38- static void fixI8UseChain (Instruction &I,
39+ static bool fixI8UseChain (Instruction &I,
3940 SmallVectorImpl<Instruction *> &ToRemove,
4041 DenseMap<Value *, Value *> &ReplacedValues) {
4142
@@ -74,19 +75,19 @@ static void fixI8UseChain(Instruction &I,
7475 if (Trunc->getDestTy ()->isIntegerTy (8 )) {
7576 ReplacedValues[Trunc] = Trunc->getOperand (0 );
7677 ToRemove.push_back (Trunc);
77- return ;
78+ return true ;
7879 }
7980 }
8081
8182 if (auto *Store = dyn_cast<StoreInst>(&I)) {
8283 if (!Store->getValueOperand ()->getType ()->isIntegerTy (8 ))
83- return ;
84+ return false ;
8485 SmallVector<Value *> NewOperands;
8586 ProcessOperands (NewOperands);
8687 Value *NewStore = Builder.CreateStore (NewOperands[0 ], NewOperands[1 ]);
8788 ReplacedValues[Store] = NewStore;
8889 ToRemove.push_back (Store);
89- return ;
90+ return true ;
9091 }
9192
9293 if (auto *Load = dyn_cast<LoadInst>(&I);
@@ -104,17 +105,17 @@ static void fixI8UseChain(Instruction &I,
104105 LoadInst *NewLoad = Builder.CreateLoad (ElementType, NewOperands[0 ]);
105106 ReplacedValues[Load] = NewLoad;
106107 ToRemove.push_back (Load);
107- return ;
108+ return true ;
108109 }
109110
110111 if (auto *Load = dyn_cast<LoadInst>(&I);
111112 Load && isa<ConstantExpr>(Load->getPointerOperand ())) {
112113 auto *CE = dyn_cast<ConstantExpr>(Load->getPointerOperand ());
113114 if (!(CE->getOpcode () == Instruction::GetElementPtr))
114- return ;
115+ return false ;
115116 auto *GEP = dyn_cast<GEPOperator>(CE);
116117 if (!GEP->getSourceElementType ()->isIntegerTy (8 ))
117- return ;
118+ return false ;
118119
119120 Type *ElementType = Load->getType ();
120121 ConstantInt *Offset = dyn_cast<ConstantInt>(GEP->getOperand (1 ));
@@ -143,12 +144,12 @@ static void fixI8UseChain(Instruction &I,
143144 ReplacedValues[Load] = NewLoad;
144145 Load->replaceAllUsesWith (NewLoad);
145146 ToRemove.push_back (Load);
146- return ;
147+ return true ;
147148 }
148149
149150 if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
150151 if (!I.getType ()->isIntegerTy (8 ))
151- return ;
152+ return false ;
152153 SmallVector<Value *> NewOperands;
153154 ProcessOperands (NewOperands);
154155 Value *NewInst =
@@ -162,43 +163,43 @@ static void fixI8UseChain(Instruction &I,
162163 }
163164 ReplacedValues[BO] = NewInst;
164165 ToRemove.push_back (BO);
165- return ;
166+ return true ;
166167 }
167168
168169 if (auto *Sel = dyn_cast<SelectInst>(&I)) {
169170 if (!I.getType ()->isIntegerTy (8 ))
170- return ;
171+ return false ;
171172 SmallVector<Value *> NewOperands;
172173 ProcessOperands (NewOperands);
173174 Value *NewInst = Builder.CreateSelect (Sel->getCondition (), NewOperands[1 ],
174175 NewOperands[2 ]);
175176 ReplacedValues[Sel] = NewInst;
176177 ToRemove.push_back (Sel);
177- return ;
178+ return true ;
178179 }
179180
180181 if (auto *Cmp = dyn_cast<CmpInst>(&I)) {
181182 if (!Cmp->getOperand (0 )->getType ()->isIntegerTy (8 ))
182- return ;
183+ return false ;
183184 SmallVector<Value *> NewOperands;
184185 ProcessOperands (NewOperands);
185186 Value *NewInst =
186187 Builder.CreateCmp (Cmp->getPredicate (), NewOperands[0 ], NewOperands[1 ]);
187188 Cmp->replaceAllUsesWith (NewInst);
188189 ReplacedValues[Cmp] = NewInst;
189190 ToRemove.push_back (Cmp);
190- return ;
191+ return true ;
191192 }
192193
193194 if (auto *Cast = dyn_cast<CastInst>(&I)) {
194195 if (!Cast->getSrcTy ()->isIntegerTy (8 ))
195- return ;
196+ return false ;
196197
197198 ToRemove.push_back (Cast);
198199 auto *Replacement = ReplacedValues[Cast->getOperand (0 )];
199200 if (Cast->getType () == Replacement->getType ()) {
200201 Cast->replaceAllUsesWith (Replacement);
201- return ;
202+ return true ;
202203 }
203204
204205 Value *AdjustedCast = nullptr ;
@@ -213,7 +214,7 @@ static void fixI8UseChain(Instruction &I,
213214 if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
214215 if (!GEP->getType ()->isPointerTy () ||
215216 !GEP->getSourceElementType ()->isIntegerTy (8 ))
216- return ;
217+ return false ;
217218
218219 Value *BasePtr = GEP->getPointerOperand ();
219220 if (ReplacedValues.count (BasePtr))
@@ -248,15 +249,17 @@ static void fixI8UseChain(Instruction &I,
248249 ReplacedValues[GEP] = NewGEP;
249250 GEP->replaceAllUsesWith (NewGEP);
250251 ToRemove.push_back (GEP);
252+ return true ;
251253 }
254+ return false ;
252255}
253256
254- static void upcastI8AllocasAndUses (Instruction &I,
257+ static bool upcastI8AllocasAndUses (Instruction &I,
255258 SmallVectorImpl<Instruction *> &ToRemove,
256259 DenseMap<Value *, Value *> &ReplacedValues) {
257260 auto *AI = dyn_cast<AllocaInst>(&I);
258261 if (!AI || !AI->getAllocatedType ()->isIntegerTy (8 ))
259- return ;
262+ return false ;
260263
261264 Type *SmallestType = nullptr ;
262265
@@ -291,16 +294,17 @@ static void upcastI8AllocasAndUses(Instruction &I,
291294 }
292295
293296 if (!SmallestType)
294- return ; // no valid casts found
297+ return false ; // no valid casts found
295298
296299 // Replace alloca
297300 IRBuilder<> Builder (AI);
298301 auto *NewAlloca = Builder.CreateAlloca (SmallestType);
299302 ReplacedValues[AI] = NewAlloca;
300303 ToRemove.push_back (AI);
304+ return true ;
301305}
302306
303- static void
307+ static bool
304308downcastI64toI32InsertExtractElements (Instruction &I,
305309 SmallVectorImpl<Instruction *> &ToRemove,
306310 DenseMap<Value *, Value *> &) {
@@ -318,6 +322,7 @@ downcastI64toI32InsertExtractElements(Instruction &I,
318322
319323 Extract->replaceAllUsesWith (NewExtract);
320324 ToRemove.push_back (Extract);
325+ return true ;
321326 }
322327 }
323328
@@ -335,8 +340,10 @@ downcastI64toI32InsertExtractElements(Instruction &I,
335340
336341 Insert->replaceAllUsesWith (Insert32Index);
337342 ToRemove.push_back (Insert);
343+ return true ;
338344 }
339345 }
346+ return false ;
340347}
341348
342349static void emitMemcpyExpansion (IRBuilder<> &Builder, Value *Dst, Value *Src,
@@ -453,17 +460,17 @@ static void emitMemsetExpansion(IRBuilder<> &Builder, Value *Dst, Value *Val,
453460// Expands the instruction `I` into corresponding loads and stores if it is a
454461// memcpy call. In that case, the call instruction is added to the `ToRemove`
455462// vector. `ReplacedValues` is unused.
456- static void legalizeMemCpy (Instruction &I,
463+ static bool legalizeMemCpy (Instruction &I,
457464 SmallVectorImpl<Instruction *> &ToRemove,
458465 DenseMap<Value *, Value *> &ReplacedValues) {
459466
460467 CallInst *CI = dyn_cast<CallInst>(&I);
461468 if (!CI)
462- return ;
469+ return false ;
463470
464471 Intrinsic::ID ID = CI->getIntrinsicID ();
465472 if (ID != Intrinsic::memcpy)
466- return ;
473+ return false ;
467474
468475 IRBuilder<> Builder (&I);
469476 Value *Dst = CI->getArgOperand (0 );
@@ -476,19 +483,20 @@ static void legalizeMemCpy(Instruction &I,
476483 assert (IsVolatile->getZExtValue () == 0 && " Expected IsVolatile to be false" );
477484 emitMemcpyExpansion (Builder, Dst, Src, Length);
478485 ToRemove.push_back (CI);
486+ return true ;
479487}
480488
481- static void legalizeMemSet (Instruction &I,
489+ static bool legalizeMemSet (Instruction &I,
482490 SmallVectorImpl<Instruction *> &ToRemove,
483491 DenseMap<Value *, Value *> &ReplacedValues) {
484492
485493 CallInst *CI = dyn_cast<CallInst>(&I);
486494 if (!CI)
487- return ;
495+ return false ;
488496
489497 Intrinsic::ID ID = CI->getIntrinsicID ();
490498 if (ID != Intrinsic::memset)
491- return ;
499+ return false ;
492500
493501 IRBuilder<> Builder (&I);
494502 Value *Dst = CI->getArgOperand (0 );
@@ -497,23 +505,25 @@ static void legalizeMemSet(Instruction &I,
497505 assert (Size && " Expected Size to be a ConstantInt" );
498506 emitMemsetExpansion (Builder, Dst, Val, Size, ReplacedValues);
499507 ToRemove.push_back (CI);
508+ return true ;
500509}
501510
502- static void updateFnegToFsub (Instruction &I,
511+ static bool updateFnegToFsub (Instruction &I,
503512 SmallVectorImpl<Instruction *> &ToRemove,
504513 DenseMap<Value *, Value *> &) {
505514 const Intrinsic::ID ID = I.getOpcode ();
506515 if (ID != Instruction::FNeg)
507- return ;
516+ return false ;
508517
509518 IRBuilder<> Builder (&I);
510519 Value *In = I.getOperand (0 );
511520 Value *Zero = ConstantFP::get (In->getType (), -0.0 );
512521 I.replaceAllUsesWith (Builder.CreateFSub (Zero, In));
513522 ToRemove.push_back (&I);
523+ return true ;
514524}
515525
516- static void
526+ static bool
517527legalizeGetHighLowi64Bytes (Instruction &I,
518528 SmallVectorImpl<Instruction *> &ToRemove,
519529 DenseMap<Value *, Value *> &ReplacedValues) {
@@ -523,13 +533,13 @@ legalizeGetHighLowi64Bytes(Instruction &I,
523533 BitCast->getSrcTy ()->isIntegerTy (64 )) {
524534 ToRemove.push_back (BitCast);
525535 ReplacedValues[BitCast] = BitCast->getOperand (0 );
526- return ;
536+ return true ;
527537 }
528538 }
529539
530540 if (auto *Extract = dyn_cast<ExtractElementInst>(&I)) {
531541 if (!dyn_cast<BitCastInst>(Extract->getVectorOperand ()))
532- return ;
542+ return false ;
533543 auto *VecTy = dyn_cast<FixedVectorType>(Extract->getVectorOperandType ());
534544 if (VecTy && VecTy->getElementType ()->isIntegerTy (32 ) &&
535545 VecTy->getNumElements () == 2 ) {
@@ -557,12 +567,14 @@ legalizeGetHighLowi64Bytes(Instruction &I,
557567 }
558568 ToRemove.push_back (Extract);
559569 Extract->replaceAllUsesWith (ReplacedValues[Extract]);
570+ return true ;
560571 }
561572 }
562573 }
574+ return false ;
563575}
564576
565- static void
577+ static bool
566578legalizeScalarLoadStoreOnArrays (Instruction &I,
567579 SmallVectorImpl<Instruction *> &ToRemove,
568580 DenseMap<Value *, Value *> &) {
@@ -579,25 +591,25 @@ legalizeScalarLoadStoreOnArrays(Instruction &I,
579591 PtrOpIndex = SI->getPointerOperandIndex ();
580592 LoadStoreTy = SI->getValueOperand ()->getType ();
581593 } else
582- return ;
594+ return false ;
583595
584596 // If the load/store is not of a single-value type (i.e., scalar or vector)
585597 // then we do not modify it. It shouldn't be a vector either because the
586598 // dxil-data-scalarization pass is expected to run before this, but it's not
587599 // incorrect to apply this transformation to vector load/stores.
588600 if (!LoadStoreTy->isSingleValueType ())
589- return ;
601+ return false ;
590602
591603 Type *ArrayTy;
592604 if (auto *GlobalVarPtrOp = dyn_cast<GlobalVariable>(PtrOp))
593605 ArrayTy = GlobalVarPtrOp->getValueType ();
594606 else if (auto *AllocaPtrOp = dyn_cast<AllocaInst>(PtrOp))
595607 ArrayTy = AllocaPtrOp->getAllocatedType ();
596608 else
597- return ;
609+ return false ;
598610
599611 if (!isa<ArrayType>(ArrayTy))
600- return ;
612+ return false ;
601613
602614 assert (ArrayTy->getArrayElementType () == LoadStoreTy &&
603615 " Expected array element type to be the same as to the scalar load or "
@@ -607,6 +619,7 @@ legalizeScalarLoadStoreOnArrays(Instruction &I,
607619 Value *GEP = GetElementPtrInst::Create (
608620 ArrayTy, PtrOp, {Zero, Zero}, GEPNoWrapFlags::all (), " " , I.getIterator ());
609621 I.setOperand (PtrOpIndex, GEP);
622+ return true ;
610623}
611624
612625namespace {
@@ -624,13 +637,11 @@ class DXILLegalizationPipeline {
624637 ReplacedValues.clear ();
625638 for (auto &I : instructions (F)) {
626639 for (auto &LegalizationFn : LegalizationPipeline[Stage])
627- LegalizationFn (I, ToRemove, ReplacedValues);
640+ MadeChange |= LegalizationFn (I, ToRemove, ReplacedValues);
628641 }
629642
630643 for (auto *Inst : reverse (ToRemove))
631644 Inst->eraseFromParent ();
632-
633- MadeChange |= !ToRemove.empty ();
634645 }
635646 return MadeChange;
636647 }
@@ -639,7 +650,7 @@ class DXILLegalizationPipeline {
639650 enum LegalizationStage { Stage1 = 0 , Stage2 = 1 , NumStages };
640651
641652 using LegalizationFnTy =
642- std::function<void (Instruction &, SmallVectorImpl<Instruction *> &,
653+ std::function<bool (Instruction &, SmallVectorImpl<Instruction *> &,
643654 DenseMap<Value *, Value *> &)>;
644655
645656 SmallVector<LegalizationFnTy> LegalizationPipeline[NumStages];
0 commit comments