diff options
Diffstat (limited to 'lib/CodeGen/AggressiveAntiDepBreaker.cpp')
| -rw-r--r-- | lib/CodeGen/AggressiveAntiDepBreaker.cpp | 241 | 
1 files changed, 134 insertions, 107 deletions
diff --git a/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/lib/CodeGen/AggressiveAntiDepBreaker.cpp index c37c793b56d0..8e3f8e770486 100644 --- a/lib/CodeGen/AggressiveAntiDepBreaker.cpp +++ b/lib/CodeGen/AggressiveAntiDepBreaker.cpp @@ -28,10 +28,15 @@  #include "llvm/Support/raw_ostream.h"  using namespace llvm; +// If DebugDiv > 0 then only break antidep with (ID % DebugDiv) == DebugMod  static cl::opt<int> -AntiDepTrials("agg-antidep-trials", -              cl::desc("Maximum number of anti-dependency breaking passes"), -              cl::init(1), cl::Hidden); +DebugDiv("agg-antidep-debugdiv", +                      cl::desc("Debug control for aggressive anti-dep breaker"), +                      cl::init(0), cl::Hidden); +static cl::opt<int> +DebugMod("agg-antidep-debugmod", +                      cl::desc("Debug control for aggressive anti-dep breaker"), +                      cl::init(0), cl::Hidden);  AggressiveAntiDepState::AggressiveAntiDepState(MachineBasicBlock *BB) :    GroupNodes(TargetRegisterInfo::FirstVirtualRegister, 0) { @@ -108,7 +113,7 @@ AggressiveAntiDepBreaker(MachineFunction& MFi,    MRI(MF.getRegInfo()),    TRI(MF.getTarget().getRegisterInfo()),    AllocatableSet(TRI->getAllocatableSet(MF)), -  State(NULL), SavedState(NULL) { +  State(NULL) {    /* Collect a bitset of all registers that are only broken if they       are on the critical path. */    for (unsigned i = 0, e = CriticalPathRCs.size(); i < e; ++i) { @@ -128,13 +133,6 @@ AggressiveAntiDepBreaker(MachineFunction& MFi,  AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() {    delete State; -  delete SavedState; -} - -unsigned AggressiveAntiDepBreaker::GetMaxTrials() { -  if (AntiDepTrials <= 0) -    return 1; -  return AntiDepTrials;  }  void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { @@ -206,8 +204,6 @@ void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) {  void AggressiveAntiDepBreaker::FinishBlock() {    delete State;    State = NULL; -  delete SavedState; -  SavedState = NULL;  }  void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, @@ -241,10 +237,6 @@ void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,      }    }    DEBUG(errs() << '\n'); - -  // We're starting a new schedule region so forget any saved state. -  delete SavedState; -  SavedState = NULL;  }  bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr *MI, @@ -283,27 +275,20 @@ void AggressiveAntiDepBreaker::GetPassthruRegs(MachineInstr *MI,    }  } -/// AntiDepEdges - Return in Edges the anti- and output- -/// dependencies on Regs in SU that we want to consider for breaking. -static void AntiDepEdges(SUnit *SU,  -                         const AntiDepBreaker::AntiDepRegVector& Regs, -                         std::vector<SDep*>& Edges) { -  AntiDepBreaker::AntiDepRegSet RegSet; -  for (unsigned i = 0, e = Regs.size(); i < e; ++i) -    RegSet.insert(Regs[i]); - +/// AntiDepEdges - Return in Edges the anti- and output- dependencies +/// in SU that we want to consider for breaking. +static void AntiDepEdges(SUnit *SU, std::vector<SDep*>& Edges) { +  SmallSet<unsigned, 4> RegSet;    for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end();         P != PE; ++P) {      if ((P->getKind() == SDep::Anti) || (P->getKind() == SDep::Output)) {        unsigned Reg = P->getReg(); -      if (RegSet.count(Reg) != 0) { +      if (RegSet.count(Reg) == 0) {          Edges.push_back(&*P); -        RegSet.erase(Reg); +        RegSet.insert(Reg);        }      }    } - -  assert(RegSet.empty() && "Expected all antidep registers to be found");  }  /// CriticalPathStep - Return the next SUnit after SU on the bottom-up @@ -332,7 +317,8 @@ static SUnit *CriticalPathStep(SUnit *SU) {  }  void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx, -                                             const char *tag) { +                                             const char *tag, const char *header, +                                             const char *footer) {    unsigned *KillIndices = State->GetKillIndices();    unsigned *DefIndices = State->GetDefIndices();    std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&  @@ -343,6 +329,8 @@ void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx,      DefIndices[Reg] = ~0u;      RegRefs.erase(Reg);      State->LeaveGroup(Reg); +    DEBUG(if (header != NULL) { +        errs() << header << TRI->getName(Reg); header = NULL; });      DEBUG(errs() << "->g" << State->GetGroup(Reg) << tag);    }    // Repeat for subregisters. @@ -354,10 +342,14 @@ void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx,        DefIndices[SubregReg] = ~0u;        RegRefs.erase(SubregReg);        State->LeaveGroup(SubregReg); +      DEBUG(if (header != NULL) { +          errs() << header << TRI->getName(Reg); header = NULL; });        DEBUG(errs() << " " << TRI->getName(SubregReg) << "->g" <<              State->GetGroup(SubregReg) << tag);      }    } + +  DEBUG(if ((header == NULL) && (footer != NULL)) errs() << footer);  }  void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Count, @@ -377,9 +369,7 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou      unsigned Reg = MO.getReg();      if (Reg == 0) continue; -    DEBUG(errs() << "\tDead Def: " << TRI->getName(Reg)); -    HandleLastUse(Reg, Count + 1, ""); -    DEBUG(errs() << '\n'); +    HandleLastUse(Reg, Count + 1, "", "\tDead Def: ", "\n");    }    DEBUG(errs() << "\tDef Groups:"); @@ -427,15 +417,17 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou      if (!MO.isReg() || !MO.isDef()) continue;      unsigned Reg = MO.getReg();      if (Reg == 0) continue; -    // Ignore passthru registers for liveness... -    if (PassthruRegs.count(Reg) != 0) continue; +    // Ignore KILLs and passthru registers for liveness... +    if ((MI->getOpcode() == TargetInstrInfo::KILL) || +        (PassthruRegs.count(Reg) != 0)) +      continue; -    // Update def for Reg and subregs. +    // Update def for Reg and aliases.      DefIndices[Reg] = Count; -    for (const unsigned *Subreg = TRI->getSubRegisters(Reg); -         *Subreg; ++Subreg) { -      unsigned SubregReg = *Subreg; -      DefIndices[SubregReg] = Count; +    for (const unsigned *Alias = TRI->getAliasSet(Reg); +         *Alias; ++Alias) { +      unsigned AliasReg = *Alias; +      DefIndices[AliasReg] = Count;      }    }  } @@ -589,72 +581,108 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(        return false;    } -  // FIXME: for now just handle single register in group case... -  if (Regs.size() > 1) { -    DEBUG(errs() << "\tMultiple rename registers in group\n"); -    return false; +#ifndef NDEBUG +  // If DebugDiv > 0 then only rename (renamecnt % DebugDiv) == DebugMod +  if (DebugDiv > 0) { +    static int renamecnt = 0; +    if (renamecnt++ % DebugDiv != DebugMod) +      return false; +     +    errs() << "*** Performing rename " << TRI->getName(SuperReg) << +      " for debug ***\n";    } +#endif    // Check each possible rename register for SuperReg in round-robin    // order. If that register is available, and the corresponding    // registers are available for the other group subregisters, then we    // can use those registers to rename. -  BitVector SuperBV = RenameRegisterMap[SuperReg];    const TargetRegisterClass *SuperRC =       TRI->getPhysicalRegisterRegClass(SuperReg, MVT::Other);    const TargetRegisterClass::iterator RB = SuperRC->allocation_order_begin(MF);    const TargetRegisterClass::iterator RE = SuperRC->allocation_order_end(MF);    if (RB == RE) { -    DEBUG(errs() << "\tEmpty Regclass!!\n"); +    DEBUG(errs() << "\tEmpty Super Regclass!!\n");      return false;    } +  DEBUG(errs() << "\tFind Registers:"); +    if (RenameOrder.count(SuperRC) == 0)      RenameOrder.insert(RenameOrderType::value_type(SuperRC, RE)); -  DEBUG(errs() << "\tFind Register:"); -    const TargetRegisterClass::iterator OrigR = RenameOrder[SuperRC];    const TargetRegisterClass::iterator EndR = ((OrigR == RE) ? RB : OrigR);    TargetRegisterClass::iterator R = OrigR;    do {      if (R == RB) R = RE;      --R; -    const unsigned Reg = *R; +    const unsigned NewSuperReg = *R;      // Don't replace a register with itself. -    if (Reg == SuperReg) continue; -     -    DEBUG(errs() << " " << TRI->getName(Reg)); +    if (NewSuperReg == SuperReg) continue; -    // If Reg is dead and Reg's most recent def is not before -    // SuperRegs's kill, it's safe to replace SuperReg with Reg. We -    // must also check all subregisters of Reg. -    if (State->IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) { -      DEBUG(errs() << "(live)"); -      continue; -    } else { -      bool found = false; -      for (const unsigned *Subreg = TRI->getSubRegisters(Reg); -           *Subreg; ++Subreg) { -        unsigned SubregReg = *Subreg; -        if (State->IsLive(SubregReg) || (KillIndices[SuperReg] > DefIndices[SubregReg])) { -          DEBUG(errs() << "(subreg " << TRI->getName(SubregReg) << " live)"); -          found = true; -          break; +    DEBUG(errs() << " [" << TRI->getName(NewSuperReg) << ':'); +    RenameMap.clear(); + +    // For each referenced group register (which must be a SuperReg or +    // a subregister of SuperReg), find the corresponding subregister +    // of NewSuperReg and make sure it is free to be renamed. +    for (unsigned i = 0, e = Regs.size(); i != e; ++i) { +      unsigned Reg = Regs[i]; +      unsigned NewReg = 0; +      if (Reg == SuperReg) { +        NewReg = NewSuperReg; +      } else { +        unsigned NewSubRegIdx = TRI->getSubRegIndex(SuperReg, Reg); +        if (NewSubRegIdx != 0) +          NewReg = TRI->getSubReg(NewSuperReg, NewSubRegIdx); +      } + +      DEBUG(errs() << " " << TRI->getName(NewReg)); +       +      // Check if Reg can be renamed to NewReg. +      BitVector BV = RenameRegisterMap[Reg]; +      if (!BV.test(NewReg)) { +        DEBUG(errs() << "(no rename)"); +        goto next_super_reg; +      } + +      // If NewReg is dead and NewReg's most recent def is not before +      // Regs's kill, it's safe to replace Reg with NewReg. We +      // must also check all aliases of NewReg, because we can't define a +      // register when any sub or super is already live. +      if (State->IsLive(NewReg) || (KillIndices[Reg] > DefIndices[NewReg])) { +        DEBUG(errs() << "(live)"); +        goto next_super_reg; +      } else { +        bool found = false; +        for (const unsigned *Alias = TRI->getAliasSet(NewReg); +             *Alias; ++Alias) { +          unsigned AliasReg = *Alias; +          if (State->IsLive(AliasReg) || (KillIndices[Reg] > DefIndices[AliasReg])) { +            DEBUG(errs() << "(alias " << TRI->getName(AliasReg) << " live)"); +            found = true; +            break; +          }          } +        if (found) +          goto next_super_reg;        } -      if (found) -        continue; +       +      // Record that 'Reg' can be renamed to 'NewReg'. +      RenameMap.insert(std::pair<unsigned, unsigned>(Reg, NewReg));      } -    if (Reg != 0) {  -      DEBUG(errs() << '\n'); -      RenameOrder.erase(SuperRC); -      RenameOrder.insert(RenameOrderType::value_type(SuperRC, R)); -      RenameMap.insert(std::pair<unsigned, unsigned>(SuperReg, Reg)); -      return true; -    } +    // If we fall-out here, then every register in the group can be +    // renamed, as recorded in RenameMap. +    RenameOrder.erase(SuperRC); +    RenameOrder.insert(RenameOrderType::value_type(SuperRC, R)); +    DEBUG(errs() << "]\n"); +    return true; + +  next_super_reg: +    DEBUG(errs() << ']');    } while (R != EndR);    DEBUG(errs() << '\n'); @@ -668,7 +696,6 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(  ///  unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(                                std::vector<SUnit>& SUnits, -                              CandidateMap& Candidates,                                MachineBasicBlock::iterator& Begin,                                MachineBasicBlock::iterator& End,                                unsigned InsertPosIndex) { @@ -681,16 +708,6 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(    // so just duck out immediately if the block is empty.    if (SUnits.empty()) return 0; -  // Manage saved state to enable multiple passes... -  if (AntiDepTrials > 1) { -    if (SavedState == NULL) { -      SavedState = new AggressiveAntiDepState(*State); -    } else { -      delete State; -      State = new AggressiveAntiDepState(*SavedState); -    } -  } -      // For each regclass the next register to use for renaming.    RenameOrderType RenameOrder; @@ -719,21 +736,14 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(      CriticalPathMI = CriticalPathSU->getInstr();    } -  // Even if there are no anti-dependencies we still need to go -  // through the instructions to update Def, Kills, etc.  #ifndef NDEBUG  -  if (Candidates.empty()) { -    DEBUG(errs() << "\n===== No anti-dependency candidates\n"); -  } else { -    DEBUG(errs() << "\n===== Attempting to break " << Candidates.size() <<  -          " anti-dependencies\n"); -    DEBUG(errs() << "Available regs:"); -    for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { -      if (!State->IsLive(Reg)) -        DEBUG(errs() << " " << TRI->getName(Reg)); -    } -    DEBUG(errs() << '\n'); +  DEBUG(errs() << "\n===== Aggressive anti-dependency breaking\n"); +  DEBUG(errs() << "Available regs:"); +  for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { +    if (!State->IsLive(Reg)) +      DEBUG(errs() << " " << TRI->getName(Reg));    } +  DEBUG(errs() << '\n');  #endif    // Attempt to break anti-dependence edges. Walk the instructions @@ -754,14 +764,11 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(      // Process the defs in MI...      PrescanInstruction(MI, Count, PassthruRegs); -    // The the dependence edges that represent anti- and output- +    // The dependence edges that represent anti- and output-      // dependencies that are candidates for breaking.      std::vector<SDep*> Edges;      SUnit *PathSU = MISUnitMap[MI]; -    AntiDepBreaker::CandidateMap::iterator  -      citer = Candidates.find(PathSU); -    if (citer != Candidates.end()) -      AntiDepEdges(PathSU, citer->second, Edges); +    AntiDepEdges(PathSU, Edges);      // If MI is not on the critical path, then we don't rename      // registers in the CriticalPathSet. @@ -817,12 +824,32 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(            // anti-dependency since those edges would prevent such            // units from being scheduled past each other            // regardless. +          // +          // Also, if there are dependencies on other SUnits with the +          // same register as the anti-dependency, don't attempt to +          // break it. +          for (SUnit::pred_iterator P = PathSU->Preds.begin(), +                 PE = PathSU->Preds.end(); P != PE; ++P) { +            if (P->getSUnit() == NextSU ? +                (P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) : +                (P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) { +              AntiDepReg = 0; +              break; +            } +          }            for (SUnit::pred_iterator P = PathSU->Preds.begin(),                   PE = PathSU->Preds.end(); P != PE; ++P) { -            if ((P->getSUnit() == NextSU) && (P->getKind() != SDep::Anti)) { +            if ((P->getSUnit() == NextSU) && (P->getKind() != SDep::Anti) && +                (P->getKind() != SDep::Output)) {                DEBUG(errs() << " (real dependency)\n");                AntiDepReg = 0;                break; +            } else if ((P->getSUnit() != NextSU) &&  +                       (P->getKind() == SDep::Data) &&  +                       (P->getReg() == AntiDepReg)) { +              DEBUG(errs() << " (other dependency)\n"); +              AntiDepReg = 0; +              break;              }            }  | 
