LLVM  16.0.0git
R600ClauseMergePass.cpp
Go to the documentation of this file.
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 //===----------------------------------------------------------------------===//
14 
16 #include "R600.h"
17 #include "R600Subtarget.h"
19 
20 using namespace llvm;
21 
22 #define DEBUG_TYPE "r600mergeclause"
23 
24 namespace {
25 
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;
33  }
34 }
35 
36 class R600ClauseMergePass : public MachineFunctionPass {
37 
38 private:
39  const R600InstrInfo *TII;
40 
41  unsigned getCFAluSize(const MachineInstr &MI) const;
42  bool isCFAluEnabled(const MachineInstr &MI) const;
43 
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;
49 
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;
54 
55 public:
56  static char ID;
57 
58  R600ClauseMergePass() : MachineFunctionPass(ID) { }
59 
60  bool runOnMachineFunction(MachineFunction &MF) override;
61 
62  StringRef getPassName() const override;
63 };
64 
65 } // end anonymous namespace
66 
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)
71 
72 char R600ClauseMergePass::ID = 0;
73 
74 char &llvm::R600ClauseMergePassID = R600ClauseMergePass::ID;
75 
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();
81 }
82 
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();
88 }
89 
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);
106 }
107 
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;
118  }
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;
136  }
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;
152  }
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());
160  }
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());
168  }
169  RootCFAlu.getOperand(CntIdx).setImm(CumuledInsts);
170  RootCFAlu.setDesc(TII->get(LatrCFAlu.getOpcode()));
171  return true;
172 }
173 
174 bool R600ClauseMergePass::runOnMachineFunction(MachineFunction &MF) {
175  if (skipFunction(MF.getFunction()))
176  return false;
177 
179  TII = ST.getInstrInfo();
180 
181  for (MachineBasicBlock &MBB : MF) {
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);
192 
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;
198  }
199  }
200  }
201  return false;
202 }
203 
204 StringRef R600ClauseMergePass::getPassName() const {
205  return "R600 Merge Clause Markers Pass";
206 }
207 
209  return new R600ClauseMergePass();
210 }
DEBUG_TYPE
#define DEBUG_TYPE
Definition: R600ClauseMergePass.cpp:22
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
Merge
R600 Clause Merge
Definition: R600ClauseMergePass.cpp:70
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::MachineOperand::setImm
void setImm(int64_t immVal)
Definition: MachineOperand.h:664
llvm::createR600ClauseMergePass
FunctionPass * createR600ClauseMergePass()
Definition: R600ClauseMergePass.cpp:208
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
R600.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:546
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:526
false
Definition: StackSlotColoring.cpp:141
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
R600MCTargetDesc.h
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:657
llvm::Clause
Definition: DirectiveEmitter.h:123
llvm::R600Subtarget
Definition: R600Subtarget.h:29
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
I
#define I(x, y, z)
Definition: MD5.cpp:58
MachineFunctionPass.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(R600ClauseMergePass, DEBUG_TYPE, "R600 Clause Merge", false, false) INITIALIZE_PASS_END(R600ClauseMergePass
llvm::MachineFunction
Definition: MachineFunction.h:257
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:516
llvm::MachineInstr::getParent
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:313
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:623
llvm::R600ClauseMergePassID
char & R600ClauseMergePassID
Definition: R600ClauseMergePass.cpp:74
Enabled
static bool Enabled
Definition: Statistic.cpp:46
R600Subtarget.h
llvm::R600InstrInfo
Definition: R600InstrInfo.h:38
llvm::MachineInstr::setDesc
void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
Definition: MachineInstr.h:1763
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:305
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:307