24
24
25
25
using namespace llvm ;
26
26
27
- static void legalizeFreeze (Instruction &I,
27
+ static bool legalizeFreeze (Instruction &I,
28
28
SmallVectorImpl<Instruction *> &ToRemove,
29
29
DenseMap<Value *, Value *>) {
30
30
auto *FI = dyn_cast<FreezeInst>(&I);
31
31
if (!FI)
32
- return ;
32
+ return false ;
33
33
34
34
FI->replaceAllUsesWith (FI->getOperand (0 ));
35
35
ToRemove.push_back (FI);
36
+ return true ;
36
37
}
37
38
38
- static void fixI8UseChain (Instruction &I,
39
+ static bool fixI8UseChain (Instruction &I,
39
40
SmallVectorImpl<Instruction *> &ToRemove,
40
41
DenseMap<Value *, Value *> &ReplacedValues) {
41
42
@@ -74,19 +75,19 @@ static void fixI8UseChain(Instruction &I,
74
75
if (Trunc->getDestTy ()->isIntegerTy (8 )) {
75
76
ReplacedValues[Trunc] = Trunc->getOperand (0 );
76
77
ToRemove.push_back (Trunc);
77
- return ;
78
+ return true ;
78
79
}
79
80
}
80
81
81
82
if (auto *Store = dyn_cast<StoreInst>(&I)) {
82
83
if (!Store->getValueOperand ()->getType ()->isIntegerTy (8 ))
83
- return ;
84
+ return false ;
84
85
SmallVector<Value *> NewOperands;
85
86
ProcessOperands (NewOperands);
86
87
Value *NewStore = Builder.CreateStore (NewOperands[0 ], NewOperands[1 ]);
87
88
ReplacedValues[Store] = NewStore;
88
89
ToRemove.push_back (Store);
89
- return ;
90
+ return true ;
90
91
}
91
92
92
93
if (auto *Load = dyn_cast<LoadInst>(&I);
@@ -104,17 +105,17 @@ static void fixI8UseChain(Instruction &I,
104
105
LoadInst *NewLoad = Builder.CreateLoad (ElementType, NewOperands[0 ]);
105
106
ReplacedValues[Load] = NewLoad;
106
107
ToRemove.push_back (Load);
107
- return ;
108
+ return true ;
108
109
}
109
110
110
111
if (auto *Load = dyn_cast<LoadInst>(&I);
111
112
Load && isa<ConstantExpr>(Load->getPointerOperand ())) {
112
113
auto *CE = dyn_cast<ConstantExpr>(Load->getPointerOperand ());
113
114
if (!(CE->getOpcode () == Instruction::GetElementPtr))
114
- return ;
115
+ return false ;
115
116
auto *GEP = dyn_cast<GEPOperator>(CE);
116
117
if (!GEP->getSourceElementType ()->isIntegerTy (8 ))
117
- return ;
118
+ return false ;
118
119
119
120
Type *ElementType = Load->getType ();
120
121
ConstantInt *Offset = dyn_cast<ConstantInt>(GEP->getOperand (1 ));
@@ -143,12 +144,12 @@ static void fixI8UseChain(Instruction &I,
143
144
ReplacedValues[Load] = NewLoad;
144
145
Load->replaceAllUsesWith (NewLoad);
145
146
ToRemove.push_back (Load);
146
- return ;
147
+ return true ;
147
148
}
148
149
149
150
if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
150
151
if (!I.getType ()->isIntegerTy (8 ))
151
- return ;
152
+ return false ;
152
153
SmallVector<Value *> NewOperands;
153
154
ProcessOperands (NewOperands);
154
155
Value *NewInst =
@@ -162,43 +163,43 @@ static void fixI8UseChain(Instruction &I,
162
163
}
163
164
ReplacedValues[BO] = NewInst;
164
165
ToRemove.push_back (BO);
165
- return ;
166
+ return true ;
166
167
}
167
168
168
169
if (auto *Sel = dyn_cast<SelectInst>(&I)) {
169
170
if (!I.getType ()->isIntegerTy (8 ))
170
- return ;
171
+ return false ;
171
172
SmallVector<Value *> NewOperands;
172
173
ProcessOperands (NewOperands);
173
174
Value *NewInst = Builder.CreateSelect (Sel->getCondition (), NewOperands[1 ],
174
175
NewOperands[2 ]);
175
176
ReplacedValues[Sel] = NewInst;
176
177
ToRemove.push_back (Sel);
177
- return ;
178
+ return true ;
178
179
}
179
180
180
181
if (auto *Cmp = dyn_cast<CmpInst>(&I)) {
181
182
if (!Cmp->getOperand (0 )->getType ()->isIntegerTy (8 ))
182
- return ;
183
+ return false ;
183
184
SmallVector<Value *> NewOperands;
184
185
ProcessOperands (NewOperands);
185
186
Value *NewInst =
186
187
Builder.CreateCmp (Cmp->getPredicate (), NewOperands[0 ], NewOperands[1 ]);
187
188
Cmp->replaceAllUsesWith (NewInst);
188
189
ReplacedValues[Cmp] = NewInst;
189
190
ToRemove.push_back (Cmp);
190
- return ;
191
+ return true ;
191
192
}
192
193
193
194
if (auto *Cast = dyn_cast<CastInst>(&I)) {
194
195
if (!Cast->getSrcTy ()->isIntegerTy (8 ))
195
- return ;
196
+ return false ;
196
197
197
198
ToRemove.push_back (Cast);
198
199
auto *Replacement = ReplacedValues[Cast->getOperand (0 )];
199
200
if (Cast->getType () == Replacement->getType ()) {
200
201
Cast->replaceAllUsesWith (Replacement);
201
- return ;
202
+ return true ;
202
203
}
203
204
204
205
Value *AdjustedCast = nullptr ;
@@ -213,7 +214,7 @@ static void fixI8UseChain(Instruction &I,
213
214
if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
214
215
if (!GEP->getType ()->isPointerTy () ||
215
216
!GEP->getSourceElementType ()->isIntegerTy (8 ))
216
- return ;
217
+ return false ;
217
218
218
219
Value *BasePtr = GEP->getPointerOperand ();
219
220
if (ReplacedValues.count (BasePtr))
@@ -248,15 +249,17 @@ static void fixI8UseChain(Instruction &I,
248
249
ReplacedValues[GEP] = NewGEP;
249
250
GEP->replaceAllUsesWith (NewGEP);
250
251
ToRemove.push_back (GEP);
252
+ return true ;
251
253
}
254
+ return false ;
252
255
}
253
256
254
- static void upcastI8AllocasAndUses (Instruction &I,
257
+ static bool upcastI8AllocasAndUses (Instruction &I,
255
258
SmallVectorImpl<Instruction *> &ToRemove,
256
259
DenseMap<Value *, Value *> &ReplacedValues) {
257
260
auto *AI = dyn_cast<AllocaInst>(&I);
258
261
if (!AI || !AI->getAllocatedType ()->isIntegerTy (8 ))
259
- return ;
262
+ return false ;
260
263
261
264
Type *SmallestType = nullptr ;
262
265
@@ -291,16 +294,17 @@ static void upcastI8AllocasAndUses(Instruction &I,
291
294
}
292
295
293
296
if (!SmallestType)
294
- return ; // no valid casts found
297
+ return false ; // no valid casts found
295
298
296
299
// Replace alloca
297
300
IRBuilder<> Builder (AI);
298
301
auto *NewAlloca = Builder.CreateAlloca (SmallestType);
299
302
ReplacedValues[AI] = NewAlloca;
300
303
ToRemove.push_back (AI);
304
+ return true ;
301
305
}
302
306
303
- static void
307
+ static bool
304
308
downcastI64toI32InsertExtractElements (Instruction &I,
305
309
SmallVectorImpl<Instruction *> &ToRemove,
306
310
DenseMap<Value *, Value *> &) {
@@ -318,6 +322,7 @@ downcastI64toI32InsertExtractElements(Instruction &I,
318
322
319
323
Extract->replaceAllUsesWith (NewExtract);
320
324
ToRemove.push_back (Extract);
325
+ return true ;
321
326
}
322
327
}
323
328
@@ -335,8 +340,10 @@ downcastI64toI32InsertExtractElements(Instruction &I,
335
340
336
341
Insert->replaceAllUsesWith (Insert32Index);
337
342
ToRemove.push_back (Insert);
343
+ return true ;
338
344
}
339
345
}
346
+ return false ;
340
347
}
341
348
342
349
static void emitMemcpyExpansion (IRBuilder<> &Builder, Value *Dst, Value *Src,
@@ -453,17 +460,17 @@ static void emitMemsetExpansion(IRBuilder<> &Builder, Value *Dst, Value *Val,
453
460
// Expands the instruction `I` into corresponding loads and stores if it is a
454
461
// memcpy call. In that case, the call instruction is added to the `ToRemove`
455
462
// vector. `ReplacedValues` is unused.
456
- static void legalizeMemCpy (Instruction &I,
463
+ static bool legalizeMemCpy (Instruction &I,
457
464
SmallVectorImpl<Instruction *> &ToRemove,
458
465
DenseMap<Value *, Value *> &ReplacedValues) {
459
466
460
467
CallInst *CI = dyn_cast<CallInst>(&I);
461
468
if (!CI)
462
- return ;
469
+ return false ;
463
470
464
471
Intrinsic::ID ID = CI->getIntrinsicID ();
465
472
if (ID != Intrinsic::memcpy)
466
- return ;
473
+ return false ;
467
474
468
475
IRBuilder<> Builder (&I);
469
476
Value *Dst = CI->getArgOperand (0 );
@@ -476,19 +483,20 @@ static void legalizeMemCpy(Instruction &I,
476
483
assert (IsVolatile->getZExtValue () == 0 && " Expected IsVolatile to be false" );
477
484
emitMemcpyExpansion (Builder, Dst, Src, Length);
478
485
ToRemove.push_back (CI);
486
+ return true ;
479
487
}
480
488
481
- static void legalizeMemSet (Instruction &I,
489
+ static bool legalizeMemSet (Instruction &I,
482
490
SmallVectorImpl<Instruction *> &ToRemove,
483
491
DenseMap<Value *, Value *> &ReplacedValues) {
484
492
485
493
CallInst *CI = dyn_cast<CallInst>(&I);
486
494
if (!CI)
487
- return ;
495
+ return false ;
488
496
489
497
Intrinsic::ID ID = CI->getIntrinsicID ();
490
498
if (ID != Intrinsic::memset)
491
- return ;
499
+ return false ;
492
500
493
501
IRBuilder<> Builder (&I);
494
502
Value *Dst = CI->getArgOperand (0 );
@@ -497,23 +505,25 @@ static void legalizeMemSet(Instruction &I,
497
505
assert (Size && " Expected Size to be a ConstantInt" );
498
506
emitMemsetExpansion (Builder, Dst, Val, Size, ReplacedValues);
499
507
ToRemove.push_back (CI);
508
+ return true ;
500
509
}
501
510
502
- static void updateFnegToFsub (Instruction &I,
511
+ static bool updateFnegToFsub (Instruction &I,
503
512
SmallVectorImpl<Instruction *> &ToRemove,
504
513
DenseMap<Value *, Value *> &) {
505
514
const Intrinsic::ID ID = I.getOpcode ();
506
515
if (ID != Instruction::FNeg)
507
- return ;
516
+ return false ;
508
517
509
518
IRBuilder<> Builder (&I);
510
519
Value *In = I.getOperand (0 );
511
520
Value *Zero = ConstantFP::get (In->getType (), -0.0 );
512
521
I.replaceAllUsesWith (Builder.CreateFSub (Zero, In));
513
522
ToRemove.push_back (&I);
523
+ return true ;
514
524
}
515
525
516
- static void
526
+ static bool
517
527
legalizeGetHighLowi64Bytes (Instruction &I,
518
528
SmallVectorImpl<Instruction *> &ToRemove,
519
529
DenseMap<Value *, Value *> &ReplacedValues) {
@@ -523,13 +533,13 @@ legalizeGetHighLowi64Bytes(Instruction &I,
523
533
BitCast->getSrcTy ()->isIntegerTy (64 )) {
524
534
ToRemove.push_back (BitCast);
525
535
ReplacedValues[BitCast] = BitCast->getOperand (0 );
526
- return ;
536
+ return true ;
527
537
}
528
538
}
529
539
530
540
if (auto *Extract = dyn_cast<ExtractElementInst>(&I)) {
531
541
if (!dyn_cast<BitCastInst>(Extract->getVectorOperand ()))
532
- return ;
542
+ return false ;
533
543
auto *VecTy = dyn_cast<FixedVectorType>(Extract->getVectorOperandType ());
534
544
if (VecTy && VecTy->getElementType ()->isIntegerTy (32 ) &&
535
545
VecTy->getNumElements () == 2 ) {
@@ -557,12 +567,14 @@ legalizeGetHighLowi64Bytes(Instruction &I,
557
567
}
558
568
ToRemove.push_back (Extract);
559
569
Extract->replaceAllUsesWith (ReplacedValues[Extract]);
570
+ return true ;
560
571
}
561
572
}
562
573
}
574
+ return false ;
563
575
}
564
576
565
- static void
577
+ static bool
566
578
legalizeScalarLoadStoreOnArrays (Instruction &I,
567
579
SmallVectorImpl<Instruction *> &ToRemove,
568
580
DenseMap<Value *, Value *> &) {
@@ -579,25 +591,25 @@ legalizeScalarLoadStoreOnArrays(Instruction &I,
579
591
PtrOpIndex = SI->getPointerOperandIndex ();
580
592
LoadStoreTy = SI->getValueOperand ()->getType ();
581
593
} else
582
- return ;
594
+ return false ;
583
595
584
596
// If the load/store is not of a single-value type (i.e., scalar or vector)
585
597
// then we do not modify it. It shouldn't be a vector either because the
586
598
// dxil-data-scalarization pass is expected to run before this, but it's not
587
599
// incorrect to apply this transformation to vector load/stores.
588
600
if (!LoadStoreTy->isSingleValueType ())
589
- return ;
601
+ return false ;
590
602
591
603
Type *ArrayTy;
592
604
if (auto *GlobalVarPtrOp = dyn_cast<GlobalVariable>(PtrOp))
593
605
ArrayTy = GlobalVarPtrOp->getValueType ();
594
606
else if (auto *AllocaPtrOp = dyn_cast<AllocaInst>(PtrOp))
595
607
ArrayTy = AllocaPtrOp->getAllocatedType ();
596
608
else
597
- return ;
609
+ return false ;
598
610
599
611
if (!isa<ArrayType>(ArrayTy))
600
- return ;
612
+ return false ;
601
613
602
614
assert (ArrayTy->getArrayElementType () == LoadStoreTy &&
603
615
" Expected array element type to be the same as to the scalar load or "
@@ -607,6 +619,7 @@ legalizeScalarLoadStoreOnArrays(Instruction &I,
607
619
Value *GEP = GetElementPtrInst::Create (
608
620
ArrayTy, PtrOp, {Zero, Zero}, GEPNoWrapFlags::all (), " " , I.getIterator ());
609
621
I.setOperand (PtrOpIndex, GEP);
622
+ return true ;
610
623
}
611
624
612
625
namespace {
@@ -624,13 +637,11 @@ class DXILLegalizationPipeline {
624
637
ReplacedValues.clear ();
625
638
for (auto &I : instructions (F)) {
626
639
for (auto &LegalizationFn : LegalizationPipeline[Stage])
627
- LegalizationFn (I, ToRemove, ReplacedValues);
640
+ MadeChange |= LegalizationFn (I, ToRemove, ReplacedValues);
628
641
}
629
642
630
643
for (auto *Inst : reverse (ToRemove))
631
644
Inst->eraseFromParent ();
632
-
633
- MadeChange |= !ToRemove.empty ();
634
645
}
635
646
return MadeChange;
636
647
}
@@ -639,7 +650,7 @@ class DXILLegalizationPipeline {
639
650
enum LegalizationStage { Stage1 = 0 , Stage2 = 1 , NumStages };
640
651
641
652
using LegalizationFnTy =
642
- std::function<void (Instruction &, SmallVectorImpl<Instruction *> &,
653
+ std::function<bool (Instruction &, SmallVectorImpl<Instruction *> &,
643
654
DenseMap<Value *, Value *> &)>;
644
655
645
656
SmallVector<LegalizationFnTy> LegalizationPipeline[NumStages];
0 commit comments