diff --git a/llvm/include/llvm/CodeGen/AntiDepBreaker.h b/llvm/include/llvm/CodeGen/AntiDepBreaker.h index af45eb9b2f74..dac700076a8e 100644 --- a/llvm/include/llvm/CodeGen/AntiDepBreaker.h +++ b/llvm/include/llvm/CodeGen/AntiDepBreaker.h @@ -31,6 +31,10 @@ class AntiDepBreaker { public: virtual ~AntiDepBreaker(); + /// GetMaxTrials - Return the maximum number of anti-dependence + /// breaking attempts that will be made for a block. + virtual unsigned GetMaxTrials() =0; + /// Start - Initialize anti-dep breaking for a new basic block. virtual void StartBlock(MachineBasicBlock *BB) =0; diff --git a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp index 0fb15eae0daf..fef2c5008947 100644 --- a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp +++ b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp @@ -22,26 +22,19 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" - using namespace llvm; -AggressiveAntiDepBreaker:: -AggressiveAntiDepBreaker(MachineFunction& MFi) : - AntiDepBreaker(), MF(MFi), - MRI(MF.getRegInfo()), - TRI(MF.getTarget().getRegisterInfo()), - AllocatableSet(TRI->getAllocatableSet(MF)), - GroupNodes(TargetRegisterInfo::FirstVirtualRegister, 0) -{ -} +static cl::opt +AntiDepTrials("agg-antidep-trials", + cl::desc("Maximum number of anti-dependency breaking passes"), + cl::init(2), cl::Hidden); -AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() { -} - -void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { +AggressiveAntiDepState::AggressiveAntiDepState(MachineBasicBlock *BB) : + GroupNodes(TargetRegisterInfo::FirstVirtualRegister, 0) { // Initialize all registers to be in their own group. Initially we // assign the register to the same-indexed GroupNode. for (unsigned i = 0; i < TargetRegisterInfo::FirstVirtualRegister; ++i) @@ -50,102 +43,9 @@ void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { // Initialize the indices to indicate that no registers are live. std::fill(KillIndices, array_endof(KillIndices), ~0u); std::fill(DefIndices, array_endof(DefIndices), BB->size()); - - bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); - - // Determine the live-out physregs for this block. - if (IsReturnBlock) { - // In a return block, examine the function live-out regs. - for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), - E = MRI.liveout_end(); I != E; ++I) { - unsigned Reg = *I; - UnionGroups(Reg, 0); - KillIndices[Reg] = BB->size(); - DefIndices[Reg] = ~0u; - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - UnionGroups(AliasReg, 0); - KillIndices[AliasReg] = BB->size(); - DefIndices[AliasReg] = ~0u; - } - } - } else { - // In a non-return block, examine the live-in regs of all successors. - for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), - SE = BB->succ_end(); SI != SE; ++SI) - for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), - E = (*SI)->livein_end(); I != E; ++I) { - unsigned Reg = *I; - UnionGroups(Reg, 0); - KillIndices[Reg] = BB->size(); - DefIndices[Reg] = ~0u; - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - UnionGroups(AliasReg, 0); - KillIndices[AliasReg] = BB->size(); - DefIndices[AliasReg] = ~0u; - } - } - } - - // Mark live-out callee-saved registers. In a return block this is - // all callee-saved registers. In non-return this is any - // callee-saved register that is not saved in the prolog. - const MachineFrameInfo *MFI = MF.getFrameInfo(); - BitVector Pristine = MFI->getPristineRegs(BB); - for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { - unsigned Reg = *I; - if (!IsReturnBlock && !Pristine.test(Reg)) continue; - UnionGroups(Reg, 0); - KillIndices[Reg] = BB->size(); - DefIndices[Reg] = ~0u; - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - UnionGroups(AliasReg, 0); - KillIndices[AliasReg] = BB->size(); - DefIndices[AliasReg] = ~0u; - } - } } -void AggressiveAntiDepBreaker::FinishBlock() { - RegRefs.clear(); -} - -void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, - unsigned InsertPosIndex) { - assert(Count < InsertPosIndex && "Instruction index out of expected range!"); - - DEBUG(errs() << "Observe: "); - DEBUG(MI->dump()); - - for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { - // If Reg is current live, then mark that it can't be renamed as - // we don't know the extent of its live-range anymore (now that it - // has been scheduled). If it is not live but was defined in the - // previous schedule region, then set its def index to the most - // conservative location (i.e. the beginning of the previous - // schedule region). - if (IsLive(Reg)) { - DEBUG(if (GetGroup(Reg) != 0) - errs() << " " << TRI->getName(Reg) << "=g" << - GetGroup(Reg) << "->g0(region live-out)"); - UnionGroups(Reg, 0); - } else if ((DefIndices[Reg] < InsertPosIndex) && (DefIndices[Reg] >= Count)) { - DefIndices[Reg] = Count; - } - } - - std::set PassthruRegs; - GetPassthruRegs(MI, PassthruRegs); - PrescanInstruction(MI, Count, PassthruRegs); - ScanInstruction(MI, Count); -} - -unsigned AggressiveAntiDepBreaker::GetGroup(unsigned Reg) +unsigned AggressiveAntiDepState::GetGroup(unsigned Reg) { unsigned Node = GroupNodeIndices[Reg]; while (GroupNodes[Node] != Node) @@ -154,7 +54,7 @@ unsigned AggressiveAntiDepBreaker::GetGroup(unsigned Reg) return Node; } -void AggressiveAntiDepBreaker::GetGroupRegs(unsigned Group, std::vector &Regs) +void AggressiveAntiDepState::GetGroupRegs(unsigned Group, std::vector &Regs) { for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { if (GetGroup(Reg) == Group) @@ -162,7 +62,7 @@ void AggressiveAntiDepBreaker::GetGroupRegs(unsigned Group, std::vectorgetAllocatableSet(MF)), + State(NULL), SavedState(NULL) { +} + +AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() { + delete State; + delete SavedState; +} + +unsigned AggressiveAntiDepBreaker::GetMaxTrials() { + if (AntiDepTrials <= 0) + return 1; + return AntiDepTrials; +} + +void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { + assert(State == NULL); + State = new AggressiveAntiDepState(BB); + + bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); + + // Determine the live-out physregs for this block. + if (IsReturnBlock) { + // In a return block, examine the function live-out regs. + for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), + E = MRI.liveout_end(); I != E; ++I) { + unsigned Reg = *I; + State->UnionGroups(Reg, 0); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + State->UnionGroups(AliasReg, 0); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } + } else { + // In a non-return block, examine the live-in regs of all successors. + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), + SE = BB->succ_end(); SI != SE; ++SI) + for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), + E = (*SI)->livein_end(); I != E; ++I) { + unsigned Reg = *I; + State->UnionGroups(Reg, 0); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + State->UnionGroups(AliasReg, 0); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } + } + + // Mark live-out callee-saved registers. In a return block this is + // all callee-saved registers. In non-return this is any + // callee-saved register that is not saved in the prolog. + const MachineFrameInfo *MFI = MF.getFrameInfo(); + BitVector Pristine = MFI->getPristineRegs(BB); + for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { + unsigned Reg = *I; + if (!IsReturnBlock && !Pristine.test(Reg)) continue; + State->UnionGroups(Reg, 0); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + State->UnionGroups(AliasReg, 0); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } +} + +void AggressiveAntiDepBreaker::FinishBlock() { + delete State; + State = NULL; + delete SavedState; + SavedState = NULL; +} + +void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, + unsigned InsertPosIndex) { + assert(Count < InsertPosIndex && "Instruction index out of expected range!"); + + DEBUG(errs() << "Observe: "); + DEBUG(MI->dump()); + + unsigned *DefIndices = State->GetDefIndices(); + for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { + // If Reg is current live, then mark that it can't be renamed as + // we don't know the extent of its live-range anymore (now that it + // has been scheduled). If it is not live but was defined in the + // previous schedule region, then set its def index to the most + // conservative location (i.e. the beginning of the previous + // schedule region). + if (State->IsLive(Reg)) { + DEBUG(if (State->GetGroup(Reg) != 0) + errs() << " " << TRI->getName(Reg) << "=g" << + State->GetGroup(Reg) << "->g0(region live-out)"); + State->UnionGroups(Reg, 0); + } else if ((DefIndices[Reg] < InsertPosIndex) && (DefIndices[Reg] >= Count)) { + DefIndices[Reg] = Count; + } + } + + std::set PassthruRegs; + GetPassthruRegs(MI, PassthruRegs); + PrescanInstruction(MI, Count, PassthruRegs); + ScanInstruction(MI, Count); + + // We're starting a new schedule region so forget any saved state. + delete SavedState; + SavedState = NULL; +} + bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO) { @@ -249,6 +279,10 @@ static void AntiDepPathStep(SUnit *SU, std::vector& Edges) { void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Count, std::set& PassthruRegs) { + unsigned *DefIndices = State->GetDefIndices(); + std::multimap& + RegRefs = State->GetRegRefs(); + // Scan the register defs for this instruction and update // live-ranges, groups and RegRefs. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { @@ -275,23 +309,23 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou unsigned Reg = MO.getReg(); if (Reg == 0) continue; - DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << GetGroup(Reg)); + DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << State->GetGroup(Reg)); // If MI's defs have special allocation requirement, don't allow // any def registers to be changed. Also assume all registers // defined in a call must not be changed (ABI). if (MI->getDesc().isCall() || MI->getDesc().hasExtraDefRegAllocReq()) { - DEBUG(if (GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); - UnionGroups(Reg, 0); + DEBUG(if (State->GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); + State->UnionGroups(Reg, 0); } // Any aliased that are live at this point are completely or // partially defined here, so group those subregisters with Reg. for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { unsigned AliasReg = *Alias; - if (IsLive(AliasReg)) { - UnionGroups(Reg, AliasReg); - DEBUG(errs() << "->g" << GetGroup(Reg) << "(via " << + if (State->IsLive(AliasReg)) { + State->UnionGroups(Reg, AliasReg); + DEBUG(errs() << "->g" << State->GetGroup(Reg) << "(via " << TRI->getName(AliasReg) << ")"); } } @@ -300,7 +334,7 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou const TargetRegisterClass *RC = NULL; if (i < MI->getDesc().getNumOperands()) RC = MI->getDesc().OpInfo[i].getRegClass(TRI); - RegisterReference RR = { &MO, RC }; + AggressiveAntiDepState::RegisterReference RR = { &MO, RC }; RegRefs.insert(std::make_pair(Reg, RR)); } @@ -310,6 +344,10 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI, unsigned Count) { DEBUG(errs() << "\tUse Groups:"); + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); + std::multimap& + RegRefs = State->GetRegRefs(); // Scan the register uses for this instruction and update // live-ranges, groups and RegRefs. @@ -319,29 +357,30 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI, unsigned Reg = MO.getReg(); if (Reg == 0) continue; - DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << GetGroup(Reg)); + DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << + State->GetGroup(Reg)); // It wasn't previously live but now it is, this is a kill. Forget // the previous live-range information and start a new live-range // for the register. - if (!IsLive(Reg)) { + if (!State->IsLive(Reg)) { KillIndices[Reg] = Count; DefIndices[Reg] = ~0u; RegRefs.erase(Reg); - LeaveGroup(Reg); - DEBUG(errs() << "->g" << GetGroup(Reg) << "(last-use)"); + State->LeaveGroup(Reg); + DEBUG(errs() << "->g" << State->GetGroup(Reg) << "(last-use)"); } // Repeat, for subregisters. for (const unsigned *Subreg = TRI->getSubRegisters(Reg); *Subreg; ++Subreg) { unsigned SubregReg = *Subreg; - if (!IsLive(SubregReg)) { + if (!State->IsLive(SubregReg)) { KillIndices[SubregReg] = Count; DefIndices[SubregReg] = ~0u; RegRefs.erase(SubregReg); - LeaveGroup(SubregReg); + State->LeaveGroup(SubregReg); DEBUG(errs() << " " << TRI->getName(SubregReg) << "->g" << - GetGroup(SubregReg) << "(last-use)"); + State->GetGroup(SubregReg) << "(last-use)"); } } @@ -349,15 +388,15 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI, // any use registers to be changed. Also assume all registers // used in a call must not be changed (ABI). if (MI->getDesc().isCall() || MI->getDesc().hasExtraSrcRegAllocReq()) { - DEBUG(if (GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); - UnionGroups(Reg, 0); + DEBUG(if (State->GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); + State->UnionGroups(Reg, 0); } // Note register reference... const TargetRegisterClass *RC = NULL; if (i < MI->getDesc().getNumOperands()) RC = MI->getDesc().OpInfo[i].getRegClass(TRI); - RegisterReference RR = { &MO, RC }; + AggressiveAntiDepState::RegisterReference RR = { &MO, RC }; RegRefs.insert(std::make_pair(Reg, RR)); } @@ -377,14 +416,14 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI, if (FirstReg != 0) { DEBUG(errs() << "=" << TRI->getName(Reg)); - UnionGroups(FirstReg, Reg); + State->UnionGroups(FirstReg, Reg); } else { DEBUG(errs() << " " << TRI->getName(Reg)); FirstReg = Reg; } } - DEBUG(errs() << "->g" << GetGroup(FirstReg) << '\n'); + DEBUG(errs() << "->g" << State->GetGroup(FirstReg) << '\n'); } } @@ -395,10 +434,12 @@ BitVector AggressiveAntiDepBreaker::GetRenameRegisters(unsigned Reg) { // Check all references that need rewriting for Reg. For each, use // the corresponding register class to narrow the set of registers // that are appropriate for renaming. - std::pair::iterator, - std::multimap::iterator> - Range = RegRefs.equal_range(Reg); - for (std::multimap::iterator + std::pair::iterator, + std::multimap::iterator> + Range = State->GetRegRefs().equal_range(Reg); + for (std::multimap::iterator Q = Range.first, QE = Range.second; Q != QE; ++Q) { const TargetRegisterClass *RC = Q->second.RC; if (RC == NULL) continue; @@ -420,11 +461,16 @@ BitVector AggressiveAntiDepBreaker::GetRenameRegisters(unsigned Reg) { bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters( unsigned AntiDepGroupIndex, std::map &RenameMap) { + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); + std::multimap& + RegRefs = State->GetRegRefs(); + // Collect all registers in the same group as AntiDepReg. These all // need to be renamed together if we are to break the // anti-dependence. std::vector Regs; - GetGroupRegs(AntiDepGroupIndex, Regs); + State->GetGroupRegs(AntiDepGroupIndex, Regs); assert(Regs.size() > 0 && "Empty register group!"); if (Regs.size() == 0) return false; @@ -484,7 +530,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters( // 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 (IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) { + if (State->IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) { DEBUG(errs() << "(live)"); continue; } else { @@ -492,7 +538,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters( for (const unsigned *Subreg = TRI->getSubRegisters(Reg); *Subreg; ++Subreg) { unsigned SubregReg = *Subreg; - if (IsLive(SubregReg) || (KillIndices[SuperReg] > DefIndices[SubregReg])) { + if (State->IsLive(SubregReg) || (KillIndices[SuperReg] > DefIndices[SubregReg])) { DEBUG(errs() << "(subreg " << TRI->getName(SubregReg) << " live)"); found = true; break; @@ -518,13 +564,29 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters( /// BreakAntiDependencies - Identifiy anti-dependencies within the /// ScheduleDAG and break them by renaming registers. /// -unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(std::vector& SUnits, - MachineBasicBlock::iterator& Begin, - MachineBasicBlock::iterator& End, - unsigned InsertPosIndex) { +unsigned AggressiveAntiDepBreaker::BreakAntiDependencies( + std::vector& SUnits, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex) { + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); + std::multimap& + RegRefs = State->GetRegRefs(); + // The code below assumes that there is at least one instruction, // so just duck out immediately if the block is empty. if (SUnits.empty()) return false; + + // Manage saved state to enable multiple passes... + if (AntiDepTrials > 1) { + if (SavedState == NULL) { + SavedState = new AggressiveAntiDepState(*State); + } else { + delete State; + State = new AggressiveAntiDepState(*SavedState); + } + } // ...need a map from MI to SUnit. std::map MISUnitMap; @@ -539,7 +601,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(std::vector& SUn { DEBUG(errs() << "Available regs:"); for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { - if (!IsLive(Reg)) + if (!State->IsLive(Reg)) DEBUG(errs() << " " << TRI->getName(Reg)); } DEBUG(errs() << '\n'); @@ -623,7 +685,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(std::vector& SUn if (AntiDepReg == 0) continue; // Determine AntiDepReg's register group. - const unsigned GroupIndex = GetGroup(AntiDepReg); + const unsigned GroupIndex = State->GetGroup(AntiDepReg); if (GroupIndex == 0) { DEBUG(errs() << " (zero group)\n"); continue; @@ -649,10 +711,12 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(std::vector& SUn // Update the references to the old register CurrReg to // refer to the new register NewReg. - std::pair::iterator, - std::multimap::iterator> + std::pair::iterator, + std::multimap::iterator> Range = RegRefs.equal_range(CurrReg); - for (std::multimap::iterator + for (std::multimap::iterator Q = Range.first, QE = Range.second; Q != QE; ++Q) { Q->second.Operand->setReg(NewReg); } @@ -660,12 +724,12 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(std::vector& SUn // We just went back in time and modified history; the // liveness information for CurrReg is now inconsistent. Set // the state as if it were dead. - UnionGroups(NewReg, 0); + State->UnionGroups(NewReg, 0); RegRefs.erase(NewReg); DefIndices[NewReg] = DefIndices[CurrReg]; KillIndices[NewReg] = KillIndices[CurrReg]; - UnionGroups(CurrReg, 0); + State->UnionGroups(CurrReg, 0); RegRefs.erase(CurrReg); DefIndices[CurrReg] = KillIndices[CurrReg]; KillIndices[CurrReg] = ~0u; diff --git a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h index e6b7268e778d..f4a05290c018 100644 --- a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h +++ b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h @@ -28,11 +28,12 @@ #include "llvm/ADT/SmallSet.h" namespace llvm { - class AggressiveAntiDepBreaker : public AntiDepBreaker { - MachineFunction& MF; - MachineRegisterInfo &MRI; - const TargetRegisterInfo *TRI; - + /// Class AggressiveAntiDepState + /// Contains all the state necessary for anti-dep breaking. We place + /// into a separate class so be can conveniently save/restore it to + /// enable multi-pass anti-dep breaking. + class AggressiveAntiDepState { + public: /// RegisterReference - Information about a register reference /// within a liverange typedef struct { @@ -42,59 +43,43 @@ namespace llvm { const TargetRegisterClass *RC; } RegisterReference; - /// AllocatableSet - The set of allocatable registers. - /// We'll be ignoring anti-dependencies on non-allocatable registers, - /// because they may not be safe to break. - const BitVector AllocatableSet; - + private: /// GroupNodes - Implements a disjoint-union data structure to /// form register groups. A node is represented by an index into /// the vector. A node can "point to" itself to indicate that it /// is the parent of a group, or point to another node to indicate /// that it is a member of the same group as that node. std::vector GroupNodes; - + /// GroupNodeIndices - For each register, the index of the GroupNode /// currently representing the group that the register belongs to. /// Register 0 is always represented by the 0 group, a group /// composed of registers that are not eligible for anti-aliasing. unsigned GroupNodeIndices[TargetRegisterInfo::FirstVirtualRegister]; - - /// RegRegs - Map registers to all their references within a live range. + + /// RegRefs - Map registers to all their references within a live range. std::multimap RegRefs; - + /// KillIndices - The index of the most recent kill (proceding bottom-up), /// or ~0u if the register is not live. unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; - + /// DefIndices - The index of the most recent complete def (proceding bottom /// up), or ~0u if the register is live. unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; public: - AggressiveAntiDepBreaker(MachineFunction& MFi); - ~AggressiveAntiDepBreaker(); + AggressiveAntiDepState(MachineBasicBlock *BB); - /// Start - Initialize anti-dep breaking for a new basic block. - void StartBlock(MachineBasicBlock *BB); + /// GetKillIndices - Return the kill indices. + unsigned *GetKillIndices() { return KillIndices; } - /// BreakAntiDependencies - Identifiy anti-dependencies along the critical path - /// of the ScheduleDAG and break them by renaming registers. - /// - unsigned BreakAntiDependencies(std::vector& SUnits, - MachineBasicBlock::iterator& Begin, - MachineBasicBlock::iterator& End, - unsigned InsertPosIndex); + /// GetDefIndices - Return the define indices. + unsigned *GetDefIndices() { return DefIndices; } - /// Observe - Update liveness information to account for the current - /// instruction, which will not be scheduled. - /// - void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex); + /// GetRegRefs - Return the RegRefs map. + std::multimap& GetRegRefs() { return RegRefs; } - /// Finish - Finish anti-dep breaking for a basic block. - void FinishBlock(); - - private: // GetGroup - Get the group for a register. The returned value is // the index of the GroupNode representing the group. unsigned GetGroup(unsigned Reg); @@ -115,7 +100,57 @@ namespace llvm { /// IsLive - Return true if Reg is live bool IsLive(unsigned Reg); + }; + + + /// Class AggressiveAntiDepBreaker + class AggressiveAntiDepBreaker : public AntiDepBreaker { + MachineFunction& MF; + MachineRegisterInfo &MRI; + const TargetRegisterInfo *TRI; + + /// AllocatableSet - The set of allocatable registers. + /// We'll be ignoring anti-dependencies on non-allocatable registers, + /// because they may not be safe to break. + const BitVector AllocatableSet; + + /// State - The state used to identify and rename anti-dependence + /// registers. + AggressiveAntiDepState *State; + + /// SavedState - The state for the start of an anti-dep + /// region. Used to restore the state at the beginning of each + /// pass + AggressiveAntiDepState *SavedState; + + public: + AggressiveAntiDepBreaker(MachineFunction& MFi); + ~AggressiveAntiDepBreaker(); + /// GetMaxTrials - As anti-dependencies are broken, additional + /// dependencies may be exposed, so multiple passes are required. + unsigned GetMaxTrials(); + + /// Start - Initialize anti-dep breaking for a new basic block. + void StartBlock(MachineBasicBlock *BB); + + /// BreakAntiDependencies - Identifiy anti-dependencies along the critical path + /// of the ScheduleDAG and break them by renaming registers. + /// + unsigned BreakAntiDependencies(std::vector& SUnits, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex); + + /// Observe - Update liveness information to account for the current + /// instruction, which will not be scheduled. + /// + void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex); + + /// Finish - Finish anti-dep breaking for a basic block. + void FinishBlock(); + + private: /// IsImplicitDefUse - Return true if MO represents a register /// that is both implicitly used and defined in MI bool IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO); diff --git a/llvm/lib/CodeGen/CriticalAntiDepBreaker.h b/llvm/lib/CodeGen/CriticalAntiDepBreaker.h index 830b29a060df..700851c297c2 100644 --- a/llvm/lib/CodeGen/CriticalAntiDepBreaker.h +++ b/llvm/lib/CodeGen/CriticalAntiDepBreaker.h @@ -64,6 +64,10 @@ namespace llvm { CriticalAntiDepBreaker(MachineFunction& MFi); ~CriticalAntiDepBreaker(); + /// GetMaxTrials - Critical path anti-dependence breaking requires + /// only a single pass + unsigned GetMaxTrials() { return 1; } + /// Start - Initialize anti-dep breaking for a new basic block. void StartBlock(MachineBasicBlock *BB); diff --git a/llvm/lib/CodeGen/PostRASchedulerList.cpp b/llvm/lib/CodeGen/PostRASchedulerList.cpp index 8fe20876bccd..c3cae8a4beef 100644 --- a/llvm/lib/CodeGen/PostRASchedulerList.cpp +++ b/llvm/lib/CodeGen/PostRASchedulerList.cpp @@ -40,6 +40,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetSubtarget.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -315,16 +316,20 @@ void SchedulePostRATDList::StartBlock(MachineBasicBlock *BB) { /// Schedule - Schedule the instruction range using list scheduling. /// void SchedulePostRATDList::Schedule() { - DEBUG(errs() << "********** List Scheduling **********\n"); - // Build the scheduling graph. BuildSchedGraph(AA); if (AntiDepBreak != NULL) { - unsigned Broken = - AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, - InsertPosIndex); - if (Broken > 0) { + for (unsigned i = 0, Trials = AntiDepBreak->GetMaxTrials(); + i < Trials; ++i) { + DEBUG(errs() << "********** Break Anti-Deps, Trial " << + i << " **********\n"); + unsigned Broken = + AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, + InsertPosIndex); + if (Broken == 0) + break; + // We made changes. Update the dependency graph. // Theoretically we could update the graph in place: // When a live range is changed to use a different register, remove @@ -340,6 +345,8 @@ void SchedulePostRATDList::Schedule() { } } + DEBUG(errs() << "********** List Scheduling **********\n"); + DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) SUnits[su].dumpAll(this));