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;

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

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

28

29

30

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();

95 return Config;

96}

97

98

99

100

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);

128 if (Node) {

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) {

143 UniqueMachineInstr *MaybeNewNode = UMI;

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");

159 auto *Node = new (UniqueInstrAllocator) UniqueMachineInstr(MI);

161}

162

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

165

166 TemporaryInsts.remove(MI);

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);

177 return const_cast<MachineInstr *>(Inst->MI);

178 }

179 return nullptr;

180}

181

183#ifndef NDEBUG

184 ++OpcodeHitTable[Opc];

185#endif

186

187}

188

191 TemporaryInsts.insert(MI);

193 }

194}

195

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

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

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

200 if (UMI) {

201

202 invalidateUniqueMachineInstr(UMI);

203 InstrMapping.erase(MI);

204 }

205

206 if (UMI) {

207

208

210 insertNode(UMI, nullptr);

211 } else {

212

213

214 insertInstr(MI);

215 }

216}

217

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

220 invalidateUniqueMachineInstr(UMI);

221 InstrMapping.erase(MI);

222 }

223 TemporaryInsts.remove(MI);

224}

225

227 if (HandlingRecordedInstrs)

228 return;

229 HandlingRecordedInstrs = true;

230 while (!TemporaryInsts.empty()) {

231 auto *MI = TemporaryInsts.pop_back_val();

233 }

234 HandlingRecordedInstrs = false;

235}

236

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

239 return CSEOpt->shouldCSEOpc(Opc);

240}

241

250

253 for (auto &MBB : MF) {

256 continue;

258 insertInstr(&MI);

259 }

260 }

261}

262

265 CSEMap.clear();

266 InstrMapping.clear();

267 UniqueInstrAllocator.Reset();

268 TemporaryInsts.clear();

269 CSEOpt.reset();

270 MRI = nullptr;

271 MF = nullptr;

272#ifndef NDEBUG

273 OpcodeHitTable.clear();

274#endif

275}

276

277#ifndef NDEBUG

280 OS << *MI;

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

282}

283#endif

284

286#ifndef NDEBUG

287 std::string S1, S2;

289

290

291 for (auto &It : InstrMapping) {

294 void *InsertPos;

296 CSEMap.FindNodeOrInsertPos(TmpID, InsertPos);

297 if (FoundNode != It.second)

299 "CSEMap mismatch, InstrMapping has MIs without "

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

302 }

303

304

305

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

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

311

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

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

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

317 }

318#endif

320}

321

324 for (auto &It : OpcodeHitTable)

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

326 << "\n";

327 });

328}

329

330

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

338 return *this;

339}

340

343 ID.AddInteger(Opc);

344 return *this;

345}

346

349 uint64_t Val = Ty.getUniqueRAWLLTData();

350 ID.AddInteger(Val);

351 return *this;

352}

353

356 ID.AddPointer(RC);

357 return *this;

358}

359

362 ID.AddPointer(RB);

363 return *this;

364}

365

369

371 if (RCOrRB) {

374 else

376 }

377 return *this;

378}

379

382 ID.AddInteger(Imm);

383 return *this;

384}

385

388 ID.AddInteger(Reg.id());

389 return *this;

390}

391

397

400 ID.AddPointer(MBB);

401 return *this;

402}

403

406 if (Flag)

407 ID.AddInteger(Flag);

408 return *this;

409}

410

416

419 if (MO.isReg()) {

423

424

427 } else if (MO.isImm())

428 ID.AddInteger(MO.getImm());

429 else if (MO.isCImm())

430 ID.AddPointer(MO.getCImm());

432 ID.AddPointer(MO.getFPImm());

435 else

437

438 return *this;

439}

440

443 bool Recompute) {

444 if (!AlreadyComputed || Recompute) {

445 Info.releaseMemory();

446 Info.setCSEConfig(std::move(CSEOpt));

447 Info.analyze(*MF);

448 AlreadyComputed = true;

449 }

450 return Info;

451}

456

459 Wrapper.setMF(MF);

460 return false;

461}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

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

Definition CSEInfo.cpp:278

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)

Represent the analysis usage information of a pass.

void setPreservesAll()

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

bool shouldCSEOpc(unsigned Opc) override

Definition CSEInfo.cpp:83

bool shouldCSEOpc(unsigned Opc) override

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

Definition CSEInfo.cpp:37

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...

Definition CSEInfo.cpp:452

bool runOnMachineFunction(MachineFunction &MF) override

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

Definition CSEInfo.cpp:457

GISelCSEAnalysisWrapperPass()

Definition CSEInfo.cpp:20

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

Takes a CSEConfigBase object that defines what opcodes get CSEd.

Definition CSEInfo.cpp:442

bool shouldCSE(unsigned Opc) const

Definition CSEInfo.cpp:237

void changingInstr(MachineInstr &MI) override

This instruction is about to be mutated in some way.

Definition CSEInfo.cpp:244

void analyze(MachineFunction &MF)

Definition CSEInfo.cpp:251

void changedInstr(MachineInstr &MI) override

This instruction was mutated in some way.

Definition CSEInfo.cpp:249

void recordNewInstruction(MachineInstr *MI)

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

Definition CSEInfo.cpp:189

void setMF(MachineFunction &MF)

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

Definition CSEInfo.cpp:101

void erasingInstr(MachineInstr &MI) override

An instruction is about to be erased.

Definition CSEInfo.cpp:242

void countOpcodeHit(unsigned Opc)

Definition CSEInfo.cpp:182

void handleRecordedInsts()

Use this callback to insert all the recorded instructions.

Definition CSEInfo.cpp:226

void handleRecordedInst(MachineInstr *MI)

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

Definition CSEInfo.cpp:196

void handleRemoveInst(MachineInstr *MI)

Remove this inst from the CSE map.

Definition CSEInfo.cpp:218

void releaseMemory()

Definition CSEInfo.cpp:263

Error verify()

Definition CSEInfo.cpp:285

void print()

Definition CSEInfo.cpp:322

void createdInstr(MachineInstr &MI) override

An instruction has been created and inserted into the function.

Definition CSEInfo.cpp:243

LLVM_ABI const GISelInstProfileBuilder & addNodeIDOpcode(unsigned Opc) const

Definition CSEInfo.cpp:342

LLVM_ABI const GISelInstProfileBuilder & addNodeIDRegNum(Register Reg) const

Definition CSEInfo.cpp:387

LLVM_ABI const GISelInstProfileBuilder & addNodeIDFlag(unsigned Flag) const

Definition CSEInfo.cpp:405

LLVM_ABI const GISelInstProfileBuilder & addNodeIDImmediate(int64_t Imm) const

Definition CSEInfo.cpp:381

LLVM_ABI const GISelInstProfileBuilder & addNodeIDReg(Register Reg) const

Definition CSEInfo.cpp:412

LLVM_ABI const GISelInstProfileBuilder & addNodeID(const MachineInstr *MI) const

Definition CSEInfo.cpp:332

LLVM_ABI const GISelInstProfileBuilder & addNodeIDMBB(const MachineBasicBlock *MBB) const

Definition CSEInfo.cpp:399

GISelInstProfileBuilder(FoldingSetNodeID &ID, const MachineRegisterInfo &MRI)

LLVM_ABI const GISelInstProfileBuilder & addNodeIDRegType(const LLT Ty) const

Definition CSEInfo.cpp:348

LLVM_ABI const GISelInstProfileBuilder & addNodeIDMachineOperand(const MachineOperand &MO) const

Definition CSEInfo.cpp:417

MachineFunctionPass(char &ID)

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.

static LLVM_ABI 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.

LLVM_ABI void Profile(FoldingSetNodeID &ID)

-----— UniqueMachineInstr ----------—//

Definition CSEInfo.cpp:31

A raw_ostream that writes to an std::string.

std::string & str()

Returns the string's reference.

#define llvm_unreachable(msg)

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

unsigned ID

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

NodeAddr< NodeBase * > Node

This is an optimization pass for GlobalISel generic memory operations.

PointerUnion< const TargetRegisterClass *, const RegisterBank * > RegClassOrRegBank

Convenient type to represent either a register class or a register bank.

auto dyn_cast_if_present(const Y &Val)

dyn_cast_if_present - Functionally identical to dyn_cast, except that a null (or none in the case ...

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

Create formatted StringError object.

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

Definition CSEInfo.cpp:89

LLVM_ABI raw_ostream & dbgs()

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

CodeGenOptLevel

Code generation optimization level.

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

LLVM_ABI void initializeGISelCSEAnalysisWrapperPassPass(PassRegistry &)

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