gpt4 book ai didi

ocaml - 改进 OCaml 为断言生成的 lambda 代码

转载 作者:行者123 更新时间:2023-12-03 22:19:04 25 4
gpt4 key购买 nike

我想改进为“断言”OCaml 3.12.1 构造生成的 lambda 代码。这是一个例子:

let f x =
assert (x = 4);
assert (2 + x = 6);
assert (x - x = 0);
exit x

上面的文件 longfilename.ml 代表了我希望改进 lambda 代码生成的大型 OCaml 模块。它编译为:
$ ocamlopt -S longfilename.ml
$ cat longfilename.s
...
.data
.quad 3072
_camlLongfilename__2:
.quad L100007
.quad 9
.quad 9
.quad 2300
L100007: .L100007:
.ascii "longfilename.ml"
.byte 0
.data
.quad 3072
_camlLongfilename__3:
.quad L100006
.quad 7
.quad 9
.quad 2300
L100006: .L100006:
.ascii "longfilename.ml"
.byte 0
.data
.quad 3072
_camlLongfilename__4:
.quad L100005
.quad 5
.quad 9
.quad 2300
L100005: .L100005:
.ascii "longfilename.ml"
.byte 0
...

以上是非常多余的。每个断言可能来自的源文件的名称是重复的。罪魁祸首似乎是 bytecomp/translcore.ml:
let assert_failed loc =
(* [Location.get_pos_info] is too expensive *)
let fname = match loc.Location.loc_start.Lexing.pos_fname with
| "" -> !Location.input_name
| x -> x
in
let pos = loc.Location.loc_start in
let line = pos.Lexing.pos_lnum in
let char = pos.Lexing.pos_cnum - pos.Lexing.pos_bol in
Lprim(Praise, [Lprim(Pmakeblock(0, Immutable),
[transl_path Predef.path_assert_failure;
Lconst(Const_block(0,
[Const_base(Const_string fname);
Const_base(Const_int line);
Const_base(Const_int char)]))])])
;;

从表面上看,给一个名字就足够了 Const_base(Const_string fname) , 并存储和重用它
一个编译时哈希表。对于模块内优化,
这些变化可能是可控的
(只要在每个编译单元重置哈希表)。

我在这里有点超出我的深度,尤其是“每次编译时重置”
单元”部分。有什么提示吗?

最佳答案

OCaml 编译器中已经有一种机制可以共享一些常量:参见 asmcomp/compilenv.ml及其使用,尤其是 structured_constants值,在 asmcomp/cmmgen.ml .我不熟悉此代码,因此不确定为什么不共享您的特定用例,但在 lambda 代码中,Const_base (Const_string foo) 之间似乎存在差异和 Const_immstring foo ;后者是共享的,而前者可能不是。

我不知道 immstring 的预期语义是什么.编译器似乎在内部使用它来编译方法标签( bytecomp/translclass.ml ),但不暴露于输入语言。

(我怀疑区别是因为字符串是可变的,所以共享用户可见的字符串将是可观察的并改变程序的行为。但是字符串常量已经被 lambda 提升,因此用户已经可以观察到语义上不一致的共享。增加用户可见字符串的共享可能仍会因为兼容性中断而被拒绝。)

看看这些直接字符串是由常量发射代码( asmcomp/cmmgen.ml:emit_constant )处理的方式,它们像通常的字符串一样表示,所以也许你可以修补编译器以使用 immstringassert_failed事情会奏效。

[由操作编辑]

更改 Const_base (Const_string fname)进入 Const_immstring fname ,虽然略有不兼容,但允许 OCaml 自行编译,编译 Frama-C 并且新的 Frama-C 通过其回归测试。在原始示例中,效果如下,这正是我们想要的结果:

$ cat longfilename.s 
...
.data
.quad 3072
_camlLongfilename__2:
.quad L100005
.quad 9
.quad 9
.data
.quad 3072
_camlLongfilename__3:
.quad L100005
.quad 7
.quad 9
.data
.quad 3072
_camlLongfilename__4:
.quad L100005
.quad 5
.quad 9
.quad 2300
L100005: .L100005:
.ascii "longfilename.ml"
.byte 0

关于ocaml - 改进 OCaml 为断言生成的 lambda 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10008552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com