Skip to content

Commit d109aa7

Browse files
author
Prem Chintalapudi
committed
Fix tests and move TBAA node generation to codegen_shared
1 parent 370aa84 commit d109aa7

File tree

5 files changed

+95
-82
lines changed

5 files changed

+95
-82
lines changed

src/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ $(build_shlibdir)/libllvmcalltest.$(SHLIB_EXT): $(SRCDIR)/codegen_shared.h $(BUI
293293
$(BUILDDIR)/llvm-alloc-opt.o $(BUILDDIR)/llvm-alloc-opt.dbg.obj: $(SRCDIR)/codegen_shared.h $(SRCDIR)/llvm-pass-helpers.h
294294
$(BUILDDIR)/llvm-final-gc-lowering.o $(BUILDDIR)/llvm-final-gc-lowering.dbg.obj: $(SRCDIR)/llvm-pass-helpers.h
295295
$(BUILDDIR)/llvm-gc-invariant-verifier.o $(BUILDDIR)/llvm-gc-invariant-verifier.dbg.obj: $(SRCDIR)/codegen_shared.h
296-
$(BUILDDIR)/llvm-late-gc-lowering.o $(BUILDDIR)/llvm-late-gc-lowering.dbg.obj: $(SRCDIR)/llvm-pass-helpers.h
296+
$(BUILDDIR)/llvm-late-gc-lowering.o $(BUILDDIR)/llvm-late-gc-lowering.dbg.obj: $(SRCDIR)/llvm-pass-helpers.h $(SRCDIR)/codegen_shared.h
297297
$(BUILDDIR)/llvm-lower-handlers.o $(BUILDDIR)/llvm-lower-handlers.dbg.obj: $(SRCDIR)/codegen_shared.h
298298
$(BUILDDIR)/llvm-multiversioning.o $(BUILDDIR)/llvm-multiversioning.dbg.obj: $(SRCDIR)/codegen_shared.h $(SRCDIR)/processor.h
299299
$(BUILDDIR)/llvm-pass-helpers.o $(BUILDDIR)/llvm-pass-helpers.dbg.obj: $(SRCDIR)/llvm-pass-helpers.h $(SRCDIR)/codegen_shared.h

src/codegen.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4804,14 +4804,6 @@ static Value *get_current_ptls(jl_codectx_t &ctx)
48044804
return get_current_ptls_from_task(ctx.builder, get_current_task(ctx));
48054805
}
48064806

4807-
llvm::MDNode *get_tbaa_gcframe() {
4808-
return tbaa_gcframe;
4809-
}
4810-
4811-
llvm::MDNode *get_tbaa_const() {
4812-
return tbaa_const;
4813-
}
4814-
48154807
// Store world age at the entry block of the function. This function should be
48164808
// called right after `allocate_gc_frame` and there should be no context switch.
48174809
static void emit_last_age_field(jl_codectx_t &ctx)

src/codegen_shared.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <llvm/Support/Debug.h>
66
#include <llvm/IR/DebugLoc.h>
77
#include <llvm/IR/IRBuilder.h>
8+
#include <llvm/IR/MDBuilder.h>
89

910
#define STR(csym) #csym
1011
#define XSTR(csym) STR(csym)
@@ -88,13 +89,27 @@ static inline void llvm_dump(llvm::DebugLoc *dbg)
8889
llvm::dbgs() << "\n";
8990
}
9091

91-
llvm::MDNode *get_tbaa_gcframe();
92-
llvm::MDNode *get_tbaa_const();
92+
static inline std::pair<llvm::MDNode*,llvm::MDNode*> tbaa_make_child_with_context(llvm::LLVMContext &ctxt, const char *name, llvm::MDNode *parent=nullptr, bool isConstant=false)
93+
{
94+
llvm::MDBuilder mbuilder(ctxt);
95+
llvm::MDNode *jtbaa = mbuilder.createTBAARoot("jtbaa");
96+
llvm::MDNode *tbaa_root = mbuilder.createTBAAScalarTypeNode("jtbaa", jtbaa);
97+
llvm::MDNode *scalar = mbuilder.createTBAAScalarTypeNode(name, parent ? parent : tbaa_root);
98+
llvm::MDNode *n = mbuilder.createTBAAStructTagNode(scalar, scalar, 0, isConstant);
99+
return std::make_pair(n, scalar);
100+
}
101+
102+
static inline llvm::MDNode *get_tbaa_gcframe(llvm::LLVMContext &ctxt) {
103+
return tbaa_make_child_with_context(ctxt, "jtbaa_gcframe").first;
104+
}
105+
static inline llvm::MDNode *get_tbaa_const(llvm::LLVMContext &ctxt) {
106+
return tbaa_make_child_with_context(ctxt, "jtbaa_const", nullptr, true).first;
107+
}
93108

94109
static inline llvm::Instruction *tbaa_decorate(llvm::MDNode *md, llvm::Instruction *inst)
95110
{
96111
inst->setMetadata(llvm::LLVMContext::MD_tbaa, md);
97-
if (llvm::isa<llvm::LoadInst>(inst) && md == get_tbaa_const())
112+
if (llvm::isa<llvm::LoadInst>(inst) && md == get_tbaa_const(md->getContext()))
98113
inst->setMetadata(llvm::LLVMContext::MD_invariant_load, llvm::MDNode::get(md->getContext(), llvm::None));
99114
return inst;
100115
}
@@ -130,7 +145,7 @@ static inline llvm::Value *get_current_ptls_from_task(llvm::IRBuilder<> &builder
130145
LoadInst *ptls_load = builder.CreateAlignedLoad(
131146
emit_bitcast_with_builder(builder, pptls, T_ppjlvalue), Align(sizeof(void *)), "ptls_load");
132147
// Note: Corresponding store (`t->ptls = ptls`) happens in `ctx_switch` of tasks.c.
133-
tbaa_decorate(get_tbaa_gcframe(), ptls_load);
148+
tbaa_decorate(get_tbaa_gcframe(builder.getContext()), ptls_load);
134149
// Using `CastInst::Create` to get an `Instruction*` without explicit cast:
135150
auto ptls = CastInst::Create(Instruction::BitCast, ptls_load, T_ppjlvalue, "ptls");
136151
builder.Insert(ptls);

test/llvmpasses/alloc-opt-gcframe.jl

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,19 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
1212

1313
# CHECK-LABEL: @return_obj
1414
# CHECK-NOT: @julia.gc_alloc_obj
15-
# CHECK: %v = call noalias nonnull {} addrspace(10)* @ijl_gc_pool_alloc
16-
# CHECK: store atomic {} addrspace(10)* @tag, {} addrspace(10)* addrspace(10)* {{.*}} unordered, align 8, !tbaa !0
15+
# CHECK: %current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12
16+
# CHECK-NEXT: [[ptls_field:%.*]] = getelementptr inbounds {}*, {}** %current_task, i64 14
17+
# CHECK-NEXT: [[ptls_load:%.*]] = load {}*, {}** [[ptls_field]], align 8, !tbaa !0
18+
# CHECK-NEXT: [[ppjl_ptls:%.*]] = bitcast {}* [[ptls_load]] to {}**
19+
# CHECK-NEXT: [[ptls_i8:%.*]] = bitcast {}** [[ppjl_ptls]] to i8*
20+
# CHECK-NEXT: %v = call noalias nonnull {} addrspace(10)* @ijl_gc_pool_alloc(i8* [[ptls_i8]], i32 [[SIZE_T:[0-9]+]], i32 16)
21+
# CHECK: store atomic {} addrspace(10)* @tag, {} addrspace(10)* addrspace(10)* {{.*}} unordered, align 8, !tbaa !4
1722
println("""
1823
define {} addrspace(10)* @return_obj() {
1924
%pgcstack = call {}*** @julia.get_pgcstack()
20-
%ptls = call {}*** @julia.ptls_states()
21-
%ptls_i8 = bitcast {}*** %ptls to i8*
22-
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, $isz 8, {} addrspace(10)* @tag)
25+
%gcstack = bitcast {}*** %pgcstack to {}**
26+
%current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12
27+
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj({}** %current_task, $isz 8, {} addrspace(10)* @tag)
2328
ret {} addrspace(10)* %v
2429
}
2530
""")
@@ -35,9 +40,9 @@ define {} addrspace(10)* @return_obj() {
3540
println("""
3641
define i64 @return_load(i64 %i) {
3742
%pgcstack = call {}*** @julia.get_pgcstack()
38-
%ptls = call {}*** @julia.ptls_states()
39-
%ptls_i8 = bitcast {}*** %ptls to i8*
40-
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, $isz 8, {} addrspace(10)* @tag)
43+
%gcstack = bitcast {}*** %pgcstack to {}**
44+
%current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12
45+
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj({}** %current_task, $isz 8, {} addrspace(10)* @tag)
4146
%v64 = bitcast {} addrspace(10)* %v to i64 addrspace(10)*
4247
%v64a11 = addrspacecast i64 addrspace(10)* %v64 to i64 addrspace(11)*
4348
store i64 %i, i64 addrspace(11)* %v64a11, align 16, !tbaa !4
@@ -50,16 +55,15 @@ define i64 @return_load(i64 %i) {
5055

5156
# CHECK-LABEL: @ccall_obj
5257
# CHECK: call {}*** @julia.get_pgcstack()
53-
# CHECK: call {}*** @julia.ptls_states()
5458
# CHECK-NOT: @julia.gc_alloc_obj
5559
# CHECK: @ijl_gc_pool_alloc
56-
# CHECK: store atomic {} addrspace(10)* @tag, {} addrspace(10)* addrspace(10)* {{.*}} unordered, align 8, !tbaa !0
60+
# CHECK: store atomic {} addrspace(10)* @tag, {} addrspace(10)* addrspace(10)* {{.*}} unordered, align 8, !tbaa !4
5761
println("""
5862
define void @ccall_obj(i8* %fptr) {
5963
%pgcstack = call {}*** @julia.get_pgcstack()
60-
%ptls = call {}*** @julia.ptls_states()
61-
%ptls_i8 = bitcast {}*** %ptls to i8*
62-
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, $isz 8, {} addrspace(10)* @tag)
64+
%gcstack = bitcast {}*** %pgcstack to {}**
65+
%current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12
66+
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj({}** %current_task, $isz 8, {} addrspace(10)* @tag)
6367
%f = bitcast i8* %fptr to void ({} addrspace(10)*)*
6468
call void %f({} addrspace(10)* %v)
6569
ret void
@@ -70,7 +74,6 @@ define void @ccall_obj(i8* %fptr) {
7074
# CHECK-LABEL: @ccall_ptr
7175
# CHECK: alloca i64
7276
# CHECK: call {}*** @julia.get_pgcstack()
73-
# CHECK: call {}*** @julia.ptls_states()
7477
# CHECK-NOT: @julia.gc_alloc_obj
7578
# CHECK-NOT: @jl_gc_pool_alloc
7679
# CHECK: call void @llvm.lifetime.start{{.*}}(i64 8, i8*
@@ -81,9 +84,9 @@ define void @ccall_obj(i8* %fptr) {
8184
println("""
8285
define void @ccall_ptr(i8* %fptr) {
8386
%pgcstack = call {}*** @julia.get_pgcstack()
84-
%ptls = call {}*** @julia.ptls_states()
85-
%ptls_i8 = bitcast {}*** %ptls to i8*
86-
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, $isz 8, {} addrspace(10)* @tag)
87+
%gcstack = bitcast {}*** %pgcstack to {}**
88+
%current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12
89+
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj({}** %current_task, $isz 8, {} addrspace(10)* @tag)
8790
%va = addrspacecast {} addrspace(10)* %v to {} addrspace(11)*
8891
%ptrj = call {}* @julia.pointer_from_objref({} addrspace(11)* %va)
8992
%ptr = bitcast {}* %ptrj to i8*
@@ -96,16 +99,15 @@ define void @ccall_ptr(i8* %fptr) {
9699

97100
# CHECK-LABEL: @ccall_unknown_bundle
98101
# CHECK: call {}*** @julia.get_pgcstack()
99-
# CHECK: call {}*** @julia.ptls_states()
100102
# CHECK-NOT: @julia.gc_alloc_obj
101103
# CHECK: @ijl_gc_pool_alloc
102-
# CHECK: store atomic {} addrspace(10)* @tag, {} addrspace(10)* addrspace(10)* {{.*}} unordered, align 8, !tbaa !0
104+
# CHECK: store atomic {} addrspace(10)* @tag, {} addrspace(10)* addrspace(10)* {{.*}} unordered, align 8, !tbaa !4
103105
println("""
104106
define void @ccall_unknown_bundle(i8* %fptr) {
105107
%pgcstack = call {}*** @julia.get_pgcstack()
106-
%ptls = call {}*** @julia.ptls_states()
107-
%ptls_i8 = bitcast {}*** %ptls to i8*
108-
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, $isz 8, {} addrspace(10)* @tag)
108+
%gcstack = bitcast {}*** %pgcstack to {}**
109+
%current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12
110+
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj({}** %current_task, $isz 8, {} addrspace(10)* @tag)
109111
%va = addrspacecast {} addrspace(10)* %v to {} addrspace(11)*
110112
%ptrj = call {}* @julia.pointer_from_objref({} addrspace(11)* %va)
111113
%ptr = bitcast {}* %ptrj to i8*
@@ -119,7 +121,6 @@ define void @ccall_unknown_bundle(i8* %fptr) {
119121
# CHECK-LABEL: @lifetime_branches
120122
# CHECK: alloca i64
121123
# CHECK: call {}*** @julia.get_pgcstack()
122-
# CHECK: call {}*** @julia.ptls_states()
123124
# CHECK: L1:
124125
# CHECK-NEXT: call void @llvm.lifetime.start{{.*}}(i64 8,
125126
# CHECK: %f = bitcast i8* %fptr to void (i8*)*
@@ -136,12 +137,12 @@ define void @ccall_unknown_bundle(i8* %fptr) {
136137
println("""
137138
define void @lifetime_branches(i8* %fptr, i1 %b, i1 %b2) {
138139
%pgcstack = call {}*** @julia.get_pgcstack()
139-
%ptls = call {}*** @julia.ptls_states()
140-
%ptls_i8 = bitcast {}*** %ptls to i8*
140+
%gcstack = bitcast {}*** %pgcstack to {}**
141+
%current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12
141142
br i1 %b, label %L1, label %L3
142143
143144
L1:
144-
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, $isz 8, {} addrspace(10)* @tag)
145+
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj({}** %current_task, $isz 8, {} addrspace(10)* @tag)
145146
%va = addrspacecast {} addrspace(10)* %v to {} addrspace(11)*
146147
%ptrj = call {}* @julia.pointer_from_objref({} addrspace(11)* %va)
147148
%ptr = bitcast {}* %ptrj to i8*
@@ -162,16 +163,15 @@ L3:
162163

163164
# CHECK-LABEL: @object_field
164165
# CHECK: call {}*** @julia.get_pgcstack()
165-
# CHECK: call {}*** @julia.ptls_states()
166166
# CHECK-NOT: @julia.gc_alloc_obj
167167
# CHECK-NOT: @jl_gc_pool_alloc
168-
# CHECK-NOT: store {} addrspace(10)* @tag, {} addrspace(10)* addrspace(10)* {{.*}}, align 8, !tbaa !0
168+
# CHECK-NOT: store {} addrspace(10)* @tag, {} addrspace(10)* addrspace(10)* {{.*}}, align 8, !tbaa !4
169169
println("""
170170
define void @object_field({} addrspace(10)* %field) {
171171
%pgcstack = call {}*** @julia.get_pgcstack()
172-
%ptls = call {}*** @julia.ptls_states()
173-
%ptls_i8 = bitcast {}*** %ptls to i8*
174-
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, $isz 8, {} addrspace(10)* @tag)
172+
%gcstack = bitcast {}*** %pgcstack to {}**
173+
%current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12
174+
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj({}** %current_task, $isz 8, {} addrspace(10)* @tag)
175175
%va = addrspacecast {} addrspace(10)* %v to {} addrspace(11)*
176176
%vab = bitcast {} addrspace(11)* %va to {} addrspace(10)* addrspace(11)*
177177
store {} addrspace(10)* %field, {} addrspace(10)* addrspace(11)* %vab, align 8
@@ -183,17 +183,16 @@ define void @object_field({} addrspace(10)* %field) {
183183
# CHECK-LABEL: @memcpy_opt
184184
# CHECK: alloca [16 x i8], align 16
185185
# CHECK: call {}*** @julia.get_pgcstack()
186-
# CHECK: call {}*** @julia.ptls_states()
187186
# CHECK-NOT: @julia.gc_alloc_obj
188187
# CHECK-NOT: @jl_gc_pool_alloc
189188
# CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
190189
println("""
191190
define void @memcpy_opt(i8* %v22) {
192191
top:
193192
%pgcstack = call {}*** @julia.get_pgcstack()
194-
%v6 = call {}*** @julia.ptls_states()
195-
%v18 = bitcast {}*** %v6 to i8*
196-
%v19 = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %v18, $isz 16, {} addrspace(10)* @tag)
193+
%gcstack = bitcast {}*** %pgcstack to {}**
194+
%current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12
195+
%v19 = call noalias {} addrspace(10)* @julia.gc_alloc_obj({}** %current_task, $isz 16, {} addrspace(10)* @tag)
197196
%v20 = bitcast {} addrspace(10)* %v19 to i8 addrspace(10)*
198197
%v21 = addrspacecast i8 addrspace(10)* %v20 to i8 addrspace(11)*
199198
call void @llvm.memcpy.p11i8.p0i8.i64(i8 addrspace(11)* %v21, i8* %v22, i64 16, i32 8, i1 false)
@@ -204,7 +203,6 @@ top:
204203

205204
# CHECK-LABEL: @preserve_opt
206205
# CHECK: call {}*** @julia.get_pgcstack()
207-
# CHECK: call {}*** @julia.ptls_states()
208206
# CHECK-NOT: @julia.gc_alloc_obj
209207
# CHECK-NOT: @jl_gc_pool_alloc
210208
# CHECK-NOT: @llvm.lifetime.end
@@ -213,9 +211,9 @@ println("""
213211
define void @preserve_opt(i8* %v22) {
214212
top:
215213
%pgcstack = call {}*** @julia.get_pgcstack()
216-
%v6 = call {}*** @julia.ptls_states()
217-
%v18 = bitcast {}*** %v6 to i8*
218-
%v19 = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %v18, $isz 16, {} addrspace(10)* @tag)
214+
%gcstack = bitcast {}*** %pgcstack to {}**
215+
%current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12
216+
%v19 = call noalias {} addrspace(10)* @julia.gc_alloc_obj({}** %current_task, $isz 16, {} addrspace(10)* @tag)
219217
%v20 = bitcast {} addrspace(10)* %v19 to i8 addrspace(10)*
220218
%v21 = addrspacecast i8 addrspace(10)* %v20 to i8 addrspace(11)*
221219
%tok = call token (...) @llvm.julia.gc_preserve_begin({} addrspace(10)* %v19)
@@ -229,7 +227,6 @@ top:
229227

230228
# CHECK-LABEL: @preserve_branches
231229
# CHECK: call {}*** @julia.get_pgcstack()
232-
# CHECK: call {}*** @julia.ptls_states()
233230
# CHECK: L1:
234231
# CHECK-NEXT: @external_function()
235232
# CHECK-NEXT: br i1 %b2, label %L2, label %L3
@@ -242,12 +239,12 @@ top:
242239
println("""
243240
define void @preserve_branches(i8* %fptr, i1 %b, i1 %b2) {
244241
%pgcstack = call {}*** @julia.get_pgcstack()
245-
%ptls = call {}*** @julia.ptls_states()
246-
%ptls_i8 = bitcast {}*** %ptls to i8*
242+
%gcstack = bitcast {}*** %pgcstack to {}**
243+
%current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12
247244
br i1 %b, label %L1, label %L3
248245
249246
L1:
250-
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, $isz 8, {} addrspace(10)* @tag)
247+
%v = call noalias {} addrspace(10)* @julia.gc_alloc_obj({}** %current_task, $isz 8, {} addrspace(10)* @tag)
251248
%tok = call token (...) @llvm.julia.gc_preserve_begin({} addrspace(10)* %v)
252249
call void @external_function()
253250
br i1 %b2, label %L2, label %L3
@@ -266,9 +263,8 @@ L3:
266263
# CHECK: declare noalias nonnull {} addrspace(10)* @ijl_gc_big_alloc(i8*,
267264
println("""
268265
declare void @external_function()
269-
declare {}*** @julia.ptls_states()
270266
declare {}*** @julia.get_pgcstack()
271-
declare noalias nonnull {} addrspace(10)* @julia.gc_alloc_obj(i8*, $isz, {} addrspace(10)*)
267+
declare noalias nonnull {} addrspace(10)* @julia.gc_alloc_obj({}**, $isz, {} addrspace(10)*)
272268
declare {}* @julia.pointer_from_objref({} addrspace(11)*)
273269
declare void @llvm.memcpy.p11i8.p0i8.i64(i8 addrspace(11)* nocapture writeonly, i8* nocapture readonly, i64, i32, i1)
274270
declare token @llvm.julia.gc_preserve_begin(...)

0 commit comments

Comments
 (0)