diff options
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/DeadStoreElimination.cpp | 20 | ||||
-rw-r--r-- | lib/Transforms/Scalar/GVN.cpp | 21 |
2 files changed, 41 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index e3f43372ec..60b12fd867 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -154,6 +154,26 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { continue; } } + + // If this is a lifetime end marker, we can throw away the store. + if (IntrinsicInst* II = dyn_cast<IntrinsicInst>(InstDep.getInst())) { + if (II->getIntrinsicID() == Intrinsic::lifetime_end) { + // Delete the store and now-dead instructions that feed it. + // DeleteDeadInstruction can delete the current instruction. Save BBI + // in case we need it. + WeakVH NextInst(BBI); + + DeleteDeadInstruction(SI); + + if (NextInst == 0) // Next instruction deleted. + BBI = BB.begin(); + else if (BBI != BB.begin()) // Revisit this instruction if possible. + --BBI; + NumFastStores++; + MadeChange = true; + continue; + } + } } // If this block ends in a return, unwind, or unreachable, all allocas are diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 32d027aa36..dd8859b5e8 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1248,6 +1248,15 @@ bool GVN::processNonLocalLoad(LoadInst *LI, UndefValue::get(LI->getType()))); continue; } + + // Loading immediately after lifetime begin or end -> undef. + if (IntrinsicInst* II = dyn_cast<IntrinsicInst>(DepInst)) { + if (II->getIntrinsicID() == Intrinsic::lifetime_start || + II->getIntrinsicID() == Intrinsic::lifetime_end) { + ValuesPerBlock.push_back(AvailableValueInBlock::get(DepBB, + UndefValue::get(LI->getType()))); + } + } if (StoreInst *S = dyn_cast<StoreInst>(DepInst)) { // Reject loads and stores that are to the same address but are of @@ -1591,6 +1600,18 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) { NumGVNLoad++; return true; } + + // If this load occurs either right after a lifetime begin or a lifetime end, + // then the loaded value is undefined. + if (IntrinsicInst* II = dyn_cast<IntrinsicInst>(DepInst)) { + if (II->getIntrinsicID() == Intrinsic::lifetime_start || + II->getIntrinsicID() == Intrinsic::lifetime_end) { + L->replaceAllUsesWith(UndefValue::get(L->getType())); + toErase.push_back(L); + NumGVNLoad++; + return true; + } + } return false; } |