authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-18 20:22:28-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-18 20:22:28-05:00
logcfc9f7422f3b0e4077eca42d7b71cd5523dad0a9
tree5ed9a44de4b73e2efa0deaca9b8bae87bd605f91
parent82101198f1ff2438f5db61d3a85eee3e0e1b95db

IR: add MaybeOkOr instruction


1 files changed, 43 insertions(+), 1 deletions(-)

src/ir.cpp+43-1
......@@ -2194,6 +2194,48 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod
21942194 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
21952195}
21962196
2197static IrInstruction *ir_gen_maybe_ok_or(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
2198 assert(node->type == NodeTypeBinOpExpr);
2199
2200 AstNode *op1_node = node->data.bin_op_expr.op1;
2201 AstNode *op2_node = node->data.bin_op_expr.op2;
2202
2203 bool is_inline = ir_should_inline(irb);
2204
2205 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPurposeAddressOf);
2206 if (maybe_ptr == irb->codegen->invalid_instruction)
2207 return irb->codegen->invalid_instruction;
2208
2209 IrInstruction *is_non_null = ir_build_test_null(irb, parent_scope, node, maybe_ptr);
2210
2211 IrBasicBlock *ok_block = ir_build_basic_block(irb, parent_scope, "MaybeNonNull");
2212 IrBasicBlock *null_block = ir_build_basic_block(irb, parent_scope, "MaybeNull");
2213 IrBasicBlock *end_block = ir_build_basic_block(irb, parent_scope, "MaybeEnd");
2214 ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_inline);
2215
2216 ir_set_cursor_at_end(irb, null_block);
2217 IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope);
2218 if (null_result == irb->codegen->invalid_instruction)
2219 return irb->codegen->invalid_instruction;
2220 IrBasicBlock *after_null_block = irb->current_basic_block;
2221 ir_build_br(irb, parent_scope, node, end_block, is_inline);
2222
2223 ir_set_cursor_at_end(irb, ok_block);
2224 IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, parent_scope, node, maybe_ptr, false);
2225 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr);
2226 IrBasicBlock *after_ok_block = irb->current_basic_block;
2227 ir_build_br(irb, parent_scope, node, end_block, is_inline);
2228
2229 ir_set_cursor_at_end(irb, end_block);
2230 IrInstruction **incoming_values = allocate<IrInstruction *>(2);
2231 incoming_values[0] = null_result;
2232 incoming_values[1] = unwrapped_payload;
2233 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
2234 incoming_blocks[0] = after_null_block;
2235 incoming_blocks[1] = after_ok_block;
2236 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);
2237}
2238
21972239static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) {
21982240 assert(node->type == NodeTypeBinOpExpr);
21992241
......@@ -2284,7 +2326,7 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node)
22842326 case BinOpTypeArrayMult:
22852327 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult);
22862328 case BinOpTypeUnwrapMaybe:
2287 zig_panic("TODO gen IR for unwrap maybe binary operation");
2329 return ir_gen_maybe_ok_or(irb, scope, node);
22882330 }
22892331 zig_unreachable();
22902332}