peep.c 10 KB

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