You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
2.1 KiB

  1. From aab54373e9406ee2a154b8d6166b3045aa3484ee Mon Sep 17 00:00:00 2001
  2. From: Muh Muhten <muh.muhten@gmail.com>
  3. Date: Sat, 9 Feb 2019 17:24:18 -0500
  4. Subject: [PATCH 2/9] Reimplement block_drop_unreferenced in linear time
  5. ---
  6. src/compile.c | 50 +++++++++++++++++++++++++++++---------------------
  7. 1 file changed, 29 insertions(+), 21 deletions(-)
  8. --- a/src/compile.c
  9. +++ b/src/compile.c
  10. @@ -53,6 +53,7 @@ struct inst {
  11. struct inst* bound_by;
  12. char* symbol;
  13. int any_unbound;
  14. + int referenced;
  15. int nformals;
  16. int nactuals;
  17. @@ -75,6 +76,7 @@ static inst* inst_new(opcode op) {
  18. i->bound_by = 0;
  19. i->symbol = 0;
  20. i->any_unbound = 0;
  21. + i->referenced = 0;
  22. i->nformals = -1;
  23. i->nactuals = -1;
  24. i->subfn = gen_noop();
  25. @@ -465,30 +467,36 @@ block block_bind_referenced(block binder
  26. return block_join(refd, body);
  27. }
  28. +static void block_mark_referenced(block body) {
  29. + int saw_top = 0;
  30. + for (inst* i = body.last; i; i = i->prev) {
  31. + if (saw_top && i->bound_by == i && !i->referenced)
  32. + continue;
  33. + if (i->op == TOP) {
  34. + saw_top = 1;
  35. + }
  36. + if (i->bound_by) {
  37. + i->bound_by->referenced = 1;
  38. + }
  39. +
  40. + block_mark_referenced(i->arglist);
  41. + block_mark_referenced(i->subfn);
  42. + }
  43. +}
  44. +
  45. block block_drop_unreferenced(block body) {
  46. - inst* curr;
  47. + block_mark_referenced(body);
  48. +
  49. block refd = gen_noop();
  50. - block unrefd = gen_noop();
  51. - int drop;
  52. - do {
  53. - drop = 0;
  54. - while ((curr = block_take(&body)) && curr->op != TOP) {
  55. - block b = inst_block(curr);
  56. - if (block_count_refs(b,refd) + block_count_refs(b,body) == 0) {
  57. - unrefd = BLOCK(unrefd, b);
  58. - drop++;
  59. - } else {
  60. - refd = BLOCK(refd, b);
  61. - }
  62. - }
  63. - if (curr && curr->op == TOP) {
  64. - body = BLOCK(inst_block(curr),body);
  65. + inst* curr;
  66. + while ((curr = block_take(&body))) {
  67. + if (curr->bound_by == curr && !curr->referenced) {
  68. + inst_free(curr);
  69. + } else {
  70. + refd = BLOCK(inst_block(curr), refd);
  71. }
  72. - body = BLOCK(refd, body);
  73. - refd = gen_noop();
  74. - } while (drop != 0);
  75. - block_free(unrefd);
  76. - return body;
  77. + }
  78. + return refd;
  79. }
  80. jv block_take_imports(block* body) {