Ignore generating a return instruction in accumulated functions, eventually we'll...
authorDale Weiler <killfieldengine@gmail.com>
Thu, 17 Oct 2013 08:45:24 +0000 (04:45 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Thu, 17 Oct 2013 08:45:24 +0000 (04:45 -0400)
ast.c
ir.c
ir.h

diff --git a/ast.c b/ast.c
index cb4ad064979ad824b70ec33dde0df709819529c7..21a29ead5cf193a45616635a08f6aa7df7352c09 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -1879,6 +1879,8 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
         for (i = 0; i < vec_size(ec->params); i++)
             vec_push(call->params, (ast_expression*)ec->params[i]);
         vec_push(vec_last(self->blocks)->exprs, (ast_expression*)call);
+
+        self->ir_func->flags |= IR_FLAG_ACCUMULATE;
     }
 
     for (i = 0; i < vec_size(self->blocks); ++i) {
diff --git a/ir.c b/ir.c
index 9967d7d8dbd91649a62c55b69772a91fa3c6e2de..fbb79f2e6cd0e03005cb7c5167fe229279e485bc 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -1583,7 +1583,13 @@ bool ir_block_create_return(ir_block *self, lex_ctx_t ctx, ir_value *v)
     ir_instr *in;
     if (!ir_check_unreachable(self))
         return false;
+
     self->final = true;
+
+    /* can eliminate the return instructions for accumulation */
+    if (self->owner->flags & IR_FLAG_ACCUMULATE)
+        return true;
+
     self->is_return = true;
     in = ir_instr_new(ctx, self, INSTR_RETURN);
     if (!in)
diff --git a/ir.h b/ir.h
index 3c236ea7f12e83200656afd82697abd08946d69e..507a2317e461c6251d39656cb8101ff25d0a4b49 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -232,6 +232,7 @@ typedef struct ir_function_s
 #define IR_FLAG_HAS_GOTO          (1<<3)
 #define IR_FLAG_INCLUDE_DEF       (1<<4)
 #define IR_FLAG_ERASEABLE         (1<<5)
+#define IR_FLAG_ACCUMULATE        (1<<6)
 #define IR_FLAG_MASK_NO_OVERLAP     (IR_FLAG_HAS_ARRAYS | IR_FLAG_HAS_UNINITIALIZED)
 #define IR_FLAG_MASK_NO_LOCAL_TEMPS (IR_FLAG_HAS_ARRAYS | IR_FLAG_HAS_UNINITIALIZED)