diff options
| author | Theresa Foley <10618364+tangent-vector@users.noreply.github.com> | 2025-07-24 12:59:58 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-24 19:59:58 +0000 |
| commit | 8ccd495d5eaa82cb831378c28dd190e657b6c999 (patch) | |
| tree | c39dc364d95f78984fd4ba2776d259ff944d2596 /source/slang/slang-target-program.h | |
| parent | 2d23a962766a97cbb11bcee5483a66aec923da49 (diff) | |
Organize code better by splitting some big files (#7890)
* Organize code better by splitting some big files
The basic change here is that the majority of the declarations in `slang-compiler.h` have been split out into a set of smaller and more focused files.
As a result, the implement of those declarations have been moved from `slang-compiler.cpp` and `slang.cpp` over to those new files when the proper home for code is obvious.
I have tried as much as possible to *not* make any edits to the code along the way, and just copy-paste declarations from one place to another as-is.
The exceptions I am aware of are:
* In some cases a function that used to be file-scope `static` was used by code that landed in two or more different `.cpp` files. In these cases, I changed the function to be non-`static` (removing the `_` prefix from its name, if it had one, per our naming conventions), and put a declaration for the function into the most appropriate header I could identify.
* I added a few comments in places where I saw ugly or unfortunate things in the code I was moving, and wanted to tag them with `TODO`s so we can hopefully get to them in the fullness of time.
* I added top-level comments to each of the new `.h` files that was introduced to try to explain the logic for what goes into that file.
* In cases where one of the new header files mostly existed to declare a single type, I sometimes added more detail to the doc comment on that type, to better explain the type and its role in the compiler (this is text that otherwise might have gone into the comment at the top leve lof the file, but I figured that the doc comment would have higher discoverability).
I expect that the most contentious choice here is that the `Session` class lands in `slang-global-session.h` while `slang-session.h` holds the `Linkage` class.
The names used in this change are consistent with how the relevant concepts in the public Slang API are named, and are consistent with how we *intend* to rename the classes themselves in time.
* format code
* fixup
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source/slang/slang-target-program.h')
| -rw-r--r-- | source/slang/slang-target-program.h | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/source/slang/slang-target-program.h b/source/slang/slang-target-program.h new file mode 100644 index 000000000..57a9c46fb --- /dev/null +++ b/source/slang/slang-target-program.h @@ -0,0 +1,143 @@ +// slang-target-program.h +#pragma once + +// +// This file declares the `TargetProgram` class, which is +// primarily used to cache generated target code for a +// linked program/binary and/or its entry points. +// + +#include "../core/slang-smart-pointer.h" +#include "slang-hlsl-to-vulkan-layout-options.h" +#include "slang-ir.h" +#include "slang-linkable.h" +#include "slang-target.h" + +namespace Slang +{ + +/// A `TargetProgram` represents a `ComponentType` specialized for a particular `TargetRequest` +/// +/// TODO: This should probably be renamed to `TargetComponentType`. +/// +/// By binding a component type to a specific target, a `TargetProgram` allows +/// for things like layout to be computed, that fundamentally depend on +/// the choice of target. +/// +/// A `TargetProgram` handles request for compiled kernel code for +/// entry point functions. In practice, kernel code can only be +/// correctly generated when the underlying `ComponentType` is "fully linked" +/// (has no remaining unsatisfied requirements). +/// +class TargetProgram : public RefObject +{ +public: + TargetProgram(ComponentType* componentType, TargetRequest* targetReq); + + /// Get the underlying program + ComponentType* getProgram() { return m_program; } + + /// Get the underlying target + TargetRequest* getTargetReq() { return m_targetReq; } + + /// Get the layout for the program on the target. + /// + /// If this is the first time the layout has been + /// requested, report any errors that arise during + /// layout to the given `sink`. + /// + ProgramLayout* getOrCreateLayout(DiagnosticSink* sink); + + /// Get the layout for the program on the target. + /// + /// This routine assumes that `getOrCreateLayout` + /// has already been called previously. + /// + ProgramLayout* getExistingLayout() + { + SLANG_ASSERT(m_layout); + return m_layout; + } + + /// Get the compiled code for an entry point on the target. + /// + /// If this is the first time that code generation has + /// been requested, report any errors that arise during + /// code generation to the given `sink`. + /// + IArtifact* getOrCreateEntryPointResult(Int entryPointIndex, DiagnosticSink* sink); + IArtifact* getOrCreateWholeProgramResult(DiagnosticSink* sink); + + IArtifact* getExistingWholeProgramResult() { return m_wholeProgramResult; } + /// Get the compiled code for an entry point on the target. + /// + /// This routine assumes that `getOrCreateEntryPointResult` + /// has already been called previously. + /// + IArtifact* getExistingEntryPointResult(Int entryPointIndex) + { + return m_entryPointResults[entryPointIndex]; + } + + IArtifact* _createWholeProgramResult( + DiagnosticSink* sink, + EndToEndCompileRequest* endToEndReq = nullptr); + + /// Internal helper for `getOrCreateEntryPointResult`. + /// + /// This is used so that command-line and API-based + /// requests for code can bottleneck through the same place. + /// + /// Shouldn't be called directly by most code. + /// + IArtifact* _createEntryPointResult( + Int entryPointIndex, + DiagnosticSink* sink, + EndToEndCompileRequest* endToEndReq = nullptr); + + RefPtr<IRModule> getOrCreateIRModuleForLayout(DiagnosticSink* sink); + + RefPtr<IRModule> getExistingIRModuleForLayout() { return m_irModuleForLayout; } + + CompilerOptionSet& getOptionSet() { return m_optionSet; } + + HLSLToVulkanLayoutOptions* getHLSLToVulkanLayoutOptions() + { + return m_targetReq->getHLSLToVulkanLayoutOptions(); + } + + bool shouldEmitSPIRVDirectly() + { + return isKhronosTarget(m_targetReq) && getOptionSet().shouldEmitSPIRVDirectly(); + } + +private: + RefPtr<IRModule> createIRModuleForLayout(DiagnosticSink* sink); + + // The program being compiled or laid out + ComponentType* m_program; + + // The target that code/layout will be generated for + TargetRequest* m_targetReq; + + // The computed layout, if it has been generated yet + RefPtr<ProgramLayout> m_layout; + + CompilerOptionSet m_optionSet; + + // Generated compile results for each entry point + // in the parent `Program` (indexing matches + // the order they are given in the `Program`) + ComPtr<IArtifact> m_wholeProgramResult; + List<ComPtr<IArtifact>> m_entryPointResults; + + RefPtr<IRModule> m_irModuleForLayout; +}; + +/// Given a target request returns which (if any) intermediate source language is required +/// to produce it. +/// +/// If no intermediate source language is required, will return SourceLanguage::Unknown +SourceLanguage getIntermediateSourceLanguageForTarget(TargetProgram* req); + +} // namespace Slang |
