LLVM: lib/CodeGen/MachineLateInstrsCleanup.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
31
32using namespace llvm;
33
34#define DEBUG_TYPE "machine-latecleanup"
35
36STATISTIC(NumRemoved, "Number of redundant instructions removed.");
37
38namespace {
39
40class MachineLateInstrsCleanup {
43
44
45 struct Reg2MIMap : public SmallDenseMap<Register, MachineInstr *> {
48 return MI && MI->isIdenticalTo(*ArgMI);
49 }
50 };
51 typedef SmallDenseMap<Register, TinyPtrVector<MachineInstr *>> Reg2MIVecMap;
52 std::vector RegDefs;
53 std::vector RegKills;
54
55
56
57 bool processBlock(MachineBasicBlock *MBB);
58
59 void removeRedundantDef(MachineInstr *MI);
60 void clearKillsForDef(Register Reg, MachineBasicBlock *MBB,
61 BitVector &VisitedPreds, MachineInstr *ToRemoveMI);
62
63public:
64 bool run(MachineFunction &MF);
65};
66
68public:
69 static char ID;
70
71 MachineLateInstrsCleanupLegacy() : MachineFunctionPass(ID) {
74 }
75
76 void getAnalysisUsage(AnalysisUsage &AU) const override {
79 }
80
81 bool runOnMachineFunction(MachineFunction &MF) override;
82
83 MachineFunctionProperties getRequiredProperties() const override {
84 return MachineFunctionProperties().setNoVRegs();
85 }
86};
87
88}
89
90char MachineLateInstrsCleanupLegacy::ID = 0;
91
93
95 "Machine Late Instructions Cleanup Pass", false, false)
96
97bool MachineLateInstrsCleanupLegacy::runOnMachineFunction(MachineFunction &MF) {
98 if (skipFunction(MF.getFunction()))
99 return false;
100
101 return MachineLateInstrsCleanup().run(MF);
102}
103
108 if (!MachineLateInstrsCleanup().run(MF))
112 return PA;
113}
114
118
119 RegDefs.clear();
121 RegKills.clear();
123
124
129
131}
132
133
134
135void MachineLateInstrsCleanup::clearKillsForDef(Register Reg,
139 VisitedPreds.set(MBB->getNumber());
140
141
142
143
144
145 Reg2MIVecMap &MBBKills = RegKills[MBB->getNumber()];
146 if (auto Kills = MBBKills.find(Reg); Kills != MBBKills.end())
147 for (auto *KillMI : Kills->second)
148 KillMI->clearRegisterKills(Reg, TRI);
149
150
151 Reg2MIMap &MBBDefs = RegDefs[MBB->getNumber()];
153 assert(DefMI->isIdenticalTo(*ToRemoveMI) && "Previous def not identical?");
154 if (DefMI->getParent() == MBB)
155 return;
156
157
158 if (->isLiveIn(Reg))
160 assert(->pred_empty() && "Predecessor def not found!");
162 if (!VisitedPreds.test(Pred->getNumber()))
163 clearKillsForDef(Reg, Pred, VisitedPreds, ToRemoveMI);
164}
165
166void MachineLateInstrsCleanup::removeRedundantDef(MachineInstr *MI) {
168 BitVector VisitedPreds(MI->getMF()->getNumBlockIDs());
169 clearKillsForDef(Reg, MI->getParent(), VisitedPreds, MI);
170 MI->eraseFromParent();
171 ++NumRemoved;
172}
173
174
175
176
177
178
182 bool SawStore = true;
183 if (->isSafeToMove(SawStore) || MI->isImplicitDef() || MI->isInlineAsm())
184 return false;
185 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
187 if (MO.isReg()) {
188 if (MO.isDef()) {
190 DefedReg = MO.getReg();
191 else
192 return false;
193 } else if (MO.getReg() && MO.getReg() != FrameReg)
194 return false;
197 return false;
198 }
199 return DefedReg.isValid();
200}
201
204 Reg2MIMap &MBBDefs = RegDefs[MBB->getNumber()];
205 Reg2MIVecMap &MBBKills = RegKills[MBB->getNumber()];
206
207
215 return RegDefs[Pred->getNumber()].hasIdentical(Reg, DefMI);
216 })) {
218 LLVM_DEBUG(dbgs() << "Reusable instruction from pred(s): in "
220 }
221 }
222
223
226 Register FrameReg = TRI->getFrameRegister(*MF);
228
229
230 if (MI.modifiesRegister(FrameReg, TRI)) {
231 MBBDefs.clear();
232 MBBKills.clear();
233 continue;
234 }
235
237 bool IsCandidate = isCandidate(&MI, DefedReg, FrameReg);
238
239
240 if (IsCandidate && MBBDefs.hasIdentical(DefedReg, &MI)) {
241 LLVM_DEBUG(dbgs() << "Removing redundant instruction in "
243 removeRedundantDef(&MI);
245 continue;
246 }
247
248
251 if (MI.modifiesRegister(Reg, TRI)) {
252 MBBDefs.erase(Reg);
253 MBBKills.erase(Reg);
254 } else if (MI.findRegisterUseOperandIdx(Reg, TRI, true ) != -1)
255
256 MBBKills[Reg].push_back(&MI);
257 }
258
259
260 if (IsCandidate) {
261 LLVM_DEBUG(dbgs() << "Found interesting instruction in "
263 MBBDefs[DefedReg] = &MI;
264 assert(!MBBKills.count(DefedReg) && "Should already have been removed.");
265 }
266 }
267
269}
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
This file implements the BitVector class.
static bool lookup(const GsymReader &GR, DataExtractor &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)
Definition MachineLateInstrsCleanup.cpp:179
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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)
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool test(unsigned Idx) const
Represents analyses that only rely on functions' control flow.
static constexpr unsigned NoRegister
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...
pred_iterator pred_begin()
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.
PreservedAnalyses run(MachineFunction &MachineFunction, MachineFunctionAnalysisManager &MachineFunctionAM)
Definition MachineLateInstrsCleanup.cpp:105
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.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
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.
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the 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.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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...
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...
Definition MachineLateInstrsCleanup.cpp:92
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void initializeMachineLateInstrsCleanupLegacyPass(PassRegistry &)
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.