Selector thunk confusion -- codegen not generating selectors when it should
Not sure if this is a bug or not, but something interesting regarding selector thunk generation.
This closure uses a standard selector thunk info table in the generated code:
data T = T Integer Integer
selector :: T -> Maybe Integer
selector p = Just (case p of T x y -> x)
Cmm:
[Test.selector_entry() { // [R2]
{ info_tbls: [(cp9,
label: Test.selector_info
rep: HeapRep static { Fun {arity: 1 fun_type: ArgSpec 5} }
srt: Nothing)]
stack_info: arg_space: 8 updfr_space: Just 8
}
{offset
cp9: // global
Hp = Hp + 40;
if (Hp > HpLim) (likely: False) goto cpd; else goto cpc;
cpd: // global
HpAlloc = 40;
R2 = R2;
R1 = Test.selector_closure;
call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;
cpc: // global
I64[Hp - 32] = stg_sel_0_upd_info;
P64[Hp - 16] = R2;
I64[Hp - 8] = GHC.Maybe.Just_con_info;
P64[Hp] = Hp - 32;
R1 = Hp - 6;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
}
},
section ""data" . Test.selector_closure" {
Test.selector_closure:
const Test.selector_info;
}]
This is as expected. However this closure with the same expression:
not_selector = case t of T a b -> a
does not use a standard thunk info table:
[Test.not_selector_entry() { // [R1]
{ info_tbls: [(cps,
label: Test.not_selector_info
rep: HeapRep static { Thunk }
srt: Nothing)]
stack_info: arg_space: 8 updfr_space: Just 8
}
{offset
cps: // global
if ((Sp + -16) < SpLim) (likely: False) goto cpt; else goto cpu;
cpt: // global
R1 = R1;
call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8;
cpu: // global
(_cpo::I64) = call "ccall" arg hints: [PtrHint,
PtrHint] result hints: [PtrHint] newCAF(BaseReg, R1);
if (_cpo::I64 == 0) goto cpq; else goto cpp;
cpq: // global
call (I64[R1])() args: 8, res: 0, upd: 8;
cpp: // global
I64[Sp - 16] = stg_bh_upd_frame_info;
I64[Sp - 8] = _cpo::I64;
R1 = P64[Test.t_closure+8] & (-8);
Sp = Sp - 16;
call (I64[R1])(R1) args: 24, res: 0, upd: 24;
}
},
section ""data" . Test.not_selector_closure" {
Test.not_selector_closure:
const Test.not_selector_info;
const 0;
const 0;
const 0;
}]
Using the standard selector thunks we could generate this for not_selector_closure
:
[section ""data" . Test.not_selector_closure" {
Test.not_selector_closure:
const stg_sel_0_upd_info;
const 0; // padding for thunk updates
const Main.t_closure; // selectee
...
}]
and avoid generating code for it. This would make code smaller.