summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-ir-com-interface.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-06-08 10:23:01 -0400
committerGitHub <noreply@github.com>2022-06-08 10:23:01 -0400
commit8e6e884eca5b33218a8cb2714266fb6ed4548d75 (patch)
treea9c8aee79a71450a64e6660da7266b6a45da0264 /source/slang/slang-ir-com-interface.cpp
parent01d0154ae90f5c587321d39b8fd8f82e2764f360 (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.cpp147
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();
}
}