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

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)

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

82

84

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

192 if (MBB->empty())

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

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 }

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

272 }

273 }

275 while (!ArtifactList.empty()) {

278 "Expecting generic opcode");

282 continue;

283 }

287 WrapperObserver)) {

288 WorkListObserver.printNewInstrs();

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

312 return false;

314 init(MF);

319

320 std::unique_ptr MIRBuilder;

325 if (EnableCSE) {

326 MIRBuilder = std::make_unique();

328 MIRBuilder->setCSEInfo(CSEInfo);

329 } else

330 MIRBuilder = std::make_unique();

331

333 if (EnableCSE && CSEInfo) {

334

336 }

340 AuxObservers.push_back(&LocObserver);

341

342

345

348 *MIRBuilder, VT);

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

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

amdgpu aa AMDGPU Address space based Alias Analysis Wrapper

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)

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

Provides analysis for querying information about KnownBits during GISel passes.

GISelWorkList< 128 > ArtifactListTy

Definition Legalizer.cpp:117

DebugLocVerifyLevel

Definition Legalizer.cpp:49

@ None

Definition Legalizer.cpp:50

@ LegalizationsAndArtifactCombiners

Definition Legalizer.cpp:52

@ Legalizations

Definition Legalizer.cpp:51

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

GISelWorkList< 256 > InstListTy

Definition Legalizer.cpp:116

static bool isArtifact(const MachineInstr &MI)

Definition Legalizer.cpp:98

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.

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.

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

void addObserver(GISelChangeObserver *O)

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

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.

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

Definition Legalizer.cpp:309

void getAnalysisUsage(AnalysisUsage &AU) const override

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

Definition Legalizer.cpp:85

Legalizer()

Definition Legalizer.cpp:83

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

Definition Legalizer.cpp:176

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(char &ID)

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

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

AnalysisType & getAnalysis() const

getAnalysis() - This function is used by subclasses to get to the analysis information ...

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

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.

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

LLVM_ABI void reportGISelWarning(MachineFunction &MF, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)

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

LLVM_ABI raw_ostream & dbgs()

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

LLVM_ABI void reportGISelFailure(MachineFunction &MF, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)

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

LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)

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

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

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

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