[llvm] [IR][Attribute] Add support for intersecting AttributeLists; NFC (PR #109719)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 26 12:49:26 PDT 2024
================
@@ -903,6 +956,112 @@ AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
return get(C, B);
}
+std::optional<AttributeSet>
+AttributeSet::intersectWith(LLVMContext &C, AttributeSet Other) const {
+ if (*this == Other)
+ return *this;
+
+ AttrBuilder Intersected(C);
+ // Iterate over both attr sets at once.
+ auto ItBegin0 = begin();
+ auto ItEnd0 = end();
+ auto ItBegin1 = Other.begin();
+ auto ItEnd1 = Other.end();
+
+ while (ItBegin0 != ItEnd0 || ItBegin1 != ItEnd1) {
+ std::optional<Attribute> Attr0, Attr1;
+ if (ItBegin1 == ItEnd1)
+ Attr0 = *ItBegin0++;
+ else if (ItBegin0 == ItEnd0)
+ Attr1 = *ItBegin1++;
+ else {
+ int Cmp = ItBegin0->cmpKind(*ItBegin1);
+ if (Cmp == 0) {
+ Attr0 = *ItBegin0++;
+ Attr1 = *ItBegin1++;
+ } else if (Cmp < 0)
+ Attr0 = *ItBegin0++;
+ else
+ Attr1 = *ItBegin1++;
+ }
+ Attribute Attr = Attr0 ? *Attr0 : *Attr1;
+ auto IntersectEq = [&]() {
+ if (!Attr0 || !Attr1)
+ return false;
+ if (*Attr0 != *Attr1)
+ return false;
+ Intersected.addAttribute(Attr);
+ return true;
+ };
+
+ if (!Attr.hasKindAsEnum()) {
+ if (!IntersectEq())
+ return std::nullopt;
+ continue;
+ }
+
+ Attribute::AttrKind Kind = Attr.getKindAsEnum();
+ bool BothValid = Attr0 && Attr1 && Attr0->isValid() && Attr1->isValid();
----------------
nikic wrote:
I find the current structure of the code somewhat hard to understand. I'd prefer this to be split into two paths at the top level. One to handle the case where we have two attributes with the same enum value and have to apply intersection rules. And the other to handle the case where we only have the attribute on one side, and we only need to query whether we are allowed to drop it.
https://github.com/llvm/llvm-project/pull/109719
More information about the llvm-commits
mailing list