Skip to content
2 changes: 1 addition & 1 deletion src/llvm.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/llvm/basic_block.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
12 changes: 6 additions & 6 deletions src/llvm/builder.cr
Original file line number Diff line number Diff line change
Expand Up @@ -255,23 +255,23 @@ 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))
LLVM::OperandBundleDef.new LibLLVMExt.build_operand_bundle_def(name, values.to_unsafe.as(LibLLVM::ValueRef*), values.size)
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+")]
Expand Down Expand Up @@ -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 = "")
Expand Down
107 changes: 4 additions & 103 deletions src/llvm/ext/llvm_ext.cc
Original file line number Diff line number Diff line change
@@ -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 <llvm-c/Core.h>
#include <llvm/IR/DIBuilder.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Module.h>
#include <llvm/Support/CBindingWrapping.h>
#include <llvm/IR/DebugLoc.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Metadata.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/ADT/Triple.h>
#include <llvm-c/TargetMachine.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/RTDyldMemoryManager.h>

Expand All @@ -27,7 +22,6 @@ using namespace llvm;
(LLVM_VERSION_MAJOR < (major) || LLVM_VERSION_MAJOR == (major) && LLVM_VERSION_MINOR <= (minor))

#include <llvm/Target/CodeGenCWrappers.h>
#include <llvm-c/DebugInfo.h>
#include <llvm/Bitcode/BitcodeWriter.h>
#include <llvm/Analysis/ModuleSummaryAnalysis.h>

Expand Down Expand Up @@ -243,20 +237,6 @@ LLVMMetadataRef LLVMExtDIBuilderCreatePointerType(
return wrap(T);
}

LLVMMetadataRef LLVMTemporaryMDNode2(
LLVMContextRef C, LLVMMetadataRef *MDs, unsigned Count) {
return wrap(MDTuple::getTemporary(*unwrap(C),
ArrayRef<Metadata *>(unwrap(MDs), Count))
.release());
}

void LLVMMetadataReplaceAllUsesWith2(
LLVMMetadataRef MD, LLVMMetadataRef New) {
auto *Node = unwrap<MDNode>(MD);
Node->replaceAllUsesWith(unwrap<MDNode>(New));
MDNode::deleteTemporary(Node);
}

void LLVMExtSetCurrentDebugLocation(
LLVMBuilderRef Bref, unsigned Line, unsigned Col, LLVMMetadataRef Scope,
LLVMMetadataRef InlinedAt) {
Expand All @@ -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<Value>(MemAccessInst);
AtomicOrdering O = (AtomicOrdering) Ordering;

if (LoadInst *LI = dyn_cast<LoadInst>(P))
return LI->setOrdering(O);
return cast<StoreInst>(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<Value *>(Args, ArgCount), Name));
}

LLVMValueRef LLVMExtBuildCatchRet(
LLVMBuilderRef B, LLVMValueRef Pad, LLVMBasicBlockRef BB) {
return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(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<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
}

OperandBundleDef *LLVMExtBuildOperandBundleDef(
const char *Name, LLVMValueRef *Inputs, unsigned NumInputs) {
return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
Expand Down Expand Up @@ -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<TargetMachine *>(P);
}
Expand Down
7 changes: 1 addition & 6 deletions src/llvm/function.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 11 additions & 1 deletion src/llvm/lib_llvm.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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*)
Expand All @@ -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
Expand Down Expand Up @@ -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*)
Expand All @@ -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
Expand All @@ -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*
Expand Down Expand Up @@ -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*
Expand Down
30 changes: 0 additions & 30 deletions src/llvm/lib_llvm_ext.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
20 changes: 13 additions & 7 deletions src/llvm/value_methods.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down