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 return "WebAssembly Register Stackify";

46 }

47

58 }

59

61

62public:

63 static char ID;

65};

66}

67

68char WebAssemblyRegStackify::ID = 0;

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

71 false, false)

72

74 return new WebAssemblyRegStackify();

75}

76

77

78

79

81

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

84 true,

85 true));

86

87

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

90 false,

91 true));

92}

93

94

95

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

102

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

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

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

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

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

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

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

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

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

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

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

124 } else {

126 }

127}

128

129

130

131

133 bool &Effects, bool &StackPointer) {

134

135 StackPointer = true;

136

140 if (const auto *GA = dyn_cast(GV))

141 if (!GA->isInterposable())

142 GV = GA->getAliasee();

143

144 if (const auto *F = dyn_cast(GV)) {

145 if (F->doesNotThrow())

146 Effects = true;

147 if (F->doesNotAccessMemory())

148 return;

149 if (F->onlyReadsMemory()) {

151 return;

152 }

153 }

154 }

155

156

159 Effects = true;

160}

161

162

163

165 bool &Effects, bool &StackPointer) {

167

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

169 return;

170

171

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

174

175

176 if (MI.mayStore()) {

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

179 switch (MI.getOpcode()) {

180 case WebAssembly::DIV_S_I32:

181 case WebAssembly::DIV_S_I64:

182 case WebAssembly::REM_S_I32:

183 case WebAssembly::REM_S_I64:

184 case WebAssembly::DIV_U_I32:

185 case WebAssembly::DIV_U_I64:

186 case WebAssembly::REM_U_I32:

187 case WebAssembly::REM_U_I64:

188 case WebAssembly::I32_TRUNC_S_F32:

189 case WebAssembly::I64_TRUNC_S_F32:

190 case WebAssembly::I32_TRUNC_S_F64:

191 case WebAssembly::I64_TRUNC_S_F64:

192 case WebAssembly::I32_TRUNC_U_F32:

193 case WebAssembly::I64_TRUNC_U_F32:

194 case WebAssembly::I32_TRUNC_U_F64:

195 case WebAssembly::I64_TRUNC_U_F64:

196

197

198

199

200 break;

201 default:

202

203

204 if (MI.isCall()) {

206 Effects = true;

207 }

208 break;

209 }

210 }

211

212

213 if (MI.hasUnmodeledSideEffects()) {

214 switch (MI.getOpcode()) {

215 case WebAssembly::DIV_S_I32:

216 case WebAssembly::DIV_S_I64:

217 case WebAssembly::REM_S_I32:

218 case WebAssembly::REM_S_I64:

219 case WebAssembly::DIV_U_I32:

220 case WebAssembly::DIV_U_I64:

221 case WebAssembly::REM_U_I32:

222 case WebAssembly::REM_U_I64:

223 case WebAssembly::I32_TRUNC_S_F32:

224 case WebAssembly::I64_TRUNC_S_F32:

225 case WebAssembly::I32_TRUNC_S_F64:

226 case WebAssembly::I64_TRUNC_S_F64:

227 case WebAssembly::I32_TRUNC_U_F32:

228 case WebAssembly::I64_TRUNC_U_F32:

229 case WebAssembly::I32_TRUNC_U_F64:

230 case WebAssembly::I64_TRUNC_U_F64:

231

232

233

234

235 break;

236 default:

237 Effects = true;

238 break;

239 }

240 }

241

242

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

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

245 strcmp(MI.getOperand(0).getSymbolName(), "__stack_pointer") == 0)

246 StackPointer = true;

247

248

249 if (MI.isCall()) {

251 }

252}

253

254

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

258}

259

260

261

262

266

268 return Def;

269

270

274

275 return nullptr;

276}

277

278

279

280

284

285 if (MRI.hasOneNonDBGUse(Reg))

286 return true;

287

288 bool HasOne = false;

290 const VNInfo *DefVNI =

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

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

296 if (!Result.isKill())

297 return false;

298 if (HasOne)

299 return false;

300 HasOne = true;

301 }

302 }

303 return HasOne;

304}

305

306

307

308

309

310

319

320

321

322

323

324

325

326

327

328

329

330

331 if (Def != DefI->defs().begin())

332 return false;

333

334

335

336

337

338

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

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

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

344 if (&PriorUse == Use)

345 break;

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

347 return false;

348 }

349 }

350 }

351

352

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

356 ;

357 if (NextI == Insert)

358 return true;

359

360

361

363 return false;

364

365

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

369 continue;

371

372

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

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

375 continue;

376

377 if (Reg.isPhysical()) {

378

379

380 if (Reg == WebAssembly::ARGUMENTS)

381 continue;

382

383 if (MRI.isPhysRegModified(Reg))

384 continue;

385

386 return false;

387 }

388

389

390

391

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

394 }

395

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

398

399

400

401 bool HasMutableRegisters = !MutableRegisters.empty();

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

403 return true;

404

405

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

408 bool InterveningRead = false;

409 bool InterveningWrite = false;

410 bool InterveningEffects = false;

411 bool InterveningStackPointer = false;

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

413 InterveningStackPointer);

414 if (Effects && InterveningEffects)

415 return false;

416 if (Read && InterveningWrite)

417 return false;

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

419 return false;

420 if (StackPointer && InterveningStackPointer)

421 return false;

422

423 for (unsigned Reg : MutableRegisters)

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

426 return false;

427 }

428

429 return true;

430}

431

432

440

443

445 if (&Use == &OneUse)

446 continue;

447

450

451 if (UseVNI != OneUseVNI)

452 continue;

453

454 if (UseInst == OneUseInst) {

455

456

457 if (&OneUse > &Use)

458 return false;

459 } else {

460

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

462

463

464

465

466

468 return false;

471 return false;

474 return false;

475 assert(MRI.hasOneNonDBGUse(DefReg));

478 if (NewUseInst == OneUseInst) {

479 if (&OneUse > &NewUse)

480 return false;

481 break;

482 }

483 UseInst = NewUseInst;

484 }

485 }

486 }

487 return true;

488}

489

490

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

493 return WebAssembly::TEE_I32;

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

495 return WebAssembly::TEE_I64;

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

497 return WebAssembly::TEE_F32;

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

499 return WebAssembly::TEE_F64;

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

501 return WebAssembly::TEE_V128;

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

503 return WebAssembly::TEE_EXTERNREF;

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

505 return WebAssembly::TEE_FUNCREF;

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

507 return WebAssembly::TEE_EXNREF;

509}

510

511

516 }

517}

518

519

520

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

527

529 DefDIs.sink(Insert);

531

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

533

534

536 } else {

537

538

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

540 Op.setReg(NewReg);

542

543

545

546

550 true);

551

553

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

555 }

556

558 return Def;

559}

560

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

563 if (I->isDebugInstr())

564 return I;

565 return nullptr;

566}

567

568

569

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

577

579

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

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

582 Op.setReg(NewReg);

589

591

592

593 bool IsDead = MRI.use_empty(Reg);

598 }

599

600

608 }

609

610 return Clone;

611}

612

613

614

615

616

617

618

619

620

621

622

623

624

625

626

627

628

629

630

631

632

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

638

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

640 Register TeeReg = MRI.createVirtualRegister(RegClass);

641 Register DefReg = MRI.createVirtualRegister(RegClass);

642

643

645 DefDIs.sink(Insert);

647

648

654 Op.setReg(TeeReg);

658

659

663 I->start = TeeIdx;

664 ValNo->def = TeeIdx;

666

667

674

675

676

677

678

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

680

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

683 return Def;

684}

685

686namespace {

687

688

689class TreeWalkerState {

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

694

695public:

696 explicit TreeWalkerState(MachineInstr *Insert) {

698 if (Range.empty())

700 }

701

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

703

705 RangeTy &Range = Worklist.back();

708 if (Range.empty())

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

712 return Op;

713 }

714

715

718 if (Range.empty())

720 }

721

722

723

725 assert(hasRemainingOperands(Instr) &&

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

727 "an operand still on the stack");

729 }

730

731

732

733 bool hasRemainingOperands(const MachineInstr *Instr) const {

734 if (Worklist.empty())

735 return false;

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

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

738 }

739

740

741

742

743

744

745

746 bool isOnStack(unsigned Reg) const {

747 for (const RangeTy &Range : Worklist)

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

750 return true;

751 return false;

752 }

753};

754

755

756

757class CommutingState {

758

759

760

761

762

763 bool TentativelyCommuting = false;

764 bool Declined = false;

765

766

767

768 unsigned Operand0, Operand1;

769

770public:

771

772

773

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

776 if (TentativelyCommuting) {

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

779

780 TII->commuteInstruction(*Insert, false, Operand0, Operand1);

781 TentativelyCommuting = false;

782 Declined = true;

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

786 if (TII->findCommutedOpIndices(*Insert, Operand0, Operand1)) {

787

788 TII->commuteInstruction(*Insert, false, Operand0, Operand1);

789 TreeWalker.resetTopOperands(Insert);

790 TentativelyCommuting = true;

791 Declined = false;

792 }

793 }

794 }

795

796

797

798 void reset() {

799 TentativelyCommuting = false;

800 Declined = false;

801 }

802};

803}

804

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

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

807 "********** Function: "

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

809

810 bool Changed = false;

815 auto &MDT = getAnalysis().getDomTree();

816 auto &LIS = getAnalysis().getLIS();

817

818

819

820

822

823

826

827

828 if (Insert->isInlineAsm())

829 continue;

830

831

832 if (Insert->isDebugValue())

833 continue;

834

835

836

837 CommutingState Commuting;

838 TreeWalkerState TreeWalker(Insert);

839 while (!TreeWalker.done()) {

841

842

843 if (Use.isReg())

844 continue;

845

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

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

850 if (Reg.isPhysical())

851 continue;

852

853

855 if (!DefI)

856 continue;

857

858

859

861 continue;

862

863

864

866 continue;

867

870 assert(Def != nullptr);

871

872

873

874

875

876

877

879 bool CanMove = SameBlock && isSafeToMove(Def, &Use, Insert, MFI, MRI) &&

880 !TreeWalker.isOnStack(Reg);

883

884

885

886

894 LIS, MFI)) {

897 } else {

898

899

900 if (!CanMove && SameBlock)

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

902

903 continue;

904 }

905

906

907

908

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

910 auto *SubsequentUse = &Use;

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

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

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

914 break;

915 Register DefReg = SubsequentDef->getReg();

917

918 if (DefReg != UseReg || MRI.hasOneNonDBGUse(DefReg))

919 break;

921 ++SubsequentDef;

922 ++SubsequentUse;

923 }

924

925

926

927

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

930

931

932

933 Commuting.reset();

934 TreeWalker.pushOperands(Insert);

935 }

936

937

938

939 if (Insert != &*MII) {

942 Changed = true;

943 }

944 }

945 }

946

947

948

949 if (Changed) {

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

953 }

954

955#ifndef NDEBUG

956

960 if (MI.isDebugInstr())

961 continue;

963 if (!MO.isReg())

964 continue;

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

969 }

971 if (!MO.isReg())

972 continue;

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

976 }

977 }

978

979

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

982 }

983#endif

984

985 return Changed;

986}

unsigned const MachineRegisterInfo * MRI

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

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

static Register UseReg(const MachineOperand &MO)

const HexagonInstrInfo * TII

unsigned const TargetRegisterInfo * TRI

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

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

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

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 MachineInstr * rematerializeCheapDef(unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII, const WebAssemblyRegisterInfo *TRI)

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

static unsigned getTeeOpcode(const TargetRegisterClass *RC)

Get the appropriate tee opcode for the given register class.

static MachineInstr * getVRegDef(unsigned Reg, const MachineInstr *Insert, const MachineRegisterInfo &MRI, const LiveIntervals &LIS)

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

static bool hasOneNonDBGUse(unsigned Reg, MachineInstr *Def, MachineRegisterInfo &MRI, MachineDominatorTree &MDT, LiveIntervals &LIS)

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

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

static void imposeStackOrdering(MachineInstr *MI)

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

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

static MachineInstr * getPrevNonDebugInst(MachineInstr *MI)

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

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

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.

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

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.

void setPreservesCFG()

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

This is an important base class in LLVM.

static Constant * getNullValue(Type *Ty)

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

This class represents an Operation in the Expression.

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)

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.

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

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

void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)

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

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

Split separate components in LiveInterval LI into separate intervals.

LiveInterval & createAndComputeVirtRegInterval(Register Reg)

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.

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.

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.

virtual bool runOnMachineFunction(MachineFunction &MF)=0

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

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.

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.

iterator_range< mop_iterator > operands()

iterator_range< mop_iterator > defs()

Returns a range over all explicit operands that are register definitions.

MachineOperand * mop_iterator

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

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

virtual StringRef getPassName() const

getPassName - Return a nice clean name for a pass.

Wrapper class representing virtual and physical registers.

constexpr bool isVirtual() const

Return true if the specified register number is in the virtual 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.

static const unsigned CommuteAnyOperandIndex

static Type * getDoubleTy(LLVMContext &C)

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

iterator_range< use_iterator > uses()

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

bool isVRegStackified(unsigned VReg) const

unsigned getFrameBaseVreg() const

void stackifyVReg(MachineRegisterInfo &MRI, unsigned VReg)

void clearFrameBaseVreg()

bool isFrameBaseVirtual() const

A range adaptor for a pair of iterators.

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

Reg

All possible values of the reg field in the ModR/M byte.

NodeAddr< InstrNode * > Instr

NodeAddr< DefNode * > Def

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.

auto reverse(ContainerTy &&C)

raw_ostream & dbgs()

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

unsigned getUndefRegState(bool B)

DWARFExpression::Operation Op

char & LiveVariablesID

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

FunctionPass * createWebAssemblyRegStackify()