1 //===-- R600ClauseMergePass - Merge consecutive CF_ALU -------------------===//
3 // 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
7 //===----------------------------------------------------------------------===//
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 //===----------------------------------------------------------------------===//
16 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
17 #include "R600Subtarget.h"
21 #define DEBUG_TYPE "r600mergeclause"
25 static bool isCFAlu(const MachineInstr
&MI
) {
26 switch (MI
.getOpcode()) {
28 case R600::CF_ALU_PUSH_BEFORE
:
35 class R600ClauseMergePass
: public MachineFunctionPass
{
38 const R600InstrInfo
*TII
;
40 unsigned getCFAluSize(const MachineInstr
&MI
) const;
41 bool isCFAluEnabled(const MachineInstr
&MI
) const;
43 /// IfCvt pass can generate "disabled" ALU clause marker that need to be
44 /// removed and their content affected to the previous alu clause.
45 /// This function parse instructions after CFAlu until it find a disabled
46 /// CFAlu and merge the content, or an enabled CFAlu.
47 void cleanPotentialDisabledCFAlu(MachineInstr
&CFAlu
) const;
49 /// Check whether LatrCFAlu can be merged into RootCFAlu and do it if
51 bool mergeIfPossible(MachineInstr
&RootCFAlu
,
52 const MachineInstr
&LatrCFAlu
) const;
57 R600ClauseMergePass() : MachineFunctionPass(ID
) { }
59 bool runOnMachineFunction(MachineFunction
&MF
) override
;
61 StringRef
getPassName() const override
;
64 } // end anonymous namespace
66 INITIALIZE_PASS_BEGIN(R600ClauseMergePass
, DEBUG_TYPE
,
67 "R600 Clause Merge", false, false)
68 INITIALIZE_PASS_END(R600ClauseMergePass
, DEBUG_TYPE
,
69 "R600 Clause Merge", false, false)
71 char R600ClauseMergePass::ID
= 0;
73 char &llvm::R600ClauseMergePassID
= R600ClauseMergePass::ID
;
75 unsigned R600ClauseMergePass::getCFAluSize(const MachineInstr
&MI
) const {
78 .getOperand(TII
->getOperandIdx(MI
.getOpcode(), R600::OpName::COUNT
))
82 bool R600ClauseMergePass::isCFAluEnabled(const MachineInstr
&MI
) const {
85 .getOperand(TII
->getOperandIdx(MI
.getOpcode(), R600::OpName::Enabled
))
89 void R600ClauseMergePass::cleanPotentialDisabledCFAlu(
90 MachineInstr
&CFAlu
) const {
91 int CntIdx
= TII
->getOperandIdx(R600::CF_ALU
, R600::OpName::COUNT
);
92 MachineBasicBlock::iterator I
= CFAlu
, E
= CFAlu
.getParent()->end();
95 while (I
!= E
&& !isCFAlu(*I
))
99 MachineInstr
&MI
= *I
++;
100 if (isCFAluEnabled(MI
))
102 CFAlu
.getOperand(CntIdx
).setImm(getCFAluSize(CFAlu
) + getCFAluSize(MI
));
103 MI
.eraseFromParent();
107 bool R600ClauseMergePass::mergeIfPossible(MachineInstr
&RootCFAlu
,
108 const MachineInstr
&LatrCFAlu
) const {
109 assert(isCFAlu(RootCFAlu
) && isCFAlu(LatrCFAlu
));
110 int CntIdx
= TII
->getOperandIdx(R600::CF_ALU
, R600::OpName::COUNT
);
111 unsigned RootInstCount
= getCFAluSize(RootCFAlu
),
112 LaterInstCount
= getCFAluSize(LatrCFAlu
);
113 unsigned CumuledInsts
= RootInstCount
+ LaterInstCount
;
114 if (CumuledInsts
>= TII
->getMaxAlusPerClause()) {
115 LLVM_DEBUG(dbgs() << "Excess inst counts\n");
118 if (RootCFAlu
.getOpcode() == R600::CF_ALU_PUSH_BEFORE
)
120 // Is KCache Bank 0 compatible ?
122 TII
->getOperandIdx(R600::CF_ALU
, R600::OpName::KCACHE_MODE0
);
124 TII
->getOperandIdx(R600::CF_ALU
, R600::OpName::KCACHE_BANK0
);
126 TII
->getOperandIdx(R600::CF_ALU
, R600::OpName::KCACHE_ADDR0
);
127 if (LatrCFAlu
.getOperand(Mode0Idx
).getImm() &&
128 RootCFAlu
.getOperand(Mode0Idx
).getImm() &&
129 (LatrCFAlu
.getOperand(KBank0Idx
).getImm() !=
130 RootCFAlu
.getOperand(KBank0Idx
).getImm() ||
131 LatrCFAlu
.getOperand(KBank0LineIdx
).getImm() !=
132 RootCFAlu
.getOperand(KBank0LineIdx
).getImm())) {
133 LLVM_DEBUG(dbgs() << "Wrong KC0\n");
136 // Is KCache Bank 1 compatible ?
138 TII
->getOperandIdx(R600::CF_ALU
, R600::OpName::KCACHE_MODE1
);
140 TII
->getOperandIdx(R600::CF_ALU
, R600::OpName::KCACHE_BANK1
);
142 TII
->getOperandIdx(R600::CF_ALU
, R600::OpName::KCACHE_ADDR1
);
143 if (LatrCFAlu
.getOperand(Mode1Idx
).getImm() &&
144 RootCFAlu
.getOperand(Mode1Idx
).getImm() &&
145 (LatrCFAlu
.getOperand(KBank1Idx
).getImm() !=
146 RootCFAlu
.getOperand(KBank1Idx
).getImm() ||
147 LatrCFAlu
.getOperand(KBank1LineIdx
).getImm() !=
148 RootCFAlu
.getOperand(KBank1LineIdx
).getImm())) {
149 LLVM_DEBUG(dbgs() << "Wrong KC0\n");
152 if (LatrCFAlu
.getOperand(Mode0Idx
).getImm()) {
153 RootCFAlu
.getOperand(Mode0Idx
).setImm(
154 LatrCFAlu
.getOperand(Mode0Idx
).getImm());
155 RootCFAlu
.getOperand(KBank0Idx
).setImm(
156 LatrCFAlu
.getOperand(KBank0Idx
).getImm());
157 RootCFAlu
.getOperand(KBank0LineIdx
)
158 .setImm(LatrCFAlu
.getOperand(KBank0LineIdx
).getImm());
160 if (LatrCFAlu
.getOperand(Mode1Idx
).getImm()) {
161 RootCFAlu
.getOperand(Mode1Idx
).setImm(
162 LatrCFAlu
.getOperand(Mode1Idx
).getImm());
163 RootCFAlu
.getOperand(KBank1Idx
).setImm(
164 LatrCFAlu
.getOperand(KBank1Idx
).getImm());
165 RootCFAlu
.getOperand(KBank1LineIdx
)
166 .setImm(LatrCFAlu
.getOperand(KBank1LineIdx
).getImm());
168 RootCFAlu
.getOperand(CntIdx
).setImm(CumuledInsts
);
169 RootCFAlu
.setDesc(TII
->get(LatrCFAlu
.getOpcode()));
173 bool R600ClauseMergePass::runOnMachineFunction(MachineFunction
&MF
) {
174 if (skipFunction(MF
.getFunction()))
177 const R600Subtarget
&ST
= MF
.getSubtarget
<R600Subtarget
>();
178 TII
= ST
.getInstrInfo();
180 for (MachineFunction::iterator BB
= MF
.begin(), BB_E
= MF
.end();
182 MachineBasicBlock
&MBB
= *BB
;
183 MachineBasicBlock::iterator I
= MBB
.begin(), E
= MBB
.end();
184 MachineBasicBlock::iterator LatestCFAlu
= E
;
186 MachineInstr
&MI
= *I
++;
187 if ((!TII
->canBeConsideredALU(MI
) && !isCFAlu(MI
)) ||
188 TII
->mustBeLastInClause(MI
.getOpcode()))
192 cleanPotentialDisabledCFAlu(MI
);
194 if (LatestCFAlu
!= E
&& mergeIfPossible(*LatestCFAlu
, MI
)) {
195 MI
.eraseFromParent();
197 assert(MI
.getOperand(8).getImm() && "CF ALU instruction disabled");
205 StringRef
R600ClauseMergePass::getPassName() const {
206 return "R600 Merge Clause Markers Pass";
209 llvm::FunctionPass
*llvm::createR600ClauseMergePass() {
210 return new R600ClauseMergePass();