aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore/Function.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2007-11-30 18:19:18 +0000
committerDuncan Sands <baldrick@free.fr>2007-11-30 18:19:18 +0000
commit757d243167a52fef433146be11fa1462f6468270 (patch)
treeaa3c16399f7b2fdb1556a69aef681da2ff8d4678 /lib/VMCore/Function.cpp
parenta8b974648f9d8bacc43280653dc654c9120d05ca (diff)
downloadexternal_llvm-757d243167a52fef433146be11fa1462f6468270.zip
external_llvm-757d243167a52fef433146be11fa1462f6468270.tar.gz
external_llvm-757d243167a52fef433146be11fa1462f6468270.tar.bz2
Add a convenience method for modifying parameter
attributes. While there, I noticed that not all attribute methods returned a pointer-to-constant, so I fixed that. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44457 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/Function.cpp')
-rw-r--r--lib/VMCore/Function.cpp60
1 files changed, 59 insertions, 1 deletions
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index 92853e3..16728f6 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -167,7 +167,7 @@ ParamAttrsList::Profile(FoldingSetNodeID &ID) const {
static ManagedStatic<FoldingSet<ParamAttrsList> > ParamAttrsLists;
-ParamAttrsList *
+const ParamAttrsList *
ParamAttrsList::get(const ParamAttrsVector &attrVec) {
// If there are no attributes then return a null ParamAttrsList pointer.
if (attrVec.empty())
@@ -200,6 +200,64 @@ ParamAttrsList::get(const ParamAttrsVector &attrVec) {
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);
+}
+
ParamAttrsList::~ParamAttrsList() {
ParamAttrsLists->RemoveNode(this);
}