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)

63 "Select target instructions out of generic instructions",

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

94

97 if (MII.getInstrIterator().getNodePtr() == &MI) {

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

133

135

137 return false;

138

140

141

146

150 if (PSI && PSI->hasProfileSummary())

152 }

153

155}

156

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

160

162 ISel->setupMF(MF, VT, &CoverageInfo, PSI, BFI);

163

164

167

168

169

171#ifndef NDEBUG

172

173

174

175

179 *MI);

180 return false;

181 }

182

183

184 const size_t NumBlocks = MF.size();

185#endif

186

188

189 {

190

191

192

193

194

197 AllObservers.addObserver(&MIIMaintainer);

199 ISel->AllObservers = &AllObservers;

200

204

205

206 MIIMaintainer.MII = MBB->rbegin();

207 for (auto End = MBB->rend(); MIIMaintainer.MII != End;) {

209

210 ++MIIMaintainer.MII;

211

217 return false;

218 }

220 }

221 }

222 }

223

225 if (MBB.empty())

226 continue;

227

229

230

231

232 MBB.clear();

233

234

235 continue;

236 }

237

238 for (auto MII = MBB.rbegin(), End = MBB.rend(); MII != End;) {

240 ++MII;

241

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

243 continue;

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

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

247 auto SrcRC = MRI.getRegClass(SrcReg);

248 auto DstRC = MRI.getRegClass(DstReg);

249 if (SrcRC == DstRC) {

250 MRI.replaceRegWith(DstReg, SrcReg);

251 MI.eraseFromParent();

252 }

253 }

254 }

255 }

256

257#ifndef NDEBUG

259

260

261

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

264

266 if (MRI.def_empty(VReg))

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

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

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

270

271 if (MI->isDebugValue())

272 continue;

273 }

274 if (MI)

275 continue;

276

278 if (!RC) {

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

281 return false;

282 }

283

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

285 if (Ty.isValid() &&

288 MF, MORE, "gisel-select",

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

290 return false;

291 }

292 }

293

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

297 nullptr);

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

300 return false;

301 }

302#endif

303

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

307 return false;

308 }

309

310

311

313 for (const auto &MBB : MF) {

315 break;

316

317 for (const auto &MI : MBB) {

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

320 if (MI.isInlineAsm())

322 }

323 }

324

325

328

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

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

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

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

334 });

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

337

338

339

340

341 MRI.clearVirtRegTypes();

342

343

344 return true;

345}

346

349

350

351

355 MI.eraseFromParent();

356 return true;

357 }

358

359

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

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

363

364

365

366

367

369 if (DstRC)

370 MRI.setRegClass(SrcReg, DstRC);

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

373 MI.eraseFromParent();

374 MRI.replaceRegWith(DstReg, SrcReg);

375 return true;

376 }

377

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

379 MI.eraseFromParent();

380 return true;

381 }

382

383 return ISel->select(MI);

384}

unsigned const MachineRegisterInfo * MRI

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

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.

static const std::string CoveragePrefix

Definition InstructionSelect.cpp:51

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

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

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.

Definition InstructionSelect.cpp:77

MachineBasicBlock::reverse_iterator MII

Definition InstructionSelect.cpp:82

void reportFullyCreatedInstrs()

Definition InstructionSelect.cpp:106

void erasingInstr(MachineInstr &MI) override

An instruction is about to be erased.

Definition InstructionSelect.cpp:95

void changedInstr(MachineInstr &MI) override

This instruction was mutated in some way.

Definition InstructionSelect.cpp:87

void changingInstr(MachineInstr &MI) override

This instruction is about to be mutated in some way.

Definition InstructionSelect.cpp:84

void createdInstr(MachineInstr &MI) override

An instruction has been created and inserted into the function.

Definition InstructionSelect.cpp:91

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(CounterInfo &Counter)

Implements a dense probed hash-table based set.

DISubprogram * getSubprogram() const

Get the attached subprogram.

bool hasOptNone() const

Do not optimize this function (-O0).

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

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

InstructionSelector * ISel

bool selectMachineFunction(MachineFunction &MF)

Definition InstructionSelect.cpp:157

void getAnalysisUsage(AnalysisUsage &AU) const override

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

Definition InstructionSelect.cpp:121

InstructionSelect(CodeGenOptLevel OL=CodeGenOptLevel::Default, char &PassID=ID)

Definition InstructionSelect.cpp:66

bool runOnMachineFunction(MachineFunction &MF) override

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

Definition InstructionSelect.cpp:134

bool selectInstr(MachineInstr &MI)

Definition InstructionSelect.cpp:347

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.

MachineInstrBundleIterator< MachineInstr, true > reverse_iterator

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

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

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

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

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

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.

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 InstructionSelector * getInstructionSelector() const

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

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)

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

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

bool isPreISelGenericOptimizationHint(unsigned Opcode)

LLVM_ABI cl::opt< bool > DisableGISelLegalityCheck

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

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

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.

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.

LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)

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

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