Vuo  2.0.0
VuoCompilerBitcodeParser.cc
Go to the documentation of this file.
1 
11 
12 
17 {
18  this->module = module;
19 }
20 
26 {
27  GlobalValue *gv = module->getNamedValue(name);
28  if((gv == NULL) || (gv->getValueID() != Value::GlobalVariableVal))
29  return 0;
30 
31  Value *v = gv->getOperand(0);
32  if(v->getValueID() != Value::ConstantIntVal)
33  return 0;
34 
35  ConstantInt *ci = (ConstantInt *)v;
36  return ci->getValue().getLimitedValue();
37 }
38 
43 {
44  string s = resolveGlobalToConst(name);
45  if(s=="")
46  return "";
47 
48  return getGlobalValueConstString(s);
49 }
50 
56 {
57  vector<string> globalConstStrings;
58  GlobalValue *gv = module->getNamedValue(name);
59 
60  if((gv == NULL) || (gv->getValueID() != Value::GlobalVariableVal))
61  {
62  return globalConstStrings;
63  }
64  Value *v = gv->getOperand(0);
65 
66  if(v->getValueID() != Value::ConstantArrayVal)
67  {
68  return globalConstStrings;
69  }
70  ConstantArray *constantArray = (ConstantArray *)v;
71  int numArrayElmts = constantArray->getNumOperands();
72 
73  for(int i = 0; i < numArrayElmts; i++)
74  {
75  Constant *arrayConstElmt = (Constant *)(constantArray->getOperand(i));
76 
77  if(arrayConstElmt->getValueID() == Value::ConstantExprVal)
78  {
79  ConstantExpr *ce = (ConstantExpr *)arrayConstElmt;
80 
81  if(ce->getOpcode() == Instruction::GetElementPtr)
82  {
83  // `ConstantExpr` operands: https://llvm.org/docs/LangRef.html#constantexprs
84  Value *gv2 = ce->getOperand(0);
85 
86  if(gv2->getValueID() == Value::GlobalVariableVal)
87  {
88  string constantName = gv2->getName().str();
89  string constantVal = getGlobalValueConstString(constantName);
90  globalConstStrings.push_back(constantVal);
91  }
92  }
93  }
94  }
95  return globalConstStrings;
96 }
97 
98 string VuoCompilerBitcodeParser::resolveGlobalToConst(string name)
99 {
100  GlobalValue *gv = module->getNamedValue(name);
101  if((gv == NULL) || (gv->getValueID() != Value::GlobalVariableVal))
102  return "";
103 
104  Value *v = gv->getOperand(0);
105  if(v->getValueID() != Value::ConstantExprVal)
106  return "";
107  ConstantExpr *ce = (ConstantExpr *)v;
108  if(ce->getOpcode() != Instruction::GetElementPtr)
109  return "";
110 
111  // `ConstantExpr` operands: https://llvm.org/docs/LangRef.html#constantexprs
112  Value *gv2 = ce->getOperand(0);
113 
114  if(gv2->getValueID() != Value::GlobalVariableVal)
115  return "";
116 
117  return gv2->getName().str();
118 }
119 
120 string VuoCompilerBitcodeParser::getGlobalValueConstString(string name)
121 {
122  GlobalValue *gv = module->getNamedValue(name);
123 
124  // assumption: the zeroth operand of a Value::GlobalVariableVal is the actual Value
125  Value *v = gv->getOperand(0);
126  if(v->getValueID() != Value::ConstantDataArrayVal)
127  return ""; // if the string's value is "", v->getValueID() is Value::ConstantAggregateZeroVal
128 
129  ConstantDataArray *ca = (ConstantDataArray *)v;
130  string caStr = ca->getAsCString().str();
131  return caStr;
132 }
133 
138 {
139  return module->getFunction(name);
140 }
141 
146 string VuoCompilerBitcodeParser::getArgumentNameInSourceCode(string argumentNameInBitcode)
147 {
148  return argumentNameInBitcode.substr(0, argumentNameInBitcode.find('.'));
149 }
150 
157 {
158  Function *function = firstArgument->getParent();
159  for (Function::arg_iterator i = function->arg_begin(); i != function->arg_end(); ++i)
160  {
161  Argument *currArgument = i;
162  if (currArgument == firstArgument)
163  {
164  if (++i != function->arg_end())
165  {
166  Argument *secondArgument = i;
167 
168  string firstArgumentName = getArgumentNameInSourceCode(firstArgument->getName());
169  string secondArgumentName = getArgumentNameInSourceCode(secondArgument->getName());
170  return (firstArgumentName == secondArgumentName);
171  }
172  break;
173  }
174  }
175  return false;
176 }
177 
181 vector<pair<Argument *, string> > VuoCompilerBitcodeParser::getAnnotatedArguments(Function *function)
182 {
183  vector<pair<Argument *, string> > annotatedArguments;
184 
185  // assumption: @llvm.var.annotation calls are always in the function's entry block.
186  BasicBlock *b = &function->getEntryBlock();
187 
188  // Run through the entry block to associate annotations with function parameters.
189  BitCastInst *precedingBitCastInst = NULL;
190  for(BasicBlock::iterator it = b->begin();it!=b->end();++it)
191  {
192  Instruction *inst = it;
193  if(! CallInst::classof(inst))
194  {
195  if (BitCastInst::classof(inst))
196  precedingBitCastInst = static_cast<BitCastInst *>(inst);
197  continue;
198  }
199 
200  // assumption: Instruction::Call's operands are the function arguments, followed by the function name
201  Value *calledFunction = inst->getOperand(inst->getNumOperands()-1);
202  if(calledFunction->getName().str() != "llvm.var.annotation")
203  continue;
204 
205  // Find an operand whose name has the same prefix as the corresponding function parameter's name.
206  // The correct place to look for this operand depends on the data type of the parameter.
207  // For a struct, it's the bitcast. For a bool, it's the llvm.var.annotation call.
208  // For other data types, either works.
209  Value *annotatedValue;
210  if (precedingBitCastInst)
211  {
212  // `bitcast` operands: https://llvm.org/docs/LangRef.html#bitcast-to-instruction
213  annotatedValue = precedingBitCastInst->getOperand(0);
214  precedingBitCastInst = NULL;
215  }
216  else
217  {
218  // `llvm.var.annotation` operands: https://llvm.org/docs/LangRef.html#llvm-var-annotation-intrinsic
219  annotatedValue = inst->getOperand(0);
220  }
221 
222  // Find the first function parameter whose name matches the operand's name.
223  // The function parameter and/or the operand may have a suffix that begins with ".", e.g. ".coerce" or ".addr1".
224  Argument *argument = NULL;
225  string annotationNamePrefix = getArgumentNameInSourceCode(annotatedValue->getName());
226  for (Function::arg_iterator i = function->arg_begin(); i != function->arg_end(); ++i)
227  {
228  Argument *currArgument = i;
229  string argNamePrefix = getArgumentNameInSourceCode(currArgument->getName());
230  if (argNamePrefix == annotationNamePrefix)
231  {
232  argument = currArgument;
233  break;
234  }
235  }
236  if(!argument)
237  {
238  // Workaround for vuo.image.make.checkerboard2 center (https://b33p.net/kosada/node/15936)
239  for (Function::arg_iterator i = function->arg_begin(); i != function->arg_end(); ++i)
240  {
241  Argument *currArgument = i;
242  if (currArgument->getName().empty())
243  {
244  argument = currArgument;
245  argument->setName(annotationNamePrefix + ".workaround");
246  break;
247  }
248  }
249 
250  continue;
251  }
252 
253  Value *annotation = inst->getOperand(1);
254  if(annotation->getValueID() != Value::ConstantExprVal)
255  continue;
256  ConstantExpr *ce = (ConstantExpr *)annotation;
257  if(ce->getOpcode() != Instruction::GetElementPtr)
258  continue;
259 
260  // `ConstantExpr` operands: https://llvm.org/docs/LangRef.html#constant-expressions
261  Value *gv = ce->getOperand(0);
262 
263  if(gv->getValueID() != Value::GlobalVariableVal)
264  continue;
265 
266  string annotationName = getGlobalValueConstString(gv->getName().str());
267 
268  annotatedArguments.push_back(pair<Argument *, string>(argument, annotationName));
269  }
270 
271  return annotatedArguments;
272 }