diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7967fa03e3..9146b4e1db 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -44,8 +44,8 @@ stages: displayName: 'DXIL Tests' - script: | call utils\hct\hctstart.cmd %HLSL_SRC_DIR% %HLSL_BLD_DIR% - call utils\hct\hcttest.cmd -$(configuration) exec-warp - displayName: 'DXIL Execution Tests (Nuget WARP)' + call utils\hct\hcttest.cmd -$(configuration) exec + displayName: 'DXIL Execution Tests' - job: Nix timeoutInMinutes: 120 diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake index f25de66a32..9b92e3f22e 100644 --- a/cmake/modules/AddLLVM.cmake +++ b/cmake/modules/AddLLVM.cmake @@ -222,11 +222,35 @@ function(set_output_directory target bindir libdir) set(moddir ${libdir}) endif() if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") + # HLSL change begin: work around broken MSVC_BUILD_AS_X + get_target_property(target_type ${target} TYPE) + if(target_type STREQUAL "SHARED_LIBRARY" AND MSVC_BUILD_AS_X EQUAL 1) + set(arm64x_workaround 1) + message(NOTICE "Working around ARM64X / MSVC_BUILD_AS_X bug for ${target}") + else() + set(arm64x_workaround 0) + endif() + # HLSL change end + foreach(build_mode ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER "${build_mode}" CONFIG_SUFFIX) string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} bi ${bindir}) string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} li ${libdir}) string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} mi ${moddir}) + + # HLSL change begin: work around broken MSVC_BUILD_AS_X + # + # MSVC_BUILD_AS_X generates a vcxproj that builds for both ARM64 and + # ARM64EC, but these two platforms are only visible in msbuild. It also + # currently configures the import libraries to all be output to the same + # location, which means it's a race for if we get the ARM64 or ARM64X + # version there. The appended $(PLATFORM) is evaluated by msbuild at + # build time to separate the ARM64EC from ARM64 builds. + if(arm64x_workaround EQUAL 1) + string(APPEND li "/$(PLATFORM)") + endif() + # HLSL change end + set_target_properties(${target} PROPERTIES "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${bi}) set_target_properties(${target} PROPERTIES "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${li}) set_target_properties(${target} PROPERTIES "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${mi}) diff --git a/cmake/modules/Nuget.cmake b/cmake/modules/Nuget.cmake deleted file mode 100644 index 5c8aaea337..0000000000 --- a/cmake/modules/Nuget.cmake +++ /dev/null @@ -1,233 +0,0 @@ -include_guard(GLOBAL) - -if(NOT DEFINED BINARY_DIR) - message(SEND_ERROR "Callers must provide BINARY_DIR") -endif() - -if(NOT DEFINED BUILD_TYPE) - message(SEND_ERROR "Callers must provide BUILD_TYPE") -endif() - -if(NOT DEFINED ENV{USE_WARP_FROM_NUGET}) - message(SEND_ERROR "Callers must set a string value for the environment variable USE_WARP_FROM_NUGET." - "Either 'LATEST_RELEASE' or 'LATEST_PREVIEW'") -endif() - -set(USE_WARP_FROM_NUGET $ENV{USE_WARP_FROM_NUGET}) - -# Downloads nuget.exe to the given path if it doesn't exist yet. -function(EnsureNugetExists target_path) - # Download the latest nuget.exe to the given path. - if(NOT EXISTS ${target_path}) - message(STATUS "Installing nuget.exe to ${target_path}...") - file(DOWNLOAD - https://dist.nuget.org/win-x86-commandline/latest/nuget.exe - ${target_path} - ) - endif() -endfunction() - -# Download the latest nuget package for the given ID. Can pass in a custom source, defaults to nuget public feed. -function(GetNuGetPackageLatestVersion) - set(params NAME ID SOURCE OUTPUT_DIR OUTPUT_VARIABLE PREVIEW) - cmake_parse_arguments(PARSE_ARGV 0 ARG "" "${params}" "") - - if(NOT ARG_OUTPUT_DIR) - set(ARG_OUTPUT_DIR ) - endif() - - set(nuget_exe_path "${ARG_OUTPUT_DIR}\\nuget.exe install") - EnsureNugetExists(${nuget_exe_path}) - - if (${ARG_ID}_LATEST_VERSION) - set(${ARG_OUTPUT_VARIABLE} ${${ARG_ID}_LATEST_VERSION} PARENT_SCOPE) - else() - if(NOT ARG_SOURCE) - set(ARG_SOURCE https://api.nuget.org/v3/index.json) - endif() - - if(NOT ARG_PREVIEW) - set(ARG_PREVIEW OFF) - endif() - - if(ARG_PREVIEW) - # Note that '-Prerelease' options will only return a prerelease package if that is also the latest. - # If you want a prerelease package with an older version number than the latest release package then you - # need to pass a specific version number. - message("Will add '-Prelease' to nuget list command") - set(prerelease "-Prerelease") - endif() - - execute_process( - COMMAND ${nuget_exe_path} - list ${ARG_ID} - -Source ${ARG_SOURCE} - ${prerelease} - RESULT_VARIABLE result - OUTPUT_VARIABLE nuget_list_output - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - if(NOT ${result} STREQUAL "0") - message(FATAL_ERROR "NuGet failed to find latest version of package ${ARG_ID} with exit code ${result}.") - endif() - - # Get last line of running nuget.exe list . - string(REPLACE "\n" ";" nuget_list_output ${nuget_list_output}) - list(POP_BACK nuget_list_output nuget_list_last_line) - if(nuget_list_last_line STREQUAL "No packages found.") - message(FATAL_ERROR "NuGet failed to find latest version of package ${ARG_ID}.") - endif() - - # The last line should have the format - string(REPLACE " " ";" nuget_list_last_line ${nuget_list_last_line}) - list(POP_BACK nuget_list_last_line nuget_version) - - if(NOT nuget_version) - message(FATAL_ERROR "NuGet failed to find latest version of package ${ARG_ID}.") - endif() - - message("Nuget found version:${nuget_version} for ${ARG_ID}") - - # Save output variable and cache the result so subsequent calls to the version-unspecified package - # are faster. - set(${ARG_OUTPUT_VARIABLE} ${nuget_version} PARENT_SCOPE) - set(${ARG_ID}_LATEST_VERSION ${nuget_version} CACHE INTERNAL "") - endif() -endfunction() - -# Installs a NuGet package under OUTPUT_DIR. -# -# FetchNuGetPackage( -# ID Microsoft.Direct3D.WARP -# VERSION 1.0.13 -# SOURCE https://api.nuget.org/v3/index.json -# ) -# -# This function sets a variable _SOURCE_DIR (e.g. Microsoft.Direct3D.WARP_SOURCE_DIR in above example) to the -# extract NuGet package contents. -function(FetchNuGetPackage) - set(params NAME ID VERSION SOURCE OUTPUT_DIR RELEASE_TYPE) - cmake_parse_arguments(PARSE_ARGV 0 ARG "" "${params}" "") - - # The NAME parameter is optional: if it's not set then the package ID is used as the name. The - # reason for having a separate NAME is to allow a consistent identifier for packages whose ID - # changes with each release (e.g. GDK). - if(NOT ARG_NAME) - set(ARG_NAME ${ARG_ID}) - endif() - - if(NOT ARG_OUTPUT_DIR) - set(ARG_OUTPUT_DIR ${BINARY_DIR}/temp) - endif() - - set(nuget_exe_path ${ARG_OUTPUT_DIR}/nuget.exe) - - if(NOT ARG_SOURCE) - set(ARG_SOURCE https://api.nuget.org/v3/index.json) - endif() - - if(NOT ARG_RELEASE_TYPE) - set(ARG_RELEASE_TYPE "LATEST_RELEASE") - endif() - - set(PREVIEW OFF) - - if(${ARG_RELEASE_TYPE} STREQUAL "LATEST_PREVIEW") - set(PREVIEW ON) - endif() - - # Default to latest version - if(NOT ARG_VERSION) - GetNuGetPackageLatestVersion( - ID ${ARG_ID} - SOURCE ${ARG_SOURCE} - PREVIEW ${PREVIEW} - OUTPUT_DIR ${ARG_OUTPUT_DIR} - OUTPUT_VARIABLE ARG_VERSION - ) - endif() - - set(nupkg_path ${ARG_OUTPUT_DIR}/${ARG_ID}.${ARG_VERSION}/${ARG_ID}.${ARG_VERSION}.nupkg) - - if(NOT EXISTS ${nupkg_path}) - message(STATUS "NuGet: adding package ${ARG_ID}.${ARG_VERSION}") - - EnsureNugetExists(${nuget_exe_path}) - - set(retry_count 0) - set(max_retries 10) - set(retry_delay 10) - set(result 1) - - # Run NuGet CLI to download the package. - while(NOT ${result} STREQUAL "0" AND ${retry_count} LESS ${max_retries}) - message(STATUS "'${nuget_exe_path}' install '${ARG_ID}' -Version '${ARG_VERSION}' -Source '${ARG_SOURCE}' -OutputDirectory '${ARG_OUTPUT_DIR}' -DependencyVersion Ignore -Verbosity quiet") - execute_process( - COMMAND - ${nuget_exe_path} - install ${ARG_ID} - -Version ${ARG_VERSION} - -Source ${ARG_SOURCE} - -OutputDirectory ${ARG_OUTPUT_DIR} - -DependencyVersion Ignore - -Verbosity quiet - RESULT_VARIABLE result - ) - if(NOT ${result} STREQUAL "0") - math(EXPR retry_count "${retry_count} + 1") - - message(STATUS "Nuget failed: '${result}'. Retrying in ${retry_delay} seconds...") - execute_process( - COMMAND - ${CMAKE_COMMAND} -E sleep ${retry_delay} - ) - endif() - endwhile() - - if(NOT ${result} STREQUAL "0") - message(FATAL_ERROR "NuGet failed: '${result}' Package '${ARG_NAME}' (${ARG_ID}.${ARG_VERSION})") - endif() - endif() - - # Set output variable. The NAME parameter is optional: if it's not set then the package ID is used as the - # name. The reason for having a separate NAME is for packages whose IDs change (e.g. GDK) so that callers - # can use a fixed name in dependents. Example, targets can reference gdk_SOURCE_DIR with the snippet below - # instead of having to reference Microsoft.GDK.PC.230300_SOURCE_DIR. - # - # FetchNuGetPackage( - # NAME gdk - # ID Microsoft.GDK.PC.220300 - # VERSION 10.0.22621.3049 - # ) - set(${ARG_NAME}_SOURCE_DIR ${ARG_OUTPUT_DIR}/${ARG_ID}.${ARG_VERSION} PARENT_SCOPE) -endfunction() - -# Begin the 'main' logic of this file. Previous code is all defintions. -message("USE_WARP_FROM_NUGET: ${USE_WARP_FROM_NUGET}") -if(${USE_WARP_FROM_NUGET} STREQUAL "LATEST_RELEASE" OR ${USE_WARP_FROM_NUGET} STREQUAL "LATEST_PREVIEW") - - message("Fetching warp from nuget") - - FetchNuGetPackage(ID Microsoft.Direct3D.WARP OUTPUT_DIR ${BINARY_DIR}/temp RELEASE_TYPE ${USE_WARP_FROM_NUGET}) - - if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64") - set(ARCH "x64") - endif() - if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "X86") - set(ARCH "win32") - endif() - if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ARM64") - set(ARCH "arm64") - endif() - - set(WARP_SOURCE_PATH "${Microsoft.Direct3D.WARP_SOURCE_DIR}/build/native/bin/${ARCH}") - set(WARP_DEST_PATH "${BINARY_DIR}/${BUILD_TYPE}/bin/") - message("Copying d3d10warp.dll and d3d10warp.pdb \n" - " from: ${WARP_SOURCE_PATH}\n" - " to: ${WARP_DEST_PATH}") - file(COPY "${WARP_SOURCE_PATH}/d3d10warp.dll" - DESTINATION "${WARP_DEST_PATH}") - file(COPY "${WARP_SOURCE_PATH}/d3d10warp.pdb" - DESTINATION "${WARP_DEST_PATH}") -endif() diff --git a/include/dxc/DxilValidation/DxilValidation.h b/include/dxc/DxilValidation/DxilValidation.h index b4f49a3515..c7e413e9ef 100644 --- a/include/dxc/DxilValidation/DxilValidation.h +++ b/include/dxc/DxilValidation/DxilValidation.h @@ -81,7 +81,7 @@ class PrintDiagnosticContext { bool HasWarnings() const; void Handle(const llvm::DiagnosticInfo &DI); - static void PrintDiagnosticHandler(const llvm::DiagnosticInfo &DI, + static void PrintDiagnosticHandler(const llvm::DiagnosticInfo *DI, void *Context); }; diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h index cf04c640c3..31f4271b14 100644 --- a/include/llvm/CodeGen/MachinePassRegistry.h +++ b/include/llvm/CodeGen/MachinePassRegistry.h @@ -23,71 +23,59 @@ namespace llvm { -typedef void *(*MachinePassCtor)(); - - //===----------------------------------------------------------------------===// /// /// MachinePassRegistryListener - Listener to adds and removals of nodes in /// registration list. /// //===----------------------------------------------------------------------===// -class MachinePassRegistryListener { - virtual void anchor(); +template class MachinePassRegistryListener { + virtual void anchor() {} + public: MachinePassRegistryListener() {} virtual ~MachinePassRegistryListener() {} - virtual void NotifyAdd(const char *N, MachinePassCtor C, const char *D) = 0; + virtual void NotifyAdd(const char *N, PassCtorTy C, const char *D) = 0; virtual void NotifyRemove(const char *N) = 0; }; - //===----------------------------------------------------------------------===// /// /// MachinePassRegistryNode - Machine pass node stored in registration list. /// //===----------------------------------------------------------------------===// -class MachinePassRegistryNode { - +template class MachinePassRegistryNode { private: MachinePassRegistryNode *Next; // Next function pass in list. const char *Name; // Name of function pass. const char *Description; // Description string. - MachinePassCtor Ctor; // Function pass creator. + PassCtorTy Ctor; // Pass creator. public: - - MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C) - : Next(nullptr) - , Name(N) - , Description(D) - , Ctor(C) - {} + MachinePassRegistryNode(const char *N, const char *D, PassCtorTy C) + : Next(nullptr), Name(N), Description(D), Ctor(C) {} // Accessors MachinePassRegistryNode *getNext() const { return Next; } MachinePassRegistryNode **getNextAddress() { return &Next; } const char *getName() const { return Name; } const char *getDescription() const { return Description; } - MachinePassCtor getCtor() const { return Ctor; } - void setNext(MachinePassRegistryNode *N) { Next = N; } - + PassCtorTy getCtor() const { return Ctor; } + void setNext(MachinePassRegistryNode *N) { Next = N; } }; - //===----------------------------------------------------------------------===// /// /// MachinePassRegistry - Track the registration of machine passes. /// //===----------------------------------------------------------------------===// -class MachinePassRegistry { - +template class MachinePassRegistry { private: - - MachinePassRegistryNode *List; // List of registry nodes. - MachinePassCtor Default; // Default function pass creator. - MachinePassRegistryListener* Listener;// Listener for list adds are removes. + MachinePassRegistryNode *List; // List of registry nodes. + PassCtorTy Default; // Default function pass creator. + MachinePassRegistryListener + *Listener; // Listener for list adds are removes. public: @@ -96,32 +84,59 @@ class MachinePassRegistry { // Accessors. // - MachinePassRegistryNode *getList() { return List; } - MachinePassCtor getDefault() { return Default; } - void setDefault(MachinePassCtor C) { Default = C; } - void setDefault(StringRef Name); - void setListener(MachinePassRegistryListener *L) { Listener = L; } + MachinePassRegistryNode *getList() { return List; } + PassCtorTy getDefault() { return Default; } + void setDefault(PassCtorTy C) { Default = C; } + /// setDefault - Set the default constructor by name. + void setDefault(StringRef Name) { + PassCtorTy Ctor = nullptr; + for (MachinePassRegistryNode *R = getList(); R; + R = R->getNext()) { + if (R->getName() == Name) { + Ctor = R->getCtor(); + break; + } + } + assert(Ctor && "Unregistered pass name"); + setDefault(Ctor); + } + void setListener(MachinePassRegistryListener *L) { Listener = L; } /// Add - Adds a function pass to the registration list. /// - void Add(MachinePassRegistryNode *Node); + void Add(MachinePassRegistryNode *Node) { + Node->setNext(List); + List = Node; + if (Listener) + Listener->NotifyAdd(Node->getName(), Node->getCtor(), + Node->getDescription()); + } /// Remove - Removes a function pass from the registration list. /// - void Remove(MachinePassRegistryNode *Node); - + void Remove(MachinePassRegistryNode *Node) { + for (MachinePassRegistryNode **I = &List; *I; + I = (*I)->getNextAddress()) { + if (*I == Node) { + if (Listener) + Listener->NotifyRemove(Node->getName()); + *I = (*I)->getNext(); + break; + } + } + } }; - //===----------------------------------------------------------------------===// /// /// RegisterPassParser class - Handle the addition of new machine passes. /// -// // -/////////////////////////////////////////////////////////////////////////////// -template -class RegisterPassParser : public MachinePassRegistryListener, - public cl::parser { +//===----------------------------------------------------------------------===// +template +class RegisterPassParser + : public MachinePassRegistryListener< + typename RegistryClass::FunctionPassCtor>, + public cl::parser { public: RegisterPassParser(cl::Option &O) : cl::parser(O) {} @@ -144,15 +159,15 @@ class RegisterPassParser : public MachinePassRegistryListener, // Implement the MachinePassRegistryListener callbacks. // - void NotifyAdd(const char *N, MachinePassCtor C, const char *D) override { - this->addLiteralOption(N, (typename RegistryClass::FunctionPassCtor)C, D); + void NotifyAdd(const char *N, typename RegistryClass::FunctionPassCtor C, + const char *D) override { + this->addLiteralOption(N, C, D); } void NotifyRemove(const char *N) override { this->removeLiteralOption(N); } }; - } // end namespace llvm #endif diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index 278d84ba5a..9506023560 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -114,17 +114,19 @@ struct MachineSchedContext { /// MachineSchedRegistry provides a selection of available machine instruction /// schedulers. -class MachineSchedRegistry : public MachinePassRegistryNode { +class MachineSchedRegistry + : public MachinePassRegistryNode< + ScheduleDAGInstrs *(*)(MachineSchedContext *)> { public: typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineSchedContext *); // RegisterPassParser requires a (misnamed) FunctionPassCtor type. typedef ScheduleDAGCtor FunctionPassCtor; - static MachinePassRegistry Registry; + static MachinePassRegistry Registry; MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C) - : MachinePassRegistryNode(N, D, (MachinePassCtor)C) { + : MachinePassRegistryNode(N, D, C) { Registry.Add(this); } ~MachineSchedRegistry() { Registry.Remove(this); } @@ -137,7 +139,8 @@ class MachineSchedRegistry : public MachinePassRegistryNode { static MachineSchedRegistry *getList() { return (MachineSchedRegistry *)Registry.getList(); } - static void setListener(MachinePassRegistryListener *L) { + + static void setListener(MachinePassRegistryListener *L) { Registry.setListener(L); } }; diff --git a/include/llvm/CodeGen/RegAllocRegistry.h b/include/llvm/CodeGen/RegAllocRegistry.h index 9a639ad817..4b5b5c1e06 100644 --- a/include/llvm/CodeGen/RegAllocRegistry.h +++ b/include/llvm/CodeGen/RegAllocRegistry.h @@ -23,23 +23,19 @@ namespace llvm { /// /// RegisterRegAlloc class - Track the registration of register allocators. /// -// // -/////////////////////////////////////////////////////////////////////////////// -class RegisterRegAlloc : public MachinePassRegistryNode { - +//===----------------------------------------------------------------------===// +class RegisterRegAlloc : public MachinePassRegistryNode { public: typedef FunctionPass *(*FunctionPassCtor)(); - static MachinePassRegistry Registry; + static MachinePassRegistry Registry; RegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C) - : MachinePassRegistryNode(N, D, (MachinePassCtor)C) - { - Registry.Add(this); + : MachinePassRegistryNode(N, D, C) { + Registry.Add(this); } ~RegisterRegAlloc() { Registry.Remove(this); } - // Accessors. // @@ -49,16 +45,14 @@ class RegisterRegAlloc : public MachinePassRegistryNode { static RegisterRegAlloc *getList() { return (RegisterRegAlloc *)Registry.getList(); } - static FunctionPassCtor getDefault() { - return (FunctionPassCtor)Registry.getDefault(); - } - static void setDefault(FunctionPassCtor C) { - Registry.setDefault((MachinePassCtor)C); - } - static void setListener(MachinePassRegistryListener *L) { + + static FunctionPassCtor getDefault() { return Registry.getDefault(); } + + static void setDefault(FunctionPassCtor C) { Registry.setDefault(C); } + + static void setListener(MachinePassRegistryListener *L) { Registry.setListener(L); } - }; } // end namespace llvm diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h index e4570a8adc..02fd338e91 100644 --- a/include/llvm/CodeGen/SchedulerRegistry.h +++ b/include/llvm/CodeGen/SchedulerRegistry.h @@ -32,16 +32,19 @@ class ScheduleDAGSDNodes; class SelectionDAG; class MachineBasicBlock; -class RegisterScheduler : public MachinePassRegistryNode { +class RegisterScheduler + : public MachinePassRegistryNode< + ScheduleDAGSDNodes *(*)(SelectionDAGISel *, CodeGenOpt::Level)> { public: typedef ScheduleDAGSDNodes *(*FunctionPassCtor)(SelectionDAGISel*, CodeGenOpt::Level); - static MachinePassRegistry Registry; + static MachinePassRegistry Registry; RegisterScheduler(const char *N, const char *D, FunctionPassCtor C) - : MachinePassRegistryNode(N, D, (MachinePassCtor)C) - { Registry.Add(this); } + : MachinePassRegistryNode(N, D, C) { + Registry.Add(this); + } ~RegisterScheduler() { Registry.Remove(this); } @@ -53,13 +56,8 @@ class RegisterScheduler : public MachinePassRegistryNode { static RegisterScheduler *getList() { return (RegisterScheduler *)Registry.getList(); } - static FunctionPassCtor getDefault() { - return (FunctionPassCtor)Registry.getDefault(); - } - static void setDefault(FunctionPassCtor C) { - Registry.setDefault((MachinePassCtor)C); - } - static void setListener(MachinePassRegistryListener *L) { + + static void setListener(MachinePassRegistryListener *L) { Registry.setListener(L); } }; diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h index 0c05329774..d964b4a14e 100644 --- a/include/llvm/IR/LLVMContext.h +++ b/include/llvm/IR/LLVMContext.h @@ -83,7 +83,7 @@ class LLVMContext { /// Defines the type of a diagnostic handler. /// \see LLVMContext::setDiagnosticHandler. /// \see LLVMContext::diagnose. - typedef void (*DiagnosticHandlerTy)(const DiagnosticInfo &DI, void *Context); + typedef void (*DiagnosticHandlerTy)(const DiagnosticInfo *DI, void *Context); /// Defines the type of a yield callback. /// \see LLVMContext::setYieldCallback. diff --git a/lib/CodeGen/MachinePassRegistry.cpp b/lib/CodeGen/MachinePassRegistry.cpp index 3ee3e40b27..82daf80a87 100644 --- a/lib/CodeGen/MachinePassRegistry.cpp +++ b/lib/CodeGen/MachinePassRegistry.cpp @@ -15,41 +15,3 @@ #include "llvm/CodeGen/MachinePassRegistry.h" using namespace llvm; - -void MachinePassRegistryListener::anchor() { } - -/// setDefault - Set the default constructor by name. -void MachinePassRegistry::setDefault(StringRef Name) { - MachinePassCtor Ctor = nullptr; - for(MachinePassRegistryNode *R = getList(); R; R = R->getNext()) { - if (R->getName() == Name) { - Ctor = R->getCtor(); - break; - } - } - assert(Ctor && "Unregistered pass name"); - setDefault(Ctor); -} - -/// Add - Adds a function pass to the registration list. -/// -void MachinePassRegistry::Add(MachinePassRegistryNode *Node) { - Node->setNext(List); - List = Node; - if (Listener) Listener->NotifyAdd(Node->getName(), - Node->getCtor(), - Node->getDescription()); -} - - -/// Remove - Removes a function pass from the registration list. -/// -void MachinePassRegistry::Remove(MachinePassRegistryNode *Node) { - for (MachinePassRegistryNode **I = &List; *I; I = (*I)->getNextAddress()) { - if (*I == Node) { - if (Listener) Listener->NotifyRemove(Node->getName()); - *I = (*I)->getNext(); - break; - } - } -} diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index a48e54caf3..b40e381e5c 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -190,7 +190,8 @@ void PostMachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } -MachinePassRegistry MachineSchedRegistry::Registry; +MachinePassRegistry + MachineSchedRegistry::Registry; /// A dummy default scheduler factory indicates whether the scheduler /// is overridden on the command line. diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index 024d166a49..3159fbd5a0 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -648,7 +648,8 @@ bool TargetPassConfig::getOptimizeRegAlloc() const { } /// RegisterRegAlloc's global Registry tracks allocator registration. -MachinePassRegistry RegisterRegAlloc::Registry; +MachinePassRegistry + RegisterRegAlloc::Registry; /// A dummy default pass factory indicates whether the register allocator is /// overridden on the command line. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 97ece8b924..6ac04cadd9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -228,7 +228,8 @@ static const bool ViewDAGCombine1 = false, /// RegisterScheduler class - Track the registration of instruction schedulers. /// //===---------------------------------------------------------------------===// -MachinePassRegistry RegisterScheduler::Registry; +MachinePassRegistry + RegisterScheduler::Registry; //===---------------------------------------------------------------------===// /// diff --git a/lib/DxilValidation/DxilValidation.cpp b/lib/DxilValidation/DxilValidation.cpp index 9587897e22..16f377edcd 100644 --- a/lib/DxilValidation/DxilValidation.cpp +++ b/lib/DxilValidation/DxilValidation.cpp @@ -85,9 +85,9 @@ void PrintDiagnosticContext::Handle(const DiagnosticInfo &DI) { m_Printer << "\n"; } -void PrintDiagnosticContext::PrintDiagnosticHandler(const DiagnosticInfo &DI, +void PrintDiagnosticContext::PrintDiagnosticHandler(const DiagnosticInfo *DI, void *Context) { - reinterpret_cast(Context)->Handle(DI); + reinterpret_cast(Context)->Handle(*DI); } struct PSExecutionInfo { diff --git a/lib/IR/LLVMContext.cpp b/lib/IR/LLVMContext.cpp index 0e4a11e11a..177129218f 100644 --- a/lib/IR/LLVMContext.cpp +++ b/lib/IR/LLVMContext.cpp @@ -227,7 +227,7 @@ void LLVMContext::diagnose(const DiagnosticInfo &DI) { // If there is a report handler, use it. if (pImpl->DiagnosticHandler) { if (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) - pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext); + pImpl->DiagnosticHandler(&DI, pImpl->DiagnosticContext); return; } diff --git a/tools/clang/lib/CodeGen/CodeGenAction.cpp b/tools/clang/lib/CodeGen/CodeGenAction.cpp index d8339f25b3..7c11771f33 100644 --- a/tools/clang/lib/CodeGen/CodeGenAction.cpp +++ b/tools/clang/lib/CodeGen/CodeGenAction.cpp @@ -238,9 +238,9 @@ namespace clang { void linkerDiagnosticHandler(const llvm::DiagnosticInfo &DI); - static void DiagnosticHandler(const llvm::DiagnosticInfo &DI, + static void DiagnosticHandler(const llvm::DiagnosticInfo *DI, void *Context) { - ((BackendConsumer *)Context)->DiagnosticHandlerImpl(DI); + ((BackendConsumer *)Context)->DiagnosticHandlerImpl(*DI); } void InlineAsmDiagHandler2(const llvm::SMDiagnostic &, diff --git a/tools/clang/test/CMakeLists.txt b/tools/clang/test/CMakeLists.txt index 6b0aa32fbc..3035d344b0 100644 --- a/tools/clang/test/CMakeLists.txt +++ b/tools/clang/test/CMakeLists.txt @@ -26,6 +26,12 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/taef/lit.site.cfg ) +# HLSL Change begin +# This must be done before configuring taef_exec's lit.site.cfg. +include(taef_exec/DownloadWarp.cmake) +# HLSL Change end + + configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/taef_exec/lit.site.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/taef_exec/lit.site.cfg @@ -122,54 +128,40 @@ add_lit_testsuites(CLANG ${CMAKE_CURRENT_SOURCE_DIR} FOLDER "Clang tests/Suites" ) -# Manually generate targets that we need to expose in visual studio builds. - -# The code below here _ONLY_ executes when building with Visual Studio or Xcode. -if (NOT CMAKE_CONFIGURATION_TYPES) - return() -endif() -# Add the unit test suite -add_lit_target("check-clang-unit" "Running lit suite clang-unit" - ${CMAKE_CURRENT_SOURCE_DIR}/Unit - PARAMS ${CLANG_TEST_PARAMS} - DEPENDS ClangUnitTests - ARGS ${CLANG_TEST_EXTRA_ARGS} - ) +# add_lit_testsuites doesn't generate targets for Visual Studio or Xcode builds +# (since these IDEs cannot handle the huge number of targets it generates). +# +# We must manually generate targets that we want to expose when using these +# generators. +if(CMAKE_CONFIGURATION_TYPES) -# Add TAEF targets -if (WIN32) - add_lit_target("check-clang-taef" "Running lit suite hlsl" - ${CMAKE_CURRENT_SOURCE_DIR}/taef - PARAMS ${CLANG_TEST_PARAMS} - DEPENDS ClangHLSLTests - ARGS ${CLANG_TEST_EXTRA_ARGS} - ) - set(TAEF_EXEC_ADAPTER "" CACHE STRING "adapter for taef exec test") - - # Use a custom target so we can depend on it and re-run the cmake logic which downloads warp - # from nuget if requested. - add_custom_target(WarpFromNuget - COMMAND "${CMAKE_COMMAND}" - -DCMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR} - -DBUILD_TYPE=${CMAKE_BUILD_TYPE} - -DBINARY_DIR=${CMAKE_BINARY_DIR} - -P "${CMAKE_SOURCE_DIR}/cmake/modules/nuget.cmake") - - add_lit_target("check-clang-taef-exec" "Running lit suite hlsl execution test" - ${CMAKE_CURRENT_SOURCE_DIR}/taef_exec + # Add the unit test suite + add_lit_target("check-clang-unit" "Running lit suite clang-unit" + ${CMAKE_CURRENT_SOURCE_DIR}/Unit PARAMS ${CLANG_TEST_PARAMS} - adapter=${TAEF_EXEC_ADAPTER} - DEPENDS ExecHLSLTests dxexp + DEPENDS ClangUnitTests ARGS ${CLANG_TEST_EXTRA_ARGS} ) - add_lit_target("check-clang-taef-exec-warp" "Running lit suite hlsl execution test with D3D WARP from nuget" - ${CMAKE_CURRENT_SOURCE_DIR}/taef_exec - PARAMS ${CLANG_TEST_PARAMS} - adapter=${TAEF_EXEC_ADAPTER} - DEPENDS ExecHLSLTests dxexp WarpFromNuget - ARGS ${CLANG_TEST_EXTRA_ARGS} - ) + # Add TAEF targets + if(WIN32) + add_lit_target("check-clang-taef" "Running lit suite hlsl" + ${CMAKE_CURRENT_SOURCE_DIR}/taef + PARAMS ${CLANG_TEST_PARAMS} + DEPENDS ClangHLSLTests + ARGS ${CLANG_TEST_EXTRA_ARGS} + ) + set(TAEF_EXEC_ADAPTER "" CACHE STRING "adapter for taef exec test") + + add_lit_target("check-clang-taef-exec" "Running lit suite hlsl execution test" + ${CMAKE_CURRENT_SOURCE_DIR}/taef_exec + PARAMS ${CLANG_TEST_PARAMS} + adapter=${TAEF_EXEC_ADAPTER} + DEPENDS ExecHLSLTests dxexp + ARGS ${CLANG_TEST_EXTRA_ARGS} + ) + endif() endif() + # HLSL Change End diff --git a/tools/clang/test/taef_exec/DownloadWarp.cmake b/tools/clang/test/taef_exec/DownloadWarp.cmake new file mode 100644 index 0000000000..c89f66ae88 --- /dev/null +++ b/tools/clang/test/taef_exec/DownloadWarp.cmake @@ -0,0 +1,97 @@ +include_guard(GLOBAL) + +# This script is run at configure time to install the latest WARP. + +if(NOT WIN32) + # WARP is only a thing on Win32 + return() +endif() + + +# +# At runtime, the Execution Tests look at the WARP_DLL runtime parameter to +# decide which DLL to use. When USE_NUGET_WARP is set to true, this will +# configure the tests by default to use the DLL from the installed nuget +# package. + +set(USE_NUGET_WARP TRUE CACHE BOOL + "Whether or not to use WARP from the Microsoft.Direct3D.WARP nuget package") + +# The NUGET_WARP_EXTRA_ARGS cmake variable can be use to specify additional +# arguments to the nuget.exe command line. For example, to install a specific +# version of WARP, set NUGET_WARP_EXTRA_ARGS to "-Version 1.0.13". +set(NUGET_WARP_EXTRA_ARGS "" CACHE STRING + "Extra arguments to pass to nuget.exe when installing Microsoft.Direct3D.WARP.") + +if(NOT USE_NUGET_WARP) + message(STATUS "Using OS version of WARP") + return() +endif() + +function(InstallWarpFailure) + message(FATAL_ERROR "Unable to install WARP nuget package. Set USE_NUGET_WARP to FALSE to use OS version of WARP.") +endfunction() + +find_program(NUGET_EXE nuget.exe HINTS ${CMAKE_BINARY_DIR}/nuget) +if(NOT NUGET_EXE) + message(STATUS "nuget.exe not found in, download nuget.exe to ${CMAKE_BINARY_DIR}/nuget/nuget.exe...") + file(DOWNLOAD + https://dist.nuget.org/win-x86-commandline/latest/nuget.exe + ${CMAKE_BINARY_DIR}/nuget/nuget.exe + ) + find_program(NUGET_EXE nuget.exe HINTS ${CMAKE_BINARY_DIR}/nuget) + if(NOT NUGET_EXE) + message(SEND_ERROR "nuget.exe not found in ${CMAKE_BINARY_DIR}/nuget/nuget.exe") + InstallWarpFailure() + endif() +endif() + +# Install the WARP nuget package. + +# NUGET_WARP_EXTRA_ARGS gets passed as a single command-line argument. In cmake, +# lists are items separated by semicolons, so these will become separate +# arguments. +if(NUGET_WARP_EXTRA_ARGS) + string(REPLACE " " ";" NUGET_WARP_EXTRA_ARGS_LIST ${NUGET_WARP_EXTRA_ARGS}) +endif() + +execute_process( + COMMAND ${NUGET_EXE} install -ForceEnglishOutput Microsoft.Direct3D.WARP -OutputDirectory ${CMAKE_BINARY_DIR}/nuget ${NUGET_WARP_EXTRA_ARGS_LIST} + RESULT_VARIABLE result + OUTPUT_VARIABLE nuget_output + ERROR_VARIABLE nuget_output) + +if(NOT result EQUAL 0) + message(SEND_ERROR "nuget install Microsoft.Direct3D.WARP failed with exit code ${result}.\n${nuget_output}") + InstallWarpFailure() +endif() + +string(REGEX MATCH "Package \"(Microsoft.Direct3D.WARP..+)\" is already installed" IGNORED_OUTPUT ${nuget_output}) +if(CMAKE_MATCH_1) + set(WARP_PACKAGE ${CMAKE_MATCH_1}) +else() + string(REGEX MATCH "Added package '(Microsoft.Direct3D.WARP..+)' to folder" IGNORED_OUTPUT ${nuget_output}) + if(CMAKE_MATCH_1) + set(WARP_PACKAGE ${CMAKE_MATCH_1}) + else() + message(SEND_ERROR "Failed to find package install named in nuget output:\n ${nuget_output}") + InstallWarpFailure() + endif() +endif() + +set(WARP_DIR ${CMAKE_BINARY_DIR}/nuget/${WARP_PACKAGE}) + +if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64") + set(WARP_ARCH "x64") +endif() +if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "X86") + set(WARP_ARCH "win32") +endif() +if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ARM64") + set(WARP_ARCH "arm64") +endif() + +# WARP_DLL is picked up by lit.site.cfg.in so it can be passed as a TAEF runtime +# parameter by lit.cfg +set(WARP_DLL ${WARP_DIR}/build/native/bin/${WARP_ARCH}/d3d10warp.dll) + diff --git a/tools/clang/test/taef_exec/lit.cfg b/tools/clang/test/taef_exec/lit.cfg index 98d50824c5..9685da6711 100644 --- a/tools/clang/test/taef_exec/lit.cfg +++ b/tools/clang/test/taef_exec/lit.cfg @@ -70,6 +70,12 @@ if config.unsupported == False: extra_params.append('/p:') extra_params.append('D3D12SDKVersion=1') + warp_dll = getattr(config, 'warp_dll', None) + if warp_dll: + extra_params.append('/p:') + extra_params.append(f'WARP_DLL={warp_dll}') + print(f"Using WARP from {warp_dll}\n") + # use ';' to split multiple params. taef_extra_params = lit_config.params.get('taef_exec_extra_params', None) if taef_extra_params: diff --git a/tools/clang/test/taef_exec/lit.site.cfg.in b/tools/clang/test/taef_exec/lit.site.cfg.in index d4d914ead9..d987a82d07 100644 --- a/tools/clang/test/taef_exec/lit.site.cfg.in +++ b/tools/clang/test/taef_exec/lit.site.cfg.in @@ -7,6 +7,7 @@ config.llvm_obj_root = "@LLVM_BINARY_DIR@" config.llvm_build_mode = "@LLVM_BUILD_MODE@" config.te = "@TAEF_EXECUTABLE@" config.taef_arch = "@TAEF_ARCH@" +config.warp_dll = "@WARP_DLL@" config.verbose = True # Support substitution of the tools_dir, libs_dirs, and build_mode with user diff --git a/tools/clang/unittests/HLSLExec/ExecutionTest.cpp b/tools/clang/unittests/HLSLExec/ExecutionTest.cpp index 6db27d7a41..99b2324ba0 100644 --- a/tools/clang/unittests/HLSLExec/ExecutionTest.cpp +++ b/tools/clang/unittests/HLSLExec/ExecutionTest.cpp @@ -806,6 +806,34 @@ class ExecutionTest { VERIFY_SUCCEEDED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))); if (GetTestParamUseWARP(UseWarpByDefault())) { + // The WARP_DLL runtime parameter can be used to specify a specific DLL to + // load. To force this to be used, we make sure that this DLL is loaded + // before attempting to create the device. + + struct WarpDll { + HMODULE Module = NULL; + + ~WarpDll() { Close(); } + + void Close() { + if (Module) { + FreeLibrary(Module); + Module = NULL; + } + } + }; + + WarpDll ExplicitlyLoadedWarpDll; + WEX::Common::String WarpDllPath; + if (SUCCEEDED(WEX::TestExecution::RuntimeParameters::TryGetValue( + L"WARP_DLL", WarpDllPath))) { + WEX::Logging::Log::Comment(WEX::Common::String().Format( + L"WARP_DLL requested: %ls", (const wchar_t *)WarpDllPath)); + ExplicitlyLoadedWarpDll.Module = LoadLibraryExW(WarpDllPath, NULL, 0); + VERIFY_WIN32_BOOL_SUCCEEDED(!!ExplicitlyLoadedWarpDll.Module); + } + + // Create the WARP device CComPtr warpAdapter; VERIFY_SUCCEEDED(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter))); HRESULT createHR = D3D12CreateDevice(warpAdapter, D3D_FEATURE_LEVEL_11_0, @@ -820,6 +848,12 @@ class ExecutionTest { return false; } + // Now that the WARP device is created we can release our reference to the + // warp dll. + ExplicitlyLoadedWarpDll.Close(); + + // Log the actual version of WARP that's loaded so we can be sure that + // we're using the version we think. if (GetModuleHandleW(L"d3d10warp.dll") != NULL) { WCHAR szFullModuleFilePath[MAX_PATH] = L""; GetModuleFileNameW(GetModuleHandleW(L"d3d10warp.dll"), diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index 6e54671002..36e432a3b3 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -115,10 +115,10 @@ class CommentWriter : public AssemblyAnnotationWriter { } // end anon namespace -static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { +static void diagnosticHandler(const DiagnosticInfo *DI, void *Context) { raw_ostream &OS = errs(); OS << (char *)Context << ": "; - switch (DI.getSeverity()) { + switch (DI->getSeverity()) { case DS_Error: OS << "error: "; break; case DS_Warning: OS << "warning: "; break; case DS_Remark: OS << "remark: "; break; @@ -126,10 +126,10 @@ static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { } DiagnosticPrinterRawOStream DP(OS); - DI.print(DP); + DI->print(DP); OS << '\n'; - if (DI.getSeverity() == DS_Error) + if (DI->getSeverity() == DS_Error) exit(1); } diff --git a/utils/hct/hctbuild.cmd b/utils/hct/hctbuild.cmd index ff6dbfa22a..8fe08a02c6 100644 --- a/utils/hct/hctbuild.cmd +++ b/utils/hct/hctbuild.cmd @@ -47,6 +47,7 @@ set INSTALL_DIR= set DEFAULT_EXEC_ADAPTER=-DTAEF_EXEC_ADAPTER= set LIT_ARGS= set FRESH= +set NUGET_WARP_EXTRA_ARGS= :parse_args if "%1"=="" ( @@ -213,6 +214,11 @@ if "%1"=="-fresh" ( set FRESH="--fresh" shift /1 & goto :parse_args ) +if "%1"=="-nuget-config" ( + set NUGET_WARP_EXTRA_ARGS="-Config %~2" + shift /1 + shift /1 & goto :parse_args +) rem Begin SPIRV change @@ -354,6 +360,8 @@ set CMAKE_OPTS=%CMAKE_OPTS% -DCLANG_CL:BOOL=OFF set CMAKE_OPTS=%CMAKE_OPTS% -DCMAKE_SYSTEM_VERSION=%DXC_CMAKE_SYSTEM_VERSION% set CMAKE_OPTS=%CMAKE_OPTS% -DCMAKE_INSTALL_PREFIX=%INSTALL_DIR% +set CMAKE_OPTS=%CMAKE_OPTS% -DNUGET_WARP_EXTRA_ARGS=%NUGET_WARP_EXTRA_ARGS% + if "%LIT_ARGS%" NEQ "" ( set CMAKE_OPTS=%CMAKE_OPTS% -DLLVM_LIT_ARGS="%LIT_ARGS%" ) diff --git a/utils/hct/hcttest.cmd b/utils/hct/hcttest.cmd index 3e536d199f..b9e05ce524 100644 --- a/utils/hct/hcttest.cmd +++ b/utils/hct/hcttest.cmd @@ -37,7 +37,6 @@ set TEST_MANUAL_FILE_CHECK=0 set SINGLE_FILE_CHECK_NAME=0 set CUSTOM_BIN_SET= set USE_AGILITY_SDK= -set USE_WARP_FROM_NUGET= set EXEC_TEST_TARGET="check-clang-taef-exec" rem Begin SPIRV change @@ -134,22 +133,6 @@ if "%1"=="-clean" ( set TEST_ALL=0 set TEST_EXEC=1 set TEST_EXEC_REQUIRED=1 -) else if "%1"=="exec-warp" ( - rem If exec-warp is explicitly supplied, hcttest will fail if machine is not configured - rem to run execution tests, otherwise, execution tests would be skipped. - set TEST_ALL=0 - set TEST_EXEC=1 - set USE_WARP_FROM_NUGET=LATEST_RELEASE - set TEST_EXEC_REQUIRED=1 - set EXEC_TEST_TARGET="check-clang-taef-exec-warp" -) else if "%1"=="exec-warp-preview" ( - rem If exec-warp-preview is explicitly supplied, hcttest will fail if machine is not configured - rem to run execution tests, otherwise, execution tests would be skipped. - set TEST_ALL=0 - set TEST_EXEC=1 - set USE_WARP_FROM_NUGET=LATEST_PREVIEW - set TEST_EXEC_REQUIRED=1 - set EXEC_TEST_TARGET="check-clang-taef-exec-warp" ) else if "%1"=="exec-filter" ( set TEST_ALL=0 set TEST_EXEC=1