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_DSP_AUX_H 23 #define LLVM_DSP_AUX_H 24 25 #include <map> 26 #include <string> 27 #include <utility> 28 #include <vector> 29 30 #include "faust/dsp/dsp.h" 31 #include "faust/gui/CInterface.h" 32 #include "faust/gui/JSONUIDecoder.h" 33 #include "faust/gui/meta.h" 34 35 #include "dsp_aux.hh" 36 #include "dsp_factory.hh" 37 #include "export.hh" 38 #include "smartpointer.h" 39 #include "timing.hh" 40 41 #include <llvm/ExecutionEngine/ObjectCache.h> 42 #include <llvm/Support/MemoryBuffer.h> 43 44 #define LLVM_MAX_OPT_LEVEL 5 45 46 #define STREAM_ERROR std::error_code 47 #define MEMORY_BUFFER llvm::MemoryBufferRef 48 #define MEMORY_BUFFER_GET(buffer) (buffer.getBuffer()) 49 #define MEMORY_BUFFER_GET_REF(buffer) (buffer->get()->getMemBufferRef()) 50 #define MEMORY_BUFFER_CREATE(stringref) (llvm::MemoryBufferRef(stringref, "")) 51 #define ModulePTR std::unique_ptr<Module> 52 #define MovePTR(ptr) std::move(ptr) 53 #define PASS_MANAGER legacy::PassManager 54 #define FUNCTION_PASS_MANAGER legacy::FunctionPassManager 55 #define sysfs_binary_flag sys::fs::OF_None 56 #define OwningPtr std::unique_ptr 57 #define llvmcreatePrintModulePass(out) createPrintModulePass(out) 58 #define GET_CPU_NAME llvm::sys::getHostCPUName().str() 59 60 #define BUFFER_SIZE 1024 61 #define SAMPLE_RATE 44100 62 #define MAX_CHAN 64 63 #define MAX_SOUNDFILE_PARTS 256 64 65 #ifdef _MSC_VER 66 #define PRE_PACKED_STRUCTURE __pragma(pack(push, 1)) 67 #define POST_PACKED_STRUCTURE \ 68 ; \ 69 __pragma(pack(pop)) 70 #else 71 #define PRE_PACKED_STRUCTURE 72 #define POST_PACKED_STRUCTURE __attribute__((__packed__)) 73 #endif 74 75 PRE_PACKED_STRUCTURE 76 struct Soundfile { 77 double** fBuffers; // use the largest size to cover 'float' and 'double' cases 78 int* fLength; // length of each part 79 int* fSR; // sample rate of each part 80 int* fOffset; // offset of each part in the global buffer 81 int fChannels; // max number of channels of all concatenated files 82 bool fIsDouble; 83 SoundfileSoundfile84 Soundfile(int max_chan) 85 { 86 fBuffers = new double*[max_chan]; 87 fLength = new int[MAX_SOUNDFILE_PARTS]; 88 fSR = new int[MAX_SOUNDFILE_PARTS]; 89 fOffset = new int[MAX_SOUNDFILE_PARTS]; 90 91 for (int part = 0; part < MAX_SOUNDFILE_PARTS; part++) { 92 fLength[part] = BUFFER_SIZE; 93 fSR[part] = SAMPLE_RATE; 94 fOffset[part] = 0; 95 } 96 97 // Allocate 1 channel 98 fChannels = 1; 99 fBuffers[0] = new double[BUFFER_SIZE]; 100 faustassert(fBuffers[0]); 101 memset(fBuffers[0], 0, BUFFER_SIZE * sizeof(double)); 102 103 // Share the same buffer for all other channels so that we have max_chan channels available 104 for (int chan = fChannels; chan < max_chan; chan++) { 105 fBuffers[chan] = fBuffers[0]; 106 } 107 } 108 ~SoundfileSoundfile109 ~Soundfile() 110 { 111 // Free the real channels only 112 for (int chan = 0; chan < fChannels; chan++) { 113 delete[] fBuffers[chan]; 114 } 115 delete[] fBuffers; 116 delete[] fLength; 117 delete[] fSR; 118 delete[] fOffset; 119 } 120 121 } POST_PACKED_STRUCTURE; 122 123 extern Soundfile* dynamic_defaultsound; 124 125 // namespace llvm 126 namespace llvm { 127 class LLVMContext; 128 class ExecutionEngine; 129 class Module; 130 } // namespace llvm 131 132 class llvm_dsp_factory; 133 134 // Public C++ interface 135 136 class EXPORT llvm_dsp : public dsp { 137 private: 138 llvm_dsp_factory* fFactory; 139 JSONUIDecoderBase* fDecoder; 140 dsp_imp* fDSP; 141 142 public: 143 llvm_dsp(llvm_dsp_factory* factory, dsp_imp* dsp); 144 virtual ~llvm_dsp(); 145 146 void operator delete(void* ptr); 147 148 virtual int getNumInputs(); 149 150 virtual int getNumOutputs(); 151 152 virtual void buildUserInterface(UI* ui_interface); 153 154 virtual void buildUserInterface(UIGlue* glue); 155 156 virtual int getSampleRate(); 157 158 virtual void init(int sample_rate); 159 160 virtual void instanceInit(int sample_rate); 161 162 virtual void instanceConstants(int sample_rate); 163 164 virtual void instanceResetUserInterface(); 165 166 virtual void instanceClear(); 167 168 virtual void classInit(int sample_rate); 169 170 virtual llvm_dsp* clone(); 171 172 virtual void metadata(Meta* m); 173 174 virtual void metadata(MetaGlue* glue); 175 176 virtual void compute(int count, FAUSTFLOAT** input, FAUSTFLOAT** output); 177 }; 178 179 class FaustObjectCache : public llvm::ObjectCache { 180 private: 181 std::string fMachineCode; 182 anchor()183 virtual void anchor() {} 184 185 public: FaustObjectCache(const std::string & machine_code="")186 FaustObjectCache(const std::string& machine_code = "") : fMachineCode(machine_code) {} 187 ~FaustObjectCache()188 virtual ~FaustObjectCache() {} 189 notifyObjectCompiled(const llvm::Module * M,llvm::MemoryBufferRef Obj)190 virtual void notifyObjectCompiled(const llvm::Module* M, llvm::MemoryBufferRef Obj) 191 { 192 fMachineCode = Obj.getBuffer().str(); 193 } 194 getObject(const llvm::Module * M)195 virtual std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* M) 196 { 197 return (fMachineCode == "") ? nullptr : llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(fMachineCode)); 198 } 199 getMachineCode()200 std::string getMachineCode() { return fMachineCode; } 201 }; 202 203 typedef class faust_smartptr<llvm_dsp_factory> SDsp_factory; 204 205 // Internal API 206 typedef void (* deleteDspFun) (dsp_imp* dsp); 207 typedef void (* allocateDspFun) (dsp_imp* dsp); 208 typedef const char* (* getJSONFun) (); 209 210 class llvm_dsp_factory_aux : public dsp_factory_imp { 211 friend class llvm_dsp; 212 friend class llvm_dsp_factory; 213 214 protected: 215 llvm::ExecutionEngine* fJIT; 216 FaustObjectCache* fObjectCache; 217 llvm::Module* fModule; 218 llvm::LLVMContext* fContext; 219 JSONUIDecoderBase* fDecoder; 220 221 int fOptLevel; 222 std::string fTarget; 223 std::string fClassName; 224 std::string fTypeName; 225 226 allocateDspFun fAllocate; 227 destroyDspFun fDestroy; 228 initFun fInstanceConstants; 229 instanceClearFun fInstanceClear; 230 classInitFun fClassInit; 231 computeFun fCompute; 232 getJSONFun fGetJSON; 233 234 uint64_t loadOptimize(const std::string& function); 235 236 void init(const std::string& dsp_name, const std::string& type_name); 237 238 bool crossCompile(const std::string& target); 239 240 static void LLVMFatalErrorHandler(const char* reason); 241 242 void startLLVMLibrary(); 243 void stopLLVMLibrary(); 244 245 std::string writeDSPFactoryToMachineAux(const std::string& target); 246 checkDecoder()247 void checkDecoder() 248 { 249 if (!fDecoder) fDecoder = createJSONUIDecoder(fGetJSON()); 250 } 251 252 public: 253 llvm_dsp_factory_aux(const std::string& sha_key, llvm::Module* module, llvm::LLVMContext* context, 254 const std::string& target, int opt_level = 0); 255 256 llvm_dsp_factory_aux(const std::string& sha_key, const std::string& machine_code, const std::string& target); 257 258 virtual ~llvm_dsp_factory_aux(); 259 260 std::string getCompileOptions(); 261 std::vector<std::string> getLibraryList(); 262 std::vector<std::string> getIncludePathnames(); 263 264 virtual bool initJIT(std::string& error_msg); 265 bool initJITAux(); 266 267 static llvm_dsp_factory* readDSPFactoryFromMachineAux(MEMORY_BUFFER buffer, const std::string& target, 268 std::string& error_msg); 269 270 // Bitcode writeDSPFactoryToBitcode()271 virtual std::string writeDSPFactoryToBitcode() { return ""; } 272 writeDSPFactoryToBitcodeFile(const std::string & bit_code_path)273 virtual bool writeDSPFactoryToBitcodeFile(const std::string& bit_code_path) { return false; } 274 275 // IR writeDSPFactoryToIR()276 virtual std::string writeDSPFactoryToIR() { return ""; } 277 writeDSPFactoryToIRFile(const std::string & ir_code_path)278 virtual bool writeDSPFactoryToIRFile(const std::string& ir_code_path) { return false; } 279 280 // Machine 281 virtual std::string writeDSPFactoryToMachine(const std::string& target); 282 283 virtual bool writeDSPFactoryToMachineFile(const std::string& machine_code_path, const std::string& target); 284 285 // Object writeDSPFactoryToObjectcodeFile(const std::string & object_code_path,const std::string & target)286 virtual bool writeDSPFactoryToObjectcodeFile(const std::string& object_code_path, const std::string& target) 287 { 288 return false; 289 } 290 291 std::string getTarget(); setTarget(const std::string & target)292 void setTarget(const std::string& target) { fTarget = target; } 293 294 int getOptlevel(); setOptlevel(int opt_level)295 void setOptlevel(int opt_level) 296 { 297 fOptLevel = ((opt_level == -1) || (opt_level > LLVM_MAX_OPT_LEVEL)) ? LLVM_MAX_OPT_LEVEL : opt_level; 298 } 299 setClassName(const std::string & class_name)300 void setClassName(const std::string& class_name) { fClassName = class_name; } 301 302 llvm_dsp* createDSPInstance(dsp_factory* factory); 303 304 void metadata(Meta* m); 305 306 void metadata(MetaGlue* glue); 307 308 static int gInstance; 309 310 static dsp_factory_table<SDsp_factory> gLLVMFactoryTable; 311 }; 312 313 // Public C++ interface 314 315 class EXPORT llvm_dsp_factory : public dsp_factory, public faust_smartable { 316 private: 317 llvm_dsp_factory_aux* fFactory; 318 ~llvm_dsp_factory()319 virtual ~llvm_dsp_factory() { delete fFactory; } 320 321 public: llvm_dsp_factory(llvm_dsp_factory_aux * factory)322 llvm_dsp_factory(llvm_dsp_factory_aux* factory) : fFactory(factory) {} 323 getName()324 std::string getName() { return fFactory->getName(); } 325 getSHAKey()326 std::string getSHAKey() { return fFactory->getSHAKey(); } setSHAKey(std::string sha_key)327 void setSHAKey(std::string sha_key) { fFactory->setSHAKey(sha_key); } 328 getDSPCode()329 std::string getDSPCode() { return fFactory->getDSPCode(); } setDSPCode(std::string code)330 void setDSPCode(std::string code) { fFactory->setDSPCode(code); } 331 getCompileOptions()332 std::string getCompileOptions() { return fFactory->getCompileOptions(); } 333 getLibraryList()334 std::vector<std::string> getLibraryList() { return fFactory->getLibraryList(); } getIncludePathnames()335 std::vector<std::string> getIncludePathnames() { return fFactory->getIncludePathnames(); } 336 getTarget()337 std::string getTarget() { return fFactory->getTarget(); } 338 339 llvm_dsp* createDSPInstance(); 340 setMemoryManager(dsp_memory_manager * manager)341 void setMemoryManager(dsp_memory_manager* manager) { fFactory->setMemoryManager(manager); } getMemoryManager()342 dsp_memory_manager* getMemoryManager() { return fFactory->getMemoryManager(); } 343 setMemoryManager(MemoryManagerGlue * manager)344 void setMemoryManager(MemoryManagerGlue* manager) 345 { 346 // To check 347 fFactory->setMemoryManager(static_cast<dsp_memory_manager*>(manager->managerInterface)); 348 } 349 write(std::ostream * out,bool binary,bool compact=false)350 void write(std::ostream* out, bool binary, bool compact = false) {} 351 writeDSPFactoryToBitcode()352 std::string writeDSPFactoryToBitcode() { return fFactory->writeDSPFactoryToBitcode(); } 353 writeDSPFactoryToBitcodeFile(const std::string & bit_code_path)354 bool writeDSPFactoryToBitcodeFile(const std::string& bit_code_path) 355 { 356 return fFactory->writeDSPFactoryToBitcodeFile(bit_code_path); 357 } 358 writeDSPFactoryToIR()359 std::string writeDSPFactoryToIR() { return fFactory->writeDSPFactoryToIR(); } 360 writeDSPFactoryToIRFile(const std::string & ir_code_path)361 bool writeDSPFactoryToIRFile(const std::string& ir_code_path) 362 { 363 return fFactory->writeDSPFactoryToIRFile(ir_code_path); 364 } 365 writeDSPFactoryToMachine(const std::string & target)366 std::string writeDSPFactoryToMachine(const std::string& target) 367 { 368 return fFactory->writeDSPFactoryToMachine(target); 369 } 370 writeDSPFactoryToMachineFile(const std::string & machine_code_path,const std::string & target)371 bool writeDSPFactoryToMachineFile(const std::string& machine_code_path, const std::string& target) 372 { 373 return fFactory->writeDSPFactoryToMachineFile(machine_code_path, target); 374 } 375 writeDSPFactoryToObjectcodeFile(const std::string & object_code_path,const std::string & target)376 bool writeDSPFactoryToObjectcodeFile(const std::string& object_code_path, const std::string& target) 377 { 378 return fFactory->writeDSPFactoryToObjectcodeFile(object_code_path, target); 379 } 380 getFactory()381 llvm_dsp_factory_aux* getFactory() { return fFactory; } 382 }; 383 384 EXPORT llvm_dsp_factory* getDSPFactoryFromSHAKey(const std::string& sha_key); 385 386 EXPORT bool deleteDSPFactory(llvm_dsp_factory* factory); 387 388 EXPORT std::string getDSPMachineTarget(); 389 390 EXPORT std::vector<std::string> getLibraryList(llvm_dsp_factory* factory); 391 392 EXPORT std::vector<std::string> getAllDSPFactories(); 393 394 EXPORT void deleteAllDSPFactories(); 395 396 // machine <==> string 397 EXPORT llvm_dsp_factory* readDSPFactoryFromMachine(const std::string& machine_code, const std::string& target, 398 std::string& error_msg); 399 400 // machine <==> file 401 EXPORT llvm_dsp_factory* readDSPFactoryFromMachineFile(const std::string& machine_code_path, const std::string& target, 402 std::string& error_msg); 403 404 EXPORT std::string writeDSPFactoryToMachine(llvm_dsp_factory* factory, const std::string& target); 405 406 EXPORT bool writeDSPFactoryToMachineFile(llvm_dsp_factory* factory, const std::string& machine_code_path, 407 const std::string& target); 408 409 #ifdef __cplusplus 410 extern "C" { 411 #endif 412 413 // Public C interface 414 415 EXPORT llvm_dsp_factory* getCDSPFactoryFromSHAKey(const char* sha_key); 416 417 EXPORT bool deleteCDSPFactory(llvm_dsp_factory* factory); 418 419 EXPORT char* getCName(llvm_dsp_factory* factory); 420 421 EXPORT char* getCSHAKey(llvm_dsp_factory* factory); 422 423 EXPORT char* getCTarget(llvm_dsp_factory* factory); 424 425 EXPORT char* getCDSPCode(llvm_dsp_factory* factory); 426 427 EXPORT char* getCDSPMachineTarget(); 428 429 EXPORT const char** getCDSPFactoryLibraryList(llvm_dsp_factory* factory); 430 431 EXPORT const char** getCDSPFactoryIncludePathnames(llvm_dsp_factory* factory); 432 433 EXPORT char* getCDSPFactoryCompileOptions(llvm_dsp_factory* factory); 434 435 EXPORT void deleteAllCDSPFactories(); 436 437 EXPORT const char** getAllCDSPFactories(); 438 439 EXPORT bool startMTCDSPFactories(); 440 441 EXPORT void stopMTCDSPFactories(); 442 443 EXPORT llvm_dsp_factory* readCDSPFactoryFromMachine(const char* machine_code, const char* target, char* error_msg); 444 445 EXPORT char* writeCDSPFactoryToMachine(llvm_dsp_factory* factory, const char* target); 446 447 EXPORT llvm_dsp_factory* readCDSPFactoryFromMachineFile(const char* machine_code_path, const char* target, 448 char* error_msg); 449 450 EXPORT bool writeCDSPFactoryToMachineFile(llvm_dsp_factory* factory, const char* machine_code_path, const char* target); 451 452 EXPORT bool writeCDSPFactoryToObjectcodeFile(llvm_dsp_factory* factory, const char* object_code_path, 453 const char* target); 454 455 EXPORT void metadataCDSPInstance(llvm_dsp* dsp, MetaGlue* meta); 456 457 EXPORT int getNumInputsCDSPInstance(llvm_dsp* dsp); 458 459 EXPORT int getNumOutputsCDSPInstance(llvm_dsp* dsp); 460 461 EXPORT void buildUserInterfaceCDSPInstance(llvm_dsp* dsp, UIGlue* ui_interface); 462 463 EXPORT int getSampleRateCDSPInstance(llvm_dsp* dsp); 464 465 EXPORT void initCDSPInstance(llvm_dsp* dsp, int sample_rate); 466 467 EXPORT void instanceInitCDSPInstance(llvm_dsp* dsp, int sample_rate); 468 469 EXPORT void instanceConstantsCDSPInstance(llvm_dsp* dsp, int sample_rate); 470 471 EXPORT void instanceResetUserInterfaceCDSPInstance(llvm_dsp* dsp); 472 473 EXPORT void instanceClearCDSPInstance(llvm_dsp* dsp); 474 475 EXPORT llvm_dsp* cloneCDSPInstance(llvm_dsp* dsp); 476 477 EXPORT void computeCDSPInstance(llvm_dsp* dsp, int count, FAUSTFLOAT** input, FAUSTFLOAT** output); 478 479 EXPORT void setCMemoryManager(llvm_dsp_factory* factory, MemoryManagerGlue* manager); 480 481 EXPORT llvm_dsp* createCDSPInstance(llvm_dsp_factory* factory); 482 483 EXPORT void deleteCDSPInstance(llvm_dsp* dsp); 484 485 EXPORT void generateCSHA1(const char* data, char* key); 486 487 #ifdef __cplusplus 488 } 489 #endif 490 491 #endif 492