X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAsmParser%2FLLParser.cpp;h=f9db40915ae07927fef1390eb26e8e43a1324923;hb=6f83c9c6ef0e7f79825a0a8f22941815e4b684c7;hp=909370cb669dca3916da9d861aeef08c35b28562;hpb=385f5a99ecc7fee48a7539bc63d3e1d3b5089c0d;p=oota-llvm.git diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 909370cb669..f9db40915ae 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -18,11 +18,14 @@ #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" #include "llvm/MDNode.h" #include "llvm/Module.h" +#include "llvm/Operator.h" #include "llvm/ValueSymbolTable.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -39,7 +42,8 @@ namespace llvm { t_Null, t_Undef, t_Zero, // No value. t_EmptyArray, // No value: [] t_Constant, // Value in ConstantVal. - t_InlineAsm // Value in StrVal/StrVal2/UIntVal. + t_InlineAsm, // Value in StrVal/StrVal2/UIntVal. + t_Metadata // Value in MetadataVal. } Kind; LLParser::LocTy Loc; @@ -48,6 +52,7 @@ namespace llvm { APSInt APSIntVal; APFloat APFloatVal; Constant *ConstantVal; + MetadataBase *MetadataVal; ValID() : APFloatVal(0.0) {} }; } @@ -83,6 +88,12 @@ bool LLParser::ValidateEndOfModule() { "use of undefined value '@" + utostr(ForwardRefValIDs.begin()->first) + "'"); + if (!ForwardRefMDNodes.empty()) + return Error(ForwardRefMDNodes.begin()->second.second, + "use of undefined metadata '!" + + utostr(ForwardRefMDNodes.begin()->first) + "'"); + + // Look for intrinsic functions and CallInst that need to be upgraded for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ) UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove @@ -109,27 +120,29 @@ bool LLParser::ParseTopLevelEntities() { case lltok::StringConstant: // FIXME: REMOVE IN LLVM 3.0 case lltok::LocalVar: if (ParseNamedType()) return true; break; case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break; + case lltok::Metadata: if (ParseStandaloneMetadata()) return true; break; // The Global variable production with no name can have many different // optional leading prefixes, the production is: // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalThreadLocal // OptionalAddrSpace ('constant'|'global') ... - case lltok::kw_private: // OptionalLinkage - case lltok::kw_internal: // OptionalLinkage - case lltok::kw_weak: // OptionalLinkage - case lltok::kw_weak_odr: // OptionalLinkage - case lltok::kw_linkonce: // OptionalLinkage - case lltok::kw_linkonce_odr: // OptionalLinkage - case lltok::kw_appending: // OptionalLinkage - case lltok::kw_dllexport: // OptionalLinkage - case lltok::kw_common: // OptionalLinkage - case lltok::kw_dllimport: // OptionalLinkage - case lltok::kw_extern_weak: // OptionalLinkage - case lltok::kw_external: { // OptionalLinkage + case lltok::kw_private : // OptionalLinkage + case lltok::kw_linker_private: // OptionalLinkage + case lltok::kw_internal: // OptionalLinkage + case lltok::kw_weak: // OptionalLinkage + case lltok::kw_weak_odr: // OptionalLinkage + case lltok::kw_linkonce: // OptionalLinkage + case lltok::kw_linkonce_odr: // OptionalLinkage + case lltok::kw_appending: // OptionalLinkage + case lltok::kw_dllexport: // OptionalLinkage + case lltok::kw_common: // OptionalLinkage + case lltok::kw_dllimport: // OptionalLinkage + case lltok::kw_extern_weak: // OptionalLinkage + case lltok::kw_external: { // OptionalLinkage unsigned Linkage, Visibility; if (ParseOptionalLinkage(Linkage) || ParseOptionalVisibility(Visibility) || - ParseGlobal("", 0, Linkage, true, Visibility)) + ParseGlobal("", SMLoc(), Linkage, true, Visibility)) return true; break; } @@ -138,7 +151,7 @@ bool LLParser::ParseTopLevelEntities() { case lltok::kw_protected: { // OptionalVisibility unsigned Visibility; if (ParseOptionalVisibility(Visibility) || - ParseGlobal("", 0, 0, false, Visibility)) + ParseGlobal("", SMLoc(), 0, false, Visibility)) return true; break; } @@ -147,7 +160,7 @@ bool LLParser::ParseTopLevelEntities() { case lltok::kw_addrspace: // OptionalAddrSpace case lltok::kw_constant: // GlobalType case lltok::kw_global: // GlobalType - if (ParseGlobal("", 0, 0, false, 0)) return true; + if (ParseGlobal("", SMLoc(), 0, false, 0)) return true; break; } } @@ -355,6 +368,90 @@ bool LLParser::ParseNamedGlobal() { return ParseAlias(Name, NameLoc, Visibility); } +// MDString: +// ::= '!' STRINGCONSTANT +bool LLParser::ParseMDString(MetadataBase *&MDS) { + std::string Str; + if (ParseStringConstant(Str)) return true; + MDS = Context.getMDString(Str); + return false; +} + +// MDNode: +// ::= '!' MDNodeNumber +bool LLParser::ParseMDNode(MetadataBase *&Node) { + // !{ ..., !42, ... } + unsigned MID = 0; + if (ParseUInt32(MID)) return true; + + // Check existing MDNode. + std::map::iterator I = MetadataCache.find(MID); + if (I != MetadataCache.end()) { + Node = I->second; + return false; + } + + // Check known forward references. + std::map >::iterator + FI = ForwardRefMDNodes.find(MID); + if (FI != ForwardRefMDNodes.end()) { + Node = FI->second.first; + return false; + } + + // Create MDNode forward reference + SmallVector Elts; + std::string FwdRefName = "llvm.mdnode.fwdref." + utostr(MID); + Elts.push_back(Context.getMDString(FwdRefName)); + MDNode *FwdNode = Context.getMDNode(Elts.data(), Elts.size()); + ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc()); + Node = FwdNode; + return false; +} + +/// ParseStandaloneMetadata: +/// !42 = !{...} +bool LLParser::ParseStandaloneMetadata() { + assert(Lex.getKind() == lltok::Metadata); + Lex.Lex(); + unsigned MetadataID = 0; + if (ParseUInt32(MetadataID)) + return true; + if (MetadataCache.find(MetadataID) != MetadataCache.end()) + return TokError("Metadata id is already used"); + if (ParseToken(lltok::equal, "expected '=' here")) + return true; + + LocTy TyLoc; + PATypeHolder Ty(Type::VoidTy); + if (ParseType(Ty, TyLoc)) + return true; + + if (Lex.getKind() != lltok::Metadata) + return TokError("Expected metadata here"); + + Lex.Lex(); + if (Lex.getKind() != lltok::lbrace) + return TokError("Expected '{' here"); + + SmallVector Elts; + if (ParseMDNodeVector(Elts) + || ParseToken(lltok::rbrace, "expected end of metadata node")) + return true; + + MDNode *Init = Context.getMDNode(Elts.data(), Elts.size()); + MetadataCache[MetadataID] = Init; + std::map >::iterator + FI = ForwardRefMDNodes.find(MetadataID); + if (FI != ForwardRefMDNodes.end()) { + MDNode *FwdNode = cast(FI->second.first); + FwdNode->replaceAllUsesWith(Init); + ForwardRefMDNodes.erase(FI); + } + + return false; +} + /// ParseAlias: /// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee /// Aliasee @@ -377,7 +474,8 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, Linkage != GlobalValue::WeakAnyLinkage && Linkage != GlobalValue::WeakODRLinkage && Linkage != GlobalValue::InternalLinkage && - Linkage != GlobalValue::PrivateLinkage) + Linkage != GlobalValue::PrivateLinkage && + Linkage != GlobalValue::LinkerPrivateLinkage) return Error(LinkageLoc, "invalid linkage type for alias"); Constant *Aliasee; @@ -486,8 +584,8 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, } if (GV == 0) { - GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, 0, Name, - M, false, AddrSpace); + GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, 0, + Name, 0, false, AddrSpace); } else { if (GV->getType()->getElementType() != Ty) return Error(TyLoc, @@ -577,8 +675,8 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty, FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); } else { - FwdVal = new GlobalVariable(PTy->getElementType(), false, - GlobalValue::ExternalWeakLinkage, 0, Name, M); + FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, + GlobalValue::ExternalWeakLinkage, 0, Name); } ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); @@ -621,8 +719,8 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) { } FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M); } else { - FwdVal = new GlobalVariable(PTy->getElementType(), false, - GlobalValue::ExternalWeakLinkage, 0, "", M); + FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, + GlobalValue::ExternalWeakLinkage, 0, ""); } ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); @@ -732,6 +830,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break; case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break; case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break; + case lltok::kw_naked: Attrs |= Attribute::Naked; break; case lltok::kw_align: { unsigned Alignment; @@ -748,6 +847,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { /// ParseOptionalLinkage /// ::= /*empty*/ /// ::= 'private' +/// ::= 'linker_private' /// ::= 'internal' /// ::= 'weak' /// ::= 'weak_odr' @@ -762,22 +862,23 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { HasLinkage = false; switch (Lex.getKind()) { - default: Res = GlobalValue::ExternalLinkage; return false; - case lltok::kw_private: Res = GlobalValue::PrivateLinkage; break; - case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break; - case lltok::kw_weak: Res = GlobalValue::WeakAnyLinkage; break; - case lltok::kw_weak_odr: Res = GlobalValue::WeakODRLinkage; break; - case lltok::kw_linkonce: Res = GlobalValue::LinkOnceAnyLinkage; break; - case lltok::kw_linkonce_odr: Res = GlobalValue::LinkOnceODRLinkage; break; + default: Res=GlobalValue::ExternalLinkage; return false; + case lltok::kw_private: Res = GlobalValue::PrivateLinkage; break; + case lltok::kw_linker_private: Res = GlobalValue::LinkerPrivateLinkage; break; + case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break; + case lltok::kw_weak: Res = GlobalValue::WeakAnyLinkage; break; + case lltok::kw_weak_odr: Res = GlobalValue::WeakODRLinkage; break; + case lltok::kw_linkonce: Res = GlobalValue::LinkOnceAnyLinkage; break; + case lltok::kw_linkonce_odr: Res = GlobalValue::LinkOnceODRLinkage; break; case lltok::kw_available_externally: Res = GlobalValue::AvailableExternallyLinkage; break; - case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break; - case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break; - case lltok::kw_common: Res = GlobalValue::CommonLinkage; break; - case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break; - case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break; - case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break; + case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break; + case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break; + case lltok::kw_common: Res = GlobalValue::CommonLinkage; break; + case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break; + case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break; + case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break; } Lex.Lex(); HasLinkage = true; @@ -968,7 +1069,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { break; case lltok::kw_opaque: // TypeRec ::= 'opaque' - Result = OpaqueType::get(); + Result = Context.getOpaqueType(); Lex.Lex(); break; case lltok::lbrace: @@ -998,7 +1099,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { if (const Type *T = M->getTypeByName(Lex.getStrVal())) { Result = T; } else { - Result = OpaqueType::get(); + Result = Context.getOpaqueType(); ForwardRefTypes.insert(std::make_pair(Lex.getStrVal(), std::make_pair(Result, Lex.getLoc()))); @@ -1017,7 +1118,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { if (I != ForwardRefTypeIDs.end()) Result = I->second.first; else { - Result = OpaqueType::get(); + Result = Context.getOpaqueType(); ForwardRefTypeIDs.insert(std::make_pair(Lex.getUIntVal(), std::make_pair(Result, Lex.getLoc()))); @@ -1030,7 +1131,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { Lex.Lex(); unsigned Val; if (ParseUInt32(Val)) return true; - OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder. + OpaqueType *OT = Context.getOpaqueType(); //Use temporary placeholder. UpRefs.push_back(UpRefRecord(Lex.getLoc(), Val, OT)); Result = OT; break; @@ -1051,7 +1152,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { return TokError("pointers to void are invalid; use i8* instead"); if (!PointerType::isValidElementType(Result.get())) return TokError("pointer to this type is invalid"); - Result = HandleUpRefs(PointerType::getUnqual(Result.get())); + Result = HandleUpRefs(Context.getPointerTypeUnqual(Result.get())); Lex.Lex(); break; @@ -1068,7 +1169,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { ParseToken(lltok::star, "expected '*' in address space")) return true; - Result = HandleUpRefs(PointerType::get(Result.get(), AddrSpace)); + Result = HandleUpRefs(Context.getPointerType(Result.get(), AddrSpace)); break; } @@ -1229,7 +1330,8 @@ bool LLParser::ParseFunctionType(PATypeHolder &Result) { for (unsigned i = 0, e = ArgList.size(); i != e; ++i) ArgListTy.push_back(ArgList[i].Type); - Result = HandleUpRefs(FunctionType::get(Result.get(), ArgListTy, isVarArg)); + Result = HandleUpRefs(Context.getFunctionType(Result.get(), + ArgListTy, isVarArg)); return false; } @@ -1244,7 +1346,7 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) { Lex.Lex(); // Consume the '{' if (EatIfPresent(lltok::rbrace)) { - Result = StructType::get(std::vector(), Packed); + Result = Context.getStructType(Packed); return false; } @@ -1276,7 +1378,7 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) { std::vector ParamsListTy; for (unsigned i = 0, e = ParamsList.size(); i != e; ++i) ParamsListTy.push_back(ParamsList[i].get()); - Result = HandleUpRefs(StructType::get(ParamsListTy, Packed)); + Result = HandleUpRefs(Context.getStructType(ParamsListTy, Packed)); return false; } @@ -1315,11 +1417,11 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) { return Error(SizeLoc, "size too large for vector"); if (!VectorType::isValidElementType(EltTy)) return Error(TypeLoc, "vector element type must be fp or integer"); - Result = VectorType::get(EltTy, unsigned(Size)); + Result = Context.getVectorType(EltTy, unsigned(Size)); } else { if (!ArrayType::isValidElementType(EltTy)) return Error(TypeLoc, "invalid array element type"); - Result = HandleUpRefs(ArrayType::get(EltTy, Size)); + Result = HandleUpRefs(Context.getArrayType(EltTy, Size)); } return false; } @@ -1343,8 +1445,8 @@ LLParser::PerFunctionState::~PerFunctionState() { for (std::map >::iterator I = ForwardRefVals.begin(), E = ForwardRefVals.end(); I != E; ++I) if (!isa(I->second.first)) { - I->second.first->replaceAllUsesWith(UndefValue::get(I->second.first - ->getType())); + I->second.first->replaceAllUsesWith( + P.getContext().getUndef(I->second.first->getType())); delete I->second.first; I->second.first = 0; } @@ -1352,8 +1454,8 @@ LLParser::PerFunctionState::~PerFunctionState() { for (std::map >::iterator I = ForwardRefValIDs.begin(), E = ForwardRefValIDs.end(); I != E; ++I) if (!isa(I->second.first)) { - I->second.first->replaceAllUsesWith(UndefValue::get(I->second.first - ->getType())); + I->second.first->replaceAllUsesWith( + P.getContext().getUndef(I->second.first->getType())); delete I->second.first; I->second.first = 0; } @@ -1584,7 +1686,7 @@ bool LLParser::ParseValID(ValID &ID) { ID.Kind = ValID::t_LocalName; break; case lltok::Metadata: { // !{...} MDNode, !"foo" MDString - ID.Kind = ValID::t_Constant; + ID.Kind = ValID::t_Metadata; Lex.Lex(); if (Lex.getKind() == lltok::lbrace) { SmallVector Elts; @@ -1592,16 +1694,19 @@ bool LLParser::ParseValID(ValID &ID) { ParseToken(lltok::rbrace, "expected end of metadata node")) return true; - ID.ConstantVal = MDNode::get(Elts.data(), Elts.size()); + ID.MetadataVal = Context.getMDNode(Elts.data(), Elts.size()); return false; } + // Standalone metadata reference + // !{ ..., !42, ... } + if (!ParseMDNode(ID.MetadataVal)) + return false; + // MDString: // ::= '!' STRINGCONSTANT - std::string Str; - if (ParseStringConstant(Str)) return true; - - ID.ConstantVal = MDString::get(Str.data(), Str.data() + Str.size()); + if (ParseMDString(ID.MetadataVal)) return true; + ID.Kind = ValID::t_Metadata; return false; } case lltok::APSInt: @@ -1613,11 +1718,11 @@ bool LLParser::ParseValID(ValID &ID) { ID.Kind = ValID::t_APFloat; break; case lltok::kw_true: - ID.ConstantVal = ConstantInt::getTrue(); + ID.ConstantVal = Context.getTrue(); ID.Kind = ValID::t_Constant; break; case lltok::kw_false: - ID.ConstantVal = ConstantInt::getFalse(); + ID.ConstantVal = Context.getFalse(); ID.Kind = ValID::t_Constant; break; case lltok::kw_null: ID.Kind = ValID::t_Null; break; @@ -1632,7 +1737,7 @@ bool LLParser::ParseValID(ValID &ID) { ParseToken(lltok::rbrace, "expected end of struct constant")) return true; - ID.ConstantVal = ConstantStruct::get(Elts.data(), Elts.size(), false); + ID.ConstantVal = Context.getConstantStruct(Elts.data(), Elts.size(), false); ID.Kind = ValID::t_Constant; return false; } @@ -1651,7 +1756,8 @@ bool LLParser::ParseValID(ValID &ID) { return true; if (isPackedStruct) { - ID.ConstantVal = ConstantStruct::get(Elts.data(), Elts.size(), true); + ID.ConstantVal = + Context.getConstantStruct(Elts.data(), Elts.size(), true); ID.Kind = ValID::t_Constant; return false; } @@ -1671,7 +1777,7 @@ bool LLParser::ParseValID(ValID &ID) { "vector element #" + utostr(i) + " is not of type '" + Elts[0]->getType()->getDescription()); - ID.ConstantVal = ConstantVector::get(Elts.data(), Elts.size()); + ID.ConstantVal = Context.getConstantVector(Elts.data(), Elts.size()); ID.Kind = ValID::t_Constant; return false; } @@ -1695,7 +1801,7 @@ bool LLParser::ParseValID(ValID &ID) { return Error(FirstEltLoc, "invalid array element type: " + Elts[0]->getType()->getDescription()); - ArrayType *ATy = ArrayType::get(Elts[0]->getType(), Elts.size()); + ArrayType *ATy = Context.getArrayType(Elts[0]->getType(), Elts.size()); // Verify all elements are correct type! for (unsigned i = 0, e = Elts.size(); i != e; ++i) { @@ -1705,13 +1811,13 @@ bool LLParser::ParseValID(ValID &ID) { " is not of type '" +Elts[0]->getType()->getDescription()); } - ID.ConstantVal = ConstantArray::get(ATy, Elts.data(), Elts.size()); + ID.ConstantVal = Context.getConstantArray(ATy, Elts.data(), Elts.size()); ID.Kind = ValID::t_Constant; return false; } case lltok::kw_c: // c "foo" Lex.Lex(); - ID.ConstantVal = ConstantArray::get(Lex.getStrVal(), false); + ID.ConstantVal = Context.getConstantArray(Lex.getStrVal(), false); if (ParseToken(lltok::StringConstant, "expected string")) return true; ID.Kind = ValID::t_Constant; return false; @@ -1757,8 +1863,8 @@ bool LLParser::ParseValID(ValID &ID) { return Error(ID.Loc, "invalid cast opcode for cast from '" + SrcVal->getType()->getDescription() + "' to '" + DestTy->getDescription() + "'"); - ID.ConstantVal = ConstantExpr::getCast((Instruction::CastOps)Opc, SrcVal, - DestTy); + ID.ConstantVal = Context.getConstantExprCast((Instruction::CastOps)Opc, + SrcVal, DestTy); ID.Kind = ValID::t_Constant; return false; } @@ -1777,7 +1883,7 @@ bool LLParser::ParseValID(ValID &ID) { Indices.end())) return Error(ID.Loc, "invalid indices for extractvalue"); ID.ConstantVal = - ConstantExpr::getExtractValue(Val, Indices.data(), Indices.size()); + Context.getConstantExprExtractValue(Val, Indices.data(), Indices.size()); ID.Kind = ValID::t_Constant; return false; } @@ -1797,15 +1903,13 @@ bool LLParser::ParseValID(ValID &ID) { if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(), Indices.end())) return Error(ID.Loc, "invalid indices for insertvalue"); - ID.ConstantVal = - ConstantExpr::getInsertValue(Val0, Val1, Indices.data(), Indices.size()); + ID.ConstantVal = Context.getConstantExprInsertValue(Val0, Val1, + Indices.data(), Indices.size()); ID.Kind = ValID::t_Constant; return false; } case lltok::kw_icmp: - case lltok::kw_fcmp: - case lltok::kw_vicmp: - case lltok::kw_vfcmp: { + case lltok::kw_fcmp: { unsigned PredVal, Opc = Lex.getUIntVal(); Constant *Val0, *Val1; Lex.Lex(); @@ -1825,24 +1929,13 @@ bool LLParser::ParseValID(ValID &ID) { if (Opc == Instruction::FCmp) { if (!Val0->getType()->isFPOrFPVector()) return Error(ID.Loc, "fcmp requires floating point operands"); - ID.ConstantVal = ConstantExpr::getFCmp(Pred, Val0, Val1); - } else if (Opc == Instruction::ICmp) { + ID.ConstantVal = Context.getConstantExprFCmp(Pred, Val0, Val1); + } else { + assert(Opc == Instruction::ICmp && "Unexpected opcode for CmpInst!"); if (!Val0->getType()->isIntOrIntVector() && !isa(Val0->getType())) return Error(ID.Loc, "icmp requires pointer or integer operands"); - ID.ConstantVal = ConstantExpr::getICmp(Pred, Val0, Val1); - } else if (Opc == Instruction::VFCmp) { - // FIXME: REMOVE VFCMP Support - if (!Val0->getType()->isFPOrFPVector() || - !isa(Val0->getType())) - return Error(ID.Loc, "vfcmp requires vector floating point operands"); - ID.ConstantVal = ConstantExpr::getVFCmp(Pred, Val0, Val1); - } else if (Opc == Instruction::VICmp) { - // FIXME: REMOVE VICMP Support - if (!Val0->getType()->isIntOrIntVector() || - !isa(Val0->getType())) - return Error(ID.Loc, "vicmp requires vector floating point operands"); - ID.ConstantVal = ConstantExpr::getVICmp(Pred, Val0, Val1); + ID.ConstantVal = Context.getConstantExprICmp(Pred, Val0, Val1); } ID.Kind = ValID::t_Constant; return false; @@ -1861,9 +1954,27 @@ bool LLParser::ParseValID(ValID &ID) { case lltok::kw_urem: case lltok::kw_srem: case lltok::kw_frem: { + bool NUW = false; + bool NSW = false; + bool Exact = false; unsigned Opc = Lex.getUIntVal(); Constant *Val0, *Val1; Lex.Lex(); + LocTy ModifierLoc = Lex.getLoc(); + if (Opc == Instruction::Add || + Opc == Instruction::Sub || + Opc == Instruction::Mul) { + if (EatIfPresent(lltok::kw_nuw)) + NUW = true; + if (EatIfPresent(lltok::kw_nsw)) { + NSW = true; + if (EatIfPresent(lltok::kw_nuw)) + NUW = true; + } + } else if (Opc == Instruction::SDiv) { + if (EatIfPresent(lltok::kw_exact)) + Exact = true; + } if (ParseToken(lltok::lparen, "expected '(' in binary constantexpr") || ParseGlobalTypeAndValue(Val0) || ParseToken(lltok::comma, "expected comma in binary constantexpr") || @@ -1872,10 +1983,25 @@ bool LLParser::ParseValID(ValID &ID) { return true; if (Val0->getType() != Val1->getType()) return Error(ID.Loc, "operands of constexpr must have same type"); + if (!Val0->getType()->isIntOrIntVector()) { + if (NUW) + return Error(ModifierLoc, "nuw only applies to integer operations"); + if (NSW) + return Error(ModifierLoc, "nsw only applies to integer operations"); + } + // API compatibility: Accept either integer or floating-point types with + // add, sub, and mul. if (!Val0->getType()->isIntOrIntVector() && !Val0->getType()->isFPOrFPVector()) return Error(ID.Loc,"constexpr requires integer, fp, or vector operands"); - ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1); + Constant *C = Context.getConstantExpr(Opc, Val0, Val1); + if (NUW) + cast(C)->setHasNoUnsignedOverflow(true); + if (NSW) + cast(C)->setHasNoSignedOverflow(true); + if (Exact) + cast(C)->setIsExact(true); + ID.ConstantVal = C; ID.Kind = ValID::t_Constant; return false; } @@ -1901,7 +2027,7 @@ bool LLParser::ParseValID(ValID &ID) { if (!Val0->getType()->isIntOrIntVector()) return Error(ID.Loc, "constexpr requires integer or integer vector operands"); - ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1); + ID.ConstantVal = Context.getConstantExpr(Opc, Val0, Val1); ID.Kind = ValID::t_Constant; return false; } @@ -1924,36 +2050,39 @@ bool LLParser::ParseValID(ValID &ID) { return Error(ID.Loc, "getelementptr requires pointer operand"); if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(), - (Value**)&Elts[1], Elts.size()-1)) + (Value**)(Elts.data() + 1), + Elts.size() - 1)) return Error(ID.Loc, "invalid indices for getelementptr"); - ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0], - &Elts[1], Elts.size()-1); + ID.ConstantVal = Context.getConstantExprGetElementPtr(Elts[0], + Elts.data() + 1, Elts.size() - 1); } else if (Opc == Instruction::Select) { if (Elts.size() != 3) return Error(ID.Loc, "expected three operands to select"); if (const char *Reason = SelectInst::areInvalidOperands(Elts[0], Elts[1], Elts[2])) return Error(ID.Loc, Reason); - ID.ConstantVal = ConstantExpr::getSelect(Elts[0], Elts[1], Elts[2]); + ID.ConstantVal = Context.getConstantExprSelect(Elts[0], Elts[1], Elts[2]); } else if (Opc == Instruction::ShuffleVector) { if (Elts.size() != 3) return Error(ID.Loc, "expected three operands to shufflevector"); if (!ShuffleVectorInst::isValidOperands(Elts[0], Elts[1], Elts[2])) return Error(ID.Loc, "invalid operands to shufflevector"); - ID.ConstantVal = ConstantExpr::getShuffleVector(Elts[0], Elts[1],Elts[2]); + ID.ConstantVal = + Context.getConstantExprShuffleVector(Elts[0], Elts[1],Elts[2]); } else if (Opc == Instruction::ExtractElement) { if (Elts.size() != 2) return Error(ID.Loc, "expected two operands to extractelement"); if (!ExtractElementInst::isValidOperands(Elts[0], Elts[1])) return Error(ID.Loc, "invalid extractelement operands"); - ID.ConstantVal = ConstantExpr::getExtractElement(Elts[0], Elts[1]); + ID.ConstantVal = Context.getConstantExprExtractElement(Elts[0], Elts[1]); } else { assert(Opc == Instruction::InsertElement && "Unknown opcode"); if (Elts.size() != 3) return Error(ID.Loc, "expected three operands to insertelement"); if (!InsertElementInst::isValidOperands(Elts[0], Elts[1], Elts[2])) return Error(ID.Loc, "invalid insertelement operands"); - ID.ConstantVal = ConstantExpr::getInsertElement(Elts[0], Elts[1],Elts[2]); + ID.ConstantVal = + Context.getConstantExprInsertElement(Elts[0], Elts[1],Elts[2]); } ID.Kind = ValID::t_Constant; @@ -1981,7 +2110,9 @@ bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, return Error(ID.Loc, "functions are not values, refer to them as pointers"); switch (ID.Kind) { - default: assert(0 && "Unknown ValID!"); + default: llvm_unreachable("Unknown ValID!"); + case ValID::t_Metadata: + return Error(ID.Loc, "invalid use of metadata"); case ValID::t_LocalID: case ValID::t_LocalName: return Error(ID.Loc, "invalid use of function-local name"); @@ -1997,7 +2128,7 @@ bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, if (!isa(Ty)) return Error(ID.Loc, "integer constant must have integer type"); ID.APSIntVal.extOrTrunc(Ty->getPrimitiveSizeInBits()); - V = ConstantInt::get(ID.APSIntVal); + V = ConstantInt::get(Context, ID.APSIntVal); return false; case ValID::t_APFloat: if (!Ty->isFloatingPoint() || @@ -2012,7 +2143,7 @@ bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, ID.APFloatVal.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &Ignored); } - V = ConstantFP::get(ID.APFloatVal); + V = ConstantFP::get(Context, ID.APFloatVal); if (V->getType() != Ty) return Error(ID.Loc, "floating point constant does not have type '" + @@ -2022,25 +2153,25 @@ bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, case ValID::t_Null: if (!isa(Ty)) return Error(ID.Loc, "null must be a pointer type"); - V = ConstantPointerNull::get(cast(Ty)); + V = Context.getConstantPointerNull(cast(Ty)); return false; case ValID::t_Undef: // FIXME: LabelTy should not be a first-class type. if ((!Ty->isFirstClassType() || Ty == Type::LabelTy) && !isa(Ty)) return Error(ID.Loc, "invalid type for undef constant"); - V = UndefValue::get(Ty); + V = Context.getUndef(Ty); return false; case ValID::t_EmptyArray: if (!isa(Ty) || cast(Ty)->getNumElements() != 0) return Error(ID.Loc, "invalid empty array initializer"); - V = UndefValue::get(Ty); + V = Context.getUndef(Ty); return false; case ValID::t_Zero: // FIXME: LabelTy should not be a first-class type. if (!Ty->isFirstClassType() || Ty == Type::LabelTy) return Error(ID.Loc, "invalid type for null constant"); - V = Constant::getNullValue(Ty); + V = Context.getNullValue(Ty); return false; case ValID::t_Constant: if (ID.ConstantVal->getType() != Ty) @@ -2098,6 +2229,8 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, return Error(ID.Loc, "invalid type for inline asm constraint string"); V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal); return false; + } else if (ID.Kind == ValID::t_Metadata) { + V = ID.MetadataVal; } else { Constant *C; if (ConvertGlobalValIDToValue(Ty, ID, C)) return true; @@ -2150,6 +2283,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { return Error(LinkageLoc, "invalid linkage for function definition"); break; case GlobalValue::PrivateLinkage: + case GlobalValue::LinkerPrivateLinkage: case GlobalValue::InternalLinkage: case GlobalValue::AvailableExternallyLinkage: case GlobalValue::LinkOnceAnyLinkage: @@ -2242,8 +2376,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { RetType != Type::VoidTy) return Error(RetTypeLoc, "functions with 'sret' argument must return void"); - const FunctionType *FT = FunctionType::get(RetType, ParamTypeList, isVarArg); - const PointerType *PFT = PointerType::getUnqual(FT); + const FunctionType *FT = + Context.getFunctionType(RetType, ParamTypeList, isVarArg); + const PointerType *PFT = Context.getPointerTypeUnqual(FT); Fn = 0; if (!FunctionName.empty()) { @@ -2418,15 +2553,49 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, // Binary Operators. case lltok::kw_add: case lltok::kw_sub: - case lltok::kw_mul: + case lltok::kw_mul: { + bool NUW = false; + bool NSW = false; + LocTy ModifierLoc = Lex.getLoc(); + if (EatIfPresent(lltok::kw_nuw)) + NUW = true; + if (EatIfPresent(lltok::kw_nsw)) { + NSW = true; + if (EatIfPresent(lltok::kw_nuw)) + NUW = true; + } // API compatibility: Accept either integer or floating-point types. - return ParseArithmetic(Inst, PFS, KeywordVal, 0); + bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 0); + if (!Result) { + if (!Inst->getType()->isIntOrIntVector()) { + if (NUW) + return Error(ModifierLoc, "nuw only applies to integer operations"); + if (NSW) + return Error(ModifierLoc, "nsw only applies to integer operations"); + } + if (NUW) + cast(Inst)->setHasNoUnsignedOverflow(true); + if (NSW) + cast(Inst)->setHasNoSignedOverflow(true); + } + return Result; + } case lltok::kw_fadd: case lltok::kw_fsub: case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2); + case lltok::kw_sdiv: { + bool Exact = false; + if (EatIfPresent(lltok::kw_exact)) + Exact = true; + bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1); + if (!Result) + if (Exact) + cast(Inst)->setIsExact(true); + return Result; + } + case lltok::kw_udiv: - case lltok::kw_sdiv: case lltok::kw_urem: case lltok::kw_srem: return ParseArithmetic(Inst, PFS, KeywordVal, 1); case lltok::kw_fdiv: @@ -2438,9 +2607,7 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_or: case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal); case lltok::kw_icmp: - case lltok::kw_fcmp: - case lltok::kw_vicmp: - case lltok::kw_vfcmp: return ParseCompare(Inst, PFS, KeywordVal); + case lltok::kw_fcmp: return ParseCompare(Inst, PFS, KeywordVal); // Casts. case lltok::kw_trunc: case lltok::kw_zext: @@ -2485,8 +2652,7 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, /// ParseCmpPredicate - Parse an integer or fp predicate, based on Kind. bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) { - // FIXME: REMOVE vicmp/vfcmp! - if (Opc == Instruction::FCmp || Opc == Instruction::VFCmp) { + if (Opc == Instruction::FCmp) { switch (Lex.getKind()) { default: TokError("expected fcmp predicate (e.g. 'oeq')"); case lltok::kw_oeq: P = CmpInst::FCMP_OEQ; break; @@ -2558,7 +2724,7 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, RVs.push_back(RV); } - RV = UndefValue::get(PFS.getFunction().getReturnType()); + RV = Context.getUndef(PFS.getFunction().getReturnType()); for (unsigned i = 0, e = RVs.size(); i != e; ++i) { Instruction *I = InsertValueInst::Create(RV, RVs[i], i, "mrv"); BB->getInstList().push_back(I); @@ -2696,8 +2862,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { if (!FunctionType::isValidReturnType(RetType)) return Error(RetTypeLoc, "Invalid result type for LLVM function"); - Ty = FunctionType::get(RetType, ParamTypes, false); - PFTy = PointerType::getUnqual(Ty); + Ty = Context.getFunctionType(RetType, ParamTypes, false); + PFTy = Context.getPointerTypeUnqual(Ty); } // Look up the callee. @@ -2778,7 +2944,7 @@ bool LLParser::ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS, bool Valid; switch (OperandType) { - default: assert(0 && "Unknown operand type!"); + default: llvm_unreachable("Unknown operand type!"); case 0: // int or FP. Valid = LHS->getType()->isIntOrIntVector() || LHS->getType()->isFPOrFPVector(); @@ -2815,8 +2981,6 @@ bool LLParser::ParseLogical(Instruction *&Inst, PerFunctionState &PFS, /// ParseCompare /// ::= 'icmp' IPredicates TypeAndValue ',' Value /// ::= 'fcmp' FPredicates TypeAndValue ',' Value -/// ::= 'vicmp' IPredicates TypeAndValue ',' Value -/// ::= 'vfcmp' FPredicates TypeAndValue ',' Value bool LLParser::ParseCompare(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc) { // Parse the integer/fp comparison predicate. @@ -2832,20 +2996,13 @@ bool LLParser::ParseCompare(Instruction *&Inst, PerFunctionState &PFS, if (Opc == Instruction::FCmp) { if (!LHS->getType()->isFPOrFPVector()) return Error(Loc, "fcmp requires floating point operands"); - Inst = new FCmpInst(CmpInst::Predicate(Pred), LHS, RHS); - } else if (Opc == Instruction::ICmp) { + Inst = new FCmpInst(Context, CmpInst::Predicate(Pred), LHS, RHS); + } else { + assert(Opc == Instruction::ICmp && "Unknown opcode for CmpInst!"); if (!LHS->getType()->isIntOrIntVector() && !isa(LHS->getType())) return Error(Loc, "icmp requires integer operands"); - Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS); - } else if (Opc == Instruction::VFCmp) { - if (!LHS->getType()->isFPOrFPVector() || !isa(LHS->getType())) - return Error(Loc, "vfcmp requires vector floating point operands"); - Inst = new VFCmpInst(CmpInst::Predicate(Pred), LHS, RHS); - } else if (Opc == Instruction::VICmp) { - if (!LHS->getType()->isIntOrIntVector() || !isa(LHS->getType())) - return Error(Loc, "vicmp requires vector floating point operands"); - Inst = new VICmpInst(CmpInst::Predicate(Pred), LHS, RHS); + Inst = new ICmpInst(Context, CmpInst::Predicate(Pred), LHS, RHS); } return false; } @@ -2926,7 +3083,7 @@ bool LLParser::ParseExtractElement(Instruction *&Inst, PerFunctionState &PFS) { if (!ExtractElementInst::isValidOperands(Op0, Op1)) return Error(Loc, "invalid extractelement operands"); - Inst = new ExtractElementInst(Op0, Op1); + Inst = ExtractElementInst::Create(Op0, Op1); return false; } @@ -2943,7 +3100,7 @@ bool LLParser::ParseInsertElement(Instruction *&Inst, PerFunctionState &PFS) { return true; if (!InsertElementInst::isValidOperands(Op0, Op1, Op2)) - return Error(Loc, "invalid extractelement operands"); + return Error(Loc, "invalid insertelement operands"); Inst = InsertElementInst::Create(Op0, Op1, Op2); return false; @@ -3045,8 +3202,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, if (!FunctionType::isValidReturnType(RetType)) return Error(RetTypeLoc, "Invalid result type for LLVM function"); - Ty = FunctionType::get(RetType, ParamTypes, false); - PFTy = PointerType::getUnqual(Ty); + Ty = Context.getFunctionType(RetType, ParamTypes, false); + PFTy = Context.getPointerTypeUnqual(Ty); } // Look up the callee. @@ -3116,7 +3273,7 @@ bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc) { PATypeHolder Ty(Type::VoidTy); Value *Size = 0; - LocTy SizeLoc = 0; + LocTy SizeLoc; unsigned Alignment = 0; if (ParseType(Ty)) return true; @@ -3286,14 +3443,28 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts) { assert(Lex.getKind() == lltok::lbrace); Lex.Lex(); do { - Value *V; + Value *V = 0; if (Lex.getKind() == lltok::kw_null) { Lex.Lex(); V = 0; } else { - Constant *C; - if (ParseGlobalTypeAndValue(C)) return true; - V = C; + PATypeHolder Ty(Type::VoidTy); + if (ParseType(Ty)) return true; + if (Lex.getKind() == lltok::Metadata) { + Lex.Lex(); + MetadataBase *Node = 0; + if (!ParseMDNode(Node)) + V = Node; + else { + MetadataBase *MDS = 0; + if (ParseMDString(MDS)) return true; + V = MDS; + } + } else { + Constant *C; + if (ParseGlobalValue(Ty, C)) return true; + V = C; + } } Elts.push_back(V); } while (EatIfPresent(lltok::comma));