LLVM: lib/CodeGen/MIRCanonicalizerPass.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

35

36using namespace llvm;

37

38#define DEBUG_TYPE "mir-canonicalizer"

39

43 cl::desc("Function number to canonicalize."));

44

45namespace {

46

48public:

49 static char ID;

51

52 StringRef getPassName() const override {

53 return "Rename register operands in a canonical ordering.";

54 }

55

56 void getAnalysisUsage(AnalysisUsage &AU) const override {

59 }

60

61 bool runOnMachineFunction(MachineFunction &MF) override;

62};

63

64}

65

66char MIRCanonicalizer::ID;

67

69

71 "Rename Register Operands Canonically", false, false)

72

74 "Rename Register Operands Canonically", false, false)

75

77 if (MF.empty())

78 return {};

80 std::vector<MachineBasicBlock *> RPOList;

82

83 return RPOList;

84}

85

86static bool

90

92 using StringInstrPair = std::pair<std::string, MachineInstr *>;

93 std::vector StringInstrMap;

94

96 std::string S;

98 II->print(OS);

100

101

102 const size_t i = S.find('=');

103 StringInstrMap.push_back({(i == std:🧵:npos) ? S : S.substr(i), II});

104 }

105

107

108 for (auto &II : StringInstrMap) {

109

111 dbgs() << "Splicing ";

112 II.second->dump();

113 dbgs() << " right before: ";

114 getPos()->dump();

115 });

116

118 MBB->splice(getPos(), MBB, II.second);

119 }

120

122}

123

126

128

129

131 unsigned i = 0;

132 for (const auto &CurMI : *MI.getParent()) {

133 if (&CurMI == &MI)

134 return i;

135 i++;

136 }

137 return ~0U;

138 };

139

140

141

142 std::vector<MachineInstr *> Instructions;

143 for (auto &MI : *MBB) {

144 Instructions.push_back(&MI);

145 }

146

147 std::map<MachineInstr *, std::vector<MachineInstr *>> MultiUsers;

148 std::map<unsigned, MachineInstr *> MultiUserLookup;

149 unsigned UseToBringDefCloserToCount = 0;

150 std::vector<MachineInstr *> PseudoIdempotentInstructions;

151 std::vector PhysRegDefs;

152 for (auto *II : Instructions) {

153 for (unsigned i = 1; i < II->getNumOperands(); i++) {

156 continue;

157

159 continue;

160

162 continue;

163

164 PhysRegDefs.push_back(MO.getReg());

165 }

166 }

167

168 for (auto *II : Instructions) {

169 if (II->getNumOperands() == 0)

170 continue;

171 if (II->mayLoadOrStore())

172 continue;

173

176 continue;

178 continue;

179

180 bool IsPseudoIdempotent = true;

181 for (unsigned i = 1; i < II->getNumOperands(); i++) {

182

183 if (II->getOperand(i).isImm()) {

184 continue;

185 }

186

187 if (II->getOperand(i).isReg()) {

188 if (II->getOperand(i).getReg().isVirtual())

190 II->getOperand(i).getReg().asMCReg())) {

191 continue;

192 }

193 }

194

195 IsPseudoIdempotent = false;

196 break;

197 }

198

199 if (IsPseudoIdempotent) {

200 PseudoIdempotentInstructions.push_back(II);

201 continue;

202 }

203

205

207 unsigned Distance = ~0U;

208 MachineInstr *UseToBringDefCloserTo = nullptr;

210 for (auto &UO : MRI->use_nodbg_operands(MO.getReg())) {

212

213 const unsigned DefLoc = getInstrIdx(*Def);

214 const unsigned UseLoc = getInstrIdx(*UseInst);

215 const unsigned Delta = (UseLoc - DefLoc);

216

217 if (UseInst->getParent() != Def->getParent())

218 continue;

219 if (DefLoc >= UseLoc)

220 continue;

221

222 if (Delta < Distance) {

223 Distance = Delta;

224 UseToBringDefCloserTo = UseInst;

225 MultiUserLookup[UseToBringDefCloserToCount++] = UseToBringDefCloserTo;

226 }

227 }

228

229 const auto BBE = MBB->instr_end();

232

233 for (auto BBI = MBB->instr_begin(); BBI != BBE; ++BBI) {

234

235 if (DefI != BBE && UseI != BBE)

236 break;

237

238 if (&*BBI == Def) {

239 DefI = BBI;

240 continue;

241 }

242

243 if (&*BBI == UseToBringDefCloserTo) {

244 UseI = BBI;

245 continue;

246 }

247 }

248

249 if (DefI == BBE || UseI == BBE)

250 continue;

251

253 dbgs() << "Splicing ";

254 DefI->dump();

255 dbgs() << " right before: ";

256 UseI->dump();

257 });

258

259 MultiUsers[UseToBringDefCloserTo].push_back(Def);

261 MBB->splice(UseI, MBB, DefI);

262 }

263

264

265 for (const auto &E : MultiUserLookup) {

266

268 return &MI == E.second;

269 });

270

271 if (UseI == MBB->instr_end())

272 continue;

273

275 dbgs() << "Rescheduling Multi-Use Instructions Lexographically.");

277 MultiUsers[E.second], MBB,

279 }

280

281 PseudoIdempotentInstCount = PseudoIdempotentInstructions.size();

282 LLVM_DEBUG(dbgs() << "Rescheduling Idempotent Instructions Lexographically.");

284 PseudoIdempotentInstructions, MBB,

286

288}

289

293

294 std::vector<MachineInstr *> Copies;

296 if (MI.isCopy())

298 }

299

301

302 if (MI->getOperand(0).isReg())

303 continue;

304 if (MI->getOperand(1).isReg())

305 continue;

306

307 const Register Dst = MI->getOperand(0).getReg();

308 const Register Src = MI->getOperand(1).getReg();

309

310 if (!Dst.isVirtual())

311 continue;

312 if (!Src.isVirtual())

313 continue;

314

315

316

317

318

319 if (MRI.getRegClassOrNull(Dst))

320 continue;

321 if (MRI.getRegClass(Dst) != MRI.getRegClass(Src))

322 continue;

323

324 std::vector<MachineOperand *> Uses;

326 Uses.push_back(&MO);

327 for (auto *MO : Uses)

328 MO->setReg(Src);

329

331 MI->eraseFromParent();

332 }

333

335}

336

339

340 for (auto &MI : *MBB) {

341 for (auto &MO : MI.operands()) {

342 if (!MO.isReg())

343 continue;

344 if (!MO.isDef() && MO.isKill()) {

346 MO.setIsKill(false);

347 }

348

349 if (MO.isDef() && MO.isDead()) {

351 MO.setIsDead(false);

352 }

353 }

354 }

355

357}

358

360 unsigned BasicBlockNum, VRegRenamer &Renamer) {

362 dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << " \n\n";

363 dbgs() << "\n\n================================================\n\n";

364 });

365

367

368 LLVM_DEBUG(dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << "\n\n");

369

370 LLVM_DEBUG(dbgs() << "MBB Before Canonical Copy Propagation:\n";

371 MBB->dump(););

373 LLVM_DEBUG(dbgs() << "MBB After Canonical Copy Propagation:\n"; MBB->dump(););

374

376 unsigned IdempotentInstCount = 0;

379

380 Changed |= Renamer.renameVRegs(MBB, BasicBlockNum);

381

382

383

385

386 LLVM_DEBUG(dbgs() << "Updated MachineBasicBlock:\n"; MBB->dump();

387 dbgs() << "\n");

389 dbgs() << "\n\n================================================\n\n");

391}

392

393bool MIRCanonicalizer::runOnMachineFunction(MachineFunction &MF) {

394

395 static unsigned functionNum = 0;

398 return false;

400 << "\n";);

401 }

402

403

404

405 std::vector<MachineBasicBlock *> RPOList = GetRPOList(MF);

406

408 dbgs() << "\n\n NEW MACHINE FUNCTION: " << MF.getName() << " \n\n";

409 dbgs() << "\n\n================================================\n\n";

410 dbgs() << "Total Basic Blocks: " << RPOList.size() << "\n";

411 for (auto MBB

413 << "\n\n================================================\n\n";);

414

415 unsigned BBNum = 0;

418 VRegRenamer Renamer(MRI);

419 for (auto *MBB : RPOList)

421

423}

unsigned const MachineRegisterInfo * MRI

Expand Atomic instructions

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static bool runOnBasicBlock(MachineBasicBlock *MBB, unsigned BasicBlockNum, VRegRenamer &Renamer)

Definition MIRCanonicalizerPass.cpp:359

static bool rescheduleLexographically(std::vector< MachineInstr * > instructions, MachineBasicBlock *MBB, std::function< MachineBasicBlock::iterator()> getPos)

Definition MIRCanonicalizerPass.cpp:87

static cl::opt< unsigned > CanonicalizeFunctionNumber("canon-nth-function", cl::Hidden, cl::init(~0u), cl::value_desc("N"), cl::desc("Function number to canonicalize."))

static bool doDefKillClear(MachineBasicBlock *MBB)

Definition MIRCanonicalizerPass.cpp:337

static bool propagateLocalCopies(MachineBasicBlock *MBB)

Definition MIRCanonicalizerPass.cpp:290

static bool rescheduleCanonically(unsigned &PseudoIdempotentInstCount, MachineBasicBlock *MBB)

Definition MIRCanonicalizerPass.cpp:124

mir Rename Register Operands static false std::vector< MachineBasicBlock * > GetRPOList(MachineFunction &MF)

Definition MIRCanonicalizerPass.cpp:76

uint64_t IntrinsicInst * II

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.

Remove Loads Into Fake Uses

LLVM_ABI void setPreservesCFG()

This function should be called by the pass, iff they do not:

MachineInstrBundleIterator< MachineInstr > iterator

LLVM_ABI StringRef getName() const

Return the name of the corresponding LLVM basic block, or an empty string.

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.

StringRef getName() const

getName - Return the name of the corresponding LLVM function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Representation of each machine instruction.

const MachineBasicBlock * getParent() const

MachineOperand class - Representation of each machine instruction operand.

bool isReg() const

isReg - Tests if this is a MO_Register operand.

LLVM_ABI void dump() const

Register getReg() const

getReg - Returns the register number.

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

Wrapper class representing virtual and physical registers.

constexpr bool isVirtual() const

Return true if the specified register number is in the virtual register namespace.

VRegRenamer - This class is used for renaming vregs in a machine basic block according to semantics o...

A raw_ostream that writes to an std::string.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

LLVM_ABI char & MIRCanonicalizerID

MIRCanonicalizer - This pass canonicalizes MIR by renaming vregs according to the semantics of the in...

Definition MIRCanonicalizerPass.cpp:68

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

Implement std::hash so that hash_code can be used in STL containers.

Function object to check whether the first component of a container supported by std::get (like std::...