+ }
+ while (todo);
+
+ return (1);
+}
+
+static void
+_do_follow(jit_state_t *_jit, jit_bool_t always)
+{
+ jit_block_t *block;
+ jit_word_t offset;
+
+ /* set live state of registers not referenced in a block, but
+ * referenced in a jump target or normal flow */
+ for (offset = 0; offset < _jitc->blocks.offset; offset++) {
+ block = _jitc->blocks.ptr + offset;
+ if (!block->label || block->label->code == jit_code_epilog)
+ continue;
+ if (always || block->again) {
+ block->again = 0;
+ jit_follow(block);
+ }
+ }
+}
+
+void
+_jit_optimize(jit_state_t *_jit)
+{
+ jit_bool_t jump;
+ jit_bool_t todo;
+ jit_int32_t mask;
+ jit_node_t *node;
+ jit_block_t *block;
+ jit_word_t offset;
+
+ todo = 0;
+ _jitc->function = NULL;
+
+ thread_jumps();
+ sequential_labels();
+ split_branches();
+ do_setup();
+ do_follow(1);
+
+ patch_registers();
+ if (simplify())
+ todo = 1;
+
+ /* Figure out labels that are only reached with a jump
+ * and is required to do a simple redundant_store removal
+ * on jit_beqi below */
+ jump = 1;
+ for (node = _jitc->head; node; node = node->next) {
+ switch (node->code) {
+ case jit_code_label:
+ if (!jump)
+ node->flag |= jit_flag_head;
+ break;
+ case jit_code_jmpi: case jit_code_jmpr:
+ case jit_code_epilog:
+ jump = 1;
+ break;
+ case jit_code_data: case jit_code_note:
+ break;
+ default:
+ jump = 0;
+ break;
+ }
+ }