reg.c 20 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264
  1. #include "gc.h"
  2. Reg*
  3. rega(void)
  4. {
  5. Reg *r;
  6. r = freer;
  7. if(r == R) {
  8. r = alloc(sizeof(*r));
  9. } else
  10. freer = r->link;
  11. *r = zreg;
  12. return r;
  13. }
  14. int
  15. rcmp(const void *a1, const void *a2)
  16. {
  17. Rgn *p1, *p2;
  18. int c1, c2;
  19. p1 = (Rgn*)a1;
  20. p2 = (Rgn*)a2;
  21. c1 = p2->cost;
  22. c2 = p1->cost;
  23. if(c1 -= c2)
  24. return c1;
  25. return p2->varno - p1->varno;
  26. }
  27. void
  28. regopt(Prog *p)
  29. {
  30. Reg *r, *r1, *r2;
  31. Prog *p1;
  32. int i, z;
  33. long initpc, val, npc;
  34. ulong vreg;
  35. Bits bit;
  36. struct
  37. {
  38. long m;
  39. long c;
  40. Reg* p;
  41. } log5[6], *lp;
  42. firstr = R;
  43. lastr = R;
  44. nvar = 0;
  45. regbits = RtoB(D_SP) | RtoB(D_AX);
  46. for(z=0; z<BITS; z++) {
  47. externs.b[z] = 0;
  48. params.b[z] = 0;
  49. consts.b[z] = 0;
  50. addrs.b[z] = 0;
  51. }
  52. /*
  53. * pass 1
  54. * build aux data structure
  55. * allocate pcs
  56. * find use and set of variables
  57. */
  58. val = 5L * 5L * 5L * 5L * 5L;
  59. lp = log5;
  60. for(i=0; i<5; i++) {
  61. lp->m = val;
  62. lp->c = 0;
  63. lp->p = R;
  64. val /= 5L;
  65. lp++;
  66. }
  67. val = 0;
  68. for(; p != P; p = p->link) {
  69. switch(p->as) {
  70. case ADATA:
  71. case AGLOBL:
  72. case ANAME:
  73. case ASIGNAME:
  74. continue;
  75. }
  76. r = rega();
  77. if(firstr == R) {
  78. firstr = r;
  79. lastr = r;
  80. } else {
  81. lastr->link = r;
  82. r->p1 = lastr;
  83. lastr->s1 = r;
  84. lastr = r;
  85. }
  86. r->prog = p;
  87. r->pc = val;
  88. val++;
  89. lp = log5;
  90. for(i=0; i<5; i++) {
  91. lp->c--;
  92. if(lp->c <= 0) {
  93. lp->c = lp->m;
  94. if(lp->p != R)
  95. lp->p->log5 = r;
  96. lp->p = r;
  97. (lp+1)->c = 0;
  98. break;
  99. }
  100. lp++;
  101. }
  102. r1 = r->p1;
  103. if(r1 != R)
  104. switch(r1->prog->as) {
  105. case ARET:
  106. case AJMP:
  107. case AIRETL:
  108. r->p1 = R;
  109. r1->s1 = R;
  110. }
  111. bit = mkvar(r, &p->from, p->as==AMOVL);
  112. if(bany(&bit))
  113. switch(p->as) {
  114. /*
  115. * funny
  116. */
  117. case ALEAL:
  118. for(z=0; z<BITS; z++)
  119. addrs.b[z] |= bit.b[z];
  120. break;
  121. /*
  122. * left side read
  123. */
  124. default:
  125. for(z=0; z<BITS; z++)
  126. r->use1.b[z] |= bit.b[z];
  127. break;
  128. }
  129. bit = mkvar(r, &p->to, 0);
  130. if(bany(&bit))
  131. switch(p->as) {
  132. default:
  133. diag(Z, "reg: unknown op: %A", p->as);
  134. break;
  135. /*
  136. * right side read
  137. */
  138. case ACMPB:
  139. case ACMPL:
  140. case ACMPW:
  141. for(z=0; z<BITS; z++)
  142. r->use2.b[z] |= bit.b[z];
  143. break;
  144. /*
  145. * right side write
  146. */
  147. case ANOP:
  148. case AMOVL:
  149. case AMOVB:
  150. case AMOVW:
  151. case AMOVBLSX:
  152. case AMOVBLZX:
  153. case AMOVWLSX:
  154. case AMOVWLZX:
  155. for(z=0; z<BITS; z++)
  156. r->set.b[z] |= bit.b[z];
  157. break;
  158. /*
  159. * right side read+write
  160. */
  161. case AADDB:
  162. case AADDL:
  163. case AADDW:
  164. case AANDB:
  165. case AANDL:
  166. case AANDW:
  167. case ASUBB:
  168. case ASUBL:
  169. case ASUBW:
  170. case AORB:
  171. case AORL:
  172. case AORW:
  173. case AXORB:
  174. case AXORL:
  175. case AXORW:
  176. case ASALB:
  177. case ASALL:
  178. case ASALW:
  179. case ASARB:
  180. case ASARL:
  181. case ASARW:
  182. case AROLB:
  183. case AROLL:
  184. case AROLW:
  185. case ARORB:
  186. case ARORL:
  187. case ARORW:
  188. case ASHLB:
  189. case ASHLL:
  190. case ASHLW:
  191. case ASHRB:
  192. case ASHRL:
  193. case ASHRW:
  194. case AIMULL:
  195. case AIMULW:
  196. case ANEGL:
  197. case ANOTL:
  198. case AADCL:
  199. case ASBBL:
  200. for(z=0; z<BITS; z++) {
  201. r->set.b[z] |= bit.b[z];
  202. r->use2.b[z] |= bit.b[z];
  203. }
  204. break;
  205. /*
  206. * funny
  207. */
  208. case AFMOVDP:
  209. case AFMOVFP:
  210. case AFMOVLP:
  211. case AFMOVVP:
  212. case AFMOVWP:
  213. case ACALL:
  214. for(z=0; z<BITS; z++)
  215. addrs.b[z] |= bit.b[z];
  216. break;
  217. }
  218. switch(p->as) {
  219. case AIMULL:
  220. case AIMULW:
  221. if(p->to.type != D_NONE)
  222. break;
  223. case AIDIVB:
  224. case AIDIVL:
  225. case AIDIVW:
  226. case AIMULB:
  227. case ADIVB:
  228. case ADIVL:
  229. case ADIVW:
  230. case AMULB:
  231. case AMULL:
  232. case AMULW:
  233. case ACWD:
  234. case ACDQ:
  235. r->regu |= RtoB(D_AX) | RtoB(D_DX);
  236. break;
  237. case AREP:
  238. case AREPN:
  239. case ALOOP:
  240. case ALOOPEQ:
  241. case ALOOPNE:
  242. r->regu |= RtoB(D_CX);
  243. break;
  244. case AMOVSB:
  245. case AMOVSL:
  246. case AMOVSW:
  247. case ACMPSB:
  248. case ACMPSL:
  249. case ACMPSW:
  250. r->regu |= RtoB(D_SI) | RtoB(D_DI);
  251. break;
  252. case ASTOSB:
  253. case ASTOSL:
  254. case ASTOSW:
  255. case ASCASB:
  256. case ASCASL:
  257. case ASCASW:
  258. r->regu |= RtoB(D_AX) | RtoB(D_DI);
  259. break;
  260. case AINSB:
  261. case AINSL:
  262. case AINSW:
  263. case AOUTSB:
  264. case AOUTSL:
  265. case AOUTSW:
  266. r->regu |= RtoB(D_DI) | RtoB(D_DX);
  267. break;
  268. case AFSTSW:
  269. case ASAHF:
  270. r->regu |= RtoB(D_AX);
  271. break;
  272. }
  273. }
  274. if(firstr == R)
  275. return;
  276. initpc = pc - val;
  277. npc = val;
  278. /*
  279. * pass 2
  280. * turn branch references to pointers
  281. * build back pointers
  282. */
  283. for(r = firstr; r != R; r = r->link) {
  284. p = r->prog;
  285. if(p->to.type == D_BRANCH) {
  286. val = p->to.offset - initpc;
  287. r1 = firstr;
  288. while(r1 != R) {
  289. r2 = r1->log5;
  290. if(r2 != R && val >= r2->pc) {
  291. r1 = r2;
  292. continue;
  293. }
  294. if(r1->pc == val)
  295. break;
  296. r1 = r1->link;
  297. }
  298. if(r1 == R) {
  299. nearln = p->lineno;
  300. diag(Z, "ref not found\n%P", p);
  301. continue;
  302. }
  303. if(r1 == r) {
  304. nearln = p->lineno;
  305. diag(Z, "ref to self\n%P", p);
  306. continue;
  307. }
  308. r->s2 = r1;
  309. r->p2link = r1->p2;
  310. r1->p2 = r;
  311. }
  312. }
  313. if(debug['R']) {
  314. p = firstr->prog;
  315. print("\n%L %D\n", p->lineno, &p->from);
  316. }
  317. /*
  318. * pass 2.5
  319. * find looping structure
  320. */
  321. for(r = firstr; r != R; r = r->link)
  322. r->active = 0;
  323. change = 0;
  324. loopit(firstr, npc);
  325. if(debug['R'] && debug['v']) {
  326. print("\nlooping structure:\n");
  327. for(r = firstr; r != R; r = r->link) {
  328. print("%ld:%P", r->loop, r->prog);
  329. for(z=0; z<BITS; z++)
  330. bit.b[z] = r->use1.b[z] |
  331. r->use2.b[z] |
  332. r->set.b[z];
  333. if(bany(&bit)) {
  334. print("\t");
  335. if(bany(&r->use1))
  336. print(" u1=%B", r->use1);
  337. if(bany(&r->use2))
  338. print(" u2=%B", r->use2);
  339. if(bany(&r->set))
  340. print(" st=%B", r->set);
  341. }
  342. print("\n");
  343. }
  344. }
  345. /*
  346. * pass 3
  347. * iterate propagating usage
  348. * back until flow graph is complete
  349. */
  350. loop1:
  351. change = 0;
  352. for(r = firstr; r != R; r = r->link)
  353. r->active = 0;
  354. for(r = firstr; r != R; r = r->link)
  355. if(r->prog->as == ARET)
  356. prop(r, zbits, zbits);
  357. loop11:
  358. /* pick up unreachable code */
  359. i = 0;
  360. for(r = firstr; r != R; r = r1) {
  361. r1 = r->link;
  362. if(r1 && r1->active && !r->active) {
  363. prop(r, zbits, zbits);
  364. i = 1;
  365. }
  366. }
  367. if(i)
  368. goto loop11;
  369. if(change)
  370. goto loop1;
  371. /*
  372. * pass 4
  373. * iterate propagating register/variable synchrony
  374. * forward until graph is complete
  375. */
  376. loop2:
  377. change = 0;
  378. for(r = firstr; r != R; r = r->link)
  379. r->active = 0;
  380. synch(firstr, zbits);
  381. if(change)
  382. goto loop2;
  383. /*
  384. * pass 5
  385. * isolate regions
  386. * calculate costs (paint1)
  387. */
  388. r = firstr;
  389. if(r) {
  390. for(z=0; z<BITS; z++)
  391. bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
  392. ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
  393. if(bany(&bit)) {
  394. nearln = r->prog->lineno;
  395. warn(Z, "used and not set: %B", bit);
  396. if(debug['R'] && !debug['w'])
  397. print("used and not set: %B\n", bit);
  398. }
  399. }
  400. if(debug['R'] && debug['v'])
  401. print("\nprop structure:\n");
  402. for(r = firstr; r != R; r = r->link)
  403. r->act = zbits;
  404. rgp = region;
  405. nregion = 0;
  406. for(r = firstr; r != R; r = r->link) {
  407. if(debug['R'] && debug['v']) {
  408. print("%P\t", r->prog);
  409. if(bany(&r->set))
  410. print("s:%B ", r->set);
  411. if(bany(&r->refahead))
  412. print("ra:%B ", r->refahead);
  413. if(bany(&r->calahead))
  414. print("ca:%B ", r->calahead);
  415. print("\n");
  416. }
  417. for(z=0; z<BITS; z++)
  418. bit.b[z] = r->set.b[z] &
  419. ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
  420. if(bany(&bit)) {
  421. nearln = r->prog->lineno;
  422. warn(Z, "set and not used: %B", bit);
  423. if(debug['R'])
  424. print("set and not used: %B\n", bit);
  425. excise(r);
  426. }
  427. for(z=0; z<BITS; z++)
  428. bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
  429. while(bany(&bit)) {
  430. i = bnum(bit);
  431. rgp->enter = r;
  432. rgp->varno = i;
  433. change = 0;
  434. if(debug['R'] && debug['v'])
  435. print("\n");
  436. paint1(r, i);
  437. bit.b[i/32] &= ~(1L<<(i%32));
  438. if(change <= 0) {
  439. if(debug['R'])
  440. print("%L$%d: %B\n",
  441. r->prog->lineno, change, blsh(i));
  442. continue;
  443. }
  444. rgp->cost = change;
  445. nregion++;
  446. if(nregion >= NRGN) {
  447. warn(Z, "too many regions");
  448. goto brk;
  449. }
  450. rgp++;
  451. }
  452. }
  453. brk:
  454. qsort(region, nregion, sizeof(region[0]), rcmp);
  455. /*
  456. * pass 6
  457. * determine used registers (paint2)
  458. * replace code (paint3)
  459. */
  460. rgp = region;
  461. for(i=0; i<nregion; i++) {
  462. bit = blsh(rgp->varno);
  463. vreg = paint2(rgp->enter, rgp->varno);
  464. vreg = allreg(vreg, rgp);
  465. if(debug['R']) {
  466. print("%L$%d %R: %B\n",
  467. rgp->enter->prog->lineno,
  468. rgp->cost,
  469. rgp->regno,
  470. bit);
  471. }
  472. if(rgp->regno != 0)
  473. paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
  474. rgp++;
  475. }
  476. /*
  477. * pass 7
  478. * peep-hole on basic block
  479. */
  480. if(!debug['R'] || debug['P'])
  481. peep();
  482. /*
  483. * pass 8
  484. * recalculate pc
  485. */
  486. val = initpc;
  487. for(r = firstr; r != R; r = r1) {
  488. r->pc = val;
  489. p = r->prog;
  490. p1 = P;
  491. r1 = r->link;
  492. if(r1 != R)
  493. p1 = r1->prog;
  494. for(; p != p1; p = p->link) {
  495. switch(p->as) {
  496. default:
  497. val++;
  498. break;
  499. case ANOP:
  500. case ADATA:
  501. case AGLOBL:
  502. case ANAME:
  503. case ASIGNAME:
  504. break;
  505. }
  506. }
  507. }
  508. pc = val;
  509. /*
  510. * fix up branches
  511. */
  512. if(debug['R'])
  513. if(bany(&addrs))
  514. print("addrs: %B\n", addrs);
  515. r1 = 0; /* set */
  516. for(r = firstr; r != R; r = r->link) {
  517. p = r->prog;
  518. if(p->to.type == D_BRANCH)
  519. p->to.offset = r->s2->pc;
  520. r1 = r;
  521. }
  522. /*
  523. * last pass
  524. * eliminate nops
  525. * free aux structures
  526. */
  527. for(p = firstr->prog; p != P; p = p->link){
  528. while(p->link && p->link->as == ANOP)
  529. p->link = p->link->link;
  530. }
  531. if(r1 != R) {
  532. r1->link = freer;
  533. freer = firstr;
  534. }
  535. }
  536. /*
  537. * add mov b,rn
  538. * just after r
  539. */
  540. void
  541. addmove(Reg *r, int bn, int rn, int f)
  542. {
  543. Prog *p, *p1;
  544. Adr *a;
  545. Var *v;
  546. p1 = alloc(sizeof(*p1));
  547. *p1 = zprog;
  548. p = r->prog;
  549. p1->link = p->link;
  550. p->link = p1;
  551. p1->lineno = p->lineno;
  552. v = var + bn;
  553. a = &p1->to;
  554. a->sym = v->sym;
  555. a->offset = v->offset;
  556. a->etype = v->etype;
  557. a->type = v->name;
  558. p1->as = AMOVL;
  559. if(v->etype == TCHAR || v->etype == TUCHAR)
  560. p1->as = AMOVB;
  561. if(v->etype == TSHORT || v->etype == TUSHORT)
  562. p1->as = AMOVW;
  563. p1->from.type = rn;
  564. if(!f) {
  565. p1->from = *a;
  566. *a = zprog.from;
  567. a->type = rn;
  568. if(v->etype == TUCHAR)
  569. p1->as = AMOVB;
  570. if(v->etype == TUSHORT)
  571. p1->as = AMOVW;
  572. }
  573. if(debug['R'])
  574. print("%P\t.a%P\n", p, p1);
  575. }
  576. ulong
  577. doregbits(int r)
  578. {
  579. ulong b;
  580. b = 0;
  581. if(r >= D_INDIR)
  582. r -= D_INDIR;
  583. if(r >= D_AX && r <= D_DI)
  584. b |= RtoB(r);
  585. else
  586. if(r >= D_AL && r <= D_BL)
  587. b |= RtoB(r-D_AL+D_AX);
  588. else
  589. if(r >= D_AH && r <= D_BH)
  590. b |= RtoB(r-D_AH+D_AX);
  591. return b;
  592. }
  593. Bits
  594. mkvar(Reg *r, Adr *a, int isro)
  595. {
  596. Var *v;
  597. int i, t, n, et, z;
  598. long o;
  599. Bits bit;
  600. Sym *s;
  601. /*
  602. * mark registers used
  603. */
  604. t = a->type;
  605. r->regu |= doregbits(t);
  606. r->regu |= doregbits(a->index);
  607. et = a->etype;
  608. switch(t) {
  609. default:
  610. goto none;
  611. case D_INDIR+D_GS:
  612. if(!isro || 1)
  613. goto none;
  614. n = t;
  615. {static Sym er; a->sym = &er;}
  616. a->sym->name = "$extreg";
  617. break;
  618. case D_ADDR:
  619. a->type = a->index;
  620. bit = mkvar(r, a, 0);
  621. for(z=0; z<BITS; z++)
  622. addrs.b[z] |= bit.b[z];
  623. a->type = t;
  624. goto none;
  625. case D_EXTERN:
  626. case D_STATIC:
  627. case D_PARAM:
  628. case D_AUTO:
  629. n = t;
  630. break;
  631. }
  632. s = a->sym;
  633. if(s == S)
  634. goto none;
  635. if(s->name[0] == '.')
  636. goto none;
  637. o = a->offset;
  638. v = var;
  639. for(i=0; i<nvar; i++) {
  640. if(s == v->sym)
  641. if(n == v->name)
  642. if(o == v->offset)
  643. goto out;
  644. v++;
  645. }
  646. if(nvar >= NVAR) {
  647. if(debug['w'] > 1 && s)
  648. warn(Z, "variable not optimized: %s", s->name);
  649. goto none;
  650. }
  651. i = nvar;
  652. nvar++;
  653. v = &var[i];
  654. v->sym = s;
  655. v->offset = o;
  656. v->name = n;
  657. v->etype = et;
  658. if(debug['R'])
  659. print("bit=%2d et=%2d %D\n", i, et, a);
  660. out:
  661. bit = blsh(i);
  662. if(n == D_EXTERN || n == D_STATIC)
  663. for(z=0; z<BITS; z++)
  664. externs.b[z] |= bit.b[z];
  665. if(n == D_PARAM)
  666. for(z=0; z<BITS; z++)
  667. params.b[z] |= bit.b[z];
  668. if(v->etype != et || !typechlpfd[et]) /* funny punning */
  669. for(z=0; z<BITS; z++)
  670. addrs.b[z] |= bit.b[z];
  671. return bit;
  672. none:
  673. return zbits;
  674. }
  675. void
  676. prop(Reg *r, Bits ref, Bits cal)
  677. {
  678. Reg *r1, *r2;
  679. int z;
  680. for(r1 = r; r1 != R; r1 = r1->p1) {
  681. for(z=0; z<BITS; z++) {
  682. ref.b[z] |= r1->refahead.b[z];
  683. if(ref.b[z] != r1->refahead.b[z]) {
  684. r1->refahead.b[z] = ref.b[z];
  685. change++;
  686. }
  687. cal.b[z] |= r1->calahead.b[z];
  688. if(cal.b[z] != r1->calahead.b[z]) {
  689. r1->calahead.b[z] = cal.b[z];
  690. change++;
  691. }
  692. }
  693. switch(r1->prog->as) {
  694. case ACALL:
  695. for(z=0; z<BITS; z++) {
  696. cal.b[z] |= ref.b[z] | externs.b[z];
  697. ref.b[z] = 0;
  698. }
  699. break;
  700. case ATEXT:
  701. for(z=0; z<BITS; z++) {
  702. cal.b[z] = 0;
  703. ref.b[z] = 0;
  704. }
  705. break;
  706. case ARET:
  707. for(z=0; z<BITS; z++) {
  708. cal.b[z] = externs.b[z];
  709. ref.b[z] = 0;
  710. }
  711. }
  712. for(z=0; z<BITS; z++) {
  713. ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
  714. r1->use1.b[z] | r1->use2.b[z];
  715. cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
  716. r1->refbehind.b[z] = ref.b[z];
  717. r1->calbehind.b[z] = cal.b[z];
  718. }
  719. if(r1->active)
  720. break;
  721. r1->active = 1;
  722. }
  723. for(; r != r1; r = r->p1)
  724. for(r2 = r->p2; r2 != R; r2 = r2->p2link)
  725. prop(r2, r->refbehind, r->calbehind);
  726. }
  727. /*
  728. * find looping structure
  729. *
  730. * 1) find reverse postordering
  731. * 2) find approximate dominators,
  732. * the actual dominators if the flow graph is reducible
  733. * otherwise, dominators plus some other non-dominators.
  734. * See Matthew S. Hecht and Jeffrey D. Ullman,
  735. * "Analysis of a Simple Algorithm for Global Data Flow Problems",
  736. * Conf. Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts,
  737. * Oct. 1-3, 1973, pp. 207-217.
  738. * 3) find all nodes with a predecessor dominated by the current node.
  739. * such a node is a loop head.
  740. * recursively, all preds with a greater rpo number are in the loop
  741. */
  742. long
  743. postorder(Reg *r, Reg **rpo2r, long n)
  744. {
  745. Reg *r1;
  746. r->rpo = 1;
  747. r1 = r->s1;
  748. if(r1 && !r1->rpo)
  749. n = postorder(r1, rpo2r, n);
  750. r1 = r->s2;
  751. if(r1 && !r1->rpo)
  752. n = postorder(r1, rpo2r, n);
  753. rpo2r[n] = r;
  754. n++;
  755. return n;
  756. }
  757. long
  758. rpolca(long *idom, long rpo1, long rpo2)
  759. {
  760. long t;
  761. if(rpo1 == -1)
  762. return rpo2;
  763. while(rpo1 != rpo2){
  764. if(rpo1 > rpo2){
  765. t = rpo2;
  766. rpo2 = rpo1;
  767. rpo1 = t;
  768. }
  769. while(rpo1 < rpo2){
  770. t = idom[rpo2];
  771. if(t >= rpo2)
  772. fatal(Z, "bad idom");
  773. rpo2 = t;
  774. }
  775. }
  776. return rpo1;
  777. }
  778. int
  779. doms(long *idom, long r, long s)
  780. {
  781. while(s > r)
  782. s = idom[s];
  783. return s == r;
  784. }
  785. int
  786. loophead(long *idom, Reg *r)
  787. {
  788. long src;
  789. src = r->rpo;
  790. if(r->p1 != R && doms(idom, src, r->p1->rpo))
  791. return 1;
  792. for(r = r->p2; r != R; r = r->p2link)
  793. if(doms(idom, src, r->rpo))
  794. return 1;
  795. return 0;
  796. }
  797. void
  798. loopmark(Reg **rpo2r, long head, Reg *r)
  799. {
  800. if(r->rpo < head || r->active == head)
  801. return;
  802. r->active = head;
  803. r->loop += LOOP;
  804. if(r->p1 != R)
  805. loopmark(rpo2r, head, r->p1);
  806. for(r = r->p2; r != R; r = r->p2link)
  807. loopmark(rpo2r, head, r);
  808. }
  809. void
  810. loopit(Reg *r, long nr)
  811. {
  812. Reg *r1;
  813. long i, d, me;
  814. if(nr > maxnr) {
  815. rpo2r = alloc(nr * sizeof(Reg*));
  816. idom = alloc(nr * sizeof(long));
  817. maxnr = nr;
  818. }
  819. d = postorder(r, rpo2r, 0);
  820. if(d > nr)
  821. fatal(Z, "too many reg nodes");
  822. nr = d;
  823. for(i = 0; i < nr / 2; i++){
  824. r1 = rpo2r[i];
  825. rpo2r[i] = rpo2r[nr - 1 - i];
  826. rpo2r[nr - 1 - i] = r1;
  827. }
  828. for(i = 0; i < nr; i++)
  829. rpo2r[i]->rpo = i;
  830. idom[0] = 0;
  831. for(i = 0; i < nr; i++){
  832. r1 = rpo2r[i];
  833. me = r1->rpo;
  834. d = -1;
  835. if(r1->p1 != R && r1->p1->rpo < me)
  836. d = r1->p1->rpo;
  837. for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)
  838. if(r1->rpo < me)
  839. d = rpolca(idom, d, r1->rpo);
  840. idom[i] = d;
  841. }
  842. for(i = 0; i < nr; i++){
  843. r1 = rpo2r[i];
  844. r1->loop++;
  845. if(r1->p2 != R && loophead(idom, r1))
  846. loopmark(rpo2r, i, r1);
  847. }
  848. }
  849. void
  850. synch(Reg *r, Bits dif)
  851. {
  852. Reg *r1;
  853. int z;
  854. for(r1 = r; r1 != R; r1 = r1->s1) {
  855. for(z=0; z<BITS; z++) {
  856. dif.b[z] = (dif.b[z] &
  857. ~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
  858. r1->set.b[z] | r1->regdiff.b[z];
  859. if(dif.b[z] != r1->regdiff.b[z]) {
  860. r1->regdiff.b[z] = dif.b[z];
  861. change++;
  862. }
  863. }
  864. if(r1->active)
  865. break;
  866. r1->active = 1;
  867. for(z=0; z<BITS; z++)
  868. dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
  869. if(r1->s2 != R)
  870. synch(r1->s2, dif);
  871. }
  872. }
  873. ulong
  874. allreg(ulong b, Rgn *r)
  875. {
  876. Var *v;
  877. int i;
  878. v = var + r->varno;
  879. r->regno = 0;
  880. switch(v->etype) {
  881. default:
  882. diag(Z, "unknown etype %d/%d", bitno(b), v->etype);
  883. break;
  884. case TCHAR:
  885. case TUCHAR:
  886. case TSHORT:
  887. case TUSHORT:
  888. case TINT:
  889. case TUINT:
  890. case TLONG:
  891. case TULONG:
  892. case TIND:
  893. case TARRAY:
  894. i = BtoR(~b);
  895. if(i && r->cost > 0) {
  896. r->regno = i;
  897. return RtoB(i);
  898. }
  899. break;
  900. case TDOUBLE:
  901. case TFLOAT:
  902. break;
  903. }
  904. return 0;
  905. }
  906. void
  907. paint1(Reg *r, int bn)
  908. {
  909. Reg *r1;
  910. Prog *p;
  911. int z;
  912. ulong bb;
  913. z = bn/32;
  914. bb = 1L<<(bn%32);
  915. if(r->act.b[z] & bb)
  916. return;
  917. for(;;) {
  918. if(!(r->refbehind.b[z] & bb))
  919. break;
  920. r1 = r->p1;
  921. if(r1 == R)
  922. break;
  923. if(!(r1->refahead.b[z] & bb))
  924. break;
  925. if(r1->act.b[z] & bb)
  926. break;
  927. r = r1;
  928. }
  929. if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
  930. change -= CLOAD * r->loop;
  931. if(debug['R'] && debug['v'])
  932. print("%ld%P\tld %B $%d\n", r->loop,
  933. r->prog, blsh(bn), change);
  934. }
  935. for(;;) {
  936. r->act.b[z] |= bb;
  937. p = r->prog;
  938. if(r->use1.b[z] & bb) {
  939. change += CREF * r->loop;
  940. if(p->as == AFMOVL || p->as == AFMOVW)
  941. if(BtoR(bb) != D_F0)
  942. change = -CINF;
  943. if(debug['R'] && debug['v'])
  944. print("%ld%P\tu1 %B $%d\n", r->loop,
  945. p, blsh(bn), change);
  946. }
  947. if((r->use2.b[z]|r->set.b[z]) & bb) {
  948. change += CREF * r->loop;
  949. if(p->as == AFMOVL || p->as == AFMOVW)
  950. if(BtoR(bb) != D_F0)
  951. change = -CINF;
  952. if(debug['R'] && debug['v'])
  953. print("%ld%P\tu2 %B $%d\n", r->loop,
  954. p, blsh(bn), change);
  955. }
  956. if(STORE(r) & r->regdiff.b[z] & bb) {
  957. change -= CLOAD * r->loop;
  958. if(p->as == AFMOVL || p->as == AFMOVW)
  959. if(BtoR(bb) != D_F0)
  960. change = -CINF;
  961. if(debug['R'] && debug['v'])
  962. print("%ld%P\tst %B $%d\n", r->loop,
  963. p, blsh(bn), change);
  964. }
  965. if(r->refbehind.b[z] & bb)
  966. for(r1 = r->p2; r1 != R; r1 = r1->p2link)
  967. if(r1->refahead.b[z] & bb)
  968. paint1(r1, bn);
  969. if(!(r->refahead.b[z] & bb))
  970. break;
  971. r1 = r->s2;
  972. if(r1 != R)
  973. if(r1->refbehind.b[z] & bb)
  974. paint1(r1, bn);
  975. r = r->s1;
  976. if(r == R)
  977. break;
  978. if(r->act.b[z] & bb)
  979. break;
  980. if(!(r->refbehind.b[z] & bb))
  981. break;
  982. }
  983. }
  984. ulong
  985. regset(Reg *r, ulong bb)
  986. {
  987. ulong b, set;
  988. Adr v;
  989. int c;
  990. set = 0;
  991. v = zprog.from;
  992. while(b = bb & ~(bb-1)) {
  993. v.type = BtoR(b);
  994. c = copyu(r->prog, &v, A);
  995. if(c == 3)
  996. set |= b;
  997. bb &= ~b;
  998. }
  999. return set;
  1000. }
  1001. ulong
  1002. reguse(Reg *r, ulong bb)
  1003. {
  1004. ulong b, set;
  1005. Adr v;
  1006. int c;
  1007. set = 0;
  1008. v = zprog.from;
  1009. while(b = bb & ~(bb-1)) {
  1010. v.type = BtoR(b);
  1011. c = copyu(r->prog, &v, A);
  1012. if(c == 1 || c == 2 || c == 4)
  1013. set |= b;
  1014. bb &= ~b;
  1015. }
  1016. return set;
  1017. }
  1018. ulong
  1019. paint2(Reg *r, int bn)
  1020. {
  1021. Reg *r1;
  1022. int z;
  1023. ulong bb, vreg, x;
  1024. z = bn/32;
  1025. bb = 1L << (bn%32);
  1026. vreg = regbits;
  1027. if(!(r->act.b[z] & bb))
  1028. return vreg;
  1029. for(;;) {
  1030. if(!(r->refbehind.b[z] & bb))
  1031. break;
  1032. r1 = r->p1;
  1033. if(r1 == R)
  1034. break;
  1035. if(!(r1->refahead.b[z] & bb))
  1036. break;
  1037. if(!(r1->act.b[z] & bb))
  1038. break;
  1039. r = r1;
  1040. }
  1041. for(;;) {
  1042. r->act.b[z] &= ~bb;
  1043. vreg |= r->regu;
  1044. if(r->refbehind.b[z] & bb)
  1045. for(r1 = r->p2; r1 != R; r1 = r1->p2link)
  1046. if(r1->refahead.b[z] & bb)
  1047. vreg |= paint2(r1, bn);
  1048. if(!(r->refahead.b[z] & bb))
  1049. break;
  1050. r1 = r->s2;
  1051. if(r1 != R)
  1052. if(r1->refbehind.b[z] & bb)
  1053. vreg |= paint2(r1, bn);
  1054. r = r->s1;
  1055. if(r == R)
  1056. break;
  1057. if(!(r->act.b[z] & bb))
  1058. break;
  1059. if(!(r->refbehind.b[z] & bb))
  1060. break;
  1061. }
  1062. bb = vreg;
  1063. for(; r; r=r->s1) {
  1064. x = r->regu & ~bb;
  1065. if(x) {
  1066. vreg |= reguse(r, x);
  1067. bb |= regset(r, x);
  1068. }
  1069. }
  1070. return vreg;
  1071. }
  1072. void
  1073. paint3(Reg *r, int bn, long rb, int rn)
  1074. {
  1075. Reg *r1;
  1076. Prog *p;
  1077. int z;
  1078. ulong bb;
  1079. z = bn/32;
  1080. bb = 1L << (bn%32);
  1081. if(r->act.b[z] & bb)
  1082. return;
  1083. for(;;) {
  1084. if(!(r->refbehind.b[z] & bb))
  1085. break;
  1086. r1 = r->p1;
  1087. if(r1 == R)
  1088. break;
  1089. if(!(r1->refahead.b[z] & bb))
  1090. break;
  1091. if(r1->act.b[z] & bb)
  1092. break;
  1093. r = r1;
  1094. }
  1095. if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
  1096. addmove(r, bn, rn, 0);
  1097. for(;;) {
  1098. r->act.b[z] |= bb;
  1099. p = r->prog;
  1100. if(r->use1.b[z] & bb) {
  1101. if(debug['R'])
  1102. print("%P", p);
  1103. addreg(&p->from, rn);
  1104. if(debug['R'])
  1105. print("\t.c%P\n", p);
  1106. }
  1107. if((r->use2.b[z]|r->set.b[z]) & bb) {
  1108. if(debug['R'])
  1109. print("%P", p);
  1110. addreg(&p->to, rn);
  1111. if(debug['R'])
  1112. print("\t.c%P\n", p);
  1113. }
  1114. if(STORE(r) & r->regdiff.b[z] & bb)
  1115. addmove(r, bn, rn, 1);
  1116. r->regu |= rb;
  1117. if(r->refbehind.b[z] & bb)
  1118. for(r1 = r->p2; r1 != R; r1 = r1->p2link)
  1119. if(r1->refahead.b[z] & bb)
  1120. paint3(r1, bn, rb, rn);
  1121. if(!(r->refahead.b[z] & bb))
  1122. break;
  1123. r1 = r->s2;
  1124. if(r1 != R)
  1125. if(r1->refbehind.b[z] & bb)
  1126. paint3(r1, bn, rb, rn);
  1127. r = r->s1;
  1128. if(r == R)
  1129. break;
  1130. if(r->act.b[z] & bb)
  1131. break;
  1132. if(!(r->refbehind.b[z] & bb))
  1133. break;
  1134. }
  1135. }
  1136. void
  1137. addreg(Adr *a, int rn)
  1138. {
  1139. a->sym = 0;
  1140. a->offset = 0;
  1141. a->type = rn;
  1142. }
  1143. long
  1144. RtoB(int r)
  1145. {
  1146. if(r < D_AX || r > D_DI)
  1147. return 0;
  1148. return 1L << (r-D_AX);
  1149. }
  1150. int
  1151. BtoR(long b)
  1152. {
  1153. b &= 0xffL;
  1154. if(b == 0)
  1155. return 0;
  1156. return bitno(b) + D_AX;
  1157. }