1 // Copyright Contributors to the Open Shading Language project. 2 // SPDX-License-Identifier: BSD-3-Clause 3 // https://github.com/AcademySoftwareFoundation/OpenShadingLanguage 4 5 #pragma once 6 7 #include <vector> 8 #include <map> 9 10 #include "oslexec_pvt.h" 11 using namespace OSL; 12 using namespace OSL::pvt; 13 14 #include "runtimeoptimize.h" 15 #include <OSL/llvm_util.h> 16 17 // additional includes for creating global OptiX variables 18 #include "llvm/IR/Constants.h" 19 #include "llvm/IR/GlobalVariable.h" 20 #include "llvm/IR/Module.h" 21 22 23 OSL_NAMESPACE_ENTER 24 25 namespace pvt { // OSL::pvt 26 27 28 29 /// OSOProcessor that generates LLVM IR and JITs it to give machine 30 /// code to implement a shader group. 31 class BackendLLVM final : public OSOProcessorBase { 32 public: 33 BackendLLVM (ShadingSystemImpl &shadingsys, ShaderGroup &group, 34 ShadingContext *context); 35 36 virtual ~BackendLLVM (); 37 38 virtual void set_inst (int layer); 39 40 /// Create an llvm function for the whole shader group, JIT it, 41 /// and store the llvm::Function* handle to it with the ShaderGroup. 42 virtual void run (); 43 44 45 /// What LLVM debug level are we at? 46 int llvm_debug() const; 47 48 /// Set up a bunch of static things we'll need for the whole group. 49 /// 50 void initialize_llvm_group (); 51 layer_remap(int origlayer)52 int layer_remap (int origlayer) const { return m_layer_remap[origlayer]; } 53 54 /// Create an llvm function for the current shader instance. 55 /// This will end up being the group entry if 'groupentry' is true. 56 llvm::Function* build_llvm_instance (bool groupentry); 57 58 /// Create an llvm function for group initialization code. 59 llvm::Function* build_llvm_init (); 60 61 /// Build up LLVM IR code for the given range [begin,end) or 62 /// opcodes, putting them (initially) into basic block bb (or the 63 /// current basic block if bb==NULL). 64 bool build_llvm_code (int beginop, int endop, llvm::BasicBlock *bb=NULL); 65 66 typedef std::map<std::string, llvm::Value*> AllocationMap; 67 68 void llvm_assign_initial_value (const Symbol& sym, bool force = false); llvm_context()69 llvm::LLVMContext &llvm_context () const { return ll.context(); } named_values()70 AllocationMap &named_values () { return m_named_values; } 71 72 /// Return an llvm::Value* corresponding to the address of the given 73 /// symbol element, with derivative (0=value, 1=dx, 2=dy) and array 74 /// index (NULL if it's not an array). 75 llvm::Value *llvm_get_pointer (const Symbol& sym, int deriv=0, 76 llvm::Value *arrayindex=NULL); 77 78 /// Return the llvm::Value* corresponding to the given element 79 /// value, with derivative (0=value, 1=dx, 2=dy), array index (NULL 80 /// if it's not an array), and component (x=0 or scalar, y=1, z=2). 81 /// If deriv >0 and the symbol doesn't have derivatives, return 0 82 /// for the derivative. If the component >0 and it's a scalar, 83 /// return the scalar -- this allows automatic casting to triples. 84 /// Finally, auto-cast int<->float if requested (no conversion is 85 /// performed if cast is the default of UNKNOWN). 86 llvm::Value *llvm_load_value (const Symbol& sym, int deriv, 87 llvm::Value *arrayindex, int component, 88 TypeDesc cast=TypeDesc::UNKNOWN); 89 90 91 /// Given an llvm::Value* of a pointer (and the type of the data 92 /// that it points to), Return the llvm::Value* corresponding to the 93 /// given element value, with derivative (0=value, 1=dx, 2=dy), 94 /// array index (NULL if it's not an array), and component (x=0 or 95 /// scalar, y=1, z=2). If deriv >0 and the symbol doesn't have 96 /// derivatives, return 0 for the derivative. If the component >0 97 /// and it's a scalar, return the scalar -- this allows automatic 98 /// casting to triples. Finally, auto-cast int<->float if requested 99 /// (no conversion is performed if cast is the default of UNKNOWN). 100 llvm::Value *llvm_load_value (llvm::Value *ptr, const TypeSpec &type, 101 int deriv, llvm::Value *arrayindex, 102 int component, TypeDesc cast=TypeDesc::UNKNOWN); 103 104 /// Just like llvm_load_value, but when both the symbol and the 105 /// array index are known to be constants. This can even handle 106 /// pulling constant-indexed elements out of constant arrays. Use 107 /// arrayindex==-1 to indicate that it's not an array dereference. 108 llvm::Value *llvm_load_constant_value (const Symbol& sym, 109 int arrayindex, int component, 110 TypeDesc cast=TypeDesc::UNKNOWN); 111 112 /// llvm_load_value with non-constant component designation. Does 113 /// not work with arrays or do type casts! 114 llvm::Value *llvm_load_component_value (const Symbol& sym, int deriv, 115 llvm::Value *component); 116 117 /// Non-array version of llvm_load_value, with default deriv & 118 /// component. 119 llvm::Value *llvm_load_value (const Symbol& sym, int deriv = 0, 120 int component = 0, 121 TypeDesc cast=TypeDesc::UNKNOWN) { 122 return (use_optix() && ! sym.typespec().is_closure() && sym.typespec().is_string()) 123 ? llvm_load_device_string (sym, /*follow*/ true) 124 : llvm_load_value (sym, deriv, NULL, component, cast); 125 } 126 127 /// Load the address of a global device-side string pointer, which may 128 /// reside in a global variable, the groupdata struct, or a local value. 129 llvm::Value *llvm_load_device_string (const Symbol& sym, bool follow); 130 131 /// Convenience function to load a string for CPU or GPU device llvm_load_string(const Symbol & sym)132 llvm::Value *llvm_load_string (const Symbol& sym) { 133 OSL_DASSERT(sym.typespec().is_string()); 134 return use_optix() 135 ? llvm_load_device_string(sym, /*follow*/ true) 136 : llvm_load_value(sym); 137 } 138 139 /// Legacy version 140 /// 141 llvm::Value *loadLLVMValue (const Symbol& sym, int component=0, 142 int deriv=0, TypeDesc cast=TypeDesc::UNKNOWN) { 143 return llvm_load_value (sym, deriv, NULL, component, cast); 144 } 145 146 /// Return an llvm::Value* that is either a scalar and derivs is 147 /// false, or a pointer to sym's values (if sym is an aggregate or 148 /// derivs == true). Furthermore, if deriv == true and sym doesn't 149 /// have derivs, coerce it into a variable with zero derivs. 150 llvm::Value *llvm_load_arg (const Symbol& sym, bool derivs); 151 152 /// Just like llvm_load_arg(sym,deriv), except use use sym's derivs 153 /// as-is, no coercion. llvm_load_arg(const Symbol & sym)154 llvm::Value *llvm_load_arg (const Symbol& sym) { 155 return llvm_load_arg (sym, sym.has_derivs()); 156 } 157 158 /// Store new_val into the given symbol, given the derivative 159 /// (0=value, 1=dx, 2=dy), array index (NULL if it's not an array), 160 /// and component (x=0 or scalar, y=1, z=2). If deriv>0 and the 161 /// symbol doesn't have a deriv, it's a nop. If the component >0 162 /// and it's a scalar, set the scalar. Returns true if ok, false 163 /// upon failure. 164 bool llvm_store_value (llvm::Value *new_val, const Symbol& sym, int deriv, 165 llvm::Value *arrayindex, int component); 166 167 /// Store new_val into the memory pointed to by dst_ptr, given the 168 /// derivative (0=value, 1=dx, 2=dy), array index (NULL if it's not 169 /// an array), and component (x=0 or scalar, y=1, z=2). If deriv>0 170 /// and the symbol doesn't have a deriv, it's a nop. If the 171 /// component >0 and it's a scalar, set the scalar. Returns true if 172 /// ok, false upon failure. 173 bool llvm_store_value (llvm::Value* new_val, llvm::Value* dst_ptr, 174 const TypeSpec &type, int deriv, 175 llvm::Value* arrayindex, int component); 176 177 /// Non-array version of llvm_store_value, with default deriv & 178 /// component. 179 bool llvm_store_value (llvm::Value *new_val, const Symbol& sym, 180 int deriv=0, int component=0) { 181 return llvm_store_value (new_val, sym, deriv, NULL, component); 182 } 183 184 /// llvm_store_value with non-constant component designation. Does 185 /// not work with arrays or do type casts! 186 bool llvm_store_component_value (llvm::Value *new_val, const Symbol& sym, 187 int deriv, llvm::Value *component); 188 189 /// Legacy version 190 /// 191 bool storeLLVMValue (llvm::Value* new_val, const Symbol& sym, 192 int component=0, int deriv=0) { 193 return llvm_store_value (new_val, sym, deriv, component); 194 } 195 196 /// Generate an alloca instruction to allocate space for the given 197 /// type, with derivs if derivs==true, and return the its pointer. 198 llvm::Value *llvm_alloca (const TypeSpec &type, bool derivs, 199 const std::string &name="", int align=0); 200 201 /// Given the OSL symbol, return the llvm::Value* corresponding to the 202 /// address of the start of that symbol (first element, first component, 203 /// and just the plain value if it has derivatives). This is retrieved 204 /// from the allocation map if already there; and if not yet in the 205 /// map, the symbol is alloca'd and placed in the map. 206 llvm::Value *getOrAllocateLLVMSymbol (const Symbol& sym); 207 208 /// Allocate a CUDA variable for the given OSL symbol and return a pointer 209 /// to the corresponding LLVM GlobalVariable, or return the pointer if it 210 /// has already been allocated. 211 llvm::Value *getOrAllocateCUDAVariable (const Symbol& sym, bool addMetadata=false); 212 213 /// Create a CUDA global variable and add it to the current Module 214 llvm::Value *addCUDAVariable (const std::string& name, int size, int alignment, 215 const void* data, TypeDesc type=TypeDesc::UNKNOWN); 216 217 /// Create the extra semantic information needed for OptiX variables 218 void createOptixMetadata (const std::string& name, const Symbol& sym ); 219 220 /// Retrieve an llvm::Value that is a pointer holding the start address 221 /// of the specified symbol. This always works for globals and params; 222 /// for stack variables (locals/temps) is succeeds only if the symbol is 223 /// already in the allocation table (will fail otherwise). This method 224 /// is not designed to retrieve constants. 225 llvm::Value *getLLVMSymbolBase (const Symbol &sym); 226 227 /// Retrieve the named global ("P", "N", etc.). 228 llvm::Value *llvm_global_symbol_ptr (ustring name); 229 230 /// Test whether val is nonzero, return the llvm::Value* that's the 231 /// result of a CreateICmpNE or CreateFCmpUNE (depending on the 232 /// type). If test_derivs is true, it it also tests whether the 233 /// derivs are zero. 234 llvm::Value *llvm_test_nonzero (Symbol &val, bool test_derivs = false); 235 236 /// Implementaiton of Simple assignment. If arrayindex >= 0, in 237 /// designates a particular array index to assign. 238 bool llvm_assign_impl (Symbol &Result, Symbol &Src, int arrayindex = -1, 239 int srccomp = -1, int dstcomp = -1); 240 241 242 /// Convert the name of a global (and its derivative index) into the 243 /// field number of the ShaderGlobals struct. 244 int ShaderGlobalNameToIndex (ustring name); 245 246 /// Return the LLVM type handle for the ShaderGlobals struct. 247 /// 248 llvm::Type *llvm_type_sg (); 249 250 /// Return the LLVM type handle for a pointer to a 251 /// ShaderGlobals struct. 252 llvm::Type *llvm_type_sg_ptr (); 253 254 /// Return the ShaderGlobals pointer. 255 /// sg_ptr()256 llvm::Value *sg_ptr () const { return m_llvm_shaderglobals_ptr; } 257 258 llvm::Type *llvm_type_closure_component (); 259 llvm::Type *llvm_type_closure_component_ptr (); 260 261 /// Return the ShaderGlobals pointer cast as a void*. 262 /// sg_void_ptr()263 llvm::Value *sg_void_ptr () { 264 return ll.void_ptr (m_llvm_shaderglobals_ptr); 265 } 266 llvm_ptr_cast(llvm::Value * val,const TypeSpec & type)267 llvm::Value *llvm_ptr_cast (llvm::Value* val, const TypeSpec &type) { 268 return ll.ptr_cast (val, type.simpletype()); 269 } 270 271 llvm::Value *llvm_void_ptr (const Symbol &sym, int deriv=0) { 272 return ll.void_ptr (llvm_get_pointer(sym, deriv)); 273 } 274 275 /// Return the LLVM type handle for a structure of the common group 276 /// data that holds all the shader params. 277 llvm::Type *llvm_type_groupdata (); 278 279 /// Return the LLVM type handle for a pointer to the common group 280 /// data that holds all the shader params. 281 llvm::Type *llvm_type_groupdata_ptr (); 282 283 /// Return the group data pointer. 284 /// groupdata_ptr()285 llvm::Value *groupdata_ptr () const { return m_llvm_groupdata_ptr; } 286 287 /// Return the group data pointer cast as a void*. 288 /// groupdata_void_ptr()289 llvm::Value *groupdata_void_ptr () { 290 return ll.void_ptr (m_llvm_groupdata_ptr); 291 } 292 293 /// Return a reference to the specified field within the group data. 294 llvm::Value *groupdata_field_ref (int fieldnum); 295 296 /// Return a pointer to the specified field within the group data, 297 /// optionally cast to pointer to a particular data type. 298 llvm::Value *groupdata_field_ptr (int fieldnum, 299 TypeDesc type = TypeDesc::UNKNOWN); 300 301 /// Return a ref to the bool where the "layer_run" flag is stored for 302 /// the specified layer. 303 llvm::Value *layer_run_ref (int layer); 304 305 /// Return a ref to the bool where the "userdata_initialized" flag is 306 /// stored for the specified userdata index. 307 llvm::Value *userdata_initialized_ref (int userdata_index=0); 308 309 /// Generate LLVM code to zero out the variable (including derivs) 310 /// 311 void llvm_assign_zero (const Symbol &sym); 312 313 /// Generate LLVM code to zero out the derivatives of sym. 314 /// 315 void llvm_zero_derivs (const Symbol &sym); 316 317 /// Generate LLVM code to zero out the derivatives of an array 318 /// only for the first count elements of it. 319 /// 320 void llvm_zero_derivs (const Symbol &sym, llvm::Value *count); 321 322 /// Generate a debugging printf at shader execution time. 323 void llvm_gen_debug_printf (string_view message); 324 325 /// Generate a warning message at shader execution time. 326 void llvm_gen_warning (string_view message); 327 328 /// Generate an error message at shader execution time. 329 void llvm_gen_error (string_view message); 330 331 /// Generate code to call the given layer. If 'unconditional' is 332 /// true, call it without even testing if the layer has already been 333 /// called. 334 void llvm_call_layer (int layer, bool unconditional = false); 335 336 /// Execute the upstream connection (if any, and if not yet run) that 337 /// establishes the value of symbol sym, which has index 'symindex' 338 /// within the current layer rop.inst(). If already_run is not NULL, 339 /// it points to a vector of layer indices that are known to have been 340 /// run -- those can be skipped without dynamically checking their 341 /// execution status. 342 void llvm_run_connected_layers (Symbol &sym, int symindex, int opnum = -1, 343 std::set<int> *already_run = NULL); 344 345 /// Generate code for a call to the named function with the given 346 /// arg list as symbols -- float & ints will be passed by value, 347 /// triples and matrices will be passed by address. If deriv_ptrs 348 /// is true, pass pointers even for floats if they have derivs. 349 /// Return an llvm::Value* corresponding to the return value of the 350 /// function, if any. 351 llvm::Value *llvm_call_function (const char *name, cspan<const Symbol *> args, 352 bool deriv_ptrs=false); 353 llvm::Value *llvm_call_function (const char *name, const Symbol &A, 354 bool deriv_ptrs=false) { 355 return llvm_call_function (name, { &A }, deriv_ptrs); 356 } 357 llvm::Value *llvm_call_function (const char *name, const Symbol &A, 358 const Symbol &B, bool deriv_ptrs=false) { 359 return llvm_call_function (name, { &A, &B }, deriv_ptrs); 360 } 361 llvm::Value *llvm_call_function (const char *name, const Symbol &A, 362 const Symbol &B, const Symbol &C, 363 bool deriv_ptrs=false) { 364 return llvm_call_function (name, { &A, &B, &C }, deriv_ptrs); 365 } 366 llvm_typedesc(const TypeSpec & typespec)367 TypeDesc llvm_typedesc (const TypeSpec &typespec) { 368 return typespec.is_closure_based() 369 ? TypeDesc(TypeDesc::PTR, typespec.arraylength()) 370 : typespec.simpletype(); 371 } 372 373 /// Generate the appropriate llvm type definition for a TypeSpec 374 /// (this is the actual type, for example when we allocate it). 375 /// Allocates ptrs for closures. llvm_type(const TypeSpec & typespec)376 llvm::Type *llvm_type (const TypeSpec &typespec) { 377 return ll.llvm_type (llvm_typedesc(typespec)); 378 } 379 380 /// Generate the parameter-passing llvm type definition for an OSL 381 /// TypeSpec. 382 llvm::Type *llvm_pass_type (const TypeSpec &typespec); 383 llvm_type_prepare_closure_func()384 llvm::PointerType *llvm_type_prepare_closure_func() { return m_llvm_type_prepare_closure_func; } llvm_type_setup_closure_func()385 llvm::PointerType *llvm_type_setup_closure_func() { return m_llvm_type_setup_closure_func; } 386 387 /// Return the basic block of the exit for the whole instance. 388 /// llvm_has_exit_instance_block()389 bool llvm_has_exit_instance_block () const { 390 return m_exit_instance_block; 391 } 392 393 /// Return the basic block of the exit for the whole instance. 394 /// llvm_exit_instance_block()395 llvm::BasicBlock *llvm_exit_instance_block () { 396 if (! m_exit_instance_block) { 397 std::string name = Strutil::sprintf ("%s_%d_exit_", inst()->layername(), inst()->id()); 398 m_exit_instance_block = ll.new_basic_block (name); 399 } 400 return m_exit_instance_block; 401 } 402 403 /// Check for inf/nan in all written-to arguments of the op 404 void llvm_generate_debugnan (const Opcode &op); 405 /// Check for uninitialized values in all read-from arguments to the op 406 void llvm_generate_debug_uninit (const Opcode &op); 407 /// Print debugging line for the op 408 void llvm_generate_debug_op_printf (const Opcode &op); 409 layer_func()410 llvm::Function *layer_func () const { return ll.current_function(); } 411 412 /// Call this when JITing a texture-like call, to track how many. generated_texture_call(bool handle)413 void generated_texture_call (bool handle) { 414 shadingsys().m_stat_tex_calls_codegened += 1; 415 if (handle) 416 shadingsys().m_stat_tex_calls_as_handles += 1; 417 } 418 419 /// Return the mapping from symbol names to GlobalVariables. get_const_map()420 std::map<std::string,llvm::GlobalVariable*>& get_const_map() { return m_const_map; } 421 422 /// Return whether or not we are compiling for an OptiX-based renderer. use_optix()423 bool use_optix() { return m_use_optix; } 424 425 /// Return the userdata index for the given Symbol. Return -1 if the Symbol 426 /// is not an input parameter or is constant and therefore doesn't have an 427 /// entry in the groupdata struct. 428 int find_userdata_index (const Symbol& sym); 429 430 LLVM_Util ll; 431 432 private: 433 std::vector<int> m_layer_remap; ///< Remapping of layer ordering 434 std::set<int> m_layers_already_run; ///< List of layers run 435 int m_num_used_layers; ///< Number of layers actually used 436 437 double m_stat_total_llvm_time; ///< total time spent on LLVM 438 double m_stat_llvm_setup_time; ///< llvm setup time 439 double m_stat_llvm_irgen_time; ///< llvm IR generation time 440 double m_stat_llvm_opt_time; ///< llvm IR optimization time 441 double m_stat_llvm_jit_time; ///< llvm JIT time 442 443 // LLVM stuff 444 AllocationMap m_named_values; 445 std::map<const Symbol*,int> m_param_order_map; 446 llvm::Value *m_llvm_shaderglobals_ptr; 447 llvm::Value *m_llvm_groupdata_ptr; 448 llvm::BasicBlock * m_exit_instance_block; // exit point for the instance 449 llvm::Type *m_llvm_type_sg; // LLVM type of ShaderGlobals struct 450 llvm::Type *m_llvm_type_groupdata; // LLVM type of group data 451 llvm::Type *m_llvm_type_closure_component; // LLVM type for ClosureComponent 452 llvm::PointerType *m_llvm_type_prepare_closure_func; 453 llvm::PointerType *m_llvm_type_setup_closure_func; 454 int m_llvm_local_mem; // Amount of memory we use for locals 455 456 // A mapping from symbol names to llvm::GlobalVariables 457 std::map<std::string,llvm::GlobalVariable*> m_const_map; 458 459 // A mapping from canonical strings to string variable names, used to 460 // detect collisions that might occur due to using the string hash to 461 // create variable names. 462 std::map<std::string,std::string> m_varname_map; 463 464 bool m_use_optix; ///< Compile for OptiX? 465 466 friend class ShadingSystemImpl; 467 }; 468 469 470 }; // namespace pvt 471 OSL_NAMESPACE_EXIT 472