summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Scalar/GVN.cpp61
1 files changed, 21 insertions, 40 deletions
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 8d3c86f4f1e..e0b1c9d2535 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -705,7 +705,7 @@ namespace {
}
- // Helper functions of redundant load elimination
+ // Helper functions of redundant load elimination
bool processLoad(LoadInst *L);
bool processNonLocalLoad(LoadInst *L);
bool processAssumeIntrinsic(IntrinsicInst *II);
@@ -1981,6 +1981,7 @@ bool GVN::processLoad(LoadInst *L) {
}
Instruction *DepInst = Dep.getInst();
+ Value *AvailableValue = nullptr;
if (StoreInst *DepSI = dyn_cast<StoreInst>(DepInst)) {
Value *StoredVal = DepSI->getValueOperand();
@@ -1998,68 +1999,48 @@ bool GVN::processLoad(LoadInst *L) {
<< '\n' << *L << "\n\n\n");
}
- // Remove it!
- L->replaceAllUsesWith(StoredVal);
- if (StoredVal->getType()->getScalarType()->isPointerTy())
- MD->invalidateCachedPointerInfo(StoredVal);
- markInstructionForDeletion(L);
- ++NumGVNLoad;
- return true;
+ AvailableValue = StoredVal;
}
if (LoadInst *DepLI = dyn_cast<LoadInst>(DepInst)) {
- Value *AvailableVal = DepLI;
-
+ AvailableValue = DepLI;
// The loads are of a must-aliased pointer, but they may not actually have
// the same type. See if we know how to reuse the previously loaded value
// (depending on its type).
if (DepLI->getType() != L->getType()) {
IRBuilder<> Builder(L);
- AvailableVal =
+ AvailableValue =
CoerceAvailableValueToLoadType(DepLI, L->getType(), Builder, DL);
- if (!AvailableVal)
+ if (!AvailableValue)
return false;
- DEBUG(dbgs() << "GVN COERCED LOAD:\n" << *DepLI << "\n" << *AvailableVal
+ DEBUG(dbgs() << "GVN COERCED LOAD:\n" << *DepLI << "\n" << *AvailableValue
<< "\n" << *L << "\n\n\n");
}
-
- // Remove it!
- patchAndReplaceAllUsesWith(L, AvailableVal);
- if (DepLI->getType()->getScalarType()->isPointerTy())
- MD->invalidateCachedPointerInfo(DepLI);
- markInstructionForDeletion(L);
- ++NumGVNLoad;
- return true;
}
// If this load really doesn't depend on anything, then we must be loading an
// undef value. This can happen when loading for a fresh allocation with no
// intervening stores, for example.
- if (isa<AllocaInst>(DepInst) || isMallocLikeFn(DepInst, TLI)) {
- L->replaceAllUsesWith(UndefValue::get(L->getType()));
- markInstructionForDeletion(L);
- ++NumGVNLoad;
- return true;
- }
-
- // If this load occurs either right after a lifetime begin,
- // then the loaded value is undefined.
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(DepInst)) {
- if (II->getIntrinsicID() == Intrinsic::lifetime_start) {
- L->replaceAllUsesWith(UndefValue::get(L->getType()));
- markInstructionForDeletion(L);
- ++NumGVNLoad;
- return true;
- }
- }
+ if (isa<AllocaInst>(DepInst) || isMallocLikeFn(DepInst, TLI) ||
+ isLifetimeStart(DepInst))
+ AvailableValue = UndefValue::get(L->getType());
// If this load follows a calloc (which zero initializes memory),
// then the loaded value is zero
- if (isCallocLikeFn(DepInst, TLI)) {
- L->replaceAllUsesWith(Constant::getNullValue(L->getType()));
+ if (isCallocLikeFn(DepInst, TLI))
+ AvailableValue = Constant::getNullValue(L->getType());
+
+ if (AvailableValue) {
+ // Do the actual replacement
+ patchAndReplaceAllUsesWith(L, AvailableValue);
markInstructionForDeletion(L);
++NumGVNLoad;
+ // Tell MDA to rexamine the reused pointer since we might have more
+ // information after forwarding it.
+ if (MD && AvailableValue->getType()->getScalarType()->isPointerTy())
+ MD->invalidateCachedPointerInfo(AvailableValue);
+
return true;
}
OpenPOWER on IntegriCloud