sac2c issueshttps://gitlab.sac-home.org/sac-group/sac2c/-/issues2024-03-07T17:31:30Zhttps://gitlab.sac-home.org/sac-group/sac2c/-/issues/2390Towards a more lazy semantics2024-03-07T17:31:30ZSven-Bodo ScholzTowards a more lazy semanticsSeveral optimisations do perform redices that in a strict evaluation would never be executed.
A simple example is: `K (2, 3/0)`. Under a strict evaluation scheme it should not terminate / yield bottom; if we optimise this into `2`, this ...Several optimisations do perform redices that in a strict evaluation would never be executed.
A simple example is: `K (2, 3/0)`. Under a strict evaluation scheme it should not terminate / yield bottom; if we optimise this into `2`, this changes the semantics even though, under a normal order regime, this is fine.
Quite some discussion on this matter was done in the context of the merge request for URR:
https://gitlab.sac-home.org/sac-group/sac2c/-/merge_requests/285#note_13840
The question remains: how do we want to deal with this?https://gitlab.sac-home.org/sac-group/sac2c/-/issues/2366Virtual stack-trace of function applications2024-01-26T16:12:15ZJordy AalderingVirtual stack-trace of function applicationsWe want to keep track of a 'virtual' stack trace so that we can give the current trace if we encounter an error during run-time.
We return the arguments or return values to avoid code-reordering from messing with the location of these s...We want to keep track of a 'virtual' stack trace so that we can give the current trace if we encounter an error during run-time.
We return the arguments or return values to avoid code-reordering from messing with the location of these stack pushes and pops.
```
x1', .., xn' = _virtual_stack_push_ (x1, .., xn, "foo signature");
res1, .., resm = foo (x1', .., xn');
res1', .., resm' = _virtual_stack_pop_ (res1, .., resm);
```
Optionally, we might also be able to use this notation to construct a stack trace for compile time errors.
But that is something we should figure out in the future, first we must investigate whether this will even work as intended.
---
We might consider multiple tracing levels:
- No stack trace; used for performance-critical applications
- Trace user-defined function applications (even inlined ones); used for printing the stack trace of e.g. type checking, ecc, or type pattern errors
- Trace all function applications (even generated ones); useful for people debugging the compiler
For the two new function we might be able to reuse `NUMVARIABLERETS` and `CONTEXTSTRING` from the guard primitive.Jordy AalderingJordy Aalderinghttps://gitlab.sac-home.org/sac-group/sac2c/-/issues/2355Add DBUG_ASSERT variations to reduce duplicate code2023-11-21T22:08:07ZMichiel VerloopAdd DBUG_ASSERT variations to reduce duplicate codeMany functions start with a bunch of assertions, and rightly so. Making preconditions explicit in dbug_asserts is extremely helpful in stopping the propagation of bugs and conveying the intent to the reader. It is, however, quite repetit...Many functions start with a bunch of assertions, and rightly so. Making preconditions explicit in dbug_asserts is extremely helpful in stopping the propagation of bugs and conveying the intent to the reader. It is, however, quite repetitive. Consider the following, which I've taken from `WLUTupdateBoundNthDim`:
```
DBUG_ASSERT (bound != NULL, "bound may not be null!");
DBUG_ASSERT (*bound != NULL, "bound may not point to null!");
DBUG_ASSERT (NODE_TYPE (*bound) == N_array || NODE_TYPE (*bound) == N_id,
"bound must be an n_id or n_array but is \"%s\"!",
NODE_TEXT (*bound));
DBUG_ASSERT (new_scalar_avis != NULL, "new_scalar_avis may not be null!");
DBUG_ASSERT (vardecs != NULL, "Vardecs may not be null!");
DBUG_ASSERT (preassigns != NULL, "Preassigns may not be null!");
```
Frankly, I'm a bit tired of writing the same helpful debug messages over and over again.
Could we instead create some variations of the assertions to weed out most cases?
```
DBUG_ASSERT_NOT_NULL (bound, *bound, new_scalar_avis, vardecs, preassigns);
DBUG_ASSERT_NODE_IS_OF_TYPES (*bound, N_array, N_id);
```
This could still expand to give helpful messages as before, just now in an automatic manner.
Are the proposed variants feasible? What variants of DBUG_ASSERT should we make?https://gitlab.sac-home.org/sac-group/sac2c/-/issues/2241reallocation within outer loop (situation with livermore loop 8)2018-11-21T15:46:18ZHans-Nikolai Viessmannreallocation within outer loop (situation with livermore loop 8)The following example [reallocation-example.sac](/uploads/7bdd0534aae02881f8bd0b0b2437e9bd/reallocation-example.sac), performs some array scalar modification within a double loop nesting. The outer loop forces a repetition of the array m...The following example [reallocation-example.sac](/uploads/7bdd0534aae02881f8bd0b0b2437e9bd/reallocation-example.sac), performs some array scalar modification within a double loop nesting. The outer loop forces a repetition of the array modification which is happening in the inner loop. When we compile with flags `-DBODY -bmem`, we can see that for the outermost loop:
```
int[101] _MAIN::_dup_587_main__Loop_4( int{1} y { ,NN } , int[101] u1 { ,NN } , int i { ,NN } )
{
...
_emlr_6056_y = _alloc_( 1, _dim_A_( y), _shape_A_( y));
_emlr_6057_y = _fill_( _copy_( y), _emlr_6056_y);
_emlr_6054_u1 = _alloc_( 1, _dim_A_( u1), _shape_A_( u1));
_emlr_6055_u1 = _fill_( _copy_( u1), _emlr_6054_u1);
_pinl_588_u1n__SSA0_1 = _MAIN::_dup_589_main__Loop_2( u1, _emlr_6055_u1, _emlr_6057_y) ;
...
}
```
on each iteration we copy `u1` to `_emlr_6055_u1`, meaning on each iteration we create an additional allocation. We see this situation within the Livermore Loop 8 C variant, where we have a triple nesting of loops. Because we are in essence doing `a = op (a)` for the inner loop, we should be able to avoid the extra allocation by performing a buffer swap.
For the current example, this can be done manually be defining our inner loop operation as `b = op (a); a = b;`, where `b` is defined outside the outer loop. If we compile with `-DBODY -DLIFT -bmem`, we get:
```
int[101] _MAIN::_dup_587_main__Loop_4( int{1} y { ,NN } , int[101] u1 { ,NN } , int[101] u1n { ,NN } , int i { ,NN } )
{
...
_emlr_6056_y = _alloc_( 1, _dim_A_( y), _shape_A_( y));
_emlr_6057_y = _fill_( _copy_( y), _emlr_6056_y);
_emlr_6054_u1n = u1n;
_emlr_6055_u1n = _fill_( _noop_( u1n), _emlr_6054_u1n);
_pinl_588_u1n__SSA0_1 = _MAIN::_dup_589_main__Loop_2( u1, _emlr_6055_u1n, _emlr_6057_y) ;
...
}
```
No we no longer perform an allocation/copy, but pass in the extra buffer and reuse it within the outer loop.
It would be nice to do this automatically within the compiler. The attached example also shows a similar case with the inner loop occurring within a separate function. Here though the manual trick from above _does not_ work.https://gitlab.sac-home.org/sac-group/sac2c/-/issues/2224Slight name confusion on sac2c binaries2018-04-30T22:17:12ZRobert BerneckySlight name confusion on sac2c binariesThe DEBUG version of sac2c is called sac2c_d. This is good.
The RELEASE version of sac2c is called sac2c_p. This is bad. Presumably, it
meant PRODUCTION in the bad old days...
If we rename the RELEASE version to be sac2c_r, the name wil...The DEBUG version of sac2c is called sac2c_d. This is good.
The RELEASE version of sac2c is called sac2c_p. This is bad. Presumably, it
meant PRODUCTION in the bad old days...
If we rename the RELEASE version to be sac2c_r, the name will make more sense.