summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMehdi Amini <mehdi.amini@apple.com>2015-01-14 05:33:01 +0000
committerMehdi Amini <mehdi.amini@apple.com>2015-01-14 05:33:01 +0000
commit8923cc5470a1a6c728c800a409d1c6c86d52825a (patch)
tree56089b2fdf800645dc970b329c3a6932f1fcd790
parenteeea8970b4b12b5493d603ceff960e4b19296c1f (diff)
downloadbcm5719-llvm-8923cc5470a1a6c728c800a409d1c6c86d52825a.tar.gz
bcm5719-llvm-8923cc5470a1a6c728c800a409d1c6c86d52825a.zip
Fold a loop for array processing in ComputeLinearIndex
When processing an array, every Elt has the same layout, it is useless to recursively call each ComputeLinearIndex on each element. Just do it once and multiply by the number of elements. Differential Revision: http://reviews.llvm.org/D6832 llvm-svn: 225949
-rw-r--r--llvm/include/llvm/CodeGen/Analysis.h17
-rw-r--r--llvm/lib/CodeGen/Analysis.cpp21
2 files changed, 27 insertions, 11 deletions
diff --git a/llvm/include/llvm/CodeGen/Analysis.h b/llvm/include/llvm/CodeGen/Analysis.h
index 3132999dde4..c4b94ede4f5 100644
--- a/llvm/include/llvm/CodeGen/Analysis.h
+++ b/llvm/include/llvm/CodeGen/Analysis.h
@@ -31,10 +31,21 @@ class SDValue;
class SelectionDAG;
struct EVT;
-/// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence
-/// of insertvalue or extractvalue indices that identify a member, return
-/// the linearized index of the start of the member.
+/// \brief Compute the linearized index of a member in a nested
+/// aggregate/struct/array.
///
+/// Given an LLVM IR aggregate type and a sequence of insertvalue or
+/// extractvalue indices that identify a member, return the linearized index of
+/// the start of the member, i.e the number of element in memory before the
+/// seeked one. This is disconnected from the number of bytes.
+///
+/// \param Ty is the type indexed by \p Indices.
+/// \param Indices is an optional pointer in the indices list to the current
+/// index.
+/// \param IndicesEnd is the end of the indices list.
+/// \param CurIndex is the current index in the recursion.
+///
+/// \returns \p CurIndex plus the linear index in \p Ty the indices list.
unsigned ComputeLinearIndex(Type *Ty,
const unsigned *Indices,
const unsigned *IndicesEnd,
diff --git a/llvm/lib/CodeGen/Analysis.cpp b/llvm/lib/CodeGen/Analysis.cpp
index 9a3b7905e4a..06826b69827 100644
--- a/llvm/lib/CodeGen/Analysis.cpp
+++ b/llvm/lib/CodeGen/Analysis.cpp
@@ -30,10 +30,9 @@
using namespace llvm;
-/// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence
-/// of insertvalue or extractvalue indices that identify a member, return
-/// the linearized index of the start of the member.
-///
+/// Compute the linearized index of a member in a nested aggregate/struct/array
+/// by recursing and accumulating CurIndex as long as there are indices in the
+/// index list.
unsigned llvm::ComputeLinearIndex(Type *Ty,
const unsigned *Indices,
const unsigned *IndicesEnd,
@@ -57,11 +56,17 @@ unsigned llvm::ComputeLinearIndex(Type *Ty,
// Given an array type, recursively traverse the elements.
else if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
Type *EltTy = ATy->getElementType();
- for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) {
- if (Indices && *Indices == i)
- return ComputeLinearIndex(EltTy, Indices+1, IndicesEnd, CurIndex);
- CurIndex = ComputeLinearIndex(EltTy, nullptr, nullptr, CurIndex);
+ unsigned NumElts = ATy->getNumElements();
+ // Compute the Linear offset when jumping one element of the array
+ unsigned EltLinearOffset = ComputeLinearIndex(EltTy, nullptr, nullptr, 0);
+ if (Indices && *Indices < NumElts) {
+ // If the indice is inside the array, compute the index to the requested
+ // elt and recurse inside the element with the end of the indices list
+ CurIndex += EltLinearOffset* *Indices;
+ return ComputeLinearIndex(EltTy, Indices+1, IndicesEnd, CurIndex);
}
+ // Out of bound? Assert instead?
+ CurIndex += EltLinearOffset*NumElts;
return CurIndex;
}
// We haven't found the type we're looking for, so keep searching.
OpenPOWER on IntegriCloud