From 114049a22031be63da511ea53f4e655fc72a4578 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 27 Oct 2016 03:28:29 -0400 Subject: IR analysis unrolls a complicated loop --- src/codegen.cpp | 112 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 60 insertions(+), 52 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 023a714819..4f8af212d9 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1539,79 +1539,44 @@ static LLVMValueRef gen_arithmetic_bin_op_expr(CodeGen *g, AstNode *node) { } -static LLVMIntPredicate cmp_op_to_int_predicate(BinOpType cmp_op, bool is_signed) { +static LLVMIntPredicate cmp_op_to_int_predicate(IrBinOp cmp_op, bool is_signed) { switch (cmp_op) { - case BinOpTypeCmpEq: + case IrBinOpCmpEq: return LLVMIntEQ; - case BinOpTypeCmpNotEq: + case IrBinOpCmpNotEq: return LLVMIntNE; - case BinOpTypeCmpLessThan: + case IrBinOpCmpLessThan: return is_signed ? LLVMIntSLT : LLVMIntULT; - case BinOpTypeCmpGreaterThan: + case IrBinOpCmpGreaterThan: return is_signed ? LLVMIntSGT : LLVMIntUGT; - case BinOpTypeCmpLessOrEq: + case IrBinOpCmpLessOrEq: return is_signed ? LLVMIntSLE : LLVMIntULE; - case BinOpTypeCmpGreaterOrEq: + case IrBinOpCmpGreaterOrEq: return is_signed ? LLVMIntSGE : LLVMIntUGE; default: zig_unreachable(); } } -static LLVMRealPredicate cmp_op_to_real_predicate(BinOpType cmp_op) { +static LLVMRealPredicate cmp_op_to_real_predicate(IrBinOp cmp_op) { switch (cmp_op) { - case BinOpTypeCmpEq: + case IrBinOpCmpEq: return LLVMRealOEQ; - case BinOpTypeCmpNotEq: + case IrBinOpCmpNotEq: return LLVMRealONE; - case BinOpTypeCmpLessThan: + case IrBinOpCmpLessThan: return LLVMRealOLT; - case BinOpTypeCmpGreaterThan: + case IrBinOpCmpGreaterThan: return LLVMRealOGT; - case BinOpTypeCmpLessOrEq: + case IrBinOpCmpLessOrEq: return LLVMRealOLE; - case BinOpTypeCmpGreaterOrEq: + case IrBinOpCmpGreaterOrEq: return LLVMRealOGE; default: zig_unreachable(); } } -static LLVMValueRef gen_cmp_expr(CodeGen *g, AstNode *node) { - assert(node->type == NodeTypeBinOpExpr); - - LLVMValueRef val1 = gen_expr(g, node->data.bin_op_expr.op1); - LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2); - - TypeTableEntry *op1_type = get_expr_type(node->data.bin_op_expr.op1); - TypeTableEntry *op2_type = get_expr_type(node->data.bin_op_expr.op2); - assert(op1_type == op2_type); - - if (op1_type->id == TypeTableEntryIdFloat) { - LLVMRealPredicate pred = cmp_op_to_real_predicate(node->data.bin_op_expr.bin_op); - return LLVMBuildFCmp(g->builder, pred, val1, val2, ""); - } else if (op1_type->id == TypeTableEntryIdInt) { - LLVMIntPredicate pred = cmp_op_to_int_predicate(node->data.bin_op_expr.bin_op, - op1_type->data.integral.is_signed); - return LLVMBuildICmp(g->builder, pred, val1, val2, ""); - } else if (op1_type->id == TypeTableEntryIdEnum) { - if (op1_type->data.enumeration.gen_field_count == 0) { - LLVMIntPredicate pred = cmp_op_to_int_predicate(node->data.bin_op_expr.bin_op, false); - return LLVMBuildICmp(g->builder, pred, val1, val2, ""); - } else { - zig_unreachable(); - } - } else if (op1_type->id == TypeTableEntryIdPureError || - op1_type->id == TypeTableEntryIdPointer || - op1_type->id == TypeTableEntryIdBool) - { - LLVMIntPredicate pred = cmp_op_to_int_predicate(node->data.bin_op_expr.bin_op, false); - return LLVMBuildICmp(g->builder, pred, val1, val2, ""); - } else { - zig_unreachable(); - } -} - static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) { assert(node->type == NodeTypeBinOpExpr); @@ -1844,7 +1809,7 @@ static LLVMValueRef gen_bin_op_expr(CodeGen *g, AstNode *node) { case BinOpTypeCmpGreaterThan: case BinOpTypeCmpLessOrEq: case BinOpTypeCmpGreaterOrEq: - return gen_cmp_expr(g, node); + zig_panic("moved to ir_render"); case BinOpTypeUnwrapMaybe: return gen_unwrap_maybe_expr(g, node); case BinOpTypeBinOr: @@ -2341,6 +2306,41 @@ static LLVMValueRef ir_render_bin_op_bool(CodeGen *g, IrExecutable *executable, } } +static LLVMValueRef ir_render_bin_op_cmp(CodeGen *g, IrExecutable *executable, + IrInstructionBinOp *bin_op_instruction) +{ + IrBinOp op_id = bin_op_instruction->op_id; + LLVMValueRef val1 = ir_llvm_value(g, bin_op_instruction->op1); + LLVMValueRef val2 = ir_llvm_value(g, bin_op_instruction->op2); + + TypeTableEntry *op1_type = bin_op_instruction->op1->type_entry; + TypeTableEntry *op2_type = bin_op_instruction->op2->type_entry; + assert(op1_type == op2_type); + + if (op1_type->id == TypeTableEntryIdFloat) { + LLVMRealPredicate pred = cmp_op_to_real_predicate(op_id); + return LLVMBuildFCmp(g->builder, pred, val1, val2, ""); + } else if (op1_type->id == TypeTableEntryIdInt) { + LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, op1_type->data.integral.is_signed); + return LLVMBuildICmp(g->builder, pred, val1, val2, ""); + } else if (op1_type->id == TypeTableEntryIdEnum) { + if (op1_type->data.enumeration.gen_field_count == 0) { + LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false); + return LLVMBuildICmp(g->builder, pred, val1, val2, ""); + } else { + zig_unreachable(); + } + } else if (op1_type->id == TypeTableEntryIdPureError || + op1_type->id == TypeTableEntryIdPointer || + op1_type->id == TypeTableEntryIdBool) + { + LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false); + return LLVMBuildICmp(g->builder, pred, val1, val2, ""); + } else { + zig_unreachable(); + } +} + static LLVMValueRef ir_render_bin_op_add(CodeGen *g, IrExecutable *executable, IrInstructionBinOp *bin_op_instruction) { @@ -2389,7 +2389,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, case IrBinOpCmpGreaterThan: case IrBinOpCmpLessOrEq: case IrBinOpCmpGreaterOrEq: - zig_panic("TODO bin op cmp"); + return ir_render_bin_op_cmp(g, executable, bin_op_instruction); case IrBinOpAdd: case IrBinOpAddWrap: return ir_render_bin_op_add(g, executable, bin_op_instruction); @@ -2860,6 +2860,13 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI return LLVMBuildLoad(g->builder, ir_llvm_value(g, instruction->ptr), ""); } +static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) { + LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); + LLVMValueRef value = ir_llvm_value(g, instruction->value); + LLVMBuildStore(g->builder, value, ptr); + return nullptr; +} + static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) { return instruction->var->value_ref; } @@ -2931,13 +2938,14 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, return ir_render_un_op(g, executable, (IrInstructionUnOp *)instruction); case IrInstructionIdLoadPtr: return ir_render_load_ptr(g, executable, (IrInstructionLoadPtr *)instruction); + case IrInstructionIdStorePtr: + return ir_render_store_ptr(g, executable, (IrInstructionStorePtr *)instruction); case IrInstructionIdVarPtr: return ir_render_var_ptr(g, executable, (IrInstructionVarPtr *)instruction); case IrInstructionIdCall: return ir_render_call(g, executable, (IrInstructionCall *)instruction); case IrInstructionIdSwitchBr: case IrInstructionIdPhi: - case IrInstructionIdStorePtr: case IrInstructionIdBuiltinCall: case IrInstructionIdContainerInitList: case IrInstructionIdContainerInitFields: -- cgit v1.2.3