You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.179
Former-commit-id: 67aa10e65b237e1c4537630979ee99ebe1374215
This commit is contained in:
parent
d6bde52373
commit
8625704ad8
147
external/llvm/lib/Target/AMDGPU/AMDGPUUnifyMetadata.cpp
vendored
Normal file
147
external/llvm/lib/Target/AMDGPU/AMDGPUUnifyMetadata.cpp
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
//===- AMDGPUUnifyMetadata.cpp - Unify OpenCL metadata --------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// \file
|
||||
// \brief This pass that unifies multiple OpenCL metadata due to linking.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AMDGPU.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
namespace kOCLMD {
|
||||
|
||||
const char SpirVer[] = "opencl.spir.version";
|
||||
const char OCLVer[] = "opencl.ocl.version";
|
||||
const char UsedExt[] = "opencl.used.extensions";
|
||||
const char UsedOptCoreFeat[] = "opencl.used.optional.core.features";
|
||||
const char CompilerOptions[] = "opencl.compiler.options";
|
||||
const char LLVMIdent[] = "llvm.ident";
|
||||
|
||||
} // end namespace kOCLMD
|
||||
|
||||
/// \brief Unify multiple OpenCL metadata due to linking.
|
||||
class AMDGPUUnifyMetadata : public ModulePass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
explicit AMDGPUUnifyMetadata() : ModulePass(ID) {}
|
||||
|
||||
private:
|
||||
bool runOnModule(Module &M) override;
|
||||
|
||||
/// \brief Unify version metadata.
|
||||
/// \return true if changes are made.
|
||||
/// Assume the named metadata has operands each of which is a pair of
|
||||
/// integer constant, e.g.
|
||||
/// !Name = {!n1, !n2}
|
||||
/// !n1 = {i32 1, i32 2}
|
||||
/// !n2 = {i32 2, i32 0}
|
||||
/// Keep the largest version as the sole operand if PickFirst is false.
|
||||
/// Otherwise pick it from the first value, representing kernel module.
|
||||
bool unifyVersionMD(Module &M, StringRef Name, bool PickFirst) {
|
||||
auto NamedMD = M.getNamedMetadata(Name);
|
||||
if (!NamedMD || NamedMD->getNumOperands() <= 1)
|
||||
return false;
|
||||
MDNode *MaxMD = nullptr;
|
||||
auto MaxVer = 0U;
|
||||
for (const auto &VersionMD : NamedMD->operands()) {
|
||||
assert(VersionMD->getNumOperands() == 2);
|
||||
auto CMajor = mdconst::extract<ConstantInt>(VersionMD->getOperand(0));
|
||||
auto VersionMajor = CMajor->getZExtValue();
|
||||
auto CMinor = mdconst::extract<ConstantInt>(VersionMD->getOperand(1));
|
||||
auto VersionMinor = CMinor->getZExtValue();
|
||||
auto Ver = (VersionMajor * 100) + (VersionMinor * 10);
|
||||
if (Ver > MaxVer) {
|
||||
MaxVer = Ver;
|
||||
MaxMD = VersionMD;
|
||||
}
|
||||
if (PickFirst)
|
||||
break;
|
||||
}
|
||||
NamedMD->eraseFromParent();
|
||||
NamedMD = M.getOrInsertNamedMetadata(Name);
|
||||
NamedMD->addOperand(MaxMD);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \brief Unify version metadata.
|
||||
/// \return true if changes are made.
|
||||
/// Assume the named metadata has operands each of which is a list e.g.
|
||||
/// !Name = {!n1, !n2}
|
||||
/// !n1 = !{!"cl_khr_fp16", {!"cl_khr_fp64"}}
|
||||
/// !n2 = !{!"cl_khr_image"}
|
||||
/// Combine it into a single list with unique operands.
|
||||
bool unifyExtensionMD(Module &M, StringRef Name) {
|
||||
auto NamedMD = M.getNamedMetadata(Name);
|
||||
if (!NamedMD || NamedMD->getNumOperands() == 1)
|
||||
return false;
|
||||
|
||||
SmallVector<Metadata *, 4> All;
|
||||
for (const auto &MD : NamedMD->operands())
|
||||
for (const auto &Op : MD->operands())
|
||||
if (std::find(All.begin(), All.end(), Op.get()) == All.end())
|
||||
All.push_back(Op.get());
|
||||
|
||||
NamedMD->eraseFromParent();
|
||||
NamedMD = M.getOrInsertNamedMetadata(Name);
|
||||
for (const auto &MD : All)
|
||||
NamedMD->addOperand(MDNode::get(M.getContext(), MD));
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char AMDGPUUnifyMetadata::ID = 0;
|
||||
|
||||
char &llvm::AMDGPUUnifyMetadataID = AMDGPUUnifyMetadata::ID;
|
||||
|
||||
INITIALIZE_PASS(AMDGPUUnifyMetadata, "amdgpu-unify-metadata",
|
||||
"Unify multiple OpenCL metadata due to linking",
|
||||
false, false)
|
||||
|
||||
ModulePass* llvm::createAMDGPUUnifyMetadataPass() {
|
||||
return new AMDGPUUnifyMetadata();
|
||||
}
|
||||
|
||||
bool AMDGPUUnifyMetadata::runOnModule(Module &M) {
|
||||
const char* Vers[] = {
|
||||
kOCLMD::SpirVer,
|
||||
kOCLMD::OCLVer
|
||||
};
|
||||
const char* Exts[] = {
|
||||
kOCLMD::UsedExt,
|
||||
kOCLMD::UsedOptCoreFeat,
|
||||
kOCLMD::CompilerOptions,
|
||||
kOCLMD::LLVMIdent
|
||||
};
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
for (auto &I : Vers)
|
||||
Changed |= unifyVersionMD(M, I, true);
|
||||
|
||||
for (auto &I : Exts)
|
||||
Changed |= unifyExtensionMD(M, I);
|
||||
|
||||
return Changed;
|
||||
}
|
Reference in New Issue
Block a user