peep.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. #include "gc.h"
  2. static int
  3. needc(Prog *p)
  4. {
  5. while(p != P) {
  6. switch(p->as) {
  7. case AADCL:
  8. case ASBBL:
  9. case ARCRL:
  10. return 1;
  11. case AADDL:
  12. case ASUBL:
  13. case AJMP:
  14. case ARET:
  15. case ACALL:
  16. return 0;
  17. default:
  18. if(p->to.type == D_BRANCH)
  19. return 0;
  20. }
  21. p = p->link;
  22. }
  23. return 0;
  24. }
  25. void
  26. peep(void)
  27. {
  28. Reg *r, *r1, *r2;
  29. Prog *p, *p1;
  30. int t;
  31. /*
  32. * complete R structure
  33. */
  34. t = 0;
  35. for(r=firstr; r!=R; r=r1) {
  36. r1 = r->link;
  37. if(r1 == R)
  38. break;
  39. p = r->prog->link;
  40. while(p != r1->prog)
  41. switch(p->as) {
  42. default:
  43. r2 = rega();
  44. r->link = r2;
  45. r2->link = r1;
  46. r2->prog = p;
  47. r2->p1 = r;
  48. r->s1 = r2;
  49. r2->s1 = r1;
  50. r1->p1 = r2;
  51. r = r2;
  52. t++;
  53. case ADATA:
  54. case AGLOBL:
  55. case ANAME:
  56. case ASIGNAME:
  57. p = p->link;
  58. }
  59. }
  60. pc = 0; /* speculating it won't kill */
  61. loop1:
  62. if(debug['b'])
  63. comtarg();
  64. t = 0;
  65. for(r=firstr; r!=R; r=r->link) {
  66. p = r->prog;
  67. switch(p->as) {
  68. case AMOVL:
  69. if(regtyp(&p->to))
  70. if(regtyp(&p->from)) {
  71. if(copyprop(r)) {
  72. excise(r);
  73. t++;
  74. }
  75. if(subprop(r) && copyprop(r)) {
  76. excise(r);
  77. t++;
  78. }
  79. }
  80. break;
  81. case AMOVBLSX:
  82. case AMOVBLZX:
  83. case AMOVWLSX:
  84. case AMOVWLZX:
  85. if(regtyp(&p->to)) {
  86. r1 = uniqs(r);
  87. if(r1 != R) {
  88. p1 = r1->prog;
  89. if(p->as == p1->as && p->to.type == p1->from.type)
  90. p1->as = AMOVL;
  91. }
  92. }
  93. break;
  94. case AADDL:
  95. case AADDW:
  96. if(p->from.type != D_CONST || needc(p->link))
  97. break;
  98. if(p->from.offset == -1){
  99. if(p->as == AADDL)
  100. p->as = ADECL;
  101. else
  102. p->as = ADECW;
  103. p->from = zprog.from;
  104. }
  105. else if(p->from.offset == 1){
  106. if(p->as == AADDL)
  107. p->as = AINCL;
  108. else
  109. p->as = AINCW;
  110. p->from = zprog.from;
  111. }
  112. break;
  113. case ASUBL:
  114. case ASUBW:
  115. if(p->from.type != D_CONST || needc(p->link))
  116. break;
  117. if(p->from.offset == -1) {
  118. if(p->as == ASUBL)
  119. p->as = AINCL;
  120. else
  121. p->as = AINCW;
  122. p->from = zprog.from;
  123. }
  124. else if(p->from.offset == 1){
  125. if(p->as == ASUBL)
  126. p->as = ADECL;
  127. else
  128. p->as = ADECW;
  129. p->from = zprog.from;
  130. }
  131. break;
  132. }
  133. }
  134. if(t)
  135. goto loop1;
  136. }
  137. void
  138. excise(Reg *r)
  139. {
  140. Prog *p;
  141. p = r->prog;
  142. p->as = ANOP;
  143. p->from = zprog.from;
  144. p->to = zprog.to;
  145. }
  146. Reg*
  147. uniqp(Reg *r)
  148. {
  149. Reg *r1;
  150. r1 = r->p1;
  151. if(r1 == R) {
  152. r1 = r->p2;
  153. if(r1 == R || r1->p2link != R)
  154. return R;
  155. } else
  156. if(r->p2 != R)
  157. return R;
  158. return r1;
  159. }
  160. Reg*
  161. uniqs(Reg *r)
  162. {
  163. Reg *r1;
  164. r1 = r->s1;
  165. if(r1 == R) {
  166. r1 = r->s2;
  167. if(r1 == R)
  168. return R;
  169. } else
  170. if(r->s2 != R)
  171. return R;
  172. return r1;
  173. }
  174. int
  175. regtyp(Adr *a)
  176. {
  177. int t;
  178. t = a->type;
  179. if(t >= D_AX && t <= D_DI)
  180. return 1;
  181. return 0;
  182. }
  183. /*
  184. * the idea is to substitute
  185. * one register for another
  186. * from one MOV to another
  187. * MOV a, R0
  188. * ADD b, R0 / no use of R1
  189. * MOV R0, R1
  190. * would be converted to
  191. * MOV a, R1
  192. * ADD b, R1
  193. * MOV R1, R0
  194. * hopefully, then the former or latter MOV
  195. * will be eliminated by copy propagation.
  196. */
  197. int
  198. subprop(Reg *r0)
  199. {
  200. Prog *p;
  201. Adr *v1, *v2;
  202. Reg *r;
  203. int t;
  204. p = r0->prog;
  205. v1 = &p->from;
  206. if(!regtyp(v1))
  207. return 0;
  208. v2 = &p->to;
  209. if(!regtyp(v2))
  210. return 0;
  211. for(r=uniqp(r0); r!=R; r=uniqp(r)) {
  212. if(uniqs(r) == R)
  213. break;
  214. p = r->prog;
  215. switch(p->as) {
  216. case ACALL:
  217. return 0;
  218. case AIMULL:
  219. case AIMULW:
  220. if(p->to.type != D_NONE)
  221. break;
  222. case ADIVB:
  223. case ADIVL:
  224. case ADIVW:
  225. case AIDIVB:
  226. case AIDIVL:
  227. case AIDIVW:
  228. case AIMULB:
  229. case AMULB:
  230. case AMULL:
  231. case AMULW:
  232. case AROLB:
  233. case AROLL:
  234. case AROLW:
  235. case ARORB:
  236. case ARORL:
  237. case ARORW:
  238. case ASALB:
  239. case ASALL:
  240. case ASALW:
  241. case ASARB:
  242. case ASARL:
  243. case ASARW:
  244. case ASHLB:
  245. case ASHLL:
  246. case ASHLW:
  247. case ASHRB:
  248. case ASHRL:
  249. case ASHRW:
  250. case AREP:
  251. case AREPN:
  252. case ACWD:
  253. case ACDQ:
  254. case AMOVSL:
  255. case AFSTSW:
  256. return 0;
  257. case AMOVL:
  258. if(p->to.type == v1->type)
  259. goto gotit;
  260. break;
  261. }
  262. if(copyau(&p->from, v2) ||
  263. copyau(&p->to, v2))
  264. break;
  265. if(copysub(&p->from, v1, v2, 0) ||
  266. copysub(&p->to, v1, v2, 0))
  267. break;
  268. }
  269. return 0;
  270. gotit:
  271. copysub(&p->to, v1, v2, 1);
  272. if(debug['P']) {
  273. print("gotit: %D->%D\n%P", v1, v2, r->prog);
  274. if(p->from.type == v2->type)
  275. print(" excise");
  276. print("\n");
  277. }
  278. for(r=uniqs(r); r!=r0; r=uniqs(r)) {
  279. p = r->prog;
  280. copysub(&p->from, v1, v2, 1);
  281. copysub(&p->to, v1, v2, 1);
  282. if(debug['P'])
  283. print("%P\n", r->prog);
  284. }
  285. t = v1->type;
  286. v1->type = v2->type;
  287. v2->type = t;
  288. if(debug['P'])
  289. print("%P last\n", r->prog);
  290. return 1;
  291. }
  292. /*
  293. * The idea is to remove redundant copies.
  294. * v1->v2 F=0
  295. * (use v2 s/v2/v1/)*
  296. * set v1 F=1
  297. * use v2 return fail
  298. * -----------------
  299. * v1->v2 F=0
  300. * (use v2 s/v2/v1/)*
  301. * set v1 F=1
  302. * set v2 return success
  303. */
  304. int
  305. copyprop(Reg *r0)
  306. {
  307. Prog *p;
  308. Adr *v1, *v2;
  309. Reg *r;
  310. p = r0->prog;
  311. v1 = &p->from;
  312. v2 = &p->to;
  313. if(copyas(v1, v2))
  314. return 1;
  315. for(r=firstr; r!=R; r=r->link)
  316. r->active = 0;
  317. return copy1(v1, v2, r0->s1, 0);
  318. }
  319. int
  320. copy1(Adr *v1, Adr *v2, Reg *r, int f)
  321. {
  322. int t;
  323. Prog *p;
  324. if(r->active) {
  325. if(debug['P'])
  326. print("act set; return 1\n");
  327. return 1;
  328. }
  329. r->active = 1;
  330. if(debug['P'])
  331. print("copy %D->%D f=%d\n", v1, v2, f);
  332. for(; r != R; r = r->s1) {
  333. p = r->prog;
  334. if(debug['P'])
  335. print("%P", p);
  336. if(!f && uniqp(r) == R) {
  337. f = 1;
  338. if(debug['P'])
  339. print("; merge; f=%d", f);
  340. }
  341. t = copyu(p, v2, A);
  342. switch(t) {
  343. case 2: /* rar, cant split */
  344. if(debug['P'])
  345. print("; %D rar; return 0\n", v2);
  346. return 0;
  347. case 3: /* set */
  348. if(debug['P'])
  349. print("; %D set; return 1\n", v2);
  350. return 1;
  351. case 1: /* used, substitute */
  352. case 4: /* use and set */
  353. if(f) {
  354. if(!debug['P'])
  355. return 0;
  356. if(t == 4)
  357. print("; %D used+set and f=%d; return 0\n", v2, f);
  358. else
  359. print("; %D used and f=%d; return 0\n", v2, f);
  360. return 0;
  361. }
  362. if(copyu(p, v2, v1)) {
  363. if(debug['P'])
  364. print("; sub fail; return 0\n");
  365. return 0;
  366. }
  367. if(debug['P'])
  368. print("; sub %D/%D", v2, v1);
  369. if(t == 4) {
  370. if(debug['P'])
  371. print("; %D used+set; return 1\n", v2);
  372. return 1;
  373. }
  374. break;
  375. }
  376. if(!f) {
  377. t = copyu(p, v1, A);
  378. if(!f && (t == 2 || t == 3 || t == 4)) {
  379. f = 1;
  380. if(debug['P'])
  381. print("; %D set and !f; f=%d", v1, f);
  382. }
  383. }
  384. if(debug['P'])
  385. print("\n");
  386. if(r->s2)
  387. if(!copy1(v1, v2, r->s2, f))
  388. return 0;
  389. }
  390. return 1;
  391. }
  392. /*
  393. * return
  394. * 1 if v only used (and substitute),
  395. * 2 if read-alter-rewrite
  396. * 3 if set
  397. * 4 if set and used
  398. * 0 otherwise (not touched)
  399. */
  400. int
  401. copyu(Prog *p, Adr *v, Adr *s)
  402. {
  403. switch(p->as) {
  404. default:
  405. if(debug['P'])
  406. print("unknown op %A\n", p->as);
  407. return 2;
  408. case ANEGB:
  409. case ANEGW:
  410. case ANEGL:
  411. case ANOTB:
  412. case ANOTW:
  413. case ANOTL:
  414. if(copyas(&p->to, v))
  415. return 2;
  416. break;
  417. case ALEAL: /* lhs addr, rhs store */
  418. if(copyas(&p->from, v))
  419. return 2;
  420. case ANOP: /* rhs store */
  421. case AMOVL:
  422. case AMOVBLSX:
  423. case AMOVBLZX:
  424. case AMOVWLSX:
  425. case AMOVWLZX:
  426. if(copyas(&p->to, v)) {
  427. if(s != A)
  428. return copysub(&p->from, v, s, 1);
  429. if(copyau(&p->from, v))
  430. return 4;
  431. return 3;
  432. }
  433. goto caseread;
  434. case AROLB:
  435. case AROLL:
  436. case AROLW:
  437. case ARORB:
  438. case ARORL:
  439. case ARORW:
  440. case ASALB:
  441. case ASALL:
  442. case ASALW:
  443. case ASARB:
  444. case ASARL:
  445. case ASARW:
  446. case ASHLB:
  447. case ASHLL:
  448. case ASHLW:
  449. case ASHRB:
  450. case ASHRL:
  451. case ASHRW:
  452. if(copyas(&p->to, v))
  453. return 2;
  454. if(copyas(&p->from, v))
  455. if(p->from.type == D_CX)
  456. return 2;
  457. goto caseread;
  458. case AADDB: /* rhs rar */
  459. case AADDL:
  460. case AADDW:
  461. case AANDB:
  462. case AANDL:
  463. case AANDW:
  464. case ADECL:
  465. case ADECW:
  466. case AINCL:
  467. case AINCW:
  468. case ASUBB:
  469. case ASUBL:
  470. case ASUBW:
  471. case AORB:
  472. case AORL:
  473. case AORW:
  474. case AXORB:
  475. case AXORL:
  476. case AXORW:
  477. case AMOVB:
  478. case AMOVW:
  479. case AFMOVB:
  480. case AFMOVBP:
  481. case AFMOVD:
  482. case AFMOVDP:
  483. case AFMOVF:
  484. case AFMOVFP:
  485. case AFMOVL:
  486. case AFMOVLP:
  487. case AFMOVV:
  488. case AFMOVVP:
  489. case AFMOVW:
  490. case AFMOVWP:
  491. case AFMOVX:
  492. case AFMOVXP:
  493. case AFADDDP:
  494. case AFADDW:
  495. case AFADDL:
  496. case AFADDF:
  497. case AFADDD:
  498. case AFMULDP:
  499. case AFMULW:
  500. case AFMULL:
  501. case AFMULF:
  502. case AFMULD:
  503. case AFSUBDP:
  504. case AFSUBW:
  505. case AFSUBL:
  506. case AFSUBF:
  507. case AFSUBD:
  508. case AFSUBRDP:
  509. case AFSUBRW:
  510. case AFSUBRL:
  511. case AFSUBRF:
  512. case AFSUBRD:
  513. case AFDIVDP:
  514. case AFDIVW:
  515. case AFDIVL:
  516. case AFDIVF:
  517. case AFDIVD:
  518. case AFDIVRDP:
  519. case AFDIVRW:
  520. case AFDIVRL:
  521. case AFDIVRF:
  522. case AFDIVRD:
  523. if(copyas(&p->to, v))
  524. return 2;
  525. goto caseread;
  526. case ACMPL: /* read only */
  527. case ACMPW:
  528. case ACMPB:
  529. case AFCOMB:
  530. case AFCOMBP:
  531. case AFCOMD:
  532. case AFCOMDP:
  533. case AFCOMDPP:
  534. case AFCOMF:
  535. case AFCOMFP:
  536. case AFCOML:
  537. case AFCOMLP:
  538. case AFCOMW:
  539. case AFCOMWP:
  540. case AFUCOM:
  541. case AFUCOMP:
  542. case AFUCOMPP:
  543. caseread:
  544. if(s != A) {
  545. if(copysub(&p->from, v, s, 1))
  546. return 1;
  547. return copysub(&p->to, v, s, 1);
  548. }
  549. if(copyau(&p->from, v))
  550. return 1;
  551. if(copyau(&p->to, v))
  552. return 1;
  553. break;
  554. case AJGE: /* no reference */
  555. case AJNE:
  556. case AJLE:
  557. case AJEQ:
  558. case AJHI:
  559. case AJLS:
  560. case AJMI:
  561. case AJPL:
  562. case AJGT:
  563. case AJLT:
  564. case AJCC:
  565. case AJCS:
  566. case AADJSP:
  567. case AFLDZ:
  568. case AWAIT:
  569. break;
  570. case AIMULL:
  571. case AIMULW:
  572. if(p->to.type != D_NONE) {
  573. if(copyas(&p->to, v))
  574. return 2;
  575. goto caseread;
  576. }
  577. case ADIVB:
  578. case ADIVL:
  579. case ADIVW:
  580. case AIDIVB:
  581. case AIDIVL:
  582. case AIDIVW:
  583. case AIMULB:
  584. case AMULB:
  585. case AMULL:
  586. case AMULW:
  587. case ACWD:
  588. case ACDQ:
  589. if(v->type == D_AX || v->type == D_DX)
  590. return 2;
  591. goto caseread;
  592. case AMOVSL:
  593. case AREP:
  594. case AREPN:
  595. if(v->type == D_CX || v->type == D_DI || v->type == D_SI)
  596. return 2;
  597. goto caseread;
  598. case AFSTSW:
  599. if(v->type == D_AX)
  600. return 2;
  601. goto caseread;
  602. case AJMP: /* funny */
  603. if(s != A) {
  604. if(copysub(&p->to, v, s, 1))
  605. return 1;
  606. return 0;
  607. }
  608. if(copyau(&p->to, v))
  609. return 1;
  610. return 0;
  611. case ARET: /* funny */
  612. if(v->type == REGRET)
  613. return 2;
  614. if(s != A)
  615. return 1;
  616. return 3;
  617. case ACALL: /* funny */
  618. if(REGARG && v->type == REGARG)
  619. return 2;
  620. if(s != A) {
  621. if(copysub(&p->to, v, s, 1))
  622. return 1;
  623. return 0;
  624. }
  625. if(copyau(&p->to, v))
  626. return 4;
  627. return 3;
  628. }
  629. return 0;
  630. }
  631. /*
  632. * direct reference,
  633. * could be set/use depending on
  634. * semantics
  635. */
  636. int
  637. copyas(Adr *a, Adr *v)
  638. {
  639. if(a->type != v->type)
  640. return 0;
  641. if(regtyp(v))
  642. return 1;
  643. if(v->type == D_AUTO || v->type == D_PARAM)
  644. if(v->offset == a->offset)
  645. return 1;
  646. return 0;
  647. }
  648. /*
  649. * either direct or indirect
  650. */
  651. int
  652. copyau(Adr *a, Adr *v)
  653. {
  654. if(copyas(a, v))
  655. return 1;
  656. if(regtyp(v)) {
  657. if(a->type-D_INDIR == v->type)
  658. return 1;
  659. if(a->index == v->type)
  660. return 1;
  661. }
  662. return 0;
  663. }
  664. /*
  665. * substitute s for v in a
  666. * return failure to substitute
  667. */
  668. int
  669. copysub(Adr *a, Adr *v, Adr *s, int f)
  670. {
  671. int t;
  672. if(copyas(a, v)) {
  673. t = s->type;
  674. if(t >= D_AX && t <= D_DI) {
  675. if(f)
  676. a->type = t;
  677. }
  678. return 0;
  679. }
  680. if(regtyp(v)) {
  681. t = v->type;
  682. if(a->type == t+D_INDIR) {
  683. if(s->type == D_BP && a->index != D_NONE)
  684. return 1; /* can't use BP-base with index */
  685. if(f)
  686. a->type = s->type+D_INDIR;
  687. // return 0;
  688. }
  689. if(a->index == t) {
  690. if(f)
  691. a->index = s->type;
  692. return 0;
  693. }
  694. return 0;
  695. }
  696. return 0;
  697. }