diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-02-01 20:13:36 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-02-01 20:13:36 -0700 |
| commit | a2035eefba0fe8f29d0bcffbe254c066fc97069b (patch) | |
| tree | 63993adc8abbf5e8dfc6564215c505d9ba1a23bf /src/analyze.cpp | |
| parent | 74eaf4376800ab1a3405a69e4f65ecfecb1e1db9 (diff) | |
| download | zig-a2035eefba0fe8f29d0bcffbe254c066fc97069b.tar.gz zig-a2035eefba0fe8f29d0bcffbe254c066fc97069b.zip | |
codegen: avoid table lookup in assembly expression
Diffstat (limited to 'src/analyze.cpp')
| -rw-r--r-- | src/analyze.cpp | 75 |
1 files changed, 38 insertions, 37 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 81874e0fdb..49d04057eb 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2431,19 +2431,6 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, return g->builtin_types.entry_invalid; } -static TypeTableEntry *analyze_variable_name(CodeGen *g, ImportTableEntry *import, BlockContext *context, - AstNode *node, Buf *variable_name) -{ - VariableTableEntry *var = find_variable(context, variable_name); - if (var) { - return var->type; - } else { - add_node_error(g, node, - buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); - return g->builtin_types.entry_invalid; - } -} - static bool is_op_allowed(TypeTableEntry *type, BinOpType op) { switch (op) { case BinOpTypeAssign: @@ -4402,6 +4389,42 @@ static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, return return_type; } +static TypeTableEntry *analyze_asm_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, + TypeTableEntry *expected_type, AstNode *node) +{ + node->data.asm_expr.return_count = 0; + TypeTableEntry *return_type = g->builtin_types.entry_void; + for (int i = 0; i < node->data.asm_expr.output_list.length; i += 1) { + AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); + if (asm_output->return_type) { + node->data.asm_expr.return_count += 1; + return_type = analyze_type_expr(g, import, context, asm_output->return_type); + if (node->data.asm_expr.return_count > 1) { + add_node_error(g, node, + buf_sprintf("inline assembly allows up to one output value")); + break; + } + } else { + Buf *variable_name = &asm_output->variable_name; + VariableTableEntry *var = find_variable(context, variable_name); + if (var) { + asm_output->variable = var; + return var->type; + } else { + add_node_error(g, node, + buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); + return g->builtin_types.entry_invalid; + } + } + } + for (int i = 0; i < node->data.asm_expr.input_list.length; i += 1) { + AsmInput *asm_input = node->data.asm_expr.input_list.at(i); + analyze_expression(g, import, context, nullptr, asm_input->expr); + } + + return return_type; +} + // When you call analyze_expression, the node you pass might no longer be the child node // you thought it was due to implicit casting rewriting the AST. static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context, @@ -4441,30 +4464,8 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, return_type = analyze_continue_expr(g, import, context, expected_type, node); break; case NodeTypeAsmExpr: - { - node->data.asm_expr.return_count = 0; - return_type = g->builtin_types.entry_void; - for (int i = 0; i < node->data.asm_expr.output_list.length; i += 1) { - AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); - if (asm_output->return_type) { - node->data.asm_expr.return_count += 1; - return_type = analyze_type_expr(g, import, context, asm_output->return_type); - if (node->data.asm_expr.return_count > 1) { - add_node_error(g, node, - buf_sprintf("inline assembly allows up to one output value")); - break; - } - } else { - analyze_variable_name(g, import, context, node, &asm_output->variable_name); - } - } - for (int i = 0; i < node->data.asm_expr.input_list.length; i += 1) { - AsmInput *asm_input = node->data.asm_expr.input_list.at(i); - analyze_expression(g, import, context, nullptr, asm_input->expr); - } - - break; - } + return_type = analyze_asm_expr(g, import, context, expected_type, node); + break; case NodeTypeBinOpExpr: return_type = analyze_bin_op_expr(g, import, context, expected_type, node); break; |
