145bb48eaSTom Stellard //===-- R600ClauseMergePass - Merge consecutive CF_ALU -------------------===// 245bb48eaSTom Stellard // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 645bb48eaSTom Stellard // 745bb48eaSTom Stellard //===----------------------------------------------------------------------===// 845bb48eaSTom Stellard // 945bb48eaSTom Stellard /// \file 1045bb48eaSTom Stellard /// R600EmitClauseMarker pass emits CFAlu instruction in a conservative maneer. 1145bb48eaSTom Stellard /// This pass is merging consecutive CFAlus where applicable. 1245bb48eaSTom Stellard /// It needs to be called after IfCvt for best results. 1345bb48eaSTom Stellard //===----------------------------------------------------------------------===// 1445bb48eaSTom Stellard 15*48958d02SDaniil Fukalov #include "MCTargetDesc/R600MCTargetDesc.h" 16*48958d02SDaniil Fukalov #include "R600.h" 17560d7e04Sdfukalov #include "R600Subtarget.h" 1845bb48eaSTom Stellard 1945bb48eaSTom Stellard using namespace llvm; 2045bb48eaSTom Stellard 2145bb48eaSTom Stellard #define DEBUG_TYPE "r600mergeclause" 2245bb48eaSTom Stellard 2345bb48eaSTom Stellard namespace { 2445bb48eaSTom Stellard 254d295118SDuncan P. N. Exon Smith static bool isCFAlu(const MachineInstr &MI) { 264d295118SDuncan P. N. Exon Smith switch (MI.getOpcode()) { 27c5a154dbSTom Stellard case R600::CF_ALU: 28c5a154dbSTom Stellard case R600::CF_ALU_PUSH_BEFORE: 2945bb48eaSTom Stellard return true; 3045bb48eaSTom Stellard default: 3145bb48eaSTom Stellard return false; 3245bb48eaSTom Stellard } 3345bb48eaSTom Stellard } 3445bb48eaSTom Stellard 3545bb48eaSTom Stellard class R600ClauseMergePass : public MachineFunctionPass { 3645bb48eaSTom Stellard 3745bb48eaSTom Stellard private: 3845bb48eaSTom Stellard const R600InstrInfo *TII; 3945bb48eaSTom Stellard 404d295118SDuncan P. N. Exon Smith unsigned getCFAluSize(const MachineInstr &MI) const; 414d295118SDuncan P. N. Exon Smith bool isCFAluEnabled(const MachineInstr &MI) const; 4245bb48eaSTom Stellard 4345bb48eaSTom Stellard /// IfCvt pass can generate "disabled" ALU clause marker that need to be 4445bb48eaSTom Stellard /// removed and their content affected to the previous alu clause. 4545bb48eaSTom Stellard /// This function parse instructions after CFAlu until it find a disabled 4645bb48eaSTom Stellard /// CFAlu and merge the content, or an enabled CFAlu. 474d295118SDuncan P. N. Exon Smith void cleanPotentialDisabledCFAlu(MachineInstr &CFAlu) const; 4845bb48eaSTom Stellard 4945bb48eaSTom Stellard /// Check whether LatrCFAlu can be merged into RootCFAlu and do it if 5045bb48eaSTom Stellard /// it is the case. 514d295118SDuncan P. N. Exon Smith bool mergeIfPossible(MachineInstr &RootCFAlu, 524d295118SDuncan P. N. Exon Smith const MachineInstr &LatrCFAlu) const; 5345bb48eaSTom Stellard 5445bb48eaSTom Stellard public: 55a2f57be2STom Stellard static char ID; 56a2f57be2STom Stellard 578b61764cSFrancis Visoiu Mistrih R600ClauseMergePass() : MachineFunctionPass(ID) { } 5845bb48eaSTom Stellard 5945bb48eaSTom Stellard bool runOnMachineFunction(MachineFunction &MF) override; 6045bb48eaSTom Stellard 61117296c0SMehdi Amini StringRef getPassName() const override; 6245bb48eaSTom Stellard }; 6345bb48eaSTom Stellard 64a2f57be2STom Stellard } // end anonymous namespace 65a2f57be2STom Stellard 66a2f57be2STom Stellard INITIALIZE_PASS_BEGIN(R600ClauseMergePass, DEBUG_TYPE, 67a2f57be2STom Stellard "R600 Clause Merge", false, false) 68a2f57be2STom Stellard INITIALIZE_PASS_END(R600ClauseMergePass, DEBUG_TYPE, 69a2f57be2STom Stellard "R600 Clause Merge", false, false) 70a2f57be2STom Stellard 7145bb48eaSTom Stellard char R600ClauseMergePass::ID = 0; 7245bb48eaSTom Stellard 73a2f57be2STom Stellard char &llvm::R600ClauseMergePassID = R600ClauseMergePass::ID; 74a2f57be2STom Stellard 754d295118SDuncan P. N. Exon Smith unsigned R600ClauseMergePass::getCFAluSize(const MachineInstr &MI) const { 7645bb48eaSTom Stellard assert(isCFAlu(MI)); 774d295118SDuncan P. N. Exon Smith return MI 78c5a154dbSTom Stellard .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::COUNT)) 794d295118SDuncan P. N. Exon Smith .getImm(); 8045bb48eaSTom Stellard } 8145bb48eaSTom Stellard 824d295118SDuncan P. N. Exon Smith bool R600ClauseMergePass::isCFAluEnabled(const MachineInstr &MI) const { 8345bb48eaSTom Stellard assert(isCFAlu(MI)); 844d295118SDuncan P. N. Exon Smith return MI 85c5a154dbSTom Stellard .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::Enabled)) 864d295118SDuncan P. N. Exon Smith .getImm(); 8745bb48eaSTom Stellard } 8845bb48eaSTom Stellard 894d295118SDuncan P. N. Exon Smith void R600ClauseMergePass::cleanPotentialDisabledCFAlu( 904d295118SDuncan P. N. Exon Smith MachineInstr &CFAlu) const { 91c5a154dbSTom Stellard int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT); 924d295118SDuncan P. N. Exon Smith MachineBasicBlock::iterator I = CFAlu, E = CFAlu.getParent()->end(); 9345bb48eaSTom Stellard I++; 9445bb48eaSTom Stellard do { 954d295118SDuncan P. N. Exon Smith while (I != E && !isCFAlu(*I)) 9645bb48eaSTom Stellard I++; 9745bb48eaSTom Stellard if (I == E) 9845bb48eaSTom Stellard return; 994d295118SDuncan P. N. Exon Smith MachineInstr &MI = *I++; 10045bb48eaSTom Stellard if (isCFAluEnabled(MI)) 10145bb48eaSTom Stellard break; 1024d295118SDuncan P. N. Exon Smith CFAlu.getOperand(CntIdx).setImm(getCFAluSize(CFAlu) + getCFAluSize(MI)); 1034d295118SDuncan P. N. Exon Smith MI.eraseFromParent(); 10445bb48eaSTom Stellard } while (I != E); 10545bb48eaSTom Stellard } 10645bb48eaSTom Stellard 1074d295118SDuncan P. N. Exon Smith bool R600ClauseMergePass::mergeIfPossible(MachineInstr &RootCFAlu, 1084d295118SDuncan P. N. Exon Smith const MachineInstr &LatrCFAlu) const { 10945bb48eaSTom Stellard assert(isCFAlu(RootCFAlu) && isCFAlu(LatrCFAlu)); 110c5a154dbSTom Stellard int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT); 11145bb48eaSTom Stellard unsigned RootInstCount = getCFAluSize(RootCFAlu), 11245bb48eaSTom Stellard LaterInstCount = getCFAluSize(LatrCFAlu); 11345bb48eaSTom Stellard unsigned CumuledInsts = RootInstCount + LaterInstCount; 11445bb48eaSTom Stellard if (CumuledInsts >= TII->getMaxAlusPerClause()) { 115d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Excess inst counts\n"); 11645bb48eaSTom Stellard return false; 11745bb48eaSTom Stellard } 118c5a154dbSTom Stellard if (RootCFAlu.getOpcode() == R600::CF_ALU_PUSH_BEFORE) 11945bb48eaSTom Stellard return false; 12045bb48eaSTom Stellard // Is KCache Bank 0 compatible ? 12145bb48eaSTom Stellard int Mode0Idx = 122c5a154dbSTom Stellard TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE0); 12345bb48eaSTom Stellard int KBank0Idx = 124c5a154dbSTom Stellard TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK0); 12545bb48eaSTom Stellard int KBank0LineIdx = 126c5a154dbSTom Stellard TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR0); 1274d295118SDuncan P. N. Exon Smith if (LatrCFAlu.getOperand(Mode0Idx).getImm() && 1284d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(Mode0Idx).getImm() && 1294d295118SDuncan P. N. Exon Smith (LatrCFAlu.getOperand(KBank0Idx).getImm() != 1304d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(KBank0Idx).getImm() || 1314d295118SDuncan P. N. Exon Smith LatrCFAlu.getOperand(KBank0LineIdx).getImm() != 1324d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(KBank0LineIdx).getImm())) { 133d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Wrong KC0\n"); 13445bb48eaSTom Stellard return false; 13545bb48eaSTom Stellard } 13645bb48eaSTom Stellard // Is KCache Bank 1 compatible ? 13745bb48eaSTom Stellard int Mode1Idx = 138c5a154dbSTom Stellard TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE1); 13945bb48eaSTom Stellard int KBank1Idx = 140c5a154dbSTom Stellard TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK1); 14145bb48eaSTom Stellard int KBank1LineIdx = 142c5a154dbSTom Stellard TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR1); 1434d295118SDuncan P. N. Exon Smith if (LatrCFAlu.getOperand(Mode1Idx).getImm() && 1444d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(Mode1Idx).getImm() && 1454d295118SDuncan P. N. Exon Smith (LatrCFAlu.getOperand(KBank1Idx).getImm() != 1464d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(KBank1Idx).getImm() || 1474d295118SDuncan P. N. Exon Smith LatrCFAlu.getOperand(KBank1LineIdx).getImm() != 1484d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(KBank1LineIdx).getImm())) { 149d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Wrong KC0\n"); 15045bb48eaSTom Stellard return false; 15145bb48eaSTom Stellard } 1524d295118SDuncan P. N. Exon Smith if (LatrCFAlu.getOperand(Mode0Idx).getImm()) { 1534d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(Mode0Idx).setImm( 1544d295118SDuncan P. N. Exon Smith LatrCFAlu.getOperand(Mode0Idx).getImm()); 1554d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(KBank0Idx).setImm( 1564d295118SDuncan P. N. Exon Smith LatrCFAlu.getOperand(KBank0Idx).getImm()); 1574d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(KBank0LineIdx) 1584d295118SDuncan P. N. Exon Smith .setImm(LatrCFAlu.getOperand(KBank0LineIdx).getImm()); 15945bb48eaSTom Stellard } 1604d295118SDuncan P. N. Exon Smith if (LatrCFAlu.getOperand(Mode1Idx).getImm()) { 1614d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(Mode1Idx).setImm( 1624d295118SDuncan P. N. Exon Smith LatrCFAlu.getOperand(Mode1Idx).getImm()); 1634d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(KBank1Idx).setImm( 1644d295118SDuncan P. N. Exon Smith LatrCFAlu.getOperand(KBank1Idx).getImm()); 1654d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(KBank1LineIdx) 1664d295118SDuncan P. N. Exon Smith .setImm(LatrCFAlu.getOperand(KBank1LineIdx).getImm()); 16745bb48eaSTom Stellard } 1684d295118SDuncan P. N. Exon Smith RootCFAlu.getOperand(CntIdx).setImm(CumuledInsts); 1694d295118SDuncan P. N. Exon Smith RootCFAlu.setDesc(TII->get(LatrCFAlu.getOpcode())); 17045bb48eaSTom Stellard return true; 17145bb48eaSTom Stellard } 17245bb48eaSTom Stellard 17345bb48eaSTom Stellard bool R600ClauseMergePass::runOnMachineFunction(MachineFunction &MF) { 174f1caa283SMatthias Braun if (skipFunction(MF.getFunction())) 1757de74af9SAndrew Kaylor return false; 1767de74af9SAndrew Kaylor 17743e92fe3SMatt Arsenault const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>(); 17843e92fe3SMatt Arsenault TII = ST.getInstrInfo(); 17943e92fe3SMatt Arsenault 18045bb48eaSTom Stellard for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end(); 18145bb48eaSTom Stellard BB != BB_E; ++BB) { 18245bb48eaSTom Stellard MachineBasicBlock &MBB = *BB; 18345bb48eaSTom Stellard MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); 18445bb48eaSTom Stellard MachineBasicBlock::iterator LatestCFAlu = E; 18545bb48eaSTom Stellard while (I != E) { 1864d295118SDuncan P. N. Exon Smith MachineInstr &MI = *I++; 1874d295118SDuncan P. N. Exon Smith if ((!TII->canBeConsideredALU(MI) && !isCFAlu(MI)) || 1884d295118SDuncan P. N. Exon Smith TII->mustBeLastInClause(MI.getOpcode())) 18945bb48eaSTom Stellard LatestCFAlu = E; 19045bb48eaSTom Stellard if (!isCFAlu(MI)) 19145bb48eaSTom Stellard continue; 19245bb48eaSTom Stellard cleanPotentialDisabledCFAlu(MI); 19345bb48eaSTom Stellard 1944d295118SDuncan P. N. Exon Smith if (LatestCFAlu != E && mergeIfPossible(*LatestCFAlu, MI)) { 1954d295118SDuncan P. N. Exon Smith MI.eraseFromParent(); 19645bb48eaSTom Stellard } else { 1974d295118SDuncan P. N. Exon Smith assert(MI.getOperand(8).getImm() && "CF ALU instruction disabled"); 19845bb48eaSTom Stellard LatestCFAlu = MI; 19945bb48eaSTom Stellard } 20045bb48eaSTom Stellard } 20145bb48eaSTom Stellard } 20245bb48eaSTom Stellard return false; 20345bb48eaSTom Stellard } 20445bb48eaSTom Stellard 205117296c0SMehdi Amini StringRef R600ClauseMergePass::getPassName() const { 20645bb48eaSTom Stellard return "R600 Merge Clause Markers Pass"; 20745bb48eaSTom Stellard } 20845bb48eaSTom Stellard 2098b61764cSFrancis Visoiu Mistrih llvm::FunctionPass *llvm::createR600ClauseMergePass() { 2108b61764cSFrancis Visoiu Mistrih return new R600ClauseMergePass(); 21145bb48eaSTom Stellard } 212