The cmm pipeline may generate redundant cmm locals for the wasm32 target
One example is the cmm_sink_sp
test case, containing the following .cmm
code:
#include "Cmm.h"
stg_sink_things ( P_ x1 )
{
W_ res;
W_ x2, x3, x4, x5, x6;
// Should produce a series of loads that are sunk into
// stores to Sp like this:
// I64[Sp - 64] = I64[R1 + 1]; // CmmStore
// I64[Sp - 56] = I64[R1 + 2]; // CmmStore
x2 = W_[x1+4];
x3 = W_[x1+8];
x4 = W_[x1+12];
x5 = W_[x1+16];
x6 = W_[x1+20];
W_[Sp - 8] = x2;
W_[Sp - 16] = x3;
W_[Sp - 24] = x4;
W_[Sp - 32] = x5;
W_[Sp - 40] = x6;
return (x1);
}
When compiled with -O
, the cmm dump looks like:
==================== Output Cmm ====================
[stg_sink_things() { // [R1]
{ info_tbls: []
stack_info: arg_space: 8
}
{offset
_lbl_: // global
//tick src<cmm_sink_sp.cmm:(4,1)-(24,1)>
//tick src<cmm_sink_sp.cmm:12:8-22>
//tick src<cmm_sink_sp.cmm:13:8-22>
//tick src<cmm_sink_sp.cmm:14:8-23>
//tick src<cmm_sink_sp.cmm:15:8-23>
//tick src<cmm_sink_sp.cmm:16:8-23>
//tick src<cmm_sink_sp.cmm:17:11-24>
I64[Sp - 8] = I64[R1 + 4]; // CmmStore
//tick src<cmm_sink_sp.cmm:18:11-25>
I64[Sp - 16] = I64[R1 + 8]; // CmmStore
//tick src<cmm_sink_sp.cmm:19:11-25>
I64[Sp - 24] = I64[R1 + 12]; // CmmStore
//tick src<cmm_sink_sp.cmm:20:11-25>
I64[Sp - 32] = I64[R1 + 16]; // CmmStore
//tick src<cmm_sink_sp.cmm:21:11-25>
I64[Sp - 40] = I64[R1 + 20]; // CmmStore
call (P64[Sp])(R1) args: 8, res: 0, upd: 8; // CmmCall
}
}]
However, for wasm32
target, it produces cmm that contains a redundant cmm local:
==================== Output Cmm ====================
[stg_sink_things() { // [R1]
{ info_tbls: []
stack_info: arg_space: 0
}
{offset
_lbl_: // global
//tick src<cmm_sink_sp.cmm:(4,1)-(24,1)>
//tick src<cmm_sink_sp.cmm:12:8-22>
//tick src<cmm_sink_sp.cmm:13:8-22>
//tick src<cmm_sink_sp.cmm:14:8-23>
//tick src<cmm_sink_sp.cmm:15:8-23>
//tick src<cmm_sink_sp.cmm:16:8-23>
//tick src<cmm_sink_sp.cmm:17:11-24>
__locVar_::P32 = R1;
I32[Sp - 8] = I32[__locVar_::P32 + 4];
//tick src<cmm_sink_sp.cmm:18:11-25>
I32[Sp - 16] = I32[__locVar_::P32 + 8];
//tick src<cmm_sink_sp.cmm:19:11-25>
I32[Sp - 24] = I32[__locVar_::P32 + 12];
//tick src<cmm_sink_sp.cmm:20:11-25>
I32[Sp - 32] = I32[__locVar_::P32 + 16];
//tick src<cmm_sink_sp.cmm:21:11-25>
I32[Sp - 40] = I32[__locVar_::P32 + 20];
R1 = __locVar_::P32;
call (I32[P32[Sp]])(R1) args: 4, res: 0, upd: 4;
}
}]
This doesn't affect correctness of output code, but it still bothers me, since the parts of cmm pipeline before the NCG backend should be more or less target independent, and it doesn't ring me a quick bell why it would generate code like this for wasm32
.