llvm.org GIT mirror llvm / 22af77d
[DeadStoreElimination] remove a redundant store even if the load is in a different block. DeadStoreElimination does eliminate a store if it stores a value which was loaded from the same memory location. So far this worked only if the store is in the same block as the load. Now we can also handle stores which are in a different block than the load. Example: define i32 @test(i1, i32*) { entry: %l2 = load i32, i32* %1, align 4 br i1 %0, label %bb1, label %bb2 bb1: br label %bb3 bb2: ; This store is redundant store i32 %l2, i32* %1, align 4 br label %bb3 bb3: ret i32 0 } Differential Revision: http://reviews.llvm.org/D11854 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244901 91177308-0d34-0410-b5e6-96231b3b80d8 Erik Eckstein 4 years ago
2 changed file(s) with 234 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
3939
4040 #define DEBUG_TYPE "dse"
4141
42 STATISTIC(NumRedundantStores, "Number of redundant stores deleted");
4243 STATISTIC(NumFastStores, "Number of stores deleted");
4344 STATISTIC(NumFastOther , "Number of other instrs removed");
4445
7576 }
7677
7778 bool runOnBasicBlock(BasicBlock &BB);
79 bool MemoryIsNotModifiedBetween(LoadInst *LI, StoreInst *SI);
7880 bool HandleFree(CallInst *F);
7981 bool handleEndBlock(BasicBlock &BB);
8082 void RemoveAccessedObjects(const MemoryLocation &LoadedLoc,
494496 if (!hasMemoryWrite(Inst, *TLI))
495497 continue;
496498
499 // If we're storing the same value back to a pointer that we just
500 // loaded from, then the store can be removed.
501 if (StoreInst *SI = dyn_cast(Inst)) {
502 if (LoadInst *DepLoad = dyn_cast(SI->getValueOperand())) {
503 if (SI->getPointerOperand() == DepLoad->getPointerOperand() &&
504 isRemovable(SI) &&
505 MemoryIsNotModifiedBetween(DepLoad, SI)) {
506
507 DEBUG(dbgs() << "DSE: Remove Store Of Load from same pointer:\n "
508 << "LOAD: " << *DepLoad << "\n STORE: " << *SI << '\n');
509
510 // DeleteDeadInstruction can delete the current instruction. Save BBI
511 // in case we need it.
512 WeakVH NextInst(BBI);
513
514 DeleteDeadInstruction(SI, *MD, *TLI);
515
516 if (!NextInst) // Next instruction deleted.
517 BBI = BB.begin();
518 else if (BBI != BB.begin()) // Revisit this instruction if possible.
519 --BBI;
520 ++NumRedundantStores;
521 MadeChange = true;
522 continue;
523 }
524 }
525 }
526
497527 MemDepResult InstDep = MD->getDependency(Inst);
498528
499529 // Ignore any store where we can't find a local dependence.
500530 // FIXME: cross-block DSE would be fun. :)
501531 if (!InstDep.isDef() && !InstDep.isClobber())
502532 continue;
503
504 // If we're storing the same value back to a pointer that we just
505 // loaded from, then the store can be removed.
506 if (StoreInst *SI = dyn_cast(Inst)) {
507 if (LoadInst *DepLoad = dyn_cast(InstDep.getInst())) {
508 if (SI->getPointerOperand() == DepLoad->getPointerOperand() &&
509 SI->getOperand(0) == DepLoad && isRemovable(SI)) {
510 DEBUG(dbgs() << "DSE: Remove Store Of Load from same pointer:\n "
511 << "LOAD: " << *DepLoad << "\n STORE: " << *SI << '\n');
512
513 // DeleteDeadInstruction can delete the current instruction. Save BBI
514 // in case we need it.
515 WeakVH NextInst(BBI);
516
517 DeleteDeadInstruction(SI, *MD, *TLI);
518
519 if (!NextInst) // Next instruction deleted.
520 BBI = BB.begin();
521 else if (BBI != BB.begin()) // Revisit this instruction if possible.
522 --BBI;
523 ++NumFastStores;
524 MadeChange = true;
525 continue;
526 }
527 }
528 }
529533
530534 // Figure out what location is being stored to.
531535 MemoryLocation Loc = getLocForWrite(Inst, *AA);
626630 return MadeChange;
627631 }
628632
633 /// Returns true if the memory which is accessed by the store instruction is not
634 /// modified between the load and the store instruction.
635 /// Precondition: The store instruction must be dominated by the load
636 /// instruction.
637 bool DSE::MemoryIsNotModifiedBetween(LoadInst *LI, StoreInst *SI) {
638 SmallVector WorkList;
639 SmallPtrSet Visited;
640 BasicBlock::iterator LoadBBI(LI);
641 ++LoadBBI;
642 BasicBlock::iterator StoreBBI(SI);
643 BasicBlock *LoadBB = LI->getParent();
644 BasicBlock *StoreBB = SI->getParent();
645 MemoryLocation StoreLoc = MemoryLocation::get(SI);
646
647 // Start checking the store-block.
648 WorkList.push_back(StoreBB);
649 bool isFirstBlock = true;
650
651 // Check all blocks going backward until we reach the load-block.
652 while (!WorkList.empty()) {
653 BasicBlock *B = WorkList.pop_back_val();
654
655 // Ignore instructions before LI if this is the LoadBB.
656 BasicBlock::iterator BI = (B == LoadBB ? LoadBBI : B->begin());
657
658 BasicBlock::iterator EI;
659 if (isFirstBlock) {
660 // Ignore instructions after SI if this is the first visit of StoreBB.
661 assert(B == StoreBB && "first block is not the store block");
662 EI = StoreBBI;
663 isFirstBlock = false;
664 } else {
665 // It's not StoreBB or (in case of a loop) the second visit of StoreBB.
666 // In this case we also have to look at instructions after SI.
667 EI = B->end();
668 }
669 for (; BI != EI; ++BI) {
670 Instruction *I = BI;
671 if (I->mayWriteToMemory() && I != SI) {
672 auto Res = AA->getModRefInfo(I, StoreLoc);
673 if (Res != MRI_NoModRef)
674 return false;
675 }
676 }
677 if (B != LoadBB) {
678 assert(B != &LoadBB->getParent()->getEntryBlock() &&
679 "Should not hit the entry block because SI must be dominated by LI");
680 for (auto PredI = pred_begin(B), PE = pred_end(B); PredI != PE; ++PredI) {
681 if (!Visited.insert(*PredI).second)
682 continue;
683 WorkList.push_back(*PredI);
684 }
685 }
686 }
687 return true;
688 }
689
629690 /// Find all blocks that will unconditionally lead to the block BB and append
630691 /// them to F.
631692 static void FindUnconditionalPreds(SmallVectorImpl &Blocks,
349349 store i8 %tmp, i8* %p.4, align 1
350350 ret i8* %q
351351 }
352
353 ; Remove redundant store if loaded value is in another block.
354 ; CHECK-LABEL: @test26(
355 ; CHECK-NOT: store
356 ; CHECK: ret
357 define i32 @test26(i1 %c, i32* %p) {
358 entry:
359 %v = load i32, i32* %p, align 4
360 br i1 %c, label %bb1, label %bb2
361 bb1:
362 br label %bb3
363 bb2:
364 store i32 %v, i32* %p, align 4
365 br label %bb3
366 bb3:
367 ret i32 0
368 }
369
370 ; Remove redundant store if loaded value is in another block.
371 ; CHECK-LABEL: @test27(
372 ; CHECK-NOT: store
373 ; CHECK: ret
374 define i32 @test27(i1 %c, i32* %p) {
375 entry:
376 %v = load i32, i32* %p, align 4
377 br i1 %c, label %bb1, label %bb2
378 bb1:
379 br label %bb3
380 bb2:
381 br label %bb3
382 bb3:
383 store i32 %v, i32* %p, align 4
384 ret i32 0
385 }
386
387 ; Don't remove redundant store because of may-aliased store.
388 ; CHECK-LABEL: @test28(
389 ; CHECK: bb3:
390 ; CHECK-NEXT: store i32 %v
391 define i32 @test28(i1 %c, i32* %p, i32* %p2, i32 %i) {
392 entry:
393 %v = load i32, i32* %p, align 4
394
395 ; Might overwrite value at %p
396 store i32 %i, i32* %p2, align 4
397 br i1 %c, label %bb1, label %bb2
398 bb1:
399 br label %bb3
400 bb2:
401 br label %bb3
402 bb3:
403 store i32 %v, i32* %p, align 4
404 ret i32 0
405 }
406
407 ; Don't remove redundant store because of may-aliased store.
408 ; CHECK-LABEL: @test29(
409 ; CHECK: bb3:
410 ; CHECK-NEXT: store i32 %v
411 define i32 @test29(i1 %c, i32* %p, i32* %p2, i32 %i) {
412 entry:
413 %v = load i32, i32* %p, align 4
414 br i1 %c, label %bb1, label %bb2
415 bb1:
416 br label %bb3
417 bb2:
418 ; Might overwrite value at %p
419 store i32 %i, i32* %p2, align 4
420 br label %bb3
421 bb3:
422 store i32 %v, i32* %p, align 4
423 ret i32 0
424 }
425
426 declare void @unknown_func()
427
428 ; Don't remove redundant store because of unknown call.
429 ; CHECK-LABEL: @test30(
430 ; CHECK: bb3:
431 ; CHECK-NEXT: store i32 %v
432 define i32 @test30(i1 %c, i32* %p, i32 %i) {
433 entry:
434 %v = load i32, i32* %p, align 4
435 br i1 %c, label %bb1, label %bb2
436 bb1:
437 br label %bb3
438 bb2:
439 ; Might overwrite value at %p
440 call void @unknown_func()
441 br label %bb3
442 bb3:
443 store i32 %v, i32* %p, align 4
444 ret i32 0
445 }
446
447 ; Remove redundant store if loaded value is in another block inside a loop.
448 ; CHECK-LABEL: @test31(
449 ; CHECK-NOT: store
450 ; CHECK: ret
451 define i32 @test31(i1 %c, i32* %p, i32 %i) {
452 entry:
453 %v = load i32, i32* %p, align 4
454 br label %bb1
455 bb1:
456 store i32 %v, i32* %p, align 4
457 br i1 undef, label %bb1, label %bb2
458 bb2:
459 ret i32 0
460 }
461
462 ; Don't remove redundant store in a loop with a may-alias store.
463 ; CHECK-LABEL: @test32(
464 ; CHECK: bb1:
465 ; CHECK-NEXT: store i32 %v
466 ; CHECK-NEXT: call void @unknown_func
467 define i32 @test32(i1 %c, i32* %p, i32 %i) {
468 entry:
469 %v = load i32, i32* %p, align 4
470 br label %bb1
471 bb1:
472 store i32 %v, i32* %p, align 4
473 ; Might read and overwrite value at %p
474 call void @unknown_func()
475 br i1 undef, label %bb1, label %bb2
476 bb2:
477 ret i32 0
478 }
479
480 ; Remove redundant store, which is in the lame loop as the load.
481 ; CHECK-LABEL: @test33(
482 ; CHECK-NOT: store
483 ; CHECK: ret
484 define i32 @test33(i1 %c, i32* %p, i32 %i) {
485 entry:
486 br label %bb1
487 bb1:
488 %v = load i32, i32* %p, align 4
489 br label %bb2
490 bb2:
491 store i32 %v, i32* %p, align 4
492 ; Might read and overwrite value at %p, but doesn't matter.
493 call void @unknown_func()
494 br i1 undef, label %bb1, label %bb3
495 bb3:
496 ret i32 0
497 }
498