-//===----------------------------------------------------------------------===//
-// Non-trivial closed-form SCEV Expanders
-//===----------------------------------------------------------------------===//
-
-Value *SCEVTruncateExpr::expandCodeFor(ScalarEvolutionRewriter &SER,
- Instruction *InsertPt) {
- Value *V = SER.ExpandCodeFor(getOperand(), InsertPt);
- return new CastInst(V, getType(), "tmp.", InsertPt);
-}
-
-Value *SCEVZeroExtendExpr::expandCodeFor(ScalarEvolutionRewriter &SER,
- Instruction *InsertPt) {
- Value *V = SER.ExpandCodeFor(getOperand(), InsertPt,
- getOperand()->getType()->getUnsignedVersion());
- return new CastInst(V, getType(), "tmp.", InsertPt);
-}
-
-Value *SCEVAddExpr::expandCodeFor(ScalarEvolutionRewriter &SER,
- Instruction *InsertPt) {
- const Type *Ty = getType();
- Value *V = SER.ExpandCodeFor(getOperand(getNumOperands()-1), InsertPt, Ty);
-
- // Emit a bunch of add instructions
- for (int i = getNumOperands()-2; i >= 0; --i)
- V = BinaryOperator::create(Instruction::Add, V,
- SER.ExpandCodeFor(getOperand(i), InsertPt, Ty),
- "tmp.", InsertPt);
- return V;
-}
-
-Value *SCEVMulExpr::expandCodeFor(ScalarEvolutionRewriter &SER,
- Instruction *InsertPt) {
- const Type *Ty = getType();
- int FirstOp = 0; // Set if we should emit a subtract.
- if (SCEVConstant *SC = dyn_cast<SCEVConstant>(getOperand(0)))
- if (SC->getValue()->isAllOnesValue())
- FirstOp = 1;
-
- int i = getNumOperands()-2;
- Value *V = SER.ExpandCodeFor(getOperand(i+1), InsertPt, Ty);
-
- // Emit a bunch of multiply instructions
- for (; i >= FirstOp; --i)
- V = BinaryOperator::create(Instruction::Mul, V,
- SER.ExpandCodeFor(getOperand(i), InsertPt, Ty),
- "tmp.", InsertPt);
- // -1 * ... ---> 0 - ...
- if (FirstOp == 1)
- V = BinaryOperator::create(Instruction::Sub, Constant::getNullValue(Ty), V,
- "tmp.", InsertPt);
- return V;
-}
-
-Value *SCEVUDivExpr::expandCodeFor(ScalarEvolutionRewriter &SER,
- Instruction *InsertPt) {
- const Type *Ty = getType();
- Value *LHS = SER.ExpandCodeFor(getLHS(), InsertPt, Ty);
- Value *RHS = SER.ExpandCodeFor(getRHS(), InsertPt, Ty);
- return BinaryOperator::create(Instruction::Div, LHS, RHS, "tmp.", InsertPt);
-}
-
-Value *SCEVAddRecExpr::expandCodeFor(ScalarEvolutionRewriter &SER,
- Instruction *InsertPt) {
- const Type *Ty = getType();
- // We cannot yet do fp recurrences, e.g. the xform of {X,+,F} --> X+{0,+,F}
- assert(Ty->isIntegral() && "Cannot expand fp recurrences yet!");
-
- // {X,+,F} --> X + {0,+,F}
- if (!isa<SCEVConstant>(getStart()) ||
- !cast<SCEVConstant>(getStart())->getValue()->isNullValue()) {
- Value *Start = SER.ExpandCodeFor(getStart(), InsertPt, Ty);
- std::vector<SCEVHandle> NewOps(op_begin(), op_end());
- NewOps[0] = getIntegerSCEV(0, getType());
- Value *Rest = SER.ExpandCodeFor(SCEVAddRecExpr::get(NewOps, getLoop()),
- InsertPt, getType());
-
- // FIXME: look for an existing add to use.
- return BinaryOperator::create(Instruction::Add, Rest, Start, "tmp.",
- InsertPt);
- }
-
- // {0,+,1} --> Insert a canonical induction variable into the loop!
- if (getNumOperands() == 2 && getOperand(1) == getIntegerSCEV(1, getType())) {
- // Create and insert the PHI node for the induction variable in the
- // specified loop.
- BasicBlock *Header = getLoop()->getHeader();
- PHINode *PN = new PHINode(Ty, "indvar", Header->begin());
- PN->addIncoming(Constant::getNullValue(Ty), L->getLoopPreheader());
-
- pred_iterator HPI = pred_begin(Header);
- assert(HPI != pred_end(Header) && "Loop with zero preds???");
- if (!getLoop()->contains(*HPI)) ++HPI;
- assert(HPI != pred_end(Header) && getLoop()->contains(*HPI) &&
- "No backedge in loop?");
-
- // Insert a unit add instruction right before the terminator corresponding
- // to the back-edge.
- Constant *One = Ty->isFloatingPoint() ? (Constant*)ConstantFP::get(Ty, 1.0)
- : (Constant*)ConstantInt::get(Ty, 1);
- Instruction *Add = BinaryOperator::create(Instruction::Add, PN, One,
- "indvar.next",
- (*HPI)->getTerminator());
-
- pred_iterator PI = pred_begin(Header);
- if (*PI == L->getLoopPreheader())
- ++PI;
- PN->addIncoming(Add, *PI);
- return PN;
- }
-
- // Get the canonical induction variable I for this loop.
- Value *I = SER.GetOrInsertCanonicalInductionVariable(getLoop(), Ty);
-
- if (getNumOperands() == 2) { // {0,+,F} --> i*F
- Value *F = SER.ExpandCodeFor(getOperand(1), InsertPt, Ty);
- return BinaryOperator::create(Instruction::Mul, I, F, "tmp.", InsertPt);
- }
-
- // If this is a chain of recurrences, turn it into a closed form, using the
- // folders, then expandCodeFor the closed form. This allows the folders to
- // simplify the expression without having to build a bunch of special code
- // into this folder.
- SCEVHandle IH = SCEVUnknown::get(I); // Get I as a "symbolic" SCEV.
-
- SCEVHandle V = evaluateAtIteration(IH);
- //std::cerr << "Evaluated: " << *this << "\n to: " << *V << "\n";
-
- return SER.ExpandCodeFor(V, InsertPt, Ty);
-}
-
-