llvm.org GIT mirror llvm / ebe9301
[DeadStoreElimination] Remove dead zero store to calloc initialized memory This change allows dead store elimination to remove zero and null stores into memory freshly allocated with calloc-like function. Differential Revision: http://reviews.llvm.org/D13021 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248374 91177308-0d34-0410-b5e6-96231b3b80d8 Igor Laevsky 4 years ago
2 changed file(s) with 125 addition(s) and 35 deletion(s). Raw diff Collapse all Expand all
7777 }
7878
7979 bool runOnBasicBlock(BasicBlock &BB);
80 bool MemoryIsNotModifiedBetween(LoadInst *LI, StoreInst *SI);
80 bool MemoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI);
8181 bool HandleFree(CallInst *F);
8282 bool handleEndBlock(BasicBlock &BB);
8383 void RemoveAccessedObjects(const MemoryLocation &LoadedLoc,
482482 //===----------------------------------------------------------------------===//
483483
484484 bool DSE::runOnBasicBlock(BasicBlock &BB) {
485 const DataLayout &DL = BB.getModule()->getDataLayout();
485486 bool MadeChange = false;
486487
487488 // Do a top-down walk on the BB.
501502 // If we're storing the same value back to a pointer that we just
502503 // loaded from, then the store can be removed.
503504 if (StoreInst *SI = dyn_cast(Inst)) {
505
506 auto RemoveDeadInstAndUpdateBBI = [&](Instruction *DeadInst) {
507 // DeleteDeadInstruction can delete the current instruction. Save BBI
508 // in case we need it.
509 WeakVH NextInst(BBI);
510
511 DeleteDeadInstruction(DeadInst, *MD, *TLI);
512
513 if (!NextInst) // Next instruction deleted.
514 BBI = BB.begin();
515 else if (BBI != BB.begin()) // Revisit this instruction if possible.
516 --BBI;
517 ++NumRedundantStores;
518 MadeChange = true;
519 };
520
504521 if (LoadInst *DepLoad = dyn_cast(SI->getValueOperand())) {
505522 if (SI->getPointerOperand() == DepLoad->getPointerOperand() &&
506523 isRemovable(SI) &&
509526 DEBUG(dbgs() << "DSE: Remove Store Of Load from same pointer:\n "
510527 << "LOAD: " << *DepLoad << "\n STORE: " << *SI << '\n');
511528
512 // DeleteDeadInstruction can delete the current instruction. Save BBI
513 // in case we need it.
514 WeakVH NextInst(BBI);
515
516 DeleteDeadInstruction(SI, *MD, *TLI);
517
518 if (!NextInst) // Next instruction deleted.
519 BBI = BB.begin();
520 else if (BBI != BB.begin()) // Revisit this instruction if possible.
521 --BBI;
522 ++NumRedundantStores;
523 MadeChange = true;
529 RemoveDeadInstAndUpdateBBI(SI);
530 continue;
531 }
532 }
533
534 // Remove null stores into the calloc'ed objects
535 Constant *StoredConstant = dyn_cast(SI->getValueOperand());
536
537 if (StoredConstant && StoredConstant->isNullValue() &&
538 isRemovable(SI)) {
539 Instruction *UnderlyingPointer = dyn_cast(
540 GetUnderlyingObject(SI->getPointerOperand(), DL));
541
542 if (UnderlyingPointer && isCallocLikeFn(UnderlyingPointer, TLI) &&
543 MemoryIsNotModifiedBetween(UnderlyingPointer, SI)) {
544 DEBUG(dbgs()
545 << "DSE: Remove null store to the calloc'ed object:\n DEAD: "
546 << *Inst << "\n OBJECT: " << *UnderlyingPointer << '\n');
547
548 RemoveDeadInstAndUpdateBBI(SI);
524549 continue;
525550 }
526551 }
560585 if (isRemovable(DepWrite) &&
561586 !isPossibleSelfRead(Inst, Loc, DepWrite, *TLI, *AA)) {
562587 int64_t InstWriteOffset, DepWriteOffset;
563 const DataLayout &DL = BB.getModule()->getDataLayout();
564588 OverwriteResult OR =
565589 isOverwrite(Loc, DepLoc, DL, *TLI, DepWriteOffset, InstWriteOffset);
566590 if (OR == OverwriteComplete) {
632656 return MadeChange;
633657 }
634658
635 /// Returns true if the memory which is accessed by the store instruction is not
636 /// modified between the load and the store instruction.
637 /// Precondition: The store instruction must be dominated by the load
659 /// Returns true if the memory which is accessed by the second instruction is not
660 /// modified between the first and the second instruction.
661 /// Precondition: Second instruction must be dominated by the first
638662 /// instruction.
639 bool DSE::MemoryIsNotModifiedBetween(LoadInst *LI, StoreInst *SI) {
663 bool DSE::MemoryIsNotModifiedBetween(Instruction *FirstI,
664 Instruction *SecondI) {
640665 SmallVector WorkList;
641666 SmallPtrSet Visited;
642 BasicBlock::iterator LoadBBI(LI);
643 ++LoadBBI;
644 BasicBlock::iterator StoreBBI(SI);
645 BasicBlock *LoadBB = LI->getParent();
646 BasicBlock *StoreBB = SI->getParent();
647 MemoryLocation StoreLoc = MemoryLocation::get(SI);
667 BasicBlock::iterator FirstBBI(FirstI);
668 ++FirstBBI;
669 BasicBlock::iterator SecondBBI(SecondI);
670 BasicBlock *FirstBB = FirstI->getParent();
671 BasicBlock *SecondBB = SecondI->getParent();
672 MemoryLocation MemLoc = MemoryLocation::get(SecondI);
648673
649674 // Start checking the store-block.
650 WorkList.push_back(StoreBB);
675 WorkList.push_back(SecondBB);
651676 bool isFirstBlock = true;
652677
653678 // Check all blocks going backward until we reach the load-block.
654679 while (!WorkList.empty()) {
655680 BasicBlock *B = WorkList.pop_back_val();
656681
657 // Ignore instructions before LI if this is the LoadBB.
658 BasicBlock::iterator BI = (B == LoadBB ? LoadBBI : B->begin());
682 // Ignore instructions before LI if this is the FirstBB.
683 BasicBlock::iterator BI = (B == FirstBB ? FirstBBI : B->begin());
659684
660685 BasicBlock::iterator EI;
661686 if (isFirstBlock) {
662 // Ignore instructions after SI if this is the first visit of StoreBB.
663 assert(B == StoreBB && "first block is not the store block");
664 EI = StoreBBI;
687 // Ignore instructions after SI if this is the first visit of SecondBB.
688 assert(B == SecondBB && "first block is not the store block");
689 EI = SecondBBI;
665690 isFirstBlock = false;
666691 } else {
667 // It's not StoreBB or (in case of a loop) the second visit of StoreBB.
692 // It's not SecondBB or (in case of a loop) the second visit of SecondBB.
668693 // In this case we also have to look at instructions after SI.
669694 EI = B->end();
670695 }
671696 for (; BI != EI; ++BI) {
672697 Instruction *I = BI;
673 if (I->mayWriteToMemory() && I != SI) {
674 auto Res = AA->getModRefInfo(I, StoreLoc);
698 if (I->mayWriteToMemory() && I != SecondI) {
699 auto Res = AA->getModRefInfo(I, MemLoc);
675700 if (Res != MRI_NoModRef)
676701 return false;
677702 }
678703 }
679 if (B != LoadBB) {
680 assert(B != &LoadBB->getParent()->getEntryBlock() &&
704 if (B != FirstBB) {
705 assert(B != &FirstBB->getParent()->getEntryBlock() &&
681706 "Should not hit the entry block because SI must be dominated by LI");
682707 for (auto PredI = pred_begin(B), PE = pred_end(B); PredI != PE; ++PredI) {
683708 if (!Visited.insert(*PredI).second)
0 ; RUN: opt < %s -basicaa -dse -S | FileCheck %s
1
2 declare noalias i8* @calloc(i64, i64)
3
4 define i32* @test1() {
5 ; CHECK-LABEL: test1
6 %1 = tail call noalias i8* @calloc(i64 1, i64 4)
7 %2 = bitcast i8* %1 to i32*
8 ; This store is dead and should be removed
9 store i32 0, i32* %2, align 4
10 ; CHECK-NOT: store i32 0, i32* %2, align 4
11 ret i32* %2
12 }
13
14 define i32* @test2() {
15 ; CHECK-LABEL: test2
16 %1 = tail call noalias i8* @calloc(i64 1, i64 4)
17 %2 = bitcast i8* %1 to i32*
18 %3 = getelementptr i32, i32* %2, i32 5
19 store i32 0, i32* %3, align 4
20 ; CHECK-NOT: store i32 0, i32* %2, align 4
21 ret i32* %2
22 }
23
24 define i32* @test3(i32 *%arg) {
25 ; CHECK-LABEL: test3
26 store i32 0, i32* %arg, align 4
27 ; CHECK: store i32 0, i32* %arg, align 4
28 ret i32* %arg
29 }
30
31 declare void @clobber_memory(i8*)
32 define i8* @test4() {
33 ; CHECK-LABEL: test4
34 %1 = tail call noalias i8* @calloc(i64 1, i64 4)
35 call void @clobber_memory(i8* %1)
36 store i8 0, i8* %1, align 4
37 ; CHECK: store i8 0, i8* %1, align 4
38 ret i8* %1
39 }
40
41 define i32* @test5() {
42 ; CHECK-LABEL: test5
43 %1 = tail call noalias i8* @calloc(i64 1, i64 4)
44 %2 = bitcast i8* %1 to i32*
45 store volatile i32 0, i32* %2, align 4
46 ; CHECK: store volatile i32 0, i32* %2, align 4
47 ret i32* %2
48 }
49
50 define i8* @test6() {
51 ; CHECK-LABEL: test6
52 %1 = tail call noalias i8* @calloc(i64 1, i64 4)
53 store i8 5, i8* %1, align 4
54 ; CHECK: store i8 5, i8* %1, align 4
55 ret i8* %1
56 }
57
58 define i8* @test7(i8 %arg) {
59 ; CHECK-LABEL: test7
60 %1 = tail call noalias i8* @calloc(i64 1, i64 4)
61 store i8 %arg, i8* %1, align 4
62 ; CHECK: store i8 %arg, i8* %1, align 4
63 ret i8* %1
64 }