[llvm-commits] CAST patch: Part #2: .ll/.bc readers + Analysis
Chris Lattner
clattner at apple.com
Mon Nov 20 14:07:19 PST 2006
On Nov 18, 2006, at 11:24 AM, Reid Spencer wrote:
> Chris,
>
> Here's the CAST patch. This passes 100% of llvm/test and llvm-test.
> The
> order of the files in the patch has been set up for logical review.
> Some
> of this you've already seen, but its changed so much that those things
> should probably be reviewed again.
The two occurrences of:
+ if ($1.obsolete && ($4->get() == Type::BoolTy)) {
+ // The previous definition of cast to bool was a compare
against zero.
+ // We have to retain that semantic so we do it here.
+ $$ = new SetCondInst(Instruction::SetEQ, $2,
+ Constant::getNullValue($2->getType()));
+ $1.obsolete = false;
are wrong, this should be SetNE X, nullvalue. You got this right
once in the bc reader, but this one is wrong:
@@ -1585,13 +1660,23 @@ inline unsigned BytecodeReader::upgradeC
Opcode = Instruction::SetGT;
break;
case 26: // GetElementPtr
Opcode = Instruction::GetElementPtr;
break;
- case 28: // Cast
- Opcode = Instruction::Cast;
+ case 28: { // Cast
+ const Type *Ty = getType(TypeID);
+ if (Ty == Type::BoolTy) {
+ // The previous definition of cast to bool was a compare
against zero.
+ // We have to retain that semantic so we do it here.
+ Opcode = Instruction::SetEQ;
+ return ConstantExpr::get(Instruction::SetEQ, ArgVec[0],
+ Constant::getNullValue(ArgVec[0]-
>getType()));
+ } else {
+ Opcode = CastInst::getCastOpcode(ArgVec[0], Ty);
+ }
break;
+ }
case 30: // Shl
Opcode = Instruction::Shl;
break;
case 31: // Shr
if (ArgVec[0]->getType()->isSigned())
diff -t -d -u -p -5 -r1.38 Reader.h
--- lib/Bytecode/Reader/Reader.h 14 Nov 2006 04:47:22 -0000 1.38
+++ lib/Bytecode/Reader/Reader.h 18 Nov 2006 19:22:09 -0000
@@ -300,10 +301,12 @@ private:
// In version 7, the Shr, Cast and Setcc instructions changed to
their
// signed counterparts. This flag will be true if these
instructions are
// signless (version 6 and prior).
bool hasSignlessShrCastSetcc;
+ bool hasSingleCast;
+
This needs a comment.
@@ -1345,29 +1343,39 @@ SCEVHandle ScalarEvolutionsImpl::createN
///
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))
+ // If this is a noop cast (eg, conversion from int to uint),
ignore it.
+ // NOTE: We should be passing in TargetData->getIntPtrType() to
isNoopCast
+ // here for more accurate Int->Ptr and Ptr->Int no-op detection.
Using
+ // ULongTy pessimizes this check for 32-bit platforms.
+ if (CI->isNoopCast(Type::ULongTy))
return getSCEV(CI->getOperand(0));
I believe that this is subtly wrong. The SCEV code doesn't really
handle pointers correctly, and the old isLosslesslyConvertibleTo
method would not return true for int<->ptr casts. Please change this
to check for isa<BitCast>, which is equivalent to the old code.
Please also remove the NOTE comment.
+ // The cast operations can deal with bool and other types here. We
only want
+ // integer casts so check that condition.
if (SrcTy->isInteger() && DestTy->isInteger()) {
+ switch (CI->getOpcode()) {
+ case Instruction::Trunc:
+ return SCEVTruncateExpr::get(getSCEV(CI->getOperand(0)),
+ DestTy->getUnsignedVersion());
+ case Instruction::ZExt:
+ return SCEVZeroExtendExpr::get(getSCEV(CI->getOperand(0)),
+ DestTy->getUnsignedVersion());
+ case Instruction::BitCast:
+ return SCEVZeroExtendExpr::get(getSCEV(CI->getOperand(0)),
+ DestTy->getUnsignedVersion());
+ break;
+ default:
+ // If this is a sign or zero extending cast and we can prove
that the
+ // value will never overflow, we could do similar
transformations. But,
+ // we can't handle this yet.
+ break;
+ }
The Instruction::BitCast case has already been handled by the
isa<BitCast> check above, plz remove it. Overall, I think it would
be cleaner to split createNodeForCast into createNodeForBitCast,
createNodeForZext and createNodeForTrunc than to try to handle these
three cases in one method.
+++ lib/Analysis/ValueNumbering.cpp 18 Nov 2006 19:22:11 -0000
@@ -110,12 +110,16 @@ void BVNImpl::visitCastInst(CastInst &CI
Function *F = I.getParent()->getParent();
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() &&
+ // Check that the source types are the same
+ CI.getOperand(0)->getType() == Other->getOperand(0)-
>getType() &&
// Is it embedded in the same function? (This could be
false if LHS
// is a constant or global!)
Other->getParent()->getParent() == F &&
// Check to see if this new cast is not I.
Other != &I) {
There is no need to check this:
+ // Check that the source types are the same
+ CI.getOperand(0)->getType() == Other->getOperand(0)-
>getType() &&
Since you know that CI.getOperand(0) == Other->getOperand(0) already.
--- lib/Analysis/IPA/GlobalsModRef.cpp 1 Oct 2006 22:46:33 -0000 1.23
+++ lib/Analysis/IPA/GlobalsModRef.cpp 18 Nov 2006 19:22:12 -0000
@@ -165,14 +165,17 @@ static Value *getUnderlyingObject(Value
// If we are at some type of object... return it.
if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) return GV;
// Traverse through different addressing mechanisms.
if (Instruction *I = dyn_cast<Instruction>(V)) {
- if (isa<CastInst>(I) || isa<GetElementPtrInst>(I))
+ if (isa<BitCastInst>(I) ||
+ isa<IntToPtrInst>(I) ||
+ isa<GetElementPtrInst>(I))
return getUnderlyingObject(I->getOperand(0));
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
- if (CE->getOpcode() == Instruction::Cast ||
+ if (CE->getOpcode() == Instruction::BitCast ||
+ CE->getOpcode() == Instruction::IntToPtr ||
CE->getOpcode() == Instruction::GetElementPtr)
return getUnderlyingObject(CE->getOperand(0));
}
// Othewise, we don't know what this is, return it as the base
pointer.
You don't want to include IntToPtr in either of these.
@@ -250,12 +253,11 @@ bool GlobalsModRef::AnalyzeUsesOfPointer
// Make sure that this is just the function being called, not
that it is
// passing into the function.
for (unsigned i = 3, e = II->getNumOperands(); i != e; ++i)
if (II->getOperand(i) == V) return true;
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(*UI)) {
- if (CE->getOpcode() == Instruction::GetElementPtr ||
- CE->getOpcode() == Instruction::Cast) {
+ if (CE->getOpcode() == Instruction::GetElementPtr || CE->isCast
()) {
if (AnalyzeUsesOfPointer(CE, Readers, Writers))
return true;
This should just allow GEP and BitCast, not any Cast.
-Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20061120/aa97b81c/attachment.html>
More information about the llvm-commits
mailing list