This is an archive of the discontinued LLVM Phabricator instance.

[WIP] [CodeGen] Allow specifying Extend to CoerceAndExpand
AbandonedPublic

Authored by rogfer01 on Jun 26 2018, 2:37 AM.

Details

Reviewers
rjmccall
Summary

This is WIP and it is motivated by the suggestions in http://lists.llvm.org/pipermail/cfe-dev/2018-June/058263.html

First attempt, piggybacking the extend information in a structure where the bit-width of the integer represents the exact extension intended. There is a bit of overlapping with the original Extend but I'm not convinced we win anything from rewriting it into the new representation.

I plan to test this using unit tests but I can link a diff with the current usage in case it helps.

Diff Detail

Event Timeline

rogfer01 created this revision.Jun 26 2018, 2:37 AM
rogfer01 added inline comments.
include/clang/CodeGen/CGFunctionInfo.h
469

I think this is the right trait here. I spent too much time debugging this :)

rjmccall added inline comments.Jun 26 2018, 12:05 PM
include/clang/CodeGen/CGFunctionInfo.h
91–94

Hmm. I understand the need to use something uniqued here, but I think it would probably be more natural to at least use a llvm::ConstantDataArray (which could be null if there are no interesting bits) instead of encoding the information into the types of a struct type. That would also make it easy to generalize the elements to an arbitrary flags type.

Also, on 64-bit targets this will increase the size of an ABIArgInfo to four pointers from three. That's fine to the extent that we work with independent ABIArgInfos, but I'm getting a little annoyed at the storage overhead of the array of ABIArgInfos in CGFunctionInfo given that, in the overwhelmingly common case, an ABIArgInfo is no more than a kind and maybe a few of these flags. Maybe there's some reasonable way to optimize the storage of an ABIArgInfo in a CGFunctionInfo so that we only need the extra storage in less-common cases? Like extracting out a base class that's the Kind+Flags and making the main array be an array of those + an optional index into a second trailing array of full ABIArgInfos.

I might be overthinking this, though.

rogfer01 added inline comments.Jun 26 2018, 2:03 PM
include/clang/CodeGen/CGFunctionInfo.h
91–94

Oh, of course, using a value rather than a type is more sensible. I will change this.

The idea of having a lighter ABIArgInfo and an ancillary extra array for it seems sensible. I guess it may depend on how early/late we know the precise kind of ABIArgInfo we need to represent. I haven't looked at this yet, I'll investigate.

469

But today I realised that GCC 4.9 does not implement this so it will have to go away :(

rjmccall added inline comments.Jun 26 2018, 2:22 PM
include/clang/CodeGen/CGFunctionInfo.h
91–94

CGFunctionInfo should be totally immutable and just ultimately constructed with an array of ABIArgInfo, which seems like a reasonable place to inject some representation tricks.

469

You could gate it on the compiler if you want, maybe extracting a HAS_IS_TRIVIALLY_COPYABLE test macro in llvm/Support/type_traits.h out of the implementation of llvm::isPodLike.

rogfer01 updated this revision to Diff 153070.Jun 27 2018, 6:18 AM

ChangeLog:

  • Use a ConstantDataArray instead of a struct of types.
  • Use LLVM_IS_TRIVIALLY_COPYABLE

@rjmccall because we do not want to impact the clients of ABIArgInfo I thought of two possible approaches

  1. extend CGFunctionInfo with a third trailing array (now it has two), with as many elements as ABIArgInfo (call it ABIArgExtraInfo) then during the creation of CGFunctionInfo link (somehow, see discussion below) each ABIArgInfoto its corresponding ABIArgExtraInfo.
  2. add a dynamic container like a SmallVector<ABIArgExtraInfo, 2> in CGFunctionInfo and allocate ABIArgExtraInfo as needed.

In both cases during getFOO, ABIArgInfo would put the extra (less commonly used) data into the corresponding ABIArgExtraInfo (overflowing object).

In both cases too, we need a way to navigate to our enclosing CGFunctionInfo but strictly only during the getFOO that fills the ABIArgInfo. Getting it from the users is not possible, so we would need a pointer to CGFunctionInfo in ABIArgInfo (set up during the creation of CGFunctionInfo). That said, there is no need of its value all the time, only at the beginning of getFOO. We could reuse its storage to point the overflowing object (if needed, and set it to null otherwise).

Do any of the approaches look any close to what you had in mind? Perhaps I'm missing the point.

Thank you!

@rjmccall because we do not want to impact the clients of ABIArgInfo I thought of two possible approaches

  1. extend CGFunctionInfo with a third trailing array (now it has two), with as many elements as ABIArgInfo (call it ABIArgExtraInfo) then during the creation of CGFunctionInfo link (somehow, see discussion below) each ABIArgInfoto its corresponding ABIArgExtraInfo.
  2. add a dynamic container like a SmallVector<ABIArgExtraInfo, 2> in CGFunctionInfo and allocate ABIArgExtraInfo as needed.

In both cases during getFOO, ABIArgInfo would put the extra (less commonly used) data into the corresponding ABIArgExtraInfo (overflowing object).

In both cases too, we need a way to navigate to our enclosing CGFunctionInfo but strictly only during the getFOO that fills the ABIArgInfo. Getting it from the users is not possible, so we would need a pointer to CGFunctionInfo in ABIArgInfo (set up during the creation of CGFunctionInfo). That said, there is no need of its value all the time, only at the beginning of getFOO. We could reuse its storage to point the overflowing object (if needed, and set it to null otherwise).

Do any of the approaches look any close to what you had in mind? Perhaps I'm missing the point.

Well, there's no point in having a trailing array that's always got the same number of elements as there are ABIArgInfos, because then we're not actually saving any memory. What I was thinking was that the representation of ABIArgInfo doesn't really change when it's being passed around as an independent value, but when it's stored in a CGFunctionInfo, we break it up into two components: one that stores all the stuff that frequently appears in ABIArgInfos (which can go in a trailing array indexed by argument index) and one for all the uncommon information (which can go in a condensed trailing array indexed by nothing externally meaningful). When you ask a CGFunctionInfo for the ABIArgInfo for the kth argument, it has to reassemble it, which it does by getting the common-subset ABIArgInfo, asking whether it needs any extra information, and (if so) pulling that out of the second array. Storing the common-subset data together with an index into the trailing array (actually, this could reasonably just be a 32-bit byte offset from the address point of the CGFunctionInfo, which would be more efficient when recreating the ABIArgInfo and would also let us use the zero offset to mean there's no extra information) should be doable in 64 bits, vs. 192 bits in the current representation, so it's a significant savings even before we start adding new fields to ABIArgInfo.

rogfer01 abandoned this revision.Dec 7 2018, 3:17 AM

Upstream recently amended the ABI spec so it looks to me this is not going to be needed.