Vuo 2.4.4
Loading...
Searching...
No Matches
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
98string 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
120string 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
147{
148 return argumentNameInBitcode.substr(0, argumentNameInBitcode.find('.'));
149}
150
154vector<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}