提交 f160fa5a 编写于 作者: S Shreedhar Hardikar

Add new GUC to control Codegen Optimization level.

Used when compiling generated code. EXPLAIN codegen also
runs optimize with this optimize level, making it easier to see
the features the compiler optimizes.
上级 f525cd66
......@@ -23,6 +23,11 @@
#include "codegen/utils/codegen_utils.h"
#include "codegen/utils/gp_codegen_utils.h"
extern "C" {
#include "postgres.h" // NOLINT(build/include)
#include "utils/guc.h"
}
using gpcodegen::CodegenManager;
CodegenManager::CodegenManager(const std::string& module_name) {
......@@ -63,10 +68,19 @@ unsigned int CodegenManager::PrepareGeneratedFunctions() {
return success_count;
}
STATIC_ASSERT_OPTIMIZATION_LEVEL(kNone,
CODEGEN_OPTIMIZATION_LEVEL_NONE);
STATIC_ASSERT_OPTIMIZATION_LEVEL(kLess,
CODEGEN_OPTIMIZATION_LEVEL_LESS);
STATIC_ASSERT_OPTIMIZATION_LEVEL(kDefault,
CODEGEN_OPTIMIZATION_LEVEL_DEFAULT);
STATIC_ASSERT_OPTIMIZATION_LEVEL(kAggressive,
CODEGEN_OPTIMIZATION_LEVEL_AGGRESSIVE);
// Call GpCodegenUtils to compile entire module
bool compilation_status = codegen_utils_->PrepareForExecution(
gpcodegen::GpCodegenUtils::OptimizationLevel::kDefault, true);
gpcodegen::GpCodegenUtils::OptimizationLevel(codegen_optimization_level),
true);
if (!compilation_status) {
return success_count;
......@@ -99,6 +113,12 @@ const std::string& CodegenManager::GetExplainString() {
void CodegenManager::AccumulateExplainString() {
explain_string_.clear();
// This is called only when EXPLAIN CODEGEN. Because we don't want to compile
// at this time, we need to call CodegenUtils::Optimize to "optimize" LLVM IR.
codegen_utils_->Optimize(gpcodegen::CodegenUtils::OptimizationLevel(
codegen_optimization_level),
gpcodegen::CodegenUtils::SizeLevel::kNormal,
false);
llvm::raw_string_ostream out(explain_string_);
codegen_utils_->PrintUnderlyingModules(out);
}
......@@ -55,6 +55,15 @@ template <typename> class FunctionTypeUnpacker;
template <typename, typename> class ArithOpMaker;
} // namespace codegen_utils_detail
// Easy static check to match integer macros with enum equivalents
#define STATIC_ASSERT_OPTIMIZATION_LEVEL(ename, mname) \
static_assert(gpcodegen::CodegenUtils::OptimizationLevel::ename == \
gpcodegen::CodegenUtils::OptimizationLevel(mname), \
"gpcodegen::CodegenUtils::OptimizationLevel::" #ename \
" == " #mname)
/** \addtogroup gpcodegen
* @{
*/
......
......@@ -86,6 +86,8 @@ static const char *assign_optimizer_minidump(const char *newval,
bool doit, GucSource source);
static bool assign_optimizer(bool newval, bool doit, GucSource source);
static bool assign_codegen(bool newval, bool doit, GucSource source);
static const char *assign_codegen_optimization_level(const char *newval,
bool doit, GucSource source);
static const char *assign_optimizer_cost_model(const char *newval,
bool doit, GucSource source);
static const char *assign_gp_workfile_caching_loglevel(const char *newval,
......@@ -572,7 +574,10 @@ bool optimizer_array_constraints;
bool init_codegen;
bool codegen;
bool codegen_validate_functions;
int codegen_varlen_tolerance;
int codegen_varlen_tolerance;
int codegen_optimization_level;
static char *codegen_optimization_level_str;
/* Security */
bool gp_reject_internal_tcp_conn = true;
......@@ -5453,6 +5458,16 @@ struct config_string ConfigureNamesString_gp[] =
"csv", assign_gp_log_format, NULL
},
{
{"codegen_optimization_level", PGC_USERSET, DEVELOPER_OPTIONS,
gettext_noop("Sets optimizer level to use when compiling generated code."),
gettext_noop("Valid values are none, less, default, aggressive."),
GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_GPDB_ADDOPT
},
&codegen_optimization_level_str,
"default", assign_codegen_optimization_level, NULL
},
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
......@@ -5619,6 +5634,39 @@ assign_optimizer_log_failure(const char *val, bool assign, GucSource source)
return val;
}
static const char*
assign_codegen_optimization_level(const char *val, bool assign, GucSource source) {
#ifndef USE_CODEGEN
if (val)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("Code generation is not supported by this build")));
#endif
if (pg_strcasecmp(val, "none") == 0 && assign)
{
codegen_optimization_level = CODEGEN_OPTIMIZATION_LEVEL_NONE;
}
else if (pg_strcasecmp(val, "less") == 0 && assign)
{
codegen_optimization_level = CODEGEN_OPTIMIZATION_LEVEL_LESS;
}
else if (pg_strcasecmp(val, "default") == 0 && assign)
{
codegen_optimization_level = CODEGEN_OPTIMIZATION_LEVEL_DEFAULT;
}
else if (pg_strcasecmp(val, "aggressive") == 0 && assign)
{
codegen_optimization_level = CODEGEN_OPTIMIZATION_LEVEL_AGGRESSIVE;
}
else
{
return NULL; /* fail */
}
return val;
}
static const char *
assign_optimizer_minidump(const char *val, bool assign, GucSource source)
......
......@@ -466,10 +466,16 @@ extern bool optimizer_array_constraints;
/**
* GUCs related to code generation.
**/
#define CODEGEN_OPTIMIZATION_LEVEL_NONE 0
#define CODEGEN_OPTIMIZATION_LEVEL_LESS 1
#define CODEGEN_OPTIMIZATION_LEVEL_DEFAULT 2
#define CODEGEN_OPTIMIZATION_LEVEL_AGGRESSIVE 3
extern bool init_codegen;
extern bool codegen;
extern bool codegen_validate_functions;
extern int codegen_varlen_tolerance;
extern int codegen_optimization_level;
/**
* Enable logging of DPE match in optimizer.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册