common-lisp - 在 SBCL 中检查编译器优化
问题描述
有没有办法判断 SBCL 是否对特定的源代码进行了优化?例如,在输入以下内容时,我希望该case
语句被优化为(print "0")
:
(defconstant +n+ 0)
(case +n+
(0 (print "0"))
(1 (print "1")))
但是扩展给出了不同的东西:
* (macroexpand '(case +n+ (0 (print "0")) (1 (print "1"))))
(LET ((#:G415 +N+))
(DECLARE (IGNORABLE #:G415))
(COND ((EQL #:G415 '0) NIL (PRINT "0")) ((EQL #:G415 '1) NIL (PRINT "1"))))
这可能是一个不寻常的例子,但一般来说,如何检查优化。
解决方案
正如 Rainer Joswig 所解释的,一种可能性是检查拆卸。例如,对于 SBCL:
CL-USER> (defconstant +n+ 0)
"0"
"0"
CL-USER> (disassemble (compile nil (lambda () (case +n+
(0 (print "0"))
(1 (print "1"))))))
上面输出了这个,说明代码已经被简化了:
; disassembly for (LAMBDA ())
; Size: 32 bytes. Origin: #x52E552CC ; (LAMBDA ())
; CC: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer
; D0: 488945F8 MOV [RBP-8], RAX
; D4: 488B15B5FFFFFF MOV RDX, [RIP-75] ; "0"
; DB: B902000000 MOV ECX, 2
; E0: FF7508 PUSH QWORD PTR [RBP+8]
; E3: B8A2324950 MOV EAX, #x504932A2 ; #<FDEFN PRINT>
; E8: FFE0 JMP RAX
; EA: CC10 INT3 16 ; Invalid argument count trap
NIL
还可以显示编译器的配置方式:
CL-USER> (sb-ext:describe-compiler-policy)
Basic qualities:
COMPILATION-SPEED = 1
DEBUG = 1
SAFETY = 1
SPACE = 1
SPEED = 1
INHIBIT-WARNINGS = 1
Dependent qualities:
SB-C::CHECK-CONSTANT-MODIFICATION = 1 -> 1 (maybe)
SB-C::TYPE-CHECK = 1 -> 3 (full)
SB-C::CHECK-TAG-EXISTENCE = 1 -> 3 (yes)
SB-C::LET-CONVERSION = 1 -> 3 (on)
SB-C:ALIEN-FUNCALL-SAVES-FP-AND-PC = 1 -> 3 (yes)
SB-C:VERIFY-ARG-COUNT = 1 -> 3 (yes)
SB-C::INSERT-DEBUG-CATCH = 1 -> 1 (maybe)
SB-C::RECOGNIZE-SELF-CALLS = 1 -> 0 (no)
SB-C::FLOAT-ACCURACY = 1 -> 3 (full)
SB-C:INSERT-STEP-CONDITIONS = 1 -> 0 (no)
SB-C::COMPUTE-DEBUG-FUN = 1 -> 1 (yes)
SB-C:STORE-SOURCE-FORM = 1 -> 1 (maybe)
SB-C::PRESERVE-SINGLE-USE-DEBUG-VARIABLES = 1 -> 0 (no)
SB-C::INSERT-ARRAY-BOUNDS-CHECKS = 1 -> 3 (yes)
SB-C::STORE-XREF-DATA = 1 -> 3 (yes)
SB-C:STORE-COVERAGE-DATA = 1 -> 0 (no)
SB-C::INSTRUMENT-CONSING = 1 -> 1 (no)
SB-C::STORE-CLOSURE-DEBUG-POINTER = 1 -> 0 (no)
SB-KERNEL:ALLOW-NON-RETURNING-TAIL-CALL = 1 -> 0 (no)
推荐阅读
- python - 在 QLabel 内旋转 QPixmap 会导致像素图沿 x 轴移动,而不是停留在 QLabel 内
- r - 如何清理 R 中按州/月分组的数据?
- authentication - SplashScreen 的 Flutter 身份验证流程
- php - 如何根据两个键一起删除集合中的重复行
- c++ - 标准输入 C++
- wordpress - Wordpress 删除类="the_content_wraper"
- python - 如何使用 xtick.major.width 和 xtick.minor.widtch rcParams 键?
- c# - 如何在同一个项目中使用 2 个不同的数据库架构来组织 Entity Framework Core 迁移(代码优先)?
- kubernetes - 谷歌云:如何将 Kubernetes 集群移动到不同的区域?
- node.js - NodeJS - Apollo Server:文件上传流解析期间请求断开连接