This is an archive of the discontinued LLVM Phabricator instance.

Add module flags metadata to record the settings for enum and wchar width
ClosedPublic

Authored by olista01 on Jun 19 2014, 6:45 AM.

Details

Reviewers
rengolin
Summary

Add module flags metadata to record the settings for enum and wchar width, to allow correct ARM build attribute generation

Diff Detail

Event Timeline

olista01 updated this revision to Diff 10633.Jun 19 2014, 6:45 AM
olista01 retitled this revision from to Add module flags metadata to record the settings for enum and wchar width.
olista01 updated this object.
olista01 edited the test plan for this revision. (Show Details)
olista01 added a subscriber: Unknown Object (MLST).

Hi Oliver,

This code will force anyone not using the -f flags to have long enums and wchars. Is that true for *all* ARM architectures and instruction sets? The ABI document wasn't clear about this.

cheers,
--renato

This code will force anyone not using the -f flags to have long enums and wchars. Is that true for *all* ARM architectures and instruction sets? The ABI document wasn't clear about this.

I'm not sure I understand. The clang defaults on all of the architectures I tried are long enums and long wchar, so anyone not using the -f flags already has long enums and wchars. This just adds the build attributes, so that anyone using a linker which understands build attributes will not accidentally use the wrong libraries.

wchar_t is unsigned long on any ARM environment strictly following AAPCS. Windows on ARM does not strictly follow AAPCS (it is pretty close though), and uses an unsigned short for wchar_t.

Enums are a bit more tricky, with them defaulting to short, but extending to long if any of the elements of the enumeration exceed the limits of short.

This seems to simply be recording the values for the short_wchar and short_enum, which is fine.

That said, would you be opposed to using an enumeration for the values of this metadata Oliver? That would allow us to extend the values in the future if we need to. If we do so, it would be nicer to rename the metadata to wchar_size and enum_size reflecting that this is not a boolean value. I realise that this would also require a change to the implementation in D4213.

Even though we "assumed" that was true, we didn't have the attributes in place, if the default was different, say v4 from v7, than you'll get weird results. I'm just making sure this is intentional and clear.

But there's a second issue. This code will output the metadata on any architecture not just ARM, right? So, you'll get odd flags on IR where this has no meaning, and worse still, could be used in the future to mean something on a different architecture, which is not future proof.

I think a better approach is to *just* emit the metadata is the flag exists, and make the back-end work out what the defaults are on their own platforms and options.

wchar_t is unsigned long on any ARM environment strictly following AAPCS. Windows on ARM does not strictly follow AAPCS (it is pretty close though), and uses an unsigned short for wchar_t.

The AAPCS allows wchar_t to be unsigned int or unsigned short, with the choice left up to the platform ABI [1, 7.1.1]. Windows on ARM defines wchar_t to be unsigned short [2, C/C++ Specifics], which is allowed by the AAPCS.

Enums are a bit more tricky, with them defaulting to short, but extending to long if any of the elements of the enumeration exceed the limits of short.

I think we are getting our terminology mixed up. The two variants permitted by the AAPCS are [1, 7.1.3]:

  • An enumerated type normally occupies a word (int or unsigned int). If a word cannot represent all of its enumerated values the type occupies a double word (long long or unsigned long long). This corresponds to clang's -fno-short-enums.
  • The type of the storage container for an enumerated type is the smallest integer type that can contain all of its enumerated values. This corresponds to clang's -fshort-enums, which is the default.

According to the C standard (I only checked C99), the enum type is implementation defined [3, 6.7.2.2.4], but it looks like clang implements it as above for all targets (Sema::ActOnEnumBody, currently line 13014-13107).

That said, would you be opposed to using an enumeration for the values of this metadata Oliver?

With the current patch, the backend needs to know what the frontend is doing when using long/short wchar/enums. Perhaps it would be better to store the size of wchar_t and the minimum size of an enum? This should avoid the need to duplicate this target- and language-specific knowledge.

Even though we "assumed" that was true, we didn't have the attributes in place, if the default was different, say v4 from v7, than you'll get weird results.

If the default was different, the code will have been compiled with different assumptions about wchar_t and enum size, so we want the build attributes to prevent the user from linking these two objects together.

I think a better approach is to *just* emit the metadata is the flag exists.

With the current backend implementation, if there is no metadata the build attribute will not be emitted, and the default build attribute is that enums/wchars were not used as this is the only safe default. If the backend were to work out the default, this would duplicate the logic for selecting the default, and if we get it wrong the build attributes will not match the code.

  1. http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.pdf
  2. http://msdn.microsoft.com/en-us/library/dn736986.aspx
  3. C99 draft with TC1-3
olista01 updated this revision to Diff 10684.Jun 20 2014, 2:12 AM

Emit the size of wchar_t and the minimum size of an enum, rather than a boolean representing which option was used.

With the current backend implementation, if there is no metadata the build attribute will not be emitted, and the default build attribute is that enums/wchars were not used as this is the only safe default. If the backend were to work out the default, this would duplicate the logic for selecting the default, and if we get it wrong the build attributes will not match the code.

I know, and that was my point. I think we are in agreement as to what the dangers are (regarding dealing with the default and the current implementation, which might not be the same). I haven't gone through all possibilities myself, but I trust you have, so if you're happy with the metadata being applied for every ARM target, I'm happy too.

Though, it'd be best not to do that for any other target, since this is an ARM ABI specific flag.

rengolin added inline comments.Jun 20 2014, 2:38 AM
lib/CodeGen/CodeGenModule.cpp
364

two semi-colons

olista01 updated this revision to Diff 10691.Jun 20 2014, 3:41 AM

Only emit the metadata when targeting ARM.

rengolin accepted this revision.Jun 20 2014, 4:49 AM
rengolin added a reviewer: rengolin.

LGTM, thanks!

This revision is now accepted and ready to land.Jun 20 2014, 4:49 AM
olista01 closed this revision.Jun 20 2014, 5:51 AM

Thanks, committed revision 211354.