From 4c3a25d5e69967494108eef646e5c8b0eaa63eac Mon Sep 17 00:00:00 2001 From: John Lorentzson Date: Thu, 31 Jul 2025 12:45:24 +0200 Subject: [PATCH] Add constant folding for purely constant operations --- user-side-compiler/interface.lisp | 1 + user-side-compiler/middle/optimizations.lisp | 29 ++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/user-side-compiler/interface.lisp b/user-side-compiler/interface.lisp index 232dc54..d97db57 100644 --- a/user-side-compiler/interface.lisp +++ b/user-side-compiler/interface.lisp @@ -65,6 +65,7 @@ (defun ci-optimize-ir (start-iblock) (do-iblocks (ib start-iblock) (optim-reorder-arguments ib) + (optim-trivial-constant-folding ib) (optim-call-duplicate-args ib) (optim-remove-unused ib))) diff --git a/user-side-compiler/middle/optimizations.lisp b/user-side-compiler/middle/optimizations.lisp index 22bff01..2174d44 100644 --- a/user-side-compiler/middle/optimizations.lisp +++ b/user-side-compiler/middle/optimizations.lisp @@ -29,6 +29,35 @@ (when add-post (list output)))))) +(defun optim-trivial-constant-folding (iblock) + "Replaces operations taking two constants with the result." + (declare (optimize (debug 3))) + (let ((folders + `((ir-plus . ,(lambda (x y) (ldb (byte 8 0) (+ x y)))) + (ir-minus . ,(lambda (x y) (ldb (byte 8 0) (- x y)))) + (ir-mult . ,(lambda (x y) (ldb (byte 8 0) (* x y)))) + (ir-div . ,(lambda (x y) (ldb (byte 8 0) (floor (/ x y))))) + (ir-test-equal . ,(lambda (x y) (if (= x y) 1 0))) + (ir-test-not-equal . ,(lambda (x y) (if (/= x y) 1 0))) + (ir-test-less . ,(lambda (x y) (if (< x y) 1 0))) + (ir-test-less-or-equal . ,(lambda (x y) (if (<= x y) 1 0))) + (ir-test-greater . ,(lambda (x y) (if (> x y) 1 0))) + (ir-test-greater-or-equal . ,(lambda (x y) (if (>= x y) 1 0)))))) + (do-instructions (inst iblock) + (let ((folder (cdr (assoc inst folders :test #'typep)))) + (when (and folder (every #'ir-constant-p (inputs inst))) + (let* ((output (change-class (output inst) 'ir-constant + :users (users (output inst)))) + (operands (mapcar #'ir-constant-value (inputs inst)))) + (setf (output inst) nil + (inputs inst) nil) + (insert-instruction-above + (make-instance 'ir-getconst + :input (apply folder operands) + :output output) + inst) + (delete-instruction inst))))))) + (defun optim-commutative-constant-folding (iblock) "Attempts to replace operations with compile-time computed constants." (do-instructions (inst iblock)