From ca1a4bebb3928ba18fb8751e2f0c0f88fad54cfd Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 4 Feb 2006 09:51:53 +0000 Subject: [PATCH] Pull the InsertCastOfTo out of the header, implement CSE'ing of arguments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25973 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ScalarEvolutionExpander.cpp | 51 ++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index e2a98d4d862..fd33e2fae2b 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -17,6 +17,57 @@ #include "llvm/Analysis/ScalarEvolutionExpander.h" using namespace llvm; +/// InsertCastOfTo - Insert a cast of V to the specified type, doing what +/// we can to share the casts. +Value *SCEVExpander::InsertCastOfTo(Value *V, const Type *Ty) { + // FIXME: keep track of the cast instruction. + if (Constant *C = dyn_cast(V)) + return ConstantExpr::getCast(C, Ty); + + if (Argument *A = dyn_cast(V)) { + // Check to see if there is already a cast! + for (Value::use_iterator UI = A->use_begin(), E = A->use_end(); + UI != E; ++UI) { + if ((*UI)->getType() == Ty) + if (CastInst *CI = dyn_cast(cast(*UI))) { + // If the cast isn't in the first instruction of the function, + // move it. + if (BasicBlock::iterator(CI) != + A->getParent()->getEntryBlock().begin()) { + CI->moveBefore(A->getParent()->getEntryBlock().begin()); + } + return CI; + } + } + return new CastInst(V, Ty, V->getName(), + A->getParent()->getEntryBlock().begin()); + } + + Instruction *I = cast(V); + + // Check to see if there is already a cast. If there is, use it. + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); + UI != E; ++UI) { + if ((*UI)->getType() == Ty) + if (CastInst *CI = dyn_cast(cast(*UI))) { + BasicBlock::iterator It = I; ++It; + if (isa(I)) + It = cast(I)->getNormalDest()->begin(); + while (isa(It)) ++It; + if (It != BasicBlock::iterator(CI)) { + // Splice the cast immediately after the operand in question. + CI->moveBefore(It); + } + return CI; + } + } + BasicBlock::iterator IP = I; ++IP; + if (InvokeInst *II = dyn_cast(I)) + IP = II->getNormalDest()->begin(); + while (isa(IP)) ++IP; + return new CastInst(V, Ty, V->getName(), IP); +} + Value *SCEVExpander::visitMulExpr(SCEVMulExpr *S) { const Type *Ty = S->getType(); int FirstOp = 0; // Set if we should emit a subtract.