summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-compiler.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2020-01-31 16:01:03 -0800
committerGitHub <noreply@github.com>2020-01-31 16:01:03 -0800
commit2c1fbf8330efc34b85e09ee9b101c6a55327778a (patch)
tree79707def5dec6a753bafaffcb474c8a92fb5081b /source/slang/slang-compiler.cpp
parent2ee06a4f2f3c995717bf18ba287a20e81d6141bc (diff)
Some Slang API additions (#1195)
* Some Slang API additions These are additions to the public Slang API that came up while I was trying to write an example to demonstrate GPU printing. The additions aren't strictly necessary for the example, but I found these to be missing services when writing the code the way I wanted to. The main public changes are: * There is a new distinct `IEntryPoint` interface which inherit from `IComponentType` (much like `IModule` before). For now this doesn't expose any new functions on top of `IComponentType`, but I expect it to do so eventually. * It is now possible to get the `IModule` for a specific translation unit in a compile request with `spCompileRequest_getModule`. Even for a compile request that had only one translation unit this is *not* the same object as gets returned by `spCompileRequest_getProgram`. The latter should probably be called `*_getLinkedProgram` because it returns a composite component type that links the module with everything it `import`s. * An `IModule` can look up entry points declared in the module. Eventually a module should support looking up most of the declarations in the module (e.g., types) by name, but entry points are an obvious case. * A new `link()` operation is added to `IComponentType`. It is possible to have component types that have unsatisfied dependencies, such that trying to generate kernel code from them will fail. The `link()` operation tries to produce a new composite component type that combines a component with its dependencies, to enable code generation. The implementation of end-to-end compilation was using a function like this internally, but it hadn't been exposed to the API. Notes on the implementation: * The list of entry points declared in a given translation unit has moved from `TranslationUnitRequest` to the `Module` inside of it. * `EntryPoint` now has to do a song and dance much like `Module` to both inherit from `ComponentType` and support the `IEntryPoint` interface. * The `Session* m_session` member in `Linkage` (in terms of public API, this is the `slang::ISession` holding a pointer to the `slang::IGlobalSession`) has been changed to a `RefPtr`. Without this change an application can't just hold onto a `ComPtr<slang::ISession>`; they also need to retain the `IGlobalSession` or things will crash. The new behavior seems more correct, but I worry that it might introduce a leak. * The `asInternal` operation for `IComponentType` had to be updated to not just perform a cast. A type like `Module` has two `IComponentType` sub-objects, and only one of these is at the same address as the `ComponentType` base. * Similarly, the `Module::getInterface` logic was changed to fall back to `Super::getInterface` for all the cases other than `IID_IModule`, so that it would be guaranteed to return the `IComponentType` at the same address as `ComponentType` in response to a `queryInterface`. * Fixes for memory retain cycles As part of the earlier change, I made the `Linkage` type hold a `RefPtr` to the `Session`. The motivation there is it lets a user hang onto just a `slang::ISession` without having to also retain the `slang::IGlobalSession` for no immediately apparent reason. There are two problems that this surfaced, one pre-existing and one new. The new problem was that `Session` already held a `RefPtr<Linkage> m_builtinLinkage` for the linkage that holds the stdlib code. I solved that problem by splitting the parent pointer in `Linkage` into two pointers: a raw pointer that is used to actually locate the parent session, and a ref-counted one that can be used to *optionally* retain the parent session. The builtin linkage is then set up to explicitly not retain its parent, thus breaking the cycle. The second problem was a pre-existing one, where every `ComponentType` was holding a retained pointer to its parent `Linkage`, but in turn the `Linkage` was holding retained pointers to many `ComponentTypes` (and subclasses thereof). For this case I used the more expedient fix of making the parent pointer into a raw pointer, and figuring that it is a reasonable rule to expect user to retain the `Linkage` (aka `slang::ISession`) that owns a component type if they want to be able to use the component type. I might need/want to investigate a better fix for the latter issue, but for now this seems to clean up the issues I was seeing in the tests. Fingers crossed.
Diffstat (limited to 'source/slang/slang-compiler.cpp')
-rw-r--r--source/slang/slang-compiler.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index d0fca1ab5..65c48d2f2 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -196,6 +196,16 @@ namespace Slang
// EntryPoint
//
+ static const Guid IID_IEntryPoint = SLANG_UUID_IEntryPoint;
+
+ ISlangUnknown* EntryPoint::getInterface(const Guid& guid)
+ {
+ if(guid == IID_IEntryPoint)
+ return static_cast<slang::IEntryPoint*>(this);
+
+ return Super::getInterface(guid);
+ }
+
RefPtr<EntryPoint> EntryPoint::create(
Linkage* linkage,
DeclRef<FuncDecl> funcDeclRef,
@@ -2059,6 +2069,15 @@ SlangResult dissassembleDXILUsingDXC(
if( result.format != ResultFormat::None )
return result;
+ // If we haven't yet computed a layout for this target
+ // program, we need to make sure that is done before
+ // code generation.
+ //
+ if( !getOrCreateIRModuleForLayout(sink) )
+ {
+ return result;
+ }
+
RefPtr<BackEndCompileRequest> backEndRequest = new BackEndCompileRequest(
m_program->getLinkage(),
sink,