[qfcc] Don't dereference pointer for field access

As I suspected, the dereference was premature, although it can act as an
optimization when multiple fields of an object are accessed, though it
won't work for writes to lvalues (which means my fixes for spir-v
code-gen currently don't work for lvalue writes). Still, progress. Need
to get field member ids set.
This commit is contained in:
Bill Currie 2024-11-13 14:05:46 +09:00
parent fb58c1aace
commit 14f428a81d
2 changed files with 17 additions and 7 deletions

View file

@ -102,7 +102,6 @@ proc_field (const expr_t *expr)
if (is_reference (obj_type)) {
obj_type = dereference_type (obj_type);
object = pointer_deref (object);
}
if (is_class (obj_type)) {
@ -116,7 +115,6 @@ proc_field (const expr_t *expr)
|| is_class (ref_type))) {
return type_mismatch (object, member, '.');
}
object = pointer_deref (object);
obj_type = ref_type;
}
if (is_algebra (obj_type)) {

View file

@ -998,18 +998,19 @@ spirv_field (const expr_t *e, spirvctx_t *ctx)
auto base_type = get_type (e);
unsigned base_id = spirv_emit_expr (e, ctx);
int op = SpvOpCompositeExtract;
bool literal_ind = true;
if (is_pointer (base_type)) {
res_type = pointer_type (res_type);
auto acc_type = res_type;
bool literal_ind = true;
if (is_pointer (base_type) || is_reference (base_type)) {
acc_type = pointer_type (res_type);
op = SpvOpAccessChain;
literal_ind = false;
}
int tid = type_id (res_type, ctx);
int acc_type_id = type_id (acc_type, ctx);
int id = spirv_id (ctx);
auto insn = spirv_new_insn (op, 4 + num_fields, ctx->code_space);
INSN (insn, 1) = tid;
INSN (insn, 1) = acc_type_id;
INSN (insn, 2) = id;
INSN (insn, 3) = base_id;
auto field_ind = &INSN (insn, 4);
@ -1025,6 +1026,17 @@ spirv_field (const expr_t *e, spirvctx_t *ctx)
*field_ind++ = spirv_emit_expr (ind, ctx);
}
}
if (acc_type != res_type) {
// base is a pointer or reference so load the value
unsigned ptr_id = id;
int res_type_id = type_id (res_type, ctx);
id = spirv_id (ctx);
insn = spirv_new_insn (SpvOpLoad, 4, ctx->code_space);
INSN (insn, 1) = res_type_id;
INSN (insn, 2) = id;
INSN (insn, 3) = ptr_id;
}
return id;
}