[llvm-commits] [llvm] r52315 - in /llvm/trunk: include/llvm/Analysis/ValueTracking.h lib/Analysis/ValueTracking.cpp lib/Transforms/Scalar/InstructionCombining.cpp

Matthijs Kooijman matthijs at stdin.nl
Mon Jun 16 05:48:21 PDT 2008


Author: matthijs
Date: Mon Jun 16 07:48:21 2008
New Revision: 52315

URL: http://llvm.org/viewvc/llvm-project?rev=52315&view=rev
Log:
Move FindScalarValue from InstructionCombining.cpp to ValueTracking.cpp. While
I'm at it, rename it to FindInsertedValue.

The only functional change is that newly created instructions are no longer
added to instcombine's worklist, but that is not really necessary anyway (and
I'll commit some improvements next that will completely remove the need).

Modified:
    llvm/trunk/include/llvm/Analysis/ValueTracking.h
    llvm/trunk/lib/Analysis/ValueTracking.cpp
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ValueTracking.h?rev=52315&r1=52314&r2=52315&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/ValueTracking.h (original)
+++ llvm/trunk/include/llvm/Analysis/ValueTracking.h Mon Jun 16 07:48:21 2008
@@ -17,6 +17,7 @@
 
 namespace llvm {
   class Value;
+  class Instruction;
   class APInt;
   class TargetData;
   
@@ -50,6 +51,14 @@
   /// value is never equal to -0.0.
   ///
   bool CannotBeNegativeZero(const Value *V, unsigned Depth = 0);
+
+  /// FindScalarValue - Given an aggregrate and an sequence of indices, see if the
+  /// scalar value indexed is already around as a register, for example if it were
+  /// inserted directly into the aggregrate.
+  Value *FindInsertedValue(Value *V,
+                         const unsigned *idx_begin,
+                         const unsigned *idx_end,
+                         Instruction &InsertBefore);
 } // end namespace llvm
 
 #endif

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=52315&r1=52314&r2=52315&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Mon Jun 16 07:48:21 2008
@@ -755,3 +755,131 @@
   return false;
 }
 
+// This is the recursive version of BuildSubAggregate. It takes a few different
+// arguments. Idxs is the index within the nested struct From that we are
+// looking at now (which is of type IndexedType). IdxSkip is the number of
+// indices from Idxs that should be left out when inserting into the resulting
+// struct. To is the result struct built so far, new insertvalue instructions
+// build on that.
+Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType,
+                                 SmallVector<unsigned, 10> &Idxs,
+                                 unsigned IdxSkip,
+                                 Instruction &InsertBefore) {
+  const llvm::StructType *STy = llvm::dyn_cast<llvm::StructType>(IndexedType);
+  if (STy) {
+    // General case, the type indexed by Idxs is a struct
+    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+      // Process each struct element recursively
+      Idxs.push_back(i);
+      To = BuildSubAggregate(From, To, STy->getElementType(i), Idxs, IdxSkip, InsertBefore);
+      Idxs.pop_back();
+    }
+    return To;
+  } else {
+    // Base case, the type indexed by SourceIdxs is not a struct
+    // Load the value from the nested struct into the sub struct (and skip
+    // IdxSkip indices when indexing the sub struct).
+    Instruction *V = llvm::ExtractValueInst::Create(From, Idxs.begin(), Idxs.end(), "tmp", &InsertBefore);
+    Instruction *Ins = llvm::InsertValueInst::Create(To, V, Idxs.begin() + IdxSkip, Idxs.end(), "tmp", &InsertBefore);
+    return Ins;
+  }
+}
+
+// This helper takes a nested struct and extracts a part of it (which is again a
+// struct) into a new value. For example, given the struct:
+// { a, { b, { c, d }, e } }
+// and the indices "1, 1" this returns
+// { c, d }.
+//
+// It does this by inserting an extractvalue and insertvalue for each element in
+// the resulting struct, as opposed to just inserting a single struct. This
+// allows for later folding of these individual extractvalue instructions with
+// insertvalue instructions that fill the nested struct.
+//
+// Any inserted instructions are inserted before InsertBefore
+Value *BuildSubAggregate(Value *From, const unsigned *idx_begin, const unsigned *idx_end, Instruction &InsertBefore) {
+  const Type *IndexedType = ExtractValueInst::getIndexedType(From->getType(), idx_begin, idx_end);
+  Value *To = UndefValue::get(IndexedType);
+  SmallVector<unsigned, 10> Idxs(idx_begin, idx_end);
+  unsigned IdxSkip = Idxs.size();
+
+  return BuildSubAggregate(From, To, IndexedType, Idxs, IdxSkip, InsertBefore);
+}
+
+/// FindInsertedValue - Given an aggregrate and an sequence of indices, see if the
+/// scalar value indexed is already around as a register, for example if it were
+/// inserted directly into the aggregrate.
+Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
+                         const unsigned *idx_end, Instruction &InsertBefore) {
+  // Nothing to index? Just return V then (this is useful at the end of our
+  // recursion)
+  if (idx_begin == idx_end)
+    return V;
+  // We have indices, so V should have an indexable type
+  assert((isa<StructType>(V->getType()) || isa<ArrayType>(V->getType()))
+         && "Not looking at a struct or array?");
+  assert(ExtractValueInst::getIndexedType(V->getType(), idx_begin, idx_end)
+         && "Invalid indices for type?");
+  const CompositeType *PTy = cast<CompositeType>(V->getType());
+  
+  if (isa<UndefValue>(V))
+    return UndefValue::get(ExtractValueInst::getIndexedType(PTy,
+                                                              idx_begin,
+                                                              idx_end));
+  else if (isa<ConstantAggregateZero>(V))
+    return Constant::getNullValue(ExtractValueInst::getIndexedType(PTy, 
+                                                                     idx_begin,
+                                                                     idx_end));
+  else if (Constant *C = dyn_cast<Constant>(V)) {
+    if (isa<ConstantArray>(C) || isa<ConstantStruct>(C))
+      // Recursively process this constant
+      return FindInsertedValue(C->getOperand(*idx_begin), ++idx_begin, idx_end, InsertBefore);
+  } else if (InsertValueInst *I = dyn_cast<InsertValueInst>(V)) {
+    // Loop the indices for the insertvalue instruction in parallel with the
+    // requested indices
+    const unsigned *req_idx = idx_begin;
+    for (const unsigned *i = I->idx_begin(), *e = I->idx_end(); i != e; ++i, ++req_idx) {
+      if (req_idx == idx_end)
+        // The requested index is a part of a nested aggregate. Handle this
+        // specially.
+        return BuildSubAggregate(V, idx_begin, req_idx, InsertBefore);
+      
+      // This insert value inserts something else than what we are looking for.
+      // See if the (aggregrate) value inserted into has the value we are
+      // looking for, then.
+      if (*req_idx != *i)
+        return FindInsertedValue(I->getAggregateOperand(), idx_begin, idx_end, InsertBefore);
+    }
+    // If we end up here, the indices of the insertvalue match with those
+    // requested (though possibly only partially). Now we recursively look at
+    // the inserted value, passing any remaining indices.
+    return FindInsertedValue(I->getInsertedValueOperand(), req_idx, idx_end, InsertBefore);
+  } else if (ExtractValueInst *I = dyn_cast<ExtractValueInst>(V)) {
+    // If we're extracting a value from an aggregrate that was extracted from
+    // something else, we can extract from that something else directly instead.
+    // However, we will need to chain I's indices with the requested indices.
+   
+    // Calculate the number of indices required 
+    unsigned size = I->getNumIndices() + (idx_end - idx_begin);
+    // Allocate some space to put the new indices in
+    unsigned *new_begin = new unsigned[size];
+    // Auto cleanup this array
+    std::auto_ptr<unsigned> newptr(new_begin);
+    // Start inserting at the beginning
+    unsigned *new_end = new_begin;
+    // Add indices from the extract value instruction
+    for (const unsigned *i = I->idx_begin(), *e = I->idx_end(); i != e; ++i, ++new_end)
+      *new_end = *i;
+    
+    // Add requested indices
+    for (const unsigned *i = idx_begin, *e = idx_end; i != e; ++i, ++new_end)
+      *new_end = *i;
+
+    assert((unsigned)(new_end - new_begin) == size && "Number of indices added not correct?");
+    
+    return FindInsertedValue(I->getAggregateOperand(), new_begin, new_end, InsertBefore);
+  }
+  // Otherwise, we don't know (such as, extracting from a function return value
+  // or load instruction)
+  return 0;
+}

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=52315&r1=52314&r2=52315&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Jun 16 07:48:21 2008
@@ -399,21 +399,6 @@
     unsigned GetOrEnforceKnownAlignment(Value *V,
                                         unsigned PrefAlign = 0);
 
-    // visitExtractValue helpers
-    Value *FindScalarValue(Value *V,
-                           const unsigned *idx_begin,
-                           const unsigned *idx_end,
-                           Instruction &InsertBefore);
-    Value *BuildSubAggregate(Value *From,
-                             const unsigned *idx_begin,
-                             const unsigned *idx_end,
-                             Instruction &InsertBefore);
-    Value *BuildSubAggregate(Value *From,
-                             Value* To,
-                             const Type *IndexedType,
-                             SmallVector<unsigned, 10> &Idxs,
-                             unsigned IdxSkip,
-                             Instruction &InsertBefore);
   };
 }
 
@@ -10533,140 +10518,9 @@
   return 0;
 }
 
-// This is the recursive version of BuildSubAggregate. It takes a few different
-// arguments. Idxs is the index within the nested struct From that we are
-// looking at now (which is of type IndexedType). IdxSkip is the number of
-// indices from Idxs that should be left out when inserting into the resulting
-// struct. To is the result struct built so far, new insertvalue instructions
-// build on that.
-Value *InstCombiner::BuildSubAggregate(Value *From, Value* To, const Type *IndexedType,
-                                 SmallVector<unsigned, 10> &Idxs,
-                                 unsigned IdxSkip,
-                                 Instruction &InsertBefore) {
-  const llvm::StructType *STy = llvm::dyn_cast<llvm::StructType>(IndexedType);
-  if (STy) {
-    // General case, the type indexed by Idxs is a struct
-    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
-      // Process each struct element recursively
-      Idxs.push_back(i);
-      To = BuildSubAggregate(From, To, STy->getElementType(i), Idxs, IdxSkip, InsertBefore);
-      Idxs.pop_back();
-    }
-    return To;
-  } else {
-    // Base case, the type indexed by SourceIdxs is not a struct
-    // Load the value from the nested struct into the sub struct (and skip
-    // IdxSkip indices when indexing the sub struct).
-    Instruction *V = llvm::ExtractValueInst::Create(From, Idxs.begin(), Idxs.end(), "tmp");
-    InsertNewInstBefore(V, InsertBefore);
-    Instruction *Ins = llvm::InsertValueInst::Create(To, V, Idxs.begin() + IdxSkip, Idxs.end(), "tmp");
-    InsertNewInstBefore(Ins, InsertBefore);
-    return Ins;
-  }
-}
-
-// This helper takes a nested struct and extracts a part of it (which is again a
-// struct) into a new value. For example, given the struct:
-// { a, { b, { c, d }, e } }
-// and the indices "1, 1" this returns
-// { c, d }.
-//
-// It does this by inserting an extractvalue and insertvalue for each element in
-// the resulting struct, as opposed to just inserting a single struct. This
-// allows for later folding of these individual extractvalue instructions with
-// insertvalue instructions that fill the nested struct.
-//
-// Any inserted instructions are inserted before InsertBefore
-Value *InstCombiner::BuildSubAggregate(Value *From, const unsigned *idx_begin, const unsigned *idx_end, Instruction &InsertBefore) {
-  const Type *IndexedType = ExtractValueInst::getIndexedType(From->getType(), idx_begin, idx_end);
-  Value *To = UndefValue::get(IndexedType);
-  SmallVector<unsigned, 10> Idxs(idx_begin, idx_end);
-  unsigned IdxSkip = Idxs.size();
-
-  return BuildSubAggregate(From, To, IndexedType, Idxs, IdxSkip, InsertBefore);
-}
-
-/// FindScalarValue - Given an aggregrate and an sequence of indices, see if the
-/// scalar value indexed is already around as a register, for example if it were
-/// inserted directly into the aggregrate.
-Value *InstCombiner::FindScalarValue(Value *V, const unsigned *idx_begin,
-                                const unsigned *idx_end, Instruction &InsertBefore) {
-  // Nothing to index? Just return V then (this is useful at the end of our
-  // recursion)
-  if (idx_begin == idx_end)
-    return V;
-  // We have indices, so V should have an indexable type
-  assert((isa<StructType>(V->getType()) || isa<ArrayType>(V->getType()))
-         && "Not looking at a struct or array?");
-  assert(ExtractValueInst::getIndexedType(V->getType(), idx_begin, idx_end)
-         && "Invalid indices for type?");
-  const CompositeType *PTy = cast<CompositeType>(V->getType());
-  
-  if (isa<UndefValue>(V))
-    return UndefValue::get(ExtractValueInst::getIndexedType(PTy,
-                                                              idx_begin,
-                                                              idx_end));
-  else if (isa<ConstantAggregateZero>(V))
-    return Constant::getNullValue(ExtractValueInst::getIndexedType(PTy, 
-                                                                     idx_begin,
-                                                                     idx_end));
-  else if (Constant *C = dyn_cast<Constant>(V)) {
-    if (isa<ConstantArray>(C) || isa<ConstantStruct>(C))
-      // Recursively process this constant
-      return FindScalarValue(C->getOperand(*idx_begin), ++idx_begin, idx_end, InsertBefore);
-  } else if (InsertValueInst *I = dyn_cast<InsertValueInst>(V)) {
-    // Loop the indices for the insertvalue instruction in parallel with the
-    // requested indices
-    const unsigned *req_idx = idx_begin;
-    for (const unsigned *i = I->idx_begin(), *e = I->idx_end(); i != e; ++i, ++req_idx) {
-      if (req_idx == idx_end)
-        // The requested index is a part of a nested aggregate. Handle this
-        // specially.
-        return BuildSubAggregate(V, idx_begin, req_idx, InsertBefore);
-      
-      // This insert value inserts something else than what we are looking for.
-      // See if the (aggregrate) value inserted into has the value we are
-      // looking for, then.
-      if (*req_idx != *i)
-        return FindScalarValue(I->getAggregateOperand(), idx_begin, idx_end, InsertBefore);
-    }
-    // If we end up here, the indices of the insertvalue match with those
-    // requested (though possibly only partially). Now we recursively look at
-    // the inserted value, passing any remaining indices.
-    return FindScalarValue(I->getInsertedValueOperand(), req_idx, idx_end, InsertBefore);
-  } else if (ExtractValueInst *I = dyn_cast<ExtractValueInst>(V)) {
-    // If we're extracting a value from an aggregrate that was extracted from
-    // something else, we can extract from that something else directly instead.
-    // However, we will need to chain I's indices with the requested indices.
-   
-    // Calculate the number of indices required 
-    unsigned size = I->getNumIndices() + (idx_end - idx_begin);
-    // Allocate some space to put the new indices in
-    unsigned *new_begin = new unsigned[size];
-    // Auto cleanup this array
-    std::auto_ptr<unsigned> newptr(new_begin);
-    // Start inserting at the beginning
-    unsigned *new_end = new_begin;
-    // Add indices from the extract value instruction
-    for (const unsigned *i = I->idx_begin(), *e = I->idx_end(); i != e; ++i, ++new_end)
-      *new_end = *i;
-    
-    // Add requested indices
-    for (const unsigned *i = idx_begin, *e = idx_end; i != e; ++i, ++new_end)
-      *new_end = *i;
-
-    assert((unsigned)(new_end - new_begin) == size && "Number of indices added not correct?");
-    
-    return FindScalarValue(I->getAggregateOperand(), new_begin, new_end, InsertBefore);
-  }
-  // Otherwise, we don't know (such as, extracting from a function return value
-  // or load instruction)
-  return 0;
-}
-
 Instruction *InstCombiner::visitExtractValueInst(ExtractValueInst &EV) {
   // See if we are trying to extract a known value. If so, use that instead.
-  if (Value *Elt = FindScalarValue(EV.getOperand(0), EV.idx_begin(), EV.idx_end(), EV))
+  if (Value *Elt = FindInsertedValue(EV.getOperand(0), EV.idx_begin(), EV.idx_end(), EV))
     return ReplaceInstUsesWith(EV, Elt);
 
   // No changes





More information about the llvm-commits mailing list