Vuo  2.3.2
VuoCompilerChain.cc
Go to the documentation of this file.
1 
10 #include "VuoCompilerChain.hh"
12 #include "VuoCompilerNode.hh"
13 #include "VuoStringUtilities.hh"
14 
21 VuoCompilerChain::VuoCompilerChain(vector<VuoCompilerNode *> nodes, bool lastNodeInLoop)
22 {
23  this->nodes = nodes;
24  this->lastNodeInLoop = lastNodeInLoop;
25 }
26 
31 Value * VuoCompilerChain::generateMakeContext(Module *module, BasicBlock *block, Value *compositionStateValue, Value *eventIdValue)
32 {
33  PointerType *voidPointerType = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
34 
35  // unsigned long *eventIdPtr = (unsigned long *)malloc(sizeof(unsigned long));
36  // *eventIdPtr = eventId;
37 
38  Value *eventIdPtrValue = VuoCompilerCodeGenUtilities::generateMemoryAllocation(module, block, eventIdValue->getType(), 1);
39  new StoreInst(eventIdValue, eventIdPtrValue, "", block);
40 
41  // size_t contextBytes = 2 * sizeof(void *);
42  // void **context = (void **)malloc(contextBytes);
43  // context[0] = (void *)compositionState;
44  // context[1] = (void *)eventIdPtr;
45 
46  Value *contextValue = VuoCompilerCodeGenUtilities::generateMemoryAllocation(module, block, voidPointerType, 2);
47 
48  BitCastInst *compositionStateAsVoidPointer = new BitCastInst(compositionStateValue, voidPointerType, "", block);
49  VuoCompilerCodeGenUtilities::generateSetArrayElement(module, block, contextValue, 0, compositionStateAsVoidPointer);
50 
51  BitCastInst *eventIdPtrValueAsVoidPointer = new BitCastInst(eventIdPtrValue, voidPointerType, "", block);
52  VuoCompilerCodeGenUtilities::generateSetArrayElement(module, block, contextValue, 1, eventIdPtrValueAsVoidPointer);
53 
54  // VuoRegister(context, vuoFreeChainWorkerContext);
55 
57 
58  // VuoRetain(compositionState);
59 
60  VuoCompilerCodeGenUtilities::generateRetainCall(module, block, compositionStateValue);
61 
62  return new BitCastInst(contextValue, voidPointerType, "", block);
63 }
64 
68 Value * VuoCompilerChain::generateCompositionStateValue(Module *module, BasicBlock *block, Value *contextValue)
69 {
70  Type *compositionStatePointerType = PointerType::get(VuoCompilerCodeGenUtilities::getCompositionStateType(module), 0);
71  Type *voidPointerType = contextValue->getType();
72  Type *voidPointerPointerType = PointerType::get(voidPointerType, 0);
73 
74  // VuoCompositionState *compositionState = (VuoCompositionState *)((void **)context)[0]);
75 
76  Value *contextValueAsVoidPointerArray = new BitCastInst(contextValue, voidPointerPointerType, "", block);
77  Value *compositionStateAsVoidPointer = VuoCompilerCodeGenUtilities::generateGetArrayElement(module, block, contextValueAsVoidPointerArray, (size_t)0);
78  return new BitCastInst(compositionStateAsVoidPointer, compositionStatePointerType, "", block);
79 }
80 
84 Value * VuoCompilerChain::generateEventIdValue(Module *module, BasicBlock *block, Value *contextValue)
85 {
86  Type *eventIdPtrType = PointerType::get(IntegerType::get(module->getContext(), 64), 0);
87  Type *voidPointerType = contextValue->getType();
88  Type *voidPointerPointerType = PointerType::get(voidPointerType, 0);
89 
90  // unsigned long *eventIdPtr = (unsigned long *)((void **)context)[1]);
91  // unsigned long eventId = *eventIdPtr;
92 
93  Value *contextValueAsVoidPointerArray = new BitCastInst(contextValue, voidPointerPointerType, "", block);
94  Value *eventIdPtrValueAsVoidPointer = VuoCompilerCodeGenUtilities::generateGetArrayElement(module, block, contextValueAsVoidPointerArray, 1);
95  Value *eventIdPtrValue = new BitCastInst(eventIdPtrValueAsVoidPointer, eventIdPtrType, "", block);
96  return new LoadInst(eventIdPtrValue, "", block);
97 }
98 
103 {
104  // void vuoFreeChainWorkerContext(void *context)
105  // {
106  // VuoRelease(((void **)context)[0]);
107  // free(((void **)context)[1]);
108  // free(context);
109  // }
110 
111  const char *functionName = "vuoFreeChainWorkerContext";
112  Function *function = module->getFunction(functionName);
113  if (! function)
114  {
115  PointerType *voidPointerType = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
116  PointerType *voidPointerPointerType = PointerType::get(voidPointerType, 0);
117  ConstantInt *zeroValue = ConstantInt::get(module->getContext(), APInt(64, 0));
118  ConstantInt *oneValue = ConstantInt::get(module->getContext(), APInt(64, 1));
119 
120  Function *freeFunction = VuoCompilerCodeGenUtilities::getFreeFunction(module);
121 
122  FunctionType *functionType = FunctionType::get(Type::getVoidTy(module->getContext()), voidPointerType, false);
123  function = Function::Create(functionType, GlobalValue::InternalLinkage, functionName, module);
124  BasicBlock *block = BasicBlock::Create(module->getContext(), "", function, 0);
125 
126  Value *contextValue = function->arg_begin();
127  BitCastInst *contextValueAsVoidPointerArray = new BitCastInst(contextValue, voidPointerPointerType, "", block);
128 
129  Value *compositionStateVariable = GetElementPtrInst::Create(voidPointerType, contextValueAsVoidPointerArray, zeroValue, "", block);
130  Value *compositionStateValue = new LoadInst(compositionStateVariable, "", block);
131  VuoCompilerCodeGenUtilities::generateReleaseCall(module, block, compositionStateValue);
132 
133  Value *eventIdPtrVariable = GetElementPtrInst::Create(voidPointerType, contextValueAsVoidPointerArray, oneValue, "", block);
134  Value *eventIdPtrValue = new LoadInst(eventIdPtrVariable, "", block);
135  CallInst::Create(freeFunction, eventIdPtrValue, "", block);
136 
137  CallInst::Create(freeFunction, contextValue, "", block);
138 
139  ReturnInst::Create(module->getContext(), block);
140  }
141 
142  return function;
143 }
144 
150 Function * VuoCompilerChain::generateScheduleWorker(Module *module, BasicBlock *block, Value *compositionStateValue,
151  Value *contextValue, string triggerIdentifier,
152  int minThreadsNeeded, int maxThreadsNeeded, size_t chainIndex,
153  vector<size_t> upstreamChainIndices)
154 {
155  Type *voidPointerType = contextValue->getType();
156  FunctionType *workerFunctionType = FunctionType::get(Type::getVoidTy(module->getContext()), voidPointerType, false);
157 
158  string workerFunctionName = VuoStringUtilities::prefixSymbolName(nodes.front()->getIdentifier(), triggerIdentifier);
159  if (lastNodeInLoop)
160  workerFunctionName += "__loop";
161  workerFunctionName += "__worker";
162  Function *workerFunction = Function::Create(workerFunctionType, GlobalValue::InternalLinkage, workerFunctionName, module);
163 
164  Value *globalQueue = VuoCompilerCodeGenUtilities::generateGetGlobalDispatchQueue(module, block);
165 
166  Value *eventIdValue = generateEventIdValue(module, block, contextValue);
167 
168  VuoCompilerCodeGenUtilities::generateScheduleChainWorker(module, block, globalQueue, contextValue, workerFunction,
169  minThreadsNeeded, maxThreadsNeeded,
170  eventIdValue, compositionStateValue, chainIndex, upstreamChainIndices);
171 
172  return workerFunction;
173 }
174 
178 vector<VuoCompilerNode *> VuoCompilerChain::getNodes(void)
179 {
180  return nodes;
181 }
182 
187 {
188  return lastNodeInLoop;
189 }