all.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. #include <assert.h>
  2. #include <inttypes.h>
  3. #include <limits.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #define MAKESURE(what, x) typedef char make_sure_##what[(x)?1:-1]
  8. #define die(...) die_(__FILE__, __VA_ARGS__)
  9. typedef unsigned char uchar;
  10. typedef unsigned int uint;
  11. typedef unsigned long ulong;
  12. typedef unsigned long long bits;
  13. typedef struct BSet BSet;
  14. typedef struct Ref Ref;
  15. typedef struct Op Op;
  16. typedef struct Ins Ins;
  17. typedef struct Phi Phi;
  18. typedef struct Blk Blk;
  19. typedef struct Use Use;
  20. typedef struct Sym Sym;
  21. typedef struct Num Num;
  22. typedef struct Alias Alias;
  23. typedef struct Tmp Tmp;
  24. typedef struct Con Con;
  25. typedef struct Addr Mem;
  26. typedef struct Fn Fn;
  27. typedef struct Typ Typ;
  28. typedef struct Field Field;
  29. typedef struct Dat Dat;
  30. typedef struct Lnk Lnk;
  31. typedef struct Target Target;
  32. enum {
  33. NString = 80,
  34. NIns = 1 << 20,
  35. NAlign = 3,
  36. NField = 32,
  37. NBit = CHAR_BIT * sizeof(bits),
  38. };
  39. struct Target {
  40. char name[16];
  41. char apple;
  42. int gpr0; /* first general purpose reg */
  43. int ngpr;
  44. int fpr0; /* first floating point reg */
  45. int nfpr;
  46. bits rglob; /* globally live regs (e.g., sp, fp) */
  47. int nrglob;
  48. int *rsave; /* caller-save */
  49. int nrsave[2];
  50. bits (*retregs)(Ref, int[2]);
  51. bits (*argregs)(Ref, int[2]);
  52. int (*memargs)(int);
  53. void (*abi0)(Fn *);
  54. void (*abi1)(Fn *);
  55. void (*isel)(Fn *);
  56. void (*emitfn)(Fn *, FILE *);
  57. void (*emitfin)(FILE *);
  58. char asloc[4];
  59. char assym[4];
  60. };
  61. #define BIT(n) ((bits)1 << (n))
  62. enum {
  63. RXX = 0,
  64. Tmp0 = NBit, /* first non-reg temporary */
  65. };
  66. struct BSet {
  67. uint nt;
  68. bits *t;
  69. };
  70. struct Ref {
  71. uint type:3;
  72. uint val:29;
  73. };
  74. enum {
  75. RTmp,
  76. RCon,
  77. RInt,
  78. RType, /* last kind to come out of the parser */
  79. RSlot,
  80. RCall,
  81. RMem,
  82. };
  83. #define R (Ref){RTmp, 0}
  84. #define UNDEF (Ref){RCon, 0} /* represents uninitialized data */
  85. #define CON_Z (Ref){RCon, 1}
  86. #define TMP(x) (Ref){RTmp, x}
  87. #define CON(x) (Ref){RCon, x}
  88. #define SLOT(x) (Ref){RSlot, (x)&0x1fffffff}
  89. #define TYPE(x) (Ref){RType, x}
  90. #define CALL(x) (Ref){RCall, x}
  91. #define MEM(x) (Ref){RMem, x}
  92. #define INT(x) (Ref){RInt, (x)&0x1fffffff}
  93. static inline int req(Ref a, Ref b)
  94. {
  95. return a.type == b.type && a.val == b.val;
  96. }
  97. static inline int rtype(Ref r)
  98. {
  99. if (req(r, R))
  100. return -1;
  101. return r.type;
  102. }
  103. static inline int rsval(Ref r)
  104. {
  105. return ((int)r.val ^ 0x10000000) - 0x10000000;
  106. }
  107. enum CmpI {
  108. Cieq,
  109. Cine,
  110. Cisge,
  111. Cisgt,
  112. Cisle,
  113. Cislt,
  114. Ciuge,
  115. Ciugt,
  116. Ciule,
  117. Ciult,
  118. NCmpI,
  119. };
  120. enum CmpF {
  121. Cfeq,
  122. Cfge,
  123. Cfgt,
  124. Cfle,
  125. Cflt,
  126. Cfne,
  127. Cfo,
  128. Cfuo,
  129. NCmpF,
  130. NCmp = NCmpI + NCmpF,
  131. };
  132. enum O {
  133. Oxxx,
  134. #define O(op, x, y) O##op,
  135. #include "ops.h"
  136. NOp,
  137. };
  138. enum J {
  139. Jxxx,
  140. #define JMPS(X) \
  141. X(retw) X(retl) X(rets) X(retd) \
  142. X(retsb) X(retub) X(retsh) X(retuh) \
  143. X(retc) X(ret0) X(jmp) X(jnz) \
  144. X(jfieq) X(jfine) X(jfisge) X(jfisgt) \
  145. X(jfisle) X(jfislt) X(jfiuge) X(jfiugt) \
  146. X(jfiule) X(jfiult) X(jffeq) X(jffge) \
  147. X(jffgt) X(jffle) X(jfflt) X(jffne) \
  148. X(jffo) X(jffuo) X(hlt)
  149. #define X(j) J##j,
  150. JMPS(X)
  151. #undef X
  152. NJmp
  153. };
  154. enum {
  155. Ocmpw = Oceqw,
  156. Ocmpw1 = Ocultw,
  157. Ocmpl = Oceql,
  158. Ocmpl1 = Ocultl,
  159. Ocmps = Oceqs,
  160. Ocmps1 = Ocuos,
  161. Ocmpd = Oceqd,
  162. Ocmpd1 = Ocuod,
  163. Oalloc = Oalloc4,
  164. Oalloc1 = Oalloc16,
  165. Oflag = Oflagieq,
  166. Oflag1 = Oflagfuo,
  167. NPubOp = Onop,
  168. Jjf = Jjfieq,
  169. Jjf1 = Jjffuo,
  170. };
  171. #define INRANGE(x, l, u) ((unsigned)(x) - l <= u - l) /* linear in x */
  172. #define isstore(o) INRANGE(o, Ostoreb, Ostored)
  173. #define isload(o) INRANGE(o, Oloadsb, Oload)
  174. #define isalloc(o) INRANGE(o, Oalloc4, Oalloc16)
  175. #define isext(o) INRANGE(o, Oextsb, Oextuw)
  176. #define ispar(o) INRANGE(o, Opar, Opare)
  177. #define isarg(o) INRANGE(o, Oarg, Oargv)
  178. #define isret(j) INRANGE(j, Jretw, Jret0)
  179. #define isparbh(o) INRANGE(o, Oparsb, Oparuh)
  180. #define isargbh(o) INRANGE(o, Oargsb, Oarguh)
  181. #define isretbh(j) INRANGE(j, Jretsb, Jretuh)
  182. enum {
  183. Kx = -1, /* "top" class (see usecheck() and clsmerge()) */
  184. Kw,
  185. Kl,
  186. Ks,
  187. Kd
  188. };
  189. #define KWIDE(k) ((k)&1)
  190. #define KBASE(k) ((k)>>1)
  191. struct Op {
  192. char *name;
  193. short argcls[2][4];
  194. uint canfold:1;
  195. uint hasid:1; /* op identity value? */
  196. uint idval:1; /* identity value 0/1 */
  197. uint commutes:1; /* commutative op? */
  198. uint assoc:1; /* associative op? */
  199. uint idemp:1; /* idempotent op? */
  200. uint cmpeqwl:1; /* Kl/Kw cmp eq/ne? */
  201. uint cmplgtewl:1; /* Kl/Kw cmp lt/gt/le/ge? */
  202. uint eqval:1; /* 1 for eq; 0 for ne */
  203. uint pinned:1; /* GCM pinned op? */
  204. };
  205. struct Ins {
  206. uint op:30;
  207. uint cls:2;
  208. Ref to;
  209. Ref arg[2];
  210. };
  211. struct Phi {
  212. Ref to;
  213. Ref *arg;
  214. Blk **blk;
  215. uint narg;
  216. short cls;
  217. uint visit:1;
  218. Phi *link;
  219. };
  220. struct Blk {
  221. Phi *phi;
  222. Ins *ins;
  223. uint nins;
  224. struct {
  225. short type;
  226. Ref arg;
  227. } jmp;
  228. Blk *s1;
  229. Blk *s2;
  230. Blk *link;
  231. uint id;
  232. uint visit;
  233. Blk *idom;
  234. Blk *dom, *dlink;
  235. Blk **fron;
  236. uint nfron;
  237. int depth;
  238. Blk **pred;
  239. uint npred;
  240. BSet in[1], out[1], gen[1];
  241. int nlive[2];
  242. int loop;
  243. char name[NString];
  244. };
  245. struct Use {
  246. enum {
  247. UXXX,
  248. UPhi,
  249. UIns,
  250. UJmp,
  251. } type;
  252. uint bid;
  253. union {
  254. Ins *ins;
  255. Phi *phi;
  256. } u;
  257. };
  258. struct Sym {
  259. enum {
  260. SGlo,
  261. SThr,
  262. } type;
  263. uint32_t id;
  264. };
  265. struct Num {
  266. uchar n;
  267. uchar nl, nr;
  268. Ref l, r;
  269. };
  270. enum {
  271. NoAlias,
  272. MayAlias,
  273. MustAlias
  274. };
  275. struct Alias {
  276. enum {
  277. ABot = 0,
  278. ALoc = 1, /* stack local */
  279. ACon = 2,
  280. AEsc = 3, /* stack escaping */
  281. ASym = 4,
  282. AUnk = 6,
  283. #define astack(t) ((t) & 1)
  284. } type;
  285. int base;
  286. int64_t offset;
  287. union {
  288. Sym sym;
  289. struct {
  290. int sz; /* -1 if > NBit */
  291. bits m;
  292. } loc;
  293. } u;
  294. Alias *slot;
  295. };
  296. struct Tmp {
  297. char name[NString];
  298. Ins *def;
  299. Use *use;
  300. uint ndef, nuse;
  301. uint bid; /* id of a defining block */
  302. uint cost;
  303. int slot; /* -1 for unset */
  304. short cls;
  305. struct {
  306. int r; /* register or -1 */
  307. int w; /* weight */
  308. bits m; /* avoid these registers */
  309. } hint;
  310. int phi;
  311. Alias alias;
  312. enum {
  313. WFull,
  314. Wsb, /* must match Oload/Oext order */
  315. Wub,
  316. Wsh,
  317. Wuh,
  318. Wsw,
  319. Wuw
  320. } width;
  321. int visit;
  322. uint gcmbid;
  323. };
  324. struct Con {
  325. enum {
  326. CUndef,
  327. CBits,
  328. CAddr,
  329. } type;
  330. Sym sym;
  331. union {
  332. int64_t i;
  333. double d;
  334. float s;
  335. } bits;
  336. char flt; /* 1 to print as s, 2 to print as d */
  337. };
  338. typedef struct Addr Addr;
  339. struct Addr { /* amd64 addressing */
  340. Con offset;
  341. Ref base;
  342. Ref index;
  343. int scale;
  344. };
  345. struct Lnk {
  346. char export;
  347. char thread;
  348. char common;
  349. char align;
  350. char *sec;
  351. char *secf;
  352. };
  353. struct Fn {
  354. Blk *start;
  355. Tmp *tmp;
  356. Con *con;
  357. Mem *mem;
  358. int ntmp;
  359. int ncon;
  360. int nmem;
  361. uint nblk;
  362. int retty; /* index in typ[], -1 if no aggregate return */
  363. Ref retr;
  364. Blk **rpo;
  365. bits reg;
  366. int slot;
  367. int salign;
  368. char vararg;
  369. char dynalloc;
  370. char leaf;
  371. char name[NString];
  372. Lnk lnk;
  373. };
  374. struct Typ {
  375. char name[NString];
  376. char isdark;
  377. char isunion;
  378. int align;
  379. uint64_t size;
  380. uint nunion;
  381. struct Field {
  382. enum {
  383. FEnd,
  384. Fb,
  385. Fh,
  386. Fw,
  387. Fl,
  388. Fs,
  389. Fd,
  390. FPad,
  391. FTyp,
  392. } type;
  393. uint len; /* or index in typ[] for FTyp */
  394. } (*fields)[NField+1];
  395. };
  396. struct Dat {
  397. enum {
  398. DStart,
  399. DEnd,
  400. DB,
  401. DH,
  402. DW,
  403. DL,
  404. DZ
  405. } type;
  406. char *name;
  407. Lnk *lnk;
  408. union {
  409. int64_t num;
  410. double fltd;
  411. float flts;
  412. char *str;
  413. struct {
  414. char *name;
  415. int64_t off;
  416. } ref;
  417. } u;
  418. char isref;
  419. char isstr;
  420. };
  421. /* main.c */
  422. extern Target T;
  423. extern char debug['Z'+1];
  424. /* util.c */
  425. typedef enum {
  426. PHeap, /* free() necessary */
  427. PFn, /* discarded after processing the function */
  428. } Pool;
  429. extern Typ *typ;
  430. extern Ins insb[NIns], *curi;
  431. uint32_t hash(char *);
  432. void die_(char *, char *, ...) __attribute__((noreturn));
  433. void *emalloc(size_t);
  434. void *alloc(size_t);
  435. void freeall(void);
  436. void *vnew(ulong, size_t, Pool);
  437. void vfree(void *);
  438. void vgrow(void *, ulong);
  439. void addins(Ins **, uint *, Ins *);
  440. void addbins(Blk *, Ins **, uint *);
  441. void strf(char[NString], char *, ...);
  442. uint32_t intern(char *);
  443. char *str(uint32_t);
  444. int argcls(Ins *, int);
  445. int isreg(Ref);
  446. int iscmp(int, int *, int *);
  447. void igroup(Blk *, Ins *, Ins **, Ins **);
  448. void emit(int, int, Ref, Ref, Ref);
  449. void emiti(Ins);
  450. void idup(Blk *, Ins *, ulong);
  451. Ins *icpy(Ins *, Ins *, ulong);
  452. int cmpop(int);
  453. int cmpneg(int);
  454. int cmpwlneg(int);
  455. int clsmerge(short *, short);
  456. int phicls(int, Tmp *);
  457. uint phiargn(Phi *, Blk *);
  458. Ref phiarg(Phi *, Blk *);
  459. Ref newtmp(char *, int, Fn *);
  460. void chuse(Ref, int, Fn *);
  461. int symeq(Sym, Sym);
  462. Ref newcon(Con *, Fn *);
  463. Ref getcon(int64_t, Fn *);
  464. int addcon(Con *, Con *, int);
  465. int isconbits(Fn *fn, Ref r, int64_t *v);
  466. void salloc(Ref, Ref, Fn *);
  467. void dumpts(BSet *, Tmp *, FILE *);
  468. void runmatch(uchar *, Num *, Ref, Ref *);
  469. void bsinit(BSet *, uint);
  470. void bszero(BSet *);
  471. uint bscount(BSet *);
  472. void bsset(BSet *, uint);
  473. void bsclr(BSet *, uint);
  474. void bscopy(BSet *, BSet *);
  475. void bsunion(BSet *, BSet *);
  476. void bsinter(BSet *, BSet *);
  477. void bsdiff(BSet *, BSet *);
  478. int bsequal(BSet *, BSet *);
  479. int bsiter(BSet *, int *);
  480. static inline int
  481. bshas(BSet *bs, uint elt)
  482. {
  483. assert(elt < bs->nt * NBit);
  484. return (bs->t[elt/NBit] & BIT(elt%NBit)) != 0;
  485. }
  486. /* parse.c */
  487. extern Op optab[NOp];
  488. void parse(FILE *, char *, void (char *), void (Dat *), void (Fn *));
  489. void printfn(Fn *, FILE *);
  490. void printref(Ref, Fn *, FILE *);
  491. void err(char *, ...) __attribute__((noreturn));
  492. /* abi.c */
  493. void elimsb(Fn *);
  494. /* cfg.c */
  495. Blk *newblk(void);
  496. void fillpreds(Fn *);
  497. void fillcfg(Fn *);
  498. void filldom(Fn *);
  499. int sdom(Blk *, Blk *);
  500. int dom(Blk *, Blk *);
  501. void fillfron(Fn *);
  502. void loopiter(Fn *, void (*)(Blk *, Blk *));
  503. void filldepth(Fn *);
  504. Blk *lca(Blk *, Blk *);
  505. void fillloop(Fn *);
  506. void simpljmp(Fn *);
  507. int reaches(Fn *, Blk *, Blk *);
  508. int reachesnotvia(Fn *, Blk *, Blk *, Blk *);
  509. /* mem.c */
  510. void promote(Fn *);
  511. void coalesce(Fn *);
  512. /* alias.c */
  513. void fillalias(Fn *);
  514. void getalias(Alias *, Ref, Fn *);
  515. int alias(Ref, int, int, Ref, int, int *, Fn *);
  516. int escapes(Ref, Fn *);
  517. /* load.c */
  518. int loadsz(Ins *);
  519. int storesz(Ins *);
  520. void loadopt(Fn *);
  521. /* ssa.c */
  522. void adduse(Tmp *, int, Blk *, ...);
  523. void filluse(Fn *);
  524. void ssa(Fn *);
  525. void ssacheck(Fn *);
  526. /* copy.c */
  527. void narrowpars(Fn *fn);
  528. Ref copyref(Fn *, Blk *, Ins *);
  529. Ref phicopyref(Fn *, Blk *, Phi *);
  530. /* fold.c */
  531. int foldint(Con *, int, int, Con *, Con *);
  532. Ref foldref(Fn *, Ins *);
  533. /* gvn.c */
  534. extern Ref con01[2]; /* 0 and 1 */
  535. int zeroval(Fn *, Blk *, Ref, int, int *);
  536. void gvn(Fn *);
  537. /* gcm.c */
  538. int pinned(Ins *);
  539. void gcm(Fn *);
  540. /* simpl.c */
  541. void simpl(Fn *);
  542. /* live.c */
  543. void liveon(BSet *, Blk *, Blk *);
  544. void filllive(Fn *);
  545. /* spill.c */
  546. void fillcost(Fn *);
  547. void spill(Fn *);
  548. /* rega.c */
  549. void rega(Fn *);
  550. /* emit.c */
  551. void emitfnlnk(char *, Lnk *, FILE *);
  552. void emitdat(Dat *, FILE *);
  553. void emitdbgfile(char *, FILE *);
  554. void emitdbgloc(uint, uint, FILE *);
  555. int stashbits(bits, int);
  556. void elf_emitfnfin(char *, FILE *);
  557. void elf_emitfin(FILE *);
  558. void macho_emitfin(FILE *);