Skip to content

Commit

Permalink
Merge #16
Browse files Browse the repository at this point in the history
Added fixes for scalar transform symbol names.

Squashed commit of the following:

commit 92321f5
Author: Peter Zotov <whitequark@whitequark.org>
Date:   Tue Jan 22 00:48:58 2013 +0400

    Add constant int_to_ptr and ptr_to_int.

commit ed0389f
Author: Peter Zotov <whitequark@whitequark.org>
Date:   Mon Jan 21 15:11:22 2013 +0400

    Reword the JIT passage in readme.

commit 1a61cf7
Author: Peter Zotov <whitequark@whitequark.org>
Date:   Mon Jan 21 14:56:10 2013 +0400

    Add missing nsw/nuw instructions (#10).

commit 969a044
Author: Peter Zotov <whitequark@whitequark.org>
Date:   Mon Jan 21 14:46:03 2013 +0400

    Add missing arithmetic operations on constants (#10).

commit e69d2db
Author: Peter Zotov <whitequark@whitequark.org>
Date:   Mon Jan 21 14:31:46 2013 +0400

    Add missing indirectbr instruction (#10).

commit 2a7b342
Author: Peter Zotov <whitequark@whitequark.org>
Date:   Mon Jan 21 13:59:42 2013 +0400

    Add missing scalar and IPO passes (#10).

commit e619a83
Author: Peter Zotov <whitequark@whitequark.org>
Date:   Mon Jan 21 13:18:44 2013 +0400

    Remove stray comment.

commit 6dcebc1
Author: Peter Zotov <whitequark@whitequark.org>
Date:   Mon Jan 21 13:17:54 2013 +0400

    Fix LLVM.with_message_output.

    One should first check for the return value, which is consistently
    LLVMBool with True indicating an error, and only then try to fetch
    the message.
  • Loading branch information
jvoorhis committed Jan 22, 2013
1 parent c8f395b commit 6772b4d
Show file tree
Hide file tree
Showing 7 changed files with 321 additions and 62 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -4,8 +4,8 @@ Ruby-LLVM
Ruby-LLVM is a Ruby language binding to the LLVM compiler infrastructure
library. LLVM allows users to create just-in-time (JIT) compilers, ahead-of-time
(AOT) compilers for multiple architectures, code analyzers and more. LLVM
bindings can also be used to speed up Ruby code by compiling Ruby methods on the
fly.
bindings can also be used to speed up Ruby code by compiling and loading
computationally intensive algorithms on the fly.

Requirements
------------
Expand Down
12 changes: 7 additions & 5 deletions lib/llvm/core.rb
Expand Up @@ -15,20 +15,22 @@ module C
# @yield [FFI::MemoryPointer]
# @return [String, nil]
def self.with_message_output
result = nil
message = nil

FFI::MemoryPointer.new(FFI.type_size(:pointer)) do |str|
yield str
result = yield str

msg_ptr = str.read_pointer

unless msg_ptr.null?
result = msg_ptr.read_string
if result != 0
raise RuntimeError, "Error is signalled, but msg_ptr is null" if msg_ptr.null?

message = msg_ptr.read_string
C.dispose_message msg_ptr
end
end

result
message
end

# Same as #with_message_output, but raises a RuntimeError with the
Expand Down
92 changes: 87 additions & 5 deletions lib/llvm/core/builder.rb
Expand Up @@ -79,7 +79,7 @@ def aggregate_ret(*vals)
end

# Unconditional branching (i.e. goto)
# @param [LLVM::BasicBlock] block Where to jump
# @param [LLVM::BasicBlock] block Where to jump
# @return [LLVM::Instruction]
# @LLVMinst br
def br(block)
Expand All @@ -88,10 +88,20 @@ def br(block)
C.build_br(self, block))
end

# Indirect branching (i.e. computed goto)
# @param [LLVM::BasicBlock] addr Where to jump
# @param [Integer] num_dests Number of possible destinations to be added
# @return [LLVM::Instruction]
# @LLVMinst indirectbr
def ibr(addr, num_dests)
IndirectBr.from_ptr(
C.build_indirect_br(self, addr, num_dests))
end

# Conditional branching (i.e. if)
# @param [LLVM::Value] cond The condition
# @param [LLVM::BasicBlock] iftrue Where to jump if condition is true
# @param [LLVM::BasicBlock] iffalse Where to jump if condition is false
# @param [LLVM::Value] cond The condition
# @param [LLVM::BasicBlock] iftrue Where to jump if condition is true
# @param [LLVM::BasicBlock] iffalse Where to jump if condition is false
# @return [LLVM::Instruction]
# @LLVMinst br
def cond(cond, iftrue, iffalse)
Expand Down Expand Up @@ -147,6 +157,7 @@ def unreachable
Instruction.from_ptr(C.build_unreachable(self))
end

# Integer addition.
# @param [LLVM::Value] lhs Integer or vector of integers
# @param [LLVM::Value] rhs Integer or vector of integers
# @param [String] name Name of the result in LLVM IR
Expand All @@ -156,7 +167,7 @@ def add(lhs, rhs, name = "")
Instruction.from_ptr(C.build_add(self, lhs, rhs, name))
end

# No signed wrap addition.
# "No signed wrap" integer addition.
# @param [LLVM::Value] lhs Integer or vector of integers
# @param [LLVM::Value] rhs Integer or vector of integers
# @param [String] name Name of the result in LLVM IR
Expand All @@ -166,6 +177,16 @@ def nsw_add(lhs, rhs, name = "")
Instruction.from_ptr(C.build_nsw_add(self, lhs, rhs, name))
end

# "No unsigned wrap" integer addition.
# @param [LLVM::Value] lhs Integer or vector of integers
# @param [LLVM::Value] rhs Integer or vector of integers
# @param [String] name Name of the result in LLVM IR
# @return [LLVM::Instruction] The integer sum of the two operands
# @LLVMinst add
def nuw_add(lhs, rhs, name = "")
Instruction.from_ptr(C.build_nuw_add(self, lhs, rhs, name))
end

# @param [LLVM::Value] lhs Floating point or vector of floating points
# @param [LLVM::Value] rhs Floating point or vector of floating points
# @param [String] name Name of the result in LLVM IR
Expand All @@ -175,6 +196,7 @@ def fadd(lhs, rhs, name = "")
Instruction.from_ptr(C.build_f_add(self, lhs, rhs, name))
end

# Integer subtraction.
# @param [LLVM::Value] lhs Integer or vector of integers
# @param [LLVM::Value] rhs Integer or vector of integers
# @param [String] name Name of the result in LLVM IR
Expand All @@ -184,6 +206,26 @@ def sub(lhs, rhs, name = "")
Instruction.from_ptr(C.build_sub(self, lhs, rhs, name))
end

# No signed wrap integer subtraction.
# @param [LLVM::Value] lhs Integer or vector of integers
# @param [LLVM::Value] rhs Integer or vector of integers
# @param [String] name Name of the result in LLVM IR
# @return [LLVM::Instruction] The integer difference of the two operands
# @LLVMinst sub
def nsw_sub(lhs, rhs, name = "")
Instruction.from_ptr(C.build_nsw_sub(self, lhs, rhs, name))
end

# No unsigned wrap integer subtraction.
# @param [LLVM::Value] lhs Integer or vector of integers
# @param [LLVM::Value] rhs Integer or vector of integers
# @param [String] name Name of the result in LLVM IR
# @return [LLVM::Instruction] The integer difference of the two operands
# @LLVMinst sub
def nuw_sub(lhs, rhs, name = "")
Instruction.from_ptr(C.build_nuw_sub(self, lhs, rhs, name))
end

# @param [LLVM::Value] lhs Floating point or vector of floating points
# @param [LLVM::Value] rhs Floating point or vector of floating points
# @param [String] name Name of the result in LLVM IR
Expand All @@ -194,6 +236,7 @@ def fsub(lhs, rhs, name = "")
Instruction.from_ptr(C.build_f_sub(self, lhs, rhs, name))
end

# Integer multiplication.
# @param [LLVM::Value] lhs Integer or vector of integers
# @param [LLVM::Value] rhs Integer or vector of integers
# @param [String] name Name of the result in LLVM IR
Expand All @@ -203,6 +246,27 @@ def mul(lhs, rhs, name = "")
Instruction.from_ptr(C.build_mul(self, lhs, rhs, name))
end

# "No signed wrap" integer multiplication.
# @param [LLVM::Value] lhs Integer or vector of integers
# @param [LLVM::Value] rhs Integer or vector of integers
# @param [String] name Name of the result in LLVM IR
# @return [LLVM::Instruction] The integer product of the two operands
# @LLVMinst mul
def nsw_mul(lhs, rhs, name = "")
Instruction.from_ptr(C.build_nsw_mul(self, lhs, rhs, name))
end

# "No unsigned wrap" integer multiplication.
# @param [LLVM::Value] lhs Integer or vector of integers
# @param [LLVM::Value] rhs Integer or vector of integers
# @param [String] name Name of the result in LLVM IR
# @return [LLVM::Instruction] The integer product of the two operands
# @LLVMinst mul
def nuw_mul(lhs, rhs, name = "")
Instruction.from_ptr(C.build_nuw_mul(self, lhs, rhs, name))
end

# Floating point multiplication
# @param [LLVM::Value] lhs Floating point or vector of floating points
# @param [LLVM::Value] rhs Floating point or vector of floating points
# @param [String] name Name of the result in LLVM IR
Expand Down Expand Up @@ -348,6 +412,24 @@ def neg(arg, name = "")
Instruction.from_ptr(C.build_neg(self, arg, name))
end

# "No signed wrap" integer negation.
# @param [LLVM::Value] arg Integer or vector of integers
# @param [String] name Name of the result in LLVM IR
# @return [LLVM::Instruction] The negated operand
# @LLVMinst sub
def nsw_neg(arg, name = "")
Instruction.from_ptr(C.build_nsw_neg(self, arg, name))
end

# "No unsigned wrap" integer negation.
# @param [LLVM::Value] arg Integer or vector of integers
# @param [String] name Name of the result in LLVM IR
# @return [LLVM::Instruction] The negated operand
# @LLVMinst sub
def nuw_neg(arg, name = "")
Instruction.from_ptr(C.build_nuw_neg(self, arg, name))
end

# Boolean negation.
# @param [LLVM::Value] arg Integer or vector of integers
# @param [String] name The name of the result in LLVM IR
Expand Down
125 changes: 101 additions & 24 deletions lib/llvm/core/value.rb
Expand Up @@ -219,6 +219,9 @@ def bitcast_to(type)
ConstantExpr.from_ptr(C.const_bit_cast(self, type))
end

# @deprecated
alias bit_cast bitcast_to

# Returns the element pointer at the given indices of the constant.
# For more information on gep go to: http://llvm.org/docs/GetElementPtr.html
def gep(*indices)
Expand All @@ -230,8 +233,9 @@ def gep(*indices)
end
end

def bit_cast(type)
return ConstantExpr.from_ptr(C.const_bit_cast(self, type))
# Conversion to integer.
def ptr_to_int(type)
ConstantInt.from_ptr(C.const_ptr_to_int(self, type))
end
end

Expand Down Expand Up @@ -290,29 +294,69 @@ def -@
self.class.from_ptr(C.const_neg(self))
end

# Boolean negation.
def ~@
self.class.from_ptr(C.const_not(self))
alias neg -@

# "No signed wrap" negation.
def nsw_neg
self.class.from_ptr(C.const_nsw_neg(self))
end

alias not ~
# "No unsigned wrap" negation.
def nuw_neg
self.class.from_ptr(C.const_nuw_neg(self))
end

# Addition.
def +(rhs)
self.class.from_ptr(C.const_add(self, rhs))
end

# "No signed wrap" addition. See
# http://llvm.org/docs/LangRef.html#i_add for discusison.
alias add +

# "No signed wrap" addition.
def nsw_add(rhs)
self.class.from_ptr(C.const_nsw_add(self, rhs))
end

# "No unsigned wrap" addition.
def nuw_add(rhs)
self.class.from_ptr(C.const_nuw_add(self, rhs))
end

# Subtraction.
def -(rhs)
self.class.from_ptr(C.const_sub(self, rhs))
end

alias sub -

# "No signed wrap" subtraction.
def nsw_sub(rhs)
self.class.from_ptr(C.const_nsw_sub(self, rhs))
end

# "No unsigned wrap" subtraction.
def nuw_sub(rhs)
self.class.from_ptr(C.const_nuw_sub(self, rhs))
end

# Multiplication.
def *(rhs)
self.class.from_ptr(C.const_mul(self, rhs))
end

alias mul *

# "No signed wrap" multiplication.
def nsw_mul(rhs)
self.class.from_ptr(C.const_nsw_mul(self, rhs))
end

# "No unsigned wrap" multiplication.
def nuw_mul(rhs)
self.class.from_ptr(C.const_nuw_mul(self, rhs))
end

# Unsigned division.
def udiv(rhs)
self.class.from_ptr(C.const_u_div(self, rhs))
Expand All @@ -333,21 +377,53 @@ def rem(rhs)
self.class.from_ptr(C.const_s_rem(self, rhs))
end

# Boolean negation.
def ~@
self.class.from_ptr(C.const_not(self))
end

alias not ~

# Integer AND.
def and(rhs)
def &(rhs)
self.class.from_ptr(C.const_and(self, rhs))
end

alias and &

# Integer OR.
def or(rhs)
def |(rhs)
self.class.from_ptr(C.const_or(self, rhs))
end

alias or |

# Integer XOR.
def xor(rhs)
def ^(rhs)
self.class.from_ptr(C.const_xor(self, rhs))
end

alias xor ^

# Shift left.
def <<(bits)
self.class.from_ptr(C.const_shl(self, bits))
end

alias shl <<

# Shift right.
def >>(bits)
self.class.from_ptr(C.const_l_shr(self, bits))
end

alias shr >>

# Arithmatic shift right.
def ashr(bits)
self.class.from_ptr(C.const_a_shr(self, bits))
end

# Integer comparison using the predicate specified via the first parameter.
# Predicate can be any of:
# :eq - equal to
Expand All @@ -364,19 +440,9 @@ def icmp(pred, rhs)
self.class.from_ptr(C.const_i_cmp(pred, self, rhs))
end

# Shift left.
def <<(bits)
self.class.from_ptr(C.const_shl(self, bits))
end

# Shift right.
def >>(bits)
self.class.from_ptr(C.const_l_shr(self, bits))
end

# Arithmatic shift right.
def ashr(bits)
self.class.from_ptr(C.const_a_shr(self, bits))
# Conversion to pointer.
def int_to_ptr(type)
ConstantExpr.from_ptr(C.const_int_to_ptr(self, type))
end
end

Expand Down Expand Up @@ -789,4 +855,15 @@ def add_case(val, block)
C.add_case(self, val, block)
end
end


# @private
class IndirectBr < Instruction
# Adds a basic block reference as a destination for this indirect branch.
def add_dest(dest)
C.add_destination(self, dest)
end

alias :<< :add_dest
end
end

0 comments on commit 6772b4d

Please sign in to comment.