blob: 290a960ae9017ea04a061da2a86ca5efa5037369 [file] [log] [blame]
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +00001//===-- R600ClauseMergePass - Merge consecutive CF_ALU -------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +00006//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// R600EmitClauseMarker pass emits CFAlu instruction in a conservative maneer.
11/// This pass is merging consecutive CFAlus where applicable.
12/// It needs to be called after IfCvt for best results.
13//===----------------------------------------------------------------------===//
14
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000015#include "AMDGPU.h"
Benjamin Kramer799003b2015-03-23 19:32:43 +000016#include "AMDGPUSubtarget.h"
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000017#include "R600Defines.h"
18#include "R600InstrInfo.h"
19#include "R600MachineFunctionInfo.h"
20#include "R600RegisterInfo.h"
Tom Stellard44b30b42018-05-22 02:03:23 +000021#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000022#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
28using namespace llvm;
29
Chandler Carruth84e68b22014-04-22 02:41:26 +000030#define DEBUG_TYPE "r600mergeclause"
31
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000032namespace {
33
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +000034static bool isCFAlu(const MachineInstr &MI) {
35 switch (MI.getOpcode()) {
Tom Stellardc5a154d2018-06-28 23:47:12 +000036 case R600::CF_ALU:
37 case R600::CF_ALU_PUSH_BEFORE:
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000038 return true;
39 default:
40 return false;
41 }
42}
43
44class R600ClauseMergePass : public MachineFunctionPass {
45
46private:
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000047 const R600InstrInfo *TII;
48
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +000049 unsigned getCFAluSize(const MachineInstr &MI) const;
50 bool isCFAluEnabled(const MachineInstr &MI) const;
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000051
52 /// IfCvt pass can generate "disabled" ALU clause marker that need to be
53 /// removed and their content affected to the previous alu clause.
Alp Tokercb402912014-01-24 17:20:08 +000054 /// This function parse instructions after CFAlu until it find a disabled
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000055 /// CFAlu and merge the content, or an enabled CFAlu.
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +000056 void cleanPotentialDisabledCFAlu(MachineInstr &CFAlu) const;
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000057
58 /// Check whether LatrCFAlu can be merged into RootCFAlu and do it if
59 /// it is the case.
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +000060 bool mergeIfPossible(MachineInstr &RootCFAlu,
61 const MachineInstr &LatrCFAlu) const;
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000062
63public:
Tom Stellarda2f57be2017-08-02 22:19:45 +000064 static char ID;
65
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +000066 R600ClauseMergePass() : MachineFunctionPass(ID) { }
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000067
Craig Topper5656db42014-04-29 07:57:24 +000068 bool runOnMachineFunction(MachineFunction &MF) override;
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000069
Mehdi Amini117296c2016-10-01 02:56:57 +000070 StringRef getPassName() const override;
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000071};
72
Tom Stellarda2f57be2017-08-02 22:19:45 +000073} // end anonymous namespace
74
75INITIALIZE_PASS_BEGIN(R600ClauseMergePass, DEBUG_TYPE,
76 "R600 Clause Merge", false, false)
77INITIALIZE_PASS_END(R600ClauseMergePass, DEBUG_TYPE,
78 "R600 Clause Merge", false, false)
79
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000080char R600ClauseMergePass::ID = 0;
81
Tom Stellarda2f57be2017-08-02 22:19:45 +000082char &llvm::R600ClauseMergePassID = R600ClauseMergePass::ID;
83
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +000084unsigned R600ClauseMergePass::getCFAluSize(const MachineInstr &MI) const {
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000085 assert(isCFAlu(MI));
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +000086 return MI
Tom Stellardc5a154d2018-06-28 23:47:12 +000087 .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::COUNT))
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +000088 .getImm();
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000089}
90
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +000091bool R600ClauseMergePass::isCFAluEnabled(const MachineInstr &MI) const {
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000092 assert(isCFAlu(MI));
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +000093 return MI
Tom Stellardc5a154d2018-06-28 23:47:12 +000094 .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::Enabled))
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +000095 .getImm();
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +000096}
97
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +000098void R600ClauseMergePass::cleanPotentialDisabledCFAlu(
99 MachineInstr &CFAlu) const {
Tom Stellardc5a154d2018-06-28 23:47:12 +0000100 int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000101 MachineBasicBlock::iterator I = CFAlu, E = CFAlu.getParent()->end();
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000102 I++;
103 do {
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000104 while (I != E && !isCFAlu(*I))
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000105 I++;
106 if (I == E)
107 return;
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000108 MachineInstr &MI = *I++;
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000109 if (isCFAluEnabled(MI))
110 break;
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000111 CFAlu.getOperand(CntIdx).setImm(getCFAluSize(CFAlu) + getCFAluSize(MI));
112 MI.eraseFromParent();
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000113 } while (I != E);
114}
115
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000116bool R600ClauseMergePass::mergeIfPossible(MachineInstr &RootCFAlu,
117 const MachineInstr &LatrCFAlu) const {
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000118 assert(isCFAlu(RootCFAlu) && isCFAlu(LatrCFAlu));
Tom Stellardc5a154d2018-06-28 23:47:12 +0000119 int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000120 unsigned RootInstCount = getCFAluSize(RootCFAlu),
121 LaterInstCount = getCFAluSize(LatrCFAlu);
122 unsigned CumuledInsts = RootInstCount + LaterInstCount;
123 if (CumuledInsts >= TII->getMaxAlusPerClause()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000124 LLVM_DEBUG(dbgs() << "Excess inst counts\n");
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000125 return false;
126 }
Tom Stellardc5a154d2018-06-28 23:47:12 +0000127 if (RootCFAlu.getOpcode() == R600::CF_ALU_PUSH_BEFORE)
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000128 return false;
129 // Is KCache Bank 0 compatible ?
130 int Mode0Idx =
Tom Stellardc5a154d2018-06-28 23:47:12 +0000131 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE0);
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000132 int KBank0Idx =
Tom Stellardc5a154d2018-06-28 23:47:12 +0000133 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK0);
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000134 int KBank0LineIdx =
Tom Stellardc5a154d2018-06-28 23:47:12 +0000135 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR0);
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000136 if (LatrCFAlu.getOperand(Mode0Idx).getImm() &&
137 RootCFAlu.getOperand(Mode0Idx).getImm() &&
138 (LatrCFAlu.getOperand(KBank0Idx).getImm() !=
139 RootCFAlu.getOperand(KBank0Idx).getImm() ||
140 LatrCFAlu.getOperand(KBank0LineIdx).getImm() !=
141 RootCFAlu.getOperand(KBank0LineIdx).getImm())) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000142 LLVM_DEBUG(dbgs() << "Wrong KC0\n");
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000143 return false;
144 }
145 // Is KCache Bank 1 compatible ?
146 int Mode1Idx =
Tom Stellardc5a154d2018-06-28 23:47:12 +0000147 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE1);
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000148 int KBank1Idx =
Tom Stellardc5a154d2018-06-28 23:47:12 +0000149 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK1);
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000150 int KBank1LineIdx =
Tom Stellardc5a154d2018-06-28 23:47:12 +0000151 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR1);
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000152 if (LatrCFAlu.getOperand(Mode1Idx).getImm() &&
153 RootCFAlu.getOperand(Mode1Idx).getImm() &&
154 (LatrCFAlu.getOperand(KBank1Idx).getImm() !=
155 RootCFAlu.getOperand(KBank1Idx).getImm() ||
156 LatrCFAlu.getOperand(KBank1LineIdx).getImm() !=
157 RootCFAlu.getOperand(KBank1LineIdx).getImm())) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000158 LLVM_DEBUG(dbgs() << "Wrong KC0\n");
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000159 return false;
160 }
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000161 if (LatrCFAlu.getOperand(Mode0Idx).getImm()) {
162 RootCFAlu.getOperand(Mode0Idx).setImm(
163 LatrCFAlu.getOperand(Mode0Idx).getImm());
164 RootCFAlu.getOperand(KBank0Idx).setImm(
165 LatrCFAlu.getOperand(KBank0Idx).getImm());
166 RootCFAlu.getOperand(KBank0LineIdx)
167 .setImm(LatrCFAlu.getOperand(KBank0LineIdx).getImm());
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000168 }
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000169 if (LatrCFAlu.getOperand(Mode1Idx).getImm()) {
170 RootCFAlu.getOperand(Mode1Idx).setImm(
171 LatrCFAlu.getOperand(Mode1Idx).getImm());
172 RootCFAlu.getOperand(KBank1Idx).setImm(
173 LatrCFAlu.getOperand(KBank1Idx).getImm());
174 RootCFAlu.getOperand(KBank1LineIdx)
175 .setImm(LatrCFAlu.getOperand(KBank1LineIdx).getImm());
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000176 }
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000177 RootCFAlu.getOperand(CntIdx).setImm(CumuledInsts);
178 RootCFAlu.setDesc(TII->get(LatrCFAlu.getOpcode()));
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000179 return true;
180}
181
182bool R600ClauseMergePass::runOnMachineFunction(MachineFunction &MF) {
Matthias Braunf1caa282017-12-15 22:22:58 +0000183 if (skipFunction(MF.getFunction()))
Andrew Kaylor7de74af2016-04-25 22:23:44 +0000184 return false;
185
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000186 const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>();
187 TII = ST.getInstrInfo();
188
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000189 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
190 BB != BB_E; ++BB) {
191 MachineBasicBlock &MBB = *BB;
192 MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
193 MachineBasicBlock::iterator LatestCFAlu = E;
194 while (I != E) {
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000195 MachineInstr &MI = *I++;
196 if ((!TII->canBeConsideredALU(MI) && !isCFAlu(MI)) ||
197 TII->mustBeLastInClause(MI.getOpcode()))
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000198 LatestCFAlu = E;
199 if (!isCFAlu(MI))
200 continue;
201 cleanPotentialDisabledCFAlu(MI);
202
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000203 if (LatestCFAlu != E && mergeIfPossible(*LatestCFAlu, MI)) {
204 MI.eraseFromParent();
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000205 } else {
Duncan P. N. Exon Smith4d295112016-07-08 19:16:05 +0000206 assert(MI.getOperand(8).getImm() && "CF ALU instruction disabled");
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000207 LatestCFAlu = MI;
208 }
209 }
210 }
211 return false;
212}
213
Mehdi Amini117296c2016-10-01 02:56:57 +0000214StringRef R600ClauseMergePass::getPassName() const {
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000215 return "R600 Merge Clause Markers Pass";
216}
217
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000218llvm::FunctionPass *llvm::createR600ClauseMergePass() {
219 return new R600ClauseMergePass();
Vincent Lejeunea4da6fb2013-10-01 19:32:58 +0000220}