diff options
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 37 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIInstrInfo.h | 13 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp | 49 | 
3 files changed, 84 insertions, 15 deletions
| diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp index aae6595f417..c97bb4cd093 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -6410,3 +6410,40 @@ bool llvm::execMayBeModifiedBeforeAnyUse(const MachineRegisterInfo &MRI,        return true;    }  } + +MachineInstr *SIInstrInfo::createPHIDestinationCopy( +    MachineBasicBlock &MBB, MachineBasicBlock::iterator LastPHIIt, +    const DebugLoc &DL, Register Src, Register Dst) const { +  auto Cur = MBB.begin(); +  if (Cur != MBB.end()) +    do { +      if (!Cur->isPHI() && Cur->readsRegister(Dst)) +        return BuildMI(MBB, Cur, DL, get(TargetOpcode::COPY), Dst).addReg(Src); +      ++Cur; +    } while (Cur != MBB.end() && Cur != LastPHIIt); + +  return TargetInstrInfo::createPHIDestinationCopy(MBB, LastPHIIt, DL, Src, +                                                   Dst); +} + +MachineInstr *SIInstrInfo::createPHISourceCopy( +    MachineBasicBlock &MBB, MachineBasicBlock::iterator InsPt, +    const DebugLoc &DL, Register Src, Register SrcSubReg, Register Dst) const { +  if (InsPt != MBB.end() && +      (InsPt->getOpcode() == AMDGPU::SI_IF || +       InsPt->getOpcode() == AMDGPU::SI_ELSE || +       InsPt->getOpcode() == AMDGPU::SI_IF_BREAK) && +      InsPt->definesRegister(Src)) { +    InsPt++; +    return BuildMI(MBB, InsPt, InsPt->getDebugLoc(), +                   get(ST.isWave32() ? AMDGPU::S_MOV_B32_term +                                     : AMDGPU::S_MOV_B64_term), +                   Dst) +        .addReg(Src, 0, SrcSubReg) +        .addReg(AMDGPU::EXEC, RegState::Implicit); +  } +  return TargetInstrInfo::createPHISourceCopy(MBB, InsPt, DL, Src, SrcSubReg, +                                              Dst); +} + +bool llvm::SIInstrInfo::isWave32() const { return ST.isWave32(); } diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h index 2e629c47256..04671a073d3 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h @@ -954,6 +954,19 @@ public:    bool isBasicBlockPrologue(const MachineInstr &MI) const override; +  MachineInstr *createPHIDestinationCopy(MachineBasicBlock &MBB, +                                         MachineBasicBlock::iterator InsPt, +                                         const DebugLoc &DL, Register Src, +                                         Register Dst) const override; + +  MachineInstr *createPHISourceCopy(MachineBasicBlock &MBB, +                                    MachineBasicBlock::iterator InsPt, +                                    const DebugLoc &DL, Register Src, +                                    Register SrcSubReg, +                                    Register Dst) const override; + +  bool isWave32() const; +    /// Return a partially built integer add instruction without carry.    /// Caller must add source operands.    /// For pre-GFX9 it will generate unused carry destination operand. diff --git a/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp b/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp index 1a51b7ebffa..6f9abd3a8d9 100644 --- a/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp +++ b/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp @@ -98,6 +98,8 @@ private:    void emitLoop(MachineInstr &MI);    void emitEndCf(MachineInstr &MI); +  Register getSaveExec(MachineInstr* MI); +    void findMaskOperands(MachineInstr &MI, unsigned OpNo,                          SmallVectorImpl<MachineOperand> &Src) const; @@ -175,17 +177,31 @@ static bool isSimpleIf(const MachineInstr &MI, const MachineRegisterInfo *MRI,    return true;  } +Register SILowerControlFlow::getSaveExec(MachineInstr *MI) { +  MachineBasicBlock *MBB = MI->getParent(); +  MachineOperand &SaveExec = MI->getOperand(0); +  assert(SaveExec.getSubReg() == AMDGPU::NoSubRegister); + +  Register SaveExecReg = SaveExec.getReg(); +  unsigned FalseTermOpc = +      TII->isWave32() ? AMDGPU::S_MOV_B32_term : AMDGPU::S_MOV_B64_term; +  MachineBasicBlock::iterator I = (MI); +  MachineBasicBlock::iterator J = std::next(I); +  if (J != MBB->end() && J->getOpcode() == FalseTermOpc && +      J->getOperand(1).isReg() && J->getOperand(1).getReg() == SaveExecReg) { +    SaveExecReg = J->getOperand(0).getReg(); +    J->eraseFromParent(); +  } +  return SaveExecReg; +} +  void SILowerControlFlow::emitIf(MachineInstr &MI) {    MachineBasicBlock &MBB = *MI.getParent();    const DebugLoc &DL = MI.getDebugLoc();    MachineBasicBlock::iterator I(&MI); - -  MachineOperand &SaveExec = MI.getOperand(0); -  MachineOperand &Cond = MI.getOperand(1); -  assert(SaveExec.getSubReg() == AMDGPU::NoSubRegister && -         Cond.getSubReg() == AMDGPU::NoSubRegister); - -  Register SaveExecReg = SaveExec.getReg(); +  Register SaveExecReg = getSaveExec(&MI); +  MachineOperand& Cond = MI.getOperand(1); +  assert(Cond.getSubReg() == AMDGPU::NoSubRegister);    MachineOperand &ImpDefSCC = MI.getOperand(4);    assert(ImpDefSCC.getReg() == AMDGPU::SCC && ImpDefSCC.isDef()); @@ -266,8 +282,7 @@ void SILowerControlFlow::emitElse(MachineInstr &MI) {    MachineBasicBlock &MBB = *MI.getParent();    const DebugLoc &DL = MI.getDebugLoc(); -  Register DstReg = MI.getOperand(0).getReg(); -  assert(MI.getOperand(0).getSubReg() == AMDGPU::NoSubRegister); +  Register DstReg = getSaveExec(&MI);    bool ExecModified = MI.getOperand(3).getImm() != 0;    MachineBasicBlock::iterator Start = MBB.begin(); @@ -339,7 +354,7 @@ void SILowerControlFlow::emitElse(MachineInstr &MI) {  void SILowerControlFlow::emitIfBreak(MachineInstr &MI) {    MachineBasicBlock &MBB = *MI.getParent();    const DebugLoc &DL = MI.getDebugLoc(); -  auto Dst = MI.getOperand(0).getReg(); +  auto Dst = getSaveExec(&MI);    // Skip ANDing with exec if the break condition is already masked by exec    // because it is a V_CMP in the same basic block. (We know the break @@ -400,13 +415,17 @@ void SILowerControlFlow::emitLoop(MachineInstr &MI) {  void SILowerControlFlow::emitEndCf(MachineInstr &MI) {    MachineBasicBlock &MBB = *MI.getParent(); +  MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); +  unsigned CFMask = MI.getOperand(0).getReg(); +  MachineInstr *Def = MRI.getUniqueVRegDef(CFMask);    const DebugLoc &DL = MI.getDebugLoc(); -  MachineBasicBlock::iterator InsPt = MBB.begin(); -  MachineInstr *NewMI = -      BuildMI(MBB, InsPt, DL, TII->get(OrOpc), Exec) -          .addReg(Exec) -          .add(MI.getOperand(0)); +  MachineBasicBlock::iterator InsPt = +      Def && Def->getParent() == &MBB ? std::next(MachineBasicBlock::iterator(Def)) +                               : MBB.begin(); +  MachineInstr *NewMI = BuildMI(MBB, InsPt, DL, TII->get(OrOpc), Exec) +                            .addReg(Exec) +                            .add(MI.getOperand(0));    if (LIS)      LIS->ReplaceMachineInstrInMaps(MI, *NewMI); | 

