41 if (instanceDataClass)
46 constantStrings = NULL;
47 indexInOrderedNodes = ULONG_MAX - 1;
55 this->indexInOrderedNodes = indexInOrderedNodes;
63 return indexInOrderedNodes;
71 this->constantStrings = constantStrings;
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);
103 identifierParts.push_back(constantStrings->
get(module,
"/" +
getIdentifier()));
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)
142 Value *portIdentifierValue = constantStrings->
get(module, port->
getIdentifier());
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 = constantStrings->
get(module, initialValue);
165 portNameValue, typeIndex, initialValueValue);
168 if (subcompositionFunctionSrc)
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);
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())
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);
474 Value *arg = eventPort->
generateLoadData(module, block, nodeContextValue, portContextValue);
475 Value *secondArg = NULL;
484 if (
getBase()->getNodeClass()->getCompiler()->isSubcomposition() &&
485 arg->getType()->isStructTy() &&
489 arg =
new BitCastInst(argAsPointer, functionSrc->getFunctionType()->getParamType(index),
"", block);
494 Value **secondArgIfNeeded = (isLoweredToTwoParameters ? &secondArg : NULL);
498 VUserLog(
"Warning: Couldn't convert argument for input port '%s' of function %s; not generating call.",
499 (*i)->getClass()->getName().c_str(),
500 functionDst->getName().str().c_str());
507 args[index + 1] = secondArg;
514 map<VuoCompilerOutputEventPort *, Value *> outputPortDataVariables;
515 map<VuoCompilerOutputEventPort *, AllocaInst *> outputPortEventVariables;
516 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
522 bool isEventArgumentInFunction = isArgumentInFunction(eventPort, functionSrc);
523 bool isDataArgumentInFunction = data && isArgumentInFunction(data, functionSrc);
525 if (isEventArgumentInFunction)
527 size_t index = getArgumentIndexInFunction(eventPort, functionSrc);
528 PointerType *eventPointerType =
static_cast<PointerType *
>( functionDst->getFunctionType()->getParamType(index) );
529 AllocaInst *arg =
new AllocaInst(eventPointerType->getElementType(),
"", block);
530 new StoreInst(ConstantInt::get(eventPointerType->getElementType(), 0), arg, block);
531 outputPortEventVariables[eventPort] = arg;
535 if (isDataArgumentInFunction)
537 map<VuoCompilerEventPort *, Value *>::const_iterator iter = portContextForEventPort.find(eventPort);
538 Value *portContextValue = (iter != portContextForEventPort.end() ?
542 size_t index = getArgumentIndexInFunction(data, functionSrc);
545 outputPortDataVariables[eventPort] = dataVariable;
550 VUserLog(
"Warning: Couldn't convert argument for output port '%s' of function %s; not generating call.",
551 (*i)->getClass()->getName().c_str(),
552 functionDst->getName().str().c_str());
561 if (isArgumentInFunction(triggerPort, functionSrc))
563 size_t index = getArgumentIndexInFunction(triggerPort, functionSrc);
570 Value *instanceDataVariable = NULL;
571 if (instanceData && isArgumentInFunction(instanceData, functionSrc))
576 size_t index = getArgumentIndexInFunction(instanceData, functionSrc);
577 Value *arg = instanceDataVariable;
581 VUserLog(
"Warning: Couldn't convert argument for instance data of function %s; not generating call.", functionDst->getName().str().c_str());
587 map<VuoCompilerOutputEventPort *, Value *> oldOutputDataValues;
588 for (map<VuoCompilerOutputEventPort *, Value *>::iterator i = outputPortDataVariables.begin(); i != outputPortDataVariables.end(); ++i)
591 Value *dataVariable = i->second;
593 oldOutputDataValues[eventPort] =
new LoadInst(dataVariable,
"",
false, block);
597 Value *oldInstanceDataValue = NULL;
598 if (instanceDataVariable)
600 oldInstanceDataValue =
new LoadInst(instanceDataVariable,
"",
false, block);
607 for (
auto arg : args)
612 raw_string_ostream type(s);
613 functionDst->getFunctionType()->getParamType(i)->print(type);
614 ostringstream argIndex;
616 string details =
"When trying to generate a call to function " + functionDst->getName().str() +
617 ", argument " + argIndex.str() +
" (" + type.str() +
") was missing.";
626 CallInst *call = CallInst::Create(functionDst, args,
"", block);
632 for (map<VuoCompilerOutputEventPort *, AllocaInst *>::iterator i = outputPortEventVariables.begin(); i != outputPortEventVariables.end(); ++i)
635 AllocaInst *eventVariable = i->second;
636 Value *eventValue =
new LoadInst(eventVariable,
"",
false, block);
641 for (map<VuoCompilerOutputEventPort *, Value *>::iterator i = outputPortDataVariables.begin(); i != outputPortDataVariables.end(); ++i)
644 Value *dataVariable = i->second;
646 Value *outputDataValue =
new LoadInst(dataVariable,
"",
false, block);
652 for (map<VuoCompilerOutputEventPort *, Value *>::iterator i = oldOutputDataValues.begin(); i != oldOutputDataValues.end(); ++i)
655 Value *oldOutputDataValue = i->second;
661 if (instanceDataVariable)
664 Value *instanceDataValue =
new LoadInst(instanceDataVariable,
"",
false, block);
671 if (
getBase()->getNodeClass()->getCompiler()->isSubcomposition())
689 if (
function ==
getBase()->getNodeClass()->getCompiler()->getEventFunction())
691 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getInitFunction())
693 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStartFunction())
695 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackUpdateFunction())
697 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStopFunction())
699 else if (instanceData == argument &&
700 (
function ==
getBase()->getNodeClass()->getCompiler()->getFiniFunction()))
714 if (
function ==
getBase()->getNodeClass()->getCompiler()->getEventFunction())
716 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getInitFunction())
718 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getFiniFunction())
719 return (
getBase()->getNodeClass()->getCompiler()->isSubcomposition() ? 1 : 0);
720 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStartFunction())
722 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackUpdateFunction())
724 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStopFunction())
741 vector<VuoPort *> selectedInputPorts,
742 const map<VuoCompilerEventPort *, Value *> &portContextForEventPort)
744 Value *conditionValue = ConstantInt::getFalse(block->getContext());
745 for (vector<VuoPort *>::iterator i = selectedInputPorts.begin(); i != selectedInputPorts.end(); ++i)
750 map<VuoCompilerEventPort *, Value *>::const_iterator iter = portContextForEventPort.find(eventPort);
751 Value *portContextValue = (iter != portContextForEventPort.end() ?
755 Value *pushValue = eventPort->
generateLoadEvent(module, block, nodeContextValue, portContextValue);
756 conditionValue = BinaryOperator::Create(Instruction::Or, conditionValue, pushValue,
"", block);
759 return conditionValue;
793 if (titleWithoutSpaces.empty())
796 return titleWithoutSpaces;
804 this->graphvizIdentifier = graphvizIdentifier;
812 return graphvizIdentifier;
820 VuoPort *manuallyFirableInputPort)
822 ostringstream declaration;
838 for (vector<VuoPort *>::iterator i = inputPorts.begin(); i != inputPorts.end(); ++i)
841 declaration <<
"|<" << portName <<
">" << portName <<
"\\l";
843 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
846 declaration <<
"|<" << portName <<
">" << portName <<
"\\r";
851 if (shouldPrintPosition)
852 declaration <<
" pos=\"" <<
getBase()->
getX()+xPositionOffset <<
"," <<
getBase()->
getY()+yPositionOffset <<
"\"";
856 declaration <<
" collapsed";
859 if (
getBase()->getTintColor() != VuoNode::TintNone)
863 for (vector<VuoPort *>::iterator i = inputPorts.begin(); i != inputPorts.end(); ++i)
872 declaration <<
" _" << port->
getClass()->
getName() <<
"=\"" << escapedPortConstant <<
"\"";
877 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
883 declaration <<
" _" << port->
getClass()->
getName() <<
"_eventThrottling=\"" << eventThrottling <<
"\"";
888 if (manuallyFirableInputPort)
889 declaration <<
" _" << manuallyFirableInputPort->
getClass()->
getName() <<
"_manuallyFirable";
893 return declaration.str();