Vuo  2.3.2
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 
154 vector<pair<Argument *, string> > VuoCompilerBitcodeParser::getAnnotatedArguments(Function *function)
155 {
156  vector<pair<Argument *, string> > annotatedArguments;
157 
158  // assumption: @llvm.var.annotation calls are always in the function's entry block.
159  BasicBlock *b = &function->getEntryBlock();
160 
161  // Run through the entry block to associate annotations with function parameters.
162  BitCastInst *precedingBitCastInst = NULL;
163  for(BasicBlock::iterator it = b->begin();it!=b->end();++it)
164  {
165  Instruction *inst = &(*it);
166  if(! CallInst::classof(inst))
167  {
168  if (BitCastInst::classof(inst))
169  precedingBitCastInst = static_cast<BitCastInst *>(inst);
170  continue;
171  }
172 
173  // assumption: Instruction::Call's operands are the function arguments, followed by the function name
174  Value *calledFunction = inst->getOperand(inst->getNumOperands()-1);
175  if(calledFunction->getName().str() != "llvm.var.annotation")
176  continue;
177 
178  // Find an operand whose name has the same prefix as the corresponding function parameter's name.
179  // The correct place to look for this operand depends on the data type of the parameter.
180  // For a struct, it's the bitcast. For a bool, it's the llvm.var.annotation call.
181  // For other data types, either works.
182  Value *annotatedValue;
183  if (precedingBitCastInst)
184  {
185  // `bitcast` operands: https://llvm.org/docs/LangRef.html#bitcast-to-instruction
186  annotatedValue = precedingBitCastInst->getOperand(0);
187  precedingBitCastInst = NULL;
188  }
189  else
190  {
191  // `llvm.var.annotation` operands: https://llvm.org/docs/LangRef.html#llvm-var-annotation-intrinsic
192  annotatedValue = inst->getOperand(0);
193  }
194 
195  // Find the first function parameter whose name matches the operand's name.
196  // The function parameter and/or the operand may have a suffix that begins with ".", e.g. ".coerce" or ".addr1".
197  Argument *argument = NULL;
198  string annotationNamePrefix = getArgumentNameInSourceCode(annotatedValue->getName());
199  for (Function::arg_iterator i = function->arg_begin(); i != function->arg_end(); ++i)
200  {
201  Argument *currArgument = i;
202  string argNamePrefix = getArgumentNameInSourceCode(currArgument->getName());
203  if (argNamePrefix == annotationNamePrefix)
204  {
205  argument = currArgument;
206  break;
207  }
208  }
209  if(!argument)
210  {
211  // Workaround for vuo.image.make.checkerboard2 center (https://b33p.net/kosada/node/15936)
212  for (Function::arg_iterator i = function->arg_begin(); i != function->arg_end(); ++i)
213  {
214  Argument *currArgument = i;
215  if (currArgument->getName().empty())
216  {
217  argument = currArgument;
218  argument->setName(annotationNamePrefix + ".workaround");
219  break;
220  }
221  }
222 
223  continue;
224  }
225 
226  Value *annotation = inst->getOperand(1);
227  if(annotation->getValueID() != Value::ConstantExprVal)
228  continue;
229  ConstantExpr *ce = (ConstantExpr *)annotation;
230  if(ce->getOpcode() != Instruction::GetElementPtr)
231  continue;
232 
233  // `ConstantExpr` operands: https://llvm.org/docs/LangRef.html#constant-expressions
234  Value *gv = ce->getOperand(0);
235 
236  if(gv->getValueID() != Value::GlobalVariableVal)
237  continue;
238 
239  string annotationName = getGlobalValueConstString(gv->getName().str());
240 
241  annotatedArguments.push_back(pair<Argument *, string>(argument, annotationName));
242  }
243 
244  return annotatedArguments;
245 }