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_CODE_CONTAINER_H 23 #define _LLVM_CODE_CONTAINER_H 24 25 #include "code_container.hh" 26 #include "llvm_instructions.hh" 27 #include "omp_code_container.hh" 28 #include "struct_manager.hh" 29 #include "vec_code_container.hh" 30 #include "wss_code_container.hh" 31 32 using namespace std; 33 using namespace llvm; 34 35 class LLVMCodeContainer : public virtual CodeContainer { 36 protected: 37 using CodeContainer::generateFillFun; 38 using CodeContainer::generateInstanceInitFun; 39 40 IRBuilder<>* fBuilder; 41 LLVMInstVisitor* fCodeProducer; 42 StructInstVisitor fStructVisitor; 43 44 Module* fModule; 45 LLVMContext* fContext; 46 47 // To be used for mathematical function mapping (-fm and exp10 on OSX) 48 void generateFunMap(const string& fun1_aux, const string& fun2_aux, int num_args, bool body = false); 49 void generateFunMaps(); 50 51 PointerType* generateDspStruct(); 52 53 // To be implemented in each LLVMScalarCodeContainer, LLVMVectorCodeContainer and LLVMWorkStealingCodeContainer 54 // classes 55 virtual void generateCompute() = 0; 56 57 template <typename REAL> generateGetJSON()58 void generateGetJSON() 59 { 60 PointerType* string_ptr = PointerType::get(fBuilder->getInt8Ty(), 0); 61 LLVMVecTypes getJSON_args; 62 FunctionType* getJSON_type = FunctionType::get(string_ptr, makeArrayRef(getJSON_args), false); 63 Function* getJSON = Function::Create(getJSON_type, GlobalValue::ExternalLinkage, "getJSON" + fKlassName, fModule); 64 65 // Prepare compilation options 66 stringstream compile_options; 67 gGlobal->printCompilationOptions(compile_options, false); 68 69 // JSON generation 70 JSONInstVisitor<REAL> json_visitor1; 71 generateUserInterface(&json_visitor1); 72 73 map<string, int> path_index_table; 74 for (const auto& it : json_visitor1.fPathTable) { 75 // Get field index 76 path_index_table[it.second] = fStructVisitor.getFieldOffset(it.first); 77 } 78 79 faustassert(fStructVisitor.getFieldOffset("fSampleRate") != -1); 80 81 JSONInstVisitor<REAL> json_visitor2("", "", fNumInputs, fNumOutputs, fStructVisitor.getFieldOffset("fSampleRate"), "", "", 82 FAUSTVERSION, compile_options.str(), gGlobal->gReader.listLibraryFiles(), 83 gGlobal->gImportDirList, fStructVisitor.getStructSize(), path_index_table); 84 generateUserInterface(&json_visitor2); 85 generateMetaData(&json_visitor2); 86 87 BasicBlock* return_block = BasicBlock::Create(*fContext, "return_block", getJSON); 88 ReturnInst::Create(*fContext, fCodeProducer->genStringConstant(json_visitor2.JSON(true)), return_block); 89 90 verifyFunction(*getJSON); 91 fBuilder->ClearInsertionPoint(); 92 } 93 94 void init(const string& name, int numInputs, int numOutputs, Module* module, LLVMContext* context); 95 96 public: 97 LLVMCodeContainer(const string& name, int numInputs, int numOutputs); 98 LLVMCodeContainer(const string& name, int numInputs, int numOutputs, Module* module, LLVMContext* context); 99 virtual ~LLVMCodeContainer(); 100 101 virtual dsp_factory_base* produceFactory(); 102 void produceInternal(); 103 104 CodeContainer* createScalarContainer(const string& name, int sub_container_type); 105 106 static CodeContainer* createContainer(const string& name, int numInputs, int numOutputs); 107 }; 108 109 class LLVMScalarCodeContainer : public LLVMCodeContainer { 110 protected: 111 void generateCompute(); 112 BlockInst* generateComputeAux(); 113 114 public: 115 LLVMScalarCodeContainer(const string& name, int numInputs, int numOutputs); 116 LLVMScalarCodeContainer(const string& name, int numInputs, int numOutputs, Module* module, LLVMContext* context, 117 int sub_container_type); 118 virtual ~LLVMScalarCodeContainer(); 119 }; 120 121 class LLVMVectorCodeContainer : public VectorCodeContainer, public LLVMCodeContainer { 122 protected: 123 void generateCompute(); 124 BlockInst* generateComputeAux(); 125 126 public: 127 LLVMVectorCodeContainer(const string& name, int numInputs, int numOutputs); 128 virtual ~LLVMVectorCodeContainer(); 129 }; 130 131 class LLVMOpenMPCodeContainer : public OpenMPCodeContainer, public LLVMCodeContainer { 132 protected: 133 void generateOMPDeclarations(); 134 void generateOMPCompute(); 135 void generateCompute(); 136 BlockInst* generateComputeAux(); 137 138 void generateGOMP_parallel_start(); 139 void generateGOMP_parallel_end(); 140 LLVMValue generateGOMP_single_start(); 141 void generateGOMP_barrier(); 142 void generateGOMP_sections_start(LLVMValue num); 143 void generateGOMP_sections_end(); 144 void generateGOMP_sections_next(); 145 146 void generateDSPOMPCompute(); 147 148 public: 149 LLVMOpenMPCodeContainer(const string& name, int numInputs, int numOutputs); 150 virtual ~LLVMOpenMPCodeContainer(); 151 }; 152 153 class LLVMWorkStealingCodeContainer : public WSSCodeContainer, public LLVMCodeContainer { 154 protected: 155 void generateCompute(); 156 BlockInst* generateComputeAux(); 157 158 public: 159 LLVMWorkStealingCodeContainer(const string& name, int numInputs, int numOutputs); 160 virtual ~LLVMWorkStealingCodeContainer(); 161 }; 162 163 #endif 164