openwrt-packages/utils/jq/patches/0002-Reimplement-block_drop...

86 lines
2.1 KiB
Diff

From aab54373e9406ee2a154b8d6166b3045aa3484ee Mon Sep 17 00:00:00 2001
From: Muh Muhten <muh.muhten@gmail.com>
Date: Sat, 9 Feb 2019 17:24:18 -0500
Subject: [PATCH 2/9] Reimplement block_drop_unreferenced in linear time
---
src/compile.c | 50 +++++++++++++++++++++++++++++---------------------
1 file changed, 29 insertions(+), 21 deletions(-)
--- a/src/compile.c
+++ b/src/compile.c
@@ -53,6 +53,7 @@ struct inst {
struct inst* bound_by;
char* symbol;
int any_unbound;
+ int referenced;
int nformals;
int nactuals;
@@ -75,6 +76,7 @@ static inst* inst_new(opcode op) {
i->bound_by = 0;
i->symbol = 0;
i->any_unbound = 0;
+ i->referenced = 0;
i->nformals = -1;
i->nactuals = -1;
i->subfn = gen_noop();
@@ -465,30 +467,36 @@ block block_bind_referenced(block binder
return block_join(refd, body);
}
+static void block_mark_referenced(block body) {
+ int saw_top = 0;
+ for (inst* i = body.last; i; i = i->prev) {
+ if (saw_top && i->bound_by == i && !i->referenced)
+ continue;
+ if (i->op == TOP) {
+ saw_top = 1;
+ }
+ if (i->bound_by) {
+ i->bound_by->referenced = 1;
+ }
+
+ block_mark_referenced(i->arglist);
+ block_mark_referenced(i->subfn);
+ }
+}
+
block block_drop_unreferenced(block body) {
- inst* curr;
+ block_mark_referenced(body);
+
block refd = gen_noop();
- block unrefd = gen_noop();
- int drop;
- do {
- drop = 0;
- while ((curr = block_take(&body)) && curr->op != TOP) {
- block b = inst_block(curr);
- if (block_count_refs(b,refd) + block_count_refs(b,body) == 0) {
- unrefd = BLOCK(unrefd, b);
- drop++;
- } else {
- refd = BLOCK(refd, b);
- }
- }
- if (curr && curr->op == TOP) {
- body = BLOCK(inst_block(curr),body);
+ inst* curr;
+ while ((curr = block_take(&body))) {
+ if (curr->bound_by == curr && !curr->referenced) {
+ inst_free(curr);
+ } else {
+ refd = BLOCK(inst_block(curr), refd);
}
- body = BLOCK(refd, body);
- refd = gen_noop();
- } while (drop != 0);
- block_free(unrefd);
- return body;
+ }
+ return refd;
}
jv block_take_imports(block* body) {