diff options
Diffstat (limited to 'lib/CodeGen/BranchFolding.cpp')
| -rw-r--r-- | lib/CodeGen/BranchFolding.cpp | 74 | 
1 files changed, 68 insertions, 6 deletions
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index 2128da1b8aac..b8d9a1a29edc 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -24,6 +24,7 @@  #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"  #include "llvm/CodeGen/MachineFunctionPass.h"  #include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/CodeGen/MachineMemOperand.h"  #include "llvm/CodeGen/MachineModuleInfo.h"  #include "llvm/CodeGen/MachineRegisterInfo.h"  #include "llvm/CodeGen/Passes.h" @@ -601,8 +602,7 @@ static bool ProfitableToMerge(MachineBasicBlock *MBB1,    // instructions that would be deleted in the merge.    MachineFunction *MF = MBB1->getParent();    if (EffectiveTailLen >= 2 && -      MF->getFunction()->getAttributes(). -        hasAttribute(AttributeSet::FunctionIndex, Attribute::OptimizeForSize) && +      MF->getFunction()->hasFnAttribute(Attribute::OptimizeForSize) &&        (I1 == MBB1->begin() || I2 == MBB2->begin()))      return true; @@ -728,6 +728,62 @@ bool BranchFolder::CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB,    return true;  } +static bool hasIdenticalMMOs(const MachineInstr *MI1, const MachineInstr *MI2) { +  auto I1 = MI1->memoperands_begin(), E1 = MI1->memoperands_end(); +  auto I2 = MI2->memoperands_begin(), E2 = MI2->memoperands_end(); +  if ((E1 - I1) != (E2 - I2)) +    return false; +  for (; I1 != E1; ++I1, ++I2) { +    if (**I1 != **I2) +      return false; +  } +  return true; +} + +static void +removeMMOsFromMemoryOperations(MachineBasicBlock::iterator MBBIStartPos, +                               MachineBasicBlock &MBBCommon) { +  // Remove MMOs from memory operations in the common block +  // when they do not match the ones from the block being tail-merged. +  // This ensures later passes conservatively compute dependencies. +  MachineBasicBlock *MBB = MBBIStartPos->getParent(); +  // Note CommonTailLen does not necessarily matches the size of +  // the common BB nor all its instructions because of debug +  // instructions differences. +  unsigned CommonTailLen = 0; +  for (auto E = MBB->end(); MBBIStartPos != E; ++MBBIStartPos) +    ++CommonTailLen; + +  MachineBasicBlock::reverse_iterator MBBI = MBB->rbegin(); +  MachineBasicBlock::reverse_iterator MBBIE = MBB->rend(); +  MachineBasicBlock::reverse_iterator MBBICommon = MBBCommon.rbegin(); +  MachineBasicBlock::reverse_iterator MBBIECommon = MBBCommon.rend(); + +  while (CommonTailLen--) { +    assert(MBBI != MBBIE && "Reached BB end within common tail length!"); +    (void)MBBIE; + +    if (MBBI->isDebugValue()) { +      ++MBBI; +      continue; +    } + +    while ((MBBICommon != MBBIECommon) && MBBICommon->isDebugValue()) +      ++MBBICommon; + +    assert(MBBICommon != MBBIECommon && +           "Reached BB end within common tail length!"); +    assert(MBBICommon->isIdenticalTo(&*MBBI) && "Expected matching MIIs!"); + +    if (MBBICommon->mayLoad() || MBBICommon->mayStore()) +      if (!hasIdenticalMMOs(&*MBBI, &*MBBICommon)) +        MBBICommon->clearMemRefs(); + +    ++MBBI; +    ++MBBICommon; +  } +} +  // See if any of the blocks in MergePotentials (which all have a common single  // successor, or all have no successor) can be tail-merged.  If there is a  // successor, any blocks in MergePotentials that are not tail-merged and @@ -762,7 +818,7 @@ bool BranchFolder::TryTailMergeBlocks(MachineBasicBlock *SuccBB,    // Sort by hash value so that blocks with identical end sequences sort    // together. -  std::stable_sort(MergePotentials.begin(), MergePotentials.end()); +  array_pod_sort(MergePotentials.begin(), MergePotentials.end());    // Walk through equivalence sets looking for actual exact matches.    while (MergePotentials.size() > 1) { @@ -841,6 +897,8 @@ bool BranchFolder::TryTailMergeBlocks(MachineBasicBlock *SuccBB,          continue;        DEBUG(dbgs() << "BB#" << SameTails[i].getBlock()->getNumber()                     << (i == e-1 ? "" : ", ")); +      // Remove MMOs from memory operations as needed. +      removeMMOsFromMemoryOperations(SameTails[i].getTailStartPos(), *MBB);        // Hack the end off BB i, making it jump to BB commonTailIndex instead.        ReplaceTailWithBranchTo(SameTails[i].getTailStartPos(), MBB);        // BB i is no longer a predecessor of SuccBB; remove it from the worklist. @@ -1145,6 +1203,11 @@ ReoptimizeBlock:      if (FallThrough == MF.end()) {        // TODO: Simplify preds to not branch here if possible! +    } else if (FallThrough->isLandingPad()) { +      // Don't rewrite to a landing pad fallthough.  That could lead to the case +      // where a BB jumps to more than one landing pad. +      // TODO: Is it ever worth rewriting predecessors which don't already +      // jump to a landing pad, and so can safely jump to the fallthrough?      } else {        // Rewrite all predecessors of the old block to go to the fallthrough        // instead. @@ -1620,8 +1683,7 @@ MachineBasicBlock::iterator findHoistingInsertPosAndDeps(MachineBasicBlock *MBB,    // Also avoid moving code above predicated instruction since it's hard to    // reason about register liveness with predicated instruction.    bool DontMoveAcrossStore = true; -  if (!PI->isSafeToMove(TII, nullptr, DontMoveAcrossStore) || -      TII->isPredicated(PI)) +  if (!PI->isSafeToMove(nullptr, DontMoveAcrossStore) || TII->isPredicated(PI))      return MBB->end(); @@ -1759,7 +1821,7 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) {        break;      bool DontMoveAcrossStore = true; -    if (!TIB->isSafeToMove(TII, nullptr, DontMoveAcrossStore)) +    if (!TIB->isSafeToMove(nullptr, DontMoveAcrossStore))        break;      // Remove kills from LocalDefsSet, these registers had short live ranges.  | 
