@@ -52,7 +52,7 @@ using namespace llvm;
52
52
namespace {
53
53
54
54
struct IntRange {
55
- int64_t Low, High;
55
+ APInt Low, High;
56
56
};
57
57
58
58
} // end anonymous namespace
@@ -66,8 +66,8 @@ bool IsInRanges(const IntRange &R, const std::vector<IntRange> &Ranges) {
66
66
// then check if the Low field is <= R.Low. If so, we
67
67
// have a Range that covers R.
68
68
auto I = llvm::lower_bound (
69
- Ranges, R, [](IntRange A, IntRange B) { return A.High < B.High ; });
70
- return I != Ranges.end () && I->Low <= R.Low ;
69
+ Ranges, R, [](IntRange A, IntRange B) { return A.High . slt ( B.High ) ; });
70
+ return I != Ranges.end () && I->Low . sle ( R.Low ) ;
71
71
}
72
72
73
73
struct CaseRange {
@@ -116,15 +116,14 @@ raw_ostream &operator<<(raw_ostream &O, const CaseVector &C) {
116
116
// / 2) Removed if subsequent incoming values now share the same case, i.e.,
117
117
// / multiple outcome edges are condensed into one. This is necessary to keep the
118
118
// / number of phi values equal to the number of branches to SuccBB.
119
- void FixPhis (
120
- BasicBlock *SuccBB, BasicBlock *OrigBB, BasicBlock *NewBB,
121
- const unsigned NumMergedCases = std::numeric_limits<unsigned >::max()) {
119
+ void FixPhis (BasicBlock *SuccBB, BasicBlock *OrigBB, BasicBlock *NewBB,
120
+ const APInt &NumMergedCases) {
122
121
for (auto &I : SuccBB->phis ()) {
123
122
PHINode *PN = cast<PHINode>(&I);
124
123
125
124
// Only update the first occurrence if NewBB exists.
126
125
unsigned Idx = 0 , E = PN->getNumIncomingValues ();
127
- unsigned LocalNumMergedCases = NumMergedCases;
126
+ APInt LocalNumMergedCases = NumMergedCases;
128
127
for (; Idx != E && NewBB; ++Idx) {
129
128
if (PN->getIncomingBlock (Idx) == OrigBB) {
130
129
PN->setIncomingBlock (Idx, NewBB);
@@ -139,10 +138,10 @@ void FixPhis(
139
138
// Remove additional occurrences coming from condensed cases and keep the
140
139
// number of incoming values equal to the number of branches to SuccBB.
141
140
SmallVector<unsigned , 8 > Indices;
142
- for (; LocalNumMergedCases > 0 && Idx < E; ++Idx)
141
+ for (; LocalNumMergedCases. ugt ( 0 ) && Idx < E; ++Idx)
143
142
if (PN->getIncomingBlock (Idx) == OrigBB) {
144
143
Indices.push_back (Idx);
145
- LocalNumMergedCases-- ;
144
+ LocalNumMergedCases -= 1 ;
146
145
}
147
146
// Remove incoming values in the reverse order to prevent invalidating
148
147
// *successive* index.
@@ -209,8 +208,8 @@ BasicBlock *NewLeafBlock(CaseRange &Leaf, Value *Val, ConstantInt *LowerBound,
209
208
for (BasicBlock::iterator I = Succ->begin (); isa<PHINode>(I); ++I) {
210
209
PHINode *PN = cast<PHINode>(I);
211
210
// Remove all but one incoming entries from the cluster
212
- uint64_t Range = Leaf.High ->getSExtValue () - Leaf.Low ->getSExtValue ();
213
- for (uint64_t j = 0 ; j < Range; ++j) {
211
+ APInt Range = Leaf.High ->getValue () - Leaf.Low ->getValue ();
212
+ for (APInt j (Range. getBitWidth (), 0 , true ) ; j. slt ( Range) ; ++j) {
214
213
PN->removeIncomingValue (OrigBlock);
215
214
}
216
215
@@ -241,8 +240,7 @@ BasicBlock *SwitchConvert(CaseItr Begin, CaseItr End, ConstantInt *LowerBound,
241
240
// emitting the code that checks if the value actually falls in the range
242
241
// because the bounds already tell us so.
243
242
if (Begin->Low == LowerBound && Begin->High == UpperBound) {
244
- unsigned NumMergedCases = 0 ;
245
- NumMergedCases = UpperBound->getSExtValue () - LowerBound->getSExtValue ();
243
+ APInt NumMergedCases = UpperBound->getValue () - LowerBound->getValue ();
246
244
FixPhis (Begin->BB , OrigBlock, Predecessor, NumMergedCases);
247
245
return Begin->BB ;
248
246
}
@@ -273,17 +271,17 @@ BasicBlock *SwitchConvert(CaseItr Begin, CaseItr End, ConstantInt *LowerBound,
273
271
274
272
if (!UnreachableRanges.empty ()) {
275
273
// Check if the gap between LHS's highest and NewLowerBound is unreachable.
276
- int64_t GapLow = LHS.back ().High ->getSExtValue () + 1 ;
277
- int64_t GapHigh = NewLowerBound->getSExtValue () - 1 ;
274
+ APInt GapLow = LHS.back ().High ->getValue () + 1 ;
275
+ APInt GapHigh = NewLowerBound->getValue () - 1 ;
278
276
IntRange Gap = {GapLow, GapHigh};
279
- if (GapHigh >= GapLow && IsInRanges (Gap, UnreachableRanges))
277
+ if (GapHigh. sge ( GapLow) && IsInRanges (Gap, UnreachableRanges))
280
278
NewUpperBound = LHS.back ().High ;
281
279
}
282
280
283
- LLVM_DEBUG (dbgs () << " LHS Bounds ==> [" << LowerBound->getSExtValue () << " , "
284
- << NewUpperBound->getSExtValue () << " ]\n "
285
- << " RHS Bounds ==> [" << NewLowerBound->getSExtValue ()
286
- << " , " << UpperBound->getSExtValue () << " ]\n " );
281
+ LLVM_DEBUG (dbgs () << " LHS Bounds ==> [" << LowerBound->getValue () << " , "
282
+ << NewUpperBound->getValue () << " ]\n "
283
+ << " RHS Bounds ==> [" << NewLowerBound->getValue () << " , "
284
+ << UpperBound->getValue () << " ]\n " );
287
285
288
286
// Create a new node that checks if the value is < pivot. Go to the
289
287
// left branch if it is and right branch if not.
@@ -327,14 +325,15 @@ unsigned Clusterify(CaseVector &Cases, SwitchInst *SI) {
327
325
if (Cases.size () >= 2 ) {
328
326
CaseItr I = Cases.begin ();
329
327
for (CaseItr J = std::next (I), E = Cases.end (); J != E; ++J) {
330
- int64_t nextValue = J->Low ->getSExtValue ();
331
- int64_t currentValue = I->High ->getSExtValue ();
328
+ const APInt & nextValue = J->Low ->getValue ();
329
+ const APInt & currentValue = I->High ->getValue ();
332
330
BasicBlock *nextBB = J->BB ;
333
331
BasicBlock *currentBB = I->BB ;
334
332
335
333
// If the two neighboring cases go to the same destination, merge them
336
334
// into a single case.
337
- assert (nextValue > currentValue && " Cases should be strictly ascending" );
335
+ assert (nextValue.sgt (currentValue) &&
336
+ " Cases should be strictly ascending" );
338
337
if ((nextValue == currentValue + 1 ) && (currentBB == nextBB)) {
339
338
I->High = J->High ;
340
339
// FIXME: Combine branch weights.
@@ -369,6 +368,10 @@ void ProcessSwitchInst(SwitchInst *SI,
369
368
// Prepare cases vector.
370
369
CaseVector Cases;
371
370
const unsigned NumSimpleCases = Clusterify (Cases, SI);
371
+ IntegerType *IT = cast<IntegerType>(SI->getCondition ()->getType ());
372
+ const unsigned BitWidth = IT->getBitWidth ();
373
+ APInt SignedZero (BitWidth, 0 );
374
+ APInt UnsignedMax = APInt::getMaxValue (BitWidth);
372
375
LLVM_DEBUG (dbgs () << " Clusterify finished. Total clusters: " << Cases.size ()
373
376
<< " . Total non-default cases: " << NumSimpleCases
374
377
<< " \n Case clusters: " << Cases << " \n " );
@@ -377,7 +380,7 @@ void ProcessSwitchInst(SwitchInst *SI,
377
380
if (Cases.empty ()) {
378
381
BranchInst::Create (Default, OrigBlock);
379
382
// Remove all the references from Default's PHIs to OrigBlock, but one.
380
- FixPhis (Default, OrigBlock, OrigBlock);
383
+ FixPhis (Default, OrigBlock, OrigBlock, UnsignedMax );
381
384
SI->eraseFromParent ();
382
385
return ;
383
386
}
@@ -414,8 +417,8 @@ void ProcessSwitchInst(SwitchInst *SI,
414
417
// the unlikely event that some of them survived, we just conservatively
415
418
// maintain the invariant that all the cases lie between the bounds. This
416
419
// may, however, still render the default case effectively unreachable.
417
- APInt Low = Cases.front ().Low ->getValue ();
418
- APInt High = Cases.back ().High ->getValue ();
420
+ const APInt & Low = Cases.front ().Low ->getValue ();
421
+ const APInt & High = Cases.back ().High ->getValue ();
419
422
APInt Min = APIntOps::smin (ValRange.getSignedMin (), Low);
420
423
APInt Max = APIntOps::smax (ValRange.getSignedMax (), High);
421
424
@@ -427,35 +430,38 @@ void ProcessSwitchInst(SwitchInst *SI,
427
430
std::vector<IntRange> UnreachableRanges;
428
431
429
432
if (DefaultIsUnreachableFromSwitch) {
430
- DenseMap<BasicBlock *, unsigned > Popularity;
431
- unsigned MaxPop = 0 ;
433
+ DenseMap<BasicBlock *, APInt > Popularity;
434
+ APInt MaxPop (SignedZero) ;
432
435
BasicBlock *PopSucc = nullptr ;
433
436
434
- IntRange R = {std::numeric_limits<int64_t >::min (),
435
- std::numeric_limits<int64_t >::max ()};
437
+ APInt SignedMax = APInt::getSignedMaxValue (BitWidth);
438
+ APInt SignedMin = APInt::getSignedMinValue (BitWidth);
439
+ IntRange R = {SignedMin, SignedMax};
436
440
UnreachableRanges.push_back (R);
437
441
for (const auto &I : Cases) {
438
- int64_t Low = I.Low ->getSExtValue ();
439
- int64_t High = I.High ->getSExtValue ();
442
+ const APInt & Low = I.Low ->getValue ();
443
+ const APInt & High = I.High ->getValue ();
440
444
441
445
IntRange &LastRange = UnreachableRanges.back ();
442
- if (LastRange.Low == Low) {
446
+ if (LastRange.Low . eq ( Low) ) {
443
447
// There is nothing left of the previous range.
444
448
UnreachableRanges.pop_back ();
445
449
} else {
446
450
// Terminate the previous range.
447
- assert (Low > LastRange.Low );
451
+ assert (Low. sgt ( LastRange.Low ) );
448
452
LastRange.High = Low - 1 ;
449
453
}
450
- if (High != std::numeric_limits< int64_t >:: max ( )) {
451
- IntRange R = {High + 1 , std::numeric_limits< int64_t >:: max () };
454
+ if (High. ne (SignedMax )) {
455
+ IntRange R = {High + 1 , SignedMax };
452
456
UnreachableRanges.push_back (R);
453
457
}
454
458
455
459
// Count popularity.
456
- int64_t N = High - Low + 1 ;
457
- unsigned &Pop = Popularity[I.BB ];
458
- if ((Pop += N) > MaxPop) {
460
+ APInt N = High - Low + 1 ;
461
+ assert (N.sge (SignedZero) && " Popularity shouldn't be negative." );
462
+ // Explict insert to make sure the bitwidth of APInts match
463
+ APInt &Pop = Popularity.insert ({I.BB , APInt (SignedZero)}).first ->second ;
464
+ if ((Pop += N).sgt (MaxPop)) {
459
465
MaxPop = Pop;
460
466
PopSucc = I.BB ;
461
467
}
@@ -464,10 +470,10 @@ void ProcessSwitchInst(SwitchInst *SI,
464
470
/* UnreachableRanges should be sorted and the ranges non-adjacent. */
465
471
for (auto I = UnreachableRanges.begin (), E = UnreachableRanges.end ();
466
472
I != E; ++I) {
467
- assert (I->Low <= I->High );
473
+ assert (I->Low . sle ( I->High ) );
468
474
auto Next = I + 1 ;
469
475
if (Next != E) {
470
- assert (Next->Low > I->High );
476
+ assert (Next->Low . sgt ( I->High ) );
471
477
}
472
478
}
473
479
#endif
@@ -480,7 +486,8 @@ void ProcessSwitchInst(SwitchInst *SI,
480
486
481
487
// Use the most popular block as the new default, reducing the number of
482
488
// cases.
483
- assert (MaxPop > 0 && PopSucc);
489
+ assert (MaxPop.sgt (SignedZero) && PopSucc &&
490
+ " Max populartion shouldn't be negative." );
484
491
Default = PopSucc;
485
492
llvm::erase_if (Cases,
486
493
[PopSucc](const CaseRange &R) { return R.BB == PopSucc; });
@@ -491,7 +498,7 @@ void ProcessSwitchInst(SwitchInst *SI,
491
498
SI->eraseFromParent ();
492
499
// As all the cases have been replaced with a single branch, only keep
493
500
// one entry in the PHI nodes.
494
- for (unsigned I = 0 ; I < (MaxPop - 1 ); ++I)
501
+ for (APInt I (SignedZero) ; I. slt (MaxPop - 1 ); ++I)
495
502
PopSucc->removePredecessor (OrigBlock);
496
503
return ;
497
504
}
@@ -512,7 +519,7 @@ void ProcessSwitchInst(SwitchInst *SI,
512
519
// that SwitchBlock is the same as Default, under which the PHIs in Default
513
520
// are fixed inside SwitchConvert().
514
521
if (SwitchBlock != Default)
515
- FixPhis (Default, OrigBlock, nullptr );
522
+ FixPhis (Default, OrigBlock, nullptr , UnsignedMax );
516
523
517
524
// Branch to our shiny new if-then stuff...
518
525
BranchInst::Create (SwitchBlock, OrigBlock);
0 commit comments