diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/RegAllocLinearScan.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 66 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMRegisterInfo.cpp | 158 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMRegisterInfo.h | 5 | 
5 files changed, 158 insertions, 84 deletions
diff --git a/llvm/lib/CodeGen/RegAllocLinearScan.cpp b/llvm/lib/CodeGen/RegAllocLinearScan.cpp index f7f5dc74b5d..41a42fd22d3 100644 --- a/llvm/lib/CodeGen/RegAllocLinearScan.cpp +++ b/llvm/lib/CodeGen/RegAllocLinearScan.cpp @@ -1356,9 +1356,15 @@ unsigned RALinScan::getFreePhysReg(LiveInterval* cur,    unsigned FreeReg = 0;    unsigned FreeRegInactiveCount = 0; +  std::pair<unsigned, unsigned> Hint = mri_->getRegAllocationHint(cur->reg); +  // Resolve second part of the hint (if possible) given the current allocation. +  unsigned physReg = Hint.second; +  if (physReg && +      TargetRegisterInfo::isVirtualRegister(physReg) && vrm_->hasPhys(physReg)) +    physReg = vrm_->getPhys(physReg); +    TargetRegisterClass::iterator I, E; -  tie(I, E) = tri_->getAllocationOrder(RC, -                                    mri_->getRegAllocationHint(cur->reg), *mf_); +  tie(I, E) = tri_->getAllocationOrder(RC, Hint.first, physReg, *mf_);    assert(I != E && "No allocatable register in this register class!");    // Scan for the first available register. diff --git a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp index c363ba52b5e..20348055bd9 100644 --- a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -1766,6 +1766,9 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {    // being merged.    li_->removeInterval(SrcReg); +  // Update regalloc hint. +  tri_->UpdateRegAllocHint(SrcReg, DstReg, *mf_); +    // Manually deleted the live interval copy.    if (SavedLI) {      SavedLI->clear(); diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp index 1b8223aa0ab..f8de0efc0d4 100644 --- a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp +++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp @@ -41,6 +41,12 @@ STATISTIC(NumSTMGened , "Number of stm instructions generated");  STATISTIC(NumFLDMGened, "Number of fldm instructions generated");  STATISTIC(NumFSTMGened, "Number of fstm instructions generated");  STATISTIC(NumLdStMoved, "Number of load / store instructions moved"); +STATISTIC(NumLDRDFormed,"Number of ldrd created before allocation"); +STATISTIC(NumSTRDFormed,"Number of strd created before allocation"); +STATISTIC(NumLDRD2LDM,  "Number of ldrd instructions turned back into ldm"); +STATISTIC(NumSTRD2STM,  "Number of strd instructions turned back into stm"); +STATISTIC(NumLDRD2LDR,  "Number of ldrd instructions turned back into ldr's"); +STATISTIC(NumSTRD2STR,  "Number of strd instructions turned back into str's");  /// ARMAllocLoadStoreOpt - Post- register allocation pass the combine  /// load / store instructions to form ldm / stm instructions. @@ -651,9 +657,9 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,      if ((EvenRegNum & 1) == 0 && (EvenRegNum + 1) == OddRegNum)        return false; -    bool isDef = Opcode == ARM::LDRD; -    bool EvenKill = isDef ? false : MI->getOperand(0).isKill(); -    bool OddKill  = isDef ? false : MI->getOperand(1).isKill(); +    bool isLd = Opcode == ARM::LDRD; +    bool EvenKill = isLd ? false : MI->getOperand(0).isKill(); +    bool OddKill  = isLd ? false : MI->getOperand(1).isKill();      const MachineOperand &BaseOp = MI->getOperand(2);      unsigned BaseReg = BaseOp.getReg();      bool BaseKill = BaseOp.isKill(); @@ -668,34 +674,49 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,        // Ascending register numbers and no offset. It's safe to change it to a        // ldm or stm.        unsigned NewOpc = (Opcode == ARM::LDRD) ? ARM::LDM : ARM::STM; -      BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(NewOpc)) -        .addReg(BaseReg, getKillRegState(BaseKill)) -        .addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia)) -        .addImm(Pred).addReg(PredReg) -        .addReg(EvenReg, getDefRegState(isDef)) -        .addReg(OddReg, getDefRegState(isDef)); +      if (isLd) { +        BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(NewOpc)) +          .addReg(BaseReg, getKillRegState(BaseKill)) +          .addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia)) +          .addImm(Pred).addReg(PredReg) +          .addReg(EvenReg, getDefRegState(isLd)) +          .addReg(OddReg, getDefRegState(isLd)); +        ++NumLDRD2LDM; +      } else { +        BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(NewOpc)) +          .addReg(BaseReg, getKillRegState(BaseKill)) +          .addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia)) +          .addImm(Pred).addReg(PredReg) +          .addReg(EvenReg, getKillRegState(EvenKill)) +          .addReg(OddReg, getKillRegState(OddKill)); +        ++NumSTRD2STM; +      }      } else {        // Split into two instructions.        unsigned NewOpc = (Opcode == ARM::LDRD) ? ARM::LDR : ARM::STR;        DebugLoc dl = MBBI->getDebugLoc();        // If this is a load and base register is killed, it may have been        // re-defed by the load, make sure the first load does not clobber it. -      if (isDef && +      if (isLd &&            (BaseKill || OffKill) &&            (TRI->regsOverlap(EvenReg, BaseReg) ||             (OffReg && TRI->regsOverlap(EvenReg, OffReg)))) {          assert(!TRI->regsOverlap(OddReg, BaseReg) &&                 (!OffReg || !TRI->regsOverlap(OddReg, OffReg))); -        InsertLDR_STR(MBB, MBBI, OffImm+4, isDef, dl, NewOpc, OddReg, OddKill, +        InsertLDR_STR(MBB, MBBI, OffImm+4, isLd, dl, NewOpc, OddReg, OddKill,                        BaseReg, false, OffReg, false, Pred, PredReg, TII); -        InsertLDR_STR(MBB, MBBI, OffImm, isDef, dl, NewOpc, EvenReg, EvenKill, +        InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc, EvenReg, EvenKill,                        BaseReg, BaseKill, OffReg, OffKill, Pred, PredReg, TII);        } else { -        InsertLDR_STR(MBB, MBBI, OffImm, isDef, dl, NewOpc, EvenReg, EvenKill, +        InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc, EvenReg, EvenKill,                        BaseReg, false, OffReg, false, Pred, PredReg, TII); -        InsertLDR_STR(MBB, MBBI, OffImm+4, isDef, dl, NewOpc, OddReg, OddKill, +        InsertLDR_STR(MBB, MBBI, OffImm+4, isLd, dl, NewOpc, OddReg, OddKill,                        BaseReg, BaseKill, OffReg, OffKill, Pred, PredReg, TII);        } +      if (isLd) +        ++NumLDRD2LDR; +      else +        ++NumSTRD2STR;      }      MBBI = prior(MBBI); @@ -1069,6 +1090,7 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,      MachineInstr *FirstOp = 0;      MachineInstr *LastOp = 0;      int LastOffset = 0; +    unsigned LastOpcode = 0;      unsigned LastBytes = 0;      unsigned NumMove = 0;      for (int i = Ops.size() - 1; i >= 0; --i) { @@ -1083,6 +1105,10 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,          LastOp = Op;        } +      unsigned Opcode = Op->getOpcode(); +      if (LastOpcode && Opcode != LastOpcode) +        break; +        int Offset = getMemoryOpOffset(Op);        unsigned Bytes = getLSMultipleTransferSize(Op);        if (LastBytes) { @@ -1091,6 +1117,7 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,        }        LastOffset = Offset;        LastBytes = Bytes; +      LastOpcode = Opcode;        if (++NumMove == 4)          break;      } @@ -1131,22 +1158,25 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,                                               Offset, PredReg, Pred)) {            Ops.pop_back();            Ops.pop_back(); -          MBB->erase(Op0); -          MBB->erase(Op1);            // Form the pair instruction. -          if (isLd) +          if (isLd) {              BuildMI(*MBB, InsertPos, dl, TII->get(NewOpc))                .addReg(EvenReg, RegState::Define)                .addReg(OddReg, RegState::Define)                .addReg(BaseReg).addReg(0).addImm(Offset)                .addImm(Pred).addReg(PredReg); -          else +            ++NumLDRDFormed; +          } else {              BuildMI(*MBB, InsertPos, dl, TII->get(NewOpc))                .addReg(EvenReg)                .addReg(OddReg)                .addReg(BaseReg).addReg(0).addImm(Offset)                .addImm(Pred).addReg(PredReg); +            ++NumSTRDFormed; +          } +          MBB->erase(Op0); +          MBB->erase(Op1);            // Add register allocation hints to form register pairs.            MRI->setRegAllocationHint(EvenReg, ARMRI::RegPairEven, OddReg); diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMRegisterInfo.cpp index 6298df9773f..71137dd75fe 100644 --- a/llvm/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMRegisterInfo.cpp @@ -308,7 +308,7 @@ const TargetRegisterClass *ARMRegisterInfo::getPointerRegClass() const {  /// register class in the form of a pair of TargetRegisterClass iterators.  std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>  ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC, -                                    std::pair<unsigned, unsigned> Hint, +                                    unsigned HintType, unsigned HintReg,                                      const MachineFunction &MF) const {    // Alternative register allocation orders when favoring even / odd registers    // of register pairs. @@ -384,7 +384,13 @@ ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,    }; -  if (Hint.first == ARMRI::RegPairEven) { +  if (HintType == ARMRI::RegPairEven) { +    if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0) +      // It's no longer possible to fulfill this hint. Return the default +      // allocation order. +      return std::make_pair(RC->allocation_order_begin(MF), +                            RC->allocation_order_end(MF)); +      if (!STI.isTargetDarwin() && !hasFP(MF)) {        if (!STI.isR9Reserved())          return std::make_pair(GPREven1, @@ -407,7 +413,13 @@ ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,          return std::make_pair(GPREven6,                                GPREven6 + (sizeof(GPREven6)/sizeof(unsigned)));      } -  } else if (Hint.first == ARMRI::RegPairOdd) { +  } else if (HintType == ARMRI::RegPairOdd) { +    if (isPhysicalRegister(HintReg) && getRegisterPairOdd(HintReg, MF) == 0) +      // It's no longer possible to fulfill this hint. Return the default +      // allocation order. +      return std::make_pair(RC->allocation_order_begin(MF), +                            RC->allocation_order_end(MF)); +      if (!STI.isTargetDarwin() && !hasFP(MF)) {        if (!STI.isR9Reserved())          return std::make_pair(GPROdd1, @@ -453,6 +465,26 @@ ARMRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,    return 0;  } +void +ARMRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg, +                                    MachineFunction &MF) const { +  MachineRegisterInfo *MRI = &MF.getRegInfo(); +  std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg); +  if ((Hint.first == (unsigned)ARMRI::RegPairOdd || +       Hint.first == (unsigned)ARMRI::RegPairEven) && +      Hint.second && TargetRegisterInfo::isVirtualRegister(Hint.second)) { +    // If 'Reg' is one of the even / odd register pair and it's now changed +    // (e.g. coalesced) into a different register. The other register of the +    // pair allocation hint must be updated to reflect the relationship +    // change. +    unsigned OtherReg = Hint.second; +    Hint = MRI->getRegAllocationHint(OtherReg); +    if (Hint.second == Reg) +      // Make sure the pair has not already divorced. +      MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg); +  } +} +  bool  ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {    const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); @@ -1680,68 +1712,68 @@ unsigned ARMRegisterInfo::getRegisterPairEven(unsigned Reg,    default: break;    // Return 0 if either register of the pair is a special register.    // So no R12, etc. -  case ARM::R0: case ARM::R1: +  case ARM::R1:      return ARM::R0; -  case ARM::R2: case ARM::R3: +  case ARM::R3:      // FIXME!      return STI.isThumb() ? 0 : ARM::R2; -  case ARM::R4: case ARM::R5: +  case ARM::R5:      return ARM::R4; -  case ARM::R6: case ARM::R7: +  case ARM::R7:      return isReservedReg(MF, ARM::R7)  ? 0 : ARM::R6; -  case ARM::R8: case ARM::R9: +  case ARM::R9:      return isReservedReg(MF, ARM::R9)  ? 0 :ARM::R8; -  case ARM::R10: case ARM::R11: +  case ARM::R11:      return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10; -  case ARM::S0: case ARM::S1: +  case ARM::S1:      return ARM::S0; -  case ARM::S2: case ARM::S3: +  case ARM::S3:      return ARM::S2; -  case ARM::S4: case ARM::S5: +  case ARM::S5:      return ARM::S4; -  case ARM::S6: case ARM::S7: +  case ARM::S7:      return ARM::S6; -  case ARM::S8: case ARM::S9: +  case ARM::S9:      return ARM::S8; -  case ARM::S10: case ARM::S11: +  case ARM::S11:      return ARM::S10; -  case ARM::S12: case ARM::S13: +  case ARM::S13:      return ARM::S12; -  case ARM::S14: case ARM::S15: +  case ARM::S15:      return ARM::S14; -  case ARM::S16: case ARM::S17: +  case ARM::S17:      return ARM::S16; -  case ARM::S18: case ARM::S19: +  case ARM::S19:      return ARM::S18; -  case ARM::S20: case ARM::S21: +  case ARM::S21:      return ARM::S20; -  case ARM::S22: case ARM::S23: +  case ARM::S23:      return ARM::S22; -  case ARM::S24: case ARM::S25: +  case ARM::S25:      return ARM::S24; -  case ARM::S26: case ARM::S27: +  case ARM::S27:      return ARM::S26; -  case ARM::S28: case ARM::S29: +  case ARM::S29:      return ARM::S28; -  case ARM::S30: case ARM::S31: +  case ARM::S31:      return ARM::S30; -  case ARM::D0: case ARM::D1: +  case ARM::D1:      return ARM::D0; -  case ARM::D2: case ARM::D3: +  case ARM::D3:      return ARM::D2; -  case ARM::D4: case ARM::D5: +  case ARM::D5:      return ARM::D4; -  case ARM::D6: case ARM::D7: +  case ARM::D7:      return ARM::D6; -  case ARM::D8: case ARM::D9: +  case ARM::D9:      return ARM::D8; -  case ARM::D10: case ARM::D11: +  case ARM::D11:      return ARM::D10; -  case ARM::D12: case ARM::D13: +  case ARM::D13:      return ARM::D12; -  case ARM::D14: case ARM::D15: +  case ARM::D15:      return ARM::D14;    } @@ -1754,68 +1786,68 @@ unsigned ARMRegisterInfo::getRegisterPairOdd(unsigned Reg,    default: break;    // Return 0 if either register of the pair is a special register.    // So no R12, etc. -  case ARM::R0: case ARM::R1: +  case ARM::R0:      return ARM::R1; -  case ARM::R2: case ARM::R3: +  case ARM::R2:      // FIXME!      return STI.isThumb() ? 0 : ARM::R3; -  case ARM::R4: case ARM::R5: +  case ARM::R4:      return ARM::R5; -  case ARM::R6: case ARM::R7: +  case ARM::R6:      return isReservedReg(MF, ARM::R7)  ? 0 : ARM::R7; -  case ARM::R8: case ARM::R9: +  case ARM::R8:      return isReservedReg(MF, ARM::R9)  ? 0 :ARM::R9; -  case ARM::R10: case ARM::R11: +  case ARM::R10:      return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11; -  case ARM::S0: case ARM::S1: +  case ARM::S0:      return ARM::S1; -  case ARM::S2: case ARM::S3: +  case ARM::S2:      return ARM::S3; -  case ARM::S4: case ARM::S5: +  case ARM::S4:      return ARM::S5; -  case ARM::S6: case ARM::S7: +  case ARM::S6:      return ARM::S7; -  case ARM::S8: case ARM::S9: +  case ARM::S8:      return ARM::S9; -  case ARM::S10: case ARM::S11: +  case ARM::S10:      return ARM::S11; -  case ARM::S12: case ARM::S13: +  case ARM::S12:      return ARM::S13; -  case ARM::S14: case ARM::S15: +  case ARM::S14:      return ARM::S15; -  case ARM::S16: case ARM::S17: +  case ARM::S16:      return ARM::S17; -  case ARM::S18: case ARM::S19: +  case ARM::S18:      return ARM::S19; -  case ARM::S20: case ARM::S21: +  case ARM::S20:      return ARM::S21; -  case ARM::S22: case ARM::S23: +  case ARM::S22:      return ARM::S23; -  case ARM::S24: case ARM::S25: +  case ARM::S24:      return ARM::S25; -  case ARM::S26: case ARM::S27: +  case ARM::S26:      return ARM::S27; -  case ARM::S28: case ARM::S29: +  case ARM::S28:      return ARM::S29; -  case ARM::S30: case ARM::S31: +  case ARM::S30:      return ARM::S31; -  case ARM::D0: case ARM::D1: +  case ARM::D0:      return ARM::D1; -  case ARM::D2: case ARM::D3: +  case ARM::D2:      return ARM::D3; -  case ARM::D4: case ARM::D5: +  case ARM::D4:      return ARM::D5; -  case ARM::D6: case ARM::D7: +  case ARM::D6:      return ARM::D7; -  case ARM::D8: case ARM::D9: +  case ARM::D8:      return ARM::D9; -  case ARM::D10: case ARM::D11: +  case ARM::D10:      return ARM::D11; -  case ARM::D12: case ARM::D13: +  case ARM::D12:      return ARM::D13; -  case ARM::D14: case ARM::D15: +  case ARM::D14:      return ARM::D15;    } diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.h b/llvm/lib/Target/ARM/ARMRegisterInfo.h index b27e3b7c0ad..e8f4fd805d5 100644 --- a/llvm/lib/Target/ARM/ARMRegisterInfo.h +++ b/llvm/lib/Target/ARM/ARMRegisterInfo.h @@ -70,12 +70,15 @@ public:    std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>    getAllocationOrder(const TargetRegisterClass *RC, -                     std::pair<unsigned,unsigned> Hint, +                     unsigned HintType, unsigned HintReg,                       const MachineFunction &MF) const;    unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg,                                 const MachineFunction &MF) const; +  void UpdateRegAllocHint(unsigned Reg, unsigned NewReg, +                          MachineFunction &MF) const; +    bool requiresRegisterScavenging(const MachineFunction &MF) const;    bool hasFP(const MachineFunction &MF) const;  | 

