This is an archive of the discontinued LLVM Phabricator instance.

[NFC][PPC] Refactor TOC representation to allow several entries for the same symbol
ClosedPublic

Authored by NeHuang on Feb 9 2021, 7:52 AM.

Details

Summary

We currently represent TOC entries by an MCSymbol. This is not
enough in some situations. For example, when accessing an
initialized TLS variable v on AIX using the general dynamic model, we
need to generate the two following entries for v:

.tc .v[TC],v@m
.tc v[TC],v

One is for the region handle (with the @m relocation), the other is for
the variable offset.
This refactoring allows storing several entries for the same symbol
with different VariantKind in the TOC. If the VariantKind is not
specified, we default to VK_None.

The AIX TLS implementation using this refactoring to generate the two
entries will be posted in a subsequent patch.

Diff Detail

Event Timeline

bsaleil created this revision.Feb 9 2021, 7:52 AM
bsaleil requested review of this revision.Feb 9 2021, 7:52 AM
amyk added a subscriber: amyk.Feb 9 2021, 2:28 PM
amyk added inline comments.
llvm/lib/MC/MCExpr.cpp
225 ↗(On Diff #322397)

nit: Address the clang format.

Also, sorry, this might be a silly question. What is the difference between VK_None and VK_Empty?

bsaleil added inline comments.Feb 10 2021, 7:57 AM
llvm/lib/MC/MCExpr.cpp
225 ↗(On Diff #322397)

You can see in MCExpr.h that VK_Empty is used to represent an empty key in a DenseMap. If I understand correctly how DenseMap works, when inserting a value, if there is a collision, it looks for a slot with an empty key to put the value. So if we use VK_None as the empty key, this prevents us from actually inserting the VK_None value in the table, because it may be overwritten by a later insertion.

sfertile added inline comments.Feb 10 2021, 11:43 AM
llvm/include/llvm/MC/MCExpr.h
421 ↗(On Diff #322397)

I'm not sure why we need this, or even why this works ... IIUC MapVector creates a dense map from the key type to the index of the value. Shouldn't we be creating a DenseMapInfo of the key type which is now a std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>?

bsaleil added inline comments.Feb 10 2021, 3:16 PM
llvm/include/llvm/MC/MCExpr.h
421 ↗(On Diff #322397)

There is a generic implementation of DenseMapInfo<std::pair<T, U>> in DenseMapInfo.h which relies on DenseMapInfo<T> and DenseMapInfo<U>.

sfertile added inline comments.Feb 11 2021, 6:38 AM
llvm/include/llvm/MC/MCExpr.h
421 ↗(On Diff #322397)

Thanks Baptiste. I'm a little hesitant to add a new value to the variant kind enum that only makes sense as a special value in a dense map. Would you consider creating the DenseMapInfo for the std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind> and not using the generic implementation of DenseMapInfo<std::pair<T, U>>? I know it is ugly, but it will be relegated to PPCAsmPrinter.cpp and we can avoid adding a new value to the VariantKinds.

bsaleil updated this revision to Diff 323057.Feb 11 2021, 9:41 AM

Specialize DenseMapInfo directly with the PPC TOC key type instead of VariantKind.

bsaleil marked 3 inline comments as done.Feb 11 2021, 9:42 AM
bsaleil added inline comments.
llvm/include/llvm/MC/MCExpr.h
421 ↗(On Diff #322397)

Sure, I just updated the patch to make that change.

sfertile accepted this revision as: sfertile.Feb 11 2021, 12:58 PM

Thanks for the update. LGTM.

This revision is now accepted and ready to land.Feb 11 2021, 12:58 PM
NeHuang commandeered this revision.Feb 16 2021, 8:24 AM
NeHuang added a reviewer: bsaleil.
This revision was landed with ongoing or failed builds.Feb 16 2021, 1:34 PM
This revision was automatically updated to reflect the committed changes.
NeHuang marked an inline comment as done.

Unfortunately it fails to build with GCC which LLVM still tries to stay compatible with:
http://lab.llvm.org:8014/#/builders/16/builds/2211
gcc-11.0.0-0.19.fc34.x86_64
gcc-10.2.1-9.fc33.x86_64
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:86:8: error: explicit specialization of 'template<class T> struct llvm::DenseMapInfo' outside its namespace must use a nested-name-specifier [-fpermissive]

86 | struct DenseMapInfo<std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>> {
   |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I have filed it to an existing GCC bugreport: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92598

dyung added a subscriber: dyung.Feb 16 2021, 11:21 PM

Unfortunately it fails to build with GCC which LLVM still tries to stay compatible with:
http://lab.llvm.org:8014/#/builders/16/builds/2211
gcc-11.0.0-0.19.fc34.x86_64
gcc-10.2.1-9.fc33.x86_64
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:86:8: error: explicit specialization of 'template<class T> struct llvm::DenseMapInfo' outside its namespace must use a nested-name-specifier [-fpermissive]

86 | struct DenseMapInfo<std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>> {
   |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I have filed it to an existing GCC bugreport: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92598

I have committed 0e3d7e61867d69721b28e557272bdf4b66010327 in order to unblock the build on gcc builders.