The process of specialisation is central to the source code analysis process and refers to the identification of called functions or methods and the construction of special versions of such functions or methods for use with particular types of arguments/parameters. The primary motivation for specialising functions in this way is to separate out the different ways that functions may be called; for example:
def f(x):
x.something()
f(1)
f("a")
f(obj)
Here, we may treat all invocations of the function f as involving the same function, along with the internal operation accessing an attribute on the name x and then calling that attribute as being the same operation across all invocations. However, if we do this, all we can infer is that the function f may take an argument which can be an integer, a string, or whatever the name obj refers to, and that the internal operation involves the access of an attribute on an object which may be an integer, a string, or whatever else was passed into the function.
However, if we specialise the function according to the type of the supplied arguments, we may resolve separate kinds of operations that may be associated with each other in a coherent fashion:
def f___1(x):
x.something() # where x is an integer
def f___2(x):
x.something() # where x is a string
def f___3(x):
x.something() # where x is whatever was passed in
f___1(1)
f___2("a")
f___3(obj)
Here, we manage to separate out each incoming parameter type and thus retain information about the internal operations in the function without such information becoming confused or lost.