LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - R600ClauseMergePass.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 71 85 83.5 %
Date: 2017-09-14 15:23:50 Functions: 8 9 88.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- R600ClauseMergePass - Merge consecutive CF_ALU -------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : /// \file
      11             : /// R600EmitClauseMarker pass emits CFAlu instruction in a conservative maneer.
      12             : /// This pass is merging consecutive CFAlus where applicable.
      13             : /// It needs to be called after IfCvt for best results.
      14             : //===----------------------------------------------------------------------===//
      15             : 
      16             : #include "AMDGPU.h"
      17             : #include "AMDGPUSubtarget.h"
      18             : #include "R600Defines.h"
      19             : #include "R600InstrInfo.h"
      20             : #include "R600MachineFunctionInfo.h"
      21             : #include "R600RegisterInfo.h"
      22             : #include "llvm/CodeGen/MachineFunctionPass.h"
      23             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      24             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      25             : #include "llvm/Support/Debug.h"
      26             : #include "llvm/Support/raw_ostream.h"
      27             : 
      28             : using namespace llvm;
      29             : 
      30             : #define DEBUG_TYPE "r600mergeclause"
      31             : 
      32             : namespace {
      33             : 
      34             : static bool isCFAlu(const MachineInstr &MI) {
      35      191533 :   switch (MI.getOpcode()) {
      36             :   case AMDGPU::CF_ALU:
      37             :   case AMDGPU::CF_ALU_PUSH_BEFORE:
      38             :     return true;
      39             :   default:
      40             :     return false;
      41             :   }
      42             : }
      43             : 
      44         243 : class R600ClauseMergePass : public MachineFunctionPass {
      45             : 
      46             : private:
      47             :   const R600InstrInfo *TII;
      48             : 
      49             :   unsigned getCFAluSize(const MachineInstr &MI) const;
      50             :   bool isCFAluEnabled(const MachineInstr &MI) const;
      51             : 
      52             :   /// IfCvt pass can generate "disabled" ALU clause marker that need to be
      53             :   /// removed and their content affected to the previous alu clause.
      54             :   /// This function parse instructions after CFAlu until it find a disabled
      55             :   /// CFAlu and merge the content, or an enabled CFAlu.
      56             :   void cleanPotentialDisabledCFAlu(MachineInstr &CFAlu) const;
      57             : 
      58             :   /// Check whether LatrCFAlu can be merged into RootCFAlu and do it if
      59             :   /// it is the case.
      60             :   bool mergeIfPossible(MachineInstr &RootCFAlu,
      61             :                        const MachineInstr &LatrCFAlu) const;
      62             : 
      63             : public:
      64             :   static char ID;
      65             : 
      66         244 :   R600ClauseMergePass() : MachineFunctionPass(ID) { }
      67             : 
      68             :   bool runOnMachineFunction(MachineFunction &MF) override;
      69             : 
      70             :   StringRef getPassName() const override;
      71             : };
      72             : 
      73             : } // end anonymous namespace
      74             : 
      75       53042 : INITIALIZE_PASS_BEGIN(R600ClauseMergePass, DEBUG_TYPE,
      76             :                       "R600 Clause Merge", false, false)
      77      312538 : INITIALIZE_PASS_END(R600ClauseMergePass, DEBUG_TYPE,
      78             :                     "R600 Clause Merge", false, false)
      79             : 
      80             : char R600ClauseMergePass::ID = 0;
      81             : 
      82             : char &llvm::R600ClauseMergePassID = R600ClauseMergePass::ID;
      83             : 
      84             : unsigned R600ClauseMergePass::getCFAluSize(const MachineInstr &MI) const {
      85             :   assert(isCFAlu(MI));
      86             :   return MI
      87        2064 :       .getOperand(TII->getOperandIdx(MI.getOpcode(), AMDGPU::OpName::COUNT))
      88         688 :       .getImm();
      89             : }
      90             : 
      91             : bool R600ClauseMergePass::isCFAluEnabled(const MachineInstr &MI) const {
      92             :   assert(isCFAlu(MI));
      93             :   return MI
      94        2966 :       .getOperand(TII->getOperandIdx(MI.getOpcode(), AMDGPU::OpName::Enabled))
      95             :       .getImm();
      96             : }
      97             : 
      98        3597 : void R600ClauseMergePass::cleanPotentialDisabledCFAlu(
      99             :     MachineInstr &CFAlu) const {
     100        3597 :   int CntIdx = TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::COUNT);
     101        7194 :   MachineBasicBlock::iterator I = CFAlu, E = CFAlu.getParent()->end();
     102        3597 :   I++;
     103             :   do {
     104      166614 :     while (I != E && !isCFAlu(*I))
     105       53836 :       I++;
     106        3623 :     if (I == E)
     107        2140 :       return;
     108        4449 :     MachineInstr &MI = *I++;
     109        2966 :     if (isCFAluEnabled(MI))
     110             :       break;
     111         130 :     CFAlu.getOperand(CntIdx).setImm(getCFAluSize(CFAlu) + getCFAluSize(MI));
     112          26 :     MI.eraseFromParent();
     113          26 :   } while (I != E);
     114             : }
     115             : 
     116         318 : bool R600ClauseMergePass::mergeIfPossible(MachineInstr &RootCFAlu,
     117             :                                           const MachineInstr &LatrCFAlu) const {
     118             :   assert(isCFAlu(RootCFAlu) && isCFAlu(LatrCFAlu));
     119         318 :   int CntIdx = TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::COUNT);
     120         636 :   unsigned RootInstCount = getCFAluSize(RootCFAlu),
     121         636 :       LaterInstCount = getCFAluSize(LatrCFAlu);
     122         318 :   unsigned CumuledInsts = RootInstCount + LaterInstCount;
     123         318 :   if (CumuledInsts >= TII->getMaxAlusPerClause()) {
     124             :     DEBUG(dbgs() << "Excess inst counts\n");
     125             :     return false;
     126             :   }
     127         184 :   if (RootCFAlu.getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE)
     128             :     return false;
     129             :   // Is KCache Bank 0 compatible ?
     130             :   int Mode0Idx =
     131          92 :       TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::KCACHE_MODE0);
     132             :   int KBank0Idx =
     133          92 :       TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::KCACHE_BANK0);
     134             :   int KBank0LineIdx =
     135          92 :       TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::KCACHE_ADDR0);
     136         186 :   if (LatrCFAlu.getOperand(Mode0Idx).getImm() &&
     137          94 :       RootCFAlu.getOperand(Mode0Idx).getImm() &&
     138           0 :       (LatrCFAlu.getOperand(KBank0Idx).getImm() !=
     139           0 :            RootCFAlu.getOperand(KBank0Idx).getImm() ||
     140           0 :        LatrCFAlu.getOperand(KBank0LineIdx).getImm() !=
     141           0 :            RootCFAlu.getOperand(KBank0LineIdx).getImm())) {
     142             :     DEBUG(dbgs() << "Wrong KC0\n");
     143             :     return false;
     144             :   }
     145             :   // Is KCache Bank 1 compatible ?
     146             :   int Mode1Idx =
     147          92 :       TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::KCACHE_MODE1);
     148             :   int KBank1Idx =
     149          92 :       TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::KCACHE_BANK1);
     150             :   int KBank1LineIdx =
     151          92 :       TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::KCACHE_ADDR1);
     152         184 :   if (LatrCFAlu.getOperand(Mode1Idx).getImm() &&
     153          92 :       RootCFAlu.getOperand(Mode1Idx).getImm() &&
     154           0 :       (LatrCFAlu.getOperand(KBank1Idx).getImm() !=
     155           0 :            RootCFAlu.getOperand(KBank1Idx).getImm() ||
     156           0 :        LatrCFAlu.getOperand(KBank1LineIdx).getImm() !=
     157           0 :            RootCFAlu.getOperand(KBank1LineIdx).getImm())) {
     158             :     DEBUG(dbgs() << "Wrong KC0\n");
     159             :     return false;
     160             :   }
     161         184 :   if (LatrCFAlu.getOperand(Mode0Idx).getImm()) {
     162           8 :     RootCFAlu.getOperand(Mode0Idx).setImm(
     163           2 :         LatrCFAlu.getOperand(Mode0Idx).getImm());
     164           8 :     RootCFAlu.getOperand(KBank0Idx).setImm(
     165           4 :         LatrCFAlu.getOperand(KBank0Idx).getImm());
     166           4 :     RootCFAlu.getOperand(KBank0LineIdx)
     167           4 :         .setImm(LatrCFAlu.getOperand(KBank0LineIdx).getImm());
     168             :   }
     169          92 :   if (LatrCFAlu.getOperand(Mode1Idx).getImm()) {
     170           0 :     RootCFAlu.getOperand(Mode1Idx).setImm(
     171           0 :         LatrCFAlu.getOperand(Mode1Idx).getImm());
     172           0 :     RootCFAlu.getOperand(KBank1Idx).setImm(
     173           0 :         LatrCFAlu.getOperand(KBank1Idx).getImm());
     174           0 :     RootCFAlu.getOperand(KBank1LineIdx)
     175           0 :         .setImm(LatrCFAlu.getOperand(KBank1LineIdx).getImm());
     176             :   }
     177         276 :   RootCFAlu.getOperand(CntIdx).setImm(CumuledInsts);
     178         368 :   RootCFAlu.setDesc(TII->get(LatrCFAlu.getOpcode()));
     179          92 :   return true;
     180             : }
     181             : 
     182        2057 : bool R600ClauseMergePass::runOnMachineFunction(MachineFunction &MF) {
     183        2057 :   if (skipFunction(*MF.getFunction()))
     184             :     return false;
     185             : 
     186        2057 :   const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>();
     187        2057 :   TII = ST.getInstrInfo();
     188             : 
     189        4114 :   for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
     190        4231 :                                                   BB != BB_E; ++BB) {
     191        2174 :     MachineBasicBlock &MBB = *BB;
     192        4348 :     MachineBasicBlock::iterator I = MBB.begin(),  E = MBB.end();
     193        2174 :     MachineBasicBlock::iterator LatestCFAlu = E;
     194       59663 :     while (I != E) {
     195      172467 :       MachineInstr &MI = *I++;
     196      107957 :       if ((!TII->canBeConsideredALU(MI) && !isCFAlu(MI)) ||
     197      100936 :           TII->mustBeLastInClause(MI.getOpcode()))
     198             :         LatestCFAlu = E;
     199       57489 :       if (!isCFAlu(MI))
     200       53892 :         continue;
     201        3597 :       cleanPotentialDisabledCFAlu(MI);
     202             : 
     203        3915 :       if (LatestCFAlu != E && mergeIfPossible(*LatestCFAlu, MI)) {
     204          92 :         MI.eraseFromParent();
     205             :       } else {
     206             :         assert(MI.getOperand(8).getImm() && "CF ALU instruction disabled");
     207             :         LatestCFAlu = MI;
     208             :       }
     209             :     }
     210             :   }
     211             :   return false;
     212             : }
     213             : 
     214         244 : StringRef R600ClauseMergePass::getPassName() const {
     215         244 :   return "R600 Merge Clause Markers Pass";
     216             : }
     217             : 
     218         244 : llvm::FunctionPass *llvm::createR600ClauseMergePass() {
     219         488 :   return new R600ClauseMergePass();
     220             : }

Generated by: LCOV version 1.13