Handle more complex array indexing expressions
authorChris Lattner <sabre@nondot.org>
Wed, 5 Dec 2001 19:41:16 +0000 (19:41 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 5 Dec 2001 19:41:16 +0000 (19:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1424 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/TransformInternals.cpp

index 5fdffda908de6dbb826095fcc122a26ac49492bb..c12fe6930faa1eb05d6eb9e3577e29fe9fb9c197 100644 (file)
@@ -180,26 +180,59 @@ const Type *ConvertableToGEP(const Type *Ty, Value *OffsetVal,
       unsigned ElSize = TD.getTypeSize(ElTy);
 
       // See if the user is indexing into a different cell of this array...
-      if (Offset >= ElSize) {
-        // Calculate the index that we are entering into the array cell with
-        unsigned Index = Offset/ElSize;
-        Indices.push_back(ConstantUInt::get(Type::UIntTy, Index));
-        Offset -= Index*ElSize;               // Consume part of the offset
+      if (Scale && Scale >= ElSize) {
+        // A scale n*ElSize might occur if we are not stepping through
+        // array by one.  In this case, we will have to insert math to munge
+        // the index.
+        //
+        unsigned ScaleAmt = Scale/ElSize;
+        if (Scale-ScaleAmt*ElSize)
+          return 0;  // Didn't scale by a multiple of element size, bail out
+        Scale = ElSize;        
 
-      } else if (Scale && Scale != 1) {
-        // Must be indexing into this element with a variable...
-        if (Scale != ElSize)
-          return 0;  // Type must not be finished yet...
+        unsigned Index = Offset/ElSize;       // is zero unless Offset > ElSize
+        Offset -= Index*ElSize;               // Consume part of the offset
 
-        if (Expr.Var->getType() != Type::UIntTy && BI) {
+        if (BI) {              // Generate code?
           BasicBlock *BB = (**BI)->getParent();
-          CastInst *IdxCast = new CastInst(Expr.Var, Type::UIntTy);
-          *BI = BB->getInstList().insert(*BI, IdxCast)+1;
-          Expr.Var = IdxCast;
-        }        
+          if (Expr.Var->getType() != Type::UIntTy) {
+            CastInst *IdxCast = new CastInst(Expr.Var, Type::UIntTy);
+            if (Expr.Var->hasName())
+              IdxCast->setName(Expr.Var->getName()+"-idxcast");
+            *BI = BB->getInstList().insert(*BI, IdxCast)+1;
+            Expr.Var = IdxCast;
+          }
+
+          if (Scale > ElSize) {  // If we have to scale up our index, do so now
+            Value *ScaleAmtVal = ConstantUInt::get(Type::UIntTy, ScaleAmt);
+            Instruction *Scaler = BinaryOperator::create(Instruction::Mul,
+                                                         Expr.Var,ScaleAmtVal);
+            if (Expr.Var->hasName())
+              Scaler->setName(Expr.Var->getName()+"-scale");
+
+            *BI = BB->getInstList().insert(*BI, Scaler)+1;
+            Expr.Var = Scaler;
+          }
+
+          if (Index) {  // Add an offset to the index
+            Value *IndexAmt = ConstantUInt::get(Type::UIntTy, Index);
+            Instruction *Offseter = BinaryOperator::create(Instruction::Add,
+                                                           Expr.Var, IndexAmt);
+            if (Expr.Var->hasName())
+              Offseter->setName(Expr.Var->getName()+"-offset");
+            *BI = BB->getInstList().insert(*BI, Offseter)+1;
+            Expr.Var = Offseter;
+          }
+        }
 
         Indices.push_back(Expr.Var);
         Scale = 0;  // Consume scale factor!
+      } else if (Offset >= ElSize) {
+        // Calculate the index that we are entering into the array cell with
+        unsigned Index = Offset/ElSize;
+        Indices.push_back(ConstantUInt::get(Type::UIntTy, Index));
+        Offset -= Index*ElSize;               // Consume part of the offset
+
       } else {
         // Must be indexing a small amount into the first cell of the array
         // Just index into element zero of the array here.