diff options
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 259 |
1 files changed, 158 insertions, 101 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 5f0d1a76de79..fb9e1ba875e1 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1286,6 +1286,11 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc, return true; if (Alignment) GV->setAlignment(*Alignment); + } else if (Lex.getKind() == lltok::kw_code_model) { + CodeModel::Model CodeModel; + if (parseOptionalCodeModel(CodeModel)) + return true; + GV->setCodeModel(CodeModel); } else if (Lex.getKind() == lltok::MetadataVar) { if (parseGlobalObjectMetadataAttachment(*GV)) return true; @@ -1977,7 +1982,6 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) { /// ::= 'spir_kernel' /// ::= 'x86_64_sysvcc' /// ::= 'win64cc' -/// ::= 'webkit_jscc' /// ::= 'anyregcc' /// ::= 'preserve_mostcc' /// ::= 'preserve_allcc' @@ -1999,6 +2003,8 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) { /// ::= 'amdgpu_cs_chain_preserve' /// ::= 'amdgpu_kernel' /// ::= 'tailcc' +/// ::= 'm68k_rtdcc' +/// ::= 'graalcc' /// ::= 'cc' UINT /// bool LLParser::parseOptionalCallingConv(unsigned &CC) { @@ -2036,7 +2042,6 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) { case lltok::kw_intel_ocl_bicc: CC = CallingConv::Intel_OCL_BI; break; case lltok::kw_x86_64_sysvcc: CC = CallingConv::X86_64_SysV; break; case lltok::kw_win64cc: CC = CallingConv::Win64; break; - case lltok::kw_webkit_jscc: CC = CallingConv::WebKit_JS; break; case lltok::kw_anyregcc: CC = CallingConv::AnyReg; break; case lltok::kw_preserve_mostcc:CC = CallingConv::PreserveMost; break; case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break; @@ -2067,6 +2072,8 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) { break; case lltok::kw_amdgpu_kernel: CC = CallingConv::AMDGPU_KERNEL; break; case lltok::kw_tailcc: CC = CallingConv::Tail; break; + case lltok::kw_m68k_rtdcc: CC = CallingConv::M68k_RTD; break; + case lltok::kw_graalcc: CC = CallingConv::GRAAL; break; case lltok::kw_cc: { Lex.Lex(); return parseUInt32(CC); @@ -2166,6 +2173,30 @@ bool LLParser::parseOptionalAlignment(MaybeAlign &Alignment, bool AllowParens) { return false; } +/// parseOptionalCodeModel +/// ::= /* empty */ +/// ::= 'code_model' "large" +bool LLParser::parseOptionalCodeModel(CodeModel::Model &model) { + Lex.Lex(); + auto StrVal = Lex.getStrVal(); + auto ErrMsg = "expected global code model string"; + if (StrVal == "tiny") + model = CodeModel::Tiny; + else if (StrVal == "small") + model = CodeModel::Small; + else if (StrVal == "kernel") + model = CodeModel::Kernel; + else if (StrVal == "medium") + model = CodeModel::Medium; + else if (StrVal == "large") + model = CodeModel::Large; + else + return tokError(ErrMsg); + if (parseToken(lltok::StringConstant, ErrMsg)) + return true; + return false; +} + /// parseOptionalDerefAttrBytes /// ::= /* empty */ /// ::= AttrKind '(' 4 ')' @@ -3803,16 +3834,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { } case lltok::kw_trunc: - case lltok::kw_zext: - case lltok::kw_sext: - case lltok::kw_fptrunc: - case lltok::kw_fpext: case lltok::kw_bitcast: case lltok::kw_addrspacecast: - case lltok::kw_uitofp: - case lltok::kw_sitofp: - case lltok::kw_fptoui: - case lltok::kw_fptosi: case lltok::kw_inttoptr: case lltok::kw_ptrtoint: { unsigned Opc = Lex.getUIntVal(); @@ -3856,10 +3879,34 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { return error(ID.Loc, "fdiv constexprs are no longer supported"); case lltok::kw_frem: return error(ID.Loc, "frem constexprs are no longer supported"); + case lltok::kw_and: + return error(ID.Loc, "and constexprs are no longer supported"); + case lltok::kw_or: + return error(ID.Loc, "or constexprs are no longer supported"); + case lltok::kw_lshr: + return error(ID.Loc, "lshr constexprs are no longer supported"); + case lltok::kw_ashr: + return error(ID.Loc, "ashr constexprs are no longer supported"); case lltok::kw_fneg: return error(ID.Loc, "fneg constexprs are no longer supported"); case lltok::kw_select: return error(ID.Loc, "select constexprs are no longer supported"); + case lltok::kw_zext: + return error(ID.Loc, "zext constexprs are no longer supported"); + case lltok::kw_sext: + return error(ID.Loc, "sext constexprs are no longer supported"); + case lltok::kw_fptrunc: + return error(ID.Loc, "fptrunc constexprs are no longer supported"); + case lltok::kw_fpext: + return error(ID.Loc, "fpext constexprs are no longer supported"); + case lltok::kw_uitofp: + return error(ID.Loc, "uitofp constexprs are no longer supported"); + case lltok::kw_sitofp: + return error(ID.Loc, "sitofp constexprs are no longer supported"); + case lltok::kw_fptoui: + return error(ID.Loc, "fptoui constexprs are no longer supported"); + case lltok::kw_fptosi: + return error(ID.Loc, "fptosi constexprs are no longer supported"); case lltok::kw_icmp: case lltok::kw_fcmp: { unsigned PredVal, Opc = Lex.getUIntVal(); @@ -3898,11 +3945,9 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { case lltok::kw_sub: case lltok::kw_mul: case lltok::kw_shl: - case lltok::kw_lshr: - case lltok::kw_ashr: { + case lltok::kw_xor: { bool NUW = false; bool NSW = false; - bool Exact = false; unsigned Opc = Lex.getUIntVal(); Constant *Val0, *Val1; Lex.Lex(); @@ -3915,10 +3960,6 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { if (EatIfPresent(lltok::kw_nuw)) NUW = true; } - } else if (Opc == Instruction::SDiv || Opc == Instruction::UDiv || - Opc == Instruction::LShr || Opc == Instruction::AShr) { - if (EatIfPresent(lltok::kw_exact)) - Exact = true; } if (parseToken(lltok::lparen, "expected '(' in binary constantexpr") || parseGlobalTypeAndValue(Val0) || @@ -3929,60 +3970,29 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { if (Val0->getType() != Val1->getType()) return error(ID.Loc, "operands of constexpr must have same type"); // Check that the type is valid for the operator. - switch (Opc) { - case Instruction::Add: - case Instruction::Sub: - case Instruction::Mul: - case Instruction::UDiv: - case Instruction::SDiv: - case Instruction::URem: - case Instruction::SRem: - case Instruction::Shl: - case Instruction::AShr: - case Instruction::LShr: - if (!Val0->getType()->isIntOrIntVectorTy()) - return error(ID.Loc, "constexpr requires integer operands"); - break; - case Instruction::FAdd: - case Instruction::FSub: - case Instruction::FMul: - case Instruction::FDiv: - case Instruction::FRem: - if (!Val0->getType()->isFPOrFPVectorTy()) - return error(ID.Loc, "constexpr requires fp operands"); - break; - default: llvm_unreachable("Unknown binary operator!"); - } + if (!Val0->getType()->isIntOrIntVectorTy()) + return error(ID.Loc, + "constexpr requires integer or integer vector operands"); unsigned Flags = 0; if (NUW) Flags |= OverflowingBinaryOperator::NoUnsignedWrap; if (NSW) Flags |= OverflowingBinaryOperator::NoSignedWrap; - if (Exact) Flags |= PossiblyExactOperator::IsExact; - Constant *C = ConstantExpr::get(Opc, Val0, Val1, Flags); - ID.ConstantVal = C; + ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1, Flags); ID.Kind = ValID::t_Constant; return false; } - // Logical Operations - case lltok::kw_and: - case lltok::kw_or: - case lltok::kw_xor: { - unsigned Opc = Lex.getUIntVal(); - Constant *Val0, *Val1; + case lltok::kw_splat: { Lex.Lex(); - if (parseToken(lltok::lparen, "expected '(' in logical constantexpr") || - parseGlobalTypeAndValue(Val0) || - parseToken(lltok::comma, "expected comma in logical constantexpr") || - parseGlobalTypeAndValue(Val1) || - parseToken(lltok::rparen, "expected ')' in logical constantexpr")) + if (parseToken(lltok::lparen, "expected '(' after vector splat")) return true; - if (Val0->getType() != Val1->getType()) - return error(ID.Loc, "operands of constexpr must have same type"); - if (!Val0->getType()->isIntOrIntVectorTy()) - return error(ID.Loc, - "constexpr requires integer or integer vector operands"); - ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1); - ID.Kind = ValID::t_Constant; + Constant *C; + if (parseGlobalTypeAndValue(C)) + return true; + if (parseToken(lltok::rparen, "expected ')' at end of vector splat")) + return true; + + ID.ConstantVal = C; + ID.Kind = ValID::t_ConstantSplat; return false; } @@ -5522,13 +5532,9 @@ bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) { return false; } -bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct) { - return parseDIArgList(Result, IsDistinct, nullptr); -} /// ParseDIArgList: /// ::= !DIArgList(i32 7, i64 %0) -bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct, - PerFunctionState *PFS) { +bool LLParser::parseDIArgList(Metadata *&MD, PerFunctionState *PFS) { assert(PFS && "Expected valid function state"); assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name"); Lex.Lex(); @@ -5548,7 +5554,7 @@ bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct, if (parseToken(lltok::rparen, "expected ')' here")) return true; - Result = GET_OR_DISTINCT(DIArgList, (Context, Args)); + MD = DIArgList::get(Context, Args); return false; } @@ -5662,13 +5668,17 @@ bool LLParser::parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg, /// ::= !DILocation(...) bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) { if (Lex.getKind() == lltok::MetadataVar) { - MDNode *N; // DIArgLists are a special case, as they are a list of ValueAsMetadata and // so parsing this requires a Function State. if (Lex.getStrVal() == "DIArgList") { - if (parseDIArgList(N, false, PFS)) + Metadata *AL; + if (parseDIArgList(AL, PFS)) return true; - } else if (parseSpecializedMDNode(N)) { + MD = AL; + return false; + } + MDNode *N; + if (parseSpecializedMDNode(N)) { return true; } MD = N; @@ -5829,6 +5839,17 @@ bool LLParser::convertValIDToValue(Type *Ty, ValID &ID, Value *&V, "' but expected '" + getTypeString(Ty) + "'"); V = ID.ConstantVal; return false; + case ValID::t_ConstantSplat: + if (!Ty->isVectorTy()) + return error(ID.Loc, "vector constant must have vector type"); + if (ID.ConstantVal->getType() != Ty->getScalarType()) + return error(ID.Loc, "constant expression type mismatch: got type '" + + getTypeString(ID.ConstantVal->getType()) + + "' but expected '" + + getTypeString(Ty->getScalarType()) + "'"); + V = ConstantVector::getSplat(cast<VectorType>(Ty)->getElementCount(), + ID.ConstantVal); + return false; case ValID::t_ConstantStruct: case ValID::t_PackedConstantStruct: if (StructType *ST = dyn_cast<StructType>(Ty)) { @@ -5866,6 +5887,7 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) { case ValID::t_APFloat: case ValID::t_Undef: case ValID::t_Constant: + case ValID::t_ConstantSplat: case ValID::t_ConstantStruct: case ValID::t_PackedConstantStruct: { Value *V; @@ -6404,8 +6426,15 @@ int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_srem: return parseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/ false); + case lltok::kw_or: { + bool Disjoint = EatIfPresent(lltok::kw_disjoint); + if (parseLogical(Inst, PFS, KeywordVal)) + return true; + if (Disjoint) + cast<PossiblyDisjointInst>(Inst)->setIsDisjoint(true); + return false; + } case lltok::kw_and: - case lltok::kw_or: case lltok::kw_xor: return parseLogical(Inst, PFS, KeywordVal); case lltok::kw_icmp: @@ -6421,8 +6450,16 @@ int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB, } // Casts. + case lltok::kw_zext: { + bool NonNeg = EatIfPresent(lltok::kw_nneg); + bool Res = parseCast(Inst, PFS, KeywordVal); + if (Res != 0) + return Res; + if (NonNeg) + Inst->setNonNeg(); + return 0; + } case lltok::kw_trunc: - case lltok::kw_zext: case lltok::kw_sext: case lltok::kw_fptrunc: case lltok::kw_fpext: @@ -8179,7 +8216,7 @@ bool LLParser::parseModuleEntry(unsigned ID) { parseToken(lltok::rparen, "expected ')' here")) return true; - auto ModuleEntry = Index->addModule(Path, ID, Hash); + auto ModuleEntry = Index->addModule(Path, Hash); ModuleIdMap[ID] = ModuleEntry->first(); return false; @@ -8612,9 +8649,9 @@ static void resolveFwdRef(ValueInfo *Fwd, ValueInfo &Resolved) { /// Stores the given Name/GUID and associated summary into the Index. /// Also updates any forward references to the associated entry ID. -void LLParser::addGlobalValueToIndex( +bool LLParser::addGlobalValueToIndex( std::string Name, GlobalValue::GUID GUID, GlobalValue::LinkageTypes Linkage, - unsigned ID, std::unique_ptr<GlobalValueSummary> Summary) { + unsigned ID, std::unique_ptr<GlobalValueSummary> Summary, LocTy Loc) { // First create the ValueInfo utilizing the Name or GUID. ValueInfo VI; if (GUID != 0) { @@ -8624,7 +8661,9 @@ void LLParser::addGlobalValueToIndex( assert(!Name.empty()); if (M) { auto *GV = M->getNamedValue(Name); - assert(GV); + if (!GV) + return error(Loc, "Reference to undefined global \"" + Name + "\""); + VI = Index->getOrInsertValueInfo(GV); } else { assert( @@ -8672,6 +8711,8 @@ void LLParser::addGlobalValueToIndex( NumberedValueInfos.resize(ID + 1); NumberedValueInfos[ID] = VI; } + + return false; } /// parseSummaryIndexFlags @@ -8718,6 +8759,7 @@ bool LLParser::parseGVEntry(unsigned ID) { parseToken(lltok::lparen, "expected '(' here")) return true; + LocTy Loc = Lex.getLoc(); std::string Name; GlobalValue::GUID GUID = 0; switch (Lex.getKind()) { @@ -8747,9 +8789,8 @@ bool LLParser::parseGVEntry(unsigned ID) { // an external definition. We pass ExternalLinkage since that is only // used when the GUID must be computed from Name, and in that case // the symbol must have external linkage. - addGlobalValueToIndex(Name, GUID, GlobalValue::ExternalLinkage, ID, - nullptr); - return false; + return addGlobalValueToIndex(Name, GUID, GlobalValue::ExternalLinkage, ID, + nullptr, Loc); } // Have a list of summaries @@ -8790,6 +8831,7 @@ bool LLParser::parseGVEntry(unsigned ID) { /// [',' OptionalRefs]? ')' bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID, unsigned ID) { + LocTy Loc = Lex.getLoc(); assert(Lex.getKind() == lltok::kw_function); Lex.Lex(); @@ -8866,10 +8908,9 @@ bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID, FS->setModulePath(ModulePath); - addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage, - ID, std::move(FS)); - - return false; + return addGlobalValueToIndex(Name, GUID, + (GlobalValue::LinkageTypes)GVFlags.Linkage, ID, + std::move(FS), Loc); } /// VariableSummary @@ -8877,6 +8918,7 @@ bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID, /// [',' OptionalRefs]? ')' bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID, unsigned ID) { + LocTy Loc = Lex.getLoc(); assert(Lex.getKind() == lltok::kw_variable); Lex.Lex(); @@ -8924,10 +8966,9 @@ bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID, GS->setModulePath(ModulePath); GS->setVTableFuncs(std::move(VTableFuncs)); - addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage, - ID, std::move(GS)); - - return false; + return addGlobalValueToIndex(Name, GUID, + (GlobalValue::LinkageTypes)GVFlags.Linkage, ID, + std::move(GS), Loc); } /// AliasSummary @@ -8974,10 +9015,9 @@ bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID, AS->setAliasee(AliaseeVI, Summary); } - addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage, - ID, std::move(AS)); - - return false; + return addGlobalValueToIndex(Name, GUID, + (GlobalValue::LinkageTypes)GVFlags.Linkage, ID, + std::move(AS), Loc); } /// Flag @@ -9086,7 +9126,8 @@ bool LLParser::parseOptionalFFlags(FunctionSummary::FFlags &FFlags) { /// OptionalCalls /// := 'calls' ':' '(' Call [',' Call]* ')' /// Call ::= '(' 'callee' ':' GVReference -/// [( ',' 'hotness' ':' Hotness | ',' 'relbf' ':' UInt32 )]? ')' +/// [( ',' 'hotness' ':' Hotness | ',' 'relbf' ':' UInt32 )]? +/// [ ',' 'tail' ]? ')' bool LLParser::parseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls) { assert(Lex.getKind() == lltok::kw_calls); Lex.Lex(); @@ -9111,23 +9152,39 @@ bool LLParser::parseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls) { CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown; unsigned RelBF = 0; - if (EatIfPresent(lltok::comma)) { - // Expect either hotness or relbf - if (EatIfPresent(lltok::kw_hotness)) { + unsigned HasTailCall = false; + + // parse optional fields + while (EatIfPresent(lltok::comma)) { + switch (Lex.getKind()) { + case lltok::kw_hotness: + Lex.Lex(); if (parseToken(lltok::colon, "expected ':'") || parseHotness(Hotness)) return true; - } else { - if (parseToken(lltok::kw_relbf, "expected relbf") || - parseToken(lltok::colon, "expected ':'") || parseUInt32(RelBF)) + break; + case lltok::kw_relbf: + Lex.Lex(); + if (parseToken(lltok::colon, "expected ':'") || parseUInt32(RelBF)) + return true; + break; + case lltok::kw_tail: + Lex.Lex(); + if (parseToken(lltok::colon, "expected ':'") || parseFlag(HasTailCall)) return true; + break; + default: + return error(Lex.getLoc(), "expected hotness, relbf, or tail"); } } + if (Hotness != CalleeInfo::HotnessType::Unknown && RelBF > 0) + return tokError("Expected only one of hotness or relbf"); // Keep track of the Call array index needing a forward reference. // We will save the location of the ValueInfo needing an update, but // can only do so once the std::vector is finalized. if (VI.getRef() == FwdVIRef) IdToIndexMap[GVId].push_back(std::make_pair(Calls.size(), Loc)); - Calls.push_back(FunctionSummary::EdgeTy{VI, CalleeInfo(Hotness, RelBF)}); + Calls.push_back( + FunctionSummary::EdgeTy{VI, CalleeInfo(Hotness, HasTailCall, RelBF)}); if (parseToken(lltok::rparen, "expected ')' in call")) return true; @@ -9801,7 +9858,7 @@ bool LLParser::parseGVReference(ValueInfo &VI, unsigned &GVId) { GVId = Lex.getUIntVal(); // Check if we already have a VI for this GV - if (GVId < NumberedValueInfos.size()) { + if (GVId < NumberedValueInfos.size() && NumberedValueInfos[GVId]) { assert(NumberedValueInfos[GVId].getRef() != FwdVIRef); VI = NumberedValueInfos[GVId]; } else |
