diff --git a/src/llvm.cr b/src/llvm.cr index 5752ade47c1a..12106d9e05d3 100644 --- a/src/llvm.cr +++ b/src/llvm.cr @@ -108,7 +108,7 @@ module LLVM end def self.normalize_triple(triple : String) : String - normalized = LibLLVMExt.normalize_target_triple(triple) + normalized = LibLLVM.normalize_target_triple(triple) normalized = LLVM.string_and_dispose(normalized) normalized diff --git a/src/llvm/basic_block.cr b/src/llvm/basic_block.cr index 973f6e38483b..47511320fc82 100644 --- a/src/llvm/basic_block.cr +++ b/src/llvm/basic_block.cr @@ -20,6 +20,6 @@ struct LLVM::BasicBlock def name block_name = LibLLVM.get_basic_block_name(self) - block_name ? LLVM.string_and_dispose(block_name) : nil + block_name ? String.new(block_name) : nil end end diff --git a/src/llvm/builder.cr b/src/llvm/builder.cr index 2b254f991d60..3194f880c215 100644 --- a/src/llvm/builder.cr +++ b/src/llvm/builder.cr @@ -255,15 +255,15 @@ class LLVM::Builder end def catch_switch(parent_pad, basic_block, num_handlers, name = "") - Value.new LibLLVMExt.build_catch_switch(self, parent_pad, basic_block, num_handlers, name) + Value.new LibLLVM.build_catch_switch(self, parent_pad, basic_block, num_handlers, name) end def catch_pad(parent_pad, args : Array(LLVM::Value), name = "") - Value.new LibLLVMExt.build_catch_pad(self, parent_pad, args.size, args.to_unsafe.as(LibLLVM::ValueRef*), name) + Value.new LibLLVM.build_catch_pad(self, parent_pad, args.to_unsafe.as(LibLLVM::ValueRef*), args.size, name) end def add_handler(catch_switch_ref, handler) - LibLLVMExt.add_handler catch_switch_ref, handler + LibLLVM.add_handler catch_switch_ref, handler end def build_operand_bundle_def(name, values : Array(LLVM::Value)) @@ -271,7 +271,7 @@ class LLVM::Builder end def build_catch_ret(pad, basic_block) - LibLLVMExt.build_catch_ret(self, pad, basic_block) + LibLLVM.build_catch_ret(self, pad, basic_block) end @[Deprecated("Pass the function type of `fn` as well (equal to `fn.function_type`) in order to support LLVM 15+")] @@ -302,8 +302,8 @@ class LLVM::Builder Value.new LibLLVM.build_atomicrmw(self, op, ptr, val, ordering, singlethread ? 1 : 0) end - def cmpxchg(pointer, cmp, new, success_ordering, failure_ordering) - Value.new LibLLVMExt.build_cmpxchg(self, pointer, cmp, new, success_ordering, failure_ordering) + def cmpxchg(pointer, cmp, new, success_ordering, failure_ordering, singlethread : Bool = false) + Value.new LibLLVM.build_atomic_cmp_xchg(self, pointer, cmp, new, success_ordering, failure_ordering, singlethread ? 1 : 0) end def fence(ordering, singlethread, name = "") diff --git a/src/llvm/ext/llvm_ext.cc b/src/llvm/ext/llvm_ext.cc index 0f38b389f802..77054025dad9 100644 --- a/src/llvm/ext/llvm_ext.cc +++ b/src/llvm/ext/llvm_ext.cc @@ -1,17 +1,12 @@ -#include "llvm/IR/DIBuilder.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/CBindingWrapping.h" -#include +#include +#include +#include +#include #include #include #include #include #include -#include -#include -#include -#include #include #include @@ -27,7 +22,6 @@ using namespace llvm; (LLVM_VERSION_MAJOR < (major) || LLVM_VERSION_MAJOR == (major) && LLVM_VERSION_MINOR <= (minor)) #include -#include #include #include @@ -243,20 +237,6 @@ LLVMMetadataRef LLVMExtDIBuilderCreatePointerType( return wrap(T); } -LLVMMetadataRef LLVMTemporaryMDNode2( - LLVMContextRef C, LLVMMetadataRef *MDs, unsigned Count) { - return wrap(MDTuple::getTemporary(*unwrap(C), - ArrayRef(unwrap(MDs), Count)) - .release()); -} - -void LLVMMetadataReplaceAllUsesWith2( - LLVMMetadataRef MD, LLVMMetadataRef New) { - auto *Node = unwrap(MD); - Node->replaceAllUsesWith(unwrap(New)); - MDNode::deleteTemporary(Node); -} - void LLVMExtSetCurrentDebugLocation( LLVMBuilderRef Bref, unsigned Line, unsigned Col, LLVMMetadataRef Scope, LLVMMetadataRef InlinedAt) { @@ -275,80 +255,6 @@ void LLVMExtSetCurrentDebugLocation( #endif } -#if LLVM_VERSION_LE(13, 0) -// A backported LLVMCreateTypeAttribute for LLVM < 13 -// from https://github.com/llvm/llvm-project/blob/bb8ce25e88218be60d2a4ea9c9b0b721809eff27/llvm/lib/IR/Core.cpp#L167 -LLVMAttributeRef LLVMExtCreateTypeAttribute( - LLVMContextRef C, unsigned KindID, LLVMTypeRef Ty) { - auto &Ctx = *unwrap(C); - auto AttrKind = (Attribute::AttrKind)KindID; -#if LLVM_VERSION_GE(12, 0) - return wrap(Attribute::get(Ctx, AttrKind, unwrap(Ty))); -#else - return wrap(Attribute::get(Ctx, AttrKind)); -#endif -} -#endif - -LLVMValueRef LLVMExtBuildCmpxchg( - LLVMBuilderRef B, LLVMValueRef PTR, LLVMValueRef Cmp, LLVMValueRef New, - LLVMAtomicOrdering SuccessOrdering, LLVMAtomicOrdering FailureOrdering) { -#if LLVM_VERSION_GE(13, 0) - return wrap( - unwrap(B)->CreateAtomicCmpXchg( - unwrap(PTR), - unwrap(Cmp), - unwrap(New), - llvm::MaybeAlign(), - (llvm::AtomicOrdering)SuccessOrdering, - (llvm::AtomicOrdering)FailureOrdering - ) - ); -#else - return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(PTR), unwrap(Cmp), unwrap(New), - (llvm::AtomicOrdering)SuccessOrdering, (llvm::AtomicOrdering)FailureOrdering)); -#endif -} - -void LLVMExtSetOrdering(LLVMValueRef MemAccessInst, LLVMAtomicOrdering Ordering) { - Value *P = unwrap(MemAccessInst); - AtomicOrdering O = (AtomicOrdering) Ordering; - - if (LoadInst *LI = dyn_cast(P)) - return LI->setOrdering(O); - return cast(P)->setOrdering(O); -} - -LLVMValueRef LLVMExtBuildCatchPad( - LLVMBuilderRef B, LLVMValueRef ParentPad, unsigned ArgCount, - LLVMValueRef *LLArgs, const char *Name) { - Value **Args = unwrap(LLArgs); - return wrap(unwrap(B)->CreateCatchPad( - unwrap(ParentPad), ArrayRef(Args, ArgCount), Name)); -} - -LLVMValueRef LLVMExtBuildCatchRet( - LLVMBuilderRef B, LLVMValueRef Pad, LLVMBasicBlockRef BB) { - return wrap(unwrap(B)->CreateCatchRet(cast(unwrap(Pad)), - unwrap(BB))); -} - -LLVMValueRef LLVMExtBuildCatchSwitch( - LLVMBuilderRef B, LLVMValueRef ParentPad, LLVMBasicBlockRef BB, - unsigned NumHandlers, const char *Name) { - if (ParentPad == nullptr) { - Type *Ty = Type::getTokenTy(unwrap(B)->getContext()); - ParentPad = wrap(Constant::getNullValue(Ty)); - } - return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB), - NumHandlers, Name)); -} - -void LLVMExtAddHandler(LLVMValueRef CatchSwitchRef, LLVMBasicBlockRef Handler) { - Value *CatchSwitch = unwrap(CatchSwitchRef); - cast(CatchSwitch)->addHandler(unwrap(Handler)); -} - OperandBundleDef *LLVMExtBuildOperandBundleDef( const char *Name, LLVMValueRef *Inputs, unsigned NumInputs) { return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs)); @@ -390,11 +296,6 @@ void LLVMExtWriteBitcodeWithSummaryToFile(LLVMModuleRef mref, const char *File) llvm::WriteBitcodeToFile(*m, OS, true, &moduleSummaryIndex, true); } -// Missing LLVMNormalizeTargetTriple in LLVM <= 7.0 -char *LLVMExtNormalizeTargetTriple(const char* triple) { - return strdup(Triple::normalize(StringRef(triple)).c_str()); -} - static TargetMachine *unwrap(LLVMTargetMachineRef P) { return reinterpret_cast(P); } diff --git a/src/llvm/function.cr b/src/llvm/function.cr index 1b4d803fc08f..a586cd6fdde5 100644 --- a/src/llvm/function.cr +++ b/src/llvm/function.cr @@ -24,12 +24,7 @@ struct LLVM::Function context = LibLLVM.get_module_context(LibLLVM.get_global_parent(self)) attribute.each_kind do |kind| - if type && LLVM::Attribute.requires_type?(kind) - attribute_ref = LibLLVMExt.create_type_attribute(context, kind, type) - else - attribute_ref = LibLLVM.create_enum_attribute(context, kind, 0) - end - LibLLVM.add_attribute_at_index(self, index, attribute_ref) + LibLLVM.add_attribute_at_index(self, index, attribute_ref(context, kind, type)) end end diff --git a/src/llvm/lib_llvm.cr b/src/llvm/lib_llvm.cr index 0393410724f8..dc491c536db2 100644 --- a/src/llvm/lib_llvm.cr +++ b/src/llvm/lib_llvm.cr @@ -84,6 +84,7 @@ lib LibLLVM fun add_clause = LLVMAddClause(lpad : ValueRef, clause_val : ValueRef) fun add_function = LLVMAddFunction(module : ModuleRef, name : UInt8*, type : TypeRef) : ValueRef fun add_global = LLVMAddGlobal(module : ModuleRef, type : TypeRef, name : UInt8*) : ValueRef + fun add_handler = LLVMAddHandler(catch_switch : ValueRef, dest : BasicBlockRef) fun add_incoming = LLVMAddIncoming(phi_node : ValueRef, incoming_values : ValueRef*, incoming_blocks : BasicBlockRef*, count : Int32) fun add_module_flag = LLVMAddModuleFlag(mod : ModuleRef, behavior : ModuleFlagBehavior, key : UInt8*, len : LibC::SizeT, val : MetadataRef) fun add_target_dependent_function_attr = LLVMAddTargetDependentFunctionAttr(fn : ValueRef, a : LibC::Char*, v : LibC::Char*) @@ -96,9 +97,13 @@ lib LibLLVM fun build_array_malloc = LLVMBuildArrayMalloc(builder : BuilderRef, type : TypeRef, val : ValueRef, name : UInt8*) : ValueRef fun build_ashr = LLVMBuildAShr(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef fun build_atomicrmw = LLVMBuildAtomicRMW(builder : BuilderRef, op : LLVM::AtomicRMWBinOp, ptr : ValueRef, val : ValueRef, ordering : LLVM::AtomicOrdering, singlethread : Int32) : ValueRef + fun build_atomic_cmp_xchg = LLVMBuildAtomicCmpXchg(builder : BuilderRef, ptr : ValueRef, cmp : ValueRef, new : ValueRef, success_ordering : LLVM::AtomicOrdering, failure_ordering : LLVM::AtomicOrdering, single_thread : Int) : ValueRef fun build_bit_cast = LLVMBuildBitCast(builder : BuilderRef, value : ValueRef, type : TypeRef, name : UInt8*) : ValueRef fun build_br = LLVMBuildBr(builder : BuilderRef, block : BasicBlockRef) : ValueRef fun build_call2 = LLVMBuildCall2(builder : BuilderRef, type : TypeRef, fn : ValueRef, args : ValueRef*, num_args : Int32, name : UInt8*) : ValueRef + fun build_catch_pad = LLVMBuildCatchPad(b : BuilderRef, parent_pad : ValueRef, args : ValueRef*, num_args : UInt, name : Char*) : ValueRef + fun build_catch_ret = LLVMBuildCatchRet(b : BuilderRef, catch_pad : ValueRef, bb : BasicBlockRef) : ValueRef + fun build_catch_switch = LLVMBuildCatchSwitch(b : BuilderRef, parent_pad : ValueRef, unwind_bb : BasicBlockRef, num_handlers : UInt, name : Char*) : ValueRef fun build_cond = LLVMBuildCondBr(builder : BuilderRef, if : ValueRef, then : BasicBlockRef, else : BasicBlockRef) : ValueRef fun build_exact_sdiv = LLVMBuildExactSDiv(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef fun build_extract_value = LLVMBuildExtractValue(builder : BuilderRef, agg_val : ValueRef, index : UInt32, name : UInt8*) : ValueRef @@ -160,6 +165,9 @@ lib LibLLVM fun create_jit_compiler_for_module = LLVMCreateJITCompilerForModule(jit : ExecutionEngineRef*, m : ModuleRef, opt_level : Int32, error : UInt8**) : Int32 fun create_mc_jit_compiler_for_module = LLVMCreateMCJITCompilerForModule(jit : ExecutionEngineRef*, m : ModuleRef, options : JITCompilerOptions*, options_length : UInt32, error : UInt8**) : Int32 fun create_target_machine = LLVMCreateTargetMachine(target : TargetRef, triple : UInt8*, cpu : UInt8*, features : UInt8*, level : LLVM::CodeGenOptLevel, reloc : LLVM::RelocMode, code_model : LLVM::CodeModel) : TargetMachineRef + {% unless LibLLVM::IS_LT_120 %} + fun create_type_attribute = LLVMCreateTypeAttribute(ctx : ContextRef, kind_id : UInt, ty : TypeRef) : AttributeRef + {% end %} fun delete_basic_block = LLVMDeleteBasicBlock(block : BasicBlockRef) fun delete_function = LLVMDeleteFunction(fn : ValueRef) fun dispose_message = LLVMDisposeMessage(msg : UInt8*) @@ -170,7 +178,7 @@ lib LibLLVM fun generic_value_to_float = LLVMGenericValueToFloat(type : TypeRef, value : GenericValueRef) : Float64 fun generic_value_to_int = LLVMGenericValueToInt(value : GenericValueRef, signed : Int32) : UInt64 fun generic_value_to_pointer = LLVMGenericValueToPointer(value : GenericValueRef) : Void* - fun get_basic_block_name = LLVMGetBasicBlockName(basic_block : LibLLVM::BasicBlockRef) : Char* + fun get_basic_block_name = LLVMGetBasicBlockName(basic_block : BasicBlockRef) : Char* fun get_current_debug_location = LLVMGetCurrentDebugLocation(builder : BuilderRef) : ValueRef fun get_first_instruction = LLVMGetFirstInstruction(block : BasicBlockRef) : ValueRef fun get_first_target = LLVMGetFirstTarget : TargetRef @@ -189,6 +197,7 @@ lib LibLLVM fun get_target_description = LLVMGetTargetDescription(target : TargetRef) : UInt8* fun get_target_machine_triple = LLVMGetTargetMachineTriple(t : TargetMachineRef) : UInt8* fun get_target_from_triple = LLVMGetTargetFromTriple(triple : UInt8*, target : TargetRef*, error_message : UInt8**) : Int32 + fun normalize_target_triple = LLVMNormalizeTargetTriple(triple : Char*) : Char* fun get_type_kind = LLVMGetTypeKind(ty : TypeRef) : LLVM::Type::Kind fun get_undef = LLVMGetUndef(ty : TypeRef) : ValueRef fun get_value_name = LLVMGetValueName(value : ValueRef) : UInt8* @@ -288,6 +297,7 @@ lib LibLLVM fun set_function_call_convention = LLVMSetFunctionCallConv(fn : ValueRef, cc : LLVM::CallConvention) fun set_instruction_call_convention = LLVMSetInstructionCallConv(instr : ValueRef, cc : LLVM::CallConvention) fun get_instruction_call_convention = LLVMGetInstructionCallConv(instr : ValueRef) : LLVM::CallConvention + fun set_ordering = LLVMSetOrdering(memory_access_inst : ValueRef, ordering : LLVM::AtomicOrdering) fun get_int_type_width = LLVMGetIntTypeWidth(ty : TypeRef) : UInt32 fun is_packed_struct = LLVMIsPackedStruct(ty : TypeRef) : Int32 fun get_struct_name = LLVMGetStructName(ty : TypeRef) : UInt8* diff --git a/src/llvm/lib_llvm_ext.cr b/src/llvm/lib_llvm_ext.cr index 5d484b06d665..c99656f5e81c 100644 --- a/src/llvm/lib_llvm_ext.cr +++ b/src/llvm/lib_llvm_ext.cr @@ -117,28 +117,6 @@ lib LibLLVMExt fun set_current_debug_location = LLVMExtSetCurrentDebugLocation(LibLLVM::BuilderRef, Int, Int, LibLLVM::MetadataRef, LibLLVM::MetadataRef) - fun build_cmpxchg = LLVMExtBuildCmpxchg(builder : LibLLVM::BuilderRef, pointer : LibLLVM::ValueRef, cmp : LibLLVM::ValueRef, new : LibLLVM::ValueRef, success_ordering : LLVM::AtomicOrdering, failure_ordering : LLVM::AtomicOrdering) : LibLLVM::ValueRef - fun set_ordering = LLVMExtSetOrdering(value : LibLLVM::ValueRef, ordering : LLVM::AtomicOrdering) - - fun build_catch_pad = LLVMExtBuildCatchPad(builder : LibLLVM::BuilderRef, - parent_pad : LibLLVM::ValueRef, - arg_count : LibC::UInt, - args : LibLLVM::ValueRef*, - name : LibC::Char*) : LibLLVM::ValueRef - - fun build_catch_ret = LLVMExtBuildCatchRet(builder : LibLLVM::BuilderRef, - pad : LibLLVM::ValueRef, - basic_block : LibLLVM::BasicBlockRef) : LibLLVM::ValueRef - - fun build_catch_switch = LLVMExtBuildCatchSwitch(builder : LibLLVM::BuilderRef, - parent_pad : LibLLVM::ValueRef, - basic_block : LibLLVM::BasicBlockRef, - num_handlers : LibC::UInt, - name : LibC::Char*) : LibLLVM::ValueRef - - fun add_handler = LLVMExtAddHandler(catch_switch_ref : LibLLVM::ValueRef, - handler : LibLLVM::BasicBlockRef) : Void - fun build_operand_bundle_def = LLVMExtBuildOperandBundleDef(name : LibC::Char*, input : LibLLVM::ValueRef*, num_input : LibC::UInt) : LibLLVMExt::OperandBundleDefRef @@ -156,16 +134,8 @@ lib LibLLVMExt fun write_bitcode_with_summary_to_file = LLVMExtWriteBitcodeWithSummaryToFile(module : LibLLVM::ModuleRef, path : UInt8*) : Void - fun normalize_target_triple = LLVMExtNormalizeTargetTriple(triple : Char*) : Char* fun di_builder_get_or_create_array_subrange = LLVMExtDIBuilderGetOrCreateArraySubrange(builder : DIBuilder, lo : UInt64, count : UInt64) : LibLLVM::MetadataRef fun target_machine_enable_global_isel = LLVMExtTargetMachineEnableGlobalIsel(machine : LibLLVM::TargetMachineRef, enable : Bool) fun create_mc_jit_compiler_for_module = LLVMExtCreateMCJITCompilerForModule(jit : LibLLVM::ExecutionEngineRef*, m : LibLLVM::ModuleRef, options : LibLLVM::JITCompilerOptions*, options_length : UInt32, enable_global_isel : Bool, error : UInt8**) : Int32 - - # LLVMCreateTypeAttribute is implemented in LLVM 13, but needed in 12 - {% if LibLLVM::IS_LT_130 %} - fun create_type_attribute = LLVMExtCreateTypeAttribute(ctx : LibLLVM::ContextRef, kind_id : LibC::UInt, ty : LibLLVM::TypeRef) : LibLLVM::AttributeRef - {% else %} - fun create_type_attribute = LLVMCreateTypeAttribute(ctx : LibLLVM::ContextRef, kind_id : LibC::UInt, ty : LibLLVM::TypeRef) : LibLLVM::AttributeRef - {% end %} end diff --git a/src/llvm/value_methods.cr b/src/llvm/value_methods.cr index 91fb55700ee0..e76daf3d53e0 100644 --- a/src/llvm/value_methods.cr +++ b/src/llvm/value_methods.cr @@ -18,13 +18,19 @@ module LLVM::ValueMethods return if attribute.value == 0 attribute.each_kind do |kind| - if type && LLVM::Attribute.requires_type?(kind) - attribute_ref = LibLLVMExt.create_type_attribute(context, kind, type) - else - attribute_ref = LibLLVM.create_enum_attribute(context, kind, 0) - end + LibLLVM.add_call_site_attribute(self, index, attribute_ref(context, kind, type)) + end + end - LibLLVM.add_call_site_attribute(self, index, attribute_ref) + private def attribute_ref(context, kind, type) + if type.is_a?(Type) && Attribute.requires_type?(kind) + {% if LibLLVM::IS_LT_120 %} + raise "Type arguments are only supported on LLVM 12.0 or above" + {% else %} + LibLLVM.create_type_attribute(context, kind, type) + {% end %} + else + LibLLVM.create_enum_attribute(context, kind, 0) end end @@ -86,7 +92,7 @@ module LLVM::ValueMethods end def ordering=(ordering) - LibLLVMExt.set_ordering(self, ordering) + LibLLVM.set_ordering(self, ordering) end def alignment=(bytes)