Skip to content

Commit ff2ae7e

Browse files
authored
Improvements around Visual Studio versions/matching versions (shader-slang#2267)
* #include an absolute path didn't work - because paths were taken to always be relative. * Use TerminatedUnownedStringSlice for literals in output C++. * Remove Escape/Unescape functions used in slang-token-reader.cpp Add target type of 'host-cpp' etc to map to the target types. * Fix some corner cases around string encoding. * Added unit test for string escaping. Fixed some assorted escaping bugs. * Updated test output. * Added decode test. * Stop using hex output, to get around 'greedy' aspect. Use octal instead. * Added HostHostCallable Small changes to use ArtifactDesc/Info instead of large switches. * Fix C++ emit to handle arbitrary function export. * Add options handling for callable without an output being specified. * Can compile with COM interface. Added example using com interface. * Use the IR Ptr type instead of hack in C++ emit for interfaces. * Fix issue with outputting the COM call when ptr is used. * Fix crash issue on compilation failure. * Add support for __global. * Added `ActualGlobalRate` Added special handling around globals and COM interfaces. Tested out in cpu-com-example. * Fix typo in NodeBase. * Support for accessing globals by name working. * Check that actual global initialization is working. * Refactor the com replacement such that it doesn't need a cache or do anything special with GlobalVar. * Remove context. Only create replacement if needed. * Split out COM host-callable into a unit-test. * host-callable com testing on C++and llvm. * Comment around the COM ptr replacement. * Disable com test on vs 32 bit. Fix C++ prelude * Disable 32 bit targets testing com host-callable. * Use JSON parsing to locate VS version. * Need platform detection in C++prelude. * Fix com host callable test for LLVM. * WIP improments finding downstream compiler version. * Work around for not being able to include "targetConditionals.h" * Matching semantic versioning support. * DownstreamMatchVersion -> DownstreamCompilerMatchVersion Small improvements.
1 parent 8e6e884 commit ff2ae7e

6 files changed

+546
-259
lines changed

source/compiler-core/slang-downstream-compiler.cpp

+81-51
Original file line numberDiff line numberDiff line change
@@ -519,34 +519,32 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio
519519

520520
/* !!!!!!!!!!!!!!!!!!!!!!!!! DownstreamCompiler::Desc !!!!!!!!!!!!!!!!!!!!!!*/
521521

522-
static DownstreamCompiler::Desc _calcCompiledWithDesc()
522+
static DownstreamCompilerMatchVersion _calcCompiledVersion()
523523
{
524-
DownstreamCompiler::Desc desc;
524+
DownstreamCompilerMatchVersion matchVersion;
525525

526526
#if SLANG_VC
527-
desc = WinVisualStudioUtil::getDesc(WinVisualStudioUtil::getCompiledVersion());
527+
matchVersion = WinVisualStudioUtil::getCompiledVersion();
528528
#elif SLANG_CLANG
529-
desc.type = SLANG_PASS_THROUGH_CLANG;
530-
desc.majorVersion = Int(__clang_major__);
531-
desc.minorVersion = Int(__clang_minor__);
529+
matchVersion.type = SLANG_PASS_THROUGH_CLANG;
530+
matchVersion.matchVersion.set(Index(__clang_major__), Index(__clang_minor__));
532531
#elif SLANG_GCC
533-
desc.type = SLANG_PASS_THROUGH_GCC;
534-
desc.majorVersion = Int(__GNUC__);
535-
desc.minorVersion = Int(__GNUC_MINOR__);
532+
matchVersion.type = SLANG_PASS_THROUGH_GCC;
533+
matchVersion.matchVersion.set(Index(__GNUC__), Index(__GNUC_MINOR__));
536534
#else
537535
// TODO(JS): Hmmm None is not quite the same as unknown. It works for now, but we might want to have a distinct enum for unknown.
538-
desc.type = SLANG_PASS_THROUGH_NONE;
536+
matchVersion.type = SLANG_PASS_THROUGH_NONE;
539537
#endif
540538

541-
return desc;
539+
return matchVersion;
542540
}
543541

544542
/* !!!!!!!!!!!!!!!!!!!!!!!!! DownstreamCompilerUtil !!!!!!!!!!!!!!!!!!!!!!*/
545543

546-
const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
544+
DownstreamCompilerMatchVersion DownstreamCompilerUtil::getCompiledVersion()
547545
{
548-
static DownstreamCompiler::Desc s_desc = _calcCompiledWithDesc();
549-
return s_desc;
546+
static DownstreamCompilerMatchVersion s_version = _calcCompiledVersion();
547+
return s_version;
550548
}
551549

552550
/* static */DownstreamCompiler* DownstreamCompilerUtil::findCompiler(const DownstreamCompilerSet* set, MatchType matchType, const DownstreamCompiler::Desc& desc)
@@ -626,22 +624,70 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
626624
return (bestIndex >= 0) ? compilers[bestIndex] : nullptr;
627625
}
628626

629-
/* static */DownstreamCompiler* DownstreamCompilerUtil::findClosestCompiler(const List<DownstreamCompiler*>& compilers, const DownstreamCompiler::Desc& desc)
627+
/* static */DownstreamCompiler* DownstreamCompilerUtil::findCompiler(const List<DownstreamCompiler*>& compilers, const DownstreamCompiler::Desc& desc)
630628
{
631-
DownstreamCompiler* compiler;
629+
for (auto compiler : compilers)
630+
{
631+
if (compiler->getDesc() == desc)
632+
{
633+
return compiler;
634+
}
635+
}
636+
return nullptr;
637+
}
632638

633-
compiler = findCompiler(compilers, MatchType::MinGreaterEqual, desc);
634-
if (compiler)
639+
/* static */DownstreamCompiler* DownstreamCompilerUtil::findCompiler(const List<DownstreamCompiler*>& compilers, SlangPassThrough type, const SemanticVersion& version)
640+
{
641+
DownstreamCompiler::Desc desc;
642+
desc.type = type;
643+
desc.majorVersion = version.m_major;
644+
desc.minorVersion = version.m_minor;
645+
return findCompiler(compilers, desc);
646+
}
647+
648+
/* static */void DownstreamCompilerUtil::findVersions(const List<DownstreamCompiler*>& compilers, SlangPassThrough type, List<SemanticVersion>& outVersions)
649+
{
650+
for (auto compiler : compilers)
635651
{
636-
return compiler;
652+
auto desc = compiler->getDesc();
653+
654+
if (desc.type == type)
655+
{
656+
outVersions.add(SemanticVersion(int(desc.majorVersion), int(desc.minorVersion), 0));
657+
}
637658
}
638-
compiler = findCompiler(compilers, MatchType::MinAbsolute, desc);
639-
if (compiler)
659+
}
660+
661+
/* static */DownstreamCompiler* DownstreamCompilerUtil::findClosestCompiler(const List<DownstreamCompiler*>& compilers, const DownstreamCompilerMatchVersion& matchVersion)
662+
{
663+
List<SemanticVersion> versions;
664+
665+
findVersions(compilers, matchVersion.type, versions);
666+
667+
if (versions.getCount() > 0)
640668
{
641-
return compiler;
669+
if (versions.getCount() == 1)
670+
{
671+
// Must be that one
672+
return findCompiler(compilers, matchVersion.type, versions[0]);
673+
}
674+
675+
// Okay lets find the best one
676+
auto bestVersion = MatchSemanticVersion::findAnyBest(versions.getBuffer(), versions.getCount(), matchVersion.matchVersion);
677+
678+
// If one is found use it
679+
if (bestVersion.isSet())
680+
{
681+
return findCompiler(compilers, matchVersion.type, bestVersion);
682+
}
642683
}
643684

644685
{
686+
// TODO(JS):
687+
// NOTE! This may not really be appropriate, because LLVM is *not* interchangable with
688+
// a 'normal' C++ compiler as cannot access standard libraries/headers.
689+
// So `slang-llvm` can't be used for 'host' code.
690+
645691
// These compilers should be usable interchangably. The order is important, as the first one that matches will
646692
// be used, so LLVM is used before CLANG or GCC if appropriate
647693
const SlangPassThrough compatiblePassThroughs[] =
@@ -651,31 +697,20 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
651697
SLANG_PASS_THROUGH_GCC,
652698
};
653699

654-
bool isCompatible = false;
655-
for (auto passThrough : compatiblePassThroughs)
656-
{
657-
if (desc.type == passThrough)
658-
{
659-
isCompatible = true;
660-
break;
661-
}
662-
}
663-
664-
if (isCompatible)
700+
// Check the version is one of the compatible types
701+
if (makeConstArrayView(compatiblePassThroughs).indexOf(matchVersion.type) >= 0)
665702
{
703+
// Try each compatible type in turn
666704
for (auto passThrough : compatiblePassThroughs)
667705
{
668-
if (passThrough != desc.type)
706+
versions.clear();
707+
findVersions(compilers, passThrough, versions);
708+
709+
if (versions.getCount() > 0)
669710
{
670-
DownstreamCompiler::Desc compatible;
671-
672-
compatible.type = passThrough;
673-
// Find the latest version.
674-
compiler = findCompiler(compilers, MatchType::Newest, compatible);
675-
if (compiler)
676-
{
677-
return compiler;
678-
}
711+
// Get the latest version (as we have no way to really compare)
712+
auto latestVersion = SemanticVersion::getLatest(versions.getBuffer(), versions.getCount());
713+
return findCompiler(compilers, matchVersion.type, latestVersion);
679714
}
680715
}
681716
}
@@ -684,16 +719,11 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
684719
return nullptr;
685720
}
686721

687-
/* static */DownstreamCompiler* DownstreamCompilerUtil::findClosestCompiler(const DownstreamCompilerSet* set, const DownstreamCompiler::Desc& desc)
722+
/* static */DownstreamCompiler* DownstreamCompilerUtil::findClosestCompiler(const DownstreamCompilerSet* set, const DownstreamCompilerMatchVersion& matchVersion)
688723
{
689-
DownstreamCompiler* compiler = set->getCompiler(desc);
690-
if (compiler)
691-
{
692-
return compiler;
693-
}
694724
List<DownstreamCompiler*> compilers;
695725
set->getCompilers(compilers);
696-
return findClosestCompiler(compilers, desc);
726+
return findClosestCompiler(compilers, matchVersion);
697727
}
698728

699729
/* static */void DownstreamCompilerUtil::updateDefault(DownstreamCompilerSet* set, SlangSourceLanguage sourceLanguage)
@@ -708,7 +738,7 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
708738
// Find the compiler closest to the compiler this was compiled with
709739
if (!compiler)
710740
{
711-
compiler = findClosestCompiler(set, getCompiledWithDesc());
741+
compiler = findClosestCompiler(set, getCompiledVersion());
712742
}
713743
break;
714744
}

source/compiler-core/slang-downstream-compiler.h

+33-3
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,21 @@ class BlobDownstreamCompileResult : public DownstreamCompileResult
154154
ComPtr<ISlangBlob> m_blob;
155155
};
156156

157+
// Combination of a downstream compiler type (pass through) and
158+
// a match version.
159+
struct DownstreamCompilerMatchVersion
160+
{
161+
DownstreamCompilerMatchVersion(SlangPassThrough inType, MatchSemanticVersion inMatchVersion):
162+
type(inType),
163+
matchVersion(inMatchVersion)
164+
{}
165+
166+
DownstreamCompilerMatchVersion():type(SLANG_PASS_THROUGH_NONE) {}
167+
168+
SlangPassThrough type; ///< The type of the compiler
169+
MatchSemanticVersion matchVersion; ///< The match version
170+
};
171+
157172
class DownstreamCompiler: public RefObject
158173
{
159174
public:
@@ -190,6 +205,8 @@ class DownstreamCompiler: public RefObject
190205
Info infos[int(SLANG_PASS_THROUGH_COUNT_OF)];
191206
};
192207

208+
209+
// Compiler description
193210
struct Desc
194211
{
195212
typedef Desc ThisType;
@@ -208,11 +225,17 @@ class DownstreamCompiler: public RefObject
208225
/// Ctor
209226
explicit Desc(SlangPassThrough inType = SLANG_PASS_THROUGH_NONE, Int inMajorVersion = 0, Int inMinorVersion = 0):type(inType), majorVersion(inMajorVersion), minorVersion(inMinorVersion) {}
210227

228+
explicit Desc(SlangPassThrough inType, const SemanticVersion& version):type(inType), majorVersion(version.m_major), minorVersion(version.m_minor) {}
229+
211230
SlangPassThrough type; ///< The type of the compiler
231+
232+
/// TODO(JS): Would probably be better if changed to SemanticVersion, but not trivial to change
233+
// because this type is part of the DownstreamCompiler interface, which is used with `slang-llvm`.
212234
Int majorVersion; ///< Major version (interpretation is type specific)
213235
Int minorVersion; ///< Minor version (interpretation is type specific)
214236
};
215237

238+
216239
enum class OptimizationLevel
217240
{
218241
None, ///< Don't optimize at all.
@@ -526,12 +549,19 @@ struct DownstreamCompilerUtil: public DownstreamCompilerBaseUtil
526549
static DownstreamCompiler* findCompiler(const DownstreamCompilerSet* set, MatchType matchType, const DownstreamCompiler::Desc& desc);
527550
static DownstreamCompiler* findCompiler(const List<DownstreamCompiler*>& compilers, MatchType matchType, const DownstreamCompiler::Desc& desc);
528551

552+
static DownstreamCompiler* findCompiler(const List<DownstreamCompiler*>& compilers, SlangPassThrough type, const SemanticVersion& version);
553+
static DownstreamCompiler* findCompiler(const List<DownstreamCompiler*>& compilers, const DownstreamCompiler::Desc& desc);
554+
555+
/// Find all the compilers with the version
556+
static void findVersions(const List<DownstreamCompiler*>& compilers, SlangPassThrough compiler, List<SemanticVersion>& versions);
557+
558+
529559
/// Find the compiler closest to the desc
530-
static DownstreamCompiler* findClosestCompiler(const List<DownstreamCompiler*>& compilers, const DownstreamCompiler::Desc& desc);
531-
static DownstreamCompiler* findClosestCompiler(const DownstreamCompilerSet* set, const DownstreamCompiler::Desc& desc);
560+
static DownstreamCompiler* findClosestCompiler(const List<DownstreamCompiler*>& compilers, const DownstreamCompilerMatchVersion& version);
561+
static DownstreamCompiler* findClosestCompiler(const DownstreamCompilerSet* set, const DownstreamCompilerMatchVersion& version);
532562

533563
/// Get the information on the compiler used to compile this source
534-
static const DownstreamCompiler::Desc& getCompiledWithDesc();
564+
static DownstreamCompilerMatchVersion getCompiledVersion();
535565

536566
static void updateDefault(DownstreamCompilerSet* set, SlangSourceLanguage sourceLanguage);
537567
static void updateDefaults(DownstreamCompilerSet* set);

0 commit comments

Comments
 (0)