Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: a431a57b37d1
Choose a base ref
...
head repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 72fe026ef85c
Choose a head ref
  • 4 commits
  • 5 files changed
  • 2 contributors

Commits on Jun 23, 2017

  1. Copy the full SHA
    16057bb View commit details
  2. LLVM: Add BasicBlock.null

    Brian J. Cardiff committed Jun 23, 2017
    Copy the full SHA
    544c893 View commit details
  3. LLVM: Render call and invoke with OperandBundle (ie: funclet)

    Brian J. Cardiff committed Jun 23, 2017
    Copy the full SHA
    ab1847d View commit details
  4. Merge pull request #4501 from bcardiff/llvm-operand-bundle-def

    Add llvm operand bundle def and catch pad/ret/switch
    bcardiff authored Jun 23, 2017
    Copy the full SHA
    72fe026 View commit details
Showing with 163 additions and 4 deletions.
  1. +4 −0 src/llvm/basic_block.cr
  2. +24 −4 src/llvm/builder.cr
  3. +86 −0 src/llvm/ext/llvm_ext.cc
  4. +37 −0 src/llvm/lib_llvm_ext.cr
  5. +12 −0 src/llvm/operand_bundle_def.cr
4 changes: 4 additions & 0 deletions src/llvm/basic_block.cr
Original file line number Diff line number Diff line change
@@ -2,6 +2,10 @@ struct LLVM::BasicBlock
def initialize(@unwrap : LibLLVM::BasicBlockRef)
end

def self.null
LLVM::BasicBlock.new(Pointer(::Void).null.as(LibLLVM::BasicBlockRef))
end

def instructions
InstructionCollection.new self
end
28 changes: 24 additions & 4 deletions src/llvm/builder.cr
Original file line number Diff line number Diff line change
@@ -63,11 +63,11 @@ class LLVM::Builder
Value.new LibLLVM.build_call(self, func, pointerof(value), 1, name)
end

def call(func, args : Array(LLVM::Value), name : String = "")
def call(func, args : Array(LLVM::Value), name : String = "", bundle : LLVM::OperandBundleDef = LLVM::OperandBundleDef.null)
# check_func(func)
# check_values(args)

Value.new LibLLVM.build_call(self, func, (args.to_unsafe.as(LibLLVM::ValueRef*)), args.size, name)
Value.new LibLLVMExt.build_call(self, func, (args.to_unsafe.as(LibLLVM::ValueRef*)), args.size, bundle, name)
end

def alloca(type, name = "")
@@ -192,10 +192,30 @@ class LLVM::Builder
Value.new lpad
end

def invoke(fn, args : Array(LLVM::Value), a_then, a_catch, name = "")
def catch_switch(parent_pad, basic_block, num_handlers, name = "")
Value.new LibLLVMExt.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)
end

def add_handler(catch_switch_ref, handler)
LibLLVMExt.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)
end

def invoke(fn, args : Array(LLVM::Value), a_then, a_catch, bundle : LLVM::OperandBundleDef = LLVM::OperandBundleDef.null, name = "")
# check_func(fn)

Value.new LibLLVM.build_invoke self, fn, (args.to_unsafe.as(LibLLVM::ValueRef*)), args.size, a_then, a_catch, name
Value.new LibLLVMExt.build_invoke self, fn, (args.to_unsafe.as(LibLLVM::ValueRef*)), args.size, a_then, a_catch, bundle, name
end

def switch(value, otherwise, cases)
86 changes: 86 additions & 0 deletions src/llvm/ext/llvm_ext.cc
Original file line number Diff line number Diff line change
@@ -499,4 +499,90 @@ void LLVMExtSetOrdering(LLVMValueRef MemAccessInst, LLVMAtomicOrdering Ordering)
return cast<StoreInst>(P)->setOrdering(O);
}

LLVMValueRef LLVMExtBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
#if LLVM_VERSION_GE(3, 8)
Value **Args = unwrap(LLArgs);
return wrap(unwrap(B)->CreateCatchPad(
unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
#else
return nullptr;
#endif
}

LLVMValueRef LLVMExtBuildCatchRet(LLVMBuilderRef B,
LLVMValueRef Pad,
LLVMBasicBlockRef BB) {
#if LLVM_VERSION_GE(3, 8)
return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
unwrap(BB)));
#else
return nullptr;
#endif
}

LLVMValueRef LLVMExtBuildCatchSwitch(LLVMBuilderRef B,
LLVMValueRef ParentPad,
LLVMBasicBlockRef BB,
unsigned NumHandlers,
const char *Name) {
#if LLVM_VERSION_GE(3, 8)
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));
#else
return nullptr;
#endif
}

void LLVMExtAddHandler(LLVMValueRef CatchSwitchRef,
LLVMBasicBlockRef Handler) {
#if LLVM_VERSION_GE(3, 8)
Value *CatchSwitch = unwrap(CatchSwitchRef);
cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
#endif
}

OperandBundleDef *LLVMExtBuildOperandBundleDef(const char *Name,
LLVMValueRef *Inputs,
unsigned NumInputs) {
#if LLVM_VERSION_GE(3, 8)
return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
#else
return nullptr;
#endif
}

LLVMValueRef LLVMExtBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
OperandBundleDef *Bundle,
const char *Name) {
#if LLVM_VERSION_GE(3, 8)
unsigned Len = Bundle ? 1 : 0;
ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
return wrap(unwrap(B)->CreateCall(
unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Bundles, Name));
#else
return LLVMBuildCall(B, Fn, Args, NumArgs, Name);
#endif
}

LLVMValueRef LLVMExtBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
unsigned NumArgs, LLVMBasicBlockRef Then,
LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
const char *Name) {
#if LLVM_VERSION_GE(3, 8)
unsigned Len = Bundle ? 1 : 0;
ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch),
makeArrayRef(unwrap(Args), NumArgs),
Bundles, Name));
#else
return LLVMBuildInvoke(B, Fn, Args, NumArgs, Then, Catch, Name);
#endif
}

}
37 changes: 37 additions & 0 deletions src/llvm/lib_llvm_ext.cr
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ lib LibLLVMExt

type DIBuilder = Void*
type Metadata = Void*
type OperandBundleDefRef = Void*

fun create_di_builder = LLVMNewDIBuilder(LibLLVM::ModuleRef) : DIBuilder
fun di_builder_finalize = LLVMDIBuilderFinalize(DIBuilder)
@@ -109,4 +110,40 @@ lib LibLLVMExt

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)

{% if LibLLVM::IS_38 || LibLLVM::IS_39 %}
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
{% end %}

fun build_operand_bundle_def = LLVMExtBuildOperandBundleDef(name : LibC::Char*,
input : LibLLVM::ValueRef*,
num_input : LibC::UInt) : LibLLVMExt::OperandBundleDefRef

fun build_call = LLVMExtBuildCall(builder : LibLLVM::BuilderRef, fn : LibLLVM::ValueRef,
args : LibLLVM::ValueRef*, arg_count : LibC::UInt,
bundle : LibLLVMExt::OperandBundleDefRef,
name : LibC::Char*) : LibLLVM::ValueRef

fun build_invoke = LLVMExtBuildInvoke(builder : LibLLVM::BuilderRef, fn : LibLLVM::ValueRef,
args : LibLLVM::ValueRef*, arg_count : LibC::UInt,
then : LibLLVM::BasicBlockRef, catch : LibLLVM::BasicBlockRef,
bundle : LibLLVMExt::OperandBundleDefRef,
name : LibC::Char*) : LibLLVM::ValueRef
end
12 changes: 12 additions & 0 deletions src/llvm/operand_bundle_def.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
struct LLVM::OperandBundleDef
def initialize(@unwrap : LibLLVMExt::OperandBundleDefRef)
end

def self.null
LLVM::OperandBundleDef.new(Pointer(::Void).null.as(LibLLVMExt::OperandBundleDefRef))
end

def to_unsafe
@unwrap
end
end