[LLVMdev] Helping the optimizer along (__assume)
Kenneth Boyd
zaimoni at zaimoni.com
Thu Oct 23 15:12:24 PDT 2008
Cédric Venet wrote:
> Kenneth Boyd a écrit :
>
>> Cédric Venet wrote:
>>
>>> you never seen assert(0 && "Not yet implemented"); ?
>>> You may want to compile a program like this :)
>>>
>>>
>> As I see it, under the proposed extension a compile-time false constant
>> would error "if the code commits to executing it".
>>
>> Heuristically, something like
>>
>> void foo(int x)
>> {
>> switch(x)
>> {
>> case 1: return;
>> case 2: return;
>> default: assert(0 && "not yet implemented")
>> }
>> }
>>
>> should itself compile, but then ideally
>>
>> foo(3)
>>
>> causes a compiler error as it commits to executing the assert.
>>
>
> Then not only the condition of the assert must be proved false, but the
> assert must be proved to be actually reached in all possible code path
> (not only be reachable, think about virtual function).
I'm thinking a bit more locally than that; as I'd rather not mess with
the halting problem.
In the example I gave, I want foo(3) to error even if it is
unreachable. But I don't want an extended assert of the compile-time
false constant, wrapped in the switch statement, to error.
[I'm visualizing this as having two extension intrinsics __precondition
and __postcondition, and using the algebra of theses intrinsics to
implement the automated proof. The compiler gets to inject these at AST
creation "wherever reasonable". In particular, each block of the switch
statement gets an implicit __postcondition at the very beginning, before
any user code in the block.
The __postcondition(1!=x && 2!=x), implicitly injected at the start of
the default: block, prevents the __precondition(0 && "not yet
implemented"), injected by the assert, from immediately erroring. The
idea is that is that
__postcondition(1!=x && 2!=x) __precondition(0 && "not yet implemented")
isn't "in normal form", we should first reduce to
__postcondition(1!=x && 2!=x) __precondition(0)
and then commutate:
__precondition(1!=x && 2!=x) __postcondition(1!=x && 2!=x) ]
> ... And then think about:
>
> int main(int argc, const char* argv[]) {
> if(argc<2) return -1; // error in command line, exit early
> ...
> assert(0); // false assert
> ...
> return 0;
> }
>
> you will never be able to demonstrate that the assert is reached since
> it is not reached in all code path,
That's fine. Then the assert goes off at runtime only in debug-mode,
just like before.
> ....
>
> Clearly this functionnality is interesting, but there is lot of work to
> do on the semantic to make it useful, and potentially need the
> adjonction of additionnal user information like: error_code_path or
> always_reached.
>
Yes.
Kenneth
More information about the llvm-dev
mailing list