41 if (instanceDataClass)
46 constantsCache = NULL;
47 indexInOrderedNodes = ULONG_MAX - 1;
55 this->indexInOrderedNodes = indexInOrderedNodes;
63 return indexInOrderedNodes;
71 this->constantsCache = constantsCache;
75 vector<VuoPort *> ports;
76 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
77 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
78 for (vector<VuoPort *>::iterator i = ports.begin(); i != ports.end(); ++i)
101 vector<Value *> identifierParts;
102 identifierParts.push_back(compositionIdentifierValue);
120 const vector<VuoCompilerType *> &orderedTypes,
121 Function *compositionCreateContextForNode,
122 Function *compositionSetPortValueFunction, Function *compositionGetPortValueFunction,
123 Function *compositionFireTriggerPortEventFunction, Function *compositionReleasePortDataFunction)
129 compositionCreateContextForNode, compositionSetPortValueFunction,
130 compositionGetPortValueFunction, compositionFireTriggerPortEventFunction,
131 compositionReleasePortDataFunction);
135 vector<VuoPort *> ports;
136 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
137 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
138 for (vector<VuoPort *>::iterator i = ports.begin(); i != ports.end(); ++i)
151 vector<VuoCompilerType *>::const_iterator typeIter = find(orderedTypes.begin(), orderedTypes.end(), dataType->
getCompiler());
152 typeIndex = typeIter - orderedTypes.begin();
159 typeIndex = orderedTypes.size();
162 Value *initialValueValue = constantsCache->
get(initialValue);
165 portNameValue, typeIndex, initialValueValue);
168 if (subcompositionFunctionSrc)
176 Value *arg =
new BitCastInst(subcompositionStateValue, subcompositionFunctionDst->getFunctionType()->getParamType(0),
"", block);
177 CallInst::Create(subcompositionFunctionDst, arg,
"", block);
192 unsigned long publishedOutputPortCount = (isSubcomposition ?
201 vector<VuoPort *> ports;
202 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
203 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
204 vector<Value *> portContextValues;
205 for (vector<VuoPort *>::iterator i = ports.begin(); i != ports.end(); ++i)
210 portContextValues.push_back(portContextValue);
215 return nodeContextValue;
231 Value *compositionStateValue)
235 Value *nodeContextValue =
generateGetContext(module, currentBlock, compositionStateValue);
237 map<VuoCompilerEventPort *, Value *> portContextForEventPort;
240 vector<VuoPort *> ports;
241 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
242 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
243 for (vector<VuoPort *>::iterator i = ports.begin(); i != ports.end(); ++i)
247 portContextForEventPort[eventPort] = eventPort->
generateGetPortContext(module, currentBlock, nodeContextValue);
250 generateFunctionCall(functionSrc, module, currentBlock, compositionStateValue, nodeContextValue, portContextForEventPort);
256 vector<VuoPort *> nonBlockingInputPorts;
257 vector<VuoPort *> doorInputPorts;
258 for (vector<VuoPort *>::iterator i = inputPorts.begin(); i != inputPorts.end(); ++i)
262 nonBlockingInputPorts.push_back(*i);
264 doorInputPorts.push_back(*i);
268 portContextForEventPort);
269 Value *transmitForAllOutputPorts = eventHitNonBlockingInputPort;
271 BasicBlock *handleTransmissionBlock = NULL;
272 BasicBlock *nextBlock = NULL;
273 if (! doorInputPorts.empty())
275 handleTransmissionBlock = BasicBlock::Create(module->getContext(),
"handleTransmission",
function, 0);
276 nextBlock = BasicBlock::Create(module->getContext(),
"next",
function, 0);
279 portContextForEventPort);
281 Value *blockForAllOutputPorts = BinaryOperator::Create(Instruction::And,
282 BinaryOperator::CreateNot(eventHitNonBlockingInputPort,
"", currentBlock),
283 BinaryOperator::CreateNot(eventHitDoorInputPort,
"", currentBlock),
285 Value *handleTransmission = BinaryOperator::Create(Instruction::Or, transmitForAllOutputPorts, blockForAllOutputPorts,
"", currentBlock);
287 Constant *zeroValue = ConstantInt::get(transmitForAllOutputPorts->getType(), 0);
288 ICmpInst *handleTransmissionComparison =
new ICmpInst(*currentBlock, ICmpInst::ICMP_NE, handleTransmission, zeroValue,
"");
289 BranchInst::Create(handleTransmissionBlock, nextBlock, handleTransmissionComparison, currentBlock);
293 handleTransmissionBlock = currentBlock;
296 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
301 Value *portContextValue = portContextForEventPort[eventPort];
302 eventPort->
generateStoreEvent(module, handleTransmissionBlock, nodeContextValue, transmitForAllOutputPorts, portContextValue);
306 if (! doorInputPorts.empty())
308 BranchInst::Create(nextBlock, handleTransmissionBlock);
309 currentBlock = nextBlock;
329 CallInst *call = generateFunctionCall(functionSrc, module, block, compositionStateValue, nodeContextValue);
331 Type *instanceDataType = instanceData->
getType();
333 instanceData->
generateStore(module, block, nodeContextValue, callCasted);
336 Value *instanceDataValue = instanceData->
generateLoad(module, block, nodeContextValue);
356 generateFunctionCall(functionSrc, module, block, compositionStateValue, nodeContextValue);
359 Value *instanceDataValue = instanceData->
generateLoad(module, block, nodeContextValue);
378 generateFunctionCall(functionSrc, module, block, compositionStateValue, nodeContextValue);
396 generateFunctionCall(functionSrc, module, block, compositionStateValue, nodeContextValue);
414 generateFunctionCall(functionSrc, module, block, compositionStateValue, nodeContextValue);
428 CallInst * VuoCompilerNode::generateFunctionCall(Function *functionSrc, Module *module, BasicBlock *block,
429 Value *compositionStateValue, Value *nodeContextValue,
430 const map<VuoCompilerEventPort *, Value *> &portContextForEventPort)
434 vector<Value *> args(functionDst->getFunctionType()->getNumParams());
437 Value *subcompositionIdentifierValue = NULL;
438 Value *subcompositionStateValue = NULL;
439 if (
getBase()->getNodeClass()->getCompiler()->isSubcomposition())
445 args[0] =
new BitCastInst(subcompositionStateValue, functionDst->getFunctionType()->getParamType(0),
"", block);
450 for (vector<VuoPort *>::iterator i = inputPorts.begin(); i != inputPorts.end(); ++i)
455 bool isEventArgumentInFunction = isArgumentInFunction(eventPort, functionSrc);
456 bool isDataArgumentInFunction = data && isArgumentInFunction(data, functionSrc);
458 if (isEventArgumentInFunction || isDataArgumentInFunction)
460 map<VuoCompilerEventPort *, Value *>::const_iterator iter = portContextForEventPort.find(eventPort);
461 Value *portContextValue = (iter != portContextForEventPort.end() ?
465 if (isEventArgumentInFunction)
467 size_t index = getArgumentIndexInFunction(eventPort, functionSrc);
468 args[index] = eventPort->
generateLoadEvent(module, block, nodeContextValue, portContextValue);
471 if (isDataArgumentInFunction)
473 size_t index = getArgumentIndexInFunction(data, functionSrc);
476 functionDst->getFunctionType(), index,
477 isUnloweredStructPointerParameter(data, functionSrc));
478 for (
auto a : loweredArgs)
486 map<VuoCompilerOutputEventPort *, Value *> outputPortDataVariables;
487 map<VuoCompilerOutputEventPort *, AllocaInst *> outputPortEventVariables;
488 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
494 bool isEventArgumentInFunction = isArgumentInFunction(eventPort, functionSrc);
495 bool isDataArgumentInFunction = data && isArgumentInFunction(data, functionSrc);
497 if (isEventArgumentInFunction)
499 size_t index = getArgumentIndexInFunction(eventPort, functionSrc);
500 PointerType *eventPointerType =
static_cast<PointerType *
>( functionDst->getFunctionType()->getParamType(index) );
501 AllocaInst *arg =
new AllocaInst(eventPointerType->getElementType(), 0,
"", block);
502 new StoreInst(ConstantInt::get(eventPointerType->getElementType(), 0), arg, block);
503 outputPortEventVariables[eventPort] = arg;
507 if (isDataArgumentInFunction)
509 map<VuoCompilerEventPort *, Value *>::const_iterator iter = portContextForEventPort.find(eventPort);
510 Value *portContextValue = (iter != portContextForEventPort.end() ?
514 size_t index = getArgumentIndexInFunction(data, functionSrc);
517 outputPortDataVariables[eventPort] = dataPointer;
519 Value *arg =
new BitCastInst(dataPointer, functionDst->getFunctionType()->getParamType(index),
"dataArgumentCasted", block);
526 if (isArgumentInFunction(triggerPort, functionSrc))
528 size_t index = getArgumentIndexInFunction(triggerPort, functionSrc);
530 args[index] =
new BitCastInst(triggerFunction, functionDst->getFunctionType()->getParamType(index),
"triggerArgumentCasted", block);
536 Value *instanceDataVariable = NULL;
537 if (instanceData && isArgumentInFunction(instanceData, functionSrc))
539 Type *type = instanceData->
getType();
542 size_t index = getArgumentIndexInFunction(instanceData, functionSrc);
543 Value *arg = instanceDataVariable;
544 args[index] =
new BitCastInst(arg, functionDst->getFunctionType()->getParamType(index),
"", block);
547 VUserLog(
"Warning: Couldn't convert argument for instance data of function %s; not generating call.", functionDst->getName().str().c_str());
553 map<VuoCompilerOutputEventPort *, Value *> oldOutputDataPointers;
554 for (map<VuoCompilerOutputEventPort *, Value *>::iterator i = outputPortDataVariables.begin(); i != outputPortDataVariables.end(); ++i)
557 Value *dataVariable = i->second;
558 Value *dataPointer =
new AllocaInst(
static_cast<PointerType *
>(dataVariable->getType())->getElementType(), 0,
"", block);
559 Value *dataValue =
new LoadInst(dataVariable,
"",
false, block);
560 new StoreInst(dataValue, dataPointer, block);
561 oldOutputDataPointers[eventPort] = dataPointer;
565 Value *oldInstanceDataValue = NULL;
566 if (instanceDataVariable)
568 oldInstanceDataValue =
new LoadInst(instanceDataVariable,
"",
false, block);
575 for (
auto arg : args)
580 raw_string_ostream type(s);
581 functionDst->getFunctionType()->getParamType(i)->print(type);
582 ostringstream argIndex;
584 string details =
"When trying to generate a call to function " + functionDst->getName().str() +
585 ", argument " + argIndex.str() +
" (" + type.str() +
") was missing.";
594 CallInst *call = CallInst::Create(functionDst, args,
"", block);
600 for (map<VuoCompilerOutputEventPort *, AllocaInst *>::iterator i = outputPortEventVariables.begin(); i != outputPortEventVariables.end(); ++i)
603 AllocaInst *eventVariable = i->second;
604 Value *eventValue =
new LoadInst(eventVariable,
"",
false, block);
609 for (map<VuoCompilerOutputEventPort *, Value *>::iterator i = outputPortDataVariables.begin(); i != outputPortDataVariables.end(); ++i)
612 Value *dataVariable = i->second;
619 for (map<VuoCompilerOutputEventPort *, Value *>::iterator i = oldOutputDataPointers.begin(); i != oldOutputDataPointers.end(); ++i)
622 Value *oldOutputDataPointer = i->second;
628 if (instanceDataVariable)
631 Value *instanceDataValue =
new LoadInst(instanceDataVariable,
"",
false, block);
638 if (
getBase()->getNodeClass()->getCompiler()->isSubcomposition())
656 if (
function ==
getBase()->getNodeClass()->getCompiler()->getEventFunction())
658 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getInitFunction())
660 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStartFunction())
662 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackUpdateFunction())
664 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStopFunction())
666 else if (instanceData == argument &&
667 (
function ==
getBase()->getNodeClass()->getCompiler()->getFiniFunction()))
681 if (
function ==
getBase()->getNodeClass()->getCompiler()->getEventFunction())
683 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getInitFunction())
685 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getFiniFunction())
686 return (
getBase()->getNodeClass()->getCompiler()->isSubcomposition() ? 1 : 0);
687 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStartFunction())
689 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackUpdateFunction())
691 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStopFunction())
703 bool VuoCompilerNode::isUnloweredStructPointerParameter(
VuoCompilerInputData *inputData, Function *
function)
731 vector<VuoPort *> selectedInputPorts,
732 const map<VuoCompilerEventPort *, Value *> &portContextForEventPort)
734 Value *conditionValue = ConstantInt::getFalse(block->getContext());
735 for (vector<VuoPort *>::iterator i = selectedInputPorts.begin(); i != selectedInputPorts.end(); ++i)
740 map<VuoCompilerEventPort *, Value *>::const_iterator iter = portContextForEventPort.find(eventPort);
741 Value *portContextValue = (iter != portContextForEventPort.end() ?
745 Value *pushValue = eventPort->
generateLoadEvent(module, block, nodeContextValue, portContextValue);
746 conditionValue = BinaryOperator::Create(Instruction::Or, conditionValue, pushValue,
"", block);
749 return conditionValue;
783 if (titleWithoutSpaces.empty())
786 return titleWithoutSpaces;
794 this->graphvizIdentifier = graphvizIdentifier;
802 return graphvizIdentifier;
810 VuoPort *manuallyFirableInputPort)
812 ostringstream declaration;
828 for (vector<VuoPort *>::iterator i = inputPorts.begin(); i != inputPorts.end(); ++i)
831 declaration <<
"|<" << portName <<
">" << portName <<
"\\l";
833 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
836 declaration <<
"|<" << portName <<
">" << portName <<
"\\r";
841 if (shouldPrintPosition)
842 declaration <<
" pos=\"" <<
getBase()->
getX()+xPositionOffset <<
"," <<
getBase()->
getY()+yPositionOffset <<
"\"";
846 declaration <<
" collapsed";
849 if (
getBase()->getTintColor() != VuoNode::TintNone)
853 for (vector<VuoPort *>::iterator i = inputPorts.begin(); i != inputPorts.end(); ++i)
862 declaration <<
" _" << port->
getClass()->
getName() <<
"=\"" << escapedPortConstant <<
"\"";
867 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
873 declaration <<
" _" << port->
getClass()->
getName() <<
"_eventThrottling=\"" << eventThrottling <<
"\"";
878 if (manuallyFirableInputPort)
879 declaration <<
" _" << manuallyFirableInputPort->
getClass()->
getName() <<
"_manuallyFirable=\"yes\"";
883 return declaration.str();