@@ -322,30 +322,40 @@ AA::combineOptionalValuesInAAValueLatice(const Optional<Value *> &A,
322
322
return nullptr ;
323
323
}
324
324
325
- bool AA::getPotentialCopiesOfStoredValue (
326
- Attributor &A, StoreInst &SI, SmallSetVector<Value *, 4 > &PotentialCopies,
327
- const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation) {
328
-
329
- Value &Ptr = *SI.getPointerOperand ();
325
+ template <bool IsLoad, typename Ty>
326
+ static bool
327
+ getPotentialCopiesOfMemoryValue (Attributor &A, Ty &I,
328
+ SmallSetVector<Value *, 4 > &PotentialCopies,
329
+ const AbstractAttribute &QueryingAA,
330
+ bool &UsedAssumedInformation, bool OnlyExact) {
331
+ LLVM_DEBUG (dbgs () << " Trying to determine the potential copies of " << I
332
+ << " (only exact: " << OnlyExact << " )\n " ;);
333
+
334
+ Value &Ptr = *I.getPointerOperand ();
330
335
SmallVector<Value *, 8 > Objects;
331
- if (!AA::getAssumedUnderlyingObjects (A, Ptr, Objects, QueryingAA, &SI ,
336
+ if (!AA::getAssumedUnderlyingObjects (A, Ptr, Objects, QueryingAA, &I ,
332
337
UsedAssumedInformation)) {
333
338
LLVM_DEBUG (
334
339
dbgs () << " Underlying objects stored into could not be determined\n " ;);
335
340
return false ;
336
341
}
337
342
343
+ // Containers to remember the pointer infos and new copies while we are not
344
+ // sure that we can find all of them. If we abort we want to avoid spurious
345
+ // dependences and potential copies in the provided container.
338
346
SmallVector<const AAPointerInfo *> PIs;
339
347
SmallVector<Value *> NewCopies;
340
348
349
+ const auto *TLI =
350
+ A.getInfoCache ().getTargetLibraryInfoForFunction (*I.getFunction ());
341
351
for (Value *Obj : Objects) {
342
352
LLVM_DEBUG (dbgs () << " Visit underlying object " << *Obj << " \n " );
343
353
if (isa<UndefValue>(Obj))
344
354
continue ;
345
355
if (isa<ConstantPointerNull>(Obj)) {
346
356
// A null pointer access can be undefined but any offset from null may
347
357
// be OK. We do not try to optimize the latter.
348
- if (!NullPointerIsDefined (SI .getFunction (),
358
+ if (!NullPointerIsDefined (I .getFunction (),
349
359
Ptr.getType ()->getPointerAddressSpace ()) &&
350
360
A.getAssumedSimplified (Ptr, QueryingAA, UsedAssumedInformation) ==
351
361
Obj)
@@ -354,8 +364,9 @@ bool AA::getPotentialCopiesOfStoredValue(
354
364
dbgs () << " Underlying object is a valid nullptr, giving up.\n " ;);
355
365
return false ;
356
366
}
367
+ // TODO: Use assumed noalias return.
357
368
if (!isa<AllocaInst>(Obj) && !isa<GlobalVariable>(Obj) &&
358
- !isNoAliasCall (Obj)) {
369
+ !(IsLoad ? isAllocationFn (Obj, TLI) : isNoAliasCall (Obj) )) {
359
370
LLVM_DEBUG (dbgs () << " Underlying object is not supported yet: " << *Obj
360
371
<< " \n " ;);
361
372
return false ;
@@ -368,23 +379,54 @@ bool AA::getPotentialCopiesOfStoredValue(
368
379
return false ;
369
380
}
370
381
382
+ if (IsLoad) {
383
+ Value *InitialValue = AA::getInitialValueForObj (*Obj, *I.getType (), TLI);
384
+ if (!InitialValue)
385
+ return false ;
386
+ NewCopies.push_back (InitialValue);
387
+ }
388
+
371
389
auto CheckAccess = [&](const AAPointerInfo::Access &Acc, bool IsExact) {
372
- if (!Acc.isRead ())
390
+ if ((IsLoad && !Acc.isWrite ()) || (!IsLoad && !Acc. isRead () ))
373
391
return true ;
374
- auto *LI = dyn_cast<LoadInst>(Acc.getRemoteInst ());
375
- if (!LI) {
376
- LLVM_DEBUG (dbgs () << " Underlying object read through a non-load "
377
- " instruction not supported yet: "
378
- << *Acc.getRemoteInst () << " \n " ;);
392
+ if (OnlyExact && !IsExact) {
393
+ LLVM_DEBUG (dbgs () << " Non exact access " << *Acc.getRemoteInst ()
394
+ << " , abort!\n " );
379
395
return false ;
380
396
}
381
- NewCopies.push_back (LI);
397
+ if (IsLoad) {
398
+ assert (isa<LoadInst>(I) && " Expected load or store instruction only!" );
399
+ if (Acc.isWrittenValueYetUndetermined ())
400
+ return true ;
401
+ if (!Acc.isWrittenValueUnknown ()) {
402
+ NewCopies.push_back (Acc.getWrittenValue ());
403
+ return true ;
404
+ }
405
+ auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst ());
406
+ if (!SI) {
407
+ LLVM_DEBUG (dbgs () << " Underlying object written through a non-store "
408
+ " instruction not supported yet: "
409
+ << *Acc.getRemoteInst () << " \n " ;);
410
+ return false ;
411
+ }
412
+ NewCopies.push_back (SI->getValueOperand ());
413
+ } else {
414
+ assert (isa<StoreInst>(I) && " Expected load or store instruction only!" );
415
+ auto *LI = dyn_cast<LoadInst>(Acc.getRemoteInst ());
416
+ if (!LI && OnlyExact) {
417
+ LLVM_DEBUG (dbgs () << " Underlying object read through a non-load "
418
+ " instruction not supported yet: "
419
+ << *Acc.getRemoteInst () << " \n " ;);
420
+ return false ;
421
+ }
422
+ NewCopies.push_back (Acc.getRemoteInst ());
423
+ }
382
424
return true ;
383
425
};
384
426
385
427
auto &PI = A.getAAFor <AAPointerInfo>(QueryingAA, IRPosition::value (*Obj),
386
428
DepClassTy::NONE);
387
- if (!PI.forallInterferingAccesses (A, QueryingAA, SI , CheckAccess)) {
429
+ if (!PI.forallInterferingAccesses (A, QueryingAA, I , CheckAccess)) {
388
430
LLVM_DEBUG (
389
431
dbgs ()
390
432
<< " Failed to verify all interfering accesses for underlying object: "
@@ -394,6 +436,9 @@ bool AA::getPotentialCopiesOfStoredValue(
394
436
PIs.push_back (&PI);
395
437
}
396
438
439
+ // Only if we were successful collection all potential copies we record
440
+ // dependences (on non-fix AAPointerInfo AAs). We also only then modify the
441
+ // given PotentialCopies container.
397
442
for (auto *PI : PIs) {
398
443
if (!PI->getState ().isAtFixpoint ())
399
444
UsedAssumedInformation = true ;
@@ -404,6 +449,23 @@ bool AA::getPotentialCopiesOfStoredValue(
404
449
return true ;
405
450
}
406
451
452
+ bool AA::getPotentiallyLoadedValues (Attributor &A, LoadInst &LI,
453
+ SmallSetVector<Value *, 4 > &PotentialValues,
454
+ const AbstractAttribute &QueryingAA,
455
+ bool &UsedAssumedInformation,
456
+ bool OnlyExact) {
457
+ return getPotentialCopiesOfMemoryValue</* IsLoad */ true >(
458
+ A, LI, PotentialValues, QueryingAA, UsedAssumedInformation, OnlyExact);
459
+ }
460
+
461
+ bool AA::getPotentialCopiesOfStoredValue (
462
+ Attributor &A, StoreInst &SI, SmallSetVector<Value *, 4 > &PotentialCopies,
463
+ const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
464
+ bool OnlyExact) {
465
+ return getPotentialCopiesOfMemoryValue</* IsLoad */ false >(
466
+ A, SI, PotentialCopies, QueryingAA, UsedAssumedInformation, OnlyExact);
467
+ }
468
+
407
469
static bool isAssumedReadOnlyOrReadNone (Attributor &A, const IRPosition &IRP,
408
470
const AbstractAttribute &QueryingAA,
409
471
bool RequireReadNone, bool &IsKnown) {
0 commit comments