Skip to content

Commit 9966658

Browse files
committed
put scope dumping code in its own file
1 parent a92109d commit 9966658

File tree

3 files changed

+140
-129
lines changed

3 files changed

+140
-129
lines changed

src/shady/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ set(SHADY_SOURCES
3939
module.c
4040

4141
analysis/scope.c
42+
analysis/scope_dump.c
4243
analysis/free_variables.c
4344
analysis/verify.c
4445
analysis/callgraph.c

src/shady/analysis/scope.c

Lines changed: 0 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -498,132 +498,3 @@ struct List* scope_get_dom_frontier(Scope* scope, const CFNode* node) {
498498

499499
return dom_frontier;
500500
}
501-
502-
static int extra_uniqueness = 0;
503-
504-
static CFNode* get_let_pred(const CFNode* n) {
505-
if (entries_count_list(n->pred_edges) == 1) {
506-
CFEdge pred = read_list(CFEdge, n->pred_edges)[0];
507-
assert(pred.dst == n);
508-
if (pred.type == LetTailEdge && entries_count_list(pred.src->succ_edges) == 1) {
509-
assert(is_case(n->node));
510-
return pred.src;
511-
}
512-
}
513-
return NULL;
514-
}
515-
516-
static void dump_cf_node(FILE* output, const CFNode* n) {
517-
const Node* bb = n->node;
518-
const Node* body = get_abstraction_body(bb);
519-
if (!body)
520-
return;
521-
if (get_let_pred(n))
522-
return;
523-
524-
String color = "black";
525-
if (is_case(bb))
526-
color = "green";
527-
else if (is_basic_block(bb))
528-
color = "blue";
529-
530-
String label = "";
531-
532-
const CFNode* let_chain_end = n;
533-
while (body->tag == Let_TAG) {
534-
const Node* instr = body->payload.let.instruction;
535-
// label = "";
536-
if (instr->tag == PrimOp_TAG)
537-
label = format_string_arena(bb->arena->arena, "%slet ... = %s (...)\n", label, get_primop_name(instr->payload.prim_op.op));
538-
else
539-
label = format_string_arena(bb->arena->arena, "%slet ... = %s (...)\n", label, node_tags[instr->tag]);
540-
541-
if (entries_count_list(let_chain_end->succ_edges) != 1 || read_list(CFEdge, let_chain_end->succ_edges)[0].type != LetTailEdge)
542-
break;
543-
544-
let_chain_end = read_list(CFEdge, let_chain_end->succ_edges)[0].dst;
545-
const Node* abs = body->payload.let.tail;
546-
assert(let_chain_end->node == abs);
547-
assert(is_case(abs));
548-
body = get_abstraction_body(abs);
549-
}
550-
551-
label = format_string_arena(bb->arena->arena, "%s%s", label, node_tags[body->tag]);
552-
553-
String abs_name = get_abstraction_name_unsafe(bb);
554-
if (!abs_name)
555-
abs_name = format_string_interned(bb->arena, "%%%d", bb->id);
556-
label = format_string_arena(bb->arena->arena, "%s\n%s", abs_name, label);
557-
558-
fprintf(output, "bb_%zu [label=\"%s\", color=\"%s\", shape=box];\n", (size_t) n, label, color);
559-
560-
for (size_t i = 0; i < entries_count_list(n->dominates); i++) {
561-
CFNode* d = read_list(CFNode*, n->dominates)[i];
562-
if (!find_key_dict(const Node*, n->structurally_dominates, d->node))
563-
dump_cf_node(output, d);
564-
}
565-
}
566-
567-
static void dump_cfg_scope(FILE* output, Scope* scope) {
568-
extra_uniqueness++;
569-
570-
const Node* entry = scope->entry->node;
571-
fprintf(output, "subgraph cluster_%s {\n", get_abstraction_name(entry));
572-
fprintf(output, "label = \"%s\";\n", get_abstraction_name(entry));
573-
for (size_t i = 0; i < entries_count_list(scope->contents); i++) {
574-
const CFNode* n = read_list(const CFNode*, scope->contents)[i];
575-
dump_cf_node(output, n);
576-
}
577-
for (size_t i = 0; i < entries_count_list(scope->contents); i++) {
578-
const CFNode* bb_node = read_list(const CFNode*, scope->contents)[i];
579-
const CFNode* src_node = bb_node;
580-
while (true) {
581-
const CFNode* let_parent = get_let_pred(src_node);
582-
if (let_parent)
583-
src_node = let_parent;
584-
else
585-
break;
586-
}
587-
588-
for (size_t j = 0; j < entries_count_list(bb_node->succ_edges); j++) {
589-
CFEdge edge = read_list(CFEdge, bb_node->succ_edges)[j];
590-
const CFNode* target_node = edge.dst;
591-
592-
if (edge.type == LetTailEdge && get_let_pred(target_node) == bb_node)
593-
continue;
594-
595-
String edge_color = "black";
596-
switch (edge.type) {
597-
case LetTailEdge: edge_color = "green"; break;
598-
case StructuredEnterBodyEdge: edge_color = "blue"; break;
599-
case StructuredLeaveBodyEdge: edge_color = "red"; break;
600-
case StructuredPseudoExitEdge: edge_color = "darkred"; break;
601-
default: break;
602-
}
603-
604-
fprintf(output, "bb_%zu -> bb_%zu [color=\"%s\"];\n", (size_t) (src_node), (size_t) (target_node), edge_color);
605-
}
606-
}
607-
fprintf(output, "}\n");
608-
}
609-
610-
void dump_cfg(FILE* output, Module* mod) {
611-
if (output == NULL)
612-
output = stderr;
613-
614-
fprintf(output, "digraph G {\n");
615-
struct List* scopes = build_scopes(mod);
616-
for (size_t i = 0; i < entries_count_list(scopes); i++) {
617-
Scope* scope = read_list(Scope*, scopes)[i];
618-
dump_cfg_scope(output, scope);
619-
destroy_scope(scope);
620-
}
621-
destroy_list(scopes);
622-
fprintf(output, "}\n");
623-
}
624-
625-
void dump_cfg_auto(Module* mod) {
626-
FILE* f = fopen("cfg.dot", "wb");
627-
dump_cfg(f, mod);
628-
fclose(f);
629-
}

src/shady/analysis/scope_dump.c

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#include "scope.h"
2+
#include "../ir_private.h"
3+
4+
#include "list.h"
5+
#include "dict.h"
6+
#include "util.h"
7+
8+
#include <assert.h>
9+
10+
static int extra_uniqueness = 0;
11+
12+
static CFNode* get_let_pred(const CFNode* n) {
13+
if (entries_count_list(n->pred_edges) == 1) {
14+
CFEdge pred = read_list(CFEdge, n->pred_edges)[0];
15+
assert(pred.dst == n);
16+
if (pred.type == LetTailEdge && entries_count_list(pred.src->succ_edges) == 1) {
17+
assert(is_case(n->node));
18+
return pred.src;
19+
}
20+
}
21+
return NULL;
22+
}
23+
24+
static void dump_cf_node(FILE* output, const CFNode* n) {
25+
const Node* bb = n->node;
26+
const Node* body = get_abstraction_body(bb);
27+
if (!body)
28+
return;
29+
if (get_let_pred(n))
30+
return;
31+
32+
String color = "black";
33+
if (is_case(bb))
34+
color = "green";
35+
else if (is_basic_block(bb))
36+
color = "blue";
37+
38+
String label = "";
39+
40+
String abs_name = get_abstraction_name_unsafe(bb);
41+
if (!abs_name)
42+
abs_name = format_string_interned(bb->arena, "%%%d", bb->id);
43+
label = format_string_arena(bb->arena->arena, "%s: %s", abs_name, label);
44+
45+
const CFNode* let_chain_end = n;
46+
while (body->tag == Let_TAG) {
47+
const Node* instr = body->payload.let.instruction;
48+
// label = "";
49+
if (instr->tag == PrimOp_TAG)
50+
label = format_string_arena(bb->arena->arena, "%slet ... = %s (...)\n", label, get_primop_name(instr->payload.prim_op.op));
51+
else
52+
label = format_string_arena(bb->arena->arena, "%slet ... = %s (...)\n", label, node_tags[instr->tag]);
53+
54+
const Node* abs = body->payload.let.tail;
55+
label = format_string_arena(bb->arena->arena, "%s%%%d: ", label, abs->id);
56+
57+
if (entries_count_list(let_chain_end->succ_edges) != 1 || read_list(CFEdge, let_chain_end->succ_edges)[0].type != LetTailEdge)
58+
break;
59+
60+
let_chain_end = read_list(CFEdge, let_chain_end->succ_edges)[0].dst;
61+
assert(let_chain_end->node == abs);
62+
assert(is_case(abs));
63+
body = get_abstraction_body(abs);
64+
}
65+
66+
label = format_string_arena(bb->arena->arena, "%s%s", label, node_tags[body->tag]);
67+
68+
fprintf(output, "bb_%zu [label=\"%s\", color=\"%s\", shape=box];\n", (size_t) n, label, color);
69+
70+
for (size_t i = 0; i < entries_count_list(n->dominates); i++) {
71+
CFNode* d = read_list(CFNode*, n->dominates)[i];
72+
if (!find_key_dict(const Node*, n->structurally_dominates, d->node))
73+
dump_cf_node(output, d);
74+
}
75+
}
76+
77+
static void dump_cfg_scope(FILE* output, Scope* scope) {
78+
extra_uniqueness++;
79+
80+
const Node* entry = scope->entry->node;
81+
fprintf(output, "subgraph cluster_%s {\n", get_abstraction_name(entry));
82+
fprintf(output, "label = \"%s\";\n", get_abstraction_name(entry));
83+
for (size_t i = 0; i < entries_count_list(scope->contents); i++) {
84+
const CFNode* n = read_list(const CFNode*, scope->contents)[i];
85+
dump_cf_node(output, n);
86+
}
87+
for (size_t i = 0; i < entries_count_list(scope->contents); i++) {
88+
const CFNode* bb_node = read_list(const CFNode*, scope->contents)[i];
89+
const CFNode* src_node = bb_node;
90+
while (true) {
91+
const CFNode* let_parent = get_let_pred(src_node);
92+
if (let_parent)
93+
src_node = let_parent;
94+
else
95+
break;
96+
}
97+
98+
for (size_t j = 0; j < entries_count_list(bb_node->succ_edges); j++) {
99+
CFEdge edge = read_list(CFEdge, bb_node->succ_edges)[j];
100+
const CFNode* target_node = edge.dst;
101+
102+
if (edge.type == LetTailEdge && get_let_pred(target_node) == bb_node)
103+
continue;
104+
105+
String edge_color = "black";
106+
switch (edge.type) {
107+
case LetTailEdge: edge_color = "green"; break;
108+
case StructuredEnterBodyEdge: edge_color = "blue"; break;
109+
case StructuredLeaveBodyEdge: edge_color = "red"; break;
110+
case StructuredPseudoExitEdge: edge_color = "darkred"; break;
111+
default: break;
112+
}
113+
114+
fprintf(output, "bb_%zu -> bb_%zu [color=\"%s\"];\n", (size_t) (src_node), (size_t) (target_node), edge_color);
115+
}
116+
}
117+
fprintf(output, "}\n");
118+
}
119+
120+
void dump_cfg(FILE* output, Module* mod) {
121+
if (output == NULL)
122+
output = stderr;
123+
124+
fprintf(output, "digraph G {\n");
125+
struct List* scopes = build_scopes(mod);
126+
for (size_t i = 0; i < entries_count_list(scopes); i++) {
127+
Scope* scope = read_list(Scope*, scopes)[i];
128+
dump_cfg_scope(output, scope);
129+
destroy_scope(scope);
130+
}
131+
destroy_list(scopes);
132+
fprintf(output, "}\n");
133+
}
134+
135+
void dump_cfg_auto(Module* mod) {
136+
FILE* f = fopen("cfg.dot", "wb");
137+
dump_cfg(f, mod);
138+
fclose(f);
139+
}

0 commit comments

Comments
 (0)