From 8e6e884eca5b33218a8cb2714266fb6ed4548d75 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 8 Jun 2022 10:23:01 -0400 Subject: 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" --- source/slang/slang-ir-com-interface.cpp | 147 +++++++++++++++++--------------- 1 file changed, 80 insertions(+), 67 deletions(-) (limited to 'source/slang/slang-ir-com-interface.cpp') 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 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*. + // 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 comInterfaces; + for (auto child : module->getGlobalInsts()) { - if (!type->findDecoration()) - return nullptr; - + auto intf = as(child); + if (intf && intf->findDecoration()) + { + 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(builder.getPtrType(type)) : - static_cast(builder.getComPtrType(type)); + List uses; - replaceTypeUses(type, result); - return result; - } + for (auto comIntf : comInterfaces) + { + uses.clear(); - void processThisType(IRThisType* type) - { - auto comPtrType = processInterfaceType(as(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(child)); - break; - case kIROp_ThisType: - processThisType(as(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(builder.getComPtrType(comIntf)) : + static_cast(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(); } } -- cgit v1.2.3