diff options
author | Duncan Sands <baldrick@free.fr> | 2007-11-25 14:10:56 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2007-11-25 14:10:56 +0000 |
commit | 827cde1c8319e51463007078a7ce3660ebc93036 (patch) | |
tree | a14ff574ff8b56c6eafd7d864d2cf756451a9d8d /lib/VMCore/Function.cpp | |
parent | 789d34f8c3d78cf439f0da2f1ba7856bdaed01a4 (diff) | |
download | external_llvm-827cde1c8319e51463007078a7ce3660ebc93036.zip external_llvm-827cde1c8319e51463007078a7ce3660ebc93036.tar.gz external_llvm-827cde1c8319e51463007078a7ce3660ebc93036.tar.bz2 |
Fix PR1816. If a bitcast of a function only exists because of a
trivial difference in function attributes, allow calls to it to
be converted to direct calls. Based on a patch by Török Edwin.
While there, move the various lists of mutually incompatible
parameters etc out of the verifier and into ParameterAttributes.h.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44315 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/Function.cpp')
-rw-r--r-- | lib/VMCore/Function.cpp | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 6c29371..2b83e6b 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -86,7 +86,6 @@ ParamAttrsList::getParamAttrs(uint16_t Index) const { return ParamAttr::None; } - std::string ParamAttrsList::getParamAttrsText(uint16_t Attrs) { std::string Result; @@ -115,6 +114,50 @@ ParamAttrsList::getParamAttrsText(uint16_t Attrs) { 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) { |