1 2 #include "polly/Support/SCEVValidator.h" 3 #include "polly/ScopInfo.h" 4 #include "llvm/Analysis/RegionInfo.h" 5 #include "llvm/Analysis/ScalarEvolution.h" 6 #include "llvm/Analysis/ScalarEvolutionExpressions.h" 7 #include "llvm/Support/Debug.h" 8 #include <vector> 9 10 using namespace llvm; 11 using namespace polly; 12 13 #define DEBUG_TYPE "polly-scev-validator" 14 15 namespace SCEVType { 16 /// @brief The type of a SCEV 17 /// 18 /// To check for the validity of a SCEV we assign to each SCEV a type. The 19 /// possible types are INT, PARAM, IV and INVALID. The order of the types is 20 /// important. The subexpressions of SCEV with a type X can only have a type 21 /// that is smaller or equal than X. 22 enum TYPE { 23 // An integer value. 24 INT, 25 26 // An expression that is constant during the execution of the Scop, 27 // but that may depend on parameters unknown at compile time. 28 PARAM, 29 30 // An expression that may change during the execution of the SCoP. 31 IV, 32 33 // An invalid expression. 34 INVALID 35 }; 36 } 37 38 /// @brief The result the validator returns for a SCEV expression. 39 class ValidatorResult { 40 /// @brief The type of the expression 41 SCEVType::TYPE Type; 42 43 /// @brief The set of Parameters in the expression. 44 std::vector<const SCEV *> Parameters; 45 46 public: 47 /// @brief The copy constructor 48 ValidatorResult(const ValidatorResult &Source) { 49 Type = Source.Type; 50 Parameters = Source.Parameters; 51 } 52 53 /// @brief Construct a result with a certain type and no parameters. 54 ValidatorResult(SCEVType::TYPE Type) : Type(Type) { 55 assert(Type != SCEVType::PARAM && "Did you forget to pass the parameter"); 56 } 57 58 /// @brief Construct a result with a certain type and a single parameter. 59 ValidatorResult(SCEVType::TYPE Type, const SCEV *Expr) : Type(Type) { 60 Parameters.push_back(Expr); 61 } 62 63 /// @brief Get the type of the ValidatorResult. 64 SCEVType::TYPE getType() { return Type; } 65 66 /// @brief Is the analyzed SCEV constant during the execution of the SCoP. 67 bool isConstant() { return Type == SCEVType::INT || Type == SCEVType::PARAM; } 68 69 /// @brief Is the analyzed SCEV valid. 70 bool isValid() { return Type != SCEVType::INVALID; } 71 72 /// @brief Is the analyzed SCEV of Type IV. 73 bool isIV() { return Type == SCEVType::IV; } 74 75 /// @brief Is the analyzed SCEV of Type INT. 76 bool isINT() { return Type == SCEVType::INT; } 77 78 /// @brief Is the analyzed SCEV of Type PARAM. 79 bool isPARAM() { return Type == SCEVType::PARAM; } 80 81 /// @brief Get the parameters of this validator result. 82 std::vector<const SCEV *> getParameters() { return Parameters; } 83 84 /// @brief Add the parameters of Source to this result. 85 void addParamsFrom(const ValidatorResult &Source) { 86 Parameters.insert(Parameters.end(), Source.Parameters.begin(), 87 Source.Parameters.end()); 88 } 89 90 /// @brief Merge a result. 91 /// 92 /// This means to merge the parameters and to set the Type to the most 93 /// specific Type that matches both. 94 void merge(const ValidatorResult &ToMerge) { 95 Type = std::max(Type, ToMerge.Type); 96 addParamsFrom(ToMerge); 97 } 98 99 void print(raw_ostream &OS) { 100 switch (Type) { 101 case SCEVType::INT: 102 OS << "SCEVType::INT"; 103 break; 104 case SCEVType::PARAM: 105 OS << "SCEVType::PARAM"; 106 break; 107 case SCEVType::IV: 108 OS << "SCEVType::IV"; 109 break; 110 case SCEVType::INVALID: 111 OS << "SCEVType::INVALID"; 112 break; 113 } 114 } 115 }; 116 117 raw_ostream &operator<<(raw_ostream &OS, class ValidatorResult &VR) { 118 VR.print(OS); 119 return OS; 120 } 121 122 /// Check if a SCEV is valid in a SCoP. 123 struct SCEVValidator 124 : public SCEVVisitor<SCEVValidator, class ValidatorResult> { 125 private: 126 const Region *R; 127 Loop *Scope; 128 ScalarEvolution &SE; 129 const Value *BaseAddress; 130 InvariantLoadsSetTy *ILS; 131 132 public: 133 SCEVValidator(const Region *R, Loop *Scope, ScalarEvolution &SE, 134 const Value *BaseAddress, InvariantLoadsSetTy *ILS) 135 : R(R), Scope(Scope), SE(SE), BaseAddress(BaseAddress), ILS(ILS) {} 136 137 class ValidatorResult visitConstant(const SCEVConstant *Constant) { 138 return ValidatorResult(SCEVType::INT); 139 } 140 141 class ValidatorResult visitTruncateExpr(const SCEVTruncateExpr *Expr) { 142 ValidatorResult Op = visit(Expr->getOperand()); 143 144 switch (Op.getType()) { 145 case SCEVType::INT: 146 case SCEVType::PARAM: 147 // We currently do not represent a truncate expression as an affine 148 // expression. If it is constant during Scop execution, we treat it as a 149 // parameter. 150 return ValidatorResult(SCEVType::PARAM, Expr); 151 case SCEVType::IV: 152 DEBUG(dbgs() << "INVALID: Truncation of SCEVType::IV expression"); 153 return ValidatorResult(SCEVType::INVALID); 154 case SCEVType::INVALID: 155 return Op; 156 } 157 158 llvm_unreachable("Unknown SCEVType"); 159 } 160 161 class ValidatorResult visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) { 162 ValidatorResult Op = visit(Expr->getOperand()); 163 164 switch (Op.getType()) { 165 case SCEVType::INT: 166 case SCEVType::PARAM: 167 // We currently do not represent a truncate expression as an affine 168 // expression. If it is constant during Scop execution, we treat it as a 169 // parameter. 170 return ValidatorResult(SCEVType::PARAM, Expr); 171 case SCEVType::IV: 172 DEBUG(dbgs() << "INVALID: ZeroExtend of SCEVType::IV expression"); 173 return ValidatorResult(SCEVType::INVALID); 174 case SCEVType::INVALID: 175 return Op; 176 } 177 178 llvm_unreachable("Unknown SCEVType"); 179 } 180 181 class ValidatorResult visitSignExtendExpr(const SCEVSignExtendExpr *Expr) { 182 // We currently allow only signed SCEV expressions. In the case of a 183 // signed value, a sign extend is a noop. 184 // 185 // TODO: Reconsider this when we add support for unsigned values. 186 return visit(Expr->getOperand()); 187 } 188 189 class ValidatorResult visitAddExpr(const SCEVAddExpr *Expr) { 190 ValidatorResult Return(SCEVType::INT); 191 192 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) { 193 ValidatorResult Op = visit(Expr->getOperand(i)); 194 Return.merge(Op); 195 196 // Early exit. 197 if (!Return.isValid()) 198 break; 199 } 200 201 // TODO: Check for NSW and NUW. 202 return Return; 203 } 204 205 class ValidatorResult visitMulExpr(const SCEVMulExpr *Expr) { 206 ValidatorResult Return(SCEVType::INT); 207 208 bool HasMultipleParams = false; 209 210 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) { 211 ValidatorResult Op = visit(Expr->getOperand(i)); 212 213 if (Op.isINT()) 214 continue; 215 216 if (Op.isPARAM() && Return.isPARAM()) { 217 HasMultipleParams = true; 218 continue; 219 } 220 221 if ((Op.isIV() || Op.isPARAM()) && !Return.isINT()) { 222 DEBUG(dbgs() << "INVALID: More than one non-int operand in MulExpr\n" 223 << "\tExpr: " << *Expr << "\n" 224 << "\tPrevious expression type: " << Return << "\n" 225 << "\tNext operand (" << Op 226 << "): " << *Expr->getOperand(i) << "\n"); 227 228 return ValidatorResult(SCEVType::INVALID); 229 } 230 231 Return.merge(Op); 232 } 233 234 if (HasMultipleParams && Return.isValid()) 235 return ValidatorResult(SCEVType::PARAM, Expr); 236 237 // TODO: Check for NSW and NUW. 238 return Return; 239 } 240 241 class ValidatorResult visitUDivExpr(const SCEVUDivExpr *Expr) { 242 ValidatorResult LHS = visit(Expr->getLHS()); 243 ValidatorResult RHS = visit(Expr->getRHS()); 244 245 // We currently do not represent an unsigned division as an affine 246 // expression. If the division is constant during Scop execution we treat it 247 // as a parameter, otherwise we bail out. 248 if (LHS.isConstant() && RHS.isConstant()) 249 return ValidatorResult(SCEVType::PARAM, Expr); 250 251 DEBUG(dbgs() << "INVALID: unsigned division of non-constant expressions"); 252 return ValidatorResult(SCEVType::INVALID); 253 } 254 255 class ValidatorResult visitAddRecExpr(const SCEVAddRecExpr *Expr) { 256 if (!Expr->isAffine()) { 257 DEBUG(dbgs() << "INVALID: AddRec is not affine"); 258 return ValidatorResult(SCEVType::INVALID); 259 } 260 261 ValidatorResult Start = visit(Expr->getStart()); 262 ValidatorResult Recurrence = visit(Expr->getStepRecurrence(SE)); 263 264 if (!Start.isValid()) 265 return Start; 266 267 if (!Recurrence.isValid()) 268 return Recurrence; 269 270 auto *L = Expr->getLoop(); 271 if (R->contains(L) && (!Scope || !L->contains(Scope))) { 272 DEBUG(dbgs() << "INVALID: AddRec out of a loop whose exit value is not " 273 "synthesizable"); 274 return ValidatorResult(SCEVType::INVALID); 275 } 276 277 if (R->contains(L)) { 278 if (Recurrence.isINT()) { 279 ValidatorResult Result(SCEVType::IV); 280 Result.addParamsFrom(Start); 281 return Result; 282 } 283 284 DEBUG(dbgs() << "INVALID: AddRec within scop has non-int" 285 "recurrence part"); 286 return ValidatorResult(SCEVType::INVALID); 287 } 288 289 assert(Start.isConstant() && Recurrence.isConstant() && 290 "Expected 'Start' and 'Recurrence' to be constant"); 291 292 // Directly generate ValidatorResult for Expr if 'start' is zero. 293 if (Expr->getStart()->isZero()) 294 return ValidatorResult(SCEVType::PARAM, Expr); 295 296 // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}' 297 // if 'start' is not zero. 298 const SCEV *ZeroStartExpr = SE.getAddRecExpr( 299 SE.getConstant(Expr->getStart()->getType(), 0), 300 Expr->getStepRecurrence(SE), Expr->getLoop(), Expr->getNoWrapFlags()); 301 302 ValidatorResult ZeroStartResult = 303 ValidatorResult(SCEVType::PARAM, ZeroStartExpr); 304 ZeroStartResult.addParamsFrom(Start); 305 306 return ZeroStartResult; 307 } 308 309 class ValidatorResult visitSMaxExpr(const SCEVSMaxExpr *Expr) { 310 ValidatorResult Return(SCEVType::INT); 311 312 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) { 313 ValidatorResult Op = visit(Expr->getOperand(i)); 314 315 if (!Op.isValid()) 316 return Op; 317 318 Return.merge(Op); 319 } 320 321 return Return; 322 } 323 324 class ValidatorResult visitUMaxExpr(const SCEVUMaxExpr *Expr) { 325 // We do not support unsigned operations. If 'Expr' is constant during Scop 326 // execution we treat this as a parameter, otherwise we bail out. 327 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) { 328 ValidatorResult Op = visit(Expr->getOperand(i)); 329 330 if (!Op.isConstant()) { 331 DEBUG(dbgs() << "INVALID: UMaxExpr has a non-constant operand"); 332 return ValidatorResult(SCEVType::INVALID); 333 } 334 } 335 336 return ValidatorResult(SCEVType::PARAM, Expr); 337 } 338 339 ValidatorResult visitGenericInst(Instruction *I, const SCEV *S) { 340 if (R->contains(I)) { 341 DEBUG(dbgs() << "INVALID: UnknownExpr references an instruction " 342 "within the region\n"); 343 return ValidatorResult(SCEVType::INVALID); 344 } 345 346 return ValidatorResult(SCEVType::PARAM, S); 347 } 348 349 ValidatorResult visitLoadInstruction(Instruction *I, const SCEV *S) { 350 if (R->contains(I) && ILS) { 351 ILS->insert(cast<LoadInst>(I)); 352 return ValidatorResult(SCEVType::PARAM, S); 353 } 354 355 return visitGenericInst(I, S); 356 } 357 358 ValidatorResult visitSDivInstruction(Instruction *SDiv, const SCEV *S) { 359 assert(SDiv->getOpcode() == Instruction::SDiv && 360 "Assumed SDiv instruction!"); 361 362 auto *Divisor = SDiv->getOperand(1); 363 auto *CI = dyn_cast<ConstantInt>(Divisor); 364 if (!CI) 365 return visitGenericInst(SDiv, S); 366 367 auto *Dividend = SDiv->getOperand(0); 368 auto *DividendSCEV = SE.getSCEV(Dividend); 369 return visit(DividendSCEV); 370 } 371 372 ValidatorResult visitSRemInstruction(Instruction *SRem, const SCEV *S) { 373 assert(SRem->getOpcode() == Instruction::SRem && 374 "Assumed SRem instruction!"); 375 376 auto *Divisor = SRem->getOperand(1); 377 auto *CI = dyn_cast<ConstantInt>(Divisor); 378 if (!CI) 379 return visitGenericInst(SRem, S); 380 381 auto *Dividend = SRem->getOperand(0); 382 auto *DividendSCEV = SE.getSCEV(Dividend); 383 return visit(DividendSCEV); 384 } 385 386 ValidatorResult visitUnknown(const SCEVUnknown *Expr) { 387 Value *V = Expr->getValue(); 388 389 // TODO: FIXME: IslExprBuilder is not capable of producing valid code 390 // for arbitrary pointer expressions at the moment. Until 391 // this is fixed we disallow pointer expressions completely. 392 if (Expr->getType()->isPointerTy()) { 393 DEBUG(dbgs() << "INVALID: UnknownExpr is a pointer type [FIXME]"); 394 return ValidatorResult(SCEVType::INVALID); 395 } 396 397 if (!Expr->getType()->isIntegerTy()) { 398 DEBUG(dbgs() << "INVALID: UnknownExpr is not an integer"); 399 return ValidatorResult(SCEVType::INVALID); 400 } 401 402 if (isa<UndefValue>(V)) { 403 DEBUG(dbgs() << "INVALID: UnknownExpr references an undef value"); 404 return ValidatorResult(SCEVType::INVALID); 405 } 406 407 if (BaseAddress == V) { 408 DEBUG(dbgs() << "INVALID: UnknownExpr references BaseAddress\n"); 409 return ValidatorResult(SCEVType::INVALID); 410 } 411 412 if (Instruction *I = dyn_cast<Instruction>(Expr->getValue())) { 413 switch (I->getOpcode()) { 414 case Instruction::Load: 415 return visitLoadInstruction(I, Expr); 416 case Instruction::SDiv: 417 return visitSDivInstruction(I, Expr); 418 case Instruction::SRem: 419 return visitSRemInstruction(I, Expr); 420 default: 421 return visitGenericInst(I, Expr); 422 } 423 } 424 425 return ValidatorResult(SCEVType::PARAM, Expr); 426 } 427 }; 428 429 /// @brief Check whether a SCEV refers to an SSA name defined inside a region. 430 /// 431 struct SCEVInRegionDependences 432 : public SCEVVisitor<SCEVInRegionDependences, bool> { 433 public: 434 /// Returns true when the SCEV has SSA names defined in region R. It @p 435 /// AllowLoops is false, loop dependences are checked as well. AddRec SCEVs 436 /// are only allowed within its loop (current loop determined by @p Scope), 437 /// not outside of it unless AddRec's loop is not even in the region. 438 static bool hasDependences(const SCEV *S, const Region *R, Loop *Scope, 439 bool AllowLoops) { 440 SCEVInRegionDependences Ignore(R, Scope, AllowLoops); 441 return Ignore.visit(S); 442 } 443 444 SCEVInRegionDependences(const Region *R, Loop *Scope, bool AllowLoops) 445 : R(R), Scope(Scope), AllowLoops(AllowLoops) {} 446 447 bool visit(const SCEV *Expr) { 448 return SCEVVisitor<SCEVInRegionDependences, bool>::visit(Expr); 449 } 450 451 bool visitConstant(const SCEVConstant *Constant) { return false; } 452 453 bool visitTruncateExpr(const SCEVTruncateExpr *Expr) { 454 return visit(Expr->getOperand()); 455 } 456 457 bool visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) { 458 return visit(Expr->getOperand()); 459 } 460 461 bool visitSignExtendExpr(const SCEVSignExtendExpr *Expr) { 462 return visit(Expr->getOperand()); 463 } 464 465 bool visitAddExpr(const SCEVAddExpr *Expr) { 466 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) 467 if (visit(Expr->getOperand(i))) 468 return true; 469 470 return false; 471 } 472 473 bool visitMulExpr(const SCEVMulExpr *Expr) { 474 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) 475 if (visit(Expr->getOperand(i))) 476 return true; 477 478 return false; 479 } 480 481 bool visitUDivExpr(const SCEVUDivExpr *Expr) { 482 if (visit(Expr->getLHS())) 483 return true; 484 485 if (visit(Expr->getRHS())) 486 return true; 487 488 return false; 489 } 490 491 bool visitAddRecExpr(const SCEVAddRecExpr *Expr) { 492 if (!AllowLoops) { 493 if (!Scope) 494 return true; 495 auto *L = Expr->getLoop(); 496 if (R->contains(L) && !L->contains(Scope)) 497 return true; 498 } 499 500 for (size_t i = 0; i < Expr->getNumOperands(); ++i) 501 if (visit(Expr->getOperand(i))) 502 return true; 503 504 return false; 505 } 506 507 bool visitSMaxExpr(const SCEVSMaxExpr *Expr) { 508 for (size_t i = 0; i < Expr->getNumOperands(); ++i) 509 if (visit(Expr->getOperand(i))) 510 return true; 511 512 return false; 513 } 514 515 bool visitUMaxExpr(const SCEVUMaxExpr *Expr) { 516 for (size_t i = 0; i < Expr->getNumOperands(); ++i) 517 if (visit(Expr->getOperand(i))) 518 return true; 519 520 return false; 521 } 522 523 bool visitUnknown(const SCEVUnknown *Expr) { 524 Instruction *Inst = dyn_cast<Instruction>(Expr->getValue()); 525 526 // Return true when Inst is defined inside the region R. 527 if (Inst && R->contains(Inst)) 528 return true; 529 530 return false; 531 } 532 533 private: 534 const Region *R; 535 Loop *Scope; 536 bool AllowLoops; 537 }; 538 539 namespace polly { 540 /// Find all loops referenced in SCEVAddRecExprs. 541 class SCEVFindLoops { 542 SetVector<const Loop *> &Loops; 543 544 public: 545 SCEVFindLoops(SetVector<const Loop *> &Loops) : Loops(Loops) {} 546 547 bool follow(const SCEV *S) { 548 if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) 549 Loops.insert(AddRec->getLoop()); 550 return true; 551 } 552 bool isDone() { return false; } 553 }; 554 555 void findLoops(const SCEV *Expr, SetVector<const Loop *> &Loops) { 556 SCEVFindLoops FindLoops(Loops); 557 SCEVTraversal<SCEVFindLoops> ST(FindLoops); 558 ST.visitAll(Expr); 559 } 560 561 /// Find all values referenced in SCEVUnknowns. 562 class SCEVFindValues { 563 SetVector<Value *> &Values; 564 565 public: 566 SCEVFindValues(SetVector<Value *> &Values) : Values(Values) {} 567 568 bool follow(const SCEV *S) { 569 if (const SCEVUnknown *Unknown = dyn_cast<SCEVUnknown>(S)) 570 Values.insert(Unknown->getValue()); 571 return true; 572 } 573 bool isDone() { return false; } 574 }; 575 576 void findValues(const SCEV *Expr, SetVector<Value *> &Values) { 577 SCEVFindValues FindValues(Values); 578 SCEVTraversal<SCEVFindValues> ST(FindValues); 579 ST.visitAll(Expr); 580 } 581 582 bool hasScalarDepsInsideRegion(const SCEV *Expr, const Region *R, 583 llvm::Loop *Scope, bool AllowLoops) { 584 return SCEVInRegionDependences::hasDependences(Expr, R, Scope, AllowLoops); 585 } 586 587 bool isAffineExpr(const Region *R, llvm::Loop *Scope, const SCEV *Expr, 588 ScalarEvolution &SE, const Value *BaseAddress, 589 InvariantLoadsSetTy *ILS) { 590 if (isa<SCEVCouldNotCompute>(Expr)) 591 return false; 592 593 SCEVValidator Validator(R, Scope, SE, BaseAddress, ILS); 594 DEBUG({ 595 dbgs() << "\n"; 596 dbgs() << "Expr: " << *Expr << "\n"; 597 dbgs() << "Region: " << R->getNameStr() << "\n"; 598 dbgs() << " -> "; 599 }); 600 601 ValidatorResult Result = Validator.visit(Expr); 602 603 DEBUG({ 604 if (Result.isValid()) 605 dbgs() << "VALID\n"; 606 dbgs() << "\n"; 607 }); 608 609 return Result.isValid(); 610 } 611 612 static bool isAffineParamExpr(Value *V, const Region *R, Loop *Scope, 613 ScalarEvolution &SE, 614 std::vector<const SCEV *> &Params) { 615 auto *E = SE.getSCEV(V); 616 if (isa<SCEVCouldNotCompute>(E)) 617 return false; 618 619 SCEVValidator Validator(R, Scope, SE, nullptr, nullptr); 620 ValidatorResult Result = Validator.visit(E); 621 if (!Result.isConstant()) 622 return false; 623 624 auto ResultParams = Result.getParameters(); 625 Params.insert(Params.end(), ResultParams.begin(), ResultParams.end()); 626 627 return true; 628 } 629 630 bool isAffineParamConstraint(Value *V, const Region *R, llvm::Loop *Scope, 631 ScalarEvolution &SE, 632 std::vector<const SCEV *> &Params, bool OrExpr) { 633 if (auto *ICmp = dyn_cast<ICmpInst>(V)) { 634 return isAffineParamConstraint(ICmp->getOperand(0), R, Scope, SE, Params, 635 true) && 636 isAffineParamConstraint(ICmp->getOperand(1), R, Scope, SE, Params, 637 true); 638 } else if (auto *BinOp = dyn_cast<BinaryOperator>(V)) { 639 auto Opcode = BinOp->getOpcode(); 640 if (Opcode == Instruction::And || Opcode == Instruction::Or) 641 return isAffineParamConstraint(BinOp->getOperand(0), R, Scope, SE, Params, 642 false) && 643 isAffineParamConstraint(BinOp->getOperand(1), R, Scope, SE, Params, 644 false); 645 /* Fall through */ 646 } 647 648 if (!OrExpr) 649 return false; 650 651 return isAffineParamExpr(V, R, Scope, SE, Params); 652 } 653 654 std::vector<const SCEV *> getParamsInAffineExpr(const Region *R, Loop *Scope, 655 const SCEV *Expr, 656 ScalarEvolution &SE, 657 const Value *BaseAddress) { 658 if (isa<SCEVCouldNotCompute>(Expr)) 659 return std::vector<const SCEV *>(); 660 661 InvariantLoadsSetTy ILS; 662 SCEVValidator Validator(R, Scope, SE, BaseAddress, &ILS); 663 ValidatorResult Result = Validator.visit(Expr); 664 assert(Result.isValid() && "Requested parameters for an invalid SCEV!"); 665 666 return Result.getParameters(); 667 } 668 669 std::pair<const SCEVConstant *, const SCEV *> 670 extractConstantFactor(const SCEV *S, ScalarEvolution &SE) { 671 672 auto *LeftOver = SE.getConstant(S->getType(), 1); 673 auto *ConstPart = cast<SCEVConstant>(SE.getConstant(S->getType(), 1)); 674 675 if (auto *Constant = dyn_cast<SCEVConstant>(S)) 676 return std::make_pair(Constant, LeftOver); 677 678 auto *AddRec = dyn_cast<SCEVAddRecExpr>(S); 679 if (AddRec) { 680 auto *StartExpr = AddRec->getStart(); 681 if (StartExpr->isZero()) { 682 auto StepPair = extractConstantFactor(AddRec->getStepRecurrence(SE), SE); 683 auto *LeftOverAddRec = 684 SE.getAddRecExpr(StartExpr, StepPair.second, AddRec->getLoop(), 685 AddRec->getNoWrapFlags()); 686 return std::make_pair(StepPair.first, LeftOverAddRec); 687 } 688 return std::make_pair(ConstPart, S); 689 } 690 691 auto *Mul = dyn_cast<SCEVMulExpr>(S); 692 if (!Mul) 693 return std::make_pair(ConstPart, S); 694 695 for (auto *Op : Mul->operands()) 696 if (isa<SCEVConstant>(Op)) 697 ConstPart = cast<SCEVConstant>(SE.getMulExpr(ConstPart, Op)); 698 else 699 LeftOver = SE.getMulExpr(LeftOver, Op); 700 701 return std::make_pair(ConstPart, LeftOver); 702 } 703 } 704