LLVM 24.0.0git
MachineLateInstrsCleanup.cpp
Go to the documentation of this file.
1//==--- MachineLateInstrsCleanup.cpp - Late Instructions Cleanup Pass -----===//
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// This simple pass removes any identical and redundant immediate or address
10// loads to the same register. The immediate loads removed can originally be
11// the result of rematerialization, while the addresses are redundant frame
12// addressing anchor points created during Frame Indices elimination.
13//
14//===----------------------------------------------------------------------===//
15
17#include "llvm/ADT/BitVector.h"
19#include "llvm/ADT/Statistic.h"
30#include "llvm/Pass.h"
31#include "llvm/Support/Debug.h"
32
33using namespace llvm;
34
35#define DEBUG_TYPE "machine-latecleanup"
36
37STATISTIC(NumRemoved, "Number of redundant instructions removed.");
38
39namespace {
40
41class MachineLateInstrsCleanup {
42 const TargetRegisterInfo *TRI = nullptr;
43 const TargetInstrInfo *TII = nullptr;
44
45 // Data structures to map regs to their definitions and kills per MBB.
46 struct Reg2MIMap : public SmallDenseMap<Register, MachineInstr *> {
47 bool hasIdentical(Register Reg, MachineInstr *ArgMI) {
49 return MI && MI->isIdenticalTo(*ArgMI);
50 }
51 };
52 typedef SmallDenseMap<Register, TinyPtrVector<MachineInstr *>> Reg2MIVecMap;
53 std::vector<Reg2MIMap> RegDefs;
54 std::vector<Reg2MIVecMap> RegKills;
55
56 // Walk through the instructions in MBB and remove any redundant
57 // instructions.
58 bool processBlock(MachineBasicBlock *MBB);
59
60 void removeRedundantDef(MachineInstr *MI);
61 void clearKillsForDef(Register Reg, MachineBasicBlock *MBB,
62 BitVector &VisitedPreds, MachineInstr *ToRemoveMI);
63
64public:
65 bool run(MachineFunction &MF);
66};
67
68class MachineLateInstrsCleanupLegacy : public MachineFunctionPass {
69public:
70 static char ID; // Pass identification, replacement for typeid
71
72 MachineLateInstrsCleanupLegacy() : MachineFunctionPass(ID) {}
73
74 void getAnalysisUsage(AnalysisUsage &AU) const override {
75 AU.setPreservesCFG();
76 AU.addPreserved<MachineRegisterClassInfoWrapperPass>();
78 }
79
80 bool runOnMachineFunction(MachineFunction &MF) override;
81
82 MachineFunctionProperties getRequiredProperties() const override {
83 return MachineFunctionProperties().setNoVRegs();
84 }
85};
86
87} // end anonymous namespace
88
89char MachineLateInstrsCleanupLegacy::ID = 0;
90
91char &llvm::MachineLateInstrsCleanupID = MachineLateInstrsCleanupLegacy::ID;
92
93INITIALIZE_PASS(MachineLateInstrsCleanupLegacy, DEBUG_TYPE,
94 "Machine Late Instructions Cleanup Pass", false, false)
95
96bool MachineLateInstrsCleanupLegacy::runOnMachineFunction(MachineFunction &MF) {
97 if (skipFunction(MF.getFunction()))
98 return false;
99
100 return MachineLateInstrsCleanup().run(MF);
101}
102
106 MFPropsModifier _(*this, MF);
107 if (!MachineLateInstrsCleanup().run(MF))
108 return PreservedAnalyses::all();
110 PA.preserveSet<CFGAnalyses>();
111 return PA;
112}
113
114bool MachineLateInstrsCleanup::run(MachineFunction &MF) {
117
118 RegDefs.clear();
119 RegDefs.resize(MF.getNumBlockIDs());
120 RegKills.clear();
121 RegKills.resize(MF.getNumBlockIDs());
122
123 // Visit all MBBs in an order that maximises the reuse from predecessors.
124 bool Changed = false;
126 for (MachineBasicBlock *MBB : RPOT)
127 Changed |= processBlock(MBB);
128
129 return Changed;
130}
131
132// Clear any preceding kill flag on Reg after removing a redundant
133// definition.
134void MachineLateInstrsCleanup::clearKillsForDef(Register Reg,
136 BitVector &VisitedPreds,
137 MachineInstr *ToRemoveMI) {
138 VisitedPreds.set(MBB->getNumber());
139
140 // Clear kill flag(s) in MBB, that have been seen after the preceding
141 // definition. If Reg or one of its subregs was killed, it would actually
142 // be ok to stop after removing that (and any other) kill-flag, but it
143 // doesn't seem noticeably faster while it would be a bit more complicated.
144 Reg2MIVecMap &MBBKills = RegKills[MBB->getNumber()];
145 if (auto Kills = MBBKills.find(Reg); Kills != MBBKills.end())
146 for (auto *KillMI : Kills->second)
147 KillMI->clearRegisterKills(Reg, TRI);
148
149 // Definition in current MBB: done.
150 Reg2MIMap &MBBDefs = RegDefs[MBB->getNumber()];
151 MachineInstr *DefMI = MBBDefs[Reg];
152 assert(DefMI->isIdenticalTo(*ToRemoveMI) && "Previous def not identical?");
153 if (DefMI->getParent() == MBB)
154 return;
155
156 // If an earlier def is not in MBB, continue in predecessors.
157 if (!MBB->isLiveIn(Reg))
158 MBB->addLiveIn(Reg);
159 assert(!MBB->pred_empty() && "Predecessor def not found!");
160 for (MachineBasicBlock *Pred : MBB->predecessors())
161 if (!VisitedPreds.test(Pred->getNumber()))
162 clearKillsForDef(Reg, Pred, VisitedPreds, ToRemoveMI);
163}
164
165void MachineLateInstrsCleanup::removeRedundantDef(MachineInstr *MI) {
166 Register Reg = MI->getOperand(0).getReg();
167 BitVector VisitedPreds(MI->getMF()->getNumBlockIDs());
168 clearKillsForDef(Reg, MI->getParent(), VisitedPreds, MI);
169 MI->eraseFromParent();
170 ++NumRemoved;
171}
172
173// Return true if MI is a potential candidate for reuse/removal and if so
174// also the register it defines in DefedReg. A candidate is a simple
175// instruction that does not touch memory, has only one register definition
176// and the only reg it may use is FrameReg. Typically this is an immediate
177// load or a load-address instruction.
178static bool isCandidate(const MachineInstr *MI, Register &DefedReg,
179 Register FrameReg) {
180 DefedReg = MCRegister::NoRegister;
181 bool SawStore = true;
182 if (!MI->isSafeToMove(SawStore) || MI->isImplicitDef() || MI->isInlineAsm())
183 return false;
184 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
185 const MachineOperand &MO = MI->getOperand(i);
186 if (MO.isReg()) {
187 if (MO.isDef()) {
188 if (i == 0 && !MO.isImplicit() && !MO.isDead())
189 DefedReg = MO.getReg();
190 else
191 return false;
192 } else if (MO.getReg() && MO.getReg() != FrameReg)
193 return false;
194 } else if (!(MO.isImm() || MO.isCImm() || MO.isFPImm() || MO.isCPI() ||
195 MO.isGlobal() || MO.isSymbol()))
196 return false;
197 }
198 return DefedReg.isValid();
199}
200
201bool MachineLateInstrsCleanup::processBlock(MachineBasicBlock *MBB) {
202 bool Changed = false;
203 Reg2MIMap &MBBDefs = RegDefs[MBB->getNumber()];
204 Reg2MIVecMap &MBBKills = RegKills[MBB->getNumber()];
205
206 // Find reusable definitions in the predecessor(s).
207 if (!MBB->pred_empty() && !MBB->isEHPad() &&
209 MachineBasicBlock *FirstPred = *MBB->pred_begin();
210 for (auto [Reg, DefMI] : RegDefs[FirstPred->getNumber()])
211 if (llvm::all_of(
213 [&, &Reg = Reg, &DefMI = DefMI](const MachineBasicBlock *Pred) {
214 return RegDefs[Pred->getNumber()].hasIdentical(Reg, DefMI);
215 })) {
216 MBBDefs[Reg] = DefMI;
217 LLVM_DEBUG(dbgs() << "Reusable instruction from pred(s): in "
218 << printMBBReference(*MBB) << ": " << *DefMI);
219 }
220 }
221
222 // Process MBB.
225 Register FrameReg = TRI->getFrameRegister(*MF);
227 // If FrameReg is modified, no previous load-address instructions (using
228 // it) are valid.
229 if (MI.modifiesRegister(FrameReg, TRI)) {
230 MBBDefs.clear();
231 MBBKills.clear();
232 continue;
233 }
234
235 Register DefedReg;
236 bool IsCandidate = isCandidate(&MI, DefedReg, FrameReg);
237
238 // Check for an earlier identical and reusable instruction.
239 if (IsCandidate && MBBDefs.hasIdentical(DefedReg, &MI)) {
240 LLVM_DEBUG(dbgs() << "Removing redundant instruction in "
241 << printMBBReference(*MBB) << ": " << MI);
242 removeRedundantDef(&MI);
243 Changed = true;
244 continue;
245 }
246
247 // Clear any entries in map that MI clobbers.
248 MBBDefs.remove_if([&](const auto &Entry) {
249 Register Reg = Entry.first;
250 if (MI.modifiesRegister(Reg, TRI)) {
251 MBBKills.erase(Reg);
252 return true;
253 }
254 if (MI.findRegisterUseOperandIdx(Reg, TRI, true /*isKill*/) != -1)
255 // Keep track of all instructions that fully or partially kills Reg.
256 MBBKills[Reg].push_back(&MI);
257 return false;
258 });
259
260 // Record this MI for potential later reuse.
261 if (IsCandidate) {
262 LLVM_DEBUG(dbgs() << "Found interesting instruction in "
263 << printMBBReference(*MBB) << ": " << MI);
264 MBBDefs[DefedReg] = &MI;
265 assert(!MBBKills.count(DefedReg) && "Should already have been removed.");
266 }
267 }
268
269 return Changed;
270}
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
This file implements the BitVector class.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
#define _
IRTranslator LLVM IR MI
static bool lookup(const GsymReader &GR, GsymDataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
static bool isCandidate(const MachineInstr *MI, Register &DefedReg, Register FrameReg)
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
bool test(unsigned Idx) const
Returns true if bit Idx is set.
Definition BitVector.h:482
BitVector & set()
Set all bits in the bitvector.
Definition BitVector.h:366
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
static constexpr unsigned NoRegister
Definition MCRegister.h:60
An RAII based helper class to modify MachineFunctionProperties when running pass.
bool isInlineAsmBrIndirectTarget() const
Returns true if this is the indirect dest of an INLINEASM_BR.
bool isEHPad() const
Returns true if the block is a landing pad.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< pred_iterator > predecessors()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
Representation of each machine instruction.
LLVM_ABI PreservedAnalyses run(MachineFunction &MachineFunction, MachineFunctionAnalysisManager &MachineFunctionAM)
MachineOperand class - Representation of each machine instruction operand.
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isValid() const
Definition Register.h:112
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Changed
@ Entry
Definition COFF.h:862
DXILDebugInfoMap run(Module &M)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:633
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI char & MachineLateInstrsCleanupID
MachineLateInstrsCleanup - This pass removes redundant identical instructions after register allocati...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.