Code: Select all
#include <syscall.h>
#include <platform.h>
#include <xs1.h>
#include <xclib.h>
#include <print.h>
#include "debug_print.h"
// Change either of these to 1 to avoid the issue.
#define USE_VARIABLE_BEFORE_SELECT 0 // Using the variable before the select is enough to cause it to not be optimised away.
#define LOGICAL_NOT_VARIABLE_EXPLICITLY 0 // Assigning a non-optimised-away value explicitly to the variable is enough to cause it to not be optimised away.
void Test(void)
{
timer tmr;
int t;
tmr :> t;
// Uninitialised variable.
unsigned variable;
#if USE_VARIABLE_BEFORE_SELECT
// Simply using the variable before the select is enough to cause it to not be optimised away.
debug_printf("Before Select: initial value of variable = 0x%x\n", variable);
variable = !variable;
debug_printf("Before Select: final value of variable = 0x%x\n", variable);
#endif
while (1)
{
select
{
case tmr when timerafter(t) :> int tmp:
{
// Come back in 1 second.
t += 100000000;
// Printing (reading) the variable is not enough to avoid it being optimised away.
debug_printf("In Select: initial value of variable = 0x%x\n", variable);
#if LOGICAL_NOT_VARIABLE_EXPLICITLY
// Toggling the variable explicitly within the select is enough to cause it to not be optimised away.
if (variable > 0)
{
variable = 0;
}
else
{
variable = 1;
}
#else
// Operating on the variable within select using only the variable as input is not enough to avoid the variable being optimised away.
variable = !variable;
#endif
debug_printf("In Select: final value of variable = 0x%x\n", variable);
}
break;
}
}
}
int main(void)
{
par
{
Test();
}
return 0;
}
Each time the timer fires, I would expect the variable to toggle between 0 and 1, no matter what value it started at, for an output like this:In Select: initial value of variable = 0x7FF7C
In Select: final value of variable = 0x0
In Select: initial value of variable = 0x1FFFFFF
In Select: final value of variable = 0x0
In Select: initial value of variable = 0x1FFFFFF
In Select: final value of variable = 0x0
In Select: initial value of variable = 0x1FFFFFF
In Select: final value of variable = 0x0
In Select: initial value of variable = 0x1FFFFFF
In Select: final value of variable = 0x0
In Select: initial value of variable = 0x1FFFFFF
In Select: final value of variable = 0x0
In Select: initial value of variable = 0x1FFFFFF
In Select: final value of variable = 0x0
Problem is, it seems the variable doesn't actually have its own reserved place in memory, and each time the timer fires, the variable reads as something other than what it was set to last time the timer fired.In Select: initial value of variable = 0x0
In Select: final value of variable = 0x1
In Select: initial value of variable = 0x1
In Select: final value of variable = 0x0
In Select: initial value of variable = 0x0
In Select: final value of variable = 0x1
In Select: initial value of variable = 0x1
In Select: final value of variable = 0x0
There are a number ways I've found to work around the issue:
1. Compiling with optimisation disabled.
2. Initialising the variable.
3. Using the variable outside of the select, even the same operation that doesn't work within select.
4. Assigning something to the variable other than something derived purely from the variable.
But, none of these should need to be done. Optimisation shouldn't affect the output of the program. Given that performing the same variable = !variable operation outside of the select is enough to cause the variable to be not optimised away, I would hope that that would also be enough if performed within the select. I welcome any comments, especially any suggestions from the folks at XMOS.