Specialisation of functions occurs when a call to a function is processed. There are two principal possible strategies for choosing and retaining specialisations:
Consider a loop where re-specialisation occurs:
while something:
some_value = function(some_value)
Here, the following specialisations may be detected and generated:
some_value
is int
: function(int)
is created whose result is float
some_value
was int
but is now float
: function(int or float)
is created whose result is float
some_value
was int or float
but is now float
: we have already covered this caseWith "lazy specialisation", if some_value
changes
type, the only specialisation that will be maintained will be that
containing the whole set of possible types for the parameters.
Motivations for using this strategy include only remembering the current specialisations for a node, and only maintaining a single node to represent a place where a function call is made. To collect all possible types for a particular variable it is necessary to remember the namespace entries for each iteration and to merge them together with subsequent iterations' entries.
Consider the above example. Given that
some_value
is int
: function(int)
is created whose result is float
some_value
is float
: function(float)
is created whose result is float
some_value
is float
: we have already covered this caseWith "precise specialisation" we attempt to maintain every new specialisation found, noting that the cost of doing so will be incurred in code generation where we must generate code to distinguish between the conditions for the invocation of each particular specialisation.
Requirements for using this strategy include remembering previous specialisations and/or specialising the code for the loop itself.