diff --git a/src/liboptimizer/optimizer-passes.c b/src/liboptimizer/optimizer-passes.c index 868d72ca0..449323c33 100644 --- a/src/liboptimizer/optimizer-passes.c +++ b/src/liboptimizer/optimizer-passes.c @@ -322,6 +322,7 @@ optimizer_reorder_scope (uint16_t scope_start, uint16_t scope_end) OPCODE *first_opcode = opcodes + scope_start; OPCODE *last_opcode = opcodes + scope_end; OPCODE *current_opcode, *processed_opcode = first_opcode; + OPCODE *var_decls_start; for (current_opcode = processed_opcode; current_opcode != last_opcode; current_opcode++) { @@ -374,13 +375,40 @@ optimizer_reorder_scope (uint16_t scope_start, uint16_t scope_end) current_opcode++; } + var_decls_start = processed_opcode; for (current_opcode = processed_opcode; current_opcode != last_opcode; current_opcode++) { if (current_opcode->op_idx == NAME_TO_ID (var_decl)) { - optimizer_move_opcodes (current_opcode, processed_opcode, 1); - optimizer_adjust_jumps (processed_opcode + 1, current_opcode + 1, 1); - processed_opcode++; + // If variable already declared, replace it with nop + bool was_decl = false; + if (var_decls_start->op_idx == NAME_TO_ID (var_decl) && var_decls_start != current_opcode) + { + OPCODE *var_decls_iterator; + for (var_decls_iterator = var_decls_start; + var_decls_iterator != processed_opcode; + var_decls_iterator++) + { + JERRY_ASSERT (var_decls_iterator->op_idx == NAME_TO_ID (var_decl)); + if (var_decls_iterator->data.var_decl.variable_name + == current_opcode->data.var_decl.variable_name) + { + was_decl = true; + break; + } + } + } + + if (was_decl) + { + current_opcode->op_idx = NAME_TO_ID (nop); + } + else + { + optimizer_move_opcodes (current_opcode, processed_opcode, 1); + optimizer_adjust_jumps (processed_opcode + 1, current_opcode + 1, 1); + processed_opcode++; + } } } } diff --git a/tests/unit/common.h b/tests/unit/common.h index 2872020c7..e910222e3 100644 --- a/tests/unit/common.h +++ b/tests/unit/common.h @@ -16,6 +16,8 @@ #ifndef COMMON_H #define COMMON_H +#define NAME_TO_ID(op) (__op__idx_##op) + #define OPCODE_SIZE(op) \ sizeof (struct __op_##op) + 1, @@ -35,7 +37,11 @@ opcodes_equal (const OPCODE *opcodes1, OPCODE *opcodes2, uint16_t size) if (opcode_num1 != opcode_num2) return false; - + + if (opcode_num1 == NAME_TO_ID (nop) || opcode_num1 == NAME_TO_ID (ret) + || opcode_num1 == NAME_TO_ID (end_with)) + return true; + for (j = 1; j < opcode_sizes[opcode_num1]; j++) if (((uint8_t*)&opcodes1[i])[j] != ((uint8_t*)&opcodes2[i])[j]) return false; diff --git a/tests/unit/test_optimizer_for_loops.c b/tests/unit/test_optimizer_for_loops.c index fac7a790c..05fc3080e 100644 --- a/tests/unit/test_optimizer_for_loops.c +++ b/tests/unit/test_optimizer_for_loops.c @@ -65,27 +65,27 @@ main( int __unused argc, [0] = getop_reg_var_decl (5, 8), // var tmp5 .. tmp8; [1] = getop_var_decl (0), // var i; [2] = getop_var_decl (1), // var j; - [3] = getop_var_decl (0), // var i; - [4] = getop_var_decl (1), // var j; - [5] = getop_assignment (5, 2, 2), // tmp5 = 0; - [6] = getop_assignment (0, 4, 5), // i = tmp5; - [7] = getop_assignment (7, 2, 4), // tmp7 = 10; - [8] = getop_less_than (6, 0, 7), // tmp6 = i < tmp7; - [9] = getop_is_false_jmp (6, 16), // if (!tmp6) goto 16; - [10] = getop_jmp_down (3), // goto 13; - [11] = getop_post_incr (8, 0), // tmp8 = i ++; - [12] = getop_jmp_up (5), // goto 7; - [13] = getop_assignment (5, 2, 4), // tmp5 = 10; - [14] = getop_assignment (1, 4, 5), // j = tmp5; - [15] = getop_jmp_up (5), // goto 10; - [16] = getop_assignment (5, 2, 2), // tmp5 = 0; - [17] = getop_assignment (0, 4, 5), // i = tmp5; - [18] = getop_assignment (7, 2, 4), // tmp7 = 10; - [19] = getop_less_than (6, 0, 7), // tmp6 = i < tmp7; - [20] = getop_is_false_jmp (6, 27), // if (!tmp6) goto 27; - [21] = getop_jmp_down (3), // goto 24; - [22] = getop_post_incr (8, 0), // tmp8 = i ++; - [23] = getop_jmp_up (5), // goto 18; + [3] = getop_assignment (5, 2, 2), // tmp5 = 0; + [4] = getop_assignment (0, 4, 5), // i = tmp5; + [5] = getop_assignment (7, 2, 4), // tmp7 = 10; + [6] = getop_less_than (6, 0, 7), // tmp6 = i < tmp7; + [7] = getop_is_false_jmp (6, 14), // if (!tmp6) goto 14; + [8] = getop_jmp_down (3), // goto 11; + [9] = getop_post_incr (8, 0), // tmp8 = i ++; + [10] = getop_jmp_up (5), // goto 5; + [11] = getop_assignment (5, 2, 4), // tmp5 = 10; + [12] = getop_assignment (1, 4, 5), // j = tmp5; + [13] = getop_jmp_up (5), // goto 8; + [14] = getop_nop (), // ; + [15] = getop_assignment (5, 2, 2), // tmp5 = 0; + [16] = getop_assignment (0, 4, 5), // i = tmp5; + [17] = getop_assignment (7, 2, 4), // tmp7 = 10; + [18] = getop_less_than (6, 0, 7), // tmp6 = i < tmp7; + [19] = getop_is_false_jmp (6, 27), // if (!tmp6) goto 27; + [20] = getop_jmp_down (3), // goto 23; + [21] = getop_post_incr (8, 0), // tmp8 = i ++; + [22] = getop_jmp_up (5), // goto 17; + [23] = getop_nop (), // ; [24] = getop_assignment (5, 2, 4), // tmp5 = 10; [25] = getop_assignment (1, 4, 5), // j = tmp5; [26] = getop_jmp_up (5), // goto 21;