diff options
Diffstat (limited to 'lib')
41 files changed, 2365 insertions, 4403 deletions
diff --git a/lib/AsmParser/LLLexer.h b/lib/AsmParser/LLLexer.h index 4fe705e..33b9135 100644 --- a/lib/AsmParser/LLLexer.h +++ b/lib/AsmParser/LLLexer.h @@ -38,7 +38,7 @@ namespace llvm { lltok::Kind CurKind; std::string StrVal; unsigned UIntVal; - const Type *TyVal; + Type *TyVal; APFloat APFloatVal; APSInt APSIntVal; @@ -56,7 +56,7 @@ namespace llvm { LocTy getLoc() const { return SMLoc::getFromPointer(TokStart); } lltok::Kind getKind() const { return CurKind; } const std::string &getStrVal() const { return StrVal; } - const Type *getTyVal() const { return TyVal; } + Type *getTyVal() const { return TyVal; } unsigned getUIntVal() const { return UIntVal; } const APSInt &getAPSIntVal() const { return APSIntVal; } const APFloat &getAPFloatVal() const { return APFloatVal; } diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index d985851..881b3e9 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -89,15 +89,16 @@ bool LLParser::ValidateEndOfModule() { ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin()); } - - if (!ForwardRefTypes.empty()) - return Error(ForwardRefTypes.begin()->second.second, - "use of undefined type named '" + - ForwardRefTypes.begin()->first + "'"); - if (!ForwardRefTypeIDs.empty()) - return Error(ForwardRefTypeIDs.begin()->second.second, - "use of undefined type '%" + - Twine(ForwardRefTypeIDs.begin()->first) + "'"); + for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) + if (NumberedTypes[i].second.isValid()) + return Error(NumberedTypes[i].second, + "use of undefined type '%" + Twine(i) + "'"); + + for (StringMap<std::pair<Type*, LocTy> >::iterator I = + NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I) + if (I->second.second.isValid()) + return Error(I->second.second, + "use of undefined type named '" + I->getKey() + "'"); if (!ForwardRefVals.empty()) return Error(ForwardRefVals.begin()->second.second, @@ -293,36 +294,32 @@ bool LLParser::ParseDepLibs() { /// ::= LocalVarID '=' 'type' type bool LLParser::ParseUnnamedType() { LocTy TypeLoc = Lex.getLoc(); - unsigned TypeID = NumberedTypes.size(); - if (Lex.getUIntVal() != TypeID) - return Error(Lex.getLoc(), "type expected to be numbered '%" + - Twine(TypeID) + "'"); + unsigned TypeID = Lex.getUIntVal(); Lex.Lex(); // eat LocalVarID; if (ParseToken(lltok::equal, "expected '=' after name") || ParseToken(lltok::kw_type, "expected 'type' after '='")) return true; - PATypeHolder Ty(Type::getVoidTy(Context)); - if (ParseType(Ty)) return true; - - // See if this type was previously referenced. - std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator - FI = ForwardRefTypeIDs.find(TypeID); - if (FI != ForwardRefTypeIDs.end()) { - if (FI->second.first.get() == Ty) - return Error(TypeLoc, "self referential type is invalid"); - - cast<DerivedType>(FI->second.first.get())->refineAbstractTypeTo(Ty); - Ty = FI->second.first.get(); - ForwardRefTypeIDs.erase(FI); + if (TypeID >= NumberedTypes.size()) + NumberedTypes.resize(TypeID+1); + + Type *Result = 0; + if (ParseStructDefinition(TypeLoc, "", + NumberedTypes[TypeID], Result)) return true; + + if (!isa<StructType>(Result)) { + std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID]; + if (Entry.first) + return Error(TypeLoc, "non-struct types may not be recursive"); + Entry.first = Result; + Entry.second = SMLoc(); } - NumberedTypes.push_back(Ty); - return false; } + /// toplevelentity /// ::= LocalVar '=' 'type' type bool LLParser::ParseNamedType() { @@ -330,37 +327,23 @@ bool LLParser::ParseNamedType() { LocTy NameLoc = Lex.getLoc(); Lex.Lex(); // eat LocalVar. - PATypeHolder Ty(Type::getVoidTy(Context)); - if (ParseToken(lltok::equal, "expected '=' after name") || - ParseToken(lltok::kw_type, "expected 'type' after name") || - ParseType(Ty)) + ParseToken(lltok::kw_type, "expected 'type' after name")) return true; - - // Set the type name, checking for conflicts as we do so. - bool AlreadyExists = M->addTypeName(Name, Ty); - if (!AlreadyExists) return false; - - // See if this type is a forward reference. We need to eagerly resolve - // types to allow recursive type redefinitions below. - std::map<std::string, std::pair<PATypeHolder, LocTy> >::iterator - FI = ForwardRefTypes.find(Name); - if (FI != ForwardRefTypes.end()) { - if (FI->second.first.get() == Ty) - return Error(NameLoc, "self referential type is invalid"); - - cast<DerivedType>(FI->second.first.get())->refineAbstractTypeTo(Ty); - Ty = FI->second.first.get(); - ForwardRefTypes.erase(FI); - return false; + + Type *Result = 0; + if (ParseStructDefinition(NameLoc, Name, + NamedTypes[Name], Result)) return true; + + if (!isa<StructType>(Result)) { + std::pair<Type*, LocTy> &Entry = NamedTypes[Name]; + if (Entry.first) + return Error(NameLoc, "non-struct types may not be recursive"); + Entry.first = Result; + Entry.second = SMLoc(); } - - // Inserting a name that is already defined, get the existing name. - assert(M->getTypeByName(Name) && "Conflict but no matching type?!"); - - // Otherwise, this is an attempt to redefine a type, report the error. - return Error(NameLoc, "redefinition of type named '" + Name + "' of type '" + - getTypeString(Ty) + "'"); + + return false; } @@ -536,7 +519,7 @@ bool LLParser::ParseStandaloneMetadata() { unsigned MetadataID = 0; LocTy TyLoc; - PATypeHolder Ty(Type::getVoidTy(Context)); + Type *Ty = 0; SmallVector<Value *, 16> Elts; if (ParseUInt32(MetadataID) || ParseToken(lltok::equal, "expected '=' here") || @@ -668,7 +651,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, LocTy UnnamedAddrLoc; LocTy TyLoc; - PATypeHolder Ty(Type::getVoidTy(Context)); + Type *Ty = 0; if (ParseOptionalToken(lltok::kw_thread_local, ThreadLocal) || ParseOptionalAddrSpace(AddrSpace) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, @@ -792,18 +775,11 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty, // Otherwise, create a new forward reference for this value and remember it. GlobalValue *FwdVal; - if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) { - // Function types can return opaque but functions can't. - if (FT->getReturnType()->isOpaqueTy()) { - Error(Loc, "function may not return opaque type"); - return 0; - } - + if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); - } else { + else FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, GlobalValue::ExternalWeakLinkage, 0, Name); - } ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); return FwdVal; @@ -837,17 +813,11 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) { // Otherwise, create a new forward reference for this value and remember it. GlobalValue *FwdVal; - if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) { - // Function types can return opaque but functions can't. - if (FT->getReturnType()->isOpaqueTy()) { - Error(Loc, "function may not return opaque type"); - return 0; - } + if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M); - } else { + else FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, GlobalValue::ExternalWeakLinkage, 0, ""); - } ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); return FwdVal; @@ -1228,165 +1198,68 @@ bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices, // Type Parsing. //===----------------------------------------------------------------------===// -/// ParseType - Parse and resolve a full type. -bool LLParser::ParseType(PATypeHolder &Result, bool AllowVoid) { - LocTy TypeLoc = Lex.getLoc(); - if (ParseTypeRec(Result)) return true; - - // Verify no unresolved uprefs. - if (!UpRefs.empty()) - return Error(UpRefs.back().Loc, "invalid unresolved type up reference"); - - if (!AllowVoid && Result.get()->isVoidTy()) - return Error(TypeLoc, "void type only allowed for function results"); - - return false; -} - -/// HandleUpRefs - Every time we finish a new layer of types, this function is -/// called. It loops through the UpRefs vector, which is a list of the -/// currently active types. For each type, if the up-reference is contained in -/// the newly completed type, we decrement the level count. When the level -/// count reaches zero, the up-referenced type is the type that is passed in: -/// thus we can complete the cycle. -/// -PATypeHolder LLParser::HandleUpRefs(const Type *ty) { - // If Ty isn't abstract, or if there are no up-references in it, then there is - // nothing to resolve here. - if (!ty->isAbstract() || UpRefs.empty()) return ty; - - PATypeHolder Ty(ty); -#if 0 - dbgs() << "Type '" << *Ty - << "' newly formed. Resolving upreferences.\n" - << UpRefs.size() << " upreferences active!\n"; -#endif - - // If we find any resolvable upreferences (i.e., those whose NestingLevel goes - // to zero), we resolve them all together before we resolve them to Ty. At - // the end of the loop, if there is anything to resolve to Ty, it will be in - // this variable. - OpaqueType *TypeToResolve = 0; - - for (unsigned i = 0; i != UpRefs.size(); ++i) { - // Determine if 'Ty' directly contains this up-references 'LastContainedTy'. - bool ContainsType = - std::find(Ty->subtype_begin(), Ty->subtype_end(), - UpRefs[i].LastContainedTy) != Ty->subtype_end(); - -#if 0 - dbgs() << " UR#" << i << " - TypeContains(" << *Ty << ", " - << *UpRefs[i].LastContainedTy << ") = " - << (ContainsType ? "true" : "false") - << " level=" << UpRefs[i].NestingLevel << "\n"; -#endif - if (!ContainsType) - continue; - - // Decrement level of upreference - unsigned Level = --UpRefs[i].NestingLevel; - UpRefs[i].LastContainedTy = Ty; - - // If the Up-reference has a non-zero level, it shouldn't be resolved yet. - if (Level != 0) - continue; - -#if 0 - dbgs() << " * Resolving upreference for " << UpRefs[i].UpRefTy << "\n"; -#endif - if (!TypeToResolve) - TypeToResolve = UpRefs[i].UpRefTy; - else - UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve); - UpRefs.erase(UpRefs.begin()+i); // Remove from upreference list. - --i; // Do not skip the next element. - } - - if (TypeToResolve) - TypeToResolve->refineAbstractTypeTo(Ty); - - return Ty; -} - - -/// ParseTypeRec - The recursive function used to process the internal -/// implementation details of types. -bool LLParser::ParseTypeRec(PATypeHolder &Result) { +/// ParseType - Parse a type. +bool LLParser::ParseType(Type *&Result, bool AllowVoid) { + SMLoc TypeLoc = Lex.getLoc(); switch (Lex.getKind()) { default: return TokError("expected type"); case lltok::Type: - // TypeRec ::= 'float' | 'void' (etc) + // Type ::= 'float' | 'void' (etc) Result = Lex.getTyVal(); Lex.Lex(); break; - case lltok::kw_opaque: - // TypeRec ::= 'opaque' - Result = OpaqueType::get(Context); - Lex.Lex(); - break; case lltok::lbrace: - // TypeRec ::= '{' ... '}' - if (ParseStructType(Result, false)) + // Type ::= StructType + if (ParseAnonStructType(Result, false)) return true; break; case lltok::lsquare: - // TypeRec ::= '[' ... ']' + // Type ::= '[' ... ']' Lex.Lex(); // eat the lsquare. if (ParseArrayVectorType(Result, false)) return true; break; case lltok::less: // Either vector or packed struct. - // TypeRec ::= '<' ... '>' + // Type ::= '<' ... '>' Lex.Lex(); if (Lex.getKind() == lltok::lbrace) { - if (ParseStructType(Result, true) || + if (ParseAnonStructType(Result, true) || ParseToken(lltok::greater, "expected '>' at end of packed struct")) return true; } else if (ParseArrayVectorType(Result, true)) return true; break; - case lltok::LocalVar: - // TypeRec ::= %foo - if (const Type *T = M->getTypeByName(Lex.getStrVal())) { - Result = T; - } else { - Result = OpaqueType::get(Context); - ForwardRefTypes.insert(std::make_pair(Lex.getStrVal(), - std::make_pair(Result, - Lex.getLoc()))); - M->addTypeName(Lex.getStrVal(), Result.get()); + case lltok::LocalVar: { + // Type ::= %foo + std::pair<Type*, LocTy> &Entry = NamedTypes[Lex.getStrVal()]; + + // If the type hasn't been defined yet, create a forward definition and + // remember where that forward def'n was seen (in case it never is defined). + if (Entry.first == 0) { + Entry.first = StructType::createNamed(Context, Lex.getStrVal()); + Entry.second = Lex.getLoc(); } + Result = Entry.first; Lex.Lex(); break; + } - case lltok::LocalVarID: - // TypeRec ::= %4 - if (Lex.getUIntVal() < NumberedTypes.size()) - Result = NumberedTypes[Lex.getUIntVal()]; - else { - std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator - I = ForwardRefTypeIDs.find(Lex.getUIntVal()); - if (I != ForwardRefTypeIDs.end()) - Result = I->second.first; - else { - Result = OpaqueType::get(Context); - ForwardRefTypeIDs.insert(std::make_pair(Lex.getUIntVal(), - std::make_pair(Result, - Lex.getLoc()))); - } + case lltok::LocalVarID: { + // Type ::= %4 + if (Lex.getUIntVal() >= NumberedTypes.size()) + NumberedTypes.resize(Lex.getUIntVal()+1); + std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()]; + + // If the type hasn't been defined yet, create a forward definition and + // remember where that forward def'n was seen (in case it never is defined). + if (Entry.first == 0) { + Entry.first = StructType::createNamed(Context, ""); + Entry.second = Lex.getLoc(); } + Result = Entry.first; Lex.Lex(); break; - case lltok::backslash: { - // TypeRec ::= '\' 4 - Lex.Lex(); - unsigned Val; - if (ParseUInt32(Val)) return true; - OpaqueType *OT = OpaqueType::get(Context); //Use temporary placeholder. - UpRefs.push_back(UpRefRecord(Lex.getLoc(), Val, OT)); - Result = OT; - break; } } @@ -1394,34 +1267,37 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { while (1) { switch (Lex.getKind()) { // End of type. - default: return false; + default: + if (!AllowVoid && Result->isVoidTy()) + return Error(TypeLoc, "void type only allowed for function results"); + return false; - // TypeRec ::= TypeRec '*' + // Type ::= Type '*' case lltok::star: - if (Result.get()->isLabelTy()) + if (Result->isLabelTy()) return TokError("basic block pointers are invalid"); - if (Result.get()->isVoidTy()) - return TokError("pointers to void are invalid; use i8* instead"); - if (!PointerType::isValidElementType(Result.get())) + if (Result->isVoidTy()) + return TokError("pointers to void are invalid - use i8* instead"); + if (!PointerType::isValidElementType(Result)) return TokError("pointer to this type is invalid"); - Result = HandleUpRefs(PointerType::getUnqual(Result.get())); + Result = PointerType::getUnqual(Result); Lex.Lex(); break; - // TypeRec ::= TypeRec 'addrspace' '(' uint32 ')' '*' + // Type ::= Type 'addrspace' '(' uint32 ')' '*' case lltok::kw_addrspace: { - if (Result.get()->isLabelTy()) + if (Result->isLabelTy()) return TokError("basic block pointers are invalid"); - if (Result.get()->isVoidTy()) + if (Result->isVoidTy()) return TokError("pointers to void are invalid; use i8* instead"); - if (!PointerType::isValidElementType(Result.get())) + if (!PointerType::isValidElementType(Result)) return TokError("pointer to this type is invalid"); unsigned AddrSpace; if (ParseOptionalAddrSpace(AddrSpace) || ParseToken(lltok::star, "expected '*' in address space")) return true; - Result = HandleUpRefs(PointerType::get(Result.get(), AddrSpace)); + Result = PointerType::get(Result, AddrSpace); break; } @@ -1452,7 +1328,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, // Parse the argument. LocTy ArgLoc; - PATypeHolder ArgTy(Type::getVoidTy(Context)); + Type *ArgTy = 0; unsigned ArgAttrs1 = Attribute::None; unsigned ArgAttrs2 = Attribute::None; Value *V; @@ -1472,7 +1348,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, /// ParseArgumentList - Parse the argument list for a function type or function -/// prototype. If 'inType' is true then we are parsing a FunctionType. +/// prototype. /// ::= '(' ArgTypeListI ')' /// ArgTypeListI /// ::= /*empty*/ @@ -1480,8 +1356,8 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, /// ::= ArgTypeList ',' '...' /// ::= ArgType (',' ArgType)* /// -bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList, - bool &isVarArg, bool inType) { +bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, + bool &isVarArg){ isVarArg = false; assert(Lex.getKind() == lltok::lparen); Lex.Lex(); // eat the (. @@ -1493,14 +1369,11 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList, Lex.Lex(); } else { LocTy TypeLoc = Lex.getLoc(); - PATypeHolder ArgTy(Type::getVoidTy(Context)); + Type *ArgTy = 0; unsigned Attrs; std::string Name; - // If we're parsing a type, use ParseTypeRec, because we allow recursive - // types (such as a function returning a pointer to itself). If parsing a - // function prototype, we require fully resolved types. - if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) || + if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true; if (ArgTy->isVoidTy()) @@ -1525,8 +1398,7 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList, // Otherwise must be an argument type. TypeLoc = Lex.getLoc(); - if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) || - ParseOptionalAttrs(Attrs, 0)) return true; + if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true; if (ArgTy->isVoidTy()) return Error(TypeLoc, "argument can not have void type"); @@ -1538,7 +1410,7 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList, Name = ""; } - if (!ArgTy->isFirstClassType() && !ArgTy->isOpaqueTy()) + if (!ArgTy->isFirstClassType()) return Error(TypeLoc, "invalid type for function argument"); ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name)); @@ -1550,15 +1422,15 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList, /// ParseFunctionType /// ::= Type ArgumentList OptionalAttrs -bool LLParser::ParseFunctionType(PATypeHolder &Result) { +bool LLParser::ParseFunctionType(Type *&Result) { assert(Lex.getKind() == lltok::lparen); if (!FunctionType::isValidReturnType(Result)) return TokError("invalid function return type"); - std::vector<ArgInfo> ArgList; + SmallVector<ArgInfo, 8> ArgList; bool isVarArg; - if (ParseArgumentList(ArgList, isVarArg, true)) + if (ParseArgumentList(ArgList, isVarArg)) return true; // Reject names on the arguments lists. @@ -1570,68 +1442,122 @@ bool LLParser::ParseFunctionType(PATypeHolder &Result) { "argument attributes invalid in function type"); } - std::vector<const Type*> ArgListTy; + SmallVector<const Type*, 16> ArgListTy; for (unsigned i = 0, e = ArgList.size(); i != e; ++i) - ArgListTy.push_back(ArgList[i].Type); + ArgListTy.push_back(ArgList[i].Ty); + + Result = FunctionType::get(Result, ArgListTy, isVarArg); + return false; +} - Result = HandleUpRefs(FunctionType::get(Result.get(), - ArgListTy, isVarArg)); +/// ParseAnonStructType - Parse an anonymous struct type, which is inlined into +/// other structs. +bool LLParser::ParseAnonStructType(Type *&Result, bool Packed) { + SmallVector<Type*, 8> Elts; + if (ParseStructBody(Elts)) return true; + + Result = StructType::get(Context, Elts, Packed); + return false; +} + +/// ParseStructDefinition - Parse a struct in a 'type' definition. +bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name, + std::pair<Type*, LocTy> &Entry, + Type *&ResultTy) { + // If the type was already defined, diagnose the redefinition. + if (Entry.first && !Entry.second.isValid()) + return Error(TypeLoc, "redefinition of type"); + + // If we have opaque, just return without filling in the definition for the + // struct. This counts as a definition as far as the .ll file goes. + if (EatIfPresent(lltok::kw_opaque)) { + // This type is being defined, so clear the location to indicate this. + Entry.second = SMLoc(); + + // If this type number has never been uttered, create it. + if (Entry.first == 0) + Entry.first = StructType::createNamed(Context, Name); + ResultTy = Entry.first; + return false; + } + + // If the type starts with '<', then it is either a packed struct or a vector. + bool isPacked = EatIfPresent(lltok::less); + + // If we don't have a struct, then we have a random type alias, which we + // accept for compatibility with old files. These types are not allowed to be + // forward referenced and not allowed to be recursive. + if (Lex.getKind() != lltok::lbrace) { + if (Entry.first) + return Error(TypeLoc, "forward references to non-struct type"); + + ResultTy = 0; + if (isPacked) + return ParseArrayVectorType(ResultTy, true); + return ParseType(ResultTy); + } + + // This type is being defined, so clear the location to indicate this. + Entry.second = SMLoc(); + + // If this type number has never been uttered, create it. + if (Entry.first == 0) + Entry.first = StructType::createNamed(Context, Name); + + StructType *STy = cast<StructType>(Entry.first); + + SmallVector<Type*, 8> Body; + if (ParseStructBody(Body) || + (isPacked && ParseToken(lltok::greater, "expected '>' in packed struct"))) + return true; + + STy->setBody(Body, isPacked); + ResultTy = STy; return false; } + /// ParseStructType: Handles packed and unpacked types. </> parsed elsewhere. -/// TypeRec +/// StructType /// ::= '{' '}' -/// ::= '{' TypeRec (',' TypeRec)* '}' +/// ::= '{' Type (',' Type)* '}' /// ::= '<' '{' '}' '>' -/// ::= '<' '{' TypeRec (',' TypeRec)* '}' '>' -bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) { +/// ::= '<' '{' Type (',' Type)* '}' '>' +bool LLParser::ParseStructBody(SmallVectorImpl<Type*> &Body) { assert(Lex.getKind() == lltok::lbrace); Lex.Lex(); // Consume the '{' - if (EatIfPresent(lltok::rbrace)) { - Result = StructType::get(Context, Packed); + // Handle the empty struct. + if (EatIfPresent(lltok::rbrace)) return false; - } - std::vector<PATypeHolder> ParamsList; LocTy EltTyLoc = Lex.getLoc(); - if (ParseTypeRec(Result)) return true; - ParamsList.push_back(Result); + Type *Ty = 0; + if (ParseType(Ty)) return true; + Body.push_back(Ty); - if (Result->isVoidTy()) - return Error(EltTyLoc, "struct element can not have void type"); - if (!StructType::isValidElementType(Result)) + if (!StructType::isValidElementType(Ty)) return Error(EltTyLoc, "invalid element type for struct"); while (EatIfPresent(lltok::comma)) { EltTyLoc = Lex.getLoc(); - if (ParseTypeRec(Result)) return true; + if (ParseType(Ty)) return true; - if (Result->isVoidTy()) - return Error(EltTyLoc, "struct element can not have void type"); - if (!StructType::isValidElementType(Result)) + if (!StructType::isValidElementType(Ty)) return Error(EltTyLoc, "invalid element type for struct"); - ParamsList.push_back(Result); + Body.push_back(Ty); } - if (ParseToken(lltok::rbrace, "expected '}' at end of struct")) - return true; - - std::vector<const Type*> ParamsListTy; - for (unsigned i = 0, e = ParamsList.size(); i != e; ++i) - ParamsListTy.push_back(ParamsList[i].get()); - Result = HandleUpRefs(StructType::get(Context, ParamsListTy, Packed)); - return false; + return ParseToken(lltok::rbrace, "expected '}' at end of struct"); } /// ParseArrayVectorType - Parse an array or vector type, assuming the first /// token has already been consumed. -/// TypeRec +/// Type /// ::= '[' APSINTVAL 'x' Types ']' /// ::= '<' APSINTVAL 'x' Types '>' -bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) { +bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) { if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() || Lex.getAPSIntVal().getBitWidth() > 64) return TokError("expected number in address space"); @@ -1644,11 +1570,8 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) { return true; LocTy TypeLoc = Lex.getLoc(); - PATypeHolder EltTy(Type::getVoidTy(Context)); - if (ParseTypeRec(EltTy)) return true; - - if (EltTy->isVoidTy()) - return Error(TypeLoc, "array and vector element type cannot be void"); + Type *EltTy = 0; + if (ParseType(EltTy)) return true; if (ParseToken(isVector ? lltok::greater : lltok::rsquare, "expected end of sequential type")) @@ -1665,7 +1588,7 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) { } else { if (!ArrayType::isValidElementType(EltTy)) return Error(TypeLoc, "invalid array element type"); - Result = HandleUpRefs(ArrayType::get(EltTy, Size)); + Result = ArrayType::get(EltTy, Size); } return false; } @@ -1770,7 +1693,7 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, } // Don't make placeholders with invalid type. - if (!Ty->isFirstClassType() && !Ty->isOpaqueTy() && !Ty->isLabelTy()) { + if (!Ty->isFirstClassType() && !Ty->isLabelTy()) { P.Error(Loc, "invalid use of a non-first-class type"); return 0; } @@ -1811,7 +1734,7 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, const Type *Ty, return 0; } - if (!Ty->isFirstClassType() && !Ty->isOpaqueTy() && !Ty->isLabelTy()) { + if (!Ty->isFirstClassType() && !Ty->isLabelTy()) { P.Error(Loc, "invalid use of a non-first-class type"); return 0; } @@ -1987,9 +1910,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ParseToken(lltok::rbrace, "expected end of struct constant")) return true; - // FIXME: Get this type from context instead of reconstructing it! - ID.ConstantVal = ConstantStruct::getAnon(Context, Elts); - ID.Kind = ValID::t_Constant; + ID.ConstantStructElts = new Constant*[Elts.size()]; + ID.UIntVal = Elts.size(); + memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0])); + ID.Kind = ValID::t_ConstantStruct; return false; } case lltok::less: { @@ -2007,9 +1931,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return true; if (isPackedStruct) { - // FIXME: Get this type from context instead of reconstructing it! - ID.ConstantVal = ConstantStruct::getAnon(Context, Elts, true); - ID.Kind = ValID::t_Constant; + ID.ConstantStructElts = new Constant*[Elts.size()]; + memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0])); + ID.UIntVal = Elts.size(); + ID.Kind = ValID::t_PackedConstantStruct; return false; } @@ -2131,7 +2056,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { case lltok::kw_inttoptr: case lltok::kw_ptrtoint: { unsigned Opc = Lex.getUIntVal(); - PATypeHolder DestTy(Type::getVoidTy(Context)); + Type *DestTy = 0; Constant *SrcVal; Lex.Lex(); if (ParseToken(lltok::lparen, "expected '(' after constantexpr cast") || @@ -2414,9 +2339,9 @@ bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&C) { } bool LLParser::ParseGlobalTypeAndValue(Constant *&V) { - PATypeHolder Type(Type::getVoidTy(Context)); - return ParseType(Type) || - ParseGlobalValue(Type, V); + Type *Ty = 0; + return ParseType(Ty) || + ParseGlobalValue(Ty, V); } /// ParseGlobalValueVector @@ -2562,8 +2487,7 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, return false; case ValID::t_Undef: // FIXME: LabelTy should not be a first-class type. - if ((!Ty->isFirstClassType() || Ty->isLabelTy()) && - !Ty->isOpaqueTy()) + if (!Ty->isFirstClassType() || Ty->isLabelTy()) return Error(ID.Loc, "invalid type for undef constant"); V = UndefValue::get(Ty); return false; @@ -2584,20 +2508,40 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, V = ID.ConstantVal; return false; + case ValID::t_ConstantStruct: + case ValID::t_PackedConstantStruct: + if (const StructType *ST = dyn_cast<StructType>(Ty)) { + if (ST->getNumElements() != ID.UIntVal) + return Error(ID.Loc, + "initializer with struct type has wrong # elements"); + if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct)) + return Error(ID.Loc, "packed'ness of initializer and type don't match"); + + // Verify that the elements are compatible with the structtype. + for (unsigned i = 0, e = ID.UIntVal; i != e; ++i) + if (ID.ConstantStructElts[i]->getType() != ST->getElementType(i)) + return Error(ID.Loc, "element " + Twine(i) + + " of struct initializer doesn't match struct element type"); + + V = ConstantStruct::get(ST, ArrayRef<Constant*>(ID.ConstantStructElts, + ID.UIntVal)); + } else + return Error(ID.Loc, "constant expression type mismatch"); + return false; } } -bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) { +bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState *PFS) { V = 0; ValID ID; - return ParseValID(ID, &PFS) || - ConvertValIDToValue(Ty, ID, V, &PFS); + return ParseValID(ID, PFS) || + ConvertValIDToValue(Ty, ID, V, PFS); } -bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState &PFS) { - PATypeHolder T(Type::getVoidTy(Context)); - return ParseType(T) || - ParseValue(T, V, PFS); +bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) { + Type *Ty = 0; + return ParseType(Ty) || + ParseValue(Ty, V, PFS); } bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, @@ -2623,7 +2567,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { unsigned Visibility, RetAttrs; CallingConv::ID CC; - PATypeHolder RetType(Type::getVoidTy(Context)); + Type *RetType = 0; LocTy RetTypeLoc = Lex.getLoc(); if (ParseOptionalLinkage(Linkage) || ParseOptionalVisibility(Visibility) || @@ -2660,8 +2604,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { return Error(LinkageLoc, "invalid function linkage type"); } - if (!FunctionType::isValidReturnType(RetType) || - RetType->isOpaqueTy()) + if (!FunctionType::isValidReturnType(RetType)) return Error(RetTypeLoc, "invalid function return type"); LocTy NameLoc = Lex.getLoc(); @@ -2684,7 +2627,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { if (Lex.getKind() != lltok::lparen) return TokError("expected '(' in function argument list"); - std::vector<ArgInfo> ArgList; + SmallVector<ArgInfo, 8> ArgList; bool isVarArg; unsigned FuncAttrs; std::string Section; @@ -2693,7 +2636,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { bool UnnamedAddr; LocTy UnnamedAddrLoc; - if (ParseArgumentList(ArgList, isVarArg, false) || + if (ParseArgumentList(ArgList, isVarArg) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, &UnnamedAddrLoc) || ParseOptionalAttrs(FuncAttrs, 2) || @@ -2719,7 +2662,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { - ParamTypeList.push_back(ArgList[i].Type); + ParamTypeList.push_back(ArgList[i].Ty); if (ArgList[i].Attrs != Attribute::None) Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); } @@ -3052,11 +2995,18 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) { /// ::= 'ret' void (',' !dbg, !1)* /// ::= 'ret' TypeAndValue (',' !dbg, !1)* bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, - PerFunctionState &PFS) { - PATypeHolder Ty(Type::getVoidTy(Context)); + PerFunctionState &PFS) { + SMLoc TypeLoc = Lex.getLoc(); + Type *Ty = 0; if (ParseType(Ty, true /*void allowed*/)) return true; + Type *ResType = PFS.getFunction().getReturnType(); + if (Ty->isVoidTy()) { + if (!ResType->isVoidTy()) + return Error(TypeLoc, "value doesn't match function result type '" + + getTypeString(ResType) + "'"); + Inst = ReturnInst::Create(Context); return false; } @@ -3064,6 +3014,10 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, Value *RV; if (ParseValue(Ty, RV, PFS)) return true; + if (ResType != RV->getType()) + return Error(TypeLoc, "value doesn't match function result type '" + + getTypeString(ResType) + "'"); + Inst = ReturnInst::Create(Context, RV); return false; } @@ -3191,7 +3145,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { LocTy CallLoc = Lex.getLoc(); unsigned RetAttrs, FnAttrs; CallingConv::ID CC; - PATypeHolder RetType(Type::getVoidTy(Context)); + Type *RetType = 0; LocTy RetTypeLoc; ValID CalleeID; SmallVector<ParamInfo, 16> ArgList; @@ -3369,8 +3323,9 @@ bool LLParser::ParseCompare(Instruction *&Inst, PerFunctionState &PFS, /// ::= CastOpc TypeAndValue 'to' Type bool LLParser::ParseCast(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc) { - LocTy Loc; Value *Op; - PATypeHolder DestTy(Type::getVoidTy(Context)); + LocTy Loc; + Value *Op; + Type *DestTy = 0; if (ParseTypeAndValue(Op, Loc, PFS) || ParseToken(lltok::kw_to, "expected 'to' after cast value") || ParseType(DestTy)) @@ -3409,7 +3364,7 @@ bool LLParser::ParseSelect(Instruction *&Inst, PerFunctionState &PFS) { /// ::= 'va_arg' TypeAndValue ',' Type bool LLParser::ParseVA_Arg(Instruction *&Inst, PerFunctionState &PFS) { Value *Op; - PATypeHolder EltTy(Type::getVoidTy(Context)); + Type *EltTy = 0; LocTy TypeLoc; if (ParseTypeAndValue(Op, PFS) || ParseToken(lltok::comma, "expected ',' after vaarg operand") || @@ -3481,11 +3436,10 @@ bool LLParser::ParseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) { /// ParsePHI /// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Value ']')* int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { - PATypeHolder Ty(Type::getVoidTy(Context)); + Type *Ty = 0; LocTy TypeLoc; Value *Op0, *Op1; - LocTy TypeLoc = Lex.getLoc(); - if (ParseType(Ty) || + if (ParseType(Ty, TypeLoc) || ParseToken(lltok::lsquare, "expected '[' in phi value list") || ParseValue(Ty, Op0, PFS) || ParseToken(lltok::comma, "expected ',' after insertelement value") || @@ -3531,7 +3485,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, bool isTail) { unsigned RetAttrs, FnAttrs; CallingConv::ID CC; - PATypeHolder RetType(Type::getVoidTy(Context)); + Type *RetType = 0; LocTy RetTypeLoc; ValID CalleeID; SmallVector<ParamInfo, 16> ArgList; @@ -3620,10 +3574,10 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, /// ParseAlloc /// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)? int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { - PATypeHolder Ty(Type::getVoidTy(Context)); Value *Size = 0; LocTy SizeLoc; unsigned Alignment = 0; + Type *Ty = 0; if (ParseType(Ty)) return true; bool AteExtraComma = false; @@ -3787,12 +3741,7 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts, } Value *V = 0; - PATypeHolder Ty(Type::getVoidTy(Context)); - ValID ID; - if (ParseType(Ty) || ParseValID(ID, PFS) || - ConvertValIDToValue(Ty, ID, V, PFS)) - return true; - + if (ParseTypeAndValue(V, PFS)) return true; Elts.push_back(V); } while (EatIfPresent(lltok::comma)); diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index c486799..9630657 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -18,6 +18,7 @@ #include "llvm/Module.h" #include "llvm/Type.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" #include "llvm/Support/ValueHandle.h" #include <map> @@ -32,6 +33,7 @@ namespace llvm { class GlobalValue; class MDString; class MDNode; + class StructType; /// ValID - Represents a reference of a definition of some sort with no type. /// There are several cases where we have to parse the value but where the @@ -47,7 +49,9 @@ namespace llvm { t_Constant, // Value in ConstantVal. t_InlineAsm, // Value in StrVal/StrVal2/UIntVal. t_MDNode, // Value in MDNodeVal. - t_MDString // Value in MDStringVal. + t_MDString, // Value in MDStringVal. + t_ConstantStruct, // Value in ConstantStructElts. + t_PackedConstantStruct // Value in ConstantStructElts. } Kind; LLLexer::LocTy Loc; @@ -58,12 +62,19 @@ namespace llvm { Constant *ConstantVal; MDNode *MDNodeVal; MDString *MDStringVal; - ValID() : APFloatVal(0.0) {} + Constant **ConstantStructElts; + + ValID() : Kind(t_LocalID), APFloatVal(0.0) {} + ~ValID() { + if (Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) + delete [] ConstantStructElts; + } bool operator<(const ValID &RHS) const { if (Kind == t_LocalID || Kind == t_GlobalID) return UIntVal < RHS.UIntVal; - assert((Kind == t_LocalName || Kind == t_GlobalName) && + assert((Kind == t_LocalName || Kind == t_GlobalName || + Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) && "Ordering not defined for this ValID kind yet"); return StrVal < RHS.StrVal; } @@ -93,33 +104,13 @@ namespace llvm { }; DenseMap<Instruction*, std::vector<MDRef> > ForwardRefInstMetadata; - // Type resolution handling data structures. - std::map<std::string, std::pair<PATypeHolder, LocTy> > ForwardRefTypes; - std::map<unsigned, std::pair<PATypeHolder, LocTy> > ForwardRefTypeIDs; - std::vector<PATypeHolder> NumberedTypes; + // Type resolution handling data structures. The location is set when we + // have processed a use of the type but not a definition yet. + StringMap<std::pair<Type*, LocTy> > NamedTypes; + std::vector<std::pair<Type*, LocTy> > NumberedTypes; + std::vector<TrackingVH<MDNode> > NumberedMetadata; std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> > ForwardRefMDNodes; - struct UpRefRecord { - /// Loc - This is the location of the upref. - LocTy Loc; - - /// NestingLevel - The number of nesting levels that need to be popped - /// before this type is resolved. - unsigned NestingLevel; - - /// LastContainedTy - This is the type at the current binding level for - /// the type. Every time we reduce the nesting level, this gets updated. - const Type *LastContainedTy; - - /// UpRefTy - This is the actual opaque type that the upreference is - /// represented with. - OpaqueType *UpRefTy; - - UpRefRecord(LocTy L, unsigned NL, OpaqueType *URTy) - : Loc(L), NestingLevel(NL), LastContainedTy((Type*)URTy), - UpRefTy(URTy) {} - }; - std::vector<UpRefRecord> UpRefs; // Global Value reference information. std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals; @@ -137,7 +128,7 @@ namespace llvm { M(m) {} bool Run(); - LLVMContext& getContext() { return Context; } + LLVMContext &getContext() { return Context; } private: @@ -222,16 +213,19 @@ namespace llvm { bool ParseMDNodeID(MDNode *&Result, unsigned &SlotNo); // Type Parsing. - bool ParseType(PATypeHolder &Result, bool AllowVoid = false); - bool ParseType(PATypeHolder &Result, LocTy &Loc, bool AllowVoid = false) { + bool ParseType(Type *&Result, bool AllowVoid = false); + bool ParseType(Type *&Result, LocTy &Loc, bool AllowVoid = false) { Loc = Lex.getLoc(); return ParseType(Result, AllowVoid); } - bool ParseTypeRec(PATypeHolder &H); - bool ParseStructType(PATypeHolder &H, bool Packed); - bool ParseArrayVectorType(PATypeHolder &H, bool isVector); - bool ParseFunctionType(PATypeHolder &Result); - PATypeHolder HandleUpRefs(const Type *Ty); + bool ParseAnonStructType(Type *&Result, bool Packed); + bool ParseStructBody(SmallVectorImpl<Type*> &Body); + bool ParseStructDefinition(SMLoc TypeLoc, StringRef Name, + std::pair<Type*, LocTy> &Entry, + Type *&ResultTy); + + bool ParseArrayVectorType(Type *&Result, bool isVector); + bool ParseFunctionType(Type *&Result); // Function Semantic Analysis. class PerFunctionState { @@ -278,14 +272,20 @@ namespace llvm { bool ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, PerFunctionState *PFS); - bool ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS); + bool ParseValue(const Type *Ty, Value *&V, PerFunctionState *PFS); + bool ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) { + return ParseValue(Ty, V, &PFS); + } bool ParseValue(const Type *Ty, Value *&V, LocTy &Loc, PerFunctionState &PFS) { Loc = Lex.getLoc(); - return ParseValue(Ty, V, PFS); + return ParseValue(Ty, V, &PFS); } - bool ParseTypeAndValue(Value *&V, PerFunctionState &PFS); + bool ParseTypeAndValue(Value *&V, PerFunctionState *PFS); + bool ParseTypeAndValue(Value *&V, PerFunctionState &PFS) { + return ParseTypeAndValue(V, &PFS); + } bool ParseTypeAndValue(Value *&V, LocTy &Loc, PerFunctionState &PFS) { Loc = Lex.getLoc(); return ParseTypeAndValue(V, PFS); @@ -321,14 +321,13 @@ namespace llvm { // Function Parsing. struct ArgInfo { LocTy Loc; - PATypeHolder Type; + Type *Ty; unsigned Attrs; std::string Name; - ArgInfo(LocTy L, PATypeHolder Ty, unsigned Attr, const std::string &N) - : Loc(L), Type(Ty), Attrs(Attr), Name(N) {} + ArgInfo(LocTy L, Type *ty, unsigned Attr, const std::string &N) + : Loc(L), Ty(ty), Attrs(Attr), Name(N) {} }; - bool ParseArgumentList(std::vector<ArgInfo> &ArgList, - bool &isVarArg, bool inType); + bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &isVarArg); bool ParseFunctionHeader(Function *&Fn, bool isDefine); bool ParseFunctionBody(Function &Fn); bool ParseBasicBlock(PerFunctionState &PFS); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 963791f..1bdcfe9 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -31,7 +31,7 @@ void BitcodeReader::FreeState() { if (BufferOwned) delete Buffer; Buffer = 0; - std::vector<PATypeHolder>().swap(TypeList); + std::vector<Type*>().swap(TypeList); ValueList.clear(); MDValueList.clear(); @@ -352,19 +352,28 @@ Value *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) { return V; } -const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) { - // If the TypeID is in range, return it. - if (ID < TypeList.size()) - return TypeList[ID].get(); - if (!isTypeTable) return 0; - - // The type table allows forward references. Push as many Opaque types as - // needed to get up to ID. - while (TypeList.size() <= ID) - TypeList.push_back(OpaqueType::get(Context)); - return TypeList.back().get(); +Type *BitcodeReader::getTypeByID(unsigned ID) { + // The type table size is always specified correctly. + if (ID >= TypeList.size()) + return 0; + + if (Type *Ty = TypeList[ID]) + return Ty; + + // If we have a forward reference, the only possible case is when it is to a + // named struct. Just create a placeholder for now. + return TypeList[ID] = StructType::createNamed(Context, ""); +} + +/// FIXME: Remove in LLVM 3.1, only used by ParseOldTypeTable. +Type *BitcodeReader::getTypeByIDOrNull(unsigned ID) { + if (ID >= TypeList.size()) + TypeList.resize(ID+1); + + return TypeList[ID]; } + //===----------------------------------------------------------------------===// // Functions for parsing blocks from the bitcode file //===----------------------------------------------------------------------===// @@ -471,17 +480,22 @@ bool BitcodeReader::ParseAttributeBlock() { } } - bool BitcodeReader::ParseTypeTable() { - if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID)) + if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) return Error("Malformed block record"); + + return ParseTypeTableBody(); +} +bool BitcodeReader::ParseTypeTableBody() { if (!TypeList.empty()) return Error("Multiple TYPE_BLOCKs found!"); SmallVector<uint64_t, 64> Record; unsigned NumRecords = 0; + SmallString<64> TypeName; + // Read all the records for this type table. while (1) { unsigned Code = Stream.ReadCode(); @@ -508,17 +522,15 @@ bool BitcodeReader::ParseTypeTable() { // Read a record. Record.clear(); - const Type *ResultTy = 0; + Type *ResultTy = 0; switch (Stream.ReadRecord(Code, Record)) { - default: // Default behavior: unknown type. - ResultTy = 0; - break; + default: return Error("unknown type in type table"); case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries] // TYPE_CODE_NUMENTRY contains a count of the number of types in the // type list. This allows us to reserve space. if (Record.size() < 1) return Error("Invalid TYPE_CODE_NUMENTRY record"); - TypeList.reserve(Record[0]); + TypeList.resize(Record[0]); continue; case bitc::TYPE_CODE_VOID: // VOID ResultTy = Type::getVoidTy(Context); @@ -541,9 +553,6 @@ bool BitcodeReader::ParseTypeTable() { case bitc::TYPE_CODE_LABEL: // LABEL ResultTy = Type::getLabelTy(Context); break; - case bitc::TYPE_CODE_OPAQUE: // OPAQUE - ResultTy = 0; - break; case bitc::TYPE_CODE_METADATA: // METADATA ResultTy = Type::getMetadataTy(Context); break; @@ -563,8 +572,9 @@ bool BitcodeReader::ParseTypeTable() { unsigned AddressSpace = 0; if (Record.size() == 2) AddressSpace = Record[1]; - ResultTy = PointerType::get(getTypeByID(Record[0], true), - AddressSpace); + ResultTy = getTypeByID(Record[0]); + if (ResultTy == 0) return Error("invalid element type in pointer type"); + ResultTy = PointerType::get(ResultTy, AddressSpace); break; } case bitc::TYPE_CODE_FUNCTION: { @@ -573,68 +583,305 @@ bool BitcodeReader::ParseTypeTable() { if (Record.size() < 3) return Error("Invalid FUNCTION type record"); std::vector<const Type*> ArgTys; - for (unsigned i = 3, e = Record.size(); i != e; ++i) - ArgTys.push_back(getTypeByID(Record[i], true)); + for (unsigned i = 3, e = Record.size(); i != e; ++i) { + if (Type *T = getTypeByID(Record[i])) + ArgTys.push_back(T); + else + break; + } + + ResultTy = getTypeByID(Record[2]); + if (ResultTy == 0 || ArgTys.size() < Record.size()-3) + return Error("invalid type in function type"); - ResultTy = FunctionType::get(getTypeByID(Record[2], true), ArgTys, - Record[0]); + ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]); break; } - case bitc::TYPE_CODE_STRUCT: { // STRUCT: [ispacked, eltty x N] + case bitc::TYPE_CODE_STRUCT_ANON: { // STRUCT: [ispacked, eltty x N] if (Record.size() < 1) return Error("Invalid STRUCT type record"); - std::vector<const Type*> EltTys; - for (unsigned i = 1, e = Record.size(); i != e; ++i) - EltTys.push_back(getTypeByID(Record[i], true)); + std::vector<Type*> EltTys; + for (unsigned i = 1, e = Record.size(); i != e; ++i) { + if (Type *T = getTypeByID(Record[i])) + EltTys.push_back(T); + else + break; + } + if (EltTys.size() != Record.size()-1) + return Error("invalid type in struct type"); ResultTy = StructType::get(Context, EltTys, Record[0]); break; } + case bitc::TYPE_CODE_STRUCT_NAME: // STRUCT_NAME: [strchr x N] + if (ConvertToString(Record, 0, TypeName)) + return Error("Invalid STRUCT_NAME record"); + continue; + + case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N] + if (Record.size() < 1) + return Error("Invalid STRUCT type record"); + + if (NumRecords >= TypeList.size()) + return Error("invalid TYPE table"); + + // Check to see if this was forward referenced, if so fill in the temp. + StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]); + if (Res) { + Res->setName(TypeName); + TypeList[NumRecords] = 0; + } else // Otherwise, create a new struct. + Res = StructType::createNamed(Context, TypeName); + TypeName.clear(); + + SmallVector<Type*, 8> EltTys; + for (unsigned i = 1, e = Record.size(); i != e; ++i) { + if (Type *T = getTypeByID(Record[i])) + EltTys.push_back(T); + else + break; + } + if (EltTys.size() != Record.size()-1) + return Error("invalid STRUCT type record"); + Res->setBody(EltTys, Record[0]); + ResultTy = Res; + break; + } + case bitc::TYPE_CODE_OPAQUE: { // OPAQUE: [] + if (Record.size() != 1) + return Error("Invalid OPAQUE type record"); + + if (NumRecords >= TypeList.size()) + return Error("invalid TYPE table"); + + // Check to see if this was forward referenced, if so fill in the temp. + StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]); + if (Res) { + Res->setName(TypeName); + TypeList[NumRecords] = 0; + } else // Otherwise, create a new struct with no body. + Res = StructType::createNamed(Context, TypeName); + TypeName.clear(); + ResultTy = Res; + break; + } case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty] if (Record.size() < 2) return Error("Invalid ARRAY type record"); - ResultTy = ArrayType::get(getTypeByID(Record[1], true), Record[0]); + if ((ResultTy = getTypeByID(Record[1]))) + ResultTy = ArrayType::get(ResultTy, Record[0]); + else + return Error("Invalid ARRAY type element"); break; case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] if (Record.size() < 2) return Error("Invalid VECTOR type record"); - ResultTy = VectorType::get(getTypeByID(Record[1], true), Record[0]); + if ((ResultTy = getTypeByID(Record[1]))) + ResultTy = VectorType::get(ResultTy, Record[0]); + else + return Error("Invalid ARRAY type element"); break; } - if (NumRecords == TypeList.size()) { - // If this is a new type slot, just append it. - TypeList.push_back(ResultTy ? ResultTy : OpaqueType::get(Context)); - ++NumRecords; - } else if (ResultTy == 0) { - // Otherwise, this was forward referenced, so an opaque type was created, - // but the result type is actually just an opaque. Leave the one we - // created previously. - ++NumRecords; - } else { - // Otherwise, this was forward referenced, so an opaque type was created. - // Resolve the opaque type to the real type now. - assert(NumRecords < TypeList.size() && "Typelist imbalance"); - const OpaqueType *OldTy = cast<OpaqueType>(TypeList[NumRecords++].get()); - - // Don't directly push the new type on the Tab. Instead we want to replace - // the opaque type we previously inserted with the new concrete value. The - // refinement from the abstract (opaque) type to the new type causes all - // uses of the abstract type to use the concrete type (NewTy). This will - // also cause the opaque type to be deleted. - const_cast<OpaqueType*>(OldTy)->refineAbstractTypeTo(ResultTy); - - // This should have replaced the old opaque type with the new type in the - // value table... or with a preexisting type that was already in the - // system. Let's just make sure it did. - assert(TypeList[NumRecords-1].get() != OldTy && - "refineAbstractType didn't work!"); + if (NumRecords >= TypeList.size()) + return Error("invalid TYPE table"); + assert(ResultTy && "Didn't read a type?"); + assert(TypeList[NumRecords] == 0 && "Already read type?"); + TypeList[NumRecords++] = ResultTy; + } +} + +// FIXME: Remove in LLVM 3.1 +bool BitcodeReader::ParseOldTypeTable() { + if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_OLD)) + return Error("Malformed block record"); + + if (!TypeList.empty()) + return Error("Multiple TYPE_BLOCKs found!"); + + + // While horrible, we have no good ordering of types in the bc file. Just + // iteratively parse types out of the bc file in multiple passes until we get + // them all. Do this by saving a cursor for the start of the type block. + BitstreamCursor StartOfTypeBlockCursor(Stream); + + unsigned NumTypesRead = 0; + + SmallVector<uint64_t, 64> Record; +RestartScan: + unsigned NextTypeID = 0; + bool ReadAnyTypes = false; + + // Read all the records for this type table. + while (1) { + unsigned Code = Stream.ReadCode(); + if (Code == bitc::END_BLOCK) { + if (NextTypeID != TypeList.size()) + return Error("Invalid type forward reference in TYPE_BLOCK_ID_OLD"); + + // If we haven't read all of the types yet, iterate again. + if (NumTypesRead != TypeList.size()) { + // If we didn't successfully read any types in this pass, then we must + // have an unhandled forward reference. + if (!ReadAnyTypes) + return Error("Obsolete bitcode contains unhandled recursive type"); + + Stream = StartOfTypeBlockCursor; + goto RestartScan; + } + + if (Stream.ReadBlockEnd()) + return Error("Error at end of type table block"); + return false; + } + + if (Code == bitc::ENTER_SUBBLOCK) { + // No known subblocks, always skip them. + Stream.ReadSubBlockID(); + if (Stream.SkipBlock()) + return Error("Malformed block record"); + continue; } + + if (Code == bitc::DEFINE_ABBREV) { + Stream.ReadAbbrevRecord(); + continue; + } + + // Read a record. + Record.clear(); + Type *ResultTy = 0; + switch (Stream.ReadRecord(Code, Record)) { + default: return Error("unknown type in type table"); + case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries] + // TYPE_CODE_NUMENTRY contains a count of the number of types in the + // type list. This allows us to reserve space. + if (Record.size() < 1) + return Error("Invalid TYPE_CODE_NUMENTRY record"); + TypeList.resize(Record[0]); + continue; + case bitc::TYPE_CODE_VOID: // VOID + ResultTy = Type::getVoidTy(Context); + break; + case bitc::TYPE_CODE_FLOAT: // FLOAT + ResultTy = Type::getFloatTy(Context); + break; + case bitc::TYPE_CODE_DOUBLE: // DOUBLE + ResultTy = Type::getDoubleTy(Context); + break; + case bitc::TYPE_CODE_X86_FP80: // X86_FP80 + ResultTy = Type::getX86_FP80Ty(Context); + break; + case bitc::TYPE_CODE_FP128: // FP128 + ResultTy = Type::getFP128Ty(Context); + break; + case bitc::TYPE_CODE_PPC_FP128: // PPC_FP128 + ResultTy = Type::getPPC_FP128Ty(Context); + break; + case bitc::TYPE_CODE_LABEL: // LABEL + ResultTy = Type::getLabelTy(Context); + break; + case bitc::TYPE_CODE_METADATA: // METADATA + ResultTy = Type::getMetadataTy(Context); + break; + case bitc::TYPE_CODE_X86_MMX: // X86_MMX + ResultTy = Type::getX86_MMXTy(Context); + break; + case bitc::TYPE_CODE_INTEGER: // INTEGER: [width] + if (Record.size() < 1) + return Error("Invalid Integer type record"); + ResultTy = IntegerType::get(Context, Record[0]); + break; + case bitc::TYPE_CODE_OPAQUE: // OPAQUE + if (NextTypeID < TypeList.size() && TypeList[NextTypeID] == 0) + ResultTy = StructType::createNamed(Context, ""); + break; + case bitc::TYPE_CODE_STRUCT_OLD: {// STRUCT_OLD + if (NextTypeID >= TypeList.size()) break; + // If we already read it, don't reprocess. + if (TypeList[NextTypeID] && + !cast<StructType>(TypeList[NextTypeID])->isOpaque()) + break; + + // Set a type. + if (TypeList[NextTypeID] == 0) + TypeList[NextTypeID] = StructType::createNamed(Context, ""); + + std::vector<Type*> EltTys; + for (unsigned i = 1, e = Record.size(); i != e; ++i) { + if (Type *Elt = getTypeByIDOrNull(Record[i])) + EltTys.push_back(Elt); + else + break; + } + + if (EltTys.size() != Record.size()-1) + break; // Not all elements are ready. + + cast<StructType>(TypeList[NextTypeID])->setBody(EltTys, Record[0]); + ResultTy = TypeList[NextTypeID]; + TypeList[NextTypeID] = 0; + break; + } + case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or + // [pointee type, address space] + if (Record.size() < 1) + return Error("Invalid POINTER type record"); + unsigned AddressSpace = 0; + if (Record.size() == 2) + AddressSpace = Record[1]; + if ((ResultTy = getTypeByIDOrNull(Record[0]))) + ResultTy = PointerType::get(ResultTy, AddressSpace); + break; + } + case bitc::TYPE_CODE_FUNCTION: { + // FIXME: attrid is dead, remove it in LLVM 3.0 + // FUNCTION: [vararg, attrid, retty, paramty x N] + if (Record.size() < 3) + return Error("Invalid FUNCTION type record"); + std::vector<const Type*> ArgTys; + for (unsigned i = 3, e = Record.size(); i != e; ++i) { + if (Type *Elt = getTypeByIDOrNull(Record[i])) + ArgTys.push_back(Elt); + else + break; + } + if (ArgTys.size()+3 != Record.size()) + break; // Something was null. + if ((ResultTy = getTypeByIDOrNull(Record[2]))) + ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]); + break; + } + case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty] + if (Record.size() < 2) + return Error("Invalid ARRAY type record"); + if ((ResultTy = getTypeByIDOrNull(Record[1]))) + ResultTy = ArrayType::get(ResultTy, Record[0]); + break; + case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] + if (Record.size() < 2) + return Error("Invalid VECTOR type record"); + if ((ResultTy = getTypeByIDOrNull(Record[1]))) + ResultTy = VectorType::get(ResultTy, Record[0]); + break; + } + + if (NextTypeID >= TypeList.size()) + return Error("invalid TYPE table"); + + if (ResultTy && TypeList[NextTypeID] == 0) { + ++NumTypesRead; + ReadAnyTypes = true; + + TypeList[NextTypeID] = ResultTy; + } + + ++NextTypeID; } } -bool BitcodeReader::ParseTypeSymbolTable() { - if (Stream.EnterSubBlock(bitc::TYPE_SYMTAB_BLOCK_ID)) +bool BitcodeReader::ParseOldTypeSymbolTable() { + if (Stream.EnterSubBlock(bitc::TYPE_SYMTAB_BLOCK_ID_OLD)) return Error("Malformed block record"); SmallVector<uint64_t, 64> Record; @@ -674,7 +921,10 @@ bool BitcodeReader::ParseTypeSymbolTable() { if (TypeID >= TypeList.size()) return Error("Invalid Type ID in TST_ENTRY record"); - TheModule->addTypeName(TypeName, TypeList[TypeID].get()); + // Only apply the type name to a struct type with no name. + if (StructType *STy = dyn_cast<StructType>(TypeList[TypeID])) + if (!STy->isAnonymous() && !STy->hasName()) + STy->setName(TypeName); TypeName.clear(); break; } @@ -1310,12 +1560,16 @@ bool BitcodeReader::ParseModule() { if (ParseAttributeBlock()) return true; break; - case bitc::TYPE_BLOCK_ID: + case bitc::TYPE_BLOCK_ID_NEW: if (ParseTypeTable()) return true; break; - case bitc::TYPE_SYMTAB_BLOCK_ID: - if (ParseTypeSymbolTable()) + case bitc::TYPE_BLOCK_ID_OLD: + if (ParseOldTypeTable()) + return true; + break; + case bitc::TYPE_SYMTAB_BLOCK_ID_OLD: + if (ParseOldTypeSymbolTable()) return true; break; case bitc::VALUE_SYMTAB_BLOCK_ID: @@ -2307,7 +2561,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { SmallVector<Value*, 16> Args; // Read the fixed params. for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { - if (FTy->getParamType(i)->getTypeID()==Type::LabelTyID) + if (FTy->getParamType(i)->isLabelTy()) Args.push_back(getBasicBlock(Record[OpNum])); else Args.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i))); diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 14033b0..1b3bf1a 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -131,7 +131,7 @@ class BitcodeReader : public GVMaterializer { const char *ErrorString; - std::vector<PATypeHolder> TypeList; + std::vector<Type*> TypeList; BitcodeReaderValueList ValueList; BitcodeReaderMDValueList MDValueList; SmallVector<Instruction *, 64> InstructionList; @@ -210,7 +210,8 @@ public: /// @returns true if an error occurred. bool ParseTriple(std::string &Triple); private: - const Type *getTypeByID(unsigned ID, bool isTypeTable = false); + Type *getTypeByID(unsigned ID); + Type *getTypeByIDOrNull(unsigned ID); Value *getFnValueByID(unsigned ID, const Type *Ty) { if (Ty && Ty->isMetadataTy()) return MDValueList.getValueFwdRef(ID); @@ -258,7 +259,10 @@ private: bool ParseModule(); bool ParseAttributeBlock(); bool ParseTypeTable(); - bool ParseTypeSymbolTable(); + bool ParseOldTypeTable(); // FIXME: Remove in LLVM 3.1 + bool ParseTypeTableBody(); + + bool ParseOldTypeSymbolTable(); // FIXME: Remove in LLVM 3.1 bool ParseValueSymbolTable(); bool ParseConstants(); bool RememberAndSkipFunctionBody(); diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 24b5e2d..85d67ce 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -21,7 +21,6 @@ #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Operator.h" -#include "llvm/TypeSymbolTable.h" #include "llvm/ValueSymbolTable.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/ErrorHandling.h" @@ -29,6 +28,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Program.h" #include <cctype> +#include <map> using namespace llvm; /// These are manifest constants used by the bitcode writer. They do not need to @@ -101,13 +101,16 @@ static unsigned GetEncodedBinaryOpcode(unsigned Opcode) { } } -static void WriteStringRecord(unsigned Code, const std::string &Str, +static void WriteStringRecord(unsigned Code, StringRef Str, unsigned AbbrevToUse, BitstreamWriter &Stream) { SmallVector<unsigned, 64> Vals; // Code: [strchar x N] - for (unsigned i = 0, e = Str.size(); i != e; ++i) + for (unsigned i = 0, e = Str.size(); i != e; ++i) { + if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(Str[i])) + AbbrevToUse = 0; Vals.push_back(Str[i]); + } // Emit the finished record. Stream.EmitRecord(Code, Vals, AbbrevToUse); @@ -151,7 +154,7 @@ static void WriteAttributeTable(const ValueEnumerator &VE, static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { const ValueEnumerator::TypeList &TypeList = VE.getTypes(); - Stream.EnterSubblock(bitc::TYPE_BLOCK_ID, 4 /*count from # abbrevs */); + Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */); SmallVector<uint64_t, 64> TypeVals; // Abbrev for TYPE_CODE_POINTER. @@ -172,15 +175,32 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { Log2_32_Ceil(VE.getTypes().size()+1))); unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv); - // Abbrev for TYPE_CODE_STRUCT. + // Abbrev for TYPE_CODE_STRUCT_ANON. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_ANON)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + Log2_32_Ceil(VE.getTypes().size()+1))); + unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv); + + // Abbrev for TYPE_CODE_STRUCT_NAME. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAME)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); + unsigned StructNameAbbrev = Stream.EmitAbbrev(Abbv); + + // Abbrev for TYPE_CODE_STRUCT_NAMED. Abbv = new BitCodeAbbrev(); - Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT)); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAMED)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(VE.getTypes().size()+1))); - unsigned StructAbbrev = Stream.EmitAbbrev(Abbv); + unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv); + // Abbrev for TYPE_CODE_ARRAY. Abbv = new BitCodeAbbrev(); Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY)); @@ -202,16 +222,15 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { switch (T->getTypeID()) { default: llvm_unreachable("Unknown type!"); - case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break; - case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break; - case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break; - case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break; - case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break; + case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break; + case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break; + case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break; + case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break; + case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break; case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break; - case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break; - case Type::OpaqueTyID: Code = bitc::TYPE_CODE_OPAQUE; break; - case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; - case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; + case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break; + case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; + case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; case Type::IntegerTyID: // INTEGER: [width] Code = bitc::TYPE_CODE_INTEGER; @@ -242,13 +261,28 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { case Type::StructTyID: { const StructType *ST = cast<StructType>(T); // STRUCT: [ispacked, eltty x N] - Code = bitc::TYPE_CODE_STRUCT; TypeVals.push_back(ST->isPacked()); // Output all of the element types. for (StructType::element_iterator I = ST->element_begin(), E = ST->element_end(); I != E; ++I) TypeVals.push_back(VE.getTypeID(*I)); - AbbrevToUse = StructAbbrev; + + if (ST->isAnonymous()) { + Code = bitc::TYPE_CODE_STRUCT_ANON; + AbbrevToUse = StructAnonAbbrev; + } else { + if (ST->isOpaque()) { + Code = bitc::TYPE_CODE_OPAQUE; + } else { + Code = bitc::TYPE_CODE_STRUCT_NAMED; + AbbrevToUse = StructNamedAbbrev; + } + + // Emit the name if it is present. + if (!ST->getName().empty()) + WriteStringRecord(bitc::TYPE_CODE_STRUCT_NAME, ST->getName(), + StructNameAbbrev, Stream); + } break; } case Type::ArrayTyID: { @@ -1278,46 +1312,6 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, Stream.ExitBlock(); } -/// WriteTypeSymbolTable - Emit a block for the specified type symtab. -static void WriteTypeSymbolTable(const TypeSymbolTable &TST, - const ValueEnumerator &VE, - BitstreamWriter &Stream) { - if (TST.empty()) return; - - Stream.EnterSubblock(bitc::TYPE_SYMTAB_BLOCK_ID, 3); - - // 7-bit fixed width VST_CODE_ENTRY strings. - BitCodeAbbrev *Abbv = new BitCodeAbbrev(); - Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, - Log2_32_Ceil(VE.getTypes().size()+1))); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); - unsigned V7Abbrev = Stream.EmitAbbrev(Abbv); - - SmallVector<unsigned, 64> NameVals; - - for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end(); - TI != TE; ++TI) { - // TST_ENTRY: [typeid, namechar x N] - NameVals.push_back(VE.getTypeID(TI->second)); - - const std::string &Str = TI->first; - bool is7Bit = true; - for (unsigned i = 0, e = Str.size(); i != e; ++i) { - NameVals.push_back((unsigned char)Str[i]); - if (Str[i] & 128) - is7Bit = false; - } - - // Emit the finished record. - Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, is7Bit ? V7Abbrev : 0); - NameVals.clear(); - } - - Stream.ExitBlock(); -} - // Emit blockinfo, which defines the standard abbreviations etc. static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { // We only want to emit block info records for blocks that have multiple @@ -1521,9 +1515,6 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) { // Emit metadata. WriteModuleMetadataStore(M, Stream); - // Emit the type symbol table information. - WriteTypeSymbolTable(M->getTypeSymbolTable(), VE, Stream); - // Emit names for globals/functions etc. WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream); diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 5138c3c..b68bf92 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -17,7 +17,6 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" -#include "llvm/TypeSymbolTable.h" #include "llvm/ValueSymbolTable.h" #include "llvm/Instructions.h" #include <algorithm> @@ -59,9 +58,6 @@ ValueEnumerator::ValueEnumerator(const Module *M) { I != E; ++I) EnumerateValue(I->getAliasee()); - // Enumerate types used by the type symbol table. - EnumerateTypeSymbolTable(M->getTypeSymbolTable()); - // Insert constants and metadata that are named at module level into the slot // pool so that the module symbol table can refer to them... EnumerateValueSymbolTable(M->getValueSymbolTable()); @@ -109,78 +105,12 @@ ValueEnumerator::ValueEnumerator(const Module *M) { // Optimize constant ordering. OptimizeConstants(FirstConstant, Values.size()); - - OptimizeTypes(); - - // Now that we rearranged the type table, rebuild TypeMap. - for (unsigned i = 0, e = Types.size(); i != e; ++i) - TypeMap[Types[i]] = i+1; -} - -struct TypeAndDeps { - const Type *Ty; - unsigned NumDeps; -}; - -static int CompareByDeps(const void *a, const void *b) { - const TypeAndDeps &ta = *(const TypeAndDeps*) a; - const TypeAndDeps &tb = *(const TypeAndDeps*) b; - return ta.NumDeps - tb.NumDeps; -} - -static void VisitType(const Type *Ty, SmallPtrSet<const Type*, 16> &Visited, - std::vector<const Type*> &Out) { - if (Visited.count(Ty)) - return; - - Visited.insert(Ty); - - for (Type::subtype_iterator I2 = Ty->subtype_begin(), - E2 = Ty->subtype_end(); I2 != E2; ++I2) { - const Type *InnerType = I2->get(); - VisitType(InnerType, Visited, Out); - } - - Out.push_back(Ty); } -void ValueEnumerator::OptimizeTypes(void) { - // If the types form a DAG, this will compute a topological sort and - // no forward references will be needed when reading them in. - // If there are cycles, this is a simple but reasonable heuristic for - // the minimum feedback arc set problem. - const unsigned NumTypes = Types.size(); - std::vector<TypeAndDeps> TypeDeps; - TypeDeps.resize(NumTypes); - - for (unsigned I = 0; I < NumTypes; ++I) { - const Type *Ty = Types[I]; - TypeDeps[I].Ty = Ty; - TypeDeps[I].NumDeps = 0; - } - - for (unsigned I = 0; I < NumTypes; ++I) { - const Type *Ty = TypeDeps[I].Ty; - for (Type::subtype_iterator I2 = Ty->subtype_begin(), - E2 = Ty->subtype_end(); I2 != E2; ++I2) { - const Type *InnerType = I2->get(); - unsigned InnerIndex = TypeMap.lookup(InnerType) - 1; - TypeDeps[InnerIndex].NumDeps++; - } - } - array_pod_sort(TypeDeps.begin(), TypeDeps.end(), CompareByDeps); - - SmallPtrSet<const Type*, 16> Visited; - Types.clear(); - Types.reserve(NumTypes); - for (unsigned I = 0; I < NumTypes; ++I) { - VisitType(TypeDeps[I].Ty, Visited, Types); - } -} unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const { InstructionMapType::const_iterator I = InstructionMap.find(Inst); - assert (I != InstructionMap.end() && "Instruction is not mapped!"); + assert(I != InstructionMap.end() && "Instruction is not mapped!"); return I->second; } @@ -235,14 +165,6 @@ void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) { } -/// EnumerateTypeSymbolTable - Insert all of the types in the specified symbol -/// table. -void ValueEnumerator::EnumerateTypeSymbolTable(const TypeSymbolTable &TST) { - for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end(); - TI != TE; ++TI) - EnumerateType(TI->second); -} - /// EnumerateValueSymbolTable - Insert all of the values in the specified symbol /// table into the values table. void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) { @@ -394,20 +316,40 @@ void ValueEnumerator::EnumerateValue(const Value *V) { void ValueEnumerator::EnumerateType(const Type *Ty) { - unsigned &TypeID = TypeMap[Ty]; + unsigned *TypeID = &TypeMap[Ty]; // We've already seen this type. - if (TypeID) + if (*TypeID) return; - // First time we saw this type, add it. - Types.push_back(Ty); - TypeID = Types.size(); - - // Enumerate subtypes. + // If it is a non-anonymous struct, mark the type as being visited so that we + // don't recursively visit it. This is safe because we allow forward + // references of these in the bitcode reader. + if (const StructType *STy = dyn_cast<StructType>(Ty)) + if (!STy->isAnonymous()) + *TypeID = ~0U; + + // Enumerate all of the subtypes before we enumerate this type. This ensures + // that the type will be enumerated in an order that can be directly built. for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); I != E; ++I) EnumerateType(*I); + + // Refresh the TypeID pointer in case the table rehashed. + TypeID = &TypeMap[Ty]; + + // Check to see if we got the pointer another way. This can happen when + // enumerating recursive types that hit the base case deeper than they start. + // + // If this is actually a struct that we are treating as forward ref'able, + // then emit the definition now that all of its contents are available. + if (*TypeID && *TypeID != ~0U) + return; + + // Add this type now that its contents are all happily enumerated. + Types.push_back(Ty); + + *TypeID = Types.size(); } // Enumerate the types for the specified value. If the value is a constant, diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h index 1e42a26..6617b60 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.h +++ b/lib/Bitcode/Writer/ValueEnumerator.h @@ -30,7 +30,6 @@ class Module; class MDNode; class NamedMDNode; class AttrListPtr; -class TypeSymbolTable; class ValueSymbolTable; class MDSymbolTable; @@ -135,7 +134,6 @@ public: private: void OptimizeConstants(unsigned CstStart, unsigned CstEnd); - void OptimizeTypes(); void EnumerateMDNodeOperands(const MDNode *N); void EnumerateMetadata(const Value *MD); @@ -146,7 +144,6 @@ private: void EnumerateOperandType(const Value *V); void EnumerateAttributes(const AttrListPtr &PAL); - void EnumerateTypeSymbolTable(const TypeSymbolTable &ST); void EnumerateValueSymbolTable(const ValueSymbolTable &ST); void EnumerateNamedMetadata(const Module *M); }; diff --git a/lib/CodeGen/ShadowStackGC.cpp b/lib/CodeGen/ShadowStackGC.cpp index ff58b22..d7c9ada 100644 --- a/lib/CodeGen/ShadowStackGC.cpp +++ b/lib/CodeGen/ShadowStackGC.cpp @@ -45,7 +45,8 @@ namespace { /// StackEntryTy - Abstract type of a link in the shadow stack. /// - const StructType *StackEntryTy; + StructType *StackEntryTy; + StructType *FrameMapTy; /// Roots - GC roots in the current function. Each is a pair of the /// intrinsic call and its corresponding alloca. @@ -211,18 +212,14 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) { }; Constant *DescriptorElts[] = { - ConstantStruct::get(StructType::get(Int32Ty, Int32Ty, NULL), BaseElts), + ConstantStruct::get(FrameMapTy, BaseElts), ConstantArray::get(ArrayType::get(VoidPtr, NumMeta), Metadata) }; - Constant *FrameMap = - ConstantStruct::get(StructType::get(DescriptorElts[0]->getType(), - DescriptorElts[1]->getType(), NULL), - DescriptorElts); - - std::string TypeName("gc_map."); - TypeName += utostr(NumMeta); - F.getParent()->addTypeName(TypeName, FrameMap->getType()); + Type *EltTys[] = { DescriptorElts[0]->getType(),DescriptorElts[1]->getType()}; + StructType *STy = StructType::createNamed("gc_map."+utostr(NumMeta), EltTys); + + Constant *FrameMap = ConstantStruct::get(STy, DescriptorElts); // FIXME: Is this actually dangerous as WritingAnLLVMPass.html claims? Seems // that, short of multithreaded LLVM, it should be safe; all that is @@ -250,17 +247,12 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) { const Type* ShadowStackGC::GetConcreteStackEntryType(Function &F) { // doInitialization creates the generic version of this type. - std::vector<const Type*> EltTys; + std::vector<Type*> EltTys; EltTys.push_back(StackEntryTy); for (size_t I = 0; I != Roots.size(); I++) EltTys.push_back(Roots[I].second->getAllocatedType()); - Type *Ty = StructType::get(F.getContext(), EltTys); - - std::string TypeName("gc_stackentry."); - TypeName += F.getName(); - F.getParent()->addTypeName(TypeName, Ty); - - return Ty; + + return StructType::createNamed("gc_stackentry."+F.getName().str(), EltTys); } /// doInitialization - If this module uses the GC intrinsics, find them now. If @@ -271,13 +263,12 @@ bool ShadowStackGC::initializeCustomLowering(Module &M) { // int32_t NumMeta; // Number of metadata descriptors. May be < NumRoots. // void *Meta[]; // May be absent for roots without metadata. // }; - std::vector<const Type*> EltTys; + std::vector<Type*> EltTys; // 32 bits is ok up to a 32GB stack frame. :) EltTys.push_back(Type::getInt32Ty(M.getContext())); // Specifies length of variable length array. EltTys.push_back(Type::getInt32Ty(M.getContext())); - StructType *FrameMapTy = StructType::get(M.getContext(), EltTys); - M.addTypeName("gc_map", FrameMapTy); + FrameMapTy = StructType::createNamed("gc_map", EltTys); PointerType *FrameMapPtrTy = PointerType::getUnqual(FrameMapTy); // struct StackEntry { @@ -285,18 +276,14 @@ bool ShadowStackGC::initializeCustomLowering(Module &M) { // FrameMap *Map; // Pointer to constant FrameMap. // void *Roots[]; // Stack roots (in-place array, so we pretend). // }; - OpaqueType *RecursiveTy = OpaqueType::get(M.getContext()); - + + StackEntryTy = StructType::createNamed(M.getContext(), "gc_stackentry"); + EltTys.clear(); - EltTys.push_back(PointerType::getUnqual(RecursiveTy)); + EltTys.push_back(PointerType::getUnqual(StackEntryTy)); EltTys.push_back(FrameMapPtrTy); - PATypeHolder LinkTyH = StructType::get(M.getContext(), EltTys); - - RecursiveTy->refineAbstractTypeTo(LinkTyH.get()); - StackEntryTy = cast<StructType>(LinkTyH.get()); + StackEntryTy->setBody(EltTys); const PointerType *StackEntryPtrTy = PointerType::getUnqual(StackEntryTy); - M.addTypeName("gc_stackentry", LinkTyH.get()); // FIXME: Is this safe from - // a FunctionPass? // Get the root chain if it already exists. Head = M.getGlobalVariable("llvm_gc_root_chain"); @@ -403,7 +390,7 @@ bool ShadowStackGC::performCustomLowering(Function &F) { Instruction *CurrentHead = AtEntry.CreateLoad(Head, "gc_currhead"); Instruction *EntryMapPtr = CreateGEP(Context, AtEntry, StackEntry, 0,1,"gc_frame.map"); - AtEntry.CreateStore(FrameMap, EntryMapPtr); + AtEntry.CreateStore(FrameMap, EntryMapPtr); // After all the allocas... for (unsigned I = 0, E = Roots.size(); I != E; ++I) { diff --git a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp index fe1f7fc..f7e2a4d 100644 --- a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp +++ b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp @@ -78,7 +78,6 @@ static char getTypeID(const Type *Ty) { case Type::FunctionTyID:return 'M'; case Type::StructTyID: return 'T'; case Type::ArrayTyID: return 'A'; - case Type::OpaqueTyID: return 'O'; default: return 'U'; } } diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index f372db2..d770627 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -9,337 +9,404 @@ // // This file implements the LLVM module linker. // -// Specifically, this: -// * Merges global variables between the two modules -// * Uninit + Uninit = Init, Init + Uninit = Init, Init + Init = Error if != -// * Merges functions between two modules -// //===----------------------------------------------------------------------===// #include "llvm/Linker.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" #include "llvm/Module.h" -#include "llvm/TypeSymbolTable.h" -#include "llvm/ValueSymbolTable.h" -#include "llvm/Instructions.h" -#include "llvm/Assembly/Writer.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" #include "llvm/Transforms/Utils/ValueMapper.h" -#include "llvm/ADT/DenseMap.h" using namespace llvm; -// Error - Simple wrapper function to conditionally assign to E and return true. -// This just makes error return conditions a little bit simpler... -static inline bool Error(std::string *E, const Twine &Message) { - if (E) *E = Message.str(); - return true; -} - -// Function: ResolveTypes() -// -// Description: -// Attempt to link the two specified types together. -// -// Inputs: -// DestTy - The type to which we wish to resolve. -// SrcTy - The original type which we want to resolve. -// -// Outputs: -// DestST - The symbol table in which the new type should be placed. -// -// Return value: -// true - There is an error and the types cannot yet be linked. -// false - No errors. -// -static bool ResolveTypes(const Type *DestTy, const Type *SrcTy) { - if (DestTy == SrcTy) return false; // If already equal, noop - assert(DestTy && SrcTy && "Can't handle null types"); - - if (const OpaqueType *OT = dyn_cast<OpaqueType>(DestTy)) { - // Type _is_ in module, just opaque... - const_cast<OpaqueType*>(OT)->refineAbstractTypeTo(SrcTy); - } else if (const OpaqueType *OT = dyn_cast<OpaqueType>(SrcTy)) { - const_cast<OpaqueType*>(OT)->refineAbstractTypeTo(DestTy); - } else { - return true; // Cannot link types... not-equal and neither is opaque. - } - return false; -} +//===----------------------------------------------------------------------===// +// TypeMap implementation. +//===----------------------------------------------------------------------===// -/// LinkerTypeMap - This implements a map of types that is stable -/// even if types are resolved/refined to other types. This is not a general -/// purpose map, it is specific to the linker's use. namespace { -class LinkerTypeMap : public AbstractTypeUser { - typedef DenseMap<const Type*, PATypeHolder> TheMapTy; - TheMapTy TheMap; - - LinkerTypeMap(const LinkerTypeMap&); // DO NOT IMPLEMENT - void operator=(const LinkerTypeMap&); // DO NOT IMPLEMENT +class TypeMapTy : public ValueMapTypeRemapper { + /// MappedTypes - This is a mapping from a source type to a destination type + /// to use. + DenseMap<Type*, Type*> MappedTypes; + + /// SpeculativeTypes - When checking to see if two subgraphs are isomorphic, + /// we speculatively add types to MappedTypes, but keep track of them here in + /// case we need to roll back. + SmallVector<Type*, 16> SpeculativeTypes; + + /// DefinitionsToResolve - This is a list of non-opaque structs in the source + /// module that are mapped to an opaque struct in the destination module. + SmallVector<StructType*, 16> DefinitionsToResolve; public: - LinkerTypeMap() {} - ~LinkerTypeMap() { - for (DenseMap<const Type*, PATypeHolder>::iterator I = TheMap.begin(), - E = TheMap.end(); I != E; ++I) - I->first->removeAbstractTypeUser(this); - } - - /// lookup - Return the value for the specified type or null if it doesn't - /// exist. - const Type *lookup(const Type *Ty) const { - TheMapTy::const_iterator I = TheMap.find(Ty); - if (I != TheMap.end()) return I->second; - return 0; - } - - /// insert - This returns true if the pointer was new to the set, false if it - /// was already in the set. - bool insert(const Type *Src, const Type *Dst) { - if (!TheMap.insert(std::make_pair(Src, PATypeHolder(Dst))).second) - return false; // Already in map. - if (Src->isAbstract()) - Src->addAbstractTypeUser(this); - return true; - } - -protected: - /// refineAbstractType - The callback method invoked when an abstract type is - /// resolved to another type. An object must override this method to update - /// its internal state to reference NewType instead of OldType. - /// - virtual void refineAbstractType(const DerivedType *OldTy, - const Type *NewTy) { - TheMapTy::iterator I = TheMap.find(OldTy); - const Type *DstTy = I->second; - - TheMap.erase(I); - if (OldTy->isAbstract()) - OldTy->removeAbstractTypeUser(this); - - // Don't reinsert into the map if the key is concrete now. - if (NewTy->isAbstract()) - insert(NewTy, DstTy); + + /// addTypeMapping - Indicate that the specified type in the destination + /// module is conceptually equivalent to the specified type in the source + /// module. + void addTypeMapping(Type *DstTy, Type *SrcTy); + + /// linkDefinedTypeBodies - Produce a body for an opaque type in the dest + /// module from a type definition in the source module. + void linkDefinedTypeBodies(); + + /// get - Return the mapped type to use for the specified input type from the + /// source module. + Type *get(Type *SrcTy); + + FunctionType *get(FunctionType *T) {return cast<FunctionType>(get((Type*)T));} + +private: + Type *getImpl(Type *T); + /// remapType - Implement the ValueMapTypeRemapper interface. + Type *remapType(Type *SrcTy) { + return get(SrcTy); } + + bool areTypesIsomorphic(Type *DstTy, Type *SrcTy); +}; +} - /// The other case which AbstractTypeUsers must be aware of is when a type - /// makes the transition from being abstract (where it has clients on it's - /// AbstractTypeUsers list) to concrete (where it does not). This method - /// notifies ATU's when this occurs for a type. - virtual void typeBecameConcrete(const DerivedType *AbsTy) { - TheMap.erase(AbsTy); - AbsTy->removeAbstractTypeUser(this); +void TypeMapTy::addTypeMapping(Type *DstTy, Type *SrcTy) { + Type *&Entry = MappedTypes[SrcTy]; + if (Entry) return; + + if (DstTy == SrcTy) { + Entry = DstTy; + return; } - - // for debugging... - virtual void dump() const { - dbgs() << "AbstractTypeSet!\n"; + + // Check to see if these types are recursively isomorphic and establish a + // mapping between them if so. + if (!areTypesIsomorphic(DstTy, SrcTy)) { + // Oops, they aren't isomorphic. Just discard this request by rolling out + // any speculative mappings we've established. + for (unsigned i = 0, e = SpeculativeTypes.size(); i != e; ++i) + MappedTypes.erase(SpeculativeTypes[i]); } -}; + SpeculativeTypes.clear(); } - -// RecursiveResolveTypes - This is just like ResolveTypes, except that it -// recurses down into derived types, merging the used types if the parent types -// are compatible. -static bool RecursiveResolveTypesI(const Type *DstTy, const Type *SrcTy, - LinkerTypeMap &Pointers) { - if (DstTy == SrcTy) return false; // If already equal, noop - - // If we found our opaque type, resolve it now! - if (DstTy->isOpaqueTy() || SrcTy->isOpaqueTy()) - return ResolveTypes(DstTy, SrcTy); - - // Two types cannot be resolved together if they are of different primitive - // type. For example, we cannot resolve an int to a float. - if (DstTy->getTypeID() != SrcTy->getTypeID()) return true; - - // If neither type is abstract, then they really are just different types. - if (!DstTy->isAbstract() && !SrcTy->isAbstract()) +/// areTypesIsomorphic - Recursively walk this pair of types, returning true +/// if they are isomorphic, false if they are not. +bool TypeMapTy::areTypesIsomorphic(Type *DstTy, Type *SrcTy) { + // Two types with differing kinds are clearly not isomorphic. + if (DstTy->getTypeID() != SrcTy->getTypeID()) return false; + + // If we have an entry in the MappedTypes table, then we have our answer. + Type *&Entry = MappedTypes[SrcTy]; + if (Entry) + return Entry == DstTy; + + // Two identical types are clearly isomorphic. Remember this + // non-speculatively. + if (DstTy == SrcTy) { + Entry = DstTy; return true; - - // Otherwise, resolve the used type used by this derived type... - switch (DstTy->getTypeID()) { - default: - return true; - case Type::FunctionTyID: { - const FunctionType *DstFT = cast<FunctionType>(DstTy); - const FunctionType *SrcFT = cast<FunctionType>(SrcTy); - if (DstFT->isVarArg() != SrcFT->isVarArg() || - DstFT->getNumContainedTypes() != SrcFT->getNumContainedTypes()) - return true; - - // Use TypeHolder's so recursive resolution won't break us. - PATypeHolder ST(SrcFT), DT(DstFT); - for (unsigned i = 0, e = DstFT->getNumContainedTypes(); i != e; ++i) { - const Type *SE = ST->getContainedType(i), *DE = DT->getContainedType(i); - if (SE != DE && RecursiveResolveTypesI(DE, SE, Pointers)) - return true; - } - return false; } - case Type::StructTyID: { - const StructType *DstST = cast<StructType>(DstTy); - const StructType *SrcST = cast<StructType>(SrcTy); - if (DstST->getNumContainedTypes() != SrcST->getNumContainedTypes()) + + // Okay, we have two types with identical kinds that we haven't seen before. + + // If this is an opaque struct type, special case it. + if (StructType *SSTy = dyn_cast<StructType>(SrcTy)) { + // Mapping an opaque type to any struct, just keep the dest struct. + if (SSTy->isOpaque()) { + Entry = DstTy; + SpeculativeTypes.push_back(SrcTy); return true; + } - PATypeHolder ST(SrcST), DT(DstST); - for (unsigned i = 0, e = DstST->getNumContainedTypes(); i != e; ++i) { - const Type *SE = ST->getContainedType(i), *DE = DT->getContainedType(i); - if (SE != DE && RecursiveResolveTypesI(DE, SE, Pointers)) - return true; + // Mapping a non-opaque source type to an opaque dest. Keep the dest, but + // fill it in later. This doesn't need to be speculative. + if (cast<StructType>(DstTy)->isOpaque()) { + Entry = DstTy; + DefinitionsToResolve.push_back(SSTy); + return true; } - return false; - } - case Type::ArrayTyID: { - const ArrayType *DAT = cast<ArrayType>(DstTy); - const ArrayType *SAT = cast<ArrayType>(SrcTy); - if (DAT->getNumElements() != SAT->getNumElements()) return true; - return RecursiveResolveTypesI(DAT->getElementType(), SAT->getElementType(), - Pointers); } - case Type::VectorTyID: { - const VectorType *DVT = cast<VectorType>(DstTy); - const VectorType *SVT = cast<VectorType>(SrcTy); - if (DVT->getNumElements() != SVT->getNumElements()) return true; - return RecursiveResolveTypesI(DVT->getElementType(), SVT->getElementType(), - Pointers); + + // If the number of subtypes disagree between the two types, then we fail. + if (SrcTy->getNumContainedTypes() != DstTy->getNumContainedTypes()) + return false; + + // Fail if any of the extra properties (e.g. array size) of the type disagree. + if (isa<IntegerType>(DstTy)) + return false; // bitwidth disagrees. + if (PointerType *PT = dyn_cast<PointerType>(DstTy)) { + if (PT->getAddressSpace() != cast<PointerType>(SrcTy)->getAddressSpace()) + return false; + } else if (FunctionType *FT = dyn_cast<FunctionType>(DstTy)) { + if (FT->isVarArg() != cast<FunctionType>(SrcTy)->isVarArg()) + return false; + } else if (StructType *DSTy = dyn_cast<StructType>(DstTy)) { + StructType *SSTy = cast<StructType>(SrcTy); + if (DSTy->isAnonymous() != SSTy->isAnonymous() || + DSTy->isPacked() != SSTy->isPacked()) + return false; + } else if (ArrayType *DATy = dyn_cast<ArrayType>(DstTy)) { + if (DATy->getNumElements() != cast<ArrayType>(SrcTy)->getNumElements()) + return false; + } else if (VectorType *DVTy = dyn_cast<VectorType>(DstTy)) { + if (DVTy->getNumElements() != cast<ArrayType>(SrcTy)->getNumElements()) + return false; } - case Type::PointerTyID: { - const PointerType *DstPT = cast<PointerType>(DstTy); - const PointerType *SrcPT = cast<PointerType>(SrcTy); - if (DstPT->getAddressSpace() != SrcPT->getAddressSpace()) - return true; + // Otherwise, we speculate that these two types will line up and recursively + // check the subelements. + Entry = DstTy; + SpeculativeTypes.push_back(SrcTy); + + for (unsigned i = 0, e = SrcTy->getNumContainedTypes(); i != e; ++i) + if (!areTypesIsomorphic(DstTy->getContainedType(i), + SrcTy->getContainedType(i))) + return false; + + // If everything seems to have lined up, then everything is great. + return true; +} - // If this is a pointer type, check to see if we have already seen it. If - // so, we are in a recursive branch. Cut off the search now. We cannot use - // an associative container for this search, because the type pointers (keys - // in the container) change whenever types get resolved. - if (SrcPT->isAbstract()) - if (const Type *ExistingDestTy = Pointers.lookup(SrcPT)) - return ExistingDestTy != DstPT; - - if (DstPT->isAbstract()) - if (const Type *ExistingSrcTy = Pointers.lookup(DstPT)) - return ExistingSrcTy != SrcPT; - // Otherwise, add the current pointers to the vector to stop recursion on - // this pair. - if (DstPT->isAbstract()) - Pointers.insert(DstPT, SrcPT); - if (SrcPT->isAbstract()) - Pointers.insert(SrcPT, DstPT); - - return RecursiveResolveTypesI(DstPT->getElementType(), - SrcPT->getElementType(), Pointers); - } +/// linkDefinedTypeBodies - Produce a body for an opaque type in the dest +/// module from a type definition in the source module. +void TypeMapTy::linkDefinedTypeBodies() { + SmallVector<Type*, 16> Elements; + SmallString<16> TmpName; + + // Note that processing entries in this loop (calling 'get') can add new + // entries to the DefinitionsToResolve vector. + while (!DefinitionsToResolve.empty()) { + StructType *SrcSTy = DefinitionsToResolve.pop_back_val(); + StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]); + + // TypeMap is a many-to-one mapping, if there were multiple types that + // provide a body for DstSTy then previous iterations of this loop may have + // already handled it. Just ignore this case. + if (!DstSTy->isOpaque()) continue; + assert(!SrcSTy->isOpaque() && "Not resolving a definition?"); + + // Map the body of the source type over to a new body for the dest type. + Elements.resize(SrcSTy->getNumElements()); + for (unsigned i = 0, e = Elements.size(); i != e; ++i) + Elements[i] = getImpl(SrcSTy->getElementType(i)); + + DstSTy->setBody(Elements, SrcSTy->isPacked()); + + // If DstSTy has no name or has a longer name than STy, then viciously steal + // STy's name. + if (!SrcSTy->hasName()) continue; + StringRef SrcName = SrcSTy->getName(); + + if (!DstSTy->hasName() || DstSTy->getName().size() > SrcName.size()) { + TmpName.insert(TmpName.end(), SrcName.begin(), SrcName.end()); + SrcSTy->setName(""); + DstSTy->setName(TmpName.str()); + TmpName.clear(); + } } } -static bool RecursiveResolveTypes(const Type *DestTy, const Type *SrcTy) { - LinkerTypeMap PointerTypes; - return RecursiveResolveTypesI(DestTy, SrcTy, PointerTypes); -} +/// get - Return the mapped type to use for the specified input type from the +/// source module. +Type *TypeMapTy::get(Type *Ty) { + Type *Result = getImpl(Ty); + + // If this caused a reference to any struct type, resolve it before returning. + if (!DefinitionsToResolve.empty()) + linkDefinedTypeBodies(); + return Result; +} -// LinkTypes - Go through the symbol table of the Src module and see if any -// types are named in the src module that are not named in the Dst module. -// Make sure there are no type name conflicts. -static bool LinkTypes(Module *Dest, const Module *Src, std::string *Err) { - TypeSymbolTable *DestST = &Dest->getTypeSymbolTable(); - const TypeSymbolTable *SrcST = &Src->getTypeSymbolTable(); - - // Look for a type plane for Type's... - TypeSymbolTable::const_iterator TI = SrcST->begin(); - TypeSymbolTable::const_iterator TE = SrcST->end(); - if (TI == TE) return false; // No named types, do nothing. - - // Some types cannot be resolved immediately because they depend on other - // types being resolved to each other first. This contains a list of types we - // are waiting to recheck. - std::vector<std::string> DelayedTypesToResolve; - - for ( ; TI != TE; ++TI ) { - const std::string &Name = TI->first; - const Type *RHS = TI->second; - - // Check to see if this type name is already in the dest module. - Type *Entry = DestST->lookup(Name); - - // If the name is just in the source module, bring it over to the dest. - if (Entry == 0) { - if (!Name.empty()) - DestST->insert(Name, const_cast<Type*>(RHS)); - } else if (ResolveTypes(Entry, RHS)) { - // They look different, save the types 'till later to resolve. - DelayedTypesToResolve.push_back(Name); +/// getImpl - This is the recursive version of get(). +Type *TypeMapTy::getImpl(Type *Ty) { + // If we already have an entry for this type, return it. + Type **Entry = &MappedTypes[Ty]; + if (*Entry) return *Entry; + + // If this is not a named struct type, then just map all of the elements and + // then rebuild the type from inside out. + if (!isa<StructType>(Ty) || cast<StructType>(Ty)->isAnonymous()) { + // If there are no element types to map, then the type is itself. This is + // true for the anonymous {} struct, things like 'float', integers, etc. + if (Ty->getNumContainedTypes() == 0) + return *Entry = Ty; + + // Remap all of the elements, keeping track of whether any of them change. + bool AnyChange = false; + SmallVector<Type*, 4> ElementTypes; + ElementTypes.resize(Ty->getNumContainedTypes()); + for (unsigned i = 0, e = Ty->getNumContainedTypes(); i != e; ++i) { + ElementTypes[i] = getImpl(Ty->getContainedType(i)); + AnyChange |= ElementTypes[i] != Ty->getContainedType(i); + } + + // If we found our type while recursively processing stuff, just use it. + Entry = &MappedTypes[Ty]; + if (*Entry) return *Entry; + + // If all of the element types mapped directly over, then the type is usable + // as-is. + if (!AnyChange) + return *Entry = Ty; + + // Otherwise, rebuild a modified type. + switch (Ty->getTypeID()) { + default: assert(0 && "unknown derived type to remap"); + case Type::ArrayTyID: + return *Entry = ArrayType::get(ElementTypes[0], + cast<ArrayType>(Ty)->getNumElements()); + case Type::VectorTyID: + return *Entry = VectorType::get(ElementTypes[0], + cast<VectorType>(Ty)->getNumElements()); + case Type::PointerTyID: + return *Entry = PointerType::get(ElementTypes[0], + cast<PointerType>(Ty)->getAddressSpace()); + case Type::FunctionTyID: + return *Entry = FunctionType::get(ElementTypes[0], + ArrayRef<Type*>(ElementTypes).slice(1), + cast<FunctionType>(Ty)->isVarArg()); + case Type::StructTyID: + // Note that this is only reached for anonymous structs. + return *Entry = StructType::get(Ty->getContext(), ElementTypes, + cast<StructType>(Ty)->isPacked()); } } - // Iteratively resolve types while we can... - while (!DelayedTypesToResolve.empty()) { - // Loop over all of the types, attempting to resolve them if possible... - unsigned OldSize = DelayedTypesToResolve.size(); - - // Try direct resolution by name... - for (unsigned i = 0; i != DelayedTypesToResolve.size(); ++i) { - const std::string &Name = DelayedTypesToResolve[i]; - Type *T1 = SrcST->lookup(Name); - Type *T2 = DestST->lookup(Name); - if (!ResolveTypes(T2, T1)) { - // We are making progress! - DelayedTypesToResolve.erase(DelayedTypesToResolve.begin()+i); - --i; - } - } + // Otherwise, this is an unmapped named struct. If the struct can be directly + // mapped over, just use it as-is. This happens in a case when the linked-in + // module has something like: + // %T = type {%T*, i32} + // @GV = global %T* null + // where T does not exist at all in the destination module. + // + // The other case we watch for is when the type is not in the destination + // module, but that it has to be rebuilt because it refers to something that + // is already mapped. For example, if the destination module has: + // %A = type { i32 } + // and the source module has something like + // %A' = type { i32 } + // %B = type { %A'* } + // @GV = global %B* null + // then we want to create a new type: "%B = type { %A*}" and have it take the + // pristine "%B" name from the source module. + // + // To determine which case this is, we have to recursively walk the type graph + // speculating that we'll be able to reuse it unmodified. Only if this is + // safe would we map the entire thing over. Because this is an optimization, + // and is not required for the prettiness of the linked module, we just skip + // it and always rebuild a type here. + StructType *STy = cast<StructType>(Ty); + + // If the type is opaque, we can just use it directly. + if (STy->isOpaque()) + return *Entry = STy; + + // Otherwise we create a new type and resolve its body later. This will be + // resolved by the top level of get(). + DefinitionsToResolve.push_back(STy); + return *Entry = StructType::createNamed(STy->getContext(), ""); +} - // Did we not eliminate any types? - if (DelayedTypesToResolve.size() == OldSize) { - // Attempt to resolve subelements of types. This allows us to merge these - // two types: { int* } and { opaque* } - for (unsigned i = 0, e = DelayedTypesToResolve.size(); i != e; ++i) { - const std::string &Name = DelayedTypesToResolve[i]; - if (!RecursiveResolveTypes(SrcST->lookup(Name), DestST->lookup(Name))) { - // We are making progress! - DelayedTypesToResolve.erase(DelayedTypesToResolve.begin()+i); - - // Go back to the main loop, perhaps we can resolve directly by name - // now... - break; - } - } - // If we STILL cannot resolve the types, then there is something wrong. - if (DelayedTypesToResolve.size() == OldSize) { - // Remove the symbol name from the destination. - DelayedTypesToResolve.pop_back(); - } - } - } +//===----------------------------------------------------------------------===// +// ModuleLinker implementation. +//===----------------------------------------------------------------------===// - return false; +namespace { + /// ModuleLinker - This is an implementation class for the LinkModules + /// function, which is the entrypoint for this file. + class ModuleLinker { + Module *DstM, *SrcM; + + TypeMapTy TypeMap; + + /// ValueMap - Mapping of values from what they used to be in Src, to what + /// they are now in DstM. ValueToValueMapTy is a ValueMap, which involves + /// some overhead due to the use of Value handles which the Linker doesn't + /// actually need, but this allows us to reuse the ValueMapper code. + ValueToValueMapTy ValueMap; + + struct AppendingVarInfo { + GlobalVariable *NewGV; // New aggregate global in dest module. + Constant *DstInit; // Old initializer from dest module. + Constant *SrcInit; // Old initializer from src module. + }; + + std::vector<AppendingVarInfo> AppendingVars; + + public: + std::string ErrorMsg; + + ModuleLinker(Module *dstM, Module *srcM) : DstM(dstM), SrcM(srcM) { } + + bool run(); + + private: + /// emitError - Helper method for setting a message and returning an error + /// code. + bool emitError(const Twine &Message) { + ErrorMsg = Message.str(); + return true; + } + + /// getLinkageResult - This analyzes the two global values and determines + /// what the result will look like in the destination module. + bool getLinkageResult(GlobalValue *Dest, const GlobalValue *Src, + GlobalValue::LinkageTypes <, bool &LinkFromSrc); + + /// getLinkedToGlobal - Given a global in the source module, return the + /// global in the destination module that is being linked to, if any. + GlobalValue *getLinkedToGlobal(GlobalValue *SrcGV) { + // If the source has no name it can't link. If it has local linkage, + // there is no name match-up going on. + if (!SrcGV->hasName() || SrcGV->hasLocalLinkage()) + return 0; + + // Otherwise see if we have a match in the destination module's symtab. + GlobalValue *DGV = DstM->getNamedValue(SrcGV->getName()); + if (DGV == 0) return 0; + + // If we found a global with the same name in the dest module, but it has + // internal linkage, we are really not doing any linkage here. + if (DGV->hasLocalLinkage()) + return 0; + + // Otherwise, we do in fact link to the destination global. + return DGV; + } + + void computeTypeMapping(); + + bool linkAppendingVarProto(GlobalVariable *DstGV, GlobalVariable *SrcGV); + bool linkGlobalProto(GlobalVariable *SrcGV); + bool linkFunctionProto(Function *SrcF); + bool linkAliasProto(GlobalAlias *SrcA); + + void linkAppendingVarInit(const AppendingVarInfo &AVI); + void linkGlobalInits(); + void linkFunctionBody(Function *Dst, Function *Src); + void linkAliasBodies(); + void linkNamedMDNodes(); + }; } -/// ForceRenaming - The LLVM SymbolTable class autorenames globals that conflict + + +/// forceRenaming - The LLVM SymbolTable class autorenames globals that conflict /// in the symbol table. This is good for all clients except for us. Go /// through the trouble to force this back. -static void ForceRenaming(GlobalValue *GV, const std::string &Name) { - assert(GV->getName() != Name && "Can't force rename to self"); - ValueSymbolTable &ST = GV->getParent()->getValueSymbolTable(); +static void forceRenaming(GlobalValue *GV, StringRef Name) { + // If the global doesn't force its name or if it already has the right name, + // there is nothing for us to do. + if (GV->hasLocalLinkage() || GV->getName() == Name) + return; + + Module *M = GV->getParent(); // If there is a conflict, rename the conflict. - if (GlobalValue *ConflictGV = cast_or_null<GlobalValue>(ST.lookup(Name))) { - assert(ConflictGV->hasLocalLinkage() && - "Not conflicting with a static global, should link instead!"); + if (GlobalValue *ConflictGV = M->getNamedValue(Name)) { GV->takeName(ConflictGV); ConflictGV->setName(Name); // This will cause ConflictGV to get renamed - assert(ConflictGV->getName() != Name && "ForceRenaming didn't work"); + assert(ConflictGV->getName() != Name && "forceRenaming didn't work"); } else { GV->setName(Name); // Force the name back } @@ -352,30 +419,35 @@ static void CopyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) { unsigned Alignment = std::max(DestGV->getAlignment(), SrcGV->getAlignment()); DestGV->copyAttributesFrom(SrcGV); DestGV->setAlignment(Alignment); + + forceRenaming(DestGV, SrcGV->getName()); } -/// GetLinkageResult - This analyzes the two global values and determines what +/// getLinkageResult - This analyzes the two global values and determines what /// the result will look like in the destination module. In particular, it /// computes the resultant linkage type, computes whether the global in the /// source should be copied over to the destination (replacing the existing /// one), and computes whether this linkage is an error or not. It also performs /// visibility checks: we cannot link together two symbols with different /// visibilities. -static bool GetLinkageResult(GlobalValue *Dest, const GlobalValue *Src, - GlobalValue::LinkageTypes <, bool &LinkFromSrc, - std::string *Err) { - assert((!Dest || !Src->hasLocalLinkage()) && +bool ModuleLinker::getLinkageResult(GlobalValue *Dest, const GlobalValue *Src, + GlobalValue::LinkageTypes <, + bool &LinkFromSrc) { + assert(Dest && "Must have two globals being queried"); + assert(!Src->hasLocalLinkage() && "If Src has internal linkage, Dest shouldn't be set!"); - if (!Dest) { - // Linking something to nothing. - LinkFromSrc = true; - LT = Src->getLinkage(); - } else if (Src->isDeclaration()) { + + // FIXME: GlobalAlias::isDeclaration is broken, should always be + // false. + bool SrcIsDeclaration = Src->isDeclaration() && !isa<GlobalAlias>(Src); + bool DestIsDeclaration = Dest->isDeclaration() && !isa<GlobalAlias>(Dest); + + if (SrcIsDeclaration) { // If Src is external or if both Src & Dest are external.. Just link the // external globals, we aren't adding anything. if (Src->hasDLLImportLinkage()) { // If one of GVs has DLLImport linkage, result should be dllimport'ed. - if (Dest->isDeclaration()) { + if (DestIsDeclaration) { LinkFromSrc = true; LT = Src->getLinkage(); } @@ -387,16 +459,10 @@ static bool GetLinkageResult(GlobalValue *Dest, const GlobalValue *Src, LinkFromSrc = false; LT = Dest->getLinkage(); } - } else if (Dest->isDeclaration() && !Dest->hasDLLImportLinkage()) { + } else if (DestIsDeclaration && !Dest->hasDLLImportLinkage()) { // If Dest is external but Src is not: LinkFromSrc = true; LT = Src->getLinkage(); - } else if (Src->hasAppendingLinkage() || Dest->hasAppendingLinkage()) { - if (Src->getLinkage() != Dest->getLinkage()) - return Error(Err, "Linking globals named '" + Src->getName() + - "': can only link appending global with another appending global!"); - LinkFromSrc = true; // Special cased. - LT = Src->getLinkage(); } else if (Src->isWeakForLinker()) { // At this point we know that Dest has LinkOnce, External*, Weak, Common, // or DLL* linkage. @@ -420,883 +486,485 @@ static bool GetLinkageResult(GlobalValue *Dest, const GlobalValue *Src, LT = GlobalValue::ExternalLinkage; } } else { - assert((Dest->hasExternalLinkage() || - Dest->hasDLLImportLinkage() || - Dest->hasDLLExportLinkage() || - Dest->hasExternalWeakLinkage()) && - (Src->hasExternalLinkage() || - Src->hasDLLImportLinkage() || - Src->hasDLLExportLinkage() || - Src->hasExternalWeakLinkage()) && + assert((Dest->hasExternalLinkage() || Dest->hasDLLImportLinkage() || + Dest->hasDLLExportLinkage() || Dest->hasExternalWeakLinkage()) && + (Src->hasExternalLinkage() || Src->hasDLLImportLinkage() || + Src->hasDLLExportLinkage() || Src->hasExternalWeakLinkage()) && "Unexpected linkage type!"); - return Error(Err, "Linking globals named '" + Src->getName() + + return emitError("Linking globals named '" + Src->getName() + "': symbol multiply defined!"); } // Check visibility - if (Dest && Src->getVisibility() != Dest->getVisibility() && - !Src->isDeclaration() && !Dest->isDeclaration() && + if (Src->getVisibility() != Dest->getVisibility() && + !SrcIsDeclaration && !DestIsDeclaration && !Src->hasAvailableExternallyLinkage() && !Dest->hasAvailableExternallyLinkage()) - return Error(Err, "Linking globals named '" + Src->getName() + + return emitError("Linking globals named '" + Src->getName() + "': symbols have different visibilities!"); return false; } -// Insert all of the named mdnoes in Src into the Dest module. -static void LinkNamedMDNodes(Module *Dest, Module *Src, - ValueToValueMapTy &ValueMap) { - for (Module::const_named_metadata_iterator I = Src->named_metadata_begin(), - E = Src->named_metadata_end(); I != E; ++I) { - const NamedMDNode *SrcNMD = I; - NamedMDNode *DestNMD = Dest->getOrInsertNamedMetadata(SrcNMD->getName()); - // Add Src elements into Dest node. - for (unsigned i = 0, e = SrcNMD->getNumOperands(); i != e; ++i) - DestNMD->addOperand(cast<MDNode>(MapValue(SrcNMD->getOperand(i), - ValueMap))); +/// computeTypeMapping - Loop over all of the linked values to compute type +/// mappings. For example, if we link "extern Foo *x" and "Foo *x = NULL", then +/// we have two struct types 'Foo' but one got renamed when the module was +/// loaded into the same LLVMContext. +void ModuleLinker::computeTypeMapping() { + // Incorporate globals. + for (Module::global_iterator I = SrcM->global_begin(), + E = SrcM->global_end(); I != E; ++I) { + GlobalValue *DGV = getLinkedToGlobal(I); + if (DGV == 0) continue; + + if (!DGV->hasAppendingLinkage() || !I->hasAppendingLinkage()) { + TypeMap.addTypeMapping(DGV->getType(), I->getType()); + continue; + } + + // Unify the element type of appending arrays. + ArrayType *DAT = cast<ArrayType>(DGV->getType()->getElementType()); + ArrayType *SAT = cast<ArrayType>(I->getType()->getElementType()); + TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType()); } + + // Incorporate functions. + for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I) { + if (GlobalValue *DGV = getLinkedToGlobal(I)) + TypeMap.addTypeMapping(DGV->getType(), I->getType()); + } + + // Don't bother incorporating aliases, they aren't generally typed well. + + // Now that we have discovered all of the type equivalences, get a body for + // any 'opaque' types in the dest module that are now resolved. + TypeMap.linkDefinedTypeBodies(); } -// LinkGlobals - Loop through the global variables in the src module and merge -// them into the dest module. -static bool LinkGlobals(Module *Dest, const Module *Src, - ValueToValueMapTy &ValueMap, - std::multimap<std::string, GlobalVariable *> &AppendingVars, - std::string *Err) { - ValueSymbolTable &DestSymTab = Dest->getValueSymbolTable(); - - // Loop over all of the globals in the src module, mapping them over as we go - for (Module::const_global_iterator I = Src->global_begin(), - E = Src->global_end(); I != E; ++I) { - const GlobalVariable *SGV = I; - GlobalValue *DGV = 0; - - // Check to see if may have to link the global with the global, alias or - // function. - if (SGV->hasName() && !SGV->hasLocalLinkage()) - DGV = cast_or_null<GlobalValue>(DestSymTab.lookup(SGV->getName())); - - // If we found a global with the same name in the dest module, but it has - // internal linkage, we are really not doing any linkage here. - if (DGV && DGV->hasLocalLinkage()) - DGV = 0; - - // If types don't agree due to opaque types, try to resolve them. - if (DGV && DGV->getType() != SGV->getType()) - RecursiveResolveTypes(SGV->getType(), DGV->getType()); - - assert((SGV->hasInitializer() || SGV->hasExternalWeakLinkage() || - SGV->hasExternalLinkage() || SGV->hasDLLImportLinkage()) && - "Global must either be external or have an initializer!"); +/// linkAppendingVarProto - If there were any appending global variables, link +/// them together now. Return true on error. +bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV, + GlobalVariable *SrcGV) { + + if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) + return emitError("Linking globals named '" + SrcGV->getName() + + "': can only link appending global with another appending global!"); + + ArrayType *DstTy = cast<ArrayType>(DstGV->getType()->getElementType()); + ArrayType *SrcTy = + cast<ArrayType>(TypeMap.get(SrcGV->getType()->getElementType())); + Type *EltTy = DstTy->getElementType(); + + // Check to see that they two arrays agree on type. + if (EltTy != SrcTy->getElementType()) + return emitError("Appending variables with different element types!"); + if (DstGV->isConstant() != SrcGV->isConstant()) + return emitError("Appending variables linked with different const'ness!"); + + if (DstGV->getAlignment() != SrcGV->getAlignment()) + return emitError( + "Appending variables with different alignment need to be linked!"); + + if (DstGV->getVisibility() != SrcGV->getVisibility()) + return emitError( + "Appending variables with different visibility need to be linked!"); + + if (DstGV->getSection() != SrcGV->getSection()) + return emitError( + "Appending variables with different section name need to be linked!"); + + uint64_t NewSize = DstTy->getNumElements() + SrcTy->getNumElements(); + ArrayType *NewType = ArrayType::get(EltTy, NewSize); + + // Create the new global variable. + GlobalVariable *NG = + new GlobalVariable(*DstGV->getParent(), NewType, SrcGV->isConstant(), + DstGV->getLinkage(), /*init*/0, /*name*/"", DstGV, + DstGV->isThreadLocal(), + DstGV->getType()->getAddressSpace()); + + // Propagate alignment, visibility and section info. + CopyGVAttributes(NG, DstGV); + + AppendingVarInfo AVI; + AVI.NewGV = NG; + AVI.DstInit = DstGV->getInitializer(); + AVI.SrcInit = SrcGV->getInitializer(); + AppendingVars.push_back(AVI); + + // Replace any uses of the two global variables with uses of the new + // global. + ValueMap[SrcGV] = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType())); + + DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType())); + DstGV->eraseFromParent(); + + // Zap the initializer in the source variable so we don't try to link it. + SrcGV->setInitializer(0); + SrcGV->setLinkage(GlobalValue::ExternalLinkage); + return false; +} +/// linkGlobalProto - Loop through the global variables in the src module and +/// merge them into the dest module. +bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) { + GlobalValue *DGV = getLinkedToGlobal(SGV); + + if (DGV) { + // Concatenation of appending linkage variables is magic and handled later. + if (DGV->hasAppendingLinkage() || SGV->hasAppendingLinkage()) + return linkAppendingVarProto(cast<GlobalVariable>(DGV), SGV); + + // Determine whether linkage of these two globals follows the source + // module's definition or the destination module's definition. GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; bool LinkFromSrc = false; - if (GetLinkageResult(DGV, SGV, NewLinkage, LinkFromSrc, Err)) + if (getLinkageResult(DGV, SGV, NewLinkage, LinkFromSrc)) return true; - if (DGV == 0) { - // No linking to be performed, simply create an identical version of the - // symbol over in the dest module... the initializer will be filled in - // later by LinkGlobalInits. - GlobalVariable *NewDGV = - new GlobalVariable(*Dest, SGV->getType()->getElementType(), - SGV->isConstant(), SGV->getLinkage(), /*init*/0, - SGV->getName(), 0, false, - SGV->getType()->getAddressSpace()); - // Propagate alignment, visibility and section info. - CopyGVAttributes(NewDGV, SGV); - NewDGV->setUnnamedAddr(SGV->hasUnnamedAddr()); - - // If the LLVM runtime renamed the global, but it is an externally visible - // symbol, DGV must be an existing global with internal linkage. Rename - // it. - if (!NewDGV->hasLocalLinkage() && NewDGV->getName() != SGV->getName()) - ForceRenaming(NewDGV, SGV->getName()); - + // If we're not linking from the source, then keep the definition that we + // have. + if (!LinkFromSrc) { + // Special case for const propagation. + if (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV)) + if (DGVar->isDeclaration() && SGV->isConstant() && !DGVar->isConstant()) + DGVar->setConstant(true); + + // Set calculated linkage. + DGV->setLinkage(NewLinkage); + // Make sure to remember this mapping. - ValueMap[SGV] = NewDGV; - - // Keep track that this is an appending variable. - if (SGV->hasAppendingLinkage()) - AppendingVars.insert(std::make_pair(SGV->getName(), NewDGV)); - continue; - } - - bool HasUnnamedAddr = SGV->hasUnnamedAddr() && DGV->hasUnnamedAddr(); - - // If the visibilities of the symbols disagree and the destination is a - // prototype, take the visibility of its input. - if (DGV->isDeclaration()) - DGV->setVisibility(SGV->getVisibility()); - - if (DGV->hasAppendingLinkage()) { - // No linking is performed yet. Just insert a new copy of the global, and - // keep track of the fact that it is an appending variable in the - // AppendingVars map. The name is cleared out so that no linkage is - // performed. - GlobalVariable *NewDGV = - new GlobalVariable(*Dest, SGV->getType()->getElementType(), - SGV->isConstant(), SGV->getLinkage(), /*init*/0, - "", 0, false, - SGV->getType()->getAddressSpace()); - - // Set alignment allowing CopyGVAttributes merge it with alignment of SGV. - NewDGV->setAlignment(DGV->getAlignment()); - // Propagate alignment, section and visibility info. - CopyGVAttributes(NewDGV, SGV); - - // Make sure to remember this mapping... - ValueMap[SGV] = NewDGV; - - // Keep track that this is an appending variable... - AppendingVars.insert(std::make_pair(SGV->getName(), NewDGV)); - continue; + ValueMap[SGV] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGV->getType())); + + // Destroy the source global's initializer (and convert it to a prototype) + // so that we don't attempt to copy it over when processing global + // initializers. + SGV->setInitializer(0); + SGV->setLinkage(GlobalValue::ExternalLinkage); + return false; } - - if (LinkFromSrc) { - if (isa<GlobalAlias>(DGV)) - return Error(Err, "Global-Alias Collision on '" + SGV->getName() + - "': symbol multiple defined"); - - // If the types don't match, and if we are to link from the source, nuke - // DGV and create a new one of the appropriate type. Note that the thing - // we are replacing may be a function (if a prototype, weak, etc) or a - // global variable. - GlobalVariable *NewDGV = - new GlobalVariable(*Dest, SGV->getType()->getElementType(), - SGV->isConstant(), NewLinkage, /*init*/0, - DGV->getName(), 0, false, - SGV->getType()->getAddressSpace()); - - // Set the unnamed_addr. - NewDGV->setUnnamedAddr(HasUnnamedAddr); - - // Propagate alignment, section, and visibility info. - CopyGVAttributes(NewDGV, SGV); - DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV, - DGV->getType())); - - // DGV will conflict with NewDGV because they both had the same - // name. We must erase this now so ForceRenaming doesn't assert - // because DGV might not have internal linkage. - if (GlobalVariable *Var = dyn_cast<GlobalVariable>(DGV)) - Var->eraseFromParent(); - else - cast<Function>(DGV)->eraseFromParent(); - - // If the symbol table renamed the global, but it is an externally visible - // symbol, DGV must be an existing global with internal linkage. Rename. - if (NewDGV->getName() != SGV->getName() && !NewDGV->hasLocalLinkage()) - ForceRenaming(NewDGV, SGV->getName()); - - // Inherit const as appropriate. - NewDGV->setConstant(SGV->isConstant()); - - // Make sure to remember this mapping. - ValueMap[SGV] = NewDGV; - continue; - } - - // Not "link from source", keep the one in the DestModule and remap the - // input onto it. - - // Special case for const propagation. - if (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV)) - if (DGVar->isDeclaration() && SGV->isConstant() && !DGVar->isConstant()) - DGVar->setConstant(true); - - // SGV is global, but DGV is alias. - if (isa<GlobalAlias>(DGV)) { - // The only valid mappings are: - // - SGV is external declaration, which is effectively a no-op. - // - SGV is weak, when we just need to throw SGV out. - if (!SGV->isDeclaration() && !SGV->isWeakForLinker()) - return Error(Err, "Global-Alias Collision on '" + SGV->getName() + - "': symbol multiple defined"); - } - - // Set calculated linkage and unnamed_addr - DGV->setLinkage(NewLinkage); - DGV->setUnnamedAddr(HasUnnamedAddr); - - // Make sure to remember this mapping... - ValueMap[SGV] = ConstantExpr::getBitCast(DGV, SGV->getType()); } - return false; -} - -static GlobalValue::LinkageTypes -CalculateAliasLinkage(const GlobalValue *SGV, const GlobalValue *DGV) { - GlobalValue::LinkageTypes SL = SGV->getLinkage(); - GlobalValue::LinkageTypes DL = DGV->getLinkage(); - if (SL == GlobalValue::ExternalLinkage || DL == GlobalValue::ExternalLinkage) - return GlobalValue::ExternalLinkage; - else if (SL == GlobalValue::WeakAnyLinkage || - DL == GlobalValue::WeakAnyLinkage) - return GlobalValue::WeakAnyLinkage; - else if (SL == GlobalValue::WeakODRLinkage || - DL == GlobalValue::WeakODRLinkage) - return GlobalValue::WeakODRLinkage; - else if (SL == GlobalValue::InternalLinkage && - DL == GlobalValue::InternalLinkage) - return GlobalValue::InternalLinkage; - else if (SL == GlobalValue::LinkerPrivateLinkage && - DL == GlobalValue::LinkerPrivateLinkage) - return GlobalValue::LinkerPrivateLinkage; - else if (SL == GlobalValue::LinkerPrivateWeakLinkage && - DL == GlobalValue::LinkerPrivateWeakLinkage) - return GlobalValue::LinkerPrivateWeakLinkage; - else if (SL == GlobalValue::LinkerPrivateWeakDefAutoLinkage && - DL == GlobalValue::LinkerPrivateWeakDefAutoLinkage) - return GlobalValue::LinkerPrivateWeakDefAutoLinkage; - else { - assert (SL == GlobalValue::PrivateLinkage && - DL == GlobalValue::PrivateLinkage && "Unexpected linkage type"); - return GlobalValue::PrivateLinkage; + + // No linking to be performed or linking from the source: simply create an + // identical version of the symbol over in the dest module... the + // initializer will be filled in later by LinkGlobalInits. + GlobalVariable *NewDGV = + new GlobalVariable(*DstM, TypeMap.get(SGV->getType()->getElementType()), + SGV->isConstant(), SGV->getLinkage(), /*init*/0, + SGV->getName(), /*insertbefore*/0, + SGV->isThreadLocal(), + SGV->getType()->getAddressSpace()); + // Propagate alignment, visibility and section info. + CopyGVAttributes(NewDGV, SGV); + + if (DGV) { + DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV, DGV->getType())); + DGV->eraseFromParent(); } -} - -// LinkAlias - Loop through the alias in the src module and link them into the -// dest module. We're assuming, that all functions/global variables were already -// linked in. -static bool LinkAlias(Module *Dest, const Module *Src, - ValueToValueMapTy &ValueMap, - std::string *Err) { - // Loop over all alias in the src module - for (Module::const_alias_iterator I = Src->alias_begin(), - E = Src->alias_end(); I != E; ++I) { - const GlobalAlias *SGA = I; - const GlobalValue *SAliasee = SGA->getAliasedGlobal(); - GlobalAlias *NewGA = NULL; - - // Globals were already linked, thus we can just query ValueMap for variant - // of SAliasee in Dest. - ValueToValueMapTy::const_iterator VMI = ValueMap.find(SAliasee); - assert(VMI != ValueMap.end() && "Aliasee not linked"); - GlobalValue* DAliasee = cast<GlobalValue>(VMI->second); - GlobalValue* DGV = NULL; - - // Fixup aliases to bitcasts. Note that aliases to GEPs are still broken - // by this, but aliases to GEPs are broken to a lot of other things, so - // it's less important. - Constant *DAliaseeConst = DAliasee; - if (SGA->getType() != DAliasee->getType()) - DAliaseeConst = ConstantExpr::getBitCast(DAliasee, SGA->getType()); - - // Try to find something 'similar' to SGA in destination module. - if (!DGV && !SGA->hasLocalLinkage()) { - DGV = Dest->getNamedAlias(SGA->getName()); - - // If types don't agree due to opaque types, try to resolve them. - if (DGV && DGV->getType() != SGA->getType()) - RecursiveResolveTypes(SGA->getType(), DGV->getType()); - } - - if (!DGV && !SGA->hasLocalLinkage()) { - DGV = Dest->getGlobalVariable(SGA->getName()); - - // If types don't agree due to opaque types, try to resolve them. - if (DGV && DGV->getType() != SGA->getType()) - RecursiveResolveTypes(SGA->getType(), DGV->getType()); - } - - if (!DGV && !SGA->hasLocalLinkage()) { - DGV = Dest->getFunction(SGA->getName()); - - // If types don't agree due to opaque types, try to resolve them. - if (DGV && DGV->getType() != SGA->getType()) - RecursiveResolveTypes(SGA->getType(), DGV->getType()); - } - - // No linking to be performed on internal stuff. - if (DGV && DGV->hasLocalLinkage()) - DGV = NULL; - - if (GlobalAlias *DGA = dyn_cast_or_null<GlobalAlias>(DGV)) { - // Types are known to be the same, check whether aliasees equal. As - // globals are already linked we just need query ValueMap to find the - // mapping. - if (DAliasee == DGA->getAliasedGlobal()) { - // This is just two copies of the same alias. Propagate linkage, if - // necessary. - DGA->setLinkage(CalculateAliasLinkage(SGA, DGA)); - - NewGA = DGA; - // Proceed to 'common' steps - } else - return Error(Err, "Alias Collision on '" + SGA->getName()+ - "': aliases have different aliasees"); - } else if (GlobalVariable *DGVar = dyn_cast_or_null<GlobalVariable>(DGV)) { - // The only allowed way is to link alias with external declaration or weak - // symbol.. - if (DGVar->isDeclaration() || DGVar->isWeakForLinker()) { - // But only if aliasee is global too... - if (!isa<GlobalVariable>(DAliasee)) - return Error(Err, "Global-Alias Collision on '" + SGA->getName() + - "': aliasee is not global variable"); - - NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(), - SGA->getName(), DAliaseeConst, Dest); - CopyGVAttributes(NewGA, SGA); - - // Any uses of DGV need to change to NewGA, with cast, if needed. - if (SGA->getType() != DGVar->getType()) - DGVar->replaceAllUsesWith(ConstantExpr::getBitCast(NewGA, - DGVar->getType())); - else - DGVar->replaceAllUsesWith(NewGA); - - // DGVar will conflict with NewGA because they both had the same - // name. We must erase this now so ForceRenaming doesn't assert - // because DGV might not have internal linkage. - DGVar->eraseFromParent(); - - // Proceed to 'common' steps - } else - return Error(Err, "Global-Alias Collision on '" + SGA->getName() + - "': symbol multiple defined"); - } else if (Function *DF = dyn_cast_or_null<Function>(DGV)) { - // The only allowed way is to link alias with external declaration or weak - // symbol... - if (DF->isDeclaration() || DF->isWeakForLinker()) { - // But only if aliasee is function too... - if (!isa<Function>(DAliasee)) - return Error(Err, "Function-Alias Collision on '" + SGA->getName() + - "': aliasee is not function"); - - NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(), - SGA->getName(), DAliaseeConst, Dest); - CopyGVAttributes(NewGA, SGA); - - // Any uses of DF need to change to NewGA, with cast, if needed. - if (SGA->getType() != DF->getType()) - DF->replaceAllUsesWith(ConstantExpr::getBitCast(NewGA, - DF->getType())); - else - DF->replaceAllUsesWith(NewGA); - - // DF will conflict with NewGA because they both had the same - // name. We must erase this now so ForceRenaming doesn't assert - // because DF might not have internal linkage. - DF->eraseFromParent(); - - // Proceed to 'common' steps - } else - return Error(Err, "Function-Alias Collision on '" + SGA->getName() + - "': symbol multiple defined"); - } else { - // No linking to be performed, simply create an identical version of the - // alias over in the dest module... - NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(), - SGA->getName(), DAliaseeConst, Dest); - CopyGVAttributes(NewGA, SGA); - - // Proceed to 'common' steps - } - - assert(NewGA && "No alias was created in destination module!"); - - // If the symbol table renamed the alias, but it is an externally visible - // symbol, DGA must be an global value with internal linkage. Rename it. - if (NewGA->getName() != SGA->getName() && - !NewGA->hasLocalLinkage()) - ForceRenaming(NewGA, SGA->getName()); - - // Remember this mapping so uses in the source module get remapped - // later by MapValue. - ValueMap[SGA] = NewGA; - } - + + // Make sure to remember this mapping. + ValueMap[SGV] = NewDGV; return false; } +/// linkFunctionProto - Link the function in the source module into the +/// destination module if needed, setting up mapping information. +bool ModuleLinker::linkFunctionProto(Function *SF) { + GlobalValue *DGV = getLinkedToGlobal(SF); -// LinkGlobalInits - Update the initializers in the Dest module now that all -// globals that may be referenced are in Dest. -static bool LinkGlobalInits(Module *Dest, const Module *Src, - ValueToValueMapTy &ValueMap, - std::string *Err) { - // Loop over all of the globals in the src module, mapping them over as we go - for (Module::const_global_iterator I = Src->global_begin(), - E = Src->global_end(); I != E; ++I) { - const GlobalVariable *SGV = I; - - if (SGV->hasInitializer()) { // Only process initialized GV's - // Figure out what the initializer looks like in the dest module. - Constant *SInit = - cast<Constant>(MapValue(SGV->getInitializer(), ValueMap)); - // Grab destination global variable or alias. - GlobalValue *DGV = cast<GlobalValue>(ValueMap[SGV]->stripPointerCasts()); - - // If dest if global variable, check that initializers match. - if (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV)) { - if (DGVar->hasInitializer()) { - if (SGV->hasExternalLinkage()) { - if (DGVar->getInitializer() != SInit) - return Error(Err, "Global Variable Collision on '" + - SGV->getName() + - "': global variables have different initializers"); - } else if (DGVar->isWeakForLinker()) { - // Nothing is required, mapped values will take the new global - // automatically. - } else if (SGV->isWeakForLinker()) { - // Nothing is required, mapped values will take the new global - // automatically. - } else if (DGVar->hasAppendingLinkage()) { - llvm_unreachable("Appending linkage unimplemented!"); - } else { - llvm_unreachable("Unknown linkage!"); - } - } else { - // Copy the initializer over now... - DGVar->setInitializer(SInit); - } - } else { - // Destination is alias, the only valid situation is when source is - // weak. Also, note, that we already checked linkage in LinkGlobals(), - // thus we assert here. - // FIXME: Should we weaken this assumption, 'dereference' alias and - // check for initializer of aliasee? - assert(SGV->isWeakForLinker()); - } + if (DGV) { + GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; + bool LinkFromSrc = false; + if (getLinkageResult(DGV, SF, NewLinkage, LinkFromSrc)) + return true; + + if (!LinkFromSrc) { + // Set calculated linkage + DGV->setLinkage(NewLinkage); + + // Make sure to remember this mapping. + ValueMap[SF] = ConstantExpr::getBitCast(DGV, TypeMap.get(SF->getType())); + + // Remove the body from the source module so we don't attempt to remap it. + SF->deleteBody(); + return false; } } + + // If there is no linkage to be performed or we are linking from the source, + // bring SF over. + Function *NewDF = Function::Create(TypeMap.get(SF->getFunctionType()), + SF->getLinkage(), SF->getName(), DstM); + CopyGVAttributes(NewDF, SF); + + if (DGV) { + // Any uses of DF need to change to NewDF, with cast. + DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDF, DGV->getType())); + DGV->eraseFromParent(); + } + + ValueMap[SF] = NewDF; return false; } -// LinkFunctionProtos - Link the functions together between the two modules, -// without doing function bodies... this just adds external function prototypes -// to the Dest function... -// -static bool LinkFunctionProtos(Module *Dest, const Module *Src, - ValueToValueMapTy &ValueMap, - std::string *Err) { - ValueSymbolTable &DestSymTab = Dest->getValueSymbolTable(); - - // Loop over all of the functions in the src module, mapping them over - for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) { - const Function *SF = I; // SrcFunction - GlobalValue *DGV = 0; - - // Check to see if may have to link the function with the global, alias or - // function. - if (SF->hasName() && !SF->hasLocalLinkage()) - DGV = cast_or_null<GlobalValue>(DestSymTab.lookup(SF->getName())); - - // If we found a global with the same name in the dest module, but it has - // internal linkage, we are really not doing any linkage here. - if (DGV && DGV->hasLocalLinkage()) - DGV = 0; - - // If types don't agree due to opaque types, try to resolve them. - if (DGV && DGV->getType() != SF->getType()) - RecursiveResolveTypes(SF->getType(), DGV->getType()); - +/// LinkAliasProto - Set up prototypes for any aliases that come over from the +/// source module. +bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) { + GlobalValue *DGV = getLinkedToGlobal(SGA); + + if (DGV) { GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; bool LinkFromSrc = false; - if (GetLinkageResult(DGV, SF, NewLinkage, LinkFromSrc, Err)) + if (getLinkageResult(DGV, SGA, NewLinkage, LinkFromSrc)) return true; - - // If there is no linkage to be performed, just bring over SF without - // modifying it. - if (DGV == 0) { - // Function does not already exist, simply insert an function signature - // identical to SF into the dest module. - Function *NewDF = Function::Create(SF->getFunctionType(), - SF->getLinkage(), - SF->getName(), Dest); - CopyGVAttributes(NewDF, SF); - - // If the LLVM runtime renamed the function, but it is an externally - // visible symbol, DF must be an existing function with internal linkage. - // Rename it. - if (!NewDF->hasLocalLinkage() && NewDF->getName() != SF->getName()) - ForceRenaming(NewDF, SF->getName()); - - // ... and remember this mapping... - ValueMap[SF] = NewDF; - continue; - } - - // If the visibilities of the symbols disagree and the destination is a - // prototype, take the visibility of its input. - if (DGV->isDeclaration()) - DGV->setVisibility(SF->getVisibility()); - - if (LinkFromSrc) { - if (isa<GlobalAlias>(DGV)) - return Error(Err, "Function-Alias Collision on '" + SF->getName() + - "': symbol multiple defined"); - - // We have a definition of the same name but different type in the - // source module. Copy the prototype to the destination and replace - // uses of the destination's prototype with the new prototype. - Function *NewDF = Function::Create(SF->getFunctionType(), NewLinkage, - SF->getName(), Dest); - CopyGVAttributes(NewDF, SF); - - // Any uses of DF need to change to NewDF, with cast - DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDF, - DGV->getType())); - - // DF will conflict with NewDF because they both had the same. We must - // erase this now so ForceRenaming doesn't assert because DF might - // not have internal linkage. - if (GlobalVariable *Var = dyn_cast<GlobalVariable>(DGV)) - Var->eraseFromParent(); - else - cast<Function>(DGV)->eraseFromParent(); - - // If the symbol table renamed the function, but it is an externally - // visible symbol, DF must be an existing function with internal - // linkage. Rename it. - if (NewDF->getName() != SF->getName() && !NewDF->hasLocalLinkage()) - ForceRenaming(NewDF, SF->getName()); - - // Remember this mapping so uses in the source module get remapped - // later by MapValue. - ValueMap[SF] = NewDF; - continue; + + if (!LinkFromSrc) { + // Set calculated linkage. + DGV->setLinkage(NewLinkage); + + // Make sure to remember this mapping. + ValueMap[SGA] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGA->getType())); + + // Remove the body from the source module so we don't attempt to remap it. + SGA->setAliasee(0); + return false; } + } + + // If there is no linkage to be performed or we're linking from the source, + // bring over SGA. + GlobalAlias *NewDA = new GlobalAlias(TypeMap.get(SGA->getType()), + SGA->getLinkage(), SGA->getName(), + /*aliasee*/0, DstM); + CopyGVAttributes(NewDA, SGA); + + if (DGV) { + // Any uses of DGV need to change to NewDA, with cast. + DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDA, DGV->getType())); + DGV->eraseFromParent(); + } + + ValueMap[SGA] = NewDA; + return false; +} - // Not "link from source", keep the one in the DestModule and remap the - // input onto it. - - if (isa<GlobalAlias>(DGV)) { - // The only valid mappings are: - // - SF is external declaration, which is effectively a no-op. - // - SF is weak, when we just need to throw SF out. - if (!SF->isDeclaration() && !SF->isWeakForLinker()) - return Error(Err, "Function-Alias Collision on '" + SF->getName() + - "': symbol multiple defined"); - } +void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) { + // Merge the initializer. + SmallVector<Constant*, 16> Elements; + if (ConstantArray *I = dyn_cast<ConstantArray>(AVI.DstInit)) { + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + Elements.push_back(I->getOperand(i)); + } else { + assert(isa<ConstantAggregateZero>(AVI.DstInit)); + ArrayType *DstAT = cast<ArrayType>(AVI.DstInit->getType()); + Type *EltTy = DstAT->getElementType(); + Elements.append(DstAT->getNumElements(), Constant::getNullValue(EltTy)); + } + + Constant *SrcInit = MapValue(AVI.SrcInit, ValueMap, RF_None, &TypeMap); + if (const ConstantArray *I = dyn_cast<ConstantArray>(SrcInit)) { + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + Elements.push_back(I->getOperand(i)); + } else { + assert(isa<ConstantAggregateZero>(SrcInit)); + ArrayType *SrcAT = cast<ArrayType>(SrcInit->getType()); + Type *EltTy = SrcAT->getElementType(); + Elements.append(SrcAT->getNumElements(), Constant::getNullValue(EltTy)); + } + ArrayType *NewType = cast<ArrayType>(AVI.NewGV->getType()->getElementType()); + AVI.NewGV->setInitializer(ConstantArray::get(NewType, Elements)); +} - // Set calculated linkage - DGV->setLinkage(NewLinkage); - // Make sure to remember this mapping. - ValueMap[SF] = ConstantExpr::getBitCast(DGV, SF->getType()); +// linkGlobalInits - Update the initializers in the Dest module now that all +// globals that may be referenced are in Dest. +void ModuleLinker::linkGlobalInits() { + // Loop over all of the globals in the src module, mapping them over as we go + for (Module::const_global_iterator I = SrcM->global_begin(), + E = SrcM->global_end(); I != E; ++I) { + if (!I->hasInitializer()) continue; // Only process initialized GV's. + + // Grab destination global variable. + GlobalVariable *DGV = cast<GlobalVariable>(ValueMap[I]); + // Figure out what the initializer looks like in the dest module. + DGV->setInitializer(MapValue(I->getInitializer(), ValueMap, + RF_None, &TypeMap)); } - return false; } -// LinkFunctionBody - Copy the source function over into the dest function and +// linkFunctionBody - Copy the source function over into the dest function and // fix up references to values. At this point we know that Dest is an external // function, and that Src is not. -static bool LinkFunctionBody(Function *Dest, Function *Src, - ValueToValueMapTy &ValueMap, - std::string *Err) { - assert(Src && Dest && Dest->isDeclaration() && !Src->isDeclaration()); +void ModuleLinker::linkFunctionBody(Function *Dst, Function *Src) { + assert(Src && Dst && Dst->isDeclaration() && !Src->isDeclaration()); // Go through and convert function arguments over, remembering the mapping. - Function::arg_iterator DI = Dest->arg_begin(); + Function::arg_iterator DI = Dst->arg_begin(); for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end(); I != E; ++I, ++DI) { - DI->setName(I->getName()); // Copy the name information over... + DI->setName(I->getName()); // Copy the name over. - // Add a mapping to our local map + // Add a mapping to our mapping. ValueMap[I] = DI; } // Splice the body of the source function into the dest function. - Dest->getBasicBlockList().splice(Dest->end(), Src->getBasicBlockList()); + Dst->getBasicBlockList().splice(Dst->end(), Src->getBasicBlockList()); // At this point, all of the instructions and values of the function are now // copied over. The only problem is that they are still referencing values in // the Source function as operands. Loop through all of the operands of the // functions and patch them up to point to the local versions. - for (Function::iterator BB = Dest->begin(), BE = Dest->end(); BB != BE; ++BB) + for (Function::iterator BB = Dst->begin(), BE = Dst->end(); BB != BE; ++BB) for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) - RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries); + RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries, &TypeMap); // There is no need to map the arguments anymore. for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end(); I != E; ++I) ValueMap.erase(I); - - return false; } -// LinkFunctionBodies - Link in the function bodies that are defined in the -// source module into the DestModule. This consists basically of copying the -// function over and fixing up references to values. -static bool LinkFunctionBodies(Module *Dest, Module *Src, - ValueToValueMapTy &ValueMap, - std::string *Err) { - - // Loop over all of the functions in the src module, mapping them over as we - // go - for (Module::iterator SF = Src->begin(), E = Src->end(); SF != E; ++SF) { - if (!SF->isDeclaration()) { // No body if function is external - Function *DF = dyn_cast<Function>(ValueMap[SF]); // Destination function - - // DF not external SF external? - if (DF && DF->isDeclaration()) - // Only provide the function body if there isn't one already. - if (LinkFunctionBody(DF, SF, ValueMap, Err)) - return true; +void ModuleLinker::linkAliasBodies() { + for (Module::alias_iterator I = SrcM->alias_begin(), E = SrcM->alias_end(); + I != E; ++I) + if (Constant *Aliasee = I->getAliasee()) { + GlobalAlias *DA = cast<GlobalAlias>(ValueMap[I]); + DA->setAliasee(MapValue(Aliasee, ValueMap, RF_None, &TypeMap)); } - } - return false; } -// LinkAppendingVars - If there were any appending global variables, link them -// together now. Return true on error. -static bool LinkAppendingVars(Module *M, - std::multimap<std::string, GlobalVariable *> &AppendingVars, - std::string *ErrorMsg) { - if (AppendingVars.empty()) return false; // Nothing to do. - - // Loop over the multimap of appending vars, processing any variables with the - // same name, forming a new appending global variable with both of the - // initializers merged together, then rewrite references to the old variables - // and delete them. - std::vector<Constant*> Inits; - while (AppendingVars.size() > 1) { - // Get the first two elements in the map... - std::multimap<std::string, - GlobalVariable*>::iterator Second = AppendingVars.begin(), First=Second++; - - // If the first two elements are for different names, there is no pair... - // Otherwise there is a pair, so link them together... - if (First->first == Second->first) { - GlobalVariable *G1 = First->second, *G2 = Second->second; - const ArrayType *T1 = cast<ArrayType>(G1->getType()->getElementType()); - const ArrayType *T2 = cast<ArrayType>(G2->getType()->getElementType()); - - // Check to see that they two arrays agree on type... - if (T1->getElementType() != T2->getElementType()) - return Error(ErrorMsg, - "Appending variables with different element types need to be linked!"); - if (G1->isConstant() != G2->isConstant()) - return Error(ErrorMsg, - "Appending variables linked with different const'ness!"); - - if (G1->getAlignment() != G2->getAlignment()) - return Error(ErrorMsg, - "Appending variables with different alignment need to be linked!"); - - if (G1->getVisibility() != G2->getVisibility()) - return Error(ErrorMsg, - "Appending variables with different visibility need to be linked!"); - - if (G1->getSection() != G2->getSection()) - return Error(ErrorMsg, - "Appending variables with different section name need to be linked!"); - - unsigned NewSize = T1->getNumElements() + T2->getNumElements(); - ArrayType *NewType = ArrayType::get(T1->getElementType(), - NewSize); - - G1->setName(""); // Clear G1's name in case of a conflict! - - // Create the new global variable... - GlobalVariable *NG = - new GlobalVariable(*M, NewType, G1->isConstant(), G1->getLinkage(), - /*init*/0, First->first, 0, G1->isThreadLocal(), - G1->getType()->getAddressSpace()); - - // Propagate alignment, visibility and section info. - CopyGVAttributes(NG, G1); - - // Merge the initializer... - Inits.reserve(NewSize); - if (ConstantArray *I = dyn_cast<ConstantArray>(G1->getInitializer())) { - for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i) - Inits.push_back(I->getOperand(i)); - } else { - assert(isa<ConstantAggregateZero>(G1->getInitializer())); - Constant *CV = Constant::getNullValue(T1->getElementType()); - for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i) - Inits.push_back(CV); - } - if (ConstantArray *I = dyn_cast<ConstantArray>(G2->getInitializer())) { - for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i) - Inits.push_back(I->getOperand(i)); - } else { - assert(isa<ConstantAggregateZero>(G2->getInitializer())); - Constant *CV = Constant::getNullValue(T2->getElementType()); - for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i) - Inits.push_back(CV); - } - NG->setInitializer(ConstantArray::get(NewType, Inits)); - Inits.clear(); - - // Replace any uses of the two global variables with uses of the new - // global... - - // FIXME: This should rewrite simple/straight-forward uses such as - // getelementptr instructions to not use the Cast! - G1->replaceAllUsesWith(ConstantExpr::getBitCast(NG, - G1->getType())); - G2->replaceAllUsesWith(ConstantExpr::getBitCast(NG, - G2->getType())); - - // Remove the two globals from the module now... - M->getGlobalList().erase(G1); - M->getGlobalList().erase(G2); - - // Put the new global into the AppendingVars map so that we can handle - // linking of more than two vars... - Second->second = NG; - } - AppendingVars.erase(First); +/// linkNamedMDNodes - Insert all of the named mdnodes in Src into the Dest +/// module. +void ModuleLinker::linkNamedMDNodes() { + for (Module::const_named_metadata_iterator I = SrcM->named_metadata_begin(), + E = SrcM->named_metadata_end(); I != E; ++I) { + NamedMDNode *DestNMD = DstM->getOrInsertNamedMetadata(I->getName()); + // Add Src elements into Dest node. + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + DestNMD->addOperand(MapValue(I->getOperand(i), ValueMap, + RF_None, &TypeMap)); } - - return false; } + +bool ModuleLinker::run() { + assert(DstM && "Null Destination module"); + assert(SrcM && "Null Source Module"); -static bool ResolveAliases(Module *Dest) { - for (Module::alias_iterator I = Dest->alias_begin(), E = Dest->alias_end(); - I != E; ++I) - // We can't sue resolveGlobalAlias here because we need to preserve - // bitcasts and GEPs. - if (const Constant *C = I->getAliasee()) { - while (dyn_cast<GlobalAlias>(C)) - C = cast<GlobalAlias>(C)->getAliasee(); - const GlobalValue *GV = dyn_cast<GlobalValue>(C); - if (C != I && !(GV && GV->isDeclaration())) - I->replaceAllUsesWith(const_cast<Constant*>(C)); - } - - return false; -} - -// LinkModules - This function links two modules together, with the resulting -// left module modified to be the composite of the two input modules. If an -// error occurs, true is returned and ErrorMsg (if not null) is set to indicate -// the problem. Upon failure, the Dest module could be in a modified state, and -// shouldn't be relied on to be consistent. -bool -Linker::LinkModules(Module *Dest, Module *Src, std::string *ErrorMsg) { - assert(Dest != 0 && "Invalid Destination module"); - assert(Src != 0 && "Invalid Source Module"); - - if (Dest->getDataLayout().empty()) { - if (!Src->getDataLayout().empty()) { - Dest->setDataLayout(Src->getDataLayout()); - } else { - std::string DataLayout; - - if (Dest->getEndianness() == Module::AnyEndianness) { - if (Src->getEndianness() == Module::BigEndian) - DataLayout.append("E"); - else if (Src->getEndianness() == Module::LittleEndian) - DataLayout.append("e"); - } - - if (Dest->getPointerSize() == Module::AnyPointerSize) { - if (Src->getPointerSize() == Module::Pointer64) - DataLayout.append(DataLayout.length() == 0 ? "p:64:64" : "-p:64:64"); - else if (Src->getPointerSize() == Module::Pointer32) - DataLayout.append(DataLayout.length() == 0 ? "p:32:32" : "-p:32:32"); - } - Dest->setDataLayout(DataLayout); - } - } + // Inherit the target data from the source module if the destination module + // doesn't have one already. + if (DstM->getDataLayout().empty() && !SrcM->getDataLayout().empty()) + DstM->setDataLayout(SrcM->getDataLayout()); // Copy the target triple from the source to dest if the dest's is empty. - if (Dest->getTargetTriple().empty() && !Src->getTargetTriple().empty()) - Dest->setTargetTriple(Src->getTargetTriple()); + if (DstM->getTargetTriple().empty() && !SrcM->getTargetTriple().empty()) + DstM->setTargetTriple(SrcM->getTargetTriple()); - if (!Src->getDataLayout().empty() && !Dest->getDataLayout().empty() && - Src->getDataLayout() != Dest->getDataLayout()) + if (!SrcM->getDataLayout().empty() && !DstM->getDataLayout().empty() && + SrcM->getDataLayout() != DstM->getDataLayout()) errs() << "WARNING: Linking two modules of different data layouts!\n"; - if (!Src->getTargetTriple().empty() && - Dest->getTargetTriple() != Src->getTargetTriple()) { + if (!SrcM->getTargetTriple().empty() && + DstM->getTargetTriple() != SrcM->getTargetTriple()) { errs() << "WARNING: Linking two modules of different target triples: "; - if (!Src->getModuleIdentifier().empty()) - errs() << Src->getModuleIdentifier() << ": "; - errs() << "'" << Src->getTargetTriple() << "' and '" - << Dest->getTargetTriple() << "'\n"; + if (!SrcM->getModuleIdentifier().empty()) + errs() << SrcM->getModuleIdentifier() << ": "; + errs() << "'" << SrcM->getTargetTriple() << "' and '" + << DstM->getTargetTriple() << "'\n"; } // Append the module inline asm string. - if (!Src->getModuleInlineAsm().empty()) { - if (Dest->getModuleInlineAsm().empty()) - Dest->setModuleInlineAsm(Src->getModuleInlineAsm()); + if (!SrcM->getModuleInlineAsm().empty()) { + if (DstM->getModuleInlineAsm().empty()) + DstM->setModuleInlineAsm(SrcM->getModuleInlineAsm()); else - Dest->setModuleInlineAsm(Dest->getModuleInlineAsm()+"\n"+ - Src->getModuleInlineAsm()); + DstM->setModuleInlineAsm(DstM->getModuleInlineAsm()+"\n"+ + SrcM->getModuleInlineAsm()); } // Update the destination module's dependent libraries list with the libraries // from the source module. There's no opportunity for duplicates here as the // Module ensures that duplicate insertions are discarded. - for (Module::lib_iterator SI = Src->lib_begin(), SE = Src->lib_end(); + for (Module::lib_iterator SI = SrcM->lib_begin(), SE = SrcM->lib_end(); SI != SE; ++SI) - Dest->addLibrary(*SI); + DstM->addLibrary(*SI); + + // If the source library's module id is in the dependent library list of the + // destination library, remove it since that module is now linked in. + StringRef ModuleId = SrcM->getModuleIdentifier(); + if (!ModuleId.empty()) + DstM->removeLibrary(sys::path::stem(ModuleId)); - // LinkTypes - Go through the symbol table of the Src module and see if any - // types are named in the src module that are not named in the Dst module. - // Make sure there are no type name conflicts. - if (LinkTypes(Dest, Src, ErrorMsg)) - return true; + + // Loop over all of the linked values to compute type mappings. + computeTypeMapping(); - // ValueMap - Mapping of values from what they used to be in Src, to what they - // are now in Dest. ValueToValueMapTy is a ValueMap, which involves some - // overhead due to the use of Value handles which the Linker doesn't actually - // need, but this allows us to reuse the ValueMapper code. - ValueToValueMapTy ValueMap; - - // AppendingVars - Keep track of global variables in the destination module - // with appending linkage. After the module is linked together, they are - // appended and the module is rewritten. - std::multimap<std::string, GlobalVariable *> AppendingVars; - for (Module::global_iterator I = Dest->global_begin(), E = Dest->global_end(); - I != E; ++I) { - // Add all of the appending globals already in the Dest module to - // AppendingVars. - if (I->hasAppendingLinkage()) - AppendingVars.insert(std::make_pair(I->getName(), I)); - } - - // Insert all of the globals in src into the Dest module... without linking + // Insert all of the globals in src into the DstM module... without linking // initializers (which could refer to functions not yet mapped over). - if (LinkGlobals(Dest, Src, ValueMap, AppendingVars, ErrorMsg)) - return true; + for (Module::global_iterator I = SrcM->global_begin(), + E = SrcM->global_end(); I != E; ++I) + if (linkGlobalProto(I)) + return true; // Link the functions together between the two modules, without doing function - // bodies... this just adds external function prototypes to the Dest + // bodies... this just adds external function prototypes to the DstM // function... We do this so that when we begin processing function bodies, // all of the global values that may be referenced are available in our // ValueMap. - if (LinkFunctionProtos(Dest, Src, ValueMap, ErrorMsg)) - return true; - - // If there were any alias, link them now. We really need to do this now, - // because all of the aliases that may be referenced need to be available in - // ValueMap - if (LinkAlias(Dest, Src, ValueMap, ErrorMsg)) return true; - - // Update the initializers in the Dest module now that all globals that may - // be referenced are in Dest. - if (LinkGlobalInits(Dest, Src, ValueMap, ErrorMsg)) return true; + for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I) + if (linkFunctionProto(I)) + return true; - // Link in the function bodies that are defined in the source module into the - // DestModule. This consists basically of copying the function over and - // fixing up references to values. - if (LinkFunctionBodies(Dest, Src, ValueMap, ErrorMsg)) return true; + // If there were any aliases, link them now. + for (Module::alias_iterator I = SrcM->alias_begin(), + E = SrcM->alias_end(); I != E; ++I) + if (linkAliasProto(I)) + return true; - // If there were any appending global variables, link them together now. - if (LinkAppendingVars(Dest, AppendingVars, ErrorMsg)) return true; + for (unsigned i = 0, e = AppendingVars.size(); i != e; ++i) + linkAppendingVarInit(AppendingVars[i]); + + // Update the initializers in the DstM module now that all globals that may + // be referenced are in DstM. + linkGlobalInits(); + + // Link in the function bodies that are defined in the source module into + // DstM. + for (Module::iterator SF = SrcM->begin(), E = SrcM->end(); SF != E; ++SF) { + if (SF->isDeclaration()) continue; // No body if function is external. + + linkFunctionBody(cast<Function>(ValueMap[SF]), SF); + } - // Resolve all uses of aliases with aliasees - if (ResolveAliases(Dest)) return true; + // Resolve all uses of aliases with aliasees. + linkAliasBodies(); - // Remap all of the named mdnoes in Src into the Dest module. We do this + // Remap all of the named mdnoes in Src into the DstM module. We do this // after linking GlobalValues so that MDNodes that reference GlobalValues // are properly remapped. - LinkNamedMDNodes(Dest, Src, ValueMap); - - // If the source library's module id is in the dependent library list of the - // destination library, remove it since that module is now linked in. - const std::string &modId = Src->getModuleIdentifier(); - if (!modId.empty()) - Dest->removeLibrary(sys::path::stem(modId)); + linkNamedMDNodes(); + // Now that all of the types from the source are used, resolve any structs + // copied over to the dest that didn't exist there. + TypeMap.linkDefinedTypeBodies(); + return false; } -// vim: sw=2 +//===----------------------------------------------------------------------===// +// LinkModules entrypoint. +//===----------------------------------------------------------------------===// + +// LinkModules - This function links two modules together, with the resulting +// left module modified to be the composite of the two input modules. If an +// error occurs, true is returned and ErrorMsg (if not null) is set to indicate +// the problem. Upon failure, the Dest module could be in a modified state, and +// shouldn't be relied on to be consistent. +bool Linker::LinkModules(Module *Dest, Module *Src, std::string *ErrorMsg) { + ModuleLinker TheLinker(Dest, Src); + if (TheLinker.run()) { + if (ErrorMsg) *ErrorMsg = TheLinker.ErrorMsg; + return true; + } + + return false; +} diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index c59497e..54072b2 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -20,7 +20,6 @@ #include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/PassManager.h" -#include "llvm/TypeSymbolTable.h" #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" #include "llvm/InlineAsm.h" @@ -74,29 +73,6 @@ namespace { PrivateGlobalPrefix = ""; } }; - /// CBackendNameAllUsedStructsAndMergeFunctions - This pass inserts names for - /// any unnamed structure types that are used by the program, and merges - /// external functions with the same name. - /// - class CBackendNameAllUsedStructsAndMergeFunctions : public ModulePass { - public: - static char ID; - CBackendNameAllUsedStructsAndMergeFunctions() - : ModulePass(ID) { - initializeFindUsedTypesPass(*PassRegistry::getPassRegistry()); - } - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<FindUsedTypes>(); - } - - virtual const char *getPassName() const { - return "C backend type canonicalizer"; - } - - virtual bool runOnModule(Module &M); - }; - - char CBackendNameAllUsedStructsAndMergeFunctions::ID = 0; /// CWriter - This class is the main chunk of code that converts an LLVM /// module to a C translation unit. @@ -109,7 +85,7 @@ namespace { const MCAsmInfo* TAsm; MCContext *TCtx; const TargetData* TD; - std::map<const Type *, std::string> TypeNames; + std::map<const ConstantFP *, unsigned> FPConstantMap; std::set<Function*> intrinsicPrototypesAlreadyGenerated; std::set<const Argument*> ByValParams; @@ -118,6 +94,10 @@ namespace { DenseMap<const Value*, unsigned> AnonValueNumbers; unsigned NextAnonValueNumber; + /// UnnamedStructIDs - This contains a unique ID for each struct that is + /// either anonymous or has no name. + DenseMap<const StructType*, unsigned> UnnamedStructIDs; + public: static char ID; explicit CWriter(formatted_raw_ostream &o) @@ -163,9 +143,9 @@ namespace { delete TCtx; delete TAsm; FPConstantMap.clear(); - TypeNames.clear(); ByValParams.clear(); intrinsicPrototypesAlreadyGenerated.clear(); + UnnamedStructIDs.clear(); return false; } @@ -182,6 +162,8 @@ namespace { const AttrListPtr &PAL, const PointerType *Ty); + std::string getStructName(const StructType *ST); + /// writeOperandDeref - Print the result of dereferencing the specified /// operand with '*'. This is equivalent to printing '*' then using /// writeOperand, but avoids excess syntax in some cases. @@ -214,8 +196,8 @@ namespace { /// intrinsics which need to be explicitly defined in the CBackend. void printIntrinsicDefinition(const Function &F, raw_ostream &Out); - void printModuleTypes(const TypeSymbolTable &ST); - void printContainedStructs(const Type *Ty, std::set<const Type *> &); + void printModuleTypes(); + void printContainedStructs(const Type *Ty, SmallPtrSet<const Type *, 16> &); void printFloatingPointConstants(Function &F); void printFloatingPointConstants(const Constant *C); void printFunctionSignature(const Function *F, bool Prototype); @@ -359,6 +341,7 @@ namespace { char CWriter::ID = 0; + static std::string CBEMangle(const std::string &S) { std::string Result; @@ -374,90 +357,14 @@ static std::string CBEMangle(const std::string &S) { return Result; } - -/// This method inserts names for any unnamed structure types that are used by -/// the program, and removes names from structure types that are not used by the -/// program. -/// -bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) { - // Get a set of types that are used by the program... - SetVector<const Type *> UT = getAnalysis<FindUsedTypes>().getTypes(); - - // Loop over the module symbol table, removing types from UT that are - // already named, and removing names for types that are not used. - // - TypeSymbolTable &TST = M.getTypeSymbolTable(); - for (TypeSymbolTable::iterator TI = TST.begin(), TE = TST.end(); - TI != TE; ) { - TypeSymbolTable::iterator I = TI++; - - // If this isn't a struct or array type, remove it from our set of types - // to name. This simplifies emission later. - if (!I->second->isStructTy() && !I->second->isOpaqueTy() && - !I->second->isArrayTy()) { - TST.remove(I); - } else { - // If this is not used, remove it from the symbol table. - if (!UT.count(I->second)) - TST.remove(I); - else - UT.remove(I->second); // Only keep one name for this type. - } - } - - // UT now contains types that are not named. Loop over it, naming - // structure types. - // - bool Changed = false; - unsigned RenameCounter = 0; - for (SetVector<const Type *>::const_iterator I = UT.begin(), E = UT.end(); - I != E; ++I) - if ((*I)->isStructTy() || (*I)->isArrayTy()) { - while (M.addTypeName("unnamed"+utostr(RenameCounter), *I)) - ++RenameCounter; - Changed = true; - } - - - // Loop over all external functions and globals. If we have two with - // identical names, merge them. - // FIXME: This code should disappear when we don't allow values with the same - // names when they have different types! - std::map<std::string, GlobalValue*> ExtSymbols; - for (Module::iterator I = M.begin(), E = M.end(); I != E;) { - Function *GV = I++; - if (GV->isDeclaration() && GV->hasName()) { - std::pair<std::map<std::string, GlobalValue*>::iterator, bool> X - = ExtSymbols.insert(std::make_pair(GV->getName(), GV)); - if (!X.second) { - // Found a conflict, replace this global with the previous one. - GlobalValue *OldGV = X.first->second; - GV->replaceAllUsesWith(ConstantExpr::getBitCast(OldGV, GV->getType())); - GV->eraseFromParent(); - Changed = true; - } - } - } - // Do the same for globals. - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E;) { - GlobalVariable *GV = I++; - if (GV->isDeclaration() && GV->hasName()) { - std::pair<std::map<std::string, GlobalValue*>::iterator, bool> X - = ExtSymbols.insert(std::make_pair(GV->getName(), GV)); - if (!X.second) { - // Found a conflict, replace this global with the previous one. - GlobalValue *OldGV = X.first->second; - GV->replaceAllUsesWith(ConstantExpr::getBitCast(OldGV, GV->getType())); - GV->eraseFromParent(); - Changed = true; - } - } - } - - return Changed; +std::string CWriter::getStructName(const StructType *ST) { + if (!ST->isAnonymous() && !ST->getName().empty()) + return CBEMangle("l_"+ST->getName().str()); + + return "l_unnamed_" + utostr(UnnamedStructIDs[ST]); } + /// printStructReturnPointerFunctionType - This is like printType for a struct /// return type, except, instead of printing the type as void (*)(Struct*, ...) /// print it as "Struct (*)(...)", for struct return functions. @@ -471,7 +378,7 @@ void CWriter::printStructReturnPointerFunctionType(raw_ostream &Out, bool PrintedType = false; FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); - const Type *RetTy = cast<PointerType>(I->get())->getElementType(); + const Type *RetTy = cast<PointerType>(*I)->getElementType(); unsigned Idx = 1; for (++I, ++Idx; I != E; ++I, ++Idx) { if (PrintedType) @@ -559,12 +466,6 @@ raw_ostream &CWriter::printType(raw_ostream &Out, const Type *Ty, return Out; } - // Check to see if the type is named. - if (!IgnoreName || Ty->isOpaqueTy()) { - std::map<const Type *, std::string>::iterator I = TypeNames.find(Ty); - if (I != TypeNames.end()) return Out << I->second << ' ' << NameSoFar; - } - switch (Ty->getTypeID()) { case Type::FunctionTyID: { const FunctionType *FTy = cast<FunctionType>(Ty); @@ -599,6 +500,11 @@ raw_ostream &CWriter::printType(raw_ostream &Out, const Type *Ty, } case Type::StructTyID: { const StructType *STy = cast<StructType>(Ty); + + // Check to see if the type is named. + if (!IgnoreName) + return Out << getStructName(STy) << ' ' << NameSoFar; + Out << NameSoFar + " {\n"; unsigned Idx = 0; for (StructType::element_iterator I = STy->element_begin(), @@ -639,12 +545,6 @@ raw_ostream &CWriter::printType(raw_ostream &Out, const Type *Ty, return Out << "; }"; } - case Type::OpaqueTyID: { - std::string TyName = "struct opaque_" + itostr(OpaqueCounter++); - assert(TypeNames.find(Ty) == TypeNames.end()); - TypeNames[Ty] = TyName; - return Out << TyName << ' ' << NameSoFar; - } default: llvm_unreachable("Unhandled case in getTypeProps!"); } @@ -1829,8 +1729,8 @@ bool CWriter::doInitialization(Module &M) { << "/* End Module asm statements */\n"; } - // Loop over the symbol table, emitting all named constants... - printModuleTypes(M.getTypeSymbolTable()); + // Loop over the symbol table, emitting all named constants. + printModuleTypes(); // Global variable declarations... if (!M.global_empty()) { @@ -2119,11 +2019,10 @@ void CWriter::printFloatingPointConstants(const Constant *C) { } - /// printSymbolTable - Run through symbol table looking for type names. If a /// type name is found, emit its declaration... /// -void CWriter::printModuleTypes(const TypeSymbolTable &TST) { +void CWriter::printModuleTypes() { Out << "/* Helper union for bitcasts */\n"; Out << "typedef union {\n"; Out << " unsigned int Int32;\n"; @@ -2132,46 +2031,42 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) { Out << " double Double;\n"; Out << "} llvmBitCastUnion;\n"; - // We are only interested in the type plane of the symbol table. - TypeSymbolTable::const_iterator I = TST.begin(); - TypeSymbolTable::const_iterator End = TST.end(); + // Get all of the struct types used in the module. + std::vector<StructType*> StructTypes; + TheModule->findUsedStructTypes(StructTypes); - // If there are no type names, exit early. - if (I == End) return; + if (StructTypes.empty()) return; - // Print out forward declarations for structure types before anything else! Out << "/* Structure forward decls */\n"; - for (; I != End; ++I) { - std::string Name = "struct " + CBEMangle("l_"+I->first); - Out << Name << ";\n"; - TypeNames.insert(std::make_pair(I->second, Name)); - } - Out << '\n'; + unsigned NextTypeID = 0; + + // If any of them are missing names, add a unique ID to UnnamedStructIDs. + // Print out forward declarations for structure types. + for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) { + StructType *ST = StructTypes[i]; - // Now we can print out typedefs. Above, we guaranteed that this can only be - // for struct or opaque types. - Out << "/* Typedefs */\n"; - for (I = TST.begin(); I != End; ++I) { - std::string Name = CBEMangle("l_"+I->first); - Out << "typedef "; - printType(Out, I->second, false, Name); - Out << ";\n"; + if (ST->isAnonymous() || ST->getName().empty()) + UnnamedStructIDs[ST] = NextTypeID++; + + std::string Name = getStructName(ST); + + Out << "typedef struct " << Name << ' ' << Name << ";\n"; } Out << '\n'; - // Keep track of which structures have been printed so far... - std::set<const Type *> StructPrinted; + // Keep track of which structures have been printed so far. + SmallPtrSet<const Type *, 16> StructPrinted; // Loop over all structures then push them into the stack so they are // printed in the correct order. // Out << "/* Structure contents */\n"; - for (I = TST.begin(); I != End; ++I) - if (I->second->isStructTy() || I->second->isArrayTy()) + for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) + if (StructTypes[i]->isStructTy()) // Only print out used types! - printContainedStructs(I->second, StructPrinted); + printContainedStructs(StructTypes[i], StructPrinted); } // Push the struct onto the stack and recursively push all structs @@ -2180,7 +2075,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) { // TODO: Make this work properly with vector types // void CWriter::printContainedStructs(const Type *Ty, - std::set<const Type*> &StructPrinted) { + SmallPtrSet<const Type *, 16> &StructPrinted) { // Don't walk through pointers. if (Ty->isPointerTy() || Ty->isPrimitiveType() || Ty->isIntegerTy()) return; @@ -2190,14 +2085,13 @@ void CWriter::printContainedStructs(const Type *Ty, E = Ty->subtype_end(); I != E; ++I) printContainedStructs(*I, StructPrinted); - if (Ty->isStructTy() || Ty->isArrayTy()) { + if (const StructType *ST = dyn_cast<StructType>(Ty)) { // Check to see if we have already printed this struct. - if (StructPrinted.insert(Ty).second) { - // Print structure type out. - std::string Name = TypeNames[Ty]; - printType(Out, Ty, false, Name, true); - Out << ";\n\n"; - } + if (!StructPrinted.insert(Ty)) return; + + // Print structure type out. + printType(Out, ST, false, getStructName(ST), true); + Out << ";\n\n"; } } @@ -2847,10 +2741,12 @@ static void printLimitValue(const IntegerType &Ty, bool isSigned, bool isMax, Out << "U" << type << (isMax ? "_MAX" : "0"); } +#ifndef NDEBUG static bool isSupportedIntegerSize(const IntegerType &T) { return T.getBitWidth() == 8 || T.getBitWidth() == 16 || T.getBitWidth() == 32 || T.getBitWidth() == 64; } +#endif void CWriter::printIntrinsicDefinition(const Function &F, raw_ostream &Out) { const FunctionType *funT = F.getFunctionType(); @@ -3704,7 +3600,6 @@ bool CTargetMachine::addPassesToEmitFile(PassManagerBase &PM, PM.add(createGCLoweringPass()); PM.add(createLowerInvokePass()); PM.add(createCFGSimplificationPass()); // clean up after lower invoke. - PM.add(new CBackendNameAllUsedStructsAndMergeFunctions()); PM.add(new CWriter(o)); PM.add(createGCInfoDeleter()); return false; diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index 351f1222..c4280ef 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -22,7 +22,7 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/PassManager.h" -#include "llvm/TypeSymbolTable.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/CommandLine.h" @@ -33,7 +33,7 @@ #include "llvm/Config/config.h" #include <algorithm> #include <set> - +#include <map> using namespace llvm; static cl::opt<std::string> @@ -193,26 +193,11 @@ static std::string getTypePrefix(const Type *Ty) { case Type::ArrayTyID: return "array_"; case Type::PointerTyID: return "ptr_"; case Type::VectorTyID: return "packed_"; - case Type::OpaqueTyID: return "opaque_"; default: return "other_"; } return "unknown_"; } -// Looks up the type in the symbol table and returns a pointer to its name or -// a null pointer if it wasn't found. Note that this isn't the same as the -// Mode::getTypeName function which will return an empty string, not a null -// pointer if the name is not found. -static const std::string * -findTypeName(const TypeSymbolTable& ST, const Type* Ty) { - TypeSymbolTable::const_iterator TI = ST.begin(); - TypeSymbolTable::const_iterator TE = ST.end(); - for (;TI != TE; ++TI) - if (TI->second == Ty) - return &(TI->first); - return 0; -} - void CppWriter::error(const std::string& msg) { report_fatal_error(msg); } @@ -384,18 +369,20 @@ std::string CppWriter::getCppName(const Type* Ty) { case Type::StructTyID: prefix = "StructTy_"; break; case Type::ArrayTyID: prefix = "ArrayTy_"; break; case Type::PointerTyID: prefix = "PointerTy_"; break; - case Type::OpaqueTyID: prefix = "OpaqueTy_"; break; case Type::VectorTyID: prefix = "VectorTy_"; break; default: prefix = "OtherTy_"; break; // prevent breakage } // See if the type has a name in the symboltable and build accordingly - const std::string* tName = findTypeName(TheModule->getTypeSymbolTable(), Ty); std::string name; - if (tName) - name = std::string(prefix) + *tName; - else - name = std::string(prefix) + utostr(uniqueNum++); + if (const StructType *STy = dyn_cast<StructType>(Ty)) + if (STy->hasName()) + name = STy->getName(); + + if (name.empty()) + name = utostr(uniqueNum++); + + name = std::string(prefix) + name; sanitize(name); // Save the name @@ -590,8 +577,18 @@ bool CppWriter::printTypeInternal(const Type* Ty) { Out << ");"; nl(Out); } - Out << "StructType* " << typeName << " = StructType::get(" - << typeName << "_fields, /*isPacked=*/" + + Out << "StructType *" << typeName << " = "; + if (ST->isAnonymous()) { + Out << "StructType::get(" << "mod->getContext(), "; + } else { + Out << "StructType::createNamed(mod->getContext(), \""; + printEscapedString(ST->getName()); + Out << "\");"; + nl(Out); + Out << typeName << "->setBody("; + } + Out << typeName << "_fields, /*isPacked=*/" << (ST->isPacked() ? "true" : "false") << ");"; nl(Out); break; @@ -629,25 +626,10 @@ bool CppWriter::printTypeInternal(const Type* Ty) { nl(Out); break; } - case Type::OpaqueTyID: { - Out << "OpaqueType* " << typeName; - Out << " = OpaqueType::get(mod->getContext());"; - nl(Out); - break; - } default: error("Invalid TypeID"); } - // If the type had a name, make sure we recreate it. - const std::string* progTypeName = - findTypeName(TheModule->getTypeSymbolTable(),Ty); - if (progTypeName) { - Out << "mod->addTypeName(\"" << *progTypeName << "\", " - << typeName << ");"; - nl(Out); - } - // Pop us off the type stack TypeStack.pop_back(); @@ -670,7 +652,6 @@ bool CppWriter::printTypeInternal(const Type* Ty) { case Type::StructTyID: Out << "StructType"; break; case Type::VectorTyID: Out << "VectorType"; break; case Type::PointerTyID: Out << "PointerType"; break; - case Type::OpaqueTyID: Out << "OpaqueType"; break; default: Out << "NoSuchDerivedType"; break; } Out << ">(" << I->second << "_fwd.get());"; @@ -695,26 +676,7 @@ void CppWriter::printType(const Type* Ty) { } void CppWriter::printTypes(const Module* M) { - // Walk the symbol table and print out all its types - const TypeSymbolTable& symtab = M->getTypeSymbolTable(); - for (TypeSymbolTable::const_iterator TI = symtab.begin(), TE = symtab.end(); - TI != TE; ++TI) { - - // For primitive types and types already defined, just add a name - TypeMap::const_iterator TNI = TypeNames.find(TI->second); - if (TI->second->isIntegerTy() || TI->second->isPrimitiveType() || - TNI != TypeNames.end()) { - Out << "mod->addTypeName(\""; - printEscapedString(TI->first); - Out << "\", " << getCppName(TI->second) << ");"; - nl(Out); - // For everything else, define the type - } else { - printType(TI->second); - } - } - - // Add all of the global variables to the value table... + // Add all of the global variables to the value table. for (Module::const_global_iterator I = TheModule->global_begin(), E = TheModule->global_end(); I != E; ++I) { if (I->hasInitializer()) @@ -1959,8 +1921,8 @@ void CppWriter::printVariable(const std::string& fname, Out << "}\n"; } -void CppWriter::printType(const std::string& fname, - const std::string& typeName) { +void CppWriter::printType(const std::string &fname, + const std::string &typeName) { const Type* Ty = TheModule->getTypeByName(typeName); if (!Ty) { error(std::string("Type '") + typeName + "' not found in input module"); diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index 1990bc7..6309a15 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -42,6 +42,7 @@ char TargetData::ID = 0; //===----------------------------------------------------------------------===// StructLayout::StructLayout(const StructType *ST, const TargetData &TD) { + assert(!ST->isOpaque() && "Cannot get layout of opaque structs"); StructAlignment = 0; StructSize = 0; NumElements = ST->getNumElements(); @@ -313,52 +314,16 @@ unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType, namespace { -class StructLayoutMap : public AbstractTypeUser { +class StructLayoutMap { typedef DenseMap<const StructType*, StructLayout*> LayoutInfoTy; LayoutInfoTy LayoutInfo; - void RemoveEntry(LayoutInfoTy::iterator I, bool WasAbstract) { - I->second->~StructLayout(); - free(I->second); - if (WasAbstract) - I->first->removeAbstractTypeUser(this); - LayoutInfo.erase(I); - } - - - /// refineAbstractType - The callback method invoked when an abstract type is - /// resolved to another type. An object must override this method to update - /// its internal state to reference NewType instead of OldType. - /// - virtual void refineAbstractType(const DerivedType *OldTy, - const Type *) { - LayoutInfoTy::iterator I = LayoutInfo.find(cast<const StructType>(OldTy)); - assert(I != LayoutInfo.end() && "Using type but not in map?"); - RemoveEntry(I, true); - } - - /// typeBecameConcrete - The other case which AbstractTypeUsers must be aware - /// of is when a type makes the transition from being abstract (where it has - /// clients on its AbstractTypeUsers list) to concrete (where it does not). - /// This method notifies ATU's when this occurs for a type. - /// - virtual void typeBecameConcrete(const DerivedType *AbsTy) { - LayoutInfoTy::iterator I = LayoutInfo.find(cast<const StructType>(AbsTy)); - assert(I != LayoutInfo.end() && "Using type but not in map?"); - RemoveEntry(I, true); - } - public: virtual ~StructLayoutMap() { // Remove any layouts. - for (LayoutInfoTy::iterator - I = LayoutInfo.begin(), E = LayoutInfo.end(); I != E; ++I) { - const Type *Key = I->first; + for (LayoutInfoTy::iterator I = LayoutInfo.begin(), E = LayoutInfo.end(); + I != E; ++I) { StructLayout *Value = I->second; - - if (Key->isAbstract()) - Key->removeAbstractTypeUser(this); - Value->~StructLayout(); free(Value); } @@ -367,7 +332,10 @@ public: void InvalidateEntry(const StructType *Ty) { LayoutInfoTy::iterator I = LayoutInfo.find(Ty); if (I == LayoutInfo.end()) return; - RemoveEntry(I, Ty->isAbstract()); + + I->second->~StructLayout(); + free(I->second); + LayoutInfo.erase(I); } StructLayout *&operator[](const StructType *STy) { @@ -404,9 +372,6 @@ const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { new (L) StructLayout(Ty, *this); - if (Ty->isAbstract()) - Ty->addAbstractTypeUser(STM); - return L; } diff --git a/lib/Transforms/IPO/CMakeLists.txt b/lib/Transforms/IPO/CMakeLists.txt index 179b150..3de7bfc 100644 --- a/lib/Transforms/IPO/CMakeLists.txt +++ b/lib/Transforms/IPO/CMakeLists.txt @@ -2,7 +2,6 @@ add_llvm_library(LLVMipo ArgumentPromotion.cpp ConstantMerge.cpp DeadArgumentElimination.cpp - DeadTypeElimination.cpp ExtractGV.cpp FunctionAttrs.cpp GlobalDCE.cpp diff --git a/lib/Transforms/IPO/DeadTypeElimination.cpp b/lib/Transforms/IPO/DeadTypeElimination.cpp deleted file mode 100644 index d3d4963..0000000 --- a/lib/Transforms/IPO/DeadTypeElimination.cpp +++ /dev/null @@ -1,112 +0,0 @@ -//===- DeadTypeElimination.cpp - Eliminate unused types for symbol table --===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass is used to cleanup the output of GCC. It eliminate names for types -// that are unused in the entire translation unit, using the FindUsedTypes pass. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "deadtypeelim" -#include "llvm/Transforms/IPO.h" -#include "llvm/Analysis/FindUsedTypes.h" -#include "llvm/Module.h" -#include "llvm/TypeSymbolTable.h" -#include "llvm/DerivedTypes.h" -#include "llvm/ADT/Statistic.h" -using namespace llvm; - -STATISTIC(NumKilled, "Number of unused typenames removed from symtab"); - -namespace { - struct DTE : public ModulePass { - static char ID; // Pass identification, replacement for typeid - DTE() : ModulePass(ID) { - initializeDTEPass(*PassRegistry::getPassRegistry()); - } - - // doPassInitialization - For this pass, it removes global symbol table - // entries for primitive types. These are never used for linking in GCC and - // they make the output uglier to look at, so we nuke them. - // - // Also, initialize instance variables. - // - bool runOnModule(Module &M); - - // getAnalysisUsage - This function needs FindUsedTypes to do its job... - // - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<FindUsedTypes>(); - } - }; -} - -char DTE::ID = 0; -INITIALIZE_PASS_BEGIN(DTE, "deadtypeelim", "Dead Type Elimination", - false, false) -INITIALIZE_PASS_DEPENDENCY(FindUsedTypes) -INITIALIZE_PASS_END(DTE, "deadtypeelim", "Dead Type Elimination", false, false) - -ModulePass *llvm::createDeadTypeEliminationPass() { - return new DTE(); -} - - -// ShouldNukeSymtabEntry - Return true if this module level symbol table entry -// should be eliminated. -// -static inline bool ShouldNukeSymtabEntry(const Type *Ty){ - // Nuke all names for primitive types! - if (Ty->isPrimitiveType() || Ty->isIntegerTy()) - return true; - - // Nuke all pointers to primitive types as well... - if (const PointerType *PT = dyn_cast<PointerType>(Ty)) - if (PT->getElementType()->isPrimitiveType() || - PT->getElementType()->isIntegerTy()) - return true; - - return false; -} - -// run - For this pass, it removes global symbol table entries for primitive -// types. These are never used for linking in GCC and they make the output -// uglier to look at, so we nuke them. Also eliminate types that are never used -// in the entire program as indicated by FindUsedTypes. -// -bool DTE::runOnModule(Module &M) { - bool Changed = false; - - TypeSymbolTable &ST = M.getTypeSymbolTable(); - const SetVector<const Type*> &T = getAnalysis<FindUsedTypes>().getTypes(); - std::set<const Type*> UsedTypes(T.begin(), T.end()); - - // Check the symbol table for superfluous type entries... - // - // Grab the 'type' plane of the module symbol... - TypeSymbolTable::iterator TI = ST.begin(); - TypeSymbolTable::iterator TE = ST.end(); - while ( TI != TE ) { - // If this entry should be unconditionally removed, or if we detect that - // the type is not used, remove it. - const Type *RHS = TI->second; - if (ShouldNukeSymtabEntry(RHS) || !UsedTypes.count(RHS)) { - ST.remove(TI++); - ++NumKilled; - Changed = true; - } else { - ++TI; - // We only need to leave one name for each type. - UsedTypes.erase(RHS); - } - } - - return Changed; -} - -// vim: sw=2 diff --git a/lib/Transforms/IPO/IPO.cpp b/lib/Transforms/IPO/IPO.cpp index 21dcb51..31ce95f 100644 --- a/lib/Transforms/IPO/IPO.cpp +++ b/lib/Transforms/IPO/IPO.cpp @@ -25,7 +25,6 @@ void llvm::initializeIPO(PassRegistry &Registry) { initializeConstantMergePass(Registry); initializeDAEPass(Registry); initializeDAHPass(Registry); - initializeDTEPass(Registry); initializeFunctionAttrsPass(Registry); initializeGlobalDCEPass(Registry); initializeGlobalOptPass(Registry); @@ -63,10 +62,6 @@ void LLVMAddDeadArgEliminationPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createDeadArgEliminationPass()); } -void LLVMAddDeadTypeEliminationPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createDeadTypeEliminationPass()); -} - void LLVMAddFunctionAttrsPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createFunctionAttrsPass()); } diff --git a/lib/Transforms/IPO/MergeFunctions.cpp b/lib/Transforms/IPO/MergeFunctions.cpp index f741443..183ba63 100644 --- a/lib/Transforms/IPO/MergeFunctions.cpp +++ b/lib/Transforms/IPO/MergeFunctions.cpp @@ -218,7 +218,6 @@ bool FunctionComparator::isEquivalentType(const Type *Ty1, llvm_unreachable("Unknown type!"); // Fall through in Release mode. case Type::IntegerTyID: - case Type::OpaqueTyID: case Type::VectorTyID: // Ty1 == Ty2 would have returned true earlier. return false; diff --git a/lib/Transforms/IPO/StripSymbols.cpp b/lib/Transforms/IPO/StripSymbols.cpp index a690765..5bacdf5 100644 --- a/lib/Transforms/IPO/StripSymbols.cpp +++ b/lib/Transforms/IPO/StripSymbols.cpp @@ -28,8 +28,8 @@ #include "llvm/Pass.h" #include "llvm/Analysis/DebugInfo.h" #include "llvm/ValueSymbolTable.h" -#include "llvm/TypeSymbolTable.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" using namespace llvm; @@ -174,13 +174,19 @@ static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) { } } -// Strip the symbol table of its names. -static void StripTypeSymtab(TypeSymbolTable &ST, bool PreserveDbgInfo) { - for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) { - if (PreserveDbgInfo && StringRef(TI->first).startswith("llvm.dbg")) - ++TI; - else - ST.remove(TI++); +// Strip any named types of their names. +static void StripTypeNames(Module &M, bool PreserveDbgInfo) { + std::vector<StructType*> StructTypes; + M.findUsedStructTypes(StructTypes); + + for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) { + StructType *STy = StructTypes[i]; + if (STy->isAnonymous() || STy->getName().empty()) continue; + + if (PreserveDbgInfo && STy->getName().startswith("llvm.dbg")) + continue; + + STy->setName(""); } } @@ -221,7 +227,7 @@ static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { } // Remove all names from types. - StripTypeSymtab(M.getTypeSymbolTable(), PreserveDbgInfo); + StripTypeNames(M, PreserveDbgInfo); return true; } diff --git a/lib/Transforms/Utils/CloneModule.cpp b/lib/Transforms/Utils/CloneModule.cpp index 1046c38..a08fa35 100644 --- a/lib/Transforms/Utils/CloneModule.cpp +++ b/lib/Transforms/Utils/CloneModule.cpp @@ -15,7 +15,6 @@ #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Module.h" #include "llvm/DerivedTypes.h" -#include "llvm/TypeSymbolTable.h" #include "llvm/Constant.h" #include "llvm/Transforms/Utils/ValueMapper.h" using namespace llvm; @@ -32,20 +31,13 @@ Module *llvm::CloneModule(const Module *M) { return CloneModule(M, VMap); } -Module *llvm::CloneModule(const Module *M, - ValueToValueMapTy &VMap) { - // First off, we need to create the new module... +Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) { + // First off, we need to create the new module. Module *New = new Module(M->getModuleIdentifier(), M->getContext()); New->setDataLayout(M->getDataLayout()); New->setTargetTriple(M->getTargetTriple()); New->setModuleInlineAsm(M->getModuleInlineAsm()); - - // Copy all of the type symbol table entries over. - const TypeSymbolTable &TST = M->getTypeSymbolTable(); - for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end(); - TI != TE; ++TI) - New->addTypeName(TI->first, TI->second); - + // Copy all of the dependent libraries over. for (Module::lib_iterator I = M->lib_begin(), E = M->lib_end(); I != E; ++I) New->addLibrary(*I); @@ -88,8 +80,7 @@ Module *llvm::CloneModule(const Module *M, I != E; ++I) { GlobalVariable *GV = cast<GlobalVariable>(VMap[I]); if (I->hasInitializer()) - GV->setInitializer(cast<Constant>(MapValue(I->getInitializer(), - VMap, RF_None))); + GV->setInitializer(MapValue(I->getInitializer(), VMap)); GV->setLinkage(I->getLinkage()); GV->setThreadLocal(I->isThreadLocal()); GV->setConstant(I->isConstant()); @@ -119,8 +110,8 @@ Module *llvm::CloneModule(const Module *M, I != E; ++I) { GlobalAlias *GA = cast<GlobalAlias>(VMap[I]); GA->setLinkage(I->getLinkage()); - if (const Constant* C = I->getAliasee()) - GA->setAliasee(cast<Constant>(MapValue(C, VMap, RF_None))); + if (const Constant *C = I->getAliasee()) + GA->setAliasee(MapValue(C, VMap)); } // And named metadata.... @@ -129,8 +120,7 @@ Module *llvm::CloneModule(const Module *M, const NamedMDNode &NMD = *I; NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName()); for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i) - NewNMD->addOperand(cast<MDNode>(MapValue(NMD.getOperand(i), VMap, - RF_None))); + NewNMD->addOperand(MapValue(NMD.getOperand(i), VMap)); } return New; diff --git a/lib/Transforms/Utils/LowerInvoke.cpp b/lib/Transforms/Utils/LowerInvoke.cpp index 025ae0d..3450316 100644 --- a/lib/Transforms/Utils/LowerInvoke.cpp +++ b/lib/Transforms/Utils/LowerInvoke.cpp @@ -66,7 +66,7 @@ namespace { Constant *AbortFn; // Used for expensive EH support. - const Type *JBLinkTy; + StructType *JBLinkTy; GlobalVariable *JBListHead; Constant *SetJmpFn, *LongJmpFn, *StackSaveFn, *StackRestoreFn; bool useExpensiveEHSupport; @@ -120,24 +120,16 @@ FunctionPass *llvm::createLowerInvokePass(const TargetLowering *TLI, // doInitialization - Make sure that there is a prototype for abort in the // current module. bool LowerInvoke::doInitialization(Module &M) { - const Type *VoidPtrTy = - Type::getInt8PtrTy(M.getContext()); + const Type *VoidPtrTy = Type::getInt8PtrTy(M.getContext()); if (useExpensiveEHSupport) { // Insert a type for the linked list of jump buffers. unsigned JBSize = TLI ? TLI->getJumpBufSize() : 0; JBSize = JBSize ? JBSize : 200; - const Type *JmpBufTy = ArrayType::get(VoidPtrTy, JBSize); - - { // The type is recursive, so use a type holder. - std::vector<const Type*> Elements; - Elements.push_back(JmpBufTy); - OpaqueType *OT = OpaqueType::get(M.getContext()); - Elements.push_back(PointerType::getUnqual(OT)); - PATypeHolder JBLType(StructType::get(M.getContext(), Elements)); - OT->refineAbstractTypeTo(JBLType.get()); // Complete the cycle. - JBLinkTy = JBLType.get(); - M.addTypeName("llvm.sjljeh.jmpbufty", JBLinkTy); - } + Type *JmpBufTy = ArrayType::get(VoidPtrTy, JBSize); + + JBLinkTy = StructType::createNamed(M.getContext(), "llvm.sjljeh.jmpbufty"); + Type *Elts[] = { JmpBufTy, PointerType::getUnqual(JBLinkTy) }; + JBLinkTy->setBody(Elts); const Type *PtrJBList = PointerType::getUnqual(JBLinkTy); diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp index de6cbdc..30fc600 100644 --- a/lib/Transforms/Utils/ValueMapper.cpp +++ b/lib/Transforms/Utils/ValueMapper.cpp @@ -13,16 +13,17 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/ValueMapper.h" -#include "llvm/Type.h" #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Metadata.h" -#include "llvm/ADT/SmallVector.h" using namespace llvm; -Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, - RemapFlags Flags) { +// Out of line method to get vtable etc for class. +void ValueMapTypeRemapper::Anchor() {} + +Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags, + ValueMapTypeRemapper *TypeMapper) { ValueToValueMapTy::iterator I = VM.find(V); // If the value already exists in the map, use it. @@ -46,14 +47,14 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, // Check all operands to see if any need to be remapped. for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) { Value *OP = MD->getOperand(i); - if (OP == 0 || MapValue(OP, VM, Flags) == OP) continue; + if (OP == 0 || MapValue(OP, VM, Flags, TypeMapper) == OP) continue; // Ok, at least one operand needs remapping. SmallVector<Value*, 4> Elts; Elts.reserve(MD->getNumOperands()); for (i = 0; i != e; ++i) { Value *Op = MD->getOperand(i); - Elts.push_back(Op ? MapValue(Op, VM, Flags) : 0); + Elts.push_back(Op ? MapValue(Op, VM, Flags, TypeMapper) : 0); } MDNode *NewMD = MDNode::get(V->getContext(), Elts); Dummy->replaceAllUsesWith(NewMD); @@ -76,51 +77,75 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, return 0; if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) { - Function *F = cast<Function>(MapValue(BA->getFunction(), VM, Flags)); + Function *F = + cast<Function>(MapValue(BA->getFunction(), VM, Flags, TypeMapper)); BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(), VM, - Flags)); + Flags, TypeMapper)); return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock()); } - for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { - Value *Op = C->getOperand(i); - Value *Mapped = MapValue(Op, VM, Flags); - if (Mapped == C) continue; - - // Okay, the operands don't all match. We've already processed some or all - // of the operands, set them up now. - std::vector<Constant*> Ops; - Ops.reserve(C->getNumOperands()); - for (unsigned j = 0; j != i; ++j) - Ops.push_back(cast<Constant>(C->getOperand(i))); + // Otherwise, we have some other constant to remap. Start by checking to see + // if all operands have an identity remapping. + unsigned OpNo = 0, NumOperands = C->getNumOperands(); + Value *Mapped = 0; + for (; OpNo != NumOperands; ++OpNo) { + Value *Op = C->getOperand(OpNo); + Mapped = MapValue(Op, VM, Flags, TypeMapper); + if (Mapped != C) break; + } + + // See if the type mapper wants to remap the type as well. + Type *NewTy = C->getType(); + if (TypeMapper) + NewTy = TypeMapper->remapType(NewTy); + + // If the result type and all operands match up, then just insert an identity + // mapping. + if (OpNo == NumOperands && NewTy == C->getType()) + return VM[V] = C; + + // Okay, we need to create a new constant. We've already processed some or + // all of the operands, set them all up now. + SmallVector<Constant*, 8> Ops; + Ops.reserve(NumOperands); + for (unsigned j = 0; j != OpNo; ++j) + Ops.push_back(cast<Constant>(C->getOperand(j))); + + // If one of the operands mismatch, push it and the other mapped operands. + if (OpNo != NumOperands) { Ops.push_back(cast<Constant>(Mapped)); - + // Map the rest of the operands that aren't processed yet. - for (++i; i != e; ++i) - Ops.push_back(cast<Constant>(MapValue(C->getOperand(i), VM, Flags))); - - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) - return VM[V] = CE->getWithOperands(Ops); - if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) - return VM[V] = ConstantArray::get(CA->getType(), Ops); - if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) - return VM[V] = ConstantStruct::get(CS->getType(), Ops); - assert(isa<ConstantVector>(C) && "Unknown mapped constant type"); - return VM[V] = ConstantVector::get(Ops); + for (++OpNo; OpNo != NumOperands; ++OpNo) + Ops.push_back(MapValue(cast<Constant>(C->getOperand(OpNo)), VM, + Flags, TypeMapper)); } - - // If we reach here, all of the operands of the constant match. - return VM[V] = C; + + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) + return VM[V] = CE->getWithOperands(Ops, NewTy); + if (isa<ConstantArray>(C)) + return VM[V] = ConstantArray::get(cast<ArrayType>(NewTy), Ops); + if (isa<ConstantStruct>(C)) + return VM[V] = ConstantStruct::get(cast<StructType>(NewTy), Ops); + if (isa<ConstantVector>(C)) + return VM[V] = ConstantVector::get(Ops); + // If this is a no-operand constant, it must be because the type was remapped. + if (isa<UndefValue>(C)) + return VM[V] = UndefValue::get(NewTy); + if (isa<ConstantAggregateZero>(C)) + return VM[V] = ConstantAggregateZero::get(NewTy); + assert(isa<ConstantPointerNull>(C)); + return VM[V] = ConstantPointerNull::get(cast<PointerType>(NewTy)); } /// RemapInstruction - Convert the instruction operands from referencing the /// current values into those specified by VMap. /// void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap, - RemapFlags Flags) { + RemapFlags Flags, ValueMapTypeRemapper *TypeMapper){ // Remap operands. for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) { - Value *V = MapValue(*op, VMap, Flags); + Value *V = MapValue(*op, VMap, Flags, TypeMapper); // If we aren't ignoring missing entries, assert that something happened. if (V != 0) *op = V; @@ -147,9 +172,13 @@ void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap, I->getAllMetadata(MDs); for (SmallVectorImpl<std::pair<unsigned, MDNode *> >::iterator MI = MDs.begin(), ME = MDs.end(); MI != ME; ++MI) { - Value *Old = MI->second; - Value *New = MapValue(Old, VMap, Flags); + MDNode *Old = MI->second; + MDNode *New = MapValue(Old, VMap, Flags, TypeMapper); if (New != Old) - I->setMetadata(MI->first, cast<MDNode>(New)); + I->setMetadata(MI->first, New); } + + // If the instruction's type is being remapped, do so now. + if (TypeMapper) + I->mutateType(TypeMapper->remapType(I->getType())); } diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 496f500..18776dd 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -26,8 +26,7 @@ #include "llvm/Operator.h" #include "llvm/Module.h" #include "llvm/ValueSymbolTable.h" -#include "llvm/TypeSymbolTable.h" -#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" @@ -137,72 +136,57 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) { /// TypePrinting - Type printing machinery. namespace { class TypePrinting { - DenseMap<const Type *, std::string> TypeNames; TypePrinting(const TypePrinting &); // DO NOT IMPLEMENT void operator=(const TypePrinting&); // DO NOT IMPLEMENT public: - TypePrinting() {} - ~TypePrinting() {} - - void clear() { - TypeNames.clear(); - } - - void print(const Type *Ty, raw_ostream &OS, bool IgnoreTopLevelName = false); + + /// NamedTypes - The named types that are used by the current module. + std::vector<StructType*> NamedTypes; - void printAtLeastOneLevel(const Type *Ty, raw_ostream &OS) { - print(Ty, OS, true); - } + /// NumberedTypes - The numbered types, along with their value. + DenseMap<StructType*, unsigned> NumberedTypes; - /// hasTypeName - Return true if the type has a name in TypeNames, false - /// otherwise. - bool hasTypeName(const Type *Ty) const { - return TypeNames.count(Ty); - } + TypePrinting() {} + ~TypePrinting() {} - /// addTypeName - Add a name for the specified type if it doesn't already have - /// one. This name will be printed instead of the structural version of the - /// type in order to make the output more concise. - void addTypeName(const Type *Ty, const std::string &N) { - TypeNames.insert(std::make_pair(Ty, N)); - } + void incorporateTypes(const Module &M); -private: - void CalcTypeName(const Type *Ty, SmallVectorImpl<const Type *> &TypeStack, - raw_ostream &OS, bool IgnoreTopLevelName = false); + void print(Type *Ty, raw_ostream &OS); + + void printStructBody(StructType *Ty, raw_ostream &OS); }; } // end anonymous namespace. -/// CalcTypeName - Write the specified type to the specified raw_ostream, making -/// use of type names or up references to shorten the type name where possible. -void TypePrinting::CalcTypeName(const Type *Ty, - SmallVectorImpl<const Type *> &TypeStack, - raw_ostream &OS, bool IgnoreTopLevelName) { - // Check to see if the type is named. - if (!IgnoreTopLevelName) { - DenseMap<const Type *, std::string> &TM = TypeNames; - DenseMap<const Type *, std::string>::iterator I = TM.find(Ty); - if (I != TM.end()) { - OS << I->second; - return; - } - } - - // Check to see if the Type is already on the stack... - unsigned Slot = 0, CurSize = TypeStack.size(); - while (Slot < CurSize && TypeStack[Slot] != Ty) ++Slot; // Scan for type - // This is another base case for the recursion. In this case, we know - // that we have looped back to a type that we have previously visited. - // Generate the appropriate upreference to handle this. - if (Slot < CurSize) { - OS << '\\' << unsigned(CurSize-Slot); // Here's the upreference - return; +void TypePrinting::incorporateTypes(const Module &M) { + M.findUsedStructTypes(NamedTypes); + + // The list of struct types we got back includes all the struct types, split + // the unnamed ones out to a numbering and remove the anonymous structs. + unsigned NextNumber = 0; + + std::vector<StructType*>::iterator NextToUse = NamedTypes.begin(), I, E; + for (I = NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I) { + StructType *STy = *I; + + // Ignore anonymous types. + if (STy->isAnonymous()) + continue; + + if (STy->getName().empty()) + NumberedTypes[STy] = NextNumber++; + else + *NextToUse++ = STy; } + + NamedTypes.erase(NextToUse, NamedTypes.end()); +} - TypeStack.push_back(Ty); // Recursive case: Add us to the stack.. +/// CalcTypeName - Write the specified type to the specified raw_ostream, making +/// use of type names or up references to shorten the type name where possible. +void TypePrinting::print(Type *Ty, raw_ostream &OS) { switch (Ty->getTypeID()) { case Type::VoidTyID: OS << "void"; break; case Type::FloatTyID: OS << "float"; break; @@ -215,257 +199,100 @@ void TypePrinting::CalcTypeName(const Type *Ty, case Type::X86_MMXTyID: OS << "x86_mmx"; break; case Type::IntegerTyID: OS << 'i' << cast<IntegerType>(Ty)->getBitWidth(); - break; + return; case Type::FunctionTyID: { - const FunctionType *FTy = cast<FunctionType>(Ty); - CalcTypeName(FTy->getReturnType(), TypeStack, OS); + FunctionType *FTy = cast<FunctionType>(Ty); + print(FTy->getReturnType(), OS); OS << " ("; for (FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); I != E; ++I) { if (I != FTy->param_begin()) OS << ", "; - CalcTypeName(*I, TypeStack, OS); + print(*I, OS); } if (FTy->isVarArg()) { if (FTy->getNumParams()) OS << ", "; OS << "..."; } OS << ')'; - break; + return; } case Type::StructTyID: { - const StructType *STy = cast<StructType>(Ty); - if (STy->isPacked()) - OS << '<'; - OS << '{'; - for (StructType::element_iterator I = STy->element_begin(), - E = STy->element_end(); I != E; ++I) { - OS << ' '; - CalcTypeName(*I, TypeStack, OS); - if (llvm::next(I) == STy->element_end()) - OS << ' '; - else - OS << ','; - } - OS << '}'; - if (STy->isPacked()) - OS << '>'; - break; + StructType *STy = cast<StructType>(Ty); + + if (STy->isAnonymous()) + return printStructBody(STy, OS); + + if (!STy->getName().empty()) + return PrintLLVMName(OS, STy->getName(), LocalPrefix); + + DenseMap<StructType*, unsigned>::iterator I = NumberedTypes.find(STy); + if (I != NumberedTypes.end()) + OS << '%' << I->second; + else // Not enumerated, print the hex address. + OS << "%\"type 0x" << STy << '\"'; + return; } case Type::PointerTyID: { - const PointerType *PTy = cast<PointerType>(Ty); - CalcTypeName(PTy->getElementType(), TypeStack, OS); + PointerType *PTy = cast<PointerType>(Ty); + print(PTy->getElementType(), OS); if (unsigned AddressSpace = PTy->getAddressSpace()) OS << " addrspace(" << AddressSpace << ')'; OS << '*'; - break; + return; } case Type::ArrayTyID: { - const ArrayType *ATy = cast<ArrayType>(Ty); + ArrayType *ATy = cast<ArrayType>(Ty); OS << '[' << ATy->getNumElements() << " x "; - CalcTypeName(ATy->getElementType(), TypeStack, OS); + print(ATy->getElementType(), OS); OS << ']'; - break; + return; } case Type::VectorTyID: { - const VectorType *PTy = cast<VectorType>(Ty); + VectorType *PTy = cast<VectorType>(Ty); OS << "<" << PTy->getNumElements() << " x "; - CalcTypeName(PTy->getElementType(), TypeStack, OS); + print(PTy->getElementType(), OS); OS << '>'; - break; + return; } - case Type::OpaqueTyID: - OS << "opaque"; - break; default: OS << "<unrecognized-type>"; - break; + return; } - - TypeStack.pop_back(); // Remove self from stack. } -/// printTypeInt - The internal guts of printing out a type that has a -/// potentially named portion. -/// -void TypePrinting::print(const Type *Ty, raw_ostream &OS, - bool IgnoreTopLevelName) { - // Check to see if the type is named. - if (!IgnoreTopLevelName) { - DenseMap<const Type*, std::string>::iterator I = TypeNames.find(Ty); - if (I != TypeNames.end()) { - OS << I->second; - return; - } +void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) { + if (STy->isOpaque()) { + OS << "opaque"; + return; } - - // Otherwise we have a type that has not been named but is a derived type. - // Carefully recurse the type hierarchy to print out any contained symbolic - // names. - SmallVector<const Type *, 16> TypeStack; - std::string TypeName; - - raw_string_ostream TypeOS(TypeName); - CalcTypeName(Ty, TypeStack, TypeOS, IgnoreTopLevelName); - OS << TypeOS.str(); - - // Cache type name for later use. - if (!IgnoreTopLevelName) - TypeNames.insert(std::make_pair(Ty, TypeOS.str())); -} - -namespace { - class TypeFinder { - // To avoid walking constant expressions multiple times and other IR - // objects, we keep several helper maps. - DenseSet<const Value*> VisitedConstants; - DenseSet<const Type*> VisitedTypes; - - TypePrinting &TP; - std::vector<const Type*> &NumberedTypes; - public: - TypeFinder(TypePrinting &tp, std::vector<const Type*> &numberedTypes) - : TP(tp), NumberedTypes(numberedTypes) {} - - void Run(const Module &M) { - // Get types from the type symbol table. This gets opaque types referened - // only through derived named types. - const TypeSymbolTable &ST = M.getTypeSymbolTable(); - for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end(); - TI != E; ++TI) - IncorporateType(TI->second); - - // 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()); - IncorporateValue(I->getAliasee()); - } - - // 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); - } - } - } - - private: - void IncorporateType(const 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 (((Ty->isStructTy() && cast<StructType>(Ty)->getNumElements()) - || Ty->isOpaqueTy()) && !TP.hasTypeName(Ty)) { - TP.addTypeName(Ty, "%"+utostr(unsigned(NumberedTypes.size()))); - NumberedTypes.push_back(Ty); - } - - // 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 (V == 0 || !isa<Constant>(V) || isa<GlobalValue>(V)) return; - - // Already visited? - if (!VisitedConstants.insert(V).second) - return; - - // Check this type. - IncorporateType(V->getType()); - - // Look in operands for types. - const Constant *C = cast<Constant>(V); - for (Constant::const_op_iterator I = C->op_begin(), - E = C->op_end(); I != E;++I) - IncorporateValue(*I); - } - }; -} // end anonymous namespace - - -/// AddModuleTypesToPrinter - Add all of the symbolic type names for types in -/// the specified module to the TypePrinter and all numbered types to it and the -/// NumberedTypes table. -static void AddModuleTypesToPrinter(TypePrinting &TP, - std::vector<const Type*> &NumberedTypes, - const Module *M) { - if (M == 0) return; - - // If the module has a symbol table, take all global types and stuff their - // names into the TypeNames map. - const TypeSymbolTable &ST = M->getTypeSymbolTable(); - for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end(); - TI != E; ++TI) { - const Type *Ty = cast<Type>(TI->second); - - // As a heuristic, don't insert pointer to primitive types, because - // they are used too often to have a single useful name. - if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) { - const Type *PETy = PTy->getElementType(); - if ((PETy->isPrimitiveType() || PETy->isIntegerTy()) && - !PETy->isOpaqueTy()) - continue; + + if (STy->isPacked()) + OS << '<'; + + if (STy->getNumElements() == 0) { + OS << "{}"; + } else { + StructType::element_iterator I = STy->element_begin(); + OS << "{ "; + print(*I++, OS); + for (StructType::element_iterator E = STy->element_end(); I != E; ++I) { + OS << ", "; + print(*I, OS); } - - // Likewise don't insert primitives either. - if (Ty->isIntegerTy() || Ty->isPrimitiveType()) - continue; - - // Get the name as a string and insert it into TypeNames. - std::string NameStr; - raw_string_ostream NameROS(NameStr); - formatted_raw_ostream NameOS(NameROS); - PrintLLVMName(NameOS, TI->first, LocalPrefix); - NameOS.flush(); - TP.addTypeName(Ty, NameStr); + + OS << " }"; } - - // Walk the entire module to find references to unnamed structure and opaque - // types. This is required for correctness by opaque types (because multiple - // uses of an unnamed opaque type needs to be referred to by the same ID) and - // it shrinks complex recursive structure types substantially in some cases. - TypeFinder(TP, NumberedTypes).Run(*M); + if (STy->isPacked()) + OS << '>'; } -/// WriteTypeSymbolic - This attempts to write the specified type as a symbolic -/// type, iff there is an entry in the modules symbol table for the specified -/// type or one of it's component types. -/// + void llvm::WriteTypeSymbolic(raw_ostream &OS, const Type *Ty, const Module *M) { - TypePrinting Printer; - std::vector<const Type*> NumberedTypes; - AddModuleTypesToPrinter(Printer, NumberedTypes, M); - Printer.print(Ty, OS); + // FIXME: remove this function. + OS << *Ty; } //===----------------------------------------------------------------------===// @@ -986,7 +813,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, // As a special case, print the array as a string if it is an array of // i8 with ConstantInt values. // - const Type *ETy = CA->getType()->getElementType(); + Type *ETy = CA->getType()->getElementType(); if (CA->isString()) { Out << "c\""; PrintEscapedString(CA->getAsString(), Out); @@ -1043,7 +870,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, } if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) { - const Type *ETy = CP->getType()->getElementType(); + Type *ETy = CP->getType()->getElementType(); assert(CP->getNumOperands() > 0 && "Number of operands for a PackedConst must be > 0"); Out << '<'; @@ -1241,8 +1068,8 @@ void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, if (Context == 0) Context = getModuleFromVal(V); TypePrinting TypePrinter; - std::vector<const Type*> NumberedTypes; - AddModuleTypesToPrinter(TypePrinter, NumberedTypes, Context); + if (Context) + TypePrinter.incorporateTypes(*Context); if (PrintType) { TypePrinter.print(V->getType(), Out); Out << ' '; @@ -1259,14 +1086,14 @@ class AssemblyWriter { const Module *TheModule; TypePrinting TypePrinter; AssemblyAnnotationWriter *AnnotationWriter; - std::vector<const Type*> NumberedTypes; public: inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M, AssemblyAnnotationWriter *AAW) : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { - AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M); + if (M) + TypePrinter.incorporateTypes(*M); } void printMDNodeBody(const MDNode *MD); @@ -1279,7 +1106,7 @@ public: void writeAllMDNodes(); - void printTypeSymbolTable(const TypeSymbolTable &ST); + void printTypeIdentities(); void printGlobal(const GlobalVariable *GV); void printAlias(const GlobalAlias *GV); void printFunction(const Function *F); @@ -1374,9 +1201,7 @@ void AssemblyWriter::printModule(const Module *M) { Out << " ]"; } - // Loop over the symbol table, emitting all id'd types. - if (!M->getTypeSymbolTable().empty() || !NumberedTypes.empty()) Out << '\n'; - printTypeSymbolTable(M->getTypeSymbolTable()); + printTypeIdentities(); // Output all globals. if (!M->global_empty()) Out << '\n'; @@ -1534,7 +1359,10 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { const Constant *Aliasee = GA->getAliasee(); - if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) { + if (Aliasee == 0) { + TypePrinter.print(GA->getType(), Out); + Out << " <<NULL ALIASEE>>"; + } else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) { TypePrinter.print(GV->getType(), Out); Out << ' '; PrintLLVMName(Out, GV); @@ -1560,26 +1388,40 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { Out << '\n'; } -void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) { +void AssemblyWriter::printTypeIdentities() { + if (TypePrinter.NumberedTypes.empty() && + TypePrinter.NamedTypes.empty()) + return; + + Out << '\n'; + + // We know all the numbers that each type is used and we know that it is a + // dense assignment. Convert the map to an index table. + std::vector<StructType*> NumberedTypes(TypePrinter.NumberedTypes.size()); + for (DenseMap<StructType*, unsigned>::iterator I = + TypePrinter.NumberedTypes.begin(), E = TypePrinter.NumberedTypes.end(); + I != E; ++I) { + assert(I->second < NumberedTypes.size() && "Didn't get a dense numbering?"); + NumberedTypes[I->second] = I->first; + } + // Emit all numbered types. for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) { Out << '%' << i << " = type "; - + // Make sure we print out at least one level of the type structure, so // that we do not get %2 = type %2 - TypePrinter.printAtLeastOneLevel(NumberedTypes[i], Out); + TypePrinter.printStructBody(NumberedTypes[i], Out); Out << '\n'; } - - // Print the named types. - for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end(); - TI != TE; ++TI) { - PrintLLVMName(Out, TI->first, LocalPrefix); + + for (unsigned i = 0, e = TypePrinter.NamedTypes.size(); i != e; ++i) { + PrintLLVMName(Out, TypePrinter.NamedTypes[i]->getName(), LocalPrefix); Out << " = type "; // Make sure we print out at least one level of the type structure, so // that we do not get %FILE = type %FILE - TypePrinter.printAtLeastOneLevel(TI->second, Out); + TypePrinter.printStructBody(TypePrinter.NamedTypes[i], Out); Out << '\n'; } } @@ -1893,9 +1735,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } Operand = CI->getCalledValue(); - const PointerType *PTy = cast<PointerType>(Operand->getType()); - const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); - const Type *RetTy = FTy->getReturnType(); + PointerType *PTy = cast<PointerType>(Operand->getType()); + FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); + Type *RetTy = FTy->getReturnType(); const AttrListPtr &PAL = CI->getAttributes(); if (PAL.getRetAttributes() != Attribute::None) @@ -1926,9 +1768,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << ' ' << Attribute::getAsString(PAL.getFnAttributes()); } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) { Operand = II->getCalledValue(); - const PointerType *PTy = cast<PointerType>(Operand->getType()); - const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); - const Type *RetTy = FTy->getReturnType(); + PointerType *PTy = cast<PointerType>(Operand->getType()); + FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); + Type *RetTy = FTy->getReturnType(); const AttrListPtr &PAL = II->getAttributes(); // Print the calling convention being used. @@ -2011,7 +1853,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // omit the type from all but the first operand. If the instruction has // different type operands (for example br), then they are all printed. bool PrintAllTypes = false; - const Type *TheType = Operand->getType(); + Type *TheType = Operand->getType(); // Select, Store and ShuffleVector always print all types. if (isa<SelectInst>(I) || isa<StoreInst>(I) || isa<ShuffleVectorInst>(I) @@ -2131,7 +1973,15 @@ void Type::print(raw_ostream &OS) const { OS << "<null Type>"; return; } - TypePrinting().print(this, OS); + TypePrinting TP; + TP.print(const_cast<Type*>(this), OS); + + // If the type is a named struct type, print the body as well. + if (StructType *STy = dyn_cast<StructType>(const_cast<Type*>(this))) + if (!STy->isAnonymous()) { + OS << " = type "; + TP.printStructBody(STy, OS); + } } void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { @@ -2187,14 +2037,7 @@ void Value::printCustom(raw_ostream &OS) const { void Value::dump() const { print(dbgs()); dbgs() << '\n'; } // Type::dump - allow easy printing of Types from the debugger. -// This one uses type names from the given context module -void Type::dump(const Module *Context) const { - WriteTypeSymbolic(dbgs(), this, Context); - dbgs() << '\n'; -} - -// Type::dump - allow easy printing of Types from the debugger. -void Type::dump() const { dump(0); } +void Type::dump() const { print(dbgs()); } // Module::dump() - Allow printing of Modules from the debugger. void Module::dump() const { print(dbgs(), 0); } diff --git a/lib/VMCore/CMakeLists.txt b/lib/VMCore/CMakeLists.txt index 6bde263..f60dd06 100644 --- a/lib/VMCore/CMakeLists.txt +++ b/lib/VMCore/CMakeLists.txt @@ -29,7 +29,6 @@ add_llvm_library(LLVMCore PassRegistry.cpp PrintModulePass.cpp Type.cpp - TypeSymbolTable.cpp Use.cpp User.cpp Value.cpp diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index b7a1350..2c8f430 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -1466,8 +1466,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, /// isZeroSizedType - This type is zero sized if its an array or structure of /// zero sized types. The only leaf zero sized type is an empty structure. static bool isMaybeZeroSizedType(const Type *Ty) { - if (Ty->isOpaqueTy()) return true; // Can't say. if (const StructType *STy = dyn_cast<StructType>(Ty)) { + if (STy->isOpaque()) return true; // Can't say. // If all of elements have zero size, this does too. for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 4e6e64d..d3361cc 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -31,6 +31,7 @@ #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include <algorithm> #include <cstdarg> using namespace llvm; @@ -639,13 +640,13 @@ ConstantStruct::ConstantStruct(const StructType *T, : Constant(T, ConstantStructVal, OperandTraits<ConstantStruct>::op_end(this) - V.size(), V.size()) { - assert(V.size() == T->getNumElements() && + assert((T->isOpaque() || V.size() == T->getNumElements()) && "Invalid initializer vector for constant structure"); Use *OL = OperandList; for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end(); I != E; ++I, ++OL) { Constant *C = *I; - assert(C->getType() == T->getElementType(I-V.begin()) && + assert((T->isOpaque() || C->getType() == T->getElementType(I-V.begin())) && "Initializer for struct element doesn't match struct element type!"); *OL = C; } @@ -653,14 +654,13 @@ ConstantStruct::ConstantStruct(const StructType *T, // ConstantStruct accessors. Constant *ConstantStruct::get(const StructType *ST, ArrayRef<Constant*> V) { - assert(ST->getNumElements() == V.size() && - "Incorrect # elements specified to ConstantStruct::get"); - // Create a ConstantAggregateZero value if all elements are zeros. for (unsigned i = 0, e = V.size(); i != e; ++i) if (!V[i]->isNullValue()) return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V); + assert((ST->isOpaque() || ST->getNumElements() == V.size()) && + "Incorrect # elements specified to ConstantStruct::get"); return ConstantAggregateZero::get(ST); } @@ -839,17 +839,15 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { } /// getWithOperands - This returns the current constant expression with the -/// operands replaced with the specified values. The specified operands must -/// match count and type with the existing ones. +/// operands replaced with the specified values. The specified array must +/// have the same number of operands as our current one. Constant *ConstantExpr:: -getWithOperands(ArrayRef<Constant*> Ops) const { +getWithOperands(ArrayRef<Constant*> Ops, const Type *Ty) const { assert(Ops.size() == getNumOperands() && "Operand count mismatch!"); - bool AnyChange = false; - for (unsigned i = 0; i != Ops.size(); ++i) { - assert(Ops[i]->getType() == getOperand(i)->getType() && - "Operand type mismatch!"); + bool AnyChange = Ty != getType(); + for (unsigned i = 0; i != Ops.size(); ++i) AnyChange |= Ops[i] != getOperand(i); - } + if (!AnyChange) // No operands changed, return self. return const_cast<ConstantExpr*>(this); @@ -866,7 +864,7 @@ getWithOperands(ArrayRef<Constant*> Ops) const { case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: - return ConstantExpr::getCast(getOpcode(), Ops[0], getType()); + return ConstantExpr::getCast(getOpcode(), Ops[0], Ty); case Instruction::Select: return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]); case Instruction::InsertElement: @@ -964,14 +962,14 @@ ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) { /// destroyConstant - Remove the constant from the constant table... /// void ConstantAggregateZero::destroyConstant() { - getRawType()->getContext().pImpl->AggZeroConstants.remove(this); + getType()->getContext().pImpl->AggZeroConstants.remove(this); destroyConstantImpl(); } /// destroyConstant - Remove the constant from the constant table... /// void ConstantArray::destroyConstant() { - getRawType()->getContext().pImpl->ArrayConstants.remove(this); + getType()->getContext().pImpl->ArrayConstants.remove(this); destroyConstantImpl(); } @@ -1050,14 +1048,14 @@ namespace llvm { // destroyConstant - Remove the constant from the constant table... // void ConstantStruct::destroyConstant() { - getRawType()->getContext().pImpl->StructConstants.remove(this); + getType()->getContext().pImpl->StructConstants.remove(this); destroyConstantImpl(); } // destroyConstant - Remove the constant from the constant table... // void ConstantVector::destroyConstant() { - getRawType()->getContext().pImpl->VectorConstants.remove(this); + getType()->getContext().pImpl->VectorConstants.remove(this); destroyConstantImpl(); } @@ -1098,7 +1096,7 @@ ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) { // destroyConstant - Remove the constant from the constant table... // void ConstantPointerNull::destroyConstant() { - getRawType()->getContext().pImpl->NullPtrConstants.remove(this); + getType()->getContext().pImpl->NullPtrConstants.remove(this); destroyConstantImpl(); } @@ -1113,7 +1111,7 @@ UndefValue *UndefValue::get(const Type *Ty) { // destroyConstant - Remove the constant from the constant table. // void UndefValue::destroyConstant() { - getRawType()->getContext().pImpl->UndefValueConstants.remove(this); + getType()->getContext().pImpl->UndefValueConstants.remove(this); destroyConstantImpl(); } @@ -1147,7 +1145,7 @@ BlockAddress::BlockAddress(Function *F, BasicBlock *BB) // destroyConstant - Remove the constant from the constant table. // void BlockAddress::destroyConstant() { - getFunction()->getRawType()->getContext().pImpl + getFunction()->getType()->getContext().pImpl ->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock())); getBasicBlock()->AdjustBlockAddressRefCount(-1); destroyConstantImpl(); @@ -1921,7 +1919,7 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) { // destroyConstant - Remove the constant from the constant table... // void ConstantExpr::destroyConstant() { - getRawType()->getContext().pImpl->ExprConstants.remove(this); + getType()->getContext().pImpl->ExprConstants.remove(this); destroyConstantImpl(); } @@ -1962,10 +1960,10 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast<Constant>(To); - LLVMContextImpl *pImpl = getRawType()->getContext().pImpl; + LLVMContextImpl *pImpl = getType()->getContext().pImpl; std::pair<LLVMContextImpl::ArrayConstantsTy::MapKey, ConstantArray*> Lookup; - Lookup.first.first = cast<ArrayType>(getRawType()); + Lookup.first.first = cast<ArrayType>(getType()); Lookup.second = this; std::vector<Constant*> &Values = Lookup.first.second; @@ -1999,7 +1997,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, Constant *Replacement = 0; if (isAllZeros) { - Replacement = ConstantAggregateZero::get(getRawType()); + Replacement = ConstantAggregateZero::get(getType()); } else { // Check to see if we have this array type already. bool Exists; @@ -2050,7 +2048,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!"); std::pair<LLVMContextImpl::StructConstantsTy::MapKey, ConstantStruct*> Lookup; - Lookup.first.first = cast<StructType>(getRawType()); + Lookup.first.first = cast<StructType>(getType()); Lookup.second = this; std::vector<Constant*> &Values = Lookup.first.second; Values.reserve(getNumOperands()); // Build replacement struct. @@ -2072,11 +2070,11 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, } Values[OperandToUpdate] = ToC; - LLVMContextImpl *pImpl = getRawType()->getContext().pImpl; + LLVMContextImpl *pImpl = getContext().pImpl; Constant *Replacement = 0; if (isAllZeros) { - Replacement = ConstantAggregateZero::get(getRawType()); + Replacement = ConstantAggregateZero::get(getType()); } else { // Check to see if we have this struct type already. bool Exists; @@ -2167,7 +2165,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, &Indices[0], Indices.size()); } else if (isCast()) { assert(getOperand(0) == From && "Cast only has one use!"); - Replacement = ConstantExpr::getCast(getOpcode(), To, getRawType()); + Replacement = ConstantExpr::getCast(getOpcode(), To, getType()); } else if (getOpcode() == Instruction::Select) { Constant *C1 = getOperand(0); Constant *C2 = getOperand(1); diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h index ea6ebe9..bd134d9 100644 --- a/lib/VMCore/ConstantsContext.h +++ b/lib/VMCore/ConstantsContext.h @@ -570,13 +570,11 @@ struct ConstantKeyData<InlineAsm> { template<class ValType, class ValRefType, class TypeClass, class ConstantClass, bool HasLargeKey = false /*true for arrays and structs*/ > -class ConstantUniqueMap : public AbstractTypeUser { +class ConstantUniqueMap { public: typedef std::pair<const TypeClass*, ValType> MapKey; typedef std::map<MapKey, ConstantClass *> MapTy; typedef std::map<ConstantClass *, typename MapTy::iterator> InverseMapTy; - typedef std::map<const DerivedType*, typename MapTy::iterator> - AbstractTypeMapTy; private: /// Map - This is the main map from the element descriptor to the Constants. /// This is the primary way we avoid creating two of the same shape @@ -589,10 +587,6 @@ private: /// through the map with very large keys. InverseMapTy InverseMap; - /// AbstractTypeMap - Map for abstract type constants. - /// - AbstractTypeMapTy AbstractTypeMap; - public: typename MapTy::iterator map_begin() { return Map.begin(); } typename MapTy::iterator map_end() { return Map.end(); } @@ -629,7 +623,7 @@ private: } typename MapTy::iterator I = - Map.find(MapKey(static_cast<const TypeClass*>(CP->getRawType()), + Map.find(MapKey(static_cast<const TypeClass*>(CP->getType()), ConstantKeyData<ConstantClass>::getValType(CP))); if (I == Map.end() || I->second != CP) { // FIXME: This should not use a linear scan. If this gets to be a @@ -639,24 +633,8 @@ private: } return I; } - - void AddAbstractTypeUser(const Type *Ty, typename MapTy::iterator I) { - // If the type of the constant is abstract, make sure that an entry - // exists for it in the AbstractTypeMap. - if (Ty->isAbstract()) { - const DerivedType *DTy = static_cast<const DerivedType *>(Ty); - typename AbstractTypeMapTy::iterator TI = AbstractTypeMap.find(DTy); - - if (TI == AbstractTypeMap.end()) { - // Add ourselves to the ATU list of the type. - cast<DerivedType>(DTy)->addAbstractTypeUser(this); - - AbstractTypeMap.insert(TI, std::make_pair(DTy, I)); - } - } - } - ConstantClass* Create(const TypeClass *Ty, ValRefType V, + ConstantClass *Create(const TypeClass *Ty, ValRefType V, typename MapTy::iterator I) { ConstantClass* Result = ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V); @@ -667,8 +645,6 @@ private: if (HasLargeKey) // Remember the reverse mapping if needed. InverseMap.insert(std::make_pair(Result, I)); - AddAbstractTypeUser(Ty, I); - return Result; } public: @@ -692,43 +668,6 @@ public: return Result; } - void UpdateAbstractTypeMap(const DerivedType *Ty, - typename MapTy::iterator I) { - assert(AbstractTypeMap.count(Ty) && - "Abstract type not in AbstractTypeMap?"); - typename MapTy::iterator &ATMEntryIt = AbstractTypeMap[Ty]; - if (ATMEntryIt == I) { - // Yes, we are removing the representative entry for this type. - // See if there are any other entries of the same type. - typename MapTy::iterator TmpIt = ATMEntryIt; - - // First check the entry before this one... - if (TmpIt != Map.begin()) { - --TmpIt; - if (TmpIt->first.first != Ty) // Not the same type, move back... - ++TmpIt; - } - - // If we didn't find the same type, try to move forward... - if (TmpIt == ATMEntryIt) { - ++TmpIt; - if (TmpIt == Map.end() || TmpIt->first.first != Ty) - --TmpIt; // No entry afterwards with the same type - } - - // If there is another entry in the map of the same abstract type, - // update the AbstractTypeMap entry now. - if (TmpIt != ATMEntryIt) { - ATMEntryIt = TmpIt; - } else { - // Otherwise, we are removing the last instance of this type - // from the table. Remove from the ATM, and from user list. - cast<DerivedType>(Ty)->removeAbstractTypeUser(this); - AbstractTypeMap.erase(Ty); - } - } - } - void remove(ConstantClass *CP) { typename MapTy::iterator I = FindExistingElement(CP); assert(I != Map.end() && "Constant not found in constant table!"); @@ -736,12 +675,6 @@ public: if (HasLargeKey) // Remember the reverse mapping if needed. InverseMap.erase(CP); - - // Now that we found the entry, make sure this isn't the entry that - // the AbstractTypeMap points to. - const TypeClass *Ty = I->first.first; - if (Ty->isAbstract()) - UpdateAbstractTypeMap(static_cast<const DerivedType *>(Ty), I); Map.erase(I); } @@ -755,22 +688,7 @@ public: assert(OldI != Map.end() && "Constant not found in constant table!"); assert(OldI->second == C && "Didn't find correct element?"); - // If this constant is the representative element for its abstract type, - // update the AbstractTypeMap so that the representative element is I. - // - // This must use getRawType() because if the type is under refinement, we - // will get the refineAbstractType callback below, and we don't want to - // kick union find in on the constant. - if (C->getRawType()->isAbstract()) { - typename AbstractTypeMapTy::iterator ATI = - AbstractTypeMap.find(cast<DerivedType>(C->getRawType())); - assert(ATI != AbstractTypeMap.end() && - "Abstract type not in AbstractTypeMap?"); - if (ATI->second == OldI) - ATI->second = I; - } - - // Remove the old entry from the map. + // Remove the old entry from the map. Map.erase(OldI); // Update the inverse map so that we know that this constant is now @@ -780,58 +698,6 @@ public: InverseMap[C] = I; } } - - void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { - typename AbstractTypeMapTy::iterator I = AbstractTypeMap.find(OldTy); - - assert(I != AbstractTypeMap.end() && - "Abstract type not in AbstractTypeMap?"); - - // Convert a constant at a time until the last one is gone. The last one - // leaving will remove() itself, causing the AbstractTypeMapEntry to be - // eliminated eventually. - do { - ConstantClass *C = I->second->second; - MapKey Key(cast<TypeClass>(NewTy), - ConstantKeyData<ConstantClass>::getValType(C)); - - std::pair<typename MapTy::iterator, bool> IP = - Map.insert(std::make_pair(Key, C)); - if (IP.second) { - // The map didn't previously have an appropriate constant in the - // new type. - - // Remove the old entry. - typename MapTy::iterator OldI = - Map.find(MapKey(cast<TypeClass>(OldTy), IP.first->first.second)); - assert(OldI != Map.end() && "Constant not in map!"); - UpdateAbstractTypeMap(OldTy, OldI); - Map.erase(OldI); - - // Set the constant's type. This is done in place! - setType(C, NewTy); - - // Update the inverse map so that we know that this constant is now - // located at descriptor I. - if (HasLargeKey) - InverseMap[C] = IP.first; - - AddAbstractTypeUser(NewTy, IP.first); - } else { - // The map already had an appropriate constant in the new type, so - // there's no longer a need for the old constant. - C->uncheckedReplaceAllUsesWith(IP.first->second); - C->destroyConstant(); // This constant is now dead, destroy it. - } - I = AbstractTypeMap.find(OldTy); - } while (I != AbstractTypeMap.end()); - } - - // If the type became concrete without being refined to any other existing - // type, we just remove ourselves from the ATU list. - void typeBecameConcrete(const DerivedType *AbsTy) { - AbsTy->removeAbstractTypeUser(this); - } void dump() const { DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index bdd988e..d9ced94 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -19,7 +19,6 @@ #include "llvm/GlobalVariable.h" #include "llvm/GlobalAlias.h" #include "llvm/LLVMContext.h" -#include "llvm/TypeSymbolTable.h" #include "llvm/InlineAsm.h" #include "llvm/IntrinsicInst.h" #include "llvm/PassManager.h" @@ -111,27 +110,6 @@ void LLVMSetTarget(LLVMModuleRef M, const char *Triple) { unwrap(M)->setTargetTriple(Triple); } -/*--.. Type names ..........................................................--*/ -LLVMBool LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty) { - return unwrap(M)->addTypeName(Name, unwrap(Ty)); -} - -void LLVMDeleteTypeName(LLVMModuleRef M, const char *Name) { - TypeSymbolTable &TST = unwrap(M)->getTypeSymbolTable(); - - TypeSymbolTable::iterator I = TST.find(Name); - if (I != TST.end()) - TST.remove(I); -} - -LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name) { - return wrap(unwrap(M)->getTypeByName(Name)); -} - -const char *LLVMGetTypeName(LLVMModuleRef M, LLVMTypeRef Ty) { - return unwrap(M)->getTypeName(unwrap(Ty)).c_str(); -} - void LLVMDumpModule(LLVMModuleRef M) { unwrap(M)->dump(); } @@ -182,8 +160,6 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { return LLVMArrayTypeKind; case Type::PointerTyID: return LLVMPointerTypeKind; - case Type::OpaqueTyID: - return LLVMOpaqueTypeKind; case Type::VectorTyID: return LLVMVectorTypeKind; case Type::X86_MMXTyID: @@ -382,9 +358,6 @@ LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C) { LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C) { return wrap(Type::getLabelTy(*unwrap(C))); } -LLVMTypeRef LLVMOpaqueTypeInContext(LLVMContextRef C) { - return wrap(OpaqueType::get(*unwrap(C))); -} LLVMTypeRef LLVMVoidType(void) { return LLVMVoidTypeInContext(LLVMGetGlobalContext()); @@ -392,28 +365,6 @@ LLVMTypeRef LLVMVoidType(void) { LLVMTypeRef LLVMLabelType(void) { return LLVMLabelTypeInContext(LLVMGetGlobalContext()); } -LLVMTypeRef LLVMOpaqueType(void) { - return LLVMOpaqueTypeInContext(LLVMGetGlobalContext()); -} - -/*--.. Operations on type handles ..........................................--*/ - -LLVMTypeHandleRef LLVMCreateTypeHandle(LLVMTypeRef PotentiallyAbstractTy) { - return wrap(new PATypeHolder(unwrap(PotentiallyAbstractTy))); -} - -void LLVMDisposeTypeHandle(LLVMTypeHandleRef TypeHandle) { - delete unwrap(TypeHandle); -} - -LLVMTypeRef LLVMResolveTypeHandle(LLVMTypeHandleRef TypeHandle) { - return wrap(unwrap(TypeHandle)->get()); -} - -void LLVMRefineType(LLVMTypeRef AbstractTy, LLVMTypeRef ConcreteTy) { - unwrap<DerivedType>(AbstractTy)->refineAbstractTypeTo(unwrap(ConcreteTy)); -} - /*===-- Operations on values ----------------------------------------------===*/ diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index b8fa60a..972319e 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -134,7 +134,7 @@ LLVMContext &Function::getContext() const { return getType()->getContext(); } -const FunctionType *Function::getFunctionType() const { +FunctionType *Function::getFunctionType() const { return cast<FunctionType>(getType()->getElementType()); } @@ -142,7 +142,7 @@ bool Function::isVarArg() const { return getFunctionType()->isVarArg(); } -const Type *Function::getReturnType() const { +Type *Function::getReturnType() const { return getFunctionType()->getReturnType(); } @@ -163,7 +163,7 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage, : GlobalValue(PointerType::getUnqual(Ty), Value::FunctionVal, 0, 0, Linkage, name) { assert(FunctionType::isValidReturnType(getReturnType()) && - !getReturnType()->isOpaqueTy() && "invalid return type"); + "invalid return type"); SymTab = new ValueSymbolTable(); // If the function has arguments, mark them as lazily built. diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp index 60000ad..8f2d887 100644 --- a/lib/VMCore/Globals.cpp +++ b/lib/VMCore/Globals.cpp @@ -51,6 +51,7 @@ void GlobalValue::copyAttributesFrom(const GlobalValue *Src) { setAlignment(Src->getAlignment()); setSection(Src->getSection()); setVisibility(Src->getVisibility()); + setUnnamedAddr(Src->hasUnnamedAddr()); } void GlobalValue::setAlignment(unsigned Align) { diff --git a/lib/VMCore/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp index bd3667d..5ae4a1b 100644 --- a/lib/VMCore/InlineAsm.cpp +++ b/lib/VMCore/InlineAsm.cpp @@ -47,7 +47,7 @@ InlineAsm::InlineAsm(const PointerType *Ty, const std::string &asmString, } void InlineAsm::destroyConstant() { - getRawType()->getContext().pImpl->InlineAsms.remove(this); + getType()->getContext().pImpl->InlineAsms.remove(this); delete this; } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 0eddd5a..ecb3229 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -372,7 +372,7 @@ static Instruction *createMalloc(Instruction *InsertBefore, // Create the call to Malloc. BasicBlock* BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd; Module* M = BB->getParent()->getParent(); - const Type *BPTy = Type::getInt8PtrTy(BB->getContext()); + Type *BPTy = Type::getInt8PtrTy(BB->getContext()); Value *MallocFunc = MallocF; if (!MallocFunc) // prototype malloc as "void *malloc(size_t)" @@ -823,7 +823,7 @@ bool AllocaInst::isArrayAllocation() const { return true; } -const Type *AllocaInst::getAllocatedType() const { +Type *AllocaInst::getAllocatedType() const { return getType()->getElementType(); } @@ -1098,7 +1098,7 @@ GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI) GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, const Twine &Name, Instruction *InBe) : Instruction(PointerType::get( - checkType(getIndexedType(Ptr->getType(),Idx)), retrieveAddrSpace(Ptr)), + checkGEPType(getIndexedType(Ptr->getType(),Idx)), retrieveAddrSpace(Ptr)), GetElementPtr, OperandTraits<GetElementPtrInst>::op_end(this) - 2, 2, InBe) { @@ -1108,7 +1108,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, const Twine &Name, BasicBlock *IAE) : Instruction(PointerType::get( - checkType(getIndexedType(Ptr->getType(),Idx)), + checkGEPType(getIndexedType(Ptr->getType(),Idx)), retrieveAddrSpace(Ptr)), GetElementPtr, OperandTraits<GetElementPtrInst>::op_end(this) - 2, @@ -1126,60 +1126,50 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, /// pointer type. /// template <typename IndexTy> -static const Type* getIndexedTypeInternal(const Type *Ptr, IndexTy const *Idxs, - unsigned NumIdx) { +static Type *getIndexedTypeInternal(const Type *Ptr, IndexTy const *Idxs, + unsigned NumIdx) { const PointerType *PTy = dyn_cast<PointerType>(Ptr); if (!PTy) return 0; // Type isn't a pointer type! - const Type *Agg = PTy->getElementType(); + Type *Agg = PTy->getElementType(); // Handle the special case of the empty set index set, which is always valid. if (NumIdx == 0) return Agg; // If there is at least one index, the top level type must be sized, otherwise - // it cannot be 'stepped over'. We explicitly allow abstract types (those - // that contain opaque types) under the assumption that it will be resolved to - // a sane type later. - if (!Agg->isSized() && !Agg->isAbstract()) + // it cannot be 'stepped over'. + if (!Agg->isSized()) return 0; unsigned CurIdx = 1; for (; CurIdx != NumIdx; ++CurIdx) { - const CompositeType *CT = dyn_cast<CompositeType>(Agg); + CompositeType *CT = dyn_cast<CompositeType>(Agg); if (!CT || CT->isPointerTy()) return 0; IndexTy Index = Idxs[CurIdx]; if (!CT->indexValid(Index)) return 0; Agg = CT->getTypeAtIndex(Index); - - // If the new type forwards to another type, then it is in the middle - // of being refined to another type (and hence, may have dropped all - // references to what it was using before). So, use the new forwarded - // type. - if (const Type *Ty = Agg->getForwardedType()) - Agg = Ty; } return CurIdx == NumIdx ? Agg : 0; } -const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, - Value* const *Idxs, - unsigned NumIdx) { +Type *GetElementPtrInst::getIndexedType(const Type *Ptr, Value* const *Idxs, + unsigned NumIdx) { return getIndexedTypeInternal(Ptr, Idxs, NumIdx); } -const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, - Constant* const *Idxs, - unsigned NumIdx) { +Type *GetElementPtrInst::getIndexedType(const Type *Ptr, + Constant* const *Idxs, + unsigned NumIdx) { return getIndexedTypeInternal(Ptr, Idxs, NumIdx); } -const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, - uint64_t const *Idxs, - unsigned NumIdx) { +Type *GetElementPtrInst::getIndexedType(const Type *Ptr, + uint64_t const *Idxs, + unsigned NumIdx) { return getIndexedTypeInternal(Ptr, Idxs, NumIdx); } -const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) { +Type *GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) { const PointerType *PTy = dyn_cast<PointerType>(Ptr); if (!PTy) return 0; // Type isn't a pointer type! @@ -1482,9 +1472,9 @@ ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI) // A null type is returned if the indices are invalid for the specified // pointer type. // -const Type* ExtractValueInst::getIndexedType(const Type *Agg, - const unsigned *Idxs, - unsigned NumIdx) { +Type *ExtractValueInst::getIndexedType(const Type *Agg, + const unsigned *Idxs, + unsigned NumIdx) { for (unsigned CurIdx = 0; CurIdx != NumIdx; ++CurIdx) { unsigned Index = Idxs[CurIdx]; // We can't use CompositeType::indexValid(Index) here. @@ -1505,19 +1495,11 @@ const Type* ExtractValueInst::getIndexedType(const Type *Agg, } Agg = cast<CompositeType>(Agg)->getTypeAtIndex(Index); - - // If the new type forwards to another type, then it is in the middle - // of being refined to another type (and hence, may have dropped all - // references to what it was using before). So, use the new forwarded - // type. - if (const Type *Ty = Agg->getForwardedType()) - Agg = Ty; } - return Agg; + return const_cast<Type*>(Agg); } -const Type* ExtractValueInst::getIndexedType(const Type *Agg, - unsigned Idx) { +Type *ExtractValueInst::getIndexedType(const Type *Agg, unsigned Idx) { return getIndexedType(Agg, &Idx, 1); } diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index ccb8dc5..0b7ae6c 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -31,14 +31,10 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C) Int8Ty(C, 8), Int16Ty(C, 16), Int32Ty(C, 32), - Int64Ty(C, 64), - AlwaysOpaqueTy(new OpaqueType(C)) { + Int64Ty(C, 64) { InlineAsmDiagHandler = 0; InlineAsmDiagContext = 0; - - // Make sure the AlwaysOpaqueTy stays alive as long as the Context. - AlwaysOpaqueTy->addRef(); - OpaqueTypes.insert(AlwaysOpaqueTy); + NamedStructTypesUniqueID = 0; } namespace { @@ -86,12 +82,7 @@ LLVMContextImpl::~LLVMContextImpl() { I != E; ++I) { delete I->second; } - AlwaysOpaqueTy->dropRef(); - for (OpaqueTypesTy::iterator I = OpaqueTypes.begin(), E = OpaqueTypes.end(); - I != E; ++I) { - (*I)->AbstractTypeUsers.clear(); - delete *I; - } + // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet // and the NonUniquedMDNodes sets, so copy the values out first. SmallVector<MDNode*, 8> MDNodes; @@ -109,7 +100,6 @@ LLVMContextImpl::~LLVMContextImpl() { "Destroying all MDNodes didn't empty the Context's sets."); // Destroy MDStrings. for (StringMap<MDString*>::iterator I = MDStringCache.begin(), - E = MDStringCache.end(); I != E; ++I) { + E = MDStringCache.end(); I != E; ++I) delete I->second; - } } diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index d8808b0..e36864b 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -15,10 +15,9 @@ #ifndef LLVM_LLVMCONTEXT_IMPL_H #define LLVM_LLVMCONTEXT_IMPL_H +#include "llvm/LLVMContext.h" #include "ConstantsContext.h" #include "LeaksContext.h" -#include "TypesContext.h" -#include "llvm/LLVMContext.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Metadata.h" @@ -170,34 +169,22 @@ public: LeakDetectorImpl<Value> LLVMObjects; // Basic type instances. - const Type VoidTy; - const Type LabelTy; - const Type FloatTy; - const Type DoubleTy; - const Type MetadataTy; - const Type X86_FP80Ty; - const Type FP128Ty; - const Type PPC_FP128Ty; - const Type X86_MMXTy; - const IntegerType Int1Ty; - const IntegerType Int8Ty; - const IntegerType Int16Ty; - const IntegerType Int32Ty; - const IntegerType Int64Ty; - - TypeMap<ArrayValType, ArrayType> ArrayTypes; - TypeMap<VectorValType, VectorType> VectorTypes; - TypeMap<PointerValType, PointerType> PointerTypes; - TypeMap<FunctionValType, FunctionType> FunctionTypes; - TypeMap<StructValType, StructType> StructTypes; - TypeMap<IntegerValType, IntegerType> IntegerTypes; - - // Opaque types are not structurally uniqued, so don't use TypeMap. - typedef SmallPtrSet<const OpaqueType*, 8> OpaqueTypesTy; - OpaqueTypesTy OpaqueTypes; - - /// Used as an abstract type that will never be resolved. - OpaqueType *const AlwaysOpaqueTy; + Type VoidTy, LabelTy, FloatTy, DoubleTy, MetadataTy; + Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy; + IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty; + + DenseMap<unsigned, IntegerType*> IntegerTypes; + + // TODO: Optimize FunctionTypes/AnonStructTypes! + std::map<std::vector<Type*>, FunctionType*> FunctionTypes; + std::map<std::vector<Type*>, StructType*> AnonStructTypes; + StringMap<StructType*> NamedStructTypes; + unsigned NamedStructTypesUniqueID; + + DenseMap<std::pair<Type *, uint64_t>, ArrayType*> ArrayTypes; + DenseMap<std::pair<Type *, unsigned>, VectorType*> VectorTypes; + DenseMap<Type*, PointerType*> PointerTypes; // Pointers in AddrSpace = 0 + DenseMap<std::pair<Type*, unsigned>, PointerType*> ASPointerTypes; /// ValueHandles - This map keeps track of all of the value handles that are diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index eb719e5..ace4dc2 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/STLExtras.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/ValueHandle.h" diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index 341e527..1ca7016 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -17,12 +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 <algorithm> #include <cstdarg> #include <cstdlib> @@ -60,7 +60,6 @@ template class llvm::SymbolTableListTraits<GlobalAlias, Module>; Module::Module(StringRef MID, LLVMContext& C) : Context(C), Materializer(NULL), ModuleID(MID) { ValSymTab = new ValueSymbolTable(); - TypeSymTab = new TypeSymbolTable(); NamedMDSymTab = new StringMap<NamedMDNode *>(); Context.addModule(this); } @@ -74,11 +73,10 @@ Module::~Module() { LibraryList.clear(); NamedMDList.clear(); delete ValSymTab; - delete TypeSymTab; delete static_cast<StringMap<NamedMDNode *> *>(NamedMDSymTab); } -/// Target endian information... +/// Target endian information. Module::Endianness Module::getEndianness() const { StringRef temp = DataLayout; Module::Endianness ret = AnyEndianness; @@ -340,51 +338,6 @@ void Module::eraseNamedMetadata(NamedMDNode *NMD) { NamedMDList.erase(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<Type>(ST.lookup(Name)); -} - -// 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. @@ -471,3 +424,130 @@ 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<const Value*> VisitedConstants; + DenseSet<const Type*> VisitedTypes; + + std::vector<StructType*> &StructTypes; + public: + TypeFinder(std::vector<StructType*> &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<std::pair<unsigned, MDNode*>, 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.getAllMetadata(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<StructType>(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<MDNode>(V)) + return incorporateMDNode(M); + if (!isa<Constant>(V) || isa<GlobalValue>(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<User>(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<StructType*> &StructTypes) const { + TypeFinder(StructTypes).run(*this); +} + + diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index 9299070..734d43a 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -12,81 +12,17 @@ //===----------------------------------------------------------------------===// #include "LLVMContextImpl.h" -#include "llvm/ADT/SCCIterator.h" +#include "llvm/Module.h" #include <algorithm> #include <cstdarg> +#include "llvm/ADT/SmallString.h" using namespace llvm; -// DEBUG_MERGE_TYPES - Enable this #define to see how and when derived types are -// created and later destroyed, all in an effort to make sure that there is only -// a single canonical version of a type. -// -// #define DEBUG_MERGE_TYPES 1 - -AbstractTypeUser::~AbstractTypeUser() {} - -void AbstractTypeUser::setType(Value *V, const Type *NewTy) { - V->VTy = NewTy; -} - //===----------------------------------------------------------------------===// // Type Class Implementation //===----------------------------------------------------------------------===// -/// Because of the way Type subclasses are allocated, this function is necessary -/// to use the correct kind of "delete" operator to deallocate the Type object. -/// Some type objects (FunctionTy, StructTy) allocate additional space -/// after the space for their derived type to hold the contained types array of -/// PATypeHandles. Using this allocation scheme means all the PATypeHandles are -/// allocated with the type object, decreasing allocations and eliminating the -/// need for a std::vector to be used in the Type class itself. -/// @brief Type destruction function -void Type::destroy() const { - // Nothing calls getForwardedType from here on. - if (ForwardType && ForwardType->isAbstract()) { - ForwardType->dropRef(); - ForwardType = NULL; - } - - // Structures and Functions allocate their contained types past the end of - // the type object itself. These need to be destroyed differently than the - // other types. - if (this->isFunctionTy() || this->isStructTy()) { - // First, make sure we destruct any PATypeHandles allocated by these - // subclasses. They must be manually destructed. - for (unsigned i = 0; i < NumContainedTys; ++i) - ContainedTys[i].PATypeHandle::~PATypeHandle(); - - // Now call the destructor for the subclass directly because we're going - // to delete this as an array of char. - if (this->isFunctionTy()) - static_cast<const FunctionType*>(this)->FunctionType::~FunctionType(); - else { - assert(isStructTy()); - static_cast<const StructType*>(this)->StructType::~StructType(); - } - - // Finally, remove the memory as an array deallocation of the chars it was - // constructed from. - operator delete(const_cast<Type *>(this)); - - return; - } - - if (const OpaqueType *opaque_this = dyn_cast<OpaqueType>(this)) { - LLVMContextImpl *pImpl = this->getContext().pImpl; - pImpl->OpaqueTypes.erase(opaque_this); - } - - // For all the other type subclasses, there is either no contained types or - // just one (all Sequentials). For Sequentials, the PATypeHandle is not - // allocated past the type object, its included directly in the SequentialType - // class. This means we can safely just do "normal" delete of this object and - // all the destructors that need to run will be run. - delete this; -} - -const Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) { +Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) { switch (IDNumber) { case VoidTyID : return getVoidTy(C); case FloatTyID : return getFloatTy(C); @@ -245,7 +181,11 @@ bool Type::isSizedDerivedType() const { if (!this->isStructTy()) return false; - // Okay, our struct is sized if all of the elements are... + // Opaque structs have no size. + if (cast<StructType>(this)->isOpaque()) + return false; + + // Okay, our struct is sized if all of the elements are. for (subtype_iterator I = subtype_begin(), E = subtype_end(); I != E; ++I) if (!(*I)->isSized()) return false; @@ -253,703 +193,346 @@ bool Type::isSizedDerivedType() const { return true; } -/// getForwardedTypeInternal - This method is used to implement the union-find -/// algorithm for when a type is being forwarded to another type. -const Type *Type::getForwardedTypeInternal() const { - assert(ForwardType && "This type is not being forwarded to another type!"); - - // Check to see if the forwarded type has been forwarded on. If so, collapse - // the forwarding links. - const Type *RealForwardedType = ForwardType->getForwardedType(); - if (!RealForwardedType) - return ForwardType; // No it's not forwarded again - - // Yes, it is forwarded again. First thing, add the reference to the new - // forward type. - if (RealForwardedType->isAbstract()) - RealForwardedType->addRef(); - - // Now drop the old reference. This could cause ForwardType to get deleted. - // ForwardType must be abstract because only abstract types can have their own - // ForwardTypes. - ForwardType->dropRef(); - - // Return the updated type. - ForwardType = RealForwardedType; - return ForwardType; -} - -void Type::refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { - llvm_unreachable("Attempting to refine a derived type!"); -} -void Type::typeBecameConcrete(const DerivedType *AbsTy) { - llvm_unreachable("DerivedType is already a concrete type!"); -} - -const Type *CompositeType::getTypeAtIndex(const Value *V) const { - if (const StructType *STy = dyn_cast<StructType>(this)) { - unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue(); - assert(indexValid(Idx) && "Invalid structure index!"); - return STy->getElementType(Idx); - } - - return cast<SequentialType>(this)->getElementType(); -} -const Type *CompositeType::getTypeAtIndex(unsigned Idx) const { - if (const StructType *STy = dyn_cast<StructType>(this)) { - assert(indexValid(Idx) && "Invalid structure index!"); - return STy->getElementType(Idx); - } - - return cast<SequentialType>(this)->getElementType(); -} -bool CompositeType::indexValid(const Value *V) const { - if (const StructType *STy = dyn_cast<StructType>(this)) { - // Structure indexes require 32-bit integer constants. - if (V->getType()->isIntegerTy(32)) - if (const ConstantInt *CU = dyn_cast<ConstantInt>(V)) - return CU->getZExtValue() < STy->getNumElements(); - return false; - } - - // Sequential types can be indexed by any integer. - return V->getType()->isIntegerTy(); -} - -bool CompositeType::indexValid(unsigned Idx) const { - if (const StructType *STy = dyn_cast<StructType>(this)) - return Idx < STy->getNumElements(); - // Sequential types can be indexed by any integer. - return true; -} - - //===----------------------------------------------------------------------===// // Primitive 'Type' data //===----------------------------------------------------------------------===// -const Type *Type::getVoidTy(LLVMContext &C) { - return &C.pImpl->VoidTy; -} - -const Type *Type::getLabelTy(LLVMContext &C) { - return &C.pImpl->LabelTy; -} - -const Type *Type::getFloatTy(LLVMContext &C) { - return &C.pImpl->FloatTy; -} - -const Type *Type::getDoubleTy(LLVMContext &C) { - return &C.pImpl->DoubleTy; -} - -const Type *Type::getMetadataTy(LLVMContext &C) { - return &C.pImpl->MetadataTy; -} - -const Type *Type::getX86_FP80Ty(LLVMContext &C) { - return &C.pImpl->X86_FP80Ty; -} - -const Type *Type::getFP128Ty(LLVMContext &C) { - return &C.pImpl->FP128Ty; -} - -const Type *Type::getPPC_FP128Ty(LLVMContext &C) { - return &C.pImpl->PPC_FP128Ty; -} - -const Type *Type::getX86_MMXTy(LLVMContext &C) { - return &C.pImpl->X86_MMXTy; -} - -const IntegerType *Type::getIntNTy(LLVMContext &C, unsigned N) { +Type *Type::getVoidTy(LLVMContext &C) { return &C.pImpl->VoidTy; } +Type *Type::getLabelTy(LLVMContext &C) { return &C.pImpl->LabelTy; } +Type *Type::getFloatTy(LLVMContext &C) { return &C.pImpl->FloatTy; } +Type *Type::getDoubleTy(LLVMContext &C) { return &C.pImpl->DoubleTy; } +Type *Type::getMetadataTy(LLVMContext &C) { return &C.pImpl->MetadataTy; } +Type *Type::getX86_FP80Ty(LLVMContext &C) { return &C.pImpl->X86_FP80Ty; } +Type *Type::getFP128Ty(LLVMContext &C) { return &C.pImpl->FP128Ty; } +Type *Type::getPPC_FP128Ty(LLVMContext &C) { return &C.pImpl->PPC_FP128Ty; } +Type *Type::getX86_MMXTy(LLVMContext &C) { return &C.pImpl->X86_MMXTy; } + +IntegerType *Type::getInt1Ty(LLVMContext &C) { return &C.pImpl->Int1Ty; } +IntegerType *Type::getInt8Ty(LLVMContext &C) { return &C.pImpl->Int8Ty; } +IntegerType *Type::getInt16Ty(LLVMContext &C) { return &C.pImpl->Int16Ty; } +IntegerType *Type::getInt32Ty(LLVMContext &C) { return &C.pImpl->Int32Ty; } +IntegerType *Type::getInt64Ty(LLVMContext &C) { return &C.pImpl->Int64Ty; } + +IntegerType *Type::getIntNTy(LLVMContext &C, unsigned N) { return IntegerType::get(C, N); } -const IntegerType *Type::getInt1Ty(LLVMContext &C) { - return &C.pImpl->Int1Ty; -} - -const IntegerType *Type::getInt8Ty(LLVMContext &C) { - return &C.pImpl->Int8Ty; -} - -const IntegerType *Type::getInt16Ty(LLVMContext &C) { - return &C.pImpl->Int16Ty; -} - -const IntegerType *Type::getInt32Ty(LLVMContext &C) { - return &C.pImpl->Int32Ty; -} - -const IntegerType *Type::getInt64Ty(LLVMContext &C) { - return &C.pImpl->Int64Ty; -} - -const PointerType *Type::getFloatPtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getFloatPtrTy(LLVMContext &C, unsigned AS) { return getFloatTy(C)->getPointerTo(AS); } -const PointerType *Type::getDoublePtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getDoublePtrTy(LLVMContext &C, unsigned AS) { return getDoubleTy(C)->getPointerTo(AS); } -const PointerType *Type::getX86_FP80PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getX86_FP80PtrTy(LLVMContext &C, unsigned AS) { return getX86_FP80Ty(C)->getPointerTo(AS); } -const PointerType *Type::getFP128PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getFP128PtrTy(LLVMContext &C, unsigned AS) { return getFP128Ty(C)->getPointerTo(AS); } -const PointerType *Type::getPPC_FP128PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getPPC_FP128PtrTy(LLVMContext &C, unsigned AS) { return getPPC_FP128Ty(C)->getPointerTo(AS); } -const PointerType *Type::getX86_MMXPtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getX86_MMXPtrTy(LLVMContext &C, unsigned AS) { return getX86_MMXTy(C)->getPointerTo(AS); } -const PointerType *Type::getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS) { +PointerType *Type::getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS) { return getIntNTy(C, N)->getPointerTo(AS); } -const PointerType *Type::getInt1PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getInt1PtrTy(LLVMContext &C, unsigned AS) { return getInt1Ty(C)->getPointerTo(AS); } -const PointerType *Type::getInt8PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getInt8PtrTy(LLVMContext &C, unsigned AS) { return getInt8Ty(C)->getPointerTo(AS); } -const PointerType *Type::getInt16PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getInt16PtrTy(LLVMContext &C, unsigned AS) { return getInt16Ty(C)->getPointerTo(AS); } -const PointerType *Type::getInt32PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getInt32PtrTy(LLVMContext &C, unsigned AS) { return getInt32Ty(C)->getPointerTo(AS); } -const PointerType *Type::getInt64PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getInt64PtrTy(LLVMContext &C, unsigned AS) { return getInt64Ty(C)->getPointerTo(AS); } + //===----------------------------------------------------------------------===// -// Derived Type Constructors +// IntegerType Implementation //===----------------------------------------------------------------------===// -/// isValidReturnType - Return true if the specified type is valid as a return -/// type. -bool FunctionType::isValidReturnType(const Type *RetTy) { - return !RetTy->isFunctionTy() && !RetTy->isLabelTy() && - !RetTy->isMetadataTy(); +IntegerType *IntegerType::get(LLVMContext &C, unsigned NumBits) { + assert(NumBits >= MIN_INT_BITS && "bitwidth too small"); + assert(NumBits <= MAX_INT_BITS && "bitwidth too large"); + + // Check for the built-in integer types + switch (NumBits) { + case 1: return cast<IntegerType>(Type::getInt1Ty(C)); + case 8: return cast<IntegerType>(Type::getInt8Ty(C)); + case 16: return cast<IntegerType>(Type::getInt16Ty(C)); + case 32: return cast<IntegerType>(Type::getInt32Ty(C)); + case 64: return cast<IntegerType>(Type::getInt64Ty(C)); + default: + break; + } + + IntegerType *&Entry = C.pImpl->IntegerTypes[NumBits]; + + if (Entry == 0) + Entry = new IntegerType(C, NumBits); + + return Entry; } -/// isValidArgumentType - Return true if the specified type is valid as an -/// argument type. -bool FunctionType::isValidArgumentType(const Type *ArgTy) { - return ArgTy->isFirstClassType() || ArgTy->isOpaqueTy(); +bool IntegerType::isPowerOf2ByteWidth() const { + unsigned BitWidth = getBitWidth(); + return (BitWidth > 7) && isPowerOf2_32(BitWidth); +} + +APInt IntegerType::getMask() const { + return APInt::getAllOnesValue(getBitWidth()); } -FunctionType::FunctionType(const Type *Result, - ArrayRef<const Type*> Params, +//===----------------------------------------------------------------------===// +// FunctionType Implementation +//===----------------------------------------------------------------------===// + +FunctionType::FunctionType(const Type *Result, ArrayRef<Type*> Params, bool IsVarArgs) : DerivedType(Result->getContext(), FunctionTyID) { - ContainedTys = reinterpret_cast<PATypeHandle*>(this+1); - NumContainedTys = Params.size() + 1; // + 1 for result type + Type **SubTys = reinterpret_cast<Type**>(this+1); assert(isValidReturnType(Result) && "invalid return type for function"); setSubclassData(IsVarArgs); - bool isAbstract = Result->isAbstract(); - new (&ContainedTys[0]) PATypeHandle(Result, this); + SubTys[0] = const_cast<Type*>(Result); - for (unsigned i = 0; i != Params.size(); ++i) { + for (unsigned i = 0, e = Params.size(); i != e; ++i) { assert(isValidArgumentType(Params[i]) && "Not a valid type for function argument!"); - new (&ContainedTys[i+1]) PATypeHandle(Params[i], this); - isAbstract |= Params[i]->isAbstract(); - } - - // Calculate whether or not this type is abstract - setAbstract(isAbstract); -} - -StructType::StructType(LLVMContext &C, - ArrayRef<const Type*> Types, bool isPacked) - : CompositeType(C, StructTyID) { - ContainedTys = reinterpret_cast<PATypeHandle*>(this + 1); - NumContainedTys = Types.size(); - setSubclassData(isPacked); - bool isAbstract = false; - for (unsigned i = 0; i < Types.size(); ++i) { - assert(Types[i] && "<null> type for structure field!"); - assert(isValidElementType(Types[i]) && - "Invalid type for structure element!"); - new (&ContainedTys[i]) PATypeHandle(Types[i], this); - isAbstract |= Types[i]->isAbstract(); + SubTys[i+1] = Params[i]; } - // Calculate whether or not this type is abstract - setAbstract(isAbstract); -} - -ArrayType::ArrayType(const Type *ElType, uint64_t NumEl) - : SequentialType(ArrayTyID, ElType) { - NumElements = NumEl; - - // Calculate whether or not this type is abstract - setAbstract(ElType->isAbstract()); + ContainedTys = SubTys; + NumContainedTys = Params.size() + 1; // + 1 for result type } -VectorType::VectorType(const Type *ElType, unsigned NumEl) - : SequentialType(VectorTyID, ElType) { - NumElements = NumEl; - setAbstract(ElType->isAbstract()); - assert(NumEl > 0 && "NumEl of a VectorType must be greater than 0"); - assert(isValidElementType(ElType) && - "Elements of a VectorType must be a primitive type"); - +// FIXME: Remove this version. +FunctionType *FunctionType::get(const Type *ReturnType, + ArrayRef<const Type*> Params, bool isVarArg) { + return get(ReturnType, ArrayRef<Type*>(const_cast<Type**>(Params.data()), + Params.size()), isVarArg); } +// FunctionType::get - The factory function for the FunctionType class. +FunctionType *FunctionType::get(const Type *ReturnType, + ArrayRef<Type*> Params, bool isVarArg) { + // TODO: This is brutally slow. + std::vector<Type*> Key; + Key.reserve(Params.size()+2); + Key.push_back(const_cast<Type*>(ReturnType)); + for (unsigned i = 0, e = Params.size(); i != e; ++i) + Key.push_back(const_cast<Type*>(Params[i])); + if (isVarArg) + Key.push_back(0); + + FunctionType *&FT = ReturnType->getContext().pImpl->FunctionTypes[Key]; + + if (FT == 0) { + FT = (FunctionType*) operator new(sizeof(FunctionType) + + sizeof(Type*)*(Params.size()+1)); + new (FT) FunctionType(ReturnType, Params, isVarArg); + } -PointerType::PointerType(const Type *E, unsigned AddrSpace) - : SequentialType(PointerTyID, E) { - setSubclassData(AddrSpace); - // Calculate whether or not this type is abstract - setAbstract(E->isAbstract()); -} - -OpaqueType::OpaqueType(LLVMContext &C) : DerivedType(C, OpaqueTyID) { - setAbstract(true); -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *this << "\n"); -#endif + return FT; } -void PATypeHolder::destroy() { - Ty = 0; -} -// dropAllTypeUses - When this (abstract) type is resolved to be equal to -// another (more concrete) type, we must eliminate all references to other -// types, to avoid some circular reference problems. -void DerivedType::dropAllTypeUses() { - if (NumContainedTys != 0) { - // The type must stay abstract. To do this, we insert a pointer to a type - // that will never get resolved, thus will always be abstract. - ContainedTys[0] = getContext().pImpl->AlwaysOpaqueTy; - - // Change the rest of the types to be Int32Ty's. It doesn't matter what we - // pick so long as it doesn't point back to this type. We choose something - // concrete to avoid overhead for adding to AbstractTypeUser lists and - // stuff. - const Type *ConcreteTy = Type::getInt32Ty(getContext()); - for (unsigned i = 1, e = NumContainedTys; i != e; ++i) - ContainedTys[i] = ConcreteTy; - } +FunctionType *FunctionType::get(const Type *Result, bool isVarArg) { + return get(Result, ArrayRef<const Type *>(), isVarArg); } -namespace { - -/// TypePromotionGraph and graph traits - this is designed to allow us to do -/// efficient SCC processing of type graphs. This is the exact same as -/// GraphTraits<Type*>, except that we pretend that concrete types have no -/// children to avoid processing them. -struct TypePromotionGraph { - Type *Ty; - TypePromotionGraph(Type *T) : Ty(T) {} -}; - -} - -namespace llvm { - template <> struct GraphTraits<TypePromotionGraph> { - typedef Type NodeType; - typedef Type::subtype_iterator ChildIteratorType; - - static inline NodeType *getEntryNode(TypePromotionGraph G) { return G.Ty; } - static inline ChildIteratorType child_begin(NodeType *N) { - if (N->isAbstract()) - return N->subtype_begin(); - // No need to process children of concrete types. - return N->subtype_end(); - } - static inline ChildIteratorType child_end(NodeType *N) { - return N->subtype_end(); - } - }; +/// isValidReturnType - Return true if the specified type is valid as a return +/// type. +bool FunctionType::isValidReturnType(const Type *RetTy) { + return !RetTy->isFunctionTy() && !RetTy->isLabelTy() && + !RetTy->isMetadataTy(); } - -// PromoteAbstractToConcrete - This is a recursive function that walks a type -// graph calculating whether or not a type is abstract. -// -void Type::PromoteAbstractToConcrete() { - if (!isAbstract()) return; - - scc_iterator<TypePromotionGraph> SI = scc_begin(TypePromotionGraph(this)); - scc_iterator<TypePromotionGraph> SE = scc_end (TypePromotionGraph(this)); - - for (; SI != SE; ++SI) { - std::vector<Type*> &SCC = *SI; - - // Concrete types are leaves in the tree. Since an SCC will either be all - // abstract or all concrete, we only need to check one type. - if (!SCC[0]->isAbstract()) continue; - - if (SCC[0]->isOpaqueTy()) - return; // Not going to be concrete, sorry. - - // If all of the children of all of the types in this SCC are concrete, - // then this SCC is now concrete as well. If not, neither this SCC, nor - // any parent SCCs will be concrete, so we might as well just exit. - for (unsigned i = 0, e = SCC.size(); i != e; ++i) - for (Type::subtype_iterator CI = SCC[i]->subtype_begin(), - E = SCC[i]->subtype_end(); CI != E; ++CI) - if ((*CI)->isAbstract()) - // If the child type is in our SCC, it doesn't make the entire SCC - // abstract unless there is a non-SCC abstract type. - if (std::find(SCC.begin(), SCC.end(), *CI) == SCC.end()) - return; // Not going to be concrete, sorry. - - // Okay, we just discovered this whole SCC is now concrete, mark it as - // such! - for (unsigned i = 0, e = SCC.size(); i != e; ++i) { - assert(SCC[i]->isAbstract() && "Why are we processing concrete types?"); - - SCC[i]->setAbstract(false); - } - - for (unsigned i = 0, e = SCC.size(); i != e; ++i) { - assert(!SCC[i]->isAbstract() && "Concrete type became abstract?"); - // The type just became concrete, notify all users! - cast<DerivedType>(SCC[i])->notifyUsesThatTypeBecameConcrete(); - } - } +/// isValidArgumentType - Return true if the specified type is valid as an +/// argument type. +bool FunctionType::isValidArgumentType(const Type *ArgTy) { + return ArgTy->isFirstClassType(); } - //===----------------------------------------------------------------------===// -// Type Structural Equality Testing +// StructType Implementation //===----------------------------------------------------------------------===// -// TypesEqual - Two types are considered structurally equal if they have the -// same "shape": Every level and element of the types have identical primitive -// ID's, and the graphs have the same edges/nodes in them. Nodes do not have to -// be pointer equals to be equivalent though. This uses an optimistic algorithm -// that assumes that two graphs are the same until proven otherwise. -// -static bool TypesEqual(const Type *Ty, const Type *Ty2, - std::map<const Type *, const Type *> &EqTypes) { - if (Ty == Ty2) return true; - if (Ty->getTypeID() != Ty2->getTypeID()) return false; - if (Ty->isOpaqueTy()) - return false; // Two unequal opaque types are never equal - - std::map<const Type*, const Type*>::iterator It = EqTypes.find(Ty); - if (It != EqTypes.end()) - return It->second == Ty2; // Looping back on a type, check for equality - - // Otherwise, add the mapping to the table to make sure we don't get - // recursion on the types... - EqTypes.insert(It, std::make_pair(Ty, Ty2)); - - // Two really annoying special cases that breaks an otherwise nice simple - // algorithm is the fact that arraytypes have sizes that differentiates types, - // and that function types can be varargs or not. Consider this now. - // - if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty)) { - const IntegerType *ITy2 = cast<IntegerType>(Ty2); - return ITy->getBitWidth() == ITy2->getBitWidth(); - } - - if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) { - const PointerType *PTy2 = cast<PointerType>(Ty2); - return PTy->getAddressSpace() == PTy2->getAddressSpace() && - TypesEqual(PTy->getElementType(), PTy2->getElementType(), EqTypes); +// Primitive Constructors. + +StructType *StructType::get(LLVMContext &Context, ArrayRef<Type*> ETypes, + bool isPacked) { + // FIXME: std::vector is horribly inefficient for this probe. + std::vector<Type*> Key; + for (unsigned i = 0, e = ETypes.size(); i != e; ++i) { + assert(isValidElementType(ETypes[i]) && + "Invalid type for structure element!"); + Key.push_back(ETypes[i]); } + if (isPacked) + Key.push_back(0); - if (const StructType *STy = dyn_cast<StructType>(Ty)) { - const StructType *STy2 = cast<StructType>(Ty2); - if (STy->getNumElements() != STy2->getNumElements()) return false; - if (STy->isPacked() != STy2->isPacked()) return false; - for (unsigned i = 0, e = STy2->getNumElements(); i != e; ++i) - if (!TypesEqual(STy->getElementType(i), STy2->getElementType(i), EqTypes)) - return false; - return true; - } + StructType *&ST = Context.pImpl->AnonStructTypes[Key]; + + if (ST) return ST; - if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) { - const ArrayType *ATy2 = cast<ArrayType>(Ty2); - return ATy->getNumElements() == ATy2->getNumElements() && - TypesEqual(ATy->getElementType(), ATy2->getElementType(), EqTypes); - } + // Value not found. Create a new type! + ST = new StructType(Context); + ST->setSubclassData(SCDB_IsAnonymous); // Anonymous struct. + ST->setBody(ETypes, isPacked); + return ST; +} + +void StructType::setBody(ArrayRef<Type*> Elements, bool isPacked) { + assert(isOpaque() && "Struct body already set!"); - if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) { - const VectorType *PTy2 = cast<VectorType>(Ty2); - return PTy->getNumElements() == PTy2->getNumElements() && - TypesEqual(PTy->getElementType(), PTy2->getElementType(), EqTypes); - } + setSubclassData(getSubclassData() | SCDB_HasBody); + if (isPacked) + setSubclassData(getSubclassData() | SCDB_Packed); - if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) { - const FunctionType *FTy2 = cast<FunctionType>(Ty2); - if (FTy->isVarArg() != FTy2->isVarArg() || - FTy->getNumParams() != FTy2->getNumParams() || - !TypesEqual(FTy->getReturnType(), FTy2->getReturnType(), EqTypes)) - return false; - for (unsigned i = 0, e = FTy2->getNumParams(); i != e; ++i) { - if (!TypesEqual(FTy->getParamType(i), FTy2->getParamType(i), EqTypes)) - return false; - } - return true; - } + Type **Elts = new Type*[Elements.size()]; + memcpy(Elts, Elements.data(), sizeof(Elements[0])*Elements.size()); - llvm_unreachable("Unknown derived type!"); - return false; -} - -namespace llvm { // in namespace llvm so findable by ADL -static bool TypesEqual(const Type *Ty, const Type *Ty2) { - std::map<const Type *, const Type *> EqTypes; - return ::TypesEqual(Ty, Ty2, EqTypes); -} -} - -// AbstractTypeHasCycleThrough - Return true there is a path from CurTy to -// TargetTy in the type graph. We know that Ty is an abstract type, so if we -// ever reach a non-abstract type, we know that we don't need to search the -// subgraph. -static bool AbstractTypeHasCycleThrough(const Type *TargetTy, const Type *CurTy, - SmallPtrSet<const Type*, 128> &VisitedTypes) { - if (TargetTy == CurTy) return true; - if (!CurTy->isAbstract()) return false; - - if (!VisitedTypes.insert(CurTy)) - return false; // Already been here. - - for (Type::subtype_iterator I = CurTy->subtype_begin(), - E = CurTy->subtype_end(); I != E; ++I) - if (AbstractTypeHasCycleThrough(TargetTy, *I, VisitedTypes)) - return true; - return false; + ContainedTys = Elts; + NumContainedTys = Elements.size(); } -static bool ConcreteTypeHasCycleThrough(const Type *TargetTy, const Type *CurTy, - SmallPtrSet<const Type*, 128> &VisitedTypes) { - if (TargetTy == CurTy) return true; - - if (!VisitedTypes.insert(CurTy)) - return false; // Already been here. - - for (Type::subtype_iterator I = CurTy->subtype_begin(), - E = CurTy->subtype_end(); I != E; ++I) - if (ConcreteTypeHasCycleThrough(TargetTy, *I, VisitedTypes)) - return true; - return false; -} - -/// TypeHasCycleThroughItself - Return true if the specified type has -/// a cycle back to itself. - -namespace llvm { // in namespace llvm so it's findable by ADL -static bool TypeHasCycleThroughItself(const Type *Ty) { - SmallPtrSet<const Type*, 128> VisitedTypes; - - if (Ty->isAbstract()) { // Optimized case for abstract types. - for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); - I != E; ++I) - if (AbstractTypeHasCycleThrough(Ty, *I, VisitedTypes)) - return true; - } else { - for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); - I != E; ++I) - if (ConcreteTypeHasCycleThrough(Ty, *I, VisitedTypes)) - return true; - } - return false; -} +StructType *StructType::createNamed(LLVMContext &Context, StringRef Name) { + StructType *ST = new StructType(Context); + ST->setName(Name); + return ST; } -//===----------------------------------------------------------------------===// -// Function Type Factory and Value Class... -// -const IntegerType *IntegerType::get(LLVMContext &C, unsigned NumBits) { - assert(NumBits >= MIN_INT_BITS && "bitwidth too small"); - assert(NumBits <= MAX_INT_BITS && "bitwidth too large"); +void StructType::setName(StringRef Name) { + if (Name == getName()) return; - // Check for the built-in integer types - switch (NumBits) { - case 1: return cast<IntegerType>(Type::getInt1Ty(C)); - case 8: return cast<IntegerType>(Type::getInt8Ty(C)); - case 16: return cast<IntegerType>(Type::getInt16Ty(C)); - case 32: return cast<IntegerType>(Type::getInt32Ty(C)); - case 64: return cast<IntegerType>(Type::getInt64Ty(C)); - default: - break; + // If this struct already had a name, remove its symbol table entry. + if (SymbolTableEntry) { + getContext().pImpl->NamedStructTypes.erase(getName()); + SymbolTableEntry = 0; } - - LLVMContextImpl *pImpl = C.pImpl; - IntegerValType IVT(NumBits); - IntegerType *ITy = 0; + // If this is just removing the name, we're done. + if (Name.empty()) + return; - // First, see if the type is already in the table, for which - // a reader lock suffices. - ITy = pImpl->IntegerTypes.get(IVT); - - if (!ITy) { - // Value not found. Derive a new type! - ITy = new IntegerType(C, NumBits); - pImpl->IntegerTypes.add(IVT, ITy); + // Look up the entry for the name. + StringMapEntry<StructType*> *Entry = + &getContext().pImpl->NamedStructTypes.GetOrCreateValue(Name); + + // While we have a name collision, try a random rename. + if (Entry->getValue()) { + SmallString<64> TempStr(Name); + TempStr.push_back('.'); + raw_svector_ostream TmpStream(TempStr); + + do { + TempStr.resize(Name.size()+1); + TmpStream.resync(); + TmpStream << getContext().pImpl->NamedStructTypesUniqueID++; + + Entry = &getContext().pImpl-> + NamedStructTypes.GetOrCreateValue(TmpStream.str()); + } while (Entry->getValue()); } -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *ITy << "\n"); -#endif - return ITy; -} -bool IntegerType::isPowerOf2ByteWidth() const { - unsigned BitWidth = getBitWidth(); - return (BitWidth > 7) && isPowerOf2_32(BitWidth); + // Okay, we found an entry that isn't used. It's us! + Entry->setValue(this); + + SymbolTableEntry = Entry; } -APInt IntegerType::getMask() const { - return APInt::getAllOnesValue(getBitWidth()); -} +//===----------------------------------------------------------------------===// +// StructType Helper functions. -FunctionValType FunctionValType::get(const FunctionType *FT) { - // Build up a FunctionValType - std::vector<const Type *> ParamTypes; - ParamTypes.reserve(FT->getNumParams()); - for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) - ParamTypes.push_back(FT->getParamType(i)); - return FunctionValType(FT->getReturnType(), ParamTypes, FT->isVarArg()); +// FIXME: Remove this version. +StructType *StructType::get(LLVMContext &Context, ArrayRef<const Type*>Elements, + bool isPacked) { + return get(Context, ArrayRef<Type*>(const_cast<Type**>(Elements.data()), + Elements.size()), isPacked); } -FunctionType *FunctionType::get(const Type *Result, bool isVarArg) { - return get(Result, ArrayRef<const Type *>(), isVarArg); +StructType *StructType::get(LLVMContext &Context, bool isPacked) { + return get(Context, llvm::ArrayRef<const Type*>(), isPacked); } -// FunctionType::get - The factory function for the FunctionType class... -FunctionType *FunctionType::get(const Type *ReturnType, - ArrayRef<const Type*> Params, - bool isVarArg) { - FunctionValType VT(ReturnType, Params, isVarArg); - FunctionType *FT = 0; - - LLVMContextImpl *pImpl = ReturnType->getContext().pImpl; - - FT = pImpl->FunctionTypes.get(VT); - - if (!FT) { - FT = (FunctionType*) operator new(sizeof(FunctionType) + - sizeof(PATypeHandle)*(Params.size()+1)); - new (FT) FunctionType(ReturnType, Params, isVarArg); - pImpl->FunctionTypes.add(VT, FT); +StructType *StructType::get(const Type *type, ...) { + assert(type != 0 && "Cannot create a struct type with no elements with this"); + LLVMContext &Ctx = type->getContext(); + va_list ap; + SmallVector<const llvm::Type*, 8> StructFields; + va_start(ap, type); + while (type) { + StructFields.push_back(type); + type = va_arg(ap, llvm::Type*); } - -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << FT << "\n"); -#endif - return FT; + return llvm::StructType::get(Ctx, StructFields); } -ArrayType *ArrayType::get(const Type *ElementType, uint64_t NumElements) { - assert(ElementType && "Can't get array of <null> types!"); - assert(isValidElementType(ElementType) && "Invalid type for array element!"); - - ArrayValType AVT(ElementType, NumElements); - ArrayType *AT = 0; - - LLVMContextImpl *pImpl = ElementType->getContext().pImpl; - - AT = pImpl->ArrayTypes.get(AVT); - - if (!AT) { - // Value not found. Derive a new type! - pImpl->ArrayTypes.add(AVT, AT = new ArrayType(ElementType, NumElements)); - } -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *AT << "\n"); -#endif - return AT; +StructType *StructType::createNamed(LLVMContext &Context, StringRef Name, + ArrayRef<Type*> Elements, bool isPacked) { + StructType *ST = createNamed(Context, Name); + ST->setBody(Elements, isPacked); + return ST; } -bool ArrayType::isValidElementType(const Type *ElemTy) { - return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() && - !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy(); +StructType *StructType::createNamed(StringRef Name, ArrayRef<Type*> Elements, + bool isPacked) { + assert(!Elements.empty() && + "This method may not be invoked with an empty list"); + return createNamed(Elements[0]->getContext(), Name, Elements, isPacked); } -VectorType *VectorType::get(const Type *ElementType, unsigned NumElements) { - assert(ElementType && "Can't get vector of <null> types!"); - - VectorValType PVT(ElementType, NumElements); - VectorType *PT = 0; - - LLVMContextImpl *pImpl = ElementType->getContext().pImpl; - - PT = pImpl->VectorTypes.get(PVT); - - if (!PT) { - pImpl->VectorTypes.add(PVT, PT = new VectorType(ElementType, NumElements)); +StructType *StructType::createNamed(StringRef Name, Type *type, ...) { + assert(type != 0 && "Cannot create a struct type with no elements with this"); + LLVMContext &Ctx = type->getContext(); + va_list ap; + SmallVector<llvm::Type*, 8> StructFields; + va_start(ap, type); + while (type) { + StructFields.push_back(type); + type = va_arg(ap, llvm::Type*); } -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *PT << "\n"); -#endif - return PT; -} - -bool VectorType::isValidElementType(const Type *ElemTy) { - return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() || - ElemTy->isOpaqueTy(); -} - -//===----------------------------------------------------------------------===// -// Struct Type Factory. -// - -StructType *StructType::get(LLVMContext &Context, bool isPacked) { - return get(Context, llvm::ArrayRef<const Type*>(), isPacked); + return llvm::StructType::createNamed(Ctx, Name, StructFields); } - -StructType *StructType::get(LLVMContext &Context, - ArrayRef<const Type*> ETypes, - bool isPacked) { - StructValType STV(ETypes, isPacked); - StructType *ST = 0; - - LLVMContextImpl *pImpl = Context.pImpl; +StringRef StructType::getName() const { + assert(!isAnonymous() && "Anonymous structs never have names"); + if (SymbolTableEntry == 0) return StringRef(); - ST = pImpl->StructTypes.get(STV); - - if (!ST) { - // Value not found. Derive a new type! - ST = (StructType*) operator new(sizeof(StructType) + - sizeof(PATypeHandle) * ETypes.size()); - new (ST) StructType(Context, ETypes, isPacked); - pImpl->StructTypes.add(STV, ST); - } -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *ST << "\n"); -#endif - return ST; + return ((StringMapEntry<StructType*> *)SymbolTableEntry)->getKey(); } -StructType *StructType::get(const Type *type, ...) { +void StructType::setBody(Type *type, ...) { assert(type != 0 && "Cannot create a struct type with no elements with this"); - LLVMContext &Ctx = type->getContext(); va_list ap; - SmallVector<const llvm::Type*, 8> StructFields; + SmallVector<llvm::Type*, 8> StructFields; va_start(ap, type); while (type) { StructFields.push_back(type); type = va_arg(ap, llvm::Type*); } - return llvm::StructType::get(Ctx, StructFields); + setBody(StructFields); } bool StructType::isValidElementType(const Type *ElemTy) { @@ -957,267 +540,157 @@ bool StructType::isValidElementType(const Type *ElemTy) { !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy(); } - -//===----------------------------------------------------------------------===// -// Pointer Type Factory... -// - -PointerType *PointerType::get(const Type *ValueType, unsigned AddressSpace) { - assert(ValueType && "Can't get a pointer to <null> type!"); - assert(ValueType->getTypeID() != VoidTyID && - "Pointer to void is not valid, use i8* instead!"); - assert(isValidElementType(ValueType) && "Invalid type for pointer element!"); - PointerValType PVT(ValueType, AddressSpace); - - PointerType *PT = 0; - - LLVMContextImpl *pImpl = ValueType->getContext().pImpl; +/// isLayoutIdentical - Return true if this is layout identical to the +/// specified struct. +bool StructType::isLayoutIdentical(const StructType *Other) const { + if (this == Other) return true; - PT = pImpl->PointerTypes.get(PVT); + if (isPacked() != Other->isPacked() || + getNumElements() != Other->getNumElements()) + return false; - if (!PT) { - // Value not found. Derive a new type! - pImpl->PointerTypes.add(PVT, PT = new PointerType(ValueType, AddressSpace)); - } -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *PT << "\n"); -#endif - return PT; + return std::equal(element_begin(), element_end(), Other->element_begin()); } -const PointerType *Type::getPointerTo(unsigned addrs) const { - return PointerType::get(this, addrs); -} -bool PointerType::isValidElementType(const Type *ElemTy) { - return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() && - !ElemTy->isMetadataTy(); +/// getTypeByName - Return the type with the specified name, or null if there +/// is none by that name. +StructType *Module::getTypeByName(StringRef Name) const { + StringMap<StructType*>::iterator I = + getContext().pImpl->NamedStructTypes.find(Name); + if (I != getContext().pImpl->NamedStructTypes.end()) + return I->second; + return 0; } //===----------------------------------------------------------------------===// -// Opaque Type Factory... -// +// CompositeType Implementation +//===----------------------------------------------------------------------===// -OpaqueType *OpaqueType::get(LLVMContext &C) { - OpaqueType *OT = new OpaqueType(C); // All opaque types are distinct. - LLVMContextImpl *pImpl = C.pImpl; - pImpl->OpaqueTypes.insert(OT); - return OT; +Type *CompositeType::getTypeAtIndex(const Value *V) const { + if (const StructType *STy = dyn_cast<StructType>(this)) { + unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue(); + assert(indexValid(Idx) && "Invalid structure index!"); + return STy->getElementType(Idx); + } + + return cast<SequentialType>(this)->getElementType(); +} +Type *CompositeType::getTypeAtIndex(unsigned Idx) const { + if (const StructType *STy = dyn_cast<StructType>(this)) { + assert(indexValid(Idx) && "Invalid structure index!"); + return STy->getElementType(Idx); + } + + return cast<SequentialType>(this)->getElementType(); +} +bool CompositeType::indexValid(const Value *V) const { + if (const StructType *STy = dyn_cast<StructType>(this)) { + // Structure indexes require 32-bit integer constants. + if (V->getType()->isIntegerTy(32)) + if (const ConstantInt *CU = dyn_cast<ConstantInt>(V)) + return CU->getZExtValue() < STy->getNumElements(); + return false; + } + + // Sequential types can be indexed by any integer. + return V->getType()->isIntegerTy(); } +bool CompositeType::indexValid(unsigned Idx) const { + if (const StructType *STy = dyn_cast<StructType>(this)) + return Idx < STy->getNumElements(); + // Sequential types can be indexed by any integer. + return true; +} //===----------------------------------------------------------------------===// -// Derived Type Refinement Functions +// ArrayType Implementation //===----------------------------------------------------------------------===// -// addAbstractTypeUser - Notify an abstract type that there is a new user of -// it. This function is called primarily by the PATypeHandle class. -void Type::addAbstractTypeUser(AbstractTypeUser *U) const { - assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!"); - AbstractTypeUsers.push_back(U); +ArrayType::ArrayType(Type *ElType, uint64_t NumEl) + : SequentialType(ArrayTyID, ElType) { + NumElements = NumEl; } -// removeAbstractTypeUser - Notify an abstract type that a user of the class -// no longer has a handle to the type. This function is called primarily by -// the PATypeHandle class. When there are no users of the abstract type, it -// is annihilated, because there is no way to get a reference to it ever again. -// -void Type::removeAbstractTypeUser(AbstractTypeUser *U) const { - - // Search from back to front because we will notify users from back to - // front. Also, it is likely that there will be a stack like behavior to - // users that register and unregister users. - // - unsigned i; - for (i = AbstractTypeUsers.size(); AbstractTypeUsers[i-1] != U; --i) - assert(i != 0 && "AbstractTypeUser not in user list!"); - - --i; // Convert to be in range 0 <= i < size() - assert(i < AbstractTypeUsers.size() && "Index out of range!"); // Wraparound? - - AbstractTypeUsers.erase(AbstractTypeUsers.begin()+i); - -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << " remAbstractTypeUser[" << (void*)this << ", " - << *this << "][" << i << "] User = " << U << "\n"); -#endif - - if (AbstractTypeUsers.empty() && getRefCount() == 0 && isAbstract()) { -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "DELETEing unused abstract type: <" << *this - << ">[" << (void*)this << "]" << "\n"); -#endif +ArrayType *ArrayType::get(const Type *elementType, uint64_t NumElements) { + Type *ElementType = const_cast<Type*>(elementType); + assert(isValidElementType(ElementType) && "Invalid type for array element!"); + + ArrayType *&Entry = ElementType->getContext().pImpl + ->ArrayTypes[std::make_pair(ElementType, NumElements)]; - this->destroy(); - } + if (Entry == 0) + Entry = new ArrayType(ElementType, NumElements); + return Entry; } -// refineAbstractTypeTo - This function is used when it is discovered -// that the 'this' abstract type is actually equivalent to the NewType -// specified. This causes all users of 'this' to switch to reference the more -// concrete type NewType and for 'this' to be deleted. Only used for internal -// callers. -// -void DerivedType::refineAbstractTypeTo(const Type *NewType) { - assert(isAbstract() && "refineAbstractTypeTo: Current type is not abstract!"); - assert(this != NewType && "Can't refine to myself!"); - assert(ForwardType == 0 && "This type has already been refined!"); - -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "REFINING abstract type [" << (void*)this << " " - << *this << "] to [" << (void*)NewType << " " - << *NewType << "]!\n"); -#endif - - // Make sure to put the type to be refined to into a holder so that if IT gets - // refined, that we will not continue using a dead reference... - // - PATypeHolder NewTy(NewType); - // Any PATypeHolders referring to this type will now automatically forward to - // the type we are resolved to. - ForwardType = NewType; - if (ForwardType->isAbstract()) - ForwardType->addRef(); - - // Add a self use of the current type so that we don't delete ourself until - // after the function exits. - // - PATypeHolder CurrentTy(this); - - // To make the situation simpler, we ask the subclass to remove this type from - // the type map, and to replace any type uses with uses of non-abstract types. - // This dramatically limits the amount of recursive type trouble we can find - // ourselves in. - dropAllTypeUses(); - - // Iterate over all of the uses of this type, invoking callback. Each user - // should remove itself from our use list automatically. We have to check to - // make sure that NewTy doesn't _become_ 'this'. If it does, resolving types - // will not cause users to drop off of the use list. If we resolve to ourself - // we succeed! - // - while (!AbstractTypeUsers.empty() && NewTy != this) { - AbstractTypeUser *User = AbstractTypeUsers.back(); - - unsigned OldSize = AbstractTypeUsers.size(); (void)OldSize; -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << " REFINING user " << OldSize-1 << "[" << (void*)User - << "] of abstract type [" << (void*)this << " " - << *this << "] to [" << (void*)NewTy.get() << " " - << *NewTy << "]!\n"); -#endif - User->refineAbstractType(this, NewTy); - - assert(AbstractTypeUsers.size() != OldSize && - "AbsTyUser did not remove self from user list!"); - } - - // If we were successful removing all users from the type, 'this' will be - // deleted when the last PATypeHolder is destroyed or updated from this type. - // This may occur on exit of this function, as the CurrentTy object is - // destroyed. -} - -// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type that -// the current type has transitioned from being abstract to being concrete. -// -void DerivedType::notifyUsesThatTypeBecameConcrete() { -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "typeIsREFINED type: " << (void*)this << " " << *this <<"\n"); -#endif - - unsigned OldSize = AbstractTypeUsers.size(); (void)OldSize; - while (!AbstractTypeUsers.empty()) { - AbstractTypeUser *ATU = AbstractTypeUsers.back(); - ATU->typeBecameConcrete(this); - - assert(AbstractTypeUsers.size() < OldSize-- && - "AbstractTypeUser did not remove itself from the use list!"); - } +bool ArrayType::isValidElementType(const Type *ElemTy) { + return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() && + !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy(); } -// refineAbstractType - Called when a contained type is found to be more -// concrete - this could potentially change us from an abstract type to a -// concrete type. -// -void FunctionType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - LLVMContextImpl *pImpl = OldType->getContext().pImpl; - pImpl->FunctionTypes.RefineAbstractType(this, OldType, NewType); -} +//===----------------------------------------------------------------------===// +// VectorType Implementation +//===----------------------------------------------------------------------===// -void FunctionType::typeBecameConcrete(const DerivedType *AbsTy) { - LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; - pImpl->FunctionTypes.TypeBecameConcrete(this, AbsTy); +VectorType::VectorType(Type *ElType, unsigned NumEl) + : SequentialType(VectorTyID, ElType) { + NumElements = NumEl; } - -// refineAbstractType - Called when a contained type is found to be more -// concrete - this could potentially change us from an abstract type to a -// concrete type. -// -void ArrayType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - LLVMContextImpl *pImpl = OldType->getContext().pImpl; - pImpl->ArrayTypes.RefineAbstractType(this, OldType, NewType); +VectorType *VectorType::get(const Type *elementType, unsigned NumElements) { + Type *ElementType = const_cast<Type*>(elementType); + assert(NumElements > 0 && "#Elements of a VectorType must be greater than 0"); + assert(isValidElementType(ElementType) && + "Elements of a VectorType must be a primitive type"); + + VectorType *&Entry = ElementType->getContext().pImpl + ->VectorTypes[std::make_pair(ElementType, NumElements)]; + + if (Entry == 0) + Entry = new VectorType(ElementType, NumElements); + return Entry; } -void ArrayType::typeBecameConcrete(const DerivedType *AbsTy) { - LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; - pImpl->ArrayTypes.TypeBecameConcrete(this, AbsTy); +bool VectorType::isValidElementType(const Type *ElemTy) { + return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy(); } -// refineAbstractType - Called when a contained type is found to be more -// concrete - this could potentially change us from an abstract type to a -// concrete type. -// -void VectorType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - LLVMContextImpl *pImpl = OldType->getContext().pImpl; - pImpl->VectorTypes.RefineAbstractType(this, OldType, NewType); -} +//===----------------------------------------------------------------------===// +// PointerType Implementation +//===----------------------------------------------------------------------===// -void VectorType::typeBecameConcrete(const DerivedType *AbsTy) { - LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; - pImpl->VectorTypes.TypeBecameConcrete(this, AbsTy); -} +PointerType *PointerType::get(const Type *eltTy, unsigned AddressSpace) { + Type *EltTy = const_cast<Type*>(eltTy); + assert(EltTy && "Can't get a pointer to <null> type!"); + assert(isValidElementType(EltTy) && "Invalid type for pointer element!"); + + LLVMContextImpl *CImpl = EltTy->getContext().pImpl; + + // Since AddressSpace #0 is the common case, we special case it. + PointerType *&Entry = AddressSpace == 0 ? CImpl->PointerTypes[EltTy] + : CImpl->ASPointerTypes[std::make_pair(EltTy, AddressSpace)]; -// refineAbstractType - Called when a contained type is found to be more -// concrete - this could potentially change us from an abstract type to a -// concrete type. -// -void StructType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - LLVMContextImpl *pImpl = OldType->getContext().pImpl; - pImpl->StructTypes.RefineAbstractType(this, OldType, NewType); + if (Entry == 0) + Entry = new PointerType(EltTy, AddressSpace); + return Entry; } -void StructType::typeBecameConcrete(const DerivedType *AbsTy) { - LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; - pImpl->StructTypes.TypeBecameConcrete(this, AbsTy); -} -// refineAbstractType - Called when a contained type is found to be more -// concrete - this could potentially change us from an abstract type to a -// concrete type. -// -void PointerType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - LLVMContextImpl *pImpl = OldType->getContext().pImpl; - pImpl->PointerTypes.RefineAbstractType(this, OldType, NewType); +PointerType::PointerType(Type *E, unsigned AddrSpace) + : SequentialType(PointerTyID, E) { + setSubclassData(AddrSpace); } -void PointerType::typeBecameConcrete(const DerivedType *AbsTy) { - LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; - pImpl->PointerTypes.TypeBecameConcrete(this, AbsTy); +PointerType *Type::getPointerTo(unsigned addrs) const { + return PointerType::get(this, addrs); } -namespace llvm { -raw_ostream &operator<<(raw_ostream &OS, const Type &T) { - T.print(OS); - return OS; -} +bool PointerType::isValidElementType(const Type *ElemTy) { + return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() && + !ElemTy->isMetadataTy(); } diff --git a/lib/VMCore/TypeSymbolTable.cpp b/lib/VMCore/TypeSymbolTable.cpp deleted file mode 100644 index 80c6a74..0000000 --- a/lib/VMCore/TypeSymbolTable.cpp +++ /dev/null @@ -1,168 +0,0 @@ -//===-- TypeSymbolTable.cpp - Implement the TypeSymbolTable class ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the TypeSymbolTable class for the VMCore library. -// -//===----------------------------------------------------------------------===// - -#include "llvm/TypeSymbolTable.h" -#include "llvm/DerivedTypes.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/raw_ostream.h" -#include <algorithm> -using namespace llvm; - -#define DEBUG_SYMBOL_TABLE 0 -#define DEBUG_ABSTYPE 0 - -TypeSymbolTable::~TypeSymbolTable() { - // Drop all abstract type references in the type plane... - for (iterator TI = tmap.begin(), TE = tmap.end(); TI != TE; ++TI) { - if (TI->second->isAbstract()) // If abstract, drop the reference... - cast<DerivedType>(TI->second)->removeAbstractTypeUser(this); - } -} - -std::string TypeSymbolTable::getUniqueName(StringRef BaseName) const { - std::string TryName = BaseName; - - const_iterator End = tmap.end(); - - // See if the name exists - while (tmap.find(TryName) != End) // Loop until we find a free - TryName = BaseName.str() + utostr(++LastUnique); // name in the symbol table - return TryName; -} - -// lookup a type by name - returns null on failure -Type* TypeSymbolTable::lookup(StringRef Name) const { - const_iterator TI = tmap.find(Name); - Type* result = 0; - if (TI != tmap.end()) - result = const_cast<Type*>(TI->second); - return result; -} - -// remove - Remove a type from the symbol table... -Type* TypeSymbolTable::remove(iterator Entry) { - assert(Entry != tmap.end() && "Invalid entry to remove!"); - const Type* Result = Entry->second; - -#if DEBUG_SYMBOL_TABLE - dump(); - dbgs() << " Removing Value: " << *Result << "\n"; -#endif - - tmap.erase(Entry); - - // If we are removing an abstract type, remove the symbol table from it's use - // list... - if (Result->isAbstract()) { -#if DEBUG_ABSTYPE - dbgs() << "Removing abstract type from symtab" - << *Result << "\n"; -#endif - cast<DerivedType>(Result)->removeAbstractTypeUser(this); - } - - return const_cast<Type*>(Result); -} - - -// insert - Insert a type into the symbol table with the specified name... -void TypeSymbolTable::insert(StringRef Name, const Type* T) { - assert(T && "Can't insert null type into symbol table!"); - - if (tmap.insert(std::make_pair(Name, T)).second) { - // Type inserted fine with no conflict. - -#if DEBUG_SYMBOL_TABLE - dump(); - dbgs() << " Inserted type: " << Name << ": " << *T << "\n"; -#endif - } else { - // If there is a name conflict... - - // Check to see if there is a naming conflict. If so, rename this type! - std::string UniqueName = Name; - if (lookup(Name)) - UniqueName = getUniqueName(Name); - -#if DEBUG_SYMBOL_TABLE - dump(); - dbgs() << " Inserting type: " << UniqueName << ": " - << *T << "\n"; -#endif - - // Insert the tmap entry - tmap.insert(make_pair(UniqueName, T)); - } - - // If we are adding an abstract type, add the symbol table to it's use list. - if (T->isAbstract()) { - cast<DerivedType>(T)->addAbstractTypeUser(this); -#if DEBUG_ABSTYPE - dbgs() << "Added abstract type to ST: " << *T << "\n"; -#endif - } -} - -// This function is called when one of the types in the type plane are refined -void TypeSymbolTable::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - // Loop over all of the types in the symbol table, replacing any references - // to OldType with references to NewType. Note that there may be multiple - // occurrences, and although we only need to remove one at a time, it's - // faster to remove them all in one pass. - // - for (iterator I = begin(), E = end(); I != E; ++I) { - // FIXME when Types aren't const. - if (I->second == const_cast<DerivedType *>(OldType)) { -#if DEBUG_ABSTYPE - dbgs() << "Removing type " << *OldType << "\n"; -#endif - OldType->removeAbstractTypeUser(this); - - // TODO FIXME when types aren't const - I->second = const_cast<Type *>(NewType); - if (NewType->isAbstract()) { -#if DEBUG_ABSTYPE - dbgs() << "Added type " << *NewType << "\n"; -#endif - cast<DerivedType>(NewType)->addAbstractTypeUser(this); - } - } - } -} - - -// Handle situation where type becomes Concreate from Abstract -void TypeSymbolTable::typeBecameConcrete(const DerivedType *AbsTy) { - // Loop over all of the types in the symbol table, dropping any abstract - // type user entries for AbsTy which occur because there are names for the - // type. - for (iterator TI = begin(), TE = end(); TI != TE; ++TI) - if (TI->second == const_cast<Type*>(static_cast<const Type*>(AbsTy))) - AbsTy->removeAbstractTypeUser(this); -} - -static void DumpTypes(const std::pair<const std::string, const Type*>& T ) { - dbgs() << " '" << T.first << "' = "; - T.second->dump(); - dbgs() << "\n"; -} - -void TypeSymbolTable::dump() const { - dbgs() << "TypeSymbolPlane: "; - for_each(tmap.begin(), tmap.end(), DumpTypes); -} - diff --git a/lib/VMCore/TypesContext.h b/lib/VMCore/TypesContext.h deleted file mode 100644 index ad09478..0000000 --- a/lib/VMCore/TypesContext.h +++ /dev/null @@ -1,426 +0,0 @@ -//===-- TypesContext.h - Types-related Context Internals ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines various helper methods and classes used by -// LLVMContextImpl for creating and managing types. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TYPESCONTEXT_H -#define LLVM_TYPESCONTEXT_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/STLExtras.h" -#include <map> - - -//===----------------------------------------------------------------------===// -// Derived Type Factory Functions -//===----------------------------------------------------------------------===// -namespace llvm { - -/// getSubElementHash - Generate a hash value for all of the SubType's of this -/// type. The hash value is guaranteed to be zero if any of the subtypes are -/// an opaque type. Otherwise we try to mix them in as well as possible, but do -/// not look at the subtype's subtype's. -static unsigned getSubElementHash(const Type *Ty) { - unsigned HashVal = 0; - for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); - I != E; ++I) { - HashVal *= 32; - const Type *SubTy = I->get(); - HashVal += SubTy->getTypeID(); - switch (SubTy->getTypeID()) { - default: break; - case Type::OpaqueTyID: return 0; // Opaque -> hash = 0 no matter what. - case Type::IntegerTyID: - HashVal ^= (cast<IntegerType>(SubTy)->getBitWidth() << 3); - break; - case Type::FunctionTyID: - HashVal ^= cast<FunctionType>(SubTy)->getNumParams()*2 + - cast<FunctionType>(SubTy)->isVarArg(); - break; - case Type::ArrayTyID: - HashVal ^= cast<ArrayType>(SubTy)->getNumElements(); - break; - case Type::VectorTyID: - HashVal ^= cast<VectorType>(SubTy)->getNumElements(); - break; - case Type::StructTyID: - HashVal ^= cast<StructType>(SubTy)->getNumElements(); - break; - case Type::PointerTyID: - HashVal ^= cast<PointerType>(SubTy)->getAddressSpace(); - break; - } - } - return HashVal ? HashVal : 1; // Do not return zero unless opaque subty. -} - -//===----------------------------------------------------------------------===// -// Integer Type Factory... -// -class IntegerValType { - uint32_t bits; -public: - IntegerValType(uint32_t numbits) : bits(numbits) {} - - static IntegerValType get(const IntegerType *Ty) { - return IntegerValType(Ty->getBitWidth()); - } - - static unsigned hashTypeStructure(const IntegerType *Ty) { - return (unsigned)Ty->getBitWidth(); - } - - inline bool operator<(const IntegerValType &IVT) const { - return bits < IVT.bits; - } -}; - -// PointerValType - Define a class to hold the key that goes into the TypeMap -// -class PointerValType { - const Type *ValTy; - unsigned AddressSpace; -public: - PointerValType(const Type *val, unsigned as) : ValTy(val), AddressSpace(as) {} - - static PointerValType get(const PointerType *PT) { - return PointerValType(PT->getElementType(), PT->getAddressSpace()); - } - - static unsigned hashTypeStructure(const PointerType *PT) { - return getSubElementHash(PT); - } - - bool operator<(const PointerValType &MTV) const { - if (AddressSpace < MTV.AddressSpace) return true; - return AddressSpace == MTV.AddressSpace && ValTy < MTV.ValTy; - } -}; - -//===----------------------------------------------------------------------===// -// Array Type Factory... -// -class ArrayValType { - const Type *ValTy; - uint64_t Size; -public: - ArrayValType(const Type *val, uint64_t sz) : ValTy(val), Size(sz) {} - - static ArrayValType get(const ArrayType *AT) { - return ArrayValType(AT->getElementType(), AT->getNumElements()); - } - - static unsigned hashTypeStructure(const ArrayType *AT) { - return (unsigned)AT->getNumElements(); - } - - inline bool operator<(const ArrayValType &MTV) const { - if (Size < MTV.Size) return true; - return Size == MTV.Size && ValTy < MTV.ValTy; - } -}; - -//===----------------------------------------------------------------------===// -// Vector Type Factory... -// -class VectorValType { - const Type *ValTy; - unsigned Size; -public: - VectorValType(const Type *val, int sz) : ValTy(val), Size(sz) {} - - static VectorValType get(const VectorType *PT) { - return VectorValType(PT->getElementType(), PT->getNumElements()); - } - - static unsigned hashTypeStructure(const VectorType *PT) { - return PT->getNumElements(); - } - - inline bool operator<(const VectorValType &MTV) const { - if (Size < MTV.Size) return true; - return Size == MTV.Size && ValTy < MTV.ValTy; - } -}; - -// StructValType - Define a class to hold the key that goes into the TypeMap -// -class StructValType { - std::vector<const Type*> ElTypes; - bool packed; -public: - StructValType(ArrayRef<const Type*> args, bool isPacked) - : ElTypes(args.vec()), packed(isPacked) {} - - static StructValType get(const StructType *ST) { - std::vector<const Type *> ElTypes; - ElTypes.reserve(ST->getNumElements()); - for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) - ElTypes.push_back(ST->getElementType(i)); - - return StructValType(ElTypes, ST->isPacked()); - } - - static unsigned hashTypeStructure(const StructType *ST) { - return ST->getNumElements(); - } - - inline bool operator<(const StructValType &STV) const { - if (ElTypes < STV.ElTypes) return true; - else if (ElTypes > STV.ElTypes) return false; - else return (int)packed < (int)STV.packed; - } -}; - -// FunctionValType - Define a class to hold the key that goes into the TypeMap -// -class FunctionValType { - const Type *RetTy; - std::vector<const Type*> ArgTypes; - bool isVarArg; -public: - FunctionValType(const Type *ret, ArrayRef<const Type*> args, bool isVA) - : RetTy(ret), ArgTypes(args.vec()), isVarArg(isVA) {} - - static FunctionValType get(const FunctionType *FT); - - static unsigned hashTypeStructure(const FunctionType *FT) { - unsigned Result = FT->getNumParams()*2 + FT->isVarArg(); - return Result; - } - - inline bool operator<(const FunctionValType &MTV) const { - if (RetTy < MTV.RetTy) return true; - if (RetTy > MTV.RetTy) return false; - if (isVarArg < MTV.isVarArg) return true; - if (isVarArg > MTV.isVarArg) return false; - if (ArgTypes < MTV.ArgTypes) return true; - if (ArgTypes > MTV.ArgTypes) return false; - return false; - } -}; - -class TypeMapBase { -protected: - /// TypesByHash - Keep track of types by their structure hash value. Note - /// that we only keep track of types that have cycles through themselves in - /// this map. - /// - std::multimap<unsigned, PATypeHolder> TypesByHash; - - ~TypeMapBase() { - // PATypeHolder won't destroy non-abstract types. - // We can't destroy them by simply iterating, because - // they may contain references to each-other. - for (std::multimap<unsigned, PATypeHolder>::iterator I - = TypesByHash.begin(), E = TypesByHash.end(); I != E; ++I) { - Type *Ty = const_cast<Type*>(I->second.Ty); - I->second.destroy(); - // We can't invoke destroy or delete, because the type may - // contain references to already freed types. - // So we have to destruct the object the ugly way. - if (Ty) { - Ty->AbstractTypeUsers.clear(); - static_cast<const Type*>(Ty)->Type::~Type(); - operator delete(Ty); - } - } - } - -public: - void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) { - std::multimap<unsigned, PATypeHolder>::iterator I = - TypesByHash.lower_bound(Hash); - for (; I != TypesByHash.end() && I->first == Hash; ++I) { - if (I->second == Ty) { - TypesByHash.erase(I); - return; - } - } - - // This must be do to an opaque type that was resolved. Switch down to hash - // code of zero. - assert(Hash && "Didn't find type entry!"); - RemoveFromTypesByHash(0, Ty); - } - - /// TypeBecameConcrete - When Ty gets a notification that TheType just became - /// concrete, drop uses and make Ty non-abstract if we should. - void TypeBecameConcrete(DerivedType *Ty, const DerivedType *TheType) { - // If the element just became concrete, remove 'ty' from the abstract - // type user list for the type. Do this for as many times as Ty uses - // OldType. - for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); - I != E; ++I) - if (I->get() == TheType) - TheType->removeAbstractTypeUser(Ty); - - // If the type is currently thought to be abstract, rescan all of our - // subtypes to see if the type has just become concrete! Note that this - // may send out notifications to AbstractTypeUsers that types become - // concrete. - if (Ty->isAbstract()) - Ty->PromoteAbstractToConcrete(); - } -}; - -// TypeMap - Make sure that only one instance of a particular type may be -// created on any given run of the compiler... note that this involves updating -// our map if an abstract type gets refined somehow. -// -template<class ValType, class TypeClass> -class TypeMap : public TypeMapBase { - std::map<ValType, PATypeHolder> Map; -public: - typedef typename std::map<ValType, PATypeHolder>::iterator iterator; - - inline TypeClass *get(const ValType &V) { - iterator I = Map.find(V); - return I != Map.end() ? cast<TypeClass>((Type*)I->second.get()) : 0; - } - - inline void add(const ValType &V, TypeClass *Ty) { - Map.insert(std::make_pair(V, Ty)); - - // If this type has a cycle, remember it. - TypesByHash.insert(std::make_pair(ValType::hashTypeStructure(Ty), Ty)); - print("add"); - } - - /// RefineAbstractType - This method is called after we have merged a type - /// with another one. We must now either merge the type away with - /// some other type or reinstall it in the map with it's new configuration. - void RefineAbstractType(TypeClass *Ty, const DerivedType *OldType, - const Type *NewType) { -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "RefineAbstractType(" << (void*)OldType << "[" << *OldType - << "], " << (void*)NewType << " [" << *NewType << "])\n"); -#endif - - // Otherwise, we are changing one subelement type into another. Clearly the - // OldType must have been abstract, making us abstract. - assert(Ty->isAbstract() && "Refining a non-abstract type!"); - assert(OldType != NewType); - - // Make a temporary type holder for the type so that it doesn't disappear on - // us when we erase the entry from the map. - PATypeHolder TyHolder = Ty; - - // The old record is now out-of-date, because one of the children has been - // updated. Remove the obsolete entry from the map. - unsigned NumErased = Map.erase(ValType::get(Ty)); - assert(NumErased && "Element not found!"); (void)NumErased; - - // Remember the structural hash for the type before we start hacking on it, - // in case we need it later. - unsigned OldTypeHash = ValType::hashTypeStructure(Ty); - - // Find the type element we are refining... and change it now! - for (unsigned i = 0, e = Ty->getNumContainedTypes(); i != e; ++i) - if (Ty->ContainedTys[i] == OldType) - Ty->ContainedTys[i] = NewType; - unsigned NewTypeHash = ValType::hashTypeStructure(Ty); - - // If there are no cycles going through this node, we can do a simple, - // efficient lookup in the map, instead of an inefficient nasty linear - // lookup. - if (!TypeHasCycleThroughItself(Ty)) { - typename std::map<ValType, PATypeHolder>::iterator I; - bool Inserted; - - tie(I, Inserted) = Map.insert(std::make_pair(ValType::get(Ty), Ty)); - if (!Inserted) { - // Refined to a different type altogether? - RemoveFromTypesByHash(OldTypeHash, Ty); - - // We already have this type in the table. Get rid of the newly refined - // type. - TypeClass *NewTy = cast<TypeClass>((Type*)I->second.get()); - Ty->refineAbstractTypeTo(NewTy); - return; - } - } else { - // Now we check to see if there is an existing entry in the table which is - // structurally identical to the newly refined type. If so, this type - // gets refined to the pre-existing type. - // - std::multimap<unsigned, PATypeHolder>::iterator I, E, Entry; - tie(I, E) = TypesByHash.equal_range(NewTypeHash); - Entry = E; - for (; I != E; ++I) { - if (I->second == Ty) { - // Remember the position of the old type if we see it in our scan. - Entry = I; - continue; - } - - if (!TypesEqual(Ty, I->second)) - continue; - - TypeClass *NewTy = cast<TypeClass>((Type*)I->second.get()); - - // Remove the old entry form TypesByHash. If the hash values differ - // now, remove it from the old place. Otherwise, continue scanning - // within this hashcode to reduce work. - if (NewTypeHash != OldTypeHash) { - RemoveFromTypesByHash(OldTypeHash, Ty); - } else { - if (Entry == E) { - // Find the location of Ty in the TypesByHash structure if we - // haven't seen it already. - while (I->second != Ty) { - ++I; - assert(I != E && "Structure doesn't contain type??"); - } - Entry = I; - } - TypesByHash.erase(Entry); - } - Ty->refineAbstractTypeTo(NewTy); - return; - } - - // If there is no existing type of the same structure, we reinsert an - // updated record into the map. - Map.insert(std::make_pair(ValType::get(Ty), Ty)); - } - - // If the hash codes differ, update TypesByHash - if (NewTypeHash != OldTypeHash) { - RemoveFromTypesByHash(OldTypeHash, Ty); - TypesByHash.insert(std::make_pair(NewTypeHash, Ty)); - } - - // If the type is currently thought to be abstract, rescan all of our - // subtypes to see if the type has just become concrete! Note that this - // may send out notifications to AbstractTypeUsers that types become - // concrete. - if (Ty->isAbstract()) - Ty->PromoteAbstractToConcrete(); - } - - void print(const char *Arg) const { -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "TypeMap<>::" << Arg << " table contents:\n"); - unsigned i = 0; - for (typename std::map<ValType, PATypeHolder>::const_iterator I - = Map.begin(), E = Map.end(); I != E; ++I) - DEBUG(dbgs() << " " << (++i) << ". " << (void*)I->second.get() << " " - << *I->second.get() << "\n"); -#endif - } - - void dump() const { print("dump output"); } -}; -} - -#endif diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index a03cddc..c7a4212 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -35,22 +35,21 @@ using namespace llvm; // Value Class //===----------------------------------------------------------------------===// -static inline const Type *checkType(const Type *Ty) { +static inline Type *checkType(const Type *Ty) { assert(Ty && "Value defined with a null type: Error!"); - return Ty; + return const_cast<Type*>(Ty); } Value::Value(const Type *ty, unsigned scid) : SubclassID(scid), HasValueHandle(0), - SubclassOptionalData(0), SubclassData(0), VTy(checkType(ty)), + SubclassOptionalData(0), SubclassData(0), VTy((Type*)checkType(ty)), UseList(0), Name(0) { + // FIXME: Why isn't this in the subclass gunk?? if (isa<CallInst>(this) || isa<InvokeInst>(this)) - assert((VTy->isFirstClassType() || VTy->isVoidTy() || - ty->isOpaqueTy() || VTy->isStructTy()) && - "invalid CallInst type!"); + assert((VTy->isFirstClassType() || VTy->isVoidTy() || VTy->isStructTy()) && + "invalid CallInst type!"); else if (!isa<Constant>(this) && !isa<BasicBlock>(this)) - assert((VTy->isFirstClassType() || VTy->isVoidTy() || - ty->isOpaqueTy()) && + assert((VTy->isFirstClassType() || VTy->isVoidTy()) && "Cannot create non-first-class values except for constants!"); } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 18de671..c35d5ad 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -49,7 +49,6 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/PassManager.h" -#include "llvm/TypeSymbolTable.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/ValueTypes.h" @@ -109,54 +108,6 @@ INITIALIZE_PASS(PreVerifier, "preverify", "Preliminary module verification", static char &PreVerifyID = PreVerifier::ID; namespace { - class TypeSet : public AbstractTypeUser { - public: - TypeSet() {} - - /// Insert a type into the set of types. - bool insert(const Type *Ty) { - if (!Types.insert(Ty)) - return false; - if (Ty->isAbstract()) - Ty->addAbstractTypeUser(this); - return true; - } - - // Remove ourselves as abstract type listeners for any types that remain - // abstract when the TypeSet is destroyed. - ~TypeSet() { - for (SmallSetVector<const Type *, 16>::iterator I = Types.begin(), - E = Types.end(); I != E; ++I) { - const Type *Ty = *I; - if (Ty->isAbstract()) - Ty->removeAbstractTypeUser(this); - } - } - - // Abstract type user interface. - - /// Remove types from the set when refined. Do not insert the type it was - /// refined to because that type hasn't been verified yet. - void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { - Types.remove(OldTy); - OldTy->removeAbstractTypeUser(this); - } - - /// Stop listening for changes to a type which is no longer abstract. - void typeBecameConcrete(const DerivedType *AbsTy) { - AbsTy->removeAbstractTypeUser(this); - } - - void dump() const {} - - private: - SmallSetVector<const Type *, 16> Types; - - // Disallow copying. - TypeSet(const TypeSet &); - TypeSet &operator=(const TypeSet &); - }; - struct Verifier : public FunctionPass, public InstVisitor<Verifier> { static char ID; // Pass ID, replacement for typeid bool Broken; // Is this module found to be broken? @@ -176,9 +127,6 @@ namespace { /// an instruction in the same block. SmallPtrSet<Instruction*, 16> InstsInThisBlock; - /// Types - keep track of the types that have been checked already. - TypeSet Types; - /// MDNodes - keep track of the metadata nodes that have been checked /// already. SmallPtrSet<MDNode *, 32> MDNodes; @@ -199,7 +147,6 @@ namespace { bool doInitialization(Module &M) { Mod = &M; Context = &M.getContext(); - verifyTypeSymbolTable(M.getTypeSymbolTable()); // If this is a real pass, in a pass manager, we must abort before // returning back to the pass manager, or else the pass manager may try to @@ -285,7 +232,6 @@ namespace { // Verification methods... - void verifyTypeSymbolTable(TypeSymbolTable &ST); void visitGlobalValue(GlobalValue &GV); void visitGlobalVariable(GlobalVariable &GV); void visitGlobalAlias(GlobalAlias &GA); @@ -345,7 +291,6 @@ namespace { bool isReturnValue, const Value *V); void VerifyFunctionAttrs(const FunctionType *FT, const AttrListPtr &Attrs, const Value *V); - void VerifyType(const Type *Ty); void WriteValue(const Value *V) { if (!V) return; @@ -359,8 +304,7 @@ namespace { void WriteType(const Type *T) { if (!T) return; - MessagesStr << ' '; - WriteTypeSymbolic(MessagesStr, T, Mod); + MessagesStr << ' ' << *T; } @@ -568,11 +512,6 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) { } } -void Verifier::verifyTypeSymbolTable(TypeSymbolTable &ST) { - for (TypeSymbolTable::iterator I = ST.begin(), E = ST.end(); I != E; ++I) - VerifyType(I->second); -} - // VerifyParameterAttrs - Check the given attributes for an argument or return // value of the specified type. The value V is printed in error messages. void Verifier::VerifyParameterAttrs(Attributes Attrs, const Type *Ty, @@ -1192,11 +1131,11 @@ void Verifier::VerifyCallSite(CallSite CS) { } // Verify that there's no metadata unless it's a direct call to an intrinsic. - if (!CS.getCalledFunction() || + if (CS.getCalledFunction() == 0 || !CS.getCalledFunction()->getName().startswith("llvm.")) { for (FunctionType::param_iterator PI = FTy->param_begin(), PE = FTy->param_end(); PI != PE; ++PI) - Assert1(!PI->get()->isMetadataTy(), + Assert1(!(*PI)->isMetadataTy(), "Function has metadata parameter but isn't an intrinsic", I); } @@ -1542,69 +1481,6 @@ void Verifier::visitInstruction(Instruction &I) { } } InstsInThisBlock.insert(&I); - - VerifyType(I.getType()); -} - -/// VerifyType - Verify that a type is well formed. -/// -void Verifier::VerifyType(const Type *Ty) { - if (!Types.insert(Ty)) return; - - Assert1(Context == &Ty->getContext(), - "Type context does not match Module context!", Ty); - - switch (Ty->getTypeID()) { - case Type::FunctionTyID: { - const FunctionType *FTy = cast<FunctionType>(Ty); - - const Type *RetTy = FTy->getReturnType(); - Assert2(FunctionType::isValidReturnType(RetTy), - "Function type with invalid return type", RetTy, FTy); - VerifyType(RetTy); - - for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) { - const Type *ElTy = FTy->getParamType(i); - Assert2(FunctionType::isValidArgumentType(ElTy), - "Function type with invalid parameter type", ElTy, FTy); - VerifyType(ElTy); - } - break; - } - case Type::StructTyID: { - const StructType *STy = cast<StructType>(Ty); - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { - const Type *ElTy = STy->getElementType(i); - Assert2(StructType::isValidElementType(ElTy), - "Structure type with invalid element type", ElTy, STy); - VerifyType(ElTy); - } - break; - } - case Type::ArrayTyID: { - const ArrayType *ATy = cast<ArrayType>(Ty); - Assert1(ArrayType::isValidElementType(ATy->getElementType()), - "Array type with invalid element type", ATy); - VerifyType(ATy->getElementType()); - break; - } - case Type::PointerTyID: { - const PointerType *PTy = cast<PointerType>(Ty); - Assert1(PointerType::isValidElementType(PTy->getElementType()), - "Pointer type with invalid element type", PTy); - VerifyType(PTy->getElementType()); - break; - } - case Type::VectorTyID: { - const VectorType *VTy = cast<VectorType>(Ty); - Assert1(VectorType::isValidElementType(VTy->getElementType()), - "Vector type with invalid element type", VTy); - VerifyType(VTy->getElementType()); - break; - } - default: - break; - } } // Flags used by TableGen to mark intrinsic parameters with the |