mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-07 01:42:04 +00:00
[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:
parent
fb58c1aace
commit
14f428a81d
2 changed files with 17 additions and 7 deletions
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue