[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp LowerInvoke.cpp SCCP.cpp ScalarReplAggregates.cpp

Chris Lattner lattner at cs.uiuc.edu
Sun Apr 4 20:30:37 PDT 2004


Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.176 -> 1.177
LowerInvoke.cpp updated: 1.14 -> 1.15
SCCP.cpp updated: 1.92 -> 1.93
ScalarReplAggregates.cpp updated: 1.20 -> 1.21

---
Log message:

Support getelementptr instructions which use uint's to index into structure 
types and can have arbitrary 32- and 64-bit integer types indexing into
sequential types.


---
Diffs of the changes:  (+117 -30)

Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.176 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.177
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.176	Tue Mar 30 13:37:13 2004
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Sun Apr  4 20:29:05 2004
@@ -44,9 +44,10 @@
 #include "llvm/Target/TargetData.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/InstIterator.h"
 #include "llvm/Support/InstVisitor.h"
-#include "llvm/Support/CallSite.h"
 #include "Support/Debug.h"
 #include "Support/Statistic.h"
 #include <algorithm>
@@ -92,6 +93,8 @@
       AU.setPreservesCFG();
     }
 
+    TargetData &getTargetData() const { return *TD; }
+
     // Visitation implementation - Implement instruction combining for different
     // instruction types.  The semantics are as follows:
     // Return Value:
@@ -127,6 +130,7 @@
     Instruction *visitCallSite(CallSite CS);
     bool transformConstExprCastCall(CallSite CS);
 
+  public:
     // InsertNewInstBefore - insert an instruction New before instruction Old
     // in the program.  Add the new instruction to the worklist.
     //
@@ -139,7 +143,6 @@
       return New;
     }
 
-  public:
     // ReplaceInstUsesWith - This method is to be used when an instruction is
     // found to be dead, replacable with another preexisting expression.  Here
     // we add all uses of I to the worklist, replace all uses of I with the new
@@ -2272,6 +2275,20 @@
   return 0;
 }
 
+static Value *InsertSignExtendToPtrTy(Value *V, const Type *DTy,
+                                      Instruction *InsertPoint,
+                                      InstCombiner *IC) {
+  unsigned PS = IC->getTargetData().getPointerSize();
+  const Type *VTy = V->getType();
+  Instruction *Cast;
+  if (!VTy->isSigned() && VTy->getPrimitiveSize() < PS)
+    // We must insert a cast to ensure we sign-extend.
+    V = IC->InsertNewInstBefore(new CastInst(V, VTy->getSignedVersion(),
+                                             V->getName()), *InsertPoint);
+  return IC->InsertNewInstBefore(new CastInst(V, DTy, V->getName()),
+                                 *InsertPoint);
+}
+
 
 Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
   // Is it 'getelementptr %P, long 0'  or 'getelementptr %P'
@@ -2286,6 +2303,37 @@
   if (GEP.getNumOperands() == 2 && HasZeroPointerIndex)
     return ReplaceInstUsesWith(GEP, GEP.getOperand(0));
 
+  // Eliminate unneeded casts for indices.
+  bool MadeChange = false;
+  for (unsigned i = 1, e = GEP.getNumOperands(); i != e; ++i)
+    if (CastInst *CI = dyn_cast<CastInst>(GEP.getOperand(i))) {
+      Value *Src = CI->getOperand(0);
+      const Type *SrcTy = Src->getType();
+      const Type *DestTy = CI->getType();
+      if (Src->getType()->isInteger()) {
+        if (SrcTy->getPrimitiveSize() == DestTy->getPrimitiveSize()) {
+          // We can always eliminate a cast from ulong or long to the other.  We
+          // can always eliminate a cast from uint to int or the other on 32-bit
+          // pointer platforms.
+          if (DestTy->getPrimitiveSize() >= TD->getPointerSize()) {
+            MadeChange = true;
+            GEP.setOperand(i, Src);
+          }
+        } else if (SrcTy->getPrimitiveSize() < DestTy->getPrimitiveSize() &&
+                   SrcTy->getPrimitiveSize() == 4) {
+          // We can always eliminate a cast from int to [u]long.  We can
+          // eliminate a cast from uint to [u]long iff the target is a 32-bit
+          // pointer target.
+          if (SrcTy->isSigned() || 
+              SrcTy->getPrimitiveSize() >= TD->getPointerSize()) {
+            MadeChange = true;
+            GEP.setOperand(i, Src);
+          }
+        }
+      }
+    }
+  if (MadeChange) return &GEP;
+
   // Combine Indices - If the source pointer to this getelementptr instruction
   // is a getelementptr instruction, combine the indices of the two
   // getelementptr instructions into a single instruction.
@@ -2304,14 +2352,17 @@
     // Can we combine the two pointer arithmetics offsets?
     if (SrcGEPOperands.size() == 2 && isa<Constant>(SrcGEPOperands[1]) &&
         isa<Constant>(GEP.getOperand(1))) {
+      Constant *SGC = cast<Constant>(SrcGEPOperands[1]);
+      Constant *GC  = cast<Constant>(GEP.getOperand(1));
+      if (SGC->getType() != GC->getType()) {
+        SGC = ConstantExpr::getSignExtend(SGC, Type::LongTy);
+        GC = ConstantExpr::getSignExtend(GC, Type::LongTy);
+      }
+      
       // Replace: gep (gep %P, long C1), long C2, ...
       // With:    gep %P, long (C1+C2), ...
-      Value *Sum = ConstantExpr::get(Instruction::Add,
-                                     cast<Constant>(SrcGEPOperands[1]),
-                                     cast<Constant>(GEP.getOperand(1)));
-      assert(Sum && "Constant folding of longs failed!?");
       GEP.setOperand(0, SrcGEPOperands[0]);
-      GEP.setOperand(1, Sum);
+      GEP.setOperand(1, ConstantExpr::getAdd(SGC, GC));
       if (Instruction *I = dyn_cast<Instruction>(GEP.getOperand(0)))
         AddUsersToWorkList(*I);   // Reduce use count of Src
       return &GEP;
@@ -2327,29 +2378,65 @@
           cast<Instruction>(SrcGEPOperands[0])->getNumOperands() == 2)
         return 0;   // Wait until our source is folded to completion.
 
-      Value *Sum = BinaryOperator::create(Instruction::Add, SrcGEPOperands[1],
-                                          GEP.getOperand(1),
-                                          GEP.getOperand(0)->getName()+".sum",
-                                          &GEP);
+      Value *Sum, *SO1 = SrcGEPOperands[1], *GO1 = GEP.getOperand(1);
+      if (SO1 == Constant::getNullValue(SO1->getType())) {
+        Sum = GO1;
+      } else if (GO1 == Constant::getNullValue(GO1->getType())) {
+        Sum = SO1;
+      } else {
+        // If they aren't the same type, convert both to an integer of the
+        // target's pointer size.
+        if (SO1->getType() != GO1->getType()) {
+          if (Constant *SO1C = dyn_cast<Constant>(SO1)) {
+            SO1 = ConstantExpr::getCast(SO1C, GO1->getType());
+          } else if (Constant *GO1C = dyn_cast<Constant>(GO1)) {
+            GO1 = ConstantExpr::getCast(GO1C, SO1->getType());
+          } else {
+            unsigned PS = TD->getPointerSize();
+            Instruction *Cast;
+            if (SO1->getType()->getPrimitiveSize() == PS) {
+              // Convert GO1 to SO1's type.
+              GO1 = InsertSignExtendToPtrTy(GO1, SO1->getType(), &GEP, this);
+
+            } else if (GO1->getType()->getPrimitiveSize() == PS) {
+              // Convert SO1 to GO1's type.
+              SO1 = InsertSignExtendToPtrTy(SO1, GO1->getType(), &GEP, this);
+            } else {
+              const Type *PT = TD->getIntPtrType();
+              SO1 = InsertSignExtendToPtrTy(SO1, PT, &GEP, this);
+              GO1 = InsertSignExtendToPtrTy(GO1, PT, &GEP, this);
+            }
+          }
+        }
+        Sum = BinaryOperator::create(Instruction::Add, SO1, GO1,
+                                     GEP.getOperand(0)->getName()+".sum", &GEP);
+      }
       GEP.setOperand(0, SrcGEPOperands[0]);
       GEP.setOperand(1, Sum);
       WorkList.push_back(cast<Instruction>(Sum));
       return &GEP;
-    } else if (*GEP.idx_begin() == Constant::getNullValue(Type::LongTy) &&
+    } else if (isa<Constant>(*GEP.idx_begin()) && 
+               cast<Constant>(*GEP.idx_begin())->isNullValue() &&
                SrcGEPOperands.size() != 1) { 
       // Otherwise we can do the fold if the first index of the GEP is a zero
       Indices.insert(Indices.end(), SrcGEPOperands.begin()+1,
                      SrcGEPOperands.end());
       Indices.insert(Indices.end(), GEP.idx_begin()+1, GEP.idx_end());
-    } else if (SrcGEPOperands.back() == Constant::getNullValue(Type::LongTy)) {
-      // FIXME: when we allow indices to be non-long values, support this for
-      // other types!
-
-      // If the src gep ends with a constant array index, merge this get into
-      // it, even if we have a non-zero array index.
-      Indices.insert(Indices.end(), SrcGEPOperands.begin()+1,
-                     SrcGEPOperands.end()-1);
-      Indices.insert(Indices.end(), GEP.idx_begin(), GEP.idx_end());
+    } else if (SrcGEPOperands.back() ==
+               Constant::getNullValue(SrcGEPOperands.back()->getType())) {
+      // We have to check to make sure this really is an ARRAY index we are
+      // ending up with, not a struct index.
+      generic_gep_type_iterator<std::vector<Value*>::iterator>
+        GTI = gep_type_begin(SrcGEPOperands[0]->getType(),
+                             SrcGEPOperands.begin()+1, SrcGEPOperands.end());
+      std::advance(GTI, SrcGEPOperands.size()-2);
+      if (isa<SequentialType>(*GTI)) {
+        // If the src gep ends with a constant array index, merge this get into
+        // it, even if we have a non-zero array index.
+        Indices.insert(Indices.end(), SrcGEPOperands.begin()+1,
+                       SrcGEPOperands.end()-1);
+        Indices.insert(Indices.end(), GEP.idx_begin(), GEP.idx_end());
+      }
     }
 
     if (!Indices.empty())
@@ -2428,7 +2515,7 @@
       // Now that I is pointing to the first non-allocation-inst in the block,
       // insert our getelementptr instruction...
       //
-      std::vector<Value*> Idx(2, Constant::getNullValue(Type::LongTy));
+      std::vector<Value*> Idx(2, Constant::getNullValue(Type::IntTy));
       Value *V = new GetElementPtrInst(New, Idx, New->getName()+".sub", It);
 
       // Now make everything use the getelementptr instead of the original
@@ -2469,7 +2556,7 @@
 /// expression, or null if something is funny.
 ///
 static Constant *GetGEPGlobalInitializer(Constant *C, ConstantExpr *CE) {
-  if (CE->getOperand(1) != Constant::getNullValue(Type::LongTy))
+  if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType()))
     return 0;  // Do not allow stepping over the value!
 
   // Loop over all of the operands, tracking down which value we are


Index: llvm/lib/Transforms/Scalar/LowerInvoke.cpp
diff -u llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.14 llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.15
--- llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.14	Wed Mar 31 16:00:30 2004
+++ llvm/lib/Transforms/Scalar/LowerInvoke.cpp	Sun Apr  4 20:29:05 2004
@@ -277,14 +277,14 @@
       // Store this old value as our 'next' field, and store our alloca as the
       // current jblist.
       std::vector<Value*> Idx;
-      Idx.push_back(Constant::getNullValue(Type::LongTy));
-      Idx.push_back(ConstantUInt::get(Type::UByteTy, 0));
+      Idx.push_back(Constant::getNullValue(Type::IntTy));
+      Idx.push_back(ConstantUInt::get(Type::UIntTy, 0));
       Value *NextFieldPtr = new GetElementPtrInst(JmpBuf, Idx, "NextField", II);
       new StoreInst(OldEntry, NextFieldPtr, II);
       new StoreInst(JmpBuf, JBListHead, II);
       
       // Call setjmp, passing in the address of the jmpbuffer.
-      Idx[1] = ConstantUInt::get(Type::UByteTy, 1);
+      Idx[1] = ConstantUInt::get(Type::UIntTy, 1);
       Value *JmpBufPtr = new GetElementPtrInst(JmpBuf, Idx, "TheJmpBuf", II);
       Value *SJRet = new CallInst(SetJmpFn, JmpBufPtr, "sjret", II);
 
@@ -369,14 +369,14 @@
     // JBList.
     std::vector<Value*> Idx;
     Idx.push_back(Constant::getNullValue(Type::LongTy));
-    Idx.push_back(ConstantUInt::get(Type::UByteTy, 0));
+    Idx.push_back(ConstantUInt::get(Type::UIntTy, 0));
     Value *NextFieldPtr = new GetElementPtrInst(RecPtr, Idx, "NextField", RI);
     Value *NextRec = new LoadInst(NextFieldPtr, "NextRecord", RI);
     new StoreInst(NextRec, JBListHead, RI);
 
     // Now that we popped the top of the JBList, get a pointer to the jmpbuf and
     // longjmp.
-    Idx[1] = ConstantUInt::get(Type::UByteTy, 1);
+    Idx[1] = ConstantUInt::get(Type::UIntTy, 1);
     Idx[0] = new GetElementPtrInst(RecPtr, Idx, "JmpBuf", RI);
     Idx[1] = ConstantInt::get(Type::IntTy, 1);
     new CallInst(LongJmpFn, Idx, "", RI);


Index: llvm/lib/Transforms/Scalar/SCCP.cpp
diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.92 llvm/lib/Transforms/Scalar/SCCP.cpp:1.93
--- llvm/lib/Transforms/Scalar/SCCP.cpp:1.92	Tue Mar 16 13:49:59 2004
+++ llvm/lib/Transforms/Scalar/SCCP.cpp	Sun Apr  4 20:29:05 2004
@@ -712,7 +712,7 @@
 /// null if something is funny.
 ///
 static Constant *GetGEPGlobalInitializer(Constant *C, ConstantExpr *CE) {
-  if (CE->getOperand(1) != Constant::getNullValue(Type::LongTy))
+  if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType()))
     return 0;  // Do not allow stepping over the value!
 
   // Loop over all of the operands, tracking down which value we are


Index: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
diff -u llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.20 llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.21
--- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.20	Tue Dec  2 11:43:55 2003
+++ llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp	Sun Apr  4 20:29:05 2004
@@ -193,7 +193,7 @@
           //
           std::string OldName = GEPI->getName();  // Steal the old name...
           std::vector<Value*> NewArgs;
-          NewArgs.push_back(Constant::getNullValue(Type::LongTy));
+          NewArgs.push_back(Constant::getNullValue(Type::IntTy));
           NewArgs.insert(NewArgs.end(), GEPI->op_begin()+3, GEPI->op_end());
           GEPI->setName("");
           RepValue =





More information about the llvm-commits mailing list