Generic types are an abstraction of type sets. It mimics the way functions
are defined in the OpenCL specification.
E.g.: floatN can abstract all the vector sizes of the float type.
This allows to stick more closely to the specification, which uses generic
types; factorize definitions of functions with numerous prototypes in the
tablegen file; reduce the memory impact of functions with numerous prototypes.
This patch depends on https://reviews.llvm.org/D63256/new/