[macos-port] Allow dxc and tests to run on mac (#1383)

The REGEX_H define prevented the inclusion of an Apple system header.
Not coincidentally, the same header regex_impl.h was derived from.

Prevent Apple warning by splitting macro args with an #else. Add HLSL
change comments too which were missing from the start.

Search for libdxcompiler.dylib instead of .so on Apple.

MacOS resolves symbols differently from Linux. Linux takes the first
valid resolution and then uses it wherever it is referenced. MacOS
more similar to Windows, favors symbols that are local to the
compilation unit.

This comes into play where functions set static globals such as
the malloc tls and the IMalloc contained there. The dxc binary
initializes these. For Linux, that's enough because all calls
resolve to the ones from this binary because they are encountered
first. MacOS calls that originate from within the dynamic library
resolve to the local functions, which don't have their globals
initialized. To initialize them, we need to do what is done in
DLLMain in DXCompiler.cpp.

Performing these calls results in duplicate initializations on Linux
unless the calls in question are given visibility hidden. This is
the default on Windows, but not on Unix OSes.
This commit is contained in:
Greg Roth 2018-06-27 11:42:23 -06:00 коммит произвёл Ehsan
Родитель eaff1735d0
Коммит eacaf5a58c
6 изменённых файлов: 40 добавлений и 19 удалений

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

@ -60,8 +60,6 @@ IMalloc *DxcSwapThreadMallocOrDefault(IMalloc *pMalloc, IMalloc **ppPrior) throw
// Used to retrieve the current invocation's allocator or perform an alloc/free/realloc.
IMalloc *DxcGetThreadMallocNoRef() throw();
_Ret_maybenull_ _Post_writable_byte_size_(nBytes) void *DxcThreadAlloc(size_t nBytes) throw();
void DxcThreadFree(void *) throw();
struct DxcThreadMalloc {
DxcThreadMalloc(IMalloc *pMallocOrNull) throw() {

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

@ -49,6 +49,10 @@ namespace {
static HlslOptTable *g_HlslOptTable;
#ifndef _WIN32
#pragma GCC visibility push(hidden)
#endif
std::error_code hlsl::options::initHlslOptTable() {
DXASSERT(g_HlslOptTable == nullptr, "else double-init");
g_HlslOptTable = new (std::nothrow) HlslOptTable();
@ -66,6 +70,10 @@ const OptTable * hlsl::options::getHlslOptTable() {
return g_HlslOptTable;
}
#ifndef _WIN32
#pragma GCC visibility pop
#endif
void DxcDefines::push_back(llvm::StringRef value) {
// Skip empty defines.
if (value.size() > 0) {

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

@ -21,19 +21,9 @@
static llvm::sys::ThreadLocal<IMalloc> *g_ThreadMallocTls;
static IMalloc *g_pDefaultMalloc;
// Used by DllMain to set up and tear down per-thread tracking.
HRESULT DxcInitThreadMalloc() throw();
void DxcCleanupThreadMalloc() throw();
// Used by APIs that are entry points to set up per-thread/invocation allocator.
void DxcSetThreadMalloc(IMalloc *pMalloc) throw();
void DxcSetThreadMallocOrDefault(IMalloc *pMalloc) throw();
void DxcClearThreadMalloc() throw();
// Used to retrieve the current invocation's allocator or perform an alloc/free/realloc.
IMalloc *DxcGetThreadMallocNoRef() throw();
_Ret_maybenull_ _Post_writable_byte_size_(nBytes) void *DxcThreadAlloc(size_t nBytes) throw();
void DxcThreadFree(void *) throw();
#ifndef _WIN32
#pragma GCC visibility push(hidden)
#endif
HRESULT DxcInitThreadMalloc() throw() {
DXASSERT(g_pDefaultMalloc == nullptr, "else InitThreadMalloc already called");
@ -96,3 +86,7 @@ IMalloc *DxcSwapThreadMalloc(IMalloc *pMalloc, IMalloc **ppPrior) throw() {
IMalloc *DxcSwapThreadMallocOrDefault(IMalloc *pMallocOrNull, IMalloc **ppPrior) throw() {
return DxcSwapThreadMalloc(pMallocOrNull ? pMallocOrNull : g_pDefaultMalloc, ppPrior);
}
#ifndef _WIN32
#pragma GCC visibility pop
#endif

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

@ -108,12 +108,15 @@ llvm_regerror(int errcode, const llvm_regex_t *preg, _Out_writes_all_(errbuf_siz
assert(strlen(r->name) < sizeof(convbuf));
(void) llvm_strlcpy(convbuf, r->name, sizeof convbuf);
} else
// Begin HLSL Change
#ifdef _WIN32
(void)_snprintf_s(convbuf, _countof(convbuf), _countof(convbuf),
"REG_0x%x", target);
#else
(void)snprintf(convbuf, sizeof convbuf,
#endif // WIN32
"REG_0x%x", target);
#endif // WIN32
// End HLSL Change
s = convbuf;
} else
s = r->explain;

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

@ -35,8 +35,8 @@
* @(#)regex.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _REGEX_H_
#define _REGEX_H_
#ifndef _REGEX_IMPL_H_ // HLSL Change
#define _REGEX_IMPL_H_ // HLSL Change
#include "dxc/Support/WinAdapter.h" // HLSL Change
#include <sys/types.h>
@ -119,4 +119,4 @@ size_t llvm_strlcpy(
}
#endif
#endif /* !_REGEX_H_ */
#endif /* !_REGEX_IMPL_H_ */ // HLSL Change

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

@ -14,7 +14,9 @@
#include "dxc/Support/Global.h"
#include "dxc/Support/WinIncludes.h"
#include "dxc/Support/HLSLOptions.h"
#ifdef LLVM_ON_WIN32
#include "dxcetw.h"
#endif
#include "dxillib.h"
namespace hlsl { HRESULT SetupRegistryPassForHLSL(); }
@ -22,6 +24,7 @@ namespace hlsl { HRESULT SetupRegistryPassForHLSL(); }
// C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#pragma warning( disable : 4290 )
#ifdef LLVM_ON_WIN32
// operator new and friends.
void * __CRTDECL operator new(std::size_t size) throw(std::bad_alloc) {
void * ptr = DxcGetThreadMallocNoRef()->Alloc(size);
@ -39,6 +42,7 @@ void __CRTDECL operator delete (void* ptr) throw() {
void __CRTDECL operator delete (void* ptr, const std::nothrow_t& nothrow_constant) throw() {
DxcGetThreadMallocNoRef()->Free(ptr);
}
#endif
static HRESULT InitMaybeFail() throw() {
HRESULT hr;
@ -72,7 +76,20 @@ Cleanup:
}
return hr;
}
#if defined(LLVM_ON_UNIX)
HRESULT __attribute__ ((constructor)) DllMain() {
return InitMaybeFail();
}
void __attribute__ ((destructor)) DllShutdown() {
DxcSetThreadMallocOrDefault(nullptr);
::hlsl::options::cleanupHlslOptTable();
::llvm::sys::fs::CleanupPerThreadFileSystem();
::llvm::llvm_shutdown();
DxcClearThreadMalloc();
DxcCleanupThreadMalloc();
}
#else // LLVM_ON_UNIX
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD Reason, LPVOID reserved) {
BOOL result = TRUE;
if (Reason == DLL_PROCESS_ATTACH) {
@ -102,3 +119,4 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD Reason, LPVOID reserved) {
return result;
}
#endif // LLVM_ON_UNIX