LLVM: lib/Analysis/Delinearization.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

30

31using namespace llvm;

32

33#define DL_NAME "delinearize"

34#define DEBUG_TYPE DL_NAME

35

37 "delinearize-use-fixed-size-array-heuristic", cl::init(false), cl::Hidden,

38 cl::desc("When printing analysis, use the heuristic for fixed-size arrays "

39 "if the default delinearizetion fails."));

40

41

46 return false;

47 });

48}

49

50namespace {

51

52

53struct SCEVCollectStrides {

54 ScalarEvolution &SE;

55 SmallVectorImpl<const SCEV *> &Strides;

56

57 SCEVCollectStrides(ScalarEvolution &SE, SmallVectorImpl<const SCEV *> &S)

58 : SE(SE), Strides(S) {}

59

60 bool follow(const SCEV *S) {

62 Strides.push_back(AR->getStepRecurrence(SE));

63 return true;

64 }

65

66 bool isDone() const { return false; }

67};

68

69

70struct SCEVCollectTerms {

71 SmallVectorImpl<const SCEV *> &Terms;

72

73 SCEVCollectTerms(SmallVectorImpl<const SCEV *> &T) : Terms(T) {}

74

75 bool follow(const SCEV *S) {

79 Terms.push_back(S);

80

81

82 return false;

83 }

84

85

86 return true;

87 }

88

89 bool isDone() const { return false; }

90};

91

92

93struct SCEVHasAddRec {

94 bool &ContainsAddRec;

95

96 SCEVHasAddRec(bool &ContainsAddRec) : ContainsAddRec(ContainsAddRec) {

97 ContainsAddRec = false;

98 }

99

100 bool follow(const SCEV *S) {

102 ContainsAddRec = true;

103

104

105 return false;

106 }

107

108

109 return true;

110 }

111

112 bool isDone() const { return false; }

113};

114

115

116

117

118

119

120

121

122

123

124

125

126

127struct SCEVCollectAddRecMultiplies {

128 SmallVectorImpl<const SCEV *> &Terms;

129 ScalarEvolution &SE;

130

131 SCEVCollectAddRecMultiplies(SmallVectorImpl<const SCEV *> &T,

132 ScalarEvolution &SE)

133 : Terms(T), SE(SE) {}

134

135 bool follow(const SCEV *S) {

137 bool HasAddRec = false;

139 for (const SCEV *Op : Mul->operands()) {

144 HasAddRec = true;

145 } else {

146 bool ContainsAddRec = false;

147 SCEVHasAddRec ContiansAddRec(ContainsAddRec);

149 HasAddRec |= ContainsAddRec;

150 }

151 }

152 if (Operands.size() == 0)

153 return true;

154

155 if (!HasAddRec)

156 return false;

157

158 Terms.push_back(SE.getMulExpr(Operands));

159

160 return false;

161 }

162

163

164 return true;

165 }

166

167 bool isDone() const { return false; }

168};

169

170}

171

172

173

174

175

179 SCEVCollectStrides StrideCollector(SE, Strides);

180 visitAll(Expr, StrideCollector);

181

183 dbgs() << "Strides:\n";

184 for (const SCEV *S : Strides)

186 });

187

188 for (const SCEV *S : Strides) {

189 SCEVCollectTerms TermCollector(Terms);

191 }

192

194 dbgs() << "Terms:\n";

195 for (const SCEV *T : Terms)

197 });

198

199 SCEVCollectAddRecMultiplies MulCollector(Terms, SE);

200 visitAll(Expr, MulCollector);

201}

202

207 const SCEV *Step = Terms[Last];

208

209

210 if (Last == 0) {

213 for (const SCEV *Op : M->operands())

216

218 }

219

220 Sizes.push_back(Step);

221 return true;

222 }

223

224 for (const SCEV *&Term : Terms) {

225

226 const SCEV *Q, *R;

228

229

230 if (!R->isZero())

231 return false;

232

233 Term = Q;

234 }

235

236

238

239 if (Terms.size() > 0)

241 return false;

242

243 Sizes.push_back(Step);

244 return true;

245}

246

247

249 for (const SCEV *T : Terms)

251 return true;

252

253 return false;

254}

255

256

259 return Expr->getNumOperands();

260 return 1;

261}

262

265 return nullptr;

266

268 return T;

269

272 for (const SCEV *Op : M->operands())

275

277 }

278

279 return T;

280}

281

285 const SCEV *ElementSize) {

286 if (Terms.size() < 1 || !ElementSize)

287 return;

288

289

290

292 return;

293

295 dbgs() << "Terms:\n";

296 for (const SCEV *T : Terms)

298 });

299

300

303

304

307 });

308

309

310

311 for (const SCEV *&Term : Terms) {

312 const SCEV *Q, *R;

315 Term = Q;

316 }

317

319

320

321 for (const SCEV *T : Terms)

324

326 dbgs() << "Terms after sorting:\n";

327 for (const SCEV *T : NewTerms)

329 });

330

332 Sizes.clear();

333 return;

334 }

335

336

337 Sizes.push_back(ElementSize);

338

340 dbgs() << "Sizes:\n";

341 for (const SCEV *S : Sizes)

343 });

344}

345

349

350 if (Sizes.empty())

351 return;

352

354 if (!AR->isAffine())

355 return;

356

357

358 Subscripts.clear();

359

361 << "Memory Access Function: " << *Expr << "\n");

362

363 const SCEV *Res = Expr;

364 int Last = Sizes.size() - 1;

365

366 for (int i = Last; i >= 0; i--) {

368 const SCEV *Q, *R;

369

371

373 dbgs() << "Computing 'MemAccFn / Sizes[" << i << "]':\n";

374 dbgs() << " MemAccFn: " << *Res << "\n";

375 dbgs() << " Sizes[" << i << "]: " << *Size << "\n";

376 dbgs() << " Quotient (Leftover): " << *Q << "\n";

377 dbgs() << " Remainder (Subscript Access Function): " << *R << "\n";

378 });

379

380 Res = Q;

381

382

383

384 if (i == Last) {

385

386

387 if (!R->isZero()) {

388 Subscripts.clear();

389 Sizes.clear();

390 return;

391 }

392

393 continue;

394 }

395

396

398 }

399

400

401

403

404 std::reverse(Subscripts.begin(), Subscripts.end());

405

407 dbgs() << "Subscripts:\n";

408 for (const SCEV *S : Subscripts)

410 dbgs() << "\n";

411 });

412}

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

466 const SCEV *ElementSize) {

467

468 Subscripts.clear();

469 Sizes.clear();

470

471

474

475 if (Terms.empty())

476 return;

477

478

480

481 if (Sizes.empty())

482 return;

483

484

486}

487

490 return Const->getAPInt();

491 return std::nullopt;

492}

493

494

495

496

497

501

502

504 const uint64_t Mod = Const->getAPInt().urem(ElementSize);

505 return Mod == 0;

506 }

507

510 return false;

511

513 std::optional StepAPInt = tryIntoAPInt(Step);

514 if (!StepAPInt)

515 return false;

516

520 if (R != 0)

521 return false;

522

523

524 std::optional<uint64_t> StepVal = Q.tryZExtValue();

525 if (!StepVal)

526 return false;

527

530}

531

534 const SCEV *ElementSize) {

535 if (!ElementSize)

536 return false;

537

538 std::optional ElementSizeAPInt = tryIntoAPInt(ElementSize);

539 if (!ElementSizeAPInt || *ElementSizeAPInt == 0)

540 return false;

541

542 std::optional<uint64_t> ElementSizeConst = ElementSizeAPInt->tryZExtValue();

543

544

545 if (!ElementSizeConst)

546 return false;

547

549 Sizes.empty()) {

550 Sizes.clear();

551 return false;

552 }

553

554

555

556

557

558

559

560

561

562

563

564

565

566

567

568

569

570

571 llvm::sort(Sizes.rbegin(), Sizes.rend());

572 Sizes.erase(llvm::unique(Sizes), Sizes.end());

573

574

575

576 assert(Sizes.back() != 0 && "Unexpected zero size in Sizes.");

577 Sizes.back() = 1;

578

579 for (unsigned I = 0; I + 1 < Sizes.size(); I++) {

580 uint64_t PrevSize = Sizes[I + 1];

581 if (Sizes[I] % PrevSize) {

582 Sizes.clear();

583 return false;

584 }

585 Sizes[I] /= PrevSize;

586 }

587

588

589 Sizes.back() = *ElementSizeConst;

590 return true;

591}

592

593

594

595

596

597

598

599

600

601

602

603

604

605

606

607

608

609

610

611

612

613

614

615

616

617

618

619

620

621

622

623

624

625

626

627

628

629

630

631

632

633

634

635

636

637

638

639

640

641

642

643

647 const SCEV *ElementSize) {

648

649 Subscripts.clear();

650 Sizes.clear();

651

652

655 Sizes.clear();

656 return false;

657 }

658

659

662

663

665

666 return !Subscripts.empty();

667}

668

670 const Value *Ptr) {

671 bool Inbounds = false;

673 Inbounds = SrcGEP->isInBounds();

674 if (Inbounds) {

676 if (AddRec->isAffine()) {

677

678

681 return true;

682 }

683 }

684 }

685

687}

688

689

690

691

692

693

694

697

700 if (!SType || !SizeType)

701 return false;

702 Type *MaxType =

703 (SType->getBitWidth() >= SizeType->getBitWidth()) ? SType : SizeType;

706

707 auto CollectUpperBound = [&](const Loop *L, Type *T) -> const SCEV * {

711 }

712 return nullptr;

713 };

714

715 auto CheckAddRecBECount = [&]() {

718 return false;

719 const SCEV *BECount = CollectUpperBound(AddRec->getLoop(), MaxType);

720

722 return false;

728

729

730

731

733 return true;

734

735

736

738 return true;

739

740

741

743 return true;

744

745 return false;

746 };

747

748 if (CheckAddRecBECount())

749 return true;

750

751

754}

755

759 const Value *Ptr) {

760

761

762

763

764

765

766

768 if (!SE.willNotOverflow(Instruction::Add, true, A, B))

769 return nullptr;

771 };

772

774 if (!SE.willNotOverflow(Instruction::Mul, true, A, B))

775 return nullptr;

777 };

778

779

780 for (size_t I = 1; I < Sizes.size(); ++I) {

782 const SCEV *Subscript = Subscripts[I];

784 return false;

786 return false;

787 }

788

789

790

791

792

793

794

795

796

797

798

799

800

801

802

803

804

805

806

807

808

809

810

811

813 for (const SCEV *Size : Sizes) {

815 if (!Prod)

816 return false;

817 }

819 if (!Min)

820 return false;

821

822

823

825 if (!MaxPlusOne)

826 return false;

827 if (!SE.willNotOverflow(Instruction::Sub, true, MaxPlusOne,

829 return false;

830

831 return true;

832}

833

838 assert(Subscripts.empty() && Sizes.empty() &&

839 "Expected output lists to be empty on entry to this function.");

840 assert(GEP && "getIndexExpressionsFromGEP called with a null GEP");

842 Type *Ty = nullptr;

844 bool DroppedFirstDim = false;

845 for (unsigned i = 1; i < GEP->getNumOperands(); i++) {

847 if (i == 1) {

848 Ty = GEP->getSourceElementType();

850 if (Const->getValue()->isZero()) {

851 DroppedFirstDim = true;

852 continue;

853 }

855 continue;

856 }

857

859 if (!ArrayTy) {

860 LLVM_DEBUG(dbgs() << "GEP delinearize failed: " << *Ty

861 << " is not an array type.\n");

862 Subscripts.clear();

863 Sizes.clear();

864 return false;

865 }

866

868 if (!(DroppedFirstDim && i == 2))

869 Sizes.push_back(SE.getConstant(IndexTy, ArrayTy->getNumElements()));

870

871 Ty = ArrayTy->getElementType();

872 }

874 dbgs() << "Subscripts:\n";

875 for (const SCEV *S : Subscripts)

876 dbgs() << *S << "\n";

877 dbgs() << "\n";

878 });

879

880 return !Subscripts.empty();

881}

882

883namespace {

884

887 O << "Printing analysis 'Delinearization' for function '" << F->getName()

888 << "':";

890

892 continue;

893

896

897

898 if (!L)

899 continue;

900

902

905

906 if (!BasePointer)

907 break;

908 AccessFn = SE->getMinusSCEV(AccessFn, BasePointer);

909

910 O << "\n";

911 O << "Inst:" << Inst << "\n";

912 O << "AccessFunction: " << *AccessFn << "\n";

913

915

916 auto IsDelinearizationFailed = [&]() {

917 return Subscripts.size() == 0 || Sizes.size() == 0 ||

918 Subscripts.size() != Sizes.size();

919 };

920

923 Subscripts.clear();

927 }

928

929 if (IsDelinearizationFailed()) {

930 O << "failed to delinearize\n";

931 continue;

932 }

933

934 O << "Base offset: " << *BasePointer << "\n";

935 O << "ArrayDecl[UnknownSize]";

936 int Size = Subscripts.size();

937 for (int i = 0; i < Size - 1; i++)

938 O << "[" << *Sizes[i] << "]";

939 O << " with elements of " << *Sizes[Size - 1] << " bytes.\n";

940

941 O << "ArrayRef";

942 for (int i = 0; i < Size; i++)

943 O << "[" << *Subscripts[i] << "]";

944 O << "\n";

945

948 O << "Delinearization validation: " << (IsValid ? "Succeeded" : "Failed")

949 << "\n";

950 }

951}

952

953}

954

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

Expand Atomic instructions

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

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

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

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

static const SCEV * removeConstantFactors(ScalarEvolution &SE, const SCEV *T)

Definition Delinearization.cpp:263

static bool collectConstantAbsSteps(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< uint64_t > &Steps, uint64_t ElementSize)

Collects the absolute values of constant steps for all induction variables.

Definition Delinearization.cpp:498

static bool isKnownLessThan(ScalarEvolution *SE, const SCEV *S, const SCEV *Size)

Compare to see if S is less than Size, using.

Definition Delinearization.cpp:695

static cl::opt< bool > UseFixedSizeArrayHeuristic("delinearize-use-fixed-size-array-heuristic", cl::init(false), cl::Hidden, cl::desc("When printing analysis, use the heuristic for fixed-size arrays " "if the default delinearizetion fails."))

static bool findArrayDimensionsRec(ScalarEvolution &SE, SmallVectorImpl< const SCEV * > &Terms, SmallVectorImpl< const SCEV * > &Sizes)

Definition Delinearization.cpp:203

static bool containsUndefs(const SCEV *S)

Definition Delinearization.cpp:42

static std::optional< APInt > tryIntoAPInt(const SCEV *S)

Definition Delinearization.cpp:488

static bool containsParameters(SmallVectorImpl< const SCEV * > &Terms)

Definition Delinearization.cpp:248

static int numberOfTerms(const SCEV *S)

Definition Delinearization.cpp:257

This header defines various interfaces for pass management in LLVM.

if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod

static SymbolRef::Type getType(const Symbol *Sym)

Class for arbitrary precision integers.

std::optional< uint64_t > tryZExtValue() const

Get zero extended value if possible.

static LLVM_ABI void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)

Dual division/remainder interface.

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

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

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

LLVM Basic Block Representation.

const Function * getParent() const

Return the enclosing method, or null if none.

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

Analysis pass that exposes the LoopInfo for a function.

LoopT * getLoopFor(const BlockT *BB) const

Return the inner most loop that BB lives in.

Represents a single loop in the control flow graph.

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.

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

const SCEV * getStart() const

LLVM_ABI const SCEV * evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const

Return the value of this chain of recurrences at the specified iteration number.

const SCEV * getStepRecurrence(ScalarEvolution &SE) const

Constructs and returns the recurrence indicating how much this expression steps by.

bool isAffine() const

Return true if this represents an expression A + B*x where A and B are loop invariant values.

const Loop * getLoop() const

This node represents multiplication of some number of SCEVs.

bool hasNoSignedWrap() const

This means that we are dealing with an entirely unknown SCEV value, and only represent it as its LLVM...

This class represents an analyzed expression in the program.

LLVM_ABI bool isZero() const

Return true if the expression is a constant zero.

LLVM_ABI Type * getType() const

Return the LLVM type of this SCEV expression.

Analysis pass that exposes the ScalarEvolution for a function.

The main scalar evolution driver.

LLVM_ABI bool isKnownNonNegative(const SCEV *S)

Test if the given expression is known to be non-negative.

LLVM_ABI bool isKnownNonPositive(const SCEV *S)

Test if the given expression is known to be non-positive.

LLVM_ABI bool isKnownNegative(const SCEV *S)

Test if the given expression is known to be negative.

LLVM_ABI const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)

Return a SCEV expression for the specified value at the specified scope in the program.

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

LLVM_ABI bool willNotOverflow(Instruction::BinaryOps BinOp, bool Signed, const SCEV *LHS, const SCEV *RHS, const Instruction *CtxI=nullptr)

Is operation BinOp between LHS and RHS provably does not have a signed/unsigned overflow (Signed)?

LLVM_ABI const SCEV * getConstant(ConstantInt *V)

LLVM_ABI const SCEV * getSCEV(Value *V)

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

const SCEV * getOne(Type *Ty)

Return a SCEV for the constant 1 of a specific type.

LLVM_ABI Type * getEffectiveSCEVType(Type *Ty) const

Return a type with the same bitwidth as the given type and which represents how SCEV will treat the g...

LLVM_ABI const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)

Return LHS-RHS.

LLVM_ABI bool hasLoopInvariantBackedgeTakenCount(const Loop *L)

Return true if the specified loop has an analyzable loop-invariant backedge-taken count.

LLVM_ABI const SCEV * getPointerBase(const SCEV *V)

Transitively follow the chain of pointer-type operands until reaching a SCEV that does not have a sin...

LLVM_ABI const SCEV * getMulExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)

Get a canonical multiply expression, or something simpler if possible.

LLVM_ABI const SCEV * getElementSize(Instruction *Inst)

Return the size of an element read or written by Inst.

LLVM_ABI const SCEV * getTruncateOrZeroExtend(const SCEV *V, Type *Ty, unsigned Depth=0)

Return a SCEV corresponding to a conversion of the input value to the specified type.

LLVM_ABI const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)

Get a canonical add expression, or something simpler if possible.

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

iterator erase(const_iterator CI)

void push_back(const T &Elt)

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

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM Value Representation.

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

raw_ostream & indent(unsigned NumSpaces)

indent - Insert 'NumSpaces' spaces.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

void visitAll(const SCEV *Root, SV &Visitor)

Use SCEVTraversal to visit all nodes in the given expression tree.

std::enable_if_t< std::is_signed_v< T >, T > MulOverflow(T X, T Y, T &Result)

Multiply two signed integers, computing the two's complement truncated result, returning true if an o...

void collectParametricTerms(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Terms)

Collect parametric terms occurring in step expressions (first step of delinearization).

Definition Delinearization.cpp:176

void findArrayDimensions(ScalarEvolution &SE, SmallVectorImpl< const SCEV * > &Terms, SmallVectorImpl< const SCEV * > &Sizes, const SCEV *ElementSize)

Compute the array dimensions Sizes from the set of Terms extracted from the memory access function of...

Definition Delinearization.cpp:282

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

const Value * getLoadStorePointerOperand(const Value *V)

A helper function that returns the pointer operand of a load or store instruction.

auto unique(Range &&R, Predicate P)

const Value * getPointerOperand(const Value *V)

A helper function that returns the pointer operand of a load, store or GEP instruction.

void computeAccessFunctions(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes)

Return in Subscripts the access functions for each dimension in Sizes (third step of delinearization)...

Definition Delinearization.cpp:346

bool delinearizeFixedSizeArray(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes, const SCEV *ElementSize)

Split this SCEVAddRecExpr into two vectors of SCEVs representing the subscripts and sizes of an acces...

Definition Delinearization.cpp:644

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

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

class LLVM_GSL_OWNER SmallVector

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

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

@ Mul

Product of integers.

DWARFExpression::Operation Op

void delinearize(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes, const SCEV *ElementSize)

Split this SCEVAddRecExpr into two vectors of SCEVs representing the subscripts and sizes of an array...

Definition Delinearization.cpp:463

bool findFixedSizeArrayDimensions(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< uint64_t > &Sizes, const SCEV *ElementSize)

Compute the dimensions of fixed size array from \Expr and save the results in Sizes.

Definition Delinearization.cpp:532

void erase_if(Container &C, UnaryPredicate P)

Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...

std::enable_if_t< std::is_signed_v< T >, T > AddOverflow(T X, T Y, T &Result)

Add two signed integers, computing the two's complement truncated result, returning true if overflow ...

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

void array_pod_sort(IteratorTy Start, IteratorTy End)

array_pod_sort - This sorts an array with the specified start and end extent.

bool validateDelinearizationResult(ScalarEvolution &SE, ArrayRef< const SCEV * > Sizes, ArrayRef< const SCEV * > Subscripts, const Value *Ptr=nullptr)

Check that each subscript in Subscripts is within the corresponding size in Sizes.

Definition Delinearization.cpp:756

LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)

Returns true if the give value is known to be non-negative.

bool getIndexExpressionsFromGEP(ScalarEvolution &SE, const GetElementPtrInst *GEP, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes)

Gathers the individual index expressions from a GEP instruction.

Definition Delinearization.cpp:834

bool SCEVExprContains(const SCEV *Root, PredTy Pred)

Return true if any node in Root satisfies the predicate Pred.

PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)

Definition Delinearization.cpp:957

DelinearizationPrinterPass(raw_ostream &OS)

Definition Delinearization.cpp:955

static void divide(ScalarEvolution &SE, const SCEV *Numerator, const SCEV *Denominator, const SCEV **Quotient, const SCEV **Remainder)

Computes the Quotient and Remainder of the division of Numerator by Denominator.