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 (MBB->isLiveIn(Reg))

160 assert(MBB->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 (MI->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.