PageRenderTime 63ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/pcc-20111216/mip/regs.c

#
C | 2947 lines | 2286 code | 286 blank | 375 comment | 807 complexity | e13127da7ffae5ae94509853a12ab0a6 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /* $Id: regs.c,v 1.227 2011/08/18 17:45:22 ragge Exp $ */
  2. /*
  3. * Copyright (c) 2005 Anders Magnusson (ragge@ludd.luth.se).
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. The name of the author may not be used to endorse or promote products
  15. * derived from this software without specific prior written permission
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #include "pass2.h"
  29. #include <string.h>
  30. #ifdef HAVE_STRINGS_H
  31. #include <strings.h>
  32. #endif
  33. #ifdef HAVE_STDINT_H
  34. #include <stdint.h>
  35. #endif
  36. #include <stdlib.h>
  37. #define MAXLOOP 20 /* Max number of allocation loops XXX 3 should be enough */
  38. #ifndef MAX
  39. #define MAX(a,b) (((a) > (b)) ? (a) : (b))
  40. #endif
  41. /*
  42. * New-style register allocator using graph coloring.
  43. * The design is based on the George and Appel paper
  44. * "Iterated Register Coalescing", ACM Transactions, No 3, May 1996.
  45. */
  46. #define BITALLOC(ptr,all,sz) { \
  47. int sz__s = BIT2BYTE(sz); ptr = all(sz__s); memset(ptr, 0, sz__s); }
  48. #undef COMPERR_PERM_MOVE
  49. #ifdef PCC_DEBUG
  50. #define RDEBUG(x) if (rdebug) printf x
  51. #define RRDEBUG(x) if (rdebug > 1) printf x
  52. #define RPRINTIP(x) if (rdebug) printip(x)
  53. #define RDEBUGX(x) x
  54. #define UDEBUG(x) if (udebug) printf x
  55. #define BDEBUG(x) if (b2debug) printf x
  56. #define BBDEBUG(x) if (b2debug > 1) printf x
  57. #else
  58. #define RDEBUG(x)
  59. #define RRDEBUG(x)
  60. #define RPRINTIP(x)
  61. #define RDEBUGX(x)
  62. #define UDEBUG(x)
  63. #define BDEBUG(x)
  64. #define BBDEBUG(x)
  65. #endif
  66. #define VALIDREG(p) (p->n_op == REG && TESTBIT(validregs, regno(p)))
  67. /*
  68. * Data structure overview for this implementation of graph coloring:
  69. *
  70. * Each temporary (called "node") is described by the type REGW.
  71. * Space for all nodes is allocated initially as an array, so
  72. * the nodes can be can be referenced both by the node number and
  73. * by pointer.
  74. *
  75. * All moves are represented by the type REGM, allocated when needed.
  76. *
  77. * The "live" set used during graph building is represented by a bitset.
  78. *
  79. * Interference edges are represented by struct AdjSet, hashed and linked
  80. * from index into the edgehash array.
  81. *
  82. * A mapping from each node to the moves it is assiciated with is
  83. * maintained by an array moveList which for each node number has a linked
  84. * list of MOVL types, each pointing to a REGM.
  85. *
  86. * Adjacency list is maintained by the adjList array, indexed by the
  87. * node number. Each adjList entry points to an ADJL type, and is a
  88. * single-linked list for all adjacent nodes.
  89. *
  90. * degree, alias and color are integer arrays indexed by node number.
  91. */
  92. /*
  93. * linked list of adjacent nodes.
  94. */
  95. typedef struct regw3 {
  96. struct regw3 *r_next;
  97. struct regw *a_temp;
  98. } ADJL;
  99. /*
  100. * Structure describing a move.
  101. */
  102. typedef struct regm {
  103. DLIST_ENTRY(regm) link;
  104. struct regw *src, *dst;
  105. int queue;
  106. } REGM;
  107. typedef struct movlink {
  108. struct movlink *next;
  109. REGM *regm;
  110. } MOVL;
  111. /*
  112. * Structure describing a temporary.
  113. */
  114. typedef struct regw {
  115. DLIST_ENTRY(regw) link;
  116. ADJL *r_adjList; /* linked list of adjacent nodes */
  117. int r_class; /* this nodes class */
  118. int r_nclass[NUMCLASS+1]; /* count of adjacent classes */
  119. struct regw *r_alias; /* aliased temporary */
  120. int r_color; /* final node color */
  121. struct regw *r_onlist; /* which work list this node belongs to */
  122. MOVL *r_moveList; /* moves associated with this node */
  123. #ifdef PCC_DEBUG
  124. int nodnum; /* Debug number */
  125. #endif
  126. } REGW;
  127. /*
  128. * Worklists, a node is always on exactly one of these lists.
  129. */
  130. static REGW precolored, simplifyWorklist, freezeWorklist, spillWorklist,
  131. spilledNodes, coalescedNodes, coloredNodes, selectStack;
  132. static REGW initial, *nblock;
  133. static void insnwalk(NODE *p);
  134. #ifdef PCC_DEBUG
  135. int use_regw;
  136. int nodnum = 100;
  137. int ntsz, stktemp;
  138. #define SETNUM(x) (x)->nodnum = nodnum++
  139. #define ASGNUM(x) (x)->nodnum
  140. #else
  141. #define SETNUM(x)
  142. #define ASGNUM(x)
  143. #endif
  144. #define ALLNEEDS (NACOUNT|NBCOUNT|NCCOUNT|NDCOUNT|NECOUNT|NFCOUNT|NGCOUNT)
  145. /* XXX */
  146. REGW *ablock;
  147. static int tempmin, tempmax, basetemp, xbits;
  148. /*
  149. * nsavregs is an array that matches the permregs array.
  150. * Each entry in the array may have the values:
  151. * 0 : register coalesced, just ignore.
  152. * 1 : save register on stack
  153. * If the entry is 0 but the resulting color differs from the
  154. * corresponding permregs index, add moves.
  155. * XXX - should be a bitfield!
  156. */
  157. static int *nsavregs, *ndontregs;
  158. /*
  159. * Return the REGW struct for a temporary.
  160. * If first time touched, enter into list for existing vars.
  161. * Only called from sucomp().
  162. */
  163. static REGW *
  164. newblock(NODE *p)
  165. {
  166. REGW *nb;
  167. #ifdef PCC_DEBUG
  168. if (regno(p) < tempmin || regno(p) >= tempmax)
  169. comperr("temp %p(%d) outside limits (%d-%d)",
  170. p, regno(p), tempmin, tempmax);
  171. #endif
  172. nb = &nblock[regno(p)];
  173. if (nb->link.q_forw == 0) {
  174. DLIST_INSERT_AFTER(&initial, nb, link);
  175. #ifdef PCC_DEBUG
  176. ASGNUM(nb) = regno(p);
  177. RDEBUG(("Adding longtime %d for tmp %d\n",
  178. nb->nodnum, regno(p)));
  179. #endif
  180. }
  181. if (nb->r_class == 0)
  182. nb->r_class = gclass(p->n_type);
  183. #ifdef PCC_DEBUG
  184. RDEBUG(("newblock: p %p, node %d class %d\n",
  185. p, nb->nodnum, nb->r_class));
  186. #endif
  187. return nb;
  188. }
  189. /*
  190. * Count the number of registers needed to evaluate a tree.
  191. * This is only done to find the evaluation order of the tree.
  192. * While here, assign temp numbers to the registers that will
  193. * be needed when the tree is evaluated.
  194. *
  195. * While traversing the tree, assign REGW nodes to the registers
  196. * used by all instructions:
  197. * - n_regw[0] is always set to the outgoing node. If the
  198. * instruction is 2-op (addl r0,r1) then an implicit move
  199. * is inserted just before the left (clobbered) operand.
  200. * - if the instruction has needs then REGW nodes are
  201. * allocated as n_regw[1] etc.
  202. */
  203. int
  204. nsucomp(NODE *p)
  205. {
  206. struct optab *q;
  207. int left, right;
  208. int nreg, need, i, nxreg, o;
  209. int nareg, nbreg, ncreg, ndreg, nereg, nfreg, ngreg;
  210. REGW *w;
  211. o = optype(p->n_op);
  212. UDEBUG(("entering nsucomp, node %p\n", p));
  213. if (TBLIDX(p->n_su) == 0) {
  214. int a = 0, b;
  215. p->n_regw = NULL;
  216. if (o == LTYPE ) {
  217. if (p->n_op == TEMP)
  218. p->n_regw = newblock(p);
  219. else if (p->n_op == REG)
  220. p->n_regw = &ablock[regno(p)];
  221. } else
  222. a = nsucomp(p->n_left);
  223. if (o == BITYPE) {
  224. b = nsucomp(p->n_right);
  225. if (b > a)
  226. p->n_su |= DORIGHT;
  227. a = MAX(a, b);
  228. }
  229. return a;
  230. }
  231. q = &table[TBLIDX(p->n_su)];
  232. #define NNEEDS(a,b) ((q->needs & a)/b)
  233. for (i = (q->needs & NACOUNT), nareg = 0; i; i -= NAREG)
  234. nareg++;
  235. for (i = (q->needs & NBCOUNT), nbreg = 0; i; i -= NBREG)
  236. nbreg++;
  237. for (i = (q->needs & NCCOUNT), ncreg = 0; i; i -= NCREG)
  238. ncreg++;
  239. for (i = (q->needs & NDCOUNT), ndreg = 0; i; i -= NDREG)
  240. ndreg++;
  241. for (i = (q->needs & NECOUNT), nereg = 0; i; i -= NEREG)
  242. nereg++;
  243. for (i = (q->needs & NFCOUNT), nfreg = 0; i; i -= NFREG)
  244. nfreg++;
  245. for (i = (q->needs & NGCOUNT), ngreg = 0; i; i -= NGREG)
  246. ngreg++;
  247. if (ntsz < NNEEDS(NTMASK, NTEMP) * szty(p->n_type))
  248. ntsz = NNEEDS(NTMASK, NTEMP) * szty(p->n_type);
  249. nxreg = nareg + nbreg + ncreg + ndreg + nereg + nfreg + ngreg;
  250. nreg = nxreg;
  251. if (callop(p->n_op))
  252. nreg = MAX(fregs, nreg);
  253. if (o == BITYPE) {
  254. right = nsucomp(p->n_right);
  255. } else
  256. right = 0;
  257. if (o != LTYPE)
  258. left = nsucomp(p->n_left);
  259. else
  260. left = 0;
  261. UDEBUG(("node %p left %d right %d\n", p, left, right));
  262. if (o == BITYPE) {
  263. /* Two children */
  264. if (right == left) {
  265. need = left + MAX(nreg, 1);
  266. } else {
  267. need = MAX(right, left);
  268. need = MAX(need, nreg);
  269. }
  270. if (setorder(p) == 0) {
  271. /* XXX - should take care of overlapping needs */
  272. if (right > left) {
  273. p->n_su |= DORIGHT;
  274. } else if (right == left) {
  275. /* A favor to 2-operand architectures */
  276. if ((q->rewrite & RRIGHT) == 0)
  277. p->n_su |= DORIGHT;
  278. }
  279. }
  280. } else if (o != LTYPE) {
  281. /* One child */
  282. need = MAX(right, left) + nreg;
  283. } else
  284. need = nreg;
  285. if (p->n_op == TEMP)
  286. (void)newblock(p);
  287. if (TCLASS(p->n_su) == 0 && nxreg == 0) {
  288. UDEBUG(("node %p no class\n", p));
  289. p->n_regw = NULL; /* may be set earlier */
  290. return need;
  291. }
  292. #ifdef PCC_DEBUG
  293. #define ADCL(n, cl) \
  294. for (i = 0; i < n; i++, w++) { w->r_class = cl; \
  295. DLIST_INSERT_BEFORE(&initial, w, link); SETNUM(w); \
  296. UDEBUG(("Adding " #n " %d\n", w->nodnum)); \
  297. }
  298. #else
  299. #define ADCL(n, cl) \
  300. for (i = 0; i < n; i++, w++) { w->r_class = cl; \
  301. DLIST_INSERT_BEFORE(&initial, w, link); SETNUM(w); \
  302. }
  303. #endif
  304. UDEBUG(("node %p numregs %d\n", p, nxreg+1));
  305. w = p->n_regw = tmpalloc(sizeof(REGW) * (nxreg+1));
  306. memset(w, 0, sizeof(REGW) * (nxreg+1));
  307. w->r_class = TCLASS(p->n_su);
  308. if (w->r_class == 0)
  309. w->r_class = gclass(p->n_type);
  310. w->r_nclass[0] = o == LTYPE; /* XXX store leaf info here */
  311. SETNUM(w);
  312. if (w->r_class)
  313. DLIST_INSERT_BEFORE(&initial, w, link);
  314. #ifdef PCC_DEBUG
  315. UDEBUG(("Adding short %d class %d\n", w->nodnum, w->r_class));
  316. #endif
  317. w++;
  318. ADCL(nareg, CLASSA);
  319. ADCL(nbreg, CLASSB);
  320. ADCL(ncreg, CLASSC);
  321. ADCL(ndreg, CLASSD);
  322. ADCL(nereg, CLASSE);
  323. ADCL(nfreg, CLASSF);
  324. ADCL(ngreg, CLASSG);
  325. if (q->rewrite & RESC1) {
  326. w = p->n_regw + 1;
  327. w->r_class = -1;
  328. DLIST_REMOVE(w,link);
  329. } else if (q->rewrite & RESC2) {
  330. w = p->n_regw + 2;
  331. w->r_class = -1;
  332. DLIST_REMOVE(w,link);
  333. } else if (q->rewrite & RESC3) {
  334. w = p->n_regw + 3;
  335. w->r_class = -1;
  336. DLIST_REMOVE(w,link);
  337. }
  338. UDEBUG(("node %p return regs %d\n", p, need));
  339. return need;
  340. }
  341. #define CLASS(x) (x)->r_class
  342. #define NCLASS(x,c) (x)->r_nclass[c]
  343. #define ADJLIST(x) (x)->r_adjList
  344. #define ALIAS(x) (x)->r_alias
  345. #define ONLIST(x) (x)->r_onlist
  346. #define MOVELIST(x) (x)->r_moveList
  347. #define COLOR(x) (x)->r_color
  348. static bittype *live;
  349. #define PUSHWLIST(w, l) DLIST_INSERT_AFTER(&l, w, link); w->r_onlist = &l
  350. #define POPWLIST(l) popwlist(&l);
  351. #define DELWLIST(w) DLIST_REMOVE(w, link)
  352. #define WLISTEMPTY(h) DLIST_ISEMPTY(&h,link)
  353. #define PUSHMLIST(w, l, q) DLIST_INSERT_AFTER(&l, w, link); w->queue = q
  354. #define POPMLIST(l) popmlist(&l);
  355. #define trivially_colorable(x) \
  356. trivially_colorable_p((x)->r_class, (x)->r_nclass)
  357. /*
  358. * Determine if a node is trivially colorable ("degree < K").
  359. * This implementation is a dumb one, without considering speed.
  360. */
  361. static int
  362. trivially_colorable_p(int c, int *n)
  363. {
  364. int r[NUMCLASS+1];
  365. int i;
  366. for (i = 1; i < NUMCLASS+1; i++)
  367. r[i] = n[i] < regK[i] ? n[i] : regK[i];
  368. #if 0
  369. /* add the exclusion nodes. */
  370. /* XXX can we do someything smart here? */
  371. /* worst-case for exclusion nodes are better than the `worst-case' */
  372. for (; excl; excl >>= 1)
  373. if (excl & 1)
  374. r[c]++;
  375. #endif
  376. i = COLORMAP(c, r);
  377. if (i < 0 || i > 1)
  378. comperr("trivially_colorable_p");
  379. #ifdef PCC_DEBUG
  380. if (rdebug > 1)
  381. printf("trivially_colorable_p: n[1] %d n[2] %d n[3] %d n[4] "
  382. "%d for class %d, triv %d\n", n[1], n[2], n[3], n[4], c, i);
  383. #endif
  384. return i;
  385. }
  386. int
  387. ncnt(int needs)
  388. {
  389. int i = 0;
  390. while (needs & NACOUNT)
  391. needs -= NAREG, i++;
  392. while (needs & NBCOUNT)
  393. needs -= NBREG, i++;
  394. while (needs & NCCOUNT)
  395. needs -= NCREG, i++;
  396. while (needs & NDCOUNT)
  397. needs -= NDREG, i++;
  398. while (needs & NECOUNT)
  399. needs -= NEREG, i++;
  400. while (needs & NFCOUNT)
  401. needs -= NFREG, i++;
  402. while (needs & NGCOUNT)
  403. needs -= NGREG, i++;
  404. return i;
  405. }
  406. static REGW *
  407. popwlist(REGW *l)
  408. {
  409. REGW *w = DLIST_NEXT(l, link);
  410. DLIST_REMOVE(w, link);
  411. w->r_onlist = NULL;
  412. return w;
  413. }
  414. /*
  415. * Move lists, a move node is always on only one list.
  416. */
  417. static REGM coalescedMoves, constrainedMoves, frozenMoves,
  418. worklistMoves, activeMoves;
  419. enum { COAL, CONSTR, FROZEN, WLIST, ACTIVE };
  420. static REGM *
  421. popmlist(REGM *l)
  422. {
  423. REGM *w = DLIST_NEXT(l, link);
  424. DLIST_REMOVE(w, link);
  425. return w;
  426. }
  427. /*
  428. * About data structures used in liveness analysis:
  429. *
  430. * The temporaries generated in pass1 are numbered between tempmin and
  431. * tempmax. Temporaries generated in pass2 are numbered above tempmax,
  432. * so they are sequentially numbered.
  433. *
  434. * Bitfields are used for liveness. Bit arrays are allocated on the
  435. * heap for the "live" variable and on the stack for the in, out, gen
  436. * and killed variables. Therefore, for a temp number, the bit number must
  437. * be biased with tempmin.
  438. *
  439. * There may be an idea to use a different data structure to store
  440. * pass2 allocated temporaries, because they are very sparse.
  441. */
  442. #ifdef PCC_DEBUG
  443. static void
  444. LIVEADD(int x)
  445. {
  446. RDEBUG(("Liveadd: %d\n", x));
  447. if (x >= MAXREGS && (x < tempmin || x >= tempmax))
  448. comperr("LIVEADD: out of range");
  449. if (x < MAXREGS) {
  450. BITSET(live, x);
  451. } else
  452. BITSET(live, (x-tempmin+MAXREGS));
  453. }
  454. static void
  455. LIVEDEL(int x)
  456. {
  457. RDEBUG(("Livedel: %d\n", x));
  458. if (x >= MAXREGS && (x < tempmin || x >= tempmax))
  459. comperr("LIVEDEL: out of range");
  460. if (x < MAXREGS) {
  461. BITCLEAR(live, x);
  462. } else
  463. BITCLEAR(live, (x-tempmin+MAXREGS));
  464. }
  465. #else
  466. #define LIVEADD(x) \
  467. (x >= MAXREGS ? BITSET(live, (x-tempmin+MAXREGS)) : BITSET(live, x))
  468. #define LIVEDEL(x) \
  469. (x >= MAXREGS ? BITCLEAR(live, (x-tempmin+MAXREGS)) : BITCLEAR(live, x))
  470. #endif
  471. static struct lives {
  472. DLIST_ENTRY(lives) link;
  473. REGW *var;
  474. } lused, lunused;
  475. static void
  476. LIVEADDR(REGW *x)
  477. {
  478. struct lives *l;
  479. #ifdef PCC_DEBUG
  480. RDEBUG(("LIVEADDR: %d\n", x->nodnum));
  481. DLIST_FOREACH(l, &lused, link)
  482. if (l->var == x)
  483. return;
  484. #if 0
  485. comperr("LIVEADDR: multiple %d", ASGNUM(x));
  486. #endif
  487. #endif
  488. if (!DLIST_ISEMPTY(&lunused, link)) {
  489. l = DLIST_NEXT(&lunused, link);
  490. DLIST_REMOVE(l, link);
  491. } else
  492. l = tmpalloc(sizeof(struct lives));
  493. l->var = x;
  494. DLIST_INSERT_AFTER(&lused, l, link);
  495. }
  496. static void
  497. LIVEDELR(REGW *x)
  498. {
  499. struct lives *l;
  500. #ifdef PCC_DEBUG
  501. RDEBUG(("LIVEDELR: %d\n", x->nodnum));
  502. #endif
  503. DLIST_FOREACH(l, &lused, link) {
  504. if (l->var != x)
  505. continue;
  506. DLIST_REMOVE(l, link);
  507. DLIST_INSERT_AFTER(&lunused, l, link);
  508. return;
  509. }
  510. #if 0
  511. comperr("LIVEDELR: %p not found", x);
  512. #endif
  513. }
  514. #define MOVELISTADD(t, p) movelistadd(t, p)
  515. #define WORKLISTMOVEADD(s,d) worklistmoveadd(s,d)
  516. static void
  517. movelistadd(REGW *t, REGM *p)
  518. {
  519. MOVL *w = tmpalloc(sizeof(MOVL));
  520. w->regm = p;
  521. w->next = t->r_moveList;
  522. t->r_moveList = w;
  523. }
  524. static REGM *
  525. worklistmoveadd(REGW *src, REGW *dst)
  526. {
  527. REGM *w = tmpalloc(sizeof(REGM));
  528. DLIST_INSERT_AFTER(&worklistMoves, w, link);
  529. w->src = src;
  530. w->dst = dst;
  531. w->queue = WLIST;
  532. return w;
  533. }
  534. #define HASHSZ 16384
  535. struct AdjSet {
  536. struct AdjSet *next;
  537. REGW *u, *v;
  538. } *edgehash[HASHSZ];
  539. /* Check if a node pair is adjacent */
  540. static int
  541. adjSet(REGW *u, REGW *v)
  542. {
  543. struct AdjSet *w;
  544. REGW *t;
  545. if (ONLIST(u) == &precolored) {
  546. ADJL *a = ADJLIST(v);
  547. /*
  548. * Check if any of the registers that have edges against v
  549. * alias to u.
  550. */
  551. for (; a; a = a->r_next) {
  552. if (ONLIST(a->a_temp) != &precolored)
  553. continue;
  554. t = a->a_temp;
  555. if (interferes(t - ablock, u - ablock))
  556. return 1;
  557. }
  558. }
  559. w = edgehash[(u->nodnum+v->nodnum)& (HASHSZ-1)];
  560. for (; w; w = w->next) {
  561. if ((u == w->u && v == w->v) || (u == w->v && v == w->u))
  562. return 1;
  563. }
  564. return 0;
  565. }
  566. /* Add a pair to adjset. No check for dups */
  567. static int
  568. adjSetadd(REGW *u, REGW *v)
  569. {
  570. struct AdjSet *w;
  571. int x;
  572. x = (u->nodnum+v->nodnum)& (HASHSZ-1);
  573. for (w = edgehash[x]; w; w = w->next)
  574. if ((u == w->u && v == w->v) || (u == w->v && v == w->u))
  575. return 1;
  576. w = tmpalloc(sizeof(struct AdjSet));
  577. w->u = u, w->v = v;
  578. w->next = edgehash[x];
  579. edgehash[x] = w;
  580. return 0;
  581. }
  582. /*
  583. * Add an interference edge between two nodes.
  584. */
  585. static void
  586. AddEdge(REGW *u, REGW *v)
  587. {
  588. ADJL *x;
  589. #ifdef PCC_DEBUG
  590. RRDEBUG(("AddEdge: u %d v %d\n", ASGNUM(u), ASGNUM(v)));
  591. #if 0
  592. if (ASGNUM(u) == 0)
  593. comperr("AddEdge 0");
  594. #endif
  595. if (CLASS(u) == 0 || CLASS(v) == 0)
  596. comperr("AddEdge class == 0 (%d=%d, %d=%d)",
  597. CLASS(u), ASGNUM(u), CLASS(v), ASGNUM(v));
  598. #endif
  599. if (u == v)
  600. return;
  601. if (adjSetadd(u, v))
  602. return;
  603. #if 0
  604. if (ONLIST(u) == &precolored || ONLIST(v) == &precolored)
  605. comperr("precolored node in AddEdge");
  606. #endif
  607. if (ONLIST(u) != &precolored) {
  608. x = tmpalloc(sizeof(ADJL));
  609. x->a_temp = v;
  610. x->r_next = u->r_adjList;
  611. u->r_adjList = x;
  612. NCLASS(u, CLASS(v))++;
  613. }
  614. if (ONLIST(v) != &precolored) {
  615. x = tmpalloc(sizeof(ADJL));
  616. x->a_temp = u;
  617. x->r_next = v->r_adjList;
  618. v->r_adjList = x;
  619. NCLASS(v, CLASS(u))++;
  620. }
  621. #if 0
  622. RDEBUG(("AddEdge: u %d(d %d) v %d(d %d)\n", u, DEGREE(u), v, DEGREE(v)));
  623. #endif
  624. }
  625. static int
  626. MoveRelated(REGW *n)
  627. {
  628. MOVL *l;
  629. REGM *w;
  630. for (l = MOVELIST(n); l; l = l->next) {
  631. w = l->regm;
  632. if (w->queue == ACTIVE || w->queue == WLIST)
  633. return 1;
  634. }
  635. return 0;
  636. }
  637. static void
  638. MkWorklist(void)
  639. {
  640. REGW *w;
  641. RDEBUGX(int s=0);
  642. RDEBUGX(int f=0);
  643. RDEBUGX(int d=0);
  644. DLIST_INIT(&precolored, link);
  645. DLIST_INIT(&simplifyWorklist, link);
  646. DLIST_INIT(&freezeWorklist, link);
  647. DLIST_INIT(&spillWorklist, link);
  648. DLIST_INIT(&spilledNodes, link);
  649. DLIST_INIT(&coalescedNodes, link);
  650. DLIST_INIT(&coloredNodes, link);
  651. DLIST_INIT(&selectStack, link);
  652. /*
  653. * Remove all nodes from the initial list and put them on
  654. * one of the worklists.
  655. */
  656. while (!DLIST_ISEMPTY(&initial, link)) {
  657. w = DLIST_NEXT(&initial, link);
  658. DLIST_REMOVE(w, link);
  659. if (!trivially_colorable(w)) {
  660. PUSHWLIST(w, spillWorklist);
  661. RDEBUGX(s++);
  662. } else if (MoveRelated(w)) {
  663. PUSHWLIST(w, freezeWorklist);
  664. RDEBUGX(f++);
  665. } else {
  666. PUSHWLIST(w, simplifyWorklist);
  667. RDEBUGX(d++);
  668. }
  669. }
  670. RDEBUG(("MkWorklist: spill %d freeze %d simplify %d\n", s,f,d));
  671. }
  672. static void
  673. addalledges(REGW *e)
  674. {
  675. int i, j, k;
  676. struct lives *l;
  677. #ifdef PCC_DEBUG
  678. RDEBUG(("addalledges for %d\n", e->nodnum));
  679. #endif
  680. if (e->r_class == -1)
  681. return; /* unused */
  682. if (ONLIST(e) != &precolored) {
  683. for (i = 0; ndontregs[i] >= 0; i++)
  684. AddEdge(e, &ablock[ndontregs[i]]);
  685. }
  686. /* First add to long-lived temps and hard regs */
  687. RDEBUG(("addalledges longlived "));
  688. for (i = 0; i < xbits; i += NUMBITS) {
  689. if ((k = live[i/NUMBITS])) {
  690. while (k) {
  691. j = ffs(k)-1;
  692. if (i+j < MAXREGS)
  693. AddEdge(&ablock[i+j], e);
  694. else
  695. AddEdge(&nblock[i+j+tempmin-MAXREGS],e);
  696. RRDEBUG(("%d ", i+j+tempmin));
  697. k &= ~(1 << j);
  698. }
  699. }
  700. #if NUMBITS > 32 /* XXX hack for LP64 */
  701. k = (live[i/NUMBITS] >> 32);
  702. while (k) {
  703. j = ffs(k)-1;
  704. if (i+j+32 < MAXREGS)
  705. AddEdge(&ablock[i+j+32], e);
  706. else
  707. AddEdge(&nblock[i+j+tempmin-MAXREGS+32], e);
  708. RRDEBUG(("%d ", i+j+tempmin+32));
  709. k &= ~(1 << j);
  710. }
  711. #endif
  712. }
  713. RDEBUG(("done\n"));
  714. /* short-lived temps */
  715. RDEBUG(("addalledges shortlived "));
  716. DLIST_FOREACH(l, &lused, link) {
  717. #ifdef PCC_DEBUG
  718. RRDEBUG(("%d ", ASGNUM(l->var)));
  719. #endif
  720. AddEdge(l->var, e);
  721. }
  722. RDEBUG(("done\n"));
  723. }
  724. /*
  725. * Add a move edge between def and use.
  726. */
  727. static void
  728. moveadd(REGW *def, REGW *use)
  729. {
  730. REGM *r;
  731. MOVL *w;
  732. if (def == use)
  733. return; /* no move to itself XXX - ``shouldn't happen'' */
  734. #ifdef PCC_DEBUG
  735. RDEBUG(("moveadd: def %d use %d\n", ASGNUM(def), ASGNUM(use)));
  736. #endif
  737. /*
  738. * Check if we are already on move list.
  739. * XXX How can that happen ???
  740. */
  741. for (w = MOVELIST(def); w; w = w->next) {
  742. if ((w->regm->src == def && w->regm->dst == use) ||
  743. (w->regm->src == use && w->regm->dst == def))
  744. return; /* already there XXX reverse? */
  745. }
  746. r = WORKLISTMOVEADD(use, def);
  747. MOVELISTADD(def, r);
  748. MOVELISTADD(use, r);
  749. }
  750. /*
  751. * Traverse arguments backwards.
  752. * XXX - can this be tricked in some other way?
  753. */
  754. static void
  755. argswalk(NODE *p)
  756. {
  757. if (p->n_op == CM) {
  758. argswalk(p->n_left);
  759. insnwalk(p->n_right);
  760. } else
  761. insnwalk(p);
  762. }
  763. /*
  764. * Add to (or remove from) live set variables that must not
  765. * be clobbered when traversing down on the other leg for
  766. * a BITYPE node.
  767. */
  768. static void
  769. setlive(NODE *p, int set, REGW *rv)
  770. {
  771. if (rv != NULL) {
  772. if (rv->nodnum < MAXREGS &&
  773. TESTBIT(validregs, rv->nodnum) == 0)
  774. return;
  775. set ? LIVEADDR(rv) : LIVEDELR(rv);
  776. return;
  777. }
  778. if (p->n_regw != NULL) {
  779. if (p->n_regw->nodnum < MAXREGS &&
  780. TESTBIT(validregs, p->n_regw->nodnum) == 0)
  781. return;
  782. set ? LIVEADDR(p->n_regw) : LIVEDELR(p->n_regw);
  783. return;
  784. }
  785. switch (optype(p->n_op)) {
  786. case LTYPE:
  787. if (p->n_op == TEMP || VALIDREG(p))
  788. set ? LIVEADD(regno(p)) : LIVEDEL(regno(p));
  789. break;
  790. case BITYPE:
  791. setlive(p->n_right, set, rv);
  792. /* FALLTHROUGH */
  793. case UTYPE:
  794. setlive(p->n_left, set, rv);
  795. break;
  796. }
  797. }
  798. /*
  799. * Add edges for temporary w against all temporaries that may be
  800. * used simultaneously (like index registers).
  801. */
  802. static void
  803. addedge_r(NODE *p, REGW *w)
  804. {
  805. RRDEBUG(("addedge_r: node %p regw %p\n", p, w));
  806. if (p->n_regw != NULL) {
  807. if (p->n_regw->nodnum < MAXREGS &&
  808. TESTBIT(validregs, p->n_regw->nodnum) == 0)
  809. return;
  810. AddEdge(p->n_regw, w);
  811. return;
  812. }
  813. if (optype(p->n_op) == BITYPE)
  814. addedge_r(p->n_right, w);
  815. if (optype(p->n_op) != LTYPE)
  816. addedge_r(p->n_left, w);
  817. }
  818. /*
  819. * delete early clobber liveness. Only interesting on regs.
  820. */
  821. static void
  822. delcl(NODE *p)
  823. {
  824. int cw;
  825. if (p->n_op == ICON && p->n_type == STRTY)
  826. return;
  827. cw = xasmcode(p->n_name);
  828. if ((cw & XASMCONSTR) == 0 || !XASMISOUT(cw))
  829. return;
  830. if (XASMVAL(cw) != 'r')
  831. return;
  832. LIVEDEL(regno(p->n_left));
  833. }
  834. /*
  835. * add/del parameter from live set.
  836. */
  837. static void
  838. setxarg(NODE *p)
  839. {
  840. int i, ut = 0, in = 0;
  841. REGW *rw;
  842. int c, cw;
  843. if (p->n_op == ICON && p->n_type == STRTY)
  844. return;
  845. RDEBUG(("setxarg %p %s\n", p, p->n_name));
  846. cw = xasmcode(p->n_name);
  847. if (XASMISINP(cw))
  848. in = 1;
  849. if (XASMISOUT(cw) && !(cw & XASMCONSTR))
  850. ut = 1;
  851. c = XASMVAL(cw);
  852. #ifdef MYSETXARG
  853. MYSETXARG;
  854. #endif
  855. switch (c) {
  856. case 'm':
  857. case 'g':
  858. /* must find all TEMPs/REGs and set them live */
  859. if (p->n_left->n_op != REG && p->n_left->n_op != TEMP) {
  860. insnwalk(p->n_left);
  861. break;
  862. }
  863. /* FALLTHROUGH */
  864. case 'r':
  865. i = regno(p->n_left);
  866. rw = p->n_left->n_op == REG ? ablock : nblock;
  867. if (ut) {
  868. LIVEDEL(i);
  869. }
  870. if (in) {
  871. LIVEADD(i);
  872. }
  873. addalledges(&rw[i]);
  874. break;
  875. case 'i':
  876. case 'n':
  877. break;
  878. default:
  879. comperr("bad ixarg %s", p->n_name);
  880. }
  881. #ifdef MYSETXARG
  882. MYSETXARG;
  883. #endif
  884. }
  885. /*
  886. * Do the in-tree part of liveness analysis. (the difficult part)
  887. *
  888. * Walk down the tree in reversed-evaluation order (backwards).
  889. * The moves and edges inserted and evaluation order for
  890. * instructions when code is emitted is described here, hence
  891. * this code runs the same but backwards.
  892. *
  893. * 2-op reclaim LEFT: eval L, move to DEST, eval R.
  894. * moveadd L,DEST; addedge DEST,R
  895. * 2-op reclaim LEFT DORIGHT: eval R, eval L, move to DEST.
  896. * moveadd L,DEST; addedge DEST,R; addedge L,R
  897. * 2-op reclaim RIGHT; eval L, eval R, move to DEST.
  898. * moveadd R,DEST; addedge DEST,L; addedge L,R
  899. * 2-op reclaim RIGHT DORIGHT: eval R, move to DEST, eval L.
  900. * moveadd R,DEST; addedge DEST,L
  901. * 3-op: eval L, eval R
  902. * addedge L,R
  903. * 3-op DORIGHT: eval R, eval L
  904. * addedge L,R
  905. *
  906. * Instructions with special needs are handled just like these variants,
  907. * with the exception of extra added moves and edges.
  908. * Moves to special regs are scheduled after the evaluation of both legs.
  909. */
  910. static void
  911. insnwalk(NODE *p)
  912. {
  913. int o = p->n_op;
  914. struct optab *q = &table[TBLIDX(p->n_su)];
  915. REGW *lr, *rr, *rv, *r, *rrv, *lrv;
  916. NODE *lp, *rp;
  917. int i, n;
  918. RDEBUG(("insnwalk %p\n", p));
  919. rv = p->n_regw;
  920. rrv = lrv = NULL;
  921. if (p->n_op == ASSIGN &&
  922. (p->n_left->n_op == TEMP || VALIDREG(p->n_left))) {
  923. lr = p->n_left->n_op == TEMP ? nblock : ablock;
  924. i = regno(p->n_left);
  925. LIVEDEL(i); /* remove assigned temp from live set */
  926. addalledges(&lr[i]);
  927. }
  928. /* Add edges for the result of this node */
  929. if (rv && (q->visit & INREGS || o == TEMP || VALIDREG(p)))
  930. addalledges(rv);
  931. /* special handling of CALL operators */
  932. if (callop(o)) {
  933. if (rv)
  934. moveadd(rv, &ablock[RETREG(p->n_type)]);
  935. for (i = 0; tempregs[i] >= 0; i++)
  936. addalledges(&ablock[tempregs[i]]);
  937. }
  938. /* for special return value registers add moves */
  939. if ((q->needs & NSPECIAL) && (n = rspecial(q, NRES)) >= 0) {
  940. rv = &ablock[n];
  941. moveadd(p->n_regw, rv);
  942. }
  943. /* Check leaves for results in registers */
  944. lr = optype(o) != LTYPE ? p->n_left->n_regw : NULL;
  945. lp = optype(o) != LTYPE ? p->n_left : NULL;
  946. rr = optype(o) == BITYPE ? p->n_right->n_regw : NULL;
  947. rp = optype(o) == BITYPE ? p->n_right : NULL;
  948. /* simple needs */
  949. n = ncnt(q->needs);
  950. for (i = 0; i < n; i++) {
  951. #if 1
  952. static int ncl[] =
  953. { 0, NASL, NBSL, NCSL, NDSL, NESL, NFSL, NGSL };
  954. static int ncr[] =
  955. { 0, NASR, NBSR, NCSR, NDSR, NESR, NFSR, NGSR };
  956. int j;
  957. /* edges are already added */
  958. if ((r = &p->n_regw[1+i])->r_class == -1) {
  959. r = p->n_regw;
  960. } else {
  961. AddEdge(r, p->n_regw);
  962. addalledges(r);
  963. }
  964. if (optype(o) != LTYPE && (q->needs & ncl[CLASS(r)]) == 0)
  965. addedge_r(p->n_left, r);
  966. if (optype(o) == BITYPE && (q->needs & ncr[CLASS(r)]) == 0)
  967. addedge_r(p->n_right, r);
  968. for (j = i + 1; j < n; j++) {
  969. if (p->n_regw[j+1].r_class == -1)
  970. continue;
  971. AddEdge(r, &p->n_regw[j+1]);
  972. }
  973. #else
  974. if ((r = &p->n_regw[1+i])->r_class == -1)
  975. continue;
  976. addalledges(r);
  977. if (optype(o) != LTYPE && (q->needs & NASL) == 0)
  978. addedge_r(p->n_left, r);
  979. if (optype(o) == BITYPE && (q->needs & NASR) == 0)
  980. addedge_r(p->n_right, r);
  981. #endif
  982. }
  983. /* special needs */
  984. if (q->needs & NSPECIAL) {
  985. struct rspecial *rc;
  986. for (rc = nspecial(q); rc->op; rc++) {
  987. switch (rc->op) {
  988. #define ONLY(c,s) if (c) s(c, &ablock[rc->num])
  989. case NLEFT:
  990. addalledges(&ablock[rc->num]);
  991. ONLY(lr, moveadd);
  992. if (optype(o) != BITYPE)
  993. break;
  994. /* FALLTHROUGH */
  995. case NORIGHT:
  996. addedge_r(p->n_right, &ablock[rc->num]);
  997. break;
  998. case NRIGHT:
  999. addalledges(&ablock[rc->num]);
  1000. ONLY(rr, moveadd);
  1001. /* FALLTHROUGH */
  1002. case NOLEFT:
  1003. addedge_r(p->n_left, &ablock[rc->num]);
  1004. break;
  1005. case NEVER:
  1006. addalledges(&ablock[rc->num]);
  1007. break;
  1008. #undef ONLY
  1009. }
  1010. }
  1011. }
  1012. if (o == ASSIGN) {
  1013. /* avoid use of unhandled registers */
  1014. if (p->n_left->n_op == REG &&
  1015. !TESTBIT(validregs, regno(p->n_left)))
  1016. lr = NULL;
  1017. if (p->n_right->n_op == REG &&
  1018. !TESTBIT(validregs, regno(p->n_right)))
  1019. rr = NULL;
  1020. /* needs special treatment */
  1021. if (lr && rr)
  1022. moveadd(lr, rr);
  1023. if (lr && rv)
  1024. moveadd(lr, rv);
  1025. if (rr && rv)
  1026. moveadd(rr, rv);
  1027. } else if (callop(o)) {
  1028. int *c;
  1029. for (c = livecall(p); *c != -1; c++) {
  1030. addalledges(ablock + *c);
  1031. LIVEADD(*c);
  1032. }
  1033. } else if (q->rewrite & (RESC1|RESC2|RESC3)) {
  1034. if (lr && rr)
  1035. AddEdge(lr, rr);
  1036. } else if (q->rewrite & RLEFT) {
  1037. if (lr && rv)
  1038. moveadd(rv, lr), lrv = rv;
  1039. if (rv && rp)
  1040. addedge_r(rp, rv);
  1041. } else if (q->rewrite & RRIGHT) {
  1042. if (rr && rv)
  1043. moveadd(rv, rr), rrv = rv;
  1044. if (rv && lp)
  1045. addedge_r(lp, rv);
  1046. }
  1047. switch (optype(o)) {
  1048. case BITYPE:
  1049. if (p->n_op == ASSIGN &&
  1050. (p->n_left->n_op == TEMP || p->n_left->n_op == REG)) {
  1051. /* only go down right node */
  1052. insnwalk(p->n_right);
  1053. } else if (callop(o)) {
  1054. insnwalk(p->n_left);
  1055. /* Do liveness analysis on arguments (backwards) */
  1056. argswalk(p->n_right);
  1057. } else if ((p->n_su & DORIGHT) == 0) {
  1058. setlive(p->n_left, 1, lrv);
  1059. insnwalk(p->n_right);
  1060. setlive(p->n_left, 0, lrv);
  1061. insnwalk(p->n_left);
  1062. } else {
  1063. setlive(p->n_right, 1, rrv);
  1064. insnwalk(p->n_left);
  1065. setlive(p->n_right, 0, rrv);
  1066. insnwalk(p->n_right);
  1067. }
  1068. break;
  1069. case UTYPE:
  1070. insnwalk(p->n_left);
  1071. break;
  1072. case LTYPE:
  1073. switch (o) {
  1074. case REG:
  1075. if (!TESTBIT(validregs, regno(p)))
  1076. break; /* never add moves */
  1077. /* FALLTHROUGH */
  1078. case TEMP:
  1079. i = regno(p);
  1080. rr = (o == TEMP ? &nblock[i] : &ablock[i]);
  1081. if (rv != rr) {
  1082. addalledges(rr);
  1083. moveadd(rv, rr);
  1084. }
  1085. LIVEADD(i);
  1086. break;
  1087. case OREG: /* XXX - not yet */
  1088. break;
  1089. default:
  1090. break;
  1091. }
  1092. break;
  1093. }
  1094. }
  1095. static bittype **gen, **killed, **in, **out;
  1096. struct notspill {
  1097. SLIST_ENTRY(notspill) link;
  1098. int spnum;
  1099. };
  1100. SLIST_HEAD(, notspill) nothead;
  1101. static int
  1102. innotspill(int n)
  1103. {
  1104. struct notspill *nsp;
  1105. SLIST_FOREACH(nsp, &nothead, link)
  1106. if (nsp->spnum == n)
  1107. return 1;
  1108. return 0;
  1109. }
  1110. static void
  1111. addnotspill(int n)
  1112. {
  1113. struct notspill *nsp;
  1114. if (innotspill(n))
  1115. return;
  1116. nsp = tmpalloc(sizeof(struct notspill));
  1117. nsp->spnum = n;
  1118. SLIST_INSERT_LAST(&nothead, nsp, link);
  1119. }
  1120. /*
  1121. * Found an extended assembler node, so growel out gen/killed nodes.
  1122. */
  1123. static void
  1124. xasmionize(NODE *p, void *arg)
  1125. {
  1126. int bb = *(int *)arg;
  1127. int cw, b;
  1128. if (p->n_op == ICON && p->n_type == STRTY)
  1129. return; /* dummy end marker */
  1130. cw = xasmcode(p->n_name);
  1131. if (XASMVAL(cw) == 'n' /* || XASMVAL(cw) == 'm' */)
  1132. return; /* no flow analysis */
  1133. p = p->n_left;
  1134. if (XASMVAL(cw) == 'g' && p->n_op != TEMP && p->n_op != REG)
  1135. return; /* no flow analysis */
  1136. b = regno(p);
  1137. if (XASMVAL(cw) == 'r' && p->n_op == TEMP)
  1138. addnotspill(b);
  1139. if (XASMVAL(cw) == 'm') {
  1140. if (p->n_op == UMUL && p->n_left->n_op == TEMP) {
  1141. p = p->n_left;
  1142. b = regno(p);
  1143. addnotspill(b);
  1144. cw &= ~(XASMASG|XASMINOUT);
  1145. } else
  1146. return;
  1147. }
  1148. #define MKTOFF(r) ((r) - tempmin + MAXREGS)
  1149. if (XASMISOUT(cw)) {
  1150. if (p->n_op == TEMP) {
  1151. BITCLEAR(gen[bb], MKTOFF(b));
  1152. BITSET(killed[bb], MKTOFF(b));
  1153. } else if (p->n_op == REG) {
  1154. BITCLEAR(gen[bb], b);
  1155. BITSET(killed[bb], b);
  1156. } else
  1157. uerror("bad xasm node type %d", p->n_op);
  1158. }
  1159. if (XASMISINP(cw)) {
  1160. if (p->n_op == TEMP) {
  1161. BITSET(gen[bb], MKTOFF(b));
  1162. } else if (p->n_op == REG) {
  1163. BITSET(gen[bb], b);
  1164. } else if (optype(p->n_op) != LTYPE) {
  1165. if (XASMVAL(cw) == 'r')
  1166. uerror("couldn't find available register");
  1167. else
  1168. uerror("bad xasm node type2");
  1169. }
  1170. }
  1171. }
  1172. #ifndef XASMCONSTREGS
  1173. #define XASMCONSTREGS(x) (-1)
  1174. #endif
  1175. /*
  1176. * Check that given constraints are valid.
  1177. */
  1178. static void
  1179. xasmconstr(NODE *p, void *arg)
  1180. {
  1181. int i;
  1182. if (p->n_op == ICON && p->n_type == STRTY)
  1183. return; /* no constraints */
  1184. if (strcmp(p->n_name, "cc") == 0 || strcmp(p->n_name, "memory") == 0)
  1185. return;
  1186. for (i = 0; i < MAXREGS; i++)
  1187. if (strcmp(rnames[i], p->n_name) == 0) {
  1188. addalledges(&ablock[i]);
  1189. return;
  1190. }
  1191. if ((i = XASMCONSTREGS(p->n_name)) < 0)
  1192. comperr("unsupported xasm constraint %s", p->n_name);
  1193. addalledges(&ablock[i]);
  1194. }
  1195. #define RUP(x) (((x)+NUMBITS-1)/NUMBITS)
  1196. #define SETCOPY(t,f,i,n) for (i = 0; i < RUP(n); i++) t[i] = f[i]
  1197. #define SETSET(t,f,i,n) for (i = 0; i < RUP(n); i++) t[i] |= f[i]
  1198. #define SETCLEAR(t,f,i,n) for (i = 0; i < RUP(n); i++) t[i] &= ~f[i]
  1199. #define SETCMP(v,t,f,i,n) for (i = 0; i < RUP(n); i++) \
  1200. if (t[i] != f[i]) v = 1
  1201. #define SETEMPTY(t,sz) memset(t, 0, BIT2BYTE(sz))
  1202. static int
  1203. deldead(NODE *p, bittype *lvar)
  1204. {
  1205. NODE *q;
  1206. int ty, rv = 0;
  1207. #define BNO(p) (regno(p) - tempmin+MAXREGS)
  1208. if (p->n_op == TEMP)
  1209. BITSET(lvar, BNO(p));
  1210. if (asgop(p->n_op) && p->n_left->n_op == TEMP &&
  1211. TESTBIT(lvar, BNO(p->n_left)) == 0) {
  1212. /*
  1213. * Not live, must delete the right tree at least
  1214. * down to next statement with side effects.
  1215. */
  1216. BDEBUG(("DCE deleting temp %d\n", regno(p->n_left)));
  1217. nfree(p->n_left);
  1218. q = p->n_right;
  1219. *p = *q;
  1220. nfree(q);
  1221. rv = 1;
  1222. }
  1223. ty = optype(p->n_op);
  1224. if (ty != LTYPE)
  1225. rv |= deldead(p->n_left, lvar);
  1226. if (ty == BITYPE)
  1227. rv |= deldead(p->n_right, lvar);
  1228. return rv;
  1229. }
  1230. /*
  1231. * Do dead code elimination.
  1232. */
  1233. static int
  1234. dce(struct p2env *p2e)
  1235. {
  1236. extern struct interpass prepole;
  1237. struct basicblock *bb;
  1238. struct interpass *ip;
  1239. NODE *p;
  1240. bittype *lvar;
  1241. int i, bbnum, fix = 0;
  1242. BDEBUG(("Entering DCE\n"));
  1243. /*
  1244. * Traverse over the basic blocks.
  1245. * if an assignment is found that writes to a temporary
  1246. * that is not live out, remove that assignment and its legs.
  1247. */
  1248. DLIST_INIT(&prepole, qelem);
  1249. BITALLOC(lvar, tmpalloc, xbits);
  1250. DLIST_FOREACH(bb, &p2e->bblocks, bbelem) {
  1251. bbnum = bb->bbnum;
  1252. BBDEBUG(("DCE bblock %d, start %p last %p\n",
  1253. bbnum, bb->first, bb->last));
  1254. SETCOPY(lvar, out[bbnum], i, xbits);
  1255. for (ip = bb->last; ; ip = DLIST_PREV(ip, qelem)) {
  1256. if (ip->type == IP_NODE && deldead(ip->ip_node, lvar)) {
  1257. if ((p = deluseless(ip->ip_node)) == NULL) {
  1258. struct interpass *previp;
  1259. struct basicblock *prevbb;
  1260. if (ip == bb->first && ip == bb->last) {
  1261. /* Remove basic block */
  1262. previp = DLIST_PREV(ip, qelem);
  1263. DLIST_REMOVE(ip, qelem);
  1264. prevbb = DLIST_PREV(bb, bbelem);
  1265. DLIST_REMOVE(bb, bbelem);
  1266. bb = prevbb;
  1267. } else if (ip == bb->first) {
  1268. bb->first =
  1269. DLIST_NEXT(ip, qelem);
  1270. DLIST_REMOVE(ip, qelem);
  1271. } else if (ip == bb->last) {
  1272. previp = DLIST_PREV(ip, qelem);
  1273. DLIST_REMOVE(ip, qelem);
  1274. bb->last = previp;
  1275. bb = DLIST_PREV(bb, bbelem);
  1276. } else {
  1277. previp = DLIST_NEXT(ip, qelem);
  1278. DLIST_REMOVE(ip, qelem);
  1279. ip = previp;
  1280. fix++;
  1281. continue;
  1282. }
  1283. fix++;
  1284. BDEBUG(("bb %d: DCE ip %p deleted\n",
  1285. bbnum, ip));
  1286. break;
  1287. } else while (!DLIST_ISEMPTY(&prepole, qelem)) {
  1288. BDEBUG(("bb %d: DCE doing ip prepend\n", bbnum));
  1289. #ifdef notyet
  1290. struct interpass *tipp;
  1291. tipp = DLIST_NEXT(&prepole, qelem);
  1292. DLIST_REMOVE(tipp, qelem);
  1293. DLIST_INSERT_BEFORE(ip, tipp, qelem);
  1294. if (ip == bb->first)
  1295. bb->first = tipp;
  1296. fix++;
  1297. #else
  1298. comperr("dce needs bb fixup");
  1299. #endif
  1300. BDEBUG(("DCE ip prepended\n"));
  1301. }
  1302. if (ip->type == IP_NODE) {
  1303. geninsn(p, FOREFF);
  1304. nsucomp(p);
  1305. ip->ip_node = p;
  1306. }
  1307. }
  1308. if (ip == bb->first)
  1309. break;
  1310. }
  1311. }
  1312. BDEBUG(("DCE fix %d\n", fix));
  1313. return fix;
  1314. }
  1315. /*
  1316. * Set/clear long term liveness for regs and temps.
  1317. */
  1318. static void
  1319. unionize(NODE *p, int bb)
  1320. {
  1321. int i, o, ty;
  1322. if ((o = p->n_op) == TEMP) {
  1323. #ifdef notyet
  1324. for (i = 0; i < szty(p->n_type); i++) {
  1325. BITSET(gen[bb], (regno(p) - tempmin+i+MAXREGS));
  1326. }
  1327. #else
  1328. i = 0;
  1329. BITSET(gen[bb], (regno(p) - tempmin+i+MAXREGS));
  1330. #endif
  1331. } else if (VALIDREG(p)) {
  1332. BITSET(gen[bb], regno(p));
  1333. }
  1334. if (asgop(o)) {
  1335. if (p->n_left->n_op == TEMP) {
  1336. int b = regno(p->n_left) - tempmin+MAXREGS;
  1337. #ifdef notyet
  1338. for (i = 0; i < szty(p->n_type); i++) {
  1339. BITCLEAR(gen[bb], (b+i));
  1340. BITSET(killed[bb], (b+i));
  1341. }
  1342. #else
  1343. i = 0;
  1344. BITCLEAR(gen[bb], (b+i));
  1345. BITSET(killed[bb], (b+i));
  1346. #endif
  1347. unionize(p->n_right, bb);
  1348. return;
  1349. } else if (VALIDREG(p->n_left)) {
  1350. int b = regno(p->n_left);
  1351. BITCLEAR(gen[bb], b);
  1352. BITSET(killed[bb], b);
  1353. unionize(p->n_right, bb);
  1354. return;
  1355. }
  1356. }
  1357. ty = optype(o);
  1358. if (ty != LTYPE)
  1359. unionize(p->n_left, bb);
  1360. if (ty == BITYPE)
  1361. unionize(p->n_right, bb);
  1362. }
  1363. /*
  1364. * Do variable liveness analysis. Only analyze the long-lived
  1365. * variables, and save the live-on-exit temporaries in a bit-field
  1366. * at the end of each basic block. This bit-field is later used
  1367. * when doing short-range liveness analysis in Build().
  1368. */
  1369. static void
  1370. LivenessAnalysis(struct p2env *p2e)
  1371. {
  1372. struct basicblock *bb;
  1373. struct interpass *ip;
  1374. int bbnum;
  1375. /*
  1376. * generate the gen-killed sets for all basic blocks.
  1377. */
  1378. DLIST_FOREACH(bb, &p2e->bblocks, bbelem) {
  1379. bbnum = bb->bbnum;
  1380. for (ip = bb->last; ; ip = DLIST_PREV(ip, qelem)) {
  1381. /* gen/killed is 'p', this node is 'n' */
  1382. if (ip->type == IP_NODE) {
  1383. if (ip->ip_node->n_op == XASM)
  1384. flist(ip->ip_node->n_left,
  1385. xasmionize, &bbnum);
  1386. else
  1387. unionize(ip->ip_node, bbnum);
  1388. }
  1389. if (ip == bb->first)
  1390. break;
  1391. }
  1392. memcpy(in[bbnum], gen[bbnum], BIT2BYTE(xbits));
  1393. #ifdef PCC_DEBUG
  1394. #define PRTRG(x) printf("%d ", x < MAXREGS ? x : x + tempmin-MAXREGS)
  1395. if (rdebug) {
  1396. int i;
  1397. printf("basic block %d\ngen: ", bbnum);
  1398. for (i = 0; i < xbits; i++)
  1399. if (TESTBIT(gen[bbnum], i))
  1400. PRTRG(i);
  1401. printf("\nkilled: ");
  1402. for (i = 0; i < xbits; i++)
  1403. if (TESTBIT(killed[bbnum], i))
  1404. PRTRG(i);
  1405. printf("\n");
  1406. }
  1407. #endif
  1408. }
  1409. }
  1410. /*
  1411. * Build the set of interference edges and adjacency list.
  1412. */
  1413. static void
  1414. Build(struct p2env *p2e)
  1415. {
  1416. struct interpass *ipole = &p2e->ipole;
  1417. struct basicblock bbfake;
  1418. struct interpass *ip;
  1419. struct basicblock *bb;
  1420. bittype *saved;
  1421. int i, j, again;
  1422. if (xtemps == 0) {
  1423. /*
  1424. * No basic block splitup is done if not optimizing,
  1425. * so fake one basic block to keep the liveness analysis
  1426. * happy.
  1427. */
  1428. p2e->nbblocks = 1;
  1429. bbfake.bbnum = 0;
  1430. bbfake.last = DLIST_PREV(ipole, qelem);
  1431. bbfake.first = DLIST_NEXT(ipole, qelem);
  1432. DLIST_INIT(&p2e->bblocks, bbelem);
  1433. DLIST_INSERT_AFTER(&p2e->bblocks, &bbfake, bbelem);
  1434. bbfake.ch[0] = bbfake.ch[1] = NULL;
  1435. }
  1436. /* Just fetch space for the temporaries from stack */
  1437. gen = tmpalloc(p2e->nbblocks*sizeof(bittype*));
  1438. killed = tmpalloc(p2e->nbblocks*sizeof(bittype*));
  1439. in = tmpalloc(p2e->nbblocks*sizeof(bittype*));
  1440. out = tmpalloc(p2e->nbblocks*sizeof(bittype*));
  1441. for (i = 0; i < p2e->nbblocks; i++) {
  1442. BITALLOC(gen[i],tmpalloc,xbits);
  1443. BITALLOC(killed[i],tmpalloc,xbits);
  1444. BITALLOC(in[i],tmpalloc,xbits);
  1445. BITALLOC(out[i],tmpalloc,xbits);
  1446. }
  1447. BITALLOC(saved,tmpalloc,xbits);
  1448. SLIST_INIT(&nothead);
  1449. livagain:
  1450. LivenessAnalysis(p2e);
  1451. /* register variable temporaries are live */
  1452. for (i = 0; i < NPERMREG-1; i++) {
  1453. if (nsavregs[i])
  1454. continue;
  1455. BITSET(out[p2e->nbblocks-1], (i+MAXREGS));
  1456. for (j = i+1; j < NPERMREG-1; j++) {
  1457. if (nsavregs[j])
  1458. continue;
  1459. AddEdge(&nblock[i+tempmin], &nblock[j+tempmin]);
  1460. }
  1461. }
  1462. /* do liveness analysis on basic block level */
  1463. do {
  1464. again = 0;
  1465. /* XXX - loop should be in reversed execution-order */
  1466. DLIST_FOREACH_REVERSE(bb, &p2e->bblocks, bbelem) {
  1467. i = bb->bbnum;
  1468. SETCOPY(saved, out[i], j, xbits);
  1469. if (bb->ch[0])
  1470. SETSET(out[i], in[bb->ch[0]->bblock->bbnum], j, xbits);
  1471. if (bb->ch[1])
  1472. SETSET(out[i], in[bb->ch[1]->bblock->bbnum], j, xbits);
  1473. SETCMP(again, saved, out[i], j, xbits);
  1474. SETCOPY(saved, in[i], j, xbits);
  1475. SETCOPY(in[i], out[i], j, xbits);
  1476. SETCLEAR(in[i], killed[i], j, xbits);
  1477. SETSET(in[i], gen[i], j, xbits);
  1478. SETCMP(again, saved, in[i], j, xbits);
  1479. }
  1480. } while (again);
  1481. #ifdef PCC_DEBUG
  1482. if (rdebug) {
  1483. DLIST_FOREACH(bb, &p2e->bblocks, bbelem) {
  1484. printf("basic block %d\nin: ", bb->bbnum);
  1485. for (i = 0; i < xbits; i++)
  1486. if (TESTBIT(in[bb->bbnum], i))
  1487. PRTRG(i);
  1488. printf("\nout: ");
  1489. for (i = 0; i < xbits; i++)
  1490. if (TESTBIT(out[bb->bbnum], i))
  1491. PRTRG(i);
  1492. printf("\n");
  1493. }
  1494. }
  1495. #endif
  1496. if (xtemps && xdce) {
  1497. /*
  1498. * Do dead code elimination by using live out.
  1499. * Ignores if any variable read from is marked volatile,
  1500. * but what it should do is unspecified anyway.
  1501. * Liveness Analysis should be done in optim2 instead.
  1502. *
  1503. * This should recalculate the basic block structure.
  1504. */
  1505. if (dce(p2e)) {
  1506. /* Clear bitfields */
  1507. for (i = 0; i < p2e->nbblocks; i++) {
  1508. SETEMPTY(gen[i],xbits);
  1509. SETEMPTY(killed[i],xbits);
  1510. SETEMPTY(in[i],xbits);
  1511. SETEMPTY(out[i],xbits);
  1512. }
  1513. SETEMPTY(saved,xbits);
  1514. goto livagain;
  1515. }
  1516. }
  1517. DLIST_FOREACH(bb, &p2e->bblocks, bbelem) {
  1518. RDEBUG(("liveadd bb %d\n", bb->bbnum));
  1519. i = bb->bbnum;
  1520. for (j = 0; j < xbits; j += NUMBITS)
  1521. live[j/NUMBITS] = 0;
  1522. SETCOPY(live, out[i], j, xbits);
  1523. for (ip = bb->last; ; ip = DLIST_PREV(ip, qelem)) {
  1524. if (ip->type == IP_NODE) {
  1525. if (ip->ip_node->n_op == XASM) {
  1526. flist(ip->ip_node->n_right,
  1527. xasmconstr, 0);
  1528. listf(ip->ip_node->n_left, setxarg);
  1529. listf(ip->ip_node->n_left, delcl);
  1530. } else
  1531. insnwalk(ip->ip_node);
  1532. }
  1533. if (ip == bb->first)
  1534. break;
  1535. }
  1536. }
  1537. #ifdef PCC_DEBUG
  1538. if (rdebug) {
  1539. struct AdjSet *w;
  1540. ADJL *x;
  1541. REGW *y;
  1542. MOVL *m;
  1543. printf("Interference edges\n");
  1544. for (i = 0; i < HASHSZ; i++) {
  1545. if ((w = edgehash[i]) == NULL)
  1546. continue;
  1547. for (; w; w = w->next)
  1548. printf("%d <-> %d\n", ASGNUM(w->u), ASGNUM(w->v));
  1549. }
  1550. printf("Degrees\n");
  1551. DLIST_FOREACH(y, &initial, link) {
  1552. printf("%d (%c): trivial [%d] ", ASGNUM(y),
  1553. CLASS(y)+'@', trivially_colorable(y));
  1554. i = 0;
  1555. for (x = ADJLIST(y); x; x = x->r_next) {
  1556. if (ONLIST(x->a_temp) != &selectStack &&
  1557. ONLIST(x->a_temp) != &coalescedNodes)
  1558. printf("%d ", ASGNUM(x->a_temp));
  1559. else
  1560. printf("(%d) ", ASGNUM(x->a_temp));
  1561. i++;
  1562. }
  1563. printf(": n=%d\n", i);
  1564. }
  1565. printf("Move nodes\n");
  1566. DLIST_FOREACH(y, &initial, link) {
  1567. if (MOVELIST(y) == NULL)
  1568. continue;
  1569. printf("%d: ", ASGNUM(y));
  1570. for (m = MOVELIST(y); m; m = m->next) {
  1571. REGW *yy = m->regm->src == y ?
  1572. m->regm->dst : m->regm->src;
  1573. printf("%d ", ASGNUM(yy));
  1574. }
  1575. printf("\n");
  1576. }
  1577. }
  1578. #endif
  1579. }
  1580. static void
  1581. EnableMoves(REGW *n)
  1582. {
  1583. MOVL *l;
  1584. REGM *m;
  1585. for (l = MOVELIST(n); l; l = l->next) {
  1586. m = l->regm;
  1587. if (m->queue != ACTIVE)
  1588. continue;
  1589. DLIST_REMOVE(m, link);
  1590. PUSHMLIST(m, worklistMoves, WLIST);
  1591. }
  1592. }
  1593. static void
  1594. EnableAdjMoves(REGW *nodes)
  1595. {
  1596. ADJL *w;
  1597. REGW *n;
  1598. EnableMoves(nodes);
  1599. for (w = ADJLIST(nodes); w; w = w->r_next) {
  1600. n = w->a_temp;
  1601. if (ONLIST(n) == &selectStack || ONLIST(n) == &coalescedNodes)
  1602. continue;
  1603. EnableMoves(w->a_temp);
  1604. }
  1605. }
  1606. /*
  1607. * Decrement the degree of node w for class c.
  1608. */
  1609. static void
  1610. DecrementDegree(REGW *w, int c)
  1611. {
  1612. int wast;
  1613. #ifdef PCC_DEBUG
  1614. RRDEBUG(("DecrementDegree: w %d, c %d\n", ASGNUM(w), c));
  1615. #endif
  1616. wast = trivially_colorable(w);
  1617. NCLASS(w, c)--;
  1618. if (wast == trivially_colorable(w))
  1619. return;
  1620. EnableAdjMoves(w);
  1621. DELWLIST(w);
  1622. ONLIST(w) = 0;
  1623. if (MoveRelated(w)) {
  1624. PUSHWLIST(w, freezeWorklist);
  1625. } else {
  1626. PUSHWLIST(w, simplifyWorklist);
  1627. }
  1628. }
  1629. static void
  1630. Simplify(void)
  1631. {
  1632. REGW *w;
  1633. ADJL *l;
  1634. w = POPWLIST(simplifyWorklist);
  1635. PUSHWLIST(w, selectStack);
  1636. #ifdef PCC_DEBUG
  1637. RDEBUG(("Simplify: node %d class %d\n", ASGNUM(w), w->r_class));
  1638. #endif
  1639. l = w->r_adjList;
  1640. for (; l; l = l->r_next) {
  1641. if (ONLIST(l->a_temp) == &selectStack ||
  1642. ONLIST(l->a_temp) == &coalescedNodes)
  1643. continue;
  1644. DecrementDegree(l->a_temp, w->r_class);
  1645. }
  1646. }
  1647. static REGW *
  1648. GetAlias(REGW *n)
  1649. {
  1650. if (ONLIST(n) == &coalescedNodes)
  1651. return GetAlias(ALIAS(n));
  1652. return n;
  1653. }
  1654. static int
  1655. OK(REGW *t, REGW *r)
  1656. {
  1657. #ifdef PCC_DEBUG
  1658. RDEBUG(("OK: t %d CLASS(t) %d adjSet(%d,%d)=%d\n",
  1659. ASGNUM(t), CLASS(t), ASGNUM(t), ASGNUM(r), adjSet(t, r)));
  1660. if (rdebug > 1) {
  1661. ADJL *w;
  1662. int ndeg = 0;
  1663. printf("OK degree: ");
  1664. for (w = ADJLIST(t); w; w = w->r_next) {
  1665. if (ONLIST(w->a_temp) != &selectStack &&
  1666. ONLIST(w->a_temp) != &coalescedNodes)
  1667. printf("%c%d ", CLASS(w->a_temp)+'@',
  1668. ASGNUM(w->a_temp)), ndeg++;
  1669. else
  1670. printf("(%d) ", ASGNUM(w->a_temp));
  1671. }
  1672. printf("\n");
  1673. #if 0
  1674. if (ndeg != DEGREE(t) && DEGREE(t) >= 0)
  1675. printf("!!!ndeg %d != DEGREE(t) %d\n", ndeg, DEGREE(t));
  1676. #endif
  1677. }
  1678. #endif
  1679. if (trivially_colorable(t) || ONLIST(t) == &precolored ||
  1680. (adjSet(t, r) || !aliasmap(CLASS(t), COLOR(r))))/* XXX - check aliasmap */
  1681. return 1;
  1682. return 0;
  1683. }
  1684. static int
  1685. adjok(REGW *v, REGW *u)
  1686. {
  1687. ADJL *w;
  1688. REGW *t;
  1689. RDEBUG(("adjok\n"));
  1690. for (w = ADJLIST(v); w; w = w->r_next) {
  1691. t = w->a_temp;
  1692. if (ONLIST(t) == &selectStack || ONLIST(t) == &coalescedNodes)
  1693. continue;
  1694. if (OK(t, u) == 0)
  1695. return 0;
  1696. }
  1697. RDEBUG(("adjok returns OK\n"));
  1698. return 1;
  1699. }
  1700. /*
  1701. * Do a conservative estimation of whether two temporaries can
  1702. * be coalesced. This is "Briggs-style" check.
  1703. * Neither u nor v is precolored when called.
  1704. */
  1705. static int
  1706. Conservative(REGW *u, REGW *v)
  1707. {
  1708. ADJL *w, *ww;
  1709. REGW *n;
  1710. int xncl[NUMCLASS+1], mcl = 0, j;
  1711. for (j = 0; j < NUMCLASS+1; j++)
  1712. xncl[j] = 0;
  1713. /*
  1714. * Increment xncl[class] up to K for each class.
  1715. * If all classes has reached K then check colorability and return.
  1716. */
  1717. for (w = ADJLIST(u); w; w = w->r_next) {
  1718. n = w->a_temp;
  1719. if (ONLIST(n) == &selectStack || ONLIST(n) == &coalescedNodes)
  1720. continue;
  1721. if (xncl[CLASS(n)] == regK[CLASS(n)])
  1722. continue;
  1723. if (!trivially_colorable(n) || ONLIST(n) == &precolored)
  1724. xncl[CLASS(n)]++;
  1725. if (xncl[CLASS(n)] < regK[CLASS(n)])
  1726. continue;
  1727. if (++mcl == NUMCLASS)
  1728. goto out; /* cannot get more out of it */
  1729. }
  1730. for (w = ADJLIST(v); w; w = w->r_next) {
  1731. n = w->a_temp;
  1732. if (ONLIST(n) == &selectStack || ONLIST(n) == &coalescedNodes)
  1733. continue;
  1734. if (xncl[CLASS(n)] == regK[CLASS(n)])
  1735. continue;
  1736. /* ugly: have we been here already? */
  1737. for (ww = ADJLIST(u); ww; ww = ww->r_next)
  1738. if (ww->a_temp == n)
  1739. break;
  1740. if (ww)
  1741. continue;
  1742. if (!trivially_colorable(n) || ONLIST(n) == &precolored)
  1743. xncl[CLASS(n)]++;
  1744. if (xncl[CLASS(n)] < regK[CLASS(n)])
  1745. continue;
  1746. if (++mcl == NUMCLASS)
  1747. break;
  1748. }
  1749. out: j = trivially_colorable_p(CLASS(u), xncl);
  1750. return j;
  1751. }
  1752. static void
  1753. AddWorkList(REGW *w)
  1754. {
  1755. if (ONLIST(w) != &precolored && !MoveRelated(w) &&
  1756. trivially_colorable(w)) {
  1757. DELWLIST(w);
  1758. PUSHWLIST(w, simplifyWorklist);
  1759. }
  1760. }
  1761. static void
  1762. Combine(REGW *u, REGW *v)
  1763. {
  1764. MOVL *m;
  1765. ADJL *l;
  1766. REGW *t;
  1767. #ifdef PCC_DEBUG
  1768. RDEBUG(("Combine (%d,%d)\n", ASGNUM(u), ASGNUM(v)));
  1769. #endif
  1770. if (ONLIST(v) == &freezeWorklist) {
  1771. DELWLIST(v);
  1772. } else {
  1773. DELWLIST(v);
  1774. }
  1775. PUSHWLIST(v, coalescedNodes);
  1776. ALIAS(v) = u;
  1777. #ifdef PCC_DEBUG
  1778. if (rdebug) {
  1779. printf("adjlist(%d): ", ASGNUM(v));
  1780. for (l = ADJLIST(v); l; l = l->r_next)
  1781. printf("%d ", l->a_temp->nodnum);
  1782. printf("\n");
  1783. }
  1784. #endif
  1785. #if 1
  1786. {
  1787. MOVL *m0 = MOVELIST(v);
  1788. for (m0 = MOVELIST(v); m0; m0 = m0->next) {
  1789. for (m = MOVELIST(u); m; m = m->next)
  1790. if (m->regm == m0->regm)
  1791. break; /* Already on list */
  1792. if (m)
  1793. continue; /* already on list */
  1794. MOVELISTADD(u, m0->regm);
  1795. }
  1796. }
  1797. #else
  1798. if ((m = MOVELIST(u))) {
  1799. while (m->next)
  1800. m = m->next;
  1801. m->next = MOVELIST(v);
  1802. } else
  1803. MOVELIST(u) = MOVELIST(v);
  1804. #endif
  1805. EnableMoves(v);
  1806. for (l = ADJLIST(v); l; l = l->r_next) {
  1807. t = l->a_temp;
  1808. if (ONLIST(t) == &selectStack || ONLIST(t) == &coalescedNodes)
  1809. continue;
  1810. /* Do not add edge if u cannot affect the colorability of t */
  1811. /* XXX - check aliasmap */
  1812. if (ONLIST(u) != &precolored || aliasmap(CLASS(t), COLOR(u)))
  1813. AddEdge(t, u);
  1814. DecrementDegree(t, CLASS(v));
  1815. }
  1816. if (!trivially_colorable(u) && ONLIST(u) == &freezeWorklist) {
  1817. DELWLIST(u);
  1818. PUSHWLIST(u, spillWorklist);
  1819. }
  1820. #ifdef PCC_DEBUG
  1821. if (rdebug) {
  1822. ADJL *w;
  1823. printf("Combine %d class (%d): ", ASGNUM(u), CLASS(u));
  1824. for (w = ADJLIST(u); w; w = w->r_next) {
  1825. if (ONLIST(w->a_temp) != &selectStack &&
  1826. ONLIST(w->a_temp) != &coalescedNodes)
  1827. printf("%d ", ASGNUM(w->a_temp));
  1828. else
  1829. printf("(%d) ", ASGNUM(w->a_temp));
  1830. }
  1831. printf("\n");
  1832. }
  1833. #endif
  1834. }
  1835. static void
  1836. Coalesce(void)
  1837. {
  1838. REGM *m;
  1839. REGW *x, *y, *u, *v;
  1840. m = POPMLIST(worklistMoves);
  1841. x = GetAlias(m->src);
  1842. y = GetAlias(m->dst);
  1843. if (ONLIST(y) == &precolored)
  1844. u = y, v = x;
  1845. else
  1846. u = x, v = y;
  1847. #ifdef PCC_DEBUG
  1848. RDEBUG(("Coalesce: src %d dst %d u %d v %d x %d y %d\n",
  1849. ASGNUM(m->src), ASGNUM(m->dst), ASGNUM(u), ASGNUM(v),
  1850. ASGNUM(x), ASGNUM(y)));
  1851. #endif
  1852. if (CLASS(m->src) != CLASS(m->dst))
  1853. comperr("Coalesce: src class %d, dst class %d",
  1854. CLASS(m->src), CLASS(m->dst));
  1855. if (u == v) {
  1856. RDEBUG(("Coalesce: u == v\n"));
  1857. PUSHMLIST(m, coalescedMoves, COAL);
  1858. AddWorkList(u);
  1859. } else if (ONLIST(v) == &precolored || adjSet(u, v)) {
  1860. RDEBUG(("Coalesce: constrainedMoves\n"));
  1861. PUSHMLIST(m, constrainedMoves, CONSTR);
  1862. AddWorkList(u);
  1863. AddWorkList(v);
  1864. } else if ((ONLIST(u) == &precolored && adjok(v, u)) ||
  1865. (ONLIST(u) != &precolored && Conservative(u, v))) {
  1866. RDEBUG(("Coalesce: Conservative\n"));
  1867. PUSHMLIST(m, coalescedMoves, COAL);
  1868. Combine(u, v);
  1869. AddWorkList(u);
  1870. } else {
  1871. RDEBUG(("Coalesce: activeMoves\n"));
  1872. PUSHMLIST(m, activeMoves, ACTIVE);
  1873. }
  1874. }
  1875. static void
  1876. coalasg(NODE *p, void *arg)
  1877. {
  1878. NODE *l;
  1879. REGW *u;
  1880. if (p->n_op != ASSIGN || p->n_regw == NULL)
  1881. return;
  1882. l = p->n_left;
  1883. if (l->n_op == TEMP)
  1884. u = &nblock[regno(l)];
  1885. else if (l->n_op == REG)
  1886. u = &ablock[regno(l)];
  1887. else
  1888. return;
  1889. Combine(u, p->n_regw);
  1890. AddWorkList(u);
  1891. }
  1892. /*
  1893. * Coalesce assign to a left reg with the assign temp node itself.
  1894. * This has to be done before anything else.
  1895. */
  1896. static void
  1897. Coalassign(struct p2env *p2e)
  1898. {
  1899. struct interpass *ip;
  1900. DLIST_FOREACH(ip, &p2env.ipole, qelem) {
  1901. if (ip->type == IP_NODE)
  1902. walkf(ip->ip_node, coalasg, 0);
  1903. }
  1904. }
  1905. static void
  1906. FreezeMoves(REGW *u)
  1907. {
  1908. MOVL *w, *o;
  1909. REGM *m;
  1910. REGW *z;
  1911. REGW *x, *y, *v;
  1912. for (w = MOVELIST(u); w; w = w->next) {
  1913. m = w->regm;
  1914. if (m->queue != WLIST && m->queue != ACTIVE)
  1915. continue;
  1916. x = m->src;
  1917. y = m->dst;
  1918. if (GetAlias(y) == GetAlias(u))
  1919. v = GetAlias(x);
  1920. else
  1921. v = GetAlias(y);
  1922. #ifdef PCC_DEBUG
  1923. RDEBUG(("FreezeMoves: u %d (%d,%d) v %d\n",
  1924. ASGNUM(u),ASGNUM(x),ASGNUM(y),ASGNUM(v)));
  1925. #endif
  1926. DLIST_REMOVE(m, link);
  1927. PUSHMLIST(m, frozenMoves, FROZEN);
  1928. if (ONLIST(v) != &freezeWorklist)
  1929. continue;
  1930. for (o = MOVELIST(v); o; o = o->next)
  1931. if (o->regm->queue == WLIST || o->regm->queue == ACTIVE)
  1932. break;
  1933. if (o == NULL) {
  1934. z = v;
  1935. DELWLIST(z);
  1936. PUSHWLIST(z, simplifyWorklist);
  1937. }
  1938. }
  1939. }
  1940. static void
  1941. Freeze(void)
  1942. {
  1943. REGW *u;
  1944. /*
  1945. * To find out:
  1946. * Check if the moves to freeze have exactly the same
  1947. * interference edges. If they do, coalesce them instead, it
  1948. * may free up other nodes that they interfere with.
  1949. */
  1950. /*
  1951. * Select nodes to freeze first by using following criteria:
  1952. * - Trivially colorable
  1953. * - Single or few moves to less trivial nodes.
  1954. */
  1955. DLIST_FOREACH(u, &freezeWorklist, link) {
  1956. if (u >= &nblock[tempmax] || u < &nblock[tempmin])
  1957. continue; /* No short range temps */
  1958. if (!trivially_colorable(u))
  1959. continue; /* Prefer colorable nodes */
  1960. /* Check for at most two move-related nodes */
  1961. if (u->r_moveList->next && u->r_moveList->next->next)
  1962. continue;
  1963. /* Ok, remove node */
  1964. DLIST_REMOVE(u, link);
  1965. u->r_onlist = 0;
  1966. break;
  1967. }
  1968. if (u == &freeze

Large files files are truncated, but you can click here to view the full file