This is an archive of the discontinued LLVM Phabricator instance.

Simplify AttrBuilder storage for target dependent attributes
ClosedPublic

Authored by serge-sans-paille on Jan 4 2022, 7:33 AM.

Details

Summary

Using and std::map<SmallString, SmallString> for target dependent attributes is inefficient: it makes its constructor slightly heavier, and involves extra allocation for each new string attribute. Storing the attribute key/value as strings implies extra allocation/copy step.

Use a sorted vector instead. Given the low number of attributes generally involved, this is cheaper, as showcased by https://llvm-compile-time-tracker.com/compare.php?from=5de322295f4ade692dc4f1823ae4450ad3c48af2&to=05bc480bf641a9e3b466619af43a2d123ee3f71d&stat=instructions

Diff Detail

Event Timeline

serge-sans-paille requested review of this revision.Jan 4 2022, 7:33 AM
Herald added projects: Restricted Project, Restricted Project, Restricted Project. · View Herald TranscriptJan 4 2022, 7:33 AM

upload correct patch version

nikic added a comment.Jan 4 2022, 7:55 AM

I'm generally on board with this change. After D116110, the AttrBuilder is only used in situations where we actually expect all the added attributes to be converted to Attributes in any case, so we don't lose anything by storing them directly in that form. At the same time, we don't need to do expensive conversions from Attribute to internal AttrBuilder representation and back to Attribute (involving FoldingSet lookups) when AttrBuilder is constructed from an existing AttributeList/AttributeSet. This is common, because the general approach to attribute modification is "dump everything into AttrBuilder, add new attributes, convert back to AttributeSet".

The main externality here is that AttrBuilder now requires an LLVMContext, but it doesn't look like obtaining one is a problem for any existing usage. I do think it would be good to land the LLVMContext constructor argument addition in a separate patch from the internal representation change, as that one is essentially just busywork.

I've left some implementation nits...

llvm/include/llvm/IR/Attributes.h
1006

Don't think this needs to be in the header.

1008

LLVMContext &Ctx here and elsewhere.

llvm/lib/AsmParser/LLParser.cpp
1240–1241

I'd split the if here and store the AttrBuilder in a variable and then reuse below. Getting a bit hard to read.

llvm/lib/IR/Attributes.cpp
1626

This method move looks a bit weird, I'd leave it where it was so we don't mix add/remove.

1771

Could be more specific here, e.g. TODO: Could merge both lists in one loop.

1778–1779

Unrelated to this change, but with AttributeMask this FIXME no longer makes sense.

1838

I'd combine the Attrs == B.Attrs check into this return as well, so it doesn't feel lonely :)

Take advice into account

nikic accepted this revision.Jan 5 2022, 3:03 AM

LG from my side, but I'd like a second opinion for the "require LLVMContext in AttrBuilder" part of the change, as that's the main API impact.

llvm/lib/AsmParser/LLParser.cpp
136

These M->getContext() can be replaced by just Context, as LLParser stores a reference to that.

1246

Is the separate find call here to avoid constructing AttrBuilder if it's already in the map?

I was going to suggest that you can write this as R = NumberedAttrBuilders.emplace(VarID, M->getContext()).first; and leave the construction of AttrBuilder to emplace(), but it turns out that emplace() still unconditionally constructs the object (because C++) and the sensible replacement for this (try_emplace) has only been introduced in C++17.

llvm/lib/IR/Attributes.cpp
1789–1790

We might as well directly resolve this TODO, I think it should be as simple as:

erase_if(TargetDepAttrs, [&](Attribute A) { return AM.contains(A); });
This revision is now accepted and ready to land.Jan 5 2022, 3:03 AM
rnk added a comment.Jan 5 2022, 4:21 PM

LG from my side, but I'd like a second opinion for the "require LLVMContext in AttrBuilder" part of the change, as that's the main API impact.

I think every non-toy frontend for LLVM probably uses the AttrBuilder API to construct attributes, so it's a pretty broad impact. However, I don't see a good way around it, and I think the improvements to string attribute handling are worth taking the API break.

I will say that the Google was recently affected by the opaque pointer IRBuilder API removal (rG89eb85ac6ea), and the ability to pre-migrate code to the new API was very valuable. At least in our usage, where we progressively pick new LLVM versions, it would be helpful to land a no-op AttrBuilder constructor that takes and ignores an LLVMContext. I don't know how common that usage model is for others.

This revision was landed with ongoing or failed builds.Jan 10 2022, 5:50 AM
This revision was automatically updated to reflect the committed changes.