ifopt.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include "all.h"
  2. enum {
  3. MaxIns = 2,
  4. MaxPhis = 2,
  5. };
  6. static int
  7. okbranch(Blk *b)
  8. {
  9. Ins *i;
  10. int n;
  11. n = 0;
  12. for (i=b->ins; i<&b->ins[b->nins]; i++)
  13. if (i->op != Odbgloc) {
  14. if (pinned(i))
  15. return 0;
  16. if (i->op != Onop)
  17. n++;
  18. }
  19. return n <= MaxIns;
  20. }
  21. static int
  22. okjoin(Blk *b)
  23. {
  24. Phi *p;
  25. int n;
  26. n = 0;
  27. for (p=b->phi; p; p=p->link) {
  28. if (KBASE(p->cls) != 0)
  29. return 0;
  30. n++;
  31. }
  32. return n <= MaxPhis;
  33. }
  34. static int
  35. okgraph(Blk *ifb, Blk *thenb, Blk *elseb, Blk *joinb)
  36. {
  37. if (joinb->npred != 2 || !okjoin(joinb))
  38. return 0;
  39. assert(thenb != elseb);
  40. if (thenb != ifb && !okbranch(thenb))
  41. return 0;
  42. if (elseb != ifb && !okbranch(elseb))
  43. return 0;
  44. return 1;
  45. }
  46. static void
  47. convert(Blk *ifb, Blk *thenb, Blk *elseb, Blk *joinb)
  48. {
  49. Ins *ins, sel;
  50. Phi *p;
  51. uint nins;
  52. ins = vnew(0, sizeof ins[0], PHeap);
  53. nins = 0;
  54. addbins(&ins, &nins, ifb);
  55. if (thenb != ifb)
  56. addbins(&ins, &nins, thenb);
  57. if (elseb != ifb)
  58. addbins(&ins, &nins, elseb);
  59. assert(joinb->npred == 2);
  60. if (joinb->phi) {
  61. sel = (Ins){
  62. .op = Osel0, .cls = Kw,
  63. .arg = {ifb->jmp.arg},
  64. };
  65. addins(&ins, &nins, &sel);
  66. }
  67. sel = (Ins){.op = Osel1};
  68. for (p=joinb->phi; p; p=p->link) {
  69. sel.to = p->to;
  70. sel.cls = p->cls;
  71. sel.arg[0] = phiarg(p, thenb);
  72. sel.arg[1] = phiarg(p, elseb);
  73. addins(&ins, &nins, &sel);
  74. }
  75. idup(ifb, ins, nins);
  76. ifb->jmp.type = Jjmp;
  77. ifb->jmp.arg = R;
  78. ifb->s1 = joinb;
  79. ifb->s2 = 0;
  80. joinb->npred = 1;
  81. joinb->pred[0] = ifb;
  82. joinb->phi = 0;
  83. vfree(ins);
  84. }
  85. /* eliminate if-then[-else] graphlets
  86. * using sel instructions
  87. * needs rpo pred use; breaks cfg use
  88. */
  89. void
  90. ifconvert(Fn *fn)
  91. {
  92. Blk *ifb, *thenb, *elseb, *joinb;
  93. if (debug['K'])
  94. fputs("\n> If-conversion:\n", stderr);
  95. for (ifb=fn->start; ifb; ifb=ifb->link)
  96. if (ifgraph(ifb, &thenb, &elseb, &joinb))
  97. if (okgraph(ifb, thenb, elseb, joinb)) {
  98. if (debug['K'])
  99. fprintf(stderr,
  100. " @%s -> @%s, @%s -> @%s\n",
  101. ifb->name, thenb->name, elseb->name,
  102. joinb->name);
  103. convert(ifb, thenb, elseb, joinb);
  104. }
  105. if (debug['K']) {
  106. fprintf(stderr, "\n> After if-conversion:\n");
  107. printfn(fn, stderr);
  108. }
  109. }