Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions src/atomics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
is_ordered(order::LLVM.AtomicOrdering.T) = is_stronger(order, LLVM.AtomicOrdering.Monotonic)

# (`atomicrmw` and `cmpxchg` are always atomic)
is_atomic_memop(inst::LLVM.Instruction) = inst isa LLVM.MemAccessInst && isatomic(inst)
is_atomic_memop(@nospecialize(inst::LLVM.Instruction)) =
inst isa LLVM.MemAccessInst && isatomic(inst)

# the type of the value an atomic memory operation accesses
atomic_value_type(inst::LLVM.LoadInst) = inst.value_type
Expand Down Expand Up @@ -67,11 +68,11 @@ end

# the ordering of an atomic memory operation, merging a compare-exchange's orderings
atomic_ordering(inst::LLVM.AtomicCmpXchgInst) = merged_ordering(inst)
atomic_ordering(inst::LLVM.Instruction) = inst.ordering
atomic_ordering(@nospecialize(inst::LLVM.Instruction)) = inst.ordering

# the size in bits of the value an atomic memory operation accesses, with pointers as large as
# the module's data layout says, or `nothing` if it isn't a scalar
function atomic_bits(inst::LLVM.Instruction)
function atomic_bits(@nospecialize(inst::LLVM.Instruction))
T = atomic_value_type(inst)
T isa Union{LLVM.IntegerType,LLVM.FloatingPointType,LLVM.PointerType} || return nothing
mod = LLVM.parent(LLVM.parent(LLVM.parent(inst)))
Expand All @@ -86,7 +87,7 @@ end
# when it has a pointer to it (thread memory is private to every thread), so plain accesses
# behave the same. Anything this cannot trace back to an `alloca`, e.g., a function argument
# or a loaded pointer, is not known to be private.
function is_thread_private(ptr::LLVM.Value)
function is_thread_private(@nospecialize(ptr::LLVM.Value))
seen = Set{LLVM.Value}()
worklist = LLVM.Value[ptr]
while !isempty(worklist)
Expand All @@ -113,7 +114,7 @@ end
# Replace an atomic operation on the thread's own memory (see `is_thread_private`) by plain
# accesses. Its ordering and scope don't matter either: no other thread can observe the memory
# it accesses, so it cannot synchronize with any.
function demote_private_atomic!(inst::LLVM.Instruction)
function demote_private_atomic!(@nospecialize(inst::LLVM.Instruction))
if inst isa LLVM.LoadInst || inst isa LLVM.StoreInst
# (a plain access has the default, system scope)
inst.syncscope = SyncScope("system")
Expand Down Expand Up @@ -154,7 +155,7 @@ end
# on the word containing it, like `AtomicExpand` does for targets without atomics of that
# size. Like `AtomicExpand`, this assumes that the whole word can be accessed, which the
# target has to ensure.
function expand_partword_atomic!(inst::LLVM.Instruction, word_size::Integer)
function expand_partword_atomic!(@nospecialize(inst::LLVM.Instruction), word_size::Integer)
if inst isa LLVM.LoadInst
# a word-sized load, shifted
@dispose builder=IRBuilder() begin
Expand Down
2 changes: 1 addition & 1 deletion src/debug.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function backtrace(inst::LLVM.Instruction, bt = StackTraces.StackFrame[])
frame = StackTraces.StackFrame("multiple call sites", "unknown", 0)
push!(bt, frame)
elseif length(call_sites) == 1
inst = first(call_sites).user
inst = first(call_sites).user::LLVM.CallInst
continue
end
end
Expand Down
18 changes: 10 additions & 8 deletions src/irgen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,8 @@ end
# - `name`: the name of the argument
# - `idx`: the index of the argument in the LLVM function type, or `nothing` if the argument
# is not passed at the LLVM level.
const ArgumentInfo = @NamedTuple{cc::ArgumentCC, typ::Any, name::Symbol,
idx::Union{Nothing,Int}}
function classify_arguments(@nospecialize(job::CompilerJob), codegen_ft::LLVM.FunctionType;
post_optimization::Bool=false)
source_sig = job.source.specTypes::DataType
Expand All @@ -576,12 +578,11 @@ function classify_arguments(@nospecialize(job::CompilerJob), codegen_ft::LLVM.Fu

codegen_types = codegen_ft.parameters

args = ArgumentInfo[]
if post_optimization && kernel_state_type(job) !== Nothing
args = []
push!(args, (cc=KERNEL_STATE, typ=kernel_state_type(job), name=:kernel_state, idx=1))
codegen_i = 2
else
args = []
codegen_i = 1
end
for (source_typ, source_name) in zip(source_types, source_argnames)
Expand Down Expand Up @@ -887,7 +888,7 @@ function (self::AddKernelState)(mod::LLVM.Module)
f.name = fn * ".stateless"

# create a new function
new_param_types = [T_state, ft.parameters...]
new_param_types = pushfirst!(collect(LLVMType, ft.parameters), T_state)
new_ft = LLVM.FunctionType(ft.return_type, new_param_types)
new_f = LLVM.Function(mod, fn, new_ft)
new_f.parameters[1].name = "state"
Expand Down Expand Up @@ -920,7 +921,8 @@ function (self::AddKernelState)(mod::LLVM.Module)
# is all this even sound?
typ = val.value_type::LLVM.PointerType
ft = typ.element_type::LLVM.FunctionType
new_ft = LLVM.FunctionType(ft.return_type, [T_state, ft.parameters...])
new_params = pushfirst!(collect(LLVMType, ft.parameters), T_state)
new_ft = LLVM.FunctionType(ft.return_type, new_params)
return const_bitcast(workmap[target], LLVM.PointerType(new_ft, typ.addrspace))
end
elseif val.opcode == LLVM.Opcode.PtrToInt
Expand Down Expand Up @@ -988,9 +990,9 @@ function rewrite_state_uses!(f, ft, state_intr, state_intr_ft)

# forward the state argument
position!(builder, LLVM.before(val))
state_arg = call!(builder, state_intr_ft, state_intr, Value[], "state")
state_arg = call!(builder, state_intr_ft, state_intr, Value[], "state")::LLVM.CallInst
new_val = if val isa LLVM.CallInst
call!(builder, ft, f, Value[state_arg, val.arguments...],
call!(builder, ft, f, Value[state_arg; val.arguments],
val.operand_bundles)
else
# TODO: invoke and callbr
Expand Down Expand Up @@ -1389,7 +1391,7 @@ function add_input_arguments!(@nospecialize(job::CompilerJob), mod::LLVM.Module,
ft = f.function_type
f.name = fn * ".orig"
# create a new function
new_param_types = LLVMType[ft.parameters...]
new_param_types = collect(LLVMType, ft.parameters)

for intr_fn in used_intrinsics
llvm_typ = convert(LLVMType, kernel_intrinsics[intr_fn].typ)
Expand Down Expand Up @@ -1476,7 +1478,7 @@ function rewrite_input_uses!(f, new_f, nargs)
position!(builder, LLVM.before(val))
new_val = if val isa LLVM.CallInst
call!(builder, new_f.function_type, new_f,
Value[val.arguments..., callee_f.parameters[end-nargs+1:end]...],
Value[val.arguments; callee_f.parameters[end-nargs+1:end]],
val.operand_bundles)
else
# TODO: invoke and callbr
Expand Down
Loading
Loading