From 1e6810005f426798ce2541c26f0cdc7a08670846 Mon Sep 17 00:00:00 2001 From: Will Dietz Date: Wed, 16 Oct 2013 04:10:06 +0000 Subject: [PATCH] TypeFinder: prefer iterative algorithm to keep stack usage low. Introduce subtype_reverse_iterator to maintain the numbering assigned during the recursive type walk. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192770 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/Type.h | 8 ++++++++ lib/IR/TypeFinder.cpp | 26 +++++++++++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h index 1bf8789d307..3cfb84edd82 100644 --- a/include/llvm/IR/Type.h +++ b/include/llvm/IR/Type.h @@ -324,6 +324,14 @@ public: subtype_iterator subtype_begin() const { return ContainedTys; } subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];} + typedef std::reverse_iterator subtype_reverse_iterator; + subtype_reverse_iterator subtype_rbegin() const { + return subtype_reverse_iterator(subtype_end()); + } + subtype_reverse_iterator subtype_rend() const { + return subtype_reverse_iterator(subtype_begin()); + } + /// getContainedType - This method is used to implement the type iterator /// (defined a the end of the file). For derived types, this returns the /// types 'contained' in the derived type. diff --git a/lib/IR/TypeFinder.cpp b/lib/IR/TypeFinder.cpp index dd933026ea7..689b9038913 100644 --- a/lib/IR/TypeFinder.cpp +++ b/lib/IR/TypeFinder.cpp @@ -94,19 +94,27 @@ void TypeFinder::clear() { /// incorporateType - This method adds the type to the list of used structures /// if it's not in there already. void TypeFinder::incorporateType(Type *Ty) { - // Check to see if we're already visited this type. + // Check to see if we've already visited this type. if (!VisitedTypes.insert(Ty).second) return; - // If this is a structure or opaque type, add a name for the type. - if (StructType *STy = dyn_cast(Ty)) - if (!OnlyNamed || STy->hasName()) - StructTypes.push_back(STy); + SmallVector TypeWorklist; + TypeWorklist.push_back(Ty); + do { + Ty = TypeWorklist.pop_back_val(); - // Recursively walk all contained types. - for (Type::subtype_iterator I = Ty->subtype_begin(), - E = Ty->subtype_end(); I != E; ++I) - incorporateType(*I); + // If this is a structure or opaque type, add a name for the type. + if (StructType *STy = dyn_cast(Ty)) + if (!OnlyNamed || STy->hasName()) + StructTypes.push_back(STy); + + // Add all unvisited subtypes to worklist for processing + for (Type::subtype_reverse_iterator I = Ty->subtype_rbegin(), + E = Ty->subtype_rend(); + I != E; ++I) + if (VisitedTypes.insert(*I).second) + TypeWorklist.push_back(*I); + } while (!TypeWorklist.empty()); } /// incorporateValue - This method is used to walk operand lists finding types