43 bool isTopLevelComposition,
54 bool isTopLevelComposition,
58 VuoCompilerBitcodeGenerator_Pro();
61 constantsCache =
nullptr;
63 this->composition = composition;
64 this->isTopLevelComposition = isTopLevelComposition;
65 this->moduleKey = moduleKey;
66 this->compiler = compiler;
73 makePortContextInfo();
74 makeSubcompositionModelPorts();
83 for (vector<VuoPort *>::iterator i = modelOutputPorts.begin(); i != modelOutputPorts.end(); ++i)
106 bool operator() (
const vector<VuoCompilerNode *> &chainNodes1,
const vector<VuoCompilerNode *> &chainNodes2)
113 bool isNode2DownstreamOfNode1 = find(downstreamOfChain1.begin(), downstreamOfChain1.end(), chainNodes2.front()) != downstreamOfChain1.end();
114 bool isNode1DownstreamOfNode2 = find(downstreamOfChain2.begin(), downstreamOfChain2.end(), chainNodes1.front()) != downstreamOfChain2.end();
116 if (isNode2DownstreamOfNode1 && isNode1DownstreamOfNode2)
118 else if (isNode2DownstreamOfNode1)
120 else if (isNode1DownstreamOfNode2)
126 size_t maxNumDownstreamOfTrigger[2] = { 0, 0 };
127 vector<VuoCompilerNode *> chainNodes[2] = { chainNodes1, chainNodes2 };
128 for (
int i = 0; i < 2; ++i)
130 for (vector<VuoCompilerNode *>::const_iterator j = chainNodes[i].begin(); j != chainNodes[i].end(); ++j)
134 for (vector<VuoPort *>::iterator k = outputPorts.begin(); k != outputPorts.end(); ++k)
141 maxNumDownstreamOfTrigger[i] = max(maxNumDownstreamOfTrigger[i], numDownstreamOfTrigger);
147 if (maxNumDownstreamOfTrigger[0] != maxNumDownstreamOfTrigger[1])
148 return maxNumDownstreamOfTrigger[0] > maxNumDownstreamOfTrigger[1];
152 return chainNodes1.front()->getIdentifier() < chainNodes2.front()->getIdentifier();
159void VuoCompilerBitcodeGenerator::makeOrderedNodes(
void)
165 vector<VuoCompilerChain *> chains;
166 map<VuoCompilerTriggerPort *, vector<VuoCompilerChain *> >::iterator chainsIter = chainsForTrigger.find(trigger);
167 if (chainsIter != chainsForTrigger.end())
168 chains = chainsIter->second;
170 vector< vector<VuoCompilerNode *> > chainNodeLists;
171 set<VuoCompilerNode *> lastNodeInLoop;
174 if (chain->isLastNodeInLoop())
175 lastNodeInLoop.insert( chain->getNodes().front() );
177 chainNodeLists.push_back( chain->getNodes() );
184 sort(chainNodeLists.begin(), chainNodeLists.end(), c);
186 vector<VuoCompilerNode *> orderedNodeList;
189 orderedNodeList.push_back(triggerNode);
191 for (vector<VuoCompilerNode *> chainNodeList : chainNodeLists)
193 auto triggerNodeIter = std::find(chainNodeList.begin(), chainNodeList.end(), triggerNode);
194 if (triggerNodeIter != chainNodeList.end())
195 chainNodeList.erase(triggerNodeIter);
197 orderedNodeList.insert( orderedNodeList.end(), chainNodeList.begin(), chainNodeList.end() );
200 downstreamNodesForTrigger[trigger] = orderedNodeList;
203 vector< vector<VuoCompilerNode *> > orderedNodesPerTrigger;
204 for (
const map<
VuoCompilerTriggerPort *, vector<VuoCompilerNode *> >::value_type &i : downstreamNodesForTrigger)
205 orderedNodesPerTrigger.push_back(i.second);
213 vector<VuoCompilerNode *> nodesInProgress;
214 nodesInProgress.push_back(node);
215 nodesInProgress.insert(nodesInProgress.end(), downstreamNodes.begin(), downstreamNodes.end());
216 orderedNodesPerTrigger.push_back(nodesInProgress);
221 std::sort(orderedNodesPerTrigger.begin(), orderedNodesPerTrigger.end(),
222 [](
const vector<VuoCompilerNode *> &nodes1,
const vector<VuoCompilerNode *> &nodes2) {
223 if (nodes1.size() != nodes2.size())
224 return nodes1.size() < nodes2.size();
229 for (VuoCompilerNode *n : nodes1)
230 oss1 << n->getIdentifier() <<
" ";
231 for (VuoCompilerNode *n : nodes2)
232 oss2 << n->getIdentifier() <<
" ";
233 return oss1.str() < oss2.str();
239 int previousTriggerNodeIndex = -1;
240 for (vector< vector<VuoCompilerNode *> >::reverse_iterator i = orderedNodesPerTrigger.rbegin(); i != orderedNodesPerTrigger.rend(); ++i)
243 int previousNodeIndex = previousTriggerNodeIndex;
244 bool isFirstNode =
true;
247 vector<VuoCompilerNode *>::iterator nodeIter = find(orderedNodes.begin(), orderedNodes.end(), node);
248 if (nodeIter == orderedNodes.end())
249 nodeIter = orderedNodes.insert(orderedNodes.begin() + previousNodeIndex + 1, node);
251 previousNodeIndex = max(previousNodeIndex, (
int)(nodeIter - orderedNodes.begin()));
254 previousTriggerNodeIndex = previousNodeIndex;
262 if (find(orderedNodes.begin(), orderedNodes.end(), node) == orderedNodes.end())
263 orderedNodes.push_back(node);
265 for (
size_t i = 0; i < orderedNodes.size(); ++i)
266 orderedNodes[i]->setIndexInOrderedNodes(i);
272void VuoCompilerBitcodeGenerator::sortNodes(vector<VuoCompilerNode *> &nodes)
274 vector<VuoCompilerNode *> sortedNodes;
275 for (vector<VuoCompilerNode *>::iterator i = orderedNodes.begin(); i != orderedNodes.end(); ++i)
278 if (find(nodes.begin(), nodes.end(), node) != nodes.end())
279 sortedNodes.push_back(node);
287vector<VuoCompilerNode *> VuoCompilerBitcodeGenerator::getNodesToWaitOnBeforeTransmission(
VuoCompilerTriggerPort *trigger)
310 vector<VuoCompilerNode *> sortedDownstreamNodes = downstreamNodesForTrigger[trigger];
311 sortNodes(sortedDownstreamNodes);
312 bool hasOutOfOrderDownstreamNodes = (downstreamNodesForTrigger[trigger] != sortedDownstreamNodes);
315 vector<VuoCompilerNode *> nodesToWaitOn;
316 if (hasScatterOverlappedByAnotherTrigger || hasOverlapWithSpinOff || hasOutOfOrderDownstreamNodes)
317 nodesToWaitOn = downstreamNodesForTrigger[trigger];
321 VuoCompilerNode *triggerNode = downstreamNodesForTrigger[trigger].front();
322 if (find(nodesToWaitOn.begin(), nodesToWaitOn.end(), triggerNode) == nodesToWaitOn.end())
323 nodesToWaitOn.push_back(triggerNode);
326 return nodesToWaitOn;
344 vector<VuoCompilerNode *> nodesToWaitOn =
345 (hasGatherOverlappedByAnotherTrigger ?
349 return nodesToWaitOn;
355void VuoCompilerBitcodeGenerator::makeOrderedTypes(
void)
361 vector<VuoPort *> ports;
362 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
363 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
371 vector<VuoCompilerType *>::iterator typeIter = find(orderedTypes.begin(), orderedTypes.end(), dataType->
getCompiler());
372 if (typeIter == orderedTypes.end())
382void VuoCompilerBitcodeGenerator::makePortContextInfo(
void)
388 vector<VuoPort *> ports;
389 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
390 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
391 for (
size_t i = 0; i < ports.size(); ++i)
404void VuoCompilerBitcodeGenerator::makeSubcompositionModelPorts(
void)
410 modelInputPorts.insert( modelInputPorts.end(), publishedInputPorts.begin(), publishedInputPorts.end() );
411 modelOutputPorts.insert( modelOutputPorts.end(), publishedOutputPorts.begin(), publishedOutputPorts.end() );
415 for (
size_t i = 0; i < modelOutputPorts.size(); ++i)
417 string portName = modelOutputPorts[i]->getClass()->getName();
418 if (publishedOutputTriggerNames.find(portName) != publishedOutputTriggerNames.end())
424 modelOutputPorts[i] = modelTriggerPort->
getBase();
432void VuoCompilerBitcodeGenerator::makeDependencies(
void)
438 makeDependencies_Pro();
442 compiler->getDependenciesForComposition(composition);
454 bool isStatefulComposition =
false;
459 isStatefulComposition =
true;
464 module = new Module(moduleKey, *VuoCompiler::globalLLVMContext);
470 generateCompositionMetadata();
472 generateTriggerFunctions();
474 if (! isTopLevelComposition)
475 generateNodeEventFunction(isStatefulComposition);
477 if (isStatefulComposition)
479 generateNodeInstanceInitFunction();
480 generateNodeInstanceFiniFunction();
481 generateNodeInstanceTriggerStartFunction();
482 if (! isTopLevelComposition)
483 generateNodeInstanceTriggerUpdateFunction();
486 generateNodeInstanceTriggerStopFunction();
488 generateCompositionReleasePortDataFunction();
490 generateCompositionGetPortValueFunction();
491 generateCompositionSetPortValueFunction();
492 generateCompositionFireTriggerPortEventFunction();
494 generateCompositionSetPublishedInputPortValueFunction();
496 generateCompositionCreateContextForNodeFunction();
497 generateCompositionAddNodeMetadataFunction();
498 generateCompositionPerformDataOnlyTransmissionsFunction();
500 if (isTopLevelComposition)
504 generateAllocation();
505 generateSetupFunction(isStatefulComposition);
506 generateCleanupFunction();
508 generateInstanceInitFunction(isStatefulComposition);
509 generateInstanceFiniFunction(isStatefulComposition);
510 generateInstanceTriggerStartFunction(isStatefulComposition);
511 generateInstanceTriggerStopFunction(isStatefulComposition);
513 generateSetInputPortValueFunction();
515 generateGetPublishedPortCountFunction(
true);
516 generateGetPublishedPortCountFunction(
false);
517 generateGetPublishedPortNamesFunction(
true);
518 generateGetPublishedPortNamesFunction(
false);
519 generateGetPublishedPortTypesFunction(
true);
520 generateGetPublishedPortTypesFunction(
false);
521 generateGetPublishedPortDetailsFunction(
true);
522 generateGetPublishedPortDetailsFunction(
false);
523 generateGetPublishedPortValueFunction(
true);
524 generateGetPublishedPortValueFunction(
false);
525 generateSetPublishedInputPortValueFunction();
526 generateFirePublishedInputPortEventFunction();
531 delete constantsCache;
532 constantsCache =
nullptr;
540void VuoCompilerBitcodeGenerator::generateCompositionMetadata(
void)
542 json_object *metadataJson = json_object_new_object();
543 json_object *nodeMetadataJson = json_object_new_object();
551 json_object_object_add(metadataJson,
"title", json_object_new_string(title.c_str()));
554 json_object_object_add(metadataJson,
"description", json_object_new_string(description.c_str()));
556 json_object *keywordsJson = json_object_new_array();
557 for (
const string &keyword : composition->getBase()->getMetadata()->getKeywords())
558 json_object_array_add(keywordsJson, json_object_new_string(keyword.c_str()));
559 json_object_object_add(metadataJson,
"keywords", keywordsJson);
562 if (! version.empty())
563 json_object_object_add(metadataJson,
"version", json_object_new_string(version.c_str()));
565 json_object *dependenciesJson = json_object_new_array();
566 for (
const string &dependency : dependencies)
567 json_object_array_add(dependenciesJson, json_object_new_string(dependency.c_str()));
568 json_object_object_add(metadataJson,
"dependencies", dependenciesJson);
571 json_object_object_add(metadataJson,
"compatibility", compatibilityJson);
573 if (! isTopLevelComposition)
576 generateCompositionMetadata_Pro(nodeMetadataJson);
579 json_object *triggersJson = json_object_new_array();
584 json_object_array_add(triggersJson, t);
592 json_object *t = triggerInSubcomposition->getJsonWithinSubcomposition(node);
593 json_object_array_add(triggersJson, t);
596 json_object_object_add(nodeMetadataJson,
"triggers", triggersJson);
598 json_object *nodesJson = json_object_new_object();
602 json_object_object_add(nodesJson, node->
getIdentifier().c_str(), nodeClassNameJson);
604 json_object_object_add(nodeMetadataJson,
"nodes", nodesJson);
607 json_object_object_add(metadataJson,
"node", nodeMetadataJson);
609 string metadata = json_object_to_json_string_ext(metadataJson, JSON_C_TO_STRING_PLAIN);
610 json_object_put(metadataJson);
620void VuoCompilerBitcodeGenerator::generateShouldShowSplashWindowFunction(
bool shouldShow)
622 IntegerType *returnType = IntegerType::get(module->getContext(), 8);
623 FunctionType *functionType = FunctionType::get(returnType,
false);
624 Function *function = Function::Create(functionType, GlobalValue::ExternalLinkage,
"vuoShouldShowSplashWindow", module);
625 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, NULL);
626 Value *boolValue = ConstantInt::get(returnType, shouldShow);
627 ReturnInst::Create(module->getContext(), boolValue, block);
636void VuoCompilerBitcodeGenerator::generateCompositionAddNodeMetadataFunction(
void)
639 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, NULL);
641 Function::arg_iterator args = function->arg_begin();
642 Value *compositionStateValue = args++;
643 compositionStateValue->setName(
"compositionState");
651 for (vector<VuoCompilerNode *>::iterator i = orderedNodes.begin(); i != orderedNodes.end(); ++i)
655 node->
generateAddMetadata(module, block, compositionStateValue, orderedTypes, compositionCreateContextForNodeFunction,
656 compositionSetPortValueFunction, compositionGetPortValueFunction, compositionFireTriggerPortEventFunction,
657 releasePortDataFunction);
660 ReturnInst::Create(module->getContext(), block);
669void VuoCompilerBitcodeGenerator::generateCompositionCreateContextForNodeFunction(
void)
672 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, NULL);
673 BasicBlock *finalBlock = BasicBlock::Create(module->getContext(),
"final", function, NULL);
675 Function::arg_iterator args = function->arg_begin();
676 Value *nodeIndexValue = args++;
677 nodeIndexValue->setName(
"nodeIndex");
680 AllocaInst *nodeContextVariable =
new AllocaInst(pointerToNodeContext, 0,
"nodeContext", initialBlock);
682 vector< pair<BasicBlock *, BasicBlock *> > blocksForIndex;
684 for (
size_t i = 0; i < orderedNodes.size(); ++i)
688 BasicBlock *block = BasicBlock::Create(module->getContext(), node->
getIdentifier(), function, NULL);
690 new StoreInst(nodeContextValue, nodeContextVariable, block);
692 blocksForIndex.push_back(make_pair(block, block));
697 Value *nodeContextValue =
new LoadInst(nodeContextVariable,
"",
false, finalBlock);
698 ReturnInst::Create(module->getContext(), nodeContextValue, finalBlock);
709void VuoCompilerBitcodeGenerator::generateCompositionPerformDataOnlyTransmissionsFunction(
void)
712 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, NULL);
714 Function::arg_iterator args = function->arg_begin();
715 Value *compositionStateValue = args++;
716 compositionStateValue->setName(
"compositionState");
720 for (
VuoCompilerNode *node : graph->getSourceNodesOfDataOnlyTransmission())
721 generateDataOnlyTransmissionFromNode(function, block, compositionStateValue, node, false, false, false);
728 if (subcompositionFunctionSrc)
734 Value *subcompositionStateValueDst =
new BitCastInst(subcompositionStateValue, subcompositionFunctionSrc->getFunctionType()->getParamType(0),
"", block);
740 Value *falseValue = ConstantInt::get(setPublishedInputPortValueFunctionDst->getFunctionType()->getParamType(3), 0);
742 for (
VuoPort *inputPort : node->getBase()->getInputPorts())
748 Value *inputPortNameValue = constantsCache->
get(inputPort->getClass()->getName());
751 vector<Value *> args;
752 args.push_back(subcompositionStateValueDst);
753 args.push_back(inputPortNameValue);
754 args.push_back(dataValue);
755 args.push_back(falseValue);
756 CallInst::Create(setPublishedInputPortValueFunctionDst, args,
"", block);
763 CallInst::Create(subcompositionFunctionDst, subcompositionStateValueDst,
"", block);
770 ReturnInst::Create(module->getContext(), block);
780void VuoCompilerBitcodeGenerator::generateCompositionReleasePortDataFunction(
void)
783 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, NULL);
784 BasicBlock *finalBlock = BasicBlock::Create(module->getContext(),
"final", function, NULL);
786 Function::arg_iterator args = function->arg_begin();
787 Value *portAddressAsVoidPointer = args++;
788 portAddressAsVoidPointer->setName(
"portData");
789 Value *typeIndexValue = args++;
790 typeIndexValue->setName(
"typeIndex");
792 vector< pair<BasicBlock *, BasicBlock *> > blocksForIndex;
794 for (vector<VuoCompilerType *>::iterator i = orderedTypes.begin(); i != orderedTypes.end(); ++i)
798 BasicBlock *block = BasicBlock::Create(module->getContext(), type->
getBase()->
getModuleKey(), function, NULL);
801 blocksForIndex.push_back(make_pair(block, block));
806 ReturnInst::Create(module->getContext(), finalBlock);
812void VuoCompilerBitcodeGenerator::generateSetInputDataFromNodeFunctionArguments(Function *function, BasicBlock *&block, Value *compositionStateValue,
813 map<VuoPort *, size_t> indexOfParameter,
814 map<VuoPort *, size_t> indexOfEventParameter,
815 bool shouldWaitForDataOnlyDownstreamNodes,
816 bool shouldUpdateTriggers,
bool shouldSendTelemetry)
819 if (! publishedInputNode)
822 Value *publishedNodeContextValue = publishedInputNode->
generateGetContext(module, block, compositionStateValue);
825 vector<VuoCompilerInputEventPort *> inputEventPorts;
829 for (
size_t i = 0; i < publishedInputPorts.size(); ++i)
835 inputEventPorts.push_back(inputEventPort);
839 size_t dataArgIndex = indexOfParameter[ modelInputPorts[i] ];
842 inputEventPort->
generateReplaceData(module, block, publishedNodeContextValue, dataPointer);
849 generateDataOnlyTransmissionFromNode(function, block, compositionStateValue, publishedInputNode,
850 shouldWaitForDataOnlyDownstreamNodes, shouldUpdateTriggers, shouldSendTelemetry);
854 for (
size_t i = 0; i < publishedInputPorts.size(); ++i)
859 &indexOfEventParameter :
862 auto foundIndex = indexMap->find( modelInputPorts[i] );
863 if (foundIndex != indexMap->end())
865 size_t eventArgIndex = foundIndex->second;
868 inputEventPort->
generateStoreEvent(module, block, publishedNodeContextValue, eventArg);
881void VuoCompilerBitcodeGenerator::generateNodeEventFunction(
bool isStatefulComposition)
883 vector<VuoPort *> modelPorts;
884 modelPorts.insert(modelPorts.end(), modelInputPorts.begin(), modelInputPorts.end());
885 modelPorts.insert(modelPorts.end(), modelOutputPorts.begin(), modelOutputPorts.end());
889 vector<VuoPublishedPort *> publishedPorts;
890 publishedPorts.insert(publishedPorts.end(), publishedInputPorts.begin(), publishedInputPorts.end());
891 publishedPorts.insert(publishedPorts.end(), publishedOutputPorts.begin(), publishedOutputPorts.end());
893 map<VuoPort *, string> displayNamesForPorts;
894 map<VuoPort *, json_object *> detailsForPorts;
895 for (
size_t i = 0; i < modelPorts.size(); ++i)
897 VuoPort *modelPort = modelPorts[i];
901 bool isAllCaps =
true;
902 for (
size_t j = 0; j < portName.length(); ++j)
903 if (! isupper(portName[j]))
909 displayNamesForPorts[modelPort] = portName;
914 map<VuoPort *, string> defaultValuesForInputPorts;
915 map<VuoPort *, VuoPortClass::EventBlocking> eventBlockingForInputPorts;
916 for (
size_t i = 0; i < publishedInputPorts.size(); ++i)
921 if (! defaultValue.empty())
922 defaultValuesForInputPorts[publishedInputPort] = defaultValue;
927 map<VuoPort *, size_t> indexOfParameter;
928 map<VuoPort *, size_t> indexOfEventParameter;
931 modelInputPorts, modelOutputPorts,
932 detailsForPorts, displayNamesForPorts,
933 defaultValuesForInputPorts, eventBlockingForInputPorts,
934 indexOfParameter, indexOfEventParameter, constantsCache);
935 BasicBlock *block = &(function->getEntryBlock());
940 ReturnInst::Create(module->getContext(), block);
946 Value *compositionStateValue = function->arg_begin();
955 vector<VuoCompilerNode *> triggerWaitNodes = getNodesToWaitOnBeforeTransmission(trigger);
956 generateLockNodes(module, block, compositionStateValue, triggerWaitNodes, eventIdValue);
960 bool hasClaimedNodesDownstreamOfPublishedInputNode = (triggerWaitNodes.size() > 2);
961 generateSetInputDataFromNodeFunctionArguments(function, block, compositionStateValue, indexOfParameter, indexOfEventParameter,
962 ! hasClaimedNodesDownstreamOfPublishedInputNode,
true,
true);
971 Value *triggerNodeContextValue = triggerNode->
generateGetContext(module, block, compositionStateValue);
972 Value *triggerFunctionValue = trigger->
generateLoadFunction(module, block, triggerNodeContextValue);
973 CallInst::Create(triggerFunctionValue,
"", block);
982 Value *publishedOutputNodeContext = publishedOutputNode->
generateGetContext(module, block, compositionStateValue);
983 for (
size_t i = 0; i < modelOutputPorts.size(); ++i)
985 VuoPort *modelOutputPort = modelOutputPorts[i];
991 bool hasEventParameter =
false;
992 size_t eventIndex = 0;
996 size_t index = indexOfParameter[ modelOutputPort ];
999 Value *inputDataPointer = inputPort->
generateRetrieveData(module, block, publishedOutputNodeContext);
1004 map<VuoPort *, size_t>::iterator iter = indexOfEventParameter.find(modelOutputPort);
1005 if (iter != indexOfEventParameter.end())
1007 hasEventParameter =
true;
1008 eventIndex = iter->second;
1013 hasEventParameter =
true;
1014 eventIndex = indexOfParameter[ modelOutputPort ];
1017 if (hasEventParameter)
1022 new StoreInst(eventValue, outputArg, block);
1029 generateUnlockNodes(module, block, compositionStateValue, vector<VuoCompilerNode *>(1, publishedOutputNode));
1031 ReturnInst::Create(module->getContext(), block);
1039void VuoCompilerBitcodeGenerator::generateNodeInstanceInitFunction(
void)
1041 vector<VuoPort *> inputPorts;
1042 if (! isTopLevelComposition)
1043 inputPorts = modelInputPorts;
1045 map<VuoPort *, size_t> indexOfParameter;
1048 inputPorts, indexOfParameter, constantsCache);
1049 BasicBlock *block = &(function->getEntryBlock());
1051 Value *compositionStateValue = function->arg_begin();
1053 if (! isTopLevelComposition)
1054 generateSetInputDataFromNodeFunctionArguments(function, block, compositionStateValue, indexOfParameter, map<VuoPort *, size_t>(),
1055 false,
false,
false);
1061 BasicBlock *initBlock = NULL;
1062 BasicBlock *nextBlock = NULL;
1063 Value *replacementJsonValue = NULL;
1065 compositionStateValue, block, initBlock, nextBlock,
1066 constantsCache, replacementJsonValue);
1072 BranchInst::Create(nextBlock, initBlock);
1077 PointerType *instanceDataType =
static_cast<PointerType *
>( function->getReturnType() );
1078 ConstantPointerNull *nullInstanceDataValue = ConstantPointerNull::get(instanceDataType);
1079 ReturnInst::Create(module->getContext(), nullInstanceDataValue, block);
1088void VuoCompilerBitcodeGenerator::generateNodeInstanceFiniFunction(
void)
1093 BasicBlock *block = &(function->getEntryBlock());
1095 Value *compositionStateValue = function->arg_begin();
1101 BasicBlock *finiBlock = NULL;
1102 BasicBlock *nextBlock = NULL;
1103 Value *replacementJsonValue = NULL;
1105 compositionStateValue, block, finiBlock, nextBlock,
1106 constantsCache, replacementJsonValue);
1112 BranchInst::Create(nextBlock, finiBlock);
1117 ReturnInst::Create(module->getContext(), block);
1127void VuoCompilerBitcodeGenerator::generateNodeInstanceTriggerStartFunction(
void)
1129 vector<VuoPort *> inputPorts;
1130 if (! isTopLevelComposition)
1131 inputPorts = modelInputPorts;
1133 map<VuoPort *, size_t> indexOfParameter;
1136 inputPorts, indexOfParameter, constantsCache);
1137 BasicBlock *block = &(function->getEntryBlock());
1139 Value *compositionStateValue = function->arg_begin();
1141 if (! isTopLevelComposition)
1142 generateSetInputDataFromNodeFunctionArguments(function, block, compositionStateValue, indexOfParameter, map<VuoPort *, size_t>(),
1143 false,
false,
false);
1147 generateLockNodes(module, block, compositionStateValue, orderedNodes);
1158 generateUnlockNodes(module, block, compositionStateValue, orderedNodes);
1160 ReturnInst::Create(module->getContext(), block);
1168void VuoCompilerBitcodeGenerator::generateNodeInstanceTriggerStopFunction(
void)
1173 BasicBlock *block = &(function->getEntryBlock());
1175 Value *compositionStateValue = function->arg_begin();
1178 generateLockNodes(module, block, compositionStateValue, orderedNodes);
1184 generateUnlockNodes(module, block, compositionStateValue, orderedNodes);
1186 if (isTopLevelComposition)
1193 generateLockNodes(module, block, compositionStateValue, orderedNodes);
1194 generateUnlockNodes(module, block, compositionStateValue, orderedNodes);
1197 ReturnInst::Create(module->getContext(), block);
1205void VuoCompilerBitcodeGenerator::generateNodeInstanceTriggerUpdateFunction(
void)
1207 map<VuoPort *, size_t> indexOfParameter;
1210 modelInputPorts, indexOfParameter, constantsCache);
1211 BasicBlock *block = &(function->getEntryBlock());
1213 Value *compositionStateValue = function->arg_begin();
1218 ReturnInst::Create(module->getContext(), block);
1222 vector<VuoCompilerNode *> triggerWaitNodes = getNodesToWaitOnBeforeTransmission(trigger);
1223 generateLockNodes(module, block, compositionStateValue, triggerWaitNodes);
1225 bool hasClaimedNodesDownstreamOfPublishedInputNode = (triggerWaitNodes.size() > 2);
1226 generateSetInputDataFromNodeFunctionArguments(function, block, compositionStateValue, indexOfParameter, map<VuoPort *, size_t>(),
1227 ! hasClaimedNodesDownstreamOfPublishedInputNode,
true,
true);
1229 generateUnlockNodes(module, block, compositionStateValue, triggerWaitNodes);
1231 ReturnInst::Create(module->getContext(), block);
1237void VuoCompilerBitcodeGenerator::generateLockNodes(Module *module, BasicBlock *block,
1238 Value *compositionStateValue, vector<VuoCompilerNode *> nodes,
1239 Value *eventIdValue)
1247 if (nodes.size() == 1)
1249 size_t nodeIndex = nodes[0]->getIndexInOrderedNodes();
1256 vector<size_t> nodeIndices;
1257 std::transform(nodes.begin(), nodes.end(), std::back_inserter(nodeIndices), [](
VuoCompilerNode *n) { return n->getIndexInOrderedNodes(); });
1266void VuoCompilerBitcodeGenerator::generateUnlockNodes(Module *module, BasicBlock *block, Value *compositionStateValue,
1267 vector<VuoCompilerNode *> nodes)
1272 if (nodes.size() == 1)
1274 size_t nodeIndex = nodes[0]->getIndexInOrderedNodes();
1279 vector<size_t> nodeIndices;
1280 std::transform(nodes.begin(), nodes.end(), std::back_inserter(nodeIndices), [](
VuoCompilerNode *n) { return n->getIndexInOrderedNodes(); });
1350void VuoCompilerBitcodeGenerator::generateCompositionGetPortValueFunction(
void)
1354 Function::arg_iterator args = function->arg_begin();
1355 Value *compositionStateValue = args++;
1356 compositionStateValue->setName(
"compositionState");
1357 Value *portIdentifierValue = args++;
1358 portIdentifierValue->setName(
"portIdentifier");
1359 Value *serializationTypeValue = args++;
1360 serializationTypeValue->setName(
"serializationType");
1361 Value *isThreadSafeValue = args++;
1362 isThreadSafeValue->setName(
"isThreadSafe");
1367 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, 0);
1368 PointerType *pointerToCharType = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
1370 AllocaInst *retVariable =
new AllocaInst(pointerToCharType, 0,
"ret", initialBlock);
1371 ConstantPointerNull *nullPointerToChar = ConstantPointerNull::get(pointerToCharType);
1372 new StoreInst(nullPointerToChar, retVariable,
false, initialBlock);
1380 BasicBlock *checkWaitBlock = BasicBlock::Create(module->getContext(),
"checkWait", function, 0);
1381 BasicBlock *finalBlock = BasicBlock::Create(module->getContext(),
"final", function, 0);
1383 ConstantPointerNull *nullPortAddress = ConstantPointerNull::get(
static_cast<PointerType *
>(portAddressAsVoidPointer->getType()));
1384 ICmpInst *portAddressNotEqualsNull =
new ICmpInst(*initialBlock, ICmpInst::ICMP_NE, portAddressAsVoidPointer, nullPortAddress,
"");
1385 BranchInst::Create(checkWaitBlock, finalBlock, portAddressNotEqualsNull, initialBlock);
1399 BasicBlock *waitBlock = BasicBlock::Create(module->getContext(),
"wait", function, 0);
1400 BasicBlock *checkTypeIndexBlock = BasicBlock::Create(module->getContext(),
"checkTypeIndex", function, 0);
1401 ConstantInt *falseValue = ConstantInt::get(
static_cast<IntegerType *
>(isThreadSafeValue->getType()), 0);
1402 ICmpInst *isThreadSafeEqualsTrue =
new ICmpInst(*checkWaitBlock, ICmpInst::ICMP_NE, isThreadSafeValue, falseValue,
"");
1403 BranchInst::Create(waitBlock, checkTypeIndexBlock, isThreadSafeEqualsTrue, checkWaitBlock);
1407 BranchInst::Create(checkTypeIndexBlock, waitBlock);
1430 vector< pair<BasicBlock *, BasicBlock *> > blocksForIndex;
1431 for (
size_t i = 0; i < orderedTypes.size(); ++i)
1438 BasicBlock *checkSummaryBlock = BasicBlock::Create(module->getContext(), typeName +
"_checkSummary", function, 0);
1439 BasicBlock *summaryBlock = BasicBlock::Create(module->getContext(), typeName +
"_summary", function, 0);
1440 BasicBlock *checkStringBlock = NULL;
1441 BasicBlock *stringBlock = BasicBlock::Create(module->getContext(), typeName +
"_string", function, 0);
1442 BasicBlock *interprocessBlock = NULL;
1443 BasicBlock *typeFinalBlock = BasicBlock::Create(module->getContext(), typeName +
"_final", function, 0);
1445 BasicBlock *firstStringBlock = NULL;
1446 if (hasInterprocess)
1448 checkStringBlock = BasicBlock::Create(module->getContext(), typeName +
"_checkString", function, 0);
1449 interprocessBlock = BasicBlock::Create(module->getContext(), typeName +
"_interprocess", function, 0);
1450 firstStringBlock = checkStringBlock;
1454 firstStringBlock = stringBlock;
1457 ConstantInt *zeroValue = ConstantInt::get(
static_cast<IntegerType *
>(serializationTypeValue->getType()), 0);
1458 ICmpInst *serializationTypeEqualsZero =
new ICmpInst(*checkSummaryBlock, ICmpInst::ICMP_EQ, serializationTypeValue, zeroValue,
"");
1459 BranchInst::Create(summaryBlock, firstStringBlock, serializationTypeEqualsZero, checkSummaryBlock);
1462 new StoreInst(summaryValue, retVariable, summaryBlock);
1463 BranchInst::Create(typeFinalBlock, summaryBlock);
1465 if (hasInterprocess)
1467 ConstantInt *oneValue = ConstantInt::get(
static_cast<IntegerType *
>(serializationTypeValue->getType()), 1);
1468 ICmpInst *serializationTypeEqualsOne =
new ICmpInst(*checkStringBlock, ICmpInst::ICMP_EQ, serializationTypeValue, oneValue,
"");
1469 BranchInst::Create(stringBlock, interprocessBlock, serializationTypeEqualsOne, checkStringBlock);
1473 new StoreInst(stringValue, retVariable, stringBlock);
1474 BranchInst::Create(typeFinalBlock, stringBlock);
1476 if (hasInterprocess)
1479 new StoreInst(interprocessValue, retVariable, interprocessBlock);
1480 BranchInst::Create(typeFinalBlock, interprocessBlock);
1483 blocksForIndex.push_back( make_pair(checkSummaryBlock, typeFinalBlock) );
1486 BasicBlock *checkSignalBlock = BasicBlock::Create(module->getContext(),
"checkSignal", function, 0);
1493 BasicBlock *signalBlock = BasicBlock::Create(module->getContext(),
"signal", function, 0);
1494 BranchInst::Create(signalBlock, finalBlock, isThreadSafeEqualsTrue, checkSignalBlock);
1497 BranchInst::Create(finalBlock, signalBlock);
1502 LoadInst *retValue =
new LoadInst(retVariable,
"",
false, finalBlock);
1503 ReturnInst::Create(module->getContext(), retValue, finalBlock);
1589void VuoCompilerBitcodeGenerator::generateCompositionSetPortValueFunction(
void)
1593 Function::arg_iterator args = function->arg_begin();
1594 Value *compositionStateValue = args++;
1595 compositionStateValue->setName(
"compositionState");
1596 Value *portIdentifierValue = args++;
1597 portIdentifierValue->setName(
"portIdentifier");
1598 Value *valueAsStringValue = args++;
1599 valueAsStringValue->setName(
"valueAsString");
1600 Value *isThreadSafeValue = args++;
1601 isThreadSafeValue->setName(
"isThreadSafe");
1602 Value *shouldUpdateTriggersValue = args++;
1603 shouldUpdateTriggersValue->setName(
"shouldUpdateTriggers");
1604 Value *shouldSendTelemetryValue = args++;
1605 shouldSendTelemetryValue->setName(
"shouldSendTelemetry");
1606 Value *hasOldValue = args++;
1607 hasOldValue->setName(
"hasOldValue");
1608 Value *hasNewValue = args++;
1609 hasNewValue->setName(
"hasNewValue");
1614 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, 0);
1619 BasicBlock *checkWaitBlock = BasicBlock::Create(module->getContext(),
"checkWait", function, 0);
1620 BasicBlock *finalBlock = BasicBlock::Create(module->getContext(),
"final", function, 0);
1622 ConstantPointerNull *nullPortAddress = ConstantPointerNull::get(
static_cast<PointerType *
>(portAddressAsVoidPointer->getType()));
1623 ICmpInst *portAddressNotEqualsNull =
new ICmpInst(*initialBlock, ICmpInst::ICMP_NE, portAddressAsVoidPointer, nullPortAddress,
"");
1624 BranchInst::Create(checkWaitBlock, finalBlock, portAddressNotEqualsNull, initialBlock);
1634 PointerType *pointerToCharType = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
1635 AllocaInst *summaryVariable =
new AllocaInst(pointerToCharType, 0,
"summary", checkWaitBlock);
1636 ConstantPointerNull *nullSummary = ConstantPointerNull::get(pointerToCharType);
1637 new StoreInst(nullSummary, summaryVariable,
false, checkWaitBlock);
1645 BasicBlock *waitBlock = BasicBlock::Create(module->getContext(),
"wait", function, 0);
1646 BasicBlock *checkTypeIndexBlock = BasicBlock::Create(module->getContext(),
"checkTypeIndex", function, 0);
1647 ConstantInt *falseArgValue = ConstantInt::get(
static_cast<IntegerType *
>(isThreadSafeValue->getType()), 0);
1648 ICmpInst *isThreadSafeEqualsTrue =
new ICmpInst(*checkWaitBlock, ICmpInst::ICMP_NE, isThreadSafeValue, falseArgValue,
"");
1649 BranchInst::Create(waitBlock, checkTypeIndexBlock, isThreadSafeEqualsTrue, checkWaitBlock);
1653 BranchInst::Create(checkTypeIndexBlock, waitBlock);
1689 ICmpInst *hasOldValueIsTrue =
new ICmpInst(*checkTypeIndexBlock, ICmpInst::ICMP_NE, hasOldValue, falseArgValue,
"");
1690 ICmpInst *hasNewValueIsTrue =
new ICmpInst(*checkTypeIndexBlock, ICmpInst::ICMP_NE, hasNewValue, falseArgValue,
"");
1691 ICmpInst *shouldSendTelemetryIsTrue =
new ICmpInst(*checkTypeIndexBlock, ICmpInst::ICMP_NE, shouldSendTelemetryValue, falseArgValue,
"");
1693 vector< pair<BasicBlock *, BasicBlock *> > blocksForTypeIndex;
1694 for (
size_t i = 0; i < orderedTypes.size(); ++i)
1698 BasicBlock *typeInitialBlock = BasicBlock::Create(module->getContext(), type->
getBase()->
getModuleKey() +
"_initial", function, 0);
1699 BasicBlock *makeNewValueBlock = BasicBlock::Create(module->getContext(),
"makeNewValue", function, 0);
1700 BasicBlock *checkOldValueBlock = BasicBlock::Create(module->getContext(),
"checkOldValue", function, 0);
1701 BasicBlock *releaseOldValueBlock = BasicBlock::Create(module->getContext(),
"releaseOldValue", function, 0);
1702 BasicBlock *checkNewValueBlock = BasicBlock::Create(module->getContext(),
"checkNewValue", function, 0);
1703 BasicBlock *setNewValueBlock = BasicBlock::Create(module->getContext(),
"setNewValue", function, 0);
1704 BasicBlock *summaryBlock = BasicBlock::Create(module->getContext(),
"summary", function, 0);
1705 BasicBlock *typeFinalBlock = BasicBlock::Create(module->getContext(), type->
getBase()->
getModuleKey() +
"_final", function, 0);
1707 Value *portAddress = type->
convertToPortData(typeInitialBlock, portAddressAsVoidPointer);
1708 AllocaInst *newPortValueAddress =
new AllocaInst(cast<PointerType>(portAddress->getType())->getElementType(), 0,
"newPortValueAddress", typeInitialBlock);
1710 BranchInst::Create(makeNewValueBlock, checkOldValueBlock, hasNewValueIsTrue, typeInitialBlock);
1715 BranchInst::Create(checkOldValueBlock, makeNewValueBlock);
1717 BranchInst::Create(releaseOldValueBlock, checkNewValueBlock, hasOldValueIsTrue, checkOldValueBlock);
1720 BranchInst::Create(checkNewValueBlock, releaseOldValueBlock);
1722 BranchInst::Create(setNewValueBlock, typeFinalBlock, hasNewValueIsTrue, checkNewValueBlock);
1725 BranchInst::Create(summaryBlock, typeFinalBlock, shouldSendTelemetryIsTrue, setNewValueBlock);
1728 new StoreInst(summaryValue, summaryVariable,
false, summaryBlock);
1729 BranchInst::Create(typeFinalBlock, summaryBlock);
1731 blocksForTypeIndex.push_back( make_pair(typeInitialBlock, typeFinalBlock) );
1734 BasicBlock *checkUpdateBlock = BasicBlock::Create(module->getContext(),
"checkUpdate", function, 0);
1747 Constant *zeroValue = ConstantInt::get(shouldUpdateTriggersValue->getType(), 0);
1748 ICmpInst *shouldUpdateTriggersIsTrue =
new ICmpInst(*checkUpdateBlock, ICmpInst::ICMP_NE, shouldUpdateTriggersValue, zeroValue,
"");
1749 BasicBlock *updateTriggersBlock = BasicBlock::Create(module->getContext(),
"updateTriggers", function, 0);
1750 BasicBlock *checkSendBlock = BasicBlock::Create(module->getContext(),
"checkSend", function, 0);
1751 BranchInst::Create(updateTriggersBlock, checkSendBlock, shouldUpdateTriggersIsTrue, checkUpdateBlock);
1753 vector< pair<BasicBlock *, BasicBlock *> > blocksForNodeIndex;
1754 for (
size_t i = 0; i < orderedNodes.size(); ++i)
1757 BasicBlock *currentBlock = BasicBlock::Create(module->getContext(), node->
getIdentifier(), function, 0);
1758 BasicBlock *origCurrentBlock = currentBlock;
1762 generateDataOnlyTransmissionFromNode(function, currentBlock, compositionStateValue, node,
true,
true,
true);
1764 blocksForNodeIndex.push_back( make_pair(origCurrentBlock, currentBlock) );
1767 BasicBlock *checkSignalBlock = BasicBlock::Create(module->getContext(),
"checkSignal", function, 0);
1774 BasicBlock *signalBlock = BasicBlock::Create(module->getContext(),
"signal", function, 0);
1775 BranchInst::Create(signalBlock, checkSendBlock, isThreadSafeEqualsTrue, checkSignalBlock);
1778 BranchInst::Create(checkSendBlock, signalBlock);
1787 BasicBlock *sendBlock = BasicBlock::Create(module->getContext(),
"send", function, 0);
1788 BranchInst::Create(sendBlock, finalBlock, shouldSendTelemetryIsTrue, checkSendBlock);
1790 Value *summaryValue =
new LoadInst(summaryVariable,
"",
false, sendBlock);
1793 false,
true, summaryValue);
1796 BranchInst::Create(finalBlock, sendBlock);
1798 ReturnInst::Create(module->getContext(), finalBlock);
1806void VuoCompilerBitcodeGenerator::generateSetInputPortValueFunction(
void)
1809 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, NULL);
1811 Function::arg_iterator args = function->arg_begin();
1812 Value *portIdentifierValue = args++;
1813 portIdentifierValue->setName(
"portIdentifier");
1814 Value *valueAsStringValue = args++;
1815 valueAsStringValue->setName(
"valueAsString");
1823 Value *trueValue = ConstantInt::get(compositionSetPortValueFunction->getFunctionType()->getParamType(3), 1);
1825 vector<Value *> compositionArgs;
1826 compositionArgs.push_back(compositionStateValue);
1827 compositionArgs.push_back(portIdentifierValue);
1828 compositionArgs.push_back(valueAsStringValue);
1829 compositionArgs.push_back(trueValue);
1830 compositionArgs.push_back(trueValue);
1831 compositionArgs.push_back(trueValue);
1832 compositionArgs.push_back(trueValue);
1833 compositionArgs.push_back(trueValue);
1834 CallInst::Create(compositionSetPortValueFunction, compositionArgs,
"", block);
1838 ReturnInst::Create(module->getContext(), block);
1860void VuoCompilerBitcodeGenerator::generateCompositionFireTriggerPortEventFunction(
void)
1864 Function::arg_iterator args = function->arg_begin();
1865 Value *compositionStateValue = args++;
1866 compositionStateValue->setName(
"compositionState");
1867 Value *portIdentifierValue = args++;
1868 portIdentifierValue->setName(
"portIdentifier");
1870 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, 0);
1872 map<string, pair<BasicBlock *, BasicBlock *> > blocksForString;
1879 BasicBlock *currentBlock = BasicBlock::Create(module->getContext(), currentPortIdentifier, function, 0);
1880 BasicBlock *origCurrentBlock = currentBlock;
1882 Value *nodeContextValue = triggerNode->
generateGetContext(module, currentBlock, compositionStateValue);
1883 Value *triggerFunctionValue = trigger->
generateLoadFunction(module, currentBlock, nodeContextValue);
1885 vector<Value *> triggerArgs;
1889 generateLockNodes(module, currentBlock, compositionStateValue, vector<VuoCompilerNode *>(1, triggerNode));
1897 CallInst *call = CallInst::Create(triggerFunctionValue, triggerArgs,
"", currentBlock);
1903 generateUnlockNodes(module, currentBlock, compositionStateValue, vector<VuoCompilerNode *>(1, triggerNode));
1906 blocksForString[currentPortIdentifier] = make_pair(origCurrentBlock, currentBlock);
1909 BasicBlock *finalBlock = BasicBlock::Create(module->getContext(),
"final", function, 0);
1911 ReturnInst::Create(module->getContext(), finalBlock);
1931void VuoCompilerBitcodeGenerator::generateGetPublishedPortCountFunction(
bool input)
1934 string functionName;
1938 functionName =
"getPublishedInputPortCount";
1943 functionName =
"getPublishedOutputPortCount";
1946 Function *function =
module->getFunction(functionName);
1949 vector<Type *> functionParams;
1950 FunctionType *functionType = FunctionType::get(IntegerType::get(module->getContext(), 32), functionParams,
false);
1951 function = Function::Create(functionType, GlobalValue::ExternalLinkage, functionName, module);
1954 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, 0);
1955 ConstantInt *countConstant = ConstantInt::get(module->getContext(), APInt(32, count));
1956 ReturnInst::Create(module->getContext(), countConstant, block);
1974void VuoCompilerBitcodeGenerator::generateGetPublishedPortNamesFunction(
bool input)
1976 string functionName;
1977 vector<VuoPublishedPort *> publishedPorts;
1980 functionName =
"getPublishedInputPortNames";
1985 functionName =
"getPublishedOutputPortNames";
1989 vector<string> names;
1990 for (vector<VuoPublishedPort *>::iterator i = publishedPorts.begin(); i != publishedPorts.end(); ++i)
1992 names.push_back( (*i)->getClass()->getName() );
1995 generateFunctionReturningStringArray(functionName, names);
2013void VuoCompilerBitcodeGenerator::generateGetPublishedPortTypesFunction(
bool input)
2015 string functionName;
2016 vector<VuoPublishedPort *> publishedPorts;
2019 functionName =
"getPublishedInputPortTypes";
2024 functionName =
"getPublishedOutputPortTypes";
2028 vector<string> types;
2029 for (vector<VuoPublishedPort *>::iterator i = publishedPorts.begin(); i != publishedPorts.end(); ++i)
2035 types.push_back(typeName);
2038 generateFunctionReturningStringArray(functionName, types);
2056void VuoCompilerBitcodeGenerator::generateGetPublishedPortDetailsFunction(
bool input)
2058 string functionName;
2059 vector<VuoPublishedPort *> publishedPorts;
2062 functionName =
"getPublishedInputPortDetails";
2067 functionName =
"getPublishedOutputPortDetails";
2071 vector<string> details;
2072 for (vector<VuoPublishedPort *>::iterator i = publishedPorts.begin(); i != publishedPorts.end(); ++i)
2076 json_object *detailsObj = publishedPort->
getDetails(input);
2077 string detailsSerialized = json_object_to_json_string_ext(detailsObj, JSON_C_TO_STRING_PLAIN);
2078 details.push_back(detailsSerialized);
2080 json_object_put(detailsObj);
2083 generateFunctionReturningStringArray(functionName, details);
2092void VuoCompilerBitcodeGenerator::generateFunctionReturningStringArray(
string functionName, vector<string> stringValues)
2094 Function *function =
module->getFunction(functionName);
2097 PointerType *pointerToChar = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
2098 PointerType *pointerToPointerToChar = PointerType::get(pointerToChar, 0);
2099 vector<Type *> functionParams;
2100 FunctionType *functionType = FunctionType::get(pointerToPointerToChar, functionParams,
false);
2101 function = Function::Create(functionType, GlobalValue::ExternalLinkage, functionName, module);
2104 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, 0);
2107 ReturnInst::Create(module->getContext(), stringArrayGlobalPointer, block);
2119void VuoCompilerBitcodeGenerator::generateFirePublishedInputPortEventFunction(
void)
2121 string functionName =
"firePublishedInputPortEvent";
2122 Function *function =
module->getFunction(functionName);
2123 PointerType *pointerToChar = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
2126 PointerType *pointerToPointerToChar = PointerType::get(pointerToChar, 0);
2127 Type *countType = IntegerType::get(module->getContext(), 32);
2129 vector<Type *> functionParams;
2130 functionParams.push_back(pointerToPointerToChar);
2131 functionParams.push_back(countType);
2132 FunctionType *functionType = FunctionType::get(Type::getVoidTy(module->getContext()), functionParams,
false);
2133 function = Function::Create(functionType, GlobalValue::ExternalLinkage, functionName, module);
2136 Function::arg_iterator args = function->arg_begin();
2137 Value *namesValue = args++;
2138 namesValue->setName(
"names");
2139 Value *countValue = args++;
2140 countValue->setName(
"count");
2142 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, 0);
2147 ReturnInst::Create(module->getContext(), initialBlock);
2156 compositionIdentifierValue);
2165 vector<VuoCompilerNode *> triggerWaitNodes = getNodesToWaitOnBeforeTransmission(trigger);
2168 if (find(triggerWaitNodes.begin(), triggerWaitNodes.end(), publishedOutputNode) == triggerWaitNodes.end())
2169 triggerWaitNodes.push_back(publishedOutputNode);
2171 generateLockNodes(module, initialBlock, compositionStateValue, triggerWaitNodes, eventIdValue);
2196 Value *publishedInputNodeContextValue = publishedInputNode->
generateGetContext(module, initialBlock, compositionStateValue);
2198 Value *zeroValue = ConstantInt::get(
static_cast<IntegerType *
>(countValue->getType()), 0);
2199 AllocaInst *iterVariable =
new AllocaInst(countValue->getType(), 0,
"i", initialBlock);
2200 new StoreInst(zeroValue, iterVariable,
false, initialBlock);
2202 BasicBlock *loopConditionBlock = BasicBlock::Create(module->getContext(),
"loopCondition", function, 0);
2203 BasicBlock *loopBeginBlock = BasicBlock::Create(module->getContext(),
"loopBegin", function, 0);
2204 BasicBlock *loopEndBlock = BasicBlock::Create(module->getContext(),
"loopEnd", function, 0);
2205 BasicBlock *fireBlock = BasicBlock::Create(module->getContext(),
"fire", function, 0);
2207 BranchInst::Create(loopConditionBlock, initialBlock);
2209 Value *iterValue =
new LoadInst(iterVariable,
"",
false, loopConditionBlock);
2210 ICmpInst *iterLessThanCount =
new ICmpInst(*loopConditionBlock, ICmpInst::ICMP_ULT, iterValue, countValue,
"");
2211 BranchInst::Create(loopBeginBlock, fireBlock, iterLessThanCount, loopConditionBlock);
2215 map<string, pair<BasicBlock *, BasicBlock *> > blocksForString;
2218 for (
size_t i = 0; i < publishedInputPorts.size(); ++i)
2220 string currentName = publishedInputPorts[i]->getClass()->getName();
2221 BasicBlock *currentBlock = BasicBlock::Create(module->getContext(), currentName, function, 0);
2225 inputEventPort->
generateStoreEvent(module, currentBlock, publishedInputNodeContextValue,
true);
2227 blocksForString[currentName] = make_pair(currentBlock, currentBlock);
2232 Value *oneValue = ConstantInt::get(
static_cast<IntegerType *
>(countValue->getType()), 1);
2233 Value *iterPlusOneValue = BinaryOperator::Create(Instruction::Add, iterValue, oneValue,
"", loopEndBlock);
2234 new StoreInst(iterPlusOneValue, iterVariable,
false, loopEndBlock);
2236 BranchInst::Create(loopConditionBlock, loopEndBlock);
2240 Value *triggerNodeContextValue = triggerNode->
generateGetContext(module, fireBlock, compositionStateValue);
2241 Value *triggerFunctionValue = trigger->
generateLoadFunction(module, fireBlock, triggerNodeContextValue);
2242 CallInst::Create(triggerFunctionValue,
"", fireBlock);
2246 ReturnInst::Create(module->getContext(), fireBlock);
2288void VuoCompilerBitcodeGenerator::generateGetPublishedPortValueFunction(
bool input)
2290 Function *function = (input ?
2294 Function::arg_iterator args = function->arg_begin();
2295 Value *portIdentifierValue = args++;
2296 portIdentifierValue->setName(
"portIdentifier");
2297 Value *shouldUseInterprocessSerializationValue = args++;
2298 shouldUseInterprocessSerializationValue->setName(
"shouldUseInterprocessSerialization");
2300 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, 0);
2301 PointerType *pointerToChar = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
2302 AllocaInst *retVariable =
new AllocaInst(pointerToChar, 0,
"ret", initialBlock);
2303 ConstantPointerNull *nullValue = ConstantPointerNull::get(pointerToChar);
2304 new StoreInst(nullValue, retVariable,
false, initialBlock);
2309 compositionIdentifierValue);
2311 vector<VuoPort *> inputPortsOnPublishedNode;
2315 for (
size_t i = 0; i < publishedPorts.size(); ++i)
2318 inputPortsOnPublishedNode.push_back(port);
2324 for (
size_t i = 0; i < publishedPorts.size(); ++i)
2327 inputPortsOnPublishedNode.push_back(port);
2331 map<string, pair<BasicBlock *, BasicBlock *> > blocksForString;
2332 for (
VuoPort *port : inputPortsOnPublishedNode)
2335 BasicBlock *currentBlock = BasicBlock::Create(module->getContext(), currentName, function, 0);
2338 Constant *currentIdentifierValue = constantsCache->
get(currentIdentifier);
2341 currentIdentifierValue, shouldUseInterprocessSerializationValue);
2342 new StoreInst(retValue, retVariable, currentBlock);
2344 blocksForString[currentName] = make_pair(currentBlock, currentBlock);
2347 BasicBlock *finalBlock = BasicBlock::Create(module->getContext(),
"final", function, 0);
2351 LoadInst *retValue =
new LoadInst(retVariable,
"",
false, finalBlock);
2352 ReturnInst::Create(module->getContext(), retValue, finalBlock);
2368void VuoCompilerBitcodeGenerator::generateCompositionSetPublishedInputPortValueFunction(
void)
2372 Function::arg_iterator args = function->arg_begin();
2373 Value *compositionStateValue = args++;
2374 compositionStateValue->setName(
"compositionState");
2375 Value *publishedInputPortNameValue = args++;
2376 publishedInputPortNameValue->setName(
"publishedInputPortName");
2377 Value *valueAsStringValue = args++;
2378 valueAsStringValue->setName(
"valueAsString");
2379 Value *isCompositionRunningValue = args++;
2380 isCompositionRunningValue->setName(
"isCompositionRunning");
2382 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, 0);
2387 ReturnInst::Create(module->getContext(), initialBlock);
2393 PointerType *pointerToCharType = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
2394 AllocaInst *inputPortIdentifierVariable =
new AllocaInst(pointerToCharType, 0,
"inputPortIdentifier", initialBlock);
2395 ConstantPointerNull *nullInputPortIdentifier = ConstantPointerNull::get(pointerToCharType);
2396 new StoreInst(nullInputPortIdentifier, inputPortIdentifierVariable,
false, initialBlock);
2404 map<string, pair<BasicBlock *, BasicBlock *> > blocksForString;
2406 for (
size_t i = 0; i < publishedInputPorts.size(); ++i)
2408 string currPublishedInputPortName = publishedInputPorts[i]->getClass()->getName();
2409 BasicBlock *currBlock = BasicBlock::Create(module->getContext(), currPublishedInputPortName, function, 0);
2413 Value *inputPortIdentifierValue = constantsCache->
get(inputPortIdentifier);
2415 new StoreInst(inputPortIdentifierValue, inputPortIdentifierVariable,
false, currBlock);
2417 blocksForString[currPublishedInputPortName] = make_pair(currBlock, currBlock);
2420 BasicBlock *checkBlock = BasicBlock::Create(module->getContext(),
"check", function, 0);
2421 BasicBlock *scheduleBlock = BasicBlock::Create(module->getContext(),
"schedule", function, 0);
2422 BasicBlock *finalBlock = BasicBlock::Create(module->getContext(),
"final", function, 0);
2429 Value *inputPortIdentifierValue =
new LoadInst(inputPortIdentifierVariable,
"",
false, checkBlock);
2430 ICmpInst *portIdentifierNotEqualsNull =
new ICmpInst(*checkBlock, ICmpInst::ICMP_NE, inputPortIdentifierValue, nullInputPortIdentifier,
"");
2431 BranchInst::Create(scheduleBlock, finalBlock, portIdentifierNotEqualsNull, checkBlock);
2440 inputPortIdentifierValue, valueAsStringValue,
2441 isCompositionRunningValue);
2447 Value *nodeContextValue = triggerNode->
generateGetContext(module, scheduleBlock, compositionStateValue);
2451 workerFunctionName, contextValue);
2453 BranchInst::Create(finalBlock, scheduleBlock);
2454 ReturnInst::Create(module->getContext(), finalBlock);
2461 Function::arg_iterator workerArgs = workerFunction->arg_begin();
2462 Value *contextValueInWorker = workerArgs++;
2463 contextValueInWorker->setName(
"context");
2465 BasicBlock *workerBlock = BasicBlock::Create(module->getContext(),
"", workerFunction, 0);
2472 Type *voidPointerType = contextValueInWorker->getType();
2473 Type *voidPointerPointerType = PointerType::get(voidPointerType, 0);
2475 Type *boolType = compositionSetPortValueFunction->getFunctionType()->getParamType(3);
2477 Value *contextValueAsVoidPointerArray =
new BitCastInst(contextValueInWorker, voidPointerPointerType,
"", workerBlock);
2479 Value *compositionStateValueInWorker =
new BitCastInst(compositionStateAsVoidPointer, compositionStatePointerType,
"", workerBlock);
2482 Value *inputPortIdentifierValueInWorker =
new BitCastInst(inputPortIdentifierAsVoidPointer, pointerToCharType,
"", workerBlock);
2485 Value *valueAsStringValueInWorker =
new BitCastInst(valueAsStringValueAsVoidPointer, pointerToCharType,
"", workerBlock);
2488 Value *isCompositionRunningValueInWorker =
new PtrToIntInst(isCompositionRunningValueAsVoidPointer, boolType,
"", workerBlock);
2497 Value *trueValue = ConstantInt::get(boolType, 1);
2499 vector<Value *> setValueArgs;
2500 setValueArgs.push_back(compositionStateValueInWorker);
2501 setValueArgs.push_back(inputPortIdentifierValueInWorker);
2502 setValueArgs.push_back(valueAsStringValueInWorker);
2503 setValueArgs.push_back(isCompositionRunningValueInWorker);
2504 setValueArgs.push_back(isCompositionRunningValueInWorker);
2505 setValueArgs.push_back(isCompositionRunningValueInWorker);
2506 setValueArgs.push_back(trueValue);
2507 setValueArgs.push_back(trueValue);
2508 CallInst::Create(compositionSetPortValueFunction, setValueArgs,
"", workerBlock);
2510 ReturnInst::Create(module->getContext(), workerBlock);
2520void VuoCompilerBitcodeGenerator::generateSetPublishedInputPortValueFunction(
void)
2524 Function::arg_iterator args = function->arg_begin();
2525 Value *publishedInputPortNameValue = args++;
2526 publishedInputPortNameValue->setName(
"publishedInputPortName");
2527 Value *valueAsStringValue = args++;
2528 valueAsStringValue->setName(
"valueAsString");
2530 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, NULL);
2537 Value *trueValue = ConstantInt::get(compositionFunction->getFunctionType()->getParamType(3), 1);
2539 vector<Value *> compositionArgs;
2540 compositionArgs.push_back(compositionStateValue);
2541 compositionArgs.push_back(publishedInputPortNameValue);
2542 compositionArgs.push_back(valueAsStringValue);
2543 compositionArgs.push_back(trueValue);
2544 CallInst::Create(compositionFunction, compositionArgs,
"", block);
2548 ReturnInst::Create(module->getContext(), block);
2555void VuoCompilerBitcodeGenerator::generateTransmissionFromOutputPort(Function *function, BasicBlock *¤tBlock,
2556 Value *compositionStateValue,
2558 Value *eventValue, Value *dataPointer,
2559 bool requiresEvent,
bool shouldSendTelemetry)
2561 IntegerType *boolType = IntegerType::get(module->getContext(), 1);
2562 PointerType *pointerToCharType = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
2566 Constant *trueValue = ConstantInt::get(boolType, 1);
2567 Constant *falseValue = ConstantInt::get(boolType, 0);
2568 Constant *transmittedEventValue = (requiresEvent ? trueValue : falseValue);
2571 AllocaInst *dataSummaryVariable =
new AllocaInst(pointerToCharType, 0,
"dataSummary", currentBlock);
2572 new StoreInst(ConstantPointerNull::get(pointerToCharType), dataSummaryVariable, currentBlock);
2574 map<VuoCompilerPort *, ICmpInst *> shouldSummarizeInput;
2575 if (shouldSendTelemetry)
2578 AllocaInst *sentDataVariable =
new AllocaInst(boolType, 0,
"sentData", currentBlock);
2579 new StoreInst(falseValue, sentDataVariable, currentBlock);
2581 for (set<VuoCompilerCable *>::iterator i = outgoingCables.begin(); i != outgoingCables.end(); ++i)
2588 compositionStateValue,
2590 shouldSummarizeInput[inputPort] = shouldSendDataForInput;
2597 compositionStateValue,
2600 for (set<VuoCompilerCable *>::iterator i = outgoingCables.begin(); i != outgoingCables.end(); ++i)
2607 shouldSummarizeOutput = BinaryOperator::Create(Instruction::Or, shouldSummarizeOutput, shouldSummarizeInput[inputPort],
"", currentBlock);
2611 BasicBlock *summaryBlock = BasicBlock::Create(module->getContext(),
"outputSummary", function, NULL);
2612 BasicBlock *sendOutputBlock = BasicBlock::Create(module->getContext(),
"sendOutput", function, NULL);
2613 BranchInst::Create(summaryBlock, sendOutputBlock, shouldSummarizeOutput, currentBlock);
2616 new StoreInst(trueValue, sentDataVariable, summaryBlock);
2621 new StoreInst(dataSummaryValue, dataSummaryVariable, summaryBlock);
2623 BranchInst::Create(sendOutputBlock, summaryBlock);
2624 currentBlock = sendOutputBlock;
2629 Value *sentDataValue =
new LoadInst(sentDataVariable,
"",
false, currentBlock);
2630 Value *dataSummaryValue =
new LoadInst(dataSummaryVariable,
"",
false, currentBlock);
2632 Constant *outputPortIdentifierValue = constantsCache->
get(outputPort->
getIdentifier());
2635 transmittedEventValue, sentDataValue, dataSummaryValue);
2641 BasicBlock *transmissionBlock = NULL;
2642 BasicBlock *noTransmissionBlock = NULL;
2643 if (alwaysTransmitsEvent)
2645 transmissionBlock = currentBlock;
2649 transmissionBlock = BasicBlock::Create(module->getContext(),
"transmission", function, NULL);
2650 noTransmissionBlock = BasicBlock::Create(module->getContext(),
"noTransmission", function, NULL);
2652 ConstantInt *zeroValue = ConstantInt::get(
static_cast<IntegerType *
>(eventValue->getType()), 0);
2653 ICmpInst *eventValueIsTrue =
new ICmpInst(*currentBlock, ICmpInst::ICMP_NE, eventValue, zeroValue,
"");
2654 BranchInst::Create(transmissionBlock, noTransmissionBlock, eventValueIsTrue, currentBlock);
2658 for (set<VuoCompilerCable *>::iterator i = outgoingCables.begin(); i != outgoingCables.end(); ++i)
2663 Value *inputNodeContextValue = inputNode->
generateGetContext(module, transmissionBlock, compositionStateValue);
2665 Value *inputPortContextValue = inputPort->
generateGetPortContext(module, transmissionBlock, inputNodeContextValue);
2667 Value *transmittedDataPointer = (cable->
carriesData() ? dataPointer : NULL);
2669 cable->
generateTransmission(module, transmissionBlock, inputNodeContextValue, inputPortContextValue, transmittedDataPointer, requiresEvent);
2674 AllocaInst *inputDataSummaryVariable =
new AllocaInst(pointerToCharType, 0,
"inputDataSummary", transmissionBlock);
2675 new StoreInst(ConstantPointerNull::get(pointerToCharType), inputDataSummaryVariable, transmissionBlock);
2678 AllocaInst *receivedDataVariable =
new AllocaInst(boolType, 0,
"receivedData", transmissionBlock);
2679 new StoreInst(falseValue, receivedDataVariable, transmissionBlock);
2684 BasicBlock *summaryBlock = BasicBlock::Create(module->getContext(),
"inputSummary", function, NULL);
2685 BasicBlock *sendInputBlock = BasicBlock::Create(module->getContext(),
"sendInput", function, NULL);
2686 BranchInst::Create(summaryBlock, sendInputBlock, shouldSummarizeInput[inputPort], transmissionBlock);
2688 Value *inputDataSummaryValue;
2689 if (transmittedDataPointer)
2692 new StoreInst(trueValue, receivedDataVariable, summaryBlock);
2695 inputDataSummaryValue =
new LoadInst(dataSummaryVariable,
"",
false, summaryBlock);
2703 new StoreInst(inputDataSummaryValue, inputDataSummaryVariable, summaryBlock);
2705 BranchInst::Create(sendInputBlock, summaryBlock);
2706 transmissionBlock = sendInputBlock;
2709 Value *receivedDataValue =
new LoadInst(receivedDataVariable,
"",
false, transmissionBlock);
2710 Value *inputDataSummaryValue =
new LoadInst(inputDataSummaryVariable,
"",
false, transmissionBlock);
2712 Constant *inputPortIdentifierValue = constantsCache->
get(inputPort->
getIdentifier());
2715 transmittedEventValue, receivedDataValue, inputDataSummaryValue);
2717 if (inputDataType && ! transmittedDataPointer)
2725 if (alwaysTransmitsEvent)
2727 currentBlock = transmissionBlock;
2731 BranchInst::Create(noTransmissionBlock, transmissionBlock);
2732 currentBlock = noTransmissionBlock;
2735 if (shouldSendTelemetry && dataPointer)
2739 LoadInst *dataSummaryValue =
new LoadInst(dataSummaryVariable,
"",
false, currentBlock);
2740 CallInst::Create(freeFunction, dataSummaryValue,
"", currentBlock);
2748void VuoCompilerBitcodeGenerator::generateTransmissionFromNode(Function *function, BasicBlock *¤tBlock,
2749 Value *compositionStateValue, Value *nodeContextValue,
2753 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
2757 if (! outputEventPort)
2760 Value *portContextValue = outputEventPort->
generateGetPortContext(module, currentBlock, nodeContextValue);
2761 Value *outputEventValue = outputEventPort->
generateLoadEvent(module, currentBlock, nodeContextValue, portContextValue);
2763 BasicBlock *telemetryBlock = NULL;
2764 BasicBlock *noTelemetryBlock = NULL;
2767 telemetryBlock = BasicBlock::Create(module->getContext(),
"", function, NULL);
2768 noTelemetryBlock = BasicBlock::Create(module->getContext(),
"", function, NULL);
2771 ConstantInt *zeroValue = ConstantInt::get(
static_cast<IntegerType *
>(outputEventValue->getType()), 0);
2772 ICmpInst *eventValueIsTrue =
new ICmpInst(*currentBlock, ICmpInst::ICMP_NE, outputEventValue, zeroValue,
"");
2773 BranchInst::Create(telemetryBlock, noTelemetryBlock, eventValueIsTrue, currentBlock);
2777 telemetryBlock = currentBlock;
2782 Value *outputDataPointer = (outputData ?
2783 outputEventPort->
generateRetrieveData(module, telemetryBlock, nodeContextValue, portContextValue) :
2785 generateTransmissionFromOutputPort(function, telemetryBlock, compositionStateValue,
2786 node, outputEventPort, outputEventValue, outputDataPointer, requiresEvent, shouldSendTelemetry);
2790 BranchInst::Create(noTelemetryBlock, telemetryBlock);
2791 currentBlock = noTelemetryBlock;
2795 currentBlock = telemetryBlock;
2804void VuoCompilerBitcodeGenerator::generateTelemetryFromPublishedOutputNode(Function *function, BasicBlock *¤tBlock, Value *compositionStateValue,
2807 IntegerType *boolType = IntegerType::get(module->getContext(), 1);
2808 PointerType *pointerToCharType = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
2810 for (
auto inputPort : node->getBase()->getInputPorts())
2818 BasicBlock *telemetryBlock = BasicBlock::Create(module->getContext(),
"", function, NULL);
2819 BasicBlock *noTelemetryBlock = BasicBlock::Create(module->getContext(),
"", function, NULL);
2822 Value *eventValue = inputEventPort->
generateLoadEvent(module, currentBlock, nodeContextValue);
2823 ConstantInt *zeroValue = ConstantInt::get(
static_cast<IntegerType *
>(eventValue->getType()), 0);
2824 ICmpInst *eventValueIsTrue =
new ICmpInst(*currentBlock, ICmpInst::ICMP_NE, eventValue, zeroValue,
"");
2825 BranchInst::Create(telemetryBlock, noTelemetryBlock, eventValueIsTrue, currentBlock);
2828 Value *dataPointer = data ? inputEventPort->
generateRetrieveData(module, telemetryBlock, nodeContextValue) : NULL;
2829 Constant *trueValue = ConstantInt::get(boolType, 1);
2830 Constant *falseValue = ConstantInt::get(boolType, 0);
2832 Value *sentDataValue = NULL;
2833 Value *dataSummaryValue = NULL;
2837 sentDataValue = trueValue;
2846 sentDataValue = falseValue;
2849 dataSummaryValue = ConstantPointerNull::get(pointerToCharType);
2854 sentDataValue, dataSummaryValue);
2858 BranchInst::Create(noTelemetryBlock, telemetryBlock);
2859 currentBlock = noTelemetryBlock;
2869void VuoCompilerBitcodeGenerator::generateDataOnlyTransmissionFromNode(Function *function, BasicBlock *¤tBlock, Value *compositionStateValue,
2871 bool shouldUpdateTriggers,
bool shouldSendTelemetry)
2874 if (downstreamNodes.empty())
2877 if (shouldWaitForDownstreamNodes)
2880 generateLockNodes(module, currentBlock, compositionStateValue, downstreamNodes,
nullptr);
2884 vector<VuoCompilerNode *> nodesToVisit = downstreamNodes;
2885 nodesToVisit.insert(nodesToVisit.begin(), node);
2890 Value *nodeContextValue = visitedNode->generateGetContext(module, currentBlock, compositionStateValue);
2893 vector<VuoPort *> inputPorts = visitedNode->getBase()->getInputPorts();
2901 generateNodeExecution(currentBlock, compositionStateValue, visitedNode,
false);
2904 generateTransmissionFromNode(function, currentBlock, compositionStateValue, nodeContextValue, visitedNode,
false, shouldSendTelemetry);
2910 if (visitedNode != node)
2912 if (shouldUpdateTriggers)
2915 visitedNode->generateCallbackUpdateFunctionCall(module, currentBlock, compositionStateValue);
2918 if (shouldWaitForDownstreamNodes)
2921 generateUnlockNodes(module, currentBlock, compositionStateValue, vector<VuoCompilerNode *>(1, visitedNode));
2930void VuoCompilerBitcodeGenerator::generateNodeExecution(BasicBlock *block, Value *compositionStateValue,
VuoCompilerNode *node,
2931 bool shouldSendTelemetry)
2935 if (shouldSendTelemetry)
2944 if (shouldSendTelemetry)
2954void VuoCompilerBitcodeGenerator::generateAllocation(
void)
2957 generateAllocation_Pro();
2962 new GlobalVariable(*module, value->getType(),
true, GlobalValue::ExternalLinkage, value,
"vuoTopLevelCompositionIdentifier");
2973void VuoCompilerBitcodeGenerator::generateSetupFunction(
bool isStatefulComposition)
2976 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, NULL);
2985 CallInst::Create(compositionCreateAndRegisterMetadataFunction, topLevelCompositionStateValue,
"", block);
2991 isStatefulComposition, publishedOutputPortCount);
2996 Value *falseValue = ConstantInt::get(compositionSetPublishedInputPortValueFunction->getFunctionType()->getParamType(3), 0);
2998 for (
VuoPublishedPort *publishedInputPort : composition->getBase()->getPublishedInputPorts())
3003 vector<Value *> args;
3004 args.push_back(topLevelCompositionStateValue);
3005 args.push_back( constantsCache->
get(name) );
3006 args.push_back( constantsCache->
get(initialValue) );
3007 args.push_back(falseValue);
3008 CallInst::Create(compositionSetPublishedInputPortValueFunction, args,
"", block);
3014 CallInst::Create(compositionPerformDataOnlyTransmissionsFunction, topLevelCompositionStateValue,
"", block);
3018 for (map<VuoCompilerTriggerPort *, Function *>::iterator i = topLevelTriggerFunctions.begin(); i != topLevelTriggerFunctions.end(); ++i)
3021 Function *function = i->second;
3024 Value *nodeContextValue = node->
generateGetContext(module, block, topLevelCompositionStateValue);
3030 for (map<
string, map<
size_t, map<VuoCompilerTriggerDescription *, Function *> > >::iterator i = subcompositionTriggerFunctions.begin(); i != subcompositionTriggerFunctions.end(); ++i)
3032 string compositionIdentifier = i->first;
3034 for (map<
size_t, map<VuoCompilerTriggerDescription *, Function *> >::iterator j = i->second.begin(); j != i->second.end(); ++j)
3036 size_t nodeIndex = j->first;
3038 for (map<VuoCompilerTriggerDescription *, Function *>::iterator k = j->second.begin(); k != j->second.end(); ++k)
3041 Function *function = k->second;
3043 Value *compositionIdentifierValue = constantsCache->
get(compositionIdentifier);
3058 ReturnInst::Create(module->getContext(), block);
3067void VuoCompilerBitcodeGenerator::generateCleanupFunction(
void)
3070 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, NULL);
3080 ReturnInst::Create(module->getContext(), block);
3088void VuoCompilerBitcodeGenerator::generateInstanceInitFunction(
bool isStatefulComposition)
3091 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, NULL);
3093 if (isStatefulComposition)
3095 map<VuoPort *, size_t> indexOfParameter;
3098 vector<VuoPort *>(),
3099 indexOfParameter, constantsCache);
3105 CallInst::Create(nodeInstanceInitFunction, topLevelCompositionStateValue,
"", block);
3110 ReturnInst::Create(module->getContext(), block);
3118void VuoCompilerBitcodeGenerator::generateInstanceFiniFunction(
bool isStatefulComposition)
3121 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, NULL);
3123 if (isStatefulComposition)
3133 PointerType *instanceDataType =
static_cast<PointerType *
>( nodeInstanceFiniFunction->getFunctionType()->getParamType(1) );
3134 ConstantPointerNull *nullInstanceDataValue = ConstantPointerNull::get(instanceDataType);
3136 vector<Value *> args;
3137 args.push_back(topLevelCompositionStateValue);
3138 args.push_back(nullInstanceDataValue);
3139 CallInst::Create(nodeInstanceFiniFunction, args,
"", block);
3144 ReturnInst::Create(module->getContext(), block);
3152void VuoCompilerBitcodeGenerator::generateInstanceTriggerStartFunction(
bool isStatefulComposition)
3155 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, NULL);
3157 if (isStatefulComposition)
3159 map<VuoPort *, size_t> indexOfParameter;
3162 vector<VuoPort *>(),
3170 PointerType *instanceDataType =
static_cast<PointerType *
>( nodeInstanceTriggerStartFunction->getFunctionType()->getParamType(1) );
3171 ConstantPointerNull *nullInstanceDataValue = ConstantPointerNull::get(instanceDataType);
3173 vector<Value *> args;
3174 args.push_back(topLevelCompositionStateValue);
3175 args.push_back(nullInstanceDataValue);
3176 CallInst::Create(nodeInstanceTriggerStartFunction, args,
"", block);
3181 ReturnInst::Create(module->getContext(), block);
3189void VuoCompilerBitcodeGenerator::generateInstanceTriggerStopFunction(
bool isStatefulComposition)
3192 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function, NULL);
3203 PointerType *instanceDataType =
static_cast<PointerType *
>( nodeInstanceTriggerStopFunction->getFunctionType()->getParamType(1) );
3204 ConstantPointerNull *nullInstanceDataValue = ConstantPointerNull::get(instanceDataType);
3206 vector<Value *> args;
3207 args.push_back(topLevelCompositionStateValue);
3208 args.push_back(nullInstanceDataValue);
3209 CallInst::Create(nodeInstanceTriggerStopFunction, args,
"", block);
3214 ReturnInst::Create(module->getContext(), block);
3222void VuoCompilerBitcodeGenerator::generateTriggerFunctions(
void)
3224 auto isSpinOffTrigger = [] (
const string &nodeClassName)
3231 map<VuoCompilerTriggerPort *, Function *> workerFunctionForTrigger;
3234 Function *workerFunction = generateTriggerWorkerFunction(trigger);
3235 workerFunctionForTrigger[trigger] = workerFunction;
3238 if (isTopLevelComposition)
3240 for (map<VuoCompilerTriggerPort *, Function *>::iterator i = workerFunctionForTrigger.begin(); i != workerFunctionForTrigger.end(); ++i)
3243 Function *workerFunction = i->second;
3260 int minThreadsNeeded, maxThreadsNeeded;
3263 int chainCount = (int)graph->
getChains()[trigger].size();
3266 portIdentifier, portContextIndex, canDropEvents, isPublishedTrigger, isSpinOff,
3267 minThreadsNeeded, maxThreadsNeeded, chainCount, workerFunction);
3268 topLevelTriggerFunctions[trigger] = function;
3279 for (vector<VuoCompilerTriggerDescription *>::iterator j = triggers.begin(); j != triggers.end(); ++j)
3294 string fullSubcompositionNodeIdentifier = (subcompositionNodeIdentifier.empty() ?
3301 int minThreadsNeeded, maxThreadsNeeded;
3302 if (isPublishedTrigger)
3303 minThreadsNeeded = maxThreadsNeeded = -1;
3312 Function *function = generateTriggerSchedulerFunction(dataType, fullSubcompositionNodeIdentifier, triggerNodeIndex,
3313 portIdentifier, portContextIndex, canDropEvents, isPublishedTrigger, isSpinOff,
3314 minThreadsNeeded, maxThreadsNeeded, chainCount, workerFunction);
3316 subcompositionTriggerFunctions[fullSubcompositionNodeIdentifier][triggerNodeIndex][trigger] = function;
3365Function * VuoCompilerBitcodeGenerator::generateTriggerSchedulerFunction(
VuoType *dataType,
3366 string compositionIdentifier,
size_t nodeIndex,
3367 string portIdentifier,
int portContextIndex,
3368 bool canDropEvents,
bool isPublishedInputTrigger,
bool isSpinOff,
3369 int minThreadsNeeded,
int maxThreadsNeeded,
int chainCount,
3370 Function *workerFunction)
3375 Function *function = Function::Create(functionType, GlobalValue::InternalLinkage, functionName, module);
3380 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, NULL);
3381 BasicBlock *finalBlock = BasicBlock::Create(module->getContext(),
"final", function, NULL);
3382 BasicBlock *scheduleBlock = BasicBlock::Create(module->getContext(),
"schedule", function, NULL);
3385 Value *compositionIdentifierValue = constantsCache->
get(compositionIdentifier);
3388 compositionStateValue->setName(
"compositionState");
3397 BasicBlock *checkEventDropBlock = BasicBlock::Create(module->getContext(),
"checkEventDrop", function, NULL);
3398 BranchInst::Create(checkEventDropBlock, initialBlock);
3402 Constant *zeroValue = ConstantInt::get(retValue->getType(), 0);
3403 ICmpInst *isTriggerAvailableValue =
new ICmpInst(*checkEventDropBlock, ICmpInst::ICMP_EQ, retValue, zeroValue,
"");
3404 BasicBlock *dropEventBlock = BasicBlock::Create(module->getContext(),
"dropEvent", function, NULL);
3405 BranchInst::Create(scheduleBlock, dropEventBlock, isTriggerAvailableValue, checkEventDropBlock);
3412 Constant *portIdentifierValue = constantsCache->
get(portIdentifier);
3417 BranchInst::Create(finalBlock, dropEventBlock);
3421 BranchInst::Create(scheduleBlock, initialBlock);
3428 Value *eventIdValue;
3429 if (! isPublishedInputTrigger)
3451 compositionStateValue, eventIdValue, portContextValue, dataType,
3452 minThreadsNeeded, maxThreadsNeeded, chainCount, workerFunction);
3453 BranchInst::Create(finalBlock, scheduleBlock);
3455 ReturnInst::Create(module->getContext(), finalBlock);
3609 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, NULL);
3610 BasicBlock *triggerBlock = BasicBlock::Create(module->getContext(),
"trigger", function, NULL);
3611 BasicBlock *finalBlock = BasicBlock::Create(module->getContext(),
"final", function, NULL);
3618 Value *triggerNodeContextValue = triggerNode->
generateGetContext(module, initialBlock, compositionStateValue);
3623 bool isNodeEventForSubcomposition = (! isTopLevelComposition && isPublishedInputTrigger);
3625 if (! isNodeEventForSubcomposition)
3628 BasicBlock *isPausedBlock = BasicBlock::Create(module->getContext(),
"isPaused", function, NULL);
3630 BranchInst::Create(isPausedBlock, triggerBlock, isPausedValueIsTrue, initialBlock);
3637 vector<VuoCompilerNode *> publishedOutputNodeVector(1, publishedOutputNode);
3638 if (publishedOutputNode && ! isPublishedInputTrigger)
3639 generateLockNodes(module, isPausedBlock, compositionStateValue, publishedOutputNodeVector);
3644 if (isPublishedInputTrigger)
3647 vector<VuoCompilerNode *> triggerWaitNodes = getNodesToWaitOnBeforeTransmission(trigger);
3648 generateUnlockNodes(module, isPausedBlock, compositionStateValue, triggerWaitNodes);
3652 if (publishedOutputNode)
3653 generateUnlockNodes(module, isPausedBlock, compositionStateValue, publishedOutputNodeVector);
3665 BranchInst::Create(finalBlock, isPausedBlock);
3670 BranchInst::Create(triggerBlock, initialBlock);
3673 if (isPublishedInputTrigger)
3675 if (! isNodeEventForSubcomposition)
3678 vector<VuoCompilerNode *> triggerWaitNodes = getNodesToWaitOnBeforeTransmission(trigger);
3680 if (find(triggerWaitNodes.begin(), triggerWaitNodes.end(), publishedOutputNode) == triggerWaitNodes.end())
3682 vector<VuoCompilerNode *> publishedOutputNodeVector(1, publishedOutputNode);
3683 generateUnlockNodes(module, triggerBlock, compositionStateValue, publishedOutputNodeVector);
3690 vector<VuoCompilerNode *> triggerWaitNodes = getNodesToWaitOnBeforeTransmission(trigger);
3691 generateLockNodes(module, triggerBlock, compositionStateValue, triggerWaitNodes, eventIdValue);
3694 Value *triggerDataValue = trigger->
generateDataValueUpdate(module, triggerBlock, function, triggerNodeContextValue);
3698 generateTransmissionFromOutputPort(function, triggerBlock, compositionStateValue, triggerNode, trigger, NULL, triggerDataPointer);
3703 if (find(downstreamNodes.begin(), downstreamNodes.end(), triggerNode) == downstreamNodes.end())
3704 generateUnlockNodes(module, triggerBlock, compositionStateValue, vector<VuoCompilerNode *>(1, triggerNode));
3716 map<VuoCompilerChain *, vector<VuoCompilerChain *> > chainsImmediatelyDownstream;
3717 map<VuoCompilerChain *, vector<VuoCompilerChain *> > chainsImmediatelyUpstream;
3718 set<VuoCompilerChain *> chainsScheduled;
3720 vector<VuoCompilerChain *> allChains = chainsForTrigger[trigger];
3722 if (! allChains.empty())
3725 for (vector<VuoCompilerChain *>::iterator i = allChains.begin(); i != allChains.end(); ++i)
3730 for (vector<VuoCompilerChain *>::iterator j = allChains.begin(); j != allChains.end(); ++j)
3734 if (chain == otherChain)
3739 if (graph->
mayTransmit(lastNodeInOtherChain, firstNodeInThisChain, trigger))
3741 chainsImmediatelyUpstream[chain].push_back(otherChain);
3742 chainsImmediatelyDownstream[otherChain].push_back(chain);
3751 vector<VuoCompilerChain *> firstChains;
3752 for (vector<VuoCompilerChain *>::iterator i = allChains.begin(); i != allChains.end(); ++i)
3755 map<VuoCompilerChain *, vector<VuoCompilerChain *> >::iterator upstreamIter = chainsImmediatelyUpstream.find(chain);
3756 if (upstreamIter == chainsImmediatelyUpstream.end())
3757 firstChains.push_back(chain);
3762 firstChains.pop_back();
3763 chainsScheduled.insert(chainToExecute);
3764 size_t chainIndex = find(allChains.begin(), allChains.end(), chainToExecute) - allChains.begin();
3768 int minThreadsNeeded, maxThreadsNeeded;
3771 eventIdValue, compositionStateValue, chainIndex);
3774 generateAndScheduleChainWorkerFunctions(triggerBlock, compositionStateValue, contextValue, firstChains, trigger,
3775 allChains, chainsImmediatelyDownstream, chainsImmediatelyUpstream, chainsScheduled);
3778 generateChainExecution(function, triggerBlock, compositionStateValue, contextValue, eventIdValue, chainToExecute, trigger,
3779 allChains, chainsImmediatelyDownstream, chainsImmediatelyUpstream, chainsScheduled);
3787 if (isNodeEventForSubcomposition)
3795 BranchInst::Create(finalBlock, triggerBlock);
3801 ReturnInst::Create(module->getContext(), finalBlock);
3809void VuoCompilerBitcodeGenerator::generateAndScheduleChainWorkerFunctions(BasicBlock *schedulerBlock,
3810 Value *compositionStateValueInScheduler, Value *contextValueInScheduler,
3812 const vector<VuoCompilerChain *> &allChains,
3813 const map<
VuoCompilerChain *, vector<VuoCompilerChain *> > &chainsImmediatelyDownstream,
3814 const map<
VuoCompilerChain *, vector<VuoCompilerChain *> > &chainsImmediatelyUpstream,
3815 set<VuoCompilerChain *> &chainsScheduled)
3818 vector<VuoCompilerChain *> uniqueChainsToSchedule;
3819 for (vector<VuoCompilerChain *>::const_iterator i = chainsToSchedule.begin(); i != chainsToSchedule.end(); ++i)
3822 if (chainsScheduled.find(chain) == chainsScheduled.end())
3824 uniqueChainsToSchedule.push_back(chain);
3825 chainsScheduled.insert(chain);
3830 for (vector<VuoCompilerChain *>::const_iterator i = uniqueChainsToSchedule.begin(); i != uniqueChainsToSchedule.end(); ++i)
3834 for (vector<VuoCompilerChain *>::const_iterator i = uniqueChainsToSchedule.begin(); i != uniqueChainsToSchedule.end(); ++i)
3837 generateAndScheduleChainWorkerFunction(schedulerBlock, compositionStateValueInScheduler, contextValueInScheduler,
3838 chain, trigger, allChains, chainsImmediatelyDownstream, chainsImmediatelyUpstream,
3846void VuoCompilerBitcodeGenerator::generateAndScheduleChainWorkerFunction(BasicBlock *schedulerBlock,
3847 Value *compositionStateValueInScheduler, Value *contextValueInScheduler,
3849 const vector<VuoCompilerChain *> &allChains,
3850 const map<
VuoCompilerChain *, vector<VuoCompilerChain *> > &chainsImmediatelyDownstream,
3851 const map<
VuoCompilerChain *, vector<VuoCompilerChain *> > &chainsImmediatelyUpstream,
3852 set<VuoCompilerChain *> &chainsScheduled)
3854 int minThreadsNeeded, maxThreadsNeeded;
3857 size_t chainIndex = find(allChains.begin(), allChains.end(), chain) - allChains.begin();
3859 vector<VuoCompilerChain *> upstreamChains;
3860 map<VuoCompilerChain *, vector<VuoCompilerChain *> >::const_iterator upstreamChainsIter = chainsImmediatelyUpstream.find(chain);
3861 if (upstreamChainsIter != chainsImmediatelyUpstream.end())
3862 upstreamChains = upstreamChainsIter->second;
3864 vector<size_t> upstreamChainIndices;
3865 for (vector<VuoCompilerChain *>::iterator i = upstreamChains.begin(); i != upstreamChains.end(); ++i)
3866 upstreamChainIndices.push_back( find(allChains.begin(), allChains.end(), *i) - allChains.begin() );
3869 Function *chainWorker = chain->
generateScheduleWorker(module, schedulerBlock, compositionStateValueInScheduler, contextValueInScheduler,
3870 trigger->
getIdentifier(), minThreadsNeeded, maxThreadsNeeded, chainIndex,
3871 upstreamChainIndices);
3873 BasicBlock *chainBlock = BasicBlock::Create(module->getContext(),
"", chainWorker, 0);
3874 Value *contextValueInChainWorker = chainWorker->arg_begin();
3876 Value *eventIdValue = chain->
generateEventIdValue(module, chainBlock, contextValueInChainWorker);
3879 generateChainExecution(chainWorker, chainBlock, compositionStateValueInChainWorker, contextValueInChainWorker, eventIdValue, chain, trigger,
3880 allChains, chainsImmediatelyDownstream, chainsImmediatelyUpstream, chainsScheduled);
3885 ReturnInst::Create(module->getContext(), chainBlock);
3891void VuoCompilerBitcodeGenerator::generateChainExecution(Function *function, BasicBlock *&block,
3892 Value *compositionStateValue, Value *contextValue,
3894 const vector<VuoCompilerChain *> &allChains,
3895 const map<
VuoCompilerChain *, vector<VuoCompilerChain *> > &chainsImmediatelyDownstream,
3896 const map<
VuoCompilerChain *, vector<VuoCompilerChain *> > &chainsImmediatelyUpstream,
3897 set<VuoCompilerChain *> &chainsScheduled)
3899 size_t chainIndex = find(allChains.begin(), allChains.end(), chain) - allChains.begin();
3900 Value *chainIndexValue = ConstantInt::get(eventIdValue->getType(), chainIndex);
3903 vector<VuoCompilerNode *> chainNodes = chain->
getNodes();
3904 for (vector<VuoCompilerNode *>::iterator i = chainNodes.begin(); i != chainNodes.end(); ++i)
3908 Function *nodeExecutionFunction = executionFunctionForNode[node];
3909 if (! nodeExecutionFunction)
3911 nodeExecutionFunction = generateNodeExecutionFunction(module, node);
3912 executionFunctionForNode[node] = nodeExecutionFunction;
3915 Function *nodeTransmissionFunction = transmissionFunctionForNode[node];
3916 if (! nodeTransmissionFunction)
3918 nodeTransmissionFunction = generateNodeTransmissionFunction(module, node);
3919 transmissionFunctionForNode[node] = nodeTransmissionFunction;
3923 vector<Value *> nodeExecutionArgs;
3924 nodeExecutionArgs.push_back(compositionStateValue);
3925 nodeExecutionArgs.push_back(eventIdValue);
3926 nodeExecutionArgs.push_back(chainIndexValue);
3927 CallInst *isHitValue = CallInst::Create(nodeExecutionFunction, nodeExecutionArgs,
"", block);
3932 vector<VuoCompilerNode *> outputNodes = getNodesToWaitOnBeforeTransmission(trigger, node);
3933 generateLockNodes(module, block, compositionStateValue, outputNodes, eventIdValue);
3937 vector<Value *> nodeTransmissionArgs;
3938 nodeTransmissionArgs.push_back(compositionStateValue);
3939 nodeTransmissionArgs.push_back(isHitValue);
3940 CallInst::Create(nodeTransmissionFunction, nodeTransmissionArgs,
"", block);
3949 generateUnlockNodes(module, block, compositionStateValue, vector<VuoCompilerNode *>(1, node));
3954 vector<VuoCompilerChain *> downstreamChains;
3955 map<VuoCompilerChain *, vector<VuoCompilerChain *> >::const_iterator downstreamChainsIter = chainsImmediatelyDownstream.find(chain);
3956 if (downstreamChainsIter != chainsImmediatelyDownstream.end())
3957 downstreamChains = downstreamChainsIter->second;
3958 if (! downstreamChains.empty())
3960 vector<size_t> downstreamChainIndices;
3961 for (vector<VuoCompilerChain *>::iterator i = downstreamChains.begin(); i != downstreamChains.end(); ++i)
3962 downstreamChainIndices.push_back( find(allChains.begin(), allChains.end(), *i) - allChains.begin() );
3964 vector<VuoCompilerChain *> nextChains;
3965 for (vector<VuoCompilerChain *>::iterator i = downstreamChains.begin(); i != downstreamChains.end(); ++i)
3968 nextChains.push_back(downstreamChain);
3971 generateAndScheduleChainWorkerFunctions(block, compositionStateValue, contextValue, nextChains, trigger, allChains,
3972 chainsImmediatelyDownstream, chainsImmediatelyUpstream, chainsScheduled);
4024Function * VuoCompilerBitcodeGenerator::generateNodeExecutionFunction(Module *module,
VuoCompilerNode *node)
4028 Type *boolType = IntegerType::get(module->getContext(), 1);
4030 vector<Type *> params;
4031 params.push_back(pointerToCompositionStateType);
4032 params.push_back(eventIdType);
4033 params.push_back(eventIdType);
4034 FunctionType *functionType = FunctionType::get(boolType, params,
false);
4035 Function *function = Function::Create(functionType, GlobalValue::InternalLinkage, functionName, module);
4037 Function::arg_iterator args = function->arg_begin();
4038 Value *compositionStateValue = args++;
4039 compositionStateValue->setName(
"compositionState");
4040 Value *eventIdValue = args++;
4041 eventIdValue->setName(
"eventId");
4042 Value *chainIndexValue = args++;
4043 chainIndexValue->setName(
"chainIndex");
4045 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, NULL);
4046 BasicBlock *finalBlock = BasicBlock::Create(module->getContext(),
"final", function, NULL);
4048 Value *nodeContextValue = node->
generateGetContext(module, initialBlock, compositionStateValue);
4053 if (isTopLevelComposition)
4057 BranchInst::Create(finalBlock, initialBlock);
4063 BasicBlock *currBlock = initialBlock;
4072 for (
size_t publishedPortIndex = 0; publishedPortIndex < publishedOutputPorts.size(); ++publishedPortIndex)
4080 if (publishedOutputTriggerNames.find( port->
getClass()->
getName() ) != publishedOutputTriggerNames.end())
4082 BasicBlock *triggerBlock = BasicBlock::Create(module->getContext(),
"trigger", function, NULL);
4083 BasicBlock *nextBlock = BasicBlock::Create(module->getContext(),
"next", function, NULL);
4084 Constant *falseValue = ConstantInt::get(isPortHitValue->getType(), 0);
4085 ICmpInst *isPortHitIsTrue =
new ICmpInst(*currBlock, ICmpInst::ICMP_NE, isPortHitValue, falseValue);
4086 BranchInst::Create(triggerBlock, nextBlock, isPortHitIsTrue, currBlock);
4092 vector<Value *> args;
4105 CallInst *triggerFunctionCall = CallInst::Create(triggerFunction, args,
"", triggerBlock);
4109 BranchInst::Create(nextBlock, triggerBlock);
4111 currBlock = nextBlock;
4123 ConstantInt *falseValue = ConstantInt::get(
static_cast<IntegerType *
>(subcompositionFinishedValue->getType()), 0);
4124 ICmpInst *subcompositionFinishedIsTrue =
new ICmpInst(*currBlock, ICmpInst::ICMP_NE, subcompositionFinishedValue, falseValue,
"");
4125 BasicBlock *leaveBlock = BasicBlock::Create(module->getContext(),
"leave", function, NULL);
4126 BasicBlock *signalBlock = BasicBlock::Create(module->getContext(),
"signal", function, NULL);
4127 BranchInst::Create(leaveBlock, signalBlock, subcompositionFinishedIsTrue, currBlock);
4133 BranchInst::Create(finalBlock, leaveBlock);
4138 generateUnlockNodes(module, signalBlock, compositionStateValue, vector<VuoCompilerNode *>(1, node));
4139 BranchInst::Create(finalBlock, signalBlock);
4145 BasicBlock *executeBlock = BasicBlock::Create(module->getContext(),
"execute", function, NULL);
4146 BranchInst::Create(executeBlock, finalBlock, isHitValue, initialBlock);
4157 eventIdValue, compositionStateValue, chainIndexValue,
4158 subcompositionIdentifierValue);
4164 generateNodeExecution(executeBlock, compositionStateValue, node, shouldSendTelemetry);
4165 BranchInst::Create(finalBlock, executeBlock);
4168 ReturnInst::Create(module->getContext(), isHitValue, finalBlock);
4197Function * VuoCompilerBitcodeGenerator::generateNodeTransmissionFunction(Module *module,
VuoCompilerNode *node)
4201 Type *boolType = IntegerType::get(module->getContext(), 1);
4202 vector<Type *> params;
4203 params.push_back(pointerToCompositionStateType);
4204 params.push_back(boolType);
4205 FunctionType *functionType = FunctionType::get(Type::getVoidTy(module->getContext()), params,
false);
4206 Function *function = Function::Create(functionType, GlobalValue::InternalLinkage, functionName, module);
4208 Function::arg_iterator args = function->arg_begin();
4209 Value *compositionStateValue = args++;
4210 compositionStateValue->setName(
"compositionState");
4211 Value *isHitValue = args++;
4212 isHitValue->setName(
"isHit");
4214 BasicBlock *initialBlock = BasicBlock::Create(module->getContext(),
"initial", function, NULL);
4215 BasicBlock *transmitBlock = BasicBlock::Create(module->getContext(),
"transmit", function, NULL);
4216 BasicBlock *finalBlock = BasicBlock::Create(module->getContext(),
"final", function, NULL);
4219 BranchInst::Create(transmitBlock, finalBlock, isHitValue, initialBlock);
4221 Value *nodeContextValue = node->
generateGetContext(module, transmitBlock, compositionStateValue);
4225 if (isTopLevelComposition)
4226 generateTelemetryFromPublishedOutputNode(function, transmitBlock, compositionStateValue, nodeContextValue, node);
4231 generateTransmissionFromNode(function, transmitBlock, compositionStateValue, nodeContextValue, node);
4237 BranchInst::Create(finalBlock, transmitBlock);
4238 ReturnInst::Create(module->getContext(), finalBlock);