[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