mirror of
https://github.com/ziglang/zig.git
synced 2025-12-09 07:43:10 +00:00
no-copy semantics for if expr
```zig
export fn entry() void {
var c = true;
var x = if (c) u8(4) else u32(10);
}
```
```llvm
define void @entry() #2 !dbg !35 {
Entry:
%c = alloca i1, align 1
%x = alloca i32, align 4
store i1 true, i1* %c, align 1, !dbg !44
call void @llvm.dbg.declare(metadata i1* %c, metadata !39, metadata !DIExpression()), !dbg !45
%0 = load i1, i1* %c, align 1, !dbg !46
br i1 %0, label %Then, label %Else, !dbg !46
Then: ; preds = %Entry
br label %EndIf, !dbg !47
Else: ; preds = %Entry
br label %EndIf, !dbg !47
EndIf: ; preds = %Else, %Then
%1 = phi i32 [ 4, %Then ], [ 10, %Else ], !dbg !47
store i32 %1, i32* %x, align 4, !dbg !47
call void @llvm.dbg.declare(metadata i32* %x, metadata !42, metadata !DIExpression()), !dbg !48
ret void, !dbg !49
}
```
This commit is contained in:
parent
5e1003bc81
commit
a4aca78722
18
BRANCH_TODO
18
BRANCH_TODO
@ -8,3 +8,21 @@ migrate all the alloca_list to alloca_gen_list
|
||||
migrate ir_build_var_decl_src to use ir_build_alloca_src and explicitly initialize
|
||||
|
||||
inferred comptime
|
||||
|
||||
|
||||
if (lval == LValNone) {
|
||||
if (result_loc->id == ResultLocIdNone)
|
||||
return value;
|
||||
}
|
||||
|
||||
assert(lval == LValPtr);
|
||||
|
||||
// We needed a pointer to a value, but we got a value. So we create
|
||||
// an instruction which just makes a pointer of it.
|
||||
return ir_build_ref(irb, scope, value->source_node, value, false, false);
|
||||
|
||||
handle if with no else
|
||||
|
||||
handle comptime if condition
|
||||
|
||||
handle mixed runtime and comptime peers
|
||||
|
||||
@ -42,6 +42,7 @@ struct Tld;
|
||||
struct TldExport;
|
||||
struct IrAnalyze;
|
||||
struct ResultLoc;
|
||||
struct ResultLocPeer;
|
||||
|
||||
enum X64CABIClass {
|
||||
X64CABIClass_Unknown,
|
||||
@ -2127,6 +2128,8 @@ struct IrBasicBlock {
|
||||
const char *name_hint;
|
||||
size_t debug_id;
|
||||
size_t ref_count;
|
||||
// index into the basic block list
|
||||
size_t index;
|
||||
LLVMBasicBlockRef llvm_block;
|
||||
LLVMBasicBlockRef llvm_exit_block;
|
||||
// The instruction that referenced this basic block and caused us to
|
||||
@ -2315,10 +2318,14 @@ enum IrInstructionId {
|
||||
IrInstructionIdUndeclaredIdent,
|
||||
IrInstructionIdAllocaSrc,
|
||||
IrInstructionIdAllocaGen,
|
||||
IrInstructionIdEndExpr,
|
||||
};
|
||||
|
||||
struct IrInstruction {
|
||||
IrInstructionId id;
|
||||
// true if this instruction was generated by zig and not from user code
|
||||
bool is_gen;
|
||||
|
||||
Scope *scope;
|
||||
AstNode *source_node;
|
||||
ConstExprValue value;
|
||||
@ -2332,8 +2339,6 @@ struct IrInstruction {
|
||||
// with this child field.
|
||||
IrInstruction *child;
|
||||
IrBasicBlock *owner_bb;
|
||||
// true if this instruction was generated by zig and not from user code
|
||||
bool is_gen;
|
||||
};
|
||||
|
||||
struct IrInstructionDeclVarSrc {
|
||||
@ -3571,16 +3576,28 @@ struct IrInstructionAllocaGen {
|
||||
const char *name_hint;
|
||||
};
|
||||
|
||||
struct IrInstructionEndExpr {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *value;
|
||||
ResultLoc *result_loc;
|
||||
LVal lval;
|
||||
};
|
||||
|
||||
enum ResultLocId {
|
||||
ResultLocIdInvalid,
|
||||
ResultLocIdNone,
|
||||
ResultLocIdVar,
|
||||
ResultLocIdReturn,
|
||||
ResultLocIdPeer,
|
||||
ResultLocIdPeerParent,
|
||||
};
|
||||
|
||||
struct ResultLoc {
|
||||
ResultLocId id;
|
||||
IrInstruction *source_instruction;
|
||||
IrInstruction *gen_instruction;
|
||||
ZigType *implicit_elem_type;
|
||||
};
|
||||
|
||||
struct ResultLocNone {
|
||||
@ -3597,6 +3614,28 @@ struct ResultLocReturn {
|
||||
ResultLoc base;
|
||||
};
|
||||
|
||||
struct ResultLocPeerParent {
|
||||
ResultLoc base;
|
||||
|
||||
ResultLoc *parent;
|
||||
ResultLocPeer *peers;
|
||||
size_t peer_count;
|
||||
ZigType *resolved_type;
|
||||
};
|
||||
|
||||
struct IrSuspendPosition {
|
||||
size_t basic_block_index;
|
||||
size_t instruction_index;
|
||||
};
|
||||
|
||||
struct ResultLocPeer {
|
||||
ResultLoc base;
|
||||
|
||||
ResultLocPeerParent *parent;
|
||||
IrBasicBlock *next_bb;
|
||||
IrSuspendPosition suspend_pos;
|
||||
};
|
||||
|
||||
static const size_t slice_ptr_index = 0;
|
||||
static const size_t slice_len_index = 1;
|
||||
|
||||
|
||||
@ -5606,10 +5606,9 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
||||
case IrInstructionIdUndeclaredIdent:
|
||||
case IrInstructionIdCallSrc:
|
||||
case IrInstructionIdAllocaSrc:
|
||||
zig_unreachable();
|
||||
|
||||
case IrInstructionIdEndExpr:
|
||||
case IrInstructionIdAllocaGen:
|
||||
return nullptr;
|
||||
zig_unreachable();
|
||||
|
||||
case IrInstructionIdDeclVarGen:
|
||||
return ir_render_decl_var(g, executable, (IrInstructionDeclVarGen *)instruction);
|
||||
|
||||
479
src/ir.cpp
479
src/ir.cpp
File diff suppressed because it is too large
Load Diff
@ -158,6 +158,16 @@ static const char *ir_un_op_id_str(IrUnOp op_id) {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static const char *ir_lval_str(LVal lval) {
|
||||
switch (lval) {
|
||||
case LValNone:
|
||||
return "None";
|
||||
case LValPtr:
|
||||
return "Ptr";
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static void ir_print_un_op(IrPrint *irp, IrInstructionUnOp *un_op_instruction) {
|
||||
fprintf(irp->f, "%s ", ir_un_op_id_str(un_op_instruction->op_id));
|
||||
ir_print_other_instruction(irp, un_op_instruction->value);
|
||||
@ -219,6 +229,12 @@ static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
|
||||
return;
|
||||
case ResultLocIdVar:
|
||||
return ir_print_result_loc_var(irp, (ResultLocVar *)result_loc);
|
||||
case ResultLocIdPeer:
|
||||
fprintf(irp->f, "peer");
|
||||
return;
|
||||
case ResultLocIdPeerParent:
|
||||
fprintf(irp->f, "peer_parent");
|
||||
return;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -1128,6 +1144,14 @@ static void ir_print_alloca_gen(IrPrint *irp, IrInstructionAllocaGen *instructio
|
||||
fprintf(irp->f, "Alloca(align=%" PRIu32 ",name=%s)", instruction->align, instruction->name_hint);
|
||||
}
|
||||
|
||||
static void ir_print_end_expr(IrPrint *irp, IrInstructionEndExpr *instruction) {
|
||||
fprintf(irp->f, "EndExpr(result=");
|
||||
ir_print_result_loc(irp, instruction->result_loc);
|
||||
fprintf(irp->f, ",value=");
|
||||
ir_print_other_instruction(irp, instruction->value);
|
||||
fprintf(irp->f, ",lval=%s)", ir_lval_str(instruction->lval));
|
||||
}
|
||||
|
||||
static void ir_print_int_to_err(IrPrint *irp, IrInstructionIntToErr *instruction) {
|
||||
fprintf(irp->f, "inttoerr ");
|
||||
ir_print_other_instruction(irp, instruction->target);
|
||||
@ -2014,6 +2038,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdAllocaGen:
|
||||
ir_print_alloca_gen(irp, (IrInstructionAllocaGen *)instruction);
|
||||
break;
|
||||
case IrInstructionIdEndExpr:
|
||||
ir_print_end_expr(irp, (IrInstructionEndExpr *)instruction);
|
||||
break;
|
||||
}
|
||||
fprintf(irp->f, "\n");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user