Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use ph1_ir? #174

Open
AW-AlanWu opened this issue Dec 17, 2024 · 5 comments
Open

How to use ph1_ir? #174

AW-AlanWu opened this issue Dec 17, 2024 · 5 comments

Comments

@AW-AlanWu
Copy link
Contributor

AW-AlanWu commented Dec 17, 2024

I would like to ask how to use ph1_ir. The documentation and examples for the ph1_ir opcode enum, as well as the related operations add_global_ir, add_ph1_ir, and add_insn are quite limited, which makes it difficult for me to understand how to get started.

Could someone kindly provide some guidance or examples on how to properly use ph1_ir?

Any help would be greatly appreciated! Thank you!

@vacantron
Copy link
Collaborator

The ph1_ir-related functionality, such as add_ph1_ir(), had been deprecated, but it still be preserved for the backward compatibility of @ChAoSUnItY 's work. Use add_insn() to build the IR instead.

@AW-AlanWu
Copy link
Contributor Author

@vacantron
Thank you for response! It was very helpful.
I have one more question, if you don't mind:
What do the parameters of add_insn represent? Specifically, I’m unsure how to place operands for certain opcodes like OP_allocat and OP_global_address_of. And What do the int sz and char *str parameters in add_insn mean for operands?
Finally, where in the source code would be the best place to explore the IR specifications?

@vacantron
Copy link
Collaborator

What do the parameters of add_insn represent? Specifically, I’m unsure how to place operands for certain opcodes like OP_allocat and OP_global_address_of. And What do the int sz and char *str parameters in add_insn mean for operands?

The most arguments of add_insn are same as the operands of RISC operations. In other word, there are two source operands and one destination operand. Some of operators in shecc is the pseudo instruction such as OP_define, OP_allocat, OP_address_of or control flow operator using some of those fields.

  • OP_allocat takes only destination operand and is the operation to tell the codegen to reserve the stack space of a variable.
  • OP_global_address_of is only used in register allocation since the allcator is going to detect whether the variable of OP_address_of operator is a local or a global variable.
  • int sz is used to record the length (in byte) of a variable in load/store instructions.
  • char *str stores the name of a function and is used when dumping the IRs.

Finally, where in the source code would be the best place to explore the IR specifications?

I think you could check this out, since the two stages IR had been deprecated.

@DrXiao
Copy link
Collaborator

DrXiao commented Dec 20, 2024

  • int sz is used to record the length (in byte) of a variable in load/store instructions.

If struct insn has this member to generate load/store instructions, then I am concerned about the current implementation of the backends.

For example, in Arm backend (arm-codegen.c), we can notice that it will generate either ldrb or ldr instructions for OP_read through the field (ph2_ir->src1), whose value is assigned by reg_alloc() (reg-alloc.c - Line 468).

But for OP_load (or OP_global_load), shecc always generates ldr only and lacks of consideration of the data size.

I think it may be a fault in the implementation?

@vacantron
Copy link
Collaborator

But for OP_load (or OP_global_load), shecc always generates ldr only and lacks of consideration of the data size.

The members in a structure have been aligned, and we could simply use the ldst instruction to get its members.

shecc/src/reg-alloc.c

Lines 360 to 389 in 07adb41

case OP_allocat:
if ((!strcmp(insn->rd->type_name, "void") ||
!strcmp(insn->rd->type_name, "int") ||
!strcmp(insn->rd->type_name, "char") ||
!strcmp(insn->rd->type_name, "_Bool")) &&
insn->rd->array_size == 0)
break;
insn->rd->offset = fn->func->stack_size;
fn->func->stack_size += PTR_SIZE;
src0 = fn->func->stack_size;
if (insn->rd->is_ptr)
sz = PTR_SIZE;
else {
type_t *type = find_type(insn->rd->type_name, 0);
sz = type->size;
}
if (insn->rd->array_size)
fn->func->stack_size +=
align_size(insn->rd->array_size * sz);
else
fn->func->stack_size += align_size(sz);
dest = prepare_dest(bb, insn->rd, -1, -1);
ir = bb_add_ph2_ir(bb, OP_address_of);
ir->src0 = src0;
ir->dest = dest;
break;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants