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:
Родитель
9f0b253ea3
Коммит
736c2aa4cd
|
@ -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) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче