Vuo 2.4.4
Loading...
Searching...
No Matches
VuoCompilerTriggerPort.cc
Go to the documentation of this file.
1
13#include "VuoCompilerType.hh"
14#include "VuoPort.hh"
15#include "VuoType.hh"
16
24
30Value * VuoCompilerTriggerPort::generateCreatePortContext(Module *module, BasicBlock *block)
31{
32 VuoType *dataType = getClass()->getDataVuoType();
33
35 dataType ? dataType->getCompiler() : nullptr,
36 true, "org.vuo.composition." + getIdentifier());
37}
38
46void VuoCompilerTriggerPort::generateScheduleWorker(Module *module, Function *function, BasicBlock *block,
47 Value *compositionStateValue, Value *eventIdValue,
48 Value *portContextValue, VuoType *dataType,
49 int minThreadsNeeded, int maxThreadsNeeded, int chainCount,
50 Function *workerFunction)
51{
52 PointerType *voidPointer = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
53
54 Value *dataCopyAsVoidPointer;
55 if (dataType)
56 {
57 // Create a copy of the data on the heap.
58 Value *dataPointer = dataType->getCompiler()->convertArgsToPortData(module, block, function, 0);
59 dataCopyAsVoidPointer = VuoCompilerCodeGenUtilities::generateMemoryAllocation(module, block, dataType->getCompiler());
60 VuoCompilerCodeGenUtilities::generateMemoryCopy(module, block, dataPointer, dataCopyAsVoidPointer, dataType->getCompiler());
61
62 dataType->getCompiler()->generateRetainCall(module, block, dataCopyAsVoidPointer);
63 }
64 else
65 dataCopyAsVoidPointer = ConstantPointerNull::get(voidPointer);
66
67 // Create a copy of the event ID on the heap.
68 Type *eventIdType = VuoCompilerCodeGenUtilities::generateNoEventIdConstant(module)->getType();
69 Value *eventIdCopyAddress = VuoCompilerCodeGenUtilities::generateMemoryAllocation(module, block, eventIdType, 1);
70 new StoreInst(eventIdValue, eventIdCopyAddress, false, block);
71
72 Value *contextValue = VuoCompilerCodeGenUtilities::generateCreateTriggerWorkerContext(module, block, compositionStateValue,
73 dataCopyAsVoidPointer, eventIdCopyAddress);
74
75 Value *dispatchQueueValue = VuoCompilerCodeGenUtilities::generateGetPortContextTriggerQueue(module, block, portContextValue);
76
77 VuoCompilerCodeGenUtilities::generateScheduleTriggerWorker(module, block, dispatchQueueValue, contextValue, workerFunction,
78 minThreadsNeeded, maxThreadsNeeded,
79 eventIdValue, compositionStateValue, chainCount);
80}
81
86Function * VuoCompilerTriggerPort::generateSynchronousSubmissionToDispatchQueue(Module *module, BasicBlock *block, Value *nodeContextValue,
87 string workerFunctionName, Value *workerFunctionArg)
88{
89 Function *workerFunction = getWorkerFunction(module, workerFunctionName);
90
91 PointerType *voidPointer = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
92 Value *argAsVoidPointer;
93 if (workerFunctionArg)
94 argAsVoidPointer = new BitCastInst(workerFunctionArg, voidPointer, "", block);
95 else
96 argAsVoidPointer = ConstantPointerNull::get(voidPointer);
97
98 Value *portContextValue = generateGetPortContext(module, block, nodeContextValue);
99 Value *dispatchQueueValue = VuoCompilerCodeGenUtilities::generateGetPortContextTriggerQueue(module, block, portContextValue);
100 VuoCompilerCodeGenUtilities::generateSynchronousSubmissionToDispatchQueue(module, block, dispatchQueueValue, workerFunction, argAsVoidPointer);
101
102 return workerFunction;
103}
104
108Function * VuoCompilerTriggerPort::getWorkerFunction(Module *module, string functionName, bool isExternal)
109{
110 PointerType *voidPointer = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
111
112 vector<Type *> workerFunctionParams;
113 workerFunctionParams.push_back(voidPointer);
114 FunctionType *workerFunctionType = FunctionType::get(Type::getVoidTy(module->getContext()),
115 workerFunctionParams,
116 false);
117
118 Function *workerFunction = module->getFunction(functionName);
119 if (! workerFunction) {
120 workerFunction = Function::Create(workerFunctionType,
121 isExternal ? GlobalValue::ExternalLinkage : GlobalValue::InternalLinkage,
122 functionName,
123 module);
124 }
125
126 return workerFunction;
127}
128
133Value * VuoCompilerTriggerPort::generateNonBlockingWaitForSemaphore(Module *module, BasicBlock *block, Value *portContextValue)
134{
135 ConstantInt *timeoutDeltaValue = ConstantInt::get(module->getContext(), APInt(64, 0));
136 Value *timeoutValue = VuoCompilerCodeGenUtilities::generateCreateDispatchTime(module, block, timeoutDeltaValue);
137 Value *dispatchSemaphoreValue = VuoCompilerCodeGenUtilities::generateGetPortContextTriggerSemaphore(module, block, portContextValue);
138 return VuoCompilerCodeGenUtilities::generateWaitForSemaphore(module, block, dispatchSemaphoreValue, timeoutValue);
139}
140
144void VuoCompilerTriggerPort::generateSignalForSemaphore(Module *module, BasicBlock *block, Value *nodeContextValue)
145{
146 Value *portContextValue = generateGetPortContext(module, block, nodeContextValue);
147 Value *dispatchSemaphoreValue = VuoCompilerCodeGenUtilities::generateGetPortContextTriggerSemaphore(module, block, portContextValue);
148 VuoCompilerCodeGenUtilities::generateSignalForSemaphore(module, block, dispatchSemaphoreValue);
149}
150
154Value * VuoCompilerTriggerPort::generateLoadFunction(Module *module, BasicBlock *block, Value *nodeContextValue)
155{
156 Value *portContextValue = generateGetPortContext(module, block, nodeContextValue);
157 return VuoCompilerCodeGenUtilities::generateGetPortContextTriggerFunction(module, block, portContextValue, getClass()->getFunctionType(module));
158}
159
163void VuoCompilerTriggerPort::generateStoreFunction(Module *module, BasicBlock *block, Value *nodeContextValue, Value *functionValue)
164{
165 Value *portContextValue = generateGetPortContext(module, block, nodeContextValue);
166 VuoCompilerCodeGenUtilities::generateSetPortContextTriggerFunction(module, block, portContextValue, functionValue);
167}
168
172Value * VuoCompilerTriggerPort::generateRetrievePreviousData(Module *module, BasicBlock *block, Value *nodeContextValue)
173{
174 Value *portContextValue = generateGetPortContext(module, block, nodeContextValue);
175 return VuoCompilerCodeGenUtilities::generateGetPortContextDataVariable(module, block, portContextValue, getClass()->getDataVuoType()->getCompiler());
176}
177
182void VuoCompilerTriggerPort::generateFreeContext(Module *module, BasicBlock *block, Function *workerFunction)
183{
184 Value *contextValue = workerFunction->arg_begin();
186}
187
192Value * VuoCompilerTriggerPort::generateCompositionStateValue(Module *module, BasicBlock *block, Function *workerFunction)
193{
194 // VuoCompositionState *compositionState = (VuoCompositionState *)((void **)context)[0];
195
196 Value *contextValue = workerFunction->arg_begin();
197 Type *voidPointerType = contextValue->getType();
198 Type *voidPointerPointerType = PointerType::get(voidPointerType, 0);
199 Type *compositionStatePointerType = PointerType::get(VuoCompilerCodeGenUtilities::getCompositionStateType(module), 0);
200
201 Value *contextValueAsVoidPointerArray = new BitCastInst(contextValue, voidPointerPointerType, "", block);
202 Value *compositionStateAsVoidPointer = VuoCompilerCodeGenUtilities::generateGetArrayElement(module, block, contextValueAsVoidPointerArray, (size_t)0);
203 return new BitCastInst(compositionStateAsVoidPointer, compositionStatePointerType, "", block);
204}
205
210Value * VuoCompilerTriggerPort::generateDataValue(Module *module, BasicBlock *block, Function *workerFunction)
211{
212 // PortDataType *dataCopy = (PortDataType *)((void **)context)[1]);
213 // PortDataType data = *dataCopy;
214
215 Value *contextValue = workerFunction->arg_begin();
216 Type *voidPointerType = contextValue->getType();
217 Type *voidPointerPointerType = PointerType::get(voidPointerType, 0);
218
219 Value *contextValueAsVoidPointerArray = new BitCastInst(contextValue, voidPointerPointerType, "", block);
220 return VuoCompilerCodeGenUtilities::generateGetArrayElement(module, block, contextValueAsVoidPointerArray, 1);
221}
222
227Value * VuoCompilerTriggerPort::generateEventIdValue(Module *module, BasicBlock *block, Function *workerFunction)
228{
229 // unsigned long *eventIdCopy = (unsigned long *)((void **)context)[2];
230 // unsigned long eventId = *eventIdCopy;
231
232 Value *contextValue = workerFunction->arg_begin();
233 Type *voidPointerType = contextValue->getType();
234 Type *voidPointerPointerType = PointerType::get(voidPointerType, 0);
235 Type *eventIdType = VuoCompilerCodeGenUtilities::generateNoEventIdConstant(module)->getType();
236
237 Value *contextValueAsVoidPointerArray = new BitCastInst(contextValue, voidPointerPointerType, "", block);
238 Value *eventIdCopyAsVoidPointer = VuoCompilerCodeGenUtilities::generateGetArrayElement(module, block, contextValueAsVoidPointerArray, 2);
239 PointerType *pointerToEventIdType = PointerType::get(eventIdType, 0);
240 Value *eventIdCopyValue = new BitCastInst(eventIdCopyAsVoidPointer, pointerToEventIdType, "", block);
241 return new LoadInst(eventIdCopyValue, "", block);
242}
243
249Value * VuoCompilerTriggerPort::generateDataValueUpdate(Module *module, BasicBlock *block, Function *workerFunction, Value *nodeContextValue)
250{
251 Value *currentDataValue = NULL;
252 VuoType *dataType = getClass()->getDataVuoType();
253
254 if (dataType)
255 {
256 // Load the previous data.
257 Value *previousDataPointer = generateRetrievePreviousData(module, block, nodeContextValue);
258
259 // Load the current data.
260 Value *currentDataVoidPointer = generateDataValue(module, block, workerFunction);
261 Value *currentDataPointer = dataType->getCompiler()->convertToPortData(block, currentDataVoidPointer);
262 currentDataValue = new LoadInst(currentDataPointer, "", block);
263
264 // The current data becomes the previous data.
265 dataType->getCompiler()->generateReleaseCall(module, block, previousDataPointer);
266 Value *portContextValue = generateGetPortContext(module, block, nodeContextValue);
267 VuoCompilerCodeGenUtilities::generateSetPortContextData(module, block, portContextValue, currentDataValue, dataType->getCompiler());
268 }
269
270 return currentDataValue;
271}
272
276void VuoCompilerTriggerPort::generateDataValueDiscardFromScheduler(Module *module, Function *function, BasicBlock *block,
277 VuoType *dataType)
278{
279 Value *dataPointer = dataType->getCompiler()->convertArgsToPortData(module, block, function, 0);
280 dataType->getCompiler()->generateRetainCall(module, block, dataPointer);
281 dataType->getCompiler()->generateReleaseCall(module, block, dataPointer);
282}
283
287void VuoCompilerTriggerPort::generateDataValueDiscardFromWorker(Module *module, BasicBlock *block, Function *workerFunction)
288{
289 VuoType *dataType = getClass()->getDataVuoType();
290
291 if (dataType)
292 {
293 Value *dataValue = generateDataValue(module, block, workerFunction);
294 dataValue = dataType->getCompiler()->convertToPortData(block, dataValue);
295 dataType->getCompiler()->generateReleaseCall(module, block, dataValue);
296 }
297}
298