LLVM 20.0.0git
HexagonVectorLoopCarriedReuse.cpp
Go to the documentation of this file.
1//===- HexagonVectorLoopCarriedReuse.cpp ----------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass removes the computation of provably redundant expressions that have
10// been computed earlier in a previous iteration. It relies on the use of PHIs
11// to identify loop carried dependences. This is scalar replacement for vector
12// types.
13//
14//===----------------------------------------------------------------------===//
15
17#include "llvm/ADT/SetVector.h"
19#include "llvm/ADT/Statistic.h"
22#include "llvm/IR/BasicBlock.h"
24#include "llvm/IR/IRBuilder.h"
25#include "llvm/IR/Instruction.h"
28#include "llvm/IR/Intrinsics.h"
29#include "llvm/IR/IntrinsicsHexagon.h"
30#include "llvm/IR/Use.h"
31#include "llvm/IR/Value.h"
33#include "llvm/Pass.h"
37#include "llvm/Support/Debug.h"
41#include <cassert>
42#include <map>
43#include <memory>
44#include <set>
45
46using namespace llvm;
47
48#define DEBUG_TYPE "hexagon-vlcr"
49
50STATISTIC(HexagonNumVectorLoopCarriedReuse,
51 "Number of values that were reused from a previous iteration.");
52
54 "hexagon-vlcr-iteration-lim", cl::Hidden,
55 cl::desc("Maximum distance of loop carried dependences that are handled"),
56 cl::init(2));
57
58namespace llvm {
59
62
63} // end namespace llvm
64
65namespace {
66
67 // See info about DepChain in the comments at the top of this file.
68 using ChainOfDependences = SmallVector<Instruction *, 4>;
69
70 class DepChain {
71 ChainOfDependences Chain;
72
73 public:
74 bool isIdentical(DepChain &Other) const {
75 if (Other.size() != size())
76 return false;
77 ChainOfDependences &OtherChain = Other.getChain();
78 for (int i = 0; i < size(); ++i) {
79 if (Chain[i] != OtherChain[i])
80 return false;
81 }
82 return true;
83 }
84
85 ChainOfDependences &getChain() {
86 return Chain;
87 }
88
89 int size() const {
90 return Chain.size();
91 }
92
93 void clear() {
94 Chain.clear();
95 }
96
97 void push_back(Instruction *I) {
98 Chain.push_back(I);
99 }
100
101 int iterations() const {
102 return size() - 1;
103 }
104
105 Instruction *front() const {
106 return Chain.front();
107 }
108
109 Instruction *back() const {
110 return Chain.back();
111 }
112
113 Instruction *&operator[](const int index) {
114 return Chain[index];
115 }
116
117 friend raw_ostream &operator<< (raw_ostream &OS, const DepChain &D);
118 };
119
121 raw_ostream &operator<<(raw_ostream &OS, const DepChain &D) {
122 const ChainOfDependences &CD = D.Chain;
123 int ChainSize = CD.size();
124 OS << "**DepChain Start::**\n";
125 for (int i = 0; i < ChainSize -1; ++i) {
126 OS << *(CD[i]) << " -->\n";
127 }
128 OS << *CD[ChainSize-1] << "\n";
129 return OS;
130 }
131
132 struct ReuseValue {
133 Instruction *Inst2Replace = nullptr;
134
135 // In the new PHI node that we'll construct this is the value that'll be
136 // used over the backedge. This is the value that gets reused from a
137 // previous iteration.
138 Instruction *BackedgeInst = nullptr;
139 std::map<Instruction *, DepChain *> DepChains;
140 int Iterations = -1;
141
142 ReuseValue() = default;
143
144 void reset() {
145 Inst2Replace = nullptr;
146 BackedgeInst = nullptr;
147 DepChains.clear();
148 Iterations = -1;
149 }
150 bool isDefined() { return Inst2Replace != nullptr; }
151 };
152
154 raw_ostream &operator<<(raw_ostream &OS, const ReuseValue &RU) {
155 OS << "** ReuseValue ***\n";
156 OS << "Instruction to Replace: " << *(RU.Inst2Replace) << "\n";
157 OS << "Backedge Instruction: " << *(RU.BackedgeInst) << "\n";
158 return OS;
159 }
160
161 class HexagonVectorLoopCarriedReuseLegacyPass : public LoopPass {
162 public:
163 static char ID;
164
165 explicit HexagonVectorLoopCarriedReuseLegacyPass() : LoopPass(ID) {
168 }
169
170 StringRef getPassName() const override {
171 return "Hexagon-specific loop carried reuse for HVX vectors";
172 }
173
174 void getAnalysisUsage(AnalysisUsage &AU) const override {
178 AU.setPreservesCFG();
179 }
180
181 bool runOnLoop(Loop *L, LPPassManager &LPM) override;
182 };
183
184 class HexagonVectorLoopCarriedReuse {
185 public:
186 HexagonVectorLoopCarriedReuse(Loop *L) : CurLoop(L){};
187
188 bool run();
189
190 private:
191 SetVector<DepChain *> Dependences;
192 std::set<Instruction *> ReplacedInsts;
193 Loop *CurLoop;
194 ReuseValue ReuseCandidate;
195
196 bool doVLCR();
197 void findLoopCarriedDeps();
198 void findValueToReuse();
199 void findDepChainFromPHI(Instruction *I, DepChain &D);
200 void reuseValue();
201 Value *findValueInBlock(Value *Op, BasicBlock *BB);
202 DepChain *getDepChainBtwn(Instruction *I1, Instruction *I2, int Iters);
203 bool isEquivalentOperation(Instruction *I1, Instruction *I2);
204 bool canReplace(Instruction *I);
205 bool isCallInstCommutative(CallInst *C);
206 };
207
208} // end anonymous namespace
209
210char HexagonVectorLoopCarriedReuseLegacyPass::ID = 0;
211
212INITIALIZE_PASS_BEGIN(HexagonVectorLoopCarriedReuseLegacyPass, "hexagon-vlcr",
213 "Hexagon-specific predictive commoning for HVX vectors",
214 false, false)
215INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
216INITIALIZE_PASS_DEPENDENCY(LCSSAWrapperPass)
217INITIALIZE_PASS_END(HexagonVectorLoopCarriedReuseLegacyPass, "hexagon-vlcr",
218 "Hexagon-specific predictive commoning for HVX vectors",
220
224 LPMUpdater &U) {
225 HexagonVectorLoopCarriedReuse Vlcr(&L);
226 if (!Vlcr.run())
227 return PreservedAnalyses::all();
230 return PA;
231}
232
233bool HexagonVectorLoopCarriedReuseLegacyPass::runOnLoop(Loop *L,
234 LPPassManager &LPM) {
235 if (skipLoop(L))
236 return false;
237 HexagonVectorLoopCarriedReuse Vlcr(L);
238 return Vlcr.run();
239}
240
241bool HexagonVectorLoopCarriedReuse::run() {
242 if (!CurLoop->getLoopPreheader())
243 return false;
244
245 // Work only on innermost loops.
246 if (!CurLoop->getSubLoops().empty())
247 return false;
248
249 // Work only on single basic blocks loops.
250 if (CurLoop->getNumBlocks() != 1)
251 return false;
252
253 return doVLCR();
254}
255
256bool HexagonVectorLoopCarriedReuse::isCallInstCommutative(CallInst *C) {
257 switch (C->getCalledFunction()->getIntrinsicID()) {
258 case Intrinsic::hexagon_V6_vaddb:
259 case Intrinsic::hexagon_V6_vaddb_128B:
260 case Intrinsic::hexagon_V6_vaddh:
261 case Intrinsic::hexagon_V6_vaddh_128B:
262 case Intrinsic::hexagon_V6_vaddw:
263 case Intrinsic::hexagon_V6_vaddw_128B:
264 case Intrinsic::hexagon_V6_vaddubh:
265 case Intrinsic::hexagon_V6_vaddubh_128B:
266 case Intrinsic::hexagon_V6_vadduhw:
267 case Intrinsic::hexagon_V6_vadduhw_128B:
268 case Intrinsic::hexagon_V6_vaddhw:
269 case Intrinsic::hexagon_V6_vaddhw_128B:
270 case Intrinsic::hexagon_V6_vmaxb:
271 case Intrinsic::hexagon_V6_vmaxb_128B:
272 case Intrinsic::hexagon_V6_vmaxh:
273 case Intrinsic::hexagon_V6_vmaxh_128B:
274 case Intrinsic::hexagon_V6_vmaxw:
275 case Intrinsic::hexagon_V6_vmaxw_128B:
276 case Intrinsic::hexagon_V6_vmaxub:
277 case Intrinsic::hexagon_V6_vmaxub_128B:
278 case Intrinsic::hexagon_V6_vmaxuh:
279 case Intrinsic::hexagon_V6_vmaxuh_128B:
280 case Intrinsic::hexagon_V6_vminub:
281 case Intrinsic::hexagon_V6_vminub_128B:
282 case Intrinsic::hexagon_V6_vminuh:
283 case Intrinsic::hexagon_V6_vminuh_128B:
284 case Intrinsic::hexagon_V6_vminb:
285 case Intrinsic::hexagon_V6_vminb_128B:
286 case Intrinsic::hexagon_V6_vminh:
287 case Intrinsic::hexagon_V6_vminh_128B:
288 case Intrinsic::hexagon_V6_vminw:
289 case Intrinsic::hexagon_V6_vminw_128B:
290 case Intrinsic::hexagon_V6_vmpyub:
291 case Intrinsic::hexagon_V6_vmpyub_128B:
292 case Intrinsic::hexagon_V6_vmpyuh:
293 case Intrinsic::hexagon_V6_vmpyuh_128B:
294 case Intrinsic::hexagon_V6_vavgub:
295 case Intrinsic::hexagon_V6_vavgub_128B:
296 case Intrinsic::hexagon_V6_vavgh:
297 case Intrinsic::hexagon_V6_vavgh_128B:
298 case Intrinsic::hexagon_V6_vavguh:
299 case Intrinsic::hexagon_V6_vavguh_128B:
300 case Intrinsic::hexagon_V6_vavgw:
301 case Intrinsic::hexagon_V6_vavgw_128B:
302 case Intrinsic::hexagon_V6_vavgb:
303 case Intrinsic::hexagon_V6_vavgb_128B:
304 case Intrinsic::hexagon_V6_vavguw:
305 case Intrinsic::hexagon_V6_vavguw_128B:
306 case Intrinsic::hexagon_V6_vabsdiffh:
307 case Intrinsic::hexagon_V6_vabsdiffh_128B:
308 case Intrinsic::hexagon_V6_vabsdiffub:
309 case Intrinsic::hexagon_V6_vabsdiffub_128B:
310 case Intrinsic::hexagon_V6_vabsdiffuh:
311 case Intrinsic::hexagon_V6_vabsdiffuh_128B:
312 case Intrinsic::hexagon_V6_vabsdiffw:
313 case Intrinsic::hexagon_V6_vabsdiffw_128B:
314 return true;
315 default:
316 return false;
317 }
318}
319
320bool HexagonVectorLoopCarriedReuse::isEquivalentOperation(Instruction *I1,
321 Instruction *I2) {
322 if (!I1->isSameOperationAs(I2))
323 return false;
324 // This check is in place specifically for intrinsics. isSameOperationAs will
325 // return two for any two hexagon intrinsics because they are essentially the
326 // same instruciton (CallInst). We need to scratch the surface to see if they
327 // are calls to the same function.
328 if (CallInst *C1 = dyn_cast<CallInst>(I1)) {
329 if (CallInst *C2 = dyn_cast<CallInst>(I2)) {
330 if (C1->getCalledFunction() != C2->getCalledFunction())
331 return false;
332 }
333 }
334
335 // If both the Instructions are of Vector Type and any of the element
336 // is integer constant, check their values too for equivalence.
337 if (I1->getType()->isVectorTy() && I2->getType()->isVectorTy()) {
338 unsigned NumOperands = I1->getNumOperands();
339 for (unsigned i = 0; i < NumOperands; ++i) {
340 ConstantInt *C1 = dyn_cast<ConstantInt>(I1->getOperand(i));
341 ConstantInt *C2 = dyn_cast<ConstantInt>(I2->getOperand(i));
342 if(!C1) continue;
343 assert(C2);
344 if (C1->getSExtValue() != C2->getSExtValue())
345 return false;
346 }
347 }
348
349 return true;
350}
351
352bool HexagonVectorLoopCarriedReuse::canReplace(Instruction *I) {
353 const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I);
354 if (!II)
355 return true;
356
357 switch (II->getIntrinsicID()) {
358 case Intrinsic::hexagon_V6_hi:
359 case Intrinsic::hexagon_V6_lo:
360 case Intrinsic::hexagon_V6_hi_128B:
361 case Intrinsic::hexagon_V6_lo_128B:
362 LLVM_DEBUG(dbgs() << "Not considering for reuse: " << *II << "\n");
363 return false;
364 default:
365 return true;
366 }
367}
368void HexagonVectorLoopCarriedReuse::findValueToReuse() {
369 for (auto *D : Dependences) {
370 LLVM_DEBUG(dbgs() << "Processing dependence " << *(D->front()) << "\n");
371 if (D->iterations() > HexagonVLCRIterationLim) {
373 dbgs()
374 << ".. Skipping because number of iterations > than the limit\n");
375 continue;
376 }
377
378 PHINode *PN = cast<PHINode>(D->front());
379 Instruction *BEInst = D->back();
380 int Iters = D->iterations();
381 BasicBlock *BB = PN->getParent();
382 LLVM_DEBUG(dbgs() << "Checking if any uses of " << *PN
383 << " can be reused\n");
384
386 for (Use &U : PN->uses()) {
387 Instruction *User = cast<Instruction>(U.getUser());
388
389 if (User->getParent() != BB)
390 continue;
391 if (ReplacedInsts.count(User)) {
392 LLVM_DEBUG(dbgs() << *User
393 << " has already been replaced. Skipping...\n");
394 continue;
395 }
396 if (isa<PHINode>(User))
397 continue;
398 if (User->mayHaveSideEffects())
399 continue;
400 if (!canReplace(User))
401 continue;
402
403 PNUsers.push_back(User);
404 }
405 LLVM_DEBUG(dbgs() << PNUsers.size() << " use(s) of the PHI in the block\n");
406
407 // For each interesting use I of PN, find an Instruction BEUser that
408 // performs the same operation as I on BEInst and whose other operands,
409 // if any, can also be rematerialized in OtherBB. We stop when we find the
410 // first such Instruction BEUser. This is because once BEUser is
411 // rematerialized in OtherBB, we may find more such "fixup" opportunities
412 // in this block. So, we'll start over again.
413 for (Instruction *I : PNUsers) {
414 for (Use &U : BEInst->uses()) {
415 Instruction *BEUser = cast<Instruction>(U.getUser());
416
417 if (BEUser->getParent() != BB)
418 continue;
419 if (!isEquivalentOperation(I, BEUser))
420 continue;
421
422 int NumOperands = I->getNumOperands();
423
424 // Take operands of each PNUser one by one and try to find DepChain
425 // with every operand of the BEUser. If any of the operands of BEUser
426 // has DepChain with current operand of the PNUser, break the matcher
427 // loop. Keep doing this for Every PNUser operand. If PNUser operand
428 // does not have DepChain with any of the BEUser operand, break the
429 // outer matcher loop, mark the BEUser as null and reset the ReuseCandidate.
430 // This ensures that DepChain exist for all the PNUser operand with
431 // BEUser operand. This also ensures that DepChains are independent of
432 // the positions in PNUser and BEUser.
433 std::map<Instruction *, DepChain *> DepChains;
434 CallInst *C1 = dyn_cast<CallInst>(I);
435 if ((I && I->isCommutative()) || (C1 && isCallInstCommutative(C1))) {
436 bool Found = false;
437 for (int OpNo = 0; OpNo < NumOperands; ++OpNo) {
438 Value *Op = I->getOperand(OpNo);
439 Instruction *OpInst = dyn_cast<Instruction>(Op);
440 Found = false;
441 for (int T = 0; T < NumOperands; ++T) {
442 Value *BEOp = BEUser->getOperand(T);
443 Instruction *BEOpInst = dyn_cast<Instruction>(BEOp);
444 if (!OpInst && !BEOpInst) {
445 if (Op == BEOp) {
446 Found = true;
447 break;
448 }
449 }
450
451 if ((OpInst && !BEOpInst) || (!OpInst && BEOpInst))
452 continue;
453
454 DepChain *D = getDepChainBtwn(OpInst, BEOpInst, Iters);
455
456 if (D) {
457 Found = true;
458 DepChains[OpInst] = D;
459 break;
460 }
461 }
462 if (!Found) {
463 BEUser = nullptr;
464 break;
465 }
466 }
467 } else {
468
469 for (int OpNo = 0; OpNo < NumOperands; ++OpNo) {
470 Value *Op = I->getOperand(OpNo);
471 Value *BEOp = BEUser->getOperand(OpNo);
472
473 Instruction *OpInst = dyn_cast<Instruction>(Op);
474 if (!OpInst) {
475 if (Op == BEOp)
476 continue;
477 // Do not allow reuse to occur when the operands may be different
478 // values.
479 BEUser = nullptr;
480 break;
481 }
482
483 Instruction *BEOpInst = dyn_cast<Instruction>(BEOp);
484 DepChain *D = getDepChainBtwn(OpInst, BEOpInst, Iters);
485
486 if (D) {
487 DepChains[OpInst] = D;
488 } else {
489 BEUser = nullptr;
490 break;
491 }
492 }
493 }
494 if (BEUser) {
495 LLVM_DEBUG(dbgs() << "Found Value for reuse.\n");
496 ReuseCandidate.Inst2Replace = I;
497 ReuseCandidate.BackedgeInst = BEUser;
498 ReuseCandidate.DepChains = DepChains;
499 ReuseCandidate.Iterations = Iters;
500 return;
501 }
502 ReuseCandidate.reset();
503 }
504 }
505 }
506 ReuseCandidate.reset();
507}
508
509Value *HexagonVectorLoopCarriedReuse::findValueInBlock(Value *Op,
510 BasicBlock *BB) {
511 PHINode *PN = dyn_cast<PHINode>(Op);
512 assert(PN);
513 Value *ValueInBlock = PN->getIncomingValueForBlock(BB);
514 return ValueInBlock;
515}
516
517void HexagonVectorLoopCarriedReuse::reuseValue() {
518 LLVM_DEBUG(dbgs() << ReuseCandidate);
519 Instruction *Inst2Replace = ReuseCandidate.Inst2Replace;
520 Instruction *BEInst = ReuseCandidate.BackedgeInst;
521 int NumOperands = Inst2Replace->getNumOperands();
522 std::map<Instruction *, DepChain *> &DepChains = ReuseCandidate.DepChains;
523 int Iterations = ReuseCandidate.Iterations;
524 BasicBlock *LoopPH = CurLoop->getLoopPreheader();
525 assert(!DepChains.empty() && "No DepChains");
526 LLVM_DEBUG(dbgs() << "reuseValue is making the following changes\n");
527
528 SmallVector<Instruction *, 4> InstsInPreheader;
529 for (int i = 0; i < Iterations; ++i) {
530 Instruction *InstInPreheader = Inst2Replace->clone();
532 for (int j = 0; j < NumOperands; ++j) {
533 Instruction *I = dyn_cast<Instruction>(Inst2Replace->getOperand(j));
534 if (!I)
535 continue;
536 // Get the DepChain corresponding to this operand.
537 DepChain &D = *DepChains[I];
538 // Get the PHI for the iteration number and find
539 // the incoming value from the Loop Preheader for
540 // that PHI.
541 Value *ValInPreheader = findValueInBlock(D[i], LoopPH);
542 InstInPreheader->setOperand(j, ValInPreheader);
543 }
544 InstsInPreheader.push_back(InstInPreheader);
545 InstInPreheader->setName(Inst2Replace->getName() + ".hexagon.vlcr");
546 InstInPreheader->insertBefore(LoopPH->getTerminator());
547 LLVM_DEBUG(dbgs() << "Added " << *InstInPreheader << " to "
548 << LoopPH->getName() << "\n");
549 }
550 BasicBlock *BB = BEInst->getParent();
551 IRBuilder<> IRB(BB);
552 IRB.SetInsertPoint(BB, BB->getFirstNonPHIIt());
553 Value *BEVal = BEInst;
554 PHINode *NewPhi;
555 for (int i = Iterations-1; i >=0 ; --i) {
556 Instruction *InstInPreheader = InstsInPreheader[i];
557 NewPhi = IRB.CreatePHI(InstInPreheader->getType(), 2);
558 NewPhi->addIncoming(InstInPreheader, LoopPH);
559 NewPhi->addIncoming(BEVal, BB);
560 LLVM_DEBUG(dbgs() << "Adding " << *NewPhi << " to " << BB->getName()
561 << "\n");
562 BEVal = NewPhi;
563 }
564 // We are in LCSSA form. So, a value defined inside the Loop is used only
565 // inside the loop. So, the following is safe.
566 Inst2Replace->replaceAllUsesWith(NewPhi);
567 ReplacedInsts.insert(Inst2Replace);
568 ++HexagonNumVectorLoopCarriedReuse;
569}
570
571bool HexagonVectorLoopCarriedReuse::doVLCR() {
572 assert(CurLoop->getSubLoops().empty() &&
573 "Can do VLCR on the innermost loop only");
574 assert((CurLoop->getNumBlocks() == 1) &&
575 "Can do VLCR only on single block loops");
576
577 bool Changed = false;
578 bool Continue;
579
580 LLVM_DEBUG(dbgs() << "Working on Loop: " << *CurLoop->getHeader() << "\n");
581 do {
582 // Reset datastructures.
583 Dependences.clear();
584 Continue = false;
585
586 findLoopCarriedDeps();
587 findValueToReuse();
588 if (ReuseCandidate.isDefined()) {
589 reuseValue();
590 Changed = true;
591 Continue = true;
592 }
593 llvm::for_each(Dependences, std::default_delete<DepChain>());
594 } while (Continue);
595 return Changed;
596}
597
598void HexagonVectorLoopCarriedReuse::findDepChainFromPHI(Instruction *I,
599 DepChain &D) {
600 PHINode *PN = dyn_cast<PHINode>(I);
601 if (!PN) {
602 D.push_back(I);
603 return;
604 } else {
605 auto NumIncomingValues = PN->getNumIncomingValues();
606 if (NumIncomingValues != 2) {
607 D.clear();
608 return;
609 }
610
611 BasicBlock *BB = PN->getParent();
612 if (BB != CurLoop->getHeader()) {
613 D.clear();
614 return;
615 }
616
617 Value *BEVal = PN->getIncomingValueForBlock(BB);
618 Instruction *BEInst = dyn_cast<Instruction>(BEVal);
619 // This is a single block loop with a preheader, so at least
620 // one value should come over the backedge.
621 assert(BEInst && "There should be a value over the backedge");
622
623 Value *PreHdrVal =
624 PN->getIncomingValueForBlock(CurLoop->getLoopPreheader());
625 if(!PreHdrVal || !isa<Instruction>(PreHdrVal)) {
626 D.clear();
627 return;
628 }
629 D.push_back(PN);
630 findDepChainFromPHI(BEInst, D);
631 }
632}
633
634DepChain *HexagonVectorLoopCarriedReuse::getDepChainBtwn(Instruction *I1,
635 Instruction *I2,
636 int Iters) {
637 for (auto *D : Dependences) {
638 if (D->front() == I1 && D->back() == I2 && D->iterations() == Iters)
639 return D;
640 }
641 return nullptr;
642}
643
644void HexagonVectorLoopCarriedReuse::findLoopCarriedDeps() {
645 BasicBlock *BB = CurLoop->getHeader();
646 for (auto I = BB->begin(), E = BB->end(); I != E && isa<PHINode>(I); ++I) {
647 auto *PN = cast<PHINode>(I);
648 if (!isa<VectorType>(PN->getType()))
649 continue;
650
651 DepChain *D = new DepChain();
652 findDepChainFromPHI(PN, *D);
653 if (D->size() != 0)
654 Dependences.insert(D);
655 else
656 delete D;
657 }
658 LLVM_DEBUG(dbgs() << "Found " << Dependences.size() << " dependences\n");
659 LLVM_DEBUG(for (const DepChain *D : Dependences) dbgs() << *D << "\n";);
660}
661
663 return new HexagonVectorLoopCarriedReuseLegacyPass();
664}
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:282
#define LLVM_DEBUG(...)
Definition: Debug.h:106
std::optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1313
static cl::opt< int > HexagonVLCRIterationLim("hexagon-vlcr-iteration-lim", cl::Hidden, cl::desc("Maximum distance of loop carried dependences that are handled"), cl::init(2))
hexagon Hexagon specific predictive commoning for HVX vectors
This defines the Use class.
#define I(x, y, z)
Definition: MD5.cpp:58
uint64_t IntrinsicInst * II
LoopAnalysisManager LAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:55
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:57
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file implements a set that has insertion order iteration characteristics.
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)
Definition: Statistic.h:166
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
Represent the analysis usage information of a pass.
AnalysisUsage & addRequiredID(const void *ID)
Definition: Pass.cpp:270
AnalysisUsage & addPreservedID(const void *ID)
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:256
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
iterator end()
Definition: BasicBlock.h:461
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:448
InstListType::const_iterator getFirstNonPHIIt() const
Iterator returning form of getFirstNonPHI.
Definition: BasicBlock.cpp:374
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...
Definition: BasicBlock.h:239
Represents analyses that only rely on functions' control flow.
Definition: Analysis.h:72
This class represents a function call, abstracting a target machine's calling convention.
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Definition: Constants.h:163
This class represents an Operation in the Expression.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2697
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
Definition: Instruction.cpp:97
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:48
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
virtual bool runOnLoop(Loop *L, LPPassManager &LPM)=0
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:39
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
unsigned getNumIncomingValues() const
Return the number of incoming edges.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:37
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:94
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:98
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
void preserveSet()
Mark an analysis set as preserved.
Definition: Analysis.h:146
A vector that has set insertion semantics.
Definition: SetVector.h:57
size_t size() const
Definition: SmallVector.h:78
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
bool isVectorTy() const
True if this is an instance of VectorType.
Definition: Type.h:270
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
void setOperand(unsigned i, Value *Val)
Definition: User.h:233
Value * getOperand(unsigned i) const
Definition: User.h:228
unsigned getNumOperands() const
Definition: User.h:250
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:377
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:534
iterator_range< use_iterator > uses()
Definition: Value.h:376
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
const ParentTy * getParent() const
Definition: ilist_node.h:32
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1732
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.
Definition: STLExtras.h:1697
char & LoopSimplifyID
void initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PassRegistry &)
char & LCSSAID
Definition: LCSSA.cpp:542
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:303
Pass * createHexagonVectorLoopCarriedReuseLegacyPass()
@ Continue
Definition: DWP.h:21
Hexagon Vector Loop Carried Reuse Pass.
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...