2009-09-13 40 views
10

Tôi đang viết trình tạo mã LLVM cho ngôn ngữ Gỗ, trình biên dịch hiện tại phát ra mã C. Vấn đề của tôi là tôi cần gọi các hàm C từ các tệp LLVM được tạo ra, ví dụ trình biên dịch có một trình thu gom rác thời gian thực và tôi cần gọi các hàm để thông báo khi các đối tượng mới được cấp phát trên heap. Tôi không có ý tưởng về cách liên kết các chức năng này với các tệp LLVM được tạo của tôi.LLVM - liên kết vấn đề

Tạo mã được tạo bằng cách tạo tệp .ll và sau đó biên dịch thủ công các tệp này.

Tôi đang cố gắng gọi chức năng bên ngoài từ LLVM nhưng tôi không có may mắn. Trong các ví dụ tôi đã> chỉ tìm thấy các hàm chuẩn C như "đặt" và "printf" được gọi, nhưng tôi muốn gọi một hàm tự chế. Tôi bị kẹt.

+0

Bạn có nghĩa là bạn đang cố viết mã trực tiếp trong LLVM IR và bạn không thể thực hiện cuộc gọi hoặc đang biên dịch mã bằng LLVM và gặp sự cố? –

Trả lời

5

Biên dịch file lắp ráp LLVM của bạn bình thường với llvm-as:

llvm-as *.ll 

Biên dịch các tập tin bitcode để .S tập tin assembly:

llc *.bc 

GCC họ với các thư viện runtime:

gcc *.s runtime.c -o executable 

Thay thế trong các tệp ảnh thực, thư viện được chia sẻ, v.v. nếu cần. Bạn có được ý tưởng.

12

Tôi giả sử bạn đang viết phép chuyển đổi LLVM và bạn muốn thêm cuộc gọi vào các hàm bên ngoài vào mã được chuyển đổi. Nếu đây không phải là trường hợp, hãy chỉnh sửa câu hỏi của bạn và bao gồm thêm thông tin.

Trước khi bạn có thể gọi hàm bên ngoài từ mã LLVM, bạn cần chèn một khai báo cho nó. Ví dụ:

virtual bool runOnModule(Module &m) { 
    Constant *log_func = m.getOrInsertFunction("log_func", 
               Type::VoidTy, 
               PointerType::getUnqual(Type::Int8Ty), 
               Type::Int32Ty, 
               Type::Int32Ty, 
               NULL); 
    ... 
} 

Đoạn mã trên khai báo một chức năng log_func mà trả về void và ba đối số: một con trỏ byte (string), và hai số nguyên 32-bit. getOrInsertFunction là phương pháp Module.

Để thực sự gọi hàm, bạn phải chèn CallInst. Có một số phương pháp tĩnh Create cho việc này.

+0

Đây chính xác là những gì tôi đã cố gắng tìm ra để làm với llvm, cảm ơn! – Dan

3

Tôi giải thích câu hỏi của bạn là "làm cách nào để triển khai thư viện thời gian chạy bằng C hoặc C++ cho ngôn ngữ của tôi được biên dịch sang LLVM?"

Một cách tiếp cận, được Jonathan Tang chi tiết, để chuyển đổi đầu ra của trình biên dịch từ LLVM IR sang bitcode thành lắp ráp và có liên kết vani gcc khớp với nguồn thời gian chạy (hoặc tệp đối tượng).

Cách tiếp cận thay thế, có thể linh hoạt hơn là sử dụng llvm-gcc để biên dịch thời gian chạy vào bitcoin LLVM và sau đó sử dụng llvm-ld để liên kết bitcode từ trình biên dịch với bitcode của thời gian chạy. Mã bit này sau đó có thể được tối ưu hóa lại với opt, được chuyển đổi trở lại IR bằng llvm-dis, được giải thích trực tiếp với lli (điều này sẽ, chỉ hoạt động nếu LLVM được xây dựng dựa trên libffi) hoặc được biên dịch để lắp ráp với llc (và sau đó đến một người gốc) nhị phân với vanilla gcc).

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