Skip to content

Commit fbbae43

Browse files
committed
Deprecate untyped instruction builders.
1 parent 9c3b641 commit fbbae43

File tree

8 files changed

+109
-40
lines changed

8 files changed

+109
-40
lines changed

deps/LLVMExtra/include/LLVMExtra.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ LLVMValueRef LLVMBuildCallWithOpBundle(LLVMBuilderRef B, LLVMValueRef Fn,
158158
LLVMValueRef *Args, unsigned NumArgs,
159159
LLVMOperandBundleDefRef *Bundles, unsigned NumBundles,
160160
const char *Name);
161+
LLVMValueRef LLVMBuildCallWithOpBundle2(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
162+
LLVMValueRef *Args, unsigned NumArgs,
163+
LLVMOperandBundleDefRef *Bundles, unsigned NumBundles,
164+
const char *Name);
161165
LLVMValueRef LLVMMetadataAsValue2(LLVMContextRef C, LLVMMetadataRef Metadata);
162166
void LLVMReplaceAllMetadataUsesWith(LLVMValueRef Old, LLVMValueRef New);
163167
void LLVMReplaceMDNodeOperandWith(LLVMMetadataRef MD, unsigned I, LLVMMetadataRef New);

deps/LLVMExtra/lib/llvm-api.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,11 +525,28 @@ LLVMValueRef LLVMBuildCallWithOpBundle(LLVMBuilderRef B, LLVMValueRef Fn,
525525
llvm::IRBuilder<> *Builder = unwrap(B);
526526
llvm::ArrayRef<llvm::Value*> args = makeArrayRef(unwrap(Args), NumArgs);
527527

528-
FunctionType *FnT = unwrap<Function>(Fn)->getFunctionType();
528+
Value *V = unwrap(Fn);
529+
FunctionType *FnT = cast<FunctionType>(V->getType()->getPointerElementType());
529530
llvm::CallInst *CI = Builder->CreateCall(FnT, unwrap(Fn), args ,BundleArray, Name);
530531
return wrap(CI);
531532
}
532533

534+
LLVMValueRef LLVMBuildCallWithOpBundle2(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
535+
LLVMValueRef *Args, unsigned NumArgs,
536+
LLVMOperandBundleDefRef *Bundles, unsigned NumBundles,
537+
const char *Name) {
538+
SmallVector<OperandBundleDef, 1> BundleArray;
539+
for (auto *Bundle : makeArrayRef(Bundles, NumBundles))
540+
BundleArray.push_back(*unwrap<OperandBundleDef>(Bundle));
541+
542+
llvm::IRBuilder<> *Builder = unwrap(B);
543+
llvm::ArrayRef<llvm::Value*> args = makeArrayRef(unwrap(Args), NumArgs);
544+
545+
FunctionType *FTy = unwrap<FunctionType>(Ty);
546+
llvm::CallInst *CI = Builder->CreateCall(FTy, unwrap(Fn), args ,BundleArray, Name);
547+
return wrap(CI);
548+
}
549+
533550
LLVMValueRef LLVMMetadataAsValue2(LLVMContextRef C, LLVMMetadataRef Metadata) {
534551
auto *MD = unwrap(Metadata);
535552
if (auto *VAM = dyn_cast<ValueAsMetadata>(MD))

lib/libLLVM_extra.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,10 @@ function LLVMBuildCallWithOpBundle(B, Fn, Args, NumArgs, Bundles, NumBundles, Na
399399
ccall((:LLVMBuildCallWithOpBundle, libLLVMExtra), LLVMValueRef, (LLVMBuilderRef, LLVMValueRef, Ptr{LLVMValueRef}, Cuint, Ptr{LLVMOperandBundleDefRef}, Cuint, Cstring), B, Fn, Args, NumArgs, Bundles, NumBundles, Name)
400400
end
401401

402+
function LLVMBuildCallWithOpBundle2(B, Ty, Fn, Args, NumArgs, Bundles, NumBundles, Name)
403+
ccall((:LLVMBuildCallWithOpBundle2, libLLVMExtra), LLVMValueRef, (LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, Ptr{LLVMValueRef}, Cuint, Ptr{LLVMOperandBundleDefRef}, Cuint, Cstring), B, Ty, Fn, Args, NumArgs, Bundles, NumBundles, Name)
404+
end
405+
402406
function LLVMMetadataAsValue2(C, MD)
403407
ccall((:LLVMMetadataAsValue2, libLLVMExtra), LLVMValueRef, (LLVMContextRef, LLVMMetadataRef), C, MD)
404408
end

src/core/value/constant.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@ const_ashr(lhs::Constant, rhs::Constant) =
465465

466466
function const_gep(val::Constant, Indices::Vector{<:Constant})
467467
supports_typed_pointers(context(val)) || throw_typedpointererror()
468+
Base.depwarn("const_gep without specifying the destination type is deprecated", :const_gep)
468469
Value(API.LLVMConstGEP(val, Indices, length(Indices)))
469470
end
470471

@@ -474,6 +475,7 @@ end
474475

475476
function const_inbounds_gep(val::Constant, Indices::Vector{<:Constant})
476477
supports_typed_pointers(context(val)) || throw_typedpointererror()
478+
Base.depwarn("const_inbounds_gep without specifying the destination type is deprecated", :const_inbounds_gep)
477479
Value(API.LLVMConstInboundsGEP(val, Indices, length(Indices)))
478480
end
479481

src/deprecated.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ Base.@deprecate llvmtype(x) value_type(x)
44
Base.@deprecate llvmeltype(x) eltype(value_type(x))
55

66
Base.@deprecate_binding Builder IRBuilder
7+
8+
# NOTE: there's more deprecated methods in irbuilder.jl

src/interop/pointer.jl

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,13 @@ using Core: LLVMPtr
2424
@dispose builder=IRBuilder(ctx) begin
2525
entry = BasicBlock(llvm_f, "entry"; ctx)
2626
position!(builder, entry)
27-
if supports_typed_pointers(ctx)
27+
ptr = if supports_typed_pointers(ctx)
2828
typed_ptr = bitcast!(builder, parameters(llvm_f)[1], T_typed_ptr)
29-
typed_ptr = inbounds_gep!(builder, typed_ptr, [parameters(llvm_f)[2]])
30-
ld = load!(builder, typed_ptr)
29+
inbounds_gep!(builder, eltyp, typed_ptr, [parameters(llvm_f)[2]])
3130
else
32-
ptr = inbounds_gep!(builder, eltyp, parameters(llvm_f)[1],[parameters(llvm_f)[2]])
33-
ld = load!(builder, eltyp, ptr)
31+
inbounds_gep!(builder, eltyp, parameters(llvm_f)[1], [parameters(llvm_f)[2]])
3432
end
33+
ld = load!(builder, eltyp, ptr)
3534
if A != 0
3635
metadata(ld)[LLVM.MD_tbaa] = tbaa_addrspace(A; ctx)
3736
end
@@ -62,16 +61,14 @@ end
6261
@dispose builder=IRBuilder(ctx) begin
6362
entry = BasicBlock(llvm_f, "entry"; ctx)
6463
position!(builder, entry)
65-
if supports_typed_pointers(ctx)
64+
ptr = if supports_typed_pointers(ctx)
6665
typed_ptr = bitcast!(builder, parameters(llvm_f)[1], T_typed_ptr)
67-
typed_ptr = inbounds_gep!(builder, typed_ptr, [parameters(llvm_f)[3]])
68-
val = parameters(llvm_f)[2]
69-
st = store!(builder, val, typed_ptr)
66+
inbounds_gep!(builder, eltyp, typed_ptr, [parameters(llvm_f)[3]])
7067
else
71-
ptr = inbounds_gep!(builder, eltyp, parameters(llvm_f)[1], [parameters(llvm_f)[3]])
72-
val = parameters(llvm_f)[2]
73-
st = store!(builder, val, ptr)
68+
inbounds_gep!(builder, eltyp, parameters(llvm_f)[1], [parameters(llvm_f)[3]])
7469
end
70+
val = parameters(llvm_f)[2]
71+
st = store!(builder, val, ptr)
7572
if A != 0
7673
metadata(st)[LLVM.MD_tbaa] = tbaa_addrspace(A; ctx)
7774
end

src/irbuilder.jl

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ indirectbr!(builder::IRBuilder, Addr::Value, NumDests::Integer=10) =
110110
function invoke!(builder::IRBuilder, Fn::Value, Args::Vector{<:Value}, Then::BasicBlock,
111111
Catch::BasicBlock, Name::String="")
112112
supports_typed_pointers(context(builder)) || throw_typedpointererror()
113+
Base.depwarn("invoke! without specifying the function type is deprecated", :invoke)
113114
Instruction(API.LLVMBuildInvoke(builder, Fn, Args, length(Args), Then, Catch, Name))
114115
end
115116

@@ -259,11 +260,16 @@ free!(builder::IRBuilder, PointerVal::Value) =
259260

260261
function load!(builder::IRBuilder, PointerVal::Value, Name::String="")
261262
supports_typed_pointers(context(builder)) || throw_typedpointererror()
263+
Base.depwarn("load! without specifying the destination type is deprecated", :load)
262264
Instruction(API.LLVMBuildLoad(builder, PointerVal, Name))
263265
end
264266

265267
function load!(builder::IRBuilder, Ty::LLVMType, PointerVal::Value, Name::String="")
266-
Instruction(API.LLVMBuildLoad2(builder, Ty, PointerVal, Name))
268+
@static if version() >= v"11"
269+
Instruction(API.LLVMBuildLoad2(builder, Ty, PointerVal, Name))
270+
else
271+
Instruction(API.LLVMBuildLoad(builder, PointerVal, Name))
272+
end
267273
end
268274

269275
store!(builder::IRBuilder, Val::Value, Ptr::Value) =
@@ -286,32 +292,47 @@ atomic_cmpxchg!(builder::IRBuilder, Ptr::Value, Cmp::Value, New::Value,
286292

287293
function gep!(builder::IRBuilder, Pointer::Value, Indices::Vector{<:Value}, Name::String="")
288294
supports_typed_pointers(context(builder)) || throw_typedpointererror()
295+
Base.depwarn("gep! without specifying the destination type is deprecated", :gep)
289296
Value(API.LLVMBuildGEP(builder, Pointer, Indices, length(Indices), Name))
290297
end
291298

292299
function gep!(builder::IRBuilder, Ty::LLVMType, Pointer::Value, Indices::Vector{<:Value},
293300
Name::String="")
294-
return Value(API.LLVMBuildGEP2(builder, Ty, Pointer, Indices, length(Indices), Name))
301+
@static if version() >= v"11"
302+
Value(API.LLVMBuildGEP2(builder, Ty, Pointer, Indices, length(Indices), Name))
303+
else
304+
Value(API.LLVMBuildGEP(builder, Pointer, Indices, length(Indices), Name))
305+
end
295306
end
296307

297308
function inbounds_gep!(builder::IRBuilder, Pointer::Value, Indices::Vector{<:Value},
298309
Name::String="")
299310
supports_typed_pointers(context(builder)) || throw_typedpointererror()
311+
Base.depwarn("inbounds_gep! without specifying the destination type is deprecated", :inbounds_gep)
300312
Value(API.LLVMBuildInBoundsGEP(builder, Pointer, Indices, length(Indices), Name))
301313
end
302314

303315
function inbounds_gep!(builder::IRBuilder, Ty::LLVMType, Pointer::Value,
304316
Indices::Vector{<:Value}, Name::String="")
305-
Value(API.LLVMBuildInBoundsGEP2(builder, Ty, Pointer, Indices, length(Indices), Name))
317+
@static if version() >= v"11"
318+
Value(API.LLVMBuildInBoundsGEP2(builder, Ty, Pointer, Indices, length(Indices), Name))
319+
else
320+
Value(API.LLVMBuildInBoundsGEP(builder, Pointer, Indices, length(Indices), Name))
321+
end
306322
end
307323

308324
function struct_gep!(builder::IRBuilder, Pointer::Value, Idx, Name::String="")
309325
supports_typed_pointers(context(builder)) || throw_typedpointererror()
326+
Base.depwarn("struct_gep! without specifying the destination type is deprecated", :struct_gep)
310327
Value(API.LLVMBuildStructGEP(builder, Pointer, Idx, Name))
311328
end
312329

313330
function struct_gep!(builder::IRBuilder, Ty::LLVMType, Pointer::Value, Idx, Name::String="")
314-
Value(API.LLVMBuildStructGEP2(builder, Ty, Pointer, Idx, Name))
331+
@static if version() >= v"11"
332+
Value(API.LLVMBuildStructGEP2(builder, Ty, Pointer, Idx, Name))
333+
else
334+
Value(API.LLVMBuildStructGEP(builder, Pointer, Idx, Name))
335+
end
315336
end
316337

317338
# conversion operations
@@ -394,25 +415,47 @@ select!(builder::IRBuilder, If::Value, Then::Value, Else::Value, Name::String=""
394415

395416
function call!(builder::IRBuilder, Fn::Value, Args::Vector{<:Value}=Value[], Name::String="")
396417
supports_typed_pointers(context(builder)) || throw_typedpointererror()
418+
Base.depwarn("call! without specifying the function type is deprecated", :call)
397419
Instruction(API.LLVMBuildCall(builder, Fn, Args, length(Args), Name))
398420
end
399421

400422
function call!(builder::IRBuilder, Ty::LLVMType, Fn::Value, Args::Vector{<:Value}=Value[],
401423
Name::String="")
402-
Instruction(API.LLVMBuildCall2(builder, Ty, Fn, Args, length(Args), Name))
424+
@static if version() >= v"11"
425+
Instruction(API.LLVMBuildCall2(builder, Ty, Fn, Args, length(Args), Name))
426+
else
427+
Instruction(API.LLVMBuildCall(builder, Fn, Args, length(Args), Name))
428+
end
403429
end
404430

405-
call!(builder::IRBuilder, Fn::Value, Args::Vector{<:Value},
406-
Bundles::Vector{OperandBundleDef}, Name::String="") =
431+
function call!(builder::IRBuilder, Fn::Value, Args::Vector{<:Value},
432+
Bundles::Vector{OperandBundleDef}, Name::String="")
433+
supports_typed_pointers(context(builder)) || throw_typedpointererror()
434+
Base.depwarn("call! without specifying the function type is deprecated", :call)
407435
Instruction(API.LLVMBuildCallWithOpBundle(builder, Fn, Args, length(Args), Bundles,
408436
length(Bundles), Name))
437+
end
438+
function call!(builder::IRBuilder, Ty::LLVMType, Fn::Value, Args::Vector{<:Value},
439+
Bundles::Vector{OperandBundleDef}, Name::String="")
440+
Instruction(API.LLVMBuildCallWithOpBundle2(builder, Ty, Fn, Args, length(Args), Bundles,
441+
length(Bundles), Name))
442+
end
409443

410444
# convenience function that performs the OperandBundle(Iterator|Use)->Def conversion
411-
call!(builder::IRBuilder, Fn::Value, Args::Vector{<:Value},
412-
Bundles, Name::String="") =
445+
function call!(builder::IRBuilder, Fn::Value, Args::Vector{<:Value},
446+
Bundles, Name::String="")
447+
supports_typed_pointers(context(builder)) || throw_typedpointererror()
448+
Base.depwarn("call! without specifying the function type is deprecated", :call)
413449
Instruction(API.LLVMBuildCallWithOpBundle(builder, Fn, Args, length(Args),
414450
OperandBundleDef.(Bundles),
415451
length(Bundles), Name))
452+
end
453+
function call!(builder::IRBuilder, Ty::LLVMType, Fn::Value, Args::Vector{<:Value},
454+
Bundles, Name::String="")
455+
Instruction(API.LLVMBuildCallWithOpBundle2(builder, Ty, Fn, Args, length(Args),
456+
OperandBundleDef.(Bundles),
457+
length(Bundles), Name))
458+
end
416459

417460
va_arg!(builder::IRBuilder, List::Value, Ty::LLVMType, Name::String="") =
418461
Instruction(API.LLVMBuildVAArg(builder, List, Ty, Name))
@@ -453,9 +496,15 @@ isnotnull!(builder::IRBuilder, Val::Value, Name::String="") =
453496

454497
function ptrdiff!(builder::IRBuilder, LHS::Value, RHS::Value, Name::String="")
455498
supports_typed_pointers(context(builder)) || throw_typedpointererror()
499+
Base.depwarn("ptrdiff! without specifying a pointer type is deprecated", :ptrdiff)
456500
Value(API.LLVMBuildPtrDiff(builder, LHS, RHS, Name))
457501
end
458502

459503
function ptrdiff!(builder::IRBuilder, Ty::LLVMType, LHS::Value, RHS::Value, Name::String="")
460-
Value(API.LLVMBuildPtrDiff2(builder, Ty, LHS, RHS, Name))
504+
@static if version() >= v"15"
505+
# XXX: backport this to LLVM 11, if we care
506+
Value(API.LLVMBuildPtrDiff2(builder, Ty, LHS, RHS, Name))
507+
else
508+
Value(API.LLVMBuildPtrDiff(builder, LHS, RHS, Name))
509+
end
461510
end

test/instructions.jl

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,10 @@
181181
freeinst = free!(builder, ptr1)
182182
@check_ir freeinst "tail call void @free"
183183

184+
loadinst = load!(builder, LLVM.Int32Type(ctx), ptr1)
184185
if supports_typed_pointers(ctx)
185-
loadinst = load!(builder, ptr1)
186186
@check_ir loadinst "load i32, i32* %4"
187187
else
188-
loadinst = load!(builder, LLVM.Int32Type(ctx), ptr1)
189188
@check_ir loadinst "load i32, ptr %4"
190189
end
191190
alignment!(loadinst, 4)
@@ -209,19 +208,17 @@
209208
fenceinst = fence!(builder, LLVM.API.LLVMAtomicOrderingNotAtomic)
210209
@check_ir fenceinst "fence"
211210

211+
gepinst = gep!(builder, LLVM.Int32Type(ctx), ptr1, [int1])
212212
if supports_typed_pointers(ctx)
213-
gepinst = gep!(builder, ptr1, [int1])
214213
@check_ir gepinst "getelementptr i32, i32* %4, i32 %0"
215214
else
216-
gepinst = gep!(builder, LLVM.Int32Type(ctx), ptr1, [int1])
217215
@check_ir gepinst "getelementptr i32, ptr %4, i32 %0"
218216
end
219217

218+
gepinst1 = inbounds_gep!(builder, LLVM.Int32Type(ctx), ptr1, [int1])
220219
if supports_typed_pointers(ctx)
221-
gepinst1 = inbounds_gep!(builder, ptr1, [int1])
222220
@check_ir gepinst1 "getelementptr inbounds i32, i32* %4, i32 %0"
223221
else
224-
gepinst1 = inbounds_gep!(builder, LLVM.Int32Type(ctx), ptr1, [int1])
225222
@check_ir gepinst1 "getelementptr inbounds i32, ptr %4, i32 %0"
226223
end
227224

@@ -320,11 +317,7 @@
320317

321318
trap = LLVM.Function(mod, "llvm.trap", LLVM.FunctionType(LLVM.VoidType(ctx)))
322319

323-
if supports_typed_pointers(ctx)
324-
callinst = call!(builder, trap)
325-
else
326-
callinst = call!(builder, LLVM.FunctionType(LLVM.VoidType(ctx)), trap)
327-
end
320+
callinst = call!(builder, LLVM.FunctionType(LLVM.VoidType(ctx)), trap)
328321

329322
@check_ir callinst "call void @llvm.trap()"
330323
@test called_value(callinst) == trap
@@ -367,11 +360,10 @@
367360

368361
ptr1 = parameters(fn)[5]
369362
ptr2 = parameters(fn)[6]
363+
ptrdiffinst = ptrdiff!(builder, LLVM.Int32Type(ctx), ptr1, ptr2)
370364
if supports_typed_pointers(ctx)
371-
ptrdiffinst = ptrdiff!(builder, ptr1, ptr2)
372365
@check_ir ptrdiffinst r"sdiv exact i64 %.+, ptrtoint \(i32\* getelementptr \(i32, i32\* null, i32 1\) to i64\)"
373-
elseif LLVM.version() >= v"14" # XXX: backport, if we care
374-
ptrdiffinst = ptrdiff!(builder, LLVM.Int32Type(ctx), ptr1, ptr2)
366+
else
375367
@check_ir ptrdiffinst r"sdiv exact i64 %.+, ptrtoint \(ptr getelementptr \(i32, ptr null, i32 1\) to i64\)"
376368
end
377369

@@ -479,9 +471,11 @@ end
479471
@test sprint(io->print(io, bundle1)) == "\"unknown\"(i32 1, i64 2)"
480472

481473
# use in a call
474+
f = functions(mod)["x"]
475+
ft = function_type(f)
482476
@dispose builder=IRBuilder(ctx) begin
483477
position!(builder, inst)
484-
inst = call!(builder, functions(mod)["x"], Value[], [bundle1])
478+
inst = call!(builder, ft, f, Value[], [bundle1])
485479

486480
bundles = operand_bundles(inst)
487481
@test length(bundles) == 1
@@ -500,8 +494,8 @@ end
500494
@test sprint(io->print(io, bundle3)) == "\"unknown\"(i32 1, i64 2)"
501495

502496
# creating a call should perform the necessary conversion automatically
503-
call!(builder, functions(mod)["x"], Value[], operand_bundles(inst))
504-
call!(builder, functions(mod)["x"], Value[], [bundle2])
497+
call!(builder, ft, f, Value[], operand_bundles(inst))
498+
call!(builder, ft, f, Value[], [bundle2])
505499
end
506500
end
507501
end

0 commit comments

Comments
 (0)