diff options
author | Chris Lattner <sabre@nondot.org> | 2008-01-02 23:42:30 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-01-02 23:42:30 +0000 |
commit | 50ee9ddc8f0633af6cb0a5693a2c706e98f944da (patch) | |
tree | e9d758370876a5e6235f5f0ac307f9b5d598c1cb /lib/VMCore/ParameterAttributes.cpp | |
parent | a114b14e5dd1869b8dfcf79736fe05a3616b520a (diff) |
Split param attr implementation out from Function.cpp into its
own file. Don't #include ParameterAttributes.h into any major
public header files: just move methods out of line as appropriate.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45517 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/ParameterAttributes.cpp')
-rw-r--r-- | lib/VMCore/ParameterAttributes.cpp | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/lib/VMCore/ParameterAttributes.cpp b/lib/VMCore/ParameterAttributes.cpp new file mode 100644 index 0000000000..37a2819d86 --- /dev/null +++ b/lib/VMCore/ParameterAttributes.cpp @@ -0,0 +1,226 @@ +//===-- ParameterAttributes.cpp - Implement ParameterAttrs ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the ParamAttrsList class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ParameterAttributes.h" +#include "llvm/Support/ManagedStatic.h" +using namespace llvm; + +uint16_t +ParamAttrsList::getParamAttrs(uint16_t Index) const { + unsigned limit = attrs.size(); + for (unsigned i = 0; i < limit && attrs[i].index <= Index; ++i) + if (attrs[i].index == Index) + return attrs[i].attrs; + return ParamAttr::None; +} + +std::string +ParamAttrsList::getParamAttrsText(uint16_t Attrs) { + std::string Result; + if (Attrs & ParamAttr::ZExt) + Result += "zeroext "; + if (Attrs & ParamAttr::SExt) + Result += "signext "; + if (Attrs & ParamAttr::NoReturn) + Result += "noreturn "; + if (Attrs & ParamAttr::NoUnwind) + Result += "nounwind "; + if (Attrs & ParamAttr::InReg) + Result += "inreg "; + if (Attrs & ParamAttr::NoAlias) + Result += "noalias "; + if (Attrs & ParamAttr::StructRet) + Result += "sret "; + if (Attrs & ParamAttr::ByVal) + Result += "byval "; + if (Attrs & ParamAttr::Nest) + Result += "nest "; + if (Attrs & ParamAttr::ReadNone) + Result += "readnone "; + if (Attrs & ParamAttr::ReadOnly) + Result += "readonly "; + return Result; +} + +/// onlyInformative - Returns whether only informative attributes are set. +static inline bool onlyInformative(uint16_t attrs) { + return !(attrs & ~ParamAttr::Informative); +} + +bool +ParamAttrsList::areCompatible(const ParamAttrsList *A, const ParamAttrsList *B){ + if (A == B) + return true; + unsigned ASize = A ? A->size() : 0; + unsigned BSize = B ? B->size() : 0; + unsigned AIndex = 0; + unsigned BIndex = 0; + + while (AIndex < ASize && BIndex < BSize) { + uint16_t AIdx = A->getParamIndex(AIndex); + uint16_t BIdx = B->getParamIndex(BIndex); + uint16_t AAttrs = A->getParamAttrsAtIndex(AIndex); + uint16_t BAttrs = B->getParamAttrsAtIndex(AIndex); + + if (AIdx < BIdx) { + if (!onlyInformative(AAttrs)) + return false; + ++AIndex; + } else if (BIdx < AIdx) { + if (!onlyInformative(BAttrs)) + return false; + ++BIndex; + } else { + if (!onlyInformative(AAttrs ^ BAttrs)) + return false; + ++AIndex; + ++BIndex; + } + } + for (; AIndex < ASize; ++AIndex) + if (!onlyInformative(A->getParamAttrsAtIndex(AIndex))) + return false; + for (; BIndex < BSize; ++BIndex) + if (!onlyInformative(B->getParamAttrsAtIndex(AIndex))) + return false; + return true; +} + +void ParamAttrsList::Profile(FoldingSetNodeID &ID) const { + for (unsigned i = 0; i < attrs.size(); ++i) + ID.AddInteger(unsigned(attrs[i].attrs) << 16 | unsigned(attrs[i].index)); +} + +static ManagedStatic<FoldingSet<ParamAttrsList> > ParamAttrsLists; + +const ParamAttrsList * +ParamAttrsList::get(const ParamAttrsVector &attrVec) { + // If there are no attributes then return a null ParamAttrsList pointer. + if (attrVec.empty()) + return 0; + +#ifndef NDEBUG + for (unsigned i = 0, e = attrVec.size(); i < e; ++i) { + assert(attrVec[i].attrs != ParamAttr::None + && "Pointless parameter attribute!"); + assert((!i || attrVec[i-1].index < attrVec[i].index) + && "Misordered ParamAttrsList!"); + } +#endif + + // Otherwise, build a key to look up the existing attributes. + ParamAttrsList key(attrVec); + FoldingSetNodeID ID; + key.Profile(ID); + void *InsertPos; + ParamAttrsList* PAL = ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos); + + // If we didn't find any existing attributes of the same shape then + // create a new one and insert it. + if (!PAL) { + PAL = new ParamAttrsList(attrVec); + ParamAttrsLists->InsertNode(PAL, InsertPos); + } + + // Return the ParamAttrsList that we found or created. + return PAL; +} + +const ParamAttrsList * +ParamAttrsList::getModified(const ParamAttrsList *PAL, + const ParamAttrsVector &modVec) { + if (modVec.empty()) + return PAL; + +#ifndef NDEBUG + for (unsigned i = 0, e = modVec.size(); i < e; ++i) + assert((!i || modVec[i-1].index < modVec[i].index) + && "Misordered ParamAttrsList!"); +#endif + + if (!PAL) { + // Strip any instances of ParamAttr::None from modVec before calling 'get'. + ParamAttrsVector newVec; + for (unsigned i = 0, e = modVec.size(); i < e; ++i) + if (modVec[i].attrs != ParamAttr::None) + newVec.push_back(modVec[i]); + return get(newVec); + } + + const ParamAttrsVector &oldVec = PAL->attrs; + + ParamAttrsVector newVec; + unsigned oldI = 0; + unsigned modI = 0; + unsigned oldE = oldVec.size(); + unsigned modE = modVec.size(); + + while (oldI < oldE && modI < modE) { + uint16_t oldIndex = oldVec[oldI].index; + uint16_t modIndex = modVec[modI].index; + + if (oldIndex < modIndex) { + newVec.push_back(oldVec[oldI]); + ++oldI; + } else if (modIndex < oldIndex) { + if (modVec[modI].attrs != ParamAttr::None) + newVec.push_back(modVec[modI]); + ++modI; + } else { + // Same index - overwrite or delete existing attributes. + if (modVec[modI].attrs != ParamAttr::None) + newVec.push_back(modVec[modI]); + ++oldI; + ++modI; + } + } + + for (; oldI < oldE; ++oldI) + newVec.push_back(oldVec[oldI]); + for (; modI < modE; ++modI) + if (modVec[modI].attrs != ParamAttr::None) + newVec.push_back(modVec[modI]); + + return get(newVec); +} + +const ParamAttrsList * +ParamAttrsList::includeAttrs(const ParamAttrsList *PAL, + uint16_t idx, uint16_t attrs) { + uint16_t OldAttrs = PAL ? PAL->getParamAttrs(idx) : 0; + uint16_t NewAttrs = OldAttrs | attrs; + if (NewAttrs == OldAttrs) + return PAL; + + ParamAttrsVector modVec; + modVec.push_back(ParamAttrsWithIndex::get(idx, NewAttrs)); + return getModified(PAL, modVec); +} + +const ParamAttrsList * +ParamAttrsList::excludeAttrs(const ParamAttrsList *PAL, + uint16_t idx, uint16_t attrs) { + uint16_t OldAttrs = PAL ? PAL->getParamAttrs(idx) : 0; + uint16_t NewAttrs = OldAttrs & ~attrs; + if (NewAttrs == OldAttrs) + return PAL; + + ParamAttrsVector modVec; + modVec.push_back(ParamAttrsWithIndex::get(idx, NewAttrs)); + return getModified(PAL, modVec); +} + +ParamAttrsList::~ParamAttrsList() { + ParamAttrsLists->RemoveNode(this); +} + |