www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - core.attribute - Remove friction for compiler attributes

For a while now GDC and LDC have supported a variety of their
backend's attributes, like inlining or compiling a specific
function with SSE4 in an otherwise generic x64 build.

I think we should unify those into a common core.attribute,
either aliasing or replacing the vendor specific symbols.
They don't need to be functional immediately. There are two
things that I see need to be discussed.

1. Syntax

  All attributes are currently set via  attribute(=E2=80=A6). I wonder
  if this is just easier to recognize for the compiler than
  multiple attribute names or if there are other benefits.
  Personally for the most part I'd prefer shorter versions,
  e.g.  forceinline instead of  attribute("forceinline").
  We can also achieve this by keeping the vendor specific
  modules/symbols and creating aliases, so it is mostly about
  what we prefer.

2. Semantics

  Unfortunately the compiler internals are all quite
  different. When it comes to always inlining a function for
  example, DMD won't even try unless "-inline" is given on the
  command-line. GCC will fail compilation if it cannot inline
  and I think LLVM only warns you in such cases.
  My somewhat painful idea is to split these attributes up
  into something like  forceinline (produces warning or error)
  and  inline (silent or warning at most) and map them to the
  closest the respective compilers can offer - or else make
  them a noop.


https://github.com/mleise/fast/blob/master/source/fast/helpers.d#L99
shows how we alias existing attributes or make them noops:

  version (DigitalMars)
  {
  	enum noinline;
  	enum forceinline;
  	enum sse4;
  }
  else version (GNU)
  {
  	import gcc.attribute;
  	enum noinline    =3D gcc.attribute.attribute("noinline");
  	enum forceinline =3D gcc.attribute.attribute("forceinline");
  	enum sse4        =3D gcc.attribute.attribute("target", "sse4");
  }
  else version (LDC)
  {
  	import ldc.attribute;
  	enum noinline    =3D ldc.attribute.attribute("noinline");
  	enum forceinline =3D ldc.attribute.attribute("alwaysinline");
  	enum sse4;
  }

(Note that GCC's target attribute can actually takes a list of
features.) If you target i586 and started using SSE, the
compiler would tell you that these instructions do not exist
on that architecture. So you write a generic function and an
additional SSE function with  attribute("target", "sse") and
wont run into "illegal instruction" errors at runtime on older
CPUs.

--=20
Marco
Oct 20 2015