Skip to content

Commit c323504

Browse files
committed
.
1 parent d61989c commit c323504

1 file changed

Lines changed: 30 additions & 48 deletions

File tree

zjit/mini_zjit.rb

Lines changed: 30 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ def find
296296
end
297297

298298
def make_equal_to(other)
299-
@forwarded = other
299+
find.instance_variable_set(:@forwarded, other.find)
300300
end
301301

302302
# Override in subclasses
@@ -545,7 +545,7 @@ def initialize(fun)
545545
@preds = Hash.new { |h, k| h[k] = [] }
546546
@blocks.each do |block|
547547
block.insns.each do |insn|
548-
insn = fun.find(insn)
548+
insn = insn.find
549549
case insn
550550
when Jump then @preds[insn.target.target.id] << block
551551
when IfTrue then @preds[insn.target.target.id] << block
@@ -655,30 +655,14 @@ def new_insn(insn)
655655
insn
656656
end
657657

658-
# ─── Union-Find (delegates to per-instruction forwarding) ──────
659-
# Each Insn carries its own @forwarded pointer. These are convenience
660-
# methods on Function that delegate to insn.find / insn.make_equal_to.
661-
662-
def make_equal_to(old_insn, new_insn)
663-
old_insn.find.make_equal_to(new_insn)
664-
end
665-
666-
def find(insn) = insn.find
667-
668-
# Type of the canonical representative
669-
def type_of(insn) = insn.find.type
670-
671-
# Check if insn's type is a subtype of target_type
672-
def is_a?(insn, target_type) = insn.find.type <= target_type
673-
674658
# Infer the type of a newly created instruction
675659
def infer_type(insn)
676660
case insn
677661
when Const
678662
insn.type # already set at creation
679663
when FixnumAdd, FixnumSub, FixnumMult
680-
lt = type_of(insn.left)
681-
rt = type_of(insn.right)
664+
lt = insn.left.find.type
665+
rt = insn.right.find.type
682666
if lt.has_const? && rt.has_const? && lt.fixnum? && rt.fixnum?
683667
result = case insn
684668
when FixnumAdd then lt.const_val + rt.const_val
@@ -690,7 +674,7 @@ def infer_type(insn)
690674
Types::Fixnum
691675
end
692676
when FixnumLt, FixnumEq, FixnumGt then Types::CBool
693-
when GuardType then type_of(insn.val) & insn.guard_type
677+
when GuardType then insn.val.find.type & insn.guard_type
694678
when Test then Types::CBool
695679
else insn.type
696680
end
@@ -1070,22 +1054,22 @@ def type_specialize
10701054
old_insns = block.insns.dup
10711055
block.insns.clear
10721056
old_insns.each do |insn|
1073-
insn = find(insn)
1057+
insn = insn.find
10741058
next push_insn_id(block, insn) unless insn.is_a?(Send)
10751059
next push_insn_id(block, insn) unless FIXNUM_SEND_MAP.key?(insn.method_name)
10761060

1077-
recv_type = type_of(insn.recv)
1078-
arg_type = insn.args[0] ? type_of(insn.args[0]) : nil
1061+
recv_type = insn.recv.find.type
1062+
arg_type = insn.args[0] ? insn.args[0].find.type : nil
10791063

10801064
unless recv_type.fixnum? && arg_type&.fixnum?
10811065
push_insn_id(block, insn); next
10821066
end
10831067

10841068
# Guard both operands
1085-
gl = push_insn(block, GuardType.new(find(insn.recv), Types::Fixnum, insn.state))
1086-
gl.type = type_of(insn.recv) & Types::Fixnum
1087-
gr = push_insn(block, GuardType.new(find(insn.args[0]), Types::Fixnum, insn.state))
1088-
gr.type = type_of(insn.args[0]) & Types::Fixnum
1069+
gl = push_insn(block, GuardType.new(insn.recv.find, Types::Fixnum, insn.state))
1070+
gl.type = insn.recv.find.type & Types::Fixnum
1071+
gr = push_insn(block, GuardType.new(insn.args[0].find, Types::Fixnum, insn.state))
1072+
gr.type = insn.args[0].find.type & Types::Fixnum
10891073

10901074
# Emit specialized op
10911075
specialized = case FIXNUM_SEND_MAP[insn.method_name]
@@ -1098,7 +1082,7 @@ def type_specialize
10981082
end
10991083
result = push_insn(block, specialized)
11001084
result.type = infer_type(result)
1101-
make_equal_to(insn, result)
1085+
insn.make_equal_to(result)
11021086
end
11031087
end
11041088
end
@@ -1117,13 +1101,13 @@ def fold_constants
11171101
old_insns = block.insns.dup
11181102
block.insns.clear
11191103
old_insns.each do |insn_id|
1120-
insn = find(insn_id)
1104+
insn = insn_id.find
11211105
replacement = case insn
11221106

11231107
# Guard elimination: if val already has the guarded type, forward
11241108
when GuardType
1125-
if is_a?(insn.val, insn.guard_type)
1126-
make_equal_to(insn, find(insn.val))
1109+
if insn.val.find.type <= insn.guard_type
1110+
insn.make_equal_to(insn.val)
11271111
next # drop from block
11281112
end
11291113
insn
@@ -1138,7 +1122,7 @@ def fold_constants
11381122

11391123
# Test folding on known truthy/falsy values
11401124
when Test
1141-
val_type = type_of(insn.val)
1125+
val_type = insn.val.find.type
11421126
if val_type <= Types::NilClass || val_type <= Types::FalseClass
11431127
new_insn(Const.new(false, Types::FalseClass))
11441128
elsif val_type <= Types::Fixnum || val_type <= Types::TrueClass || val_type <= Types::String
@@ -1149,9 +1133,8 @@ def fold_constants
11491133

11501134
# Branch simplification: fold IfTrue/IfFalse on known booleans
11511135
when IfTrue
1152-
val_type = type_of(insn.val)
1136+
val_type = insn.val.find.type
11531137
if val_type <= Types::TrueClass
1154-
# Always taken → replace with Jump
11551138
new_insn(Jump.new(insn.target))
11561139
elsif val_type <= Types::FalseClass
11571140
next # never taken → drop
@@ -1160,9 +1143,8 @@ def fold_constants
11601143
end
11611144

11621145
when IfFalse
1163-
val_type = type_of(insn.val)
1146+
val_type = insn.val.find.type
11641147
if val_type <= Types::FalseClass
1165-
# Always taken → replace with Jump
11661148
new_insn(Jump.new(insn.target))
11671149
elsif val_type <= Types::TrueClass
11681150
next # never taken → drop
@@ -1176,7 +1158,7 @@ def fold_constants
11761158

11771159
# If we created a new instruction, link old→new in union-find and infer type
11781160
if !replacement.equal?(insn) && replacement.type != Types::Empty
1179-
make_equal_to(insn, replacement)
1161+
insn.make_equal_to(replacement)
11801162
replacement.type = infer_type(replacement)
11811163
end
11821164
push_insn_id(block, replacement)
@@ -1196,7 +1178,7 @@ def clean_cfg
11961178
num_in_edges = ::Array.new(@blocks.size, 0)
11971179
rpo.each do |block|
11981180
block.insns.each do |insn|
1199-
insn = find(insn)
1181+
insn = insn.find
12001182
case insn
12011183
when Jump then num_in_edges[insn.target.target.id] += 1
12021184
when IfTrue then num_in_edges[insn.target.target.id] += 1
@@ -1233,11 +1215,11 @@ def eliminate_dead_code
12331215
next if necessary.include?(insn.object_id)
12341216
necessary << insn.object_id
12351217
# Follow union-find to canonical insn and mark its operands
1236-
canonical = find(insn)
1218+
canonical = insn.find
12371219
necessary << canonical.object_id
12381220
canonical.operands.each do |op|
12391221
next unless op.is_a?(Insn)
1240-
worklist << find(op)
1222+
worklist << op.find
12411223
end
12421224
end
12431225

@@ -1272,7 +1254,7 @@ def global_value_numbering
12721254
if key
12731255
existing = current_map[key]
12741256
if existing && !existing.equal?(canonical)
1275-
make_equal_to(canonical, existing)
1257+
canonical.make_equal_to(existing)
12761258
next # drop duplicate from block
12771259
else
12781260
current_map[key] = canonical
@@ -1308,7 +1290,7 @@ def push_insn_id(block, insn)
13081290
def absorb_dst_block(num_in_edges, block)
13091291
last = block.insns.last
13101292
return false unless last
1311-
last = find(last)
1293+
last = last.find
13121294
return false unless last.is_a?(Jump)
13131295

13141296
target = last.target.target
@@ -1317,7 +1299,7 @@ def absorb_dst_block(num_in_edges, block)
13171299

13181300
# Link block params → jump args via union-find
13191301
target.params.each_with_index do |param, i|
1320-
make_equal_to(param, find(last.target.args[i]))
1302+
param.make_equal_to(last.target.args[i])
13211303
end
13221304

13231305
# Remove the Jump, append target's insns
@@ -1329,8 +1311,8 @@ def absorb_dst_block(num_in_edges, block)
13291311
end
13301312

13311313
def fold_fixnum_bop(insn)
1332-
lt = type_of(insn.left)
1333-
rt = type_of(insn.right)
1314+
lt = insn.left.find.type
1315+
rt = insn.right.find.type
13341316
return nil unless lt.has_const? && rt.has_const? && lt.fixnum? && rt.fixnum?
13351317
result = case insn
13361318
when FixnumAdd then lt.const_val + rt.const_val
@@ -1341,8 +1323,8 @@ def fold_fixnum_bop(insn)
13411323
end
13421324

13431325
def fold_fixnum_pred(insn)
1344-
lt = type_of(insn.left)
1345-
rt = type_of(insn.right)
1326+
lt = insn.left.find.type
1327+
rt = insn.right.find.type
13461328
return nil unless lt.has_const? && rt.has_const? && lt.fixnum? && rt.fixnum?
13471329
result = case insn
13481330
when FixnumLt then lt.const_val < rt.const_val

0 commit comments

Comments
 (0)