Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/arch-lower.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* shecc - Architecture-specific IR lowering stage
*
* Introduces a minimal arch-lowering boundary that applies target-specific
* tweaks to phase-2 IR (ph2_ir) before final code generation. This keeps
* backends simpler by moving decisions that depend on CFG shape or target
* quirks out of emit-time where possible.
*/

#include "../config"
#include "defs.h"

/* ARM-specific lowering:
* - Mark detached conditional branches so codegen can decide between
* short/long forms without re-deriving CFG shape.
*/
void arm_lower(void)
{
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
for (basic_block_t *bb = func->bbs; bb; bb = bb->rpo_next) {
for (ph2_ir_t *insn = bb->ph2_ir_list.head; insn;
insn = insn->next) {
/* Mark branches that don't fall through to next block */
if (insn->op == OP_branch) {
/* In SSA, we index 'else_bb' first, and then 'then_bb' */
insn->is_branch_detached = (insn->else_bb != bb->rpo_next);
}
}
}
}
}

/* RISC-V-specific lowering:
* - Mark detached conditional branches
* - Future: prepare for RISC-V specific patterns
*/
void riscv_lower(void)
{
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
for (basic_block_t *bb = func->bbs; bb; bb = bb->rpo_next) {
for (ph2_ir_t *insn = bb->ph2_ir_list.head; insn;
insn = insn->next) {
/* Mark branches that don't fall through to next block */
if (insn->op == OP_branch)
insn->is_branch_detached = (insn->else_bb != bb->rpo_next);
}
}
}
}

/* Entry point: dispatch to the active architecture. */
void arch_lower(void)
{
#if ELF_MACHINE == 0x28 /* ARM */
arm_lower();
#elif ELF_MACHINE == 0xf3 /* RISC-V */
riscv_lower();
#else
/* Unknown architecture: keep behavior as-is. */
(void) 0;
#endif
}
6 changes: 1 addition & 5 deletions src/arm-codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,7 @@ void cfg_flatten(void)
flatten_ir->src1 = bb->belong_to->stack_size;
}

if (insn->op == OP_branch) {
/* In SSA, we index 'else_bb' first, and then 'then_bb' */
if (insn->else_bb != bb->rpo_next)
flatten_ir->is_branch_detached = true;
}
/* Branch detachment is determined in the arch-lowering stage */

update_elf_offset(flatten_ir);
}
Expand Down
3 changes: 3 additions & 0 deletions src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,9 @@ ph2_ir_t *add_ph2_ir(opcode_t op)
{
ph2_ir_t *ph2_ir = arena_alloc(BB_ARENA, sizeof(ph2_ir_t));
ph2_ir->op = op;
/* Set safe defaults; arch-lowering may annotate later */
ph2_ir->next = NULL;
ph2_ir->is_branch_detached = 0;
return add_existed_ph2_ir(ph2_ir);
}

Expand Down
6 changes: 6 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
/* Peephole optimization */
#include "peephole.c"

/* Arch-specific IR lowering boundary */
#include "arch-lower.c"

/* Machine code generation. support ARMv7-A and RV32I */
#include "codegen.c"

Expand Down Expand Up @@ -103,6 +106,9 @@ int main(int argc, char *argv[])

peephole();

/* Apply arch-specific IR tweaks before final codegen */
arch_lower();

/* flatten CFG to linear instruction */
cfg_flatten();

Expand Down
3 changes: 3 additions & 0 deletions src/reg-alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ ph2_ir_t *bb_add_ph2_ir(basic_block_t *bb, opcode_t op)
{
ph2_ir_t *n = arena_alloc(BB_ARENA, sizeof(ph2_ir_t));
n->op = op;
/* Ensure deterministic defaults for newly created IR nodes */
n->next = NULL; /* well-formed singly linked list */
n->is_branch_detached = 0; /* arch-lowering will set for branches */

if (!bb->ph2_ir_list.head)
bb->ph2_ir_list.head = n;
Expand Down