peep.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. #include "gc.h"
  2. void
  3. peep(void)
  4. {
  5. Reg *r, *r1, *r2;
  6. Prog *p;
  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 == AMOV)
  41. if(regtyp(&p->to))
  42. if(regtyp(&p->from)) {
  43. if(copyprop(r)) {
  44. excise(r);
  45. t++;
  46. }
  47. if(subprop(r) && copyprop(r)) {
  48. excise(r);
  49. t++;
  50. }
  51. }
  52. }
  53. if(t)
  54. goto loop1;
  55. }
  56. void
  57. excise(Reg *r)
  58. {
  59. Prog *p;
  60. p = r->prog;
  61. p->as = ANOP;
  62. p->from = zprog.from;
  63. p->to = zprog.to;
  64. }
  65. Reg*
  66. uniqp(Reg *r)
  67. {
  68. Reg *r1;
  69. r1 = r->p1;
  70. if(r1 == R) {
  71. r1 = r->p2;
  72. if(r1 == R || r1->p2link != R)
  73. return R;
  74. } else
  75. if(r->p2 != R)
  76. return R;
  77. return r1;
  78. }
  79. Reg*
  80. uniqs(Reg *r)
  81. {
  82. Reg *r1;
  83. r1 = r->s1;
  84. if(r1 == R) {
  85. r1 = r->s2;
  86. if(r1 == R)
  87. return R;
  88. } else
  89. if(r->s2 != R)
  90. return R;
  91. return r1;
  92. }
  93. int
  94. regtyp(Adr *a)
  95. {
  96. int t;
  97. t = a->type;
  98. if(t >= D_R0 && t <= D_R0+31)
  99. return 1;
  100. return 0;
  101. }
  102. /*
  103. * the idea is to substitute
  104. * one register for another
  105. * from one MOV to another
  106. * MOV a, R0
  107. * ADD b, R0 / no use of R1
  108. * MOV R0, R1
  109. * would be converted to
  110. * MOV a, R1
  111. * ADD b, R1
  112. * MOV R1, R0
  113. * hopefully, then the former or latter MOV
  114. * will be eliminated by copy propagation.
  115. */
  116. int
  117. subprop(Reg *r0)
  118. {
  119. Prog *p;
  120. Adr *v1, *v2;
  121. Reg *r;
  122. int t;
  123. p = r0->prog;
  124. v1 = &p->from;
  125. if(!regtyp(v1))
  126. return 0;
  127. v2 = &p->to;
  128. if(!regtyp(v2))
  129. return 0;
  130. for(r=uniqp(r0); r!=R; r=uniqp(r)) {
  131. if(uniqs(r) == R)
  132. break;
  133. p = r->prog;
  134. switch(p->as) {
  135. case ABAL:
  136. return 0;
  137. case AADDI: /* 3-op */
  138. case AADDO:
  139. case AAND:
  140. case ASUBI:
  141. case ASUBO:
  142. case AOR:
  143. case AXOR:
  144. case ASHLI:
  145. case ASHRI:
  146. case ASHLO:
  147. case ASHRO:
  148. case AMULI:
  149. case AMULO:
  150. case ADIVI:
  151. case ADIVO:
  152. case AREMI:
  153. case AREMO:
  154. if(p->type != D_NONE)
  155. return 0;
  156. break; /* botch */
  157. if(p->to.type == v1->type) {
  158. if(p->type == D_NONE)
  159. p->type = p->to.type;
  160. goto gotit;
  161. }
  162. break;
  163. case AMOV:
  164. if(p->to.type == v1->type)
  165. goto gotit;
  166. break;
  167. }
  168. if(copyau(&p->from, v2) ||
  169. copyau(&p->to, v2))
  170. break;
  171. if(copysub(&p->from, v1, v2, 0) ||
  172. copysub(&p->to, v1, v2, 0))
  173. break;
  174. }
  175. return 0;
  176. gotit:
  177. copysub(&p->to, v1, v2, 1);
  178. if(debug['P']) {
  179. print("gotit: %D->%D\n%P", v1, v2, r->prog);
  180. if(p->from.type == v2->type)
  181. print(" excise");
  182. print("\n");
  183. }
  184. for(r=uniqs(r); r!=r0; r=uniqs(r)) {
  185. p = r->prog;
  186. copysub(&p->from, v1, v2, 1);
  187. copysub(&p->to, v1, v2, 1);
  188. if(debug['P'])
  189. print("%P\n", r->prog);
  190. }
  191. t = v1->type;
  192. v1->type = v2->type;
  193. v2->type = t;
  194. if(debug['P'])
  195. print("%P last\n", r->prog);
  196. return 1;
  197. }
  198. /*
  199. * The idea is to remove redundant copies.
  200. * v1->v2 F=0
  201. * (use v2 s/v2/v1/)*
  202. * set v1 F=1
  203. * use v2 return fail
  204. * -----------------
  205. * v1->v2 F=0
  206. * (use v2 s/v2/v1/)*
  207. * set v1 F=1
  208. * set v2 return success
  209. */
  210. int
  211. copyprop(Reg *r0)
  212. {
  213. Prog *p;
  214. Adr *v1, *v2;
  215. Reg *r;
  216. p = r0->prog;
  217. v1 = &p->from;
  218. v2 = &p->to;
  219. if(copyas(v1, v2))
  220. return 1;
  221. for(r=firstr; r!=R; r=r->link)
  222. r->active = 0;
  223. return copy1(v1, v2, r0->s1, 0);
  224. }
  225. int
  226. copy1(Adr *v1, Adr *v2, Reg *r, int f)
  227. {
  228. int t;
  229. Prog *p;
  230. if(r->active) {
  231. if(debug['P'])
  232. print("act set; return 1\n");
  233. return 1;
  234. }
  235. r->active = 1;
  236. if(debug['P'])
  237. print("copy %D->%D f=%d\n", v1, v2, f);
  238. for(; r != R; r = r->s1) {
  239. p = r->prog;
  240. if(debug['P'])
  241. print("%P", p);
  242. if(!f && uniqp(r) == R) {
  243. f = 1;
  244. if(debug['P'])
  245. print("; merge; f=%d", f);
  246. }
  247. t = copyu(p, v2, A);
  248. switch(t) {
  249. case 2: /* rar, cant split */
  250. if(debug['P'])
  251. print("; %D rar; return 0\n", v2);
  252. return 0;
  253. case 3: /* set */
  254. if(debug['P'])
  255. print("; %D set; return 1\n", v2);
  256. return 1;
  257. case 1: /* used, substitute */
  258. case 4: /* use and set */
  259. if(f) {
  260. if(!debug['P'])
  261. return 0;
  262. if(t == 4)
  263. print("; %D used+set and f=%d; return 0\n", v2, f);
  264. else
  265. print("; %D used and f=%d; return 0\n", v2, f);
  266. return 0;
  267. }
  268. if(copyu(p, v2, v1)) {
  269. if(debug['P'])
  270. print("; sub fail; return 0\n");
  271. return 0;
  272. }
  273. if(debug['P'])
  274. print("; sub %D/%D", v2, v1);
  275. if(t == 4) {
  276. if(debug['P'])
  277. print("; %D used+set; return 1\n", v2);
  278. return 1;
  279. }
  280. break;
  281. }
  282. if(!f) {
  283. t = copyu(p, v1, A);
  284. if(!f && (t == 2 || t == 3 || t == 4)) {
  285. f = 1;
  286. if(debug['P'])
  287. print("; %D set and !f; f=%d", v1, f);
  288. }
  289. }
  290. if(debug['P'])
  291. print("\n");
  292. if(r->s2)
  293. if(!copy1(v1, v2, r->s2, f))
  294. return 0;
  295. }
  296. return 1;
  297. }
  298. /*
  299. * return
  300. * 1 if v only used (and substitute),
  301. * 2 if read-alter-rewrite
  302. * 3 if set
  303. * 4 if set and used
  304. * 0 otherwise (not touched)
  305. */
  306. copyu(Prog *p, Adr *v, Adr *s)
  307. {
  308. switch(p->as) {
  309. default:
  310. print("default -- rar %P\n", p);
  311. case ASHLI:
  312. case ASHRI:
  313. case ASHLO:
  314. case ASHRO:
  315. case AMULI:
  316. case AMULO:
  317. case ADIVI:
  318. case ADIVO:
  319. case AREMI:
  320. case AREMO:
  321. if(debug['P'])
  322. print("unknown op %A\n", p->as);
  323. return 2;
  324. case AMOVA: /* lhs addr, rhs store */
  325. if(copyas(&p->from, v))
  326. return 2;
  327. case ANOP: /* rhs store */
  328. case AMOV:
  329. case AMOVOB:
  330. case AMOVIB:
  331. case AMOVOS:
  332. case AMOVIS:
  333. if(copyas(&p->to, v)) {
  334. if(s != A)
  335. return copysub(&p->from, v, s, 1);
  336. if(copyau(&p->from, v))
  337. return 4;
  338. return 3;
  339. }
  340. goto caseread;
  341. case AADDI: /* rhs rar */
  342. case AADDO:
  343. case AAND:
  344. case ASUBI:
  345. case ASUBO:
  346. case AOR:
  347. case AXOR:
  348. if(copyas(&p->to, v))
  349. return 2;
  350. goto caseread;
  351. case ACMPI: /* read only */
  352. case ACMPO:
  353. caseread:
  354. if(p->type != D_NONE)
  355. return 2; /* botch */
  356. if(s != A) {
  357. if(copysub(&p->from, v, s, 1))
  358. return 1;
  359. return copysub(&p->to, v, s, 1);
  360. }
  361. if(copyau(&p->from, v))
  362. return 1;
  363. if(copyau(&p->to, v))
  364. return 1;
  365. break;
  366. case AB: /* no reference */
  367. case ABNE:
  368. case ABE:
  369. case ABL:
  370. case ABLE:
  371. case ABG:
  372. case ABGE:
  373. break;
  374. case ARTS: /* funny */
  375. case ABAL: /* funny */
  376. if(v->type == REGRET)
  377. return 2;
  378. if(s != A) {
  379. if(s->type == REGRET)
  380. return 2;
  381. if(copysub(&p->to, v, s, 1))
  382. return 1;
  383. return 0;
  384. }
  385. if(copyau(&p->to, v))
  386. return 4;
  387. return 3;
  388. }
  389. return 0;
  390. }
  391. /*
  392. * direct reference,
  393. * could be set/use depending on
  394. * semantics
  395. */
  396. int
  397. copyas(Adr *a, Adr *v)
  398. {
  399. if(a->type != v->type)
  400. return 0;
  401. if(regtyp(v))
  402. return 1;
  403. if(v->type == D_AUTO || v->type == D_PARAM)
  404. if(v->offset == a->offset)
  405. return 1;
  406. return 0;
  407. }
  408. int
  409. copyas1(Prog *p, Adr *v)
  410. {
  411. if(p->type != v->type)
  412. return 0;
  413. if(regtyp(v))
  414. return 1;
  415. return 0;
  416. }
  417. /*
  418. * either direct or indirect
  419. */
  420. int
  421. copyau(Adr *a, Adr *v)
  422. {
  423. if(copyas(a, v))
  424. return 1;
  425. if(regtyp(v)) {
  426. if(a->type-D_INDIR == v->type)
  427. return 1;
  428. if(a->index == v->type)
  429. return 1;
  430. }
  431. return 0;
  432. }
  433. /*
  434. * substitute s for v in a
  435. * return failure to substitute
  436. */
  437. int
  438. copysub(Adr *a, Adr *v, Adr *s, int f)
  439. {
  440. int t;
  441. if(copyas(a, v)) {
  442. t = s->type;
  443. if(t >= D_R0 && t <= D_R0+31) {
  444. if(f)
  445. a->type = t;
  446. }
  447. return 0;
  448. }
  449. if(regtyp(v)) {
  450. t = v->type;
  451. if(a->type == t+D_INDIR) {
  452. if(f)
  453. a->type = s->type+D_INDIR;
  454. return 0;
  455. }
  456. if(a->index == t) {
  457. if(f)
  458. a->index = s->type;
  459. return 0;
  460. }
  461. return 0;
  462. }
  463. return 0;
  464. }
  465. /*
  466. * substitute s for v in p
  467. * return failure to substitute
  468. */
  469. int
  470. copysub1(Prog *p, Adr *v, Adr *s, int f)
  471. {
  472. int t;
  473. if(copyas1(p, v)) {
  474. t = s->type;
  475. if(t >= D_R0 && t <= D_R0+31) {
  476. if(f)
  477. p->type = t;
  478. }
  479. return 0;
  480. }
  481. return 0;
  482. }