2012-03-09 54 views
7

Tôi đang cố gắng bắt đầu với LLVM để thêm biên dịch vào thời gian cho mã của tôi, nhưng việc tìm kiếm các tham chiếu về cách làm những thứ tôi muốn trong LLVM rất khó khăn, mặc dù có kiểm tra thông qua hướng dẫn Kaleidoscope, hướng dẫn tham khảo ngôn ngữ, sổ tay của lập trình viên và tài liệu doxygen. Có nhiều tham chiếu đến API C++ của LLVM hơn các API này không?Truy cập các phần tử trong mảng LLVM

Bây giờ cho câu hỏi cụ thể. Tôi đã phân bổ một đối tượng mảng với hai yếu tố (mà tôi giả định tương ứng với double[2] trong C++):

const llvm::Type* double_t = llvm::Type::getDoubleTy(llvm::getGlobalContext()); 
const llvm::Type* array_t = llvm::ArrayType::get(double_t,2) 

Sau đó trong mã này, tôi tạo ra một chức năng, nơi mảng này là một trong các đối số. Sau đó, trong chức năng của tôi, tôi trích xuất phần tử đầu tiên trong mảng và trả lại phần tử đó cho người dùng:

llvm::Function::arg_iterator AI = jit_function_->arg_begin(); 
llvm::Value *x = AI; 
llvm::Value *x0 = Builder.CreateExtractValue(x,0); 
Builder.CreateRet(x0); 

Mã jits tốt, nhưng khi tôi cố gắng chạy, nó không hoạt động. Ví dụ:

typedef double (*GenType)(double[2]); 
GenType FP = GenType(intptr_t(TheExecutionEngine->getPointerToFunction(jit_function_))); 
double y[2] = {10,20}; 
double r = FP(y); 
printf("r = %g\n", r); 

Giá trị trả về chỉ là vô nghĩa và tôi không thể nhìn thấy những gì tôi đang làm sai. Nếu tôi vượt qua các giá trị trong mảng (10 và 20) làm đối số vô hướng cho hàm, nó hoạt động tốt.

Trả lời

8

Tôi nghĩ rằng tôi có thể trả lời câu hỏi của riêng mình. Đối với phần đầu tiên của câu hỏi, một tài liệu tham khảo tốt để LLVM (ngoài những người đã đề cập ở trên) là viết những gì bạn muốn trong đồng bằng C và biên dịch nó với Clang và xem đầu ra LLVM: clang -S -emit-llvm test.c -o -. Đối với các câu hỏi cụ thể, vấn đề của tôi là tôi giả định rằng tôi đã đi qua một mảng của hai đôi để chức năng jitted, trong khi trên thực tế tôi đã đi qua một con trỏ cho một mảng với hai giá trị. Vì vậy, giải pháp là thay đổi:

const llvm::Type* array_t = llvm::ArrayType::get(double_t,2); 

để

const llvm::Type* array_t = llvm::PointerType::getUnqual(llvm::ArrayType::get(double_t,2)); 

Và thêm một dereferencing thêm bằng cách thay đổi

llvm::Value *x0 = Builder.CreateExtractValue(x,0); 

để

llvm::Value *x0 = Builder.CreateExtractValue(Builder.CreateLoad(x),0); 
0

Nếu bạn đang sử dụng LLVM 3.0 hoặc 3.1, CreateExtractValue lấy một ArrayRef với các chỉ mục.

+0

Vâng, tôi biết (nó được sử dụng trong đoạn mã trên). Nhưng nó không thực sự trả lời câu hỏi. – Joel

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