Multiple metadata values for records such as opencl.ocl.version, llvm.ident and similar are created after linking several modules. For some of them, notably opencl.ocl.version, this creates semantic problem because we cannot tell which version of OpenCL the composite module conforms.
Moreover, such repetitions of identical values often create a huge list of unneeded metadata, which grows bitcode size both in memory and stored on disk. It can go up to several Mb when linked against our OpenCL library. Lastly, such long lists obscure reading of dumped IR.
The pass unifies metadata after linking.
Ideally we would like to run this as a last step during linking, but such interface is not available for a target. Therefor it is run as a first step in the optimizer as guided by the AMDGPUTargetMachine::addEarlyAsPossiblePasses(). There is a drawback, passes added this way go to a function pass manager, so while pass shall be a ModulePass by the nature it is converted to a function pass to work on the function's parent. Note, second and further invocations for other functions do nothing because metadata is already unified. In the future we may consider to convert it back to a ModulePass.
For the OpenCL version we could use two modes as guided by the last argument of unifyVersionMD() - pick largest or pick the first one. In general largest may be more correct, but in reality first is a right one with our library. The library is built as OpenCL 2.0 although it does not use specific features in a calls to functions which are not 2.0 specific. The first value in the list is always user's kernel module version, so we can rely on that first value. We may reconsider this in the future, but that would also require us to split library into 1.2 and 2.0 portions.
Would it be better to use Twine here?