aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorChristopher Li <sparse@chrisli.org>2007-03-02 12:09:24 -0800
committerJosh Triplett <josh@freedesktop.org>2007-03-02 14:33:54 -0800
commitdd580753ccf1a372e3ff19ac90fdbfc92e94ca66 (patch)
tree045c200ca51480af9f9fe01e94782769b54b918e
parenta4abe00d7a45a02a3135b24d5f04747397445f7a (diff)
downloadsparse-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.c2
-rw-r--r--expand.c6
-rw-r--r--inline.c11
-rw-r--r--linearize.c44
-rw-r--r--linearize.h1
-rw-r--r--parse.h2
-rw-r--r--show-parse.c6
7 files changed, 57 insertions, 15 deletions
diff --git a/evaluate.c b/evaluate.c
index b09088ba..190a1121 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -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);
diff --git a/expand.c b/expand.c
index 96edc480..5fc02214 100644
--- a/expand.c
+++ b/expand.c
@@ -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;
diff --git a/inline.c b/inline.c
index 77adfab3..4a9fca45 100644
--- a/inline.c
+++ b/inline.c
@@ -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,
diff --git a/parse.h b/parse.h
index f43d4311..98c33bcc 100644
--- a/parse.h
+++ b/parse.h
@@ -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;
}