LLVM  13.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 maneer.
11 /// This pass is merging consecutive CFAlus where applicable.
12 /// It needs to be called after IfCvt for best results.
13 //===----------------------------------------------------------------------===//
14 
15 #include "AMDGPU.h"
17 #include "R600Subtarget.h"
18 
19 using namespace llvm;
20 
21 #define DEBUG_TYPE "r600mergeclause"
22 
23 namespace {
24 
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;
32  }
33 }
34 
35 class R600ClauseMergePass : public MachineFunctionPass {
36 
37 private:
38  const R600InstrInfo *TII;
39 
40  unsigned getCFAluSize(const MachineInstr &MI) const;
41  bool isCFAluEnabled(const MachineInstr &MI) const;
42 
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;
48 
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;
53 
54 public:
55  static char ID;
56 
57  R600ClauseMergePass() : MachineFunctionPass(ID) { }
58 
59  bool runOnMachineFunction(MachineFunction &MF) override;
60 
61  StringRef getPassName() const override;
62 };
63 
64 } // end anonymous namespace
65 
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)
70 
71 char R600ClauseMergePass::ID = 0;
72 
73 char &llvm::R600ClauseMergePassID = R600ClauseMergePass::ID;
74 
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();
80 }
81 
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();
87 }
88 
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);
105 }
106 
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;
117  }
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;
135  }
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;
151  }
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());
159  }
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());
167  }
168  RootCFAlu.getOperand(CntIdx).setImm(CumuledInsts);
169  RootCFAlu.setDesc(TII->get(LatrCFAlu.getOpcode()));
170  return true;
171 }
172 
173 bool R600ClauseMergePass::runOnMachineFunction(MachineFunction &MF) {
174  if (skipFunction(MF.getFunction()))
175  return false;
176 
178  TII = ST.getInstrInfo();
179 
180  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
181  BB != BB_E; ++BB) {
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);
193 
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;
199  }
200  }
201  }
202  return false;
203 }
204 
205 StringRef R600ClauseMergePass::getPassName() const {
206  return "R600 Merge Clause Markers Pass";
207 }
208 
210  return new R600ClauseMergePass();
211 }
DEBUG_TYPE
#define DEBUG_TYPE
Definition: R600ClauseMergePass.cpp:21
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:102
Merge
R600 Clause Merge
Definition: R600ClauseMergePass.cpp:69
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MachineFunction::end
iterator end()
Definition: MachineFunction.h:806
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:655
llvm::createR600ClauseMergePass
FunctionPass * createR600ClauseMergePass()
Definition: R600ClauseMergePass.cpp:209
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:537
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:499
false
Definition: StackSlotColoring.cpp:142
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineFunction::begin
iterator begin()
Definition: MachineFunction.h:804
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:622
llvm::Clause
Definition: DirectiveEmitter.h:123
llvm::R600Subtarget
Definition: R600Subtarget.h:36
AMDGPUMCTargetDesc.h
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
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:59
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:230
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
AMDGPU.h
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:489
llvm::MachineInstr::getParent
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:286
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:588
llvm::R600ClauseMergePassID
char & R600ClauseMergePassID
Definition: R600ClauseMergePass.cpp:73
llvm::ilist_iterator
Iterator for intrusive lists based on ilist_node.
Definition: ilist_iterator.h:57
Enabled
static bool Enabled
Definition: Statistic.cpp:46
R600Subtarget.h
llvm::R600InstrInfo
Definition: R600InstrInfo.h:39
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
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:1741
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38