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 return true;

69 }

70 return false;

71}

72

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

75 Opc == TargetOpcode::G_IMPLICIT_DEF;

76}

77

78std::unique_ptr

80 std::unique_ptr Config;

82 Config = std::make_unique();

83 else

84 Config = std::make_unique();

86}

87

88

89

90

92 this->MF = &MF;

94}

95

97

98bool GISelCSEInfo::isUniqueMachineInstValid(

100

101

102

103

104 return true;

105}

106

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

108 bool Removed = CSEMap.RemoveNode(UMI);

109 (void)Removed;

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

111

112}

113

116 void *&InsertPos) {

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

119 if (!isUniqueMachineInstValid(*Node)) {

120 invalidateUniqueMachineInstr(Node);

121 return nullptr;

122 }

123

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

125 return nullptr;

126 }

128}

129

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

134 if (InsertPos)

135 CSEMap.InsertNode(UMI, InsertPos);

136 else

137 MaybeNewNode = CSEMap.GetOrInsertNode(UMI);

138 if (MaybeNewNode != UMI) {

139

140 return;

141 }

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

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

144 InstrMapping[UMI->MI] = MaybeNewNode;

145}

146

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

151}

152

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

155

157 auto *Node = getUniqueInstrForMI(MI);

158 insertNode(Node, InsertPos);

159}

160

163 void *&InsertPos) {

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

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

168 }

169 return nullptr;

170}

171

173#ifndef NDEBUG

174 if (OpcodeHitTable.count(Opc))

175 OpcodeHitTable[Opc] += 1;

176 else

177 OpcodeHitTable[Opc] = 1;

178#endif

179

180}

181

186 }

187}

188

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

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

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

193 if (UMI) {

194

195 invalidateUniqueMachineInstr(UMI);

196 InstrMapping.erase(MI);

197 }

198

199 if (UMI) {

200

201

203 insertNode(UMI, nullptr);

204 } else {

205

206

207 insertInstr(MI);

208 }

209}

210

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

213 invalidateUniqueMachineInstr(UMI);

214 InstrMapping.erase(MI);

215 }

217}

218

220 if (HandlingRecordedInstrs)

221 return;

222 HandlingRecordedInstrs = true;

223 while (!TemporaryInsts.empty()) {

226 }

227 HandlingRecordedInstrs = false;

228}

229

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

232 return CSEOpt->shouldCSEOpc(Opc);

233}

234

238

241}

243

246 for (auto &MBB : MF) {

249 continue;

251 insertInstr(&MI);

252 }

253 }

254}

255

258 CSEMap.clear();

259 InstrMapping.clear();

260 UniqueInstrAllocator.Reset();

261 TemporaryInsts.clear();

262 CSEOpt.reset();

263 MRI = nullptr;

264 MF = nullptr;

265#ifndef NDEBUG

266 OpcodeHitTable.clear();

267#endif

268}

269

270#ifndef NDEBUG

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

275}

276#endif

277

279#ifndef NDEBUG

280 std::string S1, S2;

282

283

284 for (auto &It : InstrMapping) {

287 void *InsertPos;

289 CSEMap.FindNodeOrInsertPos(TmpID, InsertPos);

290 if (FoundNode != It.second)

292 "CSEMap mismatch, InstrMapping has MIs without "

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

295 }

296

297

298

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

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

304

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

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

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

310 }

311#endif

313}

314

317 for (auto &It : OpcodeHitTable)

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

319 << "\n";

320 });

321}

322

323

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

331 return *this;

332}

333

336 ID.AddInteger(Opc);

337 return *this;

338}

339

343 ID.AddInteger(Val);

344 return *this;

345}

346

349 ID.AddPointer(RC);

350 return *this;

351}

352

355 ID.AddPointer(RB);

356 return *this;

357}

358

362

364 if (RCOrRB) {

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

367 else

369 }

370 return *this;

371}

372

375 ID.AddInteger(Imm);

376 return *this;

377}

378

381 ID.AddInteger(Reg);

382 return *this;

383}

384

388 return *this;

389}

390

393 ID.AddPointer(MBB);

394 return *this;

395}

396

399 if (Flag)

400 ID.AddInteger(Flag);

401 return *this;

402}

403

407 return *this;

408}

409

412 if (MO.isReg()) {

416

417

420 } else if (MO.isImm())

422 else if (MO.isCImm())

428 else

430

431 return *this;

432}

433

436 bool Recompute) {

437 if (!AlreadyComputed || Recompute) {

441 AlreadyComputed = true;

442 }

443 return Info;

444}

448}

449

452 Wrapper.setMF(MF);

453 return false;

454}

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.