Move FindScalarValue from InstructionCombining.cpp to ValueTracking.cpp. While
authorMatthijs Kooijman <matthijs@stdin.nl>
Mon, 16 Jun 2008 12:48:21 +0000 (12:48 +0000)
committerMatthijs Kooijman <matthijs@stdin.nl>
Mon, 16 Jun 2008 12:48:21 +0000 (12:48 +0000)
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).

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

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

index ca8d3e39c7b006efdcb653dace0c325f60440876..df59c703a57aa589cc109fe27476ea9ef7cbdac3 100644 (file)
@@ -17,6 +17,7 @@
 
 namespace llvm {
   class Value;
+  class Instruction;
   class APInt;
   class TargetData;
   
@@ -50,6 +51,14 @@ namespace llvm {
   /// 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
index 78a9c77c3fa6f989c565640dde6eb426747261d5..7925d2756463f6a3c84c08bf6980f275de5972ef 100644 (file)
@@ -755,3 +755,131 @@ bool llvm::CannotBeNegativeZero(const Value *V, unsigned Depth) {
   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;
+}
index 8a7128bf65c329d94354dfb7350083e673b49471..4f6783b8858c09621b5f38b9f0aaf9c7b058941a 100644 (file)
@@ -399,21 +399,6 @@ namespace {
     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 @@ Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) {
   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