[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Tue Sep 13 11:36:15 PDT 2005
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.369 -> 1.370
---
Log message:
Add a simple xform to simplify array accesses with casts in the way.
This is useful for 178.galgel where resolution of dope vectors (by the
optimizer) causes the scales to become apparent.
---
Diffs of the changes: (+62 -2)
InstructionCombining.cpp | 64 +++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 62 insertions(+), 2 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.369 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.370
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.369 Mon Sep 12 19:40:14 2005
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Sep 13 13:36:04 2005
@@ -4718,8 +4718,8 @@
}
} else if (GEP.getNumOperands() == 2) {
// Transform things like:
- // %t = getelementptr ubyte* cast ([2 x sbyte]* %str to ubyte*), uint %V
- // into: %t1 = getelementptr [2 x sbyte*]* %str, int 0, uint %V; cast
+ // %t = getelementptr ubyte* cast ([2 x int]* %str to uint*), uint %V
+ // into: %t1 = getelementptr [2 x int*]* %str, int 0, uint %V; cast
const Type *SrcElTy = cast<PointerType>(X->getType())->getElementType();
const Type *ResElTy=cast<PointerType>(PtrOp->getType())->getElementType();
if (isa<ArrayType>(SrcElTy) &&
@@ -4730,6 +4730,66 @@
GEP.getOperand(1), GEP.getName()), GEP);
return new CastInst(V, GEP.getType());
}
+
+ // Transform things like:
+ // getelementptr sbyte* cast ([100 x double]* X to sbyte*), int %tmp
+ // (where tmp = 8*tmp2) into:
+ // getelementptr [100 x double]* %arr, int 0, int %tmp.2
+
+ if (isa<ArrayType>(SrcElTy) &&
+ (ResElTy == Type::SByteTy || ResElTy == Type::UByteTy)) {
+ uint64_t ArrayEltSize =
+ TD->getTypeSize(cast<ArrayType>(SrcElTy)->getElementType());
+
+ // Check to see if "tmp" is a scale by a multiple of ArrayEltSize. We
+ // allow either a mul, shift, or constant here.
+ Value *NewIdx = 0;
+ ConstantInt *Scale = 0;
+ if (ArrayEltSize == 1) {
+ NewIdx = GEP.getOperand(1);
+ Scale = ConstantInt::get(NewIdx->getType(), 1);
+ } else if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP.getOperand(1))) {
+ NewIdx = ConstantInt::get(NewIdx->getType(), 1);
+ Scale = CI;
+ } else if (Instruction *Inst =dyn_cast<Instruction>(GEP.getOperand(1))){
+ if (Inst->getOpcode() == Instruction::Shl &&
+ isa<ConstantInt>(Inst->getOperand(1))) {
+ unsigned ShAmt =cast<ConstantUInt>(Inst->getOperand(1))->getValue();
+ if (Inst->getType()->isSigned())
+ Scale = ConstantSInt::get(Inst->getType(), 1ULL << ShAmt);
+ else
+ Scale = ConstantUInt::get(Inst->getType(), 1ULL << ShAmt);
+ NewIdx = Inst->getOperand(0);
+ } else if (Inst->getOpcode() == Instruction::Mul &&
+ isa<ConstantInt>(Inst->getOperand(1))) {
+ Scale = cast<ConstantInt>(Inst->getOperand(1));
+ NewIdx = Inst->getOperand(0);
+ }
+ }
+
+ // If the index will be to exactly the right offset with the scale taken
+ // out, perform the transformation.
+ if (Scale && Scale->getRawValue() % ArrayEltSize == 0) {
+ if (ConstantSInt *C = dyn_cast<ConstantSInt>(Scale))
+ Scale = ConstantSInt::get(C->getType(),
+ C->getRawValue()/(int64_t)ArrayEltSize);
+ else
+ Scale = ConstantUInt::get(Scale->getType(),
+ Scale->getRawValue() / ArrayEltSize);
+ if (Scale->getRawValue() != 1) {
+ Constant *C = ConstantExpr::getCast(Scale, NewIdx->getType());
+ Instruction *Sc = BinaryOperator::createMul(NewIdx, C, "idxscale");
+ NewIdx = InsertNewInstBefore(Sc, GEP);
+ }
+
+ // Insert the new GEP instruction.
+ Instruction *Idx =
+ new GetElementPtrInst(X, Constant::getNullValue(Type::IntTy),
+ NewIdx, GEP.getName());
+ Idx = InsertNewInstBefore(Idx, GEP);
+ return new CastInst(Idx, GEP.getType());
+ }
+ }
}
}
More information about the llvm-commits
mailing list