peep.c 11 KB

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