Code cleanup to help build with newer version of llvm. (#4080)

* Code cleanup to help build with newer version of llvm.

* Use c++14 to enable std::make_unique for linux build.

* Merge e9110d71dd (diff-302b958882f0490f56723d598234f0cc7d3e4d3f3693e6850defdba6b75596af) to fix MacOS build error for random_shuffle is marked deprecated.
This commit is contained in:
Xiang Li 2021-11-16 12:48:11 -08:00 коммит произвёл GitHub
Родитель 9f0b253ea3
Коммит 736c2aa4cd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 513 добавлений и 373 удалений

Просмотреть файл

@ -432,17 +432,17 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE )
check_cxx_compiler_flag("-std=c++1y" CXX_SUPPORTS_CXX1Y)
append_if(CXX_SUPPORTS_CXX1Y "-std=c++1y" CMAKE_CXX_FLAGS)
else()
check_cxx_compiler_flag("-std=c++11" CXX_SUPPORTS_CXX11)
if (CXX_SUPPORTS_CXX11)
check_cxx_compiler_flag("-std=c++14" CXX_SUPPORTS_CXX14)
if (CXX_SUPPORTS_CXX14)
if (CYGWIN OR MINGW)
# MinGW and Cygwin are a bit stricter and lack things like
# 'strdup', 'stricmp', etc in c++11 mode.
append("-std=gnu++11" CMAKE_CXX_FLAGS)
append("-std=gnu++14" CMAKE_CXX_FLAGS)
else()
append("-std=c++11" CMAKE_CXX_FLAGS)
append("-std=c++14" CMAKE_CXX_FLAGS)
endif()
else()
message(FATAL_ERROR "LLVM requires C++11 support but the '-std=c++11' flag isn't supported.")
message(FATAL_ERROR "LLVM requires C++11 support but the '-std=c++14' flag isn't supported.")
endif()
endif()
if (LLVM_ENABLE_MODULES)

Просмотреть файл

@ -13,6 +13,7 @@ add_llvm_library(LLVMDXIL
DxilInterpolationMode.cpp
DxilMetadataHelper.cpp
DxilModule.cpp
DxilModuleHelper.cpp
DxilOperations.cpp
DxilResource.cpp
DxilResourceBase.cpp
@ -27,6 +28,7 @@ add_llvm_library(LLVMDXIL
DxilSubobject.cpp
DxilTypeSystem.cpp
DxilUtil.cpp
DxilUtilDbgInfoAndMisc.cpp
DxilPDB.cpp
ADDITIONAL_HEADER_DIRS

Просмотреть файл

@ -264,7 +264,7 @@ void DxilMDHelper::LoadDxilShaderModel(const ShaderModel *&pSM) {
IFTBOOL(pShaderTypeMD != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
unsigned Major = ConstMDToUint32(pShaderModelMD->getOperand(kDxilShaderModelMajorIdx));
unsigned Minor = ConstMDToUint32(pShaderModelMD->getOperand(kDxilShaderModelMinorIdx));
string ShaderModelName = pShaderTypeMD->getString();
string ShaderModelName = pShaderTypeMD->getString().str();
ShaderModelName += "_" + std::to_string(Major) + "_" +
(Minor == ShaderModel::kOfflineMinor ? "x" : std::to_string(Minor));
pSM = ShaderModel::GetByName(ShaderModelName.c_str());
@ -384,7 +384,7 @@ void DxilMDHelper::GetDxilEntryPoint(const MDNode *MDO, Function *&pFunc, string
IFTBOOL(MDOName.get() != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
MDString *pMDName = dyn_cast<MDString>(MDOName);
IFTBOOL(pMDName != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
Name = pMDName->getString();
Name = pMDName->getString().str();
pSignatures = &pTupleMD->getOperand(kDxilEntryPointSignatures);
pResources = &pTupleMD->getOperand(kDxilEntryPointResources );
@ -2580,20 +2580,14 @@ bool DxilMDHelper::IsKnownMetadataID(LLVMContext &Ctx, unsigned ID)
void DxilMDHelper::GetKnownMetadataIDs(LLVMContext &Ctx, SmallVectorImpl<unsigned> *pIDs)
{
auto AddIdIfExists = [&Ctx, &pIDs](StringRef Name) {
unsigned ID = 0;
if (Ctx.findMDKindID(hlsl::DxilMDHelper::kDxilPreciseAttributeMDName,
&ID)) {
pIDs->push_back(ID);
SmallVector<StringRef, 4> Names;
Ctx.getMDKindNames(Names);
for (auto Name : Names) {
if (Name == hlsl::DxilMDHelper::kDxilPreciseAttributeMDName ||
Name == hlsl::DxilMDHelper::kDxilNonUniformAttributeMDName) {
pIDs->push_back(Ctx.getMDKindID(Name));
}
if (Ctx.findMDKindID(hlsl::DxilMDHelper::kDxilNonUniformAttributeMDName,
&ID)) {
pIDs->push_back(ID);
}
};
AddIdIfExists(hlsl::DxilMDHelper::kDxilPreciseAttributeMDName);
AddIdIfExists(hlsl::DxilMDHelper::kDxilNonUniformAttributeMDName);
}
}
void DxilMDHelper::combineDxilMetadata(llvm::Instruction *K,
@ -2689,7 +2683,7 @@ float DxilMDHelper::ConstMDToFloat(const MDOperand &MDO) {
string DxilMDHelper::StringMDToString(const MDOperand &MDO) {
MDString *pMDString = dyn_cast<MDString>(MDO.get());
IFTBOOL(pMDString != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
return pMDString->getString();
return pMDString->getString().str();
}
StringRef DxilMDHelper::StringMDToStringRef(const MDOperand &MDO) {

Просмотреть файл

@ -31,10 +31,11 @@
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include <unordered_set>
using std::make_unique;
using namespace llvm;
using std::string;
using std::vector;
@ -85,18 +86,8 @@ const char *kDxIsHelperGlobalName = "dx.ishelper";
const char *kHostLayoutTypePrefix = "hostlayout.";
}
// Avoid dependency on DxilModule from llvm::Module using this:
void DxilModule_RemoveGlobal(llvm::Module* M, llvm::GlobalObject* G) {
if (M && G && M->HasDxilModule()) {
if (llvm::Function *F = dyn_cast<llvm::Function>(G))
M->GetDxilModule().RemoveFunction(F);
}
}
void DxilModule_ResetModule(llvm::Module* M) {
if (M && M->HasDxilModule())
delete &M->GetDxilModule();
M->SetDxilModule(nullptr);
}
void SetDxilHook(Module &M);
void ClearDxilHook(Module &M);
//------------------------------------------------------------------------------
//
@ -109,7 +100,7 @@ DxilModule::DxilModule(Module *pModule)
, m_pModule(pModule)
, m_pEntryFunc(nullptr)
, m_EntryName("")
, m_pMDHelper(llvm::make_unique<DxilMDHelper>(pModule, llvm::make_unique<DxilExtraPropertyHelper>(pModule)))
, m_pMDHelper(make_unique<DxilMDHelper>(pModule, make_unique<DxilExtraPropertyHelper>(pModule)))
, m_pDebugInfoFinder(nullptr)
, m_pSM(nullptr)
, m_DxilMajor(DXIL::kDxilMajor)
@ -117,8 +108,8 @@ DxilModule::DxilModule(Module *pModule)
, m_ValMajor(1)
, m_ValMinor(0)
, m_ForceZeroStoreLifetimes(false)
, m_pOP(llvm::make_unique<OP>(pModule->getContext(), pModule))
, m_pTypeSystem(llvm::make_unique<DxilTypeSystem>(pModule))
, m_pOP(make_unique<OP>(pModule->getContext(), pModule))
, m_pTypeSystem(make_unique<DxilTypeSystem>(pModule))
, m_bDisableOptimizations(false)
, m_bUseMinPrecision(true) // use min precision by default
, m_bAllResourcesBound(false)
@ -129,8 +120,7 @@ DxilModule::DxilModule(Module *pModule)
{
DXASSERT_NOMSG(m_pModule != nullptr);
m_pModule->pfnRemoveGlobal = &DxilModule_RemoveGlobal;
m_pModule->pfnResetDxilModule = &DxilModule_ResetModule;
SetDxilHook(*m_pModule);
#if defined(_DEBUG) || defined(DBG)
// Pin LLVM dump methods.
@ -142,10 +132,7 @@ DxilModule::DxilModule(Module *pModule)
#endif
}
DxilModule::~DxilModule() {
if (m_pModule->pfnRemoveGlobal == &DxilModule_RemoveGlobal)
m_pModule->pfnRemoveGlobal = nullptr;
}
DxilModule::~DxilModule() { ClearDxilHook(*m_pModule); }
LLVMContext &DxilModule::GetCtx() const { return m_Ctx; }
Module *DxilModule::GetModule() const { return m_pModule; }
@ -167,7 +154,7 @@ void DxilModule::SetShaderModel(const ShaderModel *pSM, bool bUseMinPrecision) {
DxilFunctionProps props;
props.shaderKind = m_pSM->GetKind();
m_DxilEntryPropsMap[nullptr] =
llvm::make_unique<DxilEntryProps>(props, m_bUseMinPrecision);
make_unique<DxilEntryProps>(props, m_bUseMinPrecision);
}
m_SerializedRootSignature.clear();
}
@ -1209,7 +1196,7 @@ void DxilModule::ReplaceDxilEntryProps(llvm::Function *F,
void DxilModule::CloneDxilEntryProps(llvm::Function *F, llvm::Function *NewF) {
DXASSERT(m_DxilEntryPropsMap.count(F) != 0, "cannot find F in map");
std::unique_ptr<DxilEntryProps> Props =
llvm::make_unique<DxilEntryProps>(*m_DxilEntryPropsMap[F]);
make_unique<DxilEntryProps>(*m_DxilEntryPropsMap[F]);
m_DxilEntryPropsMap[NewF] = std::move(Props);
}
@ -1497,7 +1484,7 @@ void DxilModule::EmitDxilMetadata() {
MDTuple *pSig = m_pMDHelper->EmitDxilSignatures(entryProps->sig);
MDTuple *pSubEntry = m_pMDHelper->EmitDxilEntryPointTuple(
const_cast<Function *>(F), F->getName(), pSig, nullptr, pProps);
const_cast<Function *>(F), F->getName().str(), pSig, nullptr, pProps);
Entries.emplace_back(pSubEntry);
}
@ -1589,7 +1576,7 @@ void DxilModule::LoadDxilMetadata() {
}
std::unique_ptr<DxilEntryProps> pEntryProps =
llvm::make_unique<DxilEntryProps>(props, m_bUseMinPrecision);
make_unique<DxilEntryProps>(props, m_bUseMinPrecision);
m_pMDHelper->LoadDxilSignatures(*pSignatures, pEntryProps->sig);
m_DxilEntryPropsMap[pFunc] = std::move(pEntryProps);
@ -1603,7 +1590,7 @@ void DxilModule::LoadDxilMetadata() {
}
} else {
std::unique_ptr<DxilEntryProps> pEntryProps =
llvm::make_unique<DxilEntryProps>(entryFuncProps, m_bUseMinPrecision);
make_unique<DxilEntryProps>(entryFuncProps, m_bUseMinPrecision);
DxilFunctionProps *pFuncProps = &pEntryProps->props;
m_pMDHelper->LoadDxilSignatures(*pEntrySignatures, pEntryProps->sig);
@ -1722,6 +1709,10 @@ StripResourcesReflection(std::vector<std::unique_ptr<TResource>> &vec) {
return bChanged;
}
bool isSequentialType(Type *Ty) {
return isa<ArrayType>(Ty) || isa<VectorType>(Ty) || isa<PointerType>(Ty);
}
// Return true if any members or components of struct <Ty> contain
// scalars of less than 32 bits or are matrices, in which case translation is required
typedef llvm::SmallSetVector<const StructType*, 4> SmallStructSetVector;
@ -1732,9 +1723,8 @@ static bool ResourceTypeRequiresTranslation(const StructType * Ty, SmallStructSe
containedStructs.insert(Ty);
for (auto eTy : Ty->elements()) {
// Skip past all levels of sequential types to test their elements
SequentialType *seqTy;
while ((seqTy = dyn_cast<SequentialType>(eTy))) {
eTy = seqTy->getElementType();
while ((isSequentialType(eTy))) {
eTy = eTy->getContainedType(0);
}
// Recursively call this function again to process internal structs
if (StructType *structTy = dyn_cast<StructType>(eTy)) {
@ -1954,39 +1944,12 @@ void DxilModule::StripDebugRelatedCode() {
}
DebugInfoFinder &DxilModule::GetOrCreateDebugInfoFinder() {
if (m_pDebugInfoFinder == nullptr) {
m_pDebugInfoFinder = llvm::make_unique<llvm::DebugInfoFinder>();
m_pDebugInfoFinder = make_unique<llvm::DebugInfoFinder>();
m_pDebugInfoFinder->processModule(*m_pModule);
}
return *m_pDebugInfoFinder;
}
hlsl::DxilModule *hlsl::DxilModule::TryGetDxilModule(llvm::Module *pModule) {
LLVMContext &Ctx = pModule->getContext();
std::string diagStr;
raw_string_ostream diagStream(diagStr);
hlsl::DxilModule *pDxilModule = nullptr;
// TODO: add detail error in DxilMDHelper.
try {
pDxilModule = &pModule->GetOrCreateDxilModule();
} catch (const ::hlsl::Exception &hlslException) {
diagStream << "load dxil metadata failed -";
try {
const char *msg = hlslException.what();
if (msg == nullptr || *msg == '\0')
diagStream << " error code " << hlslException.hr << "\n";
else
diagStream << msg;
} catch (...) {
diagStream << " unable to retrieve error message.\n";
}
Ctx.diagnose(DxilErrorDiagnosticInfo(diagStream.str().c_str()));
} catch (...) {
Ctx.diagnose(DxilErrorDiagnosticInfo("load dxil metadata failed - unknown error.\n"));
}
return pDxilModule;
}
// Check if the instruction has fast math flags configured to indicate
// the instruction is precise.
// Precise fast math flags means none of the fast math flags are set.
@ -2028,18 +1991,3 @@ bool DxilModule::IsPrecise(const Instruction *inst) const {
}
} // namespace hlsl
namespace llvm {
hlsl::DxilModule &Module::GetOrCreateDxilModule(bool skipInit) {
std::unique_ptr<hlsl::DxilModule> M;
if (!HasDxilModule()) {
M = llvm::make_unique<hlsl::DxilModule>(this);
if (!skipInit) {
M->LoadDxilMetadata();
}
SetDxilModule(M.release());
}
return GetDxilModule();
}
}

Просмотреть файл

@ -0,0 +1,133 @@
///////////////////////////////////////////////////////////////////////////////
// //
// DxilModuleHelper.cpp //
// Copyright (C) Microsoft Corporation. All rights reserved. //
// This file is distributed under the University of Illinois Open Source //
// License. See LICENSE.TXT for details. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "dxc/Support/Global.h"
#include "dxc/DXIL/DxilOperations.h"
#include "dxc/DXIL/DxilModule.h"
#include "dxc/DXIL/DxilConstants.h"
#include "dxc/DXIL/DxilShaderModel.h"
#include "dxc/DXIL/DxilSignatureElement.h"
#include "dxc/DXIL/DxilFunctionProps.h"
#include "dxc/Support/WinAdapter.h"
#include "dxc/DXIL/DxilEntryProps.h"
#include "dxc/DXIL/DxilSubobject.h"
#include "dxc/DXIL/DxilInstructions.h"
#include "dxc/DXIL/DxilCounters.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include <unordered_set>
#ifndef _WIN32
using llvm::make_unique;
#else
using std::make_unique;
#endif
using namespace llvm;
using std::string;
using std::vector;
using std::unique_ptr;
namespace {
class DxilErrorDiagnosticInfo : public DiagnosticInfo {
private:
const char *m_message;
public:
DxilErrorDiagnosticInfo(const char *str)
: DiagnosticInfo(DK_FirstPluginKind, DiagnosticSeverity::DS_Error),
m_message(str) { }
void print(DiagnosticPrinter &DP) const override {
DP << m_message;
}
};
} // anon namespace
namespace hlsl {
// Avoid dependency on DxilModule from llvm::Module using this:
void DxilModule_RemoveGlobal(llvm::Module* M, llvm::GlobalObject* G) {
if (M && G && M->HasDxilModule()) {
if (llvm::Function *F = dyn_cast<llvm::Function>(G))
M->GetDxilModule().RemoveFunction(F);
}
}
void DxilModule_ResetModule(llvm::Module* M) {
if (M && M->HasDxilModule())
delete &M->GetDxilModule();
M->SetDxilModule(nullptr);
}
void SetDxilHook(Module &M) {
M.pfnRemoveGlobal = &DxilModule_RemoveGlobal;
M.pfnResetDxilModule = &DxilModule_ResetModule;
}
void ClearDxilHook(Module &M) {
if (M.pfnRemoveGlobal == &DxilModule_RemoveGlobal)
M.pfnRemoveGlobal = nullptr;
}
hlsl::DxilModule *hlsl::DxilModule::TryGetDxilModule(llvm::Module *pModule) {
LLVMContext &Ctx = pModule->getContext();
std::string diagStr;
raw_string_ostream diagStream(diagStr);
hlsl::DxilModule *pDxilModule = nullptr;
// TODO: add detail error in DxilMDHelper.
try {
pDxilModule = &pModule->GetOrCreateDxilModule();
} catch (const ::hlsl::Exception &hlslException) {
diagStream << "load dxil metadata failed -";
try {
const char *msg = hlslException.what();
if (msg == nullptr || *msg == '\0')
diagStream << " error code " << hlslException.hr << "\n";
else
diagStream << msg;
} catch (...) {
diagStream << " unable to retrieve error message.\n";
}
Ctx.diagnose(DxilErrorDiagnosticInfo(diagStream.str().c_str()));
} catch (...) {
Ctx.diagnose(DxilErrorDiagnosticInfo("load dxil metadata failed - unknown error.\n"));
}
return pDxilModule;
}
} // namespace hlsl
namespace llvm {
hlsl::DxilModule &Module::GetOrCreateDxilModule(bool skipInit) {
std::unique_ptr<hlsl::DxilModule> M;
if (!HasDxilModule()) {
M = make_unique<hlsl::DxilModule>(this);
if (!skipInit) {
M->LoadDxilMetadata();
}
SetDxilModule(M.release());
}
return GetDxilModule();
}
}

Просмотреть файл

@ -18,7 +18,6 @@
#include "dxc/Support/Global.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/GlobalVariable.h"
@ -193,173 +192,6 @@ void PrintUnescapedString(StringRef Name, raw_ostream &Out) {
}
}
std::unique_ptr<llvm::Module> LoadModuleFromBitcode(llvm::MemoryBuffer *MB,
llvm::LLVMContext &Ctx,
std::string &DiagStr) {
// Note: the DiagStr is not used.
auto pModule = llvm::parseBitcodeFile(MB->getMemBufferRef(), Ctx);
if (!pModule) {
return nullptr;
}
return std::unique_ptr<llvm::Module>(pModule.get().release());
}
std::unique_ptr<llvm::Module> LoadModuleFromBitcodeLazy(std::unique_ptr<llvm::MemoryBuffer> &&MB,
llvm::LLVMContext &Ctx, std::string &DiagStr)
{
// Note: the DiagStr is not used.
auto pModule = llvm::getLazyBitcodeModule(std::move(MB), Ctx, nullptr, true);
if (!pModule) {
return nullptr;
}
return std::unique_ptr<llvm::Module>(pModule.get().release());
}
std::unique_ptr<llvm::Module> LoadModuleFromBitcode(llvm::StringRef BC,
llvm::LLVMContext &Ctx,
std::string &DiagStr) {
std::unique_ptr<llvm::MemoryBuffer> pBitcodeBuf(
llvm::MemoryBuffer::getMemBuffer(BC, "", false));
return LoadModuleFromBitcode(pBitcodeBuf.get(), Ctx, DiagStr);
}
DIGlobalVariable *FindGlobalVariableDebugInfo(GlobalVariable *GV,
DebugInfoFinder &DbgInfoFinder) {
struct GlobalFinder {
GlobalVariable *GV;
bool operator()(llvm::DIGlobalVariable *const arg) const {
return arg->getVariable() == GV;
}
};
GlobalFinder F = {GV};
DebugInfoFinder::global_variable_iterator Found =
std::find_if(DbgInfoFinder.global_variables().begin(),
DbgInfoFinder.global_variables().end(), F);
if (Found != DbgInfoFinder.global_variables().end()) {
return *Found;
}
return nullptr;
}
static void EmitWarningOrErrorOnInstruction(Instruction *I, Twine Msg,
DiagnosticSeverity severity);
// If we don't have debug location and this is select/phi,
// try recursing users to find instruction with debug info.
// Only recurse phi/select and limit depth to prevent doing
// too much work if no debug location found.
static bool EmitWarningOrErrorOnInstructionFollowPhiSelect(Instruction *I,
Twine Msg,
DiagnosticSeverity severity,
unsigned depth = 0) {
if (depth > 4)
return false;
if (I->getDebugLoc().get()) {
EmitWarningOrErrorOnInstruction(I, Msg, severity);
return true;
}
if (isa<PHINode>(I) || isa<SelectInst>(I)) {
for (auto U : I->users())
if (Instruction *UI = dyn_cast<Instruction>(U))
if (EmitWarningOrErrorOnInstructionFollowPhiSelect(UI, Msg, severity,
depth + 1))
return true;
}
return false;
}
static void EmitWarningOrErrorOnInstruction(Instruction *I, Twine Msg,
DiagnosticSeverity severity) {
const DebugLoc &DL = I->getDebugLoc();
if (!DL.get() && (isa<PHINode>(I) || isa<SelectInst>(I))) {
if (EmitWarningOrErrorOnInstructionFollowPhiSelect(I, Msg, severity))
return;
}
I->getContext().diagnose(DiagnosticInfoDxil(I->getParent()->getParent(),
DL.get(), Msg, severity));
}
void EmitErrorOnInstruction(Instruction *I, Twine Msg) {
EmitWarningOrErrorOnInstruction(I, Msg, DiagnosticSeverity::DS_Error);
}
void EmitWarningOnInstruction(Instruction *I, Twine Msg) {
EmitWarningOrErrorOnInstruction(I, Msg, DiagnosticSeverity::DS_Warning);
}
static void EmitWarningOrErrorOnFunction(llvm::LLVMContext &Ctx, Function *F, Twine Msg,
DiagnosticSeverity severity) {
DILocation *DLoc = nullptr;
if (DISubprogram *DISP = getDISubprogram(F)) {
DLoc = DILocation::get(F->getContext(), DISP->getLine(), 0,
DISP, nullptr /*InlinedAt*/);
}
Ctx.diagnose(DiagnosticInfoDxil(F, DLoc, Msg, severity));
}
void EmitErrorOnFunction(llvm::LLVMContext &Ctx, Function *F, Twine Msg) {
EmitWarningOrErrorOnFunction(Ctx, F, Msg, DiagnosticSeverity::DS_Error);
}
void EmitWarningOnFunction(llvm::LLVMContext &Ctx, Function *F, Twine Msg) {
EmitWarningOrErrorOnFunction(Ctx, F, Msg, DiagnosticSeverity::DS_Warning);
}
static void EmitWarningOrErrorOnGlobalVariable(llvm::LLVMContext &Ctx, GlobalVariable *GV,
Twine Msg, DiagnosticSeverity severity) {
DIGlobalVariable *DIV = nullptr;
if (GV) {
Module &M = *GV->getParent();
if (hasDebugInfo(M)) {
DebugInfoFinder FinderObj;
DebugInfoFinder &Finder = FinderObj;
// Debug modules have no dxil modules. Use it if you got it.
if (M.HasDxilModule())
Finder = M.GetDxilModule().GetOrCreateDebugInfoFinder();
else
Finder.processModule(M);
DIV = FindGlobalVariableDebugInfo(GV, Finder);
}
}
Ctx.diagnose(DiagnosticInfoDxil(nullptr /*Function*/, DIV, Msg, severity));
}
void EmitErrorOnGlobalVariable(llvm::LLVMContext &Ctx, GlobalVariable *GV, Twine Msg) {
EmitWarningOrErrorOnGlobalVariable(Ctx, GV, Msg, DiagnosticSeverity::DS_Error);
}
void EmitWarningOnGlobalVariable(llvm::LLVMContext &Ctx, GlobalVariable *GV, Twine Msg) {
EmitWarningOrErrorOnGlobalVariable(Ctx, GV, Msg, DiagnosticSeverity::DS_Warning);
}
const char *kResourceMapErrorMsg =
"local resource not guaranteed to map to unique global resource.";
void EmitResMappingError(Instruction *Res) {
EmitErrorOnInstruction(Res, kResourceMapErrorMsg);
}
// Mostly just a locationless diagnostic output
static void EmitWarningOrErrorOnContext(LLVMContext &Ctx, Twine Msg, DiagnosticSeverity severity) {
Ctx.diagnose(DiagnosticInfoDxil(nullptr /*Func*/, Msg, severity));
}
void EmitErrorOnContext(LLVMContext &Ctx, Twine Msg) {
EmitWarningOrErrorOnContext(Ctx, Msg, DiagnosticSeverity::DS_Error);
}
void EmitWarningOnContext(LLVMContext &Ctx, Twine Msg) {
EmitWarningOrErrorOnContext(Ctx, Msg, DiagnosticSeverity::DS_Warning);
}
void EmitNoteOnContext(LLVMContext &Ctx, Twine Msg) {
EmitWarningOrErrorOnContext(Ctx, Msg, DiagnosticSeverity::DS_Note);
}
void CollectSelect(llvm::Instruction *Inst,
std::unordered_set<llvm::Instruction *> &selectSet) {
unsigned startOpIdx = 0;
@ -437,75 +269,6 @@ llvm::BasicBlock *GetSwitchSuccessorForCond(llvm::SwitchInst *Switch,llvm::Const
return Switch->getDefaultDest();
}
static DbgValueInst *FindDbgValueInst(Value *Val) {
if (auto *ValAsMD = LocalAsMetadata::getIfExists(Val)) {
if (auto *ValMDAsVal = MetadataAsValue::getIfExists(Val->getContext(), ValAsMD)) {
for (User *ValMDUser : ValMDAsVal->users()) {
if (DbgValueInst *DbgValInst = dyn_cast<DbgValueInst>(ValMDUser))
return DbgValInst;
}
}
}
return nullptr;
}
void MigrateDebugValue(Value *Old, Value *New) {
DbgValueInst *DbgValInst = FindDbgValueInst(Old);
if (DbgValInst == nullptr) return;
DbgValInst->setOperand(0, MetadataAsValue::get(New->getContext(), ValueAsMetadata::get(New)));
// Move the dbg value after the new instruction
if (Instruction *NewInst = dyn_cast<Instruction>(New)) {
if (NewInst->getNextNode() != DbgValInst) {
DbgValInst->removeFromParent();
DbgValInst->insertAfter(NewInst);
}
}
}
// Propagates any llvm.dbg.value instruction for a given vector
// to the elements that were used to create it through a series
// of insertelement instructions.
//
// This is used after lowering a vector-returning intrinsic.
// If we just keep the debug info on the recomposed vector,
// we will lose it when we break it apart again during later
// optimization stages.
void TryScatterDebugValueToVectorElements(Value *Val) {
if (!isa<InsertElementInst>(Val) || !Val->getType()->isVectorTy()) return;
DbgValueInst *VecDbgValInst = FindDbgValueInst(Val);
if (VecDbgValInst == nullptr) return;
Type *ElemTy = Val->getType()->getVectorElementType();
DIBuilder DbgInfoBuilder(*VecDbgValInst->getModule());
unsigned ElemSizeInBits = VecDbgValInst->getModule()->getDataLayout().getTypeSizeInBits(ElemTy);
DIExpression *ParentBitPiece = VecDbgValInst->getExpression();
if (ParentBitPiece != nullptr && !ParentBitPiece->isBitPiece())
ParentBitPiece = nullptr;
while (InsertElementInst *InsertElt = dyn_cast<InsertElementInst>(Val)) {
Value *NewElt = InsertElt->getOperand(1);
unsigned EltIdx = static_cast<unsigned>(cast<ConstantInt>(InsertElt->getOperand(2))->getLimitedValue());
unsigned OffsetInBits = EltIdx * ElemSizeInBits;
if (ParentBitPiece) {
assert(OffsetInBits + ElemSizeInBits <= ParentBitPiece->getBitPieceSize()
&& "Nested bit piece expression exceeds bounds of its parent.");
OffsetInBits += ParentBitPiece->getBitPieceOffset();
}
DIExpression *DIExpr = DbgInfoBuilder.createBitPieceExpression(OffsetInBits, ElemSizeInBits);
// Offset is basically unused and deprecated in later LLVM versions.
// Emit it as zero otherwise later versions of the bitcode reader will drop the intrinsic.
DbgInfoBuilder.insertDbgValueIntrinsic(NewElt, /* Offset */ 0, VecDbgValInst->getVariable(),
DIExpr, VecDbgValInst->getDebugLoc(), InsertElt);
Val = InsertElt->getOperand(0);
}
}
Value *SelectOnOperation(llvm::Instruction *Inst, unsigned operandIdx) {
Instruction *prototype = Inst;
for (unsigned i = 0; i < prototype->getNumOperands(); i++) {
@ -599,7 +362,7 @@ bool IsResourceSingleComponent(Type *Ty) {
if (vectorType->getNumElements() > 1) {
return false;
}
return IsResourceSingleComponent(vectorType->getVectorElementType());
return IsResourceSingleComponent(vectorType->getElementType());
}
return true;
}
@ -1187,6 +950,10 @@ Value *GetConvergentSource(Value *V) {
return cast<CallInst>(V)->getOperand(0);
}
bool isCompositeType(Type *Ty) {
return isa<ArrayType>(Ty) || isa<StructType>(Ty) || isa<VectorType>(Ty);
}
/// If value is a bitcast to base class pattern, equivalent
/// to a getelementptr X, 0, 0, 0... turn it into the appropriate gep.
/// This can enhance SROA and other transforms that want type-safe pointers,
@ -1201,10 +968,9 @@ Value *TryReplaceBaseCastWithGep(Value *V) {
// Adapted from code in InstCombiner::visitBitCast
unsigned NumZeros = 0;
while (SrcElTy != DstElTy && isa<CompositeType>(SrcElTy) &&
!SrcElTy->isPointerTy() &&
while (SrcElTy != DstElTy && isCompositeType(SrcElTy) &&
SrcElTy->getNumContainedTypes() /* not "{}" */) {
SrcElTy = cast<CompositeType>(SrcElTy)->getTypeAtIndex(0U);
SrcElTy = SrcElTy->getContainedType(0);
++NumZeros;
}
@ -1230,32 +996,3 @@ Value *TryReplaceBaseCastWithGep(Value *V) {
}
}
///////////////////////////////////////////////////////////////////////////////
namespace {
class DxilLoadMetadata : public ModulePass {
public:
static char ID; // Pass identification, replacement for typeid
explicit DxilLoadMetadata () : ModulePass(ID) {}
const char *getPassName() const override { return "HLSL load DxilModule from metadata"; }
bool runOnModule(Module &M) override {
if (!M.HasDxilModule()) {
(void)M.GetOrCreateDxilModule();
return true;
}
return false;
}
};
}
char DxilLoadMetadata::ID = 0;
ModulePass *llvm::createDxilLoadMetadataPass() {
return new DxilLoadMetadata();
}
INITIALIZE_PASS(DxilLoadMetadata, "hlsl-dxilload", "HLSL load DxilModule from metadata", false, false)

Просмотреть файл

@ -0,0 +1,325 @@
///////////////////////////////////////////////////////////////////////////////
// //
// DxilUtilDbgInfoAndMisc.cpp //
// Copyright (C) Microsoft Corporation. All rights reserved. //
// This file is distributed under the University of Illinois Open Source //
// License. See LICENSE.TXT for details. //
// //
// Dxil helper functions. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "dxc/DXIL/DxilTypeSystem.h"
#include "dxc/DXIL/DxilUtil.h"
#include "dxc/DXIL/DxilModule.h"
#include "dxc/DXIL/DxilOperations.h"
#include "dxc/HLSL/DxilConvergentName.h"
#include "dxc/Support/Global.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/IRBuilder.h"
using namespace llvm;
using namespace hlsl;
namespace hlsl {
namespace dxilutil {
std::unique_ptr<llvm::Module> LoadModuleFromBitcode(llvm::MemoryBuffer *MB,
llvm::LLVMContext &Ctx,
std::string &DiagStr) {
// Note: the DiagStr is not used.
auto pModule = llvm::parseBitcodeFile(MB->getMemBufferRef(), Ctx);
if (!pModule) {
return nullptr;
}
return std::unique_ptr<llvm::Module>(pModule.get().release());
}
std::unique_ptr<llvm::Module>
LoadModuleFromBitcodeLazy(std::unique_ptr<llvm::MemoryBuffer> &&MB,
llvm::LLVMContext &Ctx, std::string &DiagStr) {
// Note: the DiagStr is not used.
auto pModule = llvm::getLazyBitcodeModule(std::move(MB), Ctx, nullptr, true);
if (!pModule) {
return nullptr;
}
return std::unique_ptr<llvm::Module>(pModule.get().release());
}
std::unique_ptr<llvm::Module> LoadModuleFromBitcode(llvm::StringRef BC,
llvm::LLVMContext &Ctx,
std::string &DiagStr) {
std::unique_ptr<llvm::MemoryBuffer> pBitcodeBuf(
llvm::MemoryBuffer::getMemBuffer(BC, "", false));
return LoadModuleFromBitcode(pBitcodeBuf.get(), Ctx, DiagStr);
}
DIGlobalVariable *FindGlobalVariableDebugInfo(GlobalVariable *GV,
DebugInfoFinder &DbgInfoFinder) {
struct GlobalFinder {
GlobalVariable *GV;
bool operator()(llvm::DIGlobalVariable *const arg) const {
return arg->getVariable() == GV;
}
};
GlobalFinder F = {GV};
DebugInfoFinder::global_variable_iterator Found =
std::find_if(DbgInfoFinder.global_variables().begin(),
DbgInfoFinder.global_variables().end(), F);
if (Found != DbgInfoFinder.global_variables().end()) {
return *Found;
}
return nullptr;
}
static void EmitWarningOrErrorOnInstruction(Instruction *I, Twine Msg,
DiagnosticSeverity severity);
// If we don't have debug location and this is select/phi,
// try recursing users to find instruction with debug info.
// Only recurse phi/select and limit depth to prevent doing
// too much work if no debug location found.
static bool
EmitWarningOrErrorOnInstructionFollowPhiSelect(Instruction *I, Twine Msg,
DiagnosticSeverity severity,
unsigned depth = 0) {
if (depth > 4)
return false;
if (I->getDebugLoc().get()) {
EmitWarningOrErrorOnInstruction(I, Msg, severity);
return true;
}
if (isa<PHINode>(I) || isa<SelectInst>(I)) {
for (auto U : I->users())
if (Instruction *UI = dyn_cast<Instruction>(U))
if (EmitWarningOrErrorOnInstructionFollowPhiSelect(UI, Msg, severity,
depth + 1))
return true;
}
return false;
}
static void EmitWarningOrErrorOnInstruction(Instruction *I, Twine Msg,
DiagnosticSeverity severity) {
const DebugLoc &DL = I->getDebugLoc();
if (!DL.get() && (isa<PHINode>(I) || isa<SelectInst>(I))) {
if (EmitWarningOrErrorOnInstructionFollowPhiSelect(I, Msg, severity))
return;
}
I->getContext().diagnose(
DiagnosticInfoDxil(I->getParent()->getParent(), DL.get(), Msg, severity));
}
void EmitErrorOnInstruction(Instruction *I, Twine Msg) {
EmitWarningOrErrorOnInstruction(I, Msg, DiagnosticSeverity::DS_Error);
}
void EmitWarningOnInstruction(Instruction *I, Twine Msg) {
EmitWarningOrErrorOnInstruction(I, Msg, DiagnosticSeverity::DS_Warning);
}
static void EmitWarningOrErrorOnFunction(llvm::LLVMContext &Ctx, Function *F,
Twine Msg,
DiagnosticSeverity severity) {
DILocation *DLoc = nullptr;
if (DISubprogram *DISP = getDISubprogram(F)) {
DLoc = DILocation::get(F->getContext(), DISP->getLine(), 0, DISP,
nullptr /*InlinedAt*/);
}
Ctx.diagnose(DiagnosticInfoDxil(F, DLoc, Msg, severity));
}
void EmitErrorOnFunction(llvm::LLVMContext &Ctx, Function *F, Twine Msg) {
EmitWarningOrErrorOnFunction(Ctx, F, Msg, DiagnosticSeverity::DS_Error);
}
void EmitWarningOnFunction(llvm::LLVMContext &Ctx, Function *F, Twine Msg) {
EmitWarningOrErrorOnFunction(Ctx, F, Msg, DiagnosticSeverity::DS_Warning);
}
static void EmitWarningOrErrorOnGlobalVariable(llvm::LLVMContext &Ctx,
GlobalVariable *GV, Twine Msg,
DiagnosticSeverity severity) {
DIGlobalVariable *DIV = nullptr;
if (GV) {
Module &M = *GV->getParent();
if (hasDebugInfo(M)) {
DebugInfoFinder FinderObj;
DebugInfoFinder &Finder = FinderObj;
// Debug modules have no dxil modules. Use it if you got it.
if (M.HasDxilModule())
Finder = M.GetDxilModule().GetOrCreateDebugInfoFinder();
else
Finder.processModule(M);
DIV = FindGlobalVariableDebugInfo(GV, Finder);
}
}
Ctx.diagnose(DiagnosticInfoDxil(nullptr /*Function*/, DIV, Msg, severity));
}
void EmitErrorOnGlobalVariable(llvm::LLVMContext &Ctx, GlobalVariable *GV,
Twine Msg) {
EmitWarningOrErrorOnGlobalVariable(Ctx, GV, Msg,
DiagnosticSeverity::DS_Error);
}
void EmitWarningOnGlobalVariable(llvm::LLVMContext &Ctx, GlobalVariable *GV,
Twine Msg) {
EmitWarningOrErrorOnGlobalVariable(Ctx, GV, Msg,
DiagnosticSeverity::DS_Warning);
}
const char *kResourceMapErrorMsg =
"local resource not guaranteed to map to unique global resource.";
void EmitResMappingError(Instruction *Res) {
EmitErrorOnInstruction(Res, kResourceMapErrorMsg);
}
// Mostly just a locationless diagnostic output
static void EmitWarningOrErrorOnContext(LLVMContext &Ctx, Twine Msg,
DiagnosticSeverity severity) {
Ctx.diagnose(DiagnosticInfoDxil(nullptr /*Func*/, Msg, severity));
}
void EmitErrorOnContext(LLVMContext &Ctx, Twine Msg) {
EmitWarningOrErrorOnContext(Ctx, Msg, DiagnosticSeverity::DS_Error);
}
void EmitWarningOnContext(LLVMContext &Ctx, Twine Msg) {
EmitWarningOrErrorOnContext(Ctx, Msg, DiagnosticSeverity::DS_Warning);
}
void EmitNoteOnContext(LLVMContext &Ctx, Twine Msg) {
EmitWarningOrErrorOnContext(Ctx, Msg, DiagnosticSeverity::DS_Note);
}
static DbgValueInst *FindDbgValueInst(Value *Val) {
if (auto *ValAsMD = LocalAsMetadata::getIfExists(Val)) {
if (auto *ValMDAsVal =
MetadataAsValue::getIfExists(Val->getContext(), ValAsMD)) {
for (User *ValMDUser : ValMDAsVal->users()) {
if (DbgValueInst *DbgValInst = dyn_cast<DbgValueInst>(ValMDUser))
return DbgValInst;
}
}
}
return nullptr;
}
void MigrateDebugValue(Value *Old, Value *New) {
DbgValueInst *DbgValInst = FindDbgValueInst(Old);
if (DbgValInst == nullptr)
return;
DbgValInst->setOperand(
0, MetadataAsValue::get(New->getContext(), ValueAsMetadata::get(New)));
// Move the dbg value after the new instruction
if (Instruction *NewInst = dyn_cast<Instruction>(New)) {
if (NewInst->getNextNode() != DbgValInst) {
DbgValInst->removeFromParent();
DbgValInst->insertAfter(NewInst);
}
}
}
// Propagates any llvm.dbg.value instruction for a given vector
// to the elements that were used to create it through a series
// of insertelement instructions.
//
// This is used after lowering a vector-returning intrinsic.
// If we just keep the debug info on the recomposed vector,
// we will lose it when we break it apart again during later
// optimization stages.
void TryScatterDebugValueToVectorElements(Value *Val) {
if (!isa<InsertElementInst>(Val) || !Val->getType()->isVectorTy())
return;
DbgValueInst *VecDbgValInst = FindDbgValueInst(Val);
if (VecDbgValInst == nullptr)
return;
Type *ElemTy = Val->getType()->getVectorElementType();
DIBuilder DbgInfoBuilder(*VecDbgValInst->getModule());
unsigned ElemSizeInBits =
VecDbgValInst->getModule()->getDataLayout().getTypeSizeInBits(ElemTy);
DIExpression *ParentBitPiece = VecDbgValInst->getExpression();
if (ParentBitPiece != nullptr && !ParentBitPiece->isBitPiece())
ParentBitPiece = nullptr;
while (InsertElementInst *InsertElt = dyn_cast<InsertElementInst>(Val)) {
Value *NewElt = InsertElt->getOperand(1);
unsigned EltIdx = static_cast<unsigned>(
cast<ConstantInt>(InsertElt->getOperand(2))->getLimitedValue());
unsigned OffsetInBits = EltIdx * ElemSizeInBits;
if (ParentBitPiece) {
assert(OffsetInBits + ElemSizeInBits <=
ParentBitPiece->getBitPieceSize() &&
"Nested bit piece expression exceeds bounds of its parent.");
OffsetInBits += ParentBitPiece->getBitPieceOffset();
}
DIExpression *DIExpr =
DbgInfoBuilder.createBitPieceExpression(OffsetInBits, ElemSizeInBits);
// Offset is basically unused and deprecated in later LLVM versions.
// Emit it as zero otherwise later versions of the bitcode reader will drop
// the intrinsic.
DbgInfoBuilder.insertDbgValueIntrinsic(
NewElt, /* Offset */ 0, VecDbgValInst->getVariable(), DIExpr,
VecDbgValInst->getDebugLoc(), InsertElt);
Val = InsertElt->getOperand(0);
}
}
} // namespace dxilutil
} // namespace hlsl
///////////////////////////////////////////////////////////////////////////////
namespace {
class DxilLoadMetadata : public ModulePass {
public:
static char ID; // Pass identification, replacement for typeid
explicit DxilLoadMetadata () : ModulePass(ID) {}
const char *getPassName() const override { return "HLSL load DxilModule from metadata"; }
bool runOnModule(Module &M) override {
if (!M.HasDxilModule()) {
(void)M.GetOrCreateDxilModule();
return true;
}
return false;
}
};
}
char DxilLoadMetadata::ID = 0;
ModulePass *llvm::createDxilLoadMetadataPass() {
return new DxilLoadMetadata();
}
INITIALIZE_PASS(DxilLoadMetadata, "hlsl-dxilload", "HLSL load DxilModule from metadata", false, false)

Просмотреть файл

@ -30,6 +30,7 @@
#include <algorithm>
#include <set>
#include <sstream>
#include <random>
#include <vector>
namespace llvm {
@ -114,6 +115,12 @@ public:
return Rand64() % y;
}
/// Make this like a C++11 random device
typedef uint32_t result_type;
uint32_t operator()() { return Rand32(); }
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return 0x7ffff; }
private:
unsigned Seed;
};
@ -662,7 +669,7 @@ static void IntroduceControlFlow(Function *F, Random &R) {
BoolInst.push_back(&Instr);
}
std::random_shuffle(BoolInst.begin(), BoolInst.end(), R);
std::shuffle(BoolInst.begin(), BoolInst.end(), R);
for (auto *Instr : BoolInst) {
BasicBlock *Curr = Instr->getParent();

Просмотреть файл

@ -19,19 +19,13 @@
#include "gtest/gtest.h"
#include <algorithm>
#include <list>
#include <random>
#include <vector>
using namespace llvm;
namespace {
// The world's worst RNG, but it is deterministic and makes it easy to get
// *some* shuffling of elements.
static ptrdiff_t test_shuffle_rng(ptrdiff_t i) {
return (i + i * 33) % i;
}
static ptrdiff_t (*test_shuffle_rng_p)(ptrdiff_t) = &test_shuffle_rng;
template <typename VectorT>
class TinyPtrVectorTest : public testing::Test {
protected:
@ -48,7 +42,7 @@ protected:
for (size_t i = 0, e = array_lengthof(TestValues); i != e; ++i)
TestPtrs.push_back(&TestValues[i]);
std::random_shuffle(TestPtrs.begin(), TestPtrs.end(), test_shuffle_rng_p);
std::shuffle(TestPtrs.begin(), TestPtrs.end(), std::mt19937{});
}
ArrayRef<PtrT> testArray(size_t N) {