diff options
| author | 2026-03-17 13:22:00 +0100 | |
|---|---|---|
| committer | 2026-03-17 13:22:00 +0100 | |
| commit | a8d6f8bf30c07edb775e56889f568ca20240bedf (patch) | |
| tree | b5a452b2675b2400f15013617291fe6061180bbf /ir/ir.h | |
| parent | 24f14b7ad1af08d872971d72ce089a529911f657 (diff) | |
REFACTOR: move sources to src/
Diffstat (limited to 'ir/ir.h')
| -rw-r--r-- | ir/ir.h | 353 |
1 files changed, 0 insertions, 353 deletions
diff --git a/ir/ir.h b/ir/ir.h deleted file mode 100644 index ab3e474..0000000 --- a/ir/ir.h +++ /dev/null @@ -1,353 +0,0 @@ -#include "../common.h" -#include "../type.h" - -enum irclass { - KXXX, - KI32, KI64, KPTR, - KF32, KF64, -}; - -#define kisint(k) in_range((k), KI32, KPTR) -#define kisflt(k) in_range((k), KF32, KF64) - -union irtype { - struct { ushort _ : 1, cls : 15; }; - struct { ushort isagg : 1, dat : 15; }; - ushort bits; -}; - -struct irdat { - uchar align : 6, globl : 1; - uchar section; - union type ctype; - uint siz; - uint off; - internstr name; -}; - -enum symflags { - SLOCAL = 1, - SFUNC = 2, -}; -struct xcon { - bool issym, isdat, deref; - uchar cls; - uchar flag; - union { - internstr sym; - int dat; - vlong i; - double f; - }; -}; - -struct abiarg { - union irtype ty; - union { - struct { ushort _ : 1, reg : 15; }; - struct { ushort isstk : 1, stk : 15; }; - }; -}; - -struct call { - union irtype ret; - ushort narg; - short vararg; /* first variadic arg or -1 */ - ushort argstksiz; - struct abiarg *abiarg; - struct abiarg abiret[2]; - uchar r2off; -}; - -enum refkind { - RXXX, /* used for empty ref (zeros), undef, and the special args of call,phi,etc */ - RTMP, /* reference to another instruction's result */ - RREG, /* machine register */ - RICON, /* small integer constants */ - RXCON, /* other constants (incl. external symbols) */ - RADDR, /* target-specific addressing mode */ - RTYPE, /* irtype */ - RSTACK, /* stack base offset */ -}; - -union ref { - struct { unsigned t : 3; signed i : 29; }; - uint bits; -}; -static_assert(sizeof(union ref) == 4); - -struct addr { - union ref base, index; - int shift, disp; -}; - -#define insrescls(ins) (oiscmp((ins).op) ? KI32 : (ins).cls) -#define NOREF ((union ref) {0}) -#define UNDREF ((union ref) {{ 0, -1 }}) -#define ZEROREF ((union ref) {{ RICON, 0 }}) -#define mkref(t, x) ((union ref) {{ (t), (x) }}) -#define mktyperef(t) ((union ref) {{ RTYPE, (t).bits }}) -#define ref2type(r) ((union irtype) {.bits = (r).i}) -#define rswap(a,b) do { union ref _t = (a); (a) = (b); (b) = _t; } while (0) - -enum op { - Oxxx, -#define _(o,...) O##o, -#include "op.def" -#undef _ - NOPER, -}; - -#define oiscmp(o) in_range(o, Oequ, Ougte) -#define oisarith(o) in_range(o, Oneg, Ougte) -#define oisalloca(o) in_range(o, Oalloca1, Oalloca16) -#define oisstore(o) in_range(o, Ostorei8, Ostoref64) -#define oisload(o) in_range(o, Oloads8, Oloadf64) -extern const char *opnames[]; -extern const uchar opnarg[]; - -enum intrin { - INxxx, -#define _(b,...) IN##b, -#include "intrin.def" -#undef _ -}; - -struct instr { - uchar op, - cls; /* operation data class; also result class except for cmp ops (always i32) */ - uchar skip : 1, /* ignore during codegen: forms part of one machine instruction */ - keep : 1; /* for codegen, keep instr even if result seems unused */ - uchar inplace : 1; /* set (by isel) for instructions which modify its first arg in place */ - uchar reg; /* 0 -> no reg; else reg + 1 */ - union ref l, r; /* args */ -}; -static_assert(sizeof(struct instr) == 4*3); - -enum jumpkind { JXXX, Jb, Jret, Jtrap, }; - -struct block { - int id; - int npred; - int visit; - ushort loop; - int inumstart; - union { - struct block *_pred0; - struct block **_pred; - }; - struct block *lprev, *lnext; - struct block *s1, *s2; - struct block *idom; - vec_of(ushort) phi; - vec_of(ushort) ins; - struct { uchar t; union ref arg[2]; } jmp; -}; - -#define blkpred(blk, i) 0[(blk)->npred < 2 ? &(blk)->_pred0 : &(blk)->_pred[i]] - -enum { USERJUMP = 0xFFFF }; -struct use { struct use *next; struct block *blk; ushort u; }; - -enum { MAXREGS = 64 }; -/** register set **/ -typedef uvlong regset; -#define BIT(x) (1ull<<(x)) -#define rsset(pS, r) (*(pS) |= 1ull << (r)) -#define rsclr(pS, r) (*(pS) &=~ (1ull << (r))) -#define rstest(S, r) ((S) >> (r) & 1) -static inline bool -rsiter(int *i, uvlong rs) -{ - if (*i > 63) return 0; - uvlong mask = -(1ull << *i); - if ((rs & mask) == 0) return 0; - *i = lowestsetbit(rs & mask); - return 1; -} - -enum { - FNBLKID = 1<<0, - FNUSE = 1<<1, - FNRPO = 1<<2, - FNDOM = 1<<3, -}; -struct function { - struct arena **arena, **passarena; - internstr name; - struct block *entry, *curblk; - struct use *use; - short *nuse; - union type fnty, retty; - struct abiarg *abiarg, abiret[2]; - uint prop; - uint nblk; - int stksiz; - ushort nabiarg, nabiret; - bool globl; - bool isleaf; - bool inlin; - regset regusage; -}; - -#define FREQUIRE(_prop) assert((fn->prop & (_prop)) == (_prop) && "preconditions not met") - -enum objkind { OBJELF }; - -struct mctarg { - short gpr0, /* first gpr */ - ngpr, /* gpr count */ - bpr, /* frame/base pointer reg */ - gprscratch, fprscratch, /* scratch registers for regalloc */ - fpr0, /* first fpr */ - nfpr; /* fpr count */ - regset rcallee, /* callee-saved */ - rglob; /* globally live (never used for regalloc) */ - const char (*rnames)[6]; - enum objkind objkind; - /* abiret: lower return type: - * scalar/small struct -> returns number of regs (1..2), - * r & cls filled with reg and irclass of each scalar return, - * for struct, r2off filled with byte offset within struct for 2nd reg - * big struct -> returns 0, is passed via hidden pointer argument, - * r[0] contains register for returning said pointer or -1, - * r[1] contains register for hidden pointer argument, - * *ni is set to 1 if said register is the first ABI integer argument - */ - int (*abiret)(short r[2], uchar cls[2], uchar *r2off, int *ni, union irtype); - /* abiarg: lower argument type: - * scalar/small struct -> returns number of regs (1..2), - * r & cls filled with reg and irclass of each scalar arg - * for struct, r2off filled with byte offset within struct for 2nd reg - * if reg == -1 -> stack - * big struct -> returns 0, - * if passed in stack cls[0] == 0, r[0] == negative SP offset - * if passed by pointer cls[0] == KPTR, r[0] contains integer register - * or negative SP offset if stack - */ - int (*abiarg)(short r[2], uchar cls[2], uchar *r2off, int *ni, int *nf, int *ns, union irtype); - void (*vastart)(struct function *, struct block *, int *curi); - void (*vaarg)(struct function *, struct block *, int *curi); - void (*isel)(struct function *); - void (*emit)(struct function *); -}; - -enum { MAXINSTR = 1<<15 }; - -/** ir.c **/ -extern uchar type2cls[]; -extern uchar cls2siz[]; -extern uchar cls2load[]; -extern uchar cls2store[]; -extern const uchar siz2intcls[]; -extern struct instr instrtab[]; -extern struct use *instruse[]; -extern struct calltab {vec_of(struct call);} calltab; -extern struct phitab {vec_of(union ref *);} phitab; -extern struct dattab {vec_of(struct irdat);} dattab; -extern struct contab {vec_of(struct xcon);} contab; -extern struct addrtab {vec_of(struct addr);} addrtab; -extern int visitmark; -#define mkinstr(O, C, ...) ((struct instr) { .op = (O), .cls = (C), .reg=0, __VA_ARGS__ }) -#define mkarginstr(ty, x) mkinstr(Oarg, 0, mktyperef(ty), (x)) -void irinit(struct function *); -void irfini(struct function *); -#define cls2type(k) ((union irtype){.cls=(k)}) -union irtype mkirtype(union type); -union ref newxcon(const struct xcon *); -union ref mkintcon(enum irclass, vlong); -union ref mkfltcon(enum irclass, double); -#define iscon(r) in_range((r).t, RICON, RXCON) -#define concls(r) ((r).t == RICON ? KI32 : contab.p[(r).i].cls) -#define isintcon(r) (iscon(r) && kisint(concls(r))) -#define isfltcon(r) ((r).t == RXCON && kisflt(contab.p[(r).i].cls)) -#define isnumcon(r) ((r).t == RICON || ((r).t == RXCON && contab.p[(r).i].cls)) -#define isaddrcon(r,derefok) ((r).t == RXCON && !contab.p[(r).i].cls && (derefok || !contab.p[(r).i].deref)) -#define intconval(r) ((r).t == RICON ? (r).i : contab.p[(r).i].i) -#define fltconval(r) ((r).t == RICON ? (r).i : contab.p[(r).i].f) -union ref mksymref(internstr, enum symflags); -union ref mkdatref(internstr sym, union type ctype, uint siz, uint align, - const void *, uint n, bool deref, bool funclocal); -internstr xcon2sym(int ref); -struct instr mkalloca(uint siz, uint align); -union ref mkcallarg(union irtype ret, uint narg, int vararg); -#define mkintrin(B, C, N) mkinstr(Ointrin, C, {{.t=RICON,B}}, mkcallarg((union irtype){{0}},N,-1)) -union ref mkaddr(struct addr); -void addpred(struct block *blk, struct block *p); - -struct block *newblk(struct function *); -void freeblk(struct function *, struct block *); -struct block *insertblk(struct function *, struct block *pred, struct block *subst); -struct block *blksplitafter(struct function *, struct block *, int idx); -void adduse(struct block *ublk, int ui, union ref r); -int newinstr(struct block *at, struct instr ins); -union ref insertinstr(struct block *, int idx, struct instr); -union ref insertphi(struct block *, enum irclass cls); -void replcuses(union ref from, union ref to); -bool deluse(struct block *ublk, int ui, union ref r); -void deluses(int ins); -void filluses(struct function *); -void delinstr(struct block *, int idx); -void delphi(struct block *, int idx); -void delnops(struct block *blk); -void delpred(struct block *blk, struct block *p); -void fillblkids(struct function *); -#define startbbvisit() (void)(++visitmark) -#define wasvisited(blk) ((blk)->visit == visitmark) -#define markvisited(blk) ((blk)->visit = visitmark) -uint numberinstrs(struct function *); -bool blkreachable(struct function *fn, struct block *blk); - -/** builder.c **/ -union ref irbinop(struct function *, enum op, enum irclass, union ref lhs, union ref rhs); -union ref irunop(struct function *, enum op, enum irclass, union ref); -union ref addinstr(struct function *, struct instr); -union ref addphi(struct function *, enum irclass, union ref []); -void useblk(struct function *, struct block *); -void putbranch(struct function *, struct block *); -void putcondbranch(struct function *, union ref arg, struct block *t, struct block *f); -void putreturn(struct function *, union ref r0, union ref r1); -void puttrap(struct function *); - -/** fold.c **/ -bool foldbinop(union ref *to, enum op, enum irclass, union ref l, union ref r); -bool foldunop(union ref *to, enum op, enum irclass, union ref); - -/** irdump.c **/ -void irdump(struct function *); - -/** mem2reg.c **/ -void mem2reg(struct function *); - -/** ssa.c **/ -void copyopt(struct function *); - -/** cfg.c **/ -void sortrpo(struct function *); -void filldom(struct function *); -void fillloop(struct function *); - -/** abi0.c **/ -void abi0(struct function *); -void abi0_call(struct function *, struct instr *, struct block *blk, int *curi); - -/** simpl.c **/ -void simpl(struct function *); - -/** cselim.c **/ -void cselim(struct function *); - -/** inliner.c **/ -bool maybeinlinee(struct function *); -void doinline(struct function *); - -/** intrin.c **/ -void lowerintrin(struct function *); - -/** stack.c **/ -void lowerstack(struct function *); - -/** regalloc.c **/ -void regalloc(struct function *); - -/* vim:set ts=3 sw=3 expandtab: */ |