LLVM: lib/Target/WebAssembly/WebAssemblyRegStackify.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

37#include

38using namespace llvm;

39

40#define DEBUG_TYPE "wasm-reg-stackify"

41

42namespace {

45

46 StringRef getPassName() const override {

47 return "WebAssembly Register Stackify";

48 }

49

50 void getAnalysisUsage(AnalysisUsage &AU) const override {

55 }

62 }

63

65

66public:

67 static char ID;

71};

72}

73

74char WebAssemblyRegStackify::ID = 0;

76 "Reorder instructions to use the WebAssembly value stack",

77 false, false)

78

80 return new WebAssemblyRegStackify(OptLevel);

81}

82

83

84

85

87

88 if (MI->definesRegister(WebAssembly::VALUE_STACK, nullptr))

90 true,

91 true));

92

93

94 if (MI->readsRegister(WebAssembly::VALUE_STACK, nullptr))

96 false,

97 true));

98}

99

100

101

106 assert(MI->getOpcode() == TargetOpcode::IMPLICIT_DEF);

107

108 const auto *RegClass = MRI.getRegClass(MI->getOperand(0).getReg());

109 if (RegClass == &WebAssembly::I32RegClass) {

110 MI->setDesc(TII->get(WebAssembly::CONST_I32));

112 } else if (RegClass == &WebAssembly::I64RegClass) {

113 MI->setDesc(TII->get(WebAssembly::CONST_I64));

115 } else if (RegClass == &WebAssembly::F32RegClass) {

116 MI->setDesc(TII->get(WebAssembly::CONST_F32));

120 } else if (RegClass == &WebAssembly::F64RegClass) {

121 MI->setDesc(TII->get(WebAssembly::CONST_F64));

125 } else if (RegClass == &WebAssembly::V128RegClass) {

126 MI->setDesc(TII->get(WebAssembly::CONST_V128_I64x2));

129 } else {

131 }

132}

133

134

135

136

138 bool &Effects, bool &StackPointer) {

139

140 StackPointer = true;

141

146 if (!GA->isInterposable())

147 GV = GA->getAliasee();

148

150 if (F->doesNotThrow())

151 Effects = true;

152 if (F->doesNotAccessMemory())

153 return;

154 if (F->onlyReadsMemory()) {

156 return;

157 }

158 }

159 }

160

161

164 Effects = true;

165}

166

167

168

170 bool &Effects, bool &StackPointer) {

172

173 if (MI.isDebugInstr() || MI.isPosition())

174 return;

175

176

177 if (MI.mayLoad() && MI.isDereferenceableInvariantLoad())

179

180

181 if (MI.mayStore()) {

183 } else if (MI.hasOrderedMemoryRef()) {

184 switch (MI.getOpcode()) {

185 case WebAssembly::DIV_S_I32:

186 case WebAssembly::DIV_S_I64:

187 case WebAssembly::REM_S_I32:

188 case WebAssembly::REM_S_I64:

189 case WebAssembly::DIV_U_I32:

190 case WebAssembly::DIV_U_I64:

191 case WebAssembly::REM_U_I32:

192 case WebAssembly::REM_U_I64:

193 case WebAssembly::I32_TRUNC_S_F32:

194 case WebAssembly::I64_TRUNC_S_F32:

195 case WebAssembly::I32_TRUNC_S_F64:

196 case WebAssembly::I64_TRUNC_S_F64:

197 case WebAssembly::I32_TRUNC_U_F32:

198 case WebAssembly::I64_TRUNC_U_F32:

199 case WebAssembly::I32_TRUNC_U_F64:

200 case WebAssembly::I64_TRUNC_U_F64:

201

202

203

204

205 break;

206 default:

207

208

209 if (MI.isCall()) {

211 Effects = true;

212 }

213 break;

214 }

215 }

216

217

218 if (MI.hasUnmodeledSideEffects()) {

219 switch (MI.getOpcode()) {

220 case WebAssembly::DIV_S_I32:

221 case WebAssembly::DIV_S_I64:

222 case WebAssembly::REM_S_I32:

223 case WebAssembly::REM_S_I64:

224 case WebAssembly::DIV_U_I32:

225 case WebAssembly::DIV_U_I64:

226 case WebAssembly::REM_U_I32:

227 case WebAssembly::REM_U_I64:

228 case WebAssembly::I32_TRUNC_S_F32:

229 case WebAssembly::I64_TRUNC_S_F32:

230 case WebAssembly::I32_TRUNC_S_F64:

231 case WebAssembly::I64_TRUNC_S_F64:

232 case WebAssembly::I32_TRUNC_U_F32:

233 case WebAssembly::I64_TRUNC_U_F32:

234 case WebAssembly::I32_TRUNC_U_F64:

235 case WebAssembly::I64_TRUNC_U_F64:

236

237

238

239

240 break;

241 default:

242 Effects = true;

243 break;

244 }

245 }

246

247

248 if ((MI.getOpcode() == WebAssembly::GLOBAL_SET_I32 ||

249 MI.getOpcode() == WebAssembly::GLOBAL_SET_I64) &&

250 MI.getOperand(0).isSymbol() &&

251 !strcmp(MI.getOperand(0).getSymbolName(), "__stack_pointer"))

252 StackPointer = true;

253

254

255 if (MI.isCall()) {

257 }

258}

259

260

263 return Def.isAsCheapAsAMove() && TII->isTriviallyReMaterializable(Def);

264}

265

266

267

268

272

274 return Def;

275

276

277 if (LIS != nullptr) {

281 }

282

283 return nullptr;

284}

285

286

287

288

293

294

295

296 if (MRI.hasOneUse(Reg))

297 return false;

298

300 return false;

301 return true;

302 }

303

304

305 if (MRI.hasOneNonDBGUse(Reg))

306 return true;

307

308 if (LIS == nullptr)

309 return false;

310

311 bool HasOne = false;

313 const VNInfo *DefVNI =

316 for (auto &I : MRI.use_nodbg_operands(Reg)) {

318 if (Result.valueIn() == DefVNI) {

319 if (!Result.isKill())

320 return false;

321 if (HasOne)

322 return false;

323 HasOne = true;

324 }

325 }

326 return HasOne;

327}

328

329

330

331

332

333

342

343

344

345

346

347

348

349

350

351

352

353

355 return false;

356

357

358

359

360

361

362 for (const auto &SubsequentDef : drop_begin(DefI->defs())) {

365 for (; I != E; ++I) {

366 for (const auto &PriorUse : I->uses()) {

367 if (&PriorUse == Use)

368 break;

369 if (PriorUse.isReg() && SubsequentDef.getReg() == PriorUse.getReg())

370 return false;

371 }

372 }

373 }

374

375

378 for (auto E = MBB->end(); NextI != E && NextI->isDebugInstr(); ++NextI)

379 ;

380 if (NextI == Insert)

381 return true;

382

383

384

385

387 return false;

388

389

390

392 return false;

393

394

397 if (!MO.isReg() || MO.isUndef())

398 continue;

400

401

402 if (MO.isDead() && Insert->definesRegister(Reg, nullptr) &&

403 !Insert->readsRegister(Reg, nullptr))

404 continue;

405

406 if (Reg.isPhysical()) {

407

408

409 if (Reg == WebAssembly::ARGUMENTS)

410 continue;

411

412 if (MRI.isPhysRegModified(Reg))

413 continue;

414

415 return false;

416 }

417

418

419

420

421 if (!MO.isDef() && MRI.hasOneDef(Reg))

423 }

424

425 bool Read = false, Write = false, Effects = false, StackPointer = false;

427

428

429

430 bool HasMutableRegisters = !MutableRegisters.empty();

431 if (Read && Write && !Effects && !StackPointer && !HasMutableRegisters)

432 return true;

433

434

436 for (--I; I != D; --I) {

437 bool InterveningRead = false;

438 bool InterveningWrite = false;

439 bool InterveningEffects = false;

440 bool InterveningStackPointer = false;

441 query(*I, InterveningRead, InterveningWrite, InterveningEffects,

442 InterveningStackPointer);

443 if (Effects && InterveningEffects)

444 return false;

445 if (Read && InterveningWrite)

446 return false;

447 if (Write && (InterveningRead || InterveningWrite))

448 return false;

449 if (StackPointer && InterveningStackPointer)

450 return false;

451

452 for (unsigned Reg : MutableRegisters)

454 if (MO.isReg() && MO.isDef() && MO.getReg() == Reg)

455 return false;

456 }

457

458 return true;

459}

460

461

469

472

474 if (&Use == &OneUse)

475 continue;

476

479

480 if (UseVNI != OneUseVNI)

481 continue;

482

483 if (UseInst == OneUseInst) {

484

485

486 if (&OneUse > &Use)

487 return false;

488 } else {

489

490 while (!MDT.dominates(OneUseInst, UseInst)) {

491

492

493

494

495

497 return false;

500 return false;

503 return false;

504 assert(MRI.hasOneNonDBGUse(DefReg));

507 if (NewUseInst == OneUseInst) {

508 if (&OneUse > &NewUse)

509 return false;

510 break;

511 }

512 UseInst = NewUseInst;

513 }

514 }

515 }

516 return true;

517}

518

519

521 if (RC == &WebAssembly::I32RegClass)

522 return WebAssembly::TEE_I32;

523 if (RC == &WebAssembly::I64RegClass)

524 return WebAssembly::TEE_I64;

525 if (RC == &WebAssembly::F32RegClass)

526 return WebAssembly::TEE_F32;

527 if (RC == &WebAssembly::F64RegClass)

528 return WebAssembly::TEE_F64;

529 if (RC == &WebAssembly::V128RegClass)

530 return WebAssembly::TEE_V128;

531 if (RC == &WebAssembly::EXTERNREFRegClass)

532 return WebAssembly::TEE_EXTERNREF;

533 if (RC == &WebAssembly::FUNCREFRegClass)

534 return WebAssembly::TEE_FUNCREF;

535 if (RC == &WebAssembly::EXNREFRegClass)

536 return WebAssembly::TEE_EXNREF;

538}

539

540

547

548

549

555 LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());

556

558 DefDIs.sink(Insert);

559 if (LIS != nullptr)

561

562 if (MRI.hasOneDef(Reg) && MRI.hasOneNonDBGUse(Reg)) {

563

564

566 } else {

567

568

569 Register NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));

570 Op.setReg(NewReg);

572

573 if (LIS != nullptr) {

574

576

577

581 true);

582 }

583

585 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());

586 }

587

589 return Def;

590}

591

593 for (auto *I = MI->getPrevNode(); I; I = I->getPrevNode())

594 if (I->isDebugInstr())

595 return I;

596 return nullptr;

597}

598

599

600

607 LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump());

609

611

612 Register NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));

613 DefDIs.cloneSink(&*Insert, NewReg);

614 Op.setReg(NewReg);

621

623

624

630 }

631

632

640 }

641

642 return Clone;

643}

644

645

646

647

648

649

650

651

652

653

654

655

656

657

658

659

660

661

662

663

664

669 LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump());

670

671 const auto *RegClass = MRI.getRegClass(Reg);

672 Register TeeReg = MRI.createVirtualRegister(RegClass);

673 Register DefReg = MRI.createVirtualRegister(RegClass);

674

675

677 DefDIs.sink(Insert);

679

680

686 Op.setReg(TeeReg);

690

691

695 I->start = TeeIdx;

696 ValNo->def = TeeIdx;

698

699

706

707

708

709

710

711 DefDIs.cloneSink(Insert, TeeReg, false);

712

713 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());

715 return Def;

716}

717

718namespace {

719

720

721class TreeWalkerState {

723 using mop_reverse_iterator = std::reverse_iterator<mop_iterator>;

724 using RangeTy = iterator_range<mop_reverse_iterator>;

726

727public:

728 explicit TreeWalkerState(MachineInstr *Insert) {

729 const iterator_range<mop_iterator> &Range = Insert->explicit_uses();

730 if (Range.empty())

732 }

733

734 bool done() const { return Worklist.empty(); }

735

736 MachineOperand &pop() {

737 RangeTy &Range = Worklist.back();

738 MachineOperand &Op = *Range.begin();

740 if (Range.empty())

741 Worklist.pop_back();

742 assert((Worklist.empty() || !Worklist.back().empty()) &&

743 "Empty ranges shouldn't remain in the worklist");

744 return Op;

745 }

746

747

748 void pushOperands(MachineInstr *Instr) {

749 const iterator_range<mop_iterator> &Range(Instr->explicit_uses());

750 if (Range.empty())

752 }

753

754

755

756 void resetTopOperands(MachineInstr *Instr) {

757 assert(hasRemainingOperands(Instr) &&

758 "Reseting operands should only be done when the instruction has "

759 "an operand still on the stack");

760 Worklist.back() = reverse(Instr->explicit_uses());

761 }

762

763

764

765 bool hasRemainingOperands(const MachineInstr *Instr) const {

766 if (Worklist.empty())

767 return false;

768 const RangeTy &Range = Worklist.back();

769 return Range.empty() && Range.begin()->getParent() == Instr;

770 }

771

772

773

774

775

776

777

778 bool isOnStack(unsigned Reg) const {

779 for (const RangeTy &Range : Worklist)

780 for (const MachineOperand &MO : Range)

781 if (MO.isReg() && MO.getReg() == Reg)

782 return true;

783 return false;

784 }

785};

786

787

788

789class CommutingState {

790

791

792

793

794

795 bool TentativelyCommuting = false;

796 bool Declined = false;

797

798

799

800 unsigned Operand0, Operand1;

801

802public:

803

804

805

806 void maybeCommute(MachineInstr *Insert, TreeWalkerState &TreeWalker,

807 const WebAssemblyInstrInfo *TII) {

808 if (TentativelyCommuting) {

810 "Don't decline commuting until you've finished trying it");

811

813 TentativelyCommuting = false;

814 Declined = true;

815 } else if (!Declined && TreeWalker.hasRemainingOperands(Insert)) {

819

821 TreeWalker.resetTopOperands(Insert);

822 TentativelyCommuting = true;

823 Declined = false;

824 }

825 }

826 }

827

828

829

830 void reset() {

831 TentativelyCommuting = false;

832 Declined = false;

833 }

834};

835}

836

837bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {

838 LLVM_DEBUG(dbgs() << "********** Register Stackifying **********\n"

839 "********** Function: "

840 << MF.getName() << '\n');

841

844 WebAssemblyFunctionInfo &MFI = *MF.getInfo();

845 const auto *TII = MF.getSubtarget().getInstrInfo();

846 MachineDominatorTree *MDT = nullptr;

847 LiveIntervals *LIS = nullptr;

849 MDT = &getAnalysis().getDomTree();

850 LIS = &getAnalysis().getLIS();

851 }

852

853

854

855

856 for (MachineBasicBlock &MBB : MF) {

857

858

860 MachineInstr *Insert = &*MII;

861

862

863 if (Insert->isInlineAsm())

864 continue;

865

866

867 if (Insert->isDebugValue())

868 continue;

869

870

871 if (Insert->isFakeUse())

872 continue;

873

874

875

876 CommutingState Commuting;

877 TreeWalkerState TreeWalker(Insert);

878 while (!TreeWalker.done()) {

879 MachineOperand &Use = TreeWalker.pop();

880

881

882 if (Use.isReg())

883 continue;

884

886 assert(Use.isUse() && "explicit_uses() should only iterate over uses");

888 "explicit_uses() should only iterate over explicit operands");

890 continue;

891

892

894 if (!DefI)

895 continue;

896

897

898

900 continue;

901

902

903

905 continue;

906

907 MachineOperand *Def =

909 assert(Def != nullptr);

910

911

912

913

914

915

916

918 bool CanMove = SameBlock &&

920 !TreeWalker.isOnStack(Reg);

923

924

925

926

930 "Stackifying away frame base in unoptimized code not expected");

932 }

935 *LIS, MFI, MRI, TII);

936 } else if (Optimize && CanMove &&

938 MFI)) {

941 } else {

942

943

944 if (!CanMove && SameBlock)

945 Commuting.maybeCommute(Insert, TreeWalker, TII);

946

947 continue;

948 }

949

950

951

952

953 auto *SubsequentDef = Insert->defs().begin();

954 auto *SubsequentUse = &Use;

955 while (SubsequentDef != Insert->defs().end() &&

956 SubsequentUse != Use.getParent()->uses().end()) {

957 if (!SubsequentDef->isReg() || !SubsequentUse->isReg())

958 break;

959 Register DefReg = SubsequentDef->getReg();

961

962 if (DefReg != UseReg ||

964 break;

966 ++SubsequentDef;

967 ++SubsequentUse;

968 }

969

970

971

972

973 if (Insert->getOpcode() == TargetOpcode::IMPLICIT_DEF)

975

976

977

978 Commuting.reset();

979 TreeWalker.pushOperands(Insert);

980 }

981

982

983

984 if (Insert != &*MII) {

988 }

989 }

990 }

991

992

993

995 MF.getRegInfo().addLiveIn(WebAssembly::VALUE_STACK);

996 for (MachineBasicBlock &MBB : MF)

998 }

999

1000#ifndef NDEBUG

1001

1002 SmallVector<unsigned, 0> Stack;

1003 for (MachineBasicBlock &MBB : MF) {

1004 for (MachineInstr &MI : MBB) {

1005 if (MI.isDebugInstr())

1006 continue;

1007 for (MachineOperand &MO : reverse(MI.explicit_uses())) {

1008 if (!MO.isReg())

1009 continue;

1013 "Register stack pop should be paired with a push");

1014 }

1015 for (MachineOperand &MO : MI.defs()) {

1016 if (!MO.isReg())

1017 continue;

1020 Stack.push_back(MO.getReg());

1021 }

1022 }

1023

1024

1026 "Register stack pushes and pops should be balanced");

1027 }

1028#endif

1029

1031}

unsigned const MachineRegisterInfo * MRI

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

const TargetInstrInfo & TII

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static Register UseReg(const MachineOperand &MO)

Promote Memory to Register

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

static bool isSafeToMove(const MachineInstr &From, const MachineInstr &To)

Check if it's safe to move From down to To, checking that no physical registers are clobbered.

This file contains the declaration of the WebAssembly-specific manager for DebugValues associated wit...

This file provides WebAssembly-specific target descriptions.

This file declares WebAssembly-specific per-machine-function information.

static bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use, const MachineInstr *Insert, const WebAssemblyFunctionInfo &MFI, const MachineRegisterInfo &MRI, bool Optimize)

Definition WebAssemblyRegStackify.cpp:334

static unsigned getTeeOpcode(const TargetRegisterClass *RC)

Get the appropriate tee opcode for the given register class.

Definition WebAssemblyRegStackify.cpp:520

static MachineInstr * rematerializeCheapDef(unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock::instr_iterator Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII)

A trivially cloneable instruction; clone it and nest the new copy with the current instruction.

Definition WebAssemblyRegStackify.cpp:602

static void imposeStackOrdering(MachineInstr *MI)

Definition WebAssemblyRegStackify.cpp:86

static MachineInstr * moveForSingleUse(unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals *LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI)

A single-use def in the same block with no intervening memory or register dependencies; move the def ...

Definition WebAssemblyRegStackify.cpp:550

static void query(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)

Definition WebAssemblyRegStackify.cpp:169

static void shrinkToUses(LiveInterval &LI, LiveIntervals &LIS)

Definition WebAssemblyRegStackify.cpp:541

static void convertImplicitDefToConstZero(MachineInstr *MI, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineFunction &MF)

Definition WebAssemblyRegStackify.cpp:102

static bool hasSingleUse(unsigned Reg, MachineRegisterInfo &MRI, WebAssemblyFunctionInfo &MFI, bool Optimize, MachineInstr *Def, LiveIntervals *LIS)

Definition WebAssemblyRegStackify.cpp:289

static MachineInstr * getPrevNonDebugInst(MachineInstr *MI)

Definition WebAssemblyRegStackify.cpp:592

static bool shouldRematerialize(const MachineInstr &Def, const WebAssemblyInstrInfo *TII)

Definition WebAssemblyRegStackify.cpp:261

static MachineInstr * moveAndTeeForMultiUse(unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII)

A multiple-use def in the same block with no intervening memory or register dependencies; move the de...

Definition WebAssemblyRegStackify.cpp:665

static bool oneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse, const MachineBasicBlock &MBB, const MachineRegisterInfo &MRI, const MachineDominatorTree &MDT, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI)

Test whether OneUse, a use of Reg, dominates all of Reg's other uses.

Definition WebAssemblyRegStackify.cpp:462

static void queryCallee(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)

Definition WebAssemblyRegStackify.cpp:137

This file declares the WebAssembly-specific subclass of TargetSubtarget.

This file contains the declaration of the WebAssembly-specific utility functions.

This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.

Represent the analysis usage information of a pass.

AnalysisUsage & addPreservedID(const void *ID)

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

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

LLVM_ABI void setPreservesCFG()

This function should be called by the pass, iff they do not:

This is an important base class in LLVM.

static LLVM_ABI Constant * getNullValue(Type *Ty)

Constructor to create a '0' constant of arbitrary type.

FunctionPass class - This class is used to implement most global optimizations.

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

LiveInterval - This class represents the liveness of a register, or stack slot.

MachineInstr * getInstructionFromIndex(SlotIndex index) const

Returns the instruction associated with the given index.

SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)

LLVM_ABI void handleMove(MachineInstr &MI, bool UpdateFlags=false)

Call this method to notify LiveIntervals that instruction MI has been moved within a basic block.

SlotIndex getInstructionIndex(const MachineInstr &Instr) const

Returns the base index of the given instruction.

void RemoveMachineInstrFromMaps(MachineInstr &MI)

LiveInterval & getInterval(Register Reg)

void removeInterval(Register Reg)

Interval removal.

LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)

After removing some uses of a register, shrink its live range to just the remaining uses.

LLVM_ABI void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)

Remove value numbers and related live segments starting at position Pos that are part of any liverang...

LLVM_ABI void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval * > &SplitLIs)

Split separate components in LiveInterval LI into separate intervals.

LiveInterval & createAndComputeVirtRegInterval(Register Reg)

Segments::iterator iterator

bool liveAt(SlotIndex index) const

LiveQueryResult Query(SlotIndex Idx) const

Query Liveness at Idx.

VNInfo * getVNInfoBefore(SlotIndex Idx) const

getVNInfoBefore - Return the VNInfo that is live up to but not necessarily including Idx,...

iterator FindSegmentContaining(SlotIndex Idx)

Return an iterator to the segment that contains the specified index, or end() if there is none.

LLVM_ABI void removeSegment(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo=false)

Remove the specified interval from this live range.

VNInfo * getVNInfoAt(SlotIndex Idx) const

getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.

unsigned getNumDefs() const

Return the number of MachineOperands that are register definitions.

static MCRegister from(unsigned Val)

Check the provided unsigned value is a valid MCRegister.

MachineInstrBundleIterator< const MachineInstr > const_iterator

Instructions::iterator instr_iterator

void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())

Adds the specified register as a live in.

reverse_iterator rbegin()

MachineInstrBundleIterator< MachineInstr > iterator

Analysis pass which computes a MachineDominatorTree.

DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...

bool dominates(const MachineInstr *A, const MachineInstr *B) 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.

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.

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const

Add a new virtual register operand.

reverse_iterator getReverse() const

Get a reverse iterator to the same node.

Representation of each machine instruction.

mop_range defs()

Returns all explicit operands that are register definitions.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineBasicBlock * getParent() const

const MCInstrDesc & getDesc() const

Returns the target instruction descriptor of this MachineInstr.

MachineOperand * mop_iterator

iterator/begin/end - Iterate over all operands of a machine instruction.

LLVM_ABI void dump() const

const MachineOperand & getOperand(unsigned i) const

MachineOperand * findRegisterDefOperand(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false)

Wrapper for findRegisterDefOperandIdx, it returns a pointer to the MachineOperand rather than an inde...

MachineOperand class - Representation of each machine instruction operand.

const GlobalValue * getGlobal() const

static MachineOperand CreateFPImm(const ConstantFP *CFP)

bool isReg() const

isReg - Tests if this is a MO_Register operand.

MachineInstr * getParent()

getParent - Return the instruction that this operand belongs to.

static MachineOperand CreateImm(int64_t Val)

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

Register getReg() const

getReg - Returns the register number.

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)

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

Wrapper class representing virtual and physical registers.

constexpr bool isVirtual() const

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

constexpr bool isPhysical() const

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

SlotIndex - An opaque wrapper around machine indexes.

SlotIndex getDeadSlot() const

Returns the dead def kill slot for the current instruction.

SlotIndex getRegSlot(bool EC=false) const

Returns the register use/def slot in the current instruction for a normal or early-clobber def.

void push_back(const T &Elt)

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

StringRef - Represent a constant reference to a string, i.e.

TargetInstrInfo - Interface to description of machine instruction set.

virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const

Returns true iff the routine could find two commutable operands in the given machine instruction.

MachineInstr * commuteInstruction(MachineInstr &MI, bool NewMI=false, unsigned OpIdx1=CommuteAnyOperandIndex, unsigned OpIdx2=CommuteAnyOperandIndex) const

This method commutes the operands of the given machine instruction MI.

static const unsigned CommuteAnyOperandIndex

static LLVM_ABI Type * getDoubleTy(LLVMContext &C)

static LLVM_ABI Type * getFloatTy(LLVMContext &C)

A Use represents the edge between a Value definition and its users.

VNInfo - Value Number Information.

SlotIndex def

The index of the defining instruction.

void updateReg(Register Reg)

void cloneSink(MachineInstr *Insert, Register NewReg=Register(), bool CloneDef=true) const

void sink(MachineInstr *Insert)

This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...

void stackifyVReg(MachineRegisterInfo &MRI, Register VReg)

unsigned getFrameBaseVreg() const

bool isVRegStackified(Register VReg) const

void clearFrameBaseVreg()

bool isFrameBaseVirtual() const

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

@ Define

Register definition.

bool isArgument(unsigned Opc)

const MachineOperand & getCalleeOp(const MachineInstr &MI)

Returns the operand number of a callee, assuming the argument is a call instruction.

bool isCatch(unsigned Opc)

NodeAddr< DefNode * > Def

NodeAddr< InstrNode * > Instr

NodeAddr< UseNode * > Use

This is an optimization pass for GlobalISel generic memory operations.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

decltype(auto) dyn_cast(const From &Val)

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

FunctionPass * createWebAssemblyRegStackify(CodeGenOptLevel OptLevel)

auto reverse(ContainerTy &&C)

LLVM_ABI raw_ostream & dbgs()

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

CodeGenOptLevel

Code generation optimization level.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

unsigned getUndefRegState(bool B)

DWARFExpression::Operation Op

LLVM_ABI char & LiveVariablesID

LiveVariables pass - This pass computes the set of blocks in which each variable is life and sets mac...

decltype(auto) cast(const From &Val)

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

MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)