mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 16:24:51 +00:00
hook up result locs to for loops
```zig
export fn entry() void {
var buf: [10]u8 = undefined;
var x = for (buf) |x| break foo() else bar();
}
```
```llvm
define void @entry() #2 !dbg !35 {
Entry:
%buf = alloca [10 x i8], align 1
%i = alloca i64, align 8
%x = alloca %Foo, align 4
%0 = bitcast [10 x i8]* %buf to i8*, !dbg !51
call void @llvm.memset.p0i8.i64(i8* align 1 %0, i8 -86, i64 10, i1 false), !dbg !51
call void @llvm.dbg.declare(metadata [10 x i8]* %buf, metadata !39, metadata !DIExpression()), !dbg !51
store i64 0, i64* %i, align 8, !dbg !52
call void @llvm.dbg.declare(metadata i64* %i, metadata !44, metadata !DIExpression()), !dbg !52
br label %ForCond, !dbg !52
ForCond: ; preds = %Entry
%1 = load i64, i64* %i, align 8, !dbg !52
%2 = icmp ult i64 %1, 10, !dbg !52
br i1 %2, label %ForBody, label %ForElse, !dbg !52
ForBody: ; preds = %ForCond
%3 = getelementptr inbounds [10 x i8], [10 x i8]* %buf, i64 0, i64 %1, !dbg !52
call void @llvm.dbg.declare(metadata i8* %3, metadata !45, metadata !DIExpression()), !dbg !53
call fastcc void @foo(%Foo* sret %x), !dbg !54
br label %ForEnd, !dbg !55
ForElse: ; preds = %ForCond
call fastcc void @bar(%Foo* sret %x), !dbg !56
br label %ForEnd, !dbg !52
ForEnd: ; preds = %ForElse, %ForBody
call void @llvm.dbg.declare(metadata %Foo* %x, metadata !46, metadata !DIExpression()), !dbg !57
ret void, !dbg !58
}
```
This commit is contained in:
parent
ede3436b08
commit
2b0a1b7b14
@ -1,7 +1,6 @@
|
||||
Scratch pad for stuff to do before merging master
|
||||
=================================================
|
||||
|
||||
* hook up peer result locs to for
|
||||
* hook up peer result locs to catch
|
||||
* struct initializations
|
||||
* function call parameters
|
||||
|
||||
21
src/ir.cpp
21
src/ir.cpp
@ -5983,7 +5983,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
|
||||
}
|
||||
}
|
||||
|
||||
static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
|
||||
static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval,
|
||||
ResultLoc *result_loc)
|
||||
{
|
||||
assert(node->type == NodeTypeForExpr);
|
||||
|
||||
AstNode *array_node = node->data.for_expr.array_expr;
|
||||
@ -6043,7 +6045,10 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
|
||||
IrInstruction *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
|
||||
IrBasicBlock *after_cond_block = irb->current_basic_block;
|
||||
IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node));
|
||||
ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, body_block, else_block, is_comptime));
|
||||
IrInstruction *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond,
|
||||
body_block, else_block, is_comptime));
|
||||
|
||||
ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, end_block, result_loc);
|
||||
|
||||
ir_set_cursor_at_end_and_append_block(irb, body_block);
|
||||
IrInstruction *elem_ptr = ir_build_elem_ptr(irb, parent_scope, node, array_val_ptr, index_val, false, PtrLenSingle);
|
||||
@ -6064,7 +6069,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
|
||||
loop_scope->is_comptime = is_comptime;
|
||||
loop_scope->incoming_blocks = &incoming_blocks;
|
||||
loop_scope->incoming_values = &incoming_values;
|
||||
loop_scope->lval = lval;
|
||||
loop_scope->result_loc = &peer_parent->peers[0].base;
|
||||
|
||||
// Note the body block of the loop is not the place that lval and result_loc are used -
|
||||
// it's actually in break statements, handled similarly to return statements.
|
||||
// That is why we set those values in loop_scope above and not in this ir_gen_node call.
|
||||
IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base);
|
||||
|
||||
if (!instr_is_unreachable(body_result)) {
|
||||
@ -6081,7 +6091,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
|
||||
if (else_node) {
|
||||
ir_set_cursor_at_end_and_append_block(irb, else_block);
|
||||
|
||||
else_result = ir_gen_node(irb, else_node, parent_scope);
|
||||
else_result = ir_gen_node_extra(irb, else_node, parent_scope, lval, &peer_parent->peers[1].base);
|
||||
if (else_result == irb->codegen->invalid_instruction)
|
||||
return else_result;
|
||||
if (!instr_is_unreachable(else_result))
|
||||
@ -6098,7 +6108,8 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
|
||||
incoming_values.append(void_else_value);
|
||||
}
|
||||
|
||||
return ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
|
||||
IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
|
||||
return ir_expr_wrap(irb, parent_scope, phi, result_loc);
|
||||
}
|
||||
|
||||
static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
|
||||
@ -7866,7 +7877,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
|
||||
case NodeTypeWhileExpr:
|
||||
return ir_gen_while_expr(irb, scope, node, lval, result_loc);
|
||||
case NodeTypeForExpr:
|
||||
return ir_lval_wrap(irb, scope, ir_gen_for_expr(irb, scope, node), lval, result_loc);
|
||||
return ir_gen_for_expr(irb, scope, node, lval, result_loc);
|
||||
case NodeTypeArrayAccessExpr:
|
||||
return ir_gen_array_access(irb, scope, node, lval, result_loc);
|
||||
case NodeTypeReturnExpr:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user