llvm-6502/include/llvm/Analysis/ScalarEvolutionExpander.h
Wojciech Matyjewicz e3320a1bcc Fix PR1798 - an error in the evaluation of SCEVAddRecExpr at an
arbitrary iteration.

The patch:
1) changes SCEVSDivExpr into SCEVUDivExpr,
2) replaces PartialFact() function with BinomialCoefficient(); the 
computations (essentially, the division) in BinomialCoefficient() are 
performed with the apprioprate bitwidth necessary to avoid overflow; 
unsigned division is used instead of the signed one.

Computations in BinomialCoefficient() require support from the code 
generator for APInts. Currently, we use a hack rounding up the 
neccessary bitwidth to the nearest power of 2. The hack is easy to turn 
off in future.

One remaining issue: we assume the divisor of the binomial coefficient 
formula can be computed accurately using 16 bits. It means we can handle 
AddRecs of length up to 9. In future, we should use APInts to evaluate 
the divisor.

Thanks to Nicholas for cooperation!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46955 91177308-0d34-0410-b5e6-96231b3b80d8
2008-02-11 11:03:14 +00:00

147 lines
5.2 KiB
C++

//===---- llvm/Analysis/ScalarEvolutionExpander.h - SCEV Exprs --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the classes used to generate code from scalar expressions.
//
//===----------------------------------------------------------------------===//
#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
/// rewrite expressions in canonical form.
///
/// Clients should create an instance of this class when rewriting is needed,
/// and destroy it when finished to allow the release of the associated
/// memory.
struct SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
ScalarEvolution &SE;
LoopInfo &LI;
std::map<SCEVHandle, Value*> InsertedExpressions;
std::set<Instruction*> InsertedInstructions;
Instruction *InsertPt;
friend struct SCEVVisitor<SCEVExpander, Value*>;
public:
SCEVExpander(ScalarEvolution &se, LoopInfo &li) : SE(se), LI(li) {}
LoopInfo &getLoopInfo() const { return LI; }
/// clear - Erase the contents of the InsertedExpressions map so that users
/// trying to expand the same expression into multiple BasicBlocks or
/// different places within the same BasicBlock can do so.
void clear() { InsertedExpressions.clear(); }
/// isInsertedInstruction - Return true if the specified instruction was
/// inserted by the code rewriter. If so, the client should not modify the
/// instruction.
bool isInsertedInstruction(Instruction *I) const {
return InsertedInstructions.count(I);
}
/// getOrInsertCanonicalInductionVariable - This method returns the
/// canonical induction variable of the specified type for the specified
/// 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() && "Can only insert integer induction variables!");
SCEVHandle H = SE.getAddRecExpr(SE.getIntegerSCEV(0, Ty),
SE.getIntegerSCEV(1, Ty), L);
return expand(H);
}
/// addInsertedValue - Remember the specified instruction as being the
/// canonical form for the specified SCEV.
void addInsertedValue(Instruction *I, SCEV *S) {
InsertedExpressions[S] = (Value*)I;
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.
Value *expandCodeFor(SCEVHandle SH, Instruction *IP) {
// Expand the code for this SCEV.
this->InsertPt = IP;
return expand(SH);
}
/// 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);
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 *visitZeroExtendExpr(SCEVZeroExtendExpr *S) {
Value *V = expand(S->getOperand());
return CastInst::createZExtOrBitCast(V, S->getType(), "tmp.", InsertPt);
}
Value *visitSignExtendExpr(SCEVSignExtendExpr *S) {
Value *V = expand(S->getOperand());
return CastInst::createSExtOrBitCast(V, S->getType(), "tmp.", InsertPt);
}
Value *visitAddExpr(SCEVAddExpr *S) {
Value *V = expand(S->getOperand(S->getNumOperands()-1));
// Emit a bunch of add instructions
for (int i = S->getNumOperands()-2; i >= 0; --i)
V = InsertBinop(Instruction::Add, V, expand(S->getOperand(i)),
InsertPt);
return V;
}
Value *visitMulExpr(SCEVMulExpr *S);
Value *visitUDivExpr(SCEVUDivExpr *S) {
Value *LHS = expand(S->getLHS());
Value *RHS = expand(S->getRHS());
return InsertBinop(Instruction::UDiv, LHS, RHS, InsertPt);
}
Value *visitAddRecExpr(SCEVAddRecExpr *S);
Value *visitSMaxExpr(SCEVSMaxExpr *S);
Value *visitUnknown(SCEVUnknown *S) {
return S->getValue();
}
};
}
#endif