aboutsummaryrefslogtreecommitdiff
path: root/ssa.h
diff options
context:
space:
mode:
Diffstat (limited to 'ssa.h')
-rw-r--r--ssa.h167
1 files changed, 167 insertions, 0 deletions
diff --git a/ssa.h b/ssa.h
new file mode 100644
index 0000000..2ad86cd
--- /dev/null
+++ b/ssa.h
@@ -0,0 +1,167 @@
+#ifndef SSA_H
+#define SSA_H
+#include "const.h"
+#include "semantics.h"
+
+typedef struct CInst CInst;
+typedef CInst *CInst_t;
+
+typedef struct CRange CRange;
+typedef struct CRange *CRange_t;
+struct CRange {
+ int l, r; /* [l, r) */
+ CRange_t next;
+};
+
+typedef struct COpr COpr;
+typedef COpr *COpr_t;
+struct COpr {
+ enum {
+ VAR,
+ TMP,
+ IMM,
+ IMMS,
+ IMMF
+ } kind;
+ union {
+ CVar_t var;
+ CSList_t cstr;
+ char *str;
+ int imm;
+ } info;
+
+ int sub;
+ int dep;
+ int reg; /* -1 for spilled, -2 for discarded */
+ int begin, end; /* for reg allocation */
+ int mod;
+ CType_t type;
+ CInst_t def;
+ CRange_t range;
+ COpr_t par; /* union-find */
+ COpr_t cval;
+ COpr_t spill; /* check this reference if spilled */
+ COpr_t same; /* for common exp elimination */
+};
+
+typedef struct COList COList;
+typedef COList *COList_t;
+struct COList {
+ COpr_t opr;
+ COList_t next, prev;
+};
+
+void colist_remove(COList_t node);
+
+struct CInst {
+ enum OpCode {
+ BEQ = 0, /* conditional jump */
+ BNE = 1,
+ GOTO, /* unconditional jump */
+ ARR, /* displacement */
+ PUSH, /* push to stack top */
+ CALL, /* call function */
+ RET, /* return */
+ WARR,
+ MOVE,
+ LOAD, /* load from memory */
+ ADDR, /* get address */
+ MUL, DIV, MOD, ADD, SUB,
+ SHL, SHR, AND, XOR, OR, NOR,
+ EQ, NE, LT, GT, LE, GE,
+ NEG
+ } op;
+ COpr_t dest, src1, src2;
+ CInst_t next, prev;
+ CType_t wtype; /* for WARR */
+ int id;
+ int is_def;
+ int sysp;
+ int bret; /* for CALL */
+ int offset; /* for PUSH */
+};
+
+typedef struct CPhi CPhi;
+typedef CPhi *CPhi_t;
+struct CPhi {
+ COpr_t dest;
+ COpr_t *oprs;
+ CPhi_t next, prev;
+};
+
+typedef struct CBlock CBlock;
+typedef CBlock *CBlock_t;
+struct CBlock {
+ CPhi_t phis;
+ CInst_t insts; /* instructions */
+ CBlock_t next, prev;
+ int id;
+ int ref; /* if referenced by any gotos */
+ int pred; /* the number of predecessors */
+ int first, last;
+};
+
+typedef struct CBList CBList;
+typedef CBList *CBList_t;
+struct CBList {
+ CBlock_t cblk;
+ CBList_t next;
+};
+
+CBlock_t cblock_create(int inc);
+void cblock_append(CBlock_t cblk, CInst_t inst);
+void cblock_pappend(CBlock_t cblk, CPhi_t phi);
+CInst_t cblock_getback(CBlock_t cblk);
+int cblock_isempty(CBlock_t cblk);
+
+typedef struct CEdge CEdge;
+typedef struct CGraph {
+ struct CEdge {
+ CBlock *to;
+ CEdge *next;
+ } *head[MAX_BLOCK], *rhead[MAX_BLOCK];
+} CGraph;
+
+typedef struct CInterv {
+ COpr_t opr;
+ CRange_t range;
+} CInterv;
+
+typedef struct CENode CENode;
+typedef struct CExpMap {
+ struct CENode {
+ CInst_t exp;
+ CENode *next;
+ } *head[MAX_TABLE_SIZE];
+} CExpMap;
+typedef CExpMap *CExpMap_t;
+
+CExpMap_t cexpmap_create(void);
+CExpMap_t cexpmap_dup(CExpMap_t cem);
+unsigned int cexpmap_hash(CInst_t exp);
+int cexpmap_comp(CInst_t exp1, CInst_t exp2);
+void cexpmap_insert(CExpMap_t cem, CInst_t exp);
+CInst_t cexpmap_lookup(CExpMap_t cem, CInst_t exp);
+void cexpmap_clear(CExpMap_t cem);
+void cexpmap_destroy(CExpMap_t cem);
+
+typedef struct CFuncIR CFuncIR;
+typedef CFuncIR *CFuncIR_t;
+struct CFuncIR {
+ int gbbase;
+ CBlock_t entry;
+ COList_t defs;
+ CType_t func;
+ CFuncIR_t next;
+};
+
+void ssa_generate(int quiet);
+COpr_t cinterv_repr(COpr_t opr);
+void cinst_print(FILE *stream, CInst_t inst);
+int overlap_with_beg(COpr_t i, int beg);
+
+extern CFuncIR_t func_ir;
+extern const int avail_regs[];
+extern const int MAX_AVAIL_REGS;
+
+#endif