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();
77 }
78
79 bool runOnMachineFunction(MachineFunction &MF) override;
80
81 MachineFunctionProperties getRequiredProperties() const override {
82 return MachineFunctionProperties().setNoVRegs();
83 }
84};
85
86} // end anonymous namespace
87
88char MachineLateInstrsCleanupLegacy::ID = 0;
89
90char &llvm::MachineLateInstrsCleanupID = MachineLateInstrsCleanupLegacy::ID;
91
92INITIALIZE_PASS(MachineLateInstrsCleanupLegacy, DEBUG_TYPE,
93 "Machine Late Instructions Cleanup Pass", false, false)
94
95bool MachineLateInstrsCleanupLegacy::runOnMachineFunction(MachineFunction &MF) {
96 if (skipFunction(MF.getFunction()))
97 return false;
98
99 return MachineLateInstrsCleanup().run(MF);
100}
101
105 MFPropsModifier _(*this, MF);
106 if (!MachineLateInstrsCleanup().run(MF))
107 return PreservedAnalyses::all();
109 PA.preserveSet<CFGAnalyses>();
110 return PA;
111}
112
113bool MachineLateInstrsCleanup::run(MachineFunction &MF) {
116
117 RegDefs.clear();
118 RegDefs.resize(MF.getNumBlockIDs());
119 RegKills.clear();
120 RegKills.resize(MF.getNumBlockIDs());
121
122 // Visit all MBBs in an order that maximises the reuse from predecessors.
123 bool Changed = false;
125 for (MachineBasicBlock *MBB : RPOT)
126 Changed |= processBlock(MBB);
127
128 return Changed;
129}
130
131// Clear any preceding kill flag on Reg after removing a redundant
132// definition.
133void MachineLateInstrsCleanup::clearKillsForDef(Register Reg,
135 BitVector &VisitedPreds,
136 MachineInstr *ToRemoveMI) {
137 VisitedPreds.set(MBB->getNumber());
138
139 // Clear kill flag(s) in MBB, that have been seen after the preceding
140 // definition. If Reg or one of its subregs was killed, it would actually
141 // be ok to stop after removing that (and any other) kill-flag, but it
142 // doesn't seem noticeably faster while it would be a bit more complicated.
143 Reg2MIVecMap &MBBKills = RegKills[MBB->getNumber()];
144 if (auto Kills = MBBKills.find(Reg); Kills != MBBKills.end())
145 for (auto *KillMI : Kills->second)
146 KillMI->clearRegisterKills(Reg, TRI);
147
148 // Definition in current MBB: done.
149 Reg2MIMap &MBBDefs = RegDefs[MBB->getNumber()];
150 MachineInstr *DefMI = MBBDefs[Reg];
151 assert(DefMI->isIdenticalTo(*ToRemoveMI) && "Previous def not identical?");
152 if (DefMI->getParent() == MBB)
153 return;
154
155 // If an earlier def is not in MBB, continue in predecessors.
156 if (!MBB->isLiveIn(Reg))
157 MBB->addLiveIn(Reg);
158 assert(!MBB->pred_empty() && "Predecessor def not found!");
159 for (MachineBasicBlock *Pred : MBB->predecessors())
160 if (!VisitedPreds.test(Pred->getNumber()))
161 clearKillsForDef(Reg, Pred, VisitedPreds, ToRemoveMI);
162}
163
164void MachineLateInstrsCleanup::removeRedundantDef(MachineInstr *MI) {
165 Register Reg = MI->getOperand(0).getReg();
166 BitVector VisitedPreds(MI->getMF()->getNumBlockIDs());
167 clearKillsForDef(Reg, MI->getParent(), VisitedPreds, MI);
168 MI->eraseFromParent();
169 ++NumRemoved;
170}
171
172// Return true if MI is a potential candidate for reuse/removal and if so
173// also the register it defines in DefedReg. A candidate is a simple
174// instruction that does not touch memory, has only one register definition
175// and the only reg it may use is FrameReg. Typically this is an immediate
176// load or a load-address instruction.
177static bool isCandidate(const MachineInstr *MI, Register &DefedReg,
178 Register FrameReg) {
179 DefedReg = MCRegister::NoRegister;
180 bool SawStore = true;
181 if (!MI->isSafeToMove(SawStore) || MI->isImplicitDef() || MI->isInlineAsm())
182 return false;
183 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
184 const MachineOperand &MO = MI->getOperand(i);
185 if (MO.isReg()) {
186 if (MO.isDef()) {
187 if (i == 0 && !MO.isImplicit() && !MO.isDead())
188 DefedReg = MO.getReg();
189 else
190 return false;
191 } else if (MO.getReg() && MO.getReg() != FrameReg)
192 return false;
193 } else if (!(MO.isImm() || MO.isCImm() || MO.isFPImm() || MO.isCPI() ||
194 MO.isGlobal() || MO.isSymbol()))
195 return false;
196 }
197 return DefedReg.isValid();
198}
199
200bool MachineLateInstrsCleanup::processBlock(MachineBasicBlock *MBB) {
201 bool Changed = false;
202 Reg2MIMap &MBBDefs = RegDefs[MBB->getNumber()];
203 Reg2MIVecMap &MBBKills = RegKills[MBB->getNumber()];
204
205 // Find reusable definitions in the predecessor(s).
206 if (!MBB->pred_empty() && !MBB->isEHPad() &&
208 MachineBasicBlock *FirstPred = *MBB->pred_begin();
209 for (auto [Reg, DefMI] : RegDefs[FirstPred->getNumber()])
210 if (llvm::all_of(
212 [&, &Reg = Reg, &DefMI = DefMI](const MachineBasicBlock *Pred) {
213 return RegDefs[Pred->getNumber()].hasIdentical(Reg, DefMI);
214 })) {
215 MBBDefs[Reg] = DefMI;
216 LLVM_DEBUG(dbgs() << "Reusable instruction from pred(s): in "
217 << printMBBReference(*MBB) << ": " << *DefMI);
218 }
219 }
220
221 // Process MBB.
224 Register FrameReg = TRI->getFrameRegister(*MF);
226 // If FrameReg is modified, no previous load-address instructions (using
227 // it) are valid.
228 if (MI.modifiesRegister(FrameReg, TRI)) {
229 MBBDefs.clear();
230 MBBKills.clear();
231 continue;
232 }
233
234 Register DefedReg;
235 bool IsCandidate = isCandidate(&MI, DefedReg, FrameReg);
236
237 // Check for an earlier identical and reusable instruction.
238 if (IsCandidate && MBBDefs.hasIdentical(DefedReg, &MI)) {
239 LLVM_DEBUG(dbgs() << "Removing redundant instruction in "
240 << printMBBReference(*MBB) << ": " << MI);
241 removeRedundantDef(&MI);
242 Changed = true;
243 continue;
244 }
245
246 // Clear any entries in map that MI clobbers.
247 MBBDefs.remove_if([&](const auto &Entry) {
248 Register Reg = Entry.first;
249 if (MI.modifiesRegister(Reg, TRI)) {
250 MBBKills.erase(Reg);
251 return true;
252 }
253 if (MI.findRegisterUseOperandIdx(Reg, TRI, true /*isKill*/) != -1)
254 // Keep track of all instructions that fully or partially kills Reg.
255 MBBKills[Reg].push_back(&MI);
256 return false;
257 });
258
259 // Record this MI for potential later reuse.
260 if (IsCandidate) {
261 LLVM_DEBUG(dbgs() << "Found interesting instruction in "
262 << printMBBReference(*MBB) << ": " << MI);
263 MBBDefs[DefedReg] = &MI;
264 assert(!MBBKills.count(DefedReg) && "Should already have been removed.");
265 }
266 }
267
268 return Changed;
269}
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
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.