diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2022-06-08 10:23:01 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-08 10:23:01 -0400 |
| commit | 8e6e884eca5b33218a8cb2714266fb6ed4548d75 (patch) | |
| tree | a9c8aee79a71450a64e6660da7266b6a45da0264 /source/slang/slang-ir-com-interface.cpp | |
| parent | 01d0154ae90f5c587321d39b8fd8f82e2764f360 (diff) | |
Actual global support (#2262)
* #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.
* Work around for not being able to include "targetConditionals.h"
Diffstat (limited to 'source/slang/slang-ir-com-interface.cpp')
| -rw-r--r-- | source/slang/slang-ir-com-interface.cpp | 147 |
1 files changed, 80 insertions, 67 deletions
diff --git a/source/slang/slang-ir-com-interface.cpp b/source/slang/slang-ir-com-interface.cpp index 009d2314d..899596209 100644 --- a/source/slang/slang-ir-com-interface.cpp +++ b/source/slang/slang-ir-com-interface.cpp @@ -7,92 +7,105 @@ namespace Slang { -struct ComInterfaceLoweringContext +static bool _canReplace(IRUse* use) { - IRModule* module; - DiagnosticSink* diagnosticSink; - - ArtifactStyle artifactStyle; - - SharedIRBuilder sharedBuilder; - - void replaceTypeUses(IRInst* inst, IRInst* newValue) + switch (use->getUser()->getOp()) { - List<IRUse*> uses; - for (auto use = inst->firstUse; use; use = use->nextUse) + case kIROp_WitnessTableIDType: + case kIROp_WitnessTableType: + case kIROp_RTTIPointerType: + case kIROp_RTTIHandleType: { - uses.add(use); + // Don't replace + return false; } - for (auto use : uses) + case kIROp_ThisType: { - switch (use->getUser()->getOp()) - { - case kIROp_WitnessTableIDType: - case kIROp_WitnessTableType: - case kIROp_ThisType: - case kIROp_RTTIPointerType: - case kIROp_RTTIHandleType: - case kIROp_ComPtrType: - case kIROp_PtrType: - continue; - default: - break; - } - use->set(newValue); + // Appears replacable. + break; } + case kIROp_ComPtrType: + case kIROp_PtrType: + { + // We can have ** and ComPtr<T>*. + // If it's a pointer type it could be because it is a global. + break; + } + default: break; } + return true; +} - IRType* processInterfaceType(IRInterfaceType* type) +void lowerComInterfaces(IRModule* module, ArtifactStyle artifactStyle, DiagnosticSink* sink) +{ + SLANG_UNUSED(sink); + + // Find all of the COM interfaces + List<IRInterfaceType*> comInterfaces; + for (auto child : module->getGlobalInsts()) { - if (!type->findDecoration<IRComInterfaceDecoration>()) - return nullptr; - + auto intf = as<IRInterfaceType>(child); + if (intf && intf->findDecoration<IRComInterfaceDecoration>()) + { + comInterfaces.add(intf); + } + } + + // For all interfaces found replace uses + { + SharedIRBuilder sharedBuilder; + sharedBuilder.init(module); + IRBuilder builder(sharedBuilder); builder.setInsertInto(module->getModuleInst()); - IRType* result = (artifactStyle == ArtifactStyle::Kernel) ? - static_cast<IRType*>(builder.getPtrType(type)) : - static_cast<IRType*>(builder.getComPtrType(type)); + List<IRUse*> uses; - replaceTypeUses(type, result); - return result; - } + for (auto comIntf : comInterfaces) + { + uses.clear(); - void processThisType(IRThisType* type) - { - auto comPtrType = processInterfaceType(as<IRInterfaceType>(type->getConstraintType())); - if (!comPtrType) - return; - replaceTypeUses(type, comPtrType); - } + // Find all of the uses *before* doing any replacement + // Otherwise we end up replacing the replacement leading + // to it pointing to itself. + for (auto use = comIntf->firstUse; use; use = use->nextUse) + { + // Only store off uses where replacement can be made + if (_canReplace(use)) + { + uses.add(use); + } + } - void processModule() - { - for (auto child : module->getGlobalInsts()) - { - switch (child->getOp()) + // If there are no uses that can be replaced, then we don't need + // to create a replacement result + if (uses.getCount() <= 0) { - case kIROp_InterfaceType: - processInterfaceType(as<IRInterfaceType>(child)); - break; - case kIROp_ThisType: - processThisType(as<IRThisType>(child)); - break; - default: - break; + continue; + } + + // NOTE! The following code relies on the fact that the builder + // *doesn't* dedup in general, and in particular doesn't ptr types. + // This allows the creation a 'new' pointer type, and subsequent replacment all old uses, + // leading to a `IInterface*` becoming `IInterface**`. + // + + // TODO(JS): This is a temporary fix, in that whether kernel or not + // shouldn't control the ptr type in general + // It's necessary here though because Kernel doesn't have ComPtr<> + // so has to be a raw pointer + IRType* result = (artifactStyle == ArtifactStyle::Host) ? + static_cast<IRType*>(builder.getComPtrType(comIntf)) : + static_cast<IRType*>(builder.getPtrType(comIntf)); + + // Go through replacing all of the replacable uses + for (auto use : uses) + { + // Do the replacement + use->set(result); } } } -}; - -void lowerComInterfaces(IRModule* module, ArtifactStyle artifactStyle, DiagnosticSink* sink) -{ - ComInterfaceLoweringContext context; - context.module = module; - context.diagnosticSink = sink; - context.artifactStyle = artifactStyle; - context.sharedBuilder.init(module); - return context.processModule(); } } |
