bound.c 16 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118
  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. return nil;
  465. }
  466. static void
  467. redest(Reg *s, Reg *d)
  468. {
  469. while(s != R) {
  470. s->s2 = d;
  471. s = s->p2link;
  472. }
  473. }
  474. static void
  475. changedest(Reg *s, Reg *d, int x)
  476. {
  477. Reg *l;
  478. if(bdebug) {
  479. print("change %ld [", s->rpo);
  480. printbl(s->p2);
  481. print("] -> %ld [", d->rpo);
  482. printbl(d->p2);
  483. print("]\n");
  484. }
  485. if(s->p2 == nil) {
  486. // print("deadjmp\n");
  487. return;
  488. }
  489. l = s->p2;
  490. for(;;) {
  491. if(bdebug)
  492. print("s2 %ld = %ld\n", l->rpo, d->rpo);
  493. l->s2 = d;
  494. wound(l);
  495. if(l->p2link == nil)
  496. break;
  497. l = l->p2link;
  498. }
  499. if(x) {
  500. l->p2link = delset(s, d->p2);
  501. d->p2 = s->p2;
  502. }
  503. else {
  504. l->p2link = d->p2;
  505. d->p2 = s->p2;
  506. s->p2 = nil;
  507. }
  508. if(bdebug) {
  509. print("result [");
  510. printbl(d->p2);
  511. print("]\n");
  512. }
  513. bchange = 1;
  514. }
  515. static void
  516. bexcise(BB *b)
  517. {
  518. Reg *r, *l;
  519. l = b->last;
  520. r = b->first;
  521. if(bdebug)
  522. print("excise %ld to %ld\n", r->rpo, l->rpo);
  523. for(;;) {
  524. r->prog->as = ANOP;
  525. r->prog->to.type = D_NONE;
  526. r->p2 = R;
  527. if(r->s2 != R) {
  528. r->s2->p2 = delset(r, r->s2->p2);
  529. r->s2 = R;
  530. }
  531. if(r == l)
  532. break;
  533. r = r->link;
  534. }
  535. }
  536. static int
  537. backtrack(Reg *s, Reg *d)
  538. {
  539. int i;
  540. char l[BINST], r[BINST];
  541. //print("backtrack %ld %ld\n", Rn(s), Rn(d));
  542. i = 0;
  543. while(s != nil && d != nil) {
  544. if(snprint(l, BINST, "%P", s->prog) == BINST)
  545. break;
  546. if(snprint(r, BINST, "%P", d->prog) == BINST)
  547. break;
  548. //print("%s\t%s\n", l, r);
  549. if(strcmp(l, r) != 0)
  550. break;
  551. i++;
  552. s = s->p2link;
  553. d = d->p2link;
  554. }
  555. return i;
  556. }
  557. static void
  558. checktails(void)
  559. {
  560. int c;
  561. Reg *r;
  562. c = 0;
  563. for(r = firstr; r->link != R; r = r->link) {
  564. if(r->prog->as == AJMP && r->s2 != nil)
  565. c += backtrack(r->p1, r->s2->p1);
  566. }
  567. if(c > 0)
  568. print("tails %s %d\n", firstr->prog->from.sym->name, c);
  569. }
  570. static void
  571. process(BBset *s)
  572. {
  573. Reg *h;
  574. BB *f, *o, *p, *t;
  575. if(bdebug)
  576. print("process %d %x %x\n", s->damage, s->hash[0], s->hash[1]);
  577. f = s->ents;
  578. if(f->flags & Bjo) {
  579. s->ents = nil;
  580. h = findjump(f)->s2;
  581. o = nil;
  582. while(f != nil) {
  583. t = f->link;
  584. if((f->flags & Bjo) != 0 && f->first->s2 != f->first) {
  585. changedest(f->first, h, 1);
  586. bexcise(f);
  587. }
  588. else {
  589. f->link = o;
  590. o = f;
  591. }
  592. f = t;
  593. }
  594. s->ents = o;
  595. }
  596. else {
  597. o = nil;
  598. p = nil;
  599. while(f != nil) {
  600. t = f->link;
  601. if((f->flags & (Bpre|Bpin)) != 0 || (f->last->link == R)) {
  602. f->link = p;
  603. p = f;
  604. }
  605. else {
  606. f->link = o;
  607. o = f;
  608. }
  609. f = t;
  610. }
  611. if(o == nil) {
  612. diag(Z, "all Bpre");
  613. return;
  614. }
  615. if(p == nil) {
  616. p = o;
  617. o = p->link;
  618. p->link = nil;
  619. s->ents = p;
  620. }
  621. else
  622. s->ents = p;
  623. h = p->first;
  624. // oblit o list repl with jmp to h
  625. while(o != nil) {
  626. changedest(o->first, h, 1);
  627. bexcise(o);
  628. o = o->link;
  629. }
  630. bbsrecalc(s);
  631. }
  632. }
  633. static void
  634. iterate(void)
  635. {
  636. BBset *s;
  637. BB *b, *t;
  638. heapn = 0;
  639. for(;;) {
  640. for(b = wounded; b != nil; b = t) {
  641. t = b->link;
  642. enterbb(b);
  643. }
  644. wounded = nil;
  645. for(s = recalc; s != nil; s = s->link)
  646. calcdamage(s);
  647. recalc = nil;
  648. if(heapn == 0)
  649. return;
  650. s = heap[1];
  651. heapremove(s);
  652. process(s);
  653. }
  654. }
  655. static void
  656. cleanup(void)
  657. {
  658. int i;
  659. BB *l, *n;
  660. BBset *b, *t;
  661. for(i = 0; i < BBHASH; i++) {
  662. b = bbhash[i];
  663. bbhash[i] = nil;
  664. while(b != nil) {
  665. t = b->next;
  666. bsfree(b);
  667. b = t;
  668. }
  669. }
  670. for(i = 0; i < bcount; i++)
  671. bfree(ordered[i]);
  672. for(l = bbaux; l != nil; l = n) {
  673. n = l->aux;
  674. bfree(l);
  675. }
  676. bbaux = nil;
  677. }
  678. static void
  679. prreg(Reg *r)
  680. {
  681. Prog *p;
  682. p = r->prog;
  683. if(p->to.type == D_BRANCH)
  684. p->to.offset = r->s2->rpo;
  685. print("%ld:%P\tr %lX ", r->rpo, r->prog, r->regu);
  686. print("p1 %ld p2 %ld p2l %ld s1 %ld s2 %ld link %ld",
  687. Rn(r->p1), Rn(r->p2), Rn(r->p2link),
  688. Rn(r->s1), Rn(r->s2), Rn(r->link));
  689. if(!r->active)
  690. print(" d");
  691. // print(" %p %p\n", r->prog, r->prog->link);
  692. print("\n");
  693. }
  694. static void prfunc(char*);
  695. static void
  696. checkr(int d)
  697. {
  698. Prog *p;
  699. Reg *r, *t;
  700. for(r = firstr; r->link != R; r = r->link) {
  701. for(p = r->prog->link; p != P && p != r->link->prog; p = p->link)
  702. ;
  703. if(p == P) {
  704. print("%ld: bad prog link\n", r->rpo);
  705. if(d)
  706. prfunc(nil);
  707. abort();
  708. }
  709. if(r->s1 != R && (r->s1 != r->link || r->link->p1 != r)) {
  710. print("%ld: bad s1 p1\n", r->rpo);
  711. if(d)
  712. prfunc(nil);
  713. abort();
  714. }
  715. if(r->s2 != R && r->s2->p2 == nil) {
  716. print("%ld: no p2 for s2\n", r->rpo);
  717. if(d)
  718. prfunc(nil);
  719. abort();
  720. }
  721. if(r->p2 != R) {
  722. t = r->p2->s2;
  723. while(t != r) {
  724. t = t->p2link;
  725. if(t == R) {
  726. print("%ld: bad s2 for p2\n", r->rpo);
  727. if(d)
  728. prfunc(nil);
  729. abort();
  730. }
  731. }
  732. }
  733. }
  734. }
  735. static void
  736. prfunc(char *s)
  737. {
  738. Reg *r;
  739. if(s != nil)
  740. print("%s structure %s\n", s, firstr->prog->from.sym->name);
  741. for(r = firstr; r != R; r = r->link)
  742. prreg(r);
  743. if(s != nil) {
  744. print("end\n");
  745. checkr(0);
  746. }
  747. }
  748. /* find p in r's list and replace with l */
  749. static void
  750. adjprog(Reg *r, Prog *p, Prog *l)
  751. {
  752. Prog *t, **n;
  753. for(n = &r->prog->link; (t = *n) != nil; n = &t->link) {
  754. if(t == p) {
  755. *n = l;
  756. return;
  757. }
  758. }
  759. print("adjprog botch\n");
  760. abort();
  761. }
  762. static void
  763. jumptojump(void)
  764. {
  765. Reg *r;
  766. for(r = firstr; r != R; r = r->link) {
  767. if(r->prog->as == AJMP && r->p2 != R && r->s2 != r) {
  768. if(bdebug)
  769. print("jump as dest %ld -> %ld\n", r->rpo, r->s2->rpo);
  770. changedest(r, r->s2, 0);
  771. bchange++;
  772. }
  773. }
  774. }
  775. /* drag a tail to replace a jump. seems to be a bad idea. */
  776. static void
  777. rearrange(void)
  778. {
  779. int i;
  780. Reg *j, *t;
  781. BB *b, *p, *s;
  782. for(i = 0; i < bcount; i++) {
  783. b = ordered[i];
  784. if(b->flags & Bdel)
  785. continue;
  786. j = b->last;
  787. if(j->prog->as == AJMP && j->s2->p1 == R) {
  788. t = j->s2;
  789. if(t == b->first)
  790. continue;
  791. s = findset(t->rpo);
  792. if(s == nil) {
  793. diag(Z, "no self");
  794. continue;
  795. }
  796. if(s == ordered[0])
  797. continue;
  798. if(s->flags & Bdel)
  799. continue;
  800. if(s->last->link == R)
  801. continue;
  802. if(bdebug)
  803. print("drag %ld to %ld\n", t->rpo, j->rpo);
  804. p = findset(t->rpo - 1);
  805. if(p == nil) {
  806. diag(Z, "no predec");
  807. continue;
  808. }
  809. if(p->last->link != t) {
  810. diag(Z, "bad predec %ld %ld", p->last->rpo, t->rpo);
  811. continue;
  812. }
  813. /* poison everything in sight */
  814. b->flags |= Bdel;
  815. s->flags |= Bdel;
  816. findset(j->link->rpo)->flags |= Bdel;
  817. findset(s->last->link->rpo)->flags |= Bdel;
  818. /* remove */
  819. adjprog(p->last, t->prog, s->last->link->prog);
  820. p->last->link = s->last->link;
  821. /* fix tail */
  822. adjprog(s->last, s->last->link->prog, j->link->prog);
  823. s->last->link = j->link;
  824. /* fix head */
  825. adjprog(j, j->link->prog, t->prog);
  826. j->link = t;
  827. /* nop the jump */
  828. j->prog->as = ANOP;
  829. j->prog->to.type = D_NONE;
  830. j->s2 = nil;
  831. j->link->p2 = delset(j, j->link->p2);
  832. j->s1 = t;
  833. t->p1 = j;
  834. if(bcheck)
  835. checkr(1);
  836. bchange++;
  837. }
  838. }
  839. }
  840. void
  841. jumptodot(void)
  842. {
  843. Reg *r;
  844. for(r = firstr; r != R; r = r->link) {
  845. if(r->prog->as == AJMP && r->s2 == r->link) {
  846. if(debug['v'])
  847. print("jump to next %ld\n", r->rpo);
  848. r->prog->as = ANOP;
  849. r->prog->to.type = D_NONE;
  850. r->s2 = nil;
  851. r->link->p2 = delset(r, r->link->p2);
  852. findset(r->rpo)->flags |= Bdel;
  853. findset(r->link->rpo)->flags |= Bdel;
  854. bchange++;
  855. }
  856. }
  857. }
  858. void
  859. comtarg(void)
  860. {
  861. int n;
  862. BB *b, *c;
  863. Reg *r, *l, *p, *t;
  864. loop:
  865. bchange = 0;
  866. /* excise NOPS because they just get in the way */
  867. /* some have p2 because they are excised labelled moves */
  868. if(debug['v']) {
  869. n = 0;
  870. for(r = firstr; r != R; r = r->link)
  871. r->rpo = n++;
  872. prfunc("prenop");
  873. }
  874. r = firstr;
  875. l = r->link;
  876. while(l != R) {
  877. if(l->prog->as == ANOP) {
  878. t = l->p1;
  879. p = l->p2;
  880. if(dbg) print("nop %ld [", l->rpo);
  881. if(dbg) printbl(p);
  882. for(;;) {
  883. adjprog(r, l->prog, l->prog->link);
  884. r->link = l->link;
  885. l->link = freer;
  886. freer = l;
  887. l = r->link;
  888. if(l->prog->as != ANOP)
  889. break;
  890. if(dbg) print("] %ld [", l->rpo);
  891. if(dbg) printbl(l->p2);
  892. if(p == R)
  893. p = l->p2;
  894. else if(l->p2 != nil)
  895. appset(l->p2, p);
  896. }
  897. if(dbg) print("] %ld [", l->rpo);
  898. if(dbg) printbl(l->p2);
  899. if(p != R) {
  900. redest(p, l);
  901. if(l->p2 != R)
  902. appset(p, l->p2);
  903. else
  904. l->p2 = p;
  905. }
  906. if(dbg) print("] -> [");
  907. if(dbg) printbl(l->p2);
  908. if(dbg) print("]\n");
  909. if(r->s1 != R)
  910. r->s1 = l;
  911. l->p1 = t;
  912. }
  913. r = l;
  914. l = r->link;
  915. }
  916. n = 0;
  917. for(r = firstr; r != R; r = r->link)
  918. r->rpo = n++;
  919. if(debug['v'])
  920. prfunc("input");
  921. firstbb = nil;
  922. lastbb = nil;
  923. if(debug['v'])
  924. print("bbstart\n");
  925. n = 0;
  926. r = firstr;
  927. do {
  928. b = bba();
  929. b->first = r;
  930. for(;;) {
  931. l = r;
  932. r = r->link;
  933. switch(l->prog->as) {
  934. case ARET:
  935. case AJMP:
  936. case AIRETL:
  937. goto out;
  938. }
  939. if(r->p2 != R)
  940. break;
  941. }
  942. out:
  943. b->last = l;
  944. if(lastbb == nil)
  945. firstbb = b;
  946. else
  947. lastbb->link = b;
  948. lastbb = b;
  949. if(bdebug)
  950. print("BB %ld %ld\n", b->first->rpo, b->last->rpo);
  951. n++;
  952. } while(r != R);
  953. if(debug['v'])
  954. print("end\n");
  955. if(n > bsize) {
  956. bsize = n * 3 / 2;
  957. if(bsize < BBINIT)
  958. bsize = BBINIT;
  959. ordered = alloc(bsize * sizeof(*ordered));
  960. heap = alloc((bsize + 1) * sizeof(*ordered));
  961. }
  962. if(debug['v'])
  963. print("preprocstart\n");
  964. n = 0;
  965. for(b = firstbb; b != nil; b = c) {
  966. c = b->link;
  967. preproc(b, n++);
  968. }
  969. if(debug['v'])
  970. print("end\n");
  971. bcount = n;
  972. jumptojump();
  973. if(debug['v'])
  974. print("iteratestart\n");
  975. iterate();
  976. //checktails();
  977. if(debug['v'])
  978. print("end\n");
  979. if(debug['v'])
  980. print("extrastart\n");
  981. jumptodot();
  982. // rearrange();
  983. if(debug['v'])
  984. print("end\n");
  985. cleanup();
  986. if(bballoc || bbsalloc)
  987. diag(Z, "bballoc %d %d", bballoc, bbsalloc);
  988. if(debug['v'])
  989. prfunc("output");
  990. if(1 && bchange)
  991. goto loop;
  992. }