| 29 | class TestEngine : public ::testing::Test { |
| 30 | protected: |
| 31 | std::string BuildVecAdd(Engine* gdv_engine) { |
| 32 | auto types = gdv_engine->types(); |
| 33 | llvm::IRBuilder<>* builder = gdv_engine->ir_builder(); |
| 34 | llvm::LLVMContext* context = gdv_engine->context(); |
| 35 | |
| 36 | // Create fn prototype : |
| 37 | // int64_t add_longs(int64_t *elements, int32_t nelements) |
| 38 | std::vector<llvm::Type*> arguments; |
| 39 | arguments.push_back(types->i64_ptr_type()); |
| 40 | arguments.push_back(types->i32_type()); |
| 41 | llvm::FunctionType* prototype = |
| 42 | llvm::FunctionType::get(types->i64_type(), arguments, false /*isVarArg*/); |
| 43 | |
| 44 | // Create fn |
| 45 | std::string func_name = "add_longs_test_expr"; |
| 46 | gdv_engine->AddFunctionToCompile(func_name); |
| 47 | llvm::Function* fn = llvm::Function::Create( |
| 48 | prototype, llvm::GlobalValue::ExternalLinkage, func_name, gdv_engine->module()); |
| 49 | assert(fn != nullptr); |
| 50 | |
| 51 | // Name the arguments |
| 52 | llvm::Function::arg_iterator args = fn->arg_begin(); |
| 53 | llvm::Value* arg_elements = &*args; |
| 54 | arg_elements->setName("elements"); |
| 55 | ++args; |
| 56 | llvm::Value* arg_nelements = &*args; |
| 57 | arg_nelements->setName("nelements"); |
| 58 | ++args; |
| 59 | |
| 60 | llvm::BasicBlock* loop_entry = llvm::BasicBlock::Create(*context, "entry", fn); |
| 61 | llvm::BasicBlock* loop_body = llvm::BasicBlock::Create(*context, "loop", fn); |
| 62 | llvm::BasicBlock* loop_exit = llvm::BasicBlock::Create(*context, "exit", fn); |
| 63 | |
| 64 | // Loop entry |
| 65 | builder->SetInsertPoint(loop_entry); |
| 66 | builder->CreateBr(loop_body); |
| 67 | |
| 68 | // Loop body |
| 69 | builder->SetInsertPoint(loop_body); |
| 70 | |
| 71 | llvm::PHINode* loop_var = builder->CreatePHI(types->i32_type(), 2, "loop_var"); |
| 72 | llvm::PHINode* sum = builder->CreatePHI(types->i64_type(), 2, "sum"); |
| 73 | |
| 74 | loop_var->addIncoming(types->i32_constant(0), loop_entry); |
| 75 | sum->addIncoming(types->i64_constant(0), loop_entry); |
| 76 | |
| 77 | // setup loop PHI |
| 78 | llvm::Value* loop_update = |
| 79 | builder->CreateAdd(loop_var, types->i32_constant(1), "loop_var+1"); |
| 80 | loop_var->addIncoming(loop_update, loop_body); |
| 81 | |
| 82 | // get the current value |
| 83 | llvm::Value* offset = |
| 84 | builder->CreateGEP(types->i64_type(), arg_elements, loop_var, "offset"); |
| 85 | llvm::Value* current_value = builder->CreateLoad(types->i64_type(), offset, "value"); |
| 86 | |
| 87 | // setup sum PHI |
| 88 | llvm::Value* sum_update = builder->CreateAdd(sum, current_value, "sum+ith"); |
nothing calls this directly
no test coverage detected