#ifndef IR_H #define IR_H #include "utils.h" #include "parser.h" struct _ir_node; struct _basic_block; struct symbol_def { struct _ir_node *node; bool is_lvalue; }; typedef struct { char *key; struct symbol_def *value; } symbol_table; // Basic block for CFG representation typedef struct _basic_block { int id; struct _ir_node *control; // Control node that starts this block (region, loop, proj, start) struct _ir_node **nodes; // Scheduled nodes in this block (stb_ds array) struct _basic_block **preds; // Predecessor blocks (stb_ds array) struct _basic_block **succs; // Successor blocks (stb_ds array) struct _basic_block *idom; // Immediate dominator struct _basic_block **dom_children; // Children in dominator tree (stb_ds array) int dom_depth; // Depth in dominator tree int loop_depth; // Loop nesting depth (for GCM optimization) bool visited; // For graph traversals } basic_block; // Function representation after GCM typedef struct { char *name; basic_block *entry; // Entry block basic_block **blocks; // All blocks in RPO order (stb_ds array) int block_count; } ir_function; typedef enum { OC_START, OC_ADD, OC_SUB, OC_MUL, OC_DIV, OC_MOD, OC_BAND, OC_BOR, OC_BXOR, OC_NEG, OC_EQ, OC_NEQ, OC_LT, OC_GT, OC_LE, OC_GE, OC_AND, OC_OR, OC_CONST_INT, OC_CONST_FLOAT, OC_VOID, OC_FRAME_PTR, OC_ADDR, OC_STORE, OC_LOAD, OC_REGION, OC_PHI, OC_IF, OC_PROJ, OC_LOOP, OC_CALL, OC_STOP, OC_RETURN, OC_SCOPE, } opcode; typedef struct _ir_node { opcode code; usize id; struct _ir_node **in; struct _ir_node **out; union { i64 const_int; f64 const_float; symbol_table **symbol_tables; char *start_name; char *call_name; } data; // GCM scheduling fields struct _basic_block *early; // Earliest legal block struct _basic_block *late; // Latest legal block struct _basic_block *block; // Final scheduled block bool pinned; // True if node must stay in its block (control nodes, phi, etc.) bool scheduled; // True if already scheduled } ir_node; void ir_build(ast_node *ast); // Global Code Motion and Scheduling ir_function *gcm_schedule(ir_node *func_start); void gcm_print_scheduled(ir_function *func); #endif