LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - R600ClauseMergePass.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 58 72 80.6 %
Date: 2018-10-20 13:21:21 Functions: 7 9 77.8 %
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 "MCTargetDesc/AMDGPUMCTargetDesc.h"
      23             : #include "llvm/CodeGen/MachineFunctionPass.h"
      24             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      25             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      26             : #include "llvm/Support/Debug.h"
      27             : #include "llvm/Support/raw_ostream.h"
      28             : 
      29             : using namespace llvm;
      30             : 
      31             : #define DEBUG_TYPE "r600mergeclause"
      32             : 
      33             : namespace {
      34             : 
      35             : static bool isCFAlu(const MachineInstr &MI) {
      36      245442 :   switch (MI.getOpcode()) {
      37             :   case R600::CF_ALU:
      38             :   case R600::CF_ALU_PUSH_BEFORE:
      39             :     return true;
      40             :   default:
      41             :     return false;
      42             :   }
      43             : }
      44             : 
      45             : class R600ClauseMergePass : public MachineFunctionPass {
      46             : 
      47             : private:
      48             :   const R600InstrInfo *TII;
      49             : 
      50             :   unsigned getCFAluSize(const MachineInstr &MI) const;
      51             :   bool isCFAluEnabled(const MachineInstr &MI) const;
      52             : 
      53             :   /// IfCvt pass can generate "disabled" ALU clause marker that need to be
      54             :   /// removed and their content affected to the previous alu clause.
      55             :   /// This function parse instructions after CFAlu until it find a disabled
      56             :   /// CFAlu and merge the content, or an enabled CFAlu.
      57             :   void cleanPotentialDisabledCFAlu(MachineInstr &CFAlu) const;
      58             : 
      59             :   /// Check whether LatrCFAlu can be merged into RootCFAlu and do it if
      60             :   /// it is the case.
      61             :   bool mergeIfPossible(MachineInstr &RootCFAlu,
      62             :                        const MachineInstr &LatrCFAlu) const;
      63             : 
      64             : public:
      65             :   static char ID;
      66             : 
      67         282 :   R600ClauseMergePass() : MachineFunctionPass(ID) { }
      68             : 
      69             :   bool runOnMachineFunction(MachineFunction &MF) override;
      70             : 
      71             :   StringRef getPassName() const override;
      72             : };
      73             : 
      74             : } // end anonymous namespace
      75             : 
      76       85105 : INITIALIZE_PASS_BEGIN(R600ClauseMergePass, DEBUG_TYPE,
      77             :                       "R600 Clause Merge", false, false)
      78      199024 : INITIALIZE_PASS_END(R600ClauseMergePass, DEBUG_TYPE,
      79             :                     "R600 Clause Merge", false, false)
      80             : 
      81             : char R600ClauseMergePass::ID = 0;
      82             : 
      83             : char &llvm::R600ClauseMergePassID = R600ClauseMergePass::ID;
      84             : 
      85           0 : unsigned R600ClauseMergePass::getCFAluSize(const MachineInstr &MI) const {
      86             :   assert(isCFAlu(MI));
      87             :   return MI
      88         348 :       .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::COUNT))
      89         696 :       .getImm();
      90             : }
      91             : 
      92           0 : bool R600ClauseMergePass::isCFAluEnabled(const MachineInstr &MI) const {
      93             :   assert(isCFAlu(MI));
      94             :   return MI
      95        1646 :       .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::Enabled))
      96        1646 :       .getImm();
      97             : }
      98             : 
      99        3936 : void R600ClauseMergePass::cleanPotentialDisabledCFAlu(
     100             :     MachineInstr &CFAlu) const {
     101        3936 :   int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
     102        3936 :   MachineBasicBlock::iterator I = CFAlu, E = CFAlu.getParent()->end();
     103             :   I++;
     104             :   do {
     105       60499 :     while (I != E && !isCFAlu(*I))
     106             :       I++;
     107        3962 :     if (I == E)
     108             :       return;
     109             :     MachineInstr &MI = *I++;
     110        1646 :     if (isCFAluEnabled(MI))
     111             :       break;
     112          52 :     CFAlu.getOperand(CntIdx).setImm(getCFAluSize(CFAlu) + getCFAluSize(MI));
     113          26 :     MI.eraseFromParent();
     114          26 :   } while (I != E);
     115             : }
     116             : 
     117         322 : bool R600ClauseMergePass::mergeIfPossible(MachineInstr &RootCFAlu,
     118             :                                           const MachineInstr &LatrCFAlu) const {
     119             :   assert(isCFAlu(RootCFAlu) && isCFAlu(LatrCFAlu));
     120         322 :   int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
     121         322 :   unsigned RootInstCount = getCFAluSize(RootCFAlu),
     122         322 :       LaterInstCount = getCFAluSize(LatrCFAlu);
     123         322 :   unsigned CumuledInsts = RootInstCount + LaterInstCount;
     124         322 :   if (CumuledInsts >= TII->getMaxAlusPerClause()) {
     125             :     LLVM_DEBUG(dbgs() << "Excess inst counts\n");
     126             :     return false;
     127             :   }
     128         188 :   if (RootCFAlu.getOpcode() == R600::CF_ALU_PUSH_BEFORE)
     129             :     return false;
     130             :   // Is KCache Bank 0 compatible ?
     131             :   int Mode0Idx =
     132          94 :       TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE0);
     133             :   int KBank0Idx =
     134          94 :       TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK0);
     135             :   int KBank0LineIdx =
     136          94 :       TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR0);
     137          94 :   if (LatrCFAlu.getOperand(Mode0Idx).getImm() &&
     138          94 :       RootCFAlu.getOperand(Mode0Idx).getImm() &&
     139           0 :       (LatrCFAlu.getOperand(KBank0Idx).getImm() !=
     140           0 :            RootCFAlu.getOperand(KBank0Idx).getImm() ||
     141           0 :        LatrCFAlu.getOperand(KBank0LineIdx).getImm() !=
     142           0 :            RootCFAlu.getOperand(KBank0LineIdx).getImm())) {
     143             :     LLVM_DEBUG(dbgs() << "Wrong KC0\n");
     144             :     return false;
     145             :   }
     146             :   // Is KCache Bank 1 compatible ?
     147             :   int Mode1Idx =
     148          94 :       TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE1);
     149             :   int KBank1Idx =
     150          94 :       TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK1);
     151             :   int KBank1LineIdx =
     152          94 :       TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR1);
     153          94 :   if (LatrCFAlu.getOperand(Mode1Idx).getImm() &&
     154          94 :       RootCFAlu.getOperand(Mode1Idx).getImm() &&
     155           0 :       (LatrCFAlu.getOperand(KBank1Idx).getImm() !=
     156           0 :            RootCFAlu.getOperand(KBank1Idx).getImm() ||
     157           0 :        LatrCFAlu.getOperand(KBank1LineIdx).getImm() !=
     158           0 :            RootCFAlu.getOperand(KBank1LineIdx).getImm())) {
     159             :     LLVM_DEBUG(dbgs() << "Wrong KC0\n");
     160             :     return false;
     161             :   }
     162          94 :   if (LatrCFAlu.getOperand(Mode0Idx).getImm()) {
     163           2 :     RootCFAlu.getOperand(Mode0Idx).setImm(
     164             :         LatrCFAlu.getOperand(Mode0Idx).getImm());
     165           4 :     RootCFAlu.getOperand(KBank0Idx).setImm(
     166             :         LatrCFAlu.getOperand(KBank0Idx).getImm());
     167           2 :     RootCFAlu.getOperand(KBank0LineIdx)
     168           2 :         .setImm(LatrCFAlu.getOperand(KBank0LineIdx).getImm());
     169             :   }
     170          94 :   if (LatrCFAlu.getOperand(Mode1Idx).getImm()) {
     171           0 :     RootCFAlu.getOperand(Mode1Idx).setImm(
     172             :         LatrCFAlu.getOperand(Mode1Idx).getImm());
     173           0 :     RootCFAlu.getOperand(KBank1Idx).setImm(
     174             :         LatrCFAlu.getOperand(KBank1Idx).getImm());
     175           0 :     RootCFAlu.getOperand(KBank1LineIdx)
     176           0 :         .setImm(LatrCFAlu.getOperand(KBank1LineIdx).getImm());
     177             :   }
     178         188 :   RootCFAlu.getOperand(CntIdx).setImm(CumuledInsts);
     179         188 :   RootCFAlu.setDesc(TII->get(LatrCFAlu.getOpcode()));
     180          94 :   return true;
     181             : }
     182             : 
     183        2297 : bool R600ClauseMergePass::runOnMachineFunction(MachineFunction &MF) {
     184        2297 :   if (skipFunction(MF.getFunction()))
     185             :     return false;
     186             : 
     187        2297 :   const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>();
     188        2297 :   TII = ST.getInstrInfo();
     189             : 
     190             :   for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
     191        4719 :                                                   BB != BB_E; ++BB) {
     192             :     MachineBasicBlock &MBB = *BB;
     193             :     MachineBasicBlock::iterator I = MBB.begin(),  E = MBB.end();
     194             :     MachineBasicBlock::iterator LatestCFAlu = E;
     195       63024 :     while (I != E) {
     196             :       MachineInstr &MI = *I++;
     197      113485 :       if ((!TII->canBeConsideredALU(MI) && !isCFAlu(MI)) ||
     198      105766 :           TII->mustBeLastInClause(MI.getOpcode()))
     199             :         LatestCFAlu = E;
     200             :       if (!isCFAlu(MI))
     201             :         continue;
     202        3936 :       cleanPotentialDisabledCFAlu(MI);
     203             : 
     204        3936 :       if (LatestCFAlu != E && mergeIfPossible(*LatestCFAlu, MI)) {
     205          94 :         MI.eraseFromParent();
     206             :       } else {
     207             :         assert(MI.getOperand(8).getImm() && "CF ALU instruction disabled");
     208             :         LatestCFAlu = MI;
     209             :       }
     210             :     }
     211             :   }
     212             :   return false;
     213             : }
     214             : 
     215         282 : StringRef R600ClauseMergePass::getPassName() const {
     216         282 :   return "R600 Merge Clause Markers Pass";
     217             : }
     218             : 
     219         282 : llvm::FunctionPass *llvm::createR600ClauseMergePass() {
     220         282 :   return new R600ClauseMergePass();
     221             : }

Generated by: LCOV version 1.13