//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
-#include "llvm/BasicBlock.h"
-#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Type.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
-#include "llvm/Support/CFG.h"
namespace llvm {
/// SCEVExpander - This class uses information about analyze scalars to
/// loop (inserting one if there is none). A canonical induction variable
/// starts at zero and steps by one on each iteration.
Value *getOrInsertCanonicalInductionVariable(const Loop *L, const Type *Ty){
- assert((Ty->isInteger() || Ty->isFloatingPoint()) &&
- "Can only insert integer or floating point induction variables!");
- SCEVHandle H = SCEVAddRecExpr::get(SCEVUnknown::getIntegerSCEV(0, Ty),
- SCEVUnknown::getIntegerSCEV(1, Ty), L);
+ assert(Ty->isInteger() && "Can only insert integer induction variables!");
+ SCEVHandle H = SE.getAddRecExpr(SE.getIntegerSCEV(0, Ty),
+ SE.getIntegerSCEV(1, Ty), L);
return expand(H);
}
InsertedInstructions.insert(I);
}
+ Instruction *getInsertionPoint() const { return InsertPt; }
+
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
/// specified block.
- ///
- /// If a particular value sign is required, a type may be specified for the
- /// result.
- Value *expandCodeFor(SCEVHandle SH, Instruction *IP, const Type *Ty = 0) {
- // Expand the code for this SCEV.
- this->InsertPt = IP;
- return expandInTy(SH, Ty);
- }
+ Value *expandCodeFor(SCEVHandle SH, Instruction *IP);
/// InsertCastOfTo - Insert a cast of V to the specified type, doing what
/// we can to share the casts.
static Value *InsertCastOfTo(Instruction::CastOps opcode, Value *V,
const Type *Ty);
-
+ /// InsertBinop - Insert the specified binary operator, doing a small amount
+ /// of work to avoid inserting an obviously redundant operation.
+ static Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
+ Value *RHS, Instruction *InsertPt);
protected:
- Value *expand(SCEV *S) {
- // Check to see if we already expanded this.
- std::map<SCEVHandle, Value*>::iterator I = InsertedExpressions.find(S);
- if (I != InsertedExpressions.end())
- return I->second;
-
- Value *V = visit(S);
- InsertedExpressions[S] = V;
- return V;
- }
-
- Value *expandInTy(SCEV *S, const Type *Ty) {
- Value *V = expand(S);
- if (Ty && V->getType() != Ty) {
- if (isa<PointerType>(Ty) && V->getType()->isInteger())
- return InsertCastOfTo(Instruction::IntToPtr, V, Ty);
- else if (Ty->isInteger() && isa<PointerType>(V->getType()))
- return InsertCastOfTo(Instruction::PtrToInt, V, Ty);
- else if (Ty->getPrimitiveSizeInBits() ==
- V->getType()->getPrimitiveSizeInBits())
- return InsertCastOfTo(Instruction::BitCast, V, Ty);
- else if (Ty->getPrimitiveSizeInBits() >
- V->getType()->getPrimitiveSizeInBits())
- return InsertCastOfTo(Instruction::ZExt, V, Ty);
- else
- return InsertCastOfTo(Instruction::Trunc, V, Ty);
- }
- return V;
- }
-
+ Value *expand(SCEV *S);
+
Value *visitConstant(SCEVConstant *S) {
return S->getValue();
}
- Value *visitTruncateExpr(SCEVTruncateExpr *S) {
- Value *V = expand(S->getOperand());
- return CastInst::createTruncOrBitCast(V, S->getType(), "tmp.", InsertPt);
- }
+ Value *visitTruncateExpr(SCEVTruncateExpr *S);
- Value *visitZeroExtendExpr(SCEVZeroExtendExpr *S) {
- Value *V = expandInTy(S->getOperand(), S->getType());
- return CastInst::createZExtOrBitCast(V, S->getType(), "tmp.", InsertPt);
- }
+ Value *visitZeroExtendExpr(SCEVZeroExtendExpr *S);
- Value *visitAddExpr(SCEVAddExpr *S) {
- const Type *Ty = S->getType();
- Value *V = expandInTy(S->getOperand(S->getNumOperands()-1), Ty);
+ Value *visitSignExtendExpr(SCEVSignExtendExpr *S);
- // Emit a bunch of add instructions
- for (int i = S->getNumOperands()-2; i >= 0; --i)
- V = BinaryOperator::createAdd(V, expandInTy(S->getOperand(i), Ty),
- "tmp.", InsertPt);
- return V;
- }
+ Value *visitAddExpr(SCEVAddExpr *S);
Value *visitMulExpr(SCEVMulExpr *S);
- Value *visitSDivExpr(SCEVSDivExpr *S) {
- const Type *Ty = S->getType();
- Value *LHS = expandInTy(S->getLHS(), Ty);
- Value *RHS = expandInTy(S->getRHS(), Ty);
- return BinaryOperator::createSDiv(LHS, RHS, "tmp.", InsertPt);
- }
+ Value *visitUDivExpr(SCEVUDivExpr *S);
+
+ Value *visitSDivExpr(SCEVSDivExpr *S);
Value *visitAddRecExpr(SCEVAddRecExpr *S);
+ Value *visitSMaxExpr(SCEVSMaxExpr *S);
+
+ Value *visitUMaxExpr(SCEVUMaxExpr *S);
+
Value *visitUnknown(SCEVUnknown *S) {
return S->getValue();
}