Files
openGauss-server/src/include/codegen/vecexprcodegen.h
2022-03-04 23:22:16 +08:00

471 lines
20 KiB
C++

/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* ---------------------------------------------------------------------------------------
*
* vecexprcodegen.h
* Declarations of code generation for vecexpression funtions.
*
* For each expression, first decide if this expression can be LLVM optimized
* or not according to the detail information. The expression functions
* accomplished here have the same functionality as the ones defined in
* vecexpression.h, though more constraints are used.
*
* IDENTIFICATION
* src/include/codegen/vecexprcodegen.h
*
* ---------------------------------------------------------------------------------------
*/
#ifndef LLVM_VECEXPRESSION_H
#define LLVM_VECEXPRESSION_H
#include "optimizer/clauses.h"
#include "nodes/execnodes.h"
#include "codegen/gscodegen.h"
namespace dorado {
#ifdef ENABLE_LLVM_COMPILE
/*
* @Description : Arguments used for Vectorized Expression CodeGen Engine.
*/
typedef struct {
ExprState* exprstate; /* Expression information used to
generate IR function */
PlanState* parent; /* The parent planstate information */
GsCodeGen::LlvmBuilder* builder; /* LLVM builder in upper level */
llvm::Value** llvm_args; /* LLVM parameters*/
} ExprCodeGenArgs;
/*
* @Description : Parameters needed to pass to the original c-function.
*/
typedef struct {
int nargs; /* number of args */
llvm::Value** args; /* values of parameters with length nargs */
llvm::Value** argnulls; /* flags of parameters with length nargs */
} LLVMFuncCallInfo;
typedef llvm::Value* (*VectorExprCodeGen)(ExprCodeGenArgs* args);
/*
* LlvmExecQual class implements specific optimization by using LLVM.
*/
class VecExprCodeGen : public BaseObject {
public:
/*
* @Brief : Check whether state could be legal or not.
* @Description : Check is the current state->expr could be codegened
* or not.
* @in state : exprstate, the node to be checked.
* @return : return true is state could be codegened.
*/
static bool ExprJittable(ExprState* state);
/*
* The following functions are codegen functions and their guardian function:
* Since each expression has its own restricts, we should consider them
* independently. For each expression, we have one guardian function and
* one codegen function.
*/
/*
* @Brief : Check if the whole qual list can be codegened or not.
* @Description : Check if the qual list can be codegened or not. The qual
* list can be joinqual, hashjoin_clauses and so on.
* @in qual : the expr node list need to be checked.
* @return : return true if the whole qual can be codegened.
*/
static bool QualJittable(List* qual);
/*
* @Brief : Code generation for ExecEvalQual.
* @Description : Since ExprState stored the plan-tree information, ExprContext
* stored the actual data information during execution. We need
* to separate these two parameters in 'InitNode' and 'ExecNode'
* status. So during expression processes, we should pass through
* 'Expr' as parameter in 'InitNode' and pass through 'econtext'
* as LLVM parameter in 'ExecNode'.
* @in qual : the expr node list need to be codegened.
* @in parent : the whole planstate of the expr node.
* @return : ScalarVector result of the qual list in LLVM assemble.
* @notes : firstly, econtext is passed when qual is needed; secondly, for
* each LLVM function in ExecVecQual, the interface is
* LLVM_Expr_Func(ExprCodeGenArgs);
*/
static llvm::Function* QualCodeGen(List* qual, PlanState* parent, bool isReset = true);
/*
* @Description : Check if the scalararrayop expr can be codegened or not.
* @in state : ExprState of ScalarArrayOpExpr.
* @return : return true if scalararrayop expr can be codegened.
*/
static bool ScalarArrayJittable(ExprState* state);
/*
* @Brief : Codegen for scalararrayop expression.
* @Description : Codegeneration of the ExecEvalVecScalarArrayOp:
* For integer/float/date/timestamp, we use switch
* structure in LLVM, for bpchar/varchar/text, we use
* codegen function.
* @in args : arguments of vector expr codegen engine.
* @return : return true when tuple satisfies the condition
* @Notes : Support ...in (...) and any(array[....]) only.
*/
static llvm::Value* ScalarArrayCodeGen(ExprCodeGenArgs* args);
/*
* @Description : Check if the boolean test expr can be codegened or not.
* @in state : ExprState of BooleanTest Expr.
* @Output : return true if boolean test expr can be codegened.
*/
static bool BooleanTestJittable(ExprState* state);
/*
* @Brief : Codegen for boolean test expression.
* @Description : Codegeneration of the ExecEvalBooleanTest.
* @in args : arguments of vector expr codegen engine.
* @return : return the result of Boolean Test Expr.
*/
static llvm::Value* BooleanTestCodeGen(ExprCodeGenArgs* args);
/*
* @Description : Check if the null test expr can be codegened or not.
*
* @in state : NullTest ExprState.
* @return : return true if nulltest expr can be codegened.
*/
static bool NullTestJittable(ExprState* state);
/*
* @Brief : Codegen for NullTest expression.
* @Description : Codegeneration of the ExecEvalNullTest: contains
* IS_NULL, IS_NOT_NULL.
* @in args : arguments of vector expr codegen engine.
* @return : return true only if argument is nulll, else return false.
*/
static llvm::Value* NullTestCodeGen(ExprCodeGenArgs* args);
/*
* @Brief : Check if the oper func can be codegened or not.
* @Description : Check if the FuncExprState can be codegened or not :
* right now most of the oper expr can be codegened, but
* some of them still have some constraints.
* @in state : ExprState representation of FuncExprSate.
* @return : return true if the operation function can be codegened.
*/
static bool OpJittable(ExprState* state);
/*
* @Brief : Check if the oper func with numeric data can be codegened in special path.
* @Description : Check if the Numeric OperExpr can be codegened in a special way:
* the data we considered here are all can be represented in BI64.
* @in state : ExprState representation of OperExprSate.
* @return : return true if the operation function can be codegened in fast path.
*/
static bool NumericOpFastJittable(ExprState* state);
/*
* @Brief : Codegen for vecoper expression.
* @Description : Codegeneration of the ExecEvalVecOp: Right row
* we only support several cases with data type
* int/float/date/timestamp and text(eq,gt)/bpchar(eq)
* @in args : arguments of vector expr codegen engine.
* @return : return the result of oper expr in LLVM assemble.
* @Notes : Since we have not codegen ExecMakeVecFunctionResult
* as we do in vecexpression.cpp, only seveal cases
* are supported.
*/
static llvm::Value* OpCodeGen(ExprCodeGenArgs* args);
/*
* @Brief : Codegen for numeric type operation expression.
* @Description : Codegeneration for numeric operation expression: we make a special
* path for data that can be transformed to BI64. While for other cases,
* we use normal codegen path(NormalNumericOpCodeGen).
* @in ptrbuilder : LLVM Builder associated with the current module.
* @in estate : opexprstate associated with current operation.
* @in funcoid : function oid of current numeric operation.
* @in larg : left argument passed to llvm.
* @in rarg : right argument passed to llvm.
*/
static llvm::Value* FastNumericOpCodeGen(
GsCodeGen::LlvmBuilder* ptrbuilder, ExprState* estate, llvm::Value* larg, llvm::Value* rarg);
static llvm::Value* NormalNumericOpCodeGen(
GsCodeGen::LlvmBuilder* ptrbuilder, Oid funcoid, llvm::Value* larg, llvm::Value* rarg);
/*
* @Brief : Check if the FuncExpr can be codegened or not.
* @Description : Check if the FuncExprState can be codegened or not :
* right now most of the func expr can be codegened, but
* some of them still have some constraints.
* @in state : ExprState representation of FuncExprSate.
* @return : return true if the func can be codegen.
* @Notes : We only support C / UTF-8 encoding.
*/
static bool FuncJittable(ExprState* state);
/*
* @Brief : Codegen for vecfunc expression.
* @Description : Codegeneration of the ExecEvalVecFunc: Only part of them
* have been codegened, the rest would be used by
* call original C-Function.
* @in args : arguments of vector expr codegen engine.
* @return : result of ExecEvalFunc in LLVM assemble.
* @Notes : We only support C / UTF-8 encoding.
*/
static llvm::Value* FuncCodeGen(ExprCodeGenArgs* args);
/*
* @Brief : Check if veccase expression can be codegened or not.
* @Description : Codegeneration of the ExecEvalVecCase: The logic here
* is the same as ExecEvalVecCase. Since operation is only
* partly supported, the exprs in case arg/when expr/default
* expr are the ones supported by OpCodeGen.
* @in state : context of CaseExprState
* @return : return true if veccase expr can be codegened.
*/
static bool CaseJittable(ExprState* state);
/*
* @Brief : Codegen for veccase expression.
* @Description : Codegeneration of the ExecEvalVecCase: The logic here
* is the same as ExecEvalVecCase. Since operation is only
* partly supported, the exprs in case arg/when expr/default
* expr are the ones supported by OpCodeGen.
* @in args : arguments of vector expr codegen engine.
* @return : wclause->result or default->result in LLVM assemble.
*/
static llvm::Value* CaseCodeGen(ExprCodeGenArgs* args);
/*
* @Brief : Check if nullif expression can be codegened or not.
* @Description : Codegeneration of the ExecEvalVecNullif checking.
* @in state : ExprState
* @return : return true if nullif expr can be codegened.
*/
static bool NullIfJittable(ExprState* state);
/*
* Brief : Codegen for nullif expression.
* Description : NullIfCodeGen is the codegeneration of the ExecEvalVecNullIf.
* Input : ExprCodeGenArgs
* Output : when expr1=expr2 return null, else return expr1.
* Notes : None.
*/
static llvm::Value* NullIfCodeGen(ExprCodeGenArgs* args);
/*
* @Brief : Check if and/or/not expr can be codegened or not.
* @Description : Check if the bool expr can be codegened or not. The
* expr type contatins and, or and not expr. While
* and/or expression and not expression should be
* considered independently.
* @in state : the context of bool expr state
* @return : return true the expr in state can be codegened.
*/
static bool BoolJittable(ExprState* state);
/*
* @Brief : Codegen for vector and/or expression.
* @Description : Codegeneration of the ExecEvalProcessAndOrLogic: The
* logic here is the same as ExecEvalProcessAndOrLogic.
* BoolJittable would check and/or/not expression argument,
* but and/or expression and not expression would be
* considered independently.
* @in args : arguments of vector expr codegen engine.
* @return : the and/or expr's result in LLVM assemble.
*/
static llvm::Value* AndOrLogicCodeGen(ExprCodeGenArgs* args);
/*
* @Brief : Codegen for vector not expression.
* @Description : Codegeneration of the ExecEvalVecNot.
* @in args : arguments of vector expr codegen engine.
* @return : the not expr's result in LLVM assemble.
*/
static llvm::Value* NotCodeGen(ExprCodeGenArgs* args);
/*
* @Brief : Check if vecrelabel expr can be codegened or not.
* @Description : Check if the relabel expr in genericexprstate can be
* : codegened or not. Only support the case when arg
* : is a var or casetestexpr.
* @in state : context of relabel expr.
* @return : return true if relabel expr can be codegened.
*/
static bool RelabelJittable(ExprState* state);
/*
* @Brief : Codegen for vecrelabel expression.
* @Description : Codegeneration of the ExecEvalVecRelabelType:
* Support the case when arg is a var or casetestexpr.
* @in args : arguments of vector expr codegen engine.
* @return : result of relabel expr in LLVM assemble
*/
static llvm::Value* RelabelCodeGen(ExprCodeGenArgs* args);
/*
* @Brief : Check if the var expr can be codegened or not.
* @Description : Check if the Var in state can be codegened or not,
* : only need to consider the var type.
* @in state : context of Var Expr State
* @return : return true if const expr can be codegened.
*/
static bool VarJittable(ExprState* state);
/*
* @Brief : Codegen for evalvar expr.
* @Description : Codegeneration of the ExecEvalVecVar : Get the
* values from econtext->vectorbatch with fixed
* column index and row index(loop_index). Also we
* should restore the null flag.
* @in args : arguments of vector expr codegen engine.
* @out isNull : null flag of batch->m_arr[varattno-1]
* @return : return true if const expr can be codegened.
*/
static llvm::Value* VarCodeGen(ExprCodeGenArgs* args);
/*
* @Brief : Codegen for vecconst expression.
* @Description : Check is const expr could be codegened or not.
* @in state : const expr state.
* @return : return true if const expr can be codegened.
*/
static bool ConstJittable(ExprState* state);
/*
* @Brief : Codegen for vecconst expression.
* @Description : Codegeneration of the ExecEvalVecConst
* @in args : arguments of vector expr codegen engine.
* @return : the value in const expr.
*/
static llvm::Value* ConstCodeGen(ExprCodeGenArgs* args);
/*
* @Brief : Check if the targetlist could be codegened or not.
* @Description : Check the jittable of the ExecVecTargetList, which
* : evaluates a targetlist with respect to the given
* : expression context in LLVM assemble.
* @in targetlist : the expr node list need to be checked.
* @return : return true if we were able to codegen the list.
*/
static bool TargetListJittable(List* targetlist);
/*
* @Brief : Codegen for TargetList expression.
* @Description : Codegeneration of the ExecVecTargetList, which
* : evaluates a targetlist with respect to the given
* : expression context in LLVM assemble.
* @in targetlist : the expr node list need to be codegened.
* @in parent : PlanState of the whole targetlist.
* @return : LLVM function of targetlist expr.
*/
static llvm::Function* TargetListCodeGen(List* targetlist, PlanState* parent);
/*
* @Description : CodeGen routine for Expression.
* @in args : arguments of vector expr codegen engine.
* @return : the result of current args->exprstate.
*/
static llvm::Value* CodeGen(ExprCodeGenArgs* args);
/*
* @Brief : CodeGen for general function call.
* @Description : For functions we do not codegened, invoke these
* function in LLVM assemble, and reduce the logical
* branches in dealing with arguments and return vals
* by using LLVM optimization.
* @in ptrbuilder : LLVM Builder associated with the current module.
* @in fcache : The function expr dealed with.
* @in isNull : used to record the null flag of the return value.
* @in lfcinfo : arguments about fcache.
*
*/
static llvm::Value* EvalFuncResultCodeGen(
GsCodeGen::LlvmBuilder* ptrbuilder, FuncExprState* fcache, llvm::Value* isNull, LLVMFuncCallInfo* lfcinfo);
/*
* @Brief : Make sure the ExtractFunc according the datum type.
* @Description : Wrap all the Extract Func in LLVM assemble, which could
* : easily deal with input argument according the different
* : datum type.
* @in ptrbuilder : LLVM Builder associated with the current module.
* @in argtyp : input argument datum type.type
* @in data : input data
* @return : the result after extraction.
*/
static llvm::Value* WrapChooExtFunCodeGen(GsCodeGen::LlvmBuilder* ptrbuilder, Oid argtyp, llvm::Value* argval);
static llvm::Value* WrapExtFixedTypeCodeGen(GsCodeGen::LlvmBuilder* ptrbuilder, llvm::Value* data);
static llvm::Value* WrapExtAddrTypeCodeGen(GsCodeGen::LlvmBuilder* ptrbuilder, llvm::Value* data);
static llvm::Value* WrapExtCStrTypeCodeGen(GsCodeGen::LlvmBuilder* ptrbuilder, llvm::Value* data);
static llvm::Value* WrapExtVarTypeCodeGen(GsCodeGen::LlvmBuilder* ptrbuilder, llvm::Value* data);
/*
* @Brief : Wrap Datum to Scalar Func according the datum type.
* @Description : Wrap all the Convert Func in LLVM assemble.
* @in ptrbuilder : LLVM Builder associated with the current module.
* @in val : input data argument.
* @in len : the argument data len with respect to datum type.
* @return : the result after conversation.
*/
static llvm::Value* WrapDFixLToScalCodeGen(GsCodeGen::LlvmBuilder* ptrbuilder, llvm::Value* val, llvm::Value* len);
static llvm::Value* WrapDCStrToScalCodeGen(GsCodeGen::LlvmBuilder* ptrbuilder, llvm::Value* val);
/*
* @Description : Wrap the c-function : GetVectorBatch, which is used to
* get the vectorbatch during vectargetlist-codegeneration.
* @in ptrbuilder : LLVM Builder associated with the current module.
* @in econtext : exprcontext in LLVM assemble.
*/
static llvm::Value* WrapGetVectorBatchCodeGen(GsCodeGen::LlvmBuilder* ptrbuilder, llvm::Value* econtext);
/*
* @Brief : Wrap the Invoke function.
* @Description : Codegen the interface, used to call the original
* : C-Function - FunctionCallInvoke, only consider strict
* : function, where we do not consider the flag of args.
* @in ptrbuilder : LLVM Builder associated with the current module.
* @in fcinfo : data with FunctionCallInfo type in LLVM assemble.
* @in arg : array of arguments, contain the arguments of fcinfo
* : and the flag of the result.
*/
static llvm::Value* WrapStrictOpFuncCodeGen(
GsCodeGen::LlvmBuilder* ptrbuilder, llvm::Value* fcinfo, llvm::Value* arg, llvm::Value* isNull);
/*
* @Brief : Wrap the Invoke function.
* @Description : Codegen the interface, used to call the original
* : C-Function - FunctionCallInvoke, only consider non-strict
* : function.
* @in ptrbuilder : LLVM Builder associated with the current module.
* @in fcinfo : data with FunctionCallInfo type in LLVM assemble.
* @in arg : array of arguments, contain the arguments of fcinfo
* : and the flag of the result.
* @in argnull : the flag of the input args.
* @in isNull : the flag of the result.
*/
static llvm::Value* WrapNonStrictOpFuncCodeGen(GsCodeGen::LlvmBuilder* ptrbuilder, llvm::Value* fcinfo,
llvm::Value* arg, llvm::Value* argnull, llvm::Value* isNull);
/*
* @Brief : Wrap the Invoke function.
* @Description : Codegen the interface, used to call the original
* : C-Function - MemoryContextSwitchTo.
* @in ptrbuilder : LLVM Builder associated with the current module.
* @in context : MemoryContext that we want to access.
*/
static llvm::Value* MemCxtSwitToCodeGen(GsCodeGen::LlvmBuilder* ptrbuilder, llvm::Value* context);
};
#endif
} // namespace dorado
#endif