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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

64#include

65#include

66#include

67#include

68

69using namespace llvm;

70

71#define DEBUG_TYPE "machine-sink"

72

75 cl::desc("Split critical edges during machine sinking"),

77

79 "machine-sink-bfi",

80 cl::desc("Use block frequency info to find successors to sink"),

82

84 "machine-sink-split-probability-threshold",

86 "Percentage threshold for splitting single-instruction critical edge. "

87 "If the branch threshold is higher than this threshold, we allow "

88 "speculative execution of up to 1 instruction to avoid branching to "

89 "splitted critical edge"),

91

93 "machine-sink-load-instrs-threshold",

94 cl::desc("Do not try to find alias store for a load if there is a in-path "

95 "block whose instruction number is higher than this threshold."),

97

99 "machine-sink-load-blocks-threshold",

100 cl::desc("Do not try to find alias store for a load if the block number in "

101 "the straight line is higher than this threshold."),

103

106 cl::desc("Sink instructions into cycles to avoid "

107 "register spills"),

109

111 "machine-sink-cycle-limit",

113 "The maximum number of instructions considered for cycle sinking."),

115

116STATISTIC(NumSunk, "Number of machine instructions sunk");

117STATISTIC(NumCycleSunk, "Number of machine instructions sunk into a cycle");

118STATISTIC(NumSplit, "Number of critical edges split");

119STATISTIC(NumCoalesces, "Number of copies coalesced");

120STATISTIC(NumPostRACopySink, "Number of copies sunk after RA");

121

123

124namespace {

125

126class MachineSinking {

140

145

146

148 CEBCandidates;

149

150

151

152

153

154

156 CEMergeCandidates;

157

158

159

161

163

164 using AllSuccsCache =

166

167

168

169

170

171

172

173

174

175

177

178 using SinkItem = std::pair<MachineInstr *, MachineBasicBlock *>;

179

180

181

183

184

185

187

189 HasStoreCache;

190

193 StoreInstrCache;

194

195

197 CachedRegisterPressure;

198

199 bool EnableSinkAndFold;

200

201public:

208 : DT(DT), PDT(PDT), CI(CI), PSI(PSI), MBFI(MBFI), MBPI(MBPI), AA(AA),

209 LIS(LIS), SI(SI), LV(LV), MLI(MLI),

210 EnableSinkAndFold(EnableSinkAndFold) {}

211

213

214 void releaseMemory() {

215 CEBCandidates.clear();

216 CEMergeCandidates.clear();

217 }

218

219private:

227

230

231

232

233

234

235

236

237

238

239

240

241

242

246 AllSuccsCache &AllSuccessors);

247

248

249

250

251

252 void SalvageUnsunkDebugUsersOfCopy(MachineInstr &,

256 bool &LocalUse) const;

258 bool &BreakPHIEdge,

259 AllSuccsCache &AllSuccessors);

260

263

264 bool

267

271 AllSuccsCache &AllSuccessors);

272

273 bool PerformTrivialForwardCoalescing(MachineInstr &MI,

275

277

280 AllSuccsCache &AllSuccessors) const;

281

283 bool UseCache = true);

284

285 bool registerPressureSetExceedsLimit(unsigned NRegs,

288

290};

291

293public:

294 static char ID;

295

298 }

299

301

302 void getAnalysisUsage(AnalysisUsage &AU) const override {

315 }

316};

317

318}

319

320char MachineSinkingLegacy::ID = 0;

321

323

325 false, false)

333

334

335

343 ++PI) {

344

345 if (!TII->isBasicBlockPrologue(*PI))

346 continue;

347 for (auto &MO : MI.operands()) {

348 if (!MO.isReg())

349 continue;

350 Register Reg = MO.getReg();

351 if (!Reg)

352 continue;

353 if (MO.isUse()) {

354 if (Reg.isPhysical() &&

355 (TII->isIgnorableUse(MO) || (MRI && MRI->isConstantPhysReg(Reg))))

356 continue;

357 if (PI->modifiesRegister(Reg, TRI))

358 return true;

359 } else {

360 if (PI->readsRegister(Reg, TRI))

361 return true;

362

363 auto *DefOp = PI->findRegisterDefOperand(Reg, TRI, false, true);

364 if (DefOp && !DefOp->isDead())

365 return true;

366 }

367 }

368 }

369

370 return false;

371}

372

373bool MachineSinking::PerformTrivialForwardCoalescing(MachineInstr &MI,

375 if (MI.isCopy())

376 return false;

377

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

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

381 MRI->hasOneNonDBGUse(SrcReg))

382 return false;

383

384 const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg);

385 const TargetRegisterClass *DRC = MRI->getRegClass(DstReg);

386 if (SRC != DRC)

387 return false;

388

389 MachineInstr *DefMI = MRI->getVRegDef(SrcReg);

391 return false;

394 MRI->replaceRegWith(DstReg, SrcReg);

395 MI.eraseFromParent();

396

397

398

399 MRI->clearKillFlags(SrcReg);

400

401 ++NumCoalesces;

402 return true;

403}

404

405bool MachineSinking::PerformSinkAndFold(MachineInstr &MI,

406 MachineBasicBlock *MBB) {

407 if (MI.isCopy() || MI.mayLoadOrStore() ||

408 MI.getOpcode() == TargetOpcode::REG_SEQUENCE)

409 return false;

410

411

413 return false;

414

415

416 bool SawStore = true;

417 if (MI.isSafeToMove(SawStore))

418 return false;

419

420

421

422 if (MI.isConvergent())

423 return false;

424

425

426

427

428

431 for (const MachineOperand &MO : MI.operands()) {

432 if (MO.isImm() || MO.isRegMask() || MO.isRegLiveOut() || MO.isMetadata() ||

433 MO.isMCSymbol() || MO.isDbgInstrRef() || MO.isCFIIndex() ||

434 MO.isIntrinsicID() || MO.isPredicate() || MO.isShuffleMask())

435 continue;

436 if (!MO.isReg())

437 return false;

438

440 if (Reg == 0)

441 continue;

442

444 if (MO.isDef()) {

445 if (DefReg)

446 return false;

447 DefReg = Reg;

448 continue;

449 }

450

451 if (UsedRegA == 0)

452 UsedRegA = Reg;

453 else if (UsedRegB == 0)

454 UsedRegB = Reg;

455 else

456 return false;

457 continue;

458 }

459

462 continue;

463

464 return false;

465 }

466

467

468

469

470

471 using SinkInfo = std::pair<MachineInstr *, ExtAddrMode>;

474

475 const TargetRegisterClass *RC = MRI->getRegClass(DefReg);

476 const TargetRegisterClass *RCA =

477 UsedRegA == 0 ? nullptr : MRI->getRegClass(UsedRegA);

478 const TargetRegisterClass *RCB =

479 UsedRegB == 0 ? nullptr : MRI->getRegClass(UsedRegB);

480

482 while (!Worklist.empty()) {

484

485 for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {

486 ExtAddrMode MaybeAM;

487 MachineInstr &UseInst = *MO.getParent();

488 if (UseInst.isCopy()) {

490 if (const MachineOperand &O = UseInst.getOperand(0); O.isReg())

491 DstReg = O.getReg();

492 if (DstReg == 0)

493 return false;

496 continue;

497 }

498

499

501 return false;

502

503

505 return false;

507 ExtAddrMode AM;

509 return false;

510 MaybeAM = AM;

511 } else {

512 return false;

513 }

514

515 if (UseInst.getParent() != MI.getParent()) {

516

517

518

519 const TargetRegisterClass *RCS = MRI->getRegClass(Reg);

521 RCA = nullptr;

523 RCB = nullptr;

524 if (RCA || RCB) {

525 if (RCA == nullptr) {

526 RCA = RCB;

527 RCB = nullptr;

528 }

529

530 unsigned NRegs = !!RCA + !!RCB;

531 if (RCA == RCB)

532 RCB = nullptr;

533

534

535 const MachineBasicBlock &MBB = *UseInst.getParent();

536 if (RCB == nullptr) {

537 if (registerPressureSetExceedsLimit(NRegs, RCA, MBB))

538 return false;

539 } else if (registerPressureSetExceedsLimit(1, RCA, MBB) ||

540 registerPressureSetExceedsLimit(1, RCB, MBB)) {

541 return false;

542 }

543 }

544 }

545

547 }

548 }

549

550 if (SinkInto.empty())

551 return false;

552

553

554 for (auto &[SinkDst, MaybeAM] : SinkInto) {

555 MachineInstr *New = nullptr;

557 SinkDst->dump());

558 if (SinkDst->isCopy()) {

559

560

561

562

563

564

565

566

567

568

569

571 Register DstReg = SinkDst->getOperand(0).getReg();

573 New = &*std::prev(InsertPt);

574 if (New->getDebugLoc())

575 New->setDebugLoc(SinkDst->getDebugLoc());

576

577

578

579

580 if (UsedRegA)

581 MRI->clearKillFlags(UsedRegA);

582 if (UsedRegB)

583 MRI->clearKillFlags(UsedRegB);

584 } else {

585

587

588

589

590

592 MRI->clearKillFlags(R);

594 MRI->clearKillFlags(R);

595 }

597

598 if (SinkDst->mayStore() && !SinkDst->hasOrderedMemoryRef())

599 StoreInstrCache.clear();

600 SinkDst->eraseFromParent();

601 }

602

603

604

605

608 while (!Worklist.empty()) {

610 for (MachineOperand &MO : MRI->use_operands(Reg)) {

611 MachineInstr *U = MO.getParent();

612 assert((U->isCopy() || U->isDebugInstr()) &&

613 "Only debug uses and copies must remain");

614 if (U->isCopy())

615 Worklist.push_back(U->getOperand(0).getReg());

617 }

618 }

619

620

621 for (MachineOperand *MO : Cleanup) {

622 MachineInstr *I = MO->getParent();

623 if (I->isCopy()) {

624 I->eraseFromParent();

625 } else {

626 MO->setReg(0);

627 MO->setSubReg(0);

628 }

629 }

630

631 MI.eraseFromParent();

632 return true;

633}

634

635

636

637

638

639bool MachineSinking::AllUsesDominatedByBlock(Register Reg,

640 MachineBasicBlock *MBB,

641 MachineBasicBlock *DefMBB,

642 bool &BreakPHIEdge,

643 bool &LocalUse) const {

645

646

647 if (MRI->use_nodbg_empty(Reg))

648 return true;

649

650

651

652

653

654

655

656

657

658

659

660

661

662

663

664 if (all_of(MRI->use_nodbg_operands(Reg), [&](MachineOperand &MO) {

665 MachineInstr *UseInst = MO.getParent();

666 unsigned OpNo = MO.getOperandNo();

667 MachineBasicBlock *UseBlock = UseInst->getParent();

668 return UseBlock == MBB && UseInst->isPHI() &&

669 UseInst->getOperand(OpNo + 1).getMBB() == DefMBB;

670 })) {

671 BreakPHIEdge = true;

672 return true;

673 }

674

675 for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {

676

677 MachineInstr *UseInst = MO.getParent();

678 unsigned OpNo = &MO - &UseInst->getOperand(0);

679 MachineBasicBlock *UseBlock = UseInst->getParent();

680 if (UseInst->isPHI()) {

681

682

684 } else if (UseBlock == DefMBB) {

685 LocalUse = true;

686 return false;

687 }

688

689

691 return false;

692 }

693

694 return true;

695}

696

697

698

700 assert(MI.mayLoad() && "Expected MI that loads!");

701

702

703

704 if (MI.memoperands_empty())

705 return true;

706

709 if (PSV->isGOT() || PSV->isConstantPool())

710 return true;

711

712 return false;

713}

714

715void MachineSinking::FindCycleSinkCandidates(

717 SmallVectorImpl<MachineInstr *> &Candidates) {

718 for (auto &MI : *BB) {

719 LLVM_DEBUG(dbgs() << "CycleSink: Analysing candidate: " << MI);

720 if (MI.isMetaInstruction()) {

721 LLVM_DEBUG(dbgs() << "CycleSink: not sinking meta instruction\n");

722 continue;

723 }

725 LLVM_DEBUG(dbgs() << "CycleSink: Instruction not a candidate for this "

726 "target\n");

727 continue;

728 }

730 LLVM_DEBUG(dbgs() << "CycleSink: Instruction is not cycle invariant\n");

731 continue;

732 }

733 bool DontMoveAcrossStore = true;

734 if (MI.isSafeToMove(DontMoveAcrossStore)) {

735 LLVM_DEBUG(dbgs() << "CycleSink: Instruction not safe to move.\n");

736 continue;

737 }

739 LLVM_DEBUG(dbgs() << "CycleSink: Dont sink GOT or constant pool loads\n");

740 continue;

741 }

742 if (MI.isConvergent())

743 continue;

744

745 const MachineOperand &MO = MI.getOperand(0);

747 continue;

748 if (MRI->hasOneDef(MO.getReg()))

749 continue;

750

751 LLVM_DEBUG(dbgs() << "CycleSink: Instruction added as candidate.\n");

753 }

754}

755

756PreservedAnalyses

763 .getCachedResult(

767 : nullptr;

770 .getManager()

776 MachineSinking Impl(EnableSinkAndFold, DT, PDT, LV, MLI, SI, LIS, CI, PSI,

777 MBFI, MBPI, AA);

778 bool Changed = Impl.run(MF);

784 return PA;

785}

786

789 OS << MapClassName2PassName(name());

790 if (EnableSinkAndFold)

791 OS << "";

792}

793

794bool MachineSinkingLegacy::runOnMachineFunction(MachineFunction &MF) {

796 return false;

797

798 TargetPassConfig *PassConfig = &getAnalysis();

800

801 auto *DT = &getAnalysis().getDomTree();

802 auto *PDT =

803 &getAnalysis().getPostDomTree();

804 auto *CI = &getAnalysis().getCycleInfo();

805 auto *PSI = &getAnalysis().getPSI();

806 auto *MBFI =

808 ? &getAnalysis().getMBFI()

809 : nullptr;

810 auto *MBPI =

811 &getAnalysis().getMBPI();

812 auto *AA = &getAnalysis().getAAResults();

813

814 auto *LISWrapper = getAnalysisIfAvailable();

815 auto *LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;

816 auto *SIWrapper = getAnalysisIfAvailable();

817 auto *SI = SIWrapper ? &SIWrapper->getSI() : nullptr;

818 auto *LVWrapper = getAnalysisIfAvailable();

819 auto *LV = LVWrapper ? &LVWrapper->getLV() : nullptr;

820 auto *MLIWrapper = getAnalysisIfAvailable();

821 auto *MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr;

822

823 MachineSinking Impl(EnableSinkAndFold, DT, PDT, LV, MLI, SI, LIS, CI, PSI,

824 MBFI, MBPI, AA);

825 return Impl.run(MF);

826}

827

829 LLVM_DEBUG(dbgs() << "******** Machine Sinking ********\n");

830

835

837

838 bool EverMadeChange = false;

839

840 while (true) {

841 bool MadeChange = false;

842

843

844 CEBCandidates.clear();

845 CEMergeCandidates.clear();

846 ToSplit.clear();

847 for (auto &MBB : MF)

849

850

852 MachineDomTreeUpdater::UpdateStrategy::Lazy);

853 for (const auto &Pair : ToSplit) {

854 auto NewSucc = Pair.first->SplitCriticalEdge(

855 Pair.second, {LIS, SI, LV, MLI}, nullptr, &MDTU);

856 if (NewSucc != nullptr) {

857 LLVM_DEBUG(dbgs() << " *** Splitting critical edge: "

861 if (MBFI)

862 MBFI->onEdgeSplit(*Pair.first, *NewSucc, *MBPI);

863

864 MadeChange = true;

865 ++NumSplit;

867 } else

868 LLVM_DEBUG(dbgs() << " *** Not legal to break critical edge\n");

869 }

870

871 if (!MadeChange)

872 break;

873 EverMadeChange = true;

874 }

875

878 SchedModel.init(STI);

879 bool HasHighPressure;

880

881 DenseMap<SinkItem, MachineInstr *> SunkInstrs;

882

883 enum CycleSinkStage { COPY, LOW_LATENCY, AGGRESSIVE, END };

884 for (unsigned Stage = CycleSinkStage::COPY; Stage != CycleSinkStage::END;

885 ++Stage, SunkInstrs.clear()) {

886 HasHighPressure = false;

887

888 for (auto *Cycle : Cycles) {

890 if (!Preheader) {

891 LLVM_DEBUG(dbgs() << "CycleSink: Can't find preheader\n");

892 continue;

893 }

894 SmallVector<MachineInstr *, 8> Candidates;

895 FindCycleSinkCandidates(Cycle, Preheader, Candidates);

896

897 unsigned i = 0;

898

899

900

901

903

904 if (Stage == CycleSinkStage::COPY) {

907 << "CycleSink: Limit reached of instructions to "

908 "be analyzed.");

909 break;

910 }

911

912 if (I->isCopy())

913 continue;

914 }

915

916

917

918 if (Stage == CycleSinkStage::LOW_LATENCY &&

920 continue;

921

922 if (!aggressivelySinkIntoCycle(Cycle, *I, SunkInstrs))

923 continue;

924 EverMadeChange = true;

925 ++NumCycleSunk;

926 }

927

928

929 if (!HasHighPressure)

930 HasHighPressure = registerPressureExceedsLimit(*Preheader);

931 }

932 if (!HasHighPressure)

933 break;

934 }

935 }

936

937 HasStoreCache.clear();

938 StoreInstrCache.clear();

939

940

941 for (auto I : RegsToClearKillFlags)

942 MRI->clearKillFlags(I);

943 RegsToClearKillFlags.clear();

944

945 releaseMemory();

946 return EverMadeChange;

947}

948

949bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {

951 return false;

952

953

954

955

957 return false;

958

959 bool MadeChange = false;

960

961

962 AllSuccsCache AllSuccessors;

963

964

966 --I;

967 bool ProcessedBegin, SawStore = false;

968 do {

969 MachineInstr &MI = *I;

970

971

972

973 ProcessedBegin = I == MBB.begin();

974 if (!ProcessedBegin)

975 --I;

976

977 if (MI.isDebugOrPseudoInstr() || MI.isFakeUse()) {

978 if (MI.isDebugValue())

979 ProcessDbgInst(MI);

980 continue;

981 }

982

983 if (EnableSinkAndFold && PerformSinkAndFold(MI, &MBB)) {

984 MadeChange = true;

985 continue;

986 }

987

988

990 continue;

991

992 if (PerformTrivialForwardCoalescing(MI, &MBB)) {

993 MadeChange = true;

994 continue;

995 }

996

998 ++NumSunk;

999 MadeChange = true;

1000 }

1001

1002

1003 } while (!ProcessedBegin);

1004

1005 SeenDbgUsers.clear();

1006 SeenDbgVars.clear();

1007

1008 CachedRegisterPressure.clear();

1009 return MadeChange;

1010}

1011

1012void MachineSinking::ProcessDbgInst(MachineInstr &MI) {

1013

1014

1015 assert(MI.isDebugValue() && "Expected DBG_VALUE for processing");

1016

1017 DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),

1018 MI.getDebugLoc()->getInlinedAt());

1019 bool SeenBefore = SeenDbgVars.contains(Var);

1020

1021 for (MachineOperand &MO : MI.debug_operands()) {

1023 SeenDbgUsers[MO.getReg()].push_back(SeenDbgUser(&MI, SeenBefore));

1024 }

1025

1026

1027 SeenDbgVars.insert(Var);

1028}

1029

1030bool MachineSinking::isWorthBreakingCriticalEdge(

1031 MachineInstr &MI, MachineBasicBlock *From, MachineBasicBlock *To,

1032 MachineBasicBlock *&DeferredFromBlock) {

1033

1034

1035

1036

1037

1038 if (!CEBCandidates.insert(std::make_pair(From, To)).second)

1039 return true;

1040

1042 return true;

1043

1044

1045

1046

1047

1048

1049 for (const auto &MO : MI.all_defs()) {

1051 if (Reg)

1052 continue;

1054 auto Key = std::make_pair(SrcReg, To);

1055 auto Res = CEMergeCandidates.try_emplace(Key, From);

1056

1057

1058 if (!Res.second) {

1059

1060 DeferredFromBlock = Res.first->second;

1061 return true;

1062 }

1063 }

1064

1068 return true;

1069

1070

1071

1072

1073 for (const MachineOperand &MO : MI.all_uses()) {

1075 if (Reg == 0)

1076 continue;

1077

1078

1079

1081 continue;

1082

1083

1084

1085

1086 if (MRI->hasOneNonDBGUse(Reg)) {

1087

1088

1089

1090

1091 MachineInstr *DefMI = MRI->getVRegDef(Reg);

1093 return true;

1094 }

1095 }

1096

1097

1098

1100}

1101

1102bool MachineSinking::isLegalToBreakCriticalEdge(MachineInstr &MI,

1103 MachineBasicBlock *FromBB,

1104 MachineBasicBlock *ToBB,

1105 bool BreakPHIEdge) {

1106

1108 return false;

1109

1112

1113

1114 if (FromCycle == ToCycle && FromCycle &&

1116 return false;

1117

1118

1119

1120

1121

1122

1123

1124

1125

1126

1127

1128

1129

1130

1131

1132

1133

1134

1135

1136

1137

1138

1139

1140

1141

1142

1143

1144

1145

1146

1147

1148

1149

1150

1151

1152

1153

1154

1155

1156

1157 if (!BreakPHIEdge) {

1158 for (MachineBasicBlock *Pred : ToBB->predecessors())

1159 if (Pred != FromBB && !DT->dominates(ToBB, Pred))

1160 return false;

1161 }

1162

1163 return true;

1164}

1165

1166bool MachineSinking::PostponeSplitCriticalEdge(MachineInstr &MI,

1167 MachineBasicBlock *FromBB,

1168 MachineBasicBlock *ToBB,

1169 bool BreakPHIEdge) {

1170 bool Status = false;

1171 MachineBasicBlock *DeferredFromBB = nullptr;

1172 if (isWorthBreakingCriticalEdge(MI, FromBB, ToBB, DeferredFromBB)) {

1173

1174

1175 if ((!DeferredFromBB ||

1176 ToSplit.count(std::make_pair(DeferredFromBB, ToBB)) ||

1177 isLegalToBreakCriticalEdge(MI, DeferredFromBB, ToBB, BreakPHIEdge)) &&

1178 isLegalToBreakCriticalEdge(MI, FromBB, ToBB, BreakPHIEdge)) {

1179 ToSplit.insert(std::make_pair(FromBB, ToBB));

1180 if (DeferredFromBB)

1181 ToSplit.insert(std::make_pair(DeferredFromBB, ToBB));

1182 Status = true;

1183 }

1184 }

1185

1186 return Status;

1187}

1188

1189std::vector &

1190MachineSinking::getBBRegisterPressure(const MachineBasicBlock &MBB,

1191 bool UseCache) {

1192

1193

1194

1195

1196

1197 auto RP = CachedRegisterPressure.find(&MBB);

1198 if (UseCache && RP != CachedRegisterPressure.end())

1199 return RP->second;

1200

1201 RegionPressure Pressure;

1202 RegPressureTracker RPTracker(Pressure);

1203

1204

1206 false, true);

1207

1210 MII != MIE; --MII) {

1211 const MachineInstr &MI = *std::prev(MII);

1212 if (MI.isDebugOrPseudoInstr())

1213 continue;

1214 RegisterOperands RegOpers;

1216 RPTracker.recedeSkipDebugValues();

1217 assert(&*RPTracker.getPos() == &MI && "RPTracker sync error!");

1218 RPTracker.recede(RegOpers);

1219 }

1220

1221 RPTracker.closeRegion();

1222

1223 if (RP != CachedRegisterPressure.end()) {

1224 CachedRegisterPressure[&MBB] = RPTracker.getPressure().MaxSetPressure;

1225 return CachedRegisterPressure[&MBB];

1226 }

1227

1228 auto It = CachedRegisterPressure.insert(

1229 std::make_pair(&MBB, RPTracker.getPressure().MaxSetPressure));

1230 return It.first->second;

1231}

1232

1233bool MachineSinking::registerPressureSetExceedsLimit(

1234 unsigned NRegs, const TargetRegisterClass *RC,

1235 const MachineBasicBlock &MBB) {

1236 unsigned Weight = NRegs * TRI->getRegClassWeight(RC).RegWeight;

1237 const int *PS = TRI->getRegClassPressureSets(RC);

1238 std::vector BBRegisterPressure = getBBRegisterPressure(MBB);

1239 for (; *PS != -1; PS++)

1240 if (Weight + BBRegisterPressure[*PS] >=

1242 return true;

1243 return false;

1244}

1245

1246

1247bool MachineSinking::registerPressureExceedsLimit(

1248 const MachineBasicBlock &MBB) {

1249 std::vector BBRegisterPressure = getBBRegisterPressure(MBB, false);

1250

1251 for (unsigned PS = 0; PS < BBRegisterPressure.size(); ++PS) {

1252 if (BBRegisterPressure[PS] >=

1254 return true;

1255 }

1256 }

1257

1258 return false;

1259}

1260

1261

1262bool MachineSinking::isProfitableToSinkTo(Register Reg, MachineInstr &MI,

1263 MachineBasicBlock *MBB,

1264 MachineBasicBlock *SuccToSinkTo,

1265 AllSuccsCache &AllSuccessors) {

1266 assert(SuccToSinkTo && "Invalid SinkTo Candidate BB");

1267

1268 if (MBB == SuccToSinkTo)

1269 return false;

1270

1271

1273 return true;

1274

1275

1276

1278 return true;

1279

1280

1281 bool NonPHIUse = false;

1282 for (MachineInstr &UseInst : MRI->use_nodbg_instructions(Reg)) {

1283 MachineBasicBlock *UseBlock = UseInst.getParent();

1284 if (UseBlock == SuccToSinkTo && !UseInst.isPHI())

1285 NonPHIUse = true;

1286 }

1287 if (!NonPHIUse)

1288 return true;

1289

1290

1291

1292 bool BreakPHIEdge = false;

1293

1294 if (MachineBasicBlock *MBB2 =

1295 FindSuccToSinkTo(MI, SuccToSinkTo, BreakPHIEdge, AllSuccessors))

1296 return isProfitableToSinkTo(Reg, MI, SuccToSinkTo, MBB2, AllSuccessors);

1297

1299

1300

1301

1302 if (!MCycle)

1303 return false;

1304

1305

1306

1307 for (const MachineOperand &MO : MI.operands()) {

1308

1309 if (!MO.isReg())

1310 continue;

1312 if (Reg == 0)

1313 continue;

1314

1316

1317 if (MO.isUse() && MRI->isConstantPhysReg(Reg) &&

1319 return false;

1320 continue;

1321 }

1322

1323

1324 if (MO.isDef()) {

1325

1326 bool LocalUse = false;

1327 if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, MBB, BreakPHIEdge,

1328 LocalUse))

1329 return false;

1330 } else {

1331 MachineInstr *DefMI = MRI->getVRegDef(Reg);

1333 continue;

1335

1336

1337

1338

1341 continue;

1342

1343

1344

1345 if (registerPressureSetExceedsLimit(1, MRI->getRegClass(Reg),

1346 *SuccToSinkTo)) {

1347 LLVM_DEBUG(dbgs() << "register pressure exceed limit, not profitable.");

1348 return false;

1349 }

1350 }

1351 }

1352

1353

1354

1355

1356 return true;

1357}

1358

1359

1360

1361SmallVector<MachineBasicBlock *, 4> &

1362MachineSinking::GetAllSortedSuccessors(MachineInstr &MI, MachineBasicBlock *MBB,

1363 AllSuccsCache &AllSuccessors) const {

1364

1365 auto Succs = AllSuccessors.find(MBB);

1366 if (Succs != AllSuccessors.end())

1367 return Succs->second;

1368

1369 SmallVector<MachineBasicBlock *, 4> AllSuccs(MBB->successors());

1370

1371

1372

1373

1374

1375

1376

1377

1379

1380 if (DTChild->getIDom()->getBlock() == MI.getParent() &&

1381

1383 AllSuccs.push_back(DTChild->getBlock());

1384 }

1385

1386

1388 AllSuccs, [&](const MachineBasicBlock *L, const MachineBasicBlock *R) {

1392 (!LHSFreq && !RHSFreq))

1394 return LHSFreq < RHSFreq;

1395 });

1396

1397 auto it = AllSuccessors.insert(std::make_pair(MBB, AllSuccs));

1398

1399 return it.first->second;

1400}

1401

1402

1403MachineBasicBlock *

1404MachineSinking::FindSuccToSinkTo(MachineInstr &MI, MachineBasicBlock *MBB,

1405 bool &BreakPHIEdge,

1406 AllSuccsCache &AllSuccessors) {

1407 assert(MBB && "Invalid MachineBasicBlock!");

1408

1409

1410

1411

1412

1413

1414 MachineBasicBlock *SuccToSinkTo = nullptr;

1415 for (const MachineOperand &MO : MI.operands()) {

1416 if (!MO.isReg())

1417 continue;

1418

1420 if (Reg == 0)

1421 continue;

1422

1424 if (MO.isUse()) {

1425

1426

1427

1429 return nullptr;

1430 } else if (!MO.isDead()) {

1431

1432 return nullptr;

1433 }

1434 } else {

1435

1437 continue;

1438

1439

1441 return nullptr;

1442

1443

1444

1445 if (SuccToSinkTo) {

1446

1447

1448 bool LocalUse = false;

1449 if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, MBB, BreakPHIEdge,

1450 LocalUse))

1451 return nullptr;

1452

1453 continue;

1454 }

1455

1456

1457

1458

1459

1460 for (MachineBasicBlock *SuccBlock :

1461 GetAllSortedSuccessors(MI, MBB, AllSuccessors)) {

1462 bool LocalUse = false;

1463 if (AllUsesDominatedByBlock(Reg, SuccBlock, MBB, BreakPHIEdge,

1464 LocalUse)) {

1465 SuccToSinkTo = SuccBlock;

1466 break;

1467 }

1468 if (LocalUse)

1469

1470 return nullptr;

1471 }

1472

1473

1474 if (!SuccToSinkTo)

1475 return nullptr;

1476 if (!isProfitableToSinkTo(Reg, MI, MBB, SuccToSinkTo, AllSuccessors))

1477 return nullptr;

1478 }

1479 }

1480

1481

1482

1483 if (MBB == SuccToSinkTo)

1484 return nullptr;

1485

1486

1487

1488 if (SuccToSinkTo && SuccToSinkTo->isEHPad())

1489 return nullptr;

1490

1491

1492

1493

1494

1496 return nullptr;

1497

1499 return nullptr;

1500

1501 return SuccToSinkTo;

1502}

1503

1504

1505

1506

1507

1508

1509

1510

1515

1516 auto *MBB = MI.getParent();

1517 if (MBB->pred_size() != 1)

1518 return false;

1519

1520 auto *PredMBB = *MBB->pred_begin();

1521 auto *PredBB = PredMBB->getBasicBlock();

1522

1523

1524

1525

1526 if (!PredBB ||

1527 !PredBB->getTerminator()->getMetadata(LLVMContext::MD_make_implicit))

1528 return false;

1529

1532 bool OffsetIsScalable;

1533 if (TII->getMemOperandWithOffset(MI, BaseOp, Offset, OffsetIsScalable, TRI))

1534 return false;

1535

1536 if (!BaseOp->isReg())

1537 return false;

1538

1539 if (!(MI.mayLoad() && MI.isPredicable()))

1540 return false;

1541

1542 MachineBranchPredicate MBP;

1543 if (TII->analyzeBranchPredicate(*PredMBB, MBP, false))

1544 return false;

1545

1546 return MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 &&

1547 (MBP.Predicate == MachineBranchPredicate::PRED_NE ||

1548 MBP.Predicate == MachineBranchPredicate::PRED_EQ) &&

1549 MBP.LHS.getReg() == BaseOp->getReg();

1550}

1551

1552

1553

1554

1555

1560

1561

1562

1563

1564

1565 const MachineOperand *SrcMO = nullptr, *DstMO = nullptr;

1566 auto CopyOperands = TII.isCopyInstr(SinkInst);

1567 if (!CopyOperands)

1568 return false;

1569 SrcMO = CopyOperands->Source;

1570 DstMO = CopyOperands->Destination;

1571

1572

1573 bool PostRA = MRI.getNumVirtRegs() == 0;

1574

1575

1577 return false;

1578

1579

1580

1581 bool arePhysRegs = Reg.isVirtual();

1582 if (arePhysRegs != PostRA)

1583 return false;

1584

1585

1586

1587 if (!PostRA)

1589 if (DbgMO.getSubReg() != SrcMO->getSubReg() ||

1590 DbgMO.getSubReg() != DstMO->getSubReg())

1591 return false;

1592

1593

1594

1595

1596 if (PostRA && Reg != DstMO->getReg())

1597 return false;

1598

1600 DbgMO.setReg(SrcMO->getReg());

1601 DbgMO.setSubReg(SrcMO->getSubReg());

1602 }

1603 return true;

1604}

1605

1606using MIRegs = std::pair<MachineInstr *, SmallVector<Register, 2>>;

1607

1611

1612

1613

1614 if (!SuccToSinkTo.empty() && InsertPos != SuccToSinkTo.end())

1616 InsertPos->getDebugLoc()));

1617 else

1619

1620

1622 SuccToSinkTo.splice(InsertPos, ParentBlock, MI,

1624

1625

1626

1627

1628

1629 for (const auto &DbgValueToSink : DbgValuesToSink) {

1631 MachineInstr *NewDbgMI = DbgMI->getMF()->CloneMachineInstr(DbgMI);

1632 SuccToSinkTo.insert(InsertPos, NewDbgMI);

1633

1634 bool PropagatedAllSunkOps = true;

1635 for (Register Reg : DbgValueToSink.second) {

1638 PropagatedAllSunkOps = false;

1639 break;

1640 }

1641 }

1642 }

1643 if (!PropagatedAllSunkOps)

1645 }

1646}

1647

1648

1649

1650bool MachineSinking::hasStoreBetween(MachineBasicBlock *From,

1651 MachineBasicBlock *To, MachineInstr &MI) {

1652

1653

1655 return true;

1656

1657 auto BlockPair = std::make_pair(From, To);

1658

1659

1660

1661 if (auto It = HasStoreCache.find(BlockPair); It != HasStoreCache.end())

1662 return It->second;

1663

1664 if (auto It = StoreInstrCache.find(BlockPair); It != StoreInstrCache.end())

1665 return llvm::any_of(It->second, [&](MachineInstr *I) {

1666 return I->mayAlias(AA, MI, false);

1667 });

1668

1669 bool SawStore = false;

1670 bool HasAliasedStore = false;

1671 DenseSet<MachineBasicBlock *> HandledBlocks;

1672 DenseSet<MachineBasicBlock *> HandledDomBlocks;

1673

1674 for (MachineBasicBlock *BB : depth_first(From)) {

1675

1676

1677

1678

1679 if (BB == To || BB == From)

1680 continue;

1681

1682

1683 if (HandledBlocks.count(BB))

1684 continue;

1685

1686 HandledBlocks.insert(BB);

1687

1689 if (!HandledDomBlocks.count(BB))

1690 HandledDomBlocks.insert(BB);

1691

1692

1693

1696 for (auto *DomBB : HandledDomBlocks) {

1697 if (DomBB != BB && DT->dominates(DomBB, BB))

1698 HasStoreCache[std::make_pair(DomBB, To)] = true;

1699 else if (DomBB != BB && DT->dominates(BB, DomBB))

1700 HasStoreCache[std::make_pair(From, DomBB)] = true;

1701 }

1702 HasStoreCache[BlockPair] = true;

1703 return true;

1704 }

1705

1706 for (MachineInstr &I : *BB) {

1707

1708

1709 if (I.isCall() || I.hasOrderedMemoryRef()) {

1710 for (auto *DomBB : HandledDomBlocks) {

1711 if (DomBB != BB && DT->dominates(DomBB, BB))

1712 HasStoreCache[std::make_pair(DomBB, To)] = true;

1713 else if (DomBB != BB && DT->dominates(BB, DomBB))

1714 HasStoreCache[std::make_pair(From, DomBB)] = true;

1715 }

1716 HasStoreCache[BlockPair] = true;

1717 return true;

1718 }

1719

1720 if (I.mayStore()) {

1721 SawStore = true;

1722

1723

1724

1725

1726 if (I.mayAlias(AA, MI, false))

1727 HasAliasedStore = true;

1728 StoreInstrCache[BlockPair].push_back(&I);

1729 }

1730 }

1731 }

1732 }

1733

1734 if (!SawStore)

1735 HasStoreCache[BlockPair] = false;

1736 return HasAliasedStore;

1737}

1738

1739

1740

1741

1742

1743

1744bool MachineSinking::aggressivelySinkIntoCycle(

1746 DenseMap<SinkItem, MachineInstr *> &SunkInstrs) {

1747

1748 if (I.getNumDefs() > 1)

1749 return false;

1750

1751 LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Finding sink block for: " << I);

1754

1755 MachineOperand &DefMO = I.getOperand(0);

1756 for (MachineInstr &MI : MRI->use_instructions(DefMO.getReg())) {

1758 }

1759

1760 for (std::pair<RegSubRegPair, MachineInstr *> Entry : Uses) {

1761 MachineInstr *MI = Entry.second;

1762 LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Analysing use: " << MI);

1763 if (MI->isPHI()) {

1765 dbgs() << "AggressiveCycleSink: Not attempting to sink for PHI.\n");

1766 continue;

1767 }

1768

1770 LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Use is BasicBlock prologue, "

1771 "can't sink.\n");

1772 continue;

1773 }

1776 dbgs() << "AggressiveCycleSink: Use not in cycle, can't sink.\n");

1777 continue;

1778 }

1779

1780 MachineBasicBlock *SinkBlock = MI->getParent();

1781 MachineInstr *NewMI = nullptr;

1782 SinkItem MapEntry(&I, SinkBlock);

1783

1784 auto SI = SunkInstrs.find(MapEntry);

1785

1786

1787

1788 if (SI != SunkInstrs.end()) {

1789 LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Already sunk to block: "

1791 NewMI = SI->second;

1792 }

1793

1794

1795 if (!NewMI) {

1796 LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Sinking instruction to block: "

1798

1799 NewMI = I.getMF()->CloneMachineInstr(&I);

1801 const TargetRegisterClass *TRC = MRI->getRegClass(DefMO.getReg());

1802 Register DestReg = MRI->createVirtualRegister(TRC);

1805 }

1807 NewMI);

1808 SunkInstrs.insert({MapEntry, NewMI});

1809 }

1810

1811

1812 for (MachineOperand &MO : NewMI->all_uses()) {

1814 RegsToClearKillFlags.insert(MO.getReg());

1815 }

1816

1817

1818

1821

1822

1826 }

1827

1828 if (I.isDead(*MRI))

1829 I.eraseFromParent();

1830 return true;

1831}

1832

1833

1834

1835bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,

1836 AllSuccsCache &AllSuccessors) {

1837

1839 return false;

1840

1841

1842 if (MI.isSafeToMove(SawStore))

1843 return false;

1844

1845

1846

1847 if (MI.isConvergent())

1848 return false;

1849

1850

1851

1853 return false;

1854

1855

1856

1857

1858

1859

1860

1861

1862

1863 bool BreakPHIEdge = false;

1864 MachineBasicBlock *ParentBlock = MI.getParent();

1865 MachineBasicBlock *SuccToSinkTo =

1866 FindSuccToSinkTo(MI, ParentBlock, BreakPHIEdge, AllSuccessors);

1867

1868

1869 if (!SuccToSinkTo)

1870 return false;

1871

1872

1873

1874

1875 for (const MachineOperand &MO : MI.all_defs()) {

1878 continue;

1880 return false;

1881 }

1882

1883 LLVM_DEBUG(dbgs() << "Sink instr " << MI << "\tinto block " << *SuccToSinkTo);

1884

1885

1886

1887 if (SuccToSinkTo->pred_size() > 1) {

1888

1889

1890 bool TryBreak = false;

1892 MI.mayLoad() ? hasStoreBetween(ParentBlock, SuccToSinkTo, MI) : true;

1893 if (MI.isSafeToMove(Store)) {

1894 LLVM_DEBUG(dbgs() << " *** NOTE: Won't sink load along critical edge.\n");

1895 TryBreak = true;

1896 }

1897

1898

1899

1900 if (!TryBreak && !DT->dominates(ParentBlock, SuccToSinkTo)) {

1901 LLVM_DEBUG(dbgs() << " *** NOTE: Critical edge found\n");

1902 TryBreak = true;

1903 }

1904

1905

1906 if (!TryBreak && CI->getCycle(SuccToSinkTo) &&

1909 LLVM_DEBUG(dbgs() << " *** NOTE: cycle header found\n");

1910 TryBreak = true;

1911 }

1912

1913

1914 if (!TryBreak)

1915 LLVM_DEBUG(dbgs() << "Sinking along critical edge.\n");

1916 else {

1917

1918

1919

1920 bool Status = PostponeSplitCriticalEdge(MI, ParentBlock, SuccToSinkTo,

1921 BreakPHIEdge);

1922 if (!Status)

1923 LLVM_DEBUG(dbgs() << " *** PUNTING: Not legal or profitable to "

1924 "break critical edge\n");

1925

1926 return false;

1927 }

1928 }

1929

1930 if (BreakPHIEdge) {

1931

1932

1933

1934 bool Status =

1935 PostponeSplitCriticalEdge(MI, ParentBlock, SuccToSinkTo, BreakPHIEdge);

1936 if (!Status)

1937 LLVM_DEBUG(dbgs() << " *** PUNTING: Not legal or profitable to "

1938 "break critical edge\n");

1939

1940 return false;

1941 }

1942

1943

1947 LLVM_DEBUG(dbgs() << " *** Not sinking: prologue interference\n");

1948 return false;

1949 }

1950

1951

1953 for (auto &MO : MI.all_defs()) {

1955 continue;

1956 auto It = SeenDbgUsers.find(MO.getReg());

1957 if (It == SeenDbgUsers.end())

1958 continue;

1959

1960

1961 auto &Users = It->second;

1962 for (auto &User : Users) {

1963 MachineInstr *DbgMI = User.getPointer();

1964 if (User.getInt()) {

1965

1966

1969 } else {

1972 }

1973 }

1974 }

1975

1976

1977

1978

1979 if (MI.getMF()->getFunction().getSubprogram() && MI.isCopy())

1980 SalvageUnsunkDebugUsersOfCopy(MI, SuccToSinkTo);

1981

1982 performSink(MI, *SuccToSinkTo, InsertPos, DbgUsersToSink);

1983

1984

1985

1986

1987

1988

1989 for (MachineOperand &MO : MI.all_uses())

1990 RegsToClearKillFlags.insert(MO.getReg());

1991

1992 return true;

1993}

1994

1995void MachineSinking::SalvageUnsunkDebugUsersOfCopy(

1996 MachineInstr &MI, MachineBasicBlock *TargetBlock) {

1998 assert(MI.getOperand(1).isReg());

1999

2000

2001

2002

2003 SmallVector<MachineInstr *, 4> DbgDefUsers;

2005 const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();

2006 for (auto &MO : MI.all_defs()) {

2008 continue;

2010 for (auto &User : MRI.use_instructions(MO.getReg())) {

2011 if (User.isDebugValue() || DT->dominates(TargetBlock, User.getParent()))

2012 continue;

2013

2014

2015 if (User.getParent() == MI.getParent())

2016 continue;

2017

2019 "DBG_VALUE user of vreg, but has no operand for it?");

2021 }

2022 }

2023

2024

2025

2026 for (auto *User : DbgDefUsers) {

2027 for (auto &Reg : DbgUseRegs) {

2028 for (auto &DbgOp : User->getDebugOperandsForReg(Reg)) {

2029 DbgOp.setReg(MI.getOperand(1).getReg());

2030 DbgOp.setSubReg(MI.getOperand(1).getSubReg());

2031 }

2032 }

2033 }

2034}

2035

2036

2037

2038

2039

2040

2041

2042

2043

2044

2045

2046

2047

2048

2049

2050

2051

2052

2053

2054

2055

2056

2057

2058

2059

2060

2061

2062

2063

2064

2065

2066

2067

2068

2069

2070namespace {

2071

2072class PostRAMachineSinkingImpl {

2073

2074 LiveRegUnits ModifiedRegUnits, UsedRegUnits;

2075

2076

2077

2078

2079

2080 DenseMap<MCRegUnit, SmallVector<MIRegs, 2>> SeenDbgInstrs;

2081

2082

2083

2084 bool tryToSinkCopy(MachineBasicBlock &BB, MachineFunction &MF,

2085 const TargetRegisterInfo *TRI, const TargetInstrInfo *TII);

2086

2087public:

2088 bool run(MachineFunction &MF);

2089};

2090

2091class PostRAMachineSinkingLegacy : public MachineFunctionPass {

2092public:

2093 bool runOnMachineFunction(MachineFunction &MF) override;

2094

2095 static char ID;

2096 PostRAMachineSinkingLegacy() : MachineFunctionPass(ID) {}

2097 StringRef getPassName() const override { return "PostRA Machine Sink"; }

2098

2099 void getAnalysisUsage(AnalysisUsage &AU) const override {

2102 }

2103

2104 MachineFunctionProperties getRequiredProperties() const override {

2105 return MachineFunctionProperties().setNoVRegs();

2106 }

2107};

2108

2109}

2110

2111char PostRAMachineSinkingLegacy::ID = 0;

2113

2115 "PostRA Machine Sink", false, false)

2116

2122}

2123

2124static MachineBasicBlock *

2128

2130 for (auto *SI : SinkableBBs) {

2131 if (aliasWithRegsInLiveIn(*SI, Reg, TRI)) {

2132

2133

2134 if (BB)

2135 return nullptr;

2136 BB = SI;

2137 }

2138 }

2139

2140 if (!BB)

2141 return nullptr;

2142

2143

2145 if (!SinkableBBs.count(SI) && aliasWithRegsInLiveIn(*SI, Reg, TRI))

2146 return nullptr;

2147 }

2148 return BB;

2149}

2150

2151static MachineBasicBlock *

2157 for (auto DefReg : DefedRegsInCopy) {

2160 if (!BB || (SingleBB && SingleBB != BB))

2161 return nullptr;

2162 SingleBB = BB;

2163 }

2164 return SingleBB;

2165}

2166

2171 for (auto U : UsedOpsInCopy) {

2174 if (!UsedRegUnits.available(SrcReg)) {

2177 if (UI.killsRegister(SrcReg, TRI)) {

2178 UI.clearRegisterKills(SrcReg, TRI);

2180 break;

2181 }

2182 }

2183 }

2184 }

2185}

2186

2190 for (Register DefReg : DefedRegsInCopy)

2192

2193 for (auto U : UsedOpsInCopy)

2194 SuccBB->addLiveIn(MI->getOperand(U).getReg());

2196}

2197

2203 bool HasRegDependency = false;

2204 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {

2206 if (!MO.isReg())

2207 continue;

2209 if (Reg)

2210 continue;

2211 if (MO.isDef()) {

2213 HasRegDependency = true;

2214 break;

2215 }

2217

2218

2219

2220

2221

2222 } else if (MO.isUse()) {

2224 HasRegDependency = true;

2225 break;

2226 }

2228 }

2229 }

2230 return HasRegDependency;

2231}

2232

2233bool PostRAMachineSinkingImpl::tryToSinkCopy(MachineBasicBlock &CurBB,

2234 MachineFunction &MF,

2235 const TargetRegisterInfo *TRI,

2236 const TargetInstrInfo *TII) {

2237 SmallPtrSet<MachineBasicBlock *, 2> SinkableBBs;

2238

2239

2240

2241 for (MachineBasicBlock *SI : CurBB.successors())

2242 if (SI->livein_empty() && SI->pred_size() == 1)

2243 SinkableBBs.insert(SI);

2244

2245 if (SinkableBBs.empty())

2246 return false;

2247

2249

2250

2251

2252 ModifiedRegUnits.clear();

2253 UsedRegUnits.clear();

2254 SeenDbgInstrs.clear();

2255

2257

2258 SmallVector<unsigned, 2> UsedOpsInCopy;

2259

2261

2262

2263

2264 if (MI.isDebugValue() && MI.isDebugRef()) {

2265 SmallDenseMap<MCRegUnit, SmallVector<Register, 2>, 4> MIUnits;

2266 bool IsValid = true;

2267 for (MachineOperand &MO : MI.debug_operands()) {

2269

2270

2272 ModifiedRegUnits, UsedRegUnits)) {

2273 IsValid = false;

2274 break;

2275 }

2276

2277

2278 for (MCRegUnit Unit : TRI->regunits(MO.getReg()))

2279 MIUnits[Unit].push_back(MO.getReg());

2280 }

2281 }

2282 if (IsValid) {

2283 for (auto &RegOps : MIUnits)

2284 SeenDbgInstrs[RegOps.first].emplace_back(&MI,

2285 std::move(RegOps.second));

2286 }

2287 continue;

2288 }

2289

2290

2292 continue;

2293

2294 if (MI.isDebugOrPseudoInstr())

2295 continue;

2296

2297

2298 if (MI.isCall())

2299 return false;

2300

2301 if (MI.isCopy() || MI.getOperand(0).isRenamable()) {

2304 continue;

2305 }

2306

2307

2309 ModifiedRegUnits, UsedRegUnits)) {

2312 continue;

2313 }

2314 assert((!UsedOpsInCopy.empty() && !DefedRegsInCopy.empty()) &&

2315 "Unexpect SrcReg or DefReg");

2316 MachineBasicBlock *SuccBB =

2318

2319

2320 if (!SuccBB) {

2323 continue;

2324 }

2326 "Unexpected predecessor");

2327

2328

2329

2330

2331 MapVector<MachineInstr *, MIRegs::second_type> DbgValsToSinkMap;

2332 for (auto &MO : MI.all_defs()) {

2333 for (MCRegUnit Unit : TRI->regunits(MO.getReg())) {

2334 for (const auto &MIRegs : SeenDbgInstrs.lookup(Unit)) {

2335 auto &Regs = DbgValsToSinkMap[MIRegs.first];

2337 }

2338 }

2339 }

2340 auto DbgValsToSink = DbgValsToSinkMap.takeVector();

2341

2342 LLVM_DEBUG(dbgs() << "Sink instr " << MI << "\tinto block " << *SuccBB);

2343

2349 LLVM_DEBUG(dbgs() << " *** Not sinking: prologue interference\n");

2350 continue;

2351 }

2352

2353

2354

2356 performSink(MI, *SuccBB, InsertPos, DbgValsToSink);

2357 updateLiveIn(&MI, SuccBB, UsedOpsInCopy, DefedRegsInCopy);

2358

2360 ++NumPostRACopySink;

2361 }

2363}

2364

2365bool PostRAMachineSinkingImpl::run(MachineFunction &MF) {

2369

2370 ModifiedRegUnits.init(*TRI);

2371 UsedRegUnits.init(*TRI);

2372 for (auto &BB : MF)

2374

2376}

2377

2378bool PostRAMachineSinkingLegacy::runOnMachineFunction(MachineFunction &MF) {

2380 return false;

2381

2382 return PostRAMachineSinkingImpl().run(MF);

2383}

2384

2385PreservedAnalyses

2389

2390 if (!PostRAMachineSinkingImpl().run(MF))

2392

2395 return PA;

2396}

unsigned const MachineRegisterInfo * MRI

MachineInstrBuilder MachineInstrBuilder & DefMI

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

const TargetInstrInfo & TII

This file defines the DenseSet and SmallDenseSet classes.

This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.

static const HTTPClientCleanup Cleanup

static Register UseReg(const MachineOperand &MO)

iv Induction Variable Users

static bool mayLoadFromGOTOrConstantPool(MachineInstr &MI)

Return true if this machine instruction loads from global offset table or constant pool.

static cl::opt< unsigned > SinkLoadInstsPerBlockThreshold("machine-sink-load-instrs-threshold", cl::desc("Do not try to find alias store for a load if there is a in-path " "block whose instruction number is higher than this threshold."), cl::init(2000), cl::Hidden)

static cl::opt< unsigned > SinkIntoCycleLimit("machine-sink-cycle-limit", cl::desc("The maximum number of instructions considered for cycle sinking."), cl::init(50), cl::Hidden)

TargetInstrInfo::RegSubRegPair RegSubRegPair

Definition MachineSink.cpp:122

Register Reg

Definition MachineSink.cpp:2117

static void clearKillFlags(MachineInstr *MI, MachineBasicBlock &CurBB, const SmallVectorImpl< unsigned > &UsedOpsInCopy, const LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)

Definition MachineSink.cpp:2167

static void performSink(MachineInstr &MI, MachineBasicBlock &SuccToSinkTo, MachineBasicBlock::iterator InsertPos, ArrayRef< MIRegs > DbgValuesToSink)

Sink an instruction and its associated debug instructions.

Definition MachineSink.cpp:1608

static cl::opt< bool > SplitEdges("machine-sink-split", cl::desc("Split critical edges during machine sinking"), cl::init(true), cl::Hidden)

static bool SinkingPreventsImplicitNullCheck(MachineInstr &MI, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)

Return true if MI is likely to be usable as a memory operation by the implicit null check optimizatio...

Definition MachineSink.cpp:1511

static cl::opt< bool > SinkInstsIntoCycle("sink-insts-to-avoid-spills", cl::desc("Sink instructions into cycles to avoid " "register spills"), cl::init(false), cl::Hidden)

static cl::opt< unsigned > SinkLoadBlocksThreshold("machine-sink-load-blocks-threshold", cl::desc("Do not try to find alias store for a load if the block number in " "the straight line is higher than this threshold."), cl::init(20), cl::Hidden)

static void updateLiveIn(MachineInstr *MI, MachineBasicBlock *SuccBB, const SmallVectorImpl< unsigned > &UsedOpsInCopy, const SmallVectorImpl< Register > &DefedRegsInCopy)

Definition MachineSink.cpp:2187

static bool hasRegisterDependency(MachineInstr *MI, SmallVectorImpl< unsigned > &UsedOpsInCopy, SmallVectorImpl< Register > &DefedRegsInCopy, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits)

Definition MachineSink.cpp:2198

Register const TargetRegisterInfo * TRI

Definition MachineSink.cpp:2118

std::pair< MachineInstr *, SmallVector< Register, 2 > > MIRegs

Definition MachineSink.cpp:1606

Machine code static false bool blockPrologueInterferes(const MachineBasicBlock *BB, MachineBasicBlock::const_iterator End, const MachineInstr &MI, const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, const MachineRegisterInfo *MRI)

Return true if a target defined block prologue instruction interferes with a sink candidate.

Definition MachineSink.cpp:336

static cl::opt< unsigned > SplitEdgeProbabilityThreshold("machine-sink-split-probability-threshold", cl::desc("Percentage threshold for splitting single-instruction critical edge. " "If the branch threshold is higher than this threshold, we allow " "speculative execution of up to 1 instruction to avoid branching to " "splitted critical edge"), cl::init(40), cl::Hidden)

static bool attemptDebugCopyProp(MachineInstr &SinkInst, MachineInstr &DbgMI, Register Reg)

If the sunk instruction is a copy, try to forward the copy instead of leaving an 'undef' DBG_VALUE in...

Definition MachineSink.cpp:1556

static cl::opt< bool > UseBlockFreqInfo("machine-sink-bfi", cl::desc("Use block frequency info to find successors to sink"), cl::init(true), cl::Hidden)

static MachineBasicBlock * getSingleLiveInSuccBB(MachineBasicBlock &CurBB, const SmallPtrSetImpl< MachineBasicBlock * > &SinkableBBs, Register Reg, const TargetRegisterInfo *TRI)

Definition MachineSink.cpp:2125

This file implements a map that provides insertion order iteration.

Promote Memory to Register

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

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

This file defines the PointerIntPair class.

Remove Loads Into Fake Uses

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

static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI, AAResults &AA)

static bool SinkInstruction(Instruction *Inst, SmallPtrSetImpl< Instruction * > &Stores, DominatorTree &DT, LoopInfo &LI, AAResults &AA)

SinkInstruction - Determine whether it is safe to sink the specified machine instruction out of its c...

This file defines the SmallSet class.

This file defines the SmallVector class.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

Target-Independent Code Generator Pass Configuration Options pass.

A manager for alias analyses.

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

PassT::Result * getCachedResult(IRUnitT &IR) const

Get the cached result of an analysis pass for a given IR unit.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

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.

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

uint64_t getFrequency() const

Returns the frequency as a fixpoint number scaled by the entry frequency.

Represents analyses that only rely on functions' control flow.

static LLVM_ABI DebugLoc getMergedLocation(DebugLoc LocA, DebugLoc LocB)

When two instructions are combined into a single instruction we also need to combine the original loc...

iterator find(const_arg_type_t< KeyT > Val)

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

Implements a dense probed hash-table based set.

bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const

dominates - Returns true iff A dominates B.

bool isReachableFromEntry(const NodeT *A) const

isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...

DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const

getNode - return the (Post)DominatorTree node for the specified basic block.

iterator_range< const_toplevel_iterator > toplevel_cycles() const

void splitCriticalEdge(BlockT *Pred, BlockT *Succ, BlockT *New)

unsigned getCycleDepth(const BlockT *Block) const

get the depth for the cycle which containing a given block.

CycleT * getCycle(const BlockT *Block) const

Find the innermost cycle containing a given block.

BlockT * getHeader() const

bool isReducible() const

Whether the cycle is a natural loop.

BlockT * getCyclePreheader() const

Return the preheader block for this cycle.

bool contains(const BlockT *Block) const

Return whether Block is contained in the cycle.

Module * getParent()

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

A set of register units used to track register liveness.

static void accumulateUsedDefed(const MachineInstr &MI, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)

For a machine instruction MI, adds all register units used in UsedRegUnits and defined or clobbered i...

bool available(MCRegister Reg) const

Returns true if no part of physical register Reg is live.

void init(const TargetRegisterInfo &TRI)

Initialize and clear the set.

LLVM_ABI void addLiveIns(const MachineBasicBlock &MBB)

Adds registers living into block MBB.

void clear()

Clears the set.

An RAII based helper class to modify MachineFunctionProperties when running pass.

bool isInlineAsmBrIndirectTarget() const

Returns true if this is the indirect dest of an INLINEASM_BR.

unsigned pred_size() const

bool isEHPad() const

Returns true if the block is a landing pad.

instr_iterator instr_begin()

MachineInstrBundleIterator< const MachineInstr > const_iterator

LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)

Insert MI into the instruction list before I, possibly inside a bundle.

LLVM_ABI iterator SkipPHIsAndLabels(iterator I)

Return the first instruction in MBB after I that is not a PHI or a label.

unsigned succ_size() const

LLVM_ABI void sortUniqueLiveIns()

Sorts and uniques the LiveIns vector.

pred_iterator pred_begin()

LLVM_ABI void removeLiveInOverlappedWith(MCRegister Reg)

Remove the specified register from any overlapped live in.

instr_iterator instr_end()

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

Adds the specified register as a live in.

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

iterator_range< succ_iterator > successors()

LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const

Return true if the specified MBB is a successor of this block.

iterator_range< pred_iterator > predecessors()

void splice(iterator Where, MachineBasicBlock *Other, iterator From)

Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...

MachineInstrBundleIterator< MachineInstr > iterator

LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const

Return true if the specified register is in the live in set.

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

LLVM_ABI BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const

getblockFreq - Return block frequency.

LLVM_ABI void onEdgeSplit(const MachineBasicBlock &NewPredecessor, const MachineBasicBlock &NewSuccessor, const MachineBranchProbabilityInfo &MBPI)

incrementally calculate block frequencies when we split edges, to avoid full CFG traversal.

BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const

Legacy analysis pass which computes a MachineCycleInfo.

Analysis pass which computes a MachineDominatorTree.

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.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

Representation of each machine instruction.

bool hasDebugOperandForReg(Register Reg) const

Returns whether this debug value has at least one debug operand with the register Reg.

void setDebugValueUndef()

Sets all register debug operands in this debug value instruction to be undef.

LLVM_ABI iterator_range< filter_iterator< const MachineOperand *, std::function< bool(const MachineOperand &Op)> > > getDebugOperandsForReg(Register Reg) const

Returns a range of all of the operands that correspond to a debug use of Reg.

bool mayLoadOrStore(QueryType Type=AnyInBundle) const

Return true if this instruction could possibly read or modify memory.

const MachineBasicBlock * getParent() const

bool isCopyLike() const

Return true if the instruction behaves like a copy.

bool isDebugInstr() const

LLVM_ABI void substituteRegister(Register FromReg, Register ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)

Replace all occurrences of FromReg with ToReg:SubIdx, properly composing subreg indices where necessa...

LLVM_ABI const MachineFunction * getMF() const

Return the function that contains the basic block that this instruction belongs to.

filtered_mop_range all_uses()

Returns an iterator range over all operands that are (explicit or implicit) register uses.

const MachineOperand & getOperand(unsigned i) const

void setDebugLoc(DebugLoc DL)

Replace current source information with new such.

Analysis pass that exposes the MachineLoopInfo for a machine function.

A description of a memory reference used in the backend.

MachineOperand class - Representation of each machine instruction operand.

unsigned getSubReg() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

MachineBasicBlock * getMBB() const

void setIsKill(bool Val=true)

MachineInstr * getParent()

getParent - Return the instruction that this operand belongs to.

Register getReg() const

getReg - Returns the register number.

MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...

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

PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &)

Definition MachineSink.cpp:757

void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)

Definition MachineSink.cpp:787

VectorType takeVector()

Clear the MapVector and return the underlying vector.

static LLVM_ABI PassRegistry * getPassRegistry()

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

PointerIntPair - This class implements a pair of a pointer and small integer.

PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)

Definition MachineSink.cpp:2386

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

PreservedAnalyses & preserveSet()

Mark an analysis set as preserved.

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

Analysis providing profile information.

Special value supplied for machine level alias analysis.

unsigned getRegPressureSetLimit(unsigned Idx) const

Get the register unit limit for the given pressure set index.

LLVM_ABI void runOnMachineFunction(const MachineFunction &MF, bool Rev=false)

runOnFunction - Prepare to answer questions about MF.

LLVM_ABI void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)

Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...

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.

A vector that has set insertion semantics.

A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...

size_type count(ConstPtrType Ptr) const

count - Return 1 if the specified pointer is in the set, 0 otherwise.

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

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

reference emplace_back(ArgTypes &&... Args)

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 isBasicBlockPrologue(const MachineInstr &MI, Register Reg=Register()) const

True if the instruction is bound to the top of its basic block and no other instructions shall be ins...

virtual bool hasLowDefLatency(const TargetSchedModel &SchedModel, const MachineInstr &DefMI, unsigned DefIdx) const

Compute operand latency of a def of 'Reg'.

virtual bool isSafeToSink(MachineInstr &MI, MachineBasicBlock *SuccToSinkTo, MachineCycleInfo *CI) const

virtual bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, const MachineInstr &AddrI, ExtAddrMode &AM) const

Check if it's possible and beneficial to fold the addressing computation AddrI into the addressing mo...

virtual bool shouldBreakCriticalEdgeToSink(MachineInstr &MI) const

For a "cheap" instruction which doesn't enable additional sinking, should MachineSink break a critica...

virtual bool isIgnorableUse(const MachineOperand &MO) const

Given MO is a PhysReg use return if it can be ignored for the purpose of instruction rematerializatio...

virtual bool shouldPostRASink(const MachineInstr &MI) const

virtual bool isAsCheapAsAMove(const MachineInstr &MI) const

Return true if the instruction is as cheap as a move instruction.

virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, unsigned SubIdx, const MachineInstr &Orig) const

Re-issue the specified 'original' instruction at the specific location targeting a new destination re...

virtual bool shouldSink(const MachineInstr &MI) const

Return true if the instruction should be sunk by MachineSink.

virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const

Return true if it's safe to move a machine instruction that defines the specified register class.

virtual MachineInstr * emitLdStWithAddr(MachineInstr &MemI, const ExtAddrMode &AM) const

Emit a load/store instruction with the same value register as MemI, but using the address from AM.

Target-Independent Code Generator Pass Configuration Options.

bool getEnableSinkAndFold() const

bool contains(Register Reg) const

Return true if the specified register is included in this register class.

bool hasSuperClassEq(const TargetRegisterClass *RC) const

Returns true if RC is a super-class of or equal to this class.

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

Provide an instruction scheduling machine model to CodeGen passes.

LLVM_ABI void init(const TargetSubtargetInfo *TSInfo, bool EnableSModel=true, bool EnableSItins=true)

Initialize the machine model for instruction scheduling.

TargetSubtargetInfo - Generic base class for all target subtargets.

virtual const TargetInstrInfo * getInstrInfo() const

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

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

size_type count(const_arg_type_t< ValueT > V) const

Return 1 if the specified key is in the set, 0 otherwise.

An efficient, type-erasing, non-owning reference to a callable.

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

Abstract Attribute helper functions.

unsigned ID

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

initializer< Ty > init(const Ty &Val)

PointerTypeMap run(const Module &M)

Compute the PointerTypeMap for the module M.

@ User

could "use" a pointer

This is an optimization pass for GlobalISel generic memory operations.

void stable_sort(R &&Range)

LLVM_ABI void initializeMachineSinkingLegacyPass(PassRegistry &)

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy

Provide the ModuleAnalysisManager to Function proxy.

LLVM_ABI bool isCycleInvariant(const MachineCycle *Cycle, MachineInstr &I)

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

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

Wrapper function to append range R to container C.

LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)

Returns true if machine function MF is suggested to be size-optimized based on the profile.

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

AnalysisManager< MachineFunction > MachineFunctionAnalysisManager

LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()

Returns the minimum set of Analyses that all machine function passes must preserve.

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

auto reverse(ContainerTy &&C)

LLVM_ABI raw_ostream & dbgs()

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

LLVM_ABI char & PostRAMachineSinkingID

This pass perform post-ra machine sink for COPY instructions.

Definition MachineSink.cpp:2112

class LLVM_GSL_OWNER SmallVector

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

DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode

LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key

LLVM_ABI char & MachineSinkingLegacyID

MachineSinking - This pass performs sinking on machine instructions.

Definition MachineSink.cpp:322

iterator_range< df_iterator< T > > depth_first(const T &G)

AAResults AliasAnalysis

Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.

GenericCycleInfo< MachineSSAContext > MachineCycleInfo

MachineCycleInfo::CycleT MachineCycle

LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)

Prints a machine basic block reference.

Represents a predicate at the MachineFunction level.

A pair composed of a register and a sub-register index.