diff options
Diffstat (limited to 'lib/Transforms/Scalar/GVN.cpp')
| -rw-r--r-- | lib/Transforms/Scalar/GVN.cpp | 133 | 
1 files changed, 69 insertions, 64 deletions
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index e2c1eaf58e43f..1e0a22cb14b3e 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -38,7 +38,9 @@  #include "llvm/Analysis/OptimizationRemarkEmitter.h"  #include "llvm/Analysis/PHITransAddr.h"  #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Transforms/Utils/Local.h"  #include "llvm/Analysis/ValueTracking.h" +#include "llvm/Config/llvm-config.h"  #include "llvm/IR/Attributes.h"  #include "llvm/IR/BasicBlock.h"  #include "llvm/IR/CallSite.h" @@ -69,7 +71,6 @@  #include "llvm/Support/Debug.h"  #include "llvm/Support/raw_ostream.h"  #include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/Transforms/Utils/Local.h"  #include "llvm/Transforms/Utils/SSAUpdater.h"  #include "llvm/Transforms/Utils/VNCoercion.h"  #include <algorithm> @@ -765,6 +766,15 @@ static Value *ConstructSSAForLoadSet(LoadInst *LI,      if (SSAUpdate.HasValueForBlock(BB))        continue; +    // If the value is the load that we will be eliminating, and the block it's +    // available in is the block that the load is in, then don't add it as +    // SSAUpdater will resolve the value to the relevant phi which may let it +    // avoid phi construction entirely if there's actually only one value. +    if (BB == LI->getParent() && +        ((AV.AV.isSimpleValue() && AV.AV.getSimpleValue() == LI) || +         (AV.AV.isCoercedLoadValue() && AV.AV.getCoercedLoadValue() == LI))) +      continue; +      SSAUpdate.AddAvailableValue(BB, AV.MaterializeAdjustedValue(LI, gvn));    } @@ -783,9 +793,10 @@ Value *AvailableValue::MaterializeAdjustedValue(LoadInst *LI,      if (Res->getType() != LoadTy) {        Res = getStoreValueForLoad(Res, Offset, LoadTy, InsertPt, DL); -      DEBUG(dbgs() << "GVN COERCED NONLOCAL VAL:\nOffset: " << Offset << "  " -                   << *getSimpleValue() << '\n' -                   << *Res << '\n' << "\n\n\n"); +      LLVM_DEBUG(dbgs() << "GVN COERCED NONLOCAL VAL:\nOffset: " << Offset +                        << "  " << *getSimpleValue() << '\n' +                        << *Res << '\n' +                        << "\n\n\n");      }    } else if (isCoercedLoadValue()) {      LoadInst *Load = getCoercedLoadValue(); @@ -799,20 +810,21 @@ Value *AvailableValue::MaterializeAdjustedValue(LoadInst *LI,        // but then there all of the operations based on it would need to be        // rehashed.  Just leave the dead load around.        gvn.getMemDep().removeInstruction(Load); -      DEBUG(dbgs() << "GVN COERCED NONLOCAL LOAD:\nOffset: " << Offset << "  " -                   << *getCoercedLoadValue() << '\n' -                   << *Res << '\n' -                   << "\n\n\n"); +      LLVM_DEBUG(dbgs() << "GVN COERCED NONLOCAL LOAD:\nOffset: " << Offset +                        << "  " << *getCoercedLoadValue() << '\n' +                        << *Res << '\n' +                        << "\n\n\n");      }    } else if (isMemIntrinValue()) {      Res = getMemInstValueForLoad(getMemIntrinValue(), Offset, LoadTy,                                   InsertPt, DL); -    DEBUG(dbgs() << "GVN COERCED NONLOCAL MEM INTRIN:\nOffset: " << Offset -                 << "  " << *getMemIntrinValue() << '\n' -                 << *Res << '\n' << "\n\n\n"); +    LLVM_DEBUG(dbgs() << "GVN COERCED NONLOCAL MEM INTRIN:\nOffset: " << Offset +                      << "  " << *getMemIntrinValue() << '\n' +                      << *Res << '\n' +                      << "\n\n\n");    } else {      assert(isUndefValue() && "Should be UndefVal"); -    DEBUG(dbgs() << "GVN COERCED NONLOCAL Undef:\n";); +    LLVM_DEBUG(dbgs() << "GVN COERCED NONLOCAL Undef:\n";);      return UndefValue::get(LoadTy);    }    assert(Res && "failed to materialize?"); @@ -825,7 +837,7 @@ static bool isLifetimeStart(const Instruction *Inst) {    return false;  } -/// \brief Try to locate the three instruction involved in a missed +/// Try to locate the three instruction involved in a missed  /// load-elimination case that is due to an intervening store.  static void reportMayClobberedLoad(LoadInst *LI, MemDepResult DepInfo,                                     DominatorTree *DT, @@ -914,13 +926,11 @@ bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo,        }      }      // Nothing known about this clobber, have to be conservative -    DEBUG( -      // fast print dep, using operator<< on instruction is too slow. -      dbgs() << "GVN: load "; -      LI->printAsOperand(dbgs()); -      Instruction *I = DepInfo.getInst(); -      dbgs() << " is clobbered by " << *I << '\n'; -    ); +    LLVM_DEBUG( +        // fast print dep, using operator<< on instruction is too slow. +        dbgs() << "GVN: load "; LI->printAsOperand(dbgs()); +        Instruction *I = DepInfo.getInst(); +        dbgs() << " is clobbered by " << *I << '\n';);      if (ORE->allowExtraAnalysis(DEBUG_TYPE))        reportMayClobberedLoad(LI, DepInfo, DT, ORE); @@ -978,12 +988,10 @@ bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo,    }    // Unknown def - must be conservative -  DEBUG( -    // fast print dep, using operator<< on instruction is too slow. -    dbgs() << "GVN: load "; -    LI->printAsOperand(dbgs()); -    dbgs() << " has unknown def " << *DepInst << '\n'; -  ); +  LLVM_DEBUG( +      // fast print dep, using operator<< on instruction is too slow. +      dbgs() << "GVN: load "; LI->printAsOperand(dbgs()); +      dbgs() << " has unknown def " << *DepInst << '\n';);    return false;  } @@ -1065,7 +1073,7 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,    // It is illegal to move the array access to any point above the guard,    // because if the index is out of bounds we should deoptimize rather than    // access the array. -  // Check that there is no guard in this block above our intruction. +  // Check that there is no guard in this block above our instruction.    if (!IsSafeToSpeculativelyExecute) {      auto It = FirstImplicitControlFlowInsts.find(TmpBB);      if (It != FirstImplicitControlFlowInsts.end()) { @@ -1113,9 +1121,9 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,      // If any predecessor block is an EH pad that does not allow non-PHI      // instructions before the terminator, we can't PRE the load.      if (Pred->getTerminator()->isEHPad()) { -      DEBUG(dbgs() -            << "COULD NOT PRE LOAD BECAUSE OF AN EH PAD PREDECESSOR '" -            << Pred->getName() << "': " << *LI << '\n'); +      LLVM_DEBUG( +          dbgs() << "COULD NOT PRE LOAD BECAUSE OF AN EH PAD PREDECESSOR '" +                 << Pred->getName() << "': " << *LI << '\n');        return false;      } @@ -1125,15 +1133,16 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,      if (Pred->getTerminator()->getNumSuccessors() != 1) {        if (isa<IndirectBrInst>(Pred->getTerminator())) { -        DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '" -              << Pred->getName() << "': " << *LI << '\n'); +        LLVM_DEBUG( +            dbgs() << "COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '" +                   << Pred->getName() << "': " << *LI << '\n');          return false;        }        if (LoadBB->isEHPad()) { -        DEBUG(dbgs() -              << "COULD NOT PRE LOAD BECAUSE OF AN EH PAD CRITICAL EDGE '" -              << Pred->getName() << "': " << *LI << '\n'); +        LLVM_DEBUG( +            dbgs() << "COULD NOT PRE LOAD BECAUSE OF AN EH PAD CRITICAL EDGE '" +                   << Pred->getName() << "': " << *LI << '\n');          return false;        } @@ -1161,8 +1170,8 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,      BasicBlock *NewPred = splitCriticalEdges(OrigPred, LoadBB);      assert(!PredLoads.count(OrigPred) && "Split edges shouldn't be in map!");      PredLoads[NewPred] = nullptr; -    DEBUG(dbgs() << "Split critical edge " << OrigPred->getName() << "->" -                 << LoadBB->getName() << '\n'); +    LLVM_DEBUG(dbgs() << "Split critical edge " << OrigPred->getName() << "->" +                      << LoadBB->getName() << '\n');    }    // Check if the load can safely be moved to all the unavailable predecessors. @@ -1186,8 +1195,8 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,      // If we couldn't find or insert a computation of this phi translated value,      // we fail PRE.      if (!LoadPtr) { -      DEBUG(dbgs() << "COULDN'T INSERT PHI TRANSLATED VALUE OF: " -            << *LI->getPointerOperand() << "\n"); +      LLVM_DEBUG(dbgs() << "COULDN'T INSERT PHI TRANSLATED VALUE OF: " +                        << *LI->getPointerOperand() << "\n");        CanDoPRE = false;        break;      } @@ -1208,10 +1217,10 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,    // Okay, we can eliminate this load by inserting a reload in the predecessor    // and using PHI construction to get the value in the other predecessors, do    // it. -  DEBUG(dbgs() << "GVN REMOVING PRE LOAD: " << *LI << '\n'); -  DEBUG(if (!NewInsts.empty()) -          dbgs() << "INSERTED " << NewInsts.size() << " INSTS: " -                 << *NewInsts.back() << '\n'); +  LLVM_DEBUG(dbgs() << "GVN REMOVING PRE LOAD: " << *LI << '\n'); +  LLVM_DEBUG(if (!NewInsts.empty()) dbgs() +             << "INSERTED " << NewInsts.size() << " INSTS: " << *NewInsts.back() +             << '\n');    // Assign value numbers to the new instructions.    for (Instruction *I : NewInsts) { @@ -1262,7 +1271,7 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,      ValuesPerBlock.push_back(AvailableValueInBlock::get(UnavailablePred,                                                          NewLoad));      MD->invalidateCachedPointerInfo(LoadPtr); -    DEBUG(dbgs() << "GVN INSERTED " << *NewLoad << '\n'); +    LLVM_DEBUG(dbgs() << "GVN INSERTED " << *NewLoad << '\n');    }    // Perform PHI construction. @@ -1320,11 +1329,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI) {    // clobber in the current block.  Reject this early.    if (NumDeps == 1 &&        !Deps[0].getResult().isDef() && !Deps[0].getResult().isClobber()) { -    DEBUG( -      dbgs() << "GVN: non-local load "; -      LI->printAsOperand(dbgs()); -      dbgs() << " has unknown dependencies\n"; -    ); +    LLVM_DEBUG(dbgs() << "GVN: non-local load "; LI->printAsOperand(dbgs()); +               dbgs() << " has unknown dependencies\n";);      return false;    } @@ -1353,7 +1359,7 @@ bool GVN::processNonLocalLoad(LoadInst *LI) {    // load, then it is fully redundant and we can use PHI insertion to compute    // its value.  Insert PHIs and remove the fully redundant value now.    if (UnavailableBlocks.empty()) { -    DEBUG(dbgs() << "GVN REMOVING NONLOCAL LOAD: " << *LI << '\n'); +    LLVM_DEBUG(dbgs() << "GVN REMOVING NONLOCAL LOAD: " << *LI << '\n');      // Perform PHI construction.      Value *V = ConstructSSAForLoadSet(LI, ValuesPerBlock, *this); @@ -1506,12 +1512,10 @@ bool GVN::processLoad(LoadInst *L) {    // Only handle the local case below    if (!Dep.isDef() && !Dep.isClobber()) {      // This might be a NonFuncLocal or an Unknown -    DEBUG( -      // fast print dep, using operator<< on instruction is too slow. -      dbgs() << "GVN: load "; -      L->printAsOperand(dbgs()); -      dbgs() << " has unknown dependence\n"; -    ); +    LLVM_DEBUG( +        // fast print dep, using operator<< on instruction is too slow. +        dbgs() << "GVN: load "; L->printAsOperand(dbgs()); +        dbgs() << " has unknown dependence\n";);      return false;    } @@ -1695,8 +1699,8 @@ bool GVN::replaceOperandsWithConsts(Instruction *Instr) const {      if (it != ReplaceWithConstMap.end()) {        assert(!isa<Constant>(Operand) &&               "Replacing constants with constants is invalid"); -      DEBUG(dbgs() << "GVN replacing: " << *Operand << " with " << *it->second -                   << " in instruction " << *Instr << '\n'); +      LLVM_DEBUG(dbgs() << "GVN replacing: " << *Operand << " with " +                        << *it->second << " in instruction " << *Instr << '\n');        Instr->setOperand(OpNum, it->second);        Changed = true;      } @@ -2038,7 +2042,7 @@ bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,    unsigned Iteration = 0;    while (ShouldContinue) { -    DEBUG(dbgs() << "GVN iteration: " << Iteration << "\n"); +    LLVM_DEBUG(dbgs() << "GVN iteration: " << Iteration << "\n");      ShouldContinue = iterateOnFunction(F);      Changed |= ShouldContinue;      ++Iteration; @@ -2104,9 +2108,10 @@ bool GVN::processBlock(BasicBlock *BB) {      const Instruction *MaybeFirstICF = FirstImplicitControlFlowInsts.lookup(BB);      for (auto *I : InstrsToErase) {        assert(I->getParent() == BB && "Removing instruction from wrong block?"); -      DEBUG(dbgs() << "GVN removed: " << *I << '\n'); +      LLVM_DEBUG(dbgs() << "GVN removed: " << *I << '\n'); +      salvageDebugInfo(*I);        if (MD) MD->removeInstruction(I); -      DEBUG(verifyRemoved(I)); +      LLVM_DEBUG(verifyRemoved(I));        if (MaybeFirstICF == I) {          // We have erased the first ICF in block. The map needs to be updated.          InvalidateImplicitCF = true; @@ -2288,7 +2293,7 @@ bool GVN::performScalarPRE(Instruction *CurInst) {      PREInstr = CurInst->clone();      if (!performScalarPREInsertion(PREInstr, PREPred, CurrentBlock, ValNo)) {        // If we failed insertion, make sure we remove the instruction. -      DEBUG(verifyRemoved(PREInstr)); +      LLVM_DEBUG(verifyRemoved(PREInstr));        PREInstr->deleteValue();        return false;      } @@ -2326,10 +2331,10 @@ bool GVN::performScalarPRE(Instruction *CurInst) {    VN.erase(CurInst);    removeFromLeaderTable(ValNo, CurInst, CurrentBlock); -  DEBUG(dbgs() << "GVN PRE removed: " << *CurInst << '\n'); +  LLVM_DEBUG(dbgs() << "GVN PRE removed: " << *CurInst << '\n');    if (MD)      MD->removeInstruction(CurInst); -  DEBUG(verifyRemoved(CurInst)); +  LLVM_DEBUG(verifyRemoved(CurInst));    bool InvalidateImplicitCF =        FirstImplicitControlFlowInsts.lookup(CurInst->getParent()) == CurInst;    // FIXME: Intended to be markInstructionForDeletion(CurInst), but it causes  | 
