2012-02-06 39 views
11

Tôi muốn đọc (phân tích) mã IRV LLVM (được lưu trong tệp văn bản) và thêm một số mã của riêng tôi vào đó. Tôi cần một số ví dụ về làm điều này, đó là, làm thế nào điều này được thực hiện bằng cách sử dụng các thư viện được cung cấp bởi LLVM cho mục đích này. Vì vậy, về cơ bản những gì tôi muốn là đọc trong mã IR từ một tập tin văn bản vào bộ nhớ (có lẽ thư viện LLVM đại diện cho nó ở dạng AST, tôi không biết), sửa đổi, như thêm một số nút trong AST và sau đó cuối cùng viết trả lại AST trong tệp văn bản IR.Phân tích cú pháp và sửa đổi mã IRV LLVM

Mặc dù tôi cần cả đọc và sửa đổi mã IR, tôi sẽ đánh giá rất cao nếu ai đó có thể cung cấp hoặc giới thiệu cho tôi một số ví dụ chỉ đọc (phân tích cú pháp) nó.

Trả lời

24

Trước tiên, để khắc phục sự hiểu lầm rõ ràng: LLVM là một khuôn khổ để thao tác mã ở định dạng IR. Không có ASTs trong tầm nhìn (*) - bạn đọc IR, chuyển đổi/thao tác/phân tích nó, và bạn viết IR trở lại.

Reading IR là thực sự đơn giản:

int main(int argc, char** argv) 
{ 
    if (argc < 2) { 
     errs() << "Expected an argument - IR file name\n"; 
     exit(1); 
    } 

    LLVMContext &Context = getGlobalContext(); 
    SMDiagnostic Err; 
    Module *Mod = ParseIRFile(argv[1], Err, Context); 

    if (!Mod) { 
     Err.print(argv[0], errs()); 
     return 1; 
    } 

    [...] 
    } 

Mã này chấp nhận một tên tập tin. Đây phải là một tệp IRV LLVM (văn bản). Sau đó nó tiếp tục phân tích nó thành một Module, đại diện cho một mô-đun IR trong định dạng trong bộ nhớ trong của LLVM. Điều này sau đó có thể được thao tác với các thẻ LLVM khác nhau có hoặc bạn thêm vào của riêng bạn. Hãy xem một số ví dụ trong cơ sở mã LLVM (chẳng hạn như lib/Transforms/Hello/Hello.cpp) và đọc phần này - http://llvm.org/docs/WritingAnLLVMPass.html.

Tách IR trở lại vào tệp thậm chí còn dễ dàng hơn. Lớp Module chỉ tự ghi vào luồng:

some_stream << *Mod; 

Vậy đó.

Bây giờ, nếu bạn có bất kỳ cụ câu hỏi về sửa đổi cụ thể mà bạn muốn làm để mã IR, bạn nên thực sự hỏi một cái gì đó tập trung hơn. Tôi hy vọng câu trả lời này cho bạn thấy làm thế nào để phân tích cú pháp IR và viết nó trở lại.


(*) IR không có đại diện AST bên trong LLVM, bởi vì nó là ngôn ngữ giống như lắp ráp đơn giản. Nếu bạn đi một bước lên, tới C hoặc C++, bạn có thể sử dụng Clang để phân tích cú pháp đó thành ASTs, và sau đó thực hiện các thao tác ở mức AST. Clang sau đó biết làm thế nào để sản xuất LLVM IR từ AST của nó. Tuy nhiên, bạn phải bắt đầu với C/C++ ở đây, và không phải LLVM IR. Nếu LLVM IR là tất cả những gì bạn quan tâm, hãy quên đi AST.

+0

Cảm ơn Eli. Câu trả lời của bạn rất hữu ích. – MetallicPriest

+0

Cảnh báo, tôi nghĩ rằng nó nên là "parseIRFile" với chữ thường p. http://llvm.org/docs/doxygen/html/IRReader_2IRReader_8h_source.html – user2027722

+0

@ user2027722: yep, API LLVM thay đổi thường xuyên đến nỗi khó có thể cập nhật mẫu. Tôi có một repo Github cho rằng: https://github.com/eliben/llvm-clang-samples mà tôi làm giữ như đồng bộ nhất có thể, và nó là một nguồn gốc của sự thật hơn so với ngẫu nhiên SO câu trả lời –

1

Cách dễ nhất để thực hiện việc này là xem một trong các công cụ hiện có và lấy mã từ đó. Trong trường hợp này, bạn có thể muốn xem mã nguồn cho llc. Nó có thể lấy một bitcode hoặc .ll tập tin như đầu vào. Bạn có thể sửa đổi các tập tin đầu vào bất kỳ cách nào bạn muốn và sau đó viết ra các tập tin bằng cách sử dụng một cái gì đó tương tự như mã trong llvm-dis nếu bạn muốn có một tập tin văn bản.

2

Điều này thường được thực hiện bằng cách thực hiện chuyển/chuyển đổi LLVM. Bằng cách này, bạn không phải phân tích cú pháp IR vì LLVM sẽ làm điều đó cho bạn và bạn sẽ hoạt động trên biểu diễn OO theo định hướng trong bộ nhớ của IR.

This là điểm nhập để viết thẻ LLVM. Sau đó, bạn có thể xem bất kỳ thẻ tiêu chuẩn đã được triển khai nào đi kèm với LLVM (xem lib/Transforms).

+0

Đó sẽ là những gì tôi sẽ làm cuối cùng. Nhưng tại thời điểm này, vì tôi đang ở trong giai đoạn học tập, tôi muốn có thể xem IR trong các tệp văn bản. – MetallicPriest

+3

Tôi không thấy vấn đề. Hầu hết các công cụ LLVM có thể đọc/ghi trình bày văn bản của IR. Đặc biệt, để phát ra biểu diễn văn bản, hãy thêm công tắc -S vào dòng lệnh của bạn. (Ngoài ra, hãy nhớ rằng biểu diễn nhị phân và văn bản hoàn toàn tương đương). – CAFxX

1

Công cụ Opt lấy mã IR của llvm, chạy một đoạn mã trên nó, sau đó kích hoạt IR chuyển tiếp llvm ở phía bên kia.

Cách dễ nhất để bắt đầu hack là lib \ Transforms \ Hello \ Hello.cpp. Hack nó, chạy qua lựa chọn với tập tin nguồn của bạn như đầu vào, kiểm tra đầu ra.

Ngoài ra, tài liệu để viết bài thực sự khá tốt.

1

Như đã đề cập ở trên, cách tốt nhất để viết thẻ. Nhưng nếu bạn muốn chỉ đơn giản là lặp qua các hướng dẫn và làm một cái gì đó với LLVM cung cấp một lớp InstVisitor. Đây là một lớp thực hiện mẫu khách truy cập để được hướng dẫn. Nó là rất thẳng về phía trước cho người dùng, vì vậy nếu bạn muốn tránh học cách thực hiện một vượt qua, bạn có thể nghỉ mát đó.

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