gooderp18绿色标准版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
5.8KB

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