1 #ifndef HALIDE_CODEGEN_POSIX_H 2 #define HALIDE_CODEGEN_POSIX_H 3 4 /** \file 5 * Defines a base-class for code-generators on posixy cpu platforms 6 */ 7 8 #include "CodeGen_LLVM.h" 9 10 namespace Halide { 11 namespace Internal { 12 13 /** A code generator that emits posix code from a given Halide stmt. */ 14 class CodeGen_Posix : public CodeGen_LLVM { 15 public: 16 /** Create an posix code generator. Processor features can be 17 * enabled using the appropriate arguments */ 18 CodeGen_Posix(Target t); 19 20 protected: 21 using CodeGen_LLVM::visit; 22 23 /** Posix implementation of Allocate. Small constant-sized allocations go 24 * on the stack. The rest go on the heap by calling "halide_malloc" 25 * and "halide_free" in the standard library. */ 26 // @{ 27 void visit(const Allocate *) override; 28 void visit(const Free *) override; 29 // @} 30 31 /** It can be convenient for backends to assume there is extra 32 * padding beyond the end of a buffer to enable faster 33 * loads/stores. This function gets the padding required by the 34 * implementing target. */ 35 virtual int allocation_padding(Type type) const; 36 37 /** A struct describing heap or stack allocations. */ 38 struct Allocation { 39 /** The memory */ 40 llvm::Value *ptr = nullptr; 41 42 /** Destructor stack slot for this allocation. */ 43 llvm::Value *destructor = nullptr; 44 45 /** Function to accomplish the destruction. */ 46 llvm::Function *destructor_function = nullptr; 47 48 /** Pseudostack slot for this allocation. Non-null for 49 * allocations of type Stack with dynamic size. */ 50 llvm::Value *pseudostack_slot = nullptr; 51 52 /** The (Halide) type of the allocation. */ 53 Type type; 54 55 /** How many bytes this allocation is, or 0 if not 56 * constant. */ 57 int constant_bytes = 0; 58 59 /** How many bytes of stack space used. 0 implies it was a 60 * heap allocation. */ 61 int stack_bytes = 0; 62 63 /** A unique name for this allocation. May not be equal to the 64 * Allocate node name in cases where we detect multiple 65 * Allocate nodes can share a single allocation. */ 66 std::string name; 67 }; 68 69 /** The allocations currently in scope. The stack gets pushed when 70 * we enter a new function. */ 71 Scope<Allocation> allocations; 72 73 std::string get_allocation_name(const std::string &n) override; 74 75 private: 76 /** Stack allocations that were freed, but haven't gone out of 77 * scope yet. This allows us to re-use stack allocations when 78 * they aren't being used. */ 79 std::vector<Allocation> free_stack_allocs; 80 81 /** current size of all alloca instances in use; this is tracked only 82 * for debug output purposes. */ 83 size_t cur_stack_alloc_total{0}; 84 85 /** Generates code for computing the size of an allocation from a 86 * list of its extents and its size. Fires a runtime assert 87 * (halide_error) if the size overflows 2^31 -1, the maximum 88 * positive number an int32_t can hold. */ 89 llvm::Value *codegen_allocation_size(const std::string &name, Type type, const std::vector<Expr> &extents, const Expr &condition); 90 91 /** Allocates some memory on either the stack or the heap, and 92 * returns an Allocation object describing it. For heap 93 * allocations this calls halide_malloc in the runtime, and for 94 * stack allocations it either reuses an existing block from the 95 * free_stack_blocks list, or it saves the stack pointer and calls 96 * alloca. 97 * 98 * This call returns the allocation, pushes it onto the 99 * 'allocations' map, and adds an entry to the symbol table called 100 * name.host that provides the base pointer. 101 * 102 * When the allocation can be freed call 'free_allocation', and 103 * when it goes out of scope call 'destroy_allocation'. */ 104 Allocation create_allocation(const std::string &name, Type type, MemoryType memory_type, 105 const std::vector<Expr> &extents, 106 const Expr &condition, const Expr &new_expr, std::string free_function); 107 108 /** Free an allocation previously allocated with 109 * create_allocation */ 110 void free_allocation(const std::string &name); 111 }; 112 113 } // namespace Internal 114 } // namespace Halide 115 116 #endif 117