all.h 11 KB

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