Change Value::getUnderlyingObject to have the MaxLookup value specified as a
authorBob Wilson <bob.wilson@apple.com>
Mon, 25 Jan 2010 18:26:54 +0000 (18:26 +0000)
committerBob Wilson <bob.wilson@apple.com>
Mon, 25 Jan 2010 18:26:54 +0000 (18:26 +0000)
parameter with a default value, instead of just hardcoding it in the
implementation.  The limit of MaxLookup = 6 was introduced in r69151 to fix
a performance problem with O(n^2) behavior in instcombine, but the scalarrepl
pass is relying on getUnderlyingObject to go all the way back to an AllocaInst.
Making the limit part of the method signature makes it clear that by default
the result is limited and should help avoid similar problems in the future.
This fixes pr6126.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94433 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Value.h
lib/Transforms/Scalar/ScalarReplAggregates.cpp
lib/VMCore/Value.cpp

index f0bd8bea1ede4404e86db541a2ab370c7a949036..9045906e7bee6b2468d0eff2958b3a8c39406b67 100644 (file)
@@ -285,10 +285,11 @@ public:
   /// getUnderlyingObject - This method strips off any GEP address adjustments
   /// and pointer casts from the specified value, returning the original object
   /// being addressed.  Note that the returned value has pointer type if the
-  /// specified value does.
-  Value *getUnderlyingObject();
-  const Value *getUnderlyingObject() const {
-    return const_cast<Value*>(this)->getUnderlyingObject();
+  /// specified value does.  If the MaxLookup value is non-zero, it limits the
+  /// number of instructions to be stripped off.
+  Value *getUnderlyingObject(unsigned MaxLookup = 6);
+  const Value *getUnderlyingObject(unsigned MaxLookup = 6) const {
+    return const_cast<Value*>(this)->getUnderlyingObject(MaxLookup);
   }
   
   /// DoPHITranslation - If this value is a PHI node with CurBB as its parent,
index f4734801e0f8eac3b92121350d0802bfa7c6ca58..1cf486bbdfaca883cd6ab97a5618cd43c2379b0e 100644 (file)
@@ -1384,9 +1384,9 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) {
       // If the source and destination are both to the same alloca, then this is
       // a noop copy-to-self, just delete it.  Otherwise, emit a load and store
       // as appropriate.
-      AllocaInst *OrigAI = cast<AllocaInst>(Ptr->getUnderlyingObject());
+      AllocaInst *OrigAI = cast<AllocaInst>(Ptr->getUnderlyingObject(0));
       
-      if (MTI->getSource()->getUnderlyingObject() != OrigAI) {
+      if (MTI->getSource()->getUnderlyingObject(0) != OrigAI) {
         // Dest must be OrigAI, change this to be a load from the original
         // pointer (bitcasted), then a store to our new alloca.
         assert(MTI->getRawDest() == Ptr && "Neither use is of pointer?");
@@ -1396,7 +1396,7 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) {
         LoadInst *SrcVal = Builder.CreateLoad(SrcPtr, "srcval");
         SrcVal->setAlignment(MTI->getAlignment());
         Builder.CreateStore(SrcVal, NewAI);
-      } else if (MTI->getDest()->getUnderlyingObject() != OrigAI) {
+      } else if (MTI->getDest()->getUnderlyingObject(0) != OrigAI) {
         // Src must be OrigAI, change this to be a load from NewAI then a store
         // through the original dest pointer (bitcasted).
         assert(MTI->getRawSource() == Ptr && "Neither use is of pointer?");
index 40679bfc290498fa71b4a1d546450a1fe84a3763..3759b8a7cbb4865dc171ba898f5270b1d5ae09c2 100644 (file)
@@ -341,12 +341,11 @@ Value *Value::stripPointerCasts() {
   } while (1);
 }
 
-Value *Value::getUnderlyingObject() {
+Value *Value::getUnderlyingObject(unsigned MaxLookup) {
   if (!isa<PointerType>(getType()))
     return this;
   Value *V = this;
-  unsigned MaxLookup = 6;
-  do {
+  for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) {
     if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
       V = GEP->getPointerOperand();
     } else if (Operator::getOpcode(V) == Instruction::BitCast) {
@@ -359,7 +358,7 @@ Value *Value::getUnderlyingObject() {
       return V;
     }
     assert(isa<PointerType>(V->getType()) && "Unexpected operand type!");
-  } while (--MaxLookup);
+  }
   return V;
 }