Tại sao LLVM có IR giống như lắp ráp chứ không phải IR giống như cây? Hoặc: tại sao các dự án nhắm mục tiêu LLVM IR thay vì AST của clang?


14

Tại sao đại diện trung gian của LLVM (LLVM IR) giống như lắp ráp thay vì giống như cây?

Ngoài ra, tại sao việc triển khai ngôn ngữ lại nhắm vào LLVM IR thay vì AST của clang?

Tôi không cố gắng hỏi hai câu hỏi khác nhau cùng một lúc nếu có vẻ như vậy. Đối với tôi, có vẻ như cả các lập trình viên thư viện và khách hàng đều đồng thuận rằng API của LLVM, không hơn không kém, rõ ràng là thiết kế phần mềm tốt và câu hỏi của tôi là "tại sao?".

Lý do tôi hỏi là có vẻ như LLVM có thể cung cấp nhiều chức năng hơn cho các giao diện nếu IR của nó giống như AST vì khi đó các công cụ dựa trên AST của clang có thể được sử dụng cho bất kỳ giao diện nào. Ngoài ra, các ngôn ngữ nhắm mục tiêu LLVM IR có thể có nhiều chức năng hơn nếu chúng nhắm mục tiêu AST của clang.

Clang có các lớp và chức năng để tạo và làm việc với AST và đó là dự án frontend duy nhất gắn chặt với dự án LLVM, vậy tại sao chức năng AST của clang lại nằm ngoài LLVM?

Ngoài đỉnh đầu, tôi biết rằng Rust (Rustc), D (ldc) và Haskell (GHC) đều có thể sử dụng LLVM làm phụ trợ nhưng họ không sử dụng Clang AST (theo như tôi biết, tôi có thể sai). Tôi không biết tất cả các chi tiết bên trong của các trình biên dịch này, nhưng ít nhất Rust và D chắc chắn có vẻ như chúng có thể được biên dịch sang AST của clang. Có lẽ Haskell cũng có thể, nhưng tôi không chắc lắm về điều đó.

Đây có phải là vì lý do lịch sử (LLVM ban đầu là một "máy ảo cấp thấp" và kêu vang sau này)? Đây có phải là vì các tiền tuyến khác muốn có nhiều quyền kiểm soát nhất có thể đối với những gì họ cung cấp cho LLVM? Có những lý do cơ bản nào mà AST của clang không phù hợp với các ngôn ngữ "không giống C" không?

Tôi không có ý định câu hỏi này là một bài tập trong việc đọc. Tôi chỉ muốn nó hữu ích cho những người trong chúng ta tò mò, nhưng chưa thành thạo về thiết kế trình biên dịch. Vì các dự án LLVM và clang được phát triển công khai, tôi hy vọng rằng ai đó quen thuộc với sự phát triển của các dự án này có thể trả lời hoặc câu trả lời đủ rõ ràng đối với một số mọt sách biên dịch mà họ cảm thấy đủ tự tin để trả lời.


Để trả trước một số câu trả lời rõ ràng nhưng không thỏa đáng:

Đúng, có IR giống như lắp ráp mang lại nhiều quyền kiểm soát hơn cho bất kỳ ai tạo ra IR (có lẽ X lang có định dạng mã cơ sở và AST tốt hơn clang) nhưng nếu đó là câu trả lời duy nhất, thì câu hỏi trở thành "tại sao LLVM chỉ có một hội đồng- như IR thay vì IR giống như cây cấp cao và IR giống như lắp ráp cấp thấp? ".

Đúng, không khó để phân tích ngôn ngữ lập trình thành AST (ít nhất là so với các bước biên dịch khác). Mặc dù vậy, tại sao sử dụng AST riêng biệt? Nếu không có gì khác, sử dụng cùng AST cho phép bạn sử dụng các công cụ hoạt động trên AST (thậm chí chỉ là những thứ đơn giản như máy in AST).

Vâng, tôi mạnh mẽ đồng ý rằng là mô-đun hơn là một điều tốt, nhưng nếu đó là lý do duy nhất, sau đó tại sao hiện thực ngôn ngữ khác có xu hướng để nhắm mục tiêu LLVM IR thay vì AST kêu vang không?

Những tiền giả định này có thể sai hoặc bỏ qua các chi tiết, vì vậy hãy thoải mái đưa ra những câu trả lời này nếu bạn có thêm chi tiết hoặc các giả định của tôi bị nhầm lẫn.


Đối với bất cứ ai muốn trả lời một câu hỏi dễ trả lời dứt khoát hơn: những lợi thế và bất lợi của IR giống như lắp ráp so với IR giống như cây là gì?


1
Tôi không phải là chuyên gia LLVM, nhưng tôi nghĩ có một chút hiểu lầm về phía bạn. LLVM không có asm như IR. Trong thực tế, IR của nó giống như một biểu đồ hơn là một cái cây. Tôi giả sử rằng 'giống như' bạn đang đề cập đến các tệp IR (* .ll) có thể đọc được của con người, nếu vậy thì nó được thực hiện chỉ để thuận tiện. Nhưng, chúng ta hãy chờ đợi một chuyên gia thực sự có thể đưa ra câu trả lời toàn diện hơn :)
AlexDenisov

1
Một khía cạnh quan trọng có thể là lịch sử: LLVM ban đầu được thiết kế để tách rời các phụ trợ của trình biên dịch khỏi các mặt trước của trình biên dịch. Ý tưởng là các nhà cung cấp trình biên dịch sẽ cạnh tranh về tối ưu hóa ngôn ngữ và các nhà cung cấp CPU sẽ cạnh tranh về tối ưu hóa ở mức độ thấp. Ví dụ: Microsoft và Apple sẽ cạnh tranh với nhau, trình biên dịch C tạo ra mã bit "tốt nhất" từ C, và Intel và AMD sẽ cạnh tranh với nhau có phần phụ trợ LLVM tạo ra mã máy "tốt nhất" từ bitcode. Các nhà cung cấp ứng dụng sẽ gửi các ứng dụng của họ bằng bitcode và việc biên dịch cuối cùng sẽ được thực hiện trên máy tính của người dùng
Jörg W Mittag

1
… máy móc. LLVM bắt đầu tại một thời điểm, nơi mọi người đều không sử dụng Intel. Apple vẫn còn trên PowerPC, Intel vẫn đang đẩy mạnh Itanium, v.v. AFAIK, Apple vẫn sử dụng LLVM theo cách này, trong một số khung 3D, nơi mã được vận chuyển dưới dạng bitcode và sau đó được biên dịch cho nVidia hoặc ATI tùy thuộc vào loại thẻ được cài đặt.
Jörg W Mittag

1
Tha thứ cho tôi, nhưng IR là gì?
Adam Copley

Câu trả lời:


13

Có một số câu hỏi liên quan đến nhau ở đây, tôi sẽ cố gắng tách chúng ra tốt nhất có thể.

Tại sao các ngôn ngữ khác xây dựng trên LLVM IR mà không phải tiếng kêu AST?

Điều này đơn giản là vì clang là giao diện người dùng C / C ++ và AST mà nó tạo ra được kết hợp chặt chẽ với C / C ++. Một ngôn ngữ khác có thể sử dụng nó nhưng nó sẽ cần ngữ nghĩa gần giống với một số tập hợp con của C / C ++, điều này rất hạn chế. Như bạn chỉ ra, việc phân tích cú pháp theo AST khá đơn giản nên việc hạn chế các lựa chọn ngữ nghĩa của bạn khó có thể có giá trị tiết kiệm nhỏ.

Tuy nhiên, nếu bạn đang viết công cụ cho C / C ++, ví dụ như máy phân tích tĩnh, thì việc sử dụng lại AST có ý nghĩa rất lớn vì làm việc với AST dễ dàng hơn nhiều so với văn bản thô mà bạn đang làm việc với C / C ++ .

Tại sao LLVM IR là hình thức của nó?

LLVM IR được chọn là một hình thức thích hợp để viết tối ưu hóa trình biên dịch. Như vậy, tính năng chính của nó là ở dạng SSA . Đó là một IR cấp độ thấp để nó có thể áp dụng cho nhiều ngôn ngữ, ví dụ như nó không gõ bộ nhớ vì điều này thay đổi rất nhiều giữa các ngôn ngữ.

Bây giờ, nó xảy ra trong trường hợp viết tối ưu hóa trình biên dịch là một nhiệm vụ chuyên môn và thường trực giao với thiết kế tính năng ngôn ngữ. Tuy nhiên, có một ngôn ngữ biên dịch chạy nhanh là một yêu cầu khá chung chung. Ngoài ra, việc chuyển đổi từ LLVM IR sang ASM khá cơ học và thường không thú vị đối với các nhà thiết kế ngôn ngữ.

Do đó, việc hạ thấp ngôn ngữ xuống LLVM IR mang đến cho nhà thiết kế ngôn ngữ rất nhiều "công cụ miễn phí" rất hữu ích trong thực tế khiến họ tập trung vào chính ngôn ngữ đó.

Một IR khác sẽ hữu ích (OK, không được hỏi nhưng loại ngụ ý)?

Chắc chắn rồi! AST khá tốt cho các biến đổi nhất định trên cấu trúc chương trình nhưng rất khó sử dụng nếu bạn muốn chuyển đổi luồng chương trình. Một hình thức SSA thường tốt hơn. Tuy nhiên, LLVM IR ở mức rất thấp nên rất nhiều cấu trúc cấp cao bị mất (về mục đích để nó thường được áp dụng hơn). Có IR giữa AST và IR cấp thấp có thể có lợi ở đây. Cả Rust và Swift đều thực hiện phương pháp này và có IR cao giữa hai bên.


Haskell cũng có một số IR trước khi đến LLVM.
DylanSp

1
@ DylanSp Thật vậy. Đó là bắt đầu trở thành thực tiễn tốt nhất cho các ngôn ngữ phức tạp. Ví dụ, Rust đã không làm điều này ban đầu và đã tái cấu trúc để bao gồm IR cấp cao. Tôi cũng tin rằng đã có một số cuộc nói chuyện về việc làm điều này cho tiếng kêu nhưng tôi không chắc là nó đã đi đâu.
Alex
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.