[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Target / AMDGPU / R600ClauseMergePass.cpp
bloba19d00b625029c8b37d095620cf9debf9776240e
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 maneer.
11 /// This pass is merging consecutive CFAlus where applicable.
12 /// It needs to be called after IfCvt for best results.
13 //===----------------------------------------------------------------------===//
15 #include "AMDGPU.h"
16 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
17 #include "R600Subtarget.h"
19 using namespace llvm;
21 #define DEBUG_TYPE "r600mergeclause"
23 namespace {
25 static bool isCFAlu(const MachineInstr &MI) {
26 switch (MI.getOpcode()) {
27 case R600::CF_ALU:
28 case R600::CF_ALU_PUSH_BEFORE:
29 return true;
30 default:
31 return false;
35 class R600ClauseMergePass : public MachineFunctionPass {
37 private:
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
50 /// it is the case.
51 bool mergeIfPossible(MachineInstr &RootCFAlu,
52 const MachineInstr &LatrCFAlu) const;
54 public:
55 static char ID;
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 {
76 assert(isCFAlu(MI));
77 return MI
78 .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::COUNT))
79 .getImm();
82 bool R600ClauseMergePass::isCFAluEnabled(const MachineInstr &MI) const {
83 assert(isCFAlu(MI));
84 return MI
85 .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::Enabled))
86 .getImm();
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();
93 I++;
94 do {
95 while (I != E && !isCFAlu(*I))
96 I++;
97 if (I == E)
98 return;
99 MachineInstr &MI = *I++;
100 if (isCFAluEnabled(MI))
101 break;
102 CFAlu.getOperand(CntIdx).setImm(getCFAluSize(CFAlu) + getCFAluSize(MI));
103 MI.eraseFromParent();
104 } while (I != E);
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");
116 return false;
118 if (RootCFAlu.getOpcode() == R600::CF_ALU_PUSH_BEFORE)
119 return false;
120 // Is KCache Bank 0 compatible ?
121 int Mode0Idx =
122 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE0);
123 int KBank0Idx =
124 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK0);
125 int KBank0LineIdx =
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");
134 return false;
136 // Is KCache Bank 1 compatible ?
137 int Mode1Idx =
138 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE1);
139 int KBank1Idx =
140 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK1);
141 int KBank1LineIdx =
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");
150 return false;
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()));
170 return true;
173 bool R600ClauseMergePass::runOnMachineFunction(MachineFunction &MF) {
174 if (skipFunction(MF.getFunction()))
175 return false;
177 const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>();
178 TII = ST.getInstrInfo();
180 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
181 BB != BB_E; ++BB) {
182 MachineBasicBlock &MBB = *BB;
183 MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
184 MachineBasicBlock::iterator LatestCFAlu = E;
185 while (I != E) {
186 MachineInstr &MI = *I++;
187 if ((!TII->canBeConsideredALU(MI) && !isCFAlu(MI)) ||
188 TII->mustBeLastInClause(MI.getOpcode()))
189 LatestCFAlu = E;
190 if (!isCFAlu(MI))
191 continue;
192 cleanPotentialDisabledCFAlu(MI);
194 if (LatestCFAlu != E && mergeIfPossible(*LatestCFAlu, MI)) {
195 MI.eraseFromParent();
196 } else {
197 assert(MI.getOperand(8).getImm() && "CF ALU instruction disabled");
198 LatestCFAlu = MI;
202 return false;
205 StringRef R600ClauseMergePass::getPassName() const {
206 return "R600 Merge Clause Markers Pass";
209 llvm::FunctionPass *llvm::createR600ClauseMergePass() {
210 return new R600ClauseMergePass();