bound.c 16 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117
  1. #include "gc.h"
  2. #include "bound.h"
  3. static BB* bbfree;
  4. static BBset* bbsfree;
  5. static int bballoc;
  6. static int bbsalloc;
  7. static BB bbz;
  8. static BBset bbsz;
  9. static BB* firstbb;
  10. static BB* lastbb;
  11. static BB* wounded;
  12. static BB* bbaux;
  13. static BBset* recalc;
  14. static BBset* bbhash[BBHASH];
  15. static BB** ordered;
  16. static int bcount;
  17. static BBset** heap;
  18. static int heapn;
  19. static int bsize;
  20. static char bbbuff[BBBSIZE];
  21. static int bchange;
  22. #define bdebug (debug['v'])
  23. #define dbg 0
  24. #define bcheck 0
  25. static long
  26. Rn(Reg *r)
  27. {
  28. if(r == R)
  29. return -1;
  30. return r->rpo;
  31. }
  32. static BB*
  33. bba(void)
  34. {
  35. BB *b;
  36. bballoc++;
  37. b = bbfree;
  38. if(b == nil) {
  39. b = alloc(sizeof(*b));
  40. } else
  41. bbfree = b->link;
  42. *b = bbz;
  43. return b;
  44. }
  45. static void
  46. bfree(BB *b)
  47. {
  48. bballoc--;
  49. b->link = bbfree;
  50. bbfree = b;
  51. }
  52. static BBset*
  53. bbsa(void)
  54. {
  55. BBset *b;
  56. bballoc++;
  57. b = bbsfree;
  58. if(b == nil) {
  59. b = alloc(sizeof(*b));
  60. } else
  61. bbsfree = b->link;
  62. *b = bbsz;
  63. return b;
  64. }
  65. static void
  66. bsfree(BBset *b)
  67. {
  68. bballoc--;
  69. b->link = bbsfree;
  70. bbsfree = b;
  71. }
  72. static void
  73. dumpheap(void)
  74. {
  75. int i;
  76. for(i = 1; i <= heapn; i++)
  77. print(" %d", heap[i]->damage);
  78. }
  79. static void
  80. checkheap(void)
  81. {
  82. int N, N2, n, c;
  83. N = heapn;
  84. N2 = N >> 1;
  85. for(n = 1; n <= N2; n++) {
  86. c = n << 1;
  87. if((heap[c]->damage > heap[n]->damage)
  88. || ((c < N) && (heap[c + 1]->damage > heap[n]->damage))) {
  89. print("bad heap (%d:%d) %d [", n, heap[n]->damage, heapn);
  90. dumpheap();
  91. print(" ]\n");
  92. abort();
  93. }
  94. }
  95. }
  96. static void
  97. downheap(int n)
  98. {
  99. int N, N2, d, c;
  100. BBset *s, *t, *u;
  101. s = heap[n];
  102. d = s->damage;
  103. //print("down %d %d", n, d);
  104. N = heapn;
  105. N2 = N >> 1;
  106. while(n <= N2) {
  107. c = n << 1;
  108. t = heap[c];
  109. if(c < N) {
  110. u = heap[c + 1];
  111. if(t->damage < u->damage) {
  112. t = u;
  113. c++;
  114. }
  115. }
  116. //print(" [%d %d]", c, t->damage);
  117. if(t->damage < d)
  118. break;
  119. heap[n] = t;
  120. t->index = n;
  121. n = c;
  122. }
  123. heap[n] = s;
  124. s->index = n;
  125. //print("\n");
  126. //checkheap();
  127. }
  128. static void
  129. upheap(int n)
  130. {
  131. int f, d;
  132. BBset *s, *t;
  133. s = heap[n];
  134. d = s->damage;
  135. //print("up %d %d", n, d);
  136. while(n > 1) {
  137. f = n >> 1;
  138. t = heap[f];
  139. //print(" [%d %d]", f, t->damage);
  140. if(t->damage >= d)
  141. break;
  142. heap[n] = t;
  143. t->index = n;
  144. n = f;
  145. }
  146. heap[n] = s;
  147. s->index = n;
  148. //print("\n");
  149. //checkheap();
  150. }
  151. static void
  152. heapremove(BBset *s)
  153. {
  154. int x;
  155. BBset *t;
  156. x = s->index;
  157. s->index = 0;
  158. if(x == 0)
  159. return;
  160. if(x == heapn) {
  161. heapn--;
  162. return;
  163. }
  164. t = heap[heapn--];
  165. heap[x] = t;
  166. t->index = x;
  167. if(s->damage < t->damage)
  168. upheap(x);
  169. else
  170. downheap(x);
  171. }
  172. static void
  173. heapadd(BBset *s)
  174. {
  175. int n;
  176. n = heapn + 1;
  177. heap[n] = s;
  178. s->index = n;
  179. heapn = n;
  180. upheap(n);
  181. }
  182. static void
  183. bbsrecalc(BBset *s)
  184. {
  185. if(s->recalc)
  186. return;
  187. s->recalc = 1;
  188. s->link = recalc;
  189. recalc = s;
  190. heapremove(s);
  191. }
  192. static void
  193. bbadd(BB *b, Hval h)
  194. {
  195. int k;
  196. BBset *s;
  197. k = h[0] & BBMASK;
  198. for(s = bbhash[k]; s != nil; s = s->next) {
  199. if(BBEQ(s->hash, h)) {
  200. b->set = s;
  201. b->link = s->ents;
  202. s->ents = b;
  203. bbsrecalc(s);
  204. return;
  205. }
  206. }
  207. s = bbsa();
  208. s->next = bbhash[k];
  209. bbhash[k] = s;
  210. b->set = s;
  211. b->link = nil;
  212. s->ents = b;
  213. BBCP(s->hash, h);
  214. bbsrecalc(s);
  215. }
  216. static int
  217. hashbb(BB *b, Hval h)
  218. {
  219. Reg *r;
  220. Prog *p;
  221. char *s;
  222. int c, f, i, n;
  223. r = b->first;
  224. s = bbbuff;
  225. i = 0;
  226. n = BBBSIZE;
  227. for(;;) {
  228. p = r->prog;
  229. if(p->as != ANOP) {
  230. if(p->to.type == D_BRANCH)
  231. p->to.offset = r->s2->rpo;
  232. c = snprint(s, n, "%P", p);
  233. s += c;
  234. n -= c;
  235. i++;
  236. }
  237. if(r == b->last)
  238. break;
  239. r = r->link;
  240. }
  241. if(n == 0)
  242. return Bbig;
  243. b->len = i;
  244. BBMKHASH(bbbuff, BBBSIZE - n, h);
  245. f = b->flags;
  246. if(i == 1 && r->prog->as == AJMP && b->first->p1 == R)
  247. f = Bjo;
  248. else if(b->first->p1 != R)
  249. f |= Bpre;
  250. if(bdebug)
  251. print("A %x %s %ux %ux\n", f, bbbuff, h[0], h[1]);
  252. return f;
  253. }
  254. static void
  255. enterbb(BB *b)
  256. {
  257. Hval h;
  258. b->flags = hashbb(b, h);
  259. if(b->flags != Bbig)
  260. bbadd(b, h);
  261. }
  262. static void
  263. preproc(BB *b, int x)
  264. {
  265. BB *n;
  266. Reg *r;
  267. ordered[x] = b;
  268. if(b->last->rpo - b->first->rpo > BBBIG) {
  269. b->flags = Bbig;
  270. return;
  271. }
  272. if(b->first->p2 == nil) {
  273. b->flags = Bdel;
  274. return;
  275. }
  276. switch(b->last->prog->as) {
  277. case ARET:
  278. case AJMP:
  279. case AIRETL:
  280. break;
  281. default:
  282. b->flags = Bdel;
  283. n = bba();
  284. n->first = b->first;
  285. for(r = b->last->link; r != R; r = r->link) {
  286. switch(r->prog->as) {
  287. case ARET:
  288. case AJMP:
  289. case AIRETL:
  290. n->last = r;
  291. n->flags = Bpin;
  292. enterbb(n);
  293. if(n->flags & Bpin) {
  294. n->aux = bbaux;
  295. bbaux = n;
  296. }
  297. else
  298. bfree(n);
  299. return;
  300. }
  301. }
  302. bfree(n);
  303. return;
  304. }
  305. enterbb(b);
  306. }
  307. static int
  308. p2len(Reg *r)
  309. {
  310. int c;
  311. c = 0;
  312. for(r = r->p2; r != nil; r = r->p2link)
  313. c++;
  314. return c;
  315. }
  316. static void
  317. calcdamage(BBset *s)
  318. {
  319. BB *f;
  320. int d, t;
  321. s->recalc = 0;
  322. f = s->ents;
  323. if(f == nil)
  324. return;
  325. if(f->flags & Bjo) {
  326. if(bdebug)
  327. print("add %ld jo\n", f->first->rpo);
  328. s->damage = COSTJO;
  329. heapadd(s);
  330. return;
  331. }
  332. if(f->link == nil) {
  333. if(bdebug)
  334. print("solo %x %x\n", s->hash[0], s->hash[1]);
  335. return;
  336. }
  337. d = 0;
  338. t = 0;
  339. while(f != nil) {
  340. if((f->flags & (Bpre|Bpin)) == 0 && f->last->link != R) {
  341. t = 1;
  342. d += (f->last->rpo - f->first->rpo) >> 1;
  343. }
  344. d += p2len(f->first);
  345. f = f->link;
  346. }
  347. if(t == 0) {
  348. if(bdebug)
  349. print("all pre %ld\n", s->ents->first->rpo);
  350. return;
  351. }
  352. if(bdebug)
  353. print("add %ld %d\n", s->ents->first->rpo, d);
  354. if(d > COSTHI)
  355. d = COSTHI;
  356. s->damage = d;
  357. heapadd(s);
  358. }
  359. static Reg*
  360. findjump(BB *b)
  361. {
  362. Reg *r, *l;
  363. r = b->first;
  364. l = b->last;
  365. for(;;) {
  366. if(r->prog->as == AJMP)
  367. break;
  368. if(r == l) {
  369. diag(Z, "findjump botch");
  370. break;
  371. }
  372. r = r->link;
  373. }
  374. return r;
  375. }
  376. static BB*
  377. findset(int r)
  378. {
  379. BB *s, **p;
  380. int n, n2;
  381. if(r < ordered[0]->first->rpo)
  382. return nil;
  383. n = bcount;
  384. p = ordered;
  385. while(n > 0) {
  386. n2 = n >> 1;
  387. s = p[n2];
  388. if(r < s->first->rpo) {
  389. n = n2;
  390. continue;
  391. }
  392. if(r > s->last->rpo) {
  393. n2++;
  394. p += n2;
  395. n -= n2;
  396. continue;
  397. }
  398. return s;
  399. }
  400. diag(Z, "findset botch");
  401. return nil;
  402. }
  403. static void
  404. wound(Reg *r)
  405. {
  406. BB *b, *p, **n;
  407. BBset *s;
  408. b = findset(r->rpo);
  409. if(b == nil)
  410. return;
  411. s = b->set;
  412. if(s == nil)
  413. return;
  414. for(n = &s->ents; (p = *n) != nil; n = &(*n)->link) {
  415. if(p == b) {
  416. *n = b->link;
  417. b->link = wounded;
  418. wounded = b;
  419. bbsrecalc(s);
  420. return;
  421. }
  422. }
  423. }
  424. static void
  425. printbl(Reg *l)
  426. {
  427. if(l == nil) {
  428. print("Z");
  429. return;
  430. }
  431. print("%ld", l->rpo);
  432. while((l = l->p2link) != nil)
  433. print(" %ld", l->rpo);
  434. }
  435. static void
  436. appset(Reg *e, Reg *s)
  437. {
  438. for(;;) {
  439. if(s->p2link == R) {
  440. s->p2link = e;
  441. return;
  442. }
  443. s = s->p2link;
  444. }
  445. }
  446. static Reg*
  447. delset(Reg *e, Reg *s)
  448. {
  449. Reg *c, *l;
  450. c = s;
  451. l = nil;
  452. for(;;) {
  453. if(e == c) {
  454. if(l == nil)
  455. return s->p2link;
  456. l->p2link = c->p2link;
  457. return s;
  458. }
  459. l = c;
  460. c = c->p2link;
  461. if(c == nil)
  462. return s;
  463. }
  464. }
  465. static void
  466. redest(Reg *s, Reg *d)
  467. {
  468. while(s != R) {
  469. s->s2 = d;
  470. s = s->p2link;
  471. }
  472. }
  473. static void
  474. changedest(Reg *s, Reg *d, int x)
  475. {
  476. Reg *l;
  477. if(bdebug) {
  478. print("change %ld [", s->rpo);
  479. printbl(s->p2);
  480. print("] -> %ld [", d->rpo);
  481. printbl(d->p2);
  482. print("]\n");
  483. }
  484. if(s->p2 == nil) {
  485. // print("deadjmp\n");
  486. return;
  487. }
  488. l = s->p2;
  489. for(;;) {
  490. if(bdebug)
  491. print("s2 %ld = %ld\n", l->rpo, d->rpo);
  492. l->s2 = d;
  493. wound(l);
  494. if(l->p2link == nil)
  495. break;
  496. l = l->p2link;
  497. }
  498. if(x) {
  499. l->p2link = delset(s, d->p2);
  500. d->p2 = s->p2;
  501. }
  502. else {
  503. l->p2link = d->p2;
  504. d->p2 = s->p2;
  505. s->p2 = nil;
  506. }
  507. if(bdebug) {
  508. print("result [");
  509. printbl(d->p2);
  510. print("]\n");
  511. }
  512. bchange = 1;
  513. }
  514. static void
  515. bexcise(BB *b)
  516. {
  517. Reg *r, *l;
  518. l = b->last;
  519. r = b->first;
  520. if(bdebug)
  521. print("excise %ld to %ld\n", r->rpo, l->rpo);
  522. for(;;) {
  523. r->prog->as = ANOP;
  524. r->prog->to.type = D_NONE;
  525. r->p2 = R;
  526. if(r->s2 != R) {
  527. r->s2->p2 = delset(r, r->s2->p2);
  528. r->s2 = R;
  529. }
  530. if(r == l)
  531. break;
  532. r = r->link;
  533. }
  534. }
  535. static int
  536. backtrack(Reg *s, Reg *d)
  537. {
  538. int i;
  539. char l[BINST], r[BINST];
  540. //print("backtrack %ld %ld\n", Rn(s), Rn(d));
  541. i = 0;
  542. while(s != nil && d != nil) {
  543. if(snprint(l, BINST, "%P", s->prog) == BINST)
  544. break;
  545. if(snprint(r, BINST, "%P", d->prog) == BINST)
  546. break;
  547. //print("%s\t%s\n", l, r);
  548. if(strcmp(l, r) != 0)
  549. break;
  550. i++;
  551. s = s->p2link;
  552. d = d->p2link;
  553. }
  554. return i;
  555. }
  556. static void
  557. checktails(void)
  558. {
  559. int c;
  560. Reg *r;
  561. c = 0;
  562. for(r = firstr; r->link != R; r = r->link) {
  563. if(r->prog->as == AJMP && r->s2 != nil)
  564. c += backtrack(r->p1, r->s2->p1);
  565. }
  566. if(c > 0)
  567. print("tails %s %d\n", firstr->prog->from.sym->name, c);
  568. }
  569. static void
  570. process(BBset *s)
  571. {
  572. Reg *h;
  573. BB *f, *o, *p, *t;
  574. if(bdebug)
  575. print("process %d %x %x\n", s->damage, s->hash[0], s->hash[1]);
  576. f = s->ents;
  577. if(f->flags & Bjo) {
  578. s->ents = nil;
  579. h = findjump(f)->s2;
  580. o = nil;
  581. while(f != nil) {
  582. t = f->link;
  583. if((f->flags & Bjo) != 0 && f->first->s2 != f->first) {
  584. changedest(f->first, h, 1);
  585. bexcise(f);
  586. }
  587. else {
  588. f->link = o;
  589. o = f;
  590. }
  591. f = t;
  592. }
  593. s->ents = o;
  594. }
  595. else {
  596. o = nil;
  597. p = nil;
  598. while(f != nil) {
  599. t = f->link;
  600. if((f->flags & (Bpre|Bpin)) != 0 || (f->last->link == R)) {
  601. f->link = p;
  602. p = f;
  603. }
  604. else {
  605. f->link = o;
  606. o = f;
  607. }
  608. f = t;
  609. }
  610. if(o == nil) {
  611. diag(Z, "all Bpre");
  612. return;
  613. }
  614. if(p == nil) {
  615. p = o;
  616. o = p->link;
  617. p->link = nil;
  618. s->ents = p;
  619. }
  620. else
  621. s->ents = p;
  622. h = p->first;
  623. // oblit o list repl with jmp to h
  624. while(o != nil) {
  625. changedest(o->first, h, 1);
  626. bexcise(o);
  627. o = o->link;
  628. }
  629. bbsrecalc(s);
  630. }
  631. }
  632. static void
  633. iterate(void)
  634. {
  635. BBset *s;
  636. BB *b, *t;
  637. heapn = 0;
  638. for(;;) {
  639. for(b = wounded; b != nil; b = t) {
  640. t = b->link;
  641. enterbb(b);
  642. }
  643. wounded = nil;
  644. for(s = recalc; s != nil; s = s->link)
  645. calcdamage(s);
  646. recalc = nil;
  647. if(heapn == 0)
  648. return;
  649. s = heap[1];
  650. heapremove(s);
  651. process(s);
  652. }
  653. }
  654. static void
  655. cleanup(void)
  656. {
  657. int i;
  658. BB *l, *n;
  659. BBset *b, *t;
  660. for(i = 0; i < BBHASH; i++) {
  661. b = bbhash[i];
  662. bbhash[i] = nil;
  663. while(b != nil) {
  664. t = b->next;
  665. bsfree(b);
  666. b = t;
  667. }
  668. }
  669. for(i = 0; i < bcount; i++)
  670. bfree(ordered[i]);
  671. for(l = bbaux; l != nil; l = n) {
  672. n = l->aux;
  673. bfree(l);
  674. }
  675. bbaux = nil;
  676. }
  677. static void
  678. prreg(Reg *r)
  679. {
  680. Prog *p;
  681. p = r->prog;
  682. if(p->to.type == D_BRANCH)
  683. p->to.offset = r->s2->rpo;
  684. print("%ld:%P\tr %lX ", r->rpo, r->prog, r->regu);
  685. print("p1 %ld p2 %ld p2l %ld s1 %ld s2 %ld link %ld",
  686. Rn(r->p1), Rn(r->p2), Rn(r->p2link),
  687. Rn(r->s1), Rn(r->s2), Rn(r->link));
  688. if(!r->active)
  689. print(" d");
  690. // print(" %p %p\n", r->prog, r->prog->link);
  691. print("\n");
  692. }
  693. static void prfunc(char*);
  694. static void
  695. checkr(int d)
  696. {
  697. Prog *p;
  698. Reg *r, *t;
  699. for(r = firstr; r->link != R; r = r->link) {
  700. for(p = r->prog->link; p != P && p != r->link->prog; p = p->link)
  701. ;
  702. if(p == P) {
  703. print("%ld: bad prog link\n", r->rpo);
  704. if(d)
  705. prfunc(nil);
  706. abort();
  707. }
  708. if(r->s1 != R && (r->s1 != r->link || r->link->p1 != r)) {
  709. print("%ld: bad s1 p1\n", r->rpo);
  710. if(d)
  711. prfunc(nil);
  712. abort();
  713. }
  714. if(r->s2 != R && r->s2->p2 == nil) {
  715. print("%ld: no p2 for s2\n", r->rpo);
  716. if(d)
  717. prfunc(nil);
  718. abort();
  719. }
  720. if(r->p2 != R) {
  721. t = r->p2->s2;
  722. while(t != r) {
  723. t = t->p2link;
  724. if(t == R) {
  725. print("%ld: bad s2 for p2\n", r->rpo);
  726. if(d)
  727. prfunc(nil);
  728. abort();
  729. }
  730. }
  731. }
  732. }
  733. }
  734. static void
  735. prfunc(char *s)
  736. {
  737. Reg *r;
  738. if(s != nil)
  739. print("%s structure %s\n", s, firstr->prog->from.sym->name);
  740. for(r = firstr; r != R; r = r->link)
  741. prreg(r);
  742. if(s != nil) {
  743. print("end\n");
  744. checkr(0);
  745. }
  746. }
  747. /* find p in r's list and replace with l */
  748. static void
  749. adjprog(Reg *r, Prog *p, Prog *l)
  750. {
  751. Prog *t, **n;
  752. for(n = &r->prog->link; (t = *n) != nil; n = &t->link) {
  753. if(t == p) {
  754. *n = l;
  755. return;
  756. }
  757. }
  758. print("adjprog botch\n");
  759. abort();
  760. }
  761. static void
  762. jumptojump(void)
  763. {
  764. Reg *r;
  765. for(r = firstr; r != R; r = r->link) {
  766. if(r->prog->as == AJMP && r->p2 != R && r->s2 != r) {
  767. if(bdebug)
  768. print("jump as dest %ld -> %ld\n", r->rpo, r->s2->rpo);
  769. changedest(r, r->s2, 0);
  770. bchange++;
  771. }
  772. }
  773. }
  774. /* drag a tail to replace a jump. seems to be a bad idea. */
  775. static void
  776. rearrange(void)
  777. {
  778. int i;
  779. Reg *j, *t;
  780. BB *b, *p, *s;
  781. for(i = 0; i < bcount; i++) {
  782. b = ordered[i];
  783. if(b->flags & Bdel)
  784. continue;
  785. j = b->last;
  786. if(j->prog->as == AJMP && j->s2->p1 == R) {
  787. t = j->s2;
  788. if(t == b->first)
  789. continue;
  790. s = findset(t->rpo);
  791. if(s == nil) {
  792. diag(Z, "no self");
  793. continue;
  794. }
  795. if(s == ordered[0])
  796. continue;
  797. if(s->flags & Bdel)
  798. continue;
  799. if(s->last->link == R)
  800. continue;
  801. if(bdebug)
  802. print("drag %ld to %ld\n", t->rpo, j->rpo);
  803. p = findset(t->rpo - 1);
  804. if(p == nil) {
  805. diag(Z, "no predec");
  806. continue;
  807. }
  808. if(p->last->link != t) {
  809. diag(Z, "bad predec %ld %ld", p->last->rpo, t->rpo);
  810. continue;
  811. }
  812. /* poison everything in sight */
  813. b->flags |= Bdel;
  814. s->flags |= Bdel;
  815. findset(j->link->rpo)->flags |= Bdel;
  816. findset(s->last->link->rpo)->flags |= Bdel;
  817. /* remove */
  818. adjprog(p->last, t->prog, s->last->link->prog);
  819. p->last->link = s->last->link;
  820. /* fix tail */
  821. adjprog(s->last, s->last->link->prog, j->link->prog);
  822. s->last->link = j->link;
  823. /* fix head */
  824. adjprog(j, j->link->prog, t->prog);
  825. j->link = t;
  826. /* nop the jump */
  827. j->prog->as = ANOP;
  828. j->prog->to.type = D_NONE;
  829. j->s2 = nil;
  830. j->link->p2 = delset(j, j->link->p2);
  831. j->s1 = t;
  832. t->p1 = j;
  833. if(bcheck)
  834. checkr(1);
  835. bchange++;
  836. }
  837. }
  838. }
  839. void
  840. jumptodot(void)
  841. {
  842. Reg *r;
  843. for(r = firstr; r != R; r = r->link) {
  844. if(r->prog->as == AJMP && r->s2 == r->link) {
  845. if(debug['v'])
  846. print("jump to next %ld\n", r->rpo);
  847. r->prog->as = ANOP;
  848. r->prog->to.type = D_NONE;
  849. r->s2 = nil;
  850. r->link->p2 = delset(r, r->link->p2);
  851. findset(r->rpo)->flags |= Bdel;
  852. findset(r->link->rpo)->flags |= Bdel;
  853. bchange++;
  854. }
  855. }
  856. }
  857. void
  858. comtarg(void)
  859. {
  860. int n;
  861. BB *b, *c;
  862. Reg *r, *l, *p, *t;
  863. loop:
  864. bchange = 0;
  865. /* excise NOPS because they just get in the way */
  866. /* some have p2 because they are excised labelled moves */
  867. if(debug['v']) {
  868. n = 0;
  869. for(r = firstr; r != R; r = r->link)
  870. r->rpo = n++;
  871. prfunc("prenop");
  872. }
  873. r = firstr;
  874. l = r->link;
  875. while(l != R) {
  876. if(l->prog->as == ANOP) {
  877. t = l->p1;
  878. p = l->p2;
  879. if(dbg) print("nop %ld [", l->rpo);
  880. if(dbg) printbl(p);
  881. for(;;) {
  882. adjprog(r, l->prog, l->prog->link);
  883. r->link = l->link;
  884. l->link = freer;
  885. freer = l;
  886. l = r->link;
  887. if(l->prog->as != ANOP)
  888. break;
  889. if(dbg) print("] %ld [", l->rpo);
  890. if(dbg) printbl(l->p2);
  891. if(p == R)
  892. p = l->p2;
  893. else if(l->p2 != nil)
  894. appset(l->p2, p);
  895. }
  896. if(dbg) print("] %ld [", l->rpo);
  897. if(dbg) printbl(l->p2);
  898. if(p != R) {
  899. redest(p, l);
  900. if(l->p2 != R)
  901. appset(p, l->p2);
  902. else
  903. l->p2 = p;
  904. }
  905. if(dbg) print("] -> [");
  906. if(dbg) printbl(l->p2);
  907. if(dbg) print("]\n");
  908. if(r->s1 != R)
  909. r->s1 = l;
  910. l->p1 = t;
  911. }
  912. r = l;
  913. l = r->link;
  914. }
  915. n = 0;
  916. for(r = firstr; r != R; r = r->link)
  917. r->rpo = n++;
  918. if(debug['v'])
  919. prfunc("input");
  920. firstbb = nil;
  921. lastbb = nil;
  922. if(debug['v'])
  923. print("bbstart\n");
  924. n = 0;
  925. r = firstr;
  926. do {
  927. b = bba();
  928. b->first = r;
  929. for(;;) {
  930. l = r;
  931. r = r->link;
  932. switch(l->prog->as) {
  933. case ARET:
  934. case AJMP:
  935. case AIRETL:
  936. goto out;
  937. }
  938. if(r->p2 != R)
  939. break;
  940. }
  941. out:
  942. b->last = l;
  943. if(lastbb == nil)
  944. firstbb = b;
  945. else
  946. lastbb->link = b;
  947. lastbb = b;
  948. if(bdebug)
  949. print("BB %ld %ld\n", b->first->rpo, b->last->rpo);
  950. n++;
  951. } while(r != R);
  952. if(debug['v'])
  953. print("end\n");
  954. if(n > bsize) {
  955. bsize = n * 3 / 2;
  956. if(bsize < BBINIT)
  957. bsize = BBINIT;
  958. ordered = alloc(bsize * sizeof(*ordered));
  959. heap = alloc((bsize + 1) * sizeof(*ordered));
  960. }
  961. if(debug['v'])
  962. print("preprocstart\n");
  963. n = 0;
  964. for(b = firstbb; b != nil; b = c) {
  965. c = b->link;
  966. preproc(b, n++);
  967. }
  968. if(debug['v'])
  969. print("end\n");
  970. bcount = n;
  971. jumptojump();
  972. if(debug['v'])
  973. print("iteratestart\n");
  974. iterate();
  975. //checktails();
  976. if(debug['v'])
  977. print("end\n");
  978. if(debug['v'])
  979. print("extrastart\n");
  980. jumptodot();
  981. // rearrange();
  982. if(debug['v'])
  983. print("end\n");
  984. cleanup();
  985. if(bballoc || bbsalloc)
  986. diag(Z, "bballoc %d %d", bballoc, bbsalloc);
  987. if(debug['v'])
  988. prfunc("output");
  989. if(1 && bchange)
  990. goto loop;
  991. }