diff --git a/lib/intruby.rb b/lib/intruby.rb index 53860cf..cafd54c 100644 --- a/lib/intruby.rb +++ b/lib/intruby.rb @@ -17,12 +17,15 @@ module IntRuby include LLVMUtil def gen_ivar_ptr(builder) - ftype = Type.function(P_VALUE, [VALUE, VALUE]) + ftype = Type.function(P_VALUE, [VALUE, VALUE, P_VALUE]) b = builder.define_function_raw('llvm_ivar_ptr', ftype) args = builder.arguments embed = builder.create_block nonembed = builder.create_block comm = builder.create_block + cachehit = builder.create_block + cachemiss = builder.create_block + rbp = Type.pointer(RBASIC) slfop = b.int_to_ptr(args[0], Type.pointer(ROBJECT)) slf = b.int_to_ptr(args[0], rbp) @@ -56,8 +59,8 @@ def gen_ivar_ptr(builder) niv_index_tbl = b.load(ivitp) b.br(comm) - b.set_insert_point(comm) + ptr = b.phi(P_VALUE) ptr.add_incoming(eptr, embed) ptr.add_incoming(nptr, nonembed) @@ -66,6 +69,20 @@ def gen_ivar_ptr(builder) iv_index_tbl.add_incoming(eiv_index_tbl, embed) iv_index_tbl.add_incoming(niv_index_tbl, nonembed) + oldindex = b.load(args[2]) + ishit = b.icmp_ne(oldindex, -1.llvm) + + b.cond_br(ishit, cachehit, cachemiss) + + # Inline Cache hit + b.set_insert_point(cachehit) + index = b.load(args[2]) + resp = b.gep(ptr, index) + b.return(resp) + + # Inline Cache Misss + b.set_insert_point(cachemiss) + indexp = b.alloca(VALUE, 1) @@ -75,8 +92,9 @@ def gen_ivar_ptr(builder) index = b.load(indexp) resp = b.gep(ptr, index) + + b.store(index, args[2]) b.return(resp) - end end end diff --git a/lib/llvmutil.rb b/lib/llvmutil.rb index 0f62fb6..847d456 100644 --- a/lib/llvmutil.rb +++ b/lib/llvmutil.rb @@ -107,8 +107,7 @@ def gen_call_var_args_common(para, fname, rtype, ftype) end def add_global_variable(name, type, init) - @global_malloc_area_tab[name] = [type, init] - @global_malloc_area_tab.size - 1 + @builder.define_global_variable(type, init) end def gen_binary_operator(para, core) diff --git a/lib/methoddef_ex.rb b/lib/methoddef_ex.rb index 7c2b7fa..e721da5 100644 --- a/lib/methoddef_ex.rb +++ b/lib/methoddef_ex.rb @@ -15,13 +15,11 @@ module MethodDefinition lambda {|para| info = para[:info] rettype = RubyType.fixnum(info[3], "Return type of gen_interval_cycle") - glno = add_global_variable("interval_cycle", + prevvalp = add_global_variable("interval_cycle", Type::Int64Ty, 0.llvm(Type::Int64Ty)) @expstack.push [rettype, lambda {|b, context| - prevvalp = context.builder.global_variable - prevvalp = b.struct_gep(prevvalp, glno) prevval = b.load(prevvalp) ftype = Type.function(Type::Int64Ty, []) fname = 'llvm.readcyclecounter' diff --git a/lib/vmtraverse.rb b/lib/vmtraverse.rb index 0b34d7b..437fb68 100644 --- a/lib/vmtraverse.rb +++ b/lib/vmtraverse.rb @@ -179,7 +179,7 @@ def initialize(iseq, bind, preload) } # Information of global variables by malloc - @global_malloc_area_tab = {} + @global_malloc_area_tab = [] # Number of trace(for profile speed up) @trace_no = 0 @@ -374,11 +374,15 @@ def visit_block_start(code, ins, local_vars, ln, info) if cnt > 0 and OPTION[:cache_instance_variable] and info[1] != :initialize then - ftype = Type.function(P_VALUE, [VALUE, VALUE]) + + # define inline cache area + oldindex = add_global_variable("old_index", VALUE, -1.llvm) + ftype = Type.function(P_VALUE, [VALUE, VALUE, P_VALUE]) func = context.builder.get_or_insert_function_raw('llvm_ivar_ptr', ftype) ivid = ((key.object_id << 1) / RVALUE_SIZE) slf = b.load(context.local_vars[2][:area]) - vptr = b.call(func, slf, ivid.llvm) + + vptr = b.call(func, slf, ivid.llvm, oldindex) context.instance_vars_local_area[key] = vptr else context.instance_vars_local_area[key] = nil @@ -2364,17 +2368,7 @@ def gen_init_ruby(builder) b = builder.define_function_raw('init_ruby', ftype) initfunc = builder.current_function member = [] - @global_malloc_area_tab.each do |vname, val| - member.push val[0] - end - type = Type.struct(member) - initarg = [] - @global_malloc_area_tab.each do |vname, val| - initarg.push val[1] - end - init = Value.get_struct_constant(type, *initarg) - gl = builder.define_global_variable(type, init) @generated_define_func.each do |klass, defperklass| if klass then diff --git a/lib/yarv2llvm.rb b/lib/yarv2llvm.rb index 24be3f9..b66ce9a 100644 --- a/lib/yarv2llvm.rb +++ b/lib/yarv2llvm.rb @@ -92,6 +92,7 @@ def llvm module LLVM::RubyInternals RFLOAT = Type.struct([RBASIC, Type::DoubleTy]) P_RFLOAT = Type.pointer(RFLOAT) + P_P_VALUE = Type.pointer(P_VALUE) end =begin diff --git a/sample/ao-render.rb b/sample/ao-render.rb index 72aa360..ace73a7 100644 --- a/sample/ao-render.rb +++ b/sample/ao-render.rb @@ -1,4 +1,4 @@ -# AO rebder benchmark +# AO render benchmark # Original program (C) Syoyo Fujita in Javascript (and other languages) # http://lucille.atso-net.jp/blog/?p=642 # http://lucille.atso-net.jp/blog/?p=711