diff options
| author | Christopher Li <sparse@chrisli.org> | 2007-03-02 12:09:24 -0800 |
|---|---|---|
| committer | Josh Triplett <josh@freedesktop.org> | 2007-03-02 14:33:54 -0800 |
| commit | dd580753ccf1a372e3ff19ac90fdbfc92e94ca66 (patch) | |
| tree | 045c200ca51480af9f9fe01e94782769b54b918e | |
| parent | a4abe00d7a45a02a3135b24d5f04747397445f7a (diff) | |
| download | sparse-dev-dd580753ccf1a372e3ff19ac90fdbfc92e94ca66.tar.gz | |
Add annotation for inline function call.
For inline functions, Sparse inlines the function body at evaluation. It is
very hard to find out the original function call. This change preserves the
original call as an annotation.
Signed-Off-By: Christopher Li <sparse@chrisli.org>
| -rw-r--r-- | evaluate.c | 2 | ||||
| -rw-r--r-- | expand.c | 6 | ||||
| -rw-r--r-- | inline.c | 11 | ||||
| -rw-r--r-- | linearize.c | 44 | ||||
| -rw-r--r-- | linearize.h | 1 | ||||
| -rw-r--r-- | parse.h | 2 | ||||
| -rw-r--r-- | show-parse.c | 6 |
7 files changed, 57 insertions, 15 deletions
@@ -2789,7 +2789,7 @@ struct symbol *evaluate_statement(struct statement *stmt) * Then, evaluate each statement, making the type of the * compound statement be the type of the last statement */ - type = NULL; + type = evaluate_statement(stmt->args); FOR_EACH_PTR(stmt->stmts, s) { type = evaluate_statement(s); } END_FOR_EACH_PTR(s); @@ -1053,9 +1053,9 @@ static int expand_compound(struct statement *stmt) if (stmt->ret) expand_symbol(stmt->ret); - cost = 0; - last = NULL; - statements = 0; + last = stmt->args; + cost = expand_statement(last); + statements = last != NULL; FOR_EACH_PTR(stmt->stmts, s) { statements++; last = s; @@ -443,8 +443,9 @@ void copy_statement(struct statement *src, struct statement *dst) FOR_EACH_PTR(src->stmts, stmt) { add_statement(&dst->stmts, copy_one_statement(stmt)); } END_FOR_EACH_PTR(stmt); - + dst->args = copy_one_statement(src->args); dst->ret = copy_symbol(src->pos, src->ret); + dst->inline_fn = src->inline_fn; } static struct symbol *create_copy_symbol(struct symbol *orig) @@ -489,6 +490,7 @@ int inline_function(struct expression *expr, struct symbol *sym) } if (fn->expanding) return 0; + fn->expanding = 1; name_list = fn->arguments; @@ -517,13 +519,14 @@ int inline_function(struct expression *expr, struct symbol *sym) } END_FOR_EACH_PTR(arg); FINISH_PTR_LIST(name); + copy_statement(fn->inline_stmt, stmt); + if (arg_decl) { struct statement *decl = alloc_statement(expr->pos, STMT_DECLARATION); decl->declaration = arg_decl; - add_statement(&stmt->stmts, decl); + stmt->args = decl; } - - copy_statement(fn->inline_stmt, stmt); + stmt->inline_fn = sym; unset_replace_list(fn_symbol_list); diff --git a/linearize.c b/linearize.c index fc79e5a0..26f12b69 100644 --- a/linearize.c +++ b/linearize.c @@ -27,11 +27,11 @@ pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr); static pseudo_t add_binary_op(struct entrypoint *ep, struct symbol *ctype, int op, pseudo_t left, pseudo_t right); static pseudo_t add_setval(struct entrypoint *ep, struct symbol *ctype, struct expression *val); -static void linearize_one_symbol(struct entrypoint *ep, struct symbol *sym); +static pseudo_t linearize_one_symbol(struct entrypoint *ep, struct symbol *sym); struct access_data; static pseudo_t add_load(struct entrypoint *ep, struct access_data *); -pseudo_t linearize_initializer(struct entrypoint *ep, struct expression *initializer, struct access_data *); +static pseudo_t linearize_initializer(struct entrypoint *ep, struct expression *initializer, struct access_data *); struct pseudo void_pseudo = {}; @@ -226,6 +226,7 @@ static const char *opcodes[] = { [OP_SCAST] = "scast", [OP_FPCAST] = "fpcast", [OP_PTRCAST] = "ptrcast", + [OP_INLINED_CALL] = "# call", [OP_CALL] = "call", [OP_VANEXT] = "va_next", [OP_VAARG] = "va_arg", @@ -399,6 +400,7 @@ const char *show_instruction(struct instruction *insn) case OP_STORE: case OP_SNOP: buf += sprintf(buf, "%s -> %d[%s]", show_pseudo(insn->target), insn->offset, show_pseudo(insn->src)); break; + case OP_INLINED_CALL: case OP_CALL: { struct pseudo *arg; if (insn->target && insn->target != VOID) @@ -1487,7 +1489,7 @@ static pseudo_t linearize_position(struct entrypoint *ep, struct expression *pos return linearize_initializer(ep, init_expr, ad); } -pseudo_t linearize_initializer(struct entrypoint *ep, struct expression *initializer, struct access_data *ad) +static pseudo_t linearize_initializer(struct entrypoint *ep, struct expression *initializer, struct access_data *ad) { switch (initializer->type) { case EXPR_INITIALIZER: { @@ -1505,6 +1507,7 @@ pseudo_t linearize_initializer(struct entrypoint *ep, struct expression *initial ad->source_type = base_type(initializer->ctype); ad->result_type = initializer->ctype; linearize_store_gen(ep, value, ad); + return value; } } @@ -1595,21 +1598,23 @@ pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr) return VOID; } -static void linearize_one_symbol(struct entrypoint *ep, struct symbol *sym) +static pseudo_t linearize_one_symbol(struct entrypoint *ep, struct symbol *sym) { struct access_data ad = { NULL, }; + pseudo_t value; if (!sym || !sym->initializer || sym->initialized) - return; + return VOID; /* We need to output these puppies some day too.. */ if (sym->ctype.modifiers & (MOD_STATIC | MOD_TOPLEVEL)) - return; + return VOID; sym->initialized = 1; ad.address = symbol_pseudo(ep, sym); - linearize_initializer(ep, sym->initializer, &ad); + value = linearize_initializer(ep, sym->initializer, &ad); finish_address_gen(ep, &ad); + return value; } static pseudo_t linearize_compound_statement(struct entrypoint *ep, struct statement *stmt) @@ -1637,6 +1642,29 @@ static pseudo_t linearize_compound_statement(struct entrypoint *ep, struct state } return phi_node->target; } + + return pseudo; +} + +static pseudo_t linearize_inlined_call(struct entrypoint *ep, struct statement *stmt) +{ + struct instruction *insn = alloc_instruction(OP_INLINED_CALL, 0); + struct statement *args = stmt->args; + pseudo_t pseudo; + + if (args) { + struct symbol *sym; + + concat_symbol_list(args->declaration, &ep->syms); + FOR_EACH_PTR(args->declaration, sym) { + pseudo_t value = linearize_one_symbol(ep, sym); + use_pseudo(insn, value, add_pseudo(&insn->arguments, value)); + } END_FOR_EACH_PTR(sym); + } + + insn->target = pseudo = linearize_compound_statement(ep, stmt); + use_pseudo(insn, symbol_pseudo(ep, stmt->inline_fn), &insn->func); + add_one_insn(ep, insn); return pseudo; } @@ -1920,6 +1948,8 @@ pseudo_t linearize_statement(struct entrypoint *ep, struct statement *stmt) } case STMT_COMPOUND: + if (stmt->inline_fn) + return linearize_inlined_call(ep, stmt); return linearize_compound_statement(ep, stmt); /* diff --git a/linearize.h b/linearize.h index 673d13e4..8db8e82d 100644 --- a/linearize.h +++ b/linearize.h @@ -196,6 +196,7 @@ enum opcode { OP_SCAST, OP_FPCAST, OP_PTRCAST, + OP_INLINED_CALL, OP_CALL, OP_VANEXT, OP_VAARG, @@ -55,6 +55,8 @@ struct statement { struct /* compound_struct */ { struct statement_list *stmts; struct symbol *ret; + struct symbol *inline_fn; + struct statement *args; }; struct /* labeled_struct */ { struct symbol *label_identifier; diff --git a/show-parse.c b/show-parse.c index ed6ef80a..3bfe5a9d 100644 --- a/show-parse.c +++ b/show-parse.c @@ -485,6 +485,10 @@ int show_statement(struct statement *stmt) struct statement *s; int last = 0; + if (stmt->inline_fn) { + show_statement(stmt->args); + printf("\tbegin_inline \t%s\n", show_ident(stmt->inline_fn->ident)); + } FOR_EACH_PTR(stmt->stmts, s) { last = show_statement(s); } END_FOR_EACH_PTR(s); @@ -496,6 +500,8 @@ int show_statement(struct statement *stmt) last = new_pseudo(); printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr); } + if (stmt->inline_fn) + printf("\tend_inlined\t%s\n", show_ident(stmt->inline_fn->ident)); return last; } |
