34#define DEBUG_TYPE "machine-latecleanup"
36STATISTIC(NumRemoved,
"Number of redundant instructions removed.");
40class MachineLateInstrsCleanup {
45 struct Reg2MIMap :
public SmallDenseMap<Register, MachineInstr *> {
48 return MI &&
MI->isIdenticalTo(*ArgMI);
51 typedef SmallDenseMap<Register, TinyPtrVector<MachineInstr *>> Reg2MIVecMap;
52 std::vector<Reg2MIMap> RegDefs;
53 std::vector<Reg2MIVecMap> RegKills;
57 bool processBlock(MachineBasicBlock *
MBB);
59 void removeRedundantDef(MachineInstr *
MI);
61 BitVector &VisitedPreds, MachineInstr *ToRemoveMI);
64 bool run(MachineFunction &MF);
71 MachineLateInstrsCleanupLegacy() : MachineFunctionPass(ID) {}
73 void getAnalysisUsage(AnalysisUsage &AU)
const override {
78 bool runOnMachineFunction(MachineFunction &MF)
override;
80 MachineFunctionProperties getRequiredProperties()
const override {
81 return MachineFunctionProperties().setNoVRegs();
87char MachineLateInstrsCleanupLegacy::ID = 0;
92 "Machine Late Instructions Cleanup Pass",
false,
false)
95 if (skipFunction(MF.getFunction()))
98 return MachineLateInstrsCleanup().run(MF);
105 if (!MachineLateInstrsCleanup().
run(MF))
132void MachineLateInstrsCleanup::clearKillsForDef(
Register Reg,
136 VisitedPreds.
set(
MBB->getNumber());
142 Reg2MIVecMap &MBBKills = RegKills[
MBB->getNumber()];
143 if (
auto Kills = MBBKills.find(
Reg); Kills != MBBKills.end())
144 for (
auto *KillMI : Kills->second)
145 KillMI->clearRegisterKills(
Reg,
TRI);
148 Reg2MIMap &MBBDefs = RegDefs[
MBB->getNumber()];
150 assert(
DefMI->isIdenticalTo(*ToRemoveMI) &&
"Previous def not identical?");
157 assert(!
MBB->pred_empty() &&
"Predecessor def not found!");
159 if (!VisitedPreds.
test(Pred->getNumber()))
160 clearKillsForDef(
Reg, Pred, VisitedPreds, ToRemoveMI);
163void MachineLateInstrsCleanup::removeRedundantDef(
MachineInstr *
MI) {
165 BitVector VisitedPreds(
MI->getMF()->getNumBlockIDs());
166 clearKillsForDef(
Reg,
MI->getParent(), VisitedPreds,
MI);
167 MI->eraseFromParent();
179 bool SawStore =
true;
180 if (!
MI->isSafeToMove(SawStore) ||
MI->isImplicitDef() ||
MI->isInlineAsm())
182 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
212 return RegDefs[Pred->getNumber()].hasIdentical(Reg, DefMI);
227 if (
MI.modifiesRegister(FrameReg,
TRI)) {
237 if (IsCandidate && MBBDefs.hasIdentical(DefedReg, &
MI)) {
240 removeRedundantDef(&
MI);
248 if (
MI.modifiesRegister(
Reg,
TRI)) {
251 }
else if (
MI.findRegisterUseOperandIdx(
Reg,
TRI,
true ) != -1)
253 MBBKills[
Reg].push_back(&
MI);
260 MBBDefs[DefedReg] = &
MI;
261 assert(!MBBKills.count(DefedReg) &&
"Should already have been removed.");
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
const HexagonInstrInfo * TII
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)
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)
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.
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...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.