diff options
Diffstat (limited to 'llvm/lib/AsmParser')
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.h | 4 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 534 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 36 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 8 | ||||
-rw-r--r-- | llvm/lib/AsmParser/Parser.cpp | 101 |
6 files changed, 537 insertions, 166 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index d96b5e0bff5ab..777ce3abdddd5 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -658,15 +658,19 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(noinline); KEYWORD(norecurse); KEYWORD(nonlazybind); + KEYWORD(nomerge); KEYWORD(nonnull); KEYWORD(noredzone); KEYWORD(noreturn); KEYWORD(nosync); KEYWORD(nocf_check); + KEYWORD(noundef); KEYWORD(nounwind); + KEYWORD(null_pointer_is_valid); KEYWORD(optforfuzzing); KEYWORD(optnone); KEYWORD(optsize); + KEYWORD(preallocated); KEYWORD(readnone); KEYWORD(readonly); KEYWORD(returned); @@ -738,6 +742,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(name); KEYWORD(summaries); KEYWORD(flags); + KEYWORD(blockcount); KEYWORD(linkage); KEYWORD(notEligibleToImport); KEYWORD(live); @@ -754,6 +759,8 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(alwaysInline); KEYWORD(calls); KEYWORD(callee); + KEYWORD(params); + KEYWORD(param); KEYWORD(hotness); KEYWORD(unknown); KEYWORD(hot); @@ -788,6 +795,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(sizeM1); KEYWORD(bitMask); KEYWORD(inlineBits); + KEYWORD(vcall_visibility); KEYWORD(wpdResolutions); KEYWORD(wpdRes); KEYWORD(indir); @@ -817,6 +825,7 @@ lltok::Kind LLLexer::LexIdentifier() { TYPEKEYWORD("void", Type::getVoidTy(Context)); TYPEKEYWORD("half", Type::getHalfTy(Context)); + TYPEKEYWORD("bfloat", Type::getBFloatTy(Context)); TYPEKEYWORD("float", Type::getFloatTy(Context)); TYPEKEYWORD("double", Type::getDoubleTy(Context)); TYPEKEYWORD("x86_fp80", Type::getX86_FP80Ty(Context)); @@ -982,11 +991,13 @@ lltok::Kind LLLexer::LexIdentifier() { /// HexFP128Constant 0xL[0-9A-Fa-f]+ /// HexPPC128Constant 0xM[0-9A-Fa-f]+ /// HexHalfConstant 0xH[0-9A-Fa-f]+ +/// HexBFloatConstant 0xR[0-9A-Fa-f]+ lltok::Kind LLLexer::Lex0x() { CurPtr = TokStart + 2; char Kind; - if ((CurPtr[0] >= 'K' && CurPtr[0] <= 'M') || CurPtr[0] == 'H') { + if ((CurPtr[0] >= 'K' && CurPtr[0] <= 'M') || CurPtr[0] == 'H' || + CurPtr[0] == 'R') { Kind = *CurPtr++; } else { Kind = 'J'; @@ -1004,7 +1015,7 @@ lltok::Kind LLLexer::Lex0x() { if (Kind == 'J') { // HexFPConstant - Floating point constant represented in IEEE format as a // hexadecimal number for when exponential notation is not precise enough. - // Half, Float, and double only. + // Half, BFloat, Float, and double only. APFloatVal = APFloat(APFloat::IEEEdouble(), APInt(64, HexIntToVal(TokStart + 2, CurPtr))); return lltok::APFloat; @@ -1032,6 +1043,11 @@ lltok::Kind LLLexer::Lex0x() { APFloatVal = APFloat(APFloat::IEEEhalf(), APInt(16,HexIntToVal(TokStart+3, CurPtr))); return lltok::APFloat; + case 'R': + // Brain floating point + APFloatVal = APFloat(APFloat::BFloat(), + APInt(16, HexIntToVal(TokStart + 3, CurPtr))); + return lltok::APFloat; } } diff --git a/llvm/lib/AsmParser/LLLexer.h b/llvm/lib/AsmParser/LLLexer.h index 4d3a2920e9374..c97d9781c33bd 100644 --- a/llvm/lib/AsmParser/LLLexer.h +++ b/llvm/lib/AsmParser/LLLexer.h @@ -16,13 +16,13 @@ #include "LLToken.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" -#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/SMLoc.h" #include <string> namespace llvm { - class MemoryBuffer; class Type; class SMDiagnostic; + class SourceMgr; class LLVMContext; class LLLexer { diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 1a17f633ae166..c9f21ee83826a 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -11,9 +11,10 @@ //===----------------------------------------------------------------------===// #include "LLParser.h" +#include "LLToken.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/AsmParser/SlotMapping.h" @@ -23,6 +24,7 @@ #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Comdat.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" @@ -30,14 +32,10 @@ #include "llvm/IR/GlobalIFunc.h" #include "llvm/IR/GlobalObject.h" #include "llvm/IR/InlineAsm.h" -#include "llvm/IR/Instruction.h" -#include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" -#include "llvm/IR/Operator.h" -#include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/Casting.h" @@ -61,7 +59,8 @@ static std::string getTypeString(Type *T) { } /// Run: module ::= toplevelentity* -bool LLParser::Run() { +bool LLParser::Run(bool UpgradeDebugInfo, + DataLayoutCallbackTy DataLayoutCallback) { // Prime the lexer. Lex.Lex(); @@ -70,7 +69,15 @@ bool LLParser::Run() { Lex.getLoc(), "Can't read textual IR with a Context that discards named Values"); - return ParseTopLevelEntities() || ValidateEndOfModule() || + if (M) { + if (ParseTargetDefinitions()) + return true; + + if (auto LayoutOverride = DataLayoutCallback(M->getTargetTriple())) + M->setDataLayout(*LayoutOverride); + } + + return ParseTopLevelEntities() || ValidateEndOfModule(UpgradeDebugInfo) || ValidateEndOfIndex(); } @@ -118,7 +125,7 @@ void LLParser::restoreParsingState(const SlotMapping *Slots) { /// ValidateEndOfModule - Do final validity and sanity checks at the end of the /// module. -bool LLParser::ValidateEndOfModule() { +bool LLParser::ValidateEndOfModule(bool UpgradeDebugInfo) { if (!M) return false; // Handle any function attribute group forward references. @@ -294,6 +301,23 @@ bool LLParser::ValidateEndOfIndex() { // Top-Level Entities //===----------------------------------------------------------------------===// +bool LLParser::ParseTargetDefinitions() { + while (true) { + switch (Lex.getKind()) { + case lltok::kw_target: + if (ParseTargetDefinition()) + return true; + break; + case lltok::kw_source_filename: + if (ParseSourceFileName()) + return true; + break; + default: + return false; + } + } +} + bool LLParser::ParseTopLevelEntities() { // If there is no Module, then parse just the summary index entries. if (!M) { @@ -322,11 +346,6 @@ bool LLParser::ParseTopLevelEntities() { case lltok::kw_declare: if (ParseDeclare()) return true; break; case lltok::kw_define: if (ParseDefine()) return true; break; case lltok::kw_module: if (ParseModuleAsm()) return true; break; - case lltok::kw_target: if (ParseTargetDefinition()) return true; break; - case lltok::kw_source_filename: - if (ParseSourceFileName()) - return true; - break; case lltok::kw_deplibs: if (ParseDepLibs()) return true; break; case lltok::LocalVarID: if (ParseUnnamedType()) return true; break; case lltok::LocalVar: if (ParseNamedType()) return true; break; @@ -383,8 +402,7 @@ bool LLParser::ParseTargetDefinition() { if (ParseToken(lltok::equal, "expected '=' after target datalayout") || ParseStringConstant(Str)) return true; - if (DataLayoutStr.empty()) - M->setDataLayout(Str); + M->setDataLayout(Str); return false; } } @@ -835,6 +853,12 @@ bool LLParser::ParseSummaryEntry() { case lltok::kw_typeidCompatibleVTable: result = ParseTypeIdCompatibleVtableEntry(SummaryID); break; + case lltok::kw_flags: + result = ParseSummaryIndexFlags(); + break; + case lltok::kw_blockcount: + result = ParseBlockCount(); + break; default: result = Error(Lex.getLoc(), "unexpected summary kind"); break; @@ -1286,12 +1310,15 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, B.addAttribute(Attribute::NoImplicitFloat); break; case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break; case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break; + case lltok::kw_nomerge: B.addAttribute(Attribute::NoMerge); break; case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break; case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break; case lltok::kw_nosync: B.addAttribute(Attribute::NoSync); break; case lltok::kw_nocf_check: B.addAttribute(Attribute::NoCfCheck); break; case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break; case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; + case lltok::kw_null_pointer_is_valid: + B.addAttribute(Attribute::NullPointerIsValid); break; case lltok::kw_optforfuzzing: B.addAttribute(Attribute::OptForFuzzing); break; case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break; @@ -1325,6 +1352,13 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break; case lltok::kw_willreturn: B.addAttribute(Attribute::WillReturn); break; case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break; + case lltok::kw_preallocated: { + Type *Ty; + if (ParsePreallocated(Ty)) + return true; + B.addPreallocatedAttr(Ty); + break; + } // Error handling. case lltok::kw_inreg: @@ -1340,6 +1374,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, case lltok::kw_inalloca: case lltok::kw_nest: case lltok::kw_noalias: + case lltok::kw_noundef: case lltok::kw_nocapture: case lltok::kw_nonnull: case lltok::kw_returned: @@ -1353,7 +1388,9 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, break; } - Lex.Lex(); + // ParsePreallocated() consumes token + if (Token != lltok::kw_preallocated) + Lex.Lex(); } } @@ -1605,7 +1642,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { } case lltok::kw_align: { MaybeAlign Alignment; - if (ParseOptionalAlignment(Alignment)) + if (ParseOptionalAlignment(Alignment, true)) return true; B.addAlignmentAttr(Alignment); continue; @@ -1617,6 +1654,13 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { B.addByValAttr(Ty); continue; } + case lltok::kw_preallocated: { + Type *Ty; + if (ParsePreallocated(Ty)) + return true; + B.addPreallocatedAttr(Ty); + continue; + } case lltok::kw_dereferenceable: { uint64_t Bytes; if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes)) @@ -1634,6 +1678,9 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { case lltok::kw_inalloca: B.addAttribute(Attribute::InAlloca); break; case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; case lltok::kw_nest: B.addAttribute(Attribute::Nest); break; + case lltok::kw_noundef: + B.addAttribute(Attribute::NoUndef); + break; case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); break; case lltok::kw_nofree: B.addAttribute(Attribute::NoFree); break; @@ -1662,6 +1709,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { case lltok::kw_noimplicitfloat: case lltok::kw_noinline: case lltok::kw_nonlazybind: + case lltok::kw_nomerge: case lltok::kw_noredzone: case lltok::kw_noreturn: case lltok::kw_nocf_check: @@ -1730,6 +1778,9 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { } case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; + case lltok::kw_noundef: + B.addAttribute(Attribute::NoUndef); + break; case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break; case lltok::kw_signext: B.addAttribute(Attribute::SExt); break; case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; @@ -1761,6 +1812,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { case lltok::kw_noimplicitfloat: case lltok::kw_noinline: case lltok::kw_nonlazybind: + case lltok::kw_nomerge: case lltok::kw_noredzone: case lltok::kw_noreturn: case lltok::kw_nocf_check: @@ -1784,10 +1836,15 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { case lltok::kw_uwtable: HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); break; - case lltok::kw_readnone: case lltok::kw_readonly: HaveError |= Error(Lex.getLoc(), "invalid use of attribute on return type"); + break; + case lltok::kw_preallocated: + HaveError |= + Error(Lex.getLoc(), + "invalid use of parameter-only/call site-only attribute"); + break; } Lex.Lex(); @@ -2077,14 +2134,26 @@ bool LLParser::ParseOptionalFunctionMetadata(Function &F) { /// ParseOptionalAlignment /// ::= /* empty */ /// ::= 'align' 4 -bool LLParser::ParseOptionalAlignment(MaybeAlign &Alignment) { +bool LLParser::ParseOptionalAlignment(MaybeAlign &Alignment, bool AllowParens) { Alignment = None; if (!EatIfPresent(lltok::kw_align)) return false; LocTy AlignLoc = Lex.getLoc(); uint32_t Value = 0; + + LocTy ParenLoc = Lex.getLoc(); + bool HaveParens = false; + if (AllowParens) { + if (EatIfPresent(lltok::lparen)) + HaveParens = true; + } + if (ParseUInt32(Value)) return true; + + if (HaveParens && !EatIfPresent(lltok::rparen)) + return Error(ParenLoc, "expected ')'"); + if (!isPowerOf2_32(Value)) return Error(AlignLoc, "alignment is not a power of two"); if (Value > Value::MaximumAlignment) @@ -2499,6 +2568,21 @@ bool LLParser::ParseByValWithOptionalType(Type *&Result) { return false; } +/// ParsePreallocated +/// ::= preallocated(<ty>) +bool LLParser::ParsePreallocated(Type *&Result) { + Result = nullptr; + if (!EatIfPresent(lltok::kw_preallocated)) + return true; + if (!EatIfPresent(lltok::lparen)) + return Error(Lex.getLoc(), "expected '('"); + if (ParseType(Result)) + return true; + if (!EatIfPresent(lltok::rparen)) + return Error(Lex.getLoc(), "expected ')'"); + return false; +} + /// ParseOptionalOperandBundles /// ::= /*empty*/ /// ::= '[' OperandBundle [, OperandBundle ]* ']' @@ -3416,7 +3500,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ID.Kind = ValID::t_Constant; return false; } - + // Unary Operators. case lltok::kw_fneg: { unsigned Opc = Lex.getUIntVal(); @@ -3426,7 +3510,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ParseGlobalTypeAndValue(Val) || ParseToken(lltok::rparen, "expected ')' in unary constantexpr")) return true; - + // Check that the type is valid for the operator. switch (Opc) { case Instruction::FNeg: @@ -3586,15 +3670,17 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { "explicit pointee type doesn't match operand's pointee type"); unsigned GEPWidth = - BaseType->isVectorTy() ? BaseType->getVectorNumElements() : 0; + BaseType->isVectorTy() + ? cast<FixedVectorType>(BaseType)->getNumElements() + : 0; ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end()); for (Constant *Val : Indices) { Type *ValTy = Val->getType(); if (!ValTy->isIntOrIntVectorTy()) return Error(ID.Loc, "getelementptr index must be an integer"); - if (ValTy->isVectorTy()) { - unsigned ValNumEl = ValTy->getVectorNumElements(); + if (auto *ValVTy = dyn_cast<VectorType>(ValTy)) { + unsigned ValNumEl = cast<FixedVectorType>(ValVTy)->getNumElements(); if (GEPWidth && (ValNumEl != GEPWidth)) return Error( ID.Loc, @@ -3633,8 +3719,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { 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]); + SmallVector<int, 16> Mask; + ShuffleVectorInst::getShuffleMask(cast<Constant>(Elts[2]), Mask); + ID.ConstantVal = ConstantExpr::getShuffleVector(Elts[0], Elts[1], Mask); } else if (Opc == Instruction::ExtractElement) { if (Elts.size() != 2) return Error(ID.Loc, "expected two operands to extractelement"); @@ -3695,7 +3782,7 @@ bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) { } else { if (GlobalName.empty()) return TokError("comdat cannot be unnamed"); - C = getComdat(GlobalName, KwLoc); + C = getComdat(std::string(GlobalName), KwLoc); } return false; @@ -3867,6 +3954,10 @@ struct DISPFlagField : public MDFieldImpl<DISubprogram::DISPFlags> { DISPFlagField() : MDFieldImpl(DISubprogram::SPFlagZero) {} }; +struct MDAPSIntField : public MDFieldImpl<APSInt> { + MDAPSIntField() : ImplTy(APSInt()) {} +}; + struct MDSignedField : public MDFieldImpl<int64_t> { int64_t Min; int64_t Max; @@ -3946,6 +4037,16 @@ struct MDSignedOrUnsignedField namespace llvm { template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDAPSIntField &Result) { + if (Lex.getKind() != lltok::APSInt) + return TokError("expected integer"); + + Result.assign(Lex.getAPSIntVal()); + Lex.Lex(); + return false; +} + +template <> bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDUnsignedField &Result) { if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) @@ -4277,27 +4378,6 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, } template <> -bool LLParser::ParseMDField(LocTy Loc, StringRef Name, - MDSignedOrUnsignedField &Result) { - if (Lex.getKind() != lltok::APSInt) - return false; - - if (Lex.getAPSIntVal().isSigned()) { - MDSignedField Res = Result.A; - if (ParseMDField(Loc, Name, Res)) - return true; - Result.assign(Res); - return false; - } - - MDUnsignedField Res = Result.B; - if (ParseMDField(Loc, Name, Res)) - return true; - Result.assign(Res); - return false; -} - -template <> bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDStringField &Result) { LocTy ValueLoc = Lex.getLoc(); std::string S; @@ -4446,21 +4526,41 @@ bool LLParser::ParseGenericDINode(MDNode *&Result, bool IsDistinct) { /// ParseDISubrange: /// ::= !DISubrange(count: 30, lowerBound: 2) /// ::= !DISubrange(count: !node, lowerBound: 2) +/// ::= !DISubrange(lowerBound: !node1, upperBound: !node2, stride: !node3) bool LLParser::ParseDISubrange(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ - REQUIRED(count, MDSignedOrMDField, (-1, -1, INT64_MAX, false)); \ - OPTIONAL(lowerBound, MDSignedField, ); + OPTIONAL(count, MDSignedOrMDField, (-1, -1, INT64_MAX, false)); \ + OPTIONAL(lowerBound, MDSignedOrMDField, ); \ + OPTIONAL(upperBound, MDSignedOrMDField, ); \ + OPTIONAL(stride, MDSignedOrMDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS + Metadata *Count = nullptr; + Metadata *LowerBound = nullptr; + Metadata *UpperBound = nullptr; + Metadata *Stride = nullptr; if (count.isMDSignedField()) - Result = GET_OR_DISTINCT( - DISubrange, (Context, count.getMDSignedValue(), lowerBound.Val)); + Count = ConstantAsMetadata::get(ConstantInt::getSigned( + Type::getInt64Ty(Context), count.getMDSignedValue())); else if (count.isMDField()) - Result = GET_OR_DISTINCT( - DISubrange, (Context, count.getMDFieldValue(), lowerBound.Val)); - else - return true; + Count = count.getMDFieldValue(); + + auto convToMetadata = [&](MDSignedOrMDField Bound) -> Metadata * { + if (Bound.isMDSignedField()) + return ConstantAsMetadata::get(ConstantInt::getSigned( + Type::getInt64Ty(Context), Bound.getMDSignedValue())); + if (Bound.isMDField()) + return Bound.getMDFieldValue(); + return nullptr; + }; + + LowerBound = convToMetadata(lowerBound); + UpperBound = convToMetadata(upperBound); + Stride = convToMetadata(stride); + + Result = GET_OR_DISTINCT(DISubrange, + (Context, Count, LowerBound, UpperBound, Stride)); return false; } @@ -4470,17 +4570,20 @@ bool LLParser::ParseDISubrange(MDNode *&Result, bool IsDistinct) { bool LLParser::ParseDIEnumerator(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(name, MDStringField, ); \ - REQUIRED(value, MDSignedOrUnsignedField, ); \ + REQUIRED(value, MDAPSIntField, ); \ OPTIONAL(isUnsigned, MDBoolField, (false)); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - if (isUnsigned.Val && value.isMDSignedField()) + if (isUnsigned.Val && value.Val.isNegative()) return TokError("unsigned enumerator with negative value"); - int64_t Value = value.isMDSignedField() - ? value.getMDSignedValue() - : static_cast<int64_t>(value.getMDUnsignedValue()); + APSInt Value(value.Val); + // Add a leading zero so that unsigned values with the msb set are not + // mistaken for negative values when used for signed enumerators. + if (!isUnsigned.Val && value.Val.isUnsigned() && value.Val.isSignBitSet()) + Value = Value.zext(Value.getBitWidth() + 1); + Result = GET_OR_DISTINCT(DIEnumerator, (Context, Value, isUnsigned.Val, name.Val)); @@ -4557,7 +4660,8 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) { OPTIONAL(vtableHolder, MDField, ); \ OPTIONAL(templateParams, MDField, ); \ OPTIONAL(identifier, MDStringField, ); \ - OPTIONAL(discriminator, MDField, ); + OPTIONAL(discriminator, MDField, ); \ + OPTIONAL(dataLocation, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4566,8 +4670,8 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) { if (auto *CT = DICompositeType::buildODRType( Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val, - elements.Val, runtimeLang.Val, vtableHolder.Val, - templateParams.Val, discriminator.Val)) { + elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, + discriminator.Val, dataLocation.Val)) { Result = CT; return false; } @@ -4579,7 +4683,7 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) { (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val, elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val, - discriminator.Val)); + discriminator.Val, dataLocation.Val)); return false; } @@ -4633,7 +4737,8 @@ bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) { /// isOptimized: true, flags: "-O2", runtimeVersion: 1, /// splitDebugFilename: "abc.debug", /// emissionKind: FullDebug, enums: !1, retainedTypes: !2, -/// globals: !4, imports: !5, macros: !6, dwoId: 0x0abcd) +/// globals: !4, imports: !5, macros: !6, dwoId: 0x0abcd, +/// sysroot: "/", sdk: "MacOSX.sdk") bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { if (!IsDistinct) return Lex.Error("missing 'distinct', required for !DICompileUnit"); @@ -4656,7 +4761,9 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { OPTIONAL(splitDebugInlining, MDBoolField, = true); \ OPTIONAL(debugInfoForProfiling, MDBoolField, = false); \ OPTIONAL(nameTableKind, NameTableKindField, ); \ - OPTIONAL(debugBaseAddress, MDBoolField, = false); + OPTIONAL(rangesBaseAddress, MDBoolField, = false); \ + OPTIONAL(sysroot, MDStringField, ); \ + OPTIONAL(sdk, MDStringField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4665,7 +4772,7 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val, retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val, splitDebugInlining.Val, debugInfoForProfiling.Val, nameTableKind.Val, - debugBaseAddress.Val); + rangesBaseAddress.Val, sysroot.Val, sdk.Val); return false; } @@ -4762,7 +4869,7 @@ bool LLParser::ParseDICommonBlock(MDNode *&Result, bool IsDistinct) { OPTIONAL(declaration, MDField, ); \ OPTIONAL(name, MDStringField, ); \ OPTIONAL(file, MDField, ); \ - OPTIONAL(line, LineField, ); + OPTIONAL(line, LineField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4820,51 +4927,60 @@ bool LLParser::ParseDIMacroFile(MDNode *&Result, bool IsDistinct) { } /// ParseDIModule: -/// ::= !DIModule(scope: !0, name: "SomeModule", configMacros: "-DNDEBUG", -/// includePath: "/usr/include", sysroot: "/") +/// ::= !DIModule(scope: !0, name: "SomeModule", configMacros: +/// "-DNDEBUG", includePath: "/usr/include", apinotes: "module.apinotes", +/// file: !1, line: 4) bool LLParser::ParseDIModule(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(scope, MDField, ); \ REQUIRED(name, MDStringField, ); \ OPTIONAL(configMacros, MDStringField, ); \ OPTIONAL(includePath, MDStringField, ); \ - OPTIONAL(sysroot, MDStringField, ); + OPTIONAL(apinotes, MDStringField, ); \ + OPTIONAL(file, MDField, ); \ + OPTIONAL(line, LineField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DIModule, (Context, scope.Val, name.Val, - configMacros.Val, includePath.Val, sysroot.Val)); + Result = GET_OR_DISTINCT(DIModule, (Context, file.Val, scope.Val, name.Val, + configMacros.Val, includePath.Val, + apinotes.Val, line.Val)); return false; } /// ParseDITemplateTypeParameter: -/// ::= !DITemplateTypeParameter(name: "Ty", type: !1) +/// ::= !DITemplateTypeParameter(name: "Ty", type: !1, defaulted: false) bool LLParser::ParseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(name, MDStringField, ); \ - REQUIRED(type, MDField, ); + REQUIRED(type, MDField, ); \ + OPTIONAL(defaulted, MDBoolField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = - GET_OR_DISTINCT(DITemplateTypeParameter, (Context, name.Val, type.Val)); + Result = GET_OR_DISTINCT(DITemplateTypeParameter, + (Context, name.Val, type.Val, defaulted.Val)); return false; } /// ParseDITemplateValueParameter: /// ::= !DITemplateValueParameter(tag: DW_TAG_template_value_parameter, -/// name: "V", type: !1, value: i32 7) +/// name: "V", type: !1, defaulted: false, +/// value: i32 7) bool LLParser::ParseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_template_value_parameter)); \ OPTIONAL(name, MDStringField, ); \ OPTIONAL(type, MDField, ); \ + OPTIONAL(defaulted, MDBoolField, ); \ REQUIRED(value, MDField, ); + PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DITemplateValueParameter, - (Context, tag.Val, name.Val, type.Val, value.Val)); + Result = GET_OR_DISTINCT( + DITemplateValueParameter, + (Context, tag.Val, name.Val, type.Val, defaulted.Val, value.Val)); return false; } @@ -5174,13 +5290,16 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, !ConstantFP::isValueValidForType(Ty, ID.APFloatVal)) return Error(ID.Loc, "floating point constant invalid for type"); - // The lexer has no type info, so builds all half, float, and double FP - // constants as double. Fix this here. Long double does not need this. + // The lexer has no type info, so builds all half, bfloat, float, and double + // FP constants as double. Fix this here. Long double does not need this. if (&ID.APFloatVal.getSemantics() == &APFloat::IEEEdouble()) { bool Ignored; if (Ty->isHalfTy()) ID.APFloatVal.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored); + else if (Ty->isBFloatTy()) + ID.APFloatVal.convert(APFloat::BFloat(), APFloat::rmNearestTiesToEven, + &Ignored); else if (Ty->isFloatTy()) ID.APFloatVal.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &Ignored); @@ -5545,7 +5664,7 @@ bool LLParser::PerFunctionState::resolveForwardRefBlockAddresses() { ValID ID; if (FunctionNumber == -1) { ID.Kind = ValID::t_GlobalName; - ID.StrVal = F.getName(); + ID.StrVal = std::string(F.getName()); } else { ID.Kind = ValID::t_GlobalID; ID.UIntVal = FunctionNumber; @@ -6419,9 +6538,6 @@ bool LLParser::ParseCallBr(Instruction *&Inst, PerFunctionState &PFS) { /*IsCall=*/true)) return true; - if (isa<InlineAsm>(Callee) && !Ty->getReturnType()->isVoidTy()) - return Error(RetTypeLoc, "asm-goto outputs not supported"); - // Set up the Attribute for the function. SmallVector<Value *, 8> Args; SmallVector<AttributeSet, 8> ArgAttrs; @@ -6868,9 +6984,11 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, CI->setTailCallKind(TCK); CI->setCallingConv(CC); if (FMF.any()) { - if (!isa<FPMathOperator>(CI)) + if (!isa<FPMathOperator>(CI)) { + CI->deleteValue(); return Error(CallLoc, "fast-math-flags specified for call without " "floating-point scalar or vector return type"); + } CI->setFastMathFlags(FMF); } CI->setAttributes(PAL); @@ -6937,7 +7055,12 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { if (Size && !Size->getType()->isIntegerTy()) return Error(SizeLoc, "element count must have integer type"); - AllocaInst *AI = new AllocaInst(Ty, AddrSpace, Size, Alignment); + SmallPtrSet<Type *, 4> Visited; + if (!Alignment && !Ty->isSized(&Visited)) + return Error(TyLoc, "Cannot allocate unsized type"); + if (!Alignment) + Alignment = M->getDataLayout().getPrefTypeAlign(Ty); + AllocaInst *AI = new AllocaInst(Ty, AddrSpace, Size, *Alignment); AI->setUsedWithInAlloca(IsInAlloca); AI->setSwiftError(IsSwiftError); Inst = AI; @@ -6987,8 +7110,12 @@ int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) { if (Ty != cast<PointerType>(Val->getType())->getElementType()) return Error(ExplicitTypeLoc, "explicit pointee type doesn't match operand's pointee type"); - - Inst = new LoadInst(Ty, Val, "", isVolatile, Alignment, Ordering, SSID); + SmallPtrSet<Type *, 4> Visited; + if (!Alignment && !Ty->isSized(&Visited)) + return Error(ExplicitTypeLoc, "loading unsized types is not allowed"); + if (!Alignment) + Alignment = M->getDataLayout().getABITypeAlign(Ty); + Inst = new LoadInst(Ty, Val, "", isVolatile, *Alignment, Ordering, SSID); return AteExtraComma ? InstExtraComma : InstNormal; } @@ -7034,8 +7161,13 @@ int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS) { if (Ordering == AtomicOrdering::Acquire || Ordering == AtomicOrdering::AcquireRelease) return Error(Loc, "atomic store cannot use Acquire ordering"); + SmallPtrSet<Type *, 4> Visited; + if (!Alignment && !Val->getType()->isSized(&Visited)) + return Error(Loc, "storing unsized types is not allowed"); + if (!Alignment) + Alignment = M->getDataLayout().getABITypeAlign(Val->getType()); - Inst = new StoreInst(Val, Ptr, isVolatile, Alignment, Ordering, SSID); + Inst = new StoreInst(Val, Ptr, isVolatile, *Alignment, Ordering, SSID); return AteExtraComma ? InstExtraComma : InstNormal; } @@ -7084,8 +7216,13 @@ int LLParser::ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { return Error(NewLoc, "new value and pointer type do not match"); if (!New->getType()->isFirstClassType()) return Error(NewLoc, "cmpxchg operand must be a first class value"); + + Align Alignment( + PFS.getFunction().getParent()->getDataLayout().getTypeStoreSize( + Cmp->getType())); + AtomicCmpXchgInst *CXI = new AtomicCmpXchgInst( - Ptr, Cmp, New, SuccessOrdering, FailureOrdering, SSID); + Ptr, Cmp, New, Alignment, SuccessOrdering, FailureOrdering, SSID); CXI->setVolatile(isVolatile); CXI->setWeak(isWeak); Inst = CXI; @@ -7169,9 +7306,11 @@ int LLParser::ParseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) { if (Size < 8 || (Size & (Size - 1))) return Error(ValLoc, "atomicrmw operand must be power-of-two byte-sized" " integer"); - + Align Alignment( + PFS.getFunction().getParent()->getDataLayout().getTypeStoreSize( + Val->getType())); AtomicRMWInst *RMWI = - new AtomicRMWInst(Operation, Ptr, Val, Ordering, SSID); + new AtomicRMWInst(Operation, Ptr, Val, Alignment, Ordering, SSID); RMWI->setVolatile(isVolatile); Inst = RMWI; return AteExtraComma ? InstExtraComma : InstNormal; @@ -7223,8 +7362,9 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { bool AteExtraComma = false; // GEP returns a vector of pointers if at least one of parameters is a vector. // All vector parameters should have the same vector width. - unsigned GEPWidth = BaseType->isVectorTy() ? - BaseType->getVectorNumElements() : 0; + ElementCount GEPWidth = BaseType->isVectorTy() + ? cast<VectorType>(BaseType)->getElementCount() + : ElementCount(0, false); while (EatIfPresent(lltok::comma)) { if (Lex.getKind() == lltok::MetadataVar) { @@ -7235,9 +7375,9 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { if (!Val->getType()->isIntOrIntVectorTy()) return Error(EltLoc, "getelementptr index must be an integer"); - if (Val->getType()->isVectorTy()) { - unsigned ValNumEl = Val->getType()->getVectorNumElements(); - if (GEPWidth && GEPWidth != ValNumEl) + if (auto *ValVTy = dyn_cast<VectorType>(Val->getType())) { + ElementCount ValNumEl = ValVTy->getElementCount(); + if (GEPWidth != ElementCount(0, false) && GEPWidth != ValNumEl) return Error(EltLoc, "getelementptr vector index has a wrong number of elements"); GEPWidth = ValNumEl; @@ -7659,6 +7799,9 @@ bool LLParser::ParseTypeTestResolution(TypeTestResolution &TTRes) { return true; switch (Lex.getKind()) { + case lltok::kw_unknown: + TTRes.TheKind = TypeTestResolution::Unknown; + break; case lltok::kw_unsat: TTRes.TheKind = TypeTestResolution::Unsat; break; @@ -7991,6 +8134,36 @@ void LLParser::AddGlobalValueToIndex( } } +/// ParseSummaryIndexFlags +/// ::= 'flags' ':' UInt64 +bool LLParser::ParseSummaryIndexFlags() { + assert(Lex.getKind() == lltok::kw_flags); + Lex.Lex(); + + if (ParseToken(lltok::colon, "expected ':' here")) + return true; + uint64_t Flags; + if (ParseUInt64(Flags)) + return true; + Index->setFlags(Flags); + return false; +} + +/// ParseBlockCount +/// ::= 'blockcount' ':' UInt64 +bool LLParser::ParseBlockCount() { + assert(Lex.getKind() == lltok::kw_blockcount); + Lex.Lex(); + + if (ParseToken(lltok::colon, "expected ':' here")) + return true; + uint64_t BlockCount; + if (ParseUInt64(BlockCount)) + return true; + Index->setBlockCount(BlockCount); + return false; +} + /// ParseGVEntry /// ::= 'gv' ':' '(' ('name' ':' STRINGCONSTANT | 'guid' ':' UInt64) /// [',' 'summaries' ':' Summary[',' Summary]* ]? ')' @@ -8039,12 +8212,10 @@ bool LLParser::ParseGVEntry(unsigned ID) { // Have a list of summaries if (ParseToken(lltok::kw_summaries, "expected 'summaries' here") || - ParseToken(lltok::colon, "expected ':' here")) + ParseToken(lltok::colon, "expected ':' here") || + ParseToken(lltok::lparen, "expected '(' here")) return true; - do { - if (ParseToken(lltok::lparen, "expected '(' here")) - return true; switch (Lex.getKind()) { case lltok::kw_function: if (ParseFunctionSummary(Name, GUID, ID)) @@ -8061,11 +8232,10 @@ bool LLParser::ParseGVEntry(unsigned ID) { default: return Error(Lex.getLoc(), "expected summary type"); } - if (ParseToken(lltok::rparen, "expected ')' here")) - return true; } while (EatIfPresent(lltok::comma)); - if (ParseToken(lltok::rparen, "expected ')' here")) + if (ParseToken(lltok::rparen, "expected ')' here") || + ParseToken(lltok::rparen, "expected ')' here")) return true; return false; @@ -8074,7 +8244,8 @@ bool LLParser::ParseGVEntry(unsigned ID) { /// FunctionSummary /// ::= 'function' ':' '(' 'module' ':' ModuleReference ',' GVFlags /// ',' 'insts' ':' UInt32 [',' OptionalFFlags]? [',' OptionalCalls]? -/// [',' OptionalTypeIdInfo]? [',' OptionalRefs]? ')' +/// [',' OptionalTypeIdInfo]? [',' OptionalParamAccesses]? +/// [',' OptionalRefs]? ')' bool LLParser::ParseFunctionSummary(std::string Name, GlobalValue::GUID GUID, unsigned ID) { assert(Lex.getKind() == lltok::kw_function); @@ -8087,6 +8258,7 @@ bool LLParser::ParseFunctionSummary(std::string Name, GlobalValue::GUID GUID, unsigned InstCount; std::vector<FunctionSummary::EdgeTy> Calls; FunctionSummary::TypeIdInfo TypeIdInfo; + std::vector<FunctionSummary::ParamAccess> ParamAccesses; std::vector<ValueInfo> Refs; // Default is all-zeros (conservative values). FunctionSummary::FFlags FFlags = {}; @@ -8118,6 +8290,10 @@ bool LLParser::ParseFunctionSummary(std::string Name, GlobalValue::GUID GUID, if (ParseOptionalRefs(Refs)) return true; break; + case lltok::kw_params: + if (ParseOptionalParamAccesses(ParamAccesses)) + return true; + break; default: return Error(Lex.getLoc(), "expected optional function summary field"); } @@ -8132,7 +8308,8 @@ bool LLParser::ParseFunctionSummary(std::string Name, GlobalValue::GUID GUID, std::move(TypeIdInfo.TypeTestAssumeVCalls), std::move(TypeIdInfo.TypeCheckedLoadVCalls), std::move(TypeIdInfo.TypeTestAssumeConstVCalls), - std::move(TypeIdInfo.TypeCheckedLoadConstVCalls)); + std::move(TypeIdInfo.TypeCheckedLoadConstVCalls), + std::move(ParamAccesses)); FS->setModulePath(ModulePath); @@ -8155,7 +8332,9 @@ bool LLParser::ParseVariableSummary(std::string Name, GlobalValue::GUID GUID, /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false, /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false); GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false, - /* WriteOnly */ false); + /* WriteOnly */ false, + /* Constant */ false, + GlobalObject::VCallVisibilityPublic); std::vector<ValueInfo> Refs; VTableFuncList VTableFuncs; if (ParseToken(lltok::colon, "expected ':' here") || @@ -8479,13 +8658,133 @@ bool LLParser::ParseOptionalVTableFuncs(VTableFuncList &VTableFuncs) { return false; } +/// ParamNo := 'param' ':' UInt64 +bool LLParser::ParseParamNo(uint64_t &ParamNo) { + if (ParseToken(lltok::kw_param, "expected 'param' here") || + ParseToken(lltok::colon, "expected ':' here") || ParseUInt64(ParamNo)) + return true; + return false; +} + +/// ParamAccessOffset := 'offset' ':' '[' APSINTVAL ',' APSINTVAL ']' +bool LLParser::ParseParamAccessOffset(ConstantRange &Range) { + APSInt Lower; + APSInt Upper; + auto ParseAPSInt = [&](APSInt &Val) { + if (Lex.getKind() != lltok::APSInt) + return TokError("expected integer"); + Val = Lex.getAPSIntVal(); + Val = Val.extOrTrunc(FunctionSummary::ParamAccess::RangeWidth); + Val.setIsSigned(true); + Lex.Lex(); + return false; + }; + if (ParseToken(lltok::kw_offset, "expected 'offset' here") || + ParseToken(lltok::colon, "expected ':' here") || + ParseToken(lltok::lsquare, "expected '[' here") || ParseAPSInt(Lower) || + ParseToken(lltok::comma, "expected ',' here") || ParseAPSInt(Upper) || + ParseToken(lltok::rsquare, "expected ']' here")) + return true; + + ++Upper; + Range = + (Lower == Upper && !Lower.isMaxValue()) + ? ConstantRange::getEmpty(FunctionSummary::ParamAccess::RangeWidth) + : ConstantRange(Lower, Upper); + + return false; +} + +/// ParamAccessCall +/// := '(' 'callee' ':' GVReference ',' ParamNo ',' ParamAccessOffset ')' +bool LLParser::ParseParamAccessCall(FunctionSummary::ParamAccess::Call &Call) { + if (ParseToken(lltok::lparen, "expected '(' here") || + ParseToken(lltok::kw_callee, "expected 'callee' here") || + ParseToken(lltok::colon, "expected ':' here")) + return true; + + unsigned GVId; + ValueInfo VI; + if (ParseGVReference(VI, GVId)) + return true; + + Call.Callee = VI.getGUID(); + + if (ParseToken(lltok::comma, "expected ',' here") || + ParseParamNo(Call.ParamNo) || + ParseToken(lltok::comma, "expected ',' here") || + ParseParamAccessOffset(Call.Offsets)) + return true; + + if (ParseToken(lltok::rparen, "expected ')' here")) + return true; + + return false; +} + +/// ParamAccess +/// := '(' ParamNo ',' ParamAccessOffset [',' OptionalParamAccessCalls]? ')' +/// OptionalParamAccessCalls := '(' Call [',' Call]* ')' +bool LLParser::ParseParamAccess(FunctionSummary::ParamAccess &Param) { + if (ParseToken(lltok::lparen, "expected '(' here") || + ParseParamNo(Param.ParamNo) || + ParseToken(lltok::comma, "expected ',' here") || + ParseParamAccessOffset(Param.Use)) + return true; + + if (EatIfPresent(lltok::comma)) { + if (ParseToken(lltok::kw_calls, "expected 'calls' here") || + ParseToken(lltok::colon, "expected ':' here") || + ParseToken(lltok::lparen, "expected '(' here")) + return true; + do { + FunctionSummary::ParamAccess::Call Call; + if (ParseParamAccessCall(Call)) + return true; + Param.Calls.push_back(Call); + } while (EatIfPresent(lltok::comma)); + + if (ParseToken(lltok::rparen, "expected ')' here")) + return true; + } + + if (ParseToken(lltok::rparen, "expected ')' here")) + return true; + + return false; +} + +/// OptionalParamAccesses +/// := 'params' ':' '(' ParamAccess [',' ParamAccess]* ')' +bool LLParser::ParseOptionalParamAccesses( + std::vector<FunctionSummary::ParamAccess> &Params) { + assert(Lex.getKind() == lltok::kw_params); + Lex.Lex(); + + if (ParseToken(lltok::colon, "expected ':' here") || + ParseToken(lltok::lparen, "expected '(' here")) + return true; + + do { + FunctionSummary::ParamAccess ParamAccess; + if (ParseParamAccess(ParamAccess)) + return true; + Params.push_back(ParamAccess); + } while (EatIfPresent(lltok::comma)); + + if (ParseToken(lltok::rparen, "expected ')' here")) + return true; + + return false; +} + /// OptionalRefs /// := 'refs' ':' '(' GVReference [',' GVReference]* ')' bool LLParser::ParseOptionalRefs(std::vector<ValueInfo> &Refs) { assert(Lex.getKind() == lltok::kw_refs); Lex.Lex(); - if (ParseToken(lltok::colon, "expected ':' in refs") | + if (ParseToken(lltok::colon, "expected ':' in refs") || ParseToken(lltok::lparen, "expected '(' in refs")) return true; @@ -8827,7 +9126,8 @@ bool LLParser::ParseGVFlags(GlobalValueSummary::GVFlags &GVFlags) { /// GVarFlags /// ::= 'varFlags' ':' '(' 'readonly' ':' Flag -/// ',' 'writeonly' ':' Flag ')' +/// ',' 'writeonly' ':' Flag +/// ',' 'constant' ':' Flag ')' bool LLParser::ParseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) { assert(Lex.getKind() == lltok::kw_varFlags); Lex.Lex(); @@ -8856,6 +9156,16 @@ bool LLParser::ParseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) { return true; GVarFlags.MaybeWriteOnly = Flag; break; + case lltok::kw_constant: + if (ParseRest(Flag)) + return true; + GVarFlags.Constant = Flag; + break; + case lltok::kw_vcall_visibility: + if (ParseRest(Flag)) + return true; + GVarFlags.VCallVisibility = Flag; + break; default: return Error(Lex.getLoc(), "expected gvar flag type"); } diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index cf2121dcc70a1..ebd8655dc35e9 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -16,18 +16,16 @@ #include "LLLexer.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringMap.h" +#include "llvm/AsmParser/Parser.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Instructions.h" -#include "llvm/IR/Module.h" #include "llvm/IR/ModuleSummaryIndex.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" -#include "llvm/IR/ValueHandle.h" #include <map> namespace llvm { class Module; - class OpaqueType; class Function; class Value; class BasicBlock; @@ -38,7 +36,6 @@ namespace llvm { class MDString; class MDNode; struct SlotMapping; - 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 @@ -160,23 +157,17 @@ namespace llvm { /// UpgradeDebuginfo so it can generate broken bitcode. bool UpgradeDebugInfo; - /// DataLayout string to override that in LLVM assembly. - StringRef DataLayoutStr; - std::string SourceFileName; public: LLParser(StringRef F, SourceMgr &SM, SMDiagnostic &Err, Module *M, ModuleSummaryIndex *Index, LLVMContext &Context, - SlotMapping *Slots = nullptr, bool UpgradeDebugInfo = true, - StringRef DataLayoutString = "") + SlotMapping *Slots = nullptr) : Context(Context), Lex(F, SM, Err, Context), M(M), Index(Index), - Slots(Slots), BlockAddressPFS(nullptr), - UpgradeDebugInfo(UpgradeDebugInfo), DataLayoutStr(DataLayoutString) { - if (!DataLayoutStr.empty()) - M->setDataLayout(DataLayoutStr); - } - bool Run(); + Slots(Slots), BlockAddressPFS(nullptr) {} + bool Run( + bool UpgradeDebugInfo, + DataLayoutCallbackTy DataLayoutCallback = [](Module *) {}); bool parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots); @@ -281,7 +272,8 @@ namespace llvm { void ParseOptionalVisibility(unsigned &Res); void ParseOptionalDLLStorageClass(unsigned &Res); bool ParseOptionalCallingConv(unsigned &CC); - bool ParseOptionalAlignment(MaybeAlign &Alignment); + bool ParseOptionalAlignment(MaybeAlign &Alignment, + bool AllowParens = false); bool ParseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes); bool ParseScopeAndOrdering(bool isAtomic, SyncScope::ID &SSID, AtomicOrdering &Ordering); @@ -306,8 +298,9 @@ namespace llvm { // Top-Level Entities bool ParseTopLevelEntities(); - bool ValidateEndOfModule(); + bool ValidateEndOfModule(bool UpgradeDebugInfo); bool ValidateEndOfIndex(); + bool ParseTargetDefinitions(); bool ParseTargetDefinition(); bool ParseModuleAsm(); bool ParseSourceFileName(); @@ -340,6 +333,7 @@ namespace llvm { std::vector<unsigned> &FwdRefAttrGrps, bool inAttrGrp, LocTy &BuiltinLoc); bool ParseByValWithOptionalType(Type *&Result); + bool ParsePreallocated(Type *&Result); // Module Summary Index Parsing. bool SkipModuleSummaryEntry(); @@ -347,6 +341,8 @@ namespace llvm { bool ParseModuleEntry(unsigned ID); bool ParseModuleReference(StringRef &ModulePath); bool ParseGVReference(ValueInfo &VI, unsigned &GVId); + bool ParseSummaryIndexFlags(); + bool ParseBlockCount(); bool ParseGVEntry(unsigned ID); bool ParseFunctionSummary(std::string Name, GlobalValue::GUID, unsigned ID); bool ParseVariableSummary(std::string Name, GlobalValue::GUID, unsigned ID); @@ -370,6 +366,12 @@ namespace llvm { bool ParseVFuncId(FunctionSummary::VFuncId &VFuncId, IdToIndexMapType &IdToIndexMap, unsigned Index); bool ParseOptionalVTableFuncs(VTableFuncList &VTableFuncs); + bool ParseOptionalParamAccesses( + std::vector<FunctionSummary::ParamAccess> &Params); + bool ParseParamNo(uint64_t &ParamNo); + bool ParseParamAccess(FunctionSummary::ParamAccess &Param); + bool ParseParamAccessCall(FunctionSummary::ParamAccess::Call &Call); + bool ParseParamAccessOffset(ConstantRange &range); bool ParseOptionalRefs(std::vector<ValueInfo> &Refs); bool ParseTypeIdEntry(unsigned ID); bool ParseTypeIdSummary(TypeIdSummary &TIS); diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index e430e0f6faa04..0fb3bae77dd3f 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -196,6 +196,7 @@ enum Kind { kw_naked, kw_nest, kw_noalias, + kw_noundef, kw_nobuiltin, kw_nocapture, kw_noduplicate, @@ -204,15 +205,18 @@ enum Kind { kw_noinline, kw_norecurse, kw_nonlazybind, + kw_nomerge, kw_nonnull, kw_noredzone, kw_noreturn, kw_nosync, kw_nocf_check, kw_nounwind, + kw_null_pointer_is_valid, kw_optforfuzzing, kw_optnone, kw_optsize, + kw_preallocated, kw_readnone, kw_readonly, kw_returned, @@ -371,6 +375,7 @@ enum Kind { kw_name, kw_summaries, kw_flags, + kw_blockcount, kw_linkage, kw_notEligibleToImport, kw_live, @@ -387,6 +392,8 @@ enum Kind { kw_alwaysInline, kw_calls, kw_callee, + kw_params, + kw_param, kw_hotness, kw_unknown, kw_hot, @@ -421,6 +428,7 @@ enum Kind { kw_sizeM1, kw_bitMask, kw_inlineBits, + kw_vcall_visibility, kw_wpdResolutions, kw_wpdRes, kw_indir, diff --git a/llvm/lib/AsmParser/Parser.cpp b/llvm/lib/AsmParser/Parser.cpp index b7f552a6fccb9..8147620181f9c 100644 --- a/llvm/lib/AsmParser/Parser.cpp +++ b/llvm/lib/AsmParser/Parser.cpp @@ -17,44 +17,50 @@ #include "llvm/IR/ModuleSummaryIndex.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" -#include "llvm/Support/raw_ostream.h" #include <cstring> #include <system_error> + using namespace llvm; -bool llvm::parseAssemblyInto(MemoryBufferRef F, Module *M, - ModuleSummaryIndex *Index, SMDiagnostic &Err, - SlotMapping *Slots, bool UpgradeDebugInfo, - StringRef DataLayoutString) { +static bool parseAssemblyInto(MemoryBufferRef F, Module *M, + ModuleSummaryIndex *Index, SMDiagnostic &Err, + SlotMapping *Slots, bool UpgradeDebugInfo, + DataLayoutCallbackTy DataLayoutCallback) { SourceMgr SM; std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F); SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); LLVMContext Context; return LLParser(F.getBuffer(), SM, Err, M, Index, - M ? M->getContext() : Context, Slots, UpgradeDebugInfo, - DataLayoutString) - .Run(); + M ? M->getContext() : Context, Slots) + .Run(UpgradeDebugInfo, DataLayoutCallback); +} + +bool llvm::parseAssemblyInto(MemoryBufferRef F, Module *M, + ModuleSummaryIndex *Index, SMDiagnostic &Err, + SlotMapping *Slots, + DataLayoutCallbackTy DataLayoutCallback) { + return ::parseAssemblyInto(F, M, Index, Err, Slots, + /*UpgradeDebugInfo*/ true, DataLayoutCallback); } std::unique_ptr<Module> llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, - SlotMapping *Slots, bool UpgradeDebugInfo, - StringRef DataLayoutString) { + SlotMapping *Slots, + DataLayoutCallbackTy DataLayoutCallback) { std::unique_ptr<Module> M = std::make_unique<Module>(F.getBufferIdentifier(), Context); - if (parseAssemblyInto(F, M.get(), nullptr, Err, Slots, UpgradeDebugInfo, - DataLayoutString)) + if (parseAssemblyInto(F, M.get(), nullptr, Err, Slots, DataLayoutCallback)) return nullptr; return M; } -std::unique_ptr<Module> -llvm::parseAssemblyFile(StringRef Filename, SMDiagnostic &Err, - LLVMContext &Context, SlotMapping *Slots, - bool UpgradeDebugInfo, StringRef DataLayoutString) { +std::unique_ptr<Module> llvm::parseAssemblyFile(StringRef Filename, + SMDiagnostic &Err, + LLVMContext &Context, + SlotMapping *Slots) { ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename); if (std::error_code EC = FileOrErr.getError()) { @@ -63,28 +69,40 @@ llvm::parseAssemblyFile(StringRef Filename, SMDiagnostic &Err, return nullptr; } - return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots, - UpgradeDebugInfo, DataLayoutString); + return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots); } -ParsedModuleAndIndex llvm::parseAssemblyWithIndex( - MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, - SlotMapping *Slots, bool UpgradeDebugInfo, StringRef DataLayoutString) { +static ParsedModuleAndIndex +parseAssemblyWithIndex(MemoryBufferRef F, SMDiagnostic &Err, + LLVMContext &Context, SlotMapping *Slots, + bool UpgradeDebugInfo, + DataLayoutCallbackTy DataLayoutCallback) { std::unique_ptr<Module> M = std::make_unique<Module>(F.getBufferIdentifier(), Context); std::unique_ptr<ModuleSummaryIndex> Index = std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/true); if (parseAssemblyInto(F, M.get(), Index.get(), Err, Slots, UpgradeDebugInfo, - DataLayoutString)) + DataLayoutCallback)) return {nullptr, nullptr}; return {std::move(M), std::move(Index)}; } -ParsedModuleAndIndex llvm::parseAssemblyFileWithIndex( - StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, - SlotMapping *Slots, bool UpgradeDebugInfo, StringRef DataLayoutString) { +ParsedModuleAndIndex llvm::parseAssemblyWithIndex(MemoryBufferRef F, + SMDiagnostic &Err, + LLVMContext &Context, + SlotMapping *Slots) { + return ::parseAssemblyWithIndex(F, Err, Context, Slots, + /*UpgradeDebugInfo*/ true, + [](StringRef) { return None; }); +} + +static ParsedModuleAndIndex +parseAssemblyFileWithIndex(StringRef Filename, SMDiagnostic &Err, + LLVMContext &Context, SlotMapping *Slots, + bool UpgradeDebugInfo, + DataLayoutCallbackTy DataLayoutCallback) { ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename); if (std::error_code EC = FileOrErr.getError()) { @@ -95,16 +113,32 @@ ParsedModuleAndIndex llvm::parseAssemblyFileWithIndex( return parseAssemblyWithIndex(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots, UpgradeDebugInfo, - DataLayoutString); + DataLayoutCallback); } -std::unique_ptr<Module> -llvm::parseAssemblyString(StringRef AsmString, SMDiagnostic &Err, - LLVMContext &Context, SlotMapping *Slots, - bool UpgradeDebugInfo, StringRef DataLayoutString) { +ParsedModuleAndIndex +llvm::parseAssemblyFileWithIndex(StringRef Filename, SMDiagnostic &Err, + LLVMContext &Context, SlotMapping *Slots, + DataLayoutCallbackTy DataLayoutCallback) { + return ::parseAssemblyFileWithIndex(Filename, Err, Context, Slots, + /*UpgradeDebugInfo*/ true, + DataLayoutCallback); +} + +ParsedModuleAndIndex llvm::parseAssemblyFileWithIndexNoUpgradeDebugInfo( + StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, + SlotMapping *Slots, DataLayoutCallbackTy DataLayoutCallback) { + return ::parseAssemblyFileWithIndex(Filename, Err, Context, Slots, + /*UpgradeDebugInfo*/ false, + DataLayoutCallback); +} + +std::unique_ptr<Module> llvm::parseAssemblyString(StringRef AsmString, + SMDiagnostic &Err, + LLVMContext &Context, + SlotMapping *Slots) { MemoryBufferRef F(AsmString, "<string>"); - return parseAssembly(F, Err, Context, Slots, UpgradeDebugInfo, - DataLayoutString); + return parseAssembly(F, Err, Context, Slots); } static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F, @@ -117,7 +151,8 @@ static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F, // The parser holds a reference to a context that is unused when parsing the // index, but we need to initialize it. LLVMContext unusedContext; - return LLParser(F.getBuffer(), SM, Err, nullptr, &Index, unusedContext).Run(); + return LLParser(F.getBuffer(), SM, Err, nullptr, &Index, unusedContext) + .Run(true, [](StringRef) { return None; }); } std::unique_ptr<ModuleSummaryIndex> |