ZIR: move some un_tok tags to un_node instead

Idea here is to prefer un_node to un_tok in order to avoid unnecessary
calls to `tree.firstToken`.
This commit is contained in:
Andrew Kelley 2021-03-20 17:18:44 -07:00
parent 50010447bd
commit 260c610708
3 changed files with 58 additions and 67 deletions

View File

@ -1212,7 +1212,7 @@ fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inner
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const child_type = try sema.resolveType(block, src, inst_data.operand);
const opt_type = try sema.mod.optionalType(sema.arena, child_type);
@ -1224,7 +1224,7 @@ fn zirOptionalTypeFromPtrElem(sema: *Sema, block: *Scope.Block, inst: zir.Inst.I
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const ptr = try sema.resolveInst(inst_data.operand);
const elem_ty = ptr.ty.elemType();
const opt_ty = try sema.mod.optionalType(sema.arena, elem_ty);
@ -1459,7 +1459,7 @@ fn zirOptionalPayloadPtr(
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const optional_ptr = try sema.resolveInst(inst_data.operand);
assert(optional_ptr.ty.zigTypeTag() == .Pointer);
const src = inst_data.src();
@ -1502,7 +1502,7 @@ fn zirOptionalPayload(
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const operand = try sema.resolveInst(inst_data.operand);
const opt_type = operand.ty;
@ -1540,7 +1540,7 @@ fn zirErrUnionPayload(
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const operand = try sema.resolveInst(inst_data.operand);
if (operand.ty.zigTypeTag() != .ErrorUnion)
@ -1574,7 +1574,7 @@ fn zirErrUnionPayloadPtr(
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const operand = try sema.resolveInst(inst_data.operand);
assert(operand.ty.zigTypeTag() == .Pointer);
@ -1613,7 +1613,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inner
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const operand = try sema.resolveInst(inst_data.operand);
if (operand.ty.zigTypeTag() != .ErrorUnion)
@ -1637,7 +1637,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const operand = try sema.resolveInst(inst_data.operand);
assert(operand.ty.zigTypeTag() == .Pointer);
@ -2710,7 +2710,7 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const uncasted_operand = try sema.resolveInst(inst_data.operand);

View File

@ -376,8 +376,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
.negation => @panic("TODO"),
.negation_wrap => @panic("TODO"),
.bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node), node),
.bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node), node),
.bool_not => return boolNot(mod, scope, rl, node),
.bit_not => return bitNot(mod, scope, rl, node),
//.negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)),
//.negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)),
@ -466,27 +466,21 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
return rvalue(mod, scope, rl, result, node);
},
.optional_type => {
const src_token = tree.firstToken(node);
const operand = try typeExpr(mod, scope, node_datas[node].lhs);
const result = try gz.addUnTok(.optional_type, operand, src_token);
const result = try gz.addUnNode(.optional_type, operand, node);
return rvalue(mod, scope, rl, result, node);
},
.unwrap_optional => {
const src_token = tree.firstToken(node);
switch (rl) {
.ref => return gz.addUnTok(
.optional_payload_safe_ptr,
try expr(mod, scope, .ref, node_datas[node].lhs),
src_token,
),
else => return rvalue(mod, scope, rl, try gz.addUnTok(
.optional_payload_safe,
try expr(mod, scope, .none, node_datas[node].lhs),
src_token,
), node),
}
.unwrap_optional => switch (rl) {
.ref => return gz.addUnNode(
.optional_payload_safe_ptr,
try expr(mod, scope, .ref, node_datas[node].lhs),
node,
),
else => return rvalue(mod, scope, rl, try gz.addUnNode(
.optional_payload_safe,
try expr(mod, scope, .none, node_datas[node].lhs),
node,
), node),
},
.block_two, .block_two_semicolon => {
const statements = [2]ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
@ -1315,27 +1309,24 @@ fn assignOp(
_ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result);
}
fn boolNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref {
fn boolNot(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!zir.Inst.Ref {
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const src_token = tree.firstToken(node);
const gz = scope.getGenZir();
const operand = try expr(mod, scope, .{ .ty = @enumToInt(zir.Const.bool_type) }, node_datas[node].lhs);
return gz.addUnTok(.bool_not, operand, src_token);
const gz = scope.getGenZir();
const result = try gz.addUnNode(.bool_not, operand, node);
return rvalue(mod, scope, rl, result, node);
}
fn bitNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref {
fn bitNot(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!zir.Inst.Ref {
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const src_token = tree.firstToken(node);
const gz = scope.getGenZir();
const operand = try expr(mod, scope, .none, node_datas[node].lhs);
return gz.addUnTok(.bit_not, operand, src_token);
const result = try gz.addUnTok(.bit_not, operand, node);
return rvalue(mod, scope, rl, result, node);
}
fn negation(

View File

@ -445,7 +445,7 @@ pub const Inst = struct {
/// The new result location pointer has an inferred type.
bitcast_result_ptr,
/// Bitwise NOT. `~`
/// uses `un_tok`
/// Uses `un_node`.
bit_not,
/// Bitwise OR. `|`
bit_or,
@ -464,7 +464,7 @@ pub const Inst = struct {
/// Uses the `bin` field.
bool_and,
/// Boolean NOT. See also `bit_not`.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
bool_not,
/// Boolean OR. See also `bit_or`.
/// Uses the `bin` field.
@ -749,57 +749,57 @@ pub const Inst = struct {
/// Bitwise XOR. `^`
xor,
/// Create an optional type '?T'
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
optional_type,
/// Create an optional type '?T'. The operand is a pointer value. The optional type will
/// be the type of the pointer element, wrapped in an optional.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
optional_type_from_ptr_elem,
/// ?T => T with safety.
/// Given an optional value, returns the payload value, with a safety check that
/// the value is non-null. Used for `orelse`, `if` and `while`.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
optional_payload_safe,
/// ?T => T without safety.
/// Given an optional value, returns the payload value. No safety checks.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
optional_payload_unsafe,
/// *?T => *T with safety.
/// Given a pointer to an optional value, returns a pointer to the payload value,
/// with a safety check that the value is non-null. Used for `orelse`, `if` and `while`.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
optional_payload_safe_ptr,
/// *?T => *T without safety.
/// Given a pointer to an optional value, returns a pointer to the payload value.
/// No safety checks.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
optional_payload_unsafe_ptr,
/// E!T => T with safety.
/// Given an error union value, returns the payload value, with a safety check
/// that the value is not an error. Used for catch, if, and while.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
err_union_payload_safe,
/// E!T => T without safety.
/// Given an error union value, returns the payload value. No safety checks.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
err_union_payload_unsafe,
/// *E!T => *T with safety.
/// Given a pointer to an error union value, returns a pointer to the payload value,
/// with a safety check that the value is not an error. Used for catch, if, and while.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
err_union_payload_safe_ptr,
/// *E!T => *T without safety.
/// Given a pointer to a error union value, returns a pointer to the payload value.
/// No safety checks.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
err_union_payload_unsafe_ptr,
/// E!T => E without safety.
/// Given an error union value, returns the error code. No safety checks.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
err_union_code,
/// *E!T => E without safety.
/// Given a pointer to an error union value, returns the error code. No safety checks.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
err_union_code_ptr,
/// Takes a *E!T and raises a compiler error if T != void
/// Uses the `un_tok` field.
@ -1326,6 +1326,7 @@ const Writer = struct {
.indexable_ptr_len,
.@"await",
.bit_not,
.bool_not,
.call_none,
.compile_error,
.deref_node,
@ -1337,20 +1338,6 @@ const Writer = struct {
.set_eval_branch_quota,
.resolve_inferred_alloc,
.suspend_block_one,
=> try self.writeUnNode(stream, inst),
.bool_not,
.break_void_tok,
.is_non_null,
.is_null,
.is_non_null_ptr,
.is_null_ptr,
.is_err,
.is_err_ptr,
.ref,
.ret_tok,
.ret_coerce,
.typeof,
.optional_type,
.optional_type_from_ptr_elem,
.optional_payload_safe,
@ -1363,6 +1350,19 @@ const Writer = struct {
.err_union_payload_unsafe_ptr,
.err_union_code,
.err_union_code_ptr,
=> try self.writeUnNode(stream, inst),
.break_void_tok,
.is_non_null,
.is_null,
.is_non_null_ptr,
.is_null_ptr,
.is_err,
.is_err_ptr,
.ref,
.ret_tok,
.ret_coerce,
.typeof,
.ensure_err_payload_void,
=> try self.writeUnTok(stream, inst),