2
0

llvmjit_emit.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * llvmjit_emit.h
  3. * Helpers to make emitting LLVM IR a bit more concise and pgindent proof.
  4. *
  5. * Copyright (c) 2018-2022, PostgreSQL Global Development Group
  6. *
  7. * src/include/jit/llvmjit_emit.h
  8. */
  9. #ifndef LLVMJIT_EMIT_H
  10. #define LLVMJIT_EMIT_H
  11. /*
  12. * To avoid breaking cpluspluscheck, allow including the file even when LLVM
  13. * is not available.
  14. */
  15. #ifdef USE_LLVM
  16. #include <llvm-c/Core.h>
  17. #include "jit/llvmjit.h"
  18. /*
  19. * Emit a non-LLVM pointer as an LLVM constant.
  20. */
  21. static inline LLVMValueRef
  22. l_ptr_const(void *ptr, LLVMTypeRef type)
  23. {
  24. LLVMValueRef c = LLVMConstInt(TypeSizeT, (uintptr_t) ptr, false);
  25. return LLVMConstIntToPtr(c, type);
  26. }
  27. /*
  28. * Emit pointer.
  29. */
  30. static inline LLVMTypeRef
  31. l_ptr(LLVMTypeRef t)
  32. {
  33. return LLVMPointerType(t, 0);
  34. }
  35. /*
  36. * Emit constant integer.
  37. */
  38. static inline LLVMValueRef
  39. l_int8_const(int8 i)
  40. {
  41. return LLVMConstInt(LLVMInt8Type(), i, false);
  42. }
  43. /*
  44. * Emit constant integer.
  45. */
  46. static inline LLVMValueRef
  47. l_int16_const(int16 i)
  48. {
  49. return LLVMConstInt(LLVMInt16Type(), i, false);
  50. }
  51. /*
  52. * Emit constant integer.
  53. */
  54. static inline LLVMValueRef
  55. l_int32_const(int32 i)
  56. {
  57. return LLVMConstInt(LLVMInt32Type(), i, false);
  58. }
  59. /*
  60. * Emit constant integer.
  61. */
  62. static inline LLVMValueRef
  63. l_int64_const(int64 i)
  64. {
  65. return LLVMConstInt(LLVMInt64Type(), i, false);
  66. }
  67. /*
  68. * Emit constant integer.
  69. */
  70. static inline LLVMValueRef
  71. l_sizet_const(size_t i)
  72. {
  73. return LLVMConstInt(TypeSizeT, i, false);
  74. }
  75. /*
  76. * Emit constant boolean, as used for storage (e.g. global vars, structs).
  77. */
  78. static inline LLVMValueRef
  79. l_sbool_const(bool i)
  80. {
  81. return LLVMConstInt(TypeStorageBool, (int) i, false);
  82. }
  83. /*
  84. * Emit constant boolean, as used for parameters (e.g. function parameters).
  85. */
  86. static inline LLVMValueRef
  87. l_pbool_const(bool i)
  88. {
  89. return LLVMConstInt(TypeParamBool, (int) i, false);
  90. }
  91. /*
  92. * Load a pointer member idx from a struct.
  93. */
  94. static inline LLVMValueRef
  95. l_load_struct_gep(LLVMBuilderRef b, LLVMValueRef v, int32 idx, const char *name)
  96. {
  97. LLVMValueRef v_ptr = LLVMBuildStructGEP(b, v, idx, "");
  98. return LLVMBuildLoad(b, v_ptr, name);
  99. }
  100. /*
  101. * Load value of a pointer, after applying one index operation.
  102. */
  103. static inline LLVMValueRef
  104. l_load_gep1(LLVMBuilderRef b, LLVMValueRef v, LLVMValueRef idx, const char *name)
  105. {
  106. LLVMValueRef v_ptr = LLVMBuildGEP(b, v, &idx, 1, "");
  107. return LLVMBuildLoad(b, v_ptr, name);
  108. }
  109. /* separate, because pg_attribute_printf(2, 3) can't appear in definition */
  110. static inline LLVMBasicBlockRef l_bb_before_v(LLVMBasicBlockRef r, const char *fmt,...) pg_attribute_printf(2, 3);
  111. /*
  112. * Insert a new basic block, just before r, the name being determined by fmt
  113. * and arguments.
  114. */
  115. static inline LLVMBasicBlockRef
  116. l_bb_before_v(LLVMBasicBlockRef r, const char *fmt,...)
  117. {
  118. char buf[512];
  119. va_list args;
  120. va_start(args, fmt);
  121. vsnprintf(buf, sizeof(buf), fmt, args);
  122. va_end(args);
  123. return LLVMInsertBasicBlock(r, buf);
  124. }
  125. /* separate, because pg_attribute_printf(2, 3) can't appear in definition */
  126. static inline LLVMBasicBlockRef l_bb_append_v(LLVMValueRef f, const char *fmt,...) pg_attribute_printf(2, 3);
  127. /*
  128. * Insert a new basic block after previous basic blocks, the name being
  129. * determined by fmt and arguments.
  130. */
  131. static inline LLVMBasicBlockRef
  132. l_bb_append_v(LLVMValueRef f, const char *fmt,...)
  133. {
  134. char buf[512];
  135. va_list args;
  136. va_start(args, fmt);
  137. vsnprintf(buf, sizeof(buf), fmt, args);
  138. va_end(args);
  139. return LLVMAppendBasicBlock(f, buf);
  140. }
  141. /*
  142. * Mark a callsite as readonly.
  143. */
  144. static inline void
  145. l_callsite_ro(LLVMValueRef f)
  146. {
  147. const char argname[] = "readonly";
  148. LLVMAttributeRef ref;
  149. ref = LLVMCreateStringAttribute(LLVMGetGlobalContext(),
  150. argname,
  151. sizeof(argname) - 1,
  152. NULL, 0);
  153. LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, ref);
  154. }
  155. /*
  156. * Mark a callsite as alwaysinline.
  157. */
  158. static inline void
  159. l_callsite_alwaysinline(LLVMValueRef f)
  160. {
  161. const char argname[] = "alwaysinline";
  162. int id;
  163. LLVMAttributeRef attr;
  164. id = LLVMGetEnumAttributeKindForName(argname,
  165. sizeof(argname) - 1);
  166. attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), id, 0);
  167. LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, attr);
  168. }
  169. /*
  170. * Emit code to switch memory context.
  171. */
  172. static inline LLVMValueRef
  173. l_mcxt_switch(LLVMModuleRef mod, LLVMBuilderRef b, LLVMValueRef nc)
  174. {
  175. const char *cmc = "CurrentMemoryContext";
  176. LLVMValueRef cur;
  177. LLVMValueRef ret;
  178. if (!(cur = LLVMGetNamedGlobal(mod, cmc)))
  179. cur = LLVMAddGlobal(mod, l_ptr(StructMemoryContextData), cmc);
  180. ret = LLVMBuildLoad(b, cur, cmc);
  181. LLVMBuildStore(b, nc, cur);
  182. return ret;
  183. }
  184. /*
  185. * Return pointer to the argno'th argument nullness.
  186. */
  187. static inline LLVMValueRef
  188. l_funcnullp(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
  189. {
  190. LLVMValueRef v_args;
  191. LLVMValueRef v_argn;
  192. v_args = LLVMBuildStructGEP(b,
  193. v_fcinfo,
  194. FIELDNO_FUNCTIONCALLINFODATA_ARGS,
  195. "");
  196. v_argn = LLVMBuildStructGEP(b, v_args, argno, "");
  197. return LLVMBuildStructGEP(b, v_argn, FIELDNO_NULLABLE_DATUM_ISNULL, "");
  198. }
  199. /*
  200. * Return pointer to the argno'th argument datum.
  201. */
  202. static inline LLVMValueRef
  203. l_funcvaluep(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
  204. {
  205. LLVMValueRef v_args;
  206. LLVMValueRef v_argn;
  207. v_args = LLVMBuildStructGEP(b,
  208. v_fcinfo,
  209. FIELDNO_FUNCTIONCALLINFODATA_ARGS,
  210. "");
  211. v_argn = LLVMBuildStructGEP(b, v_args, argno, "");
  212. return LLVMBuildStructGEP(b, v_argn, FIELDNO_NULLABLE_DATUM_DATUM, "");
  213. }
  214. /*
  215. * Return argno'th argument nullness.
  216. */
  217. static inline LLVMValueRef
  218. l_funcnull(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
  219. {
  220. return LLVMBuildLoad(b, l_funcnullp(b, v_fcinfo, argno), "");
  221. }
  222. /*
  223. * Return argno'th argument datum.
  224. */
  225. static inline LLVMValueRef
  226. l_funcvalue(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
  227. {
  228. return LLVMBuildLoad(b, l_funcvaluep(b, v_fcinfo, argno), "");
  229. }
  230. #endif /* USE_LLVM */
  231. #endif