SsaNode* ssa_if(Parser* p, SsaNode* cond, SsaBlock* br1, SsaBlock* br2)
{
+ (void)br1, (void)br2;
cond = load(p, cond);
return NULL;
}
}
}
-static void print_block_graph(Parser* p, Bitset* set, SsaBlock* block)
+static void topsort(Bitset* set, SsaBlock** sorted, SsaBlock* block)
{
- if (bitset_has(set, block->id))
+ if (block && !bitset_has(set, block->id))
{
- return;
+ /* mark it visited and visit children */
+ bitset_add(set, block->id);
+ topsort(set, sorted, block->links[1]);
+ topsort(set, sorted, block->links[0]);
+
+ /* push block to the sorted list */
+ block->next = *sorted;
+ *sorted = block;
}
- bitset_add(set, block->id);
+}
- /* print the phis */
- for (SsaPhi* phi = block->phis; phi; phi = phi->next)
+void ssa_print_graph(Parser* p, SsaBlock* block)
+{
+ /* perform a topological sort of the nodes */
+ SsaBlock* sorted = NULL;
+ Bitset* set = bitset_new(p->blockid);
+ topsort(set, &sorted, block);
+
+
+ /* now let's print the plantuml representation */
+ printf("@startuml\n");
+ printf("[*] --> block%lu\n", block->id);
+ for (SsaBlock* curr = sorted; curr; curr = curr->next)
{
- Symbol* s = symbol_getbyid(p, phi->symid);
- s->version++;
- printf("block%lu: %s.%lu = phi(", block->id, s->name, s->version);
- for (SsaPhiVar* var = phi->vars; var; var = var->next)
+
+ /* print the phis */
+ for (SsaPhi* phi = block->phis; phi; phi = phi->next)
{
- printf("%s.%lu", s->name, var->version);
- if (var->next)
+ Symbol* s = symbol_getbyid(p, phi->symid);
+ s->version++;
+ printf("block%lu: %s.%lu = phi(", curr->id, s->name, s->version);
+ for (SsaPhiVar* var = phi->vars; var; var = var->next)
{
- printf(", ");
+ printf("%s.%lu", s->name, var->version);
+ if (var->next)
+ {
+ printf(", ");
+ }
}
+ puts(")");
}
- puts(")");
- }
-
- /* print the instructions */
- for (SsaNode* node = block->head; node; node = node->next)
- {
- printf("block%lu : ", block->id);
- print_dest(p, node);
- ssa_print(p, node);
- puts("");
- }
- /* print the next nodes */
- if (block->links[0])
- {
- printf("block%lu --> block%lu\n", block->id, block->links[0]->id);
- print_block_graph(p, set, block->links[0]);
- }
+ /* print the instructions */
+ for (SsaNode* node = curr->head; node; node = node->next)
+ {
+ printf("block%lu : ", curr->id);
+ print_dest(p, node);
+ ssa_print(p, node);
+ puts("");
+ }
- if (block->links[1])
- {
- printf("block%lu --> block%lu\n", block->id, block->links[1]->id);
-// if (!block->links[1]->phis)
+ /* print the links */
+ if (curr->links[1])
{
- print_block_graph(p, set, block->links[1]);
+ printf("block%lu --> block%lu\n", curr->id, curr->links[1]->id);
+ }
+ if (curr->links[0])
+ {
+ printf("block%lu --> block%lu\n", curr->id, curr->links[0]->id);
}
- }
-}
-void ssa_print_graph(Parser* p, SsaBlock* block)
-{
- printf("@startuml\n");
- printf("[*] --> block%lu\n", block->id);
- Bitset* set = bitset_new(p->blockid);
- print_block_graph(p, set, block);
+ puts("");
+ }
printf("@enduml\n");
}