cast_off 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,16 +14,12 @@ module CastOff
14
14
  % top = @insn.iseq
15
15
  % a = [@insn.iseq]
16
16
  % a = @insn.iseq.ancestors.reverse + a if @translator.inline_block?
17
- % stacks = a.map{|s| s.depth}
18
- % stacks.shift
19
- % stacks.push(@insn.depth)
20
- % stacks = stacks.zip(a.map{|s| s.depth}).map{|d0, d1| d0 - d1}
21
- % valid = @translator.inline_block? ? @insn.depth : (@insn.depth - @insn.iseq.depth)
22
- % bug() unless stacks.inject(0){|sum, d| sum + d} == valid
23
17
  % a.each_with_index do |s, idx|
24
18
  {
25
- % local_c = s.lvars.size()
26
- % stack_c = stacks[idx]
19
+ % bug() unless @dependent_local_variables[s]
20
+ % bug() unless @dependent_stack_variables[s]
21
+ % local_c = @dependent_local_variables[s].size()
22
+ % stack_c = @dependent_stack_variables[s].size()
27
23
  % if @translator.inline_block?
28
24
  int local_c = <%= local_c %>;
29
25
  VALUE local_v[<%= local_c %>];
@@ -31,13 +27,13 @@ module CastOff
31
27
  int stack_c = <%= stack_c %>;
32
28
  VALUE stack_v[<%= stack_c %>];
33
29
  rb_iseq_t *iseq = <%= s %>;
34
- % s.lvars.each_with_index do |(var_name, var_id, op_idx, depth, var_annotation), i|
30
+ % @dependent_local_variables[s].each_with_index do |v, i|
35
31
  % if @translator.inline_block?
36
- local_v[<%= i %>] = local<%= var_id %>_<%= var_name %>; /* FIXME */
32
+ local_v[<%= i %>] = <%= get_variable(v).boxed_form %>;
37
33
  % end
38
34
  % end
39
- % stack_c.times do |i|
40
- stack_v[<%= i %>] = tmp<%= s.depth + i %>;
35
+ % @dependent_stack_variables[s].each_with_index do |v, i|
36
+ stack_v[<%= i %>] = <%= get_variable(v).boxed_form %>;
41
37
  % end
42
38
  % method_p = (s.itype == :method ? 1 : 0)
43
39
  % lambda_p = (s.itype == :method ? 0 : 'lambda_p')
@@ -100,30 +96,44 @@ static void <RECOMPILATION_FUNCTION_NAME>(VALUE obj)
100
96
  #if 1
101
97
  if(!sampling_table) register_sampling_table(rb_hash_new());
102
98
  % count = 0
103
- % defs = get_definition(@guard_value)
104
- % defs.each do |defn|
105
- % case defn
106
- % when SubIR
107
- % case defn.src
108
- % when LocalVariable, DynamicVariable, InstanceVariable, ClassVariable, GlobalVariable, Self
109
- % count += 1
99
+ % done = []
100
+ % queue = [@guard_value]
101
+ % while (val = queue.pop)
102
+ % bug() if done.include?(val)
103
+ % done << val
104
+ % bug() unless val.is_a?(Variable)
105
+ % defs = get_definition(val)
106
+ % defs.each do |defn|
107
+ % case defn
108
+ % when SubIR
109
+ % case defn.src
110
+ % when LocalVariable, DynamicVariable, InstanceVariable, ClassVariable, GlobalVariable, Self
111
+ % count += 1
110
112
  sampling_variable(obj, ID2SYM(rb_intern("<%= defn.src.source %>")));
111
- % when ConstWrapper
112
- % # Fixme
113
+ % if !queue.include?(defn.src) && !done.include?(defn.src)
114
+ % dlog("add recompilation queue \#{defn.src}")
115
+ % queue << defn.src
116
+ % end
117
+ % when ConstWrapper
118
+ % # Fixme
113
119
  /* <%= defn.src.path %> */
114
- % when Literal
115
- % # nothing to do
116
- % else
117
- % bug(defn.src)
118
- % end
119
- % when InvokeIR
120
- % recv = defn.param_variables.first
121
- % bug() if recv.dynamic?
122
- % recv.types.each do |k|
123
- % recv_class = @translator.get_c_classname(k)
124
- % bug() unless recv_class
125
- % count += 1
120
+ % when Literal, Argument, TmpBuffer
121
+ % # nothing to do
122
+ % else
123
+ % bug(defn.src)
124
+ % end
125
+ % when InvokeIR
126
+ % recv = defn.param_variables.first
127
+ % if recv.dynamic?
128
+ % bug() if val == @guard_value
129
+ % next
130
+ % end
131
+ % recv.types.each do |k|
132
+ % recv_class = @translator.get_c_classname(k)
133
+ % bug() unless recv_class
134
+ % count += 1
126
135
  __sampling_poscall(obj, <%= recv_class %>, ID2SYM(rb_intern("<%= defn.method_id %>")));
136
+ % end
127
137
  % end
128
138
  % end
129
139
  % end
@@ -244,7 +254,9 @@ static int <CLASS_CHECK_FUNCTION_NAME>_failed(VALUE obj, VALUE klass)
244
254
  @variables << @guard_value
245
255
  @variables_without_result << @guard_value
246
256
  @result_variable = nil
247
- @dependent_variables = get_dependent_variables(vars)
257
+ @dependent_local_variables = get_dependent_local_variables(vars)
258
+ @dependent_stack_variables = get_dependent_stack_variables(vars)
259
+ @dependent_variables = @dependent_local_variables.values.flatten + @dependent_stack_variables.values.flatten
248
260
  @source = @insn.source
249
261
  @source = @source.empty? ? nil : @source
250
262
  @source_line = @insn.line.to_s
@@ -252,58 +264,37 @@ static int <CLASS_CHECK_FUNCTION_NAME>_failed(VALUE obj, VALUE klass)
252
264
 
253
265
  ### unboxing begin ###
254
266
  def unboxing_prelude()
255
- # TODO inline api の返り値で unbox 可能なものは、class_exact にして伝播させること。
256
- if @guard_value.class_exact? && @guard_value.can_unbox?
257
- @guard_value.can_unbox()
258
- else
259
- @guard_value.can_not_unbox()
260
- end
267
+ @guard_value.box() unless @guard_value.class_exact? && @guard_value.can_unbox?
261
268
  end
262
269
 
263
- def propergate_value_which_can_not_unbox(defs)
270
+ def propergate_boxed_value(defs)
264
271
  change = false
265
272
 
266
273
  # forward
267
- change |= defs.can_not_unbox_variable_resolve_forward(@guard_value)
268
-
269
- # backward
270
- if @guard_value.can_not_unbox?
271
- change |= defs.can_not_unbox_variable_resolve_backward(@guard_value)
272
- if @configuration.deoptimize?
273
- @dependent_variables.each do |v|
274
- change |= v.can_not_unbox()
275
- end
276
- end
277
- end
278
-
279
- change
280
- end
281
-
282
- def propergate_box_value(defs)
283
- change = false
284
-
285
- # forward
286
- change |= defs.box_value_resolve_forward(@guard_value)
274
+ change |= defs.propergate_boxed_value_forward(@guard_value)
287
275
 
288
276
  # backward
289
277
  if @guard_value.boxed?
290
- change |= defs.box_value_resolve_backward(@guard_value)
278
+ change |= defs.propergate_boxed_value_backward(@guard_value)
291
279
  if @configuration.deoptimize?
292
- @dependent_variables.each do |v|
293
- v.box()
294
- change |= defs.box_value_resolve_backward(v)
280
+ @dependent_variables.each do |var|
281
+ if var.is_a?(DynamicVariable)
282
+ bug() unless var.boxed?
283
+ next
284
+ end
285
+ vars = defs.get_variables(var)
286
+ boxed_p = !!vars.find{|v| v.boxed?}
287
+ next unless boxed_p
288
+ vars.each do |v|
289
+ change |= v.box()
290
+ change |= defs.propergate_boxed_value_backward(v)
291
+ end
295
292
  end
296
293
  end
297
294
  end
298
295
 
299
296
  change
300
297
  end
301
-
302
- def propergate_unbox_value(defs)
303
- return false if @guard_value.can_not_unbox?
304
- bug() unless @guard_value.class_exact?
305
- defs.unbox_value_resolve(@guard_value)
306
- end
307
298
  ### unboxing end ###
308
299
 
309
300
  def propergate_exact_class(defs)
@@ -357,29 +348,54 @@ static int <CLASS_CHECK_FUNCTION_NAME>_failed(VALUE obj, VALUE klass)
357
348
  " }"
358
349
  end
359
350
 
360
- def get_dependent_variables(vars)
361
- targets = []
351
+ def get_dependent_local_variables(vars)
352
+ local_variables = {}
362
353
  s = @insn.iseq
363
354
  level = @insn.iseq.generation
364
355
  while s
356
+ variables = []
365
357
  s.lvars.each do |var_name, var_id, op_idx, depth, var_annotation|
366
358
  bug() unless depth == level
367
359
  if @translator.inline_block?
368
- targets << "local#{var_id}_#{var_name}" # FIXME
360
+ var = vars.find{|v| v.to_name == "local#{var_id}_#{var_name}"} # FIXME
369
361
  else
370
- targets << "dfp#{depth}[#{op_idx}]" # FIXME
362
+ var = vars.find{|v| v.to_name == "dfp#{depth}[#{op_idx}]"} # FIXME
371
363
  end
364
+ bug() unless var.is_a?(LocalVariable) || var.is_a?(DynamicVariable)
365
+ variables << var
372
366
  end
367
+ local_variables[s] = variables
373
368
  level -= 1
374
369
  s = s.parent
375
370
  end
376
371
  bug() unless level == -1
377
- d = @insn.depth
378
- while d > 0 do
379
- d -= 1
380
- targets << "tmp#{d}" # FIXME
372
+ bug() unless local_variables.size == (@insn.iseq.generation + 1)
373
+ local_variables
374
+ end
375
+
376
+ def get_dependent_stack_variables(vars)
377
+ stack_variables = {}
378
+ a = [@insn.iseq]
379
+ a = @insn.iseq.ancestors.reverse + a if @translator.inline_block?
380
+ stacks = a.map{|s| s.depth}
381
+ stacks.shift
382
+ stacks.push(@insn.depth)
383
+ stacks = stacks.zip(a.map{|s| s.depth}).map{|d0, d1| d0 - d1}
384
+ valid = @translator.inline_block? ? @insn.depth : (@insn.depth - @insn.iseq.depth)
385
+ bug() unless stacks.inject(0){|sum, d| sum + d} == valid
386
+ a.each_with_index do |s, idx|
387
+ stack_c = stacks[idx]
388
+ variables = []
389
+ stack_c.times do |i|
390
+ var = vars.find{|v| v.to_name == "tmp#{s.depth + i}"} # FIXME
391
+ bug() unless var.is_a?(TmpVariable)
392
+ variables << var
393
+ end
394
+ bug() unless variables.size == stack_c
395
+ stack_variables[s] = variables
381
396
  end
382
- vars.select{|v| targets.include?(v.to_name)}.uniq()
397
+ bug() unless stack_variables.size == a.size
398
+ stack_variables
383
399
  end
384
400
  end
385
401
 
@@ -44,25 +44,13 @@ module CastOff::Compiler
44
44
 
45
45
  ### unboxing begin ###
46
46
  def unboxing_prelude()
47
- @cond_value.can_not_unbox() if @cond_value
47
+ @cond_value.box() if @cond_value
48
48
  end
49
49
 
50
- def propergate_value_which_can_not_unbox(defs)
51
- return false unless @cond_value
52
- bug() unless @cond_value.can_not_unbox?
53
- defs.can_not_unbox_variable_resolve_backward(@cond_value)
54
- end
55
-
56
- def propergate_box_value(defs)
50
+ def propergate_boxed_value(defs)
57
51
  return false unless @cond_value
58
52
  bug() unless @cond_value.boxed?
59
- defs.box_value_resolve_backward(@cond_value)
60
- end
61
-
62
- def propergate_unbox_value(defs)
63
- return false unless @cond_value
64
- bug() unless @cond_value.can_not_unbox?
65
- false
53
+ defs.propergate_boxed_value_backward(@cond_value)
66
54
  end
67
55
  ### unboxing end ###
68
56
 
@@ -26,29 +26,33 @@ module CastOff::Compiler
26
26
  @state = :undefined
27
27
  @annotation = []
28
28
  @ignore = []
29
- @unboxing_state = :undefined
29
+ @unboxing_state = :unboxed
30
30
  @negative_cond_value = false
31
31
  end
32
32
 
33
33
  ### unboxing begin ###
34
- def unbox()
35
- case @unboxing_state
36
- when :can_unbox
37
- @unboxing_state = :unboxed
38
- return true
39
- when :unboxed
40
- return false
34
+ def can_unbox?
35
+ if instance_of?(LocalVariable) || instance_of?(TmpVariable) || instance_of?(Literal)
36
+ if dynamic? || @types.size != 1
37
+ false
38
+ else
39
+ bug() unless @types[0].instance_of?(ClassWrapper)
40
+ case @types[0]
41
+ when FloatWrapper, FixnumWrapper
42
+ true
43
+ else
44
+ false
45
+ end
46
+ end
47
+ else
48
+ # ConstWrapper, Self, Pointer, Argument, TmpBuffer
49
+ false
41
50
  end
42
- bug()
43
- end
44
-
45
- def unboxed?
46
- @unboxing_state == :unboxed
47
51
  end
48
52
 
49
53
  def box()
50
54
  case @unboxing_state
51
- when :unboxed, :can_unbox, :can_not_unbox
55
+ when :unboxed
52
56
  @unboxing_state = :boxed
53
57
  return true
54
58
  when :boxed
@@ -61,42 +65,24 @@ module CastOff::Compiler
61
65
  @unboxing_state == :boxed
62
66
  end
63
67
 
64
- def can_unbox?
65
- if instance_of?(LocalVariable) || instance_of?(TmpVariable) || instance_of?(Literal)
66
- if dynamic? || @types.size != 1
67
- false
68
- else
69
- true
70
- end
71
- else
72
- # ConstWrapper, Self, Pointer, Argument, TmpBuffer
73
- false
74
- end
75
- end
76
-
77
- def can_not_unbox?
78
- @unboxing_state == :can_not_unbox
79
- end
80
-
81
- def can_unbox()
82
- bug() unless @unboxing_state == :undefined
83
- @unboxing_state = :can_unbox
68
+ def unboxed?
69
+ @unboxing_state == :unboxed
84
70
  end
85
71
 
86
- def can_not_unbox()
72
+ def boxed_form()
87
73
  case @unboxing_state
88
- when :undefined, :can_unbox
89
- @unboxing_state = :can_not_unbox
90
- true
91
- when :can_not_unbox
92
- false
93
- else
94
- bug()
74
+ when :boxed
75
+ return self.to_s
76
+ when :unboxed
77
+ bug() unless can_unbox?
78
+ case @types.first
79
+ when FixnumWrapper
80
+ return "LONG2FIX(#{self.to_s})"
81
+ when FloatWrapper
82
+ return "DBL2NUM(#{self.to_s})"
83
+ end
95
84
  end
96
- end
97
-
98
- def box_unbox_undefined?
99
- @unboxing_state == :undefined
85
+ bug()
100
86
  end
101
87
  ### unboxing end ###
102
88
 
@@ -114,7 +100,7 @@ module CastOff::Compiler
114
100
  when FixnumWrapper
115
101
  return :long
116
102
  end
117
- when :can_unbox, :can_not_unbox, :boxed
103
+ when :boxed
118
104
  return :VALUE
119
105
  end
120
106
  bug()
@@ -23,38 +23,17 @@ module CastOff::Compiler
23
23
  # nothing to do
24
24
  end
25
25
 
26
- def propergate_value_which_can_not_unbox(defs)
26
+ def propergate_boxed_value(defs)
27
27
  change = false
28
28
 
29
29
  # forward
30
- change |= defs.can_not_unbox_variable_resolve_forward(@param_value)
30
+ change |= defs.propergate_boxed_value_forward(@param_value)
31
31
 
32
32
  # backward
33
- if @param_value.can_not_unbox?
34
- change |= defs.can_not_unbox_variable_resolve_backward(@param_value)
35
- end
33
+ change |= defs.propergate_boxed_value_backward(@param_value) if @param_value.boxed?
36
34
 
37
35
  change
38
36
  end
39
-
40
- def propergate_box_value(defs)
41
- change = false
42
-
43
- # forward
44
- change |= defs.box_value_resolve_forward(@param_value)
45
-
46
- # backward
47
- if @param_value.boxed?
48
- change |= defs.box_value_resolve_backward(@param_value)
49
- end
50
-
51
- change
52
- end
53
-
54
- def propergate_unbox_value(defs)
55
- return false if @param_value.can_not_unbox?
56
- defs.unbox_value_resolve(@param_value)
57
- end
58
37
  ### unboxing end ###
59
38
 
60
39
  def propergate_exact_class(defs)
@@ -31,22 +31,12 @@ module CastOff::Compiler
31
31
 
32
32
  ### unboxing begin ###
33
33
  def unboxing_prelude()
34
- @return_value.can_not_unbox()
34
+ @return_value.box()
35
35
  end
36
36
 
37
- def propergate_value_which_can_not_unbox(defs)
38
- bug() unless @return_value.can_not_unbox?
39
- defs.can_not_unbox_variable_resolve_backward(@return_value)
40
- end
41
-
42
- def propergate_box_value(defs)
37
+ def propergate_boxed_value(defs)
43
38
  bug() unless @return_value.boxed?
44
- defs.box_value_resolve_backward(@return_value)
45
- end
46
-
47
- def propergate_unbox_value(defs)
48
- bug() unless @return_value.can_not_unbox?
49
- false
39
+ defs.propergate_boxed_value_backward(@return_value)
50
40
  end
51
41
  ### unboxing end ###
52
42
 
@@ -606,11 +606,7 @@ Call site is (#{insn}).
606
606
  bug()
607
607
  end
608
608
 
609
- def propergate_value_which_can_not_unbox(defs)
610
- bug()
611
- end
612
-
613
- def propergate_unbox_value(defs)
609
+ def propergate_boxed_value(defs)
614
610
  bug()
615
611
  end
616
612
  ### unboxing end ###
@@ -746,7 +742,15 @@ Call site is (#{insn}).
746
742
  return [target]
747
743
  when Variable
748
744
  ds = @information.definition_of(target)
749
- bug() if ds.empty?
745
+ if ds.empty?
746
+ case target
747
+ when TmpBuffer, Pointer, Argument, Self
748
+ return []
749
+ else
750
+ bug() unless @information.undefined_variables.include?(target)
751
+ return [] # FIXME
752
+ end
753
+ end
750
754
  ary = []
751
755
  ds.each do |d|
752
756
  case d
@@ -790,6 +794,12 @@ Call site is (#{insn}).
790
794
  }.join("\n")
791
795
  end
792
796
 
797
+ def get_variable(v)
798
+ bug() unless v.is_a?(Variable)
799
+ bug() unless @information
800
+ @information.get_variable(v)
801
+ end
802
+
793
803
  def dispatch_method?
794
804
  # FIXME 型情報を活用(Fixnum#+ とかはインスタンス変数を触らないよね)
795
805
  return true if !@translator.inline_block? && self.is_a?(LoopIR)
@@ -26,86 +26,28 @@ module CastOff::Compiler
26
26
 
27
27
  ### unboxing begin ###
28
28
  def unboxing_prelude()
29
- if @src.can_unbox? && @dst.can_unbox?
30
- @src.can_unbox()
31
- @dst.can_unbox()
32
- else
33
- @src.can_not_unbox()
34
- @dst.can_not_unbox()
29
+ unless @src.can_unbox? && @dst.can_unbox?
30
+ @src.box()
31
+ @dst.box()
35
32
  end
36
33
  end
37
34
 
38
- def propergate_value_which_can_not_unbox(defs)
35
+ def propergate_boxed_value(defs)
39
36
  change = false
40
37
 
41
38
  # forward
42
- change |= defs.can_not_unbox_variable_resolve_forward(@src)
43
- if @src.can_not_unbox?
44
- change |= @dst.can_not_unbox()
45
- end
39
+ change |= defs.propergate_boxed_value_forward(@src)
40
+ change |= @dst.box() if @src.boxed?
46
41
 
47
42
  # backward
48
- if @dst.can_not_unbox?
49
- change |= @src.can_not_unbox()
50
- end
51
- if @src.can_not_unbox?
52
- change |= defs.can_not_unbox_variable_resolve_backward(@src)
53
- end
54
- bug() unless @src.can_not_unbox? == @dst.can_not_unbox?
55
-
56
- change
57
- end
58
-
59
- def propergate_box_value(defs)
60
- change = false
61
-
62
- # forward
63
- change |= defs.box_value_resolve_forward(@src)
64
- if @src.boxed?
65
- change |= @dst.box()
66
- end
43
+ change |= @src.box() if @dst.boxed?
44
+ change |= defs.propergate_boxed_value_backward(@src) if @src.boxed?
67
45
 
68
- # backward
69
- if @dst.boxed?
70
- change |= @src.box()
71
- end
72
- if @src.boxed?
73
- change |= defs.box_value_resolve_backward(@src)
74
- end
75
46
  bug() unless @src.boxed? == @dst.boxed?
76
47
  bug() unless @src.unboxed? == @dst.unboxed?
77
48
 
78
49
  change
79
50
  end
80
-
81
- def propergate_unbox_value(defs)
82
- #return false if @src.unboxed? && @dst.unboxed?
83
- if @src.can_not_unbox?
84
- bug() unless @dst.can_not_unbox?
85
- return false
86
- else
87
- bug() if @dst.can_not_unbox?
88
- change = false
89
-
90
- if @src.instance_of?(Literal)
91
- bug() unless @src.types.size == 1
92
- bug() unless @src.static?
93
- floatwrap = ClassWrapper.new(Float, true)
94
- fixnumwrap = ClassWrapper.new(Fixnum, true)
95
- case @src.types[0]
96
- when floatwrap, fixnumwrap
97
- change |= @src.unbox()
98
- end
99
- end
100
-
101
- change |= defs.unbox_value_resolve(@src)
102
- if @src.unboxed? && !@dst.unboxed?
103
- @dst.unbox()
104
- change = true
105
- end
106
- return change
107
- end
108
- end
109
51
  ### unboxing end ###
110
52
 
111
53
  def propergate_exact_class(defs)
@@ -300,6 +300,7 @@ static void <%= ifunc_node_generator() %>()
300
300
  rb_thread_t *th = current_thread();
301
301
  VALUE cast_off_argv[<%= own_argv_size() %>];
302
302
  VALUE cast_off_tmp;
303
+ VALUE sampling_tmp;
303
304
  VALUE self = get_self(th);
304
305
  int lambda_p = cast_off_lambda_p(arg, argc, argv);
305
306
  int i, num;
@@ -441,6 +442,16 @@ static void <%= ifunc_node_generator() %>()
441
442
  @excs[exc] << entry unless @excs[exc].include?(entry)
442
443
  end
443
444
 
445
+ def delete_labels(ls)
446
+ entries = @excs[:break]
447
+ return unless entries
448
+ entries.delete_if do |(pc, label, stack)|
449
+ del_p = ls.include?(label)
450
+ dlog("#{self}: delete break label #{label}") if del_p
451
+ del_p
452
+ end
453
+ end
454
+
444
455
  def to_name
445
456
  "#{@name}: #{@source_file} #{@source_line}"
446
457
  end