peep.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "gc.h"
  10. static int
  11. needc(Prog *p)
  12. {
  13. while(p != P) {
  14. switch(p->as) {
  15. case AADCL:
  16. case AADCQ:
  17. case ASBBL:
  18. case ASBBQ:
  19. case ARCRL:
  20. case ARCRQ:
  21. return 1;
  22. case AADDL:
  23. case AADDQ:
  24. case ASUBL:
  25. case ASUBQ:
  26. case AJMP:
  27. case ARET:
  28. case ACALL:
  29. return 0;
  30. default:
  31. if(p->to.type == D_BRANCH)
  32. return 0;
  33. }
  34. p = p->link;
  35. }
  36. return 0;
  37. }
  38. static Reg*
  39. rnops(Reg *r)
  40. {
  41. Prog *p;
  42. Reg *r1;
  43. if(r != R)
  44. for(;;){
  45. p = r->prog;
  46. if(p->as != ANOP || p->from.type != D_NONE || p->to.type != D_NONE)
  47. break;
  48. r1 = uniqs(r);
  49. if(r1 == R)
  50. break;
  51. r = r1;
  52. }
  53. return r;
  54. }
  55. void
  56. peep(void)
  57. {
  58. Reg *r, *r1, *r2;
  59. Prog *p, *p1;
  60. int t;
  61. /*
  62. * complete R structure
  63. */
  64. t = 0;
  65. for(r=firstr; r!=R; r=r1) {
  66. r1 = r->link;
  67. if(r1 == R)
  68. break;
  69. p = r->prog->link;
  70. while(p != r1->prog)
  71. switch(p->as) {
  72. default:
  73. r2 = rega();
  74. r->link = r2;
  75. r2->link = r1;
  76. r2->prog = p;
  77. r2->p1 = r;
  78. r->s1 = r2;
  79. r2->s1 = r1;
  80. r1->p1 = r2;
  81. r = r2;
  82. t++;
  83. case ADATA:
  84. case AGLOBL:
  85. case ANAME:
  86. case ASIGNAME:
  87. p = p->link;
  88. }
  89. }
  90. pc = 0; /* speculating it won't kill */
  91. loop1:
  92. t = 0;
  93. for(r=firstr; r!=R; r=r->link) {
  94. p = r->prog;
  95. switch(p->as) {
  96. case AMOVL:
  97. case AMOVQ:
  98. case AMOVSS:
  99. case AMOVSD:
  100. if(regtyp(&p->to))
  101. if(regtyp(&p->from)) {
  102. if(copyprop(r)) {
  103. excise(r);
  104. t++;
  105. } else
  106. if(subprop(r) && copyprop(r)) {
  107. excise(r);
  108. t++;
  109. }
  110. }
  111. break;
  112. case AMOVBLZX:
  113. case AMOVWLZX:
  114. case AMOVBLSX:
  115. case AMOVWLSX:
  116. if(regtyp(&p->to)) {
  117. r1 = rnops(uniqs(r));
  118. if(r1 != R) {
  119. p1 = r1->prog;
  120. if(p->as == p1->as && p->to.type == p1->from.type){
  121. p1->as = AMOVL;
  122. t++;
  123. }
  124. }
  125. }
  126. break;
  127. case AMOVBQSX:
  128. case AMOVBQZX:
  129. case AMOVWQSX:
  130. case AMOVWQZX:
  131. case AMOVLQSX:
  132. case AMOVLQZX:
  133. if(regtyp(&p->to)) {
  134. r1 = rnops(uniqs(r));
  135. if(r1 != R) {
  136. p1 = r1->prog;
  137. if(p->as == p1->as && p->to.type == p1->from.type){
  138. p1->as = AMOVQ;
  139. t++;
  140. }
  141. }
  142. }
  143. break;
  144. case AADDL:
  145. case AADDQ:
  146. case AADDW:
  147. if(p->from.type != D_CONST || needc(p->link))
  148. break;
  149. if(p->from.offset == -1){
  150. if(p->as == AADDQ)
  151. p->as = ADECQ;
  152. else if(p->as == AADDL)
  153. p->as = ADECL;
  154. else
  155. p->as = ADECW;
  156. p->from = zprog.from;
  157. }
  158. else if(p->from.offset == 1){
  159. if(p->as == AADDQ)
  160. p->as = AINCQ;
  161. else if(p->as == AADDL)
  162. p->as = AINCL;
  163. else
  164. p->as = AINCW;
  165. p->from = zprog.from;
  166. }
  167. break;
  168. case ASUBL:
  169. case ASUBQ:
  170. case ASUBW:
  171. if(p->from.type != D_CONST || needc(p->link))
  172. break;
  173. if(p->from.offset == -1) {
  174. if(p->as == ASUBQ)
  175. p->as = AINCQ;
  176. else if(p->as == ASUBL)
  177. p->as = AINCL;
  178. else
  179. p->as = AINCW;
  180. p->from = zprog.from;
  181. }
  182. else if(p->from.offset == 1){
  183. if(p->as == ASUBQ)
  184. p->as = ADECQ;
  185. else if(p->as == ASUBL)
  186. p->as = ADECL;
  187. else
  188. p->as = ADECW;
  189. p->from = zprog.from;
  190. }
  191. break;
  192. }
  193. }
  194. if(t)
  195. goto loop1;
  196. }
  197. void
  198. excise(Reg *r)
  199. {
  200. Prog *p;
  201. p = r->prog;
  202. p->as = ANOP;
  203. p->from = zprog.from;
  204. p->to = zprog.to;
  205. }
  206. Reg*
  207. uniqp(Reg *r)
  208. {
  209. Reg *r1;
  210. r1 = r->p1;
  211. if(r1 == R) {
  212. r1 = r->p2;
  213. if(r1 == R || r1->p2link != R)
  214. return R;
  215. } else
  216. if(r->p2 != R)
  217. return R;
  218. return r1;
  219. }
  220. Reg*
  221. uniqs(Reg *r)
  222. {
  223. Reg *r1;
  224. r1 = r->s1;
  225. if(r1 == R) {
  226. r1 = r->s2;
  227. if(r1 == R)
  228. return R;
  229. } else
  230. if(r->s2 != R)
  231. return R;
  232. return r1;
  233. }
  234. int
  235. regtyp(Adr *a)
  236. {
  237. int t;
  238. t = a->type;
  239. if(t >= D_AX && t <= D_R15)
  240. return 1;
  241. if(t >= D_X0 && t <= D_X0+15)
  242. return 1;
  243. return 0;
  244. }
  245. /*
  246. * the idea is to substitute
  247. * one register for another
  248. * from one MOV to another
  249. * MOV a, R0
  250. * ADD b, R0 / no use of R1
  251. * MOV R0, R1
  252. * would be converted to
  253. * MOV a, R1
  254. * ADD b, R1
  255. * MOV R1, R0
  256. * hopefully, then the former or latter MOV
  257. * will be eliminated by copy propagation.
  258. */
  259. int
  260. subprop(Reg *r0)
  261. {
  262. Prog *p;
  263. Adr *v1, *v2;
  264. Reg *r;
  265. int t;
  266. p = r0->prog;
  267. v1 = &p->from;
  268. if(!regtyp(v1))
  269. return 0;
  270. v2 = &p->to;
  271. if(!regtyp(v2))
  272. return 0;
  273. for(r=uniqp(r0); r!=R; r=uniqp(r)) {
  274. if(uniqs(r) == R)
  275. break;
  276. p = r->prog;
  277. switch(p->as) {
  278. case ACALL:
  279. return 0;
  280. case AIMULL:
  281. case AIMULQ:
  282. case AIMULW:
  283. if(p->to.type != D_NONE)
  284. break;
  285. case ADIVB:
  286. case ADIVL:
  287. case ADIVQ:
  288. case ADIVW:
  289. case AIDIVB:
  290. case AIDIVL:
  291. case AIDIVQ:
  292. case AIDIVW:
  293. case AIMULB:
  294. case AMULB:
  295. case AMULL:
  296. case AMULQ:
  297. case AMULW:
  298. case AROLB:
  299. case AROLL:
  300. case AROLQ:
  301. case AROLW:
  302. case ARORB:
  303. case ARORL:
  304. case ARORQ:
  305. case ARORW:
  306. case ASALB:
  307. case ASALL:
  308. case ASALQ:
  309. case ASALW:
  310. case ASARB:
  311. case ASARL:
  312. case ASARQ:
  313. case ASARW:
  314. case ASHLB:
  315. case ASHLL:
  316. case ASHLQ:
  317. case ASHLW:
  318. case ASHRB:
  319. case ASHRL:
  320. case ASHRQ:
  321. case ASHRW:
  322. case AREP:
  323. case AREPN:
  324. case ACWD:
  325. case ACDQ:
  326. case ACQO:
  327. case AMOVSL:
  328. case AMOVSQ:
  329. return 0;
  330. case AMOVL:
  331. case AMOVQ:
  332. if(p->to.type == v1->type)
  333. goto gotit;
  334. break;
  335. }
  336. if(copyau(&p->from, v2) ||
  337. copyau(&p->to, v2))
  338. break;
  339. if(copysub(&p->from, v1, v2, 0) ||
  340. copysub(&p->to, v1, v2, 0))
  341. break;
  342. }
  343. return 0;
  344. gotit:
  345. copysub(&p->to, v1, v2, 1);
  346. if(debug['P']) {
  347. print("gotit: %D->%D\n%P", v1, v2, r->prog);
  348. if(p->from.type == v2->type)
  349. print(" excise");
  350. print("\n");
  351. }
  352. for(r=uniqs(r); r!=r0; r=uniqs(r)) {
  353. p = r->prog;
  354. copysub(&p->from, v1, v2, 1);
  355. copysub(&p->to, v1, v2, 1);
  356. if(debug['P'])
  357. print("%P\n", r->prog);
  358. }
  359. t = v1->type;
  360. v1->type = v2->type;
  361. v2->type = t;
  362. if(debug['P'])
  363. print("%P last\n", r->prog);
  364. return 1;
  365. }
  366. /*
  367. * The idea is to remove redundant copies.
  368. * v1->v2 F=0
  369. * (use v2 s/v2/v1/)*
  370. * set v1 F=1
  371. * use v2 return fail
  372. * -----------------
  373. * v1->v2 F=0
  374. * (use v2 s/v2/v1/)*
  375. * set v1 F=1
  376. * set v2 return success
  377. */
  378. int
  379. copyprop(Reg *r0)
  380. {
  381. Prog *p;
  382. Adr *v1, *v2;
  383. Reg *r;
  384. p = r0->prog;
  385. v1 = &p->from;
  386. v2 = &p->to;
  387. if(copyas(v1, v2))
  388. return 1;
  389. for(r=firstr; r!=R; r=r->link)
  390. r->active = 0;
  391. return copy1(v1, v2, r0->s1, 0);
  392. }
  393. int
  394. copy1(Adr *v1, Adr *v2, Reg *r, int f)
  395. {
  396. int t;
  397. Prog *p;
  398. if(r->active) {
  399. if(debug['P'])
  400. print("act set; return 1\n");
  401. return 1;
  402. }
  403. r->active = 1;
  404. if(debug['P'])
  405. print("copy %D->%D f=%d\n", v1, v2, f);
  406. for(; r != R; r = r->s1) {
  407. p = r->prog;
  408. if(debug['P'])
  409. print("%P", p);
  410. if(!f && uniqp(r) == R) {
  411. f = 1;
  412. if(debug['P'])
  413. print("; merge; f=%d", f);
  414. }
  415. t = copyu(p, v2, A);
  416. switch(t) {
  417. case 2: /* rar, cant split */
  418. if(debug['P'])
  419. print("; %D rar; return 0\n", v2);
  420. return 0;
  421. case 3: /* set */
  422. if(debug['P'])
  423. print("; %D set; return 1\n", v2);
  424. return 1;
  425. case 1: /* used, substitute */
  426. case 4: /* use and set */
  427. if(f) {
  428. if(!debug['P'])
  429. return 0;
  430. if(t == 4)
  431. print("; %D used+set and f=%d; return 0\n", v2, f);
  432. else
  433. print("; %D used and f=%d; return 0\n", v2, f);
  434. return 0;
  435. }
  436. if(copyu(p, v2, v1)) {
  437. if(debug['P'])
  438. print("; sub fail; return 0\n");
  439. return 0;
  440. }
  441. if(debug['P'])
  442. print("; sub %D/%D", v2, v1);
  443. if(t == 4) {
  444. if(debug['P'])
  445. print("; %D used+set; return 1\n", v2);
  446. return 1;
  447. }
  448. break;
  449. }
  450. if(!f) {
  451. t = copyu(p, v1, A);
  452. if(!f && (t == 2 || t == 3 || t == 4)) {
  453. f = 1;
  454. if(debug['P'])
  455. print("; %D set and !f; f=%d", v1, f);
  456. }
  457. }
  458. if(debug['P'])
  459. print("\n");
  460. if(r->s2)
  461. if(!copy1(v1, v2, r->s2, f))
  462. return 0;
  463. }
  464. return 1;
  465. }
  466. /*
  467. * return
  468. * 1 if v only used (and substitute),
  469. * 2 if read-alter-rewrite
  470. * 3 if set
  471. * 4 if set and used
  472. * 0 otherwise (not touched)
  473. */
  474. int
  475. copyu(Prog *p, Adr *v, Adr *s)
  476. {
  477. switch(p->as) {
  478. default:
  479. if(debug['P'])
  480. print("unknown op %A\n", p->as);
  481. /* SBBL; ADCL; FLD1; SAHF */
  482. return 2;
  483. case ANEGB:
  484. case ANEGW:
  485. case ANEGL:
  486. case ANEGQ:
  487. case ANOTB:
  488. case ANOTW:
  489. case ANOTL:
  490. case ANOTQ:
  491. if(copyas(&p->to, v))
  492. return 2;
  493. break;
  494. case ALEAL: /* lhs addr, rhs store */
  495. case ALEAQ:
  496. if(copyas(&p->from, v))
  497. return 2;
  498. case ANOP: /* rhs store */
  499. case AMOVL:
  500. case AMOVQ:
  501. case AMOVBLSX:
  502. case AMOVBLZX:
  503. case AMOVBQSX:
  504. case AMOVBQZX:
  505. case AMOVLQSX:
  506. case AMOVLQZX:
  507. case AMOVWLSX:
  508. case AMOVWLZX:
  509. case AMOVWQSX:
  510. case AMOVWQZX:
  511. case AMOVSS:
  512. case AMOVSD:
  513. case ACVTSD2SL:
  514. case ACVTSD2SQ:
  515. case ACVTSD2SS:
  516. case ACVTSL2SD:
  517. case ACVTSL2SS:
  518. case ACVTSQ2SD:
  519. case ACVTSQ2SS:
  520. case ACVTSS2SD:
  521. case ACVTSS2SL:
  522. case ACVTSS2SQ:
  523. case ACVTTSD2SL:
  524. case ACVTTSD2SQ:
  525. case ACVTTSS2SL:
  526. case ACVTTSS2SQ:
  527. if(copyas(&p->to, v)) {
  528. if(s != A)
  529. return copysub(&p->from, v, s, 1);
  530. if(copyau(&p->from, v))
  531. return 4;
  532. return 3;
  533. }
  534. goto caseread;
  535. case AROLB:
  536. case AROLL:
  537. case AROLQ:
  538. case AROLW:
  539. case ARORB:
  540. case ARORL:
  541. case ARORQ:
  542. case ARORW:
  543. case ASALB:
  544. case ASALL:
  545. case ASALQ:
  546. case ASALW:
  547. case ASARB:
  548. case ASARL:
  549. case ASARQ:
  550. case ASARW:
  551. case ASHLB:
  552. case ASHLL:
  553. case ASHLQ:
  554. case ASHLW:
  555. case ASHRB:
  556. case ASHRL:
  557. case ASHRQ:
  558. case ASHRW:
  559. if(copyas(&p->to, v))
  560. return 2;
  561. if(copyas(&p->from, v))
  562. if(p->from.type == D_CX)
  563. return 2;
  564. goto caseread;
  565. case AADDB: /* rhs rar */
  566. case AADDL:
  567. case AADDQ:
  568. case AADDW:
  569. case AANDB:
  570. case AANDL:
  571. case AANDQ:
  572. case AANDW:
  573. case ADECL:
  574. case ADECQ:
  575. case ADECW:
  576. case AINCL:
  577. case AINCQ:
  578. case AINCW:
  579. case ASUBB:
  580. case ASUBL:
  581. case ASUBQ:
  582. case ASUBW:
  583. case AORB:
  584. case AORL:
  585. case AORQ:
  586. case AORW:
  587. case AXORB:
  588. case AXORL:
  589. case AXORQ:
  590. case AXORW:
  591. case AMOVB:
  592. case AMOVW:
  593. case AADDSD:
  594. case AADDSS:
  595. case ACMPSD:
  596. case ACMPSS:
  597. case ADIVSD:
  598. case ADIVSS:
  599. case AMAXSD:
  600. case AMAXSS:
  601. case AMINSD:
  602. case AMINSS:
  603. case AMULSD:
  604. case AMULSS:
  605. case ARCPSS:
  606. case ARSQRTSS:
  607. case ASQRTSD:
  608. case ASQRTSS:
  609. case ASUBSD:
  610. case ASUBSS:
  611. case AXORPD:
  612. if(copyas(&p->to, v))
  613. return 2;
  614. goto caseread;
  615. case ACMPL: /* read only */
  616. case ACMPW:
  617. case ACMPB:
  618. case ACMPQ:
  619. case ACOMISD:
  620. case ACOMISS:
  621. case AUCOMISD:
  622. case AUCOMISS:
  623. caseread:
  624. if(s != A) {
  625. if(copysub(&p->from, v, s, 1))
  626. return 1;
  627. return copysub(&p->to, v, s, 1);
  628. }
  629. if(copyau(&p->from, v))
  630. return 1;
  631. if(copyau(&p->to, v))
  632. return 1;
  633. break;
  634. case AJGE: /* no reference */
  635. case AJNE:
  636. case AJLE:
  637. case AJEQ:
  638. case AJHI:
  639. case AJLS:
  640. case AJMI:
  641. case AJPL:
  642. case AJGT:
  643. case AJLT:
  644. case AJCC:
  645. case AJCS:
  646. case AADJSP:
  647. case AWAIT:
  648. case ACLD:
  649. break;
  650. case AIMULL:
  651. case AIMULQ:
  652. case AIMULW:
  653. if(p->to.type != D_NONE) {
  654. if(copyas(&p->to, v))
  655. return 2;
  656. goto caseread;
  657. }
  658. case ADIVB:
  659. case ADIVL:
  660. case ADIVQ:
  661. case ADIVW:
  662. case AIDIVB:
  663. case AIDIVL:
  664. case AIDIVQ:
  665. case AIDIVW:
  666. case AIMULB:
  667. case AMULB:
  668. case AMULL:
  669. case AMULQ:
  670. case AMULW:
  671. case ACWD:
  672. case ACDQ:
  673. case ACQO:
  674. if(v->type == D_AX || v->type == D_DX)
  675. return 2;
  676. goto caseread;
  677. case AMOVSL:
  678. case AMOVSQ:
  679. case AREP:
  680. case AREPN:
  681. if(v->type == D_CX || v->type == D_DI || v->type == D_SI)
  682. return 2;
  683. goto caseread;
  684. case AJMP: /* funny */
  685. if(s != A) {
  686. if(copysub(&p->to, v, s, 1))
  687. return 1;
  688. return 0;
  689. }
  690. if(copyau(&p->to, v))
  691. return 1;
  692. return 0;
  693. case ARET: /* funny */
  694. if(v->type == REGRET || v->type == FREGRET)
  695. return 2;
  696. if(s != A)
  697. return 1;
  698. return 3;
  699. case ACALL: /* funny */
  700. if(REGEXT && v->type <= REGEXT && v->type > exregoffset)
  701. return 2;
  702. if(REGARG && v->type == REGARG)
  703. return 2;
  704. if(s != A) {
  705. if(copysub(&p->to, v, s, 1))
  706. return 1;
  707. return 0;
  708. }
  709. if(copyau(&p->to, v))
  710. return 4;
  711. return 3;
  712. case ATEXT: /* funny */
  713. if(REGARG && v->type == REGARG)
  714. return 3;
  715. return 0;
  716. }
  717. return 0;
  718. }
  719. /*
  720. * direct reference,
  721. * could be set/use depending on
  722. * semantics
  723. */
  724. int
  725. copyas(Adr *a, Adr *v)
  726. {
  727. if(a->type != v->type)
  728. return 0;
  729. if(regtyp(v))
  730. return 1;
  731. if(v->type == D_AUTO || v->type == D_PARAM)
  732. if(v->offset == a->offset)
  733. return 1;
  734. return 0;
  735. }
  736. /*
  737. * either direct or indirect
  738. */
  739. int
  740. copyau(Adr *a, Adr *v)
  741. {
  742. if(copyas(a, v))
  743. return 1;
  744. if(regtyp(v)) {
  745. if(a->type-D_INDIR == v->type)
  746. return 1;
  747. if(a->index == v->type)
  748. return 1;
  749. }
  750. return 0;
  751. }
  752. /*
  753. * substitute s for v in a
  754. * return failure to substitute
  755. */
  756. int
  757. copysub(Adr *a, Adr *v, Adr *s, int f)
  758. {
  759. int t;
  760. if(copyas(a, v)) {
  761. t = s->type;
  762. if(t >= D_AX && t <= D_R15 || t >= D_X0 && t <= D_X0+15) {
  763. if(f)
  764. a->type = t;
  765. }
  766. return 0;
  767. }
  768. if(regtyp(v)) {
  769. t = v->type;
  770. if(a->type == t+D_INDIR) {
  771. if((s->type == D_BP || s->type == D_R13) && a->index != D_NONE)
  772. return 1; /* can't use BP-base with index */
  773. if(f)
  774. a->type = s->type+D_INDIR;
  775. // return 0;
  776. }
  777. if(a->index == t) {
  778. if(f)
  779. a->index = s->type;
  780. return 0;
  781. }
  782. return 0;
  783. }
  784. return 0;
  785. }