libjit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libjit] [PATCH 2/2] Add constant folding optimization pass


From: George Barrett
Subject: [Libjit] [PATCH 2/2] Add constant folding optimization pass
Date: Wed, 24 May 2017 14:01:16 +1000
User-agent: NeoMutt/20170428 (1.8.2)

This commit adds an additional optimization pass that statically
computes constant temporary variables and propagates the result to the
operands of following instructions.

Since this involves iterating through all subsequent instructions
looking for references to the old temporary, this can be quite expensive
for long functions. The math.pas test is the best example, showing
_jit_block_fold_constants() to be the second-longest running function in
libjit.
---
 jit/jit-block.c    | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 jit/jit-compile.c  |  3 +++
 jit/jit-internal.h |  6 ++++++
 3 files changed, 71 insertions(+)

diff --git a/jit/jit-block.c b/jit/jit-block.c
index 6ffd329..e9c21a2 100644
--- a/jit/jit-block.c
+++ b/jit/jit-block.c
@@ -750,6 +750,68 @@ _jit_block_free(jit_function_t func)
 }
 
 void
+_jit_block_fold_constants(jit_function_t func)
+{
+       int insn_index, forward_insn_index, insn_flags;
+       jit_block_t block;
+       jit_insn_t insn, forward_insn;
+       jit_value_t old_dest, new_dest;
+       jit_nuint old_dest_usage;
+
+       for(block = func->builder->entry_block; block; block = block->next)
+       {
+               for(insn_index = 0; insn_index < block->num_insns; insn_index++)
+               {
+                       insn = &block->insns[insn_index];
+                       insn_flags = jit_opcodes[insn->opcode].flags;
+
+                       if(insn_flags & JIT_OPCODE_DEST_ANY
+                          && insn->dest && insn->dest->is_temporary && 
!insn->dest->is_volatile
+                          && insn->value1 && insn->value1->is_constant
+                          && (!insn->value2 || insn->value2->is_constant))
+                       {
+                               old_dest = insn->dest;
+                               new_dest = _jit_opcode_apply(func, 
insn->opcode, insn->dest->type, insn->value1, insn->value2);
+
+                               if(!new_dest)
+                               {
+                                       continue;
+                               }
+
+                               new_dest->usage_count = 1;
+                               old_dest_usage = old_dest->usage_count;
+                               old_dest->usage_count = 0;
+
+                               for(forward_insn_index = insn_index + 1; 
forward_insn_index < block->num_insns; forward_insn_index++)
+                               {
+                                       forward_insn = 
&block->insns[forward_insn_index];
+
+                                       if(forward_insn->value1 == old_dest)
+                                       {
+                                               forward_insn->value1 = new_dest;
+                                       }
+                                       else if(forward_insn->value2 == 
old_dest)
+                                       {
+                                               forward_insn->value2 = new_dest;
+                                       }
+                                       else if(forward_insn->dest == old_dest)
+                                       {
+                                               old_dest->usage_count = 
old_dest_usage;
+                                               break;
+                                       }
+                                       else
+                                       {
+                                               continue;
+                                       }
+                               }
+
+                               insn->opcode = JIT_OP_NOP;
+                       }
+               }
+       }
+}
+
+void
 _jit_block_build_cfg(jit_function_t func)
 {
        /* Count the edges */
diff --git a/jit/jit-compile.c b/jit/jit-compile.c
index ba310e4..fd1e246 100644
--- a/jit/jit-compile.c
+++ b/jit/jit-compile.c
@@ -71,6 +71,9 @@ optimize(jit_function_t func)
                return;
        }
 
+       /* Compute and propagate constant temps */
+       _jit_block_fold_constants(func);
+
        /* Build control flow graph */
        _jit_block_build_cfg(func);
 
diff --git a/jit/jit-internal.h b/jit/jit-internal.h
index 2efb796..701ae2b 100644
--- a/jit/jit-internal.h
+++ b/jit/jit-internal.h
@@ -669,6 +669,12 @@ int _jit_block_init(jit_function_t func);
 void _jit_block_free(jit_function_t func);
 
 /*
+ * Statically evaluate temporary variables with constant inputs and propagate
+ * the value.
+ */
+void _jit_block_fold_constants(jit_function_t func);
+
+/*
  * Build control flow graph edges for all blocks associated with a
  * function.
  */
-- 
2.13.0

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]