X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FModule.cpp;h=c29029bf6c06333a2e90f79620e5d785c8974f77;hb=586a55a29089c6128f843cd331fed210c480ed0a;hp=94840f07a4abf82857f9566557b63d41600e9add;hpb=a495c7232d63d4eeab394791397ee384620f6864;p=oota-llvm.git diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index 94840f07a4a..c29029bf6c0 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -17,11 +17,12 @@ #include "llvm/DerivedTypes.h" #include "llvm/GVMaterializer.h" #include "llvm/LLVMContext.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/LeakDetector.h" #include "SymbolTableListTraitsImpl.h" -#include "llvm/TypeSymbolTable.h" #include #include #include @@ -31,25 +32,10 @@ using namespace llvm; // Methods to implement the globals and functions lists. // -GlobalVariable *ilist_traits::createSentinel() { - GlobalVariable *Ret = new GlobalVariable(Type::getInt32Ty(getGlobalContext()), - false, GlobalValue::ExternalLinkage); - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(Ret); - return Ret; -} -GlobalAlias *ilist_traits::createSentinel() { - GlobalAlias *Ret = new GlobalAlias(Type::getInt32Ty(getGlobalContext()), - GlobalValue::ExternalLinkage); - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(Ret); - return Ret; -} - // Explicit instantiations of SymbolTableListTraits since some of the methods // are not in the public header file. -template class llvm::SymbolTableListTraits; template class llvm::SymbolTableListTraits; +template class llvm::SymbolTableListTraits; template class llvm::SymbolTableListTraits; //===----------------------------------------------------------------------===// @@ -57,13 +43,14 @@ template class llvm::SymbolTableListTraits; // Module::Module(StringRef MID, LLVMContext& C) - : Context(C), Materializer(NULL), ModuleID(MID), DataLayout("") { + : Context(C), Materializer(NULL), ModuleID(MID) { ValSymTab = new ValueSymbolTable(); - TypeSymTab = new TypeSymbolTable(); - NamedMDSymTab = new MDSymbolTable(); + NamedMDSymTab = new StringMap(); + Context.addModule(this); } Module::~Module() { + Context.removeModule(this); dropAllReferences(); GlobalList.clear(); FunctionList.clear(); @@ -71,18 +58,19 @@ Module::~Module() { LibraryList.clear(); NamedMDList.clear(); delete ValSymTab; - delete TypeSymTab; - delete NamedMDSymTab; + delete static_cast *>(NamedMDSymTab); } -/// Target endian information... +/// Target endian information. Module::Endianness Module::getEndianness() const { StringRef temp = DataLayout; Module::Endianness ret = AnyEndianness; while (!temp.empty()) { - StringRef token = DataLayout; - tie(token, temp) = getToken(temp, "-"); + std::pair P = getToken(temp, "-"); + + StringRef token = P.first; + temp = P.second; if (token[0] == 'e') { ret = LittleEndian; @@ -94,15 +82,16 @@ Module::Endianness Module::getEndianness() const { return ret; } -/// Target Pointer Size information... +/// Target Pointer Size information. Module::PointerSize Module::getPointerSize() const { StringRef temp = DataLayout; Module::PointerSize ret = AnyPointerSize; while (!temp.empty()) { - StringRef token, signalToken; - tie(token, temp) = getToken(temp, "-"); - tie(signalToken, token) = getToken(token, ":"); + std::pair TmpP = getToken(temp, "-"); + temp = TmpP.second; + TmpP = getToken(TmpP.first, ":"); + StringRef token = TmpP.second, signalToken = TmpP.first; if (signalToken[0] == 'p') { int size = 0; @@ -148,7 +137,7 @@ void Module::getMDKindNames(SmallVectorImpl &Result) const { // the symbol table directly for this common task. // Constant *Module::getOrInsertFunction(StringRef Name, - const FunctionType *Ty, + FunctionType *Ty, AttrListPtr AttributeList) { // See if we have a definition for the specified function already. GlobalValue *F = getNamedValue(Name); @@ -181,7 +170,7 @@ Constant *Module::getOrInsertFunction(StringRef Name, } Constant *Module::getOrInsertTargetIntrinsic(StringRef Name, - const FunctionType *Ty, + FunctionType *Ty, AttrListPtr AttributeList) { // See if we have a definition for the specified function already. GlobalValue *F = getNamedValue(Name); @@ -198,7 +187,7 @@ Constant *Module::getOrInsertTargetIntrinsic(StringRef Name, } Constant *Module::getOrInsertFunction(StringRef Name, - const FunctionType *Ty) { + FunctionType *Ty) { AttrListPtr AttributeList = AttrListPtr::get((AttributeWithIndex *)0, 0); return getOrInsertFunction(Name, Ty, AttributeList); } @@ -210,13 +199,13 @@ Constant *Module::getOrInsertFunction(StringRef Name, // Constant *Module::getOrInsertFunction(StringRef Name, AttrListPtr AttributeList, - const Type *RetTy, ...) { + Type *RetTy, ...) { va_list Args; va_start(Args, RetTy); // Build the list of argument types... - std::vector ArgTys; - while (const Type *ArgTy = va_arg(Args, const Type*)) + std::vector ArgTys; + while (Type *ArgTy = va_arg(Args, Type*)) ArgTys.push_back(ArgTy); va_end(Args); @@ -228,13 +217,13 @@ Constant *Module::getOrInsertFunction(StringRef Name, } Constant *Module::getOrInsertFunction(StringRef Name, - const Type *RetTy, ...) { + Type *RetTy, ...) { va_list Args; va_start(Args, RetTy); // Build the list of argument types... - std::vector ArgTys; - while (const Type *ArgTy = va_arg(Args, const Type*)) + std::vector ArgTys; + while (Type *ArgTy = va_arg(Args, Type*)) ArgTys.push_back(ArgTy); va_end(Args); @@ -278,7 +267,7 @@ GlobalVariable *Module::getGlobalVariable(StringRef Name, /// with a constantexpr cast to the right type. /// 3. Finally, if the existing global is the correct delclaration, return the /// existing global. -Constant *Module::getOrInsertGlobal(StringRef Name, const Type *Ty) { +Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { // See if we have a definition for the specified global already. GlobalVariable *GV = dyn_cast_or_null(getNamedValue(Name)); if (GV == 0) { @@ -311,66 +300,32 @@ GlobalAlias *Module::getNamedAlias(StringRef Name) const { /// getNamedMetadata - Return the first NamedMDNode in the module with the /// specified name. This method returns null if a NamedMDNode with the -//// specified name is not found. -NamedMDNode *Module::getNamedMetadata(StringRef Name) const { - return NamedMDSymTab->lookup(Name); +/// specified name is not found. +NamedMDNode *Module::getNamedMetadata(const Twine &Name) const { + SmallString<256> NameData; + StringRef NameRef = Name.toStringRef(NameData); + return static_cast *>(NamedMDSymTab)->lookup(NameRef); } /// getOrInsertNamedMetadata - Return the first named MDNode in the module /// with the specified name. This method returns a new NamedMDNode if a /// NamedMDNode with the specified name is not found. NamedMDNode *Module::getOrInsertNamedMetadata(StringRef Name) { - NamedMDNode *NMD = NamedMDSymTab->lookup(Name); - if (!NMD) - NMD = NamedMDNode::Create(getContext(), Name, NULL, 0, this); + NamedMDNode *&NMD = + (*static_cast *>(NamedMDSymTab))[Name]; + if (!NMD) { + NMD = new NamedMDNode(Name); + NMD->setParent(this); + NamedMDList.push_back(NMD); + } return NMD; } -//===----------------------------------------------------------------------===// -// Methods for easy access to the types in the module. -// - - -// addTypeName - Insert an entry in the symbol table mapping Str to Type. If -// there is already an entry for this name, true is returned and the symbol -// table is not modified. -// -bool Module::addTypeName(StringRef Name, const Type *Ty) { - TypeSymbolTable &ST = getTypeSymbolTable(); - - if (ST.lookup(Name)) return true; // Already in symtab... - - // Not in symbol table? Set the name with the Symtab as an argument so the - // type knows what to update... - ST.insert(Name, Ty); - - return false; -} - -/// getTypeByName - Return the type with the specified name in this module, or -/// null if there is none by that name. -const Type *Module::getTypeByName(StringRef Name) const { - const TypeSymbolTable &ST = getTypeSymbolTable(); - return cast_or_null(ST.lookup(Name)); +void Module::eraseNamedMetadata(NamedMDNode *NMD) { + static_cast *>(NamedMDSymTab)->erase(NMD->getName()); + NamedMDList.erase(NMD); } -// getTypeName - If there is at least one entry in the symbol table for the -// specified type, return it. -// -std::string Module::getTypeName(const Type *Ty) const { - const TypeSymbolTable &ST = getTypeSymbolTable(); - - TypeSymbolTable::const_iterator TI = ST.begin(); - TypeSymbolTable::const_iterator TE = ST.end(); - if ( TI == TE ) return ""; // No names for types - - while (TI != TE && TI->second != Ty) - ++TI; - - if (TI != TE) // Must have found an entry! - return TI->first; - return ""; // Must not have found anything... -} //===----------------------------------------------------------------------===// // Methods to control the materialization of GlobalValues in the Module. @@ -457,3 +412,128 @@ void Module::removeLibrary(StringRef Lib) { return; } } + +//===----------------------------------------------------------------------===// +// Type finding functionality. +//===----------------------------------------------------------------------===// + +namespace { + /// TypeFinder - Walk over a module, identifying all of the types that are + /// used by the module. + class TypeFinder { + // To avoid walking constant expressions multiple times and other IR + // objects, we keep several helper maps. + DenseSet VisitedConstants; + DenseSet VisitedTypes; + + std::vector &StructTypes; + public: + TypeFinder(std::vector &structTypes) + : StructTypes(structTypes) {} + + void run(const Module &M) { + // Get types from global variables. + for (Module::const_global_iterator I = M.global_begin(), + E = M.global_end(); I != E; ++I) { + incorporateType(I->getType()); + if (I->hasInitializer()) + incorporateValue(I->getInitializer()); + } + + // Get types from aliases. + for (Module::const_alias_iterator I = M.alias_begin(), + E = M.alias_end(); I != E; ++I) { + incorporateType(I->getType()); + if (const Value *Aliasee = I->getAliasee()) + incorporateValue(Aliasee); + } + + SmallVector, 4> MDForInst; + + // Get types from functions. + for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) { + incorporateType(FI->getType()); + + for (Function::const_iterator BB = FI->begin(), E = FI->end(); + BB != E;++BB) + for (BasicBlock::const_iterator II = BB->begin(), + E = BB->end(); II != E; ++II) { + const Instruction &I = *II; + // Incorporate the type of the instruction and all its operands. + incorporateType(I.getType()); + for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end(); + OI != OE; ++OI) + incorporateValue(*OI); + + // Incorporate types hiding in metadata. + I.getAllMetadataOtherThanDebugLoc(MDForInst); + for (unsigned i = 0, e = MDForInst.size(); i != e; ++i) + incorporateMDNode(MDForInst[i].second); + MDForInst.clear(); + } + } + + for (Module::const_named_metadata_iterator I = M.named_metadata_begin(), + E = M.named_metadata_end(); I != E; ++I) { + const NamedMDNode *NMD = I; + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) + incorporateMDNode(NMD->getOperand(i)); + } + } + + private: + void incorporateType(Type *Ty) { + // Check to see if we're 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)) + StructTypes.push_back(STy); + + // Recursively walk all contained types. + for (Type::subtype_iterator I = Ty->subtype_begin(), + E = Ty->subtype_end(); I != E; ++I) + incorporateType(*I); + } + + /// incorporateValue - This method is used to walk operand lists finding + /// types hiding in constant expressions and other operands that won't be + /// walked in other ways. GlobalValues, basic blocks, instructions, and + /// inst operands are all explicitly enumerated. + void incorporateValue(const Value *V) { + if (const MDNode *M = dyn_cast(V)) + return incorporateMDNode(M); + if (!isa(V) || isa(V)) return; + + // Already visited? + if (!VisitedConstants.insert(V).second) + return; + + // Check this type. + incorporateType(V->getType()); + + // Look in operands for types. + const User *U = cast(V); + for (Constant::const_op_iterator I = U->op_begin(), + E = U->op_end(); I != E;++I) + incorporateValue(*I); + } + + void incorporateMDNode(const MDNode *V) { + + // Already visited? + if (!VisitedConstants.insert(V).second) + return; + + // Look in operands for types. + for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i) + if (Value *Op = V->getOperand(i)) + incorporateValue(Op); + } + }; +} // end anonymous namespace + +void Module::findUsedStructTypes(std::vector &StructTypes) const { + TypeFinder(StructTypes).run(*this); +}