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