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

1

2

3

4

5

6

7

8

9

10

15

16#define DEBUG_TYPE "cseinfo"

17

18using namespace llvm;

23}

25 "Analysis containing CSE Info", false, true)

28

29

30

33}

34

35

36

38 switch (Opc) {

39 default:

40 break;

41 case TargetOpcode::G_ADD:

42 case TargetOpcode::G_AND:

43 case TargetOpcode::G_ASHR:

44 case TargetOpcode::G_LSHR:

45 case TargetOpcode::G_MUL:

46 case TargetOpcode::G_OR:

47 case TargetOpcode::G_SHL:

48 case TargetOpcode::G_SUB:

49 case TargetOpcode::G_XOR:

50 case TargetOpcode::G_UDIV:

51 case TargetOpcode::G_SDIV:

52 case TargetOpcode::G_UREM:

53 case TargetOpcode::G_SREM:

54 case TargetOpcode::G_CONSTANT:

55 case TargetOpcode::G_FCONSTANT:

56 case TargetOpcode::G_IMPLICIT_DEF:

57 case TargetOpcode::G_ZEXT:

58 case TargetOpcode::G_SEXT:

59 case TargetOpcode::G_ANYEXT:

60 case TargetOpcode::G_UNMERGE_VALUES:

61 case TargetOpcode::G_TRUNC:

62 case TargetOpcode::G_PTR_ADD:

63 case TargetOpcode::G_EXTRACT:

64 case TargetOpcode::G_SELECT:

65 case TargetOpcode::G_BUILD_VECTOR:

66 case TargetOpcode::G_BUILD_VECTOR_TRUNC:

67 case TargetOpcode::G_SEXT_INREG:

68 case TargetOpcode::G_FADD:

69 case TargetOpcode::G_FSUB:

70 case TargetOpcode::G_FMUL:

71 case TargetOpcode::G_FDIV:

72 case TargetOpcode::G_FABS:

73

74 case TargetOpcode::G_FMAXNUM:

75 case TargetOpcode::G_FMINNUM:

76 case TargetOpcode::G_FMAXNUM_IEEE:

77 case TargetOpcode::G_FMINNUM_IEEE:

78 return true;

79 }

80 return false;

81}

82

84 return Opc == TargetOpcode::G_CONSTANT || Opc == TargetOpcode::G_FCONSTANT ||

85 Opc == TargetOpcode::G_IMPLICIT_DEF;

86}

87

88std::unique_ptr

90 std::unique_ptr Config;

92 Config = std::make_unique();

93 else

94 Config = std::make_unique();

96}

97

98

99

100

102 this->MF = &MF;

104}

105

107

108bool GISelCSEInfo::isUniqueMachineInstValid(

110

111

112

113

114 return true;

115}

116

117void GISelCSEInfo::invalidateUniqueMachineInstr(UniqueMachineInstr *UMI) {

118 bool Removed = CSEMap.RemoveNode(UMI);

119 (void)Removed;

120 assert(Removed && "Invalidation called on invalid UMI");

121

122}

123

126 void *&InsertPos) {

127 auto *Node = CSEMap.FindNodeOrInsertPos(ID, InsertPos);

129 if (!isUniqueMachineInstValid(*Node)) {

130 invalidateUniqueMachineInstr(Node);

131 return nullptr;

132 }

133

134 if (Node->MI->getParent() != MBB)

135 return nullptr;

136 }

138}

139

140void GISelCSEInfo::insertNode(UniqueMachineInstr *UMI, void *InsertPos) {

144 if (InsertPos)

145 CSEMap.InsertNode(UMI, InsertPos);

146 else

147 MaybeNewNode = CSEMap.GetOrInsertNode(UMI);

148 if (MaybeNewNode != UMI) {

149

150 return;

151 }

152 assert(InstrMapping.count(UMI->MI) == 0 &&

153 "This instruction should not be in the map");

154 InstrMapping[UMI->MI] = MaybeNewNode;

155}

156

158 assert(shouldCSE(MI->getOpcode()) && "Trying to CSE an unsupported Node");

161}

162

163void GISelCSEInfo::insertInstr(MachineInstr *MI, void *InsertPos) {

165

167 auto *Node = getUniqueInstrForMI(MI);

168 insertNode(Node, InsertPos);

169}

170

173 void *&InsertPos) {

175 if (auto *Inst = getNodeIfExists(ID, MBB, InsertPos)) {

176 LLVM_DEBUG(dbgs() << "CSEInfo::Found Instr " << *Inst->MI);

178 }

179 return nullptr;

180}

181

183#ifndef NDEBUG

184 if (OpcodeHitTable.count(Opc))

185 OpcodeHitTable[Opc] += 1;

186 else

187 OpcodeHitTable[Opc] = 1;

188#endif

189

190}

191

196 }

197}

198

200 assert(shouldCSE(MI->getOpcode()) && "Invalid instruction for CSE");

201 auto *UMI = InstrMapping.lookup(MI);

202 LLVM_DEBUG(dbgs() << "CSEInfo::Handling recorded MI " << *MI);

203 if (UMI) {

204

205 invalidateUniqueMachineInstr(UMI);

206 InstrMapping.erase(MI);

207 }

208

209 if (UMI) {

210

211

213 insertNode(UMI, nullptr);

214 } else {

215

216

217 insertInstr(MI);

218 }

219}

220

222 if (auto *UMI = InstrMapping.lookup(MI)) {

223 invalidateUniqueMachineInstr(UMI);

224 InstrMapping.erase(MI);

225 }

227}

228

230 if (HandlingRecordedInstrs)

231 return;

232 HandlingRecordedInstrs = true;

233 while (!TemporaryInsts.empty()) {

236 }

237 HandlingRecordedInstrs = false;

238}

239

241 assert(CSEOpt.get() && "CSEConfig not set");

242 return CSEOpt->shouldCSEOpc(Opc);

243}

244

248

251}

253

256 for (auto &MBB : MF) {

259 continue;

261 insertInstr(&MI);

262 }

263 }

264}

265

268 CSEMap.clear();

269 InstrMapping.clear();

270 UniqueInstrAllocator.Reset();

271 TemporaryInsts.clear();

272 CSEOpt.reset();

273 MRI = nullptr;

274 MF = nullptr;

275#ifndef NDEBUG

276 OpcodeHitTable.clear();

277#endif

278}

279

280#ifndef NDEBUG

284 return OS.str().c_str();

285}

286#endif

287

289#ifndef NDEBUG

290 std::string S1, S2;

292

293

294 for (auto &It : InstrMapping) {

297 void *InsertPos;

299 CSEMap.FindNodeOrInsertPos(TmpID, InsertPos);

300 if (FoundNode != It.second)

302 "CSEMap mismatch, InstrMapping has MIs without "

303 "corresponding Nodes in CSEMap:\n%s",

305 }

306

307

308

310 if (!InstrMapping.count(UMI.MI))

312 "Node in CSE without InstrMapping:\n%s",

314

315 if (InstrMapping[UMI.MI] != &UMI)

316 return createStringError(std::make_error_code(std::errc::not_supported),

317 "Mismatch in CSE mapping:\n%s\n%s",

320 }

321#endif

323}

324

327 for (auto &It : OpcodeHitTable)

328 dbgs() << "CSEInfo::CSE Hit for Opc " << It.first << " : " << It.second

329 << "\n";

330 });

331}

332

333

338 for (const auto &Op : MI->operands())

341 return *this;

342}

343

346 ID.AddInteger(Opc);

347 return *this;

348}

349

353 ID.AddInteger(Val);

354 return *this;

355}

356

359 ID.AddPointer(RC);

360 return *this;

361}

362

365 ID.AddPointer(RB);

366 return *this;

367}

368

372

374 if (RCOrRB) {

375 if (const auto *RB = dyn_cast_if_present<const RegisterBank *>(RCOrRB))

377 else

379 }

380 return *this;

381}

382

385 ID.AddInteger(Imm);

386 return *this;

387}

388

391 ID.AddInteger(Reg);

392 return *this;

393}

394

398 return *this;

399}

400

403 ID.AddPointer(MBB);

404 return *this;

405}

406

409 if (Flag)

410 ID.AddInteger(Flag);

411 return *this;

412}

413

417 return *this;

418}

419

422 if (MO.isReg()) {

426

427

430 } else if (MO.isImm())

432 else if (MO.isCImm())

438 else

440

441 return *this;

442}

443

446 bool Recompute) {

447 if (!AlreadyComputed || Recompute) {

451 AlreadyComputed = true;

452 }

453 return Info;

454}

458}

459

462 Wrapper.setMF(MF);

463 return false;

464}

block Block Frequency Analysis

static const char * stringify(const MachineInstr *MI, std::string &S)

Provides analysis for continuously CSEing during GISel passes.

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

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

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

separate const offset from Split GEPs to a variadic base and a constant offset for better CSE

Represent the analysis usage information of a pass.

void setPreservesAll()

Set by analyses that do not transform their input at all.

void Reset()

Deallocate all but the current slab and reset the current pointer to the beginning of it,...

bool shouldCSEOpc(unsigned Opc) override

bool shouldCSEOpc(unsigned Opc) override

------— CSEConfigFull -------— ///

This class represents an Operation in the Expression.

size_type count(const_arg_type_t< KeyT > Val) const

Return 1 if the specified key is in the map, 0 otherwise.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

FoldingSetNodeID - This class is used to gather all the unique data bits of a node.

The actual analysis pass wrapper.

void releaseMemory() override

releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...

bool runOnMachineFunction(MachineFunction &MF) override

runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...

GISelCSEAnalysisWrapperPass()

void setMF(MachineFunction &MFunc)

GISelCSEInfo & get(std::unique_ptr< CSEConfigBase > CSEOpt, bool ReCompute=false)

Takes a CSEConfigBase object that defines what opcodes get CSEd.

bool shouldCSE(unsigned Opc) const

void changingInstr(MachineInstr &MI) override

This instruction is about to be mutated in some way.

void analyze(MachineFunction &MF)

void changedInstr(MachineInstr &MI) override

This instruction was mutated in some way.

void recordNewInstruction(MachineInstr *MI)

Records a newly created inst in a list and lazily insert it to the CSEMap.

void setMF(MachineFunction &MF)

-----— GISelCSEInfo ----------—//

void erasingInstr(MachineInstr &MI) override

An instruction is about to be erased.

void countOpcodeHit(unsigned Opc)

void setCSEConfig(std::unique_ptr< CSEConfigBase > Opt)

void handleRecordedInsts()

Use this callback to insert all the recorded instructions.

void handleRecordedInst(MachineInstr *MI)

Use this callback to inform CSE about a newly fully created instruction.

void handleRemoveInst(MachineInstr *MI)

Remove this inst from the CSE map.

void createdInstr(MachineInstr &MI) override

An instruction has been created and inserted into the function.

const GISelInstProfileBuilder & addNodeIDOpcode(unsigned Opc) const

const GISelInstProfileBuilder & addNodeIDRegNum(Register Reg) const

const GISelInstProfileBuilder & addNodeIDFlag(unsigned Flag) const

const GISelInstProfileBuilder & addNodeIDImmediate(int64_t Imm) const

const GISelInstProfileBuilder & addNodeIDReg(Register Reg) const

const GISelInstProfileBuilder & addNodeID(const MachineInstr *MI) const

const GISelInstProfileBuilder & addNodeIDMBB(const MachineBasicBlock *MBB) const

const GISelInstProfileBuilder & addNodeIDRegType(const LLT Ty) const

const GISelInstProfileBuilder & addNodeIDMachineOperand(const MachineOperand &MO) const

void insert(MachineInstr *I)

Add the specified instruction to the worklist if it isn't already in it.

MachineInstr * pop_back_val()

void remove(const MachineInstr *I)

Remove I from the worklist if it exists.

constexpr uint64_t getUniqueRAWLLTData() const

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.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Representation of each machine instruction.

MachineOperand class - Representation of each machine instruction operand.

const ConstantInt * getCImm() const

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 isImm() const

isImm - Tests if this is a MO_Immediate operand.

Register getReg() const

getReg - Returns the register number.

const ConstantFP * getFPImm() const

unsigned getPredicate() const

static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)

bool isFPImm() const

isFPImm - Tests if this is a MO_FPImmediate operand.

VRegAttrs getVRegAttrs(Register Reg) const

Returns register class or bank and low level type of Reg.

static PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

This class implements the register bank concept.

Wrapper class representing virtual and physical registers.

A class that wraps MachineInstrs and derives from FoldingSetNode in order to be uniqued in a CSEMap.

A raw_ostream that writes to an std::string.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

This is an optimization pass for GlobalISel generic memory operations.

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)

raw_ostream & dbgs()

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

CodeGenOptLevel

Code generation optimization level.

void initializeGISelCSEAnalysisWrapperPassPass(PassRegistry &)

All attributes(register class or bank and low-level type) a virtual register can have.