Improve optimization inside iotile-sgcompile
- Dominant language
- Python
- Stars
- 14
- Forks
- 7
- PR merge metrics
- No merged PRs in 30d
Description
There are some important sgf files that are not currently well optimized by `iotile-sgcompile`. In particular, the intermediate node elimination optimization is too restrictive and misses several opportunities to do so.
### Example SGF
```
on input 1
{
copy => output 32;
}
on value(system input 1538) == 0
{
copy => constant 1;
call 0x8035 on slot 2;
call 0x200e on controller;
}
on value(system input 1538) == 1
{
copy => constant 1;
call 0x8036 on slot 2;
call 0x200e on controller;
}
on system input 1024 and value(constant 1) == 1
{
call 0x8036 on slot 2;
}
when value(constant 1) == 1
{
every 1 tick_1
{
call 0x8000 on slot 4;
call 0x8003 on slot 4 => output 34;
call 0x8002 on slot 4 => output 33;
call 0x8001 on slot 4 => output 35;
# Also trigger a vibration capture
call 0x8034 on slot 2;
}
}
when connected to controller
{
every 1 second
{
call 0x8003 on slot 2 => unbuffered 18;
call 0x8000 on slot 4;
call 0x8003 on slot 4 => unbuffered 15;
call 0x8002 on slot 4 => unbuffered 22;
call 0x8001 on slot 4 => unbuffered 25;
}
}
manual streamer on all outputs;
manual streamer on all system outputs with streamer 0;
manual streamer on all system buffered with streamer 0;
realtime streamer on unbuffered 18;
realtime streamer on unbuffered 15;
realtime streamer on unbuffered 22;
realtime streamer on unbuffered 25;
```
This turns into:
```
(system input 3 always) => counter 1025 using copy_latest_a
(system input 5 always) => counter 1026 using copy_latest_a
(input 1 always) => unbuffered 1024 using copy_latest_a
(system input 1538 when value == 0) => unbuffered 1025 using copy_latest_a
(system input 1538 when value == 1) => unbuffered 1028 using copy_latest_a
(system input 1024 always) => unbuffered 1032 using copy_latest_a
(system input 1025 always) => unbuffered 1037 using copy_latest_a
(system input 1026 always) => unbuffered 1038 using copy_latest_a
(unbuffered 1024 always) => output 32 using copy_latest_a
(unbuffered 1025 always) => constant 1 using copy_latest_a
(unbuffered 1025 when count == 1 && constant 1024 always) => unbuffered 1026 using call_rpc
(unbuffered 1025 when count == 1 && constant 1025 always) => unbuffered 1027 using call_rpc
(unbuffered 1028 always) => constant 1 using copy_latest_a
(unbuffered 1028 when count == 1 && constant 1026 always) => unbuffered 1029 using call_rpc
(unbuffered 1028 when count == 1 && constant 1027 always) => unbuffered 1030 using call_rpc
(constant 1036 always && unbuffered 1037 when value == 8) => constant 1035 using copy_latest_a
(constant 1037 always && unbuffered 1038 when value == 8) => constant 1035 using copy_latest_a
(unbuffered 1032 always && constant 1 when value == 1) => unbuffered 1031 using copy_latest_a
(counter 1026 always && constant 1 when value == 1) => counter 1028 using copy_latest_a
(counter 1025 always && constant 1035 when value == 1) => counter 1031 using copy_latest_a
(unbuffered 1031 when count == 1 && constant 1028 always) => unbuffered 1034 using call_rpc
(counter 1028 when count >= 1 && constant 1030 always) => unbuffered 1035 using call_rpc
(counter 1028 when count >= 1 && constant 1031 always) => output 34 using call_rpc
(counter 1028 when count >= 1 && constant 1032 always) => output 33 using call_rpc
(counter 1028 when count >= 1) => counter 1030 using copy_latest_a
(counter 1031 when count >= 1 && constant 1039 always) => unbuffered 18 using call_rpc
(counter 1031 when count >= 1 && constant 1040 always) => unbuffered 1039 using call_rpc
(counter 1031 when count >= 1 && constant 1041 always) => unbuffered 15 using call_rpc
(counter 1031 when count >= 1) => counter 1033 using copy_latest_a
(counter 1030 when count == 1 && constant 1033 always) => output 35 using call_rpc
(counter 1030 when count == 1 && constant 1034 always) => unbuffered 1036 using call_rpc
(counter 1033 when count == 1 && constant 1042 always) => unbuffered 22 using call_rpc
(counter 1033 when count == 1 && constant 1043 always) => unbuffered 25 using call_rpc
```
Look at the edge (for example):
```
(system input 3 always) => counter 1025 using copy_latest_a
(counter 1025 always && constant 1035 when value == 1) => counter 1031 using copy_latest_a
```
This could be expressed as a single node but the optimizer does not because it doesn't know that it can downgrade a counter to an unbuffered when the condition is always and it doesn't know that it's safe to combine a node into an input node if the second input is a constant.
There are issues if the second input is connected to another node which is why the optimizer doesn't always perform this operation. In this case, doing the safe optimizations could free up 10-15% of the available node space at least.
Contributor guide
Assessment
This issue has not been assessed yet.