diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/GVN.cpp | 61 |
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; } |

