diff options
| author | Linus Torvalds <torvalds@home.osdl.org> | 2004-02-11 14:53:39 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:01:20 -0700 |
| commit | 7f2bd1a27e9df408cbae57cf2aa9aa45383a7bb7 (patch) | |
| tree | 5074b20247dbc3ce9ed5296ddc42fc0a4ba872d6 /linearize.c | |
| parent | 3ffb6bac9871d6e2ed08ffbd61835561c48e9608 (diff) | |
| download | sparse-dev-7f2bd1a27e9df408cbae57cf2aa9aa45383a7bb7.tar.gz | |
This add a linearization phase. It's not even close to done
yet, but the framework is there.
When we linearize the tree we just generate a list of basic
blocks of statement expressions (and branches between them,
although that "small details" isn't actually done yet ;).
Diffstat (limited to 'linearize.c')
| -rw-r--r-- | linearize.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/linearize.c b/linearize.c new file mode 100644 index 00000000..ccaca661 --- /dev/null +++ b/linearize.c @@ -0,0 +1,110 @@ +/* + * Linearize - walk the statement tree (but _not_ the expressions) + * to generate a linear version of it and the basic blocks. + * + * NOTE! We're not interested in the actual sub-expressions yet, + * even though they can generate conditional branches and + * subroutine calls. That's all "local" behaviour. + * + * Copyright (C) 2004 Linus Torvalds + */ + +#include <string.h> +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> + +#include "linearize.h" + +static struct entrypoint *alloc_entrypoint(void) +{ + return __alloc_entrypoint(0); +} + +static struct basic_block *alloc_basic_block(void) +{ + return __alloc_basic_block(0); +} + +static void show_bb(struct basic_block *bb) +{ + struct statement *stmt; + + printf("bb: %p\n", bb); + FOR_EACH_PTR(bb->stmts, stmt) { + show_statement(stmt); + } END_FOR_EACH_PTR; +} + +static void show_entry(struct entrypoint *ep) +{ + struct symbol *sym; + struct basic_block *bb; + + printf("ep %p: %s\n", ep, show_ident(ep->name->ident)); + + FOR_EACH_PTR(ep->syms, sym) { + printf(" sym: %p %s\n", sym, show_ident(sym->ident)); + } END_FOR_EACH_PTR; + + printf("\n"); + + FOR_EACH_PTR(ep->bbs, bb) { + show_bb(bb); + } END_FOR_EACH_PTR; + + printf("\n"); +} + +static struct basic_block * linearize_statement(struct symbol_list **syms, + struct basic_block_list **bbs, + struct basic_block *bb, + struct statement *stmt) +{ + if (!stmt) + return bb; + + switch (stmt->type) { + case STMT_NONE: + return bb; + + case STMT_EXPRESSION: + add_statement(&bb->stmts, stmt); + break; + + case STMT_COMPOUND: { + struct statement *s; + copy_symbol_list(stmt->syms, syms); + FOR_EACH_PTR(stmt->stmts, s) { + bb = linearize_statement(syms, bbs, bb, s); + } END_FOR_EACH_PTR; + break; + } + + default: + break; + } + return bb; +} + +void linearize_symbol(struct symbol *sym) +{ + struct symbol *base_type; + + if (!sym) + return; + base_type = sym->ctype.base_type; + if (!base_type) + return; + if (base_type->type == SYM_FN) { + if (base_type->stmt) { + struct entrypoint *ep = alloc_entrypoint(); + struct basic_block *bb = alloc_basic_block(); + ep->name = sym; + add_bb(&ep->bbs, bb); + copy_symbol_list(base_type->arguments, &ep->syms); + linearize_statement(&ep->syms, &ep->bbs, bb, base_type->stmt); + show_entry(ep); + } + } +} |
