2012-04-04 23 views
10

Tôi muốn cải thiện mã lambda được tạo cho cấu trúc "khẳng định" OCaml 3.12.1. Dưới đây là ví dụ:Cải thiện mã lambda-OCaml tạo ra cho các xác nhận

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

Tệp longfilename.ml ở trên đại diện cho các mô-đun OCaml lớn mà tôi muốn tạo mã lambda được cải thiện. Nó biên dịch thành:

$ 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 
... 

Ở trên là rất dư thừa. Tên của tệp nguồn mà mỗi xác nhận có thể đến từ được sao chép. Thủ phạm dường như là 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)]))])]) 
;; 

Trên mặt của nó, có vẻ như nó sẽ là đủ để đặt tên cho Const_base(Const_string fname), và để lưu trữ và tái sử dụng nó với một compile- băm thời gian. Đối với tối ưu hóa mô-đun nội bộ, các thay đổi chỉ có thể được quản lý (miễn là bảng băm được đặt lại tại mỗi đơn vị biên dịch).

Tôi có một chút về chiều sâu của mình ở đây, đặc biệt là phần "đặt lại ở mỗi phần biên dịch ". Bất kỳ gợi ý nào?

Trả lời

8

Đã có một cơ chế trong trình biên dịch OCaml chia sẻ một số hằng số: xem asmcomp/compilenv.ml và việc sử dụng nó, cụ thể là giá trị structured_constants, trong asmcomp/cmmgen.ml. Tôi không quen thuộc với mã này vì vậy tôi không chắc chắn lý do tại sao trường hợp sử dụng cụ thể của bạn không được chia sẻ, nhưng có vẻ như có sự khác biệt giữa, trong mã lambda, Const_base (Const_string foo)Const_immstring foo; sau này được chia sẻ, và có lẽ trước đây không phải.

Tôi không biết ngữ nghĩa dự định là gì cho immstring. Nó dường như được sử dụng bởi trình biên dịch nội bộ để biên dịch các nhãn phương thức (bytecomp/translclass.ml), nhưng không được tiếp xúc với ngôn ngữ đầu vào.

(Tôi nghi ngờ sự khác biệt là vì các chuỗi có thể thay đổi được, vì vậy việc chia sẻ các chuỗi hiển thị của người dùng sẽ được quan sát và thay đổi hành vi của chương trình. các chuỗi hiển thị người dùng có thể vẫn bị từ chối dưới dạng ngắt tương thích.)

Nhìn vào cách các chuỗi ngay lập tức được xử lý bằng mã phát liên tục (asmcomp/cmmgen.ml:emit_constant), chúng được thể hiện như các chuỗi thông thường, vì vậy có thể bạn chỉ có thể vá trình biên dịch để sử dụng immstring trong assert_failed và mọi thứ sẽ hoạt động.

[EDIT CỦA OP]

Thay đổi Const_base (Const_string fname) vào Const_immstring fname, trong khi hơi không tương thích, cho phép OCaml để biên dịch riêng của mình, để biên dịch FRAMA-C và mới FRAMA-C qua các bài kiểm tra hồi quy của nó. Trên ví dụ ban đầu, hiệu quả như sau, đó chính xác là kết quả mong muốn:

$ 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 
+0

Tôi biết rằng không phải SO nghi thức để gửi nhận xét khi bạn có thể chấp nhận câu trả lời, nhưng tôi muốn chúc mừng bạn trên giải pháp bạn cung cấp. Làm tốt. –

+0

Vâng, cảm ơn bạn :) Điều này có vẻ ít hài lòng hơn khi bạn đã gửi đề xuất thay đổi trên [bugtracker] (http://caml.inria.fr/mantis/) và những người thực sự biết nội dung này cho bạn biết cách xấu ý tưởng là. – gasche

+0

Tôi thà dành chút ít sự chú ý mà tôi vẫn có thể triệu tập trên bộ theo dõi vấn đề cho những điều xấu mà tôi không có giải pháp, nhưng hãy thoải mái sử dụng 5573. Nếu tôi tìm ra giải pháp cho tôi, tôi sẽ gửi giải pháp của bạn một như một bản vá xứng đáng xem xét lại. –

Các vấn đề liên quan