Codegen for looping through a batch of tuples define void @HashInt(i32 %rows, i8* %data, i32* %results) { entry: %0 = icmp sgt i32 %rows, 0 br i1 %0, label %loop, label %exit loop: ; preds = %loop, %entry %counter = phi i32 [ 0, %entry ], [ %1, %loop ] %1 = add i32 %counter, 1 %2 = mul i32 %counter, 16 %3 = getelementptr i8* %data, i32 %2 %4 = call i32
| 383 | // ret void |
| 384 | // } |
| 385 | llvm::Function* CodegenCrcHash(LlvmCodeGen* codegen, bool mixed) { |
| 386 | string name = mixed ? "HashMixed" : "HashInt"; |
| 387 | LlvmCodeGen::FnPrototype prototype(codegen, name, codegen->void_type()); |
| 388 | prototype.AddArgument( |
| 389 | LlvmCodeGen::NamedVariable("rows", codegen->i32_type())); |
| 390 | prototype.AddArgument( |
| 391 | LlvmCodeGen::NamedVariable("data", codegen->ptr_type())); |
| 392 | prototype.AddArgument( |
| 393 | LlvmCodeGen::NamedVariable("results", codegen->i32_ptr_type())); |
| 394 | |
| 395 | LlvmBuilder builder(codegen->context()); |
| 396 | llvm::Value* args[3]; |
| 397 | llvm::Function* fn = prototype.GeneratePrototype(&builder, &args[0]); |
| 398 | |
| 399 | llvm::BasicBlock* loop_start = builder.GetInsertBlock(); |
| 400 | llvm::BasicBlock* loop_body = llvm::BasicBlock::Create(codegen->context(), "loop", fn); |
| 401 | llvm::BasicBlock* loop_exit = llvm::BasicBlock::Create(codegen->context(), "exit", fn); |
| 402 | |
| 403 | int fixed_byte_size = mixed ? |
| 404 | sizeof(int8_t) + sizeof(int32_t) + sizeof(int64_t) : sizeof(int32_t) * 4; |
| 405 | |
| 406 | llvm::Function* fixed_fn = codegen->GetHashFunction(fixed_byte_size); |
| 407 | llvm::Function* string_hash_fn = codegen->GetHashFunction(); |
| 408 | |
| 409 | llvm::Value* row_size = NULL; |
| 410 | if (mixed) { |
| 411 | row_size = codegen->GetI32Constant( |
| 412 | sizeof(int8_t) + sizeof(int32_t) + sizeof(int64_t) + sizeof(StringValue)); |
| 413 | } else { |
| 414 | row_size = codegen->GetI32Constant(fixed_byte_size); |
| 415 | } |
| 416 | llvm::Value* dummy_len = codegen->GetI32Constant(0); |
| 417 | |
| 418 | // Check loop counter |
| 419 | llvm::Value* counter_check = |
| 420 | builder.CreateICmpSGT(args[0], codegen->GetI32Constant(0)); |
| 421 | builder.CreateCondBr(counter_check, loop_body, loop_exit); |
| 422 | |
| 423 | // Loop body |
| 424 | builder.SetInsertPoint(loop_body); |
| 425 | llvm::PHINode* counter = builder.CreatePHI(codegen->i32_type(), 2, "counter"); |
| 426 | counter->addIncoming(codegen->GetI32Constant(0), loop_start); |
| 427 | |
| 428 | llvm::Value* next_counter = |
| 429 | builder.CreateAdd(counter, codegen->GetI32Constant(1)); |
| 430 | counter->addIncoming(next_counter, loop_body); |
| 431 | |
| 432 | // Hash the current data |
| 433 | llvm::Value* offset = builder.CreateMul(counter, row_size); |
| 434 | llvm::Value* data = builder.CreateGEP(args[1], offset); |
| 435 | |
| 436 | llvm::Value* seed = codegen->GetI32Constant(HashUtil::FNV_SEED); |
| 437 | seed = |
| 438 | builder.CreateCall(fixed_fn, llvm::ArrayRef<llvm::Value*>({data, dummy_len, seed})); |
| 439 | |
| 440 | // Get the string data |
| 441 | if (mixed) { |
| 442 | llvm::Value* string_data = |
no test coverage detected