diff options
author | Reid Kleckner <rnk@google.com> | 2017-04-10 20:18:10 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2017-04-10 20:18:10 +0000 |
commit | 324c99dee5096be095adc3972c4a512ca0f74090 (patch) | |
tree | 9719e54e4dcaa0633d5b1aa58dec3b98d5bebebd /llvm/lib/AsmParser | |
parent | 5be1176543aa4d1fca8dbac59c7908473b3447fc (diff) | |
download | bcm5719-llvm-324c99dee5096be095adc3972c4a512ca0f74090.tar.gz bcm5719-llvm-324c99dee5096be095adc3972c4a512ca0f74090.zip |
[IR] Make AttributeSetNode public, avoid temporary AttributeList copies
Summary:
AttributeList::get(Fn|Ret|Param)Attributes no longer creates a temporary
AttributeList just to hide the AttributeSetNode type.
I've also added a factory method to create AttributeLists from a
parallel array of AttributeSetNodes. I think this simplifies
construction of AttributeLists when rewriting function prototypes.
Previously we would test if a particular index had attributes, and
conditionally add a temporary attribute list to a vector. Now the
attribute set vector is parallel to the argument vector already that
these passes already construct.
My long term vision is to wrap AttributeSetNode* inside an AttributeSet
type that holds the enum attributes, but that will come in a follow up
change.
I haven't done any performance measurements for this change because
profiling hasn't shown that any of the affected code is hot.
Reviewers: pete, chandlerc, sanjoy, hfinkel
Reviewed By: pete
Subscribers: jfb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31198
llvm-svn: 299875
Diffstat (limited to 'llvm/lib/AsmParser')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 88 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 8 |
2 files changed, 34 insertions, 62 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index d8f6c1c5146..78de0d65f25 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/AsmParser/SlotMapping.h" #include "llvm/IR/Argument.h" +#include "llvm/IR/AttributeSetNode.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallingConv.h" @@ -131,9 +132,8 @@ bool LLParser::ValidateEndOfModule() { if (Function *Fn = dyn_cast<Function>(V)) { AttributeList AS = Fn->getAttributes(); - AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeList::FunctionIndex); - AS = AS.removeAttributes(Context, AttributeList::FunctionIndex, - AS.getFnAttributes()); + AttrBuilder FnAttrs(AS.getFnAttributes()); + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex); FnAttrs.merge(B); @@ -150,9 +150,8 @@ bool LLParser::ValidateEndOfModule() { Fn->setAttributes(AS); } else if (CallInst *CI = dyn_cast<CallInst>(V)) { AttributeList AS = CI->getAttributes(); - AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeList::FunctionIndex); - AS = AS.removeAttributes(Context, AttributeList::FunctionIndex, - AS.getFnAttributes()); + AttrBuilder FnAttrs(AS.getFnAttributes()); + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex); FnAttrs.merge(B); AS = AS.addAttributes( Context, AttributeList::FunctionIndex, @@ -160,9 +159,8 @@ bool LLParser::ValidateEndOfModule() { CI->setAttributes(AS); } else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) { AttributeList AS = II->getAttributes(); - AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeList::FunctionIndex); - AS = AS.removeAttributes(Context, AttributeList::FunctionIndex, - AS.getFnAttributes()); + AttrBuilder FnAttrs(AS.getFnAttributes()); + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex); FnAttrs.merge(B); AS = AS.addAttributes( Context, AttributeList::FunctionIndex, @@ -2095,7 +2093,6 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, if (ParseToken(lltok::lparen, "expected '(' in call")) return true; - unsigned AttrIndex = 1; while (Lex.getKind() != lltok::rparen) { // If this isn't the first argument, we need a comma. if (!ArgList.empty() && @@ -2130,7 +2127,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, return true; } ArgList.push_back(ParamInfo( - ArgLoc, V, AttributeList::get(V->getContext(), AttrIndex++, ArgAttrs))); + ArgLoc, V, AttributeSetNode::get(V->getContext(), ArgAttrs))); } if (IsMustTailCall && InVarArgsFunc) @@ -2235,9 +2232,8 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, if (!FunctionType::isValidArgumentType(ArgTy)) return Error(TypeLoc, "invalid type for function argument"); - unsigned AttrIndex = 1; - ArgList.emplace_back(TypeLoc, ArgTy, AttributeList::get(ArgTy->getContext(), - AttrIndex++, Attrs), + ArgList.emplace_back(TypeLoc, ArgTy, + AttributeSetNode::get(ArgTy->getContext(), Attrs), std::move(Name)); while (EatIfPresent(lltok::comma)) { @@ -2264,10 +2260,9 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, if (!ArgTy->isFirstClassType()) return Error(TypeLoc, "invalid type for function argument"); - ArgList.emplace_back( - TypeLoc, ArgTy, - AttributeList::get(ArgTy->getContext(), AttrIndex++, Attrs), - std::move(Name)); + ArgList.emplace_back(TypeLoc, ArgTy, + AttributeSetNode::get(ArgTy->getContext(), Attrs), + std::move(Name)); } } @@ -2291,7 +2286,7 @@ bool LLParser::ParseFunctionType(Type *&Result) { for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { if (!ArgList[i].Name.empty()) return Error(ArgList[i].Loc, "argument name invalid in function type"); - if (ArgList[i].Attrs.hasAttributes(i + 1)) + if (ArgList[i].Attrs) return Error(ArgList[i].Loc, "argument attributes invalid in function type"); } @@ -4740,23 +4735,16 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { // Okay, if we got here, the function is syntactically valid. Convert types // and do semantic checks. std::vector<Type*> ParamTypeList; - SmallVector<AttributeList, 8> Attrs; + SmallVector<AttributeSetNode *, 8> Attrs; - if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeList::get(RetType->getContext(), - AttributeList::ReturnIndex, RetAttrs)); + Attrs.push_back(AttributeSetNode::get(Context, RetAttrs)); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { ParamTypeList.push_back(ArgList[i].Ty); - if (ArgList[i].Attrs.hasAttributes(i + 1)) { - AttrBuilder B(ArgList[i].Attrs, i + 1); - Attrs.push_back(AttributeList::get(RetType->getContext(), i + 1, B)); - } + Attrs.push_back(ArgList[i].Attrs); } - if (FuncAttrs.hasAttributes()) - Attrs.push_back(AttributeList::get( - RetType->getContext(), AttributeList::FunctionIndex, FuncAttrs)); + Attrs.push_back(AttributeSetNode::get(Context, FuncAttrs)); AttributeList PAL = AttributeList::get(Context, Attrs); @@ -5368,10 +5356,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return true; // Set up the Attribute for the function. - SmallVector<AttributeList, 8> Attrs; - if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeList::get(RetType->getContext(), - AttributeList::ReturnIndex, RetAttrs)); + SmallVector<AttributeSetNode *, 8> Attrs; + Attrs.push_back(AttributeSetNode::get(Context, RetAttrs)); SmallVector<Value*, 8> Args; @@ -5391,22 +5377,16 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs.hasAttributes(i + 1)) { - AttrBuilder B(ArgList[i].Attrs, i + 1); - Attrs.push_back(AttributeList::get(RetType->getContext(), i + 1, B)); - } + Attrs.push_back(ArgList[i].Attrs); } if (I != E) return Error(CallLoc, "not enough parameters specified for call"); - if (FnAttrs.hasAttributes()) { - if (FnAttrs.hasAlignmentAttr()) - return Error(CallLoc, "invoke instructions may not have an alignment"); + if (FnAttrs.hasAlignmentAttr()) + return Error(CallLoc, "invoke instructions may not have an alignment"); - Attrs.push_back(AttributeList::get(RetType->getContext(), - AttributeList::FunctionIndex, FnAttrs)); - } + Attrs.push_back(AttributeSetNode::get(Context, FnAttrs)); // Finish off the Attribute and check them AttributeList PAL = AttributeList::get(Context, Attrs); @@ -5970,10 +5950,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, return true; // Set up the Attribute for the function. - SmallVector<AttributeList, 8> Attrs; - if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeList::get(RetType->getContext(), - AttributeList::ReturnIndex, RetAttrs)); + SmallVector<AttributeSetNode *, 8> Attrs; + Attrs.push_back(AttributeSetNode::get(Context, RetAttrs)); SmallVector<Value*, 8> Args; @@ -5993,22 +5971,16 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs.hasAttributes(i + 1)) { - AttrBuilder B(ArgList[i].Attrs, i + 1); - Attrs.push_back(AttributeList::get(RetType->getContext(), i + 1, B)); - } + Attrs.push_back(ArgList[i].Attrs); } if (I != E) return Error(CallLoc, "not enough parameters specified for call"); - if (FnAttrs.hasAttributes()) { - if (FnAttrs.hasAlignmentAttr()) - return Error(CallLoc, "call instructions may not have an alignment"); + if (FnAttrs.hasAlignmentAttr()) + return Error(CallLoc, "call instructions may not have an alignment"); - Attrs.push_back(AttributeList::get(RetType->getContext(), - AttributeList::FunctionIndex, FnAttrs)); - } + Attrs.push_back(AttributeSetNode::get(Context, FnAttrs)); // Finish off the Attribute and check them AttributeList PAL = AttributeList::get(Context, Attrs); diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index 3a794142172..f3e1cc85c8b 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -395,8 +395,8 @@ namespace llvm { struct ParamInfo { LocTy Loc; Value *V; - AttributeList Attrs; - ParamInfo(LocTy loc, Value *v, AttributeList attrs) + AttributeSetNode *Attrs; + ParamInfo(LocTy loc, Value *v, AttributeSetNode *attrs) : Loc(loc), V(v), Attrs(attrs) {} }; bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, @@ -448,9 +448,9 @@ namespace llvm { struct ArgInfo { LocTy Loc; Type *Ty; - AttributeList Attrs; + AttributeSetNode *Attrs; std::string Name; - ArgInfo(LocTy L, Type *ty, AttributeList Attr, const std::string &N) + ArgInfo(LocTy L, Type *ty, AttributeSetNode *Attr, const std::string &N) : Loc(L), Ty(ty), Attrs(Attr), Name(N) {} }; bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &isVarArg); |