mirror of
https://github.com/ziglang/zig.git
synced 2025-12-09 15:53:08 +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
|
migrate ir_build_var_decl_src to use ir_build_alloca_src and explicitly initialize
|
||||||
|
|
||||||
inferred comptime
|
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 TldExport;
|
||||||
struct IrAnalyze;
|
struct IrAnalyze;
|
||||||
struct ResultLoc;
|
struct ResultLoc;
|
||||||
|
struct ResultLocPeer;
|
||||||
|
|
||||||
enum X64CABIClass {
|
enum X64CABIClass {
|
||||||
X64CABIClass_Unknown,
|
X64CABIClass_Unknown,
|
||||||
@ -2127,6 +2128,8 @@ struct IrBasicBlock {
|
|||||||
const char *name_hint;
|
const char *name_hint;
|
||||||
size_t debug_id;
|
size_t debug_id;
|
||||||
size_t ref_count;
|
size_t ref_count;
|
||||||
|
// index into the basic block list
|
||||||
|
size_t index;
|
||||||
LLVMBasicBlockRef llvm_block;
|
LLVMBasicBlockRef llvm_block;
|
||||||
LLVMBasicBlockRef llvm_exit_block;
|
LLVMBasicBlockRef llvm_exit_block;
|
||||||
// The instruction that referenced this basic block and caused us to
|
// The instruction that referenced this basic block and caused us to
|
||||||
@ -2315,10 +2318,14 @@ enum IrInstructionId {
|
|||||||
IrInstructionIdUndeclaredIdent,
|
IrInstructionIdUndeclaredIdent,
|
||||||
IrInstructionIdAllocaSrc,
|
IrInstructionIdAllocaSrc,
|
||||||
IrInstructionIdAllocaGen,
|
IrInstructionIdAllocaGen,
|
||||||
|
IrInstructionIdEndExpr,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrInstruction {
|
struct IrInstruction {
|
||||||
IrInstructionId id;
|
IrInstructionId id;
|
||||||
|
// true if this instruction was generated by zig and not from user code
|
||||||
|
bool is_gen;
|
||||||
|
|
||||||
Scope *scope;
|
Scope *scope;
|
||||||
AstNode *source_node;
|
AstNode *source_node;
|
||||||
ConstExprValue value;
|
ConstExprValue value;
|
||||||
@ -2332,8 +2339,6 @@ struct IrInstruction {
|
|||||||
// with this child field.
|
// with this child field.
|
||||||
IrInstruction *child;
|
IrInstruction *child;
|
||||||
IrBasicBlock *owner_bb;
|
IrBasicBlock *owner_bb;
|
||||||
// true if this instruction was generated by zig and not from user code
|
|
||||||
bool is_gen;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrInstructionDeclVarSrc {
|
struct IrInstructionDeclVarSrc {
|
||||||
@ -3571,16 +3576,28 @@ struct IrInstructionAllocaGen {
|
|||||||
const char *name_hint;
|
const char *name_hint;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IrInstructionEndExpr {
|
||||||
|
IrInstruction base;
|
||||||
|
|
||||||
|
IrInstruction *value;
|
||||||
|
ResultLoc *result_loc;
|
||||||
|
LVal lval;
|
||||||
|
};
|
||||||
|
|
||||||
enum ResultLocId {
|
enum ResultLocId {
|
||||||
ResultLocIdInvalid,
|
ResultLocIdInvalid,
|
||||||
ResultLocIdNone,
|
ResultLocIdNone,
|
||||||
ResultLocIdVar,
|
ResultLocIdVar,
|
||||||
ResultLocIdReturn,
|
ResultLocIdReturn,
|
||||||
|
ResultLocIdPeer,
|
||||||
|
ResultLocIdPeerParent,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResultLoc {
|
struct ResultLoc {
|
||||||
ResultLocId id;
|
ResultLocId id;
|
||||||
IrInstruction *source_instruction;
|
IrInstruction *source_instruction;
|
||||||
|
IrInstruction *gen_instruction;
|
||||||
|
ZigType *implicit_elem_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResultLocNone {
|
struct ResultLocNone {
|
||||||
@ -3597,6 +3614,28 @@ struct ResultLocReturn {
|
|||||||
ResultLoc base;
|
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_ptr_index = 0;
|
||||||
static const size_t slice_len_index = 1;
|
static const size_t slice_len_index = 1;
|
||||||
|
|
||||||
|
|||||||
@ -5606,10 +5606,9 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
|||||||
case IrInstructionIdUndeclaredIdent:
|
case IrInstructionIdUndeclaredIdent:
|
||||||
case IrInstructionIdCallSrc:
|
case IrInstructionIdCallSrc:
|
||||||
case IrInstructionIdAllocaSrc:
|
case IrInstructionIdAllocaSrc:
|
||||||
zig_unreachable();
|
case IrInstructionIdEndExpr:
|
||||||
|
|
||||||
case IrInstructionIdAllocaGen:
|
case IrInstructionIdAllocaGen:
|
||||||
return nullptr;
|
zig_unreachable();
|
||||||
|
|
||||||
case IrInstructionIdDeclVarGen:
|
case IrInstructionIdDeclVarGen:
|
||||||
return ir_render_decl_var(g, executable, (IrInstructionDeclVarGen *)instruction);
|
return ir_render_decl_var(g, executable, (IrInstructionDeclVarGen *)instruction);
|
||||||
|
|||||||
483
src/ir.cpp
483
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();
|
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) {
|
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));
|
fprintf(irp->f, "%s ", ir_un_op_id_str(un_op_instruction->op_id));
|
||||||
ir_print_other_instruction(irp, un_op_instruction->value);
|
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;
|
return;
|
||||||
case ResultLocIdVar:
|
case ResultLocIdVar:
|
||||||
return ir_print_result_loc_var(irp, (ResultLocVar *)result_loc);
|
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();
|
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);
|
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) {
|
static void ir_print_int_to_err(IrPrint *irp, IrInstructionIntToErr *instruction) {
|
||||||
fprintf(irp->f, "inttoerr ");
|
fprintf(irp->f, "inttoerr ");
|
||||||
ir_print_other_instruction(irp, instruction->target);
|
ir_print_other_instruction(irp, instruction->target);
|
||||||
@ -2014,6 +2038,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
|||||||
case IrInstructionIdAllocaGen:
|
case IrInstructionIdAllocaGen:
|
||||||
ir_print_alloca_gen(irp, (IrInstructionAllocaGen *)instruction);
|
ir_print_alloca_gen(irp, (IrInstructionAllocaGen *)instruction);
|
||||||
break;
|
break;
|
||||||
|
case IrInstructionIdEndExpr:
|
||||||
|
ir_print_end_expr(irp, (IrInstructionEndExpr *)instruction);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
fprintf(irp->f, "\n");
|
fprintf(irp->f, "\n");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user