Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / lib / Target / AMDGPU / R600ClauseMergePass.cpp
blob2b85df8ac6cf608d7aea6f28634a4d6026c97e41
1 //===-- R600ClauseMergePass - Merge consecutive CF_ALU -------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// R600EmitClauseMarker pass emits CFAlu instruction in a conservative manner.
11 /// This pass is merging consecutive CFAlus where applicable.
12 /// It needs to be called after IfCvt for best results.
13 //===----------------------------------------------------------------------===//
15 #include "MCTargetDesc/R600MCTargetDesc.h"
16 #include "R600.h"
17 #include "R600Subtarget.h"
18 #include "llvm/CodeGen/MachineFunctionPass.h"
20 using namespace llvm;
22 #define DEBUG_TYPE "r600mergeclause"
24 namespace {
26 static bool isCFAlu(const MachineInstr &MI) {
27 switch (MI.getOpcode()) {
28 case R600::CF_ALU:
29 case R600::CF_ALU_PUSH_BEFORE:
30 return true;
31 default:
32 return false;
36 class R600ClauseMergePass : public MachineFunctionPass {
38 private:
39 const R600InstrInfo *TII;
41 unsigned getCFAluSize(const MachineInstr &MI) const;
42 bool isCFAluEnabled(const MachineInstr &MI) const;
44 /// IfCvt pass can generate "disabled" ALU clause marker that need to be
45 /// removed and their content affected to the previous alu clause.
46 /// This function parse instructions after CFAlu until it find a disabled
47 /// CFAlu and merge the content, or an enabled CFAlu.
48 void cleanPotentialDisabledCFAlu(MachineInstr &CFAlu) const;
50 /// Check whether LatrCFAlu can be merged into RootCFAlu and do it if
51 /// it is the case.
52 bool mergeIfPossible(MachineInstr &RootCFAlu,
53 const MachineInstr &LatrCFAlu) const;
55 public:
56 static char ID;
58 R600ClauseMergePass() : MachineFunctionPass(ID) { }
60 bool runOnMachineFunction(MachineFunction &MF) override;
62 StringRef getPassName() const override;
65 } // end anonymous namespace
67 INITIALIZE_PASS_BEGIN(R600ClauseMergePass, DEBUG_TYPE,
68 "R600 Clause Merge", false, false)
69 INITIALIZE_PASS_END(R600ClauseMergePass, DEBUG_TYPE,
70 "R600 Clause Merge", false, false)
72 char R600ClauseMergePass::ID = 0;
74 char &llvm::R600ClauseMergePassID = R600ClauseMergePass::ID;
76 unsigned R600ClauseMergePass::getCFAluSize(const MachineInstr &MI) const {
77 assert(isCFAlu(MI));
78 return MI
79 .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::COUNT))
80 .getImm();
83 bool R600ClauseMergePass::isCFAluEnabled(const MachineInstr &MI) const {
84 assert(isCFAlu(MI));
85 return MI
86 .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::Enabled))
87 .getImm();
90 void R600ClauseMergePass::cleanPotentialDisabledCFAlu(
91 MachineInstr &CFAlu) const {
92 int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
93 MachineBasicBlock::iterator I = CFAlu, E = CFAlu.getParent()->end();
94 I++;
95 do {
96 while (I != E && !isCFAlu(*I))
97 I++;
98 if (I == E)
99 return;
100 MachineInstr &MI = *I++;
101 if (isCFAluEnabled(MI))
102 break;
103 CFAlu.getOperand(CntIdx).setImm(getCFAluSize(CFAlu) + getCFAluSize(MI));
104 MI.eraseFromParent();
105 } while (I != E);
108 bool R600ClauseMergePass::mergeIfPossible(MachineInstr &RootCFAlu,
109 const MachineInstr &LatrCFAlu) const {
110 assert(isCFAlu(RootCFAlu) && isCFAlu(LatrCFAlu));
111 int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
112 unsigned RootInstCount = getCFAluSize(RootCFAlu),
113 LaterInstCount = getCFAluSize(LatrCFAlu);
114 unsigned CumuledInsts = RootInstCount + LaterInstCount;
115 if (CumuledInsts >= TII->getMaxAlusPerClause()) {
116 LLVM_DEBUG(dbgs() << "Excess inst counts\n");
117 return false;
119 if (RootCFAlu.getOpcode() == R600::CF_ALU_PUSH_BEFORE)
120 return false;
121 // Is KCache Bank 0 compatible ?
122 int Mode0Idx =
123 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE0);
124 int KBank0Idx =
125 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK0);
126 int KBank0LineIdx =
127 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR0);
128 if (LatrCFAlu.getOperand(Mode0Idx).getImm() &&
129 RootCFAlu.getOperand(Mode0Idx).getImm() &&
130 (LatrCFAlu.getOperand(KBank0Idx).getImm() !=
131 RootCFAlu.getOperand(KBank0Idx).getImm() ||
132 LatrCFAlu.getOperand(KBank0LineIdx).getImm() !=
133 RootCFAlu.getOperand(KBank0LineIdx).getImm())) {
134 LLVM_DEBUG(dbgs() << "Wrong KC0\n");
135 return false;
137 // Is KCache Bank 1 compatible ?
138 int Mode1Idx =
139 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE1);
140 int KBank1Idx =
141 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK1);
142 int KBank1LineIdx =
143 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR1);
144 if (LatrCFAlu.getOperand(Mode1Idx).getImm() &&
145 RootCFAlu.getOperand(Mode1Idx).getImm() &&
146 (LatrCFAlu.getOperand(KBank1Idx).getImm() !=
147 RootCFAlu.getOperand(KBank1Idx).getImm() ||
148 LatrCFAlu.getOperand(KBank1LineIdx).getImm() !=
149 RootCFAlu.getOperand(KBank1LineIdx).getImm())) {
150 LLVM_DEBUG(dbgs() << "Wrong KC0\n");
151 return false;
153 if (LatrCFAlu.getOperand(Mode0Idx).getImm()) {
154 RootCFAlu.getOperand(Mode0Idx).setImm(
155 LatrCFAlu.getOperand(Mode0Idx).getImm());
156 RootCFAlu.getOperand(KBank0Idx).setImm(
157 LatrCFAlu.getOperand(KBank0Idx).getImm());
158 RootCFAlu.getOperand(KBank0LineIdx)
159 .setImm(LatrCFAlu.getOperand(KBank0LineIdx).getImm());
161 if (LatrCFAlu.getOperand(Mode1Idx).getImm()) {
162 RootCFAlu.getOperand(Mode1Idx).setImm(
163 LatrCFAlu.getOperand(Mode1Idx).getImm());
164 RootCFAlu.getOperand(KBank1Idx).setImm(
165 LatrCFAlu.getOperand(KBank1Idx).getImm());
166 RootCFAlu.getOperand(KBank1LineIdx)
167 .setImm(LatrCFAlu.getOperand(KBank1LineIdx).getImm());
169 RootCFAlu.getOperand(CntIdx).setImm(CumuledInsts);
170 RootCFAlu.setDesc(TII->get(LatrCFAlu.getOpcode()));
171 return true;
174 bool R600ClauseMergePass::runOnMachineFunction(MachineFunction &MF) {
175 if (skipFunction(MF.getFunction()))
176 return false;
178 const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>();
179 TII = ST.getInstrInfo();
181 for (MachineBasicBlock &MBB : MF) {
182 MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
183 MachineBasicBlock::iterator LatestCFAlu = E;
184 while (I != E) {
185 MachineInstr &MI = *I++;
186 if ((!TII->canBeConsideredALU(MI) && !isCFAlu(MI)) ||
187 TII->mustBeLastInClause(MI.getOpcode()))
188 LatestCFAlu = E;
189 if (!isCFAlu(MI))
190 continue;
191 cleanPotentialDisabledCFAlu(MI);
193 if (LatestCFAlu != E && mergeIfPossible(*LatestCFAlu, MI)) {
194 MI.eraseFromParent();
195 } else {
196 assert(MI.getOperand(8).getImm() && "CF ALU instruction disabled");
197 LatestCFAlu = MI;
201 return false;
204 StringRef R600ClauseMergePass::getPassName() const {
205 return "R600 Merge Clause Markers Pass";
208 llvm::FunctionPass *llvm::createR600ClauseMergePass() {
209 return new R600ClauseMergePass();