better code generation support for intrinsic math functions

* This implements a mapping from the standard C math library function name, to some intrinsic backend-specific implementation of that function. If no such mapping is present, the C function is called instead.
* For the native code generator, this gives the LLVM optimiser more information. For example, the 'sqrt' C function call will not be vectorized, but the corresponding 'llvm.sqrt.f64' intrinsic will be.
* For external backends such as PTX, calls to the corresponding intrinsic implemented in the 'libdevice' library can be inserted directly, rather than via an indirection.