Skip to content

Commit 8555a37

Browse files
committed
Move the "findUsedStructTypes" functionality outside of the Module class.
The "findUsedStructTypes" method is very expensive to run. It needs to be optimized so that LTO can run faster. Splitting this method out of the Module class will help this occur. For instance, it can keep a list of seen objects so that it doesn't process them over and over again. llvm-svn: 161228
1 parent d15385c commit 8555a37

File tree

8 files changed

+238
-153
lines changed

8 files changed

+238
-153
lines changed

llvm/include/llvm/Module.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,6 @@ class Module {
301301
typedef DenseMap<StructType*, unsigned, DenseMapInfo<StructType*> >
302302
NumeredTypesMapTy;
303303

304-
/// findUsedStructTypes - Walk the entire module and find all of the
305-
/// struct types that are in use, returning them in a vector.
306-
void findUsedStructTypes(std::vector<StructType*> &StructTypes,
307-
bool OnlyNamed = false) const;
308-
309304
/// getTypeByName - Return the type with the specified name, or null if there
310305
/// is none by that name.
311306
StructType *getTypeByName(StringRef Name) const;

llvm/include/llvm/TypeFinder.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//===-- llvm/TypeFinder.h - Class for finding used struct types -*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file contains the declaration of the TypeFinder class.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_TYPEFINDER_H
15+
#define LLVM_TYPEFINDER_H
16+
17+
#include "llvm/ADT/DenseSet.h"
18+
#include <vector>
19+
20+
namespace llvm {
21+
22+
class MDNode;
23+
class Module;
24+
class StructType;
25+
class Type;
26+
class Value;
27+
28+
/// TypeFinder - Walk over a module, identifying all of the types that are
29+
/// used by the module.
30+
class TypeFinder {
31+
// To avoid walking constant expressions multiple times and other IR
32+
// objects, we keep several helper maps.
33+
DenseSet<const Value*> VisitedConstants;
34+
DenseSet<Type*> VisitedTypes;
35+
36+
std::vector<StructType*> StructTypes;
37+
bool OnlyNamed;
38+
39+
public:
40+
TypeFinder() : OnlyNamed(false) {}
41+
42+
void run(const Module &M, bool onlyNamed);
43+
void clear();
44+
45+
typedef std::vector<StructType*>::iterator iterator;
46+
typedef std::vector<StructType*>::const_iterator const_iterator;
47+
48+
iterator begin() { return StructTypes.begin(); }
49+
iterator end() { return StructTypes.end(); }
50+
51+
const_iterator begin() const { return StructTypes.begin(); }
52+
const_iterator end() const { return StructTypes.end(); }
53+
54+
bool empty() const { return StructTypes.empty(); }
55+
size_t size() const { return StructTypes.size(); }
56+
iterator erase(iterator I, iterator E) { return StructTypes.erase(I, E); }
57+
58+
StructType *&operator[](unsigned Idx) { return StructTypes[Idx]; }
59+
60+
private:
61+
/// incorporateType - This method adds the type to the list of used
62+
/// structures if it's not in there already.
63+
void incorporateType(Type *Ty);
64+
65+
/// incorporateValue - This method is used to walk operand lists finding types
66+
/// hiding in constant expressions and other operands that won't be walked in
67+
/// other ways. GlobalValues, basic blocks, instructions, and inst operands
68+
/// are all explicitly enumerated.
69+
void incorporateValue(const Value *V);
70+
71+
/// incorporateMDNode - This method is used to walk the operands of an MDNode
72+
/// to find types hiding within.
73+
void incorporateMDNode(const MDNode *V);
74+
};
75+
76+
} // end llvm namespace
77+
78+
#endif

llvm/lib/Linker/LinkModules.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/DerivedTypes.h"
1717
#include "llvm/Instructions.h"
1818
#include "llvm/Module.h"
19+
#include "llvm/TypeFinder.h"
1920
#include "llvm/ADT/DenseSet.h"
2021
#include "llvm/ADT/Optional.h"
2122
#include "llvm/ADT/SetVector.h"
@@ -595,13 +596,13 @@ void ModuleLinker::computeTypeMapping() {
595596
// At this point, the destination module may have a type "%foo = { i32 }" for
596597
// example. When the source module got loaded into the same LLVMContext, if
597598
// it had the same type, it would have been renamed to "%foo.42 = { i32 }".
598-
std::vector<StructType*> SrcStructTypes;
599-
SrcM->findUsedStructTypes(SrcStructTypes, true);
599+
TypeFinder SrcStructTypes;
600+
SrcStructTypes.run(*SrcM, true);
600601
SmallPtrSet<StructType*, 32> SrcStructTypesSet(SrcStructTypes.begin(),
601602
SrcStructTypes.end());
602603

603-
std::vector<StructType*> DstStructTypes;
604-
DstM->findUsedStructTypes(DstStructTypes, true);
604+
TypeFinder DstStructTypes;
605+
DstStructTypes.run(*DstM, true);
605606
SmallPtrSet<StructType*, 32> DstStructTypesSet(DstStructTypes.begin(),
606607
DstStructTypes.end());
607608

llvm/lib/Transforms/IPO/StripSymbols.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/Instructions.h"
2828
#include "llvm/Module.h"
2929
#include "llvm/Pass.h"
30+
#include "llvm/TypeFinder.h"
3031
#include "llvm/ValueSymbolTable.h"
3132
#include "llvm/Transforms/Utils/Local.h"
3233
#include "llvm/ADT/DenseMap.h"
@@ -175,8 +176,8 @@ static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) {
175176

176177
// Strip any named types of their names.
177178
static void StripTypeNames(Module &M, bool PreserveDbgInfo) {
178-
std::vector<StructType*> StructTypes;
179-
M.findUsedStructTypes(StructTypes);
179+
TypeFinder StructTypes;
180+
StructTypes.run(M, false);
180181

181182
for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) {
182183
StructType *STy = StructTypes[i];

llvm/lib/VMCore/AsmWriter.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/IntrinsicInst.h"
2727
#include "llvm/Operator.h"
2828
#include "llvm/Module.h"
29+
#include "llvm/TypeFinder.h"
2930
#include "llvm/ValueSymbolTable.h"
3031
#include "llvm/ADT/DenseMap.h"
3132
#include "llvm/ADT/SmallString.h"
@@ -145,7 +146,7 @@ class TypePrinting {
145146
public:
146147

147148
/// NamedTypes - The named types that are used by the current module.
148-
std::vector<StructType*> NamedTypes;
149+
TypeFinder NamedTypes;
149150

150151
/// NumberedTypes - The numbered types, along with their value.
151152
DenseMap<StructType*, unsigned> NumberedTypes;
@@ -164,7 +165,7 @@ class TypePrinting {
164165

165166

166167
void TypePrinting::incorporateTypes(const Module &M) {
167-
M.findUsedStructTypes(NamedTypes);
168+
NamedTypes.run(M, false);
168169

169170
// The list of struct types we got back includes all the struct types, split
170171
// the unnamed ones out to a numbering and remove the anonymous structs.

llvm/lib/VMCore/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ add_llvm_library(LLVMCore
3131
PassRegistry.cpp
3232
PrintModulePass.cpp
3333
Type.cpp
34+
TypeFinder.cpp
3435
Use.cpp
3536
User.cpp
3637
Value.cpp

llvm/lib/VMCore/Module.cpp

Lines changed: 0 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -467,143 +467,3 @@ void Module::removeLibrary(StringRef Lib) {
467467
return;
468468
}
469469
}
470-
471-
//===----------------------------------------------------------------------===//
472-
// Type finding functionality.
473-
//===----------------------------------------------------------------------===//
474-
475-
namespace {
476-
/// TypeFinder - Walk over a module, identifying all of the types that are
477-
/// used by the module.
478-
class TypeFinder {
479-
// To avoid walking constant expressions multiple times and other IR
480-
// objects, we keep several helper maps.
481-
DenseSet<const Value*> VisitedConstants;
482-
DenseSet<Type*> VisitedTypes;
483-
484-
std::vector<StructType*> &StructTypes;
485-
bool OnlyNamed;
486-
public:
487-
TypeFinder(std::vector<StructType*> &structTypes, bool onlyNamed)
488-
: StructTypes(structTypes), OnlyNamed(onlyNamed) {}
489-
490-
void run(const Module &M) {
491-
// Get types from global variables.
492-
for (Module::const_global_iterator I = M.global_begin(),
493-
E = M.global_end(); I != E; ++I) {
494-
incorporateType(I->getType());
495-
if (I->hasInitializer())
496-
incorporateValue(I->getInitializer());
497-
}
498-
499-
// Get types from aliases.
500-
for (Module::const_alias_iterator I = M.alias_begin(),
501-
E = M.alias_end(); I != E; ++I) {
502-
incorporateType(I->getType());
503-
if (const Value *Aliasee = I->getAliasee())
504-
incorporateValue(Aliasee);
505-
}
506-
507-
// Get types from functions.
508-
SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst;
509-
for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
510-
incorporateType(FI->getType());
511-
512-
// First incorporate the arguments.
513-
for (Function::const_arg_iterator AI = FI->arg_begin(),
514-
AE = FI->arg_end(); AI != AE; ++AI)
515-
incorporateValue(AI);
516-
517-
for (Function::const_iterator BB = FI->begin(), E = FI->end();
518-
BB != E;++BB)
519-
for (BasicBlock::const_iterator II = BB->begin(),
520-
E = BB->end(); II != E; ++II) {
521-
const Instruction &I = *II;
522-
// Incorporate the type of the instruction.
523-
incorporateType(I.getType());
524-
525-
// Incorporate non-instruction operand types. (We are incorporating
526-
// all instructions with this loop.)
527-
for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end();
528-
OI != OE; ++OI)
529-
if (!isa<Instruction>(OI))
530-
incorporateValue(*OI);
531-
532-
// Incorporate types hiding in metadata.
533-
I.getAllMetadataOtherThanDebugLoc(MDForInst);
534-
for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
535-
incorporateMDNode(MDForInst[i].second);
536-
MDForInst.clear();
537-
}
538-
}
539-
540-
for (Module::const_named_metadata_iterator I = M.named_metadata_begin(),
541-
E = M.named_metadata_end(); I != E; ++I) {
542-
const NamedMDNode *NMD = I;
543-
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
544-
incorporateMDNode(NMD->getOperand(i));
545-
}
546-
}
547-
548-
private:
549-
void incorporateType(Type *Ty) {
550-
// Check to see if we're already visited this type.
551-
if (!VisitedTypes.insert(Ty).second)
552-
return;
553-
554-
// If this is a structure or opaque type, add a name for the type.
555-
if (StructType *STy = dyn_cast<StructType>(Ty))
556-
if (!OnlyNamed || STy->hasName())
557-
StructTypes.push_back(STy);
558-
559-
// Recursively walk all contained types.
560-
for (Type::subtype_iterator I = Ty->subtype_begin(),
561-
E = Ty->subtype_end(); I != E; ++I)
562-
incorporateType(*I);
563-
}
564-
565-
/// incorporateValue - This method is used to walk operand lists finding
566-
/// types hiding in constant expressions and other operands that won't be
567-
/// walked in other ways. GlobalValues, basic blocks, instructions, and
568-
/// inst operands are all explicitly enumerated.
569-
void incorporateValue(const Value *V) {
570-
if (const MDNode *M = dyn_cast<MDNode>(V))
571-
return incorporateMDNode(M);
572-
if (!isa<Constant>(V) || isa<GlobalValue>(V)) return;
573-
574-
// Already visited?
575-
if (!VisitedConstants.insert(V).second)
576-
return;
577-
578-
// Check this type.
579-
incorporateType(V->getType());
580-
581-
// If this is an instruction, we incorporate it separately.
582-
if (isa<Instruction>(V))
583-
return;
584-
585-
// Look in operands for types.
586-
const User *U = cast<User>(V);
587-
for (Constant::const_op_iterator I = U->op_begin(),
588-
E = U->op_end(); I != E;++I)
589-
incorporateValue(*I);
590-
}
591-
592-
void incorporateMDNode(const MDNode *V) {
593-
594-
// Already visited?
595-
if (!VisitedConstants.insert(V).second)
596-
return;
597-
598-
// Look in operands for types.
599-
for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i)
600-
if (Value *Op = V->getOperand(i))
601-
incorporateValue(Op);
602-
}
603-
};
604-
} // end anonymous namespace
605-
606-
void Module::findUsedStructTypes(std::vector<StructType*> &StructTypes,
607-
bool OnlyNamed) const {
608-
TypeFinder(StructTypes, OnlyNamed).run(*this);
609-
}

0 commit comments

Comments
 (0)