Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Port chriswailes changes (#10) #16

Closed
wants to merge 8 commits into from

2 participants

@whitequark
Owner

This pull request should not introduce backwards incompatibility.

@jvoorhis
Owner

This looks good, including the README change. I'll test this out later today.

@jvoorhis jvoorhis referenced this pull request from a commit
@jvoorhis jvoorhis Merge ruby-llvm/ruby-llvm#16
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 (ruby-llvm/ruby-llvm#10).

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

    Add missing arithmetic operations on constants (ruby-llvm/ruby-llvm#10).

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

    Add missing indirectbr instruction (ruby-llvm/ruby-llvm#10).

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

    Add missing scalar and IPO passes (ruby-llvm/ruby-llvm#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.
6772b4d
@jvoorhis
Owner

Merged, with corrections for basicaa, scalarrepl_ssa symbols.

@jvoorhis jvoorhis closed this
@whitequark
Owner

May I ask why do you squash commits when merging? This makes bisecting way harder.

@whitequark
Owner

And in particular, I don't have an easy way to find what the corrections for basicaa/scalarrepl_ssa were.

@jvoorhis
Owner

Squashing may have been a poor choice for that reason. I chose to squash, however, to avoid knowingly adding a buggy commit to master.

Because we do not yet have comprehensive test coverage, for each new call to the generated FFI bindings, I used ack to verify that the high-level API matched the underlying ffi_gen method. I found two cases where it did not, located the appropriate method, and made the change, i.e. add_basicaa_pass became add_basic_alias_analysis_pass.

I considered bouncing the request, but thought this would be easier. How would you recommend handling this in the future?

@whitequark
Owner

First, thank you for doing that. I've been going to ask you to review my PR explicitly, but forgot about it.

Second, I do not generally consider a buggy commit in master as a significant problem, provided that HEAD stays working at all times. If you do, I'd be fine with updating my pull requests, as the squashing just breaks history too much to be practical.

@jvoorhis
Owner

Thanks for your feedback. Your approach seems much more pragmatic than what I did here. It's possible that I've been warped by too much exposure to Gerrit projects where squashing was commonplace after review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 21, 2013
  1. @whitequark

    Fix LLVM.with_message_output.

    whitequark authored
    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.
  2. @whitequark

    Remove stray comment.

    whitequark authored
  3. @whitequark
  4. @whitequark
  5. @whitequark
  6. @whitequark
  7. @whitequark
  8. @whitequark
This page is out of date. Refresh to see the latest.
View
4 README.md
@@ -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
------------
View
12 lib/llvm/core.rb
@@ -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
View
92 lib/llvm/core/builder.rb
@@ -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)
@@ -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)
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
View
125 lib/llvm/core/value.rb
@@ -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)
@@ -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
@@ -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))
@@ -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
@@ -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
@@ -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
View
2  lib/llvm/linker.rb
@@ -22,8 +22,6 @@ def link_into(other)
# @return [nil, String] human-readable error if linking has failed
def link_into_and_destroy(other)
result = LLVM.with_message_output do |msg|
- # HACK ALERT: ffi-gen missed LLVMLinkerPreserveSource enumeration for
- # some reason. It is inlined as a constant here.
C.link_modules(other, self, :linker_destroy_source, msg)
end
View
68 lib/llvm/transforms/ipo.rb
@@ -5,14 +5,74 @@
module LLVM
class PassManager
- # @LLVMpass gdce
- def gdce!
- C.add_global_dce_pass(self)
+ # @LLVMpass arg_promotion
+ def arg_promote!
+ C.add_argument_promotion_pass(self)
+ end
+
+ # @LLVMpass const_merge
+ def const_merge!
+ C.add_constant_merge_pass(self)
+ end
+
+ # @LLVMpass dae
+ def dae!
+ C.add_dead_arg_elimination(self)
+ end
+
+ # @LLVMpass function_attrs
+ def fun_attrs!
+ C.add_function_attrs_pass(self)
end
-
+
# @LLVMpass inline
def inline!
C.add_function_inlining_pass(self)
end
+
+ # @LLVMpass always_inline
+ def always_inline!
+ C.add_always_inliner_pass(self)
+ end
+
+ # @LLVMpass gdce
+ def gdce!
+ C.add_global_dce_pass(self)
+ end
+
+ # @LLVMpass global_opt
+ def global_opt!
+ C.add_global_optimizer_pass(self)
+ end
+
+ # @LLVMpass ipcp
+ def ipcp!
+ C.add_ip_constant_propagation_pass(self)
+ end
+
+ # @LLVMpass prune_eh
+ def prune_eh!
+ C.add_prune_eh_pass(self)
+ end
+
+ # @LLVMpass ipsccp
+ def ipsccp!
+ C.add_ipsccp_pass(self)
+ end
+
+ # @LLVMpass internalize
+ def internalize!(all_but_main=true)
+ C.add_internalize_pass(self, all_but_main)
+ end
+
+ # @LLVMpass sdp
+ def sdp!
+ C.add_strip_dead_prototypes_pass(self)
+ end
+
+ # @LLVMpass strip
+ def strip!
+ C.add_strip_symbols_pass(self)
+ end
end
end
View
80 lib/llvm/transforms/scalar.rb
@@ -8,105 +8,145 @@ class PassManager
def adce!
C.add_aggressive_dce_pass(self)
end
-
+
# @LLVMpass simplifycfg
def simplifycfg!
C.add_cfg_simplification_pass(self)
end
-
+
# @LLVMpass dse
def dse!
C.add_dead_store_elimination_pass(self)
end
-
+
# @LLVMpass gvn
def gvn!
C.add_gvn_pass(self)
end
-
+
# @LLVMpass indvars
def indvars!
C.add_ind_var_simplify_pass(self)
end
-
+
# @LLVMpass instcombine
def instcombine!
C.add_instruction_combining_pass(self)
end
-
+
# @LLVMpass jump-threading
def jump_threading!
C.add_jump_threading_pass(self)
end
-
+
# @LLVMpass licm
def licm!
C.add_licm_pass(self)
end
-
+
# @LLVMpass loop-deletion
def loop_deletion!
C.add_loop_deletion_pass(self)
end
-
+
+ # @LLVMpass loop-idion
+ def loop_idiom!
+ C.add_loop_idiom_pass(self)
+ end
+
# @LLVMpass loop-rotate
def loop_rotate!
C.add_loop_rotate_pass(self)
end
-
+
# @LLVMpass loop-unroll
def loop_unroll!
C.add_loop_unroll_pass(self)
end
-
+
# @LLVMpass loop-unswitch
def loop_unswitch!
C.add_loop_unswitch_pass(self)
end
-
+
# @LLVMpass memcpyopt
def memcpyopt!
C.add_mem_cpy_opt_pass(self)
end
-
+
# @LLVMpass mem2reg
def mem2reg!
C.add_promote_memory_to_register_pass(self)
end
-
+
# @LLVMpass reassociate
def reassociate!
C.add_reassociate_pass(self)
end
-
+
# @LLVMpass sccp
def sccp!
C.add_sccp_pass(self)
end
-
+
# @LLVMpass scalarrepl
def scalarrepl!
C.add_scalar_repl_aggregates_pass(self)
end
-
+
+ # @LLVMpass scalarrepl
+ def scalarrepl_ssa!
+ C.add_scalar_repl_aggregates_ssa_pass(self)
+ end
+
+ # @LLVMpass scalarrepl
+ def scalarrepl_threshold!(threshold)
+ C.add_scalar_repl_aggregates_pass(self, threshold)
+ end
+
# @LLVMpass simplify-libcalls
def simplify_libcalls!
C.add_simplify_lib_calls_pass(self)
end
-
+
# @LLVMpass tailcallelim
def tailcallelim!
C.add_tail_call_elimination_pass(self)
end
-
+
# @LLVMpass constprop
def constprop!
C.add_constant_propagation_pass(self)
end
-
+
# @LLVMpass reg2mem
def reg2mem!
C.add_demote_memory_to_register_pass(self)
end
+
+ # @LLVMpass cvprop
+ def cvprop!
+ C.add_correlated_value_propagation_pass(self)
+ end
+
+ # @LLVMpass early-cse
+ def early_cse!
+ C.add_early_cse_pass(self)
+ end
+
+ # @LLVMpass lower-expect
+ def lower_expect!
+ C.add_lower_expect_intrinsic_pass(self)
+ end
+
+ # @LLVMpass tbaa
+ def tbaa!
+ C.add_type_based_alias_analysis_pass(self)
+ end
+
+ # @LLVMpass basicaa
+ def basicaa!
+ C.add_basicaa_pass(self)
+ end
end
end
Something went wrong with that request. Please try again.