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

1

2

3

4

5

6

7

8

9

10

11

30#include "llvm/Config/config.h"

37

38#define DEBUG_TYPE "instruction-select"

39

40using namespace llvm;

41

43 "Controls whether to select function with GlobalISel");

44

45#ifdef LLVM_GISEL_COV_PREFIX

48 cl::desc("Record GlobalISel rule coverage files of this "

49 "prefix if instrumentation was generated"));

50#else

52#endif

53

56 "Select target instructions out of generic instructions",

57 false, false)

65

68

69

70

71

72

73

74

75

76

78#ifndef NDEBUG

80#endif

81public:

83

85 llvm_unreachable("InstructionSelect does not track changed instructions!");

86 }

88 llvm_unreachable("InstructionSelect does not track changed instructions!");

89 }

90

93 }

94

98

99

100

102 LLVM_DEBUG(dbgs() << "Instruction removal updated iterator.\n");

103 }

104 }

105

108 if (CreatedInstrs.empty()) {

109 dbgs() << "Created no instructions.\n";

110 } else {

111 dbgs() << "Created:\n";

112 for (const auto *MI : CreatedInstrs) {

113 dbgs() << " " << *MI;

114 }

115 CreatedInstrs.clear();

116 }

117 });

118 }

119};

120

125

129 }

132}

133

135

138 return false;

139

141 ISel->TPC = &getAnalysis();

142

143

148

149 KB = &getAnalysis().get(MF);

151 PSI = &getAnalysis().getPSI();

153 BFI = &getAnalysis().getBFI();

154 }

155

157}

158

161 assert(ISel && "Cannot work without InstructionSelector");

162

166

167

170

171

172

174#ifndef NDEBUG

175

176

177

178

182 "instruction is not legal", *MI);

183 return false;

184 }

185

186

187 const size_t NumBlocks = MF.size();

188#endif

189

191

192 {

193

194

195

196

197

200 AllObservers.addObserver(&MIIMaintainer);

203

207

208

212

213 ++MIIMaintainer.MII;

214

221 return false;

222 }

224 }

225 }

226 }

227

230 continue;

231

233

234

235

237

238

239 continue;

240 }

241

244 ++MII;

245

246 if (MI.getOpcode() != TargetOpcode::COPY)

247 continue;

248 Register SrcReg = MI.getOperand(1).getReg();

249 Register DstReg = MI.getOperand(0).getReg();

251 auto SrcRC = MRI.getRegClass(SrcReg);

252 auto DstRC = MRI.getRegClass(DstReg);

253 if (SrcRC == DstRC) {

254 MRI.replaceRegWith(DstReg, SrcReg);

255 MI.eraseFromParent();

256 }

257 }

258 }

259 }

260

261#ifndef NDEBUG

263

264

265

266 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {

268

270 if (MRI.def_empty(VReg))

271 MI = &*MRI.def_instr_begin(VReg);

272 else if (MRI.use_empty(VReg)) {

273 MI = &*MRI.use_instr_begin(VReg);

274

275 if (MI->isDebugValue())

276 continue;

277 }

278 if (MI)

279 continue;

280

282 if (!RC) {

284 "VReg has no regclass after selection", *MI);

285 return false;

286 }

287

288 const LLT Ty = MRI.getType(VReg);

292 MF, TPC, MORE, "gisel-select",

293 "VReg's low-level type and register class have different sizes", *MI);

294 return false;

295 }

296 }

297

298 if (MF.size() != NumBlocks) {

301 nullptr);

302 R << "inserting blocks is not supported yet";

304 return false;

305 }

306#endif

307

309 dbgs() << "Falling back for function " << MF.getName() << "\n";

311 return false;

312 }

313

314

315

317 for (const auto &MBB : MF) {

319 break;

320

321 for (const auto &MI : MBB) {

322 if ((MI.isCall() && MI.isReturn()) || MI.isStackAligningInlineAsm())

324 if (MI.isInlineAsm())

326 }

327 }

328

329

332

334 dbgs() << "Rules covered by selecting function: " << MF.getName() << ":";

335 for (auto RuleID : CoverageInfo.covered())

336 dbgs() << " id" << RuleID;

337 dbgs() << "\n\n";

338 });

340 TLI.getTargetMachine().getTarget().getBackendName());

341

342

343

344

345 MRI.clearVirtRegTypes();

346

347

348 return true;

349}

350

353

354

355

359 MI.eraseFromParent();

360 return true;

361 }

362

363

365 MI.getOpcode() == TargetOpcode::G_CONSTANT_FOLD_BARRIER) {

366 auto [DstReg, SrcReg] = MI.getFirst2Regs();

367

368

369

370

371

373 if (DstRC)

374 MRI.setRegClass(SrcReg, DstRC);

376 "Must be able to replace dst with src!");

377 MI.eraseFromParent();

378 MRI.replaceRegWith(DstReg, SrcReg);

379 return true;

380 }

381

382 if (MI.getOpcode() == TargetOpcode::G_INVOKE_REGION_START) {

383 MI.eraseFromParent();

384 return true;

385 }

386

388}

unsigned const MachineRegisterInfo * MRI

AMDGPU Register Bank Select

This file provides an implementation of debug counters.

#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)

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

Provides analysis for querying information about KnownBits during GISel passes.

Select target instructions out of generic instructions

static const std::string CoveragePrefix

Interface for Targets to specify which operations they can successfully select and how the others sho...

unsigned const TargetRegisterInfo * TRI

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

This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...

This file implements a set that has insertion order iteration characteristics.

This file describes how to lower LLVM code to machine code.

Target-Independent Code Generator Pass Configuration Options pass.

This class observes instruction insertions/removals.

MachineBasicBlock::reverse_iterator MII

void reportFullyCreatedInstrs()

void erasingInstr(MachineInstr &MI) override

An instruction is about to be erased.

void changedInstr(MachineInstr &MI) override

This instruction was mutated in some way.

void changingInstr(MachineInstr &MI) override

This instruction is about to be mutated in some way.

void createdInstr(MachineInstr &MI) override

An instruction has been created and inserted into the function.

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.

iterator_range< const_covered_iterator > covered() const

bool emit(StringRef FilePrefix, StringRef BackendName) const

static bool shouldExecute(unsigned CounterName)

Implements a dense probed hash-table based set.

DISubprogram * getSubprogram() const

Get the attached subprogram.

bool hasOptNone() const

Do not optimize this function (-O0).

MachineBasicBlock * CurMBB

virtual void setupMF(MachineFunction &mf, GISelKnownBits *kb, CodeGenCoverage *covinfo=nullptr, ProfileSummaryInfo *psi=nullptr, BlockFrequencyInfo *bfi=nullptr)

Setup per-MF executor state.

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)

This pass is responsible for selecting generic machine instructions to target-specific instructions.

InstructionSelector * ISel

bool selectMachineFunction(MachineFunction &MF)

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

bool selectInstr(MachineInstr &MI)

GISelObserverWrapper * AllObservers

Note: InstructionSelect does not track changed instructions.

virtual bool select(MachineInstr &I)=0

Select the (possibly generic) instruction I to only use target-specific opcodes.

const TargetPassConfig * TPC

MachineOptimizationRemarkEmitter * MORE

constexpr bool isValid() const

constexpr TypeSize getSizeInBits() const

Returns the total size of the type. Must only be called on sized types.

This is an alternative analysis pass to BlockFrequencyInfoWrapperPass.

static void getLazyBFIAnalysisUsage(AnalysisUsage &AU)

Helper for client passes to set up the analysis usage on behalf of this pass.

reverse_iterator rbegin()

The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.

bool hasCalls() const

Return true if the current function has any function calls.

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.

MachineFunctionProperties & set(Property P)

bool hasProperty(Property P) const

void setHasInlineAsm(bool B)

Set a flag that indicates that the function contains inline assembly.

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.

bool hasInlineAsm() const

Returns true if the function contains any inline assembly.

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current 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.

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

instr_iterator getInstrIterator() const

Representation of each machine instruction.

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

An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.

bool hasProfileSummary() const

Returns true if profile summary is available.

A simple RAII based Delegate installer.

Wrapper class representing virtual and physical registers.

static Register index2VirtReg(unsigned Index)

Convert a 0-based index to a virtual register number.

constexpr bool isVirtual() const

Return true if the specified register number is in the virtual register namespace.

bool remove(const value_type &X)

Remove an item from the set vector.

void clear()

Completely clear the SetVector.

bool empty() const

Determine if the SetVector is empty or not.

bool insert(const value_type &X)

Insert a new element into the SetVector.

A SetVector that performs no allocations if smaller than a certain size.

virtual void finalizeLowering(MachineFunction &MF) const

Execute target specific actions to finalize target lowering.

CodeGenOptLevel getOptLevel() const

Returns the optimization level: None, Less, Default, or Aggressive.

Target-Independent Code Generator Pass Configuration Options.

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

virtual const TargetRegisterInfo * getRegisterInfo() const

getRegisterInfo - If register information is available, return it.

virtual InstructionSelector * getInstructionSelector() const

virtual const TargetLowering * getTargetLowering() const

std::pair< iterator, bool > insert(const ValueT &V)

bool contains(const_arg_type_t< ValueT > V) const

Check if the set contains the given element.

static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)

#define llvm_unreachable(msg)

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

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)

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

iterator_range< po_iterator< T > > post_order(const T &G)

bool isPreISelGenericOptimizationHint(unsigned Opcode)

cl::opt< bool > DisableGISelLegalityCheck

bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI)

Check if DstReg can be replaced with SrcReg depending on the register constraints.

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.

const MachineInstr * machineFunctionIsIllegal(const MachineFunction &MF)

Checks that MIR is fully legal, returns an illegal instruction if it's not, nullptr otherwise.

CodeGenOptLevel

Code generation optimization level.

void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)

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

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