Changes in directory llvm/lib/Analysis:
BasicAliasAnalysis.cpp updated: 1.90 -> 1.91 ScalarEvolution.cpp updated: 1.58 -> 1.59 ScalarEvolutionExpander.cpp updated: 1.4 -> 1.5 ValueNumbering.cpp updated: 1.22 -> 1.23 --- Log message: For PR950: http://llvm.org/PR950 : The long awaited CAST patch. This introduces 12 new instructions into LLVM to replace the cast instruction. Corresponding changes throughout LLVM are provided. This passes llvm-test, llvm/test, and SPEC CPUINT2000 with the exception of 175.vpr which fails only on a slight floating point output difference. --- Diffs of the changes: (+71 -75) BasicAliasAnalysis.cpp | 76 ++++++++++++++++++++++++++------------------ ScalarEvolution.cpp | 55 ++++++++++--------------------- ScalarEvolutionExpander.cpp | 9 ++--- ValueNumbering.cpp | 6 ++- 4 files changed, 71 insertions(+), 75 deletions(-) Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.90 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.91 --- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.90 Sun Nov 12 19:10:12 2006 +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp Sun Nov 26 19:05:09 2006 @@ -129,27 +129,23 @@ return new BasicAliasAnalysis(); } -// hasUniqueAddress - Return true if the specified value points to something -// with a unique, discernable, address. -static inline bool hasUniqueAddress(const Value *V) { - return isa<GlobalValue>(V) || isa<AllocationInst>(V); -} - // getUnderlyingObject - This traverses the use chain to figure out what object // the specified value points to. If the value points to, or is derived from, a // unique object or an argument, return it. static const Value *getUnderlyingObject(const Value *V) { if (!isa<PointerType>(V->getType())) return 0; - // If we are at some type of object... return it. - if (hasUniqueAddress(V) || isa<Argument>(V)) return V; + // If we are at some type of object, return it. GlobalValues and Allocations + // have unique addresses. + if (isa<GlobalValue>(V) || isa<AllocationInst>(V) || isa<Argument>(V)) + return V; // Traverse through different addressing mechanisms... if (const Instruction *I = dyn_cast<Instruction>(V)) { - if (isa<CastInst>(I) || isa<GetElementPtrInst>(I)) + if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I)) return getUnderlyingObject(I->getOperand(0)); } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() == Instruction::Cast || + if (CE->getOpcode() == Instruction::BitCast || CE->getOpcode() == Instruction::GetElementPtr) return getUnderlyingObject(CE->getOperand(0)); } @@ -192,28 +188,34 @@ return false; } +// Determine if an AllocationInst instruction escapes from the function it is +// contained in. If it does not escape, there is no way for another function to +// mod/ref it. We do this by looking at its uses and determining if the uses +// can escape (recursively). static bool AddressMightEscape(const Value *V) { for (Value::use_const_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI) { const Instruction *I = cast<Instruction>(*UI); switch (I->getOpcode()) { - case Instruction::Load: break; + case Instruction::Load: + break; //next use. case Instruction::Store: if (I->getOperand(0) == V) return true; // Escapes if the pointer is stored. - break; + break; // next use. case Instruction::GetElementPtr: - if (AddressMightEscape(I)) return true; - break; - case Instruction::Cast: + if (AddressMightEscape(I)) + return true; + case Instruction::BitCast: if (!isa<PointerType>(I->getType())) return true; - if (AddressMightEscape(I)) return true; - break; + if (AddressMightEscape(I)) + return true; + break; // next use case Instruction::Ret: // If returned, the address will escape to calling functions, but no // callees could modify it. - break; + break; // next use default: return true; } @@ -257,12 +259,10 @@ const Value *V2, unsigned V2Size) { // Strip off any constant expression casts if they exist if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V1)) - if (CE->getOpcode() == Instruction::Cast && - isa<PointerType>(CE->getOperand(0)->getType())) + if (CE->isCast() && isa<PointerType>(CE->getOperand(0)->getType())) V1 = CE->getOperand(0); if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V2)) - if (CE->getOpcode() == Instruction::Cast && - isa<PointerType>(CE->getOperand(0)->getType())) + if (CE->isCast() && isa<PointerType>(CE->getOperand(0)->getType())) V2 = CE->getOperand(0); // Are we checking for alias of the same value? @@ -273,10 +273,10 @@ return NoAlias; // Scalars cannot alias each other // Strip off cast instructions... - if (const Instruction *I = dyn_cast<CastInst>(V1)) + if (const BitCastInst *I = dyn_cast<BitCastInst>(V1)) if (isa<PointerType>(I->getOperand(0)->getType())) return alias(I->getOperand(0), V1Size, V2, V2Size); - if (const Instruction *I = dyn_cast<CastInst>(V2)) + if (const BitCastInst *I = dyn_cast<BitCastInst>(V2)) if (isa<PointerType>(I->getOperand(0)->getType())) return alias(V1, V1Size, I->getOperand(0), V2Size); @@ -450,14 +450,22 @@ return MayAlias; } -static bool ValuesEqual(Value *V1, Value *V2) { +// This function is used to determin if the indices of two GEP instructions are +// equal. V1 and V2 are the indices. +static bool IndexOperandsEqual(Value *V1, Value *V2) { if (V1->getType() == V2->getType()) return V1 == V2; if (Constant *C1 = dyn_cast<Constant>(V1)) if (Constant *C2 = dyn_cast<Constant>(V2)) { - // Sign extend the constants to long types. - C1 = ConstantExpr::getSignExtend(C1, Type::LongTy); - C2 = ConstantExpr::getSignExtend(C2, Type::LongTy); + // Sign extend the constants to long types, if necessary + if (C1->getType()->getPrimitiveSizeInBits() < 64) + C1 = ConstantExpr::getSignExtend(C1, Type::LongTy); + else if (C1->getType() == Type::ULongTy) + C1 = ConstantExpr::getBitCast(C1, Type::LongTy); + if (C2->getType()->getPrimitiveSizeInBits() < 64) + C2 = ConstantExpr::getSignExtend(C2, Type::LongTy); + else if (C2->getType() == Type::ULongTy) + C2 = ConstantExpr::getBitCast(C2, Type::LongTy); return C1 == C2; } return false; @@ -485,7 +493,7 @@ unsigned MaxOperands = std::max(NumGEP1Operands, NumGEP2Operands); unsigned UnequalOper = 0; while (UnequalOper != MinOperands && - ValuesEqual(GEP1Ops[UnequalOper], GEP2Ops[UnequalOper])) { + IndexOperandsEqual(GEP1Ops[UnequalOper], GEP2Ops[UnequalOper])) { // Advance through the type as we go... ++UnequalOper; if (const CompositeType *CT = dyn_cast<CompositeType>(BasePtr1Ty)) @@ -546,8 +554,14 @@ if (Constant *G2OC = dyn_cast<ConstantInt>(const_cast<Value*>(G2Oper))){ if (G1OC->getType() != G2OC->getType()) { // Sign extend both operands to long. - G1OC = ConstantExpr::getSignExtend(G1OC, Type::LongTy); - G2OC = ConstantExpr::getSignExtend(G2OC, Type::LongTy); + if (G1OC->getType()->getPrimitiveSizeInBits() < 64) + G1OC = ConstantExpr::getSignExtend(G1OC, Type::LongTy); + else if (G1OC->getType() == Type::ULongTy) + G1OC = ConstantExpr::getBitCast(G1OC, Type::LongTy); + if (G2OC->getType()->getPrimitiveSizeInBits() < 64) + G2OC = ConstantExpr::getSignExtend(G2OC, Type::LongTy); + else if (G2OC->getType() == Type::ULongTy) + G2OC = ConstantExpr::getBitCast(G2OC, Type::LongTy); GEP1Ops[FirstConstantOper] = G1OC; GEP2Ops[FirstConstantOper] = G2OC; } Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.58 llvm/lib/Analysis/ScalarEvolution.cpp:1.59 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.58 Wed Nov 8 13:16:43 2006 +++ llvm/lib/Analysis/ScalarEvolution.cpp Sun Nov 26 19:05:09 2006 @@ -203,7 +203,6 @@ SCEVTruncateExpr::SCEVTruncateExpr(const SCEVHandle &op, const Type *ty) : SCEV(scTruncate), Op(op), Ty(ty) { assert(Op->getType()->isInteger() && Ty->isInteger() && - Ty->isUnsigned() && "Cannot truncate non-integer value!"); assert(Op->getType()->getPrimitiveSize() > Ty->getPrimitiveSize() && "This is not a truncating conversion!"); @@ -230,7 +229,6 @@ SCEVZeroExtendExpr::SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty) : SCEV(scZeroExtend), Op(op), Ty(ty) { assert(Op->getType()->isInteger() && Ty->isInteger() && - Ty->isUnsigned() && "Cannot zero extend non-integer value!"); assert(Op->getType()->getPrimitiveSize() < Ty->getPrimitiveSize() && "This is not an extending conversion!"); @@ -1139,7 +1137,6 @@ /// createSCEV - We know that there is no SCEV for the specified value. /// Analyze the expression. SCEVHandle createSCEV(Value *V); - SCEVHandle createNodeForCast(CastInst *CI); /// createNodeForPHI - Provide the special handling we need to analyze PHI /// SCEVs. @@ -1341,35 +1338,6 @@ return SCEVUnknown::get(PN); } -/// createNodeForCast - Handle the various forms of casts that we support. -/// -SCEVHandle ScalarEvolutionsImpl::createNodeForCast(CastInst *CI) { - const Type *SrcTy = CI->getOperand(0)->getType(); - const Type *DestTy = CI->getType(); - - // If this is a noop cast (ie, conversion from int to uint), ignore it. - if (SrcTy->isLosslesslyConvertibleTo(DestTy)) - return getSCEV(CI->getOperand(0)); - - if (SrcTy->isInteger() && DestTy->isInteger()) { - // Otherwise, if this is a truncating integer cast, we can represent this - // cast. - if (SrcTy->getPrimitiveSize() > DestTy->getPrimitiveSize()) - return SCEVTruncateExpr::get(getSCEV(CI->getOperand(0)), - CI->getType()->getUnsignedVersion()); - if (SrcTy->isUnsigned() && - SrcTy->getPrimitiveSize() <= DestTy->getPrimitiveSize()) - return SCEVZeroExtendExpr::get(getSCEV(CI->getOperand(0)), - CI->getType()->getUnsignedVersion()); - } - - // If this is an sign or zero extending cast and we can prove that the value - // will never overflow, we could do similar transformations. - - // Otherwise, we can't handle this cast! - return SCEVUnknown::get(CI); -} - /// createSCEV - We know that there is no SCEV for the specified value. /// Analyze the expression. @@ -1401,8 +1369,21 @@ } break; - case Instruction::Cast: - return createNodeForCast(cast<CastInst>(I)); + case Instruction::Trunc: + if (I->getType()->isInteger() && I->getOperand(0)->getType()->isInteger()) + return SCEVTruncateExpr::get(getSCEV(I->getOperand(0)), + I->getType()->getUnsignedVersion()); + break; + + case Instruction::ZExt: + if (I->getType()->isInteger() && I->getOperand(0)->getType()->isInteger()) + return SCEVZeroExtendExpr::get(getSCEV(I->getOperand(0)), + I->getType()->getUnsignedVersion()); + break; + + case Instruction::BitCast: + // BitCasts are no-op casts so we just eliminate the cast. + return getSCEV(I->getOperand(0)); case Instruction::PHI: return createNodeForPHI(cast<PHINode>(I)); @@ -1724,9 +1705,10 @@ if (isa<BinaryOperator>(I) || isa<ShiftInst>(I)) return ConstantExpr::get(I->getOpcode(), Operands[0], Operands[1]); + if (isa<CastInst>(I)) + return ConstantExpr::getCast(I->getOpcode(), Operands[0], I->getType()); + switch (I->getOpcode()) { - case Instruction::Cast: - return ConstantExpr::getCast(Operands[0], I->getType()); case Instruction::Select: return ConstantExpr::getSelect(Operands[0], Operands[1], Operands[2]); case Instruction::Call: @@ -1734,7 +1716,6 @@ Operands.erase(Operands.begin()); return ConstantFoldCall(cast<Function>(GV), Operands); } - return 0; case Instruction::GetElementPtr: Constant *Base = Operands[0]; Index: llvm/lib/Analysis/ScalarEvolutionExpander.cpp diff -u llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.4 llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.5 --- llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.4 Fri Oct 20 02:07:24 2006 +++ llvm/lib/Analysis/ScalarEvolutionExpander.cpp Sun Nov 26 19:05:09 2006 @@ -30,8 +30,7 @@ UI != E; ++UI) { if ((*UI)->getType() == Ty) if (CastInst *CI = dyn_cast<CastInst>(cast<Instruction>(*UI))) { - // If the cast isn't in the first instruction of the function, - // move it. + // If the cast isn't the first instruction of the function, move it. if (BasicBlock::iterator(CI) != A->getParent()->getEntryBlock().begin()) { CI->moveBefore(A->getParent()->getEntryBlock().begin()); @@ -39,8 +38,8 @@ return CI; } } - return new CastInst(V, Ty, V->getName(), - A->getParent()->getEntryBlock().begin()); + return CastInst::createInferredCast(V, Ty, V->getName(), + A->getParent()->getEntryBlock().begin()); } Instruction *I = cast<Instruction>(V); @@ -65,7 +64,7 @@ if (InvokeInst *II = dyn_cast<InvokeInst>(I)) IP = II->getNormalDest()->begin(); while (isa<PHINode>(IP)) ++IP; - return new CastInst(V, Ty, V->getName(), IP); + return CastInst::createInferredCast(V, Ty, V->getName(), IP); } Value *SCEVExpander::visitMulExpr(SCEVMulExpr *S) { Index: llvm/lib/Analysis/ValueNumbering.cpp diff -u llvm/lib/Analysis/ValueNumbering.cpp:1.22 llvm/lib/Analysis/ValueNumbering.cpp:1.23 --- llvm/lib/Analysis/ValueNumbering.cpp:1.22 Sun Nov 19 19:22:35 2006 +++ llvm/lib/Analysis/ValueNumbering.cpp Sun Nov 26 19:05:09 2006 @@ -113,8 +113,10 @@ for (Value::use_iterator UI = Op->use_begin(), UE = Op->use_end(); UI != UE; ++UI) if (CastInst *Other = dyn_cast<CastInst>(*UI)) - // Check that the types are the same, since this code handles casts... - if (Other->getType() == I.getType() && + // Check that the opcode is the same + if (Other->getOpcode() == Instruction::CastOps(I.getOpcode()) && + // Check that the destination types are the same + Other->getType() == I.getType() && // Is it embedded in the same function? (This could be false if LHS // is a constant or global!) Other->getParent()->getParent() == F && _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits