LLVM: lib/CodeGen/RegAllocPBQP.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

22

23

24

25

26

27

28

29

30

64#include "llvm/Config/llvm-config.h"

74#include

75#include

76#include

77#include

78#include

79#include

80#include

81#include

82#include

83#include

84#include <system_error>

85#include

86#include

87#include

88

89using namespace llvm;

90

91#define DEBUG_TYPE "regalloc"

92

96

99 cl::desc("Attempt coalescing during PBQP register allocation."),

101

102#ifndef NDEBUG

105 cl::desc("Dump graphs for each function/round in the compilation unit."),

107#endif

108

109namespace {

110

111

112

113

114

116public:

117 static char ID;

118

119

120 RegAllocPBQP(char *cPassID = nullptr)

126 }

127

128

129 StringRef getPassName() const override { return "PBQP Register Allocator"; }

130

131

132 void getAnalysisUsage(AnalysisUsage &au) const override;

133

134

135 bool runOnMachineFunction(MachineFunction &MF) override;

136

137 MachineFunctionProperties getRequiredProperties() const override {

138 return MachineFunctionProperties().setNoPHIs();

139 }

140

141 MachineFunctionProperties getClearedProperties() const override {

142 return MachineFunctionProperties().setIsSSA();

143 }

144

145private:

146 using RegSet = std::set;

147

148 char *customPassID;

149

150 RegSet VRegsToAlloc, EmptyIntervalVRegs;

151

152

153

154

155

156 SmallPtrSet<MachineInstr *, 32> DeadRemats;

157

158

159 void findVRegIntervalsToAlloc(const MachineFunction &MF, LiveIntervals &LIS);

160

161

162 void initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM, Spiller &VRegSpiller);

163

164

165 void spillVReg(Register VReg, SmallVectorImpl &NewIntervals,

166 MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM,

167 Spiller &VRegSpiller);

168

169

170

172 const PBQP::Solution &Solution,

173 VirtRegMap &VRM,

174 Spiller &VRegSpiller);

175

176

177

178 void finalizeAlloc(MachineFunction &MF, LiveIntervals &LIS,

179 VirtRegMap &VRM) const;

180

181 void postOptimization(Spiller &VRegSpiller, LiveIntervals &LIS);

182};

183

184char RegAllocPBQP::ID = 0;

185

186

188public:

190 LiveIntervals &LIS = G.getMetadata().LIS;

191

192

193

195

196 for (auto NId : G.nodeIds()) {

199 if (SpillCost == 0.0)

200 SpillCost = std::numeric_limitsPBQP::PBQPNum::min();

201 else

202 SpillCost += MinSpillCost;

205 G.setNodeCosts(NId, std::move(NodeCosts));

206 }

207 }

208};

209

210

212private:

213 using AllowedRegVecPtr = const PBQP::RegAlloc::AllowedRegVector *;

214 using IKey = std::pair<AllowedRegVecPtr, AllowedRegVecPtr>;

215 using IMatrixCache = DenseMap<IKey, PBQPRAGraph::MatrixPtr>;

216 using DisjointAllowedRegsCache = DenseSet;

217 using IEdgeKey = std::pair<PBQP::GraphBase::NodeId, PBQP::GraphBase::NodeId>;

218 using IEdgeCache = DenseSet;

219

222 const DisjointAllowedRegsCache &D) const {

223 const auto *NRegs = &G.getNodeMetadata(NId).getAllowedRegs();

224 const auto *MRegs = &G.getNodeMetadata(MId).getAllowedRegs();

225

226 if (NRegs == MRegs)

227 return false;

228

229 if (NRegs < MRegs)

230 return D.contains(IKey(NRegs, MRegs));

231

232 return D.contains(IKey(MRegs, NRegs));

233 }

234

237 DisjointAllowedRegsCache &D) {

238 const auto *NRegs = &G.getNodeMetadata(NId).getAllowedRegs();

239 const auto *MRegs = &G.getNodeMetadata(MId).getAllowedRegs();

240

241 assert(NRegs != MRegs && "AllowedRegs can not be disjoint with itself");

242

243 if (NRegs < MRegs)

244 D.insert(IKey(NRegs, MRegs));

245 else

246 D.insert(IKey(MRegs, NRegs));

247 }

248

249

250

251

252

253 using IntervalInfo =

254 std::tuple<LiveInterval*, size_t, PBQP::GraphBase::NodeId>;

255

256 static SlotIndex getStartPoint(const IntervalInfo &I) {

257 return std::get<0>(I)->segments[std::get<1>(I)].start;

258 }

259

260 static SlotIndex getEndPoint(const IntervalInfo &I) {

261 return std::get<0>(I)->segments[std::get<1>(I)].end;

262 }

263

265 return std::get<2>(I);

266 }

267

268 static bool lowestStartPoint(const IntervalInfo &I1,

269 const IntervalInfo &I2) {

270

271

272 return getStartPoint(I1) > getStartPoint(I2);

273 }

274

275 static bool lowestEndPoint(const IntervalInfo &I1,

276 const IntervalInfo &I2) {

277 SlotIndex E1 = getEndPoint(I1);

278 SlotIndex E2 = getEndPoint(I2);

279

280 if (E1 < E2)

281 return true;

282

283 if (E1 > E2)

284 return false;

285

286

287

288

289 return std::get<0>(I1)->reg() < std::get<0>(I2)->reg();

290 }

291

292 static bool isAtLastSegment(const IntervalInfo &I) {

293 return std::get<1>(I) == std::get<0>(I)->size() - 1;

294 }

295

296 static IntervalInfo nextSegment(const IntervalInfo &I) {

297 return std::make_tuple(std::get<0>(I), std::get<1>(I) + 1, std::get<2>(I));

298 }

299

300public:

302

303

304

305

306

307 LiveIntervals &LIS = G.getMetadata().LIS;

308

309

310

311

312 IMatrixCache C;

313

314

315

316 IEdgeCache EC;

317

318

319 DisjointAllowedRegsCache D;

320

321 using IntervalSet = std::set<IntervalInfo, decltype(&lowestEndPoint)>;

322 using IntervalQueue =

323 std::priority_queue<IntervalInfo, std::vector,

324 decltype(&lowestStartPoint)>;

325 IntervalSet Active(lowestEndPoint);

326 IntervalQueue Inactive(lowestStartPoint);

327

328

329 for (auto NId : G.nodeIds()) {

330 Register VReg = G.getNodeMetadata(NId).getVReg();

331 LiveInterval &LI = LIS.getInterval(VReg);

332 assert(!LI.empty() && "PBQP graph contains node for empty interval");

333 Inactive.push(std::make_tuple(&LI, 0, NId));

334 }

335

336 while (!Inactive.empty()) {

337

338

339 IntervalInfo Cur = Inactive.top();

340

341

342 IntervalSet::iterator RetireItr = Active.begin();

343 while (RetireItr != Active.end() &&

344 (getEndPoint(*RetireItr) <= getStartPoint(Cur))) {

345

346

347 if (!isAtLastSegment(*RetireItr))

348 Inactive.push(nextSegment(*RetireItr));

349

350 ++RetireItr;

351 }

353

354

355

356 Cur = Inactive.top();

357 Inactive.pop();

358

359

360

362 for (const auto &A : Active) {

364

365

366

367 if (haveDisjointAllowedRegs(G, NId, MId, D))

368 continue;

369

370

371 IEdgeKey EK(std::min(NId, MId), std::max(NId, MId));

372 if (EC.count(EK))

373 continue;

374

375

376 if (!createInterferenceEdge(G, NId, MId, C))

377 setDisjointAllowedRegs(G, NId, MId, D);

378 else

379 EC.insert(EK);

380 }

381

382

384 }

385 }

386

387private:

388

389

390

391

392

395 IMatrixCache &C) {

396 const TargetRegisterInfo &TRI =

397 *G.getMetadata().MF.getSubtarget().getRegisterInfo();

398 const auto &NRegs = G.getNodeMetadata(NId).getAllowedRegs();

399 const auto &MRegs = G.getNodeMetadata(MId).getAllowedRegs();

400

401

402 IKey K(&NRegs, &MRegs);

404 if (I != C.end()) {

405 G.addEdgeBypassingCostAllocator(NId, MId, I->second);

406 return true;

407 }

408

410 bool NodesInterfere = false;

411 for (unsigned I = 0; I != NRegs.size(); ++I) {

412 MCRegister PRegN = NRegs[I];

413 for (unsigned J = 0; J != MRegs.size(); ++J) {

414 MCRegister PRegM = MRegs[J];

415 if (TRI.regsOverlap(PRegN, PRegM)) {

416 M[I + 1][J + 1] = std::numeric_limitsPBQP::PBQPNum::infinity();

417 NodesInterfere = true;

418 }

419 }

420 }

421

422 if (!NodesInterfere)

423 return false;

424

426 C[K] = G.getEdgeCostsPtr(EId);

427

428 return true;

429 }

430};

431

433public:

435 MachineFunction &MF = G.getMetadata().MF;

436 MachineBlockFrequencyInfo &MBFI = G.getMetadata().MBFI;

438

439

440

441 for (const auto &MBB : MF) {

442 for (const auto &MI : MBB) {

443

444 if (CP.setRegisters(&MI) || CP.getSrcReg() == CP.getDstReg())

445 continue;

446

449

451

452 if (CP.isPhys()) {

453 if (!MF.getRegInfo().isAllocatable(DstReg))

454 continue;

455

457

458 const PBQPRAGraph::NodeMetadata::AllowedRegVector &Allowed =

459 G.getNodeMetadata(NId).getAllowedRegs();

460

461 unsigned PRegOpt = 0;

462 while (PRegOpt < Allowed.size() && Allowed[PRegOpt].id() != DstReg)

463 ++PRegOpt;

464

465 if (PRegOpt < Allowed.size()) {

467 NewCosts[PRegOpt + 1] -= CBenefit;

468 G.setNodeCosts(NId, std::move(NewCosts));

469 }

470 } else {

473 const PBQPRAGraph::NodeMetadata::AllowedRegVector *Allowed1 =

474 &G.getNodeMetadata(N1Id).getAllowedRegs();

475 const PBQPRAGraph::NodeMetadata::AllowedRegVector *Allowed2 =

476 &G.getNodeMetadata(N2Id).getAllowedRegs();

477

479 if (EId == G.invalidEdgeId()) {

481 Allowed2->size() + 1, 0);

482 addVirtRegCoalesce(Costs, *Allowed1, *Allowed2, CBenefit);

483 G.addEdge(N1Id, N2Id, std::move(Costs));

484 } else {

485 if (G.getEdgeNode1Id(EId) == N2Id) {

488 }

490 addVirtRegCoalesce(Costs, *Allowed1, *Allowed2, CBenefit);

491 G.updateEdgeCosts(EId, std::move(Costs));

492 }

493 }

494 }

495 }

496 }

497

498private:

499 void addVirtRegCoalesce(

501 const PBQPRAGraph::NodeMetadata::AllowedRegVector &Allowed1,

502 const PBQPRAGraph::NodeMetadata::AllowedRegVector &Allowed2,

504 assert(CostMat.getRows() == Allowed1.size() + 1 && "Size mismatch.");

505 assert(CostMat.getCols() == Allowed2.size() + 1 && "Size mismatch.");

506 for (unsigned I = 0; I != Allowed1.size(); ++I) {

507 MCRegister PReg1 = Allowed1[I];

508 for (unsigned J = 0; J != Allowed2.size(); ++J) {

509 MCRegister PReg2 = Allowed2[J];

510 if (PReg1 == PReg2)

511 CostMat[I + 1][J + 1] -= Benefit;

512 }

513 }

514 }

515};

516

517

518class PBQPVirtRegAuxInfo final : public VirtRegAuxInfo {

519 float normalize(float UseDefFreq, unsigned Size, unsigned NumInstr) override {

520

521

523 }

524

525public:

526 PBQPVirtRegAuxInfo(MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM,

527 const MachineLoopInfo &Loops,

528 const MachineBlockFrequencyInfo &MBFI)

529 : VirtRegAuxInfo(MF, LIS, VRM, Loops, MBFI) {}

530};

531}

532

533

535

536void PBQPRAConstraint::anchor() {}

537

538void PBQPRAConstraintList::anchor() {}

539

540void RegAllocPBQP::getAnalysisUsage(AnalysisUsage &au) const {

548

549 if (customPassID)

562}

563

564void RegAllocPBQP::findVRegIntervalsToAlloc(const MachineFunction &MF,

567

568

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

571 if (MRI.reg_nodbg_empty(Reg))

572 continue;

573 VRegsToAlloc.insert(Reg);

574 }

575}

576

581 for (unsigned i = 0; CSR[i] != 0; ++i)

582 if (TRI.regsOverlap(Reg, CSR[i]))

583 return true;

584 return false;

585}

586

590

594 *G.getMetadata().MF.getSubtarget().getRegisterInfo();

595

596 std::vector Worklist(VRegsToAlloc.begin(), VRegsToAlloc.end());

597

598 std::map<Register, std::vector> VRegAllowedMap;

599

600 while (!Worklist.empty()) {

601 Register VReg = Worklist.back();

602 Worklist.pop_back();

603

605

606

607

608 if (VRegLI.empty()) {

609 EmptyIntervalVRegs.insert(VRegLI.reg());

610 VRegsToAlloc.erase(VRegLI.reg());

611 continue;

612 }

613

615

616

619

620

621 std::vector VRegAllowed;

623 for (MCPhysReg R : RawPRegOrder) {

625 if (MRI.isReserved(PReg))

626 continue;

627

628

629 if (!RegMaskOverlaps.empty() && !RegMaskOverlaps.test(PReg))

630 continue;

631

632

633 bool Interference = false;

634 for (MCRegUnit Unit : TRI.regunits(PReg)) {

636 Interference = true;

637 break;

638 }

639 }

640 if (Interference)

641 continue;

642

643

644 VRegAllowed.push_back(PReg);

645 }

646

647

648

649 if (VRegAllowed.empty()) {

651 spillVReg(VReg, NewVRegs, MF, LIS, VRM, VRegSpiller);

653 continue;

654 }

655

656 VRegAllowedMap[VReg.id()] = std::move(VRegAllowed);

657 }

658

659 for (auto &KV : VRegAllowedMap) {

660 auto VReg = KV.first;

661

662

664 EmptyIntervalVRegs.insert(VReg);

665 VRegsToAlloc.erase(VReg);

666 continue;

667 }

668

669 auto &VRegAllowed = KV.second;

670

672

673

674

675 for (unsigned i = 0; i != VRegAllowed.size(); ++i)

677 NodeCosts[1 + i] += 1.0;

678

680 G.getNodeMetadata(NId).setVReg(VReg);

681 G.getNodeMetadata(NId).setAllowedRegs(

682 G.getMetadata().getAllowedRegs(std::move(VRegAllowed)));

683 G.getMetadata().setNodeIdForVReg(VReg, NId);

684 }

685}

686

687void RegAllocPBQP::spillVReg(Register VReg,

691 VRegsToAlloc.erase(VReg);

693 nullptr, &DeadRemats);

694 VRegSpiller.spill(LRE);

695

697 (void)TRI;

699 << LRE.getParent().weight() << ", New vregs: ");

700

701

702

703 for (const Register &R : LRE) {

705 assert(!LI.empty() && "Empty spill range.");

707 VRegsToAlloc.insert(LI.reg());

708 }

709

711}

712

713bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAGraph &G,

720 (void)TRI;

721

722

723 bool AnotherRoundNeeded = false;

724

725

727

728

729

730 for (auto NId : G.nodeIds()) {

731 Register VReg = G.getNodeMetadata(NId).getVReg();

732 unsigned AllocOpt = Solution.getSelection(NId);

733

735 MCRegister PReg = G.getNodeMetadata(NId).getAllowedRegs()[AllocOpt - 1];

737 << TRI.getName(PReg) << "\n");

738 assert(PReg != 0 && "Invalid preg selected.");

740 } else {

741

742

744 spillVReg(VReg, NewVRegs, MF, LIS, VRM, VRegSpiller);

745 AnotherRoundNeeded |= !NewVRegs.empty();

746 }

747 }

748

749 return !AnotherRoundNeeded;

750}

751

756

757

758 for (const Register &R : EmptyIntervalVRegs) {

760

762

763 if (PReg == 0) {

766 for (MCRegister CandidateReg : RawPRegOrder) {

768 PReg = CandidateReg;

769 break;

770 }

771 }

773 "No un-reserved physical registers in this register class");

774 }

775

777 }

778}

779

780void RegAllocPBQP::postOptimization(Spiller &VRegSpiller, LiveIntervals &LIS) {

782

783 for (auto *DeadInst : DeadRemats) {

785 DeadInst->eraseFromParent();

786 }

787 DeadRemats.clear();

788}

789

790bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {

791 LiveIntervals &LIS = getAnalysis().getLIS();

793 getAnalysis().getMBFI();

794

795 auto &LiveStks = getAnalysis().getLS();

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

797

798 VirtRegMap &VRM = getAnalysis().getVRM();

799

800 PBQPVirtRegAuxInfo VRAI(

801 MF, LIS, VRM, getAnalysis().getLI(), MBFI);

802 VRAI.calculateSpillWeightsAndHints();

803

804

805

806

807

809 MF, LIS, VRM, getAnalysis().getLI(), MBFI);

810 std::unique_ptr VRegSpiller(

812

814

816

817

818

819

820

821

822

823

824

825

826

827 findVRegIntervalsToAlloc(MF, LIS);

828

829#ifndef NDEBUG

831 std::string FullyQualifiedName =

833#endif

834

835

836 if (!VRegsToAlloc.empty()) {

838 std::unique_ptr ConstraintsRoot =

839 std::make_unique();

840 ConstraintsRoot->addConstraint(std::make_unique());

841 ConstraintsRoot->addConstraint(std::make_unique());

843 ConstraintsRoot->addConstraint(std::make_unique());

845

846 bool PBQPAllocComplete = false;

847 unsigned Round = 0;

848

849 while (!PBQPAllocComplete) {

850 LLVM_DEBUG(dbgs() << " PBQP Regalloc round " << Round << ":\n");

851 (void) Round;

852

854 initializeGraph(G, VRM, *VRegSpiller);

855 ConstraintsRoot->apply(G);

856

857#ifndef NDEBUG

859 std::ostringstream RS;

860 RS << Round;

861 std::string GraphFileName = FullyQualifiedName + "." + RS.str() +

862 ".pbqpgraph";

863 std::error_code EC;

865 LLVM_DEBUG(dbgs() << "Dumping graph for round " << Round << " to \""

866 << GraphFileName << "\"\n");

867 G.dump(OS);

868 }

869#endif

870

872 PBQPAllocComplete = mapPBQPToRegAlloc(G, Solution, VRM, *VRegSpiller);

873 ++Round;

874 }

875 }

876

877

878 finalizeAlloc(MF, LIS, VRM);

879 postOptimization(*VRegSpiller, LIS);

880 VRegsToAlloc.clear();

881 EmptyIntervalVRegs.clear();

882

883 LLVM_DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << VRM << "\n");

884

885 return true;

886}

887

888

894 Register VReg = G.getNodeMetadata(NId).getVReg();

895 const char *RegClassName = TRI->getRegClassName(MRI.getRegClass(VReg));

896 OS << NId << " (" << RegClassName << ':' << printReg(VReg, TRI) << ')';

897 });

898}

899

900#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

902 for (auto NId : nodeIds()) {

904 assert(Costs.getLength() != 0 && "Empty vector in graph.");

905 OS << PrintNodeInfo(NId, *this) << ": " << Costs << '\n';

906 }

907 OS << '\n';

908

909 for (auto EId : edgeIds()) {

912 assert(N1Id != N2Id && "PBQP graphs should not have self-edges.");

914 assert(M.getRows() != 0 && "No rows in matrix.");

915 assert(M.getCols() != 0 && "No cols in matrix.");

916 OS << PrintNodeInfo(N1Id, *this) << ' ' << M.getRows() << " rows / ";

917 OS << PrintNodeInfo(N2Id, *this) << ' ' << M.getCols() << " cols:\n";

918 OS << M << '\n';

919 }

920}

921

925#endif

926

928 OS << "graph {\n";

929 for (auto NId : nodeIds()) {

930 OS << " node" << NId << " [ label=\""

933 }

934

935 OS << " edge [ len=" << nodeIds().size() << " ]\n";

936 for (auto EId : edgeIds()) {

939 << " [ label=\"";

941 for (unsigned i = 0; i < EdgeCosts.getRows(); ++i) {

942 OS << EdgeCosts.getRowAsVector(i) << "\\n";

943 }

944 OS << "\" ]\n";

945 }

946 OS << "}\n";

947}

948

950 return new RegAllocPBQP(customPassID);

951}

952

unsigned const MachineRegisterInfo * MRI

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

This file implements the BitVector class.

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

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

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

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

This file defines the DenseMap class.

This file defines the DenseSet and SmallDenseSet classes.

Module.h This file contains the declarations for the Module class.

Register const TargetRegisterInfo * TRI

Promote Memory to Register

static Printable PrintNodeInfo(PBQP::RegAlloc::PBQPRAGraph::NodeId NId, const PBQP::RegAlloc::PBQPRAGraph &G)

Create Printable object for node and register info.

Definition RegAllocPBQP.cpp:889

static cl::opt< bool > PBQPDumpGraphs("pbqp-dump-graphs", cl::desc("Dump graphs for each function/round in the compilation unit."), cl::init(false), cl::Hidden)

static cl::opt< bool > PBQPCoalescing("pbqp-coalescing", cl::desc("Attempt coalescing during PBQP register allocation."), cl::init(false), cl::Hidden)

static bool isACalleeSavedRegister(MCRegister Reg, const TargetRegisterInfo &TRI, const MachineFunction &MF)

Definition RegAllocPBQP.cpp:577

static RegisterRegAlloc RegisterPBQPRepAlloc("pbqp", "PBQP register allocator", createDefaultPBQPRegisterAllocator)

This file defines the SmallPtrSet class.

This file defines the SmallVector class.

A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.

Represent the analysis usage information of a pass.

LLVM_ABI AnalysisUsage & addRequiredID(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:

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

bool test(unsigned Idx) const

bool empty() const

empty - Tests whether there are no bits in this bitvector.

DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator

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

Module * getParent()

Get the module that this global value is contained inside of...

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

LLVM_ABI bool checkRegMaskInterference(const LiveInterval &LI, BitVector &UsableRegs)

Test if LI is live across any register mask instructions, and compute a bit mask of physical register...

void RemoveMachineInstrFromMaps(MachineInstr &MI)

LiveInterval & getInterval(Register Reg)

LiveRange & getRegUnit(MCRegUnit Unit)

Return the live range for register unit Unit.

bool overlaps(const LiveRange &other) const

overlaps - Return true if the intersection of the two live ranges is not empty.

Wrapper class representing physical registers. Should be passed by value.

MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...

double getBlockFreqRelativeToEntryBlock(const MachineBasicBlock *MBB) const

Compute the frequency of the block, relative to the entry block.

Analysis pass which computes a MachineDominatorTree.

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.

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

LLVM_ABI void freezeReservedRegs()

freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...

bool isReserved(MCRegister PhysReg) const

isReserved - Returns true when PhysReg is a reserved register.

LLVM_ABI const MCPhysReg * getCalleeSavedRegs() const

Returns list of callee saved registers.

const std::string & getModuleIdentifier() const

Get the module identifier which is, essentially, the name of the module.

Abstract base for classes implementing PBQP register allocation constraints (e.g.

virtual ~PBQPRAConstraint()=0

typename RegAllocSolverImpl::GraphMetadata GraphMetadata

typename RegAllocSolverImpl::Matrix Matrix

NodeId getEdgeNode2Id(EdgeId EId) const

NodeId getEdgeNode1Id(EdgeId EId) const

const Matrix & getEdgeCosts(EdgeId EId) const

typename RegAllocSolverImpl::Vector Vector

NodeIdSet nodeIds() const

typename RegAllocSolverImpl::RawMatrix RawMatrix

typename RegAllocSolverImpl::RawVector RawVector

const Vector & getNodeCosts(NodeId NId) const

EdgeIdSet edgeIds() const

void printDot(raw_ostream &OS) const

Print a representation of this graph in DOT format.

Definition RegAllocPBQP.cpp:927

void dump() const

Dump this graph to dbgs().

Definition RegAllocPBQP.cpp:922

Represents a solution to a PBQP problem.

unsigned getSelection(GraphBase::NodeId nodeId) const

Get a node's selection.

static LLVM_ABI PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

Simple wrapper around std::function<void(raw_ostream&)>.

Wrapper class representing virtual and physical registers.

static Register index2VirtReg(unsigned Index)

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

constexpr unsigned id() const

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

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

virtual void postOptimization()

virtual void spill(LiveRangeEdit &LRE, AllocationOrder *Order=nullptr)=0

spill - Spill the LRE.getParent() live interval.

ArrayRef< MCPhysReg > getRawAllocationOrder(const MachineFunction &MF, bool Rev=false) const

Returns the preferred order for allocating registers from this register class in MF.

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

TargetSubtargetInfo - Generic base class for all target subtargets.

virtual std::unique_ptr< PBQPRAConstraint > getCustomPBQPConstraints() const

Return PBQPConstraint(s) for the target.

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

Calculate auxiliary information for a virtual register such as its spill weight and allocation hint.

virtual float normalize(float UseDefFreq, unsigned Size, unsigned NumInstr)

Weight normalization function.

void clearAllVirt()

clears all virtual to physical register mappings

MachineRegisterInfo & getRegInfo() const

LLVM_ABI void assignVirt2Phys(Register virtReg, MCRegister physReg)

creates a mapping for the specified virtual register to the specified physical register

A raw_ostream that writes to a file descriptor.

This class implements an extremely fast bulk output stream that can only output to a stream.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ C

The default llvm calling convention, compatible with C.

Solution solve(PBQPRAGraph &G)

unsigned getSpillOptionIdx()

Spill option index.

void apply(Opt *O, const Mod &M, const Mods &... Ms)

initializer< Ty > init(const Ty &Val)

@ OF_TextWithCRLF

The file should be opened in text mode and use a carriage linefeed '\r '.

This is an optimization pass for GlobalISel generic memory operations.

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

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

LLVM_ABI void initializeLiveIntervalsWrapperPassPass(PassRegistry &)

PBQP::RegAlloc::PBQPRAGraph PBQPRAGraph

LLVM_ABI raw_ostream & dbgs()

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

LLVM_ABI FunctionPass * createDefaultPBQPRegisterAllocator()

PBQPRegisterAllocation Pass - This pass implements the Partitioned Boolean Quadratic Prograaming (PBQ...

Definition RegAllocPBQP.cpp:953

FunctionPass * createPBQPRegisterAllocator(char *customPassID=nullptr)

Create a PBQP register allocator instance.

Definition RegAllocPBQP.cpp:949

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...

LLVM_ABI void initializeSlotIndexesWrapperPassPass(PassRegistry &)

Spiller * createInlineSpiller(const Spiller::RequiredAnalyses &Analyses, MachineFunction &MF, VirtRegMap &VRM, VirtRegAuxInfo &VRAI, LiveRegMatrix *Matrix=nullptr)

Create and return a spiller that will insert spill code directly instead of deferring though VirtRegM...

LLVM_ABI void initializeLiveStacksWrapperLegacyPass(PassRegistry &)

LLVM_ABI void initializeVirtRegMapWrapperLegacyPass(PassRegistry &)

LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)

Prints virtual and physical registers with or without a TRI instance.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.