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

Chris Lattner lattner at cs.uiuc.edu
Sun Jan 30 20:50:59 PST 2005



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.312 -> 1.313
---
Log message:

Implement Transforms/InstCombine/cast-load-gep.ll, which allows us to devirtualize
11 indirect calls in perlbmk.


---
Diffs of the changes:  (+29 -15)

 InstructionCombining.cpp |   44 +++++++++++++++++++++++++++++---------------
 1 files changed, 29 insertions(+), 15 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.312 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.313
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.312	Fri Jan 28 18:39:08 2005
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Sun Jan 30 22:50:46 2005
@@ -4623,24 +4623,38 @@
 
 static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI) {
   User *CI = cast<User>(LI.getOperand(0));
+  Value *CastOp = CI->getOperand(0);
 
   const Type *DestPTy = cast<PointerType>(CI->getType())->getElementType();
-  if (const PointerType *SrcTy =
-      dyn_cast<PointerType>(CI->getOperand(0)->getType())) {
+  if (const PointerType *SrcTy = dyn_cast<PointerType>(CastOp->getType())) {
     const Type *SrcPTy = SrcTy->getElementType();
-    if (SrcPTy->isSized() && DestPTy->isSized() &&
-        IC.getTargetData().getTypeSize(SrcPTy) == 
-            IC.getTargetData().getTypeSize(DestPTy) &&
-        (SrcPTy->isInteger() || isa<PointerType>(SrcPTy)) &&
-        (DestPTy->isInteger() || isa<PointerType>(DestPTy))) {
-      // Okay, we are casting from one integer or pointer type to another of
-      // the same size.  Instead of casting the pointer before the load, cast
-      // the result of the loaded value.
-      Value *NewLoad = IC.InsertNewInstBefore(new LoadInst(CI->getOperand(0),
-                                                           CI->getName(),
-                                                           LI.isVolatile()),LI);
-      // Now cast the result of the load.
-      return new CastInst(NewLoad, LI.getType());
+
+    if (DestPTy->isInteger() || isa<PointerType>(DestPTy)) {
+      // If the source is an array, the code below will not succeed.  Check to
+      // see if a trivial 'gep P, 0, 0' will help matters.  Only do this for
+      // constants.
+      if (const ArrayType *ASrcTy = dyn_cast<ArrayType>(SrcPTy))
+        if (Constant *CSrc = dyn_cast<Constant>(CastOp))
+          if (ASrcTy->getNumElements() != 0) {
+            std::vector<Value*> Idxs(2, Constant::getNullValue(Type::IntTy));
+            CastOp = ConstantExpr::getGetElementPtr(CSrc, Idxs);
+            SrcTy = cast<PointerType>(CastOp->getType());
+            SrcPTy = SrcTy->getElementType();
+          }
+
+      if ((SrcPTy->isInteger() || isa<PointerType>(SrcPTy)) &&
+          IC.getTargetData().getTypeSize(SrcPTy) == 
+               IC.getTargetData().getTypeSize(DestPTy)) {
+          
+        // Okay, we are casting from one integer or pointer type to another of
+        // the same size.  Instead of casting the pointer before the load, cast
+        // the result of the loaded value.
+        Value *NewLoad = IC.InsertNewInstBefore(new LoadInst(CastOp,
+                                                             CI->getName(),
+                                                         LI.isVolatile()),LI);
+        // Now cast the result of the load.
+        return new CastInst(NewLoad, LI.getType());
+      }
     }
   }
   return 0;






More information about the llvm-commits mailing list