Skip to content

Commit 43aedd6

Browse files
committed
---
yaml --- r: 14343 b: refs/heads/try c: 54d7bff h: refs/heads/master i: 14341: d21a26c 14339: f079661 14335: 4cc2ad4 v: v3
1 parent c374078 commit 43aedd6

File tree

8 files changed

+320
-94
lines changed

8 files changed

+320
-94
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: db62154062534a61b618f46d4c8715479ce150af
5+
refs/heads/try: 54d7bffbb8f79d4680b6200ee50e0ca8eb2dc3c3
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/comp/back/upcall.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type upcalls =
1414
validate_box: ValueRef,
1515
shared_malloc: ValueRef,
1616
shared_free: ValueRef,
17+
shared_realloc: ValueRef,
1718
mark: ValueRef,
1819
create_shared_type_desc: ValueRef,
1920
free_shared_type_desc: ValueRef,
@@ -36,15 +37,17 @@ fn declare_upcalls(targ_cfg: @session::config,
3637
_tn: type_names,
3738
tydesc_type: TypeRef,
3839
llmod: ModuleRef) -> @upcalls {
39-
fn decl(llmod: ModuleRef, name: str, tys: [TypeRef], rv: TypeRef) ->
40+
fn decl(llmod: ModuleRef, prefix: str, name: str,
41+
tys: [TypeRef], rv: TypeRef) ->
4042
ValueRef {
4143
let arg_tys: [TypeRef] = [];
4244
for t: TypeRef in tys { arg_tys += [t]; }
4345
let fn_ty = T_fn(arg_tys, rv);
44-
ret base::decl_cdecl_fn(llmod, "upcall_" + name, fn_ty);
46+
ret base::decl_cdecl_fn(llmod, prefix + name, fn_ty);
4547
}
46-
let d = bind decl(llmod, _, _, _);
47-
let dv = bind decl(llmod, _, _, T_void());
48+
let d = bind decl(llmod, "upcall_", _, _, _);
49+
let dv = bind decl(llmod, "upcall_", _, _, T_void());
50+
let dvi = bind decl(llmod, "upcall_intrinsic_", _, _, T_void());
4851

4952
let int_t = T_int(targ_cfg);
5053
let size_t = T_size_t(targ_cfg);
@@ -65,6 +68,9 @@ fn declare_upcalls(targ_cfg: @session::config,
6568
T_ptr(T_i8())),
6669
shared_free:
6770
dv("shared_free", [T_ptr(T_i8())]),
71+
shared_realloc:
72+
d("shared_realloc", [T_ptr(T_i8()), size_t],
73+
T_ptr(T_i8())),
6874
mark:
6975
d("mark", [T_ptr(T_i8())], int_t),
7076
create_shared_type_desc:
@@ -83,7 +89,7 @@ fn declare_upcalls(targ_cfg: @session::config,
8389
vec_grow:
8490
dv("vec_grow", [T_ptr(T_ptr(opaque_vec_t)), int_t]),
8591
vec_push:
86-
dv("vec_push",
92+
dvi("vec_push",
8793
[T_ptr(T_ptr(opaque_vec_t)), T_ptr(tydesc_type),
8894
T_ptr(T_i8())]),
8995
cmp_type:

branches/try/src/rt/intrinsics/intrinsics.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,57 @@ rust_intrinsic_leak(void *retptr,
112112
void *thing)
113113
{
114114
}
115+
116+
extern "C" CDECL void *
117+
upcall_shared_realloc(void *ptr, size_t size);
118+
119+
inline void reserve_vec_fast(rust_vec **vpp, size_t size) {
120+
if (size > (*vpp)->alloc) {
121+
size_t new_size = next_power_of_two(size);
122+
size_t alloc_size = new_size + sizeof(rust_vec);
123+
// Because this is called from an intrinsic we need to use
124+
// the exported API
125+
*vpp = (rust_vec*)upcall_shared_realloc(*vpp, alloc_size);
126+
(*vpp)->alloc = new_size;
127+
}
128+
}
129+
130+
// Copy elements from one vector to another,
131+
// dealing with reference counts
132+
static inline void
133+
copy_elements(type_desc *elem_t,
134+
void *pdst, void *psrc, size_t n) {
135+
char *dst = (char *)pdst, *src = (char *)psrc;
136+
memmove(dst, src, n);
137+
138+
// increment the refcount of each element of the vector
139+
if (elem_t->take_glue) {
140+
glue_fn *take_glue = elem_t->take_glue;
141+
size_t elem_size = elem_t->size;
142+
const type_desc **tydescs = elem_t->first_param;
143+
for (char *p = dst; p < dst+n; p += elem_size) {
144+
take_glue(NULL, NULL, tydescs, p);
145+
}
146+
}
147+
}
148+
149+
// Because this is used so often, and it calls take glue that must run
150+
// on the rust stack, it is statically compiled into every crate.
151+
extern "C" CDECL void
152+
upcall_intrinsic_vec_push(rust_vec** vp,
153+
type_desc* elt_ty, void* elt) {
154+
155+
size_t new_sz = (*vp)->fill + elt_ty->size;
156+
reserve_vec_fast(vp, new_sz);
157+
rust_vec* v = *vp;
158+
copy_elements(elt_ty, &v->data[0] + v->fill,
159+
elt, elt_ty->size);
160+
v->fill += elt_ty->size;
161+
}
162+
163+
// FIXME: Transational. Remove
164+
extern "C" CDECL void
165+
upcall_vec_push(rust_vec** vp,
166+
type_desc* elt_ty, void* elt) {
167+
upcall_intrinsic_vec_push(vp, elt_ty, elt);
168+
}

branches/try/src/rt/intrinsics/intrinsics.i386.ll.in

Lines changed: 115 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@
22
; target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
33
target triple = "@CFG_TARGET_TRIPLE@"
44

5-
%struct.type_desc = type { %struct.type_desc**, i32, i32, void (i8*, i8*, %struct.type_desc**, i8*)*, void (i8*, i8*, %struct.type_desc**, i8*)*, void (i8*, i8*, %struct.type_desc**, i8*)*, i8*, void (i8*, i8*, %struct.type_desc**, i8*)*, void (i8*, i8*, %struct.type_desc**, i8*)*, i32, void (i8*, i8*, %struct.type_desc**, i8*, i8*, i8)*, i8*, %struct.rust_shape_tables*, i32, i32, %struct.UT_hash_handle, i32, [0 x %struct.type_desc*] }
5+
%struct.type_desc = type { %struct.type_desc**, i32, i32, void (i8*, i8*, %struct.type_desc**, i8*)*, void (i8*, i8*, %struct.type_desc**, i8*)*, void (i8*, i8*, %struct.type_desc**, i8*)*, i8*, void (i8*, i8*, %struct.type_desc**, i8*)*, void (i8*, i8*, %struct.type_desc**, i8*)*, i32, i8*, i8*, %struct.rust_shape_tables*, i32, i32, %struct.UT_hash_handle, i32, [0 x %struct.type_desc*] }
66
%struct.rust_shape_tables = type { i8*, i8* }
77
%struct.UT_hash_handle = type { %struct.UT_hash_table*, i8*, i8*, %struct.UT_hash_handle*, %struct.UT_hash_handle*, i8*, i32, i32 }
88
%struct.UT_hash_table = type { %struct.UT_hash_bucket*, i32, i32, i32, %struct.UT_hash_handle*, i32, i32, i32, i32, i32 }
99
%struct.UT_hash_bucket = type { %struct.UT_hash_handle*, i32, i32 }
1010
%struct.rust_vec = type { i32, i32, [0 x i8] }
1111
%struct.rust_fn = type { i32*, %struct.rust_box* }
1212
%struct.rust_box = type opaque
13-
%struct.rust_task = type { %struct.rust_task_user, i32, [8 x i8], %class.context, %struct.stk_seg*, i32, %struct.rust_task_thread*, %class.rust_crate_cache*, %class.rust_kernel*, i8*, %class.rust_task_list*, %struct.rust_cond*, i8*, %struct.rust_task*, i32, i32, i32*, %class.memory_region, %class.boxed_region, i8, i8, i8, %class.lock_and_signal, %class.hash_map.4, %class.rust_obstack, i32, %"class.debug::task_debug_info", i32, [4 x i8] }
14-
%struct.rust_task_user = type { i32, i32, %struct.chan_handle, i32 }
13+
%struct.rust_task = type { i32, i32, i8, %struct.chan_handle, [12 x i8], %class.context, %struct.stk_seg*, i32, %class.rust_scheduler*, %struct.rust_task_thread*, %class.rust_crate_cache*, %class.rust_kernel*, i8*, %class.rust_task_list*, %struct.rust_cond*, i8*, %struct.rust_task*, i32, i32, i32*, %class.memory_region, %class.boxed_region, i8, i8, %class.lock_and_signal, %class.hash_map.3, %class.rust_obstack, i32, %"class.debug::task_debug_info", i32, i8, i8, %struct.stk_seg*, i32, i32, %class.rust_port_selector, [8 x i8] }
1514
%struct.chan_handle = type { i32, i32 }
1615
%class.context = type { %struct.registers_t, %class.context*, [12 x i8] }
1716
%struct.registers_t = type { i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i16, i16, i32, i32, [12 x i8] }
18-
%struct.stk_seg = type { %struct.stk_seg*, %struct.stk_seg*, i32, i32, i32, [0 x i8] }
19-
%struct.rust_task_thread = type { %class.rust_thread, i32, %class.rust_log, i32, %class.rust_srv*, i8*, %class.rust_task_list, %class.rust_task_list, %class.rust_task_list, %class.rust_task_list, %class.rust_crate_cache, %struct.randctx, %class.rust_kernel*, i32, i32, %class.lock_and_signal, i32, %union.pthread_attr_t, %struct.rust_env*, [12 x i8], %class.context, i8, [15 x i8] }
20-
%class.rust_thread = type { i32 (...)**, i8, i32 }
17+
%struct.stk_seg = type { %struct.stk_seg*, %struct.stk_seg*, i32, i32, i32, i32, [0 x i8] }
18+
%class.rust_scheduler = type opaque
19+
%struct.rust_task_thread = type { %class.rust_thread, i32, %class.rust_log, i32, %class.rust_srv*, i8*, %class.rust_task_list, %class.rust_task_list, %class.rust_task_list, %class.rust_task_list, %class.rust_crate_cache, %struct.randctx, %class.rust_kernel*, %class.rust_scheduler*, i32, i32, %class.lock_and_signal, i32, %union.pthread_attr_t, %struct.rust_env*, [8 x i8], %class.context, i8, %struct.stk_seg*, %struct.stk_seg*, [4 x i8] }
20+
%class.rust_thread = type { i32 (...)**, i32, i32 }
2121
%class.rust_log = type { i32 (...)**, %class.rust_srv*, %struct.rust_task_thread*, i8 }
2222
%class.rust_srv = type { i32 (...)**, %struct.rust_env*, %class.memory_region }
2323
%struct.rust_env = type { i32, i32, i32, i8*, i8, i8, i8* }
@@ -36,24 +36,30 @@ target triple = "@CFG_TARGET_TRIPLE@"
3636
%class.rust_crate_cache = type { %struct.type_desc*, %struct.rust_hashable_dict*, %struct.rust_task_thread*, i32 }
3737
%struct.rust_hashable_dict = type { %struct.UT_hash_handle, [0 x i8*] }
3838
%struct.randctx = type { i32, [256 x i32], [256 x i32], i32, i32, i32 }
39-
%class.rust_kernel = type { i32 (...)**, %class.memory_region, %class.rust_log, %class.rust_srv*, %class.lock_and_signal, %class.array_list.3, %struct.randctx, i32, %class.hash_map, i32, i32, i32, %struct.rust_env* }
40-
%class.array_list.3 = type { i32, %struct.rust_task_thread**, i32 }
39+
%class.rust_kernel = type { %class.memory_region, %class.rust_log, %class.rust_srv*, %class.lock_and_signal, i32, i32, %class.hash_map, %class.lock_and_signal, i32, %class.lock_and_signal, i32, i32, %"class.std::map", %struct.rust_env* }
4140
%class.hash_map = type { %"struct.hash_map<int, rust_task *>::map_entry"* }
4241
%"struct.hash_map<int, rust_task *>::map_entry" = type opaque
42+
%"class.std::map" = type { %"class.std::_Rb_tree" }
43+
%"class.std::_Rb_tree" = type { %"struct.std::_Rb_tree<int, std::pair<const int, rust_scheduler *>, std::_Select1st<std::pair<const int, rust_scheduler *> >, std::less<int>, std::allocator<std::pair<const int, rust_scheduler *> > >::_Rb_tree_impl" }
44+
%"struct.std::_Rb_tree<int, std::pair<const int, rust_scheduler *>, std::_Select1st<std::pair<const int, rust_scheduler *> >, std::less<int>, std::allocator<std::pair<const int, rust_scheduler *> > >::_Rb_tree_impl" = type { %"struct.std::less", %"struct.std::_Rb_tree_node_base", i32 }
45+
%"struct.std::less" = type { i8 }
46+
%"struct.std::_Rb_tree_node_base" = type { i32, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"* }
4347
%union.pthread_attr_t = type { i32, [32 x i8] }
4448
%struct.rust_cond = type { i8 }
4549
%class.boxed_region = type { %class.memory_region*, %struct.rust_opaque_box* }
4650
%struct.rust_opaque_box = type { i32, %struct.type_desc*, %struct.rust_opaque_box*, %struct.rust_opaque_box* }
47-
%class.hash_map.4 = type { %"struct.hash_map<int, rust_port *>::map_entry"* }
51+
%class.hash_map.3 = type { %"struct.hash_map<int, rust_port *>::map_entry"* }
4852
%"struct.hash_map<int, rust_port *>::map_entry" = type opaque
4953
%class.rust_obstack = type { %struct.rust_obstack_chunk*, %struct.rust_task* }
5054
%struct.rust_obstack_chunk = type { %struct.rust_obstack_chunk*, i32, i32, i32, [0 x i8] }
51-
%"class.debug::task_debug_info" = type { %"class.std::map" }
52-
%"class.std::map" = type { %"class.std::_Rb_tree" }
53-
%"class.std::_Rb_tree" = type { %"struct.std::_Rb_tree<void *, std::pair<void *const, std::basic_string<char> >, std::_Select1st<std::pair<void *const, std::basic_string<char> > >, std::less<void *>, std::allocator<std::pair<void *const, std::basic_string<char> > > >::_Rb_tree_impl" }
54-
%"struct.std::_Rb_tree<void *, std::pair<void *const, std::basic_string<char> >, std::_Select1st<std::pair<void *const, std::basic_string<char> > >, std::less<void *>, std::allocator<std::pair<void *const, std::basic_string<char> > > >::_Rb_tree_impl" = type { %"struct.std::less", %"struct.std::_Rb_tree_node_base", i32 }
55-
%"struct.std::less" = type { i8 }
56-
%"struct.std::_Rb_tree_node_base" = type { i32, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"* }
55+
%"class.debug::task_debug_info" = type { %"class.std::map.4" }
56+
%"class.std::map.4" = type { %"class.std::_Rb_tree.5" }
57+
%"class.std::_Rb_tree.5" = type { %"struct.std::_Rb_tree<void *, std::pair<void *const, std::basic_string<char> >, std::_Select1st<std::pair<void *const, std::basic_string<char> > >, std::less<void *>, std::allocator<std::pair<void *const, std::basic_string<char> > > >::_Rb_tree_impl" }
58+
%"struct.std::_Rb_tree<void *, std::pair<void *const, std::basic_string<char> >, std::_Select1st<std::pair<void *const, std::basic_string<char> > >, std::less<void *>, std::allocator<std::pair<void *const, std::basic_string<char> > > >::_Rb_tree_impl" = type { %"struct.std::less.9", %"struct.std::_Rb_tree_node_base", i32 }
59+
%"struct.std::less.9" = type { i8 }
60+
%class.rust_port_selector = type { %class.rust_port**, i32, %class.lock_and_signal }
61+
%class.rust_port = type { i32, i32, %class.rust_kernel*, %struct.rust_task*, i32, %class.circular_buffer, %class.lock_and_signal }
62+
%class.circular_buffer = type { %class.rust_kernel*, i32, i32, i32, i32, i8* }
5763

5864
define void @rust_intrinsic_vec_len(i32* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, %struct.rust_vec** nocapture %vp) nounwind {
5965
entry:
@@ -121,27 +127,113 @@ entry:
121127
declare void @rust_task_yield(%struct.rust_task*, i8*)
122128

123129
define void @rust_intrinsic_memmove(i8* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, i8* nocapture %dst, i8* nocapture %src, i32 %count) nounwind {
124-
%1 = getelementptr inbounds %struct.type_desc* %ty, i32 0, i32 1
125-
%2 = load i32* %1, align 4, !tbaa !3
126-
%3 = mul i32 %2, %count
127-
tail call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %3, i32 1, i1 false)
130+
entry:
131+
%size = getelementptr inbounds %struct.type_desc* %ty, i32 0, i32 1
132+
%0 = load i32* %size, align 4, !tbaa !3
133+
%mul = mul i32 %0, %count
134+
tail call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %mul, i32 1, i1 false)
128135
ret void
129136
}
130137

131138
define void @rust_intrinsic_memcpy(i8* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, i8* nocapture %dst, i8* nocapture %src, i32 %count) nounwind {
132-
%1 = getelementptr inbounds %struct.type_desc* %ty, i32 0, i32 1
133-
%2 = load i32* %1, align 4, !tbaa !3
134-
%3 = mul i32 %2, %count
135-
tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %3, i32 1, i1 false)
139+
entry:
140+
%size = getelementptr inbounds %struct.type_desc* %ty, i32 0, i32 1
141+
%0 = load i32* %size, align 4, !tbaa !3
142+
%mul = mul i32 %0, %count
143+
tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %mul, i32 1, i1 false)
136144
ret void
137145
}
138146

139147
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
140148

141149
define void @rust_intrinsic_leak(i8* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, i8* nocapture %thing) nounwind readnone {
150+
entry:
142151
ret void
143152
}
144153

154+
define void @upcall_intrinsic_vec_push(%struct.rust_vec** nocapture %vp, %struct.type_desc* nocapture %elt_ty, i8* nocapture %elt) {
155+
entry:
156+
%0 = load %struct.rust_vec** %vp, align 4, !tbaa !0
157+
%fill = getelementptr inbounds %struct.rust_vec* %0, i32 0, i32 0
158+
%1 = load i32* %fill, align 4, !tbaa !3
159+
%size = getelementptr inbounds %struct.type_desc* %elt_ty, i32 0, i32 1
160+
%2 = load i32* %size, align 4, !tbaa !3
161+
%add = add i32 %2, %1
162+
%alloc.i = getelementptr inbounds %struct.rust_vec* %0, i32 0, i32 1
163+
%3 = load i32* %alloc.i, align 4, !tbaa !3
164+
%cmp.i = icmp ult i32 %3, %add
165+
br i1 %cmp.i, label %if.then.i, label %_Z16reserve_vec_fastPP8rust_vecj.exit
166+
167+
if.then.i: ; preds = %entry
168+
%sub.i.i = add i32 %add, -1
169+
%shr.i.i = lshr i32 %sub.i.i, 1
170+
%or.i.i = or i32 %shr.i.i, %sub.i.i
171+
%shr1.i.i = lshr i32 %or.i.i, 2
172+
%or2.i.i = or i32 %shr1.i.i, %or.i.i
173+
%shr3.i.i = lshr i32 %or2.i.i, 4
174+
%or4.i.i = or i32 %shr3.i.i, %or2.i.i
175+
%shr5.i.i = lshr i32 %or4.i.i, 8
176+
%or6.i.i = or i32 %shr5.i.i, %or4.i.i
177+
%shr7.i.i = lshr i32 %or6.i.i, 16
178+
%or8.i.i = or i32 %shr7.i.i, %or6.i.i
179+
%add.i.i = add i32 %or8.i.i, 1
180+
%add.i = add i32 %or8.i.i, 9
181+
%4 = bitcast %struct.rust_vec* %0 to i8*
182+
%call1.i = tail call i8* @upcall_shared_realloc(i8* %4, i32 %add.i)
183+
%5 = bitcast i8* %call1.i to %struct.rust_vec*
184+
store %struct.rust_vec* %5, %struct.rust_vec** %vp, align 4, !tbaa !0
185+
%alloc2.i = getelementptr inbounds i8* %call1.i, i32 4
186+
%6 = bitcast i8* %alloc2.i to i32*
187+
store i32 %add.i.i, i32* %6, align 4, !tbaa !3
188+
%.pr = load i32* %size, align 4
189+
%fill1.phi.trans.insert = bitcast i8* %call1.i to i32*
190+
%.pre = load i32* %fill1.phi.trans.insert, align 4, !tbaa !3
191+
br label %_Z16reserve_vec_fastPP8rust_vecj.exit
192+
193+
_Z16reserve_vec_fastPP8rust_vecj.exit: ; preds = %entry, %if.then.i
194+
%7 = phi i32 [ %1, %entry ], [ %.pre, %if.then.i ]
195+
%8 = phi %struct.rust_vec* [ %0, %entry ], [ %5, %if.then.i ]
196+
%9 = phi i32 [ %2, %entry ], [ %.pr, %if.then.i ]
197+
%fill1 = getelementptr inbounds %struct.rust_vec* %8, i32 0, i32 0
198+
%add.ptr = getelementptr inbounds %struct.rust_vec* %8, i32 0, i32 2, i32 %7
199+
tail call void @llvm.memmove.p0i8.p0i8.i32(i8* %add.ptr, i8* %elt, i32 %9, i32 1, i1 false)
200+
%take_glue.i = getelementptr inbounds %struct.type_desc* %elt_ty, i32 0, i32 3
201+
%10 = load void (i8*, i8*, %struct.type_desc**, i8*)** %take_glue.i, align 4, !tbaa !0
202+
%tobool.i = icmp eq void (i8*, i8*, %struct.type_desc**, i8*)* %10, null
203+
br i1 %tobool.i, label %_ZL13copy_elementsP9type_descPvS1_j.exit, label %if.then.i6
204+
205+
if.then.i6: ; preds = %_Z16reserve_vec_fastPP8rust_vecj.exit
206+
%11 = load i32* %size, align 4, !tbaa !3
207+
%first_param.i = getelementptr inbounds %struct.type_desc* %elt_ty, i32 0, i32 0
208+
%12 = load %struct.type_desc*** %first_param.i, align 4, !tbaa !0
209+
%add.ptr.sum = add i32 %7, %9
210+
%add.ptr.i = getelementptr inbounds %struct.rust_vec* %8, i32 0, i32 2, i32 %add.ptr.sum
211+
%cmp4.i = icmp sgt i32 %9, 0
212+
br i1 %cmp4.i, label %for.body.i, label %_ZL13copy_elementsP9type_descPvS1_j.exit
213+
214+
for.body.i: ; preds = %if.then.i6, %for.body.i
215+
%p.05.i = phi i8* [ %add.ptr3.i, %for.body.i ], [ %add.ptr, %if.then.i6 ]
216+
tail call void %10(i8* null, i8* null, %struct.type_desc** %12, i8* %p.05.i)
217+
%add.ptr3.i = getelementptr inbounds i8* %p.05.i, i32 %11
218+
%cmp.i7 = icmp ult i8* %add.ptr3.i, %add.ptr.i
219+
br i1 %cmp.i7, label %for.body.i, label %_ZL13copy_elementsP9type_descPvS1_j.exit
220+
221+
_ZL13copy_elementsP9type_descPvS1_j.exit: ; preds = %for.body.i, %_Z16reserve_vec_fastPP8rust_vecj.exit, %if.then.i6
222+
%13 = load i32* %size, align 4, !tbaa !3
223+
%14 = load i32* %fill1, align 4, !tbaa !3
224+
%add5 = add i32 %14, %13
225+
store i32 %add5, i32* %fill1, align 4, !tbaa !3
226+
ret void
227+
}
228+
229+
define void @upcall_vec_push(%struct.rust_vec** nocapture %vp, %struct.type_desc* nocapture %elt_ty, i8* nocapture %elt) {
230+
entry:
231+
tail call void @upcall_intrinsic_vec_push(%struct.rust_vec** %vp, %struct.type_desc* %elt_ty, i8* %elt)
232+
ret void
233+
}
234+
235+
declare i8* @upcall_shared_realloc(i8*, i32)
236+
145237
!0 = metadata !{metadata !"any pointer", metadata !1}
146238
!1 = metadata !{metadata !"omnipotent char", metadata !2}
147239
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}

0 commit comments

Comments
 (0)