1 /************************************************************************
2  ************************************************************************
3     FAUST compiler
4     Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
5     ---------------------------------------------------------------------
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  ************************************************************************
20  ************************************************************************/
21 
22 #ifndef _LLVM_INSTRUCTIONS_H
23 #define _LLVM_INSTRUCTIONS_H
24 
25 #ifdef WIN32
26 #pragma warning(disable : 4624 4291 4141 4267)
27 #endif
28 
29 #include <list>
30 #include <map>
31 #include <string>
32 
33 #include "Text.hh"
34 #include "binop.hh"
35 #include "exception.hh"
36 #include "fir_to_fir.hh"
37 #include "global.hh"
38 #include "instructions.hh"
39 #include "struct_manager.hh"
40 
41 #include <llvm/IR/DataLayout.h>
42 #include <llvm/IR/DerivedTypes.h>
43 #include <llvm/IR/IRBuilder.h>
44 #include <llvm/IR/LLVMContext.h>
45 #include <llvm/IR/Module.h>
46 #include <llvm/IR/Verifier.h>
47 #include <llvm/Support/raw_ostream.h>
48 #include <llvm/Support/Host.h>
49 
50 using namespace llvm;
51 
52 #define LLVMValue llvm::Value*
53 #define LLVMType llvm::Type*
54 #define LLVMPtrType llvm::PointerType*
55 #define LLVMVecTypes vector<LLVMType>
56 #define MapOfTtypes map<Typed::VarType, LLVMType>
57 
58 #define MakeIdx(beg, end) llvm::ArrayRef<LLVMValue>(beg, end)
59 #define MakeArgs(args) llvm::ArrayRef<lLLVMValue>(args)
60 #define MakeStructGEP(v1, v2) fBuilder->CreateStructGEP(0, v1, v2);
61 #define MakeConstGEP32(type_def, llvm_name) fBuilder->CreateConstGEP2_32(type_def, llvm_name, 0, 0);
62 #define MakeIntPtrType() fModule->getDataLayout().getIntPtrType(fModule->getContext())
63 
64 #define CreateFuncall(fun, args) fBuilder->CreateCall(fun, makeArrayRef(args))
65 #define CreatePhi(type, name) fBuilder->CreatePHI(type, 0, name);
66 
67 #define GetIterator(it) &(*(it))
68 
69 #define dumpLLVM(val)                    \
70     {                                    \
71         string             res;          \
72         raw_string_ostream out_str(res); \
73         out_str << *val;                 \
74         cout << out_str.str() << endl;   \
75     }
76 
77 #if defined(LLVM_140)
78     #define ADD_ATTRIBUTE_AT_INDEX(a, b, c) a->addAttributeAtIndex(b, c)
79 #else
80     #define ADD_ATTRIBUTE_AT_INDEX(a, b, c) a->addAttribute(b, c)
81 #endif
82 
83 //=============================
84 // Helper class handling types
85 //=============================
86 
87 struct LLVMTypeHelper {
88     MapOfTtypes fTypeMap;
89     Module*     fModule;
90 
LLVMTypeHelperLLVMTypeHelper91     LLVMTypeHelper(Module* module) : fModule(module)
92     {
93         // LLVM type coding
94         fTypeMap[Typed::kFloat]         = getFloatTy();
95         fTypeMap[Typed::kFloat_ptr]     = getTyPtr(fTypeMap[Typed::kFloat]);
96         fTypeMap[Typed::kFloat_ptr_ptr] = getTyPtr(fTypeMap[Typed::kFloat_ptr]);
97     #if !defined(LLVM_120) && !defined(LLVM_130) && !defined(LLVM_140)
98         fTypeMap[Typed::kFloat_vec]     = VectorType::get(fTypeMap[Typed::kFloat], gGlobal->gVecSize);
99         fTypeMap[Typed::kFloat_vec_ptr] = getTyPtr(fTypeMap[Typed::kFloat_vec]);
100     #endif
101         fTypeMap[Typed::kDouble]         = getDoubleTy();
102         fTypeMap[Typed::kDouble_ptr]     = getTyPtr(fTypeMap[Typed::kDouble]);
103         fTypeMap[Typed::kDouble_ptr_ptr] = getTyPtr(fTypeMap[Typed::kDouble_ptr]);
104     #if !defined(LLVM_120) && !defined(LLVM_130) && !defined(LLVM_140)
105         fTypeMap[Typed::kDouble_vec]     = VectorType::get(fTypeMap[Typed::kDouble], gGlobal->gVecSize);
106         fTypeMap[Typed::kDouble_vec_ptr] = getTyPtr(fTypeMap[Typed::kDouble_vec]);
107     #endif
108         fTypeMap[Typed::kInt32]         = getInt32Ty();
109         fTypeMap[Typed::kInt32_ptr]     = getTyPtr(fTypeMap[Typed::kInt32]);
110     #if !defined(LLVM_120) && !defined(LLVM_130) && !defined(LLVM_140)
111         fTypeMap[Typed::kInt32_vec]     = VectorType::get(fTypeMap[Typed::kInt32], gGlobal->gVecSize);
112         fTypeMap[Typed::kInt32_vec_ptr] = getTyPtr(fTypeMap[Typed::kInt32_vec]);
113     #endif
114         fTypeMap[Typed::kInt64]         = getInt64Ty();
115         fTypeMap[Typed::kInt64_ptr]     = getTyPtr(fTypeMap[Typed::kInt64]);
116     #if !defined(LLVM_120) && !defined(LLVM_130) && !defined(LLVM_140)
117         fTypeMap[Typed::kInt64_vec]     = VectorType::get(fTypeMap[Typed::kInt64], gGlobal->gVecSize);
118         fTypeMap[Typed::kInt64_vec_ptr] = getTyPtr(fTypeMap[Typed::kInt64_vec]);
119     #endif
120         fTypeMap[Typed::kBool]         = getInt1Ty();
121         fTypeMap[Typed::kBool_ptr]     = getTyPtr(fTypeMap[Typed::kBool]);
122     #if !defined(LLVM_120) && !defined(LLVM_130) && !defined(LLVM_140)
123         fTypeMap[Typed::kBool_vec]     = VectorType::get(fTypeMap[Typed::kBool], gGlobal->gVecSize);
124         fTypeMap[Typed::kBool_vec_ptr] = getTyPtr(fTypeMap[Typed::kBool_vec]);
125     #endif
126         // Takes the type of internal real
127         fTypeMap[Typed::kFloatMacro]         = fTypeMap[itfloat()];
128         fTypeMap[Typed::kFloatMacro_ptr]     = getTyPtr(fTypeMap[Typed::kFloatMacro]);
129         fTypeMap[Typed::kFloatMacro_ptr_ptr] = getTyPtr(fTypeMap[Typed::kFloatMacro_ptr]);
130 
131         fTypeMap[Typed::kVoid] = llvm::Type::getVoidTy(module->getContext());
132 
133         // void* must be defined as i8* type
134         fTypeMap[Typed::kVoid_ptr]     = getInt8TyPtr();
135         fTypeMap[Typed::kVoid_ptr_ptr] = getTyPtr(fTypeMap[Typed::kVoid_ptr]);
136 
137         // External structured type definition
138         for (const auto& it : gGlobal->gExternalStructTypes) {
139             LLVMType new_type                         = convertFIRType((it.second)->fType);
140             fTypeMap[it.first]                        = new_type;
141             fTypeMap[Typed::getPtrFromType(it.first)] = getTyPtr(new_type);
142         }
143     }
144 
~LLVMTypeHelperLLVMTypeHelper145     virtual ~LLVMTypeHelper() {}
146 
147     // Value generation
genInt1LLVMTypeHelper148     LLVMValue genInt1(int num) { return ConstantInt::get(llvm::Type::getInt1Ty(fModule->getContext()), num); }
genInt32LLVMTypeHelper149     LLVMValue genInt32(int num) { return ConstantInt::get(llvm::Type::getInt32Ty(fModule->getContext()), num); }
genInt64LLVMTypeHelper150     LLVMValue genInt64(int64_t num) { return ConstantInt::get(llvm::Type::getInt64Ty(fModule->getContext()), num); }
genFloatLLVMTypeHelper151     LLVMValue genFloat(float num) { return ConstantFP::get(fModule->getContext(), APFloat(num)); }
genDoubleLLVMTypeHelper152     LLVMValue genDouble(double num) { return ConstantFP::get(fModule->getContext(), APFloat(num)); }
153 
genArrayLLVMTypeHelper154     LLVMValue genArray(LLVMType type, const vector<Constant*>& num_array)
155     {
156         ArrayType* array_type = ArrayType::get(type, num_array.size());
157         return ConstantArray::get(array_type, num_array);
158     }
159 
genGlovalVarLLVMTypeHelper160     GlobalVariable* genGlovalVar(LLVMType type, bool is_const, const string& name)
161     {
162         return new GlobalVariable(*fModule, type, is_const, GlobalValue::InternalLinkage, 0, name);
163     }
164 
165     // Type generation
getFloatTyLLVMTypeHelper166     LLVMType getFloatTy() { return llvm::Type::getFloatTy(fModule->getContext()); }
getDoubleTyLLVMTypeHelper167     LLVMType getDoubleTy() { return llvm::Type::getDoubleTy(fModule->getContext()); }
getRealTyLLVMTypeHelper168     LLVMType getRealTy() { return fTypeMap[Typed::kFloatMacro]; }
getInt32TyLLVMTypeHelper169     LLVMType getInt32Ty() { return llvm::Type::getInt32Ty(fModule->getContext()); }
getInt64TyLLVMTypeHelper170     LLVMType getInt64Ty() { return llvm::Type::getInt64Ty(fModule->getContext()); }
getInt1TyLLVMTypeHelper171     LLVMType getInt1Ty() { return llvm::Type::getInt1Ty(fModule->getContext()); }
getInt8TyLLVMTypeHelper172     LLVMType getInt8Ty() { return llvm::Type::getInt8Ty(fModule->getContext()); }
getInt8TyPtrLLVMTypeHelper173     LLVMType getInt8TyPtr() { return PointerType::get(getInt8Ty(), 0); }
getTyPtrLLVMTypeHelper174     LLVMType getTyPtr(LLVMType type) { return PointerType::get(type, 0); }
175 
getStructTypeLLVMTypeHelper176     LLVMType getStructType(const string& name, const LLVMVecTypes& types)
177     {
178         // We want to have a unique creation for struct types, so check if the given type has already been created
179     #if defined(LLVM_120) || defined(LLVM_130) || defined(LLVM_140)
180         StructType* struct_type = StructType::getTypeByName(fModule->getContext(), name);
181     #else
182         StructType* struct_type = fModule->getTypeByName(name);
183     #endif
184         if (!struct_type) {
185             struct_type = StructType::create(fModule->getContext(), name);
186             // Create "packed" struct type to match the size of C++ "packed" defined ones
187             struct_type->setBody(makeArrayRef(types), true);
188         }
189         return struct_type;
190     }
191 
192     // Convert FIR types to LLVM types
convertFIRTypeLLVMTypeHelper193     LLVMType convertFIRType(Typed* ext_type)
194     {
195         BasicTyped*  basic_typed  = dynamic_cast<BasicTyped*>(ext_type);
196         NamedTyped*  named_typed  = dynamic_cast<NamedTyped*>(ext_type);
197         ArrayTyped*  array_typed  = dynamic_cast<ArrayTyped*>(ext_type);
198         VectorTyped* vector_typed = dynamic_cast<VectorTyped*>(ext_type);
199         StructTyped* struct_typed = dynamic_cast<StructTyped*>(ext_type);
200 
201         if (basic_typed) {
202             return fTypeMap[basic_typed->fType];
203         } else if (named_typed) {
204         #if defined(LLVM_120) || defined(LLVM_130) || defined(LLVM_140)
205             LLVMType type = StructType::getTypeByName(fModule->getContext(), "struct.dsp" + named_typed->fName);
206         #else
207             LLVMType type = fModule->getTypeByName("struct.dsp" + named_typed->fName);
208         #endif
209             // Subcontainer type (RWTable...)
210             return (type) ? getTyPtr(type) : convertFIRType(named_typed->fType);
211         } else if (array_typed) {
212             // Arrays of 0 size are actually pointers on the type
213             return (array_typed->fSize == 0)
214                        ? fTypeMap[array_typed->getType()]
215                        : ArrayType::get(fTypeMap[Typed::getTypeFromPtr(array_typed->getType())], array_typed->fSize);
216         } else if (vector_typed) {
217         #if !defined(LLVM_120) && !defined(LLVM_130) && !defined(LLVM_140)
218             return VectorType::get(fTypeMap[vector_typed->fType->fType], vector_typed->fSize);
219         #else
220             faustassert(false);
221             return nullptr;
222         #endif
223         } else if (struct_typed) {
224             LLVMVecTypes llvm_types;
225             for (const auto& it : struct_typed->fFields) {
226                 llvm_types.push_back(convertFIRType(it));
227             }
228             return getStructType("struct.dsp" + struct_typed->fName, llvm_types);
229         } else {
230             faustassert(false);
231             return nullptr;
232         }
233     }
234 
235 };
236 
237 //=====================
238 // LLVM code generator
239 //=====================
240 
241 class LLVMInstVisitor : public InstVisitor, public LLVMTypeHelper {
242    protected:
243     // To be used for "alloca", which have to be added in the first "entry" block of the function
244     IRBuilder<>* fAllocaBuilder;
245     IRBuilder<>* fBuilder;
246 
247     StructInstVisitor* fStructVisitor;          // Contains offset of each field in the DSP struct
248     LLVMValue          fCurValue;               // Current compilation result
249 
250     map<string, LLVMValue>       fStackVars;    // Variables on the stack
251     map<string, GlobalVariable*> fStringTable;  // Global strings
252 
253     list<string> fMathLibTable;                 // All standard math functions
254 
255 #if defined(LLVM_80) || defined(LLVM_90) || defined(LLVM_100) || defined(LLVM_110) || defined(LLVM_120) || defined(LLVM_130) || defined(LLVM_140)
256     map<string, Intrinsic::ID> fUnaryIntrinsicTable;    // LLVM unary intrinsic
257     map<string, Intrinsic::ID> fBinaryIntrinsicTable;   // LLVM binary intrinsic
258 #endif
printVarTable()259     void printVarTable()
260     {
261         for (const auto& it : fStackVars) {
262             cout << "Stack var = " << it.first << endl;
263         }
264     }
265 
getCurType()266     LLVMType getCurType() { return fCurValue->getType(); }
267 
genBlock(const string & name,Function * fun=nullptr)268     BasicBlock* genBlock(const string& name, Function* fun = nullptr)
269     {
270         return BasicBlock::Create(fModule->getContext(), name, fun);
271     }
272 
addStringConstant(string arg,LLVMType & type_def)273     GlobalVariable* addStringConstant(string arg, LLVMType& type_def)
274     {
275         string str = replaceChar(unquote(arg), '@', '_');
276         type_def   = ArrayType::get(getInt8Ty(), str.size() + 1);
277 
278         if (fStringTable.find(str) == fStringTable.end()) {
279             fStringTable[str] = genGlovalVar(type_def, true, str);
280             fStringTable[str]->setInitializer(ConstantDataArray::getString(fModule->getContext(), str, true));
281         }
282 
283         return fStringTable[str];
284     }
285 
loadStructVarAddress(const string & name)286     LLVMValue loadStructVarAddress(const string& name)
287     {
288         return MakeStructGEP(loadFunArg("dsp"), fStructVisitor->getFieldIndex(name));
289     }
290 
loadStructArrayVarAddress(const string & name)291     LLVMValue loadStructArrayVarAddress(const string& name)
292     {
293         int       field_index = fStructVisitor->getFieldIndex(name);
294         LLVMValue idx[]       = {genInt32(0), genInt32(field_index)};
295         return fBuilder->CreateInBoundsGEP(loadFunArg("dsp"), MakeIdx(idx, idx + 2));
296     }
297 
loadArrayAsPointer(LLVMValue variable,bool is_volatile=false)298     LLVMValue loadArrayAsPointer(LLVMValue variable, bool is_volatile = false)
299     {
300         if (isa<ArrayType>(variable->getType()->getPointerElementType())) {
301             LLVMValue idx[] = {genInt32(0), genInt32(0)};
302             return fBuilder->CreateInBoundsGEP(variable, MakeIdx(idx, idx + 2));
303         } else {
304             return fBuilder->CreateLoad(variable, is_volatile);
305         }
306     }
307 
loadFunArg(const string & name)308     LLVMValue loadFunArg(const string& name)
309     {
310         // Get the enclosing function
311         Function* function = fBuilder->GetInsertBlock()->getParent();
312 
313         for (Function::arg_iterator it = function->arg_begin(); it != function->arg_end(); ++it) {
314             LLVMValue arg = GetIterator(it);
315             if (arg->getName() == name) return arg;
316         }
317 
318         faustassert(false);
319         return nullptr;
320     }
321 
322    public:
LLVMInstVisitor(Module * module,IRBuilder<> * builder,StructInstVisitor * struct_visitor,llvm::PointerType * dsp_ptr)323     LLVMInstVisitor(Module* module, IRBuilder<>* builder, StructInstVisitor* struct_visitor, llvm::PointerType* dsp_ptr)
324         : LLVMTypeHelper(module), fBuilder(builder), fStructVisitor(struct_visitor), fCurValue(nullptr)
325     {
326         fTypeMap[Typed::kObj_ptr] = dsp_ptr;
327         fAllocaBuilder            = new IRBuilder<>(fModule->getContext());
328 
329     #if defined(LLVM_80) || defined(LLVM_90) || defined(LLVM_100) || defined(LLVM_110) || defined(LLVM_120) || defined(LLVM_130) || defined(LLVM_140)
330 
331         /* This does not work in visit(FunCallInst* inst) for intrinsic, which are deactivated for now
332         call_inst->addAttribute(AttributeList::FunctionIndex, Attribute::Builtin);
333         */
334 
335         /*
336         // Float version
337         fUnaryIntrinsicTable["ceilf"] = Intrinsic::ceil;
338         fUnaryIntrinsicTable["cosf"] = Intrinsic::cos;
339         fUnaryIntrinsicTable["expf"] = Intrinsic::exp;
340         fUnaryIntrinsicTable["floorf"] = Intrinsic::floor;
341         fUnaryIntrinsicTable["logf"] = Intrinsic::log;
342         fUnaryIntrinsicTable["log10f"] = Intrinsic::log10;
343         fUnaryIntrinsicTable["rintf"] = Intrinsic::rint;
344         fUnaryIntrinsicTable["roundf"] = Intrinsic::round;
345         fUnaryIntrinsicTable["sqrtf"] = Intrinsic::sqrt;
346         fBinaryIntrinsicTable["powf"] = Intrinsic::pow;
347         fUnaryIntrinsicTable["sinf"] = Intrinsic::sin;
348 
349         // Double version
350         fUnaryIntrinsicTable["ceil"] = Intrinsic::ceil;
351         fUnaryIntrinsicTable["cos"] = Intrinsic::cos;
352         fUnaryIntrinsicTable["exp"] = Intrinsic::exp;
353         fUnaryIntrinsicTable["floor"] = Intrinsic::floor;
354         fUnaryIntrinsicTable["log"] = Intrinsic::log;
355         fUnaryIntrinsicTable["log10"] = Intrinsic::log10;
356         fUnaryIntrinsicTable["rint"] = Intrinsic::rint;
357         fUnaryIntrinsicTable["round"] = Intrinsic::round;
358         fUnaryIntrinsicTable["sqrt"] = Intrinsic::sqrt;
359         fBinaryIntrinsicTable["pow"] = Intrinsic::pow;
360         fUnaryIntrinsicTable["sin"] = Intrinsic::sin;
361         */
362     #endif
363 
364         // Integer version
365         fMathLibTable.push_back("abs");
366 
367         // Float version
368         fMathLibTable.push_back("fabsf");
369         fMathLibTable.push_back("acosf");
370         fMathLibTable.push_back("asinf");
371         fMathLibTable.push_back("atanf");
372         fMathLibTable.push_back("atan2f");
373         fMathLibTable.push_back("ceilf");
374         fMathLibTable.push_back("cosf");
375         fMathLibTable.push_back("expf");
376         fMathLibTable.push_back("exp10f");
377         fMathLibTable.push_back("floorf");
378         fMathLibTable.push_back("fmodf");
379         fMathLibTable.push_back("logf");
380         fMathLibTable.push_back("log10f");
381         fMathLibTable.push_back("powf");
382         fMathLibTable.push_back("rintf");
383         fMathLibTable.push_back("roundf");
384         fMathLibTable.push_back("sinf");
385         fMathLibTable.push_back("sqrtf");
386         fMathLibTable.push_back("tanf");
387 
388         // Additional hyperbolic math functions
389         fMathLibTable.push_back("acoshf");
390         fMathLibTable.push_back("asinhf");
391         fMathLibTable.push_back("atanhf");
392         fMathLibTable.push_back("coshf");
393         fMathLibTable.push_back("sinhf");
394         fMathLibTable.push_back("tanhf");
395 
396         // Double version
397         fMathLibTable.push_back("fabs");
398         fMathLibTable.push_back("acos");
399         fMathLibTable.push_back("asin");
400         fMathLibTable.push_back("atan");
401         fMathLibTable.push_back("atan2");
402         fMathLibTable.push_back("ceil");
403         fMathLibTable.push_back("cos");
404         fMathLibTable.push_back("exp");
405         fMathLibTable.push_back("exp10");
406         fMathLibTable.push_back("floor");
407         fMathLibTable.push_back("fmod");
408         fMathLibTable.push_back("log");
409         fMathLibTable.push_back("log10");
410         fMathLibTable.push_back("pow");
411         fMathLibTable.push_back("rint");
412         fMathLibTable.push_back("round");
413         fMathLibTable.push_back("sin");
414         fMathLibTable.push_back("sqrt");
415         fMathLibTable.push_back("tan");
416 
417         // Additional hyperbolic math functions
418         fMathLibTable.push_back("acosh");
419         fMathLibTable.push_back("asinh");
420         fMathLibTable.push_back("atanh");
421         fMathLibTable.push_back("cosh");
422         fMathLibTable.push_back("sinh");
423         fMathLibTable.push_back("tanh");
424     }
425 
~LLVMInstVisitor()426     virtual ~LLVMInstVisitor() { delete fAllocaBuilder; }
427 
428     //========
429     // String
430     //========
431 
genStringConstant(const string & label)432     LLVMValue genStringConstant(const string& label)
433     {
434         // Get LLVM constant string
435         LLVMType type_def  = nullptr;
436         return MakeConstGEP32(type_def, addStringConstant(label, type_def));
437     }
438 
439     //==============
440     // Declarations
441     //==============
442 
visit(DeclareVarInst * inst)443     virtual void visit(DeclareVarInst* inst)
444     {
445         string              name   = inst->fAddress->getName();
446         Address::AccessType access = inst->fAddress->getAccess();
447 
448         if (access & Address::kStack || access & Address::kLoop) {
449 
450             // Always at the begining since the block is already branched to next one...
451             fAllocaBuilder->SetInsertPoint(GetIterator(fAllocaBuilder->GetInsertBlock()->getFirstInsertionPt()));
452             fCurValue = fAllocaBuilder->CreateAlloca(convertFIRType(inst->fType));
453 
454             fCurValue->setName(name);
455             fStackVars[name] = fCurValue;  // Keep stack variables
456 
457             // Declaration with a value
458             if (inst->fValue) {
459                 // Result is in fCurValue;
460                 inst->fValue->accept(this);
461                 genStore(fStackVars[name], fCurValue, false);
462             }
463 
464         } else if (access & Address::kGlobal || access & Address::kStaticStruct) {
465 
466             GlobalVariable* global_value = genGlovalVar(convertFIRType(inst->fType), (access & Address::kConst), name);
467 
468             // Declaration with a value
469             if (inst->fValue) {
470                 // Result is in fCurValue;
471                 inst->fValue->accept(this);
472                 global_value->setInitializer(static_cast<Constant*>(fCurValue));
473             } else {
474                 // Init with typed zero
475                 global_value->setInitializer(Constant::getNullValue(convertFIRType(inst->fType)));
476             }
477 
478         } else {
479             faustassert(false);
480         }
481 
482         // No result in fCurValue
483         fCurValue = nullptr;
484     }
485 
visit(DeclareFunInst * inst)486     virtual void visit(DeclareFunInst* inst)
487     {
488         Function* function = fModule->getFunction(inst->fName);
489 
490         // Define it
491         if (!function) {
492 
493             // Min/max are internally generated
494             if (checkMinMax(inst->fName)) {
495                 goto end;
496             }
497 
498             // Return type
499             LLVMType return_type = fTypeMap[inst->getResType()];
500 
501             // Prepare vector of LLVM types for args
502             LLVMVecTypes fun_args_type;
503             for (const auto& it : inst->fType->fArgsTypes) {
504                 fun_args_type.push_back(fTypeMap[it->getType()]);
505             }
506 
507             // Creates function
508             FunctionType* fun_type = FunctionType::get(return_type, makeArrayRef(fun_args_type), false);
509             function = Function::Create(fun_type, (inst->fType->fAttribute & FunTyped::kLocal
510                                                    || inst->fType->fAttribute & FunTyped::kStatic)
511                                         ? GlobalValue::InternalLinkage
512                                         : GlobalValue::ExternalLinkage,
513                                         inst->fName, fModule);
514 
515             // In order for auto-vectorization to correctly work with vectorizable math functions
516             if (find(fMathLibTable.begin(), fMathLibTable.end(), inst->fName) != fMathLibTable.end()) {
517                 function->setDoesNotAccessMemory();
518             }
519             function->setDoesNotThrow();
520 
521             // Set name for function arguments
522             Function::arg_iterator args = function->arg_begin();
523             for (const auto& it : inst->fType->fArgsTypes) {
524                 LLVMValue arg = GetIterator(args++);
525                 arg->setName(it->fName);
526             }
527 
528             // If there is a body, compile it
529             if (inst->fCode->fCode.size() > 0) {
530                 // Prepare a entry_block to insert into
531                 BasicBlock* entry_block = genBlock("entry_block", function);
532 
533                 fBuilder->SetInsertPoint(entry_block);
534                 // "Alloca" in first "entry_bock" are mandatory so that vectorization passes correctly work
535                 fAllocaBuilder->SetInsertPoint(entry_block);
536 
537                 // Compile code in this block
538                 inst->fCode->accept(this);
539                 verifyFunction(*function);
540 
541                 // Clear inserting points
542                 fBuilder->ClearInsertionPoint();
543                 fAllocaBuilder->ClearInsertionPoint();
544             }
545         }
546 
547     end:
548         // No result in fCurValue
549         fCurValue = nullptr;
550     }
551 
552     //==========
553     // Adresses
554     //==========
555 
visitNameAddressAux(NamedAddress * named_address)556     LLVMValue visitNameAddressAux(NamedAddress* named_address)
557     {
558         string              name   = named_address->fName;
559         Address::AccessType access = named_address->fAccess;
560 
561         if (access & Address::kStruct) {
562             return loadStructVarAddress(name);
563         } else if (access & Address::kFunArgs) {
564             return loadFunArg(name);
565         } else if (access & Address::kStack || access & Address::kLoop) {
566             return fStackVars[name];
567         } else if ((access & Address::kGlobal) || (access & Address::kStaticStruct)) {
568             return fModule->getGlobalVariable(name, true);
569         } else {
570             faustassert(false);
571             return nullptr;
572         }
573     }
574 
visitIndexedAddressAux(IndexedAddress * indexed_address)575     LLVMValue visitIndexedAddressAux(IndexedAddress* indexed_address)
576     {
577         NamedAddress* named_address = dynamic_cast<NamedAddress*>(indexed_address->fAddress);
578         faustassert(named_address);  // One level indexation for now
579 
580         // Compute index, result is in fCurValue
581         indexed_address->fIndex->accept(this);
582         Address::AccessType access = named_address->fAccess;
583         string              name   = named_address->fName;
584         LLVMValue           load_ptr;
585 
586         if (access & Address::kStruct) {
587             load_ptr = loadArrayAsPointer(loadStructArrayVarAddress(name));
588         } else if (access & Address::kFunArgs) {
589             load_ptr = loadFunArg(name);
590         } else if (access & Address::kStack || access & Address::kLoop) {
591             // We want to see array like [256 x float] as a float*
592             load_ptr = loadArrayAsPointer(fStackVars[name]);
593         } else if (access & Address::kGlobal || access & Address::kStaticStruct) {
594             // We want to see array like [256 x float] as a float*
595             load_ptr = loadArrayAsPointer(fModule->getGlobalVariable(name, true));
596         } else {
597             faustassert(false);
598             return nullptr;
599         }
600 
601         // Indexed adresses can actually be values in an array or fields in a struct type
602         if (isStructType(indexed_address->getName())) {
603             LLVMValue idx[] = {genInt32(0), fCurValue};
604             return fBuilder->CreateInBoundsGEP(load_ptr, MakeIdx(idx, idx + 2));
605         } else {
606             return fBuilder->CreateInBoundsGEP(load_ptr, fCurValue);
607         }
608     }
609 
visit(Address * address)610     virtual LLVMValue visit(Address* address)
611     {
612         NamedAddress*   named_address   = dynamic_cast<NamedAddress*>(address);
613         IndexedAddress* indexed_address = dynamic_cast<IndexedAddress*>(address);
614 
615         if (named_address) {
616             return visitNameAddressAux(named_address);
617         } else if (indexed_address) {
618             return visitIndexedAddressAux(indexed_address);
619         } else {
620             faustassert(false);
621             return nullptr;
622         }
623     }
624 
625     //=============
626     // LoadVarInst
627     //=============
628 
visit(LoadVarInst * inst)629     virtual void visit(LoadVarInst* inst)
630     {
631         NamedAddress*   named_address   = dynamic_cast<NamedAddress*>(inst->fAddress);
632         IndexedAddress* indexed_address = dynamic_cast<IndexedAddress*>(inst->fAddress);
633 
634         if (named_address) {
635             if (named_address->fAccess & Address::kFunArgs) {
636                 fCurValue = visit(inst->fAddress);
637             } else {
638                 // We want to see array like [256 x float] as a float*
639                 fCurValue = loadArrayAsPointer(visit(inst->fAddress), named_address->fAccess & Address::kVolatile);
640             }
641         } else if (indexed_address) {
642             fCurValue = fBuilder->CreateLoad(visit(inst->fAddress));
643         } else {
644             faustassert(false);
645         }
646     }
647 
648     //====================
649     // LoadVarAddressInst
650     //====================
651 
visit(LoadVarAddressInst * inst)652     virtual void visit(LoadVarAddressInst* inst)
653     {
654         fCurValue = visit(inst->fAddress);
655     }
656 
657     //==============
658     // StoreVarInst
659     //==============
660 
genStore(LLVMValue store_ptr,LLVMValue store,bool is_volatile)661     void genStore(LLVMValue store_ptr, LLVMValue store, bool is_volatile)
662     {
663         // HACK : special case if we store a 0 (null pointer) in an address
664         // (used in vec mode and in "allocate" function in scheduler mode...)
665         LLVMType type = store_ptr->getType();
666         if ((type != getTyPtr(store->getType())) && (type == getInt32Ty() || type == getInt64Ty())) {
667             store = ConstantPointerNull::get(static_cast<LLVMPtrType>(type->getContainedType(0)));
668         }
669         fBuilder->CreateStore(store, store_ptr, is_volatile);
670     }
671 
visit(StoreVarInst * inst)672     virtual void visit(StoreVarInst* inst)
673     {
674         LLVMValue store_ptr = visit(inst->fAddress);
675 
676         // Result is in fCurValue;
677         inst->fValue->accept(this);
678         genStore(store_ptr, fCurValue, inst->fAddress->getAccess() & Address::kVolatile);
679 
680         // No result in fCurValue
681         fCurValue = nullptr;
682     }
683 
684     //=========
685     // Numbers
686     //=========
687 
visit(FloatNumInst * inst)688     virtual void visit(FloatNumInst* inst) { fCurValue = genFloat(inst->fNum); }
689 
visit(FloatArrayNumInst * inst)690     virtual void visit(FloatArrayNumInst* inst)
691     {
692         vector<Constant*> num_array;
693         for (size_t i = 0; i < inst->fNumTable.size(); i++) {
694             num_array.push_back(static_cast<ConstantFP*>(genFloat(inst->fNumTable[i])));
695         }
696         fCurValue = genArray(getFloatTy(), num_array);
697     }
698 
visit(DoubleNumInst * inst)699     virtual void visit(DoubleNumInst* inst) { fCurValue = genDouble(inst->fNum); }
700 
visit(DoubleArrayNumInst * inst)701     virtual void visit(DoubleArrayNumInst* inst)
702     {
703         vector<Constant*> num_array;
704         for (size_t i = 0; i < inst->fNumTable.size(); i++) {
705             num_array.push_back(static_cast<ConstantFP*>(genDouble(inst->fNumTable[i])));
706         }
707         fCurValue = genArray(getDoubleTy(), num_array);
708     }
709 
visit(Int32NumInst * inst)710     virtual void visit(Int32NumInst* inst) { fCurValue = genInt32(inst->fNum); }
711 
visit(Int32ArrayNumInst * inst)712     virtual void visit(Int32ArrayNumInst* inst)
713     {
714         vector<Constant*> num_array;
715         for (size_t i = 0; i < inst->fNumTable.size(); i++) {
716             num_array.push_back(static_cast<ConstantFP*>(genInt32(inst->fNumTable[i])));
717         }
718         fCurValue = genArray(getInt32Ty(), num_array);
719     }
720 
visit(BoolNumInst * inst)721     virtual void visit(BoolNumInst* inst) { fCurValue = genInt1(inst->fNum); }
722 
visit(Int64NumInst * inst)723     virtual void visit(Int64NumInst* inst) { fCurValue = genInt64(inst->fNum); }
724 
visit(BinopInst * inst)725     virtual void visit(BinopInst* inst)
726     {
727         // Keep result of first arg compilation
728         inst->fInst1->accept(this);
729         LLVMValue res1 = fCurValue;
730 
731         // Keep result of second arg compilation
732         inst->fInst2->accept(this);
733         LLVMValue res2 = fCurValue;
734 
735         fCurValue = generateBinop(inst->fOpcode, res1, res2);
736     }
737 
738     //======
739     // Cast
740     //======
741 
visit(::CastInst * inst)742     virtual void visit(::CastInst* inst)
743     {
744         // Compile instruction to be casted, result in fCurValue
745         inst->fInst->accept(this);
746         visitCastAux(inst->fType->getType());
747     }
748 
visitCastAux(Typed::VarType type)749     void visitCastAux(Typed::VarType type)
750     {
751         switch (type) {
752 
753             case Typed::kInt32:
754                 if (getCurType() == getInt32Ty()) {
755                     // Nothing to do
756                 } else if (getCurType() == getFloatTy() || getCurType() == getDoubleTy()) {
757                     fCurValue = fBuilder->CreateFPToSI(fCurValue, getInt32Ty());
758                 } else if (getCurType() == getInt64Ty()) {
759                     fCurValue = fBuilder->CreateTrunc(fCurValue, getInt32Ty());
760                 } else if (getCurType()->isPointerTy()) {
761                     // Use BitCast for pointer to kInt32
762                     fCurValue = fBuilder->CreateBitCast(fCurValue, getInt32Ty());
763                 } else {
764                     faustassert(false);
765                 }
766                 break;
767 
768             case Typed::kFloat:
769                 if (getCurType() == getInt32Ty() || getCurType() == getInt64Ty()) {
770                     fCurValue = fBuilder->CreateSIToFP(fCurValue, getFloatTy());
771                 } else if (getCurType() == getFloatTy()) {
772                     // Nothing to do
773                 } else if (getCurType() == getDoubleTy()) {
774                     fCurValue = fBuilder->CreateFPTrunc(fCurValue, getFloatTy());
775                 } else {
776                     faustassert(false);
777                 }
778                 break;
779 
780             case Typed::kDouble:
781                 if (getCurType() == getInt32Ty() || getCurType() == getInt64Ty()) {
782                     fCurValue = fBuilder->CreateSIToFP(fCurValue, getDoubleTy());
783                 } else if (getCurType() == getFloatTy()) {
784                     fCurValue = fBuilder->CreateFPExt(fCurValue, getDoubleTy());
785                 } else if (getCurType() == getDoubleTy()) {
786                     // Nothing to do
787                 } else {
788                     faustassert(false);
789                 }
790                 break;
791 
792             case Typed::kFloat_ptr:
793             case Typed::kFloat_ptr_ptr:
794             case Typed::kDouble_ptr:
795             case Typed::kDouble_ptr_ptr:
796             case Typed::kInt32_ptr:
797             case Typed::kFloatMacro_ptr:
798             case Typed::kFloatMacro_ptr_ptr:
799             case Typed::kObj_ptr:
800             case Typed::kVoid_ptr:
801                 fCurValue = fBuilder->CreateBitCast(fCurValue, fTypeMap[type]);
802                 break;
803 
804             case Typed::kUint_ptr:
805                 fCurValue = fBuilder->CreatePtrToInt(fCurValue, MakeIntPtrType());
806                 break;
807 
808             case Typed::kQuad:
809             case Typed::kInt64:
810             default:
811                 faustassert(false);
812                 break;
813         }
814     }
815 
visit(::BitcastInst * inst)816     virtual void visit(::BitcastInst* inst)
817     {
818         // Compile exp to bitcast, result in fCurValue
819         inst->fInst->accept(this);
820         fCurValue = fBuilder->CreateBitCast(fCurValue, fTypeMap[inst->fType->getType()]);
821     }
822 
823     //=========
824     // Control
825     //=========
826 
visit(RetInst * inst)827     virtual void visit(RetInst* inst)
828     {
829         if (inst->fResult) {
830             // Add a return instruction
831             inst->fResult->accept(this);
832             fBuilder->CreateRet(fCurValue);
833         } else {
834             // Add a return void instruction
835             fBuilder->CreateRetVoid();
836         }
837     }
838 
visit(DropInst * inst)839     virtual void visit(DropInst* inst)
840     {
841         if (inst->fResult) {
842             // Result is in fCurValue;
843             inst->fResult->accept(this);
844         }
845         // Drop it
846         fCurValue = nullptr;
847     }
848 
visit(FunCallInst * inst)849     virtual void visit(FunCallInst* inst)
850     {
851         // Compile function arguments
852         vector<LLVMValue> fun_args;
853         for (const auto& it : inst->fArgs) {
854             // Each argument is compiled and result is in fCurValue
855             it->accept(this);
856             fun_args.push_back(fCurValue);
857         }
858 
859         // Min/max are internally generated
860         if (checkMin(inst->fName) && fun_args.size() == 2) {
861             fCurValue = generateFunPolymorphicMinMax(fun_args[0], fun_args[1], kLT);
862         } else if (checkMax(inst->fName) && fun_args.size() == 2) {
863             fCurValue = generateFunPolymorphicMinMax(fun_args[0], fun_args[1], kGT);
864     #if defined(LLVM_80) || defined(LLVM_90) || defined(LLVM_100) || defined(LLVM_110) || defined(LLVM_120) || defined(LLVM_130) || defined(LLVM_140)
865         // LLVM unary intrinsic
866         } else if (fUnaryIntrinsicTable.find(inst->fName) != fUnaryIntrinsicTable.end()) {
867 
868             CallInst* call_inst = fBuilder->CreateUnaryIntrinsic(fUnaryIntrinsicTable[inst->fName], fun_args[0]);
869             ADD_ATTRIBUTE_AT_INDEX(call_inst, AttributeList::FunctionIndex, Attribute::Builtin);
870             fCurValue = call_inst;
871 
872         // LLVM binary intrinsic
873         } else if (fBinaryIntrinsicTable.find(inst->fName) != fBinaryIntrinsicTable.end()) {
874 
875             CallInst* call_inst = fBuilder->CreateBinaryIntrinsic(fBinaryIntrinsicTable[inst->fName], fun_args[0], fun_args[1]);
876             ADD_ATTRIBUTE_AT_INDEX(call_inst, AttributeList::FunctionIndex, Attribute::Builtin);
877             fCurValue = call_inst;
878     #endif
879         } else {
880             // Get function in the module
881             Function* function = fModule->getFunction(gGlobal->getMathFunction(inst->fName));
882             faustassert(function);
883 
884             // Result is function call
885             CallInst* call_inst = CreateFuncall(function, fun_args);
886             ADD_ATTRIBUTE_AT_INDEX(call_inst, AttributeList::FunctionIndex, Attribute::Builtin);
887             fCurValue = call_inst;
888         }
889     }
890 
891     /*
892     virtual void visit(Select2Inst* inst)
893     {
894         if (inst->fThen->isSimpleValue() && inst->fElse->isSimpleValue()) {
895             visitSelect(inst);
896         } else {
897             visitIf(inst);
898         }
899     }
900     */
901 
902     // Actually faster...
visit(Select2Inst * inst)903     virtual void visit(Select2Inst* inst)
904     {
905         visitIf(inst);
906     }
907 
908     // Select that computes both branches
visitSelect(Select2Inst * inst)909     void visitSelect(Select2Inst* inst)
910     {
911         // Compile condition, result in fCurValue
912         inst->fCond->accept(this);
913 
914         // Compare condition to 0
915         LLVMValue cond_value = fBuilder->CreateICmp(ICmpInst::ICMP_NE, fCurValue, genInt32(0));
916 
917         // Compile then branch, result in fCurValue
918         inst->fThen->accept(this);
919         LLVMValue then_value = fCurValue;
920 
921         // Compile else branch, result in fCurValue
922         inst->fElse->accept(this);
923         LLVMValue else_value = fCurValue;
924 
925         // Creates the result
926         fCurValue = fBuilder->CreateSelect(cond_value, then_value, else_value);
927     }
928 
929     /*
930      Select that only computes one branch.
931 
932      This could be implemented using a PHI node (to group the result of the 'then' and 'else' blocks)
933      but is more complicated to do when hierarchical 'select' are compiled.
934 
935      Thus we create a local variable that is written in 'then' and 'else' blocks,
936      and loaded in the 'merge' block.
937 
938      LLVM passes will later one create a unique PHI node that groups all results,
939      especially when hierarchical 'select' are compiled.
940     */
visitIf(Select2Inst * inst)941     virtual void visitIf(Select2Inst* inst)
942     {
943         // Compile condition, result in fCurValue
944         inst->fCond->accept(this);
945 
946         // Compare condition to 0
947         LLVMValue cond_value = fBuilder->CreateICmp(ICmpInst::ICMP_NE, fCurValue, genInt32(0));
948 
949         // Get enclosing function
950         Function* function = fBuilder->GetInsertBlock()->getParent();
951 
952         // Create blocks for the then and else cases. Insert the 'merge_block' block at the end of the function
953         BasicBlock* then_block  = genBlock("select_then_block", function);
954         BasicBlock* else_block  = genBlock("select_else_block");
955         BasicBlock* merge_block = genBlock("select_merge_block");
956 
957         fBuilder->CreateCondBr(cond_value, then_block, else_block);
958 
959         // Emit then block
960         fBuilder->SetInsertPoint(then_block);
961 
962         // Compile then branch
963         inst->fThen->accept(this);
964 
965         // Create typed local variable
966 
967         // Always at the begining since the block is already branched to next one...
968         fAllocaBuilder->SetInsertPoint(GetIterator(fAllocaBuilder->GetInsertBlock()->getFirstInsertionPt()));
969         LLVMValue typed_res = fAllocaBuilder->CreateAlloca(getCurType(), nullptr, "select_res");
970 
971         // "Then" is a BlockInst, result is in fCurValue
972         fBuilder->CreateStore(fCurValue, typed_res);
973 
974         // Branch in merge_block
975         fBuilder->CreateBr(merge_block);
976 
977         // Emit else block
978         function->getBasicBlockList().push_back(else_block);
979         fBuilder->SetInsertPoint(else_block);
980 
981         // Compile else branch
982         inst->fElse->accept(this);
983 
984         // "Else" is a BlockInst, result is in fCurValue
985         fBuilder->CreateStore(fCurValue, typed_res);
986 
987         // Branch in merge_block
988         fBuilder->CreateBr(merge_block);
989 
990         // Emit merge block
991         function->getBasicBlockList().push_back(merge_block);
992         fBuilder->SetInsertPoint(merge_block);
993 
994         // Load result in fCurValue
995         fCurValue = fBuilder->CreateLoad(typed_res);
996     }
997 
visit(IfInst * inst)998     virtual void visit(IfInst* inst)
999     {
1000         // Compile condition, result in fCurValue
1001         inst->fCond->accept(this);
1002 
1003         // Compare condition to 0
1004         LLVMValue cond_value = fBuilder->CreateICmp(ICmpInst::ICMP_NE, fCurValue, genInt32(0));
1005 
1006         // Get enclosing function
1007         Function* function = fBuilder->GetInsertBlock()->getParent();
1008 
1009         // Create blocks for the then and else cases. Insert the 'merge_block' block at the end of the function
1010         BasicBlock* then_block  = genBlock("if_then_block", function);
1011         BasicBlock* else_block  = genBlock("if_else_block");
1012         BasicBlock* merge_block = genBlock("if_merge_block");
1013 
1014         fBuilder->CreateCondBr(cond_value, then_block, else_block);
1015 
1016         // Emit then block
1017         fBuilder->SetInsertPoint(then_block);
1018 
1019         // Compile then branch
1020         inst->fThen->accept(this);
1021         // "Then" is a BlockInst, so no result in fCurValue
1022 
1023         // Branch in merge_block
1024         fBuilder->CreateBr(merge_block);
1025 
1026         // Emit else block
1027         function->getBasicBlockList().push_back(else_block);
1028         fBuilder->SetInsertPoint(else_block);
1029 
1030         // Compile else branch
1031         inst->fElse->accept(this);
1032         // "Else" is a BlockInst, so no result in fCurValue
1033 
1034         // Branch in merge_block
1035         fBuilder->CreateBr(merge_block);
1036 
1037         // Emit merge block
1038         function->getBasicBlockList().push_back(merge_block);
1039         fBuilder->SetInsertPoint(merge_block);
1040 
1041         // No result in fCurValue
1042         fCurValue = nullptr;
1043     }
1044 
visit(ForLoopInst * inst)1045     virtual void visit(ForLoopInst* inst)
1046     {
1047         // Don't generate empty loops...
1048         if (inst->fCode->size() == 0) return;
1049 
1050         Function* function = fBuilder->GetInsertBlock()->getParent();
1051         faustassert(function);
1052 
1053         // Create init_block
1054         BasicBlock* init_block = genBlock("init_block", function);
1055 
1056         // Create test_block
1057         BasicBlock* test_block = genBlock("test_block", function);
1058 
1059         // Create loop_body_block
1060         BasicBlock* loop_body_block = genBlock("loop_body_block", function);
1061 
1062         // Create exit_block
1063         BasicBlock* exit_block = genBlock("exit_block", function);
1064 
1065         // Init condition section
1066         {
1067             // Link previous_block and init_block
1068             fBuilder->CreateBr(init_block);
1069 
1070             // Start insertion in init_block
1071             fBuilder->SetInsertPoint(init_block);
1072 
1073             // Compute init value, now loop counter is allocated
1074             inst->fInit->accept(this);
1075 
1076             // Link init_block and test_block
1077             fBuilder->CreateBr(test_block);
1078 
1079             // Start insertion in test_block
1080             fBuilder->SetInsertPoint(test_block);
1081         }
1082 
1083         // Get loop counter local variable
1084         string loop_counter_name = inst->getName();
1085 
1086         // Start the PHI node with an entry for start
1087         PHINode* phi_node = CreatePhi(getInt32Ty(), loop_counter_name);
1088         phi_node->addIncoming(genInt32(0), init_block);
1089 
1090         // End condition section
1091         {
1092             // Compute end condition, result in fCurValue
1093             inst->fEnd->accept(this);
1094 
1095             // Compare condition to 0
1096             LLVMValue end_cond = fBuilder->CreateICmp(ICmpInst::ICMP_NE, fCurValue, genInt32(0));
1097 
1098             // Insert the conditional branch into the last block of loop
1099             fBuilder->CreateCondBr(end_cond, loop_body_block, exit_block);
1100         }
1101 
1102         // Loop body section
1103         {
1104             // Start insertion in loop_body_block
1105             fBuilder->SetInsertPoint(loop_body_block);
1106 
1107             // Generates loop internal code
1108             inst->fCode->accept(this);
1109         }
1110 
1111         // Get last block of post code section
1112         BasicBlock* current_block = fBuilder->GetInsertBlock();
1113 
1114         // Increment section
1115         {
1116             // Compile increment, result in fCurValue
1117             StoreVarInst* store_inst1 = dynamic_cast<StoreVarInst*>(inst->fIncrement);
1118             store_inst1->fValue->accept(this);
1119             LLVMValue next_index = fCurValue;
1120             next_index->setName("next_index");
1121 
1122             // Store the next value
1123             fBuilder->CreateStore(next_index, fStackVars[loop_counter_name]);
1124 
1125             // Add a new entry to the PHI node for the backedge
1126             phi_node->addIncoming(next_index, current_block);
1127 
1128             // Back to start of loop
1129             fBuilder->CreateBr(test_block);
1130         }
1131 
1132         // Move insertion in exit_block
1133         fBuilder->SetInsertPoint(exit_block);
1134 
1135         // No result in fCurValue
1136         fCurValue = nullptr;
1137     }
1138 
visit(WhileLoopInst * inst)1139     virtual void visit(WhileLoopInst* inst)
1140     {
1141         Function* function = fBuilder->GetInsertBlock()->getParent();
1142         faustassert(function);
1143 
1144         // Prepare cond_block block
1145         BasicBlock* cond_block = genBlock("cond_block", function);
1146 
1147         // Link previous_block and cond_block
1148         fBuilder->CreateBr(cond_block);
1149 
1150         // Start insertion in cond_block
1151         fBuilder->SetInsertPoint(cond_block);
1152 
1153         // Compile condition, result in fCurValue
1154         inst->fCond->accept(this);
1155 
1156         // Create the test_block and insert it
1157         BasicBlock* test_block = genBlock("test_block", function);
1158 
1159         // Create the exit_block and insert it
1160         BasicBlock* exit_block = genBlock("exit_block", function);
1161 
1162         // Compare condition to 0
1163         LLVMValue end_cond = fBuilder->CreateICmp(ICmpInst::ICMP_NE, fCurValue, genInt32(0));
1164 
1165         // Insert the conditional branch into the end of cond_block
1166         fBuilder->CreateCondBr(end_cond, test_block, exit_block);
1167 
1168         // Move insertion in test_block
1169         fBuilder->SetInsertPoint(test_block);
1170 
1171         // Compiles internal block
1172         inst->fCode->accept(this);
1173 
1174         // Branch back to cond block
1175         fBuilder->CreateBr(cond_block);
1176 
1177         // Move insertion in exit_block
1178         fBuilder->SetInsertPoint(exit_block);
1179 
1180         // No result in fCurValue
1181         fCurValue = nullptr;
1182     }
1183 
visit(BlockInst * inst)1184     virtual void visit(BlockInst* inst)
1185     {
1186         if (fBuilder->GetInsertBlock()) {
1187             Function* function = fBuilder->GetInsertBlock()->getParent();
1188             faustassert(function);
1189 
1190             // Prepare code_block block
1191             BasicBlock* code_block = genBlock("code_block", function);
1192 
1193             // Link previous_block and code_block
1194             fBuilder->CreateBr(code_block);
1195 
1196             // Start insertion in code_block
1197             fBuilder->SetInsertPoint(code_block);
1198         }
1199 
1200         // Generates block internal code
1201         for (const auto& it : inst->fCode) {
1202             it->accept(this);
1203         }
1204 
1205         // No result in fCurValue
1206         fCurValue = nullptr;
1207     }
1208 
visit(::SwitchInst * inst)1209     virtual void visit(::SwitchInst* inst)
1210     {
1211         Function* function = fBuilder->GetInsertBlock()->getParent();
1212         faustassert(function);
1213 
1214         // Prepare init_code block
1215         BasicBlock* init_block = genBlock("init_block", function);
1216 
1217         // Prepare exit_block block
1218         BasicBlock* exit_block = genBlock("exit_block", function);
1219 
1220         // Link previous_block and init_block
1221         fBuilder->CreateBr(init_block);
1222 
1223         // Start insertion in init_block
1224         fBuilder->SetInsertPoint(init_block);
1225 
1226         // Compile condition, result in fCurValue
1227         inst->fCond->accept(this);
1228 
1229         // Creates "default" block
1230         BasicBlock* default_block = genBlock("default_block", function);
1231 
1232         // Creates switch
1233         llvm::SwitchInst* switch_inst = fBuilder->CreateSwitch(fCurValue, default_block, inst->fCode.size());
1234 
1235         list<pair<int, BlockInst*> >::const_iterator it;
1236         for (it = inst->fCode.begin(); it != inst->fCode.end(); it++) {
1237             if ((*it).first != -1) {  // All cases but "default"
1238                 // Creates "case" block
1239                 BasicBlock* case_block = genBlock("case_block", function);
1240                 // Move insertion in case_block
1241                 fBuilder->SetInsertPoint(case_block);
1242                 // Compiles "case" block
1243                 (*it).second->accept(this);
1244                 // Link init_block and exit_block
1245                 fBuilder->CreateBr(exit_block);
1246                 // Add it into the switch
1247                 switch_inst->addCase(static_cast<ConstantInt*>(genInt32((*it).first)), case_block);
1248             }
1249         }
1250 
1251         for (it = inst->fCode.begin(); it != inst->fCode.end(); it++) {
1252             if ((*it).first == -1) {  // Default case found
1253                 break;
1254             }
1255         }
1256 
1257         // Move insertion in default_block
1258         fBuilder->SetInsertPoint(default_block);
1259 
1260         // Compiles "default" block if one has been found
1261         if (it != inst->fCode.end()) {
1262             (*it).second->accept(this);
1263         }
1264 
1265         // Link init_block and exit_block
1266         fBuilder->CreateBr(exit_block);
1267 
1268         // Move insertion in exit_block
1269         fBuilder->SetInsertPoint(exit_block);
1270 
1271         // No result in fCurValue
1272         fCurValue = nullptr;
1273     }
1274 
1275     //=============
1276     // Helper code
1277     //=============
1278 
generateBinop(int opcode,LLVMValue arg1,LLVMValue arg2)1279     LLVMValue generateBinop(int opcode, LLVMValue arg1, LLVMValue arg2)
1280     {
1281         // Arguments are casted if needed in InstructionsCompiler::generateBinOp
1282         faustassert(arg1->getType() == arg2->getType());
1283 
1284         if (arg1->getType() == getFloatTy() || arg1->getType() == getDoubleTy()) {
1285             return generateBinOpReal(opcode, arg1, arg2);
1286         } else if (arg1->getType() == getInt32Ty() || arg1->getType() == getInt64Ty()) {
1287             return generateBinOpInt(opcode, arg1, arg2);
1288         } else {
1289             faustassert(false);
1290             return nullptr;
1291         }
1292     }
1293 
generateBinOpReal(int opcode,LLVMValue arg1,LLVMValue arg2)1294     LLVMValue generateBinOpReal(int opcode, LLVMValue arg1, LLVMValue arg2)
1295     {
1296         if (isBoolOpcode(opcode)) {
1297             LLVMValue comp_value =
1298                 fBuilder->CreateFCmp((CmpInst::Predicate)gBinOpTable[opcode]->fLLVMFloatInst, arg1, arg2);
1299             // Inst result for comparison
1300             return fBuilder->CreateSelect(comp_value, genInt32(1), genInt32(0));
1301         } else {
1302             LLVMValue value =
1303                 fBuilder->CreateBinOp((Instruction::BinaryOps)gBinOpTable[opcode]->fLLVMFloatInst, arg1, arg2);
1304             Instruction* inst = cast<Instruction>(value);
1305             inst->setMetadata(LLVMContext::MD_fpmath, fBuilder->getDefaultFPMathTag());
1306             inst->setFastMathFlags(fBuilder->getFastMathFlags());
1307             return inst;
1308         }
1309     }
1310 
generateBinOpInt(int opcode,LLVMValue arg1,LLVMValue arg2)1311     LLVMValue generateBinOpInt(int opcode, LLVMValue arg1, LLVMValue arg2)
1312     {
1313         if (isBoolOpcode(opcode)) {
1314             LLVMValue comp_value =
1315                 fBuilder->CreateICmp((CmpInst::Predicate)gBinOpTable[opcode]->fLLVMIntInst, arg1, arg2);
1316             // Inst result for comparison
1317             return fBuilder->CreateSelect(comp_value, genInt32(1), genInt32(0));
1318         } else {
1319             return fBuilder->CreateBinOp((Instruction::BinaryOps)gBinOpTable[opcode]->fLLVMIntInst, arg1, arg2);
1320         }
1321     }
1322 
generateFunPolymorphicMinMax(LLVMValue arg1,LLVMValue arg2,int comp)1323     LLVMValue generateFunPolymorphicMinMax(LLVMValue arg1, LLVMValue arg2, int comp)
1324     {
1325         faustassert(arg1->getType() == arg2->getType());
1326 
1327         if (arg1->getType() == getFloatTy() || arg1->getType() == getDoubleTy()) {
1328             return (comp == kLT) ? fBuilder->CreateMinNum(arg1, arg2) : fBuilder->CreateMaxNum(arg1, arg2);
1329         } else if (arg1->getType() == getInt32Ty()) {
1330             LLVMValue comp_value =
1331                 fBuilder->CreateICmp((CmpInst::Predicate)gBinOpTable[comp]->fLLVMIntInst, arg1, arg2);
1332             return fBuilder->CreateSelect(comp_value, arg1, arg2);
1333         } else {
1334             faustassert(false);
1335             return nullptr;
1336         }
1337     }
1338 };
1339 
1340 #endif
1341