Skip to content

Commit ecff6c3

Browse files
authored
Merge pull request #502 from savi-lang/perf/trait-bitmap-reach
Compiler performance improvement: optimize trait bitmapping reachable subtype checks
2 parents bcb47dc + 79d1809 commit ecff6c3

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

src/savi/compiler/code_gen/ponyrt.cr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,7 @@ class Savi::Compiler::CodeGen::PonyRT
444444
is_asio_event_actor = false
445445
traits_bitmap = g.trait_bitmap_size.times.map { 0 }.to_a
446446
g.ctx.reach.each_type_def.each { |other_def|
447-
g.ctx.reach.each_reached_subtype_of(g.ctx, other_def) { |sub_def|
448-
next unless sub_def == gtype.type_def
449-
447+
if gtype.type_def.is_subtype_of?(g.ctx, other_def)
450448
index = other_def.desc_id >> Math.log2(g.bitwidth).to_i
451449
raise "bad index or trait_bitmap_size" unless index < g.trait_bitmap_size
452450

@@ -455,7 +453,7 @@ class Savi::Compiler::CodeGen::PonyRT
455453

456454
# Take special note if this type is a subtype of AsioEvent.Actor.
457455
is_asio_event_actor = true if other_def.llvm_name == "AsioEvent.Actor"
458-
}
456+
end
459457
}
460458
traits_bitmap_global = g.gen_global_for_const \
461459
@isize.const_array(traits_bitmap.map { |bits| @isize.const_int(bits) }),

src/savi/compiler/reach.cr

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,20 @@ class Savi::Compiler::Reach < Savi::AST::Visitor
542542
Ref.new(Infer::MetaType.new(@reified))
543543
end
544544

545+
def is_subtype_of?(ctx, super_def : Def)
546+
super_link = super_def.link
547+
548+
# Nothing can be a subtype of a non-abstract type.
549+
return false unless super_link.is_abstract?
550+
551+
# The possible subtype list is a cheap first check with no false negatives.
552+
possible_subtype_links = ctx.pre_subtyping[super_link].possible_subtypes
553+
return false unless possible_subtype_links.includes?(self.link)
554+
555+
# Check the actual subtyping rules
556+
return ctx.subtyping.is_subtype_of?(ctx, self.reified, super_def.reified)
557+
end
558+
545559
def ordered_fields(ctx, target_info : Target)
546560
t = @reified.link.resolve(ctx)
547561
metadata = t.metadata

0 commit comments

Comments
 (0)