how to get a deterministic execution

Hello,

For debugging purposes, I’ve added a unique id member to the Value class:

global_next_vuid = 0;
Value::Value(…){
vuid = ++global_next_vuid;
}

My hope is that by looking at the vuid of a Value, I can see its vuid,
set a conditional breakpoint and re-run the compiler to
see who (what pass) constructed that value.

Maybe I am not doing it the right way, but the above ‘vuid’ field doesn’t seem
to be updated deterministically.

I am using a DEBUG built. Is LLVM multithreaded by default?

Is it possible to get a deterministic behavior?

Thank you,
Dan

Hello,

Yo!

For debugging purposes, I've added a unique id member to the Value class:

global_next_vuid = 0;
Value::Value(..){
vuid = ++global_next_vuid;
}

My hope is that by looking at the vuid of a Value, I can see its vuid,
set a conditional breakpoint and re-run the compiler to
see who (what pass) constructed that value.

Maybe I am not doing it the right way, but the above 'vuid' field doesn't
seem
to be updated deterministically.

We'd need a testcase to see what you mean...I'm not entirely sure that
what you're doing will work, though.

I am using a DEBUG built. Is LLVM multithreaded by default?

No. LLVM isn't multithreaded safe just yet.

Is it possible to get a deterministic behavior?

The code that's generated should be completely deterministic.

-bw

The generated code is deterministic, but the global order the instructions were generated
seems it is not (although the result is guaranteed to be the same).
Now I think the order functions are processed might not be guaranteed.
I’ve attached a test case, and here is what I get:

(303)$ ~/bin/llvm/bin/gcc -O3 -emit-llvm try_calls_basic.2.c -c -o try_calls_basic2.bc
(304)$ $LLVM/opt -O3 -IR-DUMP :ALL -load ~/download/llvm-objects/Debug/lib/LLVMHello.so -hello -debug-pass Structure < try_calls_basic2.bc > try_calls_basic2.2.bc 2> x1
(305)$ $LLVM/opt -O3 -IR-DUMP :ALL -load ~/download/llvm-objects/Debug/lib/LLVMHello.so -hello -debug-pass Structure < try_calls_basic2.bc > try_calls_basic2.2.bc 2> x2
(306)$ diff x1 x2|more
237c237
< %0 = tail call i32 (…)* %pf() nounwind ; [#uses=0] {vuid=69}

try_calls_basic.2.c (593 Bytes)

There are a number of places in the optimizers where instructions are held in sets or maps by pointer value, which is non-deterministic. While the final output has to be the same in all cases, there are several places where iterations are accelerated by using non-deterministic iteration orders. As long as the same final end result is produced, this is allowed.

--Owen