LLVM: lib/Target/Mips/MipsConstantIslandPass.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

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

50#include

51#include

52#include

53#include

54

55using namespace llvm;

56

57#define DEBUG_TYPE "mips-constant-islands"

58

59STATISTIC(NumCPEs, "Number of constpool entries");

60STATISTIC(NumSplit, "Number of uncond branches inserted");

61STATISTIC(NumCBrFixed, "Number of cond branches fixed");

62STATISTIC(NumUBrFixed, "Number of uncond branches fixed");

63

64

67 cl::desc("Align constant islands in code"));

68

69

70

72 "mips-constant-islands-small-offset",

74 cl::desc("Make small offsets be this amount for testing purposes"),

76

77

78

80 "mips-constant-islands-no-load-relaxation",

82 cl::desc("Don't relax loads to long loads - for testing purposes"),

84

86 switch (MI->getOpcode()) {

87 case Mips::Bimm16:

88 case Mips::BimmX16:

89 case Mips::Bteqz16:

90 case Mips::BteqzX16:

91 case Mips::Btnez16:

92 case Mips::BtnezX16:

93 case Mips::JalB16:

94 return 0;

95 case Mips::BeqzRxImm16:

96 case Mips::BeqzRxImmX16:

97 case Mips::BnezRxImm16:

98 case Mips::BnezRxImmX16:

99 return 1;

100 }

102}

103

105 switch (Opcode) {

106 case Mips::Bimm16:

107 case Mips::BimmX16:

108 return Mips::BimmX16;

109 case Mips::Bteqz16:

110 case Mips::BteqzX16:

111 return Mips::BteqzX16;

112 case Mips::Btnez16:

113 case Mips::BtnezX16:

114 return Mips::BtnezX16;

115 case Mips::JalB16:

116 return Mips::JalB16;

117 case Mips::BeqzRxImm16:

118 case Mips::BeqzRxImmX16:

119 return Mips::BeqzRxImmX16;

120 case Mips::BnezRxImm16:

121 case Mips::BnezRxImmX16:

122 return Mips::BnezRxImmX16;

123 }

125}

126

127

128

129

130

132 unsigned Bits, Scale;

133 switch (Opcode) {

134 case Mips::Bimm16:

135 Bits = 11;

136 Scale = 2;

137 break;

138 case Mips::BimmX16:

139 Bits = 16;

140 Scale = 2;

141 break;

142 case Mips::BeqzRxImm16:

143 Bits = 8;

144 Scale = 2;

145 break;

146 case Mips::BeqzRxImmX16:

147 Bits = 16;

148 Scale = 2;

149 break;

150 case Mips::BnezRxImm16:

151 Bits = 8;

152 Scale = 2;

153 break;

154 case Mips::BnezRxImmX16:

155 Bits = 16;

156 Scale = 2;

157 break;

158 case Mips::Bteqz16:

159 Bits = 8;

160 Scale = 2;

161 break;

162 case Mips::BteqzX16:

163 Bits = 16;

164 Scale = 2;

165 break;

166 case Mips::Btnez16:

167 Bits = 8;

168 Scale = 2;

169 break;

170 case Mips::BtnezX16:

171 Bits = 16;

172 Scale = 2;

173 break;

174 default:

176 }

177 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;

178 return MaxOffs;

179}

180

181namespace {

182

185

186

187

188

189

190

191

192

193

194

195

196

197

199

200

201 struct BasicBlockInfo {

202

203

204

205

206

207

208

209

210

211 unsigned Offset = 0;

212

213

214

215

216

217

218 unsigned Size = 0;

219

220 BasicBlockInfo() = default;

221

222 unsigned postOffset() const { return Offset + Size; }

223 };

224

225 std::vector BBInfo;

226

227

228

229

230 std::vector<MachineBasicBlock*> WaterList;

231

232

233

234 SmallPtrSet<MachineBasicBlock *, 4> NewWaterList;

235

236 using water_iterator = std::vector<MachineBasicBlock *>::iterator;

237

238

239

240

241

242

243

244

245

246

247

248

249

250 struct CPUser {

251 MachineInstr *MI;

252 MachineInstr *CPEMI;

253 MachineBasicBlock *HighWaterMark;

254

255 private:

256 unsigned MaxDisp;

257 unsigned LongFormMaxDisp;

258

259 unsigned LongFormOpcode;

260

261 public:

262 bool NegOk;

263

264 CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp,

265 bool neg,

266 unsigned longformmaxdisp, unsigned longformopcode)

267 : MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),

268 LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),

269 NegOk(neg){

270 HighWaterMark = CPEMI->getParent();

271 }

272

273

274 unsigned getMaxDisp() const {

277 return xMaxDisp;

278 }

279

280 void setMaxDisp(unsigned val) {

281 MaxDisp = val;

282 }

283

284 unsigned getLongFormMaxDisp() const {

285 return LongFormMaxDisp;

286 }

287

288 unsigned getLongFormOpcode() const {

289 return LongFormOpcode;

290 }

291 };

292

293

294

295 std::vector CPUsers;

296

297

298

299

300 struct CPEntry {

301 MachineInstr *CPEMI;

302 unsigned CPI;

303 unsigned RefCount;

304

305 CPEntry(MachineInstr *cpemi, unsigned cpi, unsigned rc = 0)

306 : CPEMI(cpemi), CPI(cpi), RefCount(rc) {}

307 };

308

309

310

311

312

313

314 std::vector<std::vector> CPEntries;

315

316

317

318

319

320 struct ImmBranch {

321 MachineInstr *MI;

322 unsigned MaxDisp : 31;

324 unsigned isCond : 1;

325 int UncondBr;

326

327 ImmBranch(MachineInstr *mi, unsigned maxdisp, bool cond, int ubr)

328 : MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}

329 };

330

331

332

333 std::vector ImmBranches;

334

335

336

337 bool HasFarJump;

338

339 const MipsSubtarget *STI = nullptr;

340 const Mips16InstrInfo *TII;

341 MipsFunctionInfo *MFI;

342 MachineFunction *MF = nullptr;

343 MachineConstantPool *MCP = nullptr;

344

345 unsigned PICLabelUId;

346 bool PrescannedForConstants = false;

347

348 void initPICLabelUId(unsigned UId) {

349 PICLabelUId = UId;

350 }

351

352 unsigned createPICLabelUId() {

353 return PICLabelUId++;

354 }

355

356 public:

357 static char ID;

358

359 MipsConstantIslands() : MachineFunctionPass(ID) {}

360

361 StringRef getPassName() const override { return "Mips Constant Islands"; }

362

363 bool runOnMachineFunction(MachineFunction &F) override;

364

365 MachineFunctionProperties getRequiredProperties() const override {

366 return MachineFunctionProperties().setNoVRegs();

367 }

368

369 void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);

370 CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI);

371 Align getCPEAlign(const MachineInstr &CPEMI);

372 void initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs);

373 unsigned getOffsetOf(MachineInstr *MI) const;

374 unsigned getUserOffset(CPUser&) const;

375 void dumpBBs();

376

377 bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,

378 unsigned Disp, bool NegativeOK);

379 bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,

380 const CPUser &U);

381

382 void computeBlockSize(MachineBasicBlock *MBB);

383 MachineBasicBlock *splitBlockBeforeInstr(MachineInstr &MI);

384 void updateForInsertedWaterBlock(MachineBasicBlock *NewBB);

385 void adjustBBOffsetsAfter(MachineBasicBlock *BB);

386 bool decrementCPEReferenceCount(unsigned CPI, MachineInstr* CPEMI);

387 int findInRangeCPEntry(CPUser& U, unsigned UserOffset);

388 int findLongFormInRangeCPEntry(CPUser& U, unsigned UserOffset);

389 bool findAvailableWater(CPUser&U, unsigned UserOffset,

390 water_iterator &WaterIter);

391 void createNewWater(unsigned CPUserIndex, unsigned UserOffset,

392 MachineBasicBlock *&NewMBB);

393 bool handleConstantPoolUser(unsigned CPUserIndex);

394 void removeDeadCPEMI(MachineInstr *CPEMI);

395 bool removeUnusedCPEntries();

396 bool isCPEntryInRange(MachineInstr *MI, unsigned UserOffset,

397 MachineInstr *CPEMI, unsigned Disp, bool NegOk,

398 bool DoDump = false);

399 bool isWaterInRange(unsigned UserOffset, MachineBasicBlock *Water,

400 CPUser &U, unsigned &Growth);

401 bool isBBInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp);

402 bool fixupImmediateBr(ImmBranch &Br);

403 bool fixupConditionalBr(ImmBranch &Br);

404 bool fixupUnconditionalBr(ImmBranch &Br);

405

406 void prescanForConstants();

407 };

408

409}

410

411char MipsConstantIslands::ID = 0;

412

413bool MipsConstantIslands::isOffsetInRange

414 (unsigned UserOffset, unsigned TrialOffset,

415 const CPUser &U) {

416 return isOffsetInRange(UserOffset, TrialOffset,

417 U.getMaxDisp(), U.NegOk);

418}

419

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

421

423 for (unsigned J = 0, E = BBInfo.size(); J !=E; ++J) {

424 const BasicBlockInfo &BBI = BBInfo[J];

426 << format(" size=%#x\n", BBInfo[J].Size);

427 }

428}

429#endif

430

431bool MipsConstantIslands::runOnMachineFunction(MachineFunction &mf) {

432

433

434 MF = &mf;

437 LLVM_DEBUG(dbgs() << "constant island machine function "

438 << "\n");

440 return false;

441 }

443 MFI = MF->getInfo();

445 << "\n");

446

447

448

449

450 if (!PrescannedForConstants) prescanForConstants();

451

452 HasFarJump = false;

453

455

456

457

459

460 bool MadeChange = false;

461

462

463

464 std::vector<MachineInstr*> CPEMIs;

466 doInitialPlacement(CPEMIs);

467

468

469 initPICLabelUId(CPEMIs.size());

470

471

472

473

474 initializeFunctionInfo(CPEMIs);

475 CPEMIs.clear();

477

478

479 MadeChange |= removeUnusedCPEntries();

480

481

482

483 unsigned NoCPIters = 0, NoBRIters = 0;

484 (void)NoBRIters;

485 while (true) {

486 LLVM_DEBUG(dbgs() << "Beginning CP iteration #" << NoCPIters << '\n');

487 bool CPChange = false;

488 for (unsigned i = 0, e = CPUsers.size(); i != e; ++i)

489 CPChange |= handleConstantPoolUser(i);

490 if (CPChange && ++NoCPIters > 30)

493

494

495

496 NewWaterList.clear();

497

498 LLVM_DEBUG(dbgs() << "Beginning BR iteration #" << NoBRIters << '\n');

499 bool BRChange = false;

500 for (unsigned i = 0, e = ImmBranches.size(); i != e; ++i)

501 BRChange |= fixupImmediateBr(ImmBranches[i]);

502 if (BRChange && ++NoBRIters > 30)

505 if (!CPChange && !BRChange)

506 break;

507 MadeChange = true;

508 }

509

511

512 BBInfo.clear();

513 WaterList.clear();

514 CPUsers.clear();

515 CPEntries.clear();

516 ImmBranches.clear();

517 return MadeChange;

518}

519

520

521

522void

523MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {

524

527

528

530

531

532

534

535

536

538

539

540

541

542

544 BB->end());

545

546

547

548 const std::vector &CPs = MCP->getConstants();

549

551 for (unsigned i = 0, e = CPs.size(); i != e; ++i) {

552 unsigned Size = CPs[i].getSizeInBytes(TD);

553 assert(Size >= 4 && "Too small constant pool entry");

554 Align Alignment = CPs[i].getAlign();

555

556

557 assert(isAligned(Alignment, Size) && "CP Entry not multiple of 4 bytes!");

558

559

560 unsigned LogAlign = Log2(Alignment);

562

563 MachineInstr *CPEMI =

566

567 CPEMIs.push_back(CPEMI);

568

569

570

571 for (unsigned a = LogAlign + 1; a <= Log2(MaxAlign); ++a)

572 if (InsPoint[a] == InsAt)

573 InsPoint[a] = CPEMI;

574

575 CPEntries.emplace_back(1, CPEntry(CPEMI, i));

576 ++NumCPEs;

577 LLVM_DEBUG(dbgs() << "Moved CPI#" << i << " to end of function, size = "

578 << Size << ", align = " << Alignment.value() << '\n');

579 }

581}

582

583

584

586

588

589 if (std::next(MBBI) == MBB->getParent()->end())

590 return false;

591

594}

595

596

597

598MipsConstantIslands::CPEntry

599*MipsConstantIslands::findConstPoolEntry(unsigned CPI,

600 const MachineInstr *CPEMI) {

601 std::vector &CPEs = CPEntries[CPI];

602

603

604 for (CPEntry &CPE : CPEs) {

605 if (CPE.CPEMI == CPEMI)

606 return &CPE;

607 }

608 return nullptr;

609}

610

611

612

613Align MipsConstantIslands::getCPEAlign(const MachineInstr &CPEMI) {

615

616

619

621 assert(CPI < MCP->getConstants().size() && "Invalid constant pool index.");

623}

624

625

626

627

628void MipsConstantIslands::

629initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {

630 BBInfo.clear();

632

633

634

635

636

637 for (MachineBasicBlock &MBB : *MF)

638 computeBlockSize(&MBB);

639

640

641 adjustBBOffsetsAfter(&MF->front());

642

643

644 for (MachineBasicBlock &MBB : *MF) {

645

646

648 WaterList.push_back(&MBB);

649 for (MachineInstr &MI : MBB) {

650 if (MI.isDebugInstr())

651 continue;

652

653 int Opc = MI.getOpcode();

654 if (MI.isBranch()) {

655 bool isCond = false;

656 unsigned Bits = 0;

657 unsigned Scale = 1;

658 int UOpc = Opc;

659 switch (Opc) {

660 default:

661 continue;

662 case Mips::Bimm16:

664 Scale = 2;

665 isCond = false;

666 break;

667 case Mips::BimmX16:

669 Scale = 2;

670 isCond = false;

671 break;

672 case Mips::BeqzRxImm16:

673 UOpc=Mips::Bimm16;

675 Scale = 2;

676 isCond = true;

677 break;

678 case Mips::BeqzRxImmX16:

679 UOpc=Mips::Bimm16;

681 Scale = 2;

682 isCond = true;

683 break;

684 case Mips::BnezRxImm16:

685 UOpc=Mips::Bimm16;

687 Scale = 2;

688 isCond = true;

689 break;

690 case Mips::BnezRxImmX16:

691 UOpc=Mips::Bimm16;

693 Scale = 2;

694 isCond = true;

695 break;

696 case Mips::Bteqz16:

697 UOpc=Mips::Bimm16;

699 Scale = 2;

700 isCond = true;

701 break;

702 case Mips::BteqzX16:

703 UOpc=Mips::Bimm16;

705 Scale = 2;

706 isCond = true;

707 break;

708 case Mips::Btnez16:

709 UOpc=Mips::Bimm16;

711 Scale = 2;

712 isCond = true;

713 break;

714 case Mips::BtnezX16:

715 UOpc=Mips::Bimm16;

717 Scale = 2;

718 isCond = true;

719 break;

720 }

721

722 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;

723 ImmBranches.push_back(ImmBranch(&MI, MaxOffs, isCond, UOpc));

724 }

725

726 if (Opc == Mips::CONSTPOOL_ENTRY)

727 continue;

728

729

730 for (const MachineOperand &MO : MI.operands())

731 if (MO.isCPI()) {

732

733

734

735

736 unsigned Bits = 0;

737 unsigned Scale = 1;

738 bool NegOk = false;

739 unsigned LongFormBits = 0;

740 unsigned LongFormScale = 0;

741 unsigned LongFormOpcode = 0;

742 switch (Opc) {

743 default:

744 llvm_unreachable("Unknown addressing mode for CP reference!");

745 case Mips::LwRxPcTcp16:

747 Scale = 4;

748 LongFormOpcode = Mips::LwRxPcTcpX16;

749 LongFormBits = 14;

750 LongFormScale = 1;

751 break;

752 case Mips::LwRxPcTcpX16:

754 Scale = 1;

755 NegOk = true;

756 break;

757 }

758

759 unsigned CPI = MO.getIndex();

760 MachineInstr *CPEMI = CPEMIs[CPI];

761 unsigned MaxOffs = ((1 << Bits)-1) * Scale;

762 unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;

763 CPUsers.push_back(CPUser(&MI, CPEMI, MaxOffs, NegOk, LongFormMaxOffs,

764 LongFormOpcode));

765

766

767 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);

768 assert(CPE && "Cannot find a corresponding CPEntry!");

769 CPE->RefCount++;

770

771

772

773 break;

774 }

775 }

776 }

777}

778

779

780

781void MipsConstantIslands::computeBlockSize(MachineBasicBlock *MBB) {

782 BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];

783 BBI.Size = 0;

784

785 for (const MachineInstr &MI : *MBB)

787}

788

789

790

791

792unsigned MipsConstantIslands::getOffsetOf(MachineInstr *MI) const {

793 MachineBasicBlock *MBB = MI->getParent();

794

795

796

797

799

800

802 assert(I != MBB->end() && "Didn't find MI in its own basic block?");

804 }

806}

807

808

809

812 return LHS->getNumber() < RHS->getNumber();

813}

814

815

816

817

818void MipsConstantIslands::updateForInsertedWaterBlock

819 (MachineBasicBlock *NewBB) {

820

822

823

824

825 BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());

826

827

828

830 WaterList.insert(IP, NewBB);

831}

832

833unsigned MipsConstantIslands::getUserOffset(CPUser &U) const {

834 return getOffsetOf(U.MI);

835}

836

837

838

839

840MachineBasicBlock *

841MipsConstantIslands::splitBlockBeforeInstr(MachineInstr &MI) {

842 MachineBasicBlock *OrigBB = MI.getParent();

843

844

845 MachineBasicBlock *NewBB =

846 MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());

848 MF->insert(MBBI, NewBB);

849

850

851 NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end());

852

853

854

855

856

858 ++NumSplit;

859

860

862

863

865

866

867

868

869 MF->RenumberBlocks(NewBB);

870

871

872

873 BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo());

874

875

876

877

878

880 MachineBasicBlock* WaterBB = *IP;

881 if (WaterBB == OrigBB)

882 WaterList.insert(std::next(IP), NewBB);

883 else

884 WaterList.insert(IP, OrigBB);

885 NewWaterList.insert(OrigBB);

886

887

888

889

890

891

892 computeBlockSize(OrigBB);

893

894

895

896 computeBlockSize(NewBB);

897

898

899 adjustBBOffsetsAfter(OrigBB);

900

901 return NewBB;

902}

903

904

905

906

907bool MipsConstantIslands::isOffsetInRange(unsigned UserOffset,

908 unsigned TrialOffset, unsigned MaxDisp,

909 bool NegativeOK) {

910 if (UserOffset <= TrialOffset) {

911

912 if (TrialOffset - UserOffset <= MaxDisp)

913 return true;

914 } else if (NegativeOK) {

915 if (UserOffset - TrialOffset <= MaxDisp)

916 return true;

917 }

918 return false;

919}

920

921

922

923

924

925bool MipsConstantIslands::isWaterInRange(unsigned UserOffset,

926 MachineBasicBlock* Water, CPUser &U,

927 unsigned &Growth) {

928 unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset();

929 unsigned NextBlockOffset;

930 Align NextBlockAlignment;

932 if (NextBlock == MF->end()) {

933 NextBlockOffset = BBInfo[Water->getNumber()].postOffset();

934 NextBlockAlignment = Align(1);

935 } else {

936 NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;

937 NextBlockAlignment = NextBlock->getAlignment();

938 }

939 unsigned Size = U.CPEMI->getOperand(2).getImm();

940 unsigned CPEEnd = CPEOffset + Size;

941

942

943

944

945 if (CPEEnd > NextBlockOffset) {

946 Growth = CPEEnd - NextBlockOffset;

947

948

950

951

952

953

954 if (CPEOffset < UserOffset)

955 UserOffset += Growth;

956 } else

957

958 Growth = 0;

959

960 return isOffsetInRange(UserOffset, CPEOffset, U);

961}

962

963

964

965bool MipsConstantIslands::isCPEntryInRange

966 (MachineInstr *MI, unsigned UserOffset,

967 MachineInstr *CPEMI, unsigned MaxDisp,

968 bool NegOk, bool DoDump) {

969 unsigned CPEOffset = getOffsetOf(CPEMI);

970

971 if (DoDump) {

973 unsigned Block = MI->getParent()->getNumber();

974 const BasicBlockInfo &BBI = BBInfo[Block];

976 << " max delta=" << MaxDisp

977 << format(" insn address=%#x", UserOffset) << " in "

980 << format("CPE address=%#x offset=%+d: ", CPEOffset,

981 int(CPEOffset - UserOffset));

982 });

983 }

984

985 return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);

986}

987

988#ifndef NDEBUG

989

990

992 if (MBB->pred_size() != 1 || MBB->succ_size() != 1)

993 return false;

997 if (PredMI->getOpcode() == Mips::Bimm16)

999 return false;

1000}

1001#endif

1002

1003void MipsConstantIslands::adjustBBOffsetsAfter(MachineBasicBlock *BB) {

1004 unsigned BBNum = BB->getNumber();

1005 for(unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++i) {

1006

1007

1008 unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;

1009 BBInfo[i].Offset = Offset;

1010 }

1011}

1012

1013

1014

1015

1016

1017bool MipsConstantIslands::decrementCPEReferenceCount(unsigned CPI,

1018 MachineInstr *CPEMI) {

1019

1020 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);

1021 assert(CPE && "Unexpected!");

1022 if (--CPE->RefCount == 0) {

1023 removeDeadCPEMI(CPEMI);

1024 CPE->CPEMI = nullptr;

1025 --NumCPEs;

1026 return true;

1027 }

1028 return false;

1029}

1030

1031

1032

1033

1034

1035

1036

1037int MipsConstantIslands::findInRangeCPEntry(CPUser& U, unsigned UserOffset)

1038{

1039 MachineInstr *UserMI = U.MI;

1040 MachineInstr *CPEMI = U.CPEMI;

1041

1042

1043 if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk,

1044 true)) {

1046 return 1;

1047 }

1048

1049

1051 std::vector &CPEs = CPEntries[CPI];

1052 for (CPEntry &CPE : CPEs) {

1053

1054 if (CPE.CPEMI == CPEMI)

1055 continue;

1056

1057 if (CPE.CPEMI == nullptr)

1058 continue;

1059 if (isCPEntryInRange(UserMI, UserOffset, CPE.CPEMI, U.getMaxDisp(),

1060 U.NegOk)) {

1061 LLVM_DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#" << CPE.CPI

1062 << "\n");

1063

1064 U.CPEMI = CPE.CPEMI;

1065

1066 for (MachineOperand &MO : UserMI->operands())

1067 if (MO.isCPI()) {

1068 MO.setIndex(CPE.CPI);

1069 break;

1070 }

1071

1072 CPE.RefCount++;

1073

1074

1075 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;

1076 }

1077 }

1078 return 0;

1079}

1080

1081

1082

1083

1084

1085

1086

1087

1088

1089int MipsConstantIslands::findLongFormInRangeCPEntry

1090 (CPUser& U, unsigned UserOffset)

1091{

1092 MachineInstr *UserMI = U.MI;

1093 MachineInstr *CPEMI = U.CPEMI;

1094

1095

1096 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,

1097 U.getLongFormMaxDisp(), U.NegOk,

1098 true)) {

1101 U.setMaxDisp(U.getLongFormMaxDisp());

1102 return 2;

1103 }

1104

1105

1107 std::vector &CPEs = CPEntries[CPI];

1108 for (CPEntry &CPE : CPEs) {

1109

1110 if (CPE.CPEMI == CPEMI)

1111 continue;

1112

1113 if (CPE.CPEMI == nullptr)

1114 continue;

1115 if (isCPEntryInRange(UserMI, UserOffset, CPE.CPEMI, U.getLongFormMaxDisp(),

1116 U.NegOk)) {

1117 LLVM_DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#" << CPE.CPI

1118 << "\n");

1119

1120 U.CPEMI = CPE.CPEMI;

1121

1122 for (MachineOperand &MO : UserMI->operands())

1123 if (MO.isCPI()) {

1124 MO.setIndex(CPE.CPI);

1125 break;

1126 }

1127

1128 CPE.RefCount++;

1129

1130

1131 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;

1132 }

1133 }

1134 return 0;

1135}

1136

1137

1138

1140 switch (Opc) {

1141 case Mips::Bimm16:

1142 return ((1<<10)-1)*2;

1143 case Mips::BimmX16:

1144 return ((1<<16)-1)*2;

1145 default:

1146 break;

1147 }

1148 return ((1<<16)-1)*2;

1149}

1150

1151

1152

1153

1154

1155

1156

1157

1158

1159bool MipsConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset,

1160 water_iterator &WaterIter) {

1161 if (WaterList.empty())

1162 return false;

1163

1164 unsigned BestGrowth = ~0u;

1165 for (water_iterator IP = std::prev(WaterList.end()), B = WaterList.begin();;

1166 --IP) {

1167 MachineBasicBlock* WaterBB = *IP;

1168

1169

1170

1171

1172

1173

1174

1175

1176 unsigned Growth;

1177 if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&

1178 (WaterBB->getNumber() < U.HighWaterMark->getNumber() ||

1179 NewWaterList.count(WaterBB)) && Growth < BestGrowth) {

1180

1181 BestGrowth = Growth;

1182 WaterIter = IP;

1184 << " Growth=" << Growth << '\n');

1185

1186

1187 if (BestGrowth == 0)

1188 return true;

1189 }

1190 if (IP == B)

1191 break;

1192 }

1193 return BestGrowth != ~0u;

1194}

1195

1196

1197

1198

1199

1200

1201

1202

1203void MipsConstantIslands::createNewWater(unsigned CPUserIndex,

1204 unsigned UserOffset,

1205 MachineBasicBlock *&NewMBB) {

1206 CPUser &U = CPUsers[CPUserIndex];

1207 MachineInstr *UserMI = U.MI;

1208 MachineInstr *CPEMI = U.CPEMI;

1209 MachineBasicBlock *UserMBB = UserMI->getParent();

1210 const BasicBlockInfo &UserBBI = BBInfo[UserMBB->getNumber()];

1211

1212

1213

1215

1216 unsigned Delta = 2;

1217

1218 unsigned CPEOffset = UserBBI.postOffset() + Delta;

1219

1220 if (isOffsetInRange(UserOffset, CPEOffset, U)) {

1222 << format(", expected CPE offset %#x\n", CPEOffset));

1224

1225

1226

1227

1228

1229 int UncondBr = Mips::Bimm16;

1232 ImmBranches.push_back(ImmBranch(&UserMBB->back(),

1233 MaxDisp, false, UncondBr));

1234 BBInfo[UserMBB->getNumber()].Size += Delta;

1235 adjustBBOffsetsAfter(UserMBB);

1236 return;

1237 }

1238 }

1239

1240

1241

1242

1243

1244

1245 const Align Align = MF->getAlignment();

1246 unsigned BaseInsertOffset = UserOffset + U.getMaxDisp();

1248 BaseInsertOffset));

1249

1250

1251

1252

1253 BaseInsertOffset -= 4;

1254

1256 << " la=" << Log2(Align) << '\n');

1257

1258

1259

1260

1261

1262 if (BaseInsertOffset + 8 >= UserBBI.postOffset()) {

1263 BaseInsertOffset = UserBBI.postOffset() - 8;

1265 }

1266 unsigned EndInsertOffset = BaseInsertOffset + 4 +

1269 ++MI;

1270 unsigned CPUIndex = CPUserIndex+1;

1271 unsigned NumCPUsers = CPUsers.size();

1272

1274 Offset < BaseInsertOffset;

1276 assert(MI != UserMBB->end() && "Fell off end of block");

1277 if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {

1278 CPUser &U = CPUsers[CPUIndex];

1279 if (!isOffsetInRange(Offset, EndInsertOffset, U)) {

1280

1281 BaseInsertOffset -= Align.value();

1282 EndInsertOffset -= Align.value();

1283 }

1284

1285

1286

1287

1288 EndInsertOffset += U.CPEMI->getOperand(2).getImm();

1289 CPUIndex++;

1290 }

1291 }

1292

1293 NewMBB = splitBlockBeforeInstr(*--MI);

1294}

1295

1296

1297

1298

1299

1300bool MipsConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) {

1301 CPUser &U = CPUsers[CPUserIndex];

1302 MachineInstr *UserMI = U.MI;

1303 MachineInstr *CPEMI = U.CPEMI;

1306

1307 unsigned UserOffset = getUserOffset(U);

1308

1309

1310

1311 int result = findInRangeCPEntry(U, UserOffset);

1312 if (result==1) return false;

1313 else if (result==2) return true;

1314

1315

1316 MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock();

1317 MachineBasicBlock *NewMBB;

1318 water_iterator IP;

1319 if (findAvailableWater(U, UserOffset, IP)) {

1321 MachineBasicBlock *WaterBB = *IP;

1322

1323

1324

1325

1326 if (NewWaterList.erase(WaterBB))

1327 NewWaterList.insert(NewIsland);

1328

1329

1331 } else {

1332

1333

1334

1336 result = findLongFormInRangeCPEntry(U, UserOffset);

1337 if (result != 0) return true;

1338 }

1340 createNewWater(CPUserIndex, UserOffset, NewMBB);

1341

1342

1343

1344

1345

1346

1347 MachineBasicBlock *WaterBB = &*--NewMBB->getIterator();

1348 IP = llvm::find(WaterList, WaterBB);

1349 if (IP != WaterList.end())

1350 NewWaterList.erase(WaterBB);

1351

1352

1353 NewWaterList.insert(NewIsland);

1354 }

1355

1356

1357

1358

1359

1360 if (IP != WaterList.end())

1361 WaterList.erase(IP);

1362

1363

1364 MF->insert(NewMBB->getIterator(), NewIsland);

1365

1366

1367 updateForInsertedWaterBlock(NewIsland);

1368

1369

1370 decrementCPEReferenceCount(CPI, CPEMI);

1371

1372

1373

1374 unsigned ID = createPICLabelUId();

1375

1376

1377

1378 U.HighWaterMark = NewIsland;

1381 CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));

1382 ++NumCPEs;

1383

1384

1386

1387

1389 adjustBBOffsetsAfter(&*--NewIsland->getIterator());

1390

1391

1392 for (MachineOperand &MO : UserMI->operands())

1393 if (MO.isCPI()) {

1394 MO.setIndex(ID);

1395 break;

1396 }

1397

1399 dbgs() << " Moved CPE to #" << ID << " CPI=" << CPI

1400 << format(" offset=%#x\n", BBInfo[NewIsland->getNumber()].Offset));

1401

1402 return true;

1403}

1404

1405

1406

1407void MipsConstantIslands::removeDeadCPEMI(MachineInstr *CPEMI) {

1408 MachineBasicBlock *CPEBB = CPEMI->getParent();

1412

1413 if (CPEBB->empty()) {

1414 BBInfo[CPEBB->getNumber()].Size = 0;

1415

1416

1418 } else {

1419

1421 }

1422

1423 adjustBBOffsetsAfter(CPEBB);

1424

1425

1426

1428

1429}

1430

1431

1432

1433bool MipsConstantIslands::removeUnusedCPEntries() {

1434 unsigned MadeChange = false;

1435 for (std::vector &CPEs : CPEntries) {

1436 for (CPEntry &CPE : CPEs) {

1437 if (CPE.RefCount == 0 && CPE.CPEMI) {

1438 removeDeadCPEMI(CPE.CPEMI);

1439 CPE.CPEMI = nullptr;

1440 MadeChange = true;

1441 }

1442 }

1443 }

1444 return MadeChange;

1445}

1446

1447

1448

1449bool MipsConstantIslands::isBBInRange

1450 (MachineInstr *MI,MachineBasicBlock *DestBB, unsigned MaxDisp) {

1451 unsigned PCAdj = 4;

1452 unsigned BrOffset = getOffsetOf(MI) + PCAdj;

1453 unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;

1454

1457 << " max delta=" << MaxDisp << " from " << getOffsetOf(MI)

1458 << " to " << DestOffset << " offset "

1459 << int(DestOffset - BrOffset) << "\t" << *MI);

1460

1461 if (BrOffset <= DestOffset) {

1462

1463 if (DestOffset-BrOffset <= MaxDisp)

1464 return true;

1465 } else {

1466 if (BrOffset-DestOffset <= MaxDisp)

1467 return true;

1468 }

1469 return false;

1470}

1471

1472

1473

1474bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {

1475 MachineInstr *MI = Br.MI;

1477 MachineBasicBlock *DestBB = MI->getOperand(TargetOperand).getMBB();

1478

1479

1480 if (isBBInRange(MI, DestBB, Br.MaxDisp))

1481 return false;

1482

1483 if (!Br.isCond)

1484 return fixupUnconditionalBr(Br);

1485 return fixupConditionalBr(Br);

1486}

1487

1488

1489

1490

1491

1492bool

1493MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {

1494 MachineInstr *MI = Br.MI;

1495 MachineBasicBlock *MBB = MI->getParent();

1496 MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();

1497

1498 unsigned BimmX16MaxDisp = ((1 << 16)-1) * 2;

1499 if (isBBInRange(MI, DestBB, BimmX16MaxDisp)) {

1500 Br.MaxDisp = BimmX16MaxDisp;

1501 MI->setDesc(TII->get(Mips::BimmX16));

1502 }

1503 else {

1504

1505

1506

1507

1508

1509

1510

1511

1512

1513

1514

1516 Br.MaxDisp = ((1<<24)-1) * 2;

1517 MI->setDesc(TII->get(Mips::JalB16));

1518 }

1520 adjustBBOffsetsAfter(MBB);

1521 HasFarJump = true;

1522 ++NumUBrFixed;

1523

1525

1526 return true;

1527}

1528

1529

1530

1531

1532bool

1533MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {

1534 MachineInstr *MI = Br.MI;

1536 MachineBasicBlock *DestBB = MI->getOperand(TargetOperand).getMBB();

1537 unsigned Opcode = MI->getOpcode();

1540

1541

1542 if (isBBInRange(MI, DestBB, LongFormMaxOff)) {

1543 Br.MaxDisp = LongFormMaxOff;

1544 MI->setDesc(TII->get(LongFormOpcode));

1545 return true;

1546 }

1547

1548

1549

1550

1551

1552

1553

1554

1555

1556

1557

1558

1559 MachineBasicBlock *MBB = MI->getParent();

1560 MachineInstr *BMI = &MBB->back();

1562 unsigned OppositeBranchOpcode = TII->getOppositeBranchOpc(Opcode);

1563

1564 ++NumCBrFixed;

1565 if (BMI != MI) {

1568

1569

1570

1571

1572

1573

1574

1576 MachineBasicBlock *NewDest =

1578 if (isBBInRange(MI, NewDest, Br.MaxDisp)) {

1580 dbgs() << " Invert Bcc condition and swap its destination with "

1581 << *BMI);

1582 MI->setDesc(TII->get(OppositeBranchOpcode));

1584 MI->getOperand(TargetOperand).setMBB(NewDest);

1585 return true;

1586 }

1587 }

1588 }

1589

1590 if (NeedSplit) {

1591 splitBlockBeforeInstr(*MI);

1592

1593

1597

1598 }

1600

1602 << " also invert condition and change dest. to "

1604

1605

1606

1607 if (MI->getNumExplicitOperands() == 2) {

1609 .addReg(MI->getOperand(0).getReg())

1611 } else {

1614 }

1620 ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr));

1621

1622

1624 MI->eraseFromParent();

1625 adjustBBOffsetsAfter(MBB);

1626 return true;

1627}

1628

1629void MipsConstantIslands::prescanForConstants() {

1630 for (MachineBasicBlock &B : *MF) {

1631 for (MachineInstr &MI : B) {

1632 switch (MI.getDesc().getOpcode()) {

1633 case Mips::LwConstant32: {

1634 PrescannedForConstants = true;

1635 LLVM_DEBUG(dbgs() << "constant island constant " << MI << "\n");

1636 LLVM_DEBUG(dbgs() << "num operands " << MI.getNumOperands() << "\n");

1637 MachineOperand &Literal = MI.getOperand(1);

1639 int64_t V = Literal.getImm();

1641 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());

1644 MI.getOperand(2).ChangeToImmediate(index);

1645 LLVM_DEBUG(dbgs() << "constant island constant " << MI << "\n");

1646 MI.setDesc(TII->get(Mips::LwRxPcTcp16));

1647 MI.removeOperand(1);

1648 MI.removeOperand(1);

1650 }

1651 break;

1652 }

1653 default:

1654 break;

1655 }

1656 }

1657 }

1658}

1659

1660

1662 return new MipsConstantIslands();

1663}

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

const TargetInstrInfo & TII

static bool CompareMBBNumbers(const MachineBasicBlock *LHS, const MachineBasicBlock *RHS)

CompareMBBNumbers - Little predicate function to sort the WaterList by MBB ID.

static unsigned getUnconditionalBrDisp(int Opc)

getUnconditionalBrDisp - Returns the maximum displacement that can fit in the specific unconditional ...

static bool BBIsJumpedOver(MachineBasicBlock *MBB)

BBIsJumpedOver - Return true of the specified basic block's only predecessor unconditionally branches...

MachineBasicBlock MachineBasicBlock::iterator MBBI

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

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

#define LLVM_PREFERRED_TYPE(T)

\macro LLVM_PREFERRED_TYPE Adjust type of bit-field in debug info.

#define LLVM_DUMP_METHOD

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

This file contains the declarations for the subclasses of Constant, which represent the different fla...

This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...

static unsigned int longformBranchOpcode(unsigned int Opcode)

Definition MipsConstantIslandPass.cpp:104

static unsigned int branchMaxOffsets(unsigned int Opcode)

Definition MipsConstantIslandPass.cpp:131

static cl::opt< bool > NoLoadRelaxation("mips-constant-islands-no-load-relaxation", cl::init(false), cl::desc("Don't relax loads to long loads - for testing purposes"), cl::Hidden)

static cl::opt< int > ConstantIslandsSmallOffset("mips-constant-islands-small-offset", cl::init(0), cl::desc("Make small offsets be this amount for testing purposes"), cl::Hidden)

static bool BBHasFallthrough(MachineBasicBlock *MBB)

BBHasFallthrough - Return true if the specified basic block can fallthrough into the block immediatel...

Definition MipsConstantIslandPass.cpp:585

static cl::opt< bool > AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true), cl::desc("Align constant islands in code"))

static unsigned int branchTargetOperand(MachineInstr *MI)

Definition MipsConstantIslandPass.cpp:85

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)

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

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

LLVM_ABI void transferSuccessors(MachineBasicBlock *FromMBB)

Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...

int getNumber() const

MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...

const BasicBlock * getBasicBlock() const

Return the LLVM basic block that this instance corresponded to originally.

void setAlignment(Align A)

Set alignment of the basic block.

LLVM_ABI void dump() const

LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())

Add Succ as a successor of this MachineBasicBlock.

MachineInstrBundleIterator< MachineInstr, true > reverse_iterator

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

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

Align getAlignment() const

Return alignment of the basic block.

MachineInstrBundleIterator< MachineInstr > iterator

Align getConstantPoolAlign() const

Return the alignment required by the whole constant pool, of which the first element must be aligned.

const std::vector< MachineConstantPoolEntry > & getConstants() const

bool isEmpty() const

isEmpty - Return true if this constant pool contains no constants.

unsigned getConstantPoolIndex(const Constant *C, Align Alignment)

getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

void ensureAlignment(Align A)

ensureAlignment - Make sure the function is at least A bytes aligned.

void push_back(MachineBasicBlock *MBB)

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

const DataLayout & getDataLayout() const

Return the DataLayout attached to the Module associated to this MF.

unsigned getNumBlockIDs() const

getNumBlockIDs - Return the number of MBB ID's allocated.

BasicBlockListType::iterator iterator

Ty * getInfo()

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

MachineConstantPool * getConstantPool()

getConstantPool - Return the constant pool object for the current function.

void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)

RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.

MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)

CreateMachineInstr - Allocate a new MachineInstr.

BasicBlockListType::const_iterator const_iterator

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const

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

Add a new virtual register operand.

const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineBasicBlock * getParent() const

LLVM_ABI void setDesc(const MCInstrDesc &TID)

Replace the instruction descriptor (thus opcode) of the current instruction with a new one.

bool isUnconditionalBranch(QueryType Type=AnyInBundle) const

Return true if this is a branch which always transfers control flow to some other block.

LLVM_ABI void eraseFromParent()

Unlink 'this' from the containing basic block and delete it.

const MachineOperand & getOperand(unsigned i) const

MachineBasicBlock * getMBB() const

void setMBB(MachineBasicBlock *MBB)

static MachineOperand CreateCPI(unsigned Idx, int Offset, unsigned TargetFlags=0)

void invalidateLiveness()

invalidateLiveness - Indicates that register liveness is no longer being tracked accurately.

static bool useConstantIslands()

const MipsInstrInfo * getInstrInfo() const override

bool inMips16Mode() const

bool erase(PtrType Ptr)

Remove pointer from the set.

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.

virtual unsigned getInstSizeInBytes(const MachineInstr &MI) const

Returns the size in bytes of the specified MachineInstr, or ~0U when this function is not implemented...

self_iterator getIterator()

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

unsigned ID

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

@ C

The default llvm calling convention, compatible with C.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

auto find(R &&Range, const T &Val)

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

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

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

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

FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty

bool isAligned(Align Lhs, uint64_t SizeInBytes)

Checks that SizeInBytes is a multiple of the alignment.

FunctionPass * createMipsConstantIslandPass()

Returns a pass that converts branches to long branches.

Definition MipsConstantIslandPass.cpp:1661

LLVM_ABI raw_ostream & dbgs()

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

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

class LLVM_GSL_OWNER SmallVector

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

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

uint64_t offsetToAlignment(uint64_t Value, Align Alignment)

Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...

auto lower_bound(R &&Range, T &&Value)

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

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

APFloat neg(APFloat X)

Returns the negated value of the argument.

unsigned Log2(Align A)

Returns the log2 of the alignment.

LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)

Prints a machine basic block reference.

constexpr uint64_t value() const

This is a hole in the type system and should not be abused.

unsigned Size

Size - Size of the basic block in bytes.

unsigned postOffset(Align Alignment=Align(1)) const

Compute the offset immediately following this block.

unsigned Offset

Offset - Distance from the beginning of the function to the beginning of this basic block.