| |
| |
| |
| |
| #ifndef P2S_IR_H |
| #define P2S_IR_H |
|
|
| #include "ast.h" |
|
|
| |
| typedef enum { |
| |
| IR_ADD, IR_SUB, IR_MUL, IR_DIV, IR_MOD, |
| IR_NEG, |
| IR_FADD, IR_FSUB, IR_FMUL, IR_FDIV, |
|
|
| |
| IR_AND, IR_OR, IR_XOR, IR_NOT, |
| IR_SHL, IR_SHR, |
|
|
| |
| IR_EQ, IR_NE, IR_LT, IR_GT, IR_LE, IR_GE, |
| IR_FEQ, IR_FNE, IR_FLT, IR_FGT, IR_FLE, IR_FGE, |
|
|
| |
| IR_LOAD, |
| IR_STORE, |
| IR_MOVE, |
| IR_LOAD_IMM, |
| IR_LOAD_FIMM, |
| IR_LOAD_ADDR, |
| IR_INDEX, |
|
|
| |
| IR_LABEL, |
| IR_JUMP, |
| IR_BRANCH, |
| IR_BRANCH_FALSE, |
| IR_CALL, |
| IR_RET, |
|
|
| |
| IR_INT_TO_FLOAT, |
| IR_FLOAT_TO_INT, |
| IR_WIDEN, |
| IR_NARROW, |
|
|
| |
| IR_PAR_FOR_BEGIN, |
| IR_PAR_FOR_END, |
| IR_PAR_REDUCE_BEGIN, |
| IR_PAR_REDUCE_END, |
| IR_PAR_SCAN_BEGIN, |
| IR_PAR_SCAN_END, |
| IR_BARRIER, |
| IR_ATOMIC_ADD, |
|
|
| |
| IR_SIMD_LOAD, |
| IR_SIMD_STORE, |
| IR_SIMD_BROADCAST, |
| IR_SIMD_ADD, |
| IR_SIMD_SUB, |
| IR_SIMD_MUL, |
| IR_SIMD_FMA, |
| IR_SIMD_HADD, |
| IR_SIMD_MIN, |
| IR_SIMD_MAX, |
|
|
| |
| IR_PREFETCH, |
| IR_ALLOCA, |
|
|
| |
| IR_NOP, |
| IR_PHI, |
| IR_COMMENT, |
|
|
| IR_OP_COUNT |
| } IROp; |
|
|
| |
| typedef enum { |
| VAL_REG, |
| VAL_INT, |
| VAL_FLOAT, |
| VAL_LABEL, |
| VAL_NAME, |
| VAL_NONE, |
| } IRValKind; |
|
|
| typedef struct { |
| IRValKind kind; |
| union { |
| int reg; |
| int64_t int_val; |
| double float_val; |
| int label_id; |
| const char *name; |
| }; |
| |
| TypeKind type; |
| int simd_width; |
| } IRValue; |
|
|
| |
| typedef struct IRInst { |
| IROp op; |
| IRValue dst; |
| IRValue src1; |
| IRValue src2; |
| IRValue src3; |
| SourceLoc loc; |
|
|
| |
| struct { |
| const char *iter_var; |
| int lo_reg; |
| int hi_reg; |
| int step_reg; |
| ReduceOp reduce_op; |
| int accum_reg; |
| } par; |
|
|
| |
| const char *comment; |
| int label_id; |
|
|
| struct IRInst *next; |
| struct IRInst *prev; |
| } IRInst; |
|
|
| VEC_TYPEDEF(IRInst*, IRInstVec); |
|
|
| |
| typedef struct IRBlock { |
| int id; |
| const char *name; |
| IRInstVec insts; |
| struct IRBlock *next; |
|
|
| |
| struct IRBlock *succ[2]; |
| struct IRBlock **preds; |
| int pred_count; |
|
|
| |
| bool is_loop_header; |
| int loop_depth; |
| struct IRBlock *loop_latch; |
| } IRBlock; |
|
|
| VEC_TYPEDEF(IRBlock*, IRBlockVec); |
|
|
| |
| typedef struct IRFunc { |
| const char *name; |
| IRBlockVec blocks; |
| int reg_count; |
| int label_count; |
| int param_count; |
| TypeKind return_type; |
| struct IRFunc *next; |
| } IRFunc; |
|
|
| |
| typedef struct { |
| Arena *arena; |
| IRFunc *functions; |
| int func_count; |
|
|
| |
| NodeVec preproc_lines; |
| NodeVec global_vars; |
| } IRModule; |
|
|
| |
| IRModule *ir_module_create(Arena *arena); |
| IRFunc *ir_func_create(IRModule *mod, const char *name); |
| IRBlock *ir_block_create(IRFunc *func, const char *name); |
|
|
| |
| 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); |
|
|
| |
| 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); |
|
|
| |
| IRModule *ir_build_from_ast(Arena *arena, ASTNode *program); |
|
|
| |
| void ir_print_module(IRModule *mod); |
| void ir_print_value(IRValue v); |
| const char *ir_op_name(IROp op); |
|
|
| #endif |
|
|