diff options
Diffstat (limited to 'lib/AsmParser/LLParser.cpp')
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 472 |
1 files changed, 342 insertions, 130 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index be55ac6..2c835f9 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -24,6 +24,7 @@ #include "llvm/IR/Operator.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -129,28 +130,11 @@ bool LLParser::ValidateEndOfModule() { } } - // If there are entries in ForwardRefBlockAddresses at this point, they are - // references after the function was defined. Resolve those now. - while (!ForwardRefBlockAddresses.empty()) { - // Okay, we are referencing an already-parsed function, resolve them now. - Function *TheFn = nullptr; - const ValID &Fn = ForwardRefBlockAddresses.begin()->first; - if (Fn.Kind == ValID::t_GlobalName) - TheFn = M->getFunction(Fn.StrVal); - else if (Fn.UIntVal < NumberedVals.size()) - TheFn = dyn_cast<Function>(NumberedVals[Fn.UIntVal]); - - if (!TheFn) - return Error(Fn.Loc, "unknown function referenced by blockaddress"); - - // Resolve all these references. - if (ResolveForwardRefBlockAddresses(TheFn, - ForwardRefBlockAddresses.begin()->second, - nullptr)) - return true; - - ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin()); - } + // If there are entries in ForwardRefBlockAddresses at this point, the + // function was never defined. + if (!ForwardRefBlockAddresses.empty()) + return Error(ForwardRefBlockAddresses.begin()->first.Loc, + "expected function name in blockaddress"); for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) if (NumberedTypes[i].second.isValid()) @@ -193,38 +177,6 @@ bool LLParser::ValidateEndOfModule() { return false; } -bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, - std::vector<std::pair<ValID, GlobalValue*> > &Refs, - PerFunctionState *PFS) { - // Loop over all the references, resolving them. - for (unsigned i = 0, e = Refs.size(); i != e; ++i) { - BasicBlock *Res; - if (PFS) { - if (Refs[i].first.Kind == ValID::t_LocalName) - Res = PFS->GetBB(Refs[i].first.StrVal, Refs[i].first.Loc); - else - Res = PFS->GetBB(Refs[i].first.UIntVal, Refs[i].first.Loc); - } else if (Refs[i].first.Kind == ValID::t_LocalID) { - return Error(Refs[i].first.Loc, - "cannot take address of numeric label after the function is defined"); - } else { - Res = dyn_cast_or_null<BasicBlock>( - TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal)); - } - - if (!Res) - return Error(Refs[i].first.Loc, - "referenced value is not a basic block"); - - // Get the BlockAddress for this and update references to use it. - BlockAddress *BA = BlockAddress::get(TheFn, Res); - Refs[i].second->replaceAllUsesWith(BA); - Refs[i].second->eraseFromParent(); - } - return false; -} - - //===----------------------------------------------------------------------===// // Top-Level Entities //===----------------------------------------------------------------------===// @@ -254,8 +206,6 @@ bool LLParser::ParseTopLevelEntities() { // ('constant'|'global') ... case lltok::kw_private: // OptionalLinkage case lltok::kw_internal: // OptionalLinkage - case lltok::kw_linker_private: // Obsolete OptionalLinkage - case lltok::kw_linker_private_weak: // Obsolete OptionalLinkage case lltok::kw_weak: // OptionalLinkage case lltok::kw_weak_odr: // OptionalLinkage case lltok::kw_linkonce: // OptionalLinkage @@ -289,6 +239,9 @@ bool LLParser::ParseTopLevelEntities() { } case lltok::kw_attributes: if (ParseUnnamedAttrGrp()) return true; break; + case lltok::kw_uselistorder: if (ParseUseListOrder()) return true; break; + case lltok::kw_uselistorder_bb: + if (ParseUseListOrderBB()) return true; break; } } } @@ -483,10 +436,10 @@ bool LLParser::ParseUnnamedGlobal() { parseOptionalUnnamedAddr(UnnamedAddr)) return true; - if (HasLinkage || Lex.getKind() != lltok::kw_alias) + if (Lex.getKind() != lltok::kw_alias) return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, DLLStorageClass, TLM, UnnamedAddr); - return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM, + return ParseAlias(Name, NameLoc, Linkage, Visibility, DLLStorageClass, TLM, UnnamedAddr); } @@ -512,10 +465,11 @@ bool LLParser::ParseNamedGlobal() { parseOptionalUnnamedAddr(UnnamedAddr)) return true; - if (HasLinkage || Lex.getKind() != lltok::kw_alias) + if (Lex.getKind() != lltok::kw_alias) return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, DLLStorageClass, TLM, UnnamedAddr); - return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM, + + return ParseAlias(Name, NameLoc, Linkage, Visibility, DLLStorageClass, TLM, UnnamedAddr); } @@ -693,33 +647,29 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) { } /// ParseAlias: -/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass -/// OptionalThreadLocal OptionalUnNammedAddr 'alias' -/// OptionalLinkage Aliasee +/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility +/// OptionalDLLStorageClass OptionalThreadLocal +/// OptionalUnNammedAddr 'alias' Aliasee /// /// Aliasee /// ::= TypeAndValue /// /// Everything through OptionalUnNammedAddr has already been parsed. /// -bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, +bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, unsigned Visibility, unsigned DLLStorageClass, GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr) { assert(Lex.getKind() == lltok::kw_alias); Lex.Lex(); - LocTy LinkageLoc = Lex.getLoc(); - unsigned L; - if (ParseOptionalLinkage(L)) - return true; GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L; if(!GlobalAlias::isValidLinkage(Linkage)) - return Error(LinkageLoc, "invalid linkage type for alias"); + return Error(NameLoc, "invalid linkage type for alias"); if (!isValidVisibilityForLinkage(Visibility, L)) - return Error(LinkageLoc, + return Error(NameLoc, "symbol with local linkage must have default visibility"); Constant *Aliasee; @@ -1052,6 +1002,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, "invalid use of attribute on a function"); break; case lltok::kw_byval: + case lltok::kw_dereferenceable: case lltok::kw_inalloca: case lltok::kw_nest: case lltok::kw_noalias: @@ -1212,6 +1163,16 @@ bool LLParser::ParseUInt32(unsigned &Val) { return false; } +/// ParseUInt64 +/// ::= uint64 +bool LLParser::ParseUInt64(uint64_t &Val) { + if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) + return TokError("expected integer"); + Val = Lex.getAPSIntVal().getLimitedValue(); + Lex.Lex(); + return false; +} + /// ParseTLSModel /// := 'localdynamic' /// := 'initialexec' @@ -1284,6 +1245,13 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { continue; } case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break; + case lltok::kw_dereferenceable: { + uint64_t Bytes; + if (ParseOptionalDereferenceableBytes(Bytes)) + return true; + B.addDereferenceableAttr(Bytes); + continue; + } 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; @@ -1341,6 +1309,13 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { switch (Token) { default: // End of attributes. return HaveError; + case lltok::kw_dereferenceable: { + uint64_t Bytes; + if (ParseOptionalDereferenceableBytes(Bytes)) + return true; + B.addDereferenceableAttr(Bytes); + continue; + } case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break; @@ -1409,10 +1384,6 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { /// ::= 'common' /// ::= 'extern_weak' /// ::= 'external' -/// -/// Deprecated Values: -/// ::= 'linker_private' -/// ::= 'linker_private_weak' bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { HasLinkage = false; switch (Lex.getKind()) { @@ -1430,15 +1401,6 @@ bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { case lltok::kw_common: Res = GlobalValue::CommonLinkage; break; case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break; case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break; - - case lltok::kw_linker_private: - case lltok::kw_linker_private_weak: - Lex.Warning("'" + Lex.getStrVal() + "' is deprecated, treating as" - " PrivateLinkage"); - Lex.Lex(); - // treat linker_private and linker_private_weak as PrivateLinkage - Res = GlobalValue::PrivateLinkage; - return false; } Lex.Lex(); HasLinkage = true; @@ -1486,6 +1448,7 @@ bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) { /// ::= 'x86_stdcallcc' /// ::= 'x86_fastcallcc' /// ::= 'x86_thiscallcc' +/// ::= 'x86_vectorcallcc' /// ::= 'arm_apcscc' /// ::= 'arm_aapcscc' /// ::= 'arm_aapcs_vfpcc' @@ -1502,7 +1465,7 @@ bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) { /// ::= 'preserve_allcc' /// ::= 'cc' UINT /// -bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { +bool LLParser::ParseOptionalCallingConv(unsigned &CC) { switch (Lex.getKind()) { default: CC = CallingConv::C; return false; case lltok::kw_ccc: CC = CallingConv::C; break; @@ -1511,6 +1474,7 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { case lltok::kw_x86_stdcallcc: CC = CallingConv::X86_StdCall; break; case lltok::kw_x86_fastcallcc: CC = CallingConv::X86_FastCall; break; case lltok::kw_x86_thiscallcc: CC = CallingConv::X86_ThisCall; break; + case lltok::kw_x86_vectorcallcc:CC = CallingConv::X86_VectorCall; break; case lltok::kw_arm_apcscc: CC = CallingConv::ARM_APCS; break; case lltok::kw_arm_aapcscc: CC = CallingConv::ARM_AAPCS; break; case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break; @@ -1527,12 +1491,8 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { case lltok::kw_preserve_mostcc:CC = CallingConv::PreserveMost; break; case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break; case lltok::kw_cc: { - unsigned ArbitraryCC; Lex.Lex(); - if (ParseUInt32(ArbitraryCC)) - return true; - CC = static_cast<CallingConv::ID>(ArbitraryCC); - return false; + return ParseUInt32(CC); } } @@ -1606,6 +1566,26 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) { return false; } +/// ParseOptionalDereferenceableBytes +/// ::= /* empty */ +/// ::= 'dereferenceable' '(' 4 ')' +bool LLParser::ParseOptionalDereferenceableBytes(uint64_t &Bytes) { + Bytes = 0; + if (!EatIfPresent(lltok::kw_dereferenceable)) + return false; + LocTy ParenLoc = Lex.getLoc(); + if (!EatIfPresent(lltok::lparen)) + return Error(ParenLoc, "expected '('"); + LocTy DerefLoc = Lex.getLoc(); + if (ParseUInt64(Bytes)) return true; + ParenLoc = Lex.getLoc(); + if (!EatIfPresent(lltok::rparen)) + return Error(ParenLoc, "expected ')'"); + if (!Bytes) + return Error(DerefLoc, "dereferenceable bytes must be non-zero"); + return false; +} + /// ParseOptionalCommaAlign /// ::= /// ::= ',' align 4 @@ -1837,7 +1817,8 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) { /// Arg /// ::= Type OptionalAttributes Value OptionalAttributes bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, - PerFunctionState &PFS) { + PerFunctionState &PFS, bool IsMustTailCall, + bool InVarArgsFunc) { if (ParseToken(lltok::lparen, "expected '(' in call")) return true; @@ -1848,6 +1829,17 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, ParseToken(lltok::comma, "expected ',' in argument list")) return true; + // Parse an ellipsis if this is a musttail call in a variadic function. + if (Lex.getKind() == lltok::dotdotdot) { + const char *Msg = "unexpected ellipsis in argument list for "; + if (!IsMustTailCall) + return TokError(Twine(Msg) + "non-musttail call"); + if (!InVarArgsFunc) + return TokError(Twine(Msg) + "musttail call in non-varargs function"); + Lex.Lex(); // Lex the '...', it is purely for readability. + return ParseToken(lltok::rparen, "expected ')' at end of argument list"); + } + // Parse the argument. LocTy ArgLoc; Type *ArgTy = nullptr; @@ -1864,6 +1856,10 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, ArgAttrs))); } + if (IsMustTailCall && InVarArgsFunc) + return TokError("expected '...' at end of argument list for musttail call " + "in varargs function"); + Lex.Lex(); // Lex the ')'. return false; } @@ -2159,28 +2155,6 @@ LLParser::PerFunctionState::~PerFunctionState() { } bool LLParser::PerFunctionState::FinishFunction() { - // Check to see if someone took the address of labels in this block. - if (!P.ForwardRefBlockAddresses.empty()) { - ValID FunctionID; - if (!F.getName().empty()) { - FunctionID.Kind = ValID::t_GlobalName; - FunctionID.StrVal = F.getName(); - } else { - FunctionID.Kind = ValID::t_GlobalID; - FunctionID.UIntVal = FunctionNumber; - } - - std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > >::iterator - FRBAI = P.ForwardRefBlockAddresses.find(FunctionID); - if (FRBAI != P.ForwardRefBlockAddresses.end()) { - // Resolve all these references. - if (P.ResolveForwardRefBlockAddresses(&F, FRBAI->second, this)) - return true; - - P.ForwardRefBlockAddresses.erase(FRBAI); - } - } - if (!ForwardRefVals.empty()) return P.Error(ForwardRefVals.begin()->second.second, "use of undefined value '%" + ForwardRefVals.begin()->first + @@ -2222,7 +2196,7 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, } // Don't make placeholders with invalid type. - if (!Ty->isFirstClassType() && !Ty->isLabelTy()) { + if (!Ty->isFirstClassType()) { P.Error(Loc, "invalid use of a non-first-class type"); return nullptr; } @@ -2263,7 +2237,7 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, return nullptr; } - if (!Ty->isFirstClassType() && !Ty->isLabelTy()) { + if (!Ty->isFirstClassType()) { P.Error(Loc, "invalid use of a non-first-class type"); return nullptr; } @@ -2566,12 +2540,56 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName) return Error(Label.Loc, "expected basic block name in blockaddress"); - // Make a global variable as a placeholder for this reference. - GlobalVariable *FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), - false, GlobalValue::InternalLinkage, - nullptr, ""); - ForwardRefBlockAddresses[Fn].push_back(std::make_pair(Label, FwdRef)); - ID.ConstantVal = FwdRef; + // Try to find the function (but skip it if it's forward-referenced). + GlobalValue *GV = nullptr; + if (Fn.Kind == ValID::t_GlobalID) { + if (Fn.UIntVal < NumberedVals.size()) + GV = NumberedVals[Fn.UIntVal]; + } else if (!ForwardRefVals.count(Fn.StrVal)) { + GV = M->getNamedValue(Fn.StrVal); + } + Function *F = nullptr; + if (GV) { + // Confirm that it's actually a function with a definition. + if (!isa<Function>(GV)) + return Error(Fn.Loc, "expected function name in blockaddress"); + F = cast<Function>(GV); + if (F->isDeclaration()) + return Error(Fn.Loc, "cannot take blockaddress inside a declaration"); + } + + if (!F) { + // Make a global variable as a placeholder for this reference. + GlobalValue *&FwdRef = ForwardRefBlockAddresses[Fn][Label]; + if (!FwdRef) + FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), false, + GlobalValue::InternalLinkage, nullptr, ""); + ID.ConstantVal = FwdRef; + ID.Kind = ValID::t_Constant; + return false; + } + + // We found the function; now find the basic block. Don't use PFS, since we + // might be inside a constant expression. + BasicBlock *BB; + if (BlockAddressPFS && F == &BlockAddressPFS->getFunction()) { + if (Label.Kind == ValID::t_LocalID) + BB = BlockAddressPFS->GetBB(Label.UIntVal, Label.Loc); + else + BB = BlockAddressPFS->GetBB(Label.StrVal, Label.Loc); + if (!BB) + return Error(Label.Loc, "referenced value is not a basic block"); + } else { + if (Label.Kind == ValID::t_LocalID) + return Error(Label.Loc, "cannot take address of numeric label after " + "the function is defined"); + BB = dyn_cast_or_null<BasicBlock>( + F->getValueSymbolTable().lookup(Label.StrVal)); + if (!BB) + return Error(Label.Loc, "referenced value is not a basic block"); + } + + ID.ConstantVal = BlockAddress::get(F, BB); ID.Kind = ValID::t_Constant; return false; } @@ -2886,7 +2904,7 @@ bool LLParser::parseOptionalComdat(Comdat *&C) { /// ParseGlobalValueVector /// ::= /*empty*/ /// ::= TypeAndValue (',' TypeAndValue)* -bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts) { +bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) { // Empty list. if (Lex.getKind() == lltok::rbrace || Lex.getKind() == lltok::rsquare || @@ -3111,7 +3129,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { unsigned Visibility; unsigned DLLStorageClass; AttrBuilder RetAttrs; - CallingConv::ID CC; + unsigned CC; Type *RetType = nullptr; LocTy RetTypeLoc = Lex.getLoc(); if (ParseOptionalLinkage(Linkage) || @@ -3314,13 +3332,63 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { ArgList[i].Name + "'"); } + if (isDefine) + return false; + + // Check the declaration has no block address forward references. + ValID ID; + if (FunctionName.empty()) { + ID.Kind = ValID::t_GlobalID; + ID.UIntVal = NumberedVals.size() - 1; + } else { + ID.Kind = ValID::t_GlobalName; + ID.StrVal = FunctionName; + } + auto Blocks = ForwardRefBlockAddresses.find(ID); + if (Blocks != ForwardRefBlockAddresses.end()) + return Error(Blocks->first.Loc, + "cannot take blockaddress inside a declaration"); return false; } +bool LLParser::PerFunctionState::resolveForwardRefBlockAddresses() { + ValID ID; + if (FunctionNumber == -1) { + ID.Kind = ValID::t_GlobalName; + ID.StrVal = F.getName(); + } else { + ID.Kind = ValID::t_GlobalID; + ID.UIntVal = FunctionNumber; + } + + auto Blocks = P.ForwardRefBlockAddresses.find(ID); + if (Blocks == P.ForwardRefBlockAddresses.end()) + return false; + + for (const auto &I : Blocks->second) { + const ValID &BBID = I.first; + GlobalValue *GV = I.second; + + assert((BBID.Kind == ValID::t_LocalID || BBID.Kind == ValID::t_LocalName) && + "Expected local id or name"); + BasicBlock *BB; + if (BBID.Kind == ValID::t_LocalName) + BB = GetBB(BBID.StrVal, BBID.Loc); + else + BB = GetBB(BBID.UIntVal, BBID.Loc); + if (!BB) + return P.Error(BBID.Loc, "referenced value is not a basic block"); + + GV->replaceAllUsesWith(BlockAddress::get(&F, BB)); + GV->eraseFromParent(); + } + + P.ForwardRefBlockAddresses.erase(Blocks); + return false; +} /// ParseFunctionBody -/// ::= '{' BasicBlock+ '}' -/// +/// ::= '{' BasicBlock+ UseListOrderDirective* '}' bool LLParser::ParseFunctionBody(Function &Fn) { if (Lex.getKind() != lltok::lbrace) return TokError("expected '{' in function body"); @@ -3331,13 +3399,24 @@ bool LLParser::ParseFunctionBody(Function &Fn) { PerFunctionState PFS(*this, Fn, FunctionNumber); + // Resolve block addresses and allow basic blocks to be forward-declared + // within this function. + if (PFS.resolveForwardRefBlockAddresses()) + return true; + SaveAndRestore<PerFunctionState *> ScopeExit(BlockAddressPFS, &PFS); + // We need at least one basic block. - if (Lex.getKind() == lltok::rbrace) + if (Lex.getKind() == lltok::rbrace || Lex.getKind() == lltok::kw_uselistorder) return TokError("function body requires at least one basic block"); - while (Lex.getKind() != lltok::rbrace) + while (Lex.getKind() != lltok::rbrace && + Lex.getKind() != lltok::kw_uselistorder) if (ParseBasicBlock(PFS)) return true; + while (Lex.getKind() != lltok::rbrace) + if (ParseUseListOrder(&PFS)) + return true; + // Eat the }. Lex.Lex(); @@ -3656,7 +3735,7 @@ bool LLParser::ParseSwitch(Instruction *&Inst, PerFunctionState &PFS) { ParseTypeAndBasicBlock(DestBB, PFS)) return true; - if (!SeenCases.insert(Constant)) + if (!SeenCases.insert(Constant).second) return Error(CondLoc, "duplicate case value in switch"); if (!isa<ConstantInt>(Constant)) return Error(CondLoc, "case value is not a constant integer"); @@ -3722,7 +3801,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { AttrBuilder RetAttrs, FnAttrs; std::vector<unsigned> FwdRefAttrGrps; LocTy NoBuiltinLoc; - CallingConv::ID CC; + unsigned CC; Type *RetType = nullptr; LocTy RetTypeLoc; ValID CalleeID; @@ -4136,7 +4215,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, AttrBuilder RetAttrs, FnAttrs; std::vector<unsigned> FwdRefAttrGrps; LocTy BuiltinLoc; - CallingConv::ID CC; + unsigned CC; Type *RetType = nullptr; LocTy RetTypeLoc; ValID CalleeID; @@ -4149,7 +4228,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || - ParseParameterList(ArgList, PFS) || + ParseParameterList(ArgList, PFS, TCK == CallInst::TCK_MustTail, + PFS.getFunction().isVarArg()) || ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, BuiltinLoc)) return true; @@ -4596,3 +4676,135 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts, return false; } + +//===----------------------------------------------------------------------===// +// Use-list order directives. +//===----------------------------------------------------------------------===// +bool LLParser::sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes, + SMLoc Loc) { + if (V->use_empty()) + return Error(Loc, "value has no uses"); + + unsigned NumUses = 0; + SmallDenseMap<const Use *, unsigned, 16> Order; + for (const Use &U : V->uses()) { + if (++NumUses > Indexes.size()) + break; + Order[&U] = Indexes[NumUses - 1]; + } + if (NumUses < 2) + return Error(Loc, "value only has one use"); + if (Order.size() != Indexes.size() || NumUses > Indexes.size()) + return Error(Loc, "wrong number of indexes, expected " + + Twine(std::distance(V->use_begin(), V->use_end()))); + + V->sortUseList([&](const Use &L, const Use &R) { + return Order.lookup(&L) < Order.lookup(&R); + }); + return false; +} + +/// ParseUseListOrderIndexes +/// ::= '{' uint32 (',' uint32)+ '}' +bool LLParser::ParseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes) { + SMLoc Loc = Lex.getLoc(); + if (ParseToken(lltok::lbrace, "expected '{' here")) + return true; + if (Lex.getKind() == lltok::rbrace) + return Lex.Error("expected non-empty list of uselistorder indexes"); + + // Use Offset, Max, and IsOrdered to check consistency of indexes. The + // indexes should be distinct numbers in the range [0, size-1], and should + // not be in order. + unsigned Offset = 0; + unsigned Max = 0; + bool IsOrdered = true; + assert(Indexes.empty() && "Expected empty order vector"); + do { + unsigned Index; + if (ParseUInt32(Index)) + return true; + + // Update consistency checks. + Offset += Index - Indexes.size(); + Max = std::max(Max, Index); + IsOrdered &= Index == Indexes.size(); + + Indexes.push_back(Index); + } while (EatIfPresent(lltok::comma)); + + if (ParseToken(lltok::rbrace, "expected '}' here")) + return true; + + if (Indexes.size() < 2) + return Error(Loc, "expected >= 2 uselistorder indexes"); + if (Offset != 0 || Max >= Indexes.size()) + return Error(Loc, "expected distinct uselistorder indexes in range [0, size)"); + if (IsOrdered) + return Error(Loc, "expected uselistorder indexes to change the order"); + + return false; +} + +/// ParseUseListOrder +/// ::= 'uselistorder' Type Value ',' UseListOrderIndexes +bool LLParser::ParseUseListOrder(PerFunctionState *PFS) { + SMLoc Loc = Lex.getLoc(); + if (ParseToken(lltok::kw_uselistorder, "expected uselistorder directive")) + return true; + + Value *V; + SmallVector<unsigned, 16> Indexes; + if (ParseTypeAndValue(V, PFS) || + ParseToken(lltok::comma, "expected comma in uselistorder directive") || + ParseUseListOrderIndexes(Indexes)) + return true; + + return sortUseListOrder(V, Indexes, Loc); +} + +/// ParseUseListOrderBB +/// ::= 'uselistorder_bb' @foo ',' %bar ',' UseListOrderIndexes +bool LLParser::ParseUseListOrderBB() { + assert(Lex.getKind() == lltok::kw_uselistorder_bb); + SMLoc Loc = Lex.getLoc(); + Lex.Lex(); + + ValID Fn, Label; + SmallVector<unsigned, 16> Indexes; + if (ParseValID(Fn) || + ParseToken(lltok::comma, "expected comma in uselistorder_bb directive") || + ParseValID(Label) || + ParseToken(lltok::comma, "expected comma in uselistorder_bb directive") || + ParseUseListOrderIndexes(Indexes)) + return true; + + // Check the function. + GlobalValue *GV; + if (Fn.Kind == ValID::t_GlobalName) + GV = M->getNamedValue(Fn.StrVal); + else if (Fn.Kind == ValID::t_GlobalID) + GV = Fn.UIntVal < NumberedVals.size() ? NumberedVals[Fn.UIntVal] : nullptr; + else + return Error(Fn.Loc, "expected function name in uselistorder_bb"); + if (!GV) + return Error(Fn.Loc, "invalid function forward reference in uselistorder_bb"); + auto *F = dyn_cast<Function>(GV); + if (!F) + return Error(Fn.Loc, "expected function name in uselistorder_bb"); + if (F->isDeclaration()) + return Error(Fn.Loc, "invalid declaration in uselistorder_bb"); + + // Check the basic block. + if (Label.Kind == ValID::t_LocalID) + return Error(Label.Loc, "invalid numeric label in uselistorder_bb"); + if (Label.Kind != ValID::t_LocalName) + return Error(Label.Loc, "expected basic block name in uselistorder_bb"); + Value *V = F->getValueSymbolTable().lookup(Label.StrVal); + if (!V) + return Error(Label.Loc, "invalid basic block in uselistorder_bb"); + if (!isa<BasicBlock>(V)) + return Error(Label.Loc, "expected basic block in uselistorder_bb"); + + return sortUseListOrder(V, Indexes, Loc); +} |