提交 09f00581 编写于 作者: N Nikos Armenatzoglou 提交者: Shreedhar Hardikar

Codegen expressions that contain plus, minus and mul operators on float8 data types

Signed-off-by: NKarthikeyan Jambu Rajaraman <karthi.jrk@gmail.com>
上级 20ccb77a
......@@ -53,10 +53,10 @@ class PGArithFuncGenerator {
* error block.
**/
static bool MulWithOverflow(gpcodegen::CodegenUtils* codegen_utils,
llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args,
llvm::Value** llvm_out_value);
llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args,
llvm::Value** llvm_out_value);
/**
* @brief Create LLVM Add instruction with check for overflow
......@@ -92,10 +92,10 @@ class PGArithFuncGenerator {
* error block.
**/
static bool SubWithOverflow(gpcodegen::CodegenUtils* codegen_utils,
llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args,
llvm::Value** llvm_out_value);
llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args,
llvm::Value** llvm_out_value);
};
template <typename rtype, typename Arg0, typename Arg1>
......@@ -107,30 +107,37 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::MulWithOverflow(
llvm::Value** llvm_out_value) {
assert(nullptr != llvm_out_value);
// Assumed caller checked vector size and nullptr for codegen_utils
llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock(
"mul_non_overflow_block", llvm_main_func);
llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock(
"mul_overflow_block", llvm_main_func);
llvm::Value* llvm_mul_output = codegen_utils->CreateMulOverflow<rtype>(
llvm_args[0], llvm_args[1]);
llvm::IRBuilder<>* irb = codegen_utils->ir_builder();
*llvm_out_value = irb->CreateExtractValue(llvm_mul_output, 0);
llvm::Value* llvm_overflow_flag = irb->CreateExtractValue(llvm_mul_output, 1);
if (!llvm_mul_output->getType()->isDoubleTy())
{
llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock(
"mul_non_overflow_block", llvm_main_func);
llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock(
"mul_overflow_block", llvm_main_func);
irb->CreateCondBr(
irb->CreateICmpEQ(llvm_overflow_flag,
codegen_utils->GetConstant<bool>(true)),
llvm_overflow_block,
llvm_non_overflow_block);
*llvm_out_value = irb->CreateExtractValue(llvm_mul_output, 0);
llvm::Value* llvm_overflow_flag = irb->CreateExtractValue(llvm_mul_output, 1);
irb->SetInsertPoint(llvm_overflow_block);
// TODO(krajaraman): Elog::ERROR after ElogWrapper integrated.
irb->CreateBr(llvm_error_block);
irb->CreateCondBr(
irb->CreateICmpEQ(llvm_overflow_flag,
codegen_utils->GetConstant<bool>(true)),
llvm_overflow_block,
llvm_non_overflow_block);
irb->SetInsertPoint(llvm_non_overflow_block);
irb->SetInsertPoint(llvm_overflow_block);
// TODO(krajaraman): Elog::ERROR after ElogWrapper integrated.
irb->CreateBr(llvm_error_block);
irb->SetInsertPoint(llvm_non_overflow_block);
}
else {
*llvm_out_value = llvm_mul_output;
}
return true;
}
......@@ -144,30 +151,36 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::AddWithOverflow(
llvm::Value** llvm_out_value) {
assert(nullptr != llvm_out_value);
// Assumed caller checked vector size and nullptr for codegen_utils
llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock(
"add_non_overflow_block", llvm_main_func);
llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock(
"add_overflow_block", llvm_main_func);
llvm::Value* llvm_mul_output = codegen_utils->CreateAddOverflow<rtype>(
llvm::Value* llvm_add_output = codegen_utils->CreateAddOverflow<rtype>(
llvm_args[0], llvm_args[1]);
llvm::IRBuilder<>* irb = codegen_utils->ir_builder();
*llvm_out_value = irb->CreateExtractValue(llvm_mul_output, 0);
llvm::Value* llvm_overflow_flag = irb->CreateExtractValue(llvm_mul_output, 1);
irb->CreateCondBr(
irb->CreateICmpEQ(llvm_overflow_flag,
codegen_utils->GetConstant<bool>(true)),
llvm_overflow_block,
llvm_non_overflow_block);
irb->SetInsertPoint(llvm_overflow_block);
// TODO(krajaraman): Elog::ERROR after ElogWrapper integrated.
irb->CreateBr(llvm_error_block);
irb->SetInsertPoint(llvm_non_overflow_block);
if (!llvm_add_output->getType()->isDoubleTy())
{
llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock(
"add_non_overflow_block", llvm_main_func);
llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock(
"add_overflow_block", llvm_main_func);
*llvm_out_value = irb->CreateExtractValue(llvm_add_output, 0);
llvm::Value* llvm_overflow_flag = irb->CreateExtractValue(llvm_add_output, 1);
irb->CreateCondBr(
irb->CreateICmpEQ(llvm_overflow_flag,
codegen_utils->GetConstant<bool>(true)),
llvm_overflow_block,
llvm_non_overflow_block );
irb->SetInsertPoint(llvm_overflow_block);
// TODO : krajaraman Elog::ERROR after ElogWrapper integrad.
irb->CreateBr(llvm_error_block);
irb->SetInsertPoint(llvm_non_overflow_block);
}
else {
*llvm_out_value = llvm_add_output;
}
return true;
}
......@@ -181,31 +194,38 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::SubWithOverflow(
llvm::Value** llvm_out_value) {
assert(nullptr != llvm_out_value);
// Assumed caller checked vector size and nullptr for codegen_utils
llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock(
"sub_non_overflow_block", llvm_main_func);
llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock(
"sub_overflow_block", llvm_main_func);
llvm::Value* llvm_mul_output = codegen_utils->CreateSubOverflow<rtype>(
llvm::Value* llvm_sub_output = codegen_utils->CreateSubOverflow<rtype>(
llvm_args[0], llvm_args[1]);
llvm::IRBuilder<>* irb = codegen_utils->ir_builder();
*llvm_out_value = irb->CreateExtractValue(llvm_mul_output, 0);
llvm::Value* llvm_overflow_flag = irb->CreateExtractValue(llvm_mul_output, 1);
irb->CreateCondBr(
irb->CreateICmpEQ(llvm_overflow_flag,
codegen_utils->GetConstant<bool>(true)),
llvm_overflow_block,
llvm_non_overflow_block);
irb->SetInsertPoint(llvm_overflow_block);
// TODO(krajaraman): Elog::ERROR after ElogWrapper integrated.
irb->CreateBr(llvm_error_block);
irb->SetInsertPoint(llvm_non_overflow_block);
// We only support overflow checks for integers for now
if (llvm_sub_output->getType()->isIntegerTy())
{
llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock(
"sub_non_overflow_block", llvm_main_func);
llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock(
"sub_overflow_block", llvm_main_func);
*llvm_out_value = irb->CreateExtractValue(llvm_sub_output, 0);
llvm::Value* llvm_overflow_flag = irb->CreateExtractValue(llvm_sub_output, 1);
irb->CreateCondBr(
irb->CreateICmpEQ(llvm_overflow_flag,
codegen_utils->GetConstant<bool>(true)),
llvm_overflow_block,
llvm_non_overflow_block);
irb->SetInsertPoint(llvm_overflow_block);
// TODO(krajaraman): Elog::ERROR after ElogWrapper integrated.
irb->CreateBr(llvm_error_block);
irb->SetInsertPoint(llvm_non_overflow_block);
}
else {
*llvm_out_value = llvm_sub_output;
}
return true;
}
......
......@@ -1340,6 +1340,55 @@ class ArithOpMaker<float> {
template <>
class ArithOpMaker<double> {
public:
static llvm::Value* CreateAddOverflow(CodegenUtils* generator,
llvm::Value* arg0,
llvm::Value* arg1) {
Checker(arg0, arg1);
llvm::Value* casted_arg0 = generator->ir_builder()->
CreateBitCast(arg0, generator->GetType<double>());
llvm::Value* casted_arg1 = generator->ir_builder()->
CreateBitCast(arg1, generator->GetType<double>());
// TODO: armenatzoglou Support overflow
return generator->ir_builder()->CreateFAdd(casted_arg0, casted_arg1);
}
static llvm::Value* CreateSubOverflow(CodegenUtils* generator,
llvm::Value* arg0,
llvm::Value* arg1) {
Checker(arg0, arg1);
llvm::Value* casted_arg0 = generator->ir_builder()->
CreateBitCast(arg0, generator->GetType<double>());
llvm::Value* casted_arg1 = generator->ir_builder()->
CreateBitCast(arg1, generator->GetType<double>());
// TODO: armenatzoglou Support overflow
return generator->ir_builder()->CreateFSub(casted_arg0, casted_arg1);
}
static llvm::Value* CreateMulOverflow(CodegenUtils* generator,
llvm::Value* arg0,
llvm::Value* arg1) {
Checker(arg0, arg1);
llvm::Value* casted_arg0 = generator->ir_builder()->
CreateBitCast(arg0, generator->GetType<double>());
llvm::Value* casted_arg1 = generator->ir_builder()->
CreateBitCast(arg1, generator->GetType<double>());
// TODO: armenatzoglou Support overflow
return generator->ir_builder()->CreateFMul(casted_arg0, casted_arg1);
}
private:
static void Checker(llvm::Value* arg0,
llvm::Value* arg1) {
assert(nullptr != arg0 && nullptr != arg0->getType());
assert(nullptr != arg1 && nullptr != arg1->getType());
assert(arg0->getType()->isIntegerTy());
assert(arg1->getType()->isIntegerTy());
}
};
} // namespace codegen_utils_detail
......
......@@ -17,6 +17,7 @@
#include "llvm/IR/Value.h"
extern "C" {
#include "c.h"
#include "postgres.h" // NOLINT(build/include)
#include "utils/elog.h"
#include "nodes/execnodes.h"
......@@ -36,14 +37,16 @@ OpExprTreeGenerator::supported_function_;
void OpExprTreeGenerator::InitializeSupportedFunction() {
if (!supported_function_.empty()) { return; }
supported_function_[141] = std::unique_ptr<PGFuncGeneratorInterface>(
new PGGenericFuncGenerator<int32_t, int32_t>(
141,
"int4mul",
&PGArithFuncGenerator<int32_t, int32_t, int32_t>::MulWithOverflow));
supported_function_[149] = std::unique_ptr<PGFuncGeneratorInterface>(
new PGIRBuilderFuncGenerator<decltype(&IRBuilder<>::CreateICmpSLE),
int32_t, int32_t>(149, "int4le", &IRBuilder<>::CreateICmpSLE));
supported_function_[1088] = std::unique_ptr<PGFuncGeneratorInterface>(
new PGIRBuilderFuncGenerator<decltype(&IRBuilder<>::CreateICmpSLE),
int32_t, int32_t>(1088, "date_le", &IRBuilder<>::CreateICmpSLE));
supported_function_[177] = std::unique_ptr<PGFuncGeneratorInterface>(
new PGGenericFuncGenerator<int32_t, int32_t>(
177,
......@@ -56,11 +59,29 @@ void OpExprTreeGenerator::InitializeSupportedFunction() {
"int4mi",
&PGArithFuncGenerator<int32_t, int32_t, int32_t>::SubWithOverflow));
supported_function_[141] = std::unique_ptr<PGFuncGeneratorInterface>(
new PGGenericFuncGenerator<int32_t, int32_t>(
141,
"int4mul",
&PGArithFuncGenerator<int32_t, int32_t, int32_t>::MulWithOverflow));
supported_function_[216] = std::unique_ptr<PGFuncGeneratorInterface>(
new PGGenericFuncGenerator<float8, float8>(
216,
"float8mul",
&PGArithFuncGenerator<float8, float8, int64_t>::MulWithOverflow));
supported_function_[218] = std::unique_ptr<PGFuncGeneratorInterface>(
new PGGenericFuncGenerator<float8, float8>(
218,
"float8pl",
&PGArithFuncGenerator<float8, float8, int64_t>::AddWithOverflow));
supported_function_[219] = std::unique_ptr<PGFuncGeneratorInterface>(
new PGGenericFuncGenerator<float8, float8>(
219,
"float8mi",
&PGArithFuncGenerator<float8, float8, int64_t>::SubWithOverflow));
supported_function_[1088] = std::unique_ptr<PGFuncGeneratorInterface>(
new PGIRBuilderFuncGenerator<decltype(&IRBuilder<>::CreateICmpSLE),
int32_t, int32_t>(1088, "date_le", &IRBuilder<>::CreateICmpSLE));
}
OpExprTreeGenerator::OpExprTreeGenerator(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册