Skip to content

Commit 1bf72c6

Browse files
committed
copy elision using the ir system
1 parent 2b395d4 commit 1bf72c6

File tree

5 files changed

+967
-788
lines changed

5 files changed

+967
-788
lines changed

doc/langref.html.in

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5855,13 +5855,13 @@ fn add(a: i32, b: i32) i32 { return a + b; }
58555855
This function is a low level intrinsic with no safety mechanisms. Most code
58565856
should not use this function, instead using something like this:
58575857
</p>
5858-
<pre>{#syntax#}for (source[0...byte_count]) |b, i| dest[i] = b;{#endsyntax#}</pre>
5858+
<pre>{#syntax#}for (source[0..byte_count]) |b, i| dest[i] = b;{#endsyntax#}</pre>
58595859
<p>
58605860
The optimizer is intelligent enough to turn the above snippet into a memcpy.
58615861
</p>
58625862
<p>There is also a standard library function for this:</p>
58635863
<pre>{#syntax#}const mem = @import("std").mem;
5864-
mem.copy(u8, dest[0...byte_count], source[0...byte_count]);{#endsyntax#}</pre>
5864+
mem.copy(u8, dest[0..byte_count], source[0..byte_count]);{#endsyntax#}</pre>
58655865
{#header_close#}
58665866
{#header_open|@memset#}
58675867
<pre>{#syntax#}@memset(dest: [*]u8, c: u8, byte_count: usize){#endsyntax#}</pre>
@@ -5872,7 +5872,7 @@ mem.copy(u8, dest[0...byte_count], source[0...byte_count]);{#endsyntax#}</pre>
58725872
This function is a low level intrinsic with no safety mechanisms. Most
58735873
code should not use this function, instead using something like this:
58745874
</p>
5875-
<pre>{#syntax#}for (dest[0...byte_count]) |*b| b.* = c;{#endsyntax#}</pre>
5875+
<pre>{#syntax#}for (dest[0..byte_count]) |*b| b.* = c;{#endsyntax#}</pre>
58765876
<p>
58775877
The optimizer is intelligent enough to turn the above snippet into a memset.
58785878
</p>
@@ -6514,9 +6514,10 @@ pub const TypeInfo = union(TypeId).{
65146514
{#code_end#}
65156515
{#header_close#}
65166516
{#header_open|@typeName#}
6517-
<pre>{#syntax#}@typeName(T: type) []u8{#endsyntax#}</pre>
6517+
<pre>{#syntax#}@typeName(T: type) [N]u8{#endsyntax#}</pre>
65186518
<p>
6519-
This function returns the string representation of a type.
6519+
This function returns the string representation of a type, as
6520+
an array. It is equivalent to a string literal of the type name.
65206521
</p>
65216522

65226523
{#header_close#}

src/all_types.hpp

Lines changed: 105 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct TypeStructField;
3333
struct CodeGen;
3434
struct ConstExprValue;
3535
struct IrInstruction;
36-
struct IrInstructionCast;
36+
struct IrInstructionAlloca;
3737
struct IrBasicBlock;
3838
struct ScopeDecls;
3939
struct ZigWindowsSDK;
@@ -68,6 +68,8 @@ struct IrExecutable {
6868
Scope *begin_scope;
6969
ZigList<Tld *> tld_list;
7070

71+
IrInstruction *return_result_loc;
72+
7173
IrInstruction *coro_handle;
7274
IrInstruction *atomic_state_field_ptr; // this one is shared and in the promise
7375
IrInstruction *coro_result_ptr_field_ptr;
@@ -1320,7 +1322,7 @@ struct ZigFn {
13201322
AstNode *fn_no_inline_set_node;
13211323
AstNode *fn_static_eval_set_node;
13221324

1323-
ZigList<IrInstruction *> alloca_list;
1325+
ZigList<IrInstructionAlloca *> alloca_list;
13241326
ZigList<ZigVar *> variable_list;
13251327

13261328
Buf *section_name;
@@ -1885,6 +1887,7 @@ struct ScopeBlock {
18851887
Buf *name;
18861888
IrBasicBlock *end_block;
18871889
IrInstruction *is_comptime;
1890+
IrInstruction *result_loc;
18881891
ZigList<IrInstruction *> *incoming_values;
18891892
ZigList<IrBasicBlock *> *incoming_blocks;
18901893

@@ -1937,6 +1940,7 @@ struct ScopeLoop {
19371940
IrBasicBlock *break_block;
19381941
IrBasicBlock *continue_block;
19391942
IrInstruction *is_comptime;
1943+
IrInstruction *result_loc;
19401944
ZigList<IrInstruction *> *incoming_values;
19411945
ZigList<IrBasicBlock *> *incoming_blocks;
19421946
};
@@ -2029,6 +2033,8 @@ struct IrBasicBlock {
20292033

20302034
enum IrInstructionId {
20312035
IrInstructionIdInvalid,
2036+
IrInstructionIdDeclVarSrc,
2037+
IrInstructionIdDeclVarGen,
20322038
IrInstructionIdBr,
20332039
IrInstructionIdCondBr,
20342040
IrInstructionIdSwitchBr,
@@ -2037,7 +2043,6 @@ enum IrInstructionId {
20372043
IrInstructionIdPhi,
20382044
IrInstructionIdUnOp,
20392045
IrInstructionIdBinOp,
2040-
IrInstructionIdDeclVar,
20412046
IrInstructionIdLoadPtr,
20422047
IrInstructionIdStorePtr,
20432048
IrInstructionIdFieldPtr,
@@ -2166,9 +2171,16 @@ enum IrInstructionId {
21662171
IrInstructionIdMarkErrRetTracePtr,
21672172
IrInstructionIdSqrt,
21682173
IrInstructionIdErrSetCast,
2169-
IrInstructionIdToBytes,
2170-
IrInstructionIdFromBytes,
21712174
IrInstructionIdCheckRuntimeScope,
2175+
IrInstructionIdResultErrorUnionPayload,
2176+
IrInstructionIdResultReturn,
2177+
IrInstructionIdResultBytesToSlice,
2178+
IrInstructionIdResultSliceToBytes,
2179+
IrInstructionIdResultParam,
2180+
IrInstructionIdResultPtrCast,
2181+
IrInstructionIdLoadResult,
2182+
IrInstructionIdStoreResult,
2183+
IrInstructionIdAlloca,
21722184
};
21732185

21742186
struct IrInstruction {
@@ -2190,6 +2202,21 @@ struct IrInstruction {
21902202
bool is_gen;
21912203
};
21922204

2205+
struct IrInstructionDeclVarSrc {
2206+
IrInstruction base;
2207+
2208+
ZigVar *var;
2209+
IrInstruction *var_type;
2210+
IrInstruction *align_value;
2211+
IrInstruction *ptr;
2212+
};
2213+
2214+
struct IrInstructionDeclVarGen {
2215+
IrInstruction base;
2216+
2217+
ZigVar *var;
2218+
};
2219+
21932220
struct IrInstructionCondBr {
21942221
IrInstruction base;
21952222

@@ -2303,25 +2330,30 @@ struct IrInstructionBinOp {
23032330
bool safety_check_on;
23042331
};
23052332

2306-
struct IrInstructionDeclVar {
2333+
struct IrInstructionLoadPtr {
23072334
IrInstruction base;
23082335

2309-
ZigVar *var;
2310-
IrInstruction *var_type;
2311-
IrInstruction *align_value;
2312-
IrInstruction *init_value;
2336+
IrInstruction *ptr;
23132337
};
23142338

2315-
struct IrInstructionLoadPtr {
2339+
struct IrInstructionStorePtr {
23162340
IrInstruction base;
23172341

23182342
IrInstruction *ptr;
2343+
IrInstruction *value;
23192344
};
23202345

2321-
struct IrInstructionStorePtr {
2346+
struct IrInstructionLoadResult {
23222347
IrInstruction base;
23232348

23242349
IrInstruction *ptr;
2350+
IrInstruction *result_loc;
2351+
};
2352+
2353+
struct IrInstructionStoreResult {
2354+
IrInstruction base;
2355+
2356+
IrInstruction *result_loc;
23252357
IrInstruction *value;
23262358
};
23272359

@@ -2374,13 +2406,12 @@ struct IrInstructionCall {
23742406
ZigFn *fn_entry;
23752407
size_t arg_count;
23762408
IrInstruction **args;
2377-
bool is_comptime;
2378-
LLVMValueRef tmp_ptr;
2379-
FnInline fn_inline;
2380-
bool is_async;
2381-
23822409
IrInstruction *async_allocator;
23832410
IrInstruction *new_stack;
2411+
IrInstruction *result_loc;
2412+
FnInline fn_inline;
2413+
bool is_async;
2414+
bool is_comptime;
23842415
};
23852416

23862417
struct IrInstructionConst {
@@ -2401,23 +2432,24 @@ struct IrInstructionCast {
24012432
IrInstruction base;
24022433

24032434
IrInstruction *value;
2435+
IrInstruction *result_loc;
24042436
ZigType *dest_type;
24052437
CastOp cast_op;
2406-
LLVMValueRef tmp_ptr;
24072438
};
24082439

24092440
struct IrInstructionContainerInitList {
24102441
IrInstruction base;
24112442

24122443
IrInstruction *container_type;
2444+
IrInstruction *result_loc;
24132445
size_t item_count;
24142446
IrInstruction **items;
2415-
LLVMValueRef tmp_ptr;
24162447
};
24172448

24182449
struct IrInstructionContainerInitFieldsField {
24192450
Buf *name;
24202451
IrInstruction *value;
2452+
IrInstruction *result_loc;
24212453
AstNode *source_node;
24222454
TypeStructField *type_struct_field;
24232455
};
@@ -2439,9 +2471,9 @@ struct IrInstructionStructInit {
24392471
IrInstruction base;
24402472

24412473
ZigType *struct_type;
2474+
IrInstruction *result_loc;
24422475
size_t field_count;
24432476
IrInstructionStructInitField *fields;
2444-
LLVMValueRef tmp_ptr;
24452477
};
24462478

24472479
struct IrInstructionUnionInit {
@@ -2450,7 +2482,7 @@ struct IrInstructionUnionInit {
24502482
ZigType *union_type;
24512483
TypeUnionField *field;
24522484
IrInstruction *init_value;
2453-
LLVMValueRef tmp_ptr;
2485+
IrInstruction *result_loc;
24542486
};
24552487

24562488
struct IrInstructionUnreachable {
@@ -2523,9 +2555,9 @@ struct IrInstructionSliceType {
25232555
IrInstruction base;
25242556

25252557
IrInstruction *align_value;
2558+
IrInstruction *child_type;
25262559
bool is_const;
25272560
bool is_volatile;
2528-
IrInstruction *child_type;
25292561
};
25302562

25312563
struct IrInstructionAsm {
@@ -2600,7 +2632,7 @@ struct IrInstructionRef {
26002632
IrInstruction base;
26012633

26022634
IrInstruction *value;
2603-
LLVMValueRef tmp_ptr;
2635+
IrInstruction *result_loc;
26042636
bool is_const;
26052637
bool is_volatile;
26062638
};
@@ -2662,15 +2694,14 @@ struct IrInstructionCmpxchg {
26622694
IrInstruction *new_value;
26632695
IrInstruction *success_order_value;
26642696
IrInstruction *failure_order_value;
2697+
IrInstruction *result_loc;
26652698

26662699
// if this instruction gets to runtime then we know these values:
26672700
ZigType *type;
26682701
AtomicOrder success_order;
26692702
AtomicOrder failure_order;
26702703

26712704
bool is_weak;
2672-
2673-
LLVMValueRef tmp_ptr;
26742705
};
26752706

26762707
struct IrInstructionFence {
@@ -2710,19 +2741,6 @@ struct IrInstructionErrSetCast {
27102741
IrInstruction *target;
27112742
};
27122743

2713-
struct IrInstructionToBytes {
2714-
IrInstruction base;
2715-
2716-
IrInstruction *target;
2717-
};
2718-
2719-
struct IrInstructionFromBytes {
2720-
IrInstruction base;
2721-
2722-
IrInstruction *dest_child_type;
2723-
IrInstruction *target;
2724-
};
2725-
27262744
struct IrInstructionIntToFloat {
27272745
IrInstruction base;
27282746

@@ -2778,8 +2796,8 @@ struct IrInstructionSlice {
27782796
IrInstruction *ptr;
27792797
IrInstruction *start;
27802798
IrInstruction *end;
2799+
IrInstruction *result_loc;
27812800
bool safety_check_on;
2782-
LLVMValueRef tmp_ptr;
27832801
};
27842802

27852803
struct IrInstructionMemberCount {
@@ -2867,21 +2885,21 @@ struct IrInstructionOptionalWrap {
28672885
IrInstruction base;
28682886

28692887
IrInstruction *value;
2870-
LLVMValueRef tmp_ptr;
2888+
IrInstruction *result_loc;
28712889
};
28722890

28732891
struct IrInstructionErrWrapPayload {
28742892
IrInstruction base;
28752893

28762894
IrInstruction *value;
2877-
LLVMValueRef tmp_ptr;
2895+
IrInstruction *result_loc;
28782896
};
28792897

28802898
struct IrInstructionErrWrapCode {
28812899
IrInstruction base;
28822900

28832901
IrInstruction *value;
2884-
LLVMValueRef tmp_ptr;
2902+
IrInstruction *result_loc;
28852903
};
28862904

28872905
struct IrInstructionFnProto {
@@ -2983,6 +3001,7 @@ struct IrInstructionTypeName {
29833001
IrInstruction base;
29843002

29853003
IrInstruction *type_value;
3004+
IrInstruction *result_loc;
29863005
};
29873006

29883007
enum LVal {
@@ -3007,6 +3026,7 @@ struct IrInstructionTagName {
30073026
IrInstruction base;
30083027

30093028
IrInstruction *target;
3029+
IrInstruction *result_loc;
30103030
};
30113031

30123032
struct IrInstructionTagType {
@@ -3264,6 +3284,49 @@ struct IrInstructionCheckRuntimeScope {
32643284
IrInstruction *is_comptime;
32653285
};
32663286

3287+
struct IrInstructionResultErrorUnionPayload {
3288+
IrInstruction base;
3289+
3290+
IrInstruction *prev_result_loc;
3291+
};
3292+
3293+
struct IrInstructionResultBytesToSlice {
3294+
IrInstruction base;
3295+
3296+
IrInstruction *prev_result_loc;
3297+
};
3298+
3299+
struct IrInstructionResultSliceToBytes {
3300+
IrInstruction base;
3301+
3302+
IrInstruction *elem_type;
3303+
IrInstruction *prev_result_loc;
3304+
};
3305+
3306+
struct IrInstructionResultReturn {
3307+
IrInstruction base;
3308+
};
3309+
3310+
struct IrInstructionResultParam {
3311+
IrInstruction base;
3312+
3313+
IrInstruction *fn_ref;
3314+
size_t param_index;
3315+
};
3316+
3317+
struct IrInstructionResultPtrCast {
3318+
IrInstruction base;
3319+
3320+
IrInstruction *elem_type;
3321+
IrInstruction *prev_result_loc;
3322+
};
3323+
3324+
struct IrInstructionAlloca {
3325+
IrInstruction base;
3326+
3327+
IrInstruction *ty;
3328+
};
3329+
32673330
static const size_t slice_ptr_index = 0;
32683331
static const size_t slice_len_index = 1;
32693332

0 commit comments

Comments
 (0)