clarenceleo's picture
Add IR (intermediate representation) system - ir.h and ir.c
e151452 verified
Raw
History Blame Contribute Delete
6.83 kB
/*
* par2serial-cc: ir.h - Three-address code Intermediate Representation
* Designed for optimization passes: parallel detection, vectorization, tiling
*/
#ifndef P2S_IR_H
#define P2S_IR_H
#include "ast.h"
/* ── IR Operation Codes ──────────────────────────────────── */
typedef enum {
/* Arithmetic */
IR_ADD, IR_SUB, IR_MUL, IR_DIV, IR_MOD,
IR_NEG,
IR_FADD, IR_FSUB, IR_FMUL, IR_FDIV, /* float variants */
/* Bitwise */
IR_AND, IR_OR, IR_XOR, IR_NOT,
IR_SHL, IR_SHR,
/* Comparison */
IR_EQ, IR_NE, IR_LT, IR_GT, IR_LE, IR_GE,
IR_FEQ, IR_FNE, IR_FLT, IR_FGT, IR_FLE, IR_FGE,
/* Data movement */
IR_LOAD, /* dst = *src (memory load) */
IR_STORE, /* *dst = src (memory store) */
IR_MOVE, /* dst = src */
IR_LOAD_IMM, /* dst = immediate */
IR_LOAD_FIMM, /* dst = float immediate */
IR_LOAD_ADDR, /* dst = &var */
IR_INDEX, /* dst = base + idx * stride */
/* Control flow */
IR_LABEL,
IR_JUMP,
IR_BRANCH, /* if cond goto label */
IR_BRANCH_FALSE, /* if !cond goto label */
IR_CALL, /* dst = call func(args) */
IR_RET, /* return val */
/* Type conversion */
IR_INT_TO_FLOAT,
IR_FLOAT_TO_INT,
IR_WIDEN, /* sign/zero extend */
IR_NARROW, /* truncate */
/* Parallel constructs (high-level, lowered by optimization passes) */
IR_PAR_FOR_BEGIN, /* marks start of parallel for */
IR_PAR_FOR_END, /* marks end */
IR_PAR_REDUCE_BEGIN, /* marks start of reduction */
IR_PAR_REDUCE_END,
IR_PAR_SCAN_BEGIN,
IR_PAR_SCAN_END,
IR_BARRIER, /* synchronization barrier */
IR_ATOMIC_ADD, /* atomic add */
/* SIMD operations (inserted by vectorization pass) */
IR_SIMD_LOAD, /* vdst = simd_load(addr) */
IR_SIMD_STORE, /* simd_store(addr, vsrc) */
IR_SIMD_BROADCAST, /* vdst = broadcast(scalar) */
IR_SIMD_ADD, /* vdst = vadd(va, vb) */
IR_SIMD_SUB,
IR_SIMD_MUL,
IR_SIMD_FMA, /* vdst = fma(va, vb, vc) */
IR_SIMD_HADD, /* horizontal add (reduction) */
IR_SIMD_MIN,
IR_SIMD_MAX,
/* Memory operations */
IR_PREFETCH, /* prefetch hint */
IR_ALLOCA, /* stack allocation */
/* Special */
IR_NOP,
IR_PHI, /* SSA phi node */
IR_COMMENT, /* optimization annotation */
IR_OP_COUNT
} IROp;
/* ── IR Value (virtual register or constant) ─────────────── */
typedef enum {
VAL_REG, /* virtual register %t0, %t1, ... */
VAL_INT, /* integer constant */
VAL_FLOAT, /* float constant */
VAL_LABEL, /* label reference */
VAL_NAME, /* named variable/function */
VAL_NONE, /* no value */
} IRValKind;
typedef struct {
IRValKind kind;
union {
int reg; /* register number */
int64_t int_val;
double float_val;
int label_id;
const char *name;
};
/* type info */
TypeKind type; /* data type of this value */
int simd_width; /* 0 = scalar, 4/8/16 = SIMD lanes */
} IRValue;
/* ── IR Instruction ──────────────────────────────────────── */
typedef struct IRInst {
IROp op;
IRValue dst; /* destination */
IRValue src1; /* first operand */
IRValue src2; /* second operand */
IRValue src3; /* third operand (FMA, etc) */
SourceLoc loc; /* source location for diagnostics */
/* Parallel metadata */
struct {
const char *iter_var;
int lo_reg; /* register holding loop bound */
int hi_reg;
int step_reg;
ReduceOp reduce_op;
int accum_reg;
} par;
/* Annotations */
const char *comment;
int label_id; /* for IR_LABEL */
struct IRInst *next;
struct IRInst *prev;
} IRInst;
VEC_TYPEDEF(IRInst*, IRInstVec);
/* ── IR Basic Block ──────────────────────────────────────── */
typedef struct IRBlock {
int id;
const char *name;
IRInstVec insts;
struct IRBlock *next; /* linked list */
/* CFG edges */
struct IRBlock *succ[2]; /* successors (branch: [true, false]) */
struct IRBlock **preds;
int pred_count;
/* Loop info (filled by analysis) */
bool is_loop_header;
int loop_depth;
struct IRBlock *loop_latch;
} IRBlock;
VEC_TYPEDEF(IRBlock*, IRBlockVec);
/* ── IR Function ─────────────────────────────────────────── */
typedef struct IRFunc {
const char *name;
IRBlockVec blocks;
int reg_count; /* next register number */
int label_count; /* next label number */
int param_count;
TypeKind return_type;
struct IRFunc *next;
} IRFunc;
/* ── IR Module (compilation unit) ────────────────────────── */
typedef struct {
Arena *arena;
IRFunc *functions; /* linked list */
int func_count;
/* Global declarations (passed through) */
NodeVec preproc_lines; /* #include, #define, etc */
NodeVec global_vars; /* global variable declarations */
} IRModule;
/* ── IR Builder API ──────────────────────────────────────── */
IRModule *ir_module_create(Arena *arena);
IRFunc *ir_func_create(IRModule *mod, const char *name);
IRBlock *ir_block_create(IRFunc *func, const char *name);
/* Value constructors */
IRValue ir_reg(int reg, TypeKind type);
IRValue ir_int(int64_t val);
IRValue ir_float(double val);
IRValue ir_label(int id);
IRValue ir_name(const char *name);
IRValue ir_none(void);
IRValue ir_simd_reg(int reg, TypeKind type, int width);
/* Instruction emission */
int ir_new_reg(IRFunc *func);
int ir_new_label(IRFunc *func);
IRInst *ir_emit(Arena *arena, IRBlock *bb, IROp op,
IRValue dst, IRValue src1, IRValue src2);
IRInst *ir_emit_comment(Arena *arena, IRBlock *bb, const char *comment);
/* AST → IR lowering */
IRModule *ir_build_from_ast(Arena *arena, ASTNode *program);
/* IR printing */
void ir_print_module(IRModule *mod);
void ir_print_value(IRValue v);
const char *ir_op_name(IROp op);
#endif /* P2S_IR_H */