Skip to content

Commit

Permalink
ir: refactor lvalues
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewrk committed Jul 12, 2018
1 parent 30c4add commit ce11d6d
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 50 deletions.
11 changes: 5 additions & 6 deletions src/all_types.hpp
Expand Up @@ -2005,12 +2005,6 @@ struct IrBasicBlock {
IrInstruction *must_be_comptime_source_instr;
};

struct LVal {
bool is_ptr;
bool is_const;
bool is_volatile;
};

enum IrInstructionId {
IrInstructionIdInvalid,
IrInstructionIdBr,
Expand Down Expand Up @@ -2972,6 +2966,11 @@ struct IrInstructionTypeName {
IrInstruction *type_value;
};

enum LVal {
LValNone,
LValPtr,
};

struct IrInstructionDeclRef {
IrInstruction base;

Expand Down
77 changes: 37 additions & 40 deletions src/ir.cpp
Expand Up @@ -39,9 +39,6 @@ struct IrAnalyze {
IrBasicBlock *const_predecessor_bb;
};

static const LVal LVAL_NONE = { false, false, false };
static const LVal LVAL_PTR = { true, false, false };

enum ConstCastResultId {
ConstCastResultIdOk,
ConstCastResultIdErrSet,
Expand Down Expand Up @@ -3164,7 +3161,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
case ReturnKindError:
{
assert(expr_node);
IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR);
IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
if (err_union_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr);
Expand Down Expand Up @@ -3192,7 +3189,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,

ir_set_cursor_at_end_and_append_block(irb, continue_block);
IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false);
if (lval.is_ptr)
if (lval == LValPtr)
return unwrapped_ptr;
else
return ir_build_load_ptr(irb, scope, node, unwrapped_ptr);
Expand Down Expand Up @@ -3357,7 +3354,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no
}

static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) {
IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LVAL_PTR);
IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr);
IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);

if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction)
Expand All @@ -3368,7 +3365,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node)
}

static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LVAL_PTR);
IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr);
if (lvalue == irb->codegen->invalid_instruction)
return lvalue;
IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue);
Expand Down Expand Up @@ -3470,7 +3467,7 @@ static IrInstruction *ir_gen_maybe_ok_or(IrBuilder *irb, Scope *parent_scope, As
AstNode *op1_node = node->data.bin_op_expr.op1;
AstNode *op2_node = node->data.bin_op_expr.op2;

IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LVAL_PTR);
IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr);
if (maybe_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;

Expand Down Expand Up @@ -3657,7 +3654,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,

Buf *variable_name = node->data.symbol_expr.symbol;

if (buf_eql_str(variable_name, "_") && lval.is_ptr) {
if (buf_eql_str(variable_name, "_") && lval == LValPtr) {
IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node);
const_instruction->base.value.type = get_pointer_to_type(irb->codegen,
irb->codegen->builtin_types.entry_void, false);
Expand All @@ -3669,8 +3666,8 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
if (primitive_table_entry) {
IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value);
if (lval.is_ptr) {
return ir_build_ref(irb, scope, node, value, lval.is_const, lval.is_volatile);
if (lval == LValPtr) {
return ir_build_ref(irb, scope, node, value, false, false);
} else {
return value;
}
Expand All @@ -3679,7 +3676,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
VariableTableEntry *var = find_variable(irb->codegen, scope, variable_name);
if (var) {
IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, node, var);
if (lval.is_ptr)
if (lval == LValPtr)
return var_ptr;
else
return ir_build_load_ptr(irb, scope, node, var_ptr);
Expand All @@ -3705,7 +3702,7 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode
assert(node->type == NodeTypeArrayAccessExpr);

AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LVAL_PTR);
IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr);
if (array_ref_instruction == irb->codegen->invalid_instruction)
return array_ref_instruction;

Expand All @@ -3716,7 +3713,7 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode

IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction,
subscript_instruction, true, PtrLenSingle);
if (lval.is_ptr)
if (lval == LValPtr)
return ptr_instruction;

return ir_build_load_ptr(irb, scope, node, ptr_instruction);
Expand All @@ -3728,7 +3725,7 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode
AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
Buf *field_name = node->data.field_access_expr.field_name;

IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LVAL_PTR);
IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr);
if (container_ref_instruction == irb->codegen->invalid_instruction)
return container_ref_instruction;

Expand Down Expand Up @@ -4386,7 +4383,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
case BuiltinFnIdField:
{
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LVAL_PTR);
IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr);
if (arg0_value == irb->codegen->invalid_instruction)
return arg0_value;

Expand All @@ -4397,7 +4394,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo

IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value);

if (lval.is_ptr)
if (lval == LValPtr)
return ptr_instruction;

return ir_build_load_ptr(irb, scope, node, ptr_instruction);
Expand Down Expand Up @@ -4928,18 +4925,18 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, Ast
}

static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id) {
return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LVAL_NONE);
return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone);
}

static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval) {
if (!lval.is_ptr)
if (lval != LValPtr)
return value;
if (value == irb->codegen->invalid_instruction)
return value;

// We needed a pointer to a value, but we got a value. So we create
// an instruction which just makes a const pointer of it.
return ir_build_ref(irb, scope, value->source_node, value, lval.is_const, lval.is_volatile);
return ir_build_ref(irb, scope, value->source_node, value, false, false);
}

static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) {
Expand Down Expand Up @@ -5001,15 +4998,15 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode
static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node,
LVal lval)
{
IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR);
IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
if (err_union_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;

IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true);
if (payload_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;

if (lval.is_ptr)
if (lval == LValPtr)
return payload_ptr;

return ir_build_load_ptr(irb, scope, source_node, payload_ptr);
Expand Down Expand Up @@ -5046,7 +5043,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval);
case PrefixOpAddrOf: {
AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR), lval);
return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval);
}
}
zig_unreachable();
Expand Down Expand Up @@ -5186,7 +5183,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
} else {
payload_scope = scope;
}
IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, scope, LVAL_PTR);
IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, scope, LValPtr);
if (err_val_ptr == irb->codegen->invalid_instruction)
return err_val_ptr;
IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr);
Expand Down Expand Up @@ -5269,7 +5266,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
VariableTableEntry *payload_var = ir_create_var(irb, symbol_node, scope, var_symbol,
true, false, false, is_comptime);
Scope *child_scope = payload_var->child_scope;
IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, scope, LVAL_PTR);
IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, scope, LValPtr);
if (maybe_val_ptr == irb->codegen->invalid_instruction)
return maybe_val_ptr;
IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr);
Expand Down Expand Up @@ -5413,7 +5410,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
}
assert(elem_node->type == NodeTypeSymbol);

IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LVAL_PTR);
IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr);
if (array_val_ptr == irb->codegen->invalid_instruction)
return array_val_ptr;

Expand Down Expand Up @@ -5700,7 +5697,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no
AstNode *else_node = node->data.test_expr.else_node;
bool var_is_ptr = node->data.test_expr.var_is_ptr;

IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR);
IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
if (maybe_val_ptr == irb->codegen->invalid_instruction)
return maybe_val_ptr;

Expand Down Expand Up @@ -5778,7 +5775,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
Buf *var_symbol = node->data.if_err_expr.var_symbol;
Buf *err_symbol = node->data.if_err_expr.err_symbol;

IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LVAL_PTR);
IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr);
if (err_val_ptr == irb->codegen->invalid_instruction)
return err_val_ptr;

Expand Down Expand Up @@ -5904,7 +5901,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
assert(node->type == NodeTypeSwitchExpr);

AstNode *target_node = node->data.switch_expr.expr;
IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LVAL_PTR);
IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr);
if (target_value_ptr == irb->codegen->invalid_instruction)
return target_value_ptr;
IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr);
Expand Down Expand Up @@ -6277,7 +6274,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)
AstNode *start_node = slice_expr->start;
AstNode *end_node = slice_expr->end;

IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LVAL_PTR);
IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr);
if (ptr_value == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;

Expand Down Expand Up @@ -6311,11 +6308,11 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN
add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));
return irb->codegen->invalid_instruction;
}
return ir_gen_err_assert_ok(irb, parent_scope, node, op1_node, LVAL_NONE);
return ir_gen_err_assert_ok(irb, parent_scope, node, op1_node, LValNone);
}


IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LVAL_PTR);
IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr);
if (err_union_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;

Expand Down Expand Up @@ -6868,7 +6865,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node);
if (ptr_instruction == irb->codegen->invalid_instruction)
return ptr_instruction;
if (lval.is_ptr)
if (lval == LValPtr)
return ptr_instruction;

return ir_build_load_ptr(irb, scope, node, ptr_instruction);
Expand All @@ -6884,12 +6881,12 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
case NodeTypeUnwrapOptional: {
AstNode *expr_node = node->data.unwrap_optional.expr;

IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR);
IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
if (maybe_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;

IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, scope, node, maybe_ptr, true);
if (lval.is_ptr)
if (lval == LValPtr)
return unwrapped_ptr;

return ir_build_load_ptr(irb, scope, node, unwrapped_ptr);
Expand Down Expand Up @@ -6959,7 +6956,7 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc
}

static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) {
return ir_gen_node_extra(irb, node, scope, LVAL_NONE);
return ir_gen_node_extra(irb, node, scope, LValNone);
}

static void invalidate_exec(IrExecutable *exec) {
Expand Down Expand Up @@ -7089,7 +7086,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup");
}

IrInstruction *result = ir_gen_node_extra(irb, node, scope, LVAL_NONE);
IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone);
assert(result);
if (irb->exec->invalid)
return false;
Expand Down Expand Up @@ -19752,7 +19749,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
Tld *tld = instruction->tld;
LVal lval = instruction->lval;

resolve_top_level_decl(ira->codegen, tld, lval.is_ptr, instruction->base.source_node);
resolve_top_level_decl(ira->codegen, tld, lval == LValPtr, instruction->base.source_node);
if (tld->resolution == TldResolutionInvalid)
return ira->codegen->builtin_types.entry_invalid;

Expand All @@ -19773,7 +19770,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, instruction->base.source_node);
}

if (lval.is_ptr) {
if (lval == LValPtr) {
ir_link_new_instruction(var_ptr, &instruction->base);
return var_ptr->value.type;
} else {
Expand All @@ -19794,7 +19791,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,

IrInstruction *ref_instruction = ir_create_const_fn(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, fn_entry);
if (lval.is_ptr) {
if (lval == LValPtr) {
IrInstruction *ptr_instr = ir_get_ref(ira, &instruction->base, ref_instruction, true, false);
ir_link_new_instruction(ptr_instr, &instruction->base);
return ptr_instr->value.type;
Expand Down
6 changes: 2 additions & 4 deletions src/ir_print.cpp
Expand Up @@ -1005,10 +1005,8 @@ static void ir_print_ptr_type(IrPrint *irp, IrInstructionPtrType *instruction) {
}

static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) {
const char *ptr_str = instruction->lval.is_ptr ? "ptr " : "";
const char *const_str = instruction->lval.is_const ? "const " : "";
const char *volatile_str = instruction->lval.is_volatile ? "volatile " : "";
fprintf(irp->f, "declref %s%s%s%s", const_str, volatile_str, ptr_str, buf_ptr(instruction->tld->name));
const char *ptr_str = (instruction->lval == LValPtr) ? "ptr " : "";
fprintf(irp->f, "declref %s%s", ptr_str, buf_ptr(instruction->tld->name));
}

static void ir_print_panic(IrPrint *irp, IrInstructionPanic *instruction) {
Expand Down

0 comments on commit ce11d6d

Please sign in to comment.