Skip to content

Instantly share code, notes, and snippets.

@asterite
Last active May 20, 2018 19:00
Show Gist options
  • Save asterite/da37091a28653dd78afbdc73b6a4ae63 to your computer and use it in GitHub Desktop.
Save asterite/da37091a28653dd78afbdc73b6a4ae63 to your computer and use it in GitHub Desktop.
diff --git a/src/compiler/crystal/semantic/cleanup_transformer.cr b/src/compiler/crystal/semantic/cleanup_transformer.cr
index e108c12f1..59a21ef07 100644
--- a/src/compiler/crystal/semantic/cleanup_transformer.cr
+++ b/src/compiler/crystal/semantic/cleanup_transformer.cr
@@ -23,6 +23,8 @@ module Crystal
initializer.node = initializer.node.transform(transformer)
end
end
+
+ TypesAndMethodsPrinter.new.print_types_and_methods(self)
end
def cleanup_type(type, transformer)
@@ -51,6 +53,77 @@ module Crystal
end
end
+ class TypesAndMethodsPrinter
+ def initialize
+ @all_types = Set(UInt64).new
+ end
+
+ def print_types_and_methods(program)
+ types = [] of Type
+
+ collect_types(program, types)
+
+ instances = {} of UInt64 => {Type, Def, Int32}
+
+ types.each do |type|
+ if type.is_a?(DefInstanceContainer) && !type.def_instances.empty?
+ type.def_instances.each do |instance, method|
+ existing = instances[instance.def_object_id]?
+ instances[instance.def_object_id] =
+ if existing
+ {existing[0], existing[1], existing[2] + 1}
+ else
+ {type, method, 1}
+ end
+ end
+ end
+ end
+
+ total = instances.size
+
+ puts "TOTAL: #{total}"
+
+ instances.to_a.sort_by(&.[1][2]).reverse.map(&.[1]).each do |type, method, count|
+ puts "#{type} - #{method.name} (#{count}) (#{(count * 100.0 / total).round(2)}%)"
+ end
+ end
+
+ def collect_types(type : Type, target)
+ return if @all_types.includes?(type.object_id)
+ @all_types << type.object_id
+
+ target << type
+ collect_types(type.types?, target)
+
+ if type.is_a?(NonGenericClassType)
+ collect_types(type.subclasses, target)
+ end
+
+ if type.is_a?(GenericClassType)
+ collect_types(type.generic_types, target)
+ end
+
+ if !type.metaclass?
+ collect_types(type.metaclass, target)
+ end
+ end
+
+ def collect_types(types : Hash, target)
+ types.each do |key, value|
+ collect_types(value, target)
+ end
+ end
+
+ def collect_types(types : Array, target)
+ types.each do |value|
+ collect_types(value, target)
+ end
+ end
+
+ def collect_types(x : Nil, target)
+ end
+ end
+
# This visitor runs at the end and does some simplifications to the resulting AST node.
#
# For example, it rewrites and `if true; 1; else; 2; end` to a single `1`. It does
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment