@@ -151,6 +151,11 @@ namespace {
151
151
// / This is the cache kept by LazyValueInfo which
152
152
// / maintains information about queries across the clients' queries.
153
153
class LazyValueInfoCache {
154
+ public:
155
+ typedef DenseMap<PoisoningVH<BasicBlock>, SmallPtrSet<Value *, 4 >>
156
+ PerBlockValueCacheTy;
157
+
158
+ private:
154
159
// / This is all of the cached block information for exactly one Value*.
155
160
// / The entries are sorted by the BasicBlock* of the
156
161
// / entries, allowing us to do a lookup with a binary search.
@@ -162,18 +167,19 @@ namespace {
162
167
SmallDenseMap<PoisoningVH<BasicBlock>, ValueLatticeElement, 4 > BlockVals;
163
168
};
164
169
165
- // / This tracks, on a per-block basis, the set of values that are
166
- // / over-defined at the end of that block.
167
- typedef DenseMap<PoisoningVH<BasicBlock>, SmallPtrSet<Value *, 4 >>
168
- OverDefinedCacheTy;
169
170
// / Keep track of all blocks that we have ever seen, so we
170
171
// / don't spend time removing unused blocks from our caches.
171
172
DenseSet<PoisoningVH<BasicBlock> > SeenBlocks;
172
173
173
174
// / This is all of the cached information for all values,
174
175
// / mapped from Value* to key information.
175
176
DenseMap<Value *, std::unique_ptr<ValueCacheEntryTy>> ValueCache;
176
- OverDefinedCacheTy OverDefinedCache;
177
+ // / This tracks, on a per-block basis, the set of values that are
178
+ // / over-defined at the end of that block.
179
+ PerBlockValueCacheTy OverDefinedCache;
180
+ // / This tracks, on a per-block basis, the set of pointers that are
181
+ // / dereferenced in the block (and thus non-null at the end of the block).
182
+ PerBlockValueCacheTy DereferencedPointerCache;
177
183
178
184
179
185
public:
@@ -229,11 +235,17 @@ namespace {
229
235
return BBI->second ;
230
236
}
231
237
238
+ std::pair<PerBlockValueCacheTy::iterator, bool >
239
+ getOrInitDereferencedPointers (BasicBlock *BB) {
240
+ return DereferencedPointerCache.try_emplace (BB);
241
+ }
242
+
232
243
// / clear - Empty the cache.
233
244
void clear () {
234
245
SeenBlocks.clear ();
235
246
ValueCache.clear ();
236
247
OverDefinedCache.clear ();
248
+ DereferencedPointerCache.clear ();
237
249
}
238
250
239
251
// / Inform the cache that a given value has been deleted.
@@ -252,17 +264,22 @@ namespace {
252
264
};
253
265
}
254
266
255
- void LazyValueInfoCache::eraseValue (Value *V) {
256
- for (auto I = OverDefinedCache.begin (), E = OverDefinedCache.end (); I != E;) {
267
+ static void eraseValueFromPerBlockValueCache (
268
+ Value *V, LazyValueInfoCache::PerBlockValueCacheTy &Cache) {
269
+ for (auto I = Cache.begin (), E = Cache.end (); I != E;) {
257
270
// Copy and increment the iterator immediately so we can erase behind
258
271
// ourselves.
259
272
auto Iter = I++;
260
273
SmallPtrSetImpl<Value *> &ValueSet = Iter->second ;
261
274
ValueSet.erase (V);
262
275
if (ValueSet.empty ())
263
- OverDefinedCache .erase (Iter);
276
+ Cache .erase (Iter);
264
277
}
278
+ }
265
279
280
+ void LazyValueInfoCache::eraseValue (Value *V) {
281
+ eraseValueFromPerBlockValueCache (V, OverDefinedCache);
282
+ eraseValueFromPerBlockValueCache (V, DereferencedPointerCache);
266
283
ValueCache.erase (V);
267
284
}
268
285
@@ -279,9 +296,8 @@ void LazyValueInfoCache::eraseBlock(BasicBlock *BB) {
279
296
return ;
280
297
SeenBlocks.erase (I);
281
298
282
- auto ODI = OverDefinedCache.find (BB);
283
- if (ODI != OverDefinedCache.end ())
284
- OverDefinedCache.erase (ODI);
299
+ OverDefinedCache.erase (BB);
300
+ DereferencedPointerCache.erase (BB);
285
301
286
302
for (auto &I : ValueCache)
287
303
I.second ->BlockVals .erase (BB);
@@ -438,6 +454,7 @@ namespace {
438
454
BasicBlock *BB);
439
455
bool solveBlockValueExtractValue (ValueLatticeElement &BBLV,
440
456
ExtractValueInst *EVI, BasicBlock *BB);
457
+ bool isNonNullDueToDereferenceInBlock (Value *Val, BasicBlock *BB);
441
458
void intersectAssumeOrGuardBlockValueConstantRange (Value *Val,
442
459
ValueLatticeElement &BBLV,
443
460
Instruction *BBI);
@@ -619,17 +636,6 @@ bool LazyValueInfoImpl::solveBlockValue(Value *Val, BasicBlock *BB) {
619
636
620
637
bool LazyValueInfoImpl::solveBlockValueImpl (ValueLatticeElement &Res,
621
638
Value *Val, BasicBlock *BB) {
622
-
623
- Instruction *BBI = dyn_cast<Instruction>(Val);
624
- if (!BBI || BBI->getParent () != BB)
625
- return solveBlockValueNonLocal (Res, Val, BB);
626
-
627
- if (PHINode *PN = dyn_cast<PHINode>(BBI))
628
- return solveBlockValuePHINode (Res, PN, BB);
629
-
630
- if (auto *SI = dyn_cast<SelectInst>(BBI))
631
- return solveBlockValueSelect (Res, SI, BB);
632
-
633
639
// If this value is a nonnull pointer, record it's range and bailout. Note
634
640
// that for all other pointer typed values, we terminate the search at the
635
641
// definition. We could easily extend this to look through geps, bitcasts,
@@ -639,11 +645,22 @@ bool LazyValueInfoImpl::solveBlockValueImpl(ValueLatticeElement &Res,
639
645
// This does mean that we have a sensitivity to where the defining
640
646
// instruction is placed, even if it could legally be hoisted much higher.
641
647
// That is unfortunate.
642
- PointerType *PT = dyn_cast<PointerType>(BBI ->getType ());
643
- if (PT && isKnownNonZero (BBI , DL)) {
648
+ PointerType *PT = dyn_cast<PointerType>(Val ->getType ());
649
+ if (PT && isKnownNonZero (Val , DL)) {
644
650
Res = ValueLatticeElement::getNot (ConstantPointerNull::get (PT));
645
651
return true ;
646
652
}
653
+
654
+ Instruction *BBI = dyn_cast<Instruction>(Val);
655
+ if (!BBI || BBI->getParent () != BB)
656
+ return solveBlockValueNonLocal (Res, Val, BB);
657
+
658
+ if (PHINode *PN = dyn_cast<PHINode>(BBI))
659
+ return solveBlockValuePHINode (Res, PN, BB);
660
+
661
+ if (auto *SI = dyn_cast<SelectInst>(BBI))
662
+ return solveBlockValueSelect (Res, SI, BB);
663
+
647
664
if (BBI->getType ()->isIntegerTy ()) {
648
665
if (auto *CI = dyn_cast<CastInst>(BBI))
649
666
return solveBlockValueCast (Res, CI, BB);
@@ -664,75 +681,63 @@ bool LazyValueInfoImpl::solveBlockValueImpl(ValueLatticeElement &Res,
664
681
return true ;
665
682
}
666
683
667
- static bool InstructionDereferencesPointer (Instruction *I, Value *Ptr ) {
668
- if (LoadInst *L = dyn_cast<LoadInst>(I)) {
669
- return L->getPointerAddressSpace () == 0 &&
670
- GetUnderlyingObject (L->getPointerOperand (),
671
- L->getModule ()->getDataLayout ()) == Ptr ;
684
+ static void AddDereferencedPointer (
685
+ Value *Ptr , SmallPtrSet<Value *, 4 > &PtrSet, const DataLayout &DL) {
686
+ // TODO: Use NullPointerIsDefined instead.
687
+ if (Ptr ->getType ()->getPointerAddressSpace () == 0 ) {
688
+ Ptr = GetUnderlyingObject (Ptr , DL);
689
+ PtrSet.insert (Ptr );
672
690
}
673
- if (StoreInst *S = dyn_cast<StoreInst>(I)) {
674
- return S->getPointerAddressSpace () == 0 &&
675
- GetUnderlyingObject (S->getPointerOperand (),
676
- S->getModule ()->getDataLayout ()) == Ptr ;
677
- }
678
- if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
679
- if (MI->isVolatile ()) return false ;
691
+ }
692
+
693
+ static void AddPointersDereferencedByInstruction (
694
+ Instruction *I, SmallPtrSet<Value *, 4 > &PtrSet, const DataLayout &DL) {
695
+ if (LoadInst *L = dyn_cast<LoadInst>(I)) {
696
+ AddDereferencedPointer (L->getPointerOperand (), PtrSet, DL);
697
+ } else if (StoreInst *S = dyn_cast<StoreInst>(I)) {
698
+ AddDereferencedPointer (S->getPointerOperand (), PtrSet, DL);
699
+ } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
700
+ if (MI->isVolatile ()) return ;
680
701
681
702
// FIXME: check whether it has a valuerange that excludes zero?
682
703
ConstantInt *Len = dyn_cast<ConstantInt>(MI->getLength ());
683
- if (!Len || Len->isZero ()) return false ;
704
+ if (!Len || Len->isZero ()) return ;
684
705
685
- if (MI->getDestAddressSpace () == 0 )
686
- if (GetUnderlyingObject (MI->getRawDest (),
687
- MI->getModule ()->getDataLayout ()) == Ptr )
688
- return true ;
706
+ AddDereferencedPointer (MI->getRawDest (), PtrSet, DL);
689
707
if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI))
690
- if (MTI->getSourceAddressSpace () == 0 )
691
- if (GetUnderlyingObject (MTI->getRawSource (),
692
- MTI->getModule ()->getDataLayout ()) == Ptr )
693
- return true ;
708
+ AddDereferencedPointer (MTI->getRawSource (), PtrSet, DL);
694
709
}
695
- return false ;
696
710
}
697
711
698
- // / Return true if the allocation associated with Val is ever dereferenced
699
- // / within the given basic block. This establishes the fact Val is not null,
700
- // / but does not imply that the memory at Val is dereferenceable. (Val may
701
- // / point off the end of the dereferenceable part of the object.)
702
- static bool isObjectDereferencedInBlock (Value *Val, BasicBlock *BB) {
703
- assert (Val->getType ()->isPointerTy ());
712
+ bool LazyValueInfoImpl::isNonNullDueToDereferenceInBlock (
713
+ Value *Val, BasicBlock *BB) {
714
+ if (NullPointerIsDefined (BB->getParent (),
715
+ Val->getType ()->getPointerAddressSpace ()))
716
+ return false ;
704
717
705
718
const DataLayout &DL = BB->getModule ()->getDataLayout ();
706
- Value *UnderlyingVal = GetUnderlyingObject (Val, DL);
707
- // If 'GetUnderlyingObject' didn't converge, skip it. It won't converge
708
- // inside InstructionDereferencesPointer either.
709
- if (UnderlyingVal == GetUnderlyingObject (UnderlyingVal, DL, 1 ))
719
+ Val = GetUnderlyingObject (Val, DL);
720
+
721
+ LazyValueInfoCache::PerBlockValueCacheTy::iterator It;
722
+ bool NeedsInit;
723
+ std::tie (It, NeedsInit) = TheCache.getOrInitDereferencedPointers (BB);
724
+
725
+ if (NeedsInit)
710
726
for (Instruction &I : *BB)
711
- if ( InstructionDereferencesPointer ( &I, UnderlyingVal))
712
- return true ;
713
- return false ;
727
+ AddPointersDereferencedByInstruction ( &I, It-> second , DL);
728
+
729
+ return It-> second . count (Val) ;
714
730
}
715
731
716
732
bool LazyValueInfoImpl::solveBlockValueNonLocal (ValueLatticeElement &BBLV,
717
- Value *Val, BasicBlock *BB) {
733
+ Value *Val, BasicBlock *BB) {
718
734
ValueLatticeElement Result; // Start Undefined.
719
735
720
736
// If this is the entry block, we must be asking about an argument. The
721
737
// value is overdefined.
722
738
if (BB == &BB->getParent ()->getEntryBlock ()) {
723
739
assert (isa<Argument>(Val) && " Unknown live-in to the entry block" );
724
- // Before giving up, see if we can prove the pointer non-null local to
725
- // this particular block.
726
- PointerType *PTy = dyn_cast<PointerType>(Val->getType ());
727
- if (PTy &&
728
- (isKnownNonZero (Val, DL) ||
729
- (isObjectDereferencedInBlock (Val, BB) &&
730
- !NullPointerIsDefined (BB->getParent (), PTy->getAddressSpace ())))) {
731
- Result = ValueLatticeElement::getNot (ConstantPointerNull::get (PTy));
732
- } else {
733
- Result = ValueLatticeElement::getOverdefined ();
734
- }
735
- BBLV = Result;
740
+ BBLV = ValueLatticeElement::getOverdefined ();
736
741
return true ;
737
742
}
738
743
@@ -758,14 +763,6 @@ bool LazyValueInfoImpl::solveBlockValueNonLocal(ValueLatticeElement &BBLV,
758
763
if (Result.isOverdefined ()) {
759
764
LLVM_DEBUG (dbgs () << " compute BB '" << BB->getName ()
760
765
<< " ' - overdefined because of pred (non local).\n " );
761
- // Before giving up, see if we can prove the pointer non-null local to
762
- // this particular block.
763
- PointerType *PTy = dyn_cast<PointerType>(Val->getType ());
764
- if (PTy && isObjectDereferencedInBlock (Val, BB) &&
765
- !NullPointerIsDefined (BB->getParent (), PTy->getAddressSpace ())) {
766
- Result = ValueLatticeElement::getNot (ConstantPointerNull::get (PTy));
767
- }
768
-
769
766
BBLV = Result;
770
767
return true ;
771
768
}
@@ -838,16 +835,24 @@ void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
838
835
// If guards are not used in the module, don't spend time looking for them
839
836
auto *GuardDecl = BBI->getModule ()->getFunction (
840
837
Intrinsic::getName (Intrinsic::experimental_guard));
841
- if (!GuardDecl || GuardDecl->use_empty ())
842
- return ;
838
+ if (GuardDecl && !GuardDecl->use_empty ()) {
839
+ if (BBI->getIterator () == BBI->getParent ()->begin ())
840
+ return ;
841
+ for (Instruction &I : make_range (std::next (BBI->getIterator ().getReverse ()),
842
+ BBI->getParent ()->rend ())) {
843
+ Value *Cond = nullptr ;
844
+ if (match (&I, m_Intrinsic<Intrinsic::experimental_guard>(m_Value (Cond))))
845
+ BBLV = intersect (BBLV, getValueFromCondition (Val, Cond));
846
+ }
847
+ }
843
848
844
- if (BBI-> getIterator () == BBI-> getParent ()-> begin ())
845
- return ;
846
- for (Instruction &I : make_range ( std::next (BBI-> getIterator (). getReverse ()),
847
- BBI-> getParent ()-> rend ())) {
848
- Value *Cond = nullptr ;
849
- if ( match (&I, m_Intrinsic<Intrinsic::experimental_guard>( m_Value (Cond) )))
850
- BBLV = intersect (BBLV, getValueFromCondition (Val, Cond ));
849
+ if (BBLV. isOverdefined ()) {
850
+ // Check whether we're checking at the terminator, and the pointer has
851
+ // been dereferenced in this block.
852
+ PointerType *PTy = dyn_cast<PointerType>(Val-> getType ());
853
+ if (PTy && BBI-> getParent ()-> getTerminator () == BBI &&
854
+ isNonNullDueToDereferenceInBlock (Val, BBI-> getParent ( )))
855
+ BBLV = ValueLatticeElement::getNot ( ConstantPointerNull::get (PTy ));
851
856
}
852
857
}
853
858
0 commit comments