TRUTH_*_EXPR and BOOLEAN_TYPE

Fergus Henderson fjh@cs.mu.oz.au
Tue Jan 2 18:46:00 GMT 2001


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.


More information about the Gcc mailing list