[LLVMdev] More detailed example...
Sarah Thompson
thompson at email.arc.nasa.gov
Fri Jan 5 16:43:30 PST 2007
Further to that, I thought an example might be useful. In the following
code, n should end up with a value that varies nondeterministically with
the scheduling decisions made by the underlying run time system -- my
model checker, for example, should in theory be able to enumerate all
possible values. Anyway, if you look at the compiler output (see below),
the volatile global variable, n, has vanished, with the printf output
only ever taking the (constant) result 0.
I somehow need to get around this, or my attempt to implement a C++
model checker is dead in the water.
Thank you in advance,
Sarah
PS: mcp_fork() duplicates the current stack as a new thread, and returns
true within that thread and false in the original thread. mcp_yield()
forces a reschedule. Stacks are separate, but the heap is shared. My
model checker generates correct output for the generated code, but the
generated code has the wrong semantics.
-----------------------------------------------------------------
Here is the test code:
#include <stdio.h>
#include "../../mcp/include/mcp.h"
volatile int n;
const int k = 3;
void inc(volatile int *p)
{
int i;
for(i=0; i<k; i++)
{
(*p)++;
mcp_yield();
}
}
void dec(volatile int *p)
{
int i;
for(i=0; i<k; i++)
{
(*p)--;
mcp_yield();
}
}
int main()
{
n = 0;
if(mcp_fork(1))
{
inc(&n);
return 0;
}
if(mcp_fork(2))
{
dec(&n);
return 0;
}
printf("Result: n = %d\n", n);
return 0;
}
---------------------------------------------------
llvm-dis output:
ModuleID = 'incdec.bc'
target endian = little
target pointersize = 32
target triple = "i686-pc-linux-gnu"
deplibs = [ "stdc++", "c", "crtend" ]
%.str_1 = internal constant [16 x sbyte] c"Result: n = %d\0A\00" ; <[16
x sbyte]*> [#uses=1]
implementation ; Functions:
declare int %printf(sbyte*, ...)
declare void %mcp_yield()
int %main() {
entry:
%tmp.0 = tail call bool %mcp_fork( ulong 1 ) ; <bool> [#uses=1]
br bool %tmp.0, label %_Z3incPVi.exit, label %endif.0
_Z3incPVi.exit: ; preds = %entry
tail call void %mcp_yield( )
tail call void %mcp_yield( )
tail call void %mcp_yield( )
ret int 0
endif.0: ; preds = %entry
%tmp.1 = tail call bool %mcp_fork( ulong 2 ) ; <bool> [#uses=1]
br bool %tmp.1, label %_Z3decPVi.exit, label %endif.1
_Z3decPVi.exit: ; preds = %endif.0
tail call void %mcp_yield( )
tail call void %mcp_yield( )
tail call void %mcp_yield( )
ret int 0
endif.1: ; preds = %endif.0
%tmp.2 = tail call int (sbyte*, ...)* %printf( sbyte* getelementptr
([16 x sbyte]* %.str_1, int 0, int 0), int 0 ) ; <int> [#uses=0]
ret int 0
}
declare bool %mcp_fork(ulong)
More information about the llvm-dev
mailing list