Skip to content

Commit

Permalink
Merge master & resolve conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
Blacksmoke16 committed Oct 1, 2024
2 parents 25bbf8f + 46ca8fb commit 135e4b5
Show file tree
Hide file tree
Showing 19 changed files with 148 additions and 64 deletions.
16 changes: 9 additions & 7 deletions .github/workflows/llvm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,19 @@ jobs:
matrix:
include:
- llvm_version: "13.0.0"
llvm_ubuntu_version: "20.04"
llvm_filename: "clang+llvm-13.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz"
- llvm_version: "14.0.0"
llvm_ubuntu_version: "18.04"
llvm_filename: "clang+llvm-14.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz"
- llvm_version: "15.0.6"
llvm_ubuntu_version: "18.04"
llvm_filename: "clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz"
- llvm_version: "16.0.3"
llvm_ubuntu_version: "22.04"
llvm_filename: "clang+llvm-16.0.3-x86_64-linux-gnu-ubuntu-22.04.tar.xz"
- llvm_version: "17.0.6"
llvm_ubuntu_version: "22.04"
llvm_filename: "clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04.tar.xz"
- llvm_version: "18.1.4"
llvm_ubuntu_version: "18.04"
llvm_filename: "clang+llvm-18.1.4-x86_64-linux-gnu-ubuntu-18.04.tar.xz"
- llvm_version: "19.1.0"
llvm_filename: "LLVM-19.1.0-Linux-X64.tar.xz"
name: "LLVM ${{ matrix.llvm_version }}"
steps:
- name: Checkout Crystal source
Expand All @@ -44,7 +46,7 @@ jobs:
- name: Install LLVM ${{ matrix.llvm_version }}
run: |
mkdir -p llvm
curl -L "https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.llvm_version }}/clang+llvm-${{ matrix.llvm_version }}-x86_64-linux-gnu-ubuntu-${{ matrix.llvm_ubuntu_version }}.tar.xz" > llvm.tar.xz
curl -L "https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.llvm_version }}/${{ matrix.llvm_filename }}" > llvm.tar.xz
tar x --xz -C llvm --strip-components=1 -f llvm.tar.xz
if: steps.cache-llvm.outputs.cache-hit != 'true'

Expand Down
2 changes: 0 additions & 2 deletions spec/compiler/codegen/debug_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ describe "Code gen: debug" do

it "has debug info in closure inside if (#5593)" do
codegen(%(
require "prelude"
def foo
if true && true
yield 1
Expand Down
23 changes: 9 additions & 14 deletions spec/std/kernel_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -254,27 +254,22 @@ describe "hardware exception" do
error.should_not contain("Stack overflow")
end

{% if flag?(:musl) %}
# FIXME: Pending as mitigation for https://github.com/crystal-lang/crystal/issues/7482
pending "detects stack overflow on the main stack"
{% else %}
it "detects stack overflow on the main stack", tags: %w[slow] do
# This spec can take some time under FreeBSD where
# the default stack size is 0.5G. Setting a
# smaller stack size with `ulimit -s 8192`
# will address this.
status, _, error = compile_and_run_source <<-'CRYSTAL'
it "detects stack overflow on the main stack", tags: %w[slow] do
# This spec can take some time under FreeBSD where
# the default stack size is 0.5G. Setting a
# smaller stack size with `ulimit -s 8192`
# will address this.
status, _, error = compile_and_run_source <<-'CRYSTAL'
def foo
y = StaticArray(Int8, 512).new(0)
foo
end
foo
CRYSTAL

status.success?.should be_false
error.should contain("Stack overflow")
end
{% end %}
status.success?.should be_false
error.should contain("Stack overflow")
end

it "detects stack overflow on a fiber stack", tags: %w[slow] do
status, _, error = compile_and_run_source <<-'CRYSTAL'
Expand Down
8 changes: 0 additions & 8 deletions spec/std/thread/condition_variable_spec.cr
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
{% if flag?(:musl) %}
# FIXME: These thread specs occasionally fail on musl/alpine based ci, so
# they're disabled for now to reduce noise.
# See https://github.com/crystal-lang/crystal/issues/8738
pending Thread::ConditionVariable
{% skip_file %}
{% end %}

require "../spec_helper"

# interpreter doesn't support threads yet (#14287)
Expand Down
8 changes: 0 additions & 8 deletions spec/std/thread/mutex_spec.cr
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
{% if flag?(:musl) %}
# FIXME: These thread specs occasionally fail on musl/alpine based ci, so
# they're disabled for now to reduce noise.
# See https://github.com/crystal-lang/crystal/issues/8738
pending Thread::Mutex
{% skip_file %}
{% end %}

require "../spec_helper"

# interpreter doesn't support threads yet (#14287)
Expand Down
8 changes: 0 additions & 8 deletions spec/std/thread_spec.cr
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
require "./spec_helper"

{% if flag?(:musl) %}
# FIXME: These thread specs occasionally fail on musl/alpine based ci, so
# they're disabled for now to reduce noise.
# See https://github.com/crystal-lang/crystal/issues/8738
pending Thread
{% skip_file %}
{% end %}

# interpreter doesn't support threads yet (#14287)
pending_interpreted describe: Thread do
it "allows passing an argumentless fun to execute" do
Expand Down
16 changes: 16 additions & 0 deletions src/compiler/crystal/codegen/debug.cr
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,16 @@ module Crystal
old_debug_location = @current_debug_location
set_current_debug_location location
if builder.current_debug_location != llvm_nil && (ptr = alloca)
# FIXME: When debug records are used instead of debug intrinsics, it
# seems inserting them into an empty BasicBlock will instead place them
# in a totally different (next?) function where the variable doesn't
# exist, leading to a "function-local metadata used in wrong function"
# validation error. This might happen when e.g. all variables inside a
# block are closured. Ideally every debug record should immediately
# follow the variable it declares.
{% unless LibLLVM::IS_LT_190 %}
call(do_nothing_fun) if block.instructions.empty?
{% end %}
di_builder.insert_declare_at_end(ptr, var, expr, builder.current_debug_location_metadata, block)
set_current_debug_location old_debug_location
true
Expand All @@ -376,6 +386,12 @@ module Crystal
end
end

private def do_nothing_fun
fetch_typed_fun(@llvm_mod, "llvm.donothing") do
LLVM::Type.function([] of LLVM::Type, @llvm_context.void)
end
end

# Emit debug info for toplevel variables. Used for the main module and all
# required files.
def emit_vars_debug_info(vars)
Expand Down
52 changes: 45 additions & 7 deletions src/crystal/system/unix/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,35 @@ module Crystal::System::Thread
@system_handle
end

protected setter system_handle

private def init_handle
# NOTE: the thread may start before `pthread_create` returns, so
# `@system_handle` must be set as soon as possible; we cannot use a separate
# handle and assign it to `@system_handle`, which would have been too late
# NOTE: `@system_handle` needs to be set here too, not just in
# `.thread_proc`, since the current thread might progress first; the value
# of `LibC.pthread_self` inside the new thread must be equal to this
# `@system_handle` after `pthread_create` returns
ret = GC.pthread_create(
thread: pointerof(@system_handle),
attr: Pointer(LibC::PthreadAttrT).null,
start: ->(data : Void*) { data.as(::Thread).start; Pointer(Void).null },
start: ->Thread.thread_proc(Void*),
arg: self.as(Void*),
)

raise RuntimeError.from_os_error("pthread_create", Errno.new(ret)) unless ret == 0
end

def self.thread_proc(data : Void*) : Void*
th = data.as(::Thread)

# `#start` calls `#stack_address`, which might read `@system_handle` before
# `GC.pthread_create` updates it in the original thread that spawned the
# current one, so we also assign to it here
th.system_handle = current_handle

th.start
Pointer(Void).null
end

def self.current_handle : Handle
LibC.pthread_self
end
Expand Down Expand Up @@ -116,11 +131,26 @@ module Crystal::System::Thread
ret = LibC.pthread_attr_destroy(pointerof(attr))
raise RuntimeError.from_os_error("pthread_attr_destroy", Errno.new(ret)) unless ret == 0
{% elsif flag?(:linux) %}
if LibC.pthread_getattr_np(@system_handle, out attr) == 0
LibC.pthread_attr_getstack(pointerof(attr), pointerof(address), out _)
end
ret = LibC.pthread_getattr_np(@system_handle, out attr)
raise RuntimeError.from_os_error("pthread_getattr_np", Errno.new(ret)) unless ret == 0

LibC.pthread_attr_getstack(pointerof(attr), pointerof(address), out stack_size)

ret = LibC.pthread_attr_destroy(pointerof(attr))
raise RuntimeError.from_os_error("pthread_attr_destroy", Errno.new(ret)) unless ret == 0

# with musl-libc, the main thread does not respect `rlimit -Ss` and
# instead returns the same default stack size as non-default threads, so
# we obtain the rlimit to correct the stack address manually
{% if flag?(:musl) %}
if Thread.current_is_main?
if LibC.getrlimit(LibC::RLIMIT_STACK, out rlim) == 0
address = address + stack_size - rlim.rlim_cur
else
raise RuntimeError.from_errno("getrlimit")
end
end
{% end %}
{% elsif flag?(:openbsd) %}
ret = LibC.pthread_stackseg_np(@system_handle, out stack)
raise RuntimeError.from_os_error("pthread_stackseg_np", Errno.new(ret)) unless ret == 0
Expand All @@ -138,6 +168,14 @@ module Crystal::System::Thread
address
end

{% if flag?(:musl) %}
@@main_handle : Handle = current_handle

def self.current_is_main?
current_handle == @@main_handle
end
{% end %}

# Warning: must be called from the current thread itself, because Darwin
# doesn't allow to set the name of any thread but the current one!
private def system_name=(name : String) : String
Expand Down
9 changes: 7 additions & 2 deletions src/intrinsics.cr
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,13 @@ lib LibIntrinsics
{% if flag?(:interpreted) %} @[Primitive(:interpreter_intrinsics_fshr128)] {% end %}
fun fshr128 = "llvm.fshr.i128"(a : UInt128, b : UInt128, count : UInt128) : UInt128

fun va_start = "llvm.va_start"(ap : Void*)
fun va_end = "llvm.va_end"(ap : Void*)
{% if compare_versions(Crystal::LLVM_VERSION, "19.1.0") < 0 %}
fun va_start = "llvm.va_start"(ap : Void*)
fun va_end = "llvm.va_end"(ap : Void*)
{% else %}
fun va_start = "llvm.va_start.p0"(ap : Void*)
fun va_end = "llvm.va_end.p0"(ap : Void*)
{% end %}

{% if flag?(:i386) || flag?(:x86_64) %}
{% if flag?(:interpreted) %} @[Primitive(:interpreter_intrinsics_pause)] {% end %}
Expand Down
11 changes: 11 additions & 0 deletions src/lib_c/aarch64-linux-musl/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
lib LibC
alias RlimT = ULongLong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
11 changes: 11 additions & 0 deletions src/lib_c/i386-linux-musl/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
lib LibC
alias RlimT = ULongLong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
11 changes: 11 additions & 0 deletions src/lib_c/x86_64-linux-musl/c/sys/resource.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
lib LibC
alias RlimT = ULongLong

struct Rlimit
rlim_cur : RlimT
rlim_max : RlimT
end

fun getrlimit(Int, Rlimit*) : Int

RLIMIT_STACK = 3

struct RUsage
ru_utime : Timeval
ru_stime : Timeval
Expand Down
6 changes: 5 additions & 1 deletion src/llvm/context.cr
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ class LLVM::Context
end

def const_string(string : String) : Value
Value.new LibLLVM.const_string_in_context(self, string, string.bytesize, 0)
{% if LibLLVM::IS_LT_190 %}
Value.new LibLLVM.const_string_in_context(self, string, string.bytesize, 0)
{% else %}
Value.new LibLLVM.const_string_in_context2(self, string, string.bytesize, 0)
{% end %}
end

def const_struct(values : Array(LLVM::Value), packed = false) : Value
Expand Down
6 changes: 5 additions & 1 deletion src/llvm/di_builder.cr
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,11 @@ struct LLVM::DIBuilder
end

def insert_declare_at_end(storage, var_info, expr, dl : LibLLVM::MetadataRef, block)
LibLLVM.di_builder_insert_declare_at_end(self, storage, var_info, expr, dl, block)
{% if LibLLVM::IS_LT_190 %}
LibLLVM.di_builder_insert_declare_at_end(self, storage, var_info, expr, dl, block)
{% else %}
LibLLVM.di_builder_insert_declare_record_at_end(self, storage, var_info, expr, dl, block)
{% end %}
end

def get_or_create_array(elements : Array(LibLLVM::MetadataRef))
Expand Down
2 changes: 1 addition & 1 deletion src/llvm/ext/llvm-versions.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18.1 17.0 16.0 15.0 14.0 13.0 12.0 11.1 11.0 10.0 9.0 8.0
19.1 18.1 17.0 16.0 15.0 14.0 13.0 12.0 11.1 11.0 10.0 9.0 8.0
1 change: 1 addition & 0 deletions src/llvm/lib_llvm.cr
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
IS_LT_160 = {{compare_versions(LibLLVM::VERSION, "16.0.0") < 0}}
IS_LT_170 = {{compare_versions(LibLLVM::VERSION, "17.0.0") < 0}}
IS_LT_180 = {{compare_versions(LibLLVM::VERSION, "18.0.0") < 0}}
IS_LT_190 = {{compare_versions(LibLLVM::VERSION, "19.0.0") < 0}}
end
{% end %}

Expand Down
6 changes: 5 additions & 1 deletion src/llvm/lib_llvm/core.cr
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ lib LibLLVM
fun const_int_get_zext_value = LLVMConstIntGetZExtValue(constant_val : ValueRef) : ULongLong
fun const_int_get_sext_value = LLVMConstIntGetSExtValue(constant_val : ValueRef) : LongLong

fun const_string_in_context = LLVMConstStringInContext(c : ContextRef, str : Char*, length : UInt, dont_null_terminate : Bool) : ValueRef
{% if LibLLVM::IS_LT_190 %}
fun const_string_in_context = LLVMConstStringInContext(c : ContextRef, str : Char*, length : UInt, dont_null_terminate : Bool) : ValueRef
{% else %}
fun const_string_in_context2 = LLVMConstStringInContext2(c : ContextRef, str : Char*, length : SizeT, dont_null_terminate : Bool) : ValueRef
{% end %}
fun const_struct_in_context = LLVMConstStructInContext(c : ContextRef, constant_vals : ValueRef*, count : UInt, packed : Bool) : ValueRef
fun const_array = LLVMConstArray(element_ty : TypeRef, constant_vals : ValueRef*, length : UInt) : ValueRef

Expand Down
15 changes: 11 additions & 4 deletions src/llvm/lib_llvm/debug_info.cr
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,17 @@ lib LibLLVM

fun metadata_replace_all_uses_with = LLVMMetadataReplaceAllUsesWith(target_metadata : MetadataRef, replacement : MetadataRef)

fun di_builder_insert_declare_at_end = LLVMDIBuilderInsertDeclareAtEnd(
builder : DIBuilderRef, storage : ValueRef, var_info : MetadataRef,
expr : MetadataRef, debug_loc : MetadataRef, block : BasicBlockRef,
) : ValueRef
{% if LibLLVM::IS_LT_190 %}
fun di_builder_insert_declare_at_end = LLVMDIBuilderInsertDeclareAtEnd(
builder : DIBuilderRef, storage : ValueRef, var_info : MetadataRef,
expr : MetadataRef, debug_loc : MetadataRef, block : BasicBlockRef,
) : ValueRef
{% else %}
fun di_builder_insert_declare_record_at_end = LLVMDIBuilderInsertDeclareRecordAtEnd(
builder : DIBuilderRef, storage : ValueRef, var_info : MetadataRef,
expr : MetadataRef, debug_loc : MetadataRef, block : BasicBlockRef,
) : DbgRecordRef
{% end %}

fun di_builder_create_auto_variable = LLVMDIBuilderCreateAutoVariable(
builder : DIBuilderRef, scope : MetadataRef, name : Char*, name_len : SizeT, file : MetadataRef,
Expand Down
1 change: 1 addition & 0 deletions src/llvm/lib_llvm/types.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ lib LibLLVM
{% end %}
type OperandBundleRef = Void*
type AttributeRef = Void*
type DbgRecordRef = Void*
end

0 comments on commit 135e4b5

Please sign in to comment.