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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

32

33#define DEBUG_TYPE "legalizer"

34

35using namespace llvm;

36

39 cl::desc("Should enable CSE in Legalizer"),

41

42

44 "allow-ginsert-as-artifact",

45 cl::desc("Allow G_INSERT to be considered an artifact. Hack around AMDGPU "

46 "test infinite loops."),

48

53};

54#ifndef NDEBUG

56 "verify-legalizer-debug-locs",

57 cl::desc("Verify that debug locations are handled"),

61 "Verify legalizations"),

63 "legalizations+artifactcombiners",

64 "Verify legalizations and artifact combines")),

66#else

67

68

70#endif

71

74 "Legalize the Machine IR a function's Machine IR", false,

75 false)

82

84

93}

94

96}

97

99 switch (MI.getOpcode()) {

100 default:

101 return false;

102 case TargetOpcode::G_TRUNC:

103 case TargetOpcode::G_ZEXT:

104 case TargetOpcode::G_ANYEXT:

105 case TargetOpcode::G_SEXT:

106 case TargetOpcode::G_MERGE_VALUES:

107 case TargetOpcode::G_UNMERGE_VALUES:

108 case TargetOpcode::G_CONCAT_VECTORS:

109 case TargetOpcode::G_BUILD_VECTOR:

110 case TargetOpcode::G_EXTRACT:

111 return true;

112 case TargetOpcode::G_INSERT:

114 }

115}

118

119namespace {

123#ifndef NDEBUG

125#endif

126

127public:

129 : InstList(Insts), ArtifactList(Arts) {}

130

132

133

134

138 else

140 }

141 }

142

145 createdOrChangedInstr(MI);

146 }

147

148 void printNewInstrs() {

150 for (const auto *MI : NewMIs)

151 dbgs() << ".. .. New MI: " << *MI;

152 NewMIs.clear();

153 });

154 }

155

160 }

161

164 }

165

167

168

170 createdOrChangedInstr(MI);

171 }

172};

173}

174

181 MIRBuilder.setMF(MF);

183

184

188

189

190

191 for (auto *MBB : RPOT) {

193 continue;

195

196

198 continue;

201 else

203 }

204 }

207

208

209 LegalizerWorkListManager WorkListObserver(InstList, ArtifactList);

210

211

215

216

217

219 LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder, KB);

221 bool Changed = false;

223 do {

225 assert(RetryList.empty() && "Expected no instructions in RetryList");

226 unsigned NumArtifacts = ArtifactList.size();

227 while (!InstList.empty()) {

230 "Expecting generic opcode");

234 continue;

235 }

236

237

239

240

242

243

244

246 LLVM_DEBUG(dbgs() << ".. Not legalized, moving to artifacts retry\n");

247 assert(NumArtifacts == 0 &&

248 "Artifacts are only expected in instruction list starting the "

249 "second iteration, but each iteration starting second must "

250 "start with an empty artifacts list");

251 (void)NumArtifacts;

253 continue;

254 }

256 return {Changed, &MI};

257 }

258 WorkListObserver.printNewInstrs();

261 }

262

263

264 if (!RetryList.empty()) {

265 if (!ArtifactList.empty()) {

266 while (!RetryList.empty())

268 } else {

269 LLVM_DEBUG(dbgs() << "No new artifacts created, not retrying!\n");

271 return {Changed, RetryList.front()};

272 }

273 }

275 while (!ArtifactList.empty()) {

278 "Expecting generic opcode");

282 continue;

283 }

287 WrapperObserver)) {

288 WorkListObserver.printNewInstrs();

292 DebugLocVerifyLevel::LegalizationsAndArtifactCombiners);

293 Changed = true;

294 continue;

295 }

296

297

298

299 else {

300 LLVM_DEBUG(dbgs() << ".. Not combined, moving to instructions list\n");

302 }

303 }

304 } while (!InstList.empty());

305

306 return {Changed, nullptr};

307}

308

310

313 return false;

315 init(MF);

316 const TargetPassConfig &TPC = getAnalysis();

318 getAnalysis().getCSEWrapper();

320

321 std::unique_ptr MIRBuilder;

326 if (EnableCSE) {

327 MIRBuilder = std::make_unique();

329 MIRBuilder->setCSEInfo(CSEInfo);

330 } else

331 MIRBuilder = std::make_unique();

332

334 if (EnableCSE && CSEInfo) {

335

337 }

341 AuxObservers.push_back(&LocObserver);

342

343

344 GISelKnownBits *KB = &getAnalysis().get(MF);

345

348 *MIRBuilder, KB);

349

350 if (Result.FailedOn) {

352 "unable to legalize instruction", *Result.FailedOn);

353 return false;

354 }

355

359 &*MF.begin());

360 R << "lost "

362 << " debug locations during pass";

364

365

366

367

368

369

370

371

372

373

374

375 }

376

377

378

379

380

381 if (!EnableCSE)

382 Wrapper.setComputed(false);

383 return Result.Changed;

384}

unsigned const MachineRegisterInfo * MRI

amdgpu aa AMDGPU Address space based Alias Analysis Wrapper

AMDGPU Register Bank Legalize

COFF::MachineTypes Machine

Provides analysis for continuously CSEing during GISel passes.

This file implements a version of MachineIRBuilder which CSEs insts within a MachineBasicBlock.

#define clEnumValN(ENUMVAL, FLAGNAME, DESC)

Performs the initial survey of the specified function

This contains common code to allow clients to notify changes to machine instr.

Provides analysis for querying information about KnownBits during GISel passes.

Legalize the Machine IR a function s Machine IR

@ LegalizationsAndArtifactCombiners

static cl::opt< DebugLocVerifyLevel > VerifyDebugLocs("verify-legalizer-debug-locs", cl::desc("Verify that debug locations are handled"), cl::values(clEnumValN(DebugLocVerifyLevel::None, "none", "No verification"), clEnumValN(DebugLocVerifyLevel::Legalizations, "legalizations", "Verify legalizations"), clEnumValN(DebugLocVerifyLevel::LegalizationsAndArtifactCombiners, "legalizations+artifactcombiners", "Verify legalizations and artifact combines")), cl::init(DebugLocVerifyLevel::Legalizations))

static cl::opt< bool > EnableCSEInLegalizer("enable-cse-in-legalizer", cl::desc("Should enable CSE in Legalizer"), cl::Optional, cl::init(false))

static cl::opt< bool > AllowGInsertAsArtifact("allow-ginsert-as-artifact", cl::desc("Allow G_INSERT to be considered an artifact. Hack around AMDGPU " "test infinite loops."), cl::Optional, cl::init(true))

static bool isArtifact(const MachineInstr &MI)

Tracks DebugLocs between checkpoints and verifies that they are transferred.

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

Target-Independent Code Generator Pass Configuration Options pass.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

DISubprogram * getSubprogram() const

Get the attached subprogram.

The actual analysis pass wrapper.

Simple wrapper that does the following.

Abstract class that contains various methods for clients to notify about changes.

To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelKnownBitsInfoAnalysis...

Simple wrapper observer that takes several observers, and calls each one for each event.

void addObserver(GISelChangeObserver *O)

void insert(MachineInstr *I)

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

MachineInstr * pop_back_val()

void deferred_insert(MachineInstr *I)

void remove(const MachineInstr *I)

Remove I from the worklist if it exists.

bool tryCombineInstruction(MachineInstr &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, GISelObserverWrapper &WrapperObserver)

Try to combine away MI.

@ Legalized

Instruction has been legalized and the MachineFunction changed.

@ UnableToLegalize

Some kind of error has occurred and we could not legalize this instruction.

MachineIRBuilder & MIRBuilder

Expose MIRBuilder so clients can set their own RecordInsertInstruction functions.

LegalizeResult legalizeInstrStep(MachineInstr &MI, LostDebugLocObserver &LocObserver)

Replace MI by a sequence of legal instructions that can implement the same operation.

bool runOnMachineFunction(MachineFunction &MF) override

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

void getAnalysisUsage(AnalysisUsage &AU) const override

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

static MFResult legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, ArrayRef< GISelChangeObserver * > AuxObservers, LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder, GISelKnownBits *KB)

void checkpoint(bool CheckDebugLocs=true)

Call this to indicate that it's a good point to assess whether locations have been lost.

unsigned getNumLostDebugLocs() 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.

bool hasProperty(Property P) const

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

StringRef getName() const

getName - Return the name of the corresponding LLVM function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

const MachineFunctionProperties & getProperties() const

Get the function properties.

Helper class to build MachineInstr.

void stopObservingChanges()

void setMF(MachineFunction &MF)

Representation of each machine instruction.

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

Class to install both of the above.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

Target-Independent Code Generator Pass Configuration Options.

virtual std::unique_ptr< CSEConfigBase > getCSEConfig() const

Returns the CSEConfig object to use for the current optimization level.

virtual bool isGISelCSEEnabled() const

Check whether continuous CSE should be enabled in GISel passes.

virtual const LegalizerInfo * getLegalizerInfo() const

int getNumOccurrences() const

ValuesClass values(OptsTy... Options)

Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...

initializer< Ty > init(const Ty &Val)

DiagnosticInfoOptimizationBase::Argument NV

This is an optimization pass for GlobalISel generic memory operations.

bool errorToBool(Error Err)

Helper for converting an Error to a bool.

void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)

Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...

bool isPreISelGenericOpcode(unsigned Opcode)

Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.

void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)

Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.

raw_ostream & dbgs()

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

void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)

Modify analysis usage so it preserves passes required for the SelectionDAG fallback.

void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)

void eraseInstrs(ArrayRef< MachineInstr * > DeadInstrs, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)

bool isTriviallyDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)

Check whether an instruction MI is dead: it only defines dead virtual registers, and doesn't have oth...

void reportGISelWarning(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)

Report an ISel warning as a missed optimization remark to the LLVMContext's diagnostic stream.