LLVM: lib/Transforms/Scalar/LoopInterchange.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

46#include

47#include

48#include

49

50using namespace llvm;

51

52#define DEBUG_TYPE "loop-interchange"

53

54STATISTIC(LoopsInterchanged, "Number of loops interchanged");

55

58 cl::desc("Interchange if you gain more than this number"));

59

60

64 "Maximum number of load-store instructions that should be handled "

65 "in the dependency matrix. Higher value may lead to more interchanges "

66 "at the cost of compile-time"));

67

68namespace {

69

71

72

73using CharMatrix = std::vector<std::vector>;

74

75}

76

77

80 cl::desc("Minimum depth of loop nest considered for the transform"));

81

82

85 cl::desc("Maximum depth of loop nest considered for the transform"));

86

87#ifndef NDEBUG

89 for (auto &Row : DepMatrix) {

90 for (auto D : Row)

93 }

94}

95#endif

96

102

103 ValueVector MemInstr;

104

105

107

109 if (!isa(I))

110 return false;

111 if (auto *Ld = dyn_cast(&I)) {

112 if (!Ld->isSimple())

113 return false;

115 } else if (auto *St = dyn_cast(&I)) {

116 if (!St->isSimple())

117 return false;

118 MemInstr.push_back(&I);

119 }

120 }

121 }

122

124 << " Loads and Stores to analyze\n");

126 LLVM_DEBUG(dbgs() << "The transform doesn't support more than "

128 ORE->emit([&]() {

130 L->getStartLoc(), L->getHeader())

131 << "Number of loads/stores exceeded, the supported maximum "

132 "can be increased with option "

133 "-loop-interchange-maxmeminstr-count.";

134 });

135 return false;

136 }

137 ValueVector::iterator I, IE, J, JE;

139

140 for (I = MemInstr.begin(), IE = MemInstr.end(); I != IE; ++I) {

141 for (J = I, JE = MemInstr.end(); J != JE; ++J) {

142 std::vector Dep;

144 Instruction *Dst = cast(*J);

145

146 if (isa(Src) && isa(Dst))

147 continue;

148

149 if (auto D = DI->depends(Src, Dst, true)) {

150 assert(D->isOrdered() && "Expected an output, flow or anti dep.");

151

152

153 if (D->normalize(SE))

154 LLVM_DEBUG(dbgs() << "Negative dependence vector normalized.\n");

156 D->isFlow() ? "flow" : D->isAnti() ? "anti" : "output";

157 dbgs() << "Found " << DepType

158 << " dependency between Src and Dst\n"

159 << " Src:" << *Src << "\n Dst:" << *Dst << '\n');

160 unsigned Levels = D->getLevels();

162 for (unsigned II = 1; II <= Levels; ++II) {

163 unsigned Dir = D->getDirection(II);

171 else

174 }

175 while (Dep.size() != Level) {

176 Dep.push_back('I');

177 }

178

179

180 if (Seen.insert(StringRef(Dep.data(), Dep.size())).second)

181 DepMatrix.push_back(Dep);

182 }

183 }

184 }

185

186 return true;

187}

188

189

190

192 unsigned ToIndx) {

193 for (unsigned I = 0, E = DepMatrix.size(); I < E; ++I)

194 std::swap(DepMatrix[I][ToIndx], DepMatrix[I][FromIndx]);

195}

196

197

198

199

200

202 for (unsigned char Direction : DV) {

204 return true;

206 return false;

207 }

208 return true;

209}

210

211

213 unsigned InnerLoopId,

214 unsigned OuterLoopId) {

215 unsigned NumRows = DepMatrix.size();

216 std::vector Cur;

217

218 for (unsigned Row = 0; Row < NumRows; ++Row) {

219

220

221 Cur = DepMatrix[Row];

223 return false;

224 std::swap(Cur[InnerLoopId], Cur[OuterLoopId]);

226 return false;

227 }

228 return true;

229}

230

232 LLVM_DEBUG(dbgs() << "Calling populateWorklist on Func: "

233 << L.getHeader()->getParent()->getName() << " Loop: %"

234 << L.getHeader()->getName() << '\n');

235 assert(LoopList.empty() && "LoopList should initially be empty!");

236 Loop *CurrentLoop = &L;

237 const std::vector<Loop *> *Vec = &CurrentLoop->getSubLoops();

238 while (!Vec->empty()) {

239

240

241

242 if (Vec->size() != 1) {

243 LoopList = {};

244 return;

245 }

246

247 LoopList.push_back(CurrentLoop);

248 CurrentLoop = Vec->front();

250 }

251 LoopList.push_back(CurrentLoop);

252}

253

256 unsigned LoopNestDepth = LoopList.size();

257 if (LoopNestDepth < MinLoopNestDepth || LoopNestDepth > MaxLoopNestDepth) {

258 LLVM_DEBUG(dbgs() << "Unsupported depth of loop nest " << LoopNestDepth

261 Loop **OuterLoop = LoopList.begin();

262 ORE.emit([&]() {

264 (*OuterLoop)->getStartLoc(),

265 (*OuterLoop)->getHeader())

266 << "Unsupported depth of loop nest, the supported range is ["

269 });

270 return false;

271 }

272 return true;

273}

274namespace {

275

276

277class LoopInterchangeLegality {

278public:

281 : OuterLoop(Outer), InnerLoop(Inner), SE(SE), ORE(ORE) {}

282

283

284 bool canInterchangeLoops(unsigned InnerLoopId, unsigned OuterLoopId,

285 CharMatrix &DepMatrix);

286

287

288

290

291

292

293 bool isLoopStructureUnderstood();

294

295 bool currentLimitations();

296

298 return OuterInnerReductions;

299 }

300

302 return InnerLoopInductions;

303 }

304

305private:

306 bool tightlyNested(Loop *Outer, Loop *Inner);

307 bool containsUnsafeInstructions(BasicBlock *BB);

308

309

310

311

312

313 bool findInductionAndReductions(Loop *L,

315 Loop *InnerLoop);

316

317 Loop *OuterLoop;

318 Loop *InnerLoop;

319

321

322

324

325

326

328

329

331};

332

333

334

335class LoopInterchangeProfitability {

336public:

339 : OuterLoop(Outer), InnerLoop(Inner), SE(SE), ORE(ORE) {}

340

341

343 unsigned InnerLoopId, unsigned OuterLoopId,

344 CharMatrix &DepMatrix,

346 std::unique_ptr &CC);

347

348private:

349 int getInstrOrderCost();

350 std::optional isProfitablePerLoopCacheAnalysis(

352 std::unique_ptr &CC);

353 std::optional isProfitablePerInstrOrderCost();

354 std::optional isProfitableForVectorization(unsigned InnerLoopId,

355 unsigned OuterLoopId,

356 CharMatrix &DepMatrix);

357 Loop *OuterLoop;

358 Loop *InnerLoop;

359

360

362

363

365};

366

367

368class LoopInterchangeTransform {

369public:

372 const LoopInterchangeLegality &LIL)

373 : OuterLoop(Outer), InnerLoop(Inner), SE(SE), LI(LI), DT(DT), LIL(LIL) {}

374

375

377 void restructureLoops(Loop *NewInner, Loop *NewOuter,

380 void removeChildLoop(Loop *OuterLoop, Loop *InnerLoop);

381

382private:

383 bool adjustLoopLinks();

384 bool adjustLoopBranches();

385

386 Loop *OuterLoop;

387 Loop *InnerLoop;

388

389

391

394

395 const LoopInterchangeLegality &LIL;

396};

397

398struct LoopInterchange {

403 std::unique_ptr CC = nullptr;

404

405

407

409 DominatorTree *DT, std::unique_ptr &CC,

411 : SE(SE), LI(LI), DI(DI), DT(DT), CC(std::move(CC)), ORE(ORE) {}

412

414 if (L->getParentLoop())

415 return false;

418 return processLoopList(LoopList);

419 }

420

423 for (unsigned I = 1; I < LoopList.size(); ++I)

424 if (LoopList[I]->getParentLoop() != LoopList[I - 1])

425 return false;

426 return processLoopList(LoopList);

427 }

428

430 for (Loop *L : LoopList) {

432 if (isa(ExitCountOuter)) {

433 LLVM_DEBUG(dbgs() << "Couldn't compute backedge count\n");

434 return false;

435 }

436 if (L->getNumBackEdges() != 1) {

437 LLVM_DEBUG(dbgs() << "NumBackEdges is not equal to 1\n");

438 return false;

439 }

440 if (L->getExitingBlock()) {

441 LLVM_DEBUG(dbgs() << "Loop doesn't have unique exit block\n");

442 return false;

443 }

444 }

445 return true;

446 }

447

448 unsigned selectLoopForInterchange(ArrayRef<Loop *> LoopList) {

449

450

451 return LoopList.size() - 1;

452 }

453

455 bool Changed = false;

456

457

459 "Unsupported depth of loop nest.");

460

461 unsigned LoopNestDepth = LoopList.size();

462 if (!isComputableLoopNest(LoopList)) {

463 LLVM_DEBUG(dbgs() << "Not valid loop candidate for interchange\n");

464 return false;

465 }

466

467 LLVM_DEBUG(dbgs() << "Processing LoopList of size = " << LoopNestDepth

468 << "\n");

469

470 CharMatrix DependencyMatrix;

471 Loop *OuterMostLoop = *(LoopList.begin());

473 OuterMostLoop, DI, SE, ORE)) {

474 LLVM_DEBUG(dbgs() << "Populating dependency matrix failed\n");

475 return false;

476 }

477

478 LLVM_DEBUG(dbgs() << "Dependency matrix before interchange:\n";

480

481

483 if (!LoopNestExit) {

484 LLVM_DEBUG(dbgs() << "OuterMostLoop needs an unique exit block");

485 return false;

486 }

487

488 unsigned SelecLoopId = selectLoopForInterchange(LoopList);

489

490

491

492

493

494

495

496

498 if (CC != nullptr) {

499 const auto &LoopCosts = CC->getLoopCosts();

500 for (unsigned i = 0; i < LoopCosts.size(); i++) {

501 CostMap[LoopCosts[i].first] = i;

502 }

503 }

504

505

506

507

508 for (unsigned j = SelecLoopId; j > 0; j--) {

509 bool ChangedPerIter = false;

510 for (unsigned i = SelecLoopId; i > SelecLoopId - j; i--) {

511 bool Interchanged = processLoop(LoopList[i], LoopList[i - 1], i, i - 1,

512 DependencyMatrix, CostMap);

513 if (!Interchanged)

514 continue;

515

516 std::swap(LoopList[i - 1], LoopList[i]);

517

519

520 LLVM_DEBUG(dbgs() << "Dependency matrix after interchange:\n";

522

523 ChangedPerIter |= Interchanged;

524 Changed |= Interchanged;

525 }

526

527

528 if (!ChangedPerIter)

529 break;

530 }

531 return Changed;

532 }

533

534 bool processLoop(Loop *InnerLoop, Loop *OuterLoop, unsigned InnerLoopId,

535 unsigned OuterLoopId,

536 std::vector<std::vector> &DependencyMatrix,

538 LLVM_DEBUG(dbgs() << "Processing InnerLoopId = " << InnerLoopId

539 << " and OuterLoopId = " << OuterLoopId << "\n");

540 LoopInterchangeLegality LIL(OuterLoop, InnerLoop, SE, ORE);

541 if (!LIL.canInterchangeLoops(InnerLoopId, OuterLoopId, DependencyMatrix)) {

542 LLVM_DEBUG(dbgs() << "Not interchanging loops. Cannot prove legality.\n");

543 return false;

544 }

545 LLVM_DEBUG(dbgs() << "Loops are legal to interchange\n");

546 LoopInterchangeProfitability LIP(OuterLoop, InnerLoop, SE, ORE);

547 if (!LIP.isProfitable(InnerLoop, OuterLoop, InnerLoopId, OuterLoopId,

548 DependencyMatrix, CostMap, CC)) {

549 LLVM_DEBUG(dbgs() << "Interchanging loops not profitable.\n");

550 return false;

551 }

552

553 ORE->emit([&]() {

557 << "Loop interchanged with enclosing loop.";

558 });

559

560 LoopInterchangeTransform LIT(OuterLoop, InnerLoop, SE, LI, DT, LIL);

561 LIT.transform();

563 LoopsInterchanged++;

564

566 return true;

567 }

568};

569

570}

571

572bool LoopInterchangeLegality::containsUnsafeInstructions(BasicBlock *BB) {

574 return I.mayHaveSideEffects() || I.mayReadFromMemory();

575 });

576}

577

578bool LoopInterchangeLegality::tightlyNested(Loop *OuterLoop, Loop *InnerLoop) {

582

583 LLVM_DEBUG(dbgs() << "Checking if loops are tightly nested\n");

584

585

586

587

589 dyn_cast(OuterLoopHeader->getTerminator());

590 if (!OuterLoopHeaderBI)

591 return false;

592

594 if (Succ != InnerLoopPreHeader && Succ != InnerLoop->getHeader() &&

595 Succ != OuterLoopLatch)

596 return false;

597

598 LLVM_DEBUG(dbgs() << "Checking instructions in Loop header and Loop latch\n");

599

600

601 if (containsUnsafeInstructions(OuterLoopHeader) ||

602 containsUnsafeInstructions(OuterLoopLatch))

603 return false;

604

605

606

607

608 if (InnerLoopPreHeader != OuterLoopHeader &&

609 containsUnsafeInstructions(InnerLoopPreHeader))

610 return false;

611

613

614

617 if (&SuccInner != OuterLoopLatch) {

618 LLVM_DEBUG(dbgs() << "Inner loop exit block " << *InnerLoopExit

619 << " does not lead to the outer loop latch.\n";);

620 return false;

621 }

622

623

624

625 if (containsUnsafeInstructions(InnerLoopExit))

626 return false;

627

628 LLVM_DEBUG(dbgs() << "Loops are perfectly nested\n");

629

630 return true;

631}

632

633bool LoopInterchangeLegality::isLoopStructureUnderstood() {

635 for (PHINode *InnerInduction : InnerLoopInductions) {

636 unsigned Num = InnerInduction->getNumOperands();

637 for (unsigned i = 0; i < Num; ++i) {

638 Value *Val = InnerInduction->getOperand(i);

639 if (isa(Val))

640 continue;

642 if (I)

643 return false;

644

645

646

648 if (InnerInduction->getIncomingBlock(IncomBlockIndx) ==

649 InnerLoopPreheader &&

651 return false;

652 }

653 }

654 }

655

656

657

658

659

660

661

664 dyn_cast(InnerLoopLatch->getTerminator());

666 return false;

667 if (CmpInst *InnerLoopCmp =

668 dyn_cast(InnerLoopLatchBI->getCondition())) {

669 Value *Op0 = InnerLoopCmp->getOperand(0);

670 Value *Op1 = InnerLoopCmp->getOperand(1);

671

672

673

676

677

678

679

680

681 std::function<bool(Value *)> IsPathToInnerIndVar;

682 IsPathToInnerIndVar = [this, &IsPathToInnerIndVar](const Value *V) -> bool {

684 return true;

685 if (isa(V))

686 return true;

687 const Instruction *I = dyn_cast(V);

688 if (I)

689 return false;

690 if (isa(I))

691 return IsPathToInnerIndVar(I->getOperand(0));

692 if (isa(I))

693 return IsPathToInnerIndVar(I->getOperand(0)) &&

694 IsPathToInnerIndVar(I->getOperand(1));

695 return false;

696 };

697

698

699

700 if (IsPathToInnerIndVar(Op0) && IsPathToInnerIndVar(Op1))

701 return true;

702

703

704

705 if (IsPathToInnerIndVar(Op0) && !isa(Op0)) {

708 } else if (IsPathToInnerIndVar(Op1) && !isa(Op1)) {

711 }

712

713 if (Left == nullptr)

714 return false;

715

718 return false;

719 }

720

721 return true;

722}

723

724

725

727 PHINode *PHI = dyn_cast(SV);

728 if (PHI)

729 return SV;

730

731 if (PHI->getNumIncomingValues() != 1)

732 return SV;

734}

735

736

738

739 if (isa(V))

740 return nullptr;

741

744 if (PHI->getNumIncomingValues() == 1)

745 continue;

748

750 return nullptr;

751 return PHI;

752 }

753 return nullptr;

754 }

755 }

756

757 return nullptr;

758}

759

760bool LoopInterchangeLegality::findInductionAndReductions(

762 if (L->getLoopLatch() || L->getLoopPredecessor())

763 return false;

764 for (PHINode &PHI : L->getHeader()->phis()) {

768 else {

769

770

771 if (!InnerLoop) {

772 if (!OuterInnerReductions.count(&PHI)) {

773 LLVM_DEBUG(dbgs() << "Inner loop PHI is not part of reductions "

774 "across the outer loop.\n");

775 return false;

776 }

777 } else {

778 assert(PHI.getNumIncomingValues() == 2 &&

779 "Phis in loop header should have exactly 2 incoming values");

780

781

784 if (!InnerRedPhi ||

788 << "Failed to recognize PHI as an induction or reduction.\n");

789 return false;

790 }

791 OuterInnerReductions.insert(&PHI);

792 OuterInnerReductions.insert(InnerRedPhi);

793 }

794 }

795 }

796 return true;

797}

798

799

800

801bool LoopInterchangeLegality::currentLimitations() {

803

804

805

808 !isa(InnerLoopLatch->getTerminator()) ||

811 dbgs() << "Loops where the latch is not the exiting block are not"

812 << " supported currently.\n");

813 ORE->emit([&]() {

817 << "Loops where the latch is not the exiting block cannot be"

818 " interchange currently.";

819 });

820 return true;

821 }

822

824 if (!findInductionAndReductions(OuterLoop, Inductions, InnerLoop)) {

826 dbgs() << "Only outer loops with induction or reduction PHI nodes "

827 << "are supported currently.\n");

828 ORE->emit([&]() {

832 << "Only outer loops with induction or reduction PHI nodes can be"

833 " interchanged currently.";

834 });

835 return true;

836 }

837

838 Inductions.clear();

839

840

841

842 Loop *CurLevelLoop = OuterLoop;

843 while (!CurLevelLoop->getSubLoops().empty()) {

844

845 CurLevelLoop = CurLevelLoop->getSubLoops().front();

846 if (!findInductionAndReductions(CurLevelLoop, Inductions, nullptr)) {

848 dbgs() << "Only inner loops with induction or reduction PHI nodes "

849 << "are supported currently.\n");

850 ORE->emit([&]() {

854 << "Only inner loops with induction or reduction PHI nodes can be"

855 " interchange currently.";

856 });

857 return true;

858 }

859 }

860

861

862 if (!isLoopStructureUnderstood()) {

863 LLVM_DEBUG(dbgs() << "Loop structure not understood by pass\n");

864 ORE->emit([&]() {

868 << "Inner loop structure not understood currently.";

869 });

870 return true;

871 }

872

873 return false;

874}

875

876bool LoopInterchangeLegality::findInductions(

878 for (PHINode &PHI : L->getHeader()->phis()) {

882 }

883 return !Inductions.empty();

884}

885

886

887

888

889static bool

894

895 if (PHI.getNumIncomingValues() > 1)

896 return false;

898 PHINode *PN = dyn_cast(U);

899 return !PN ||

900 (!Reductions.count(PN) && OuterL->contains(PN->getParent()));

901 })) {

902 return false;

903 }

904 }

905 return true;

906}

907

908

909

910

911

912

913

914

918 for (unsigned i = 0; i < PHI.getNumIncomingValues(); i++) {

919 Instruction *IncomingI = dyn_cast(PHI.getIncomingValue(i));

921 continue;

922

923

924

925

926

927

928

929

930

931

932

934 return false;

935 }

936 }

937 return true;

938}

939

940

941

942

943

944

945

946

947

950 return true;

951

952

953

955 return true;

956

957

958

959

960

961

962

965 for (auto *U : PHI.users()) {

967 if (InnerLoopLatch == UI->getParent())

968 return false;

969 }

970 }

971 return true;

972}

973

974bool LoopInterchangeLegality::canInterchangeLoops(unsigned InnerLoopId,

975 unsigned OuterLoopId,

976 CharMatrix &DepMatrix) {

978 LLVM_DEBUG(dbgs() << "Failed interchange InnerLoopId = " << InnerLoopId

979 << " and OuterLoopId = " << OuterLoopId

980 << " due to dependence\n");

981 ORE->emit([&]() {

985 << "Cannot interchange loops due to dependences.";

986 });

987 return false;

988 }

989

990 for (auto *BB : OuterLoop->blocks())

992 if (CallInst *CI = dyn_cast(&I)) {

993

994 if (CI->onlyWritesMemory())

995 continue;

997 dbgs() << "Loops with call instructions cannot be interchanged "

998 << "safely.");

999 ORE->emit([&]() {

1001 CI->getDebugLoc(),

1002 CI->getParent())

1003 << "Cannot interchange loops due to call instruction.";

1004 });

1005

1006 return false;

1007 }

1008

1009 if (!findInductions(InnerLoop, InnerLoopInductions)) {

1010 LLVM_DEBUG(dbgs() << "Could not find inner loop induction variables.\n");

1011 return false;

1012 }

1013

1015 LLVM_DEBUG(dbgs() << "Found unsupported PHI nodes in inner loop latch.\n");

1016 ORE->emit([&]() {

1020 << "Cannot interchange loops because unsupported PHI nodes found "

1021 "in inner loop latch.";

1022 });

1023 return false;

1024 }

1025

1026

1027

1028 if (currentLimitations()) {

1029 LLVM_DEBUG(dbgs() << "Not legal because of current transform limitation\n");

1030 return false;

1031 }

1032

1033

1034 if (!tightlyNested(OuterLoop, InnerLoop)) {

1036 ORE->emit([&]() {

1040 << "Cannot interchange loops because they are not tightly "

1041 "nested.";

1042 });

1043 return false;

1044 }

1045

1047 OuterInnerReductions)) {

1048 LLVM_DEBUG(dbgs() << "Found unsupported PHI nodes in inner loop exit.\n");

1049 ORE->emit([&]() {

1053 << "Found unsupported PHI node in loop exit.";

1054 });

1055 return false;

1056 }

1057

1059 LLVM_DEBUG(dbgs() << "Found unsupported PHI nodes in outer loop exit.\n");

1060 ORE->emit([&]() {

1064 << "Found unsupported PHI node in loop exit.";

1065 });

1066 return false;

1067 }

1068

1069 return true;

1070}

1071

1072int LoopInterchangeProfitability::getInstrOrderCost() {

1073 unsigned GoodOrder, BadOrder;

1074 BadOrder = GoodOrder = 0;

1078 unsigned NumOp = GEP->getNumOperands();

1079 bool FoundInnerInduction = false;

1080 bool FoundOuterInduction = false;

1081 for (unsigned i = 0; i < NumOp; ++i) {

1082

1083 if (!SE->isSCEVable(GEP->getOperand(i)->getType()))

1084 continue;

1085

1086 const SCEV *OperandVal = SE->getSCEV(GEP->getOperand(i));

1087 const SCEVAddRecExpr *AR = dyn_cast(OperandVal);

1088 if (!AR)

1089 continue;

1090

1091

1092

1093

1094

1095

1096 if (AR->getLoop() == InnerLoop) {

1097

1098

1099 FoundInnerInduction = true;

1100 if (FoundOuterInduction) {

1101 GoodOrder++;

1102 break;

1103 }

1104 }

1105

1106

1107

1108

1109

1110 if (AR->getLoop() == OuterLoop) {

1111

1112

1113 FoundOuterInduction = true;

1114 if (FoundInnerInduction) {

1115 BadOrder++;

1116 break;

1117 }

1118 }

1119 }

1120 }

1121 }

1122 }

1123 return GoodOrder - BadOrder;

1124}

1125

1126std::optional

1127LoopInterchangeProfitability::isProfitablePerLoopCacheAnalysis(

1129 std::unique_ptr &CC) {

1130

1131

1132

1133 if (CostMap.contains(InnerLoop) && CostMap.contains(OuterLoop)) {

1134 unsigned InnerIndex = 0, OuterIndex = 0;

1135 InnerIndex = CostMap.find(InnerLoop)->second;

1136 OuterIndex = CostMap.find(OuterLoop)->second;

1138 << ", OuterIndex = " << OuterIndex << "\n");

1139 if (InnerIndex < OuterIndex)

1140 return std::optional(true);

1141 assert(InnerIndex != OuterIndex && "CostMap should assign unique "

1142 "numbers to each loop");

1143 if (CC->getLoopCost(*OuterLoop) == CC->getLoopCost(*InnerLoop))

1144 return std::nullopt;

1145 return std::optional(false);

1146 }

1147 return std::nullopt;

1148}

1149

1150std::optional

1151LoopInterchangeProfitability::isProfitablePerInstrOrderCost() {

1152

1153

1154

1155 int Cost = getInstrOrderCost();

1158 return std::optional(true);

1159

1160 return std::nullopt;

1161}

1162

1163std::optional LoopInterchangeProfitability::isProfitableForVectorization(

1164 unsigned InnerLoopId, unsigned OuterLoopId, CharMatrix &DepMatrix) {

1165 for (auto &Row : DepMatrix) {

1166

1167

1168

1169 if (Row[InnerLoopId] == 'I' || Row[InnerLoopId] == '=')

1170 return std::optional(false);

1171

1172

1173

1174

1175 if (Row[OuterLoopId] != 'I' && Row[OuterLoopId] != '=')

1176 return std::optional(false);

1177 }

1178

1179

1180

1181 return std::optional(!DepMatrix.empty());

1182}

1183

1184bool LoopInterchangeProfitability::isProfitable(

1185 const Loop *InnerLoop, const Loop *OuterLoop, unsigned InnerLoopId,

1186 unsigned OuterLoopId, CharMatrix &DepMatrix,

1188 std::unique_ptr &CC) {

1189

1190

1191

1192

1193

1194

1195

1196

1197 std::optional shouldInterchange =

1198 isProfitablePerLoopCacheAnalysis(CostMap, CC);

1199 if (!shouldInterchange.has_value()) {

1200 shouldInterchange = isProfitablePerInstrOrderCost();

1201 if (!shouldInterchange.has_value())

1202 shouldInterchange =

1203 isProfitableForVectorization(InnerLoopId, OuterLoopId, DepMatrix);

1204 }

1205 if (!shouldInterchange.has_value()) {

1206 ORE->emit([&]() {

1210 << "Insufficient information to calculate the cost of loop for "

1211 "interchange.";

1212 });

1213 return false;

1214 } else if (!shouldInterchange.value()) {

1215 ORE->emit([&]() {

1219 << "Interchanging loops is not considered to improve cache "

1220 "locality nor vectorization.";

1221 });

1222 return false;

1223 }

1224 return true;

1225}

1226

1227void LoopInterchangeTransform::removeChildLoop(Loop *OuterLoop,

1228 Loop *InnerLoop) {

1229 for (Loop *L : *OuterLoop)

1230 if (L == InnerLoop) {

1231 OuterLoop->removeChildLoop(L);

1232 return;

1233 }

1235}

1236

1237

1238

1239

1240

1241

1242

1243

1244

1245

1246

1247

1248

1249

1250

1251

1252

1253

1254

1255

1256

1257

1258

1259

1260void LoopInterchangeTransform::restructureLoops(

1264

1265

1267 LI->changeLoopFor(OrigInnerPreHeader, OuterLoopParent);

1268

1269

1270 if (OuterLoopParent) {

1271

1272 removeChildLoop(OuterLoopParent, NewInner);

1273 removeChildLoop(NewInner, NewOuter);

1275 } else {

1276 removeChildLoop(NewInner, NewOuter);

1278 }

1282

1283

1285

1286

1287

1291

1292

1293

1296 for (BasicBlock *BB : OrigInnerBBs) {

1297

1299 continue;

1300

1301 if (BB == OuterHeader || BB == OuterLatch)

1303 else

1305 }

1306

1307

1308

1310 LI->changeLoopFor(OrigOuterPreHeader, NewOuter);

1311

1312

1314}

1315

1316bool LoopInterchangeTransform::transform() {

1317 bool Transformed = false;

1318

1321 LLVM_DEBUG(dbgs() << "Splitting the inner loop latch\n");

1322 auto &InductionPHIs = LIL.getInnerLoopInductions();

1323 if (InductionPHIs.empty()) {

1324 LLVM_DEBUG(dbgs() << "Failed to find the point to split loop latch \n");

1325 return false;

1326 }

1327

1329 for (PHINode *CurInductionPHI : InductionPHIs) {

1330 if (CurInductionPHI->getIncomingBlock(0) == InnerLoopPreHeader)

1332 dyn_cast(CurInductionPHI->getIncomingValue(1)));

1333 else

1335 dyn_cast(CurInductionPHI->getIncomingValue(0)));

1336 }

1337

1338

1339

1340

1341

1345

1347 unsigned i = 0;

1348 auto MoveInstructions = [&i, &WorkList, this, &InductionPHIs, NewLatch]() {

1349 for (; i < WorkList.size(); i++) {

1350

1351

1352 Instruction *NewI = WorkList[i]->clone();

1355 "Moving instructions with side-effects may change behavior of "

1356 "the loop nest!");

1358 Instruction *UserI = cast(U.getUser());

1360 UserI->getParent() == NewLatch ||

1362 U.set(NewI);

1363 }

1364

1365

1366 for (Value *Op : WorkList[i]->operands()) {

1368 if (!OpI ||

1371 continue;

1372 WorkList.insert(OpI);

1373 }

1374 }

1375 };

1376

1377

1378 Instruction *CondI = dyn_cast(

1380 ->getCondition());

1381 if (CondI)

1382 WorkList.insert(CondI);

1383 MoveInstructions();

1384 for (Instruction *InnerIndexVar : InnerIndexVarList)

1385 WorkList.insert(cast(InnerIndexVar));

1386 MoveInstructions();

1387 }

1388

1389

1393 LLVM_DEBUG(dbgs() << "splitting InnerLoopHeader done\n");

1394 }

1395

1396

1397

1398

1399

1400

1402 BasicBlock *OuterLoopHeader = OuterLoop->getHeader();

1403 if (InnerLoopPreHeader != OuterLoopHeader) {

1407 std::prev(InnerLoopPreHeader->end()))))

1408 I.moveBeforePreserving(OuterLoopHeader->getTerminator());

1409 }

1410

1411 Transformed |= adjustLoopLinks();

1412 if (!Transformed) {

1414 return false;

1415 }

1416

1417 return true;

1418}

1419

1420

1421

1424

1427}

1428

1429

1431

1432

1436 I->removeFromParent();

1437

1438

1440

1441

1444}

1445

1446

1447

1448

1451 std::vectorDominatorTree::UpdateType &DTUpdates,

1452 bool MustUpdateOnce = true) {

1453 assert((!MustUpdateOnce ||

1456 return BB == OldBB;

1457 }) == 1) && "BI must jump to OldBB exactly once.");

1458 bool Changed = false;

1460 if (Op == OldBB) {

1461 Op.set(NewBB);

1462 Changed = true;

1463 }

1464

1465 if (Changed) {

1466 DTUpdates.push_back(

1467 {DominatorTree::UpdateKind::Insert, BI->getParent(), NewBB});

1468 DTUpdates.push_back(

1469 {DominatorTree::UpdateKind::Delete, BI->getParent(), OldBB});

1470 }

1471 assert(Changed && "Expected a successor to be updated");

1472}

1473

1474

1479

1480

1481

1482

1483

1484

1485

1486

1488 assert(P.getNumIncomingValues() == 1 &&

1489 "Only loops with a single exit are supported!");

1490

1491

1492 auto IncI = cast(P.getIncomingValueForBlock(InnerLatch));

1493

1494

1495 auto IncIInnerMost = cast(followLCSSA(IncI));

1496

1497

1498 if (IncIInnerMost->getParent() != InnerLatch &&

1499 IncIInnerMost->getParent() != InnerHeader)

1500 continue;

1501

1503 [OuterHeader, OuterExit, IncI, InnerHeader](User *U) {

1504 return (cast(U)->getParent() == OuterHeader &&

1505 IncI->getParent() == InnerHeader) ||

1506 cast(U)->getParent() == OuterExit;

1507 }) &&

1508 "Can only replace phis iff the uses are in the loop nest exit or "

1509 "the incoming value is defined in the inner header (it will "

1510 "dominate all loop blocks after interchanging)");

1511 P.replaceAllUsesWith(IncI);

1512 P.eraseFromParent();

1513 }

1514

1518

1522

1523

1524

1525

1526

1527

1528 for (PHINode *P : LcssaInnerExit)

1530

1531

1532

1533 for (PHINode *P : LcssaInnerLatch)

1535

1536

1537

1538

1539

1540 if (OuterExit) {

1542 if (P.getNumIncomingValues() != 1)

1543 continue;

1544

1545

1546 auto I = dyn_cast(P.getIncomingValue(0));

1547 if (I || LI->getLoopFor(I->getParent()) == InnerLoop)

1548 continue;

1549

1550 PHINode *NewPhi = dyn_cast(P.clone());

1553

1554

1555 for (auto *Pred : predecessors(InnerLatch)) {

1556 if (Pred == OuterLatch)

1557 continue;

1558 NewPhi->addIncoming(P.getIncomingValue(0), Pred);

1559 }

1561 P.setIncomingValue(0, NewPhi);

1562 }

1563 }

1564

1565

1566

1567

1569}

1570

1571bool LoopInterchangeTransform::adjustLoopBranches() {

1572 LLVM_DEBUG(dbgs() << "adjustLoopBranches called\n");

1573 std::vectorDominatorTree::UpdateType DTUpdates;

1574

1575 BasicBlock *OuterLoopPreHeader = OuterLoop->getLoopPreheader();

1577

1578 assert(OuterLoopPreHeader != OuterLoop->getHeader() &&

1579 InnerLoopPreHeader != InnerLoop->getHeader() && OuterLoopPreHeader &&

1580 InnerLoopPreHeader && "Guaranteed by loop-simplify form");

1581

1582

1583

1584

1585 if (isa(OuterLoopPreHeader->begin()) ||

1587 OuterLoopPreHeader =

1589 if (InnerLoopPreHeader == OuterLoop->getHeader())

1590 InnerLoopPreHeader =

1592

1593

1595 BasicBlock *OuterLoopHeader = OuterLoop->getHeader();

1597 BasicBlock *OuterLoopLatch = OuterLoop->getLoopLatch();

1599 BasicBlock *InnerLoopLatchPredecessor =

1601 BasicBlock *InnerLoopLatchSuccessor;

1602 BasicBlock *OuterLoopLatchSuccessor;

1603

1605 dyn_cast(OuterLoopLatch->getTerminator());

1607 dyn_cast(InnerLoopLatch->getTerminator());

1609 dyn_cast(OuterLoopHeader->getTerminator());

1611 dyn_cast(InnerLoopHeader->getTerminator());

1612

1613 if (!OuterLoopPredecessor || !InnerLoopLatchPredecessor ||

1614 !OuterLoopLatchBI || !InnerLoopLatchBI || !OuterLoopHeaderBI ||

1615 !InnerLoopHeaderBI)

1616 return false;

1617

1618 BranchInst *InnerLoopLatchPredecessorBI =

1619 dyn_cast(InnerLoopLatchPredecessor->getTerminator());

1620 BranchInst *OuterLoopPredecessorBI =

1621 dyn_cast(OuterLoopPredecessor->getTerminator());

1622

1623 if (!OuterLoopPredecessorBI || !InnerLoopLatchPredecessorBI)

1624 return false;

1626 if (!InnerLoopHeaderSuccessor)

1627 return false;

1628

1629

1630

1631

1632

1633 updateSuccessor(OuterLoopPredecessorBI, OuterLoopPreHeader,

1634 InnerLoopPreHeader, DTUpdates, false);

1635

1636

1638

1639 updateSuccessor(OuterLoopHeaderBI, OuterLoopLatch, InnerLoopLatch,

1640 DTUpdates,

1641 false);

1642 }

1644 InnerLoopHeaderSuccessor, DTUpdates,

1645 false);

1646

1647

1649 OuterLoopHeader);

1650

1651 updateSuccessor(InnerLoopHeaderBI, InnerLoopHeaderSuccessor,

1652 OuterLoopPreHeader, DTUpdates);

1653

1654

1655 if (InnerLoopLatchBI->getSuccessor(0) == InnerLoopHeader)

1656 InnerLoopLatchSuccessor = InnerLoopLatchBI->getSuccessor(1);

1657 else

1658 InnerLoopLatchSuccessor = InnerLoopLatchBI->getSuccessor(0);

1659

1660 updateSuccessor(InnerLoopLatchPredecessorBI, InnerLoopLatch,

1661 InnerLoopLatchSuccessor, DTUpdates);

1662

1663 if (OuterLoopLatchBI->getSuccessor(0) == OuterLoopHeader)

1664 OuterLoopLatchSuccessor = OuterLoopLatchBI->getSuccessor(1);

1665 else

1666 OuterLoopLatchSuccessor = OuterLoopLatchBI->getSuccessor(0);

1667

1668 updateSuccessor(InnerLoopLatchBI, InnerLoopLatchSuccessor,

1669 OuterLoopLatchSuccessor, DTUpdates);

1670 updateSuccessor(OuterLoopLatchBI, OuterLoopLatchSuccessor, InnerLoopLatch,

1671 DTUpdates);

1672

1674 restructureLoops(OuterLoop, InnerLoop, InnerLoopPreHeader,

1675 OuterLoopPreHeader);

1676

1677 moveLCSSAPhis(InnerLoopLatchSuccessor, InnerLoopHeader, InnerLoopLatch,

1678 OuterLoopHeader, OuterLoopLatch, InnerLoop->getExitBlock(),

1679 InnerLoop, LI);

1680

1681

1682 OuterLoopLatchSuccessor->replacePhiUsesWith(OuterLoopLatch, InnerLoopLatch);

1683

1684 auto &OuterInnerReductions = LIL.getOuterInnerReductions();

1685

1688 if (OuterInnerReductions.contains(&PHI))

1690

1692 if (OuterInnerReductions.contains(&PHI))

1694

1695

1696

1697

1698 for (PHINode *PHI : OuterLoopPHIs) {

1699 LLVM_DEBUG(dbgs() << "Outer loop reduction PHIs:\n"; PHI->dump(););

1701 assert(OuterInnerReductions.count(PHI) && "Expected a reduction PHI node");

1702 }

1703 for (PHINode *PHI : InnerLoopPHIs) {

1704 LLVM_DEBUG(dbgs() << "Inner loop reduction PHIs:\n"; PHI->dump(););

1706 assert(OuterInnerReductions.count(PHI) && "Expected a reduction PHI node");

1707 }

1708

1709

1710 OuterLoopHeader->replacePhiUsesWith(InnerLoopPreHeader, OuterLoopPreHeader);

1711 OuterLoopHeader->replacePhiUsesWith(InnerLoopLatch, OuterLoopLatch);

1712 InnerLoopHeader->replacePhiUsesWith(OuterLoopPreHeader, InnerLoopPreHeader);

1713 InnerLoopHeader->replacePhiUsesWith(OuterLoopLatch, InnerLoopLatch);

1714

1715

1716

1717

1718

1721 make_range(OuterLoopHeader->begin(), std::prev(OuterLoopHeader->end())))

1724

1725 return true;

1726}

1727

1728bool LoopInterchangeTransform::adjustLoopLinks() {

1729

1730 bool Changed = adjustLoopBranches();

1731 if (Changed) {

1732

1733

1734

1735 BasicBlock *OuterLoopPreHeader = OuterLoop->getLoopPreheader();

1737 swapBBContents(OuterLoopPreHeader, InnerLoopPreHeader);

1738 }

1739 return Changed;

1740}

1741

1748

1750 LLVM_DEBUG(dbgs() << "MaxMemInstrCount should be at least 1");

1752 }

1754

1755

1759 std::unique_ptr CC =

1761

1762 if (!LoopInterchange(&AR.SE, &AR.LI, &DI, &AR.DT, CC, &ORE).run(LN))

1764 U.markLoopNestChanged(true);

1766}

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

Given that RA is a live propagate it s liveness to any other values it uses(according to Uses). void DeadArgumentEliminationPass

This file defines the interface for the loop cache analysis.

static cl::opt< unsigned int > MaxMemInstrCount("loop-interchange-max-meminstr-count", cl::init(64), cl::Hidden, cl::desc("Maximum number of load-store instructions that should be handled " "in the dependency matrix. Higher value may lead to more interchanges " "at the cost of compile-time"))

static cl::opt< int > LoopInterchangeCostThreshold("loop-interchange-threshold", cl::init(0), cl::Hidden, cl::desc("Interchange if you gain more than this number"))

static PHINode * findInnerReductionPhi(Loop *L, Value *V)

static cl::opt< unsigned int > MinLoopNestDepth("loop-interchange-min-loop-nest-depth", cl::init(2), cl::Hidden, cl::desc("Minimum depth of loop nest considered for the transform"))

static bool hasSupportedLoopDepth(SmallVectorImpl< Loop * > &LoopList, OptimizationRemarkEmitter &ORE)

static bool areOuterLoopExitPHIsSupported(Loop *OuterLoop, Loop *InnerLoop)

static void moveBBContents(BasicBlock *FromBB, Instruction *InsertBefore)

Move all instructions except the terminator from FromBB right before InsertBefore.

static void interChangeDependencies(CharMatrix &DepMatrix, unsigned FromIndx, unsigned ToIndx)

static void moveLCSSAPhis(BasicBlock *InnerExit, BasicBlock *InnerHeader, BasicBlock *InnerLatch, BasicBlock *OuterHeader, BasicBlock *OuterLatch, BasicBlock *OuterExit, Loop *InnerLoop, LoopInfo *LI)

static void printDepMatrix(CharMatrix &DepMatrix)

static void swapBBContents(BasicBlock *BB1, BasicBlock *BB2)

Swap instructions between BB1 and BB2 but keep terminators intact.

static cl::opt< unsigned int > MaxLoopNestDepth("loop-interchange-max-loop-nest-depth", cl::init(10), cl::Hidden, cl::desc("Maximum depth of loop nest considered for the transform"))

static bool areInnerLoopLatchPHIsSupported(Loop *OuterLoop, Loop *InnerLoop)

static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix, unsigned InnerLoopId, unsigned OuterLoopId)

static bool areInnerLoopExitPHIsSupported(Loop *InnerL, Loop *OuterL, SmallPtrSetImpl< PHINode * > &Reductions)

static Value * followLCSSA(Value *SV)

static void populateWorklist(Loop &L, LoopVector &LoopList)

static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level, Loop *L, DependenceInfo *DI, ScalarEvolution *SE, OptimizationRemarkEmitter *ORE)

static void updateSuccessor(BranchInst *BI, BasicBlock *OldBB, BasicBlock *NewBB, std::vector< DominatorTree::UpdateType > &DTUpdates, bool MustUpdateOnce=true)

static bool isLexicographicallyPositive(std::vector< char > &DV)

This file defines the interface for the loop nest analysis.

This header provides classes for managing a pipeline of passes over loops in LLVM IR.

uint64_t IntrinsicInst * II

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

This file defines the SmallVector class.

static bool isProfitable(const SmallVector< std::unique_ptr< StableFunctionMap::StableFunctionEntry > > &SFS)

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

#define STATISTIC(VARNAME, DESC)

StringSet - A set-like wrapper for the StringMap.

A container for analyses that lazily runs them and caches their results.

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

size_t size() const

size - Get the array size.

LLVM Basic Block Representation.

iterator begin()

Instruction iterator methods.

iterator_range< const_phi_iterator > phis() const

Returns a range that iterates over the phis in the basic block.

iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug(bool SkipPseudoOp=true) const

Return a const iterator range over the instructions in the block, skipping any debug instructions.

const Instruction * getFirstNonPHI() const

Returns a pointer to the first instruction in this block that is not a PHINode instruction.

const BasicBlock * getUniqueSuccessor() const

Return the successor of this block if it has a unique successor.

void replacePhiUsesWith(BasicBlock *Old, BasicBlock *New)

Update all phi nodes in this basic block to refer to basic block New instead of basic block Old.

const BasicBlock * getUniquePredecessor() const

Return the predecessor of this block if it has a unique predecessor block.

const Function * getParent() const

Return the enclosing method, or null if none.

const Instruction * getTerminator() const LLVM_READONLY

Returns the terminator instruction if the block is well formed or null if the block is not well forme...

void splice(BasicBlock::iterator ToIt, BasicBlock *FromBB)

Transfer all instructions from FromBB to this basic block at ToIt.

Conditional or Unconditional Branch instruction.

iterator_range< succ_op_iterator > successors()

bool isConditional() const

BasicBlock * getSuccessor(unsigned i) const

Value * getCondition() const

static std::unique_ptr< CacheCost > getCacheCost(Loop &Root, LoopStandardAnalysisResults &AR, DependenceInfo &DI, std::optional< unsigned > TRT=std::nullopt)

Create a CacheCost for the loop nest rooted by Root.

This class represents a function call, abstracting a target machine's calling convention.

This class is the base class for the comparison instructions.

This class represents an Operation in the Expression.

iterator find(const_arg_type_t< KeyT > Val)

bool contains(const_arg_type_t< KeyT > Val) const

Return true if the specified key is in the map, false otherwise.

DependenceInfo - This class is the main dependence-analysis driver.

std::unique_ptr< Dependence > depends(Instruction *Src, Instruction *Dst, bool PossiblyLoopIndependent)

depends - Tests for a dependence between the Src and Dst instructions.

void applyUpdates(ArrayRef< UpdateType > Updates)

Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

an instruction for type-safe pointer arithmetic to access elements of arrays and structs

A struct for saving information about induction variables.

static bool isInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE, InductionDescriptor &D, const SCEV *Expr=nullptr, SmallVectorImpl< Instruction * > *CastsToIgnore=nullptr)

Returns true if Phi is an induction in the loop L.

void insertBefore(Instruction *InsertPos)

Insert an unlinked instruction into a basic block immediately before the specified instruction.

bool mayHaveSideEffects() const LLVM_READONLY

Return true if the instruction may have side effects.

This class provides an interface for updating the loop pass manager based on mutations to the loop ne...

bool contains(const LoopT *L) const

Return true if the specified loop is contained within in this loop.

BlockT * getLoopLatch() const

If there is a single latch block for this loop, return it.

bool isInnermost() const

Return true if the loop does not contain any (natural) loops.

void removeBlockFromLoop(BlockT *BB)

This removes the specified basic block from the current loop, updating the Blocks as appropriate.

const std::vector< LoopT * > & getSubLoops() const

Return the loops contained entirely within this loop.

BlockT * getHeader() const

iterator_range< block_iterator > blocks() const

void addChildLoop(LoopT *NewChild)

Add the specified loop to be a child of this loop.

void addBlockEntry(BlockT *BB)

This adds a basic block directly to the basic block list.

BlockT * getExitBlock() const

If getExitBlocks would return exactly one block, return that block.

BlockT * getLoopPreheader() const

If there is a preheader for this loop, return it.

BlockT * getExitingBlock() const

If getExitingBlocks would return exactly one block, return that block.

LoopT * getParentLoop() const

Return the parent loop if it exists or nullptr for top level loops.

BlockT * getUniqueExitBlock() const

If getUniqueExitBlocks would return exactly one block, return that block.

LoopT * removeChildLoop(iterator I)

This removes the specified child from being a subloop of this loop.

void changeTopLevelLoop(LoopT *OldLoop, LoopT *NewLoop)

Replace the specified loop in the top-level loops list with the indicated loop.

void changeLoopFor(BlockT *BB, LoopT *L)

Change the top-level loop that contains BB to the specified loop.

LoopT * getLoopFor(const BlockT *BB) const

Return the inner most loop that BB lives in.

This class represents a loop nest and can be used to query its properties.

static const BasicBlock & skipEmptyBlockUntil(const BasicBlock *From, const BasicBlock *End, bool CheckUniquePred=false)

Recursivelly traverse all empty 'single successor' basic blocks of From (if there are any).

ArrayRef< Loop * > getLoops() const

Get the loops in the nest.

Function * getParent() const

Return the function to which the loop-nest belongs.

Loop & getOutermostLoop() const

Return the outermost loop in the loop nest.

Represents a single loop in the control flow graph.

DebugLoc getStartLoc() const

Return the debug location of the start of this loop.

bool isLoopInvariant(const Value *V) const

Return true if the specified value is loop invariant.

void addIncoming(Value *V, BasicBlock *BB)

Add an incoming value to the end of the PHI list.

op_range incoming_values()

void setIncomingBlock(unsigned i, BasicBlock *BB)

void setIncomingValue(unsigned i, Value *V)

static unsigned getIncomingValueNumForOperand(unsigned i)

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.

The RecurrenceDescriptor is used to identify recurrences variables in a loop.

Instruction * getExactFPMathInst() const

Returns 1st non-reassociative FP instruction in the PHI node's use-chain.

static bool isReductionPHI(PHINode *Phi, Loop *TheLoop, RecurrenceDescriptor &RedDes, DemandedBits *DB=nullptr, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr, ScalarEvolution *SE=nullptr)

Returns true if Phi is a reduction in TheLoop.

This node represents a polynomial recurrence on the trip count of the specified loop.

const Loop * getLoop() const

This class represents an analyzed expression in the program.

The main scalar evolution driver.

const SCEV * getBackedgeTakenCount(const Loop *L, ExitCountKind Kind=Exact)

If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCould...

const SCEV * getSCEV(Value *V)

Return a SCEV expression for the full generality of the specified expression.

void forgetLoop(const Loop *L)

This method should be called by the client when it has changed a loop in a way that may effect Scalar...

bool isLoopInvariant(const SCEV *S, const Loop *L)

Return true if the value of the given SCEV is unchanging in the specified loop.

bool isSCEVable(Type *Ty) const

Test if values of the given type are analyzable within the SCEV framework.

size_type size() const

Determine the number of elements in the SetVector.

bool insert(const value_type &X)

Insert a new element into the SetVector.

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

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

A SetVector that performs no allocations if smaller than a certain size.

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

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.

StringSet - A wrapper for StringMap that provides set-like functionality.

std::pair< typename Base::iterator, bool > insert(StringRef key)

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

LLVM Value Representation.

const ParentTy * getParent() const

self_iterator getIterator()

#define llvm_unreachable(msg)

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

unsigned ID

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

initializer< Ty > init(const Ty &Val)

PointerTypeMap run(const Module &M)

Compute the PointerTypeMap for the module M.

This is an optimization pass for GlobalISel generic memory operations.

BasicBlock * InsertPreheaderForLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, MemorySSAUpdater *MSSAU, bool PreserveLCSSA)

InsertPreheaderForLoop - Once we discover that a loop doesn't have a preheader, this method is called...

bool all_of(R &&range, UnaryPredicate P)

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

auto successors(const MachineBasicBlock *BB)

bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI, ScalarEvolution *SE)

Put a loop nest into LCSSA form.

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

Convenience function for iterating over sub-ranges.

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

auto map_range(ContainerTy &&C, FuncTy F)

OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)

Wrapper function around std::transform to apply a function to a range and store the result elsewhere.

bool any_of(R &&range, UnaryPredicate P)

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

raw_ostream & dbgs()

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

OutputIt move(R &&Range, OutputIt Out)

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

bool formLCSSAForInstructions(SmallVectorImpl< Instruction * > &Worklist, const DominatorTree &DT, const LoopInfo &LI, ScalarEvolution *SE, SmallVectorImpl< PHINode * > *PHIsToRemove=nullptr, SmallVectorImpl< PHINode * > *InsertedPHIs=nullptr)

Ensures LCSSA form for every instruction from the Worklist in the scope of innermost containing loop.

auto count_if(R &&Range, UnaryPredicate P)

Wrapper function around std::count_if to count the number of times an element satisfying a given pred...

BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="", bool Before=false)

Split the specified block at the specified instruction.

PreservedAnalyses getLoopPassPreservedAnalyses()

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

auto predecessors(const MachineBasicBlock *BB)

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

Returns true if Element is found in Range.

Implement std::hash so that hash_code can be used in STL containers.

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

Implement std::swap in terms of BitVector swap.

PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)

The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...

Direction

An enum for the direction of the loop.