提交 8cd9ed9f 编写于 作者: N Nikos Armenatzoglou 提交者: Shreedhar Hardikar

Support <= operator for date/timestamp data types and some minor refactors.

上级 564b9235
...@@ -171,12 +171,13 @@ set(GPCODEGEN_SRC ...@@ -171,12 +171,13 @@ set(GPCODEGEN_SRC
codegen_interface.cc codegen_interface.cc
codegen_manager.cc codegen_manager.cc
codegen_wrapper.cc codegen_wrapper.cc
const_expr_tree_generator.cc
exec_variable_list_codegen.cc exec_variable_list_codegen.cc
exec_eval_expr_codegen.cc exec_eval_expr_codegen.cc
expr_tree_generator.cc expr_tree_generator.cc
op_expr_tree_generator.cc op_expr_tree_generator.cc
pg_date_func_generator.cc
var_expr_tree_generator.cc var_expr_tree_generator.cc
const_expr_tree_generator.cc
) )
# Integrate with GPDB build system. # Integrate with GPDB build system.
......
...@@ -39,7 +39,7 @@ ConstExprTreeGenerator::ConstExprTreeGenerator(ExprState* expr_state) : ...@@ -39,7 +39,7 @@ ConstExprTreeGenerator::ConstExprTreeGenerator(ExprState* expr_state) :
ExprTreeGenerator(expr_state, ExprTreeNodeType::kConst) { ExprTreeGenerator(expr_state, ExprTreeNodeType::kConst) {
} }
bool ConstExprTreeGenerator::GenerateCode(CodegenUtils* codegen_utils, bool ConstExprTreeGenerator::GenerateCode(GpCodegenUtils* codegen_utils,
ExprContext* econtext, ExprContext* econtext,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
......
...@@ -32,7 +32,7 @@ class ConstExprTreeGenerator : public ExprTreeGenerator { ...@@ -32,7 +32,7 @@ class ConstExprTreeGenerator : public ExprTreeGenerator {
ExprContext* econtext, ExprContext* econtext,
std::unique_ptr<ExprTreeGenerator>* expr_tree); std::unique_ptr<ExprTreeGenerator>* expr_tree);
bool GenerateCode(gpcodegen::CodegenUtils* codegen_utils, bool GenerateCode(gpcodegen::GpCodegenUtils* codegen_utils,
ExprContext* econtext, ExprContext* econtext,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <utility> #include <utility>
#include <unordered_map> #include <unordered_map>
#include "codegen/utils/codegen_utils.h" #include "codegen/utils/gp_codegen_utils.h"
#include "llvm/IR/Value.h" #include "llvm/IR/Value.h"
...@@ -71,7 +71,7 @@ class ExprTreeGenerator { ...@@ -71,7 +71,7 @@ class ExprTreeGenerator {
* *
* @return true when it generated successfully otherwise it return false. * @return true when it generated successfully otherwise it return false.
**/ **/
virtual bool GenerateCode(gpcodegen::CodegenUtils* codegen_utils, virtual bool GenerateCode(gpcodegen::GpCodegenUtils* codegen_utils,
ExprContext* econtext, ExprContext* econtext,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
......
...@@ -45,7 +45,7 @@ class OpExprTreeGenerator : public ExprTreeGenerator { ...@@ -45,7 +45,7 @@ class OpExprTreeGenerator : public ExprTreeGenerator {
ExprContext* econtext, ExprContext* econtext,
std::unique_ptr<ExprTreeGenerator>* expr_tree); std::unique_ptr<ExprTreeGenerator>* expr_tree);
bool GenerateCode(gpcodegen::CodegenUtils* codegen_utils, bool GenerateCode(gpcodegen::GpCodegenUtils* codegen_utils,
ExprContext* econtext, ExprContext* econtext,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
#include "codegen/utils/codegen_utils.h" #include "codegen/utils/gp_codegen_utils.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Value.h" #include "llvm/IR/Value.h"
...@@ -52,11 +52,11 @@ class PGArithFuncGenerator { ...@@ -52,11 +52,11 @@ class PGArithFuncGenerator {
* @note If there is overflow, it will do elog::ERROR and then jump to given * @note If there is overflow, it will do elog::ERROR and then jump to given
* error block. * error block.
**/ **/
static bool MulWithOverflow(gpcodegen::CodegenUtils* codegen_utils, static bool MulWithOverflow(gpcodegen::GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args, const std::vector<llvm::Value*>& llvm_args,
llvm::Value** llvm_out_value); llvm::Value** llvm_out_value);
/** /**
* @brief Create LLVM Add instruction with check for overflow * @brief Create LLVM Add instruction with check for overflow
...@@ -72,7 +72,7 @@ class PGArithFuncGenerator { ...@@ -72,7 +72,7 @@ class PGArithFuncGenerator {
* @note If there is overflow, it will do elog::ERROR and then jump to given * @note If there is overflow, it will do elog::ERROR and then jump to given
* error block. * error block.
**/ **/
static bool AddWithOverflow(gpcodegen::CodegenUtils* codegen_utils, static bool AddWithOverflow(gpcodegen::GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args, const std::vector<llvm::Value*>& llvm_args,
...@@ -91,16 +91,16 @@ class PGArithFuncGenerator { ...@@ -91,16 +91,16 @@ class PGArithFuncGenerator {
* @note If there is overflow, it will do elog::ERROR and then jump to given * @note If there is overflow, it will do elog::ERROR and then jump to given
* error block. * error block.
**/ **/
static bool SubWithOverflow(gpcodegen::CodegenUtils* codegen_utils, static bool SubWithOverflow(gpcodegen::GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args, const std::vector<llvm::Value*>& llvm_args,
llvm::Value** llvm_out_value); llvm::Value** llvm_out_value);
}; };
template <typename rtype, typename Arg0, typename Arg1> template <typename rtype, typename Arg0, typename Arg1>
bool PGArithFuncGenerator<rtype, Arg0, Arg1>::MulWithOverflow( bool PGArithFuncGenerator<rtype, Arg0, Arg1>::MulWithOverflow(
gpcodegen::CodegenUtils* codegen_utils, gpcodegen::GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args, const std::vector<llvm::Value*>& llvm_args,
...@@ -113,29 +113,26 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::MulWithOverflow( ...@@ -113,29 +113,26 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::MulWithOverflow(
llvm::IRBuilder<>* irb = codegen_utils->ir_builder(); llvm::IRBuilder<>* irb = codegen_utils->ir_builder();
if (!llvm_mul_output->getType()->isDoubleTy()) if (llvm_mul_output->getType()->isIntegerTy()) {
{
llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock( llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock(
"mul_non_overflow_block", llvm_main_func); "mul_non_overflow_block", llvm_main_func);
llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock( llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock(
"mul_overflow_block", llvm_main_func); "mul_overflow_block", llvm_main_func);
*llvm_out_value = irb->CreateExtractValue(llvm_mul_output, 0); *llvm_out_value = irb->CreateExtractValue(llvm_mul_output, 0);
llvm::Value* llvm_overflow_flag = irb->CreateExtractValue(llvm_mul_output, 1); llvm::Value* llvm_overflow_flag =
irb->CreateExtractValue(llvm_mul_output, 1);
irb->CreateCondBr( irb->CreateCondBr(llvm_overflow_flag,
irb->CreateICmpEQ(llvm_overflow_flag, llvm_overflow_block,
codegen_utils->GetConstant<bool>(true)), llvm_non_overflow_block);
llvm_overflow_block,
llvm_non_overflow_block);
irb->SetInsertPoint(llvm_overflow_block); irb->SetInsertPoint(llvm_overflow_block);
// TODO(krajaraman): Elog::ERROR after ElogWrapper integrated. // TODO(krajaraman): Elog::ERROR after ElogWrapper integrated.
irb->CreateBr(llvm_error_block); irb->CreateBr(llvm_error_block);
irb->SetInsertPoint(llvm_non_overflow_block); irb->SetInsertPoint(llvm_non_overflow_block);
} } else {
else {
*llvm_out_value = llvm_mul_output; *llvm_out_value = llvm_mul_output;
} }
...@@ -144,7 +141,7 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::MulWithOverflow( ...@@ -144,7 +141,7 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::MulWithOverflow(
template <typename rtype, typename Arg0, typename Arg1> template <typename rtype, typename Arg0, typename Arg1>
bool PGArithFuncGenerator<rtype, Arg0, Arg1>::AddWithOverflow( bool PGArithFuncGenerator<rtype, Arg0, Arg1>::AddWithOverflow(
gpcodegen::CodegenUtils* codegen_utils, gpcodegen::GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args, const std::vector<llvm::Value*>& llvm_args,
...@@ -157,28 +154,25 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::AddWithOverflow( ...@@ -157,28 +154,25 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::AddWithOverflow(
llvm::IRBuilder<>* irb = codegen_utils->ir_builder(); llvm::IRBuilder<>* irb = codegen_utils->ir_builder();
if (!llvm_add_output->getType()->isDoubleTy()) if (llvm_add_output->getType()->isIntegerTy()) {
{
llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock( llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock(
"add_non_overflow_block", llvm_main_func); "add_non_overflow_block", llvm_main_func);
llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock( llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock(
"add_overflow_block", llvm_main_func); "add_overflow_block", llvm_main_func);
*llvm_out_value = irb->CreateExtractValue(llvm_add_output, 0); *llvm_out_value = irb->CreateExtractValue(llvm_add_output, 0);
llvm::Value* llvm_overflow_flag = irb->CreateExtractValue(llvm_add_output, 1); llvm::Value* llvm_overflow_flag =
irb->CreateExtractValue(llvm_add_output, 1);
irb->CreateCondBr( irb->CreateCondBr(llvm_overflow_flag,
irb->CreateICmpEQ(llvm_overflow_flag, llvm_overflow_block,
codegen_utils->GetConstant<bool>(true)), llvm_non_overflow_block);
llvm_overflow_block,
llvm_non_overflow_block );
irb->SetInsertPoint(llvm_overflow_block); irb->SetInsertPoint(llvm_overflow_block);
// TODO : krajaraman Elog::ERROR after ElogWrapper integrad. // TODO(krajaraman) Elog::ERROR after ElogWrapper integrated.
irb->CreateBr(llvm_error_block); irb->CreateBr(llvm_error_block);
irb->SetInsertPoint(llvm_non_overflow_block); irb->SetInsertPoint(llvm_non_overflow_block);
} } else {
else {
*llvm_out_value = llvm_add_output; *llvm_out_value = llvm_add_output;
} }
...@@ -187,7 +181,7 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::AddWithOverflow( ...@@ -187,7 +181,7 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::AddWithOverflow(
template <typename rtype, typename Arg0, typename Arg1> template <typename rtype, typename Arg0, typename Arg1>
bool PGArithFuncGenerator<rtype, Arg0, Arg1>::SubWithOverflow( bool PGArithFuncGenerator<rtype, Arg0, Arg1>::SubWithOverflow(
gpcodegen::CodegenUtils* codegen_utils, gpcodegen::GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args, const std::vector<llvm::Value*>& llvm_args,
...@@ -201,29 +195,26 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::SubWithOverflow( ...@@ -201,29 +195,26 @@ bool PGArithFuncGenerator<rtype, Arg0, Arg1>::SubWithOverflow(
llvm::IRBuilder<>* irb = codegen_utils->ir_builder(); llvm::IRBuilder<>* irb = codegen_utils->ir_builder();
// We only support overflow checks for integers for now // We only support overflow checks for integers for now
if (llvm_sub_output->getType()->isIntegerTy()) if (llvm_sub_output->getType()->isIntegerTy()) {
{
llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock( llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock(
"sub_non_overflow_block", llvm_main_func); "sub_non_overflow_block", llvm_main_func);
llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock( llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock(
"sub_overflow_block", llvm_main_func); "sub_overflow_block", llvm_main_func);
*llvm_out_value = irb->CreateExtractValue(llvm_sub_output, 0); *llvm_out_value = irb->CreateExtractValue(llvm_sub_output, 0);
llvm::Value* llvm_overflow_flag = irb->CreateExtractValue(llvm_sub_output, 1); llvm::Value* llvm_overflow_flag =
irb->CreateExtractValue(llvm_sub_output, 1);
irb->CreateCondBr( irb->CreateCondBr(llvm_overflow_flag,
irb->CreateICmpEQ(llvm_overflow_flag, llvm_overflow_block,
codegen_utils->GetConstant<bool>(true)), llvm_non_overflow_block);
llvm_overflow_block,
llvm_non_overflow_block);
irb->SetInsertPoint(llvm_overflow_block); irb->SetInsertPoint(llvm_overflow_block);
// TODO(krajaraman): Elog::ERROR after ElogWrapper integrated. // TODO(krajaraman): Elog::ERROR after ElogWrapper integrated.
irb->CreateBr(llvm_error_block); irb->CreateBr(llvm_error_block);
irb->SetInsertPoint(llvm_non_overflow_block); irb->SetInsertPoint(llvm_non_overflow_block);
} } else {
else {
*llvm_out_value = llvm_sub_output; *llvm_out_value = llvm_sub_output;
} }
return true; return true;
......
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2016 Pivotal Software, Inc.
//
// @filename:
// pg_date_func_generator.h
//
// @doc:
// Base class for date functions to generate code
//
//---------------------------------------------------------------------------
#ifndef GPCODEGEN_PG_DATE_FUNC_GENERATOR_H_ // NOLINT(build/header_guard)
#define GPCODEGEN_PG_DATE_FUNC_GENERATOR_H_
#include <string>
#include <vector>
#include <memory>
#include "codegen/utils/codegen_utils.h"
#include "codegen/base_codegen.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Value.h"
namespace gpcodegen {
/** \addtogroup gpcodegen
* @{
*/
/**
* @brief Class with Static member function to generate code for date
* operators.
**/
class PGDateFuncGenerator {
public:
/**
* @brief Create instructions for date_le_timestamp function
*
* @param codegen_utils Utility to easy code generation.
* @param llvm_main_func Current function for which we are generating code
* @param llvm_error_block Basic Block to jump when error happens
* @param llvm_args Vector of llvm arguments for the function
* @param llvm_out_value Store the results of function
*
* @return true if generation was successful otherwise return false
*
**/
static bool DateLETimestamp(gpcodegen::GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args,
llvm::Value** llvm_out_value);
private:
/**
* @brief Internal routines for promoting date to timestamp and timestamp
* with time zone (see date2timestamp).
*
* @param codegen_utils Utility to easy code generation.
* @param llvm_main_func Current function for which we are generating code
* @param llvm_arg llvm value for the date
* @param llvm_error_block Basic Block to jump when error happens
*
* @note If there is overflow, it will do elog::ERROR and then jump to given
* error block.
*/
static llvm::Value* GenerateDate2Timestamp(
GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func,
llvm::Value* llvm_arg,
llvm::BasicBlock* llvm_error_block);
};
/** @} */
} // namespace gpcodegen
#endif // GPCODEGEN_PG_ARITH_FUNC_GENERATOR_H_
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <memory> #include <memory>
#include "codegen/pg_func_generator_interface.h" #include "codegen/pg_func_generator_interface.h"
#include "codegen/utils/codegen_utils.h" #include "codegen/utils/gp_codegen_utils.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Value.h" #include "llvm/IR/Value.h"
...@@ -28,7 +28,7 @@ namespace gpcodegen { ...@@ -28,7 +28,7 @@ namespace gpcodegen {
* @{ * @{
*/ */
typedef bool (*PGFuncGenerator)(gpcodegen::CodegenUtils* codegen_utils, typedef bool (*PGFuncGenerator)(gpcodegen::GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args, const std::vector<llvm::Value*>& llvm_args,
...@@ -63,7 +63,7 @@ class PGFuncBaseGenerator : public PGFuncGeneratorInterface { ...@@ -63,7 +63,7 @@ class PGFuncBaseGenerator : public PGFuncGeneratorInterface {
* *
* @return true on successful preprocess otherwise return false. * @return true on successful preprocess otherwise return false.
**/ **/
bool PreProcessArgs(gpcodegen::CodegenUtils* codegen_utils, bool PreProcessArgs(gpcodegen::GpCodegenUtils* codegen_utils,
const std::vector<llvm::Value*>& llvm_in_args, const std::vector<llvm::Value*>& llvm_in_args,
std::vector<llvm::Value*>* llvm_out_args) { std::vector<llvm::Value*>* llvm_out_args) {
assert(nullptr != codegen_utils && assert(nullptr != codegen_utils &&
...@@ -132,7 +132,7 @@ Arg0, Arg1> { ...@@ -132,7 +132,7 @@ Arg0, Arg1> {
mem_func_ptr) { mem_func_ptr) {
} }
bool GenerateCode(gpcodegen::CodegenUtils* codegen_utils, bool GenerateCode(gpcodegen::GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args, const std::vector<llvm::Value*>& llvm_args,
...@@ -178,7 +178,7 @@ Arg0, Arg1> { ...@@ -178,7 +178,7 @@ Arg0, Arg1> {
func_ptr) { func_ptr) {
} }
bool GenerateCode(gpcodegen::CodegenUtils* codegen_utils, bool GenerateCode(gpcodegen::GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args, const std::vector<llvm::Value*>& llvm_args,
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "llvm/IR/Value.h" #include "llvm/IR/Value.h"
#include "codegen/utils/codegen_utils.h" #include "codegen/utils/gp_codegen_utils.h"
namespace gpcodegen { namespace gpcodegen {
...@@ -54,7 +54,7 @@ class PGFuncGeneratorInterface { ...@@ -54,7 +54,7 @@ class PGFuncGeneratorInterface {
* *
* @return true when it generated successfully otherwise it return false. * @return true when it generated successfully otherwise it return false.
**/ **/
virtual bool GenerateCode(gpcodegen::CodegenUtils* codegen_utils, virtual bool GenerateCode(gpcodegen::GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
const std::vector<llvm::Value*>& llvm_args, const std::vector<llvm::Value*>& llvm_args,
......
...@@ -492,7 +492,7 @@ class CodegenUtils { ...@@ -492,7 +492,7 @@ class CodegenUtils {
// Check that the call instruction belongs to a BasicBlock which is part of // Check that the call instruction belongs to a BasicBlock which is part of
// a valid function // a valid function
if (!(call_inst && call_inst->getParent() if (!(call_inst && call_inst->getParent()
&& call_inst->getParent()->getParent())){ && call_inst->getParent()->getParent())) {
return false; return false;
} }
llvm::InlineFunctionInfo info; llvm::InlineFunctionInfo info;
...@@ -1360,7 +1360,6 @@ class ArithOpMaker<float> { ...@@ -1360,7 +1360,6 @@ class ArithOpMaker<float> {
template <> template <>
class ArithOpMaker<double> { class ArithOpMaker<double> {
public: public:
static llvm::Value* CreateAddOverflow(CodegenUtils* generator, static llvm::Value* CreateAddOverflow(CodegenUtils* generator,
llvm::Value* arg0, llvm::Value* arg0,
llvm::Value* arg1) { llvm::Value* arg1) {
...@@ -1370,7 +1369,7 @@ class ArithOpMaker<double> { ...@@ -1370,7 +1369,7 @@ class ArithOpMaker<double> {
llvm::Value* casted_arg1 = generator->ir_builder()-> llvm::Value* casted_arg1 = generator->ir_builder()->
CreateBitCast(arg1, generator->GetType<double>()); CreateBitCast(arg1, generator->GetType<double>());
// TODO: armenatzoglou Support overflow // TODO(armenatzoglou) Support overflow
return generator->ir_builder()->CreateFAdd(casted_arg0, casted_arg1); return generator->ir_builder()->CreateFAdd(casted_arg0, casted_arg1);
} }
...@@ -1383,7 +1382,7 @@ class ArithOpMaker<double> { ...@@ -1383,7 +1382,7 @@ class ArithOpMaker<double> {
llvm::Value* casted_arg1 = generator->ir_builder()-> llvm::Value* casted_arg1 = generator->ir_builder()->
CreateBitCast(arg1, generator->GetType<double>()); CreateBitCast(arg1, generator->GetType<double>());
// TODO: armenatzoglou Support overflow // TODO(armenatzoglou) Support overflow
return generator->ir_builder()->CreateFSub(casted_arg0, casted_arg1); return generator->ir_builder()->CreateFSub(casted_arg0, casted_arg1);
} }
...@@ -1396,7 +1395,7 @@ class ArithOpMaker<double> { ...@@ -1396,7 +1395,7 @@ class ArithOpMaker<double> {
llvm::Value* casted_arg1 = generator->ir_builder()-> llvm::Value* casted_arg1 = generator->ir_builder()->
CreateBitCast(arg1, generator->GetType<double>()); CreateBitCast(arg1, generator->GetType<double>());
// TODO: armenatzoglou Support overflow // TODO(armenatzoglou) Support overflow
return generator->ir_builder()->CreateFMul(casted_arg0, casted_arg1); return generator->ir_builder()->CreateFMul(casted_arg0, casted_arg1);
} }
......
...@@ -32,7 +32,7 @@ class VarExprTreeGenerator : public ExprTreeGenerator { ...@@ -32,7 +32,7 @@ class VarExprTreeGenerator : public ExprTreeGenerator {
ExprContext* econtext, ExprContext* econtext,
std::unique_ptr<ExprTreeGenerator>* expr_tree); std::unique_ptr<ExprTreeGenerator>* expr_tree);
bool GenerateCode(gpcodegen::CodegenUtils* codegen_utils, bool GenerateCode(gpcodegen::GpCodegenUtils* codegen_utils,
ExprContext* econtext, ExprContext* econtext,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "codegen/op_expr_tree_generator.h" #include "codegen/op_expr_tree_generator.h"
#include "include/codegen/pg_arith_func_generator.h" #include "include/codegen/pg_arith_func_generator.h"
#include "include/codegen/pg_date_func_generator.h"
#include "llvm/IR/Value.h" #include "llvm/IR/Value.h"
extern "C" { extern "C" {
...@@ -25,7 +26,7 @@ extern "C" { ...@@ -25,7 +26,7 @@ extern "C" {
using gpcodegen::OpExprTreeGenerator; using gpcodegen::OpExprTreeGenerator;
using gpcodegen::ExprTreeGenerator; using gpcodegen::ExprTreeGenerator;
using gpcodegen::CodegenUtils; using gpcodegen::GpCodegenUtils;
using gpcodegen::PGFuncGeneratorInterface; using gpcodegen::PGFuncGeneratorInterface;
using gpcodegen::PGFuncGenerator; using gpcodegen::PGFuncGenerator;
using gpcodegen::CodeGenFuncMap; using gpcodegen::CodeGenFuncMap;
...@@ -59,7 +60,6 @@ void OpExprTreeGenerator::InitializeSupportedFunction() { ...@@ -59,7 +60,6 @@ void OpExprTreeGenerator::InitializeSupportedFunction() {
"int4mi", "int4mi",
&PGArithFuncGenerator<int32_t, int32_t, int32_t>::SubWithOverflow)); &PGArithFuncGenerator<int32_t, int32_t, int32_t>::SubWithOverflow));
supported_function_[216] = std::unique_ptr<PGFuncGeneratorInterface>( supported_function_[216] = std::unique_ptr<PGFuncGeneratorInterface>(
new PGGenericFuncGenerator<float8, float8>( new PGGenericFuncGenerator<float8, float8>(
216, 216,
...@@ -82,6 +82,11 @@ void OpExprTreeGenerator::InitializeSupportedFunction() { ...@@ -82,6 +82,11 @@ void OpExprTreeGenerator::InitializeSupportedFunction() {
new PGIRBuilderFuncGenerator<decltype(&IRBuilder<>::CreateICmpSLE), new PGIRBuilderFuncGenerator<decltype(&IRBuilder<>::CreateICmpSLE),
int32_t, int32_t>(1088, "date_le", &IRBuilder<>::CreateICmpSLE)); int32_t, int32_t>(1088, "date_le", &IRBuilder<>::CreateICmpSLE));
supported_function_[2339] = std::unique_ptr<PGFuncGeneratorInterface>(
new PGGenericFuncGenerator<int32_t, int64_t>(
2339,
"date_le_timestamp",
&PGDateFuncGenerator::DateLETimestamp));
} }
OpExprTreeGenerator::OpExprTreeGenerator( OpExprTreeGenerator::OpExprTreeGenerator(
...@@ -125,8 +130,8 @@ bool OpExprTreeGenerator::VerifyAndCreateExprTree( ...@@ -125,8 +130,8 @@ bool OpExprTreeGenerator::VerifyAndCreateExprTree(
assert(nullptr != argstate); assert(nullptr != argstate);
std::unique_ptr<ExprTreeGenerator> arg(nullptr); std::unique_ptr<ExprTreeGenerator> arg(nullptr);
supported_tree &= ExprTreeGenerator::VerifyAndCreateExprTree(argstate, supported_tree &= ExprTreeGenerator::VerifyAndCreateExprTree(argstate,
econtext, econtext,
&arg); &arg);
if (!supported_tree) { if (!supported_tree) {
break; break;
} }
...@@ -141,7 +146,7 @@ bool OpExprTreeGenerator::VerifyAndCreateExprTree( ...@@ -141,7 +146,7 @@ bool OpExprTreeGenerator::VerifyAndCreateExprTree(
return true; return true;
} }
bool OpExprTreeGenerator::GenerateCode(CodegenUtils* codegen_utils, bool OpExprTreeGenerator::GenerateCode(GpCodegenUtils* codegen_utils,
ExprContext* econtext, ExprContext* econtext,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
......
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2016 Pivotal Software, Inc.
//
// @filename:
// pg_date_func_generator.cc
//
// @doc:
// Base class for date functions to generate code
//
//---------------------------------------------------------------------------
#include "codegen/pg_date_func_generator.h"
#include "codegen/utils/gp_codegen_utils.h"
extern "C" {
#include "postgres.h"
#include "utils/elog.h"
#include "utils/date.h"
#include "utils/timestamp.h"
}
using gpcodegen::GpCodegenUtils;
using gpcodegen::PGDateFuncGenerator;
bool PGDateFuncGenerator::DateLETimestamp(
gpcodegen::GpCodegenUtils* 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::IRBuilder<>* irb = codegen_utils->ir_builder();
llvm::Value* llvm_arg0_DateADT = codegen_utils->
CreateCast<DateADT>(llvm_args[0]);
/* TODO: Use CreateCast*/
llvm::Value* llvm_arg1_Timestamp = irb->CreateSExt(
llvm_args[1], codegen_utils->GetType<Timestamp>());
llvm::Value* llvm_arg0_Timestamp = GenerateDate2Timestamp(
codegen_utils, llvm_main_func, llvm_arg0_DateADT, llvm_error_block);
// timestamp_cmp_internal {{{
#ifdef HAVE_INT64_TIMESTAMP
*llvm_out_value = irb->CreateICmpSLE(llvm_arg0_Timestamp, llvm_arg1_Timestamp);
#else
// TODO: We do not support NaNs.
elog(DEBUG1,"Timestamp != int_64: NaNs are not supported.");
return false;
#endif
// }}}
return true;
}
llvm::Value* PGDateFuncGenerator::GenerateDate2Timestamp(
GpCodegenUtils* codegen_utils,
llvm::Function* llvm_main_func,
llvm::Value* llvm_arg,
llvm::BasicBlock* llvm_error_block) {
assert(nullptr != llvm_arg && nullptr != llvm_arg->getType());
llvm::IRBuilder<>* irb = codegen_utils->ir_builder();
#ifdef HAVE_INT64_TIMESTAMP
llvm::BasicBlock* llvm_non_overflow_block = codegen_utils->CreateBasicBlock(
"date_non_overflow_block", llvm_main_func);
llvm::BasicBlock* llvm_overflow_block = codegen_utils->CreateBasicBlock(
"date_overflow_block", llvm_main_func);
llvm::Value *llvm_USECS_PER_DAY = codegen_utils->
GetConstant<int64_t>(USECS_PER_DAY);
/* TODO: Use CreateCast*/
llvm::Value* llvm_arg_64 = irb->CreateSExt(
llvm_arg, codegen_utils->GetType<int64_t>());
llvm::Value* llvm_mul_output = codegen_utils->CreateMulOverflow<int64_t>(
llvm_USECS_PER_DAY, llvm_arg_64);
llvm::Value* llvm_overflow_flag = irb->CreateExtractValue(llvm_mul_output, 1);
irb->CreateCondBr(llvm_overflow_flag, llvm_overflow_block, llvm_non_overflow_block);
irb->SetInsertPoint(llvm_overflow_block);
codegen_utils->CreateElog(ERROR, "date out of range for timestamp");
irb->CreateBr(llvm_error_block);
irb->SetInsertPoint(llvm_non_overflow_block);
return irb->CreateExtractValue(llvm_mul_output, 0);
#else
llvm::Value *llvm_SECS_PER_DAY = codegen_utils->
GetConstant<int64_t>(SECS_PER_DAY);
/*TODO: Use CreateCast*/
llvm::Value *llvm_arg_64 = irb->CreateSExt(llvm_arg,
codegen_utils->GetType<int64_t>());
return irb->CreateMul(llvm_arg_64, llvm_SECS_PER_DAY);
#endif
}
...@@ -23,7 +23,7 @@ extern "C" { ...@@ -23,7 +23,7 @@ extern "C" {
using gpcodegen::VarExprTreeGenerator; using gpcodegen::VarExprTreeGenerator;
using gpcodegen::ExprTreeGenerator; using gpcodegen::ExprTreeGenerator;
using gpcodegen::CodegenUtils; using gpcodegen::GpCodegenUtils;
bool VarExprTreeGenerator::VerifyAndCreateExprTree( bool VarExprTreeGenerator::VerifyAndCreateExprTree(
ExprState* expr_state, ExprState* expr_state,
...@@ -41,7 +41,7 @@ VarExprTreeGenerator::VarExprTreeGenerator(ExprState* expr_state) : ...@@ -41,7 +41,7 @@ VarExprTreeGenerator::VarExprTreeGenerator(ExprState* expr_state) :
ExprTreeGenerator(expr_state, ExprTreeNodeType::kVar) { ExprTreeGenerator(expr_state, ExprTreeNodeType::kVar) {
} }
bool VarExprTreeGenerator::GenerateCode(CodegenUtils* codegen_utils, bool VarExprTreeGenerator::GenerateCode(GpCodegenUtils* codegen_utils,
ExprContext* econtext, ExprContext* econtext,
llvm::Function* llvm_main_func, llvm::Function* llvm_main_func,
llvm::BasicBlock* llvm_error_block, llvm::BasicBlock* llvm_error_block,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册