Remove unused LLVM related codes of directory (step 3):be/src/exprs (#2910) there are many LLVM related codes in code base, but these codes are not really used. The higher version of GCC is not compatible with the LLVM 3.4.2 version currently used by Doris. The PR delete all LLVM related code of directory: be/src/exprs
This commit is contained in:
@ -17,21 +17,11 @@
|
||||
|
||||
#include "exprs/case_expr.h"
|
||||
|
||||
#include "codegen/llvm_codegen.h"
|
||||
#include "codegen/codegen_anyval.h"
|
||||
#include "exprs/anyval_util.h"
|
||||
#include "runtime/runtime_state.h"
|
||||
#include "gen_cpp/Exprs_types.h"
|
||||
|
||||
using llvm::BasicBlock;
|
||||
using llvm::Constant;
|
||||
using llvm::ConstantInt;
|
||||
using llvm::Function;
|
||||
using llvm::LLVMContext;
|
||||
using llvm::PHINode;
|
||||
using llvm::PointerType;
|
||||
using llvm::Value;
|
||||
|
||||
namespace doris {
|
||||
|
||||
struct CaseExprState {
|
||||
@ -95,208 +85,6 @@ std::string CaseExpr::debug_string() const {
|
||||
return out.str();
|
||||
}
|
||||
|
||||
// Sample IR output when there is a case expression and else expression
|
||||
// define i16 @CaseExpr(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row) #20 {
|
||||
// eval_case_expr:
|
||||
// %case_val = call i64 @GetSlotRef(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row)
|
||||
// %is_null = trunc i64 %case_val to i1
|
||||
// br i1 %is_null, label %return_else_expr, label %eval_first_when_expr
|
||||
//
|
||||
// eval_first_when_expr: ; preds = %eval_case_expr
|
||||
// %when_val = call i64 @Literal(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row)
|
||||
// %is_null1 = trunc i64 %when_val to i1
|
||||
// br i1 %is_null1, label %return_else_expr, label %check_when_expr_block
|
||||
//
|
||||
// check_when_expr_block: ; preds = %eval_first_when_expr
|
||||
// %0 = ashr i64 %when_val, 32
|
||||
// %1 = trunc i64 %0 to i32
|
||||
// %2 = ashr i64 %case_val, 32
|
||||
// %3 = trunc i64 %2 to i32
|
||||
// %eq = icmp eq i32 %3, %1
|
||||
// br i1 %eq, label %return_then_expr, label %return_else_expr
|
||||
//
|
||||
// return_then_expr: ; preds = %check_when_expr_block
|
||||
// %then_val = call i16 @Literal12(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row)
|
||||
// ret i16 %then_val
|
||||
//
|
||||
// return_else_expr: ; preds = %check_when_expr_block, %eval_first_when_expr, %eval_case_expr
|
||||
// %else_val = call i16 @Literal13(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row)
|
||||
// ret i16 %else_val
|
||||
// }
|
||||
//
|
||||
// Sample IR output when there is case expression and no else expression
|
||||
// define i16 @CaseExpr(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row) #20 {
|
||||
// eval_case_expr:
|
||||
// %case_val = call i64 @GetSlotRef(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row)
|
||||
// %is_null = trunc i64 %case_val to i1
|
||||
// br i1 %is_null, label %return_null, label %eval_first_when_expr
|
||||
//
|
||||
// eval_first_when_expr: ; preds = %eval_case_expr
|
||||
// %when_val = call i64 @Literal(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row)
|
||||
// %is_null1 = trunc i64 %when_val to i1
|
||||
// br i1 %is_null1, label %return_null, label %check_when_expr_block
|
||||
//
|
||||
// check_when_expr_block: ; preds = %eval_first_when_expr
|
||||
// %0 = ashr i64 %when_val, 32
|
||||
// %1 = trunc i64 %0 to i32
|
||||
// %2 = ashr i64 %case_val, 32
|
||||
// %3 = trunc i64 %2 to i32
|
||||
// %eq = icmp eq i32 %3, %1
|
||||
// br i1 %eq, label %return_then_expr, label %return_null
|
||||
//
|
||||
// return_then_expr: ; preds = %check_when_expr_block
|
||||
// %then_val = call i16 @Literal12(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row)
|
||||
// ret i16 %then_val
|
||||
//
|
||||
// return_null: ; preds = %check_when_expr_block, %eval_first_when_expr, %eval_case_expr
|
||||
// ret i16 1
|
||||
// }
|
||||
//
|
||||
// Sample IR output when there is no case expr and else expression
|
||||
// define i16 @CaseExpr(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row) #20 {
|
||||
// eval_first_when_expr:
|
||||
// %when_val = call i16 @Eq_IntVal_IntValWrapper1(
|
||||
// %"class.doris::ExprContext"* %context, %"class.doris::TupleRow"* %row)
|
||||
// %is_null = trunc i16 %when_val to i1
|
||||
// br i1 %is_null, label %return_else_expr, label %check_when_expr_block
|
||||
//
|
||||
// check_when_expr_block: ; preds = %eval_first_when_expr
|
||||
// %0 = ashr i16 %when_val, 8
|
||||
// %1 = trunc i16 %0 to i8
|
||||
// %val = trunc i8 %1 to i1
|
||||
// br i1 %val, label %return_then_expr, label %return_else_expr
|
||||
//
|
||||
// return_then_expr: ; preds = %check_when_expr_block
|
||||
// %then_val = call i16 @Literal14(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row)
|
||||
// ret i16 %then_val
|
||||
//
|
||||
// return_else_expr: ; preds = %check_when_expr_block, %eval_first_when_expr
|
||||
// %else_val = call i16 @Literal15(%"class.doris::ExprContext"* %context,
|
||||
// %"class.doris::TupleRow"* %row)
|
||||
// ret i16 %else_val
|
||||
// }
|
||||
Status CaseExpr::get_codegend_compute_fn(RuntimeState* state, Function** fn) {
|
||||
if (_ir_compute_fn != NULL) {
|
||||
*fn = _ir_compute_fn;
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
const int num_children = get_num_children();
|
||||
Function* child_fns[num_children];
|
||||
for (int i = 0; i < num_children; ++i) {
|
||||
RETURN_IF_ERROR(children()[i]->get_codegend_compute_fn(state, &child_fns[i]));
|
||||
}
|
||||
|
||||
LlvmCodeGen* codegen = NULL;
|
||||
RETURN_IF_ERROR(state->get_codegen(&codegen));
|
||||
LLVMContext& context = codegen->context();
|
||||
LlvmCodeGen::LlvmBuilder builder(context);
|
||||
|
||||
Value* args[2];
|
||||
Function* function = create_ir_function_prototype(codegen, "CaseExpr", &args);
|
||||
BasicBlock* eval_case_expr_block = NULL;
|
||||
|
||||
// This is the block immediately after the when/then exprs. It will either point to a
|
||||
// block which returns the else expr, or returns NULL if no else expr is specified.
|
||||
BasicBlock* default_value_block = BasicBlock::Create(
|
||||
context, has_else_expr() ? "return_else_expr" : "return_null", function);
|
||||
|
||||
// If there is a case expression, create a block to evaluate it.
|
||||
CodegenAnyVal case_val;
|
||||
BasicBlock* eval_first_when_expr_block = BasicBlock::Create(
|
||||
context, "eval_first_when_expr", function, default_value_block);
|
||||
BasicBlock* current_when_expr_block = eval_first_when_expr_block;
|
||||
if (has_case_expr()) {
|
||||
// Need at least case, when and then expr, and optionally an else expr
|
||||
DCHECK_GE(num_children, (has_else_expr()) ? 4 : 3);
|
||||
// If there is a case expr, create block eval_case_expr to evaluate the
|
||||
// case expr. Place this block before eval_first_when_expr_block
|
||||
eval_case_expr_block = BasicBlock::Create(context, "eval_case_expr",
|
||||
function, eval_first_when_expr_block);
|
||||
builder.SetInsertPoint(eval_case_expr_block);
|
||||
case_val = CodegenAnyVal::create_call_wrapped(
|
||||
codegen, &builder, children()[0]->type(), child_fns[0], args, "case_val");
|
||||
builder.CreateCondBr(
|
||||
case_val.get_is_null(), default_value_block, eval_first_when_expr_block);
|
||||
} else {
|
||||
DCHECK_GE(num_children, (has_else_expr()) ? 3 : 2);
|
||||
}
|
||||
|
||||
const int loop_end = (has_else_expr()) ? num_children - 1 : num_children;
|
||||
const int last_loop_iter = loop_end - 2;
|
||||
// The loop increments by two each time, because each iteration handles one when/then
|
||||
// pair. Both when and then subexpressions are single children. If there is a case expr
|
||||
// start loop at index 1. (case expr is children()[0] and has already be evaluated.
|
||||
for (int i = (has_case_expr()) ? 1 : 0; i < loop_end; i += 2) {
|
||||
BasicBlock* check_when_expr_block = BasicBlock::Create(
|
||||
context, "check_when_expr_block", function, default_value_block);
|
||||
BasicBlock* return_then_expr_block =
|
||||
BasicBlock::Create(context, "return_then_expr", function, default_value_block);
|
||||
|
||||
// continue_or_exit_block either points to the next eval_next_when_expr block,
|
||||
// or points to the defaut_value_block if there are no more when/then expressions.
|
||||
BasicBlock* continue_or_exit_block = NULL;
|
||||
if (i == last_loop_iter) {
|
||||
continue_or_exit_block = default_value_block;
|
||||
} else {
|
||||
continue_or_exit_block = BasicBlock::Create(
|
||||
context, "eval_next_when_expr", function, default_value_block);
|
||||
}
|
||||
|
||||
// Get the child value of the when statement. If NULL simply continue to next when
|
||||
// statement
|
||||
builder.SetInsertPoint(current_when_expr_block);
|
||||
CodegenAnyVal when_val = CodegenAnyVal::create_call_wrapped(
|
||||
codegen, &builder, children()[i]->type(), child_fns[i], args, "when_val");
|
||||
builder.CreateCondBr(
|
||||
when_val.get_is_null(), continue_or_exit_block, check_when_expr_block);
|
||||
|
||||
builder.SetInsertPoint(check_when_expr_block);
|
||||
if (has_case_expr()) {
|
||||
// Compare for equality
|
||||
Value* is_equal = case_val.eq(&when_val);
|
||||
builder.CreateCondBr(is_equal, return_then_expr_block, continue_or_exit_block);
|
||||
} else {
|
||||
builder.CreateCondBr(
|
||||
when_val.get_val(), return_then_expr_block, continue_or_exit_block);
|
||||
}
|
||||
|
||||
builder.SetInsertPoint(return_then_expr_block);
|
||||
|
||||
// Eval and return then value
|
||||
Value* then_val = CodegenAnyVal::create_call(
|
||||
codegen, &builder, child_fns[i+1], args, "then_val");
|
||||
builder.CreateRet(then_val);
|
||||
|
||||
current_when_expr_block = continue_or_exit_block;
|
||||
}
|
||||
|
||||
builder.SetInsertPoint(default_value_block);
|
||||
if (has_else_expr()) {
|
||||
Value* else_val = CodegenAnyVal::create_call(
|
||||
codegen, &builder, child_fns[num_children - 1], args, "else_val");
|
||||
builder.CreateRet(else_val);
|
||||
} else {
|
||||
builder.CreateRet(CodegenAnyVal::get_null_val(codegen, type()));
|
||||
}
|
||||
|
||||
*fn = codegen->finalize_function(function);
|
||||
DCHECK(*fn != NULL);
|
||||
_ir_compute_fn = *fn;
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
void CaseExpr::get_child_val(int child_idx, ExprContext* ctx, TupleRow* row, AnyVal* dst) {
|
||||
switch (_children[child_idx]->type().type) {
|
||||
case TYPE_BOOLEAN:
|
||||
|
||||
Reference in New Issue
Block a user