peep.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. #include "gc.h"
  2. void
  3. peep(void)
  4. {
  5. Reg *r, *r1, *r2;
  6. Prog *p, *p1;
  7. int t;
  8. /*
  9. * complete R structure
  10. */
  11. t = 0;
  12. for(r=firstr; r!=R; r=r1) {
  13. r1 = r->link;
  14. if(r1 == R)
  15. break;
  16. p = r->prog->link;
  17. while(p != r1->prog)
  18. switch(p->as) {
  19. default:
  20. r2 = rega();
  21. r->link = r2;
  22. r2->link = r1;
  23. r2->prog = p;
  24. r2->p1 = r;
  25. r->s1 = r2;
  26. r2->s1 = r1;
  27. r1->p1 = r2;
  28. r = r2;
  29. t++;
  30. case ADATA:
  31. case AGLOBL:
  32. case ANAME:
  33. p = p->link;
  34. }
  35. }
  36. loop1:
  37. t = 0;
  38. for(r=firstr; r!=R; r=r->link) {
  39. p = r->prog;
  40. if(p->as == AMOVQ || /*p->as == AMOVL ||*/ p->as == AMOVS || p->as == AMOVT)
  41. if(regtyp(&p->to)) {
  42. if(regtyp(&p->from))
  43. if(p->from.type == p->to.type) {
  44. if(copyprop(r)) {
  45. excise(r);
  46. t++;
  47. } else
  48. if(subprop(r) && copyprop(r)) {
  49. excise(r);
  50. t++;
  51. }
  52. }
  53. if(regzer(&p->from))
  54. if(p->to.type == D_REG) {
  55. p->from.type = D_REG;
  56. p->from.reg = REGZERO;
  57. if(copyprop(r)) {
  58. excise(r);
  59. t++;
  60. } else
  61. if(subprop(r) && copyprop(r)) {
  62. excise(r);
  63. t++;
  64. }
  65. }
  66. }
  67. /* if(p->as == AMOVL)
  68. if(regtyp(&p->to)) {
  69. if(regzer(&p->from))
  70. if(p->to.type == D_REG) {
  71. p->from.type = D_REG;
  72. p->from.reg = REGZERO;
  73. if(copyprop(r)) {
  74. excise(r);
  75. t++;
  76. } else
  77. if(subprop(r) && copyprop(r)) {
  78. excise(r);
  79. t++;
  80. }
  81. }
  82. } */
  83. }
  84. if(t)
  85. goto loop1;
  86. /*
  87. * look for MOVB x,R; MOVB R,R
  88. */
  89. for(r=firstr; r!=R; r=r->link) {
  90. p = r->prog;
  91. switch(p->as) {
  92. default:
  93. continue;
  94. case AMOVW:
  95. case AMOVWU:
  96. case AMOVB:
  97. case AMOVBU:
  98. if(p->to.type != D_REG)
  99. continue;
  100. break;
  101. }
  102. r1 = r->link;
  103. if(r1 == R)
  104. continue;
  105. p1 = r1->prog;
  106. if(p1->as != p->as)
  107. continue;
  108. if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
  109. continue;
  110. if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
  111. continue;
  112. excise(r1);
  113. }
  114. }
  115. void
  116. excise(Reg *r)
  117. {
  118. Prog *p;
  119. p = r->prog;
  120. p->as = ANOP;
  121. p->from = zprog.from;
  122. p->to = zprog.to;
  123. p->reg = zprog.reg; /**/
  124. }
  125. Reg*
  126. uniqp(Reg *r)
  127. {
  128. Reg *r1;
  129. r1 = r->p1;
  130. if(r1 == R) {
  131. r1 = r->p2;
  132. if(r1 == R || r1->p2link != R)
  133. return R;
  134. } else
  135. if(r->p2 != R)
  136. return R;
  137. return r1;
  138. }
  139. Reg*
  140. uniqs(Reg *r)
  141. {
  142. Reg *r1;
  143. r1 = r->s1;
  144. if(r1 == R) {
  145. r1 = r->s2;
  146. if(r1 == R)
  147. return R;
  148. } else
  149. if(r->s2 != R)
  150. return R;
  151. return r1;
  152. }
  153. int
  154. regzer(Adr *a)
  155. {
  156. if(a->type == D_CONST)
  157. if(a->sym == S)
  158. if(a->offset == 0)
  159. return 1;
  160. if(a->type == D_REG)
  161. if(a->reg == REGZERO)
  162. return 1;
  163. return 0;
  164. }
  165. int
  166. regtyp(Adr *a)
  167. {
  168. if(a->type == D_REG) {
  169. if(a->reg != REGZERO)
  170. return 1;
  171. return 0;
  172. }
  173. if(a->type == D_FREG)
  174. return 1;
  175. return 0;
  176. }
  177. /*
  178. * the idea is to substitute
  179. * one register for another
  180. * from one MOV to another
  181. * MOV a, R0
  182. * ADD b, R0 / no use of R1
  183. * MOV R0, R1
  184. * would be converted to
  185. * MOV a, R1
  186. * ADD b, R1
  187. * MOV R1, R0
  188. * hopefully, then the former or latter MOV
  189. * will be eliminated by copy propagation.
  190. */
  191. int
  192. subprop(Reg *r0)
  193. {
  194. Prog *p;
  195. Adr *v1, *v2;
  196. Reg *r;
  197. int t;
  198. p = r0->prog;
  199. v1 = &p->from;
  200. if(!regtyp(v1))
  201. return 0;
  202. v2 = &p->to;
  203. if(!regtyp(v2))
  204. return 0;
  205. for(r=uniqp(r0); r!=R; r=uniqp(r)) {
  206. if(uniqs(r) == R)
  207. break;
  208. p = r->prog;
  209. switch(p->as) {
  210. case AJSR:
  211. return 0;
  212. case AADDQ:
  213. case ASUBQ:
  214. case AADDL:
  215. case ASUBL:
  216. case ASLLQ:
  217. case ASRLQ:
  218. case ASRAQ:
  219. case ASLLL:
  220. case ASRLL:
  221. case ASRAL:
  222. case AOR:
  223. case AAND:
  224. case AXOR:
  225. case AMULQ:
  226. case ADIVQ:
  227. case ADIVQU:
  228. case AMODQ:
  229. case AMODQU:
  230. case ADIVL:
  231. case ADIVLU:
  232. case AMODL:
  233. case AMODLU:
  234. case ACMPEQ:
  235. case ACMPGT:
  236. case ACMPGE:
  237. case ACMPUGT:
  238. case ACMPUGE:
  239. case ACMPBLE:
  240. case AMULL:
  241. case AUMULH:
  242. case AADDT:
  243. case AADDS:
  244. case ASUBT:
  245. case ASUBS:
  246. case AMULT:
  247. case AMULS:
  248. case ADIVT:
  249. case ADIVS:
  250. case ACMPTEQ:
  251. case ACMPTGT:
  252. case ACMPTGE:
  253. if(p->to.type == v1->type)
  254. if(p->to.reg == v1->reg) {
  255. if(p->reg == NREG)
  256. p->reg = p->to.reg;
  257. goto gotit;
  258. }
  259. break;
  260. case AMOVS:
  261. case AMOVT:
  262. case AMOVQ:
  263. case ACVTQT:
  264. case ACVTTQ:
  265. if(p->to.type == v1->type)
  266. if(p->to.reg == v1->reg)
  267. goto gotit;
  268. break;
  269. }
  270. if(copyau(&p->from, v2) ||
  271. copyau1(p, v2) ||
  272. copyau(&p->to, v2))
  273. break;
  274. if(copysub(&p->from, v1, v2, 0) ||
  275. copysub1(p, v1, v2, 0) ||
  276. copysub(&p->to, v1, v2, 0))
  277. break;
  278. }
  279. return 0;
  280. gotit:
  281. copysub(&p->to, v1, v2, 1);
  282. if(debug['P']) {
  283. print("gotit: %D->%D\n%P", v1, v2, r->prog);
  284. if(p->from.type == v2->type)
  285. print(" excise");
  286. print("\n");
  287. }
  288. for(r=uniqs(r); r!=r0; r=uniqs(r)) {
  289. p = r->prog;
  290. copysub(&p->from, v1, v2, 1);
  291. copysub1(p, v1, v2, 1);
  292. copysub(&p->to, v1, v2, 1);
  293. if(debug['P'])
  294. print("%P\n", r->prog);
  295. }
  296. t = v1->reg;
  297. v1->reg = v2->reg;
  298. v2->reg = t;
  299. if(debug['P'])
  300. print("%P last\n", r->prog);
  301. return 1;
  302. }
  303. /*
  304. * The idea is to remove redundant copies.
  305. * v1->v2 F=0
  306. * (use v2 s/v2/v1/)*
  307. * set v1 F=1
  308. * use v2 return fail
  309. * -----------------
  310. * v1->v2 F=0
  311. * (use v2 s/v2/v1/)*
  312. * set v1 F=1
  313. * set v2 return success
  314. */
  315. int
  316. copyprop(Reg *r0)
  317. {
  318. Prog *p;
  319. Adr *v1, *v2;
  320. Reg *r;
  321. p = r0->prog;
  322. v1 = &p->from;
  323. v2 = &p->to;
  324. if(copyas(v1, v2))
  325. return 1;
  326. for(r=firstr; r!=R; r=r->link)
  327. r->active = 0;
  328. return copy1(v1, v2, r0->s1, 0);
  329. }
  330. int
  331. copy1(Adr *v1, Adr *v2, Reg *r, int f)
  332. {
  333. int t;
  334. Prog *p;
  335. if(r->active) {
  336. if(debug['P'])
  337. print("act set; return 1\n");
  338. return 1;
  339. }
  340. r->active = 1;
  341. if(debug['P'])
  342. print("copy %D->%D f=%d\n", v1, v2, f);
  343. for(; r != R; r = r->s1) {
  344. p = r->prog;
  345. if(debug['P'])
  346. print("%P", p);
  347. if(!f && uniqp(r) == R) {
  348. f = 1;
  349. if(debug['P'])
  350. print("; merge; f=%d", f);
  351. }
  352. t = copyu(p, v2, A);
  353. switch(t) {
  354. case 2: /* rar, cant split */
  355. if(debug['P'])
  356. print("; %Drar; return 0\n", v2);
  357. return 0;
  358. case 3: /* set */
  359. if(debug['P'])
  360. print("; %Dset; return 1\n", v2);
  361. return 1;
  362. case 1: /* used, substitute */
  363. case 4: /* use and set */
  364. if(f) {
  365. if(!debug['P'])
  366. return 0;
  367. if(t == 4)
  368. print("; %Dused+set and f=%d; return 0\n", v2, f);
  369. else
  370. print("; %Dused and f=%d; return 0\n", v2, f);
  371. return 0;
  372. }
  373. if(copyu(p, v2, v1)) {
  374. if(debug['P'])
  375. print("; sub fail; return 0\n");
  376. return 0;
  377. }
  378. if(debug['P'])
  379. print("; sub%D/%D", v2, v1);
  380. if(t == 4) {
  381. if(debug['P'])
  382. print("; %Dused+set; return 1\n", v2);
  383. return 1;
  384. }
  385. break;
  386. }
  387. if(!f) {
  388. t = copyu(p, v1, A);
  389. if(!f && (t == 2 || t == 3 || t == 4)) {
  390. f = 1;
  391. if(debug['P'])
  392. print("; %Dset and !f; f=%d", v1, f);
  393. }
  394. }
  395. if(debug['P'])
  396. print("\n");
  397. if(r->s2)
  398. if(!copy1(v1, v2, r->s2, f))
  399. return 0;
  400. }
  401. return 1;
  402. }
  403. /*
  404. * return
  405. * 1 if v only used (and substitute),
  406. * 2 if read-alter-rewrite
  407. * 3 if set
  408. * 4 if set and used
  409. * 0 otherwise (not touched)
  410. */
  411. copyu(Prog *p, Adr *v, Adr *s)
  412. {
  413. switch(p->as) {
  414. default:
  415. if(debug['P'])
  416. print(" (???)");
  417. diag(Z, "copyu: unknown op %P", p);
  418. return 2;
  419. case ANOP: /* read, write */
  420. case AMOVQ:
  421. case AMOVL:
  422. case AMOVLU:
  423. case AMOVW:
  424. case AMOVWU:
  425. case AMOVB:
  426. case AMOVBU:
  427. case AMOVS:
  428. case AMOVT:
  429. case ACVTTQ:
  430. case ACVTQT:
  431. case ACVTQS:
  432. case ACVTTS:
  433. if(s != A) {
  434. if(copysub(&p->from, v, s, 1))
  435. return 1;
  436. if(!copyas(&p->to, v))
  437. if(copysub(&p->to, v, s, 1))
  438. return 1;
  439. return 0;
  440. }
  441. if(copyas(&p->to, v)) {
  442. if(copyau(&p->from, v))
  443. return 4;
  444. return 3;
  445. }
  446. if(copyau(&p->from, v))
  447. return 1;
  448. if(copyau(&p->to, v))
  449. return 1;
  450. return 0;
  451. case AADDQ: /* read read write */
  452. case ASUBQ:
  453. case AADDL:
  454. case ASUBL:
  455. case ACMPEQ:
  456. case ACMPGT:
  457. case ACMPGE:
  458. case ACMPUGT:
  459. case ACMPUGE:
  460. case ACMPBLE:
  461. case ASLLQ:
  462. case ASRLQ:
  463. case ASRAQ:
  464. case ASLLL:
  465. case ASRLL:
  466. case ASRAL:
  467. case AOR:
  468. case AAND:
  469. case AXOR:
  470. case AMULQ:
  471. case AMULL:
  472. case AUMULH:
  473. case ADIVQ:
  474. case ADIVQU:
  475. case AMODQ:
  476. case AMODQU:
  477. case ADIVL:
  478. case ADIVLU:
  479. case AMODL:
  480. case AMODLU:
  481. case AADDS:
  482. case AADDT:
  483. case ASUBS:
  484. case ASUBT:
  485. case AMULS:
  486. case AMULT:
  487. case ADIVS:
  488. case ADIVT:
  489. case ACMPTEQ:
  490. case ACMPTGT:
  491. case ACMPTGE:
  492. if(s != A) {
  493. if(copysub(&p->from, v, s, 1))
  494. return 1;
  495. if(copysub1(p, v, s, 1))
  496. return 1;
  497. if(!copyas(&p->to, v))
  498. if(copysub(&p->to, v, s, 1))
  499. return 1;
  500. return 0;
  501. }
  502. if(copyas(&p->to, v)) {
  503. if(p->reg == NREG)
  504. p->reg = p->to.reg;
  505. if(copyau(&p->from, v))
  506. return 4;
  507. if(copyau1(p, v))
  508. return 4;
  509. return 3;
  510. }
  511. if(copyau(&p->from, v))
  512. return 1;
  513. if(copyau1(p, v))
  514. return 1;
  515. if(copyau(&p->to, v))
  516. return 1;
  517. return 0;
  518. case ABEQ: /* read */
  519. case ABNE:
  520. case ABLT:
  521. case ABGE:
  522. case ABLE:
  523. case ABGT:
  524. case ABLBC:
  525. case ABLBS:
  526. case AFBEQ:
  527. case AFBNE:
  528. case AFBLT:
  529. case AFBGE:
  530. case AFBLE:
  531. case AFBGT:
  532. if(s != A)
  533. return copysub(&p->from, v, s, 1);
  534. if(copyau(&p->from, v))
  535. return 1;
  536. return 0;
  537. #ifdef NOPE
  538. case ???: /* read read */
  539. if(s != A) {
  540. if(copysub(&p->from, v, s, 1))
  541. return 1;
  542. return copysub(&p->to, v, s, 1);
  543. }
  544. if(copyau(&p->from, v))
  545. return 1;
  546. if(copyau(&p->to, v))
  547. return 1;
  548. break;
  549. #endif
  550. case AJMP: /* funny */
  551. if(s != A) {
  552. if(copysub(&p->to, v, s, 1))
  553. return 1;
  554. return 0;
  555. }
  556. if(copyau(&p->to, v))
  557. return 1;
  558. return 0;
  559. case ARET: /* funny */
  560. if(v->type == D_REG)
  561. if(v->reg == REGRET)
  562. return 2;
  563. if(v->type == D_FREG)
  564. if(v->reg == FREGRET)
  565. return 2;
  566. case AJSR: /* funny */
  567. if(v->type == D_REG) {
  568. if(v->reg <= REGEXT && v->reg > exregoffset)
  569. return 2;
  570. if(REGARG != NREG && v->reg == REGARG)
  571. return 2;
  572. }
  573. if(v->type == D_FREG)
  574. if(v->reg <= FREGEXT && v->reg > exfregoffset)
  575. return 2;
  576. if(s != A) {
  577. if(copysub(&p->to, v, s, 1))
  578. return 1;
  579. return 0;
  580. }
  581. if(copyau(&p->to, v))
  582. return 4;
  583. return 3;
  584. case ATEXT: /* funny */
  585. if(v->type == D_REG)
  586. if(v->reg == REGARG)
  587. return 3;
  588. return 0;
  589. }
  590. }
  591. int
  592. a2type(Prog *p)
  593. {
  594. switch(p->as) {
  595. case AADDQ:
  596. case ASUBQ:
  597. case ASLLQ:
  598. case ASRLQ:
  599. case ASRAQ:
  600. case ASLLL:
  601. case ASRLL:
  602. case ASRAL:
  603. case AOR:
  604. case AAND:
  605. case AXOR:
  606. case AMULQ:
  607. case ADIVQ:
  608. case ADIVQU:
  609. case AMODQ:
  610. case AMODQU:
  611. case ADIVL:
  612. case ADIVLU:
  613. case AMODL:
  614. case AMODLU:
  615. case AADDL:
  616. case ASUBL:
  617. case AEXTLL:
  618. case ACMPEQ:
  619. case ACMPGT:
  620. case ACMPGE:
  621. case ACMPUGT:
  622. case ACMPUGE:
  623. case ACMPBLE:
  624. case AMULL:
  625. case AUMULH:
  626. return D_REG;
  627. case AADDS:
  628. case AADDT:
  629. case ASUBS:
  630. case ASUBT:
  631. case AMULS:
  632. case AMULT:
  633. case ADIVS:
  634. case ADIVT:
  635. case ACMPTEQ:
  636. case ACMPTGT:
  637. case ACMPTGE:
  638. case ACVTTQ:
  639. case ACVTQT:
  640. return D_FREG;
  641. }
  642. return D_NONE;
  643. }
  644. /*
  645. * direct reference,
  646. * could be set/use depending on
  647. * semantics
  648. */
  649. int
  650. copyas(Adr *a, Adr *v)
  651. {
  652. if(regtyp(v))
  653. if(a->type == v->type)
  654. if(a->reg == v->reg)
  655. return 1;
  656. return 0;
  657. }
  658. /*
  659. * either direct or indirect
  660. */
  661. int
  662. copyau(Adr *a, Adr *v)
  663. {
  664. if(copyas(a, v))
  665. return 1;
  666. if(v->type == D_REG)
  667. if(a->type == D_OREG)
  668. if(v->reg == a->reg)
  669. return 1;
  670. return 0;
  671. }
  672. int
  673. copyau1(Prog *p, Adr *v)
  674. {
  675. if(regtyp(v))
  676. if(p->from.type == v->type || p->to.type == v->type)
  677. if(p->reg == v->reg) {
  678. if(a2type(p) != v->type)
  679. print("botch a2type %P\n", p);
  680. return 1;
  681. }
  682. return 0;
  683. }
  684. /*
  685. * substitute s for v in a
  686. * return failure to substitute
  687. */
  688. int
  689. copysub(Adr *a, Adr *v, Adr *s, int f)
  690. {
  691. if(f)
  692. if(copyau(a, v))
  693. a->reg = s->reg;
  694. return 0;
  695. }
  696. int
  697. copysub1(Prog *p1, Adr *v, Adr *s, int f)
  698. {
  699. if(f)
  700. if(copyau1(p1, v))
  701. p1->reg = s->reg;
  702. return 0;
  703. }