Branch data Line data Source code
1 : : // This file is a part of Julia. License is MIT: https://julialang.org/license 2 : : 3 : : #ifndef LLVM_PASS_HELPERS_H 4 : : #define LLVM_PASS_HELPERS_H 5 : : 6 : : #include <llvm/IR/Function.h> 7 : : #include <llvm/IR/Instructions.h> 8 : : #include <llvm/IR/LLVMContext.h> 9 : : #include <llvm/IR/Metadata.h> 10 : : #include <llvm/IR/Module.h> 11 : : #include <llvm/IR/Type.h> 12 : : #include <llvm/IR/Value.h> 13 : : 14 : : struct JuliaPassContext; 15 : : 16 : : // A namespace for Julia intrinsic descriptions. 17 : : namespace jl_intrinsics { 18 : : // A description of an intrinsic that can be used to find existing 19 : : // intrinsics and declare new intrinsics if necessary. 20 : : struct IntrinsicDescription final { 21 : : // The type of function that declares an intrinsic. 22 : : typedef llvm::Function *(*DeclarationFunction)(const JuliaPassContext&); 23 : : 24 : : // Creates an intrinsic description with a particular 25 : : // name and declaration function. 26 : 6633 : IntrinsicDescription( 27 : : const llvm::StringRef &name, 28 : : const DeclarationFunction &declare) 29 : 6633 : : name(name), declare(declare) 30 : 6633 : { } 31 : : 32 : : // The intrinsic's name. 33 : : llvm::StringRef name; 34 : : // A function that declares the intrinsic in a module. 35 : : DeclarationFunction declare; 36 : : }; 37 : : } 38 : : 39 : : // A data structure that can read Julia-specific intrinsics 40 : : // from modules or add them if they're not available yet. 41 : : // Mainly useful for building Julia-specific LLVM passes. 42 : : struct JuliaPassContext { 43 : : 44 : : // Types derived from 'jl_value_t'. 45 : : llvm::PointerType *T_prjlvalue; 46 : : 47 : : // TBAA metadata nodes. 48 : : llvm::MDNode *tbaa_gcframe; 49 : : llvm::MDNode *tbaa_tag; 50 : : 51 : : // Intrinsics. 52 : : llvm::Function *pgcstack_getter; 53 : : llvm::Function *gc_flush_func; 54 : : llvm::Function *gc_preserve_begin_func; 55 : : llvm::Function *gc_preserve_end_func; 56 : : llvm::Function *pointer_from_objref_func; 57 : : llvm::Function *alloc_obj_func; 58 : : llvm::Function *typeof_func; 59 : : llvm::Function *write_barrier_func; 60 : : llvm::Function *write_barrier_binding_func; 61 : : llvm::Function *call_func; 62 : : llvm::Function *call2_func; 63 : : 64 : : // Creates a pass context. Type and function pointers 65 : : // are set to `nullptr`. Metadata nodes are initialized. 66 : : JuliaPassContext(); 67 : : 68 : : // Populates a pass context by inspecting a module. 69 : : // Also sets the current module to the given module. 70 : : void initAll(llvm::Module &M); 71 : : 72 : : // Initializes a pass context's functions only. 73 : : // Also sets the current module to the given module. 74 : : void initFunctions(llvm::Module &M); 75 : : 76 : : // Gets the LLVM context for this pass context. 77 : 4670860 : llvm::LLVMContext &getLLVMContext() const 78 : : { 79 : 4670860 : return module->getContext(); 80 : : } 81 : : 82 : : // Gets a call to the `julia.get_pgcstack' intrinsic in the entry 83 : : // point of the given function, if there exists such a call. 84 : : // Otherwise, `nullptr` is returned. 85 : : llvm::CallInst *getPGCstack(llvm::Function &F) const; 86 : : 87 : : // Gets the intrinsic or well-known function that conforms to 88 : : // the given description if it exists in the module. If not, 89 : : // `nullptr` is returned. 90 : : llvm::Function *getOrNull( 91 : : const jl_intrinsics::IntrinsicDescription &desc) const; 92 : : 93 : : // Gets the intrinsic or well-known function that conforms to 94 : : // the given description if it exists in the module. If not, 95 : : // declares the intrinsic or well-known function and adds it 96 : : // to the module. 97 : : llvm::Function *getOrDeclare( 98 : : const jl_intrinsics::IntrinsicDescription &desc); 99 : : 100 : : private: 101 : : llvm::Module *module; 102 : : }; 103 : : 104 : : namespace jl_intrinsics { 105 : : // `julia.get_gc_frame_slot`: an intrinsic that creates a 106 : : // pointer to a GC frame slot. 107 : : extern const IntrinsicDescription getGCFrameSlot; 108 : : 109 : : // `julia.gc_alloc_bytes`: an intrinsic that allocates 110 : : // the bytes for an object, but does not initialize the 111 : : // tag field. That is, its semantics and signature are 112 : : // the same as for `julia.gc_alloc_obj`, except that 113 : : // the object's tag field is neither initialized nor 114 : : // passed as an argument. 115 : : extern const IntrinsicDescription GCAllocBytes; 116 : : 117 : : // `julia.new_gc_frame`: an intrinsic that creates a new GC frame. 118 : : extern const IntrinsicDescription newGCFrame; 119 : : 120 : : // `julia.push_gc_frame`: an intrinsic that pushes a GC frame. 121 : : extern const IntrinsicDescription pushGCFrame; 122 : : 123 : : // `julia.pop_gc_frame`: an intrinsic that pops a GC frame. 124 : : extern const IntrinsicDescription popGCFrame; 125 : : 126 : : // `julia.queue_gc_root`: an intrinsic that queues a GC root. 127 : : extern const IntrinsicDescription queueGCRoot; 128 : : 129 : : // `julia.queue_gc_binding`: an intrinsic that queues a binding for GC. 130 : : extern const IntrinsicDescription queueGCBinding; 131 : : } 132 : : 133 : : // A namespace for well-known Julia runtime function descriptions. 134 : : namespace jl_well_known { 135 : : // A description of a well-known function that can be used to 136 : : // find existing declarations of that function and create new 137 : : // declarations if necessary. 138 : : // 139 : : // Aliased to `jl_intrinsics::IntrinsicDescription` because 140 : : // intrinsic descriptions are essentially the same thing. 141 : : typedef jl_intrinsics::IntrinsicDescription WellKnownFunctionDescription; 142 : : 143 : : // `jl_gc_big_alloc`: allocates bytes. 144 : : extern const WellKnownFunctionDescription GCBigAlloc; 145 : : 146 : : // `jl_gc_pool_alloc`: allocates bytes. 147 : : extern const WellKnownFunctionDescription GCPoolAlloc; 148 : : 149 : : // `jl_gc_queue_root`: queues a GC root. 150 : : extern const WellKnownFunctionDescription GCQueueRoot; 151 : : 152 : : // `jl_gc_queue_binding`: queues a binding for GC. 153 : : extern const WellKnownFunctionDescription GCQueueBinding; 154 : : } 155 : : 156 : : #endif