This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: TRUTH_*_EXPR and BOOLEAN_TYPE
On 02-Jan-2001, Mark Mitchell <mark@codesourcery.com> wrote:
>
> The key constraint is not that the TRUTH_NOT_EXPR have BOOLEAN_TYPE --
> it is that the value of the argument have value either zero or one.
OK, but the constraint that is enforced by the test in
invert_truthvalue() is stronger than that. In my front-end, I know
that the integer variable that I'm negating will always have value
either zero or one. But invert_truthvalue() doesn't trust me, and
aborts, because *it* can't *prove* that the value will always be
zero or one.
I could wrap the argument in a NE_EXPR (..., INTEGER_CST [0])).
But that could lead to less efficient code, I think.
So I think a better solution for me is to use a BOOLEAN_TYPE
for variables and expressions that my front-end knows will
only have value 0 or 1. This is easy enough to do; I was
already giving them type `boolean_type_node', but I'd copied
the definition of that from toy.c, which looks like it was
copied from the C front-end, which has boolean_type_node
equal to integer_type_node, and thus having INTEGER_TYPE
rather than BOOLEAN_TYPE.
> ! /* ANDIF and ORIF allow the second operand not to be computed if the
> ! value of the expression is determined from the first operand. AND,
> ! OR, and XOR always compute the second operand whether its value is
> ! needed or not (for side effects). The operand may have
> ! BOOLEAN_TYPE or INTEGER_TYPE. In either case, the argument will be
> ! either zero or one. For example, a TRUTH_NOT_EXPR will never have
> ! a INTEGER_TYPE VAR_DECL as its argument; instead, a NE_EXPR will be
> ! used to compare the VAR_DECL to zero, thereby obtaining a node with
> ! value zero or one. */
This is definitely an improvement. Thanks. However, it still doesn't
state precisely what requirements the back-end imposes. Unfortunately
those requirements are rather complex. The argument must be
"provably boolean", where
Anything with BOOLEAN_TYPE is provably boolean.
Any relation operator expression is provably boolean.
Any integer constant is provably boolean.
[That's what invert_truthvalue allows, anyway.
Probably only 0 and 1 integer constants should be allowed.]
A COND_EXPR is provably boolean if its 2nd and 3rd arguments
are both provably boolean.
A COMPOUND_EXPR is provably boolean if its 2nd argument is
probably boolean.
A NOT_EXPR, NON_LVALUE_EXPR, CONVERT_EXPR, FLOAT_EXPR,
WITH_RECORD_EXPR, or CLEANUP_POINTER_EXPR is provably boolean
if its 1st argument is probably boolean.
A SAVE_EXPR is always provably boolean.
[That's what invert_truthvalue allows, anyway. Why?]
I think it would be better to simplify the requirements so that the
argument is just required to have value 0 or 1, rather than to be
*provably* boolean. However, that could be a difficult task; I don't
know if removing the abort() in invert_truthvalue() would be enough,
since there may be other places in the back-end which also assume this
(or something similar).
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.