(define-symbol-macro %true-branches% ()) (defmacro with-compile-time-branching ((&rest branches) &body body &environment env) (cond ((not (null branches)) (destructuring-bind (branch . other-branches) branches (let ((true-branches (macroexpand-1 '%true-branches% env))) `(if ,branch (symbol-macrolet ((%true-branches% (,branch . ,true-branches))) (with-compile-time-branching (,@other-branches) ,@body)) (with-compile-time-branching (,@other-branches) ,@body))))) (t `(progn ,@body)))) (defmacro compile-time-if (branch then &optional else &environment env) (if (member branch (macroexpand-1 '%true-branches% env)) then (or else `(progn)))) (sb-ext:restrict-compiler-policy 'speed 3 3) (sb-ext:restrict-compiler-policy 'safety) (sb-ext:restrict-compiler-policy 'debug) ;; Compiling the below produces 72 compiler notes (defun make-adder (x &key huge-p enormous-p) (with-compile-time-branching (huge-p enormous-p) (lambda (y) (+ x y (compile-time-if huge-p (print 1000) 0) ;; note the PRINT call (compile-time-if enormous-p 2000 0))))) CL-USER> (disassemble (make-adder 10)) ; disassembly for (LAMBDA (Y) :IN MAKE-ADDER) ; Size: 28 bytes. Origin: #x5370C788 ; (LAMBDA (Y) :IN MAKE-ADDER) ; 88: 488BD1 MOV RDX, RCX ; 8B: E8A0432FFF CALL #x52A00B30 ; GENERIC-+ ; 90: 31FF XOR EDI, EDI ; 92: E899432FFF CALL #x52A00B30 ; GENERIC-+ ; 97: 31FF XOR EDI, EDI ; 99: E892432FFF CALL #x52A00B30 ; GENERIC-+ ; 9E: 488BE5 MOV RSP, RBP ; A1: F8 CLC ; A2: 5D POP RBP ; A3: C3 RET NIL CL-USER> (disassemble (make-adder 10 :huge-p t)) ; disassembly for (LAMBDA (Y) :IN MAKE-ADDER) ; Size: 28 bytes. Origin: #x5370C788 ; (LAMBDA (Y) :IN MAKE-ADDER) ; 88: 488BD1 MOV RDX, RCX ; 8B: E8A0432FFF CALL #x52A00B30 ; GENERIC-+ ; 90: 31FF XOR EDI, EDI ; 92: E899432FFF CALL #x52A00B30 ; GENERIC-+ ; 97: 31FF XOR EDI, EDI ; 99: E892432FFF CALL #x52A00B30 ; GENERIC-+ ; 9E: 488BE5 MOV RSP, RBP ; A1: F8 CLC ; A2: 5D POP RBP ; A3: C3 RET NIL