LLVM  12.0.0git
SIPostRABundler.cpp
Go to the documentation of this file.
1 //===-- SIPostRABundler.cpp -----------------------------------------------===//
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 /// This pass creates bundles of memory instructions to protect adjacent loads
11 /// and stores from beeing rescheduled apart from each other post-RA.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "AMDGPU.h"
16 #include "AMDGPUSubtarget.h"
17 #include "SIDefines.h"
18 #include "SIInstrInfo.h"
19 #include "llvm/ADT/SmallSet.h"
22 #include "llvm/InitializePasses.h"
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "si-post-ra-bundler"
27 
28 namespace {
29 
30 class SIPostRABundler : public MachineFunctionPass {
31 public:
32  static char ID;
33 
34 public:
35  SIPostRABundler() : MachineFunctionPass(ID) {
37  }
38 
39  bool runOnMachineFunction(MachineFunction &MF) override;
40 
41  StringRef getPassName() const override {
42  return "SI post-RA bundler";
43  }
44 
45  void getAnalysisUsage(AnalysisUsage &AU) const override {
46  AU.setPreservesAll();
48  }
49 
50 private:
51  const SIRegisterInfo *TRI;
52 
54 
55  bool isDependentLoad(const MachineInstr &MI) const;
56 
57 };
58 
59 } // End anonymous namespace.
60 
61 INITIALIZE_PASS(SIPostRABundler, DEBUG_TYPE, "SI post-RA bundler", false, false)
62 
63 char SIPostRABundler::ID = 0;
64 
66 
68  return new SIPostRABundler();
69 }
70 
71 bool SIPostRABundler::isDependentLoad(const MachineInstr &MI) const {
72  if (!MI.mayLoad())
73  return false;
74 
75  for (const MachineOperand &Op : MI.explicit_operands()) {
76  if (!Op.isReg())
77  continue;
78  Register Reg = Op.getReg();
79  for (Register Def : Defs)
80  if (TRI->regsOverlap(Reg, Def))
81  return true;
82  }
83 
84  return false;
85 }
86 
87 bool SIPostRABundler::runOnMachineFunction(MachineFunction &MF) {
88  if (skipFunction(MF.getFunction()))
89  return false;
90 
91  TRI = MF.getSubtarget<GCNSubtarget>().getRegisterInfo();
92  bool Changed = false;
93  const uint64_t MemFlags = SIInstrFlags::MTBUF | SIInstrFlags::MUBUF |
96 
97  for (MachineBasicBlock &MBB : MF) {
101  for (auto I = B; I != E; I = Next) {
102  Next = std::next(I);
103 
104  const uint64_t IMemFlags = I->getDesc().TSFlags & MemFlags;
105 
106  if (IMemFlags == 0 || I->isBundled() || !I->mayLoadOrStore() ||
107  B->mayLoad() != I->mayLoad() || B->mayStore() != I->mayStore() ||
108  ((B->getDesc().TSFlags & MemFlags) != IMemFlags) ||
109  isDependentLoad(*I)) {
110 
111  if (B != I) {
112  if (std::next(B) != I) {
113  finalizeBundle(MBB, B, I);
114  Changed = true;
115  }
116  Next = I;
117  }
118 
119  B = Next;
120  Defs.clear();
121  continue;
122  }
123 
124  if (I->getNumExplicitDefs() == 0)
125  continue;
126 
127  Defs.insert(I->defs().begin()->getReg());
128  }
129 
130  if (B != E && std::next(B) != E) {
131  finalizeBundle(MBB, B, E);
132  Changed = true;
133  }
134 
135  Defs.clear();
136  }
137 
138  return Changed;
139 }
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
instr_iterator instr_begin()
AMDGPU specific subclass of TargetSubtarget.
instr_iterator instr_end()
This class represents lattice values for constants.
Definition: AllocatorList.h:23
iterator_range< mop_iterator > explicit_operands()
Definition: MachineInstr.h:565
unsigned Reg
unsigned const TargetRegisterInfo * TRI
void initializeSIPostRABundlerPass(PassRegistry &)
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineBasicBlock & MBB
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
#define DEBUG_TYPE
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
FunctionPass * createSIPostRABundlerPass()
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:37
Iterator for intrusive lists based on ilist_node.
MachineOperand class - Representation of each machine instruction operand.
char & SIPostRABundlerID
void setPreservesAll()
Set by analyses that do not transform their input at all.
Representation of each machine instruction.
Definition: MachineInstr.h:62
Interface definition for SIInstrInfo.
#define I(x, y, z)
Definition: MD5.cpp:59
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Definition: MachineInstr.h:942
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
finalizeBundle - Finalize a machine instruction bundle which includes a sequence of instructions star...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19