public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
@ 2017-05-08 23:32 Daniel Santos
  2017-05-09  9:36 ` Florian Weimer
  2017-05-09 13:29 ` Allan Sandfeld Jensen
  0 siblings, 2 replies; 15+ messages in thread
From: Daniel Santos @ 2017-05-08 23:32 UTC (permalink / raw)
  To: gcc, Joseph Myers, Richard Henderson

I would like to make some changes in GCC 8, so I thought that formal 
proposal and RFC would be the best path. I'm still relatively new to the 
GCC project.

I began experimenting with C metaprogramming techniques back in 2012, in 
order to implement more efficient generic libraries in C. The code is 
ANSI C compliant and can build anywhere, but exploits GCC attributes, 
checks and optimizations (when available) to assure optimal efficiency. 
The underlying mechanisms involve the exploitation of constant 
propagation and -findirect-inline to cause an inline function to behave 
similar to a C++ templatized function that is instantiated at the call 
site. The primary aim is to facilitate high-performance generic C 
libraries for software where C++ is not suitable, but the cost of 
run-time abstraction is unacceptable. A good example is the Linux 
kernel, where the source tree is littered with more than 100 hand-coded 
or boiler-plate (copy, paste and edit) search cores required to use the 
red-black tree library.

Here is a brief example of a simplified qsort algo:

/* A header file for a generic qsort library.  */

struct qsort_def {
     size_t size;
     size_t align;
     int (*less_r)(const void *a, const void *b, void *context);
};

inline __attribute__((always_inline, flatten)) void
qsort_template(const struct qsort_def *def, void *const pbase, size_t n,
	       void *context)
{
   /* details omitted... */
}

/* An implementation file using qsort.  */

static inline my_less_r (const void *a, const void *b, void *context)
{
   const struct my_struct *_a = a;
   const struct my_struct *_b = b;

   return _a->somefield < _b->somefield;
}

static const struct qsort_def my_qsort_def = {
     .size   = sizeof (struct my_struct),
     .align  = 16,
     .less_r = my_less_r,
};

void __attribute__((flatten)) my_sort (struct my_struct *o, size_t n)
{
   qsort_template (&my_qsort_def, o, n);
}


The purpose of the "my_sort" wrapper function is to contain the template 
expansion. Beginning with GCC 4.4, when qsort_template inline expansion 
occurs, the entire struct qsort_def is compiled away. The "my_less_r" 
function is inlined, and by using __builtin_assume_aligned(), all 
manipulation of data is performed with the best available instructions 
and unneeded memcpy alignment pro/epilogues are omitted. This results in 
code that's both faster and smaller and is analogous in form and 
performance to C++'s std::sort, except that we are using the first 
parameter (const struct qsort_def *def) in lieu of formalized template 
parameters.

To further the usefulness of such techniques, I propose the addition of 
a c-family attribute to declare a parameter, variable (and possibly 
other declarations) as "constprop" or some similar word. The purpose of 
the attribute is to:

1.) Emit a warning or error when the value is not optimized away, and
2.) Direct various optimization passes to prefer (or force) either 
cloning or inlining of a function with such a parameter.

This will enable the use of pseudo-templates and:

1.) Eliminate the need for __attribute__((always_inline, flatten)) and 
complicated ASSERT_CONST() macros,
2.) Eliminate the need for an __attribute__((flatten) wrapper function,
3.) Reduce the need for the programmer to think about what the compiler 
is doing, and
4.) Allow gcc to decide rather inlining or cloning is better.

While not as powerful as C++ template metapgramming (type programming), 
there are certainly many more possibilities that haven't yet been 
discovered. I would like to be able to put something in GCC 8. Below is 
my current progress.

diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index f2a88e147ba..5ec7b615e24 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -139,6 +139,7 @@ static tree handle_bnd_variable_size_attribute (tree *, tree, tree, int, bool *)
  static tree handle_bnd_legacy (tree *, tree, tree, int, bool *);
  static tree handle_bnd_instrument (tree *, tree, tree, int, bool *);
  static tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *);
+static tree handle_constprop_attribute (tree *, tree , tree , int , bool *);
  
  /* Table of machine-independent attributes common to all C-like languages.
  
@@ -345,6 +346,8 @@ const struct attribute_spec c_common_attribute_table[] =
  			      handle_bnd_instrument, false },
    { "fallthrough",	      0, 0, false, false, false,
  			      handle_fallthrough_attribute, false },
+  { "constprop",                 0, 0, false, false, false,
+			      handle_constprop_attribute, false },
    { NULL,                     0, 0, false, false, false, NULL, false }
  };
  
@@ -3173,3 +3176,15 @@ handle_fallthrough_attribute (tree *, tree name, tree, int,
    *no_add_attrs = true;
    return NULL_TREE;
  }
+
+static tree
+handle_constprop_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+			    int flags, bool *no_add_attrs)
+{
+  if (!DECL_P (*node) || !(VAR_P (*node) || TREE_CODE (*node) == PARM_DECL))
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
+      *no_add_attrs = true;
+    }
+  return NULL_TREE;
+}
diff --git a/gcc/common.opt b/gcc/common.opt
index 4021622cf5c..93dd10e0771 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -557,6 +557,10 @@ Wcast-align
  Common Var(warn_cast_align) Warning
  Warn about pointer casts which increase alignment.
  
+Wconstprop
+Common Var(warn_constprop) Warning
+Warn when an __attribute__((constprop)) fails to constant-propagate away.
+
  Wcpp
  Common Var(warn_cpp) Init(1) Warning
  Warn when a #warning directive is encountered.
diff --git a/gcc/expr.c b/gcc/expr.c
index 29ebad3a061..c8aba05a76e 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -9717,6 +9717,16 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
        }
  
      case SSA_NAME:
+      {
+	tree var = SSA_NAME_VAR (exp);
+	/* TODO: Don't repeat warning for same declaration.  */
+	if (var && lookup_attribute ("constprop", DECL_ATTRIBUTES (var)))
+	  {
+	    warning (OPT_Wconstprop, "Expression %q+D is not constant in this context", var);
+	    /* TODO: Set something so we don't repeat this warning.  */
+	  }
+      }
+
        /* ??? ivopts calls expander, without any preparation from
           out-of-ssa.  So fake instructions as if this was an access to the
  	 base variable.  This unnecessarily allocates a pseudo, see how we can


Comments, objections, suggestions?

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-08 23:32 [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates Daniel Santos
@ 2017-05-09  9:36 ` Florian Weimer
  2017-05-10  8:46   ` Daniel Santos
  2017-05-09 13:29 ` Allan Sandfeld Jensen
  1 sibling, 1 reply; 15+ messages in thread
From: Florian Weimer @ 2017-05-09  9:36 UTC (permalink / raw)
  To: Daniel Santos, gcc, Joseph Myers, Richard Henderson

On 05/09/2017 01:36 AM, Daniel Santos wrote:
> To further the usefulness of such techniques, I propose the addition of 
> a c-family attribute to declare a parameter, variable (and possibly 
> other declarations) as "constprop" or some similar word. The purpose of 
> the attribute is to:
> 
> 1.) Emit a warning or error when the value is not optimized away, and
> 2.) Direct various optimization passes to prefer (or force) either 
> cloning or inlining of a function with such a parameter.

I think GCC used to treat C and C++ constant expressions this way in the 
old days.  That is, what was a constant expression depended to some 
degree on the capabilities of the folder at least (and maybe the 
optimizers).  This wasn't such a great idea because it made behavior 
inconsistent across architectures and GCC versions.

There are also thorny specification issues, like is an array whose 
length is a constprop value a VLA or not?

If you are interested in metaprogramming techniques, you are probably 
better off writing code generators or using a C++ subset.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-08 23:32 [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates Daniel Santos
  2017-05-09  9:36 ` Florian Weimer
@ 2017-05-09 13:29 ` Allan Sandfeld Jensen
  2017-05-10  9:13   ` Daniel Santos
  1 sibling, 1 reply; 15+ messages in thread
From: Allan Sandfeld Jensen @ 2017-05-09 13:29 UTC (permalink / raw)
  To: gcc; +Cc: Daniel Santos, Joseph Myers, Richard Henderson

On Tuesday 09 May 2017, Daniel Santos wrote:
> The primary aim is to facilitate high-performance generic C
> libraries for software where C++ is not suitable, but the cost of
> run-time abstraction is unacceptable. A good example is the Linux
> kernel, where the source tree is littered with more than 100 hand-coded
> or boiler-plate (copy, paste and edit) search cores required to use the
> red-black tree library.
That is not a good excuse, they can just use a defined subset of C++. The cost 
of C++ abstractions is zero if you don't use them. 

> 
> To further the usefulness of such techniques, I propose the addition of
> a c-family attribute to declare a parameter, variable (and possibly
> other declarations) as "constprop" or some similar word. The purpose of
> the attribute is to:
> 
> 1.) Emit a warning or error when the value is not optimized away, and
> 2.) Direct various optimization passes to prefer (or force) either
> cloning or inlining of a function with such a parameter.
> 
This I can get more behind, I have wanted a constexpr attribute for C for some 
time. If not for anything else to be able to use it in shared/system headers 
that can be used by both C and C++ and in C++ would be useful in constexpr 
expressions. If you can find a use for it in pure C as well, so much the 
better.

`Allan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-09  9:36 ` Florian Weimer
@ 2017-05-10  8:46   ` Daniel Santos
  0 siblings, 0 replies; 15+ messages in thread
From: Daniel Santos @ 2017-05-10  8:46 UTC (permalink / raw)
  To: Florian Weimer, gcc, Joseph Myers, Richard Henderson

Thanks for your feedback!

On 05/09/2017 04:36 AM, Florian Weimer wrote:
> On 05/09/2017 01:36 AM, Daniel Santos wrote:
>> To further the usefulness of such techniques, I propose the addition 
>> of a c-family attribute to declare a parameter, variable (and 
>> possibly other declarations) as "constprop" or some similar word. The 
>> purpose of the attribute is to:
>>
>> 1.) Emit a warning or error when the value is not optimized away, and
>> 2.) Direct various optimization passes to prefer (or force) either 
>> cloning or inlining of a function with such a parameter.
>
> I think GCC used to treat C and C++ constant expressions this way in 
> the old days.  That is, what was a constant expression depended to 
> some degree on the capabilities of the folder at least (and maybe the 
> optimizers).  This wasn't such a great idea because it made behavior 
> inconsistent across architectures and GCC versions.

What optimizations are enabled also effects it.  In 2012, I made a test 
program and scripted it to run on GCC versions 3.4.6 to 4.7.0 to map out 
what __builtin_constant_p() was able to resolve and put it all in a 
database.  Most of them started working between 4.2 and 4.4.  I put it 
into a spreadsheet for better analysis.

Anyway, I wasn't aware that it could vary across architectures. What I'm 
doing so far is only in the tree and I'm doing the checks as we're 
emitting RTL.

> There are also thorny specification issues, like is an array whose 
> length is a constprop value a VLA or not?

This is probably a worthwhile thought.  I wasn't actually thinking of 
specification-breaking changes, so it would be a VLA and value declared 
with __attribute__((constprop)) would just be like an optimization hint 
(like __builtin_expect) that could also notify you when you're request 
couldn't be fulfilled.

In the past, I have considered the merits of some type of 
__builtin_constexpr() to do just that, returning a value that can be 
treated as a C "constant expression" (as per the language spec.), to be 
used as a static initializer or fixed-size array length specifier.  The 
lack of such a mechanism is why the Linux kernel still resorts to 
compile-time checks using a negative-sized bitfields to signal failure 
(http://elixir.free-electrons.com/linux/latest/source/include/linux/bug.h#L37). 
I would have to do a lot more research to fully understand the issues 
and implications of that.

> If you are interested in metaprogramming techniques, you are probably 
> better off writing code generators or using a C++ subset.
>
> Thanks,
> Florian

Yeah, somehow I got myself interested in this unexploited avenue. It 
seems that more progressive programmers are of the mindset to just use 
C++, but system-level programmers tend to be wary of such magicks and 
often shun "dead-code trickery".

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-09 13:29 ` Allan Sandfeld Jensen
@ 2017-05-10  9:13   ` Daniel Santos
  2017-05-10  9:24     ` Jonathan Wakely
  0 siblings, 1 reply; 15+ messages in thread
From: Daniel Santos @ 2017-05-10  9:13 UTC (permalink / raw)
  To: Allan Sandfeld Jensen, gcc; +Cc: Joseph Myers, Richard Henderson

Thanks for your feedback!

On 05/09/2017 08:29 AM, Allan Sandfeld Jensen wrote:
> On Tuesday 09 May 2017, Daniel Santos wrote:
>> The primary aim is to facilitate high-performance generic C
>> libraries for software where C++ is not suitable, but the cost of
>> run-time abstraction is unacceptable. A good example is the Linux
>> kernel, where the source tree is littered with more than 100 hand-coded
>> or boiler-plate (copy, paste and edit) search cores required to use the
>> red-black tree library.
> That is not a good excuse, they can just use a defined subset of C++. The cost
> of C++ abstractions is zero if you don't use them.

Put simply, there are many projects who will not likely be converting to 
C++ in the in our lifetimes.  As far as abstractions, I meant the 
abstraction penalty of static types which doesn't exist when using C++ 
templates (not at run-time anyway).  In C, generic libraries typically 
resolve abstract behavior with a callback function pointer.  This costs 
a function call in addition to the optimization barrier of the function 
call (which is the worst part of it).

>> To further the usefulness of such techniques, I propose the addition of
>> a c-family attribute to declare a parameter, variable (and possibly
>> other declarations) as "constprop" or some similar word. The purpose of
>> the attribute is to:
>>
>> 1.) Emit a warning or error when the value is not optimized away, and
>> 2.) Direct various optimization passes to prefer (or force) either
>> cloning or inlining of a function with such a parameter.
>>
> This I can get more behind, I have wanted a constexpr attribute for C for some
> time. If not for anything else to be able to use it in shared/system headers
> that can be used by both C and C++ and in C++ would be useful in constexpr
> expressions. If you can find a use for it in pure C as well, so much the
> better.
>
> `Allan

Maybe "constexpr" would be a better name, as it mirrors the C++11 
keyword.  When I first read about C++ getting constexpr, my first 
thought was, "Yeah, as if they needed yet another way to do 
metaprogramming!" :)  However, I hadn't gone so far as to investigate 
using this new attribute on functions since we already have 
__attribute__((const)).  I haven't used this before so maybe I'm not 
aware of something that makes it unusable for such cases? Which of 
course raises the question if __attribute__((const)) would work out 
since it's only currently used on function declarations (and pointers to 
function declarations, but I don't fully understand what that is doing 
in handle_const_attribute).

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-10  9:13   ` Daniel Santos
@ 2017-05-10  9:24     ` Jonathan Wakely
  2017-05-10 22:09       ` Daniel Santos
  0 siblings, 1 reply; 15+ messages in thread
From: Jonathan Wakely @ 2017-05-10  9:24 UTC (permalink / raw)
  To: Daniel Santos; +Cc: Allan Sandfeld Jensen, gcc, Joseph Myers, Richard Henderson

On 10 May 2017 at 10:17, Daniel Santos wrote:
> Maybe "constexpr" would be a better name, as it mirrors the C++11 keyword.
> When I first read about C++ getting constexpr, my first thought was, "Yeah,
> as if they needed yet another way to do metaprogramming!" :)  However, I

Because writing functions in normal C++ is much simpler and more
expressive than writing class templates and recursive partial
specializations.

Just because there's already one way to do something doesn't mean
better ways to do it are bad.


> hadn't gone so far as to investigate using this new attribute on functions
> since we already have __attribute__((const)).  I haven't used this before so
> maybe I'm not aware of something that makes it unusable for such cases?
> Which of course raises the question if __attribute__((const)) would work out
> since it's only currently used on function declarations (and pointers to
> function declarations, but I don't fully understand what that is doing in
> handle_const_attribute).

__attribute__((const)) is not a substitute for constexpr, it's not
even in the same ballpark. It says the function doesn't touch global
memory, it doesn't mean its return value is a constant expression, so
you can't do:

int f() __attribute__((const));
int f() { return 1; }
int i[f()];

I don't think __attribute__((const)) is useful for your goal.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-10  9:24     ` Jonathan Wakely
@ 2017-05-10 22:09       ` Daniel Santos
  2017-05-11 10:12         ` Jonathan Wakely
  2017-05-12 15:49         ` Martin Sebor
  0 siblings, 2 replies; 15+ messages in thread
From: Daniel Santos @ 2017-05-10 22:09 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: Allan Sandfeld Jensen, gcc, Joseph Myers, Richard Henderson,
	Florian Weimer

On 05/10/2017 04:24 AM, Jonathan Wakely wrote:
> Just because there's already one way to do something doesn't mean
> better ways to do it are bad.

I'm only speaking out of jealousy being that most of my recent work has 
been in C.

>> hadn't gone so far as to investigate using this new attribute on functions
>> since we already have __attribute__((const)).  I haven't used this before so
>> maybe I'm not aware of something that makes it unusable for such cases?
>> Which of course raises the question if __attribute__((const)) would work out
>> since it's only currently used on function declarations (and pointers to
>> function declarations, but I don't fully understand what that is doing in
>> handle_const_attribute).
> __attribute__((const)) is not a substitute for constexpr, it's not
> even in the same ballpark. It says the function doesn't touch global
> memory, it doesn't mean its return value is a constant expression, so
> you can't do:
>
> int f() __attribute__((const));
> int f() { return 1; }
> int i[f()];
>
> I don't think __attribute__((const)) is useful for your goal.

Well my primary goal is programming with values that are constant in the 
compiler.  There is no language in any C specification (that I'm aware 
of) for a "compile-time constant", but the concept is very important.  
So just because some expression is a compile-time constant doesn't mean 
we morph into a "constant expression" (as per the spec), even with 
__attribute__((const)).

Perhaps I can separate this project into two stages: a const/constprop 
and a constexpr.  The first stage behaves as little more than a 
collection of optimizer hints, extra warnings/errors and fixes to some 
missed optimization opportunities, while the second implements a 
constexpr for C.  The first stage should lay a lot of the framework for 
the second, but the second probably deserves a formal specification (and 
I will certainly have to read up on changes in C++14 and 17 that I'm 
behind on).  I can state the rationale for the "const" or "constprop" 
portion of this, but before adding a constexpr to C, I think a good 
rationale should be written up and examined as well.  I am in support of 
this as I've encountered many areas where I saw it could be useful -- 
use in combination with GCC ({ statement expressions }) particularly 
comes to mind.

I still have a lot to learn about the cgraph and I know next to nothing 
about how profile guided optimization works, but an ideal implementation 
of a const/constprop attribute should include a mechanism (perhaps via 
-fopt-info?) to inform the programmer when it turns out that their 
optimization hint don't look like such a good idea. :)

I appreciate everybody's feedback!  Thoughts?

Also, still a bit new to GCC, am I missing any formal steps that should 
be taken prior to pursuing such changes?

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-10 22:09       ` Daniel Santos
@ 2017-05-11 10:12         ` Jonathan Wakely
  2017-05-11 10:44           ` Marek Polacek
  2017-05-11 14:35           ` Joseph Myers
  2017-05-12 15:49         ` Martin Sebor
  1 sibling, 2 replies; 15+ messages in thread
From: Jonathan Wakely @ 2017-05-11 10:12 UTC (permalink / raw)
  To: Daniel Santos
  Cc: Allan Sandfeld Jensen, gcc, Joseph Myers, Richard Henderson,
	Florian Weimer

On 10 May 2017 at 23:14, Daniel Santos wrote:
> Well my primary goal is programming with values that are constant in the
> compiler.  There is no language in any C specification (that I'm aware of)
> for a "compile-time constant", but the concept is very important.  So just
> because some expression is a compile-time constant doesn't mean we morph
> into a "constant expression" (as per the spec), even with
> __attribute__((const)).

The C standard says "An implementation may accept other forms of
constant expressions." That means rather than inventing some
"constprop" you could just extend GCC to treat more expressions
involving constants as constant-expressions.

There are enhancement requests for this in Bugzilla, because some
compilers are already more catholic in what they accept in constant
expressions (notably, Clang).

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-11 10:12         ` Jonathan Wakely
@ 2017-05-11 10:44           ` Marek Polacek
  2017-05-11 14:35           ` Joseph Myers
  1 sibling, 0 replies; 15+ messages in thread
From: Marek Polacek @ 2017-05-11 10:44 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: Daniel Santos, Allan Sandfeld Jensen, gcc, Joseph Myers,
	Richard Henderson, Florian Weimer

On Thu, May 11, 2017 at 11:12:24AM +0100, Jonathan Wakely wrote:
> On 10 May 2017 at 23:14, Daniel Santos wrote:
> > Well my primary goal is programming with values that are constant in the
> > compiler.  There is no language in any C specification (that I'm aware of)
> > for a "compile-time constant", but the concept is very important.  So just
> > because some expression is a compile-time constant doesn't mean we morph
> > into a "constant expression" (as per the spec), even with
> > __attribute__((const)).
> 
> The C standard says "An implementation may accept other forms of
> constant expressions." That means rather than inventing some
> "constprop" you could just extend GCC to treat more expressions
> involving constants as constant-expressions.
> 
> There are enhancement requests for this in Bugzilla, because some
> compilers are already more catholic in what they accept in constant
> expressions (notably, Clang).

Right, at least:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66618

	Marek

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-11 10:12         ` Jonathan Wakely
  2017-05-11 10:44           ` Marek Polacek
@ 2017-05-11 14:35           ` Joseph Myers
  2017-05-12 20:54             ` Daniel Santos
  1 sibling, 1 reply; 15+ messages in thread
From: Joseph Myers @ 2017-05-11 14:35 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: Daniel Santos, Allan Sandfeld Jensen, gcc, Richard Henderson,
	Florian Weimer

On Thu, 11 May 2017, Jonathan Wakely wrote:

> On 10 May 2017 at 23:14, Daniel Santos wrote:
> > Well my primary goal is programming with values that are constant in the
> > compiler.  There is no language in any C specification (that I'm aware of)
> > for a "compile-time constant", but the concept is very important.  So just
> > because some expression is a compile-time constant doesn't mean we morph
> > into a "constant expression" (as per the spec), even with
> > __attribute__((const)).
> 
> The C standard says "An implementation may accept other forms of
> constant expressions." That means rather than inventing some
> "constprop" you could just extend GCC to treat more expressions
> involving constants as constant-expressions.

Note that while "other forms" might be accepted in initializers, they 
would still not be integer constant expressions (see DR#312).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-10 22:09       ` Daniel Santos
  2017-05-11 10:12         ` Jonathan Wakely
@ 2017-05-12 15:49         ` Martin Sebor
  2017-05-12 21:11           ` Daniel Santos
  1 sibling, 1 reply; 15+ messages in thread
From: Martin Sebor @ 2017-05-12 15:49 UTC (permalink / raw)
  To: Daniel Santos, Jonathan Wakely
  Cc: Allan Sandfeld Jensen, gcc, Joseph Myers, Richard Henderson,
	Florian Weimer

On 05/10/2017 04:14 PM, Daniel Santos wrote:
> On 05/10/2017 04:24 AM, Jonathan Wakely wrote:
>> Just because there's already one way to do something doesn't mean
>> better ways to do it are bad.
>
> I'm only speaking out of jealousy being that most of my recent work has
> been in C.
>
>>> hadn't gone so far as to investigate using this new attribute on
>>> functions
>>> since we already have __attribute__((const)).  I haven't used this
>>> before so
>>> maybe I'm not aware of something that makes it unusable for such cases?
>>> Which of course raises the question if __attribute__((const)) would
>>> work out
>>> since it's only currently used on function declarations (and pointers to
>>> function declarations, but I don't fully understand what that is
>>> doing in
>>> handle_const_attribute).
>> __attribute__((const)) is not a substitute for constexpr, it's not
>> even in the same ballpark. It says the function doesn't touch global
>> memory, it doesn't mean its return value is a constant expression, so
>> you can't do:
>>
>> int f() __attribute__((const));
>> int f() { return 1; }
>> int i[f()];
>>
>> I don't think __attribute__((const)) is useful for your goal.
>
> Well my primary goal is programming with values that are constant in the
> compiler.  There is no language in any C specification (that I'm aware
> of) for a "compile-time constant", but the concept is very important.
> So just because some expression is a compile-time constant doesn't mean
> we morph into a "constant expression" (as per the spec), even with
> __attribute__((const)).

The C committee has discussed extending the set of expressions
that are considered constant in C2X.  A proposal was submitted
last year that, at least in spirit, gained pretty broad support
(the finer details, including the syntax, especially the reuse
of the register keyword, are likely to evolve):

   http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2067.pdf

The C committee's charter for C2X is to increase compatibility
with C++, so new language features with that effect have a good
chance of being considered.

I don't expect C2X to go as far as to add something as complex
as templates but some on the committee are working on enhancing
support for generic programming (via _Generic).  Interestingly,
C11 (by accident) introduced a requirement for implementations
to support true type genericity in the form of the C11 atomic
APIs.  It may not be too far out there to propose to generalize
the underlying machinery and make it available to programs (as
opposed to just the standard library alone).

Martin

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-11 14:35           ` Joseph Myers
@ 2017-05-12 20:54             ` Daniel Santos
  2017-05-12 21:03               ` Joseph Myers
  2017-05-15 11:31               ` Vincent Lefevre
  0 siblings, 2 replies; 15+ messages in thread
From: Daniel Santos @ 2017-05-12 20:54 UTC (permalink / raw)
  To: Joseph Myers, Jonathan Wakely
  Cc: Allan Sandfeld Jensen, gcc, Richard Henderson, Florian Weimer

Sorry for my delayed response.

On 05/11/2017 09:35 AM, Joseph Myers wrote:
> On Thu, 11 May 2017, Jonathan Wakely wrote:
>
>> On 10 May 2017 at 23:14, Daniel Santos wrote:
>>> Well my primary goal is programming with values that are constant in the
>>> compiler.  There is no language in any C specification (that I'm aware of)
>>> for a "compile-time constant", but the concept is very important.  So just
>>> because some expression is a compile-time constant doesn't mean we morph
>>> into a "constant expression" (as per the spec), even with
>>> __attribute__((const)).
>> The C standard says "An implementation may accept other forms of
>> constant expressions." That means rather than inventing some
>> "constprop" you could just extend GCC to treat more expressions
>> involving constants as constant-expressions.

I would rather not invent terms either.  In regards to the proposed attribute name, I'm leaning towards re-using "const" instead of adding "constprop" because it seems to fall in line with the original purpose of the attribute while  and there doesn't appear to be any overlap between what it currently applies to and what I would like to add the attribute to.  But from a conceptual standpoint, I believe the term "constant-expression" would be incorrect because the C standard defines this constraint: (6.6.3 of C11) "Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated."  I definitely do need to study the C specs more carefully to make sure I fully understand how this is used and how it's changed over different revisions of the spec.

But from what I've done so far, I can tell that around 80-90% of what I hope to achieve will be through simply improving GCC's ability to to constant propagate (I'm focusing on one issue right now where it appears that early SRA might be throwing off later constant propagation).

> Note that while "other forms" might be accepted in initializers, they
> would still not be integer constant expressions (see DR#312).

What is DR#312?

I should probably be more careful and explicit in my language.  I was 
thinking particularly of integer constant expressions that are required 
for the size of non-variable length arrays, bitfields, and such.

If only for the sake of entertainment, there *is* actually a legitimate 
way to transform an expression into an integer constant expression and 
even an integer constant, but is only practical when the range of 
possible values is limited.

#define foo (i) /* Do something here. */
#define bar (expr)		 \
   do {				 \
       ASSERT_CONST (expr);	 \
       switch (expr) {		 \
       case 1:	foo(1); break;	 \
       case 2:	foo(2); break;	 \
       case 4:	foo(4); break;	 \
       case 8:	foo(8); break;	 \
       case 16:	foo(16); break;	 \
       case 32:	foo(32); break;	 \
       case 64:	foo(64); break;	 \
       case 128:	foo(128); break; \
       case 256:	foo(256); break; \
       default:			 \
	ASSERT (0);		 \
     }				 \
   } while (0)


Daniel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-12 20:54             ` Daniel Santos
@ 2017-05-12 21:03               ` Joseph Myers
  2017-05-15 11:31               ` Vincent Lefevre
  1 sibling, 0 replies; 15+ messages in thread
From: Joseph Myers @ 2017-05-12 21:03 UTC (permalink / raw)
  To: Daniel Santos
  Cc: Jonathan Wakely, Allan Sandfeld Jensen, gcc, Richard Henderson,
	Florian Weimer

On Fri, 12 May 2017, Daniel Santos wrote:

> > Note that while "other forms" might be accepted in initializers, they
> > would still not be integer constant expressions (see DR#312).
> 
> What is DR#312?

http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_312.htm

(but cf the older 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_032.html against C90).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-12 15:49         ` Martin Sebor
@ 2017-05-12 21:11           ` Daniel Santos
  0 siblings, 0 replies; 15+ messages in thread
From: Daniel Santos @ 2017-05-12 21:11 UTC (permalink / raw)
  To: Martin Sebor, Jonathan Wakely
  Cc: Allan Sandfeld Jensen, gcc, Joseph Myers, Richard Henderson,
	Florian Weimer

On 05/12/2017 10:49 AM, Martin Sebor wrote:
> On 05/10/2017 04:14 PM, Daniel Santos wrote:
>> Well my primary goal is programming with values that are constant in the
>> compiler.  There is no language in any C specification (that I'm aware
>> of) for a "compile-time constant", but the concept is very important.
>> So just because some expression is a compile-time constant doesn't mean
>> we morph into a "constant expression" (as per the spec), even with
>> __attribute__((const)).
>
> The C committee has discussed extending the set of expressions
> that are considered constant in C2X.  A proposal was submitted
> last year that, at least in spirit, gained pretty broad support
> (the finer details, including the syntax, especially the reuse
> of the register keyword, are likely to evolve):
>
>   http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2067.pdf
>
> The C committee's charter for C2X is to increase compatibility
> with C++, so new language features with that effect have a good
> chance of being considered.
>
> I don't expect C2X to go as far as to add something as complex
> as templates but some on the committee are working on enhancing
> support for generic programming (via _Generic).  Interestingly,
> C11 (by accident) introduced a requirement for implementations
> to support true type genericity in the form of the C11 atomic
> APIs.  It may not be too far out there to propose to generalize
> the underlying machinery and make it available to programs (as
> opposed to just the standard library alone).
>
> Martin

Thank you for this!  It sounds like I need to read up on what is in the 
works with the C committee and maybe prepare my own proposal and become 
involved.  I see the monetary cost of not having generic support as very 
high -- you end up with more boiler-plate code that has to be 
maintained, thus increasing development time and the chance for bugs.  
It also takes more time to analyze the code, diagnose problems and get 
new programmers up to speed.

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates
  2017-05-12 20:54             ` Daniel Santos
  2017-05-12 21:03               ` Joseph Myers
@ 2017-05-15 11:31               ` Vincent Lefevre
  1 sibling, 0 replies; 15+ messages in thread
From: Vincent Lefevre @ 2017-05-15 11:31 UTC (permalink / raw)
  To: Daniel Santos
  Cc: Joseph Myers, Jonathan Wakely, Allan Sandfeld Jensen, gcc,
	Richard Henderson, Florian Weimer

On 2017-05-12 15:59:44 -0500, Daniel Santos wrote:
> [...] But from a conceptual standpoint, I believe the term
> "constant-expression" would be incorrect because the C standard
> defines this constraint: (6.6.3 of C11) "Constant expressions shall
> not contain assignment, increment, decrement, function-call, or
> comma operators, except when they are contained within a
> subexpression that is not evaluated." I definitely do need to study
> the C specs more carefully to make sure I fully understand how this
> is used and how it's changed over different revisions of the spec.

GCC already regards some function calls are acceptable in
constant expressions, when builtins are used, e.g. fabs (2.0),
contrary to Clang. The builtin is even used when <math.h> is
not included (note that Clang has the same behavior here). So,
there may be several issues. I've reported:

  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80756

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2017-05-15 11:31 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-08 23:32 [RFC] GCC 8 Project proposal: Extensions supporting C Metaprogramming, pseudo-templates Daniel Santos
2017-05-09  9:36 ` Florian Weimer
2017-05-10  8:46   ` Daniel Santos
2017-05-09 13:29 ` Allan Sandfeld Jensen
2017-05-10  9:13   ` Daniel Santos
2017-05-10  9:24     ` Jonathan Wakely
2017-05-10 22:09       ` Daniel Santos
2017-05-11 10:12         ` Jonathan Wakely
2017-05-11 10:44           ` Marek Polacek
2017-05-11 14:35           ` Joseph Myers
2017-05-12 20:54             ` Daniel Santos
2017-05-12 21:03               ` Joseph Myers
2017-05-15 11:31               ` Vincent Lefevre
2017-05-12 15:49         ` Martin Sebor
2017-05-12 21:11           ` Daniel Santos

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).