提交 c8125736 编写于 作者: K Karthikeyan Jambu Rajaraman 提交者: Shreedhar Hardikar

Introduce guc to enable/disable all generator.

Introduce CodegenConfig to expose api for enabling/disabling generator
using guc. Gucs for exec_variable_list, expression eval, advance aggregate and slot_getattr
are added.
Signed-off-by: NFoyzur Rahman <foyzur@gmail.com>

Update comments for codegen enroll
上级 e47f04f0
......@@ -16,6 +16,7 @@
#include <string>
#include <type_traits>
#include "codegen/codegen_config.h"
#include "codegen/base_codegen.h"
#include "codegen/codegen_manager.h"
#include "codegen/exec_eval_expr_codegen.h"
......@@ -37,9 +38,6 @@ using gpcodegen::AdvanceAggregatesCodegen;
// Current code generator manager that oversees all code generators
static void* ActiveCodeGeneratorManager = nullptr;
extern bool codegen; // defined from guc
extern bool init_codegen; // defined from guc
// Perform global set-up tasks for code generation. Returns 0 on
// success, nonzero on error.
unsigned int InitCodegen() {
......@@ -104,51 +102,20 @@ void SetActiveCodeGeneratorManager(void* manager) {
ActiveCodeGeneratorManager = manager;
}
/**
* @brief Template function to facilitate enroll for any type of
* codegen
*
* @tparam ClassType Type of Code Generator class
* @tparam FuncType Type of the regular function
* @tparam Args Variable argument that ClassType will take in its constructor
*
* @param regular_func_ptr Regular version of the target function.
* @param ptr_to_chosen_func_ptr Reference to the function pointer that the caller will call.
* @param args Variable length argument for ClassType
*
* @return Pointer to ClassType
**/
template <typename ClassType, typename FuncType, typename ...Args>
ClassType* CodegenEnroll(FuncType regular_func_ptr,
FuncType* ptr_to_chosen_func_ptr,
Args&&... args) { // NOLINT(build/c++11)
CodegenManager* manager = static_cast<CodegenManager*>(
GetActiveCodeGeneratorManager());
if (nullptr == manager ||
!codegen) { // if codegen guc is false
BaseCodegen<FuncType>::SetToRegular(
regular_func_ptr, ptr_to_chosen_func_ptr);
return nullptr;
}
ClassType* generator = new ClassType(
manager,
regular_func_ptr,
ptr_to_chosen_func_ptr,
std::forward<Args>(args)...);
bool is_enrolled = manager->EnrollCodeGenerator(
CodegenFuncLifespan_Parameter_Invariant, generator);
assert(is_enrolled);
return generator;
}
void* ExecVariableListCodegenEnroll(
ExecVariableListFn regular_func_ptr,
ExecVariableListFn* ptr_to_chosen_func_ptr,
ProjectionInfo* proj_info,
TupleTableSlot* slot) {
ExecVariableListCodegen* generator = CodegenEnroll<ExecVariableListCodegen>(
regular_func_ptr, ptr_to_chosen_func_ptr, proj_info, slot);
CodegenManager* manager = static_cast<CodegenManager*>(
GetActiveCodeGeneratorManager());
ExecVariableListCodegen* generator =
CodegenManager::CreateAndEnrollGenerator<ExecVariableListCodegen>(
manager,
regular_func_ptr,
ptr_to_chosen_func_ptr,
proj_info,
slot);
return generator;
}
......@@ -158,12 +125,16 @@ void* ExecEvalExprCodegenEnroll(
ExprState *exprstate,
ExprContext *econtext,
PlanState* plan_state) {
ExecEvalExprCodegen* generator = CodegenEnroll<ExecEvalExprCodegen>(
regular_func_ptr,
ptr_to_chosen_func_ptr,
exprstate,
econtext,
plan_state);
CodegenManager* manager = static_cast<CodegenManager*>(
GetActiveCodeGeneratorManager());
ExecEvalExprCodegen* generator =
CodegenManager::CreateAndEnrollGenerator<ExecEvalExprCodegen>(
manager,
regular_func_ptr,
ptr_to_chosen_func_ptr,
exprstate,
econtext,
plan_state);
return generator;
}
......@@ -171,8 +142,14 @@ void* AdvanceAggregatesCodegenEnroll(
AdvanceAggregatesFn regular_func_ptr,
AdvanceAggregatesFn* ptr_to_chosen_func_ptr,
AggState *aggstate) {
AdvanceAggregatesCodegen* generator = CodegenEnroll<AdvanceAggregatesCodegen>(
regular_func_ptr, ptr_to_chosen_func_ptr, aggstate);
CodegenManager* manager = static_cast<CodegenManager*>(
GetActiveCodeGeneratorManager());
AdvanceAggregatesCodegen* generator =
CodegenManager::CreateAndEnrollGenerator<AdvanceAggregatesCodegen>(
manager,
regular_func_ptr,
ptr_to_chosen_func_ptr,
aggstate);
return generator;
}
......@@ -19,13 +19,12 @@ extern "C" {
#include <string>
#include <vector>
#include "codegen/utils/gp_codegen_utils.h"
#include "codegen/codegen_manager.h"
#include "codegen/codegen_config.h"
#include "codegen/codegen_interface.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Verifier.h"
extern bool codegen_validate_functions;
namespace gpcodegen {
......@@ -33,6 +32,9 @@ namespace gpcodegen {
* @{
*/
// Forward declaration
class CodegenManager;
/**
* @brief Base code generator with common implementation that other
* code generators can use.
......
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2016 Pivotal Software, Inc.
//
// @filename:
// codegen_config.h
//
// @doc:
// Configure Class to handle gucs in gpdb
//
//---------------------------------------------------------------------------
#ifndef GPCODEGEN_CODEGEN_CONFIG_H_ // NOLINT(build/header_guard)
#define GPCODEGEN_CODEGEN_CONFIG_H_
extern "C" {
// Variables that are defined in guc
extern bool init_codegen;
extern bool codegen;
extern bool codegen_validate_functions;
extern bool codegen_exec_variable_list;
extern bool codegen_slot_getattr;
extern bool codegen_exec_eval_expr;
extern bool codegen_advance_aggregate;
// TODO(shardikar): Retire this GUC after performing experiments to find the
// tradeoff of codegen-ing slot_getattr() (potentially by measuring the
// difference in the number of instructions) when one of the first few
// attributes is varlen.
extern int codegen_varlen_tolerance;
}
namespace gpcodegen {
/** \addtogroup gpcodegen
* @{
*/
// Forward declaration
class ExecVariableListCodegen;
class SlotGetAttrCodegen;
class ExecEvalExprCodegen;
class AdvanceAggregatesCodegen;
class CodegenConfig {
public:
/**
* @brief Template function to check if generator enabled.
*
* @tparam ClassType Type of Code Generator class
*
* @return true if respective generator is enabled with gpdb guc.
**/
template <class ClassType>
inline static bool IsGeneratorEnabled();
};
template<>
inline bool CodegenConfig::IsGeneratorEnabled<ExecVariableListCodegen>() {
return codegen_exec_variable_list;
}
template<>
inline bool CodegenConfig::IsGeneratorEnabled<SlotGetAttrCodegen>() {
return codegen_slot_getattr;
}
template<>
inline bool CodegenConfig::IsGeneratorEnabled<ExecEvalExprCodegen>() {
return codegen_exec_eval_expr;
}
template<>
inline bool CodegenConfig::IsGeneratorEnabled<AdvanceAggregatesCodegen>() {
return codegen_advance_aggregate;
}
/** @} */
} // namespace gpcodegen
#endif // GPCODEGEN_CODEGEN_CONFIG_H_
......@@ -18,7 +18,9 @@
#include <string>
#include "codegen/utils/macros.h"
#include "codegen/codegen_wrapper.h"
#include "codegen/codegen_config.h"
#include "codegen/codegen_interface.h"
#include "codegen/base_codegen.h"
namespace gpcodegen {
/** \addtogroup gpcodegen
......@@ -46,6 +48,67 @@ class CodegenManager {
~CodegenManager() = default;
/**
* @brief Template function to facilitate enroll for any type of
* CodegenInterface that CodegenManager wants to keep track of.
*
* @tparam ClassType Type of Code Generator class that derives from
* CodegenInterface.
* @tparam FuncType Type of the function pointer that CodegenManager swaps.
* @tparam Args Variable argument that ClassType will take in its constructor
*
* @param manager Current Codegen Manager
* @param regular_func_ptr Regular version of the target function.
* @param ptr_to_chosen_func_ptr Pointer to the function pointer that the
* caller will call.
* @param args Variable length argument for ClassType
*
* This function creates a new code generator object of type ClassType using
* the passed-in args, and enrolls it in the given codegen manager.
*
* It does not create a generator when codegen or manager is unset, or the
* code generator ClassType is disabled (with the appropriate GUC).
* It always initializes the given double function pointer
* (ptr_to_chosen_func_ptr) to the regular_func_ptr.
*
* This transfers the ownership of the code generator to the manager.
*
* @return Pointer to ClassType
**/
template <typename ClassType, typename FuncType, typename ...Args>
static ClassType* CreateAndEnrollGenerator(
CodegenManager* manager,
FuncType regular_func_ptr,
FuncType* ptr_to_chosen_func_ptr,
Args&&... args) { // NOLINT(build/c++11)
assert(nullptr != regular_func_ptr);
assert(nullptr != ptr_to_chosen_func_ptr);
bool can_enroll =
// manager may be NULL if ExecInitNode/ExecProcNode weren't previously
// called. This happens e.g during gpinitsystem.
(nullptr != manager) &&
codegen && // if codegen guc is false
// if generator is disabled
CodegenConfig::IsGeneratorEnabled<ClassType>();
if (!can_enroll) {
gpcodegen::BaseCodegen<FuncType>::SetToRegular(
regular_func_ptr, ptr_to_chosen_func_ptr);
return nullptr;
}
ClassType* generator = new ClassType(
manager,
regular_func_ptr,
ptr_to_chosen_func_ptr,
std::forward<Args>(args)...);
bool is_enrolled = manager->EnrollCodeGenerator(
CodegenFuncLifespan_Parameter_Invariant, generator);
assert(is_enrolled);
return generator;
}
/**
* @brief Enroll a code generator with manager
*
......
......@@ -15,6 +15,8 @@
#include "codegen/base_codegen.h"
#include "codegen/codegen_wrapper.h"
#include "codegen/codegen_config.h"
#include "codegen/codegen_manager.h"
#include "codegen/slot_getattr_codegen.h"
#include "codegen/utils/gp_codegen_utils.h"
#include "codegen/utils/utility.h"
......@@ -50,12 +52,6 @@ using gpcodegen::SlotGetAttrCodegen;
constexpr char SlotGetAttrCodegen::kSlotGetAttrPrefix[];
// TODO(shardikar): Retire this GUC after performing experiments to find the
// tradeoff of codegen-ing slot_getattr() (potentially by measuring the
// difference in the number of instructions) when one of the first few
// attributes is varlen.
extern const int codegen_varlen_tolerance;
std::unordered_map<
gpcodegen::CodegenManager*, SlotGetAttrCodegen::SlotGetAttrCodegenCache>
SlotGetAttrCodegen::codegen_cache_by_manager;
......@@ -65,6 +61,13 @@ SlotGetAttrCodegen* SlotGetAttrCodegen::GetCodegenInstance(
TupleTableSlot *slot,
int max_attr) {
// TODO(krajaraman, frahman) : Refactor so creation happens through
// CodegenManager::CreateAndEnrollGenerator. In that case, we don't
// need to do this `if` condition here.
if (!CodegenConfig::IsGeneratorEnabled<SlotGetAttrCodegen>()) {
return nullptr;
}
// Create an cache entry for this manager if it doesn't already exist
auto it = codegen_cache_by_manager[manager].find(slot);
......@@ -74,6 +77,8 @@ SlotGetAttrCodegen* SlotGetAttrCodegen::GetCodegenInstance(
generator = it->second;
generator->max_attr_ = std::max(generator->max_attr_, max_attr);
} else {
// TODO(krajaraman, frahman) : Refactor so creation happens through
// CodegenManager::CreateAndEnrollGenerator.
// For a slot we haven't see before, create and add a new object
generator = new SlotGetAttrCodegen(manager, slot, max_attr);
codegen_cache_by_manager[manager].insert(std::make_pair(slot, generator));
......
......@@ -577,6 +577,10 @@ bool optimizer_array_constraints;
bool init_codegen;
bool codegen;
bool codegen_validate_functions;
bool codegen_exec_variable_list;
bool codegen_slot_getattr;
bool codegen_exec_eval_expr;
bool codegen_advance_aggregate;
int codegen_varlen_tolerance;
int codegen_optimization_level;
static char *codegen_optimization_level_str = NULL;
......@@ -3335,7 +3339,12 @@ struct config_bool ConfigureNamesBool_gp[] =
GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_GPDB_ADDOPT
},
&codegen,
false, assign_codegen, NULL
#ifdef USE_CODEGEN
true,
#else
false,
#endif
assign_codegen, NULL
},
{
......@@ -3349,6 +3358,62 @@ struct config_bool ConfigureNamesBool_gp[] =
true, /* true by default on debug builds. */
#else
false,
#endif
assign_codegen, NULL
},
{
{"codegen_exec_variable_list", PGC_USERSET, DEVELOPER_OPTIONS,
gettext_noop("Enable codegen for ExecVariableList"),
NULL,
GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_GPDB_ADDOPT
},
&codegen_exec_variable_list,
#ifdef USE_CODEGEN
true,
#else
false,
#endif
assign_codegen, NULL
},
{
{"codegen_slot_getattr", PGC_USERSET, DEVELOPER_OPTIONS,
gettext_noop("Enable codegen for slot_get_attr"),
NULL,
GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_GPDB_ADDOPT
},
&codegen_slot_getattr,
#ifdef USE_CODEGEN
true,
#else
false,
#endif
assign_codegen, NULL
},
{
{"codegen_exec_eval_expr", PGC_USERSET, DEVELOPER_OPTIONS,
gettext_noop("Enable codegen for ExecEvalExpr"),
NULL,
GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_GPDB_ADDOPT
},
&codegen_exec_eval_expr,
#ifdef USE_CODEGEN
true,
#else
false,
#endif
assign_codegen, NULL
},
{
{"codegen_advance_aggregate", PGC_USERSET, DEVELOPER_OPTIONS,
gettext_noop("Enable codegen for AdvanceAggregate"),
NULL,
GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_GPDB_ADDOPT
},
&codegen_advance_aggregate,
#ifdef USE_CODEGEN
true,
#else
false,
#endif
assign_codegen, NULL
},
......@@ -4734,7 +4799,12 @@ struct config_int ConfigureNamesInt_gp[] =
GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_GPDB_ADDOPT
},
&codegen_varlen_tolerance,
5, 0, INT_MAX, NULL, NULL
#ifdef USE_CODEGEN
5,
#else
0,
#endif
0, INT_MAX, NULL, NULL
},
/* End-of-list marker */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册