diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2009-10-01 08:26:23 +0000 | 
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2009-10-01 08:26:23 +0000 | 
| commit | 4fb2891396da90f040ce12cd2a4680df5c1d57c5 (patch) | |
| tree | a0fecb045b99920082f9992a21580d71641888c7 /llvm/lib/CodeGen | |
| parent | 1b2b64f618d4bf0b86b8d3a82eba602a8af34bd4 (diff) | |
| download | bcm5719-llvm-4fb2891396da90f040ce12cd2a4680df5c1d57c5.tar.gz bcm5719-llvm-4fb2891396da90f040ce12cd2a4680df5c1d57c5.zip | |
Observe hasExtraSrcRegAllocReq and hasExtraDefRegAllocReq. Do not change
operands of instructions with these properties while breaking anti-dep.
llvm-svn: 83198
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/PostRASchedulerList.cpp | 73 | 
1 files changed, 55 insertions, 18 deletions
| diff --git a/llvm/lib/CodeGen/PostRASchedulerList.cpp b/llvm/lib/CodeGen/PostRASchedulerList.cpp index 5fa598d95b7..8d746142d1e 100644 --- a/llvm/lib/CodeGen/PostRASchedulerList.cpp +++ b/llvm/lib/CodeGen/PostRASchedulerList.cpp @@ -123,14 +123,18 @@ namespace {      /// RegRegs - Map registers to all their references within a live range.      std::multimap<unsigned, MachineOperand *> RegRefs; -    /// The index of the most recent kill (proceding bottom-up), or ~0u if -    /// the register is not live. +    /// KillIndices - The index of the most recent kill (proceding bottom-up), +    /// or ~0u if the register is not live.      unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; -    /// The index of the most recent complete def (proceding bottom up), or ~0u -    /// if the register is live. +    /// DefIndices - The index of the most recent complete def (proceding bottom +    /// up), or ~0u if the register is live.      unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; +    /// KeepRegs - A set of registers which are live and cannot be changed to +    /// break anti-dependencies. +    SmallSet<unsigned, 4> KeepRegs; +    public:      SchedulePostRATDList(MachineFunction &MF,                           const MachineLoopInfo &MLI, @@ -293,6 +297,9 @@ void SchedulePostRATDList::StartBlock(MachineBasicBlock *BB) {    std::fill(KillIndices, array_endof(KillIndices), ~0u);    std::fill(DefIndices, array_endof(DefIndices), BB->size()); +  // Clear "do not change" set. +  KeepRegs.clear(); +    // Determine the live-out physregs for this block.    if (!BB->empty() && BB->back().getDesc().isReturn())      // In a return block, examine the function live-out regs. @@ -495,9 +502,10 @@ void SchedulePostRATDList::ScanInstruction(MachineInstr *MI,      DefIndices[Reg] = Count;      KillIndices[Reg] = ~0u; -          assert(((KillIndices[Reg] == ~0u) != -                  (DefIndices[Reg] == ~0u)) && -               "Kill and Def maps aren't consistent for Reg!"); +    assert(((KillIndices[Reg] == ~0u) != +            (DefIndices[Reg] == ~0u)) && +           "Kill and Def maps aren't consistent for Reg!"); +    KeepRegs.erase(Reg);      Classes[Reg] = 0;      RegRefs.erase(Reg);      // Repeat, for all subregs. @@ -506,6 +514,7 @@ void SchedulePostRATDList::ScanInstruction(MachineInstr *MI,        unsigned SubregReg = *Subreg;        DefIndices[SubregReg] = Count;        KillIndices[SubregReg] = ~0u; +      KeepRegs.erase(SubregReg);        Classes[SubregReg] = 0;        RegRefs.erase(SubregReg);      } @@ -690,8 +699,12 @@ bool SchedulePostRATDList::BreakAntiDependencies() {          if (Edge->getKind() == SDep::Anti) {            AntiDepReg = Edge->getReg();            assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); -          // Don't break anti-dependencies on non-allocatable registers.            if (!AllocatableSet.test(AntiDepReg)) +            // Don't break anti-dependencies on non-allocatable registers. +            AntiDepReg = 0; +          else if (KeepRegs.count(AntiDepReg)) +            // Don't break anti-dependencies if an use down below requires +            // this exact register.              AntiDepReg = 0;            else {              // If the SUnit has other dependencies on the SUnit that it @@ -723,16 +736,40 @@ bool SchedulePostRATDList::BreakAntiDependencies() {      PrescanInstruction(MI); -    // If this instruction has a use of AntiDepReg, breaking it -    // is invalid. -    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { -      MachineOperand &MO = MI->getOperand(i); -      if (!MO.isReg()) continue; -      unsigned Reg = MO.getReg(); -      if (Reg == 0) continue; -      if (MO.isUse() && AntiDepReg == Reg) { -        AntiDepReg = 0; -        break; +    if (MI->getDesc().hasExtraSrcRegAllocReq()) { +      // It's not safe to change register allocation for source operands of +      // that have special allocation requirements. +      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { +        MachineOperand &MO = MI->getOperand(i); +        if (!MO.isReg()) continue; +        unsigned Reg = MO.getReg(); +        if (Reg == 0) continue; +        if (MO.isUse()) { +          if (KeepRegs.insert(Reg)) { +            for (const unsigned *Subreg = TRI->getSubRegisters(Reg); +                 *Subreg; ++Subreg) +              KeepRegs.insert(*Subreg); +          } +        } +      } +    } + +    if (MI->getDesc().hasExtraDefRegAllocReq()) +      // If this instruction's defs have special allocation requirement, don't +      // break this anti-dependency. +      AntiDepReg = 0; +    else if (AntiDepReg) { +      // If this instruction has a use of AntiDepReg, breaking it +      // is invalid. +      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { +        MachineOperand &MO = MI->getOperand(i); +        if (!MO.isReg()) continue; +        unsigned Reg = MO.getReg(); +        if (Reg == 0) continue; +        if (MO.isUse() && AntiDepReg == Reg) { +          AntiDepReg = 0; +          break; +        }        }      } | 

