summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-09-13 18:36:04 +0000
committerChris Lattner <sabre@nondot.org>2005-09-13 18:36:04 +0000
commit2a8932960d14bc80abb31d3571997d4d400e49eb (patch)
tree8b4c5778fbf92cbfae66604624ef06264866da62 /llvm
parentfd018c8dfe1ce6e134af86af01c8d5b6e5534206 (diff)
downloadbcm5719-llvm-2a8932960d14bc80abb31d3571997d4d400e49eb.tar.gz
bcm5719-llvm-2a8932960d14bc80abb31d3571997d4d400e49eb.zip
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. llvm-svn: 23328
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp64
1 files changed, 62 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 9e75be7b95a..a1095406181 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -4718,8 +4718,8 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
}
} 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 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
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());
+ }
+ }
}
}
OpenPOWER on IntegriCloud