From f3cbadfa54915ad51818430bb1ff81121151dc12 Mon Sep 17 00:00:00 2001 From: John Lorentzson Date: Thu, 31 Jul 2025 13:08:11 +0200 Subject: [PATCH] Add dead code elimination and folding of constant conditionals --- user-side-compiler/interface.lisp | 6 ++++- user-side-compiler/middle/optimizations.lisp | 28 +++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/user-side-compiler/interface.lisp b/user-side-compiler/interface.lisp index d97db57..6c49c64 100644 --- a/user-side-compiler/interface.lisp +++ b/user-side-compiler/interface.lisp @@ -66,8 +66,12 @@ (do-iblocks (ib start-iblock) (optim-reorder-arguments ib) (optim-trivial-constant-folding ib) + (optim-constant-conditional ib) (optim-call-duplicate-args ib) - (optim-remove-unused ib))) + (optim-remove-unused-instructions ib)) + (optim-dead-code-elimination start-iblock) + (do-iblocks (ib start-iblock) + (optim-remove-unused-instructions ib))) (defun ci-allocation-info (allocs) (format *debug-io* "Values: ~D~%" (length allocs)) diff --git a/user-side-compiler/middle/optimizations.lisp b/user-side-compiler/middle/optimizations.lisp index 2174d44..4a80a2d 100644 --- a/user-side-compiler/middle/optimizations.lisp +++ b/user-side-compiler/middle/optimizations.lisp @@ -58,6 +58,22 @@ inst) (delete-instruction inst))))))) +(defun optim-constant-conditional (iblock) + (do-instructions (inst iblock) + (when (and (typep inst 'ir-if) (ir-constant-p (input inst))) + (let ((then-block (first (destinations inst))) + (else-block (second (destinations inst))) + (falsep (zerop (ir-constant-value (input inst))))) + (replace-terminator + inst + (make-instance 'ir-jump :destinations (list (if falsep + else-block + then-block)) + :source (source inst))) + (dolist (input (inputs inst)) + (when (typep input 'ir-data) + (remove-user input inst))))))) + (defun optim-commutative-constant-folding (iblock) "Attempts to replace operations with compile-time computed constants." (do-instructions (inst iblock) @@ -161,7 +177,7 @@ that uses them to assist in generating more direct 6502 code." before being cut off. This ensures that it can't get stuck forever, even though I'm pretty sure it can't anyway.") -(defun optim-remove-unused (iblock) +(defun optim-remove-unused-instructions (iblock) (let ((to-delete '())) (loop :repeat +optim-remove-unused-max-passes+ ; this many times or fewer :do (setf to-delete '()) @@ -174,6 +190,16 @@ though I'm pretty sure it can't anyway.") (mapc 'delete-instruction to-delete) :until (null to-delete)))) +(defun optim-dead-code-elimination (start-iblock) + (let ((reachable (list start-iblock))) + (do-iblocks (iblock start-iblock) + (dolist (dest (destinations (end iblock))) + (push dest reachable))) + (do-iblocks (iblock start-iblock) + (unless (member iblock reachable) + (setf (next (prev iblock)) + (next iblock)))))) + (defun optim-call-duplicate-args (iblock) "Attempts to deduplicate call arguments." (let ((calls '()))