This add a linearization phase. It's not even close to done
[smatch.git] / linearize.c
blobccaca661b8449921239e0ad5d5ec6c5860b62964
1 /*
2 * Linearize - walk the statement tree (but _not_ the expressions)
3 * to generate a linear version of it and the basic blocks.
5 * NOTE! We're not interested in the actual sub-expressions yet,
6 * even though they can generate conditional branches and
7 * subroutine calls. That's all "local" behaviour.
9 * Copyright (C) 2004 Linus Torvalds
12 #include <string.h>
13 #include <stdarg.h>
14 #include <stdlib.h>
15 #include <stdio.h>
17 #include "linearize.h"
19 static struct entrypoint *alloc_entrypoint(void)
21 return __alloc_entrypoint(0);
24 static struct basic_block *alloc_basic_block(void)
26 return __alloc_basic_block(0);
29 static void show_bb(struct basic_block *bb)
31 struct statement *stmt;
33 printf("bb: %p\n", bb);
34 FOR_EACH_PTR(bb->stmts, stmt) {
35 show_statement(stmt);
36 } END_FOR_EACH_PTR;
39 static void show_entry(struct entrypoint *ep)
41 struct symbol *sym;
42 struct basic_block *bb;
44 printf("ep %p: %s\n", ep, show_ident(ep->name->ident));
46 FOR_EACH_PTR(ep->syms, sym) {
47 printf(" sym: %p %s\n", sym, show_ident(sym->ident));
48 } END_FOR_EACH_PTR;
50 printf("\n");
52 FOR_EACH_PTR(ep->bbs, bb) {
53 show_bb(bb);
54 } END_FOR_EACH_PTR;
56 printf("\n");
59 static struct basic_block * linearize_statement(struct symbol_list **syms,
60 struct basic_block_list **bbs,
61 struct basic_block *bb,
62 struct statement *stmt)
64 if (!stmt)
65 return bb;
67 switch (stmt->type) {
68 case STMT_NONE:
69 return bb;
71 case STMT_EXPRESSION:
72 add_statement(&bb->stmts, stmt);
73 break;
75 case STMT_COMPOUND: {
76 struct statement *s;
77 copy_symbol_list(stmt->syms, syms);
78 FOR_EACH_PTR(stmt->stmts, s) {
79 bb = linearize_statement(syms, bbs, bb, s);
80 } END_FOR_EACH_PTR;
81 break;
84 default:
85 break;
87 return bb;
90 void linearize_symbol(struct symbol *sym)
92 struct symbol *base_type;
94 if (!sym)
95 return;
96 base_type = sym->ctype.base_type;
97 if (!base_type)
98 return;
99 if (base_type->type == SYM_FN) {
100 if (base_type->stmt) {
101 struct entrypoint *ep = alloc_entrypoint();
102 struct basic_block *bb = alloc_basic_block();
103 ep->name = sym;
104 add_bb(&ep->bbs, bb);
105 copy_symbol_list(base_type->arguments, &ep->syms);
106 linearize_statement(&ep->syms, &ep->bbs, bb, base_type->stmt);
107 show_entry(ep);