Add helpers for emitting LLVM IR.
authorAndres Freund <andres@anarazel.de>
Thu, 22 Mar 2018 18:10:33 +0000 (11:10 -0700)
committerAndres Freund <andres@anarazel.de>
Thu, 22 Mar 2018 18:51:58 +0000 (11:51 -0700)
These basically just help to make code a bit more concise and pgindent
proof.

Author: Andres Freund
Discussion: https://postgr.es/m/20170901064131.tazjxwus3k2w3ybh@alap3.anarazel.de

src/include/jit/llvmjit_emit.h [new file with mode: 0644]
src/tools/pgindent/typedefs.list

diff --git a/src/include/jit/llvmjit_emit.h b/src/include/jit/llvmjit_emit.h
new file mode 100644 (file)
index 0000000..374c833
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * llvmjit_emit.h
+ *   Helpers to make emitting LLVM IR a it more concise and pgindent proof.
+ *
+ * Copyright (c) 2018, PostgreSQL Global Development Group
+ *
+ * src/include/lib/llvmjit_emit.h
+ */
+#ifndef LLVMJIT_EMIT_H
+#define LLVMJIT_EMIT_H
+
+
+#include <llvm-c/Core.h>
+
+
+/*
+ * Emit a non-LLVM pointer as an LLVM constant.
+ */
+static inline LLVMValueRef
+l_ptr_const(void *ptr, LLVMTypeRef type)
+{
+   LLVMValueRef c = LLVMConstInt(TypeSizeT, (uintptr_t) ptr, false);
+
+   return LLVMConstIntToPtr(c, type);
+}
+
+/*
+ * Emit pointer.
+ */
+static inline LLVMTypeRef
+l_ptr(LLVMTypeRef t)
+{
+   return LLVMPointerType(t, 0);
+}
+
+/*
+ * Emit constant integer.
+ */
+static inline LLVMValueRef
+l_int8_const(int8 i)
+{
+   return LLVMConstInt(LLVMInt8Type(), i, false);
+}
+
+/*
+ * Emit constant integer.
+ */
+static inline LLVMValueRef
+l_int16_const(int16 i)
+{
+   return LLVMConstInt(LLVMInt16Type(), i, false);
+}
+
+/*
+ * Emit constant integer.
+ */
+static inline LLVMValueRef
+l_int32_const(int32 i)
+{
+   return LLVMConstInt(LLVMInt32Type(), i, false);
+}
+
+/*
+ * Emit constant integer.
+ */
+static inline LLVMValueRef
+l_int64_const(int64 i)
+{
+   return LLVMConstInt(LLVMInt64Type(), i, false);
+}
+
+/*
+ * Emit constant integer.
+ */
+static inline LLVMValueRef
+l_sizet_const(size_t i)
+{
+   return LLVMConstInt(TypeSizeT, i, false);
+}
+
+/*
+ * Load a pointer member idx from a struct.
+ */
+static inline LLVMValueRef
+l_load_struct_gep(LLVMBuilderRef b, LLVMValueRef v, int32 idx, const char *name)
+{
+   LLVMValueRef v_ptr = LLVMBuildStructGEP(b, v, idx, "");
+
+   return LLVMBuildLoad(b, v_ptr, name);
+}
+
+/*
+ * Load value of a pointer, after applying one index operation.
+ */
+static inline LLVMValueRef
+l_load_gep1(LLVMBuilderRef b, LLVMValueRef v, LLVMValueRef idx, const char *name)
+{
+   LLVMValueRef v_ptr = LLVMBuildGEP(b, v, &idx, 1, "");
+
+   return LLVMBuildLoad(b, v_ptr, name);
+}
+
+/* separate, because pg_attribute_printf(2, 3) can't appear in definition */
+static inline LLVMBasicBlockRef l_bb_before_v(LLVMBasicBlockRef r, const char *fmt,...) pg_attribute_printf(2, 3);
+
+/*
+ * Insert a new basic block, just before r, the name being determined by fmt
+ * and arguments.
+ */
+static inline LLVMBasicBlockRef
+l_bb_before_v(LLVMBasicBlockRef r, const char *fmt,...)
+{
+   char        buf[512];
+   va_list     args;
+
+   va_start(args, fmt);
+   vsnprintf(buf, sizeof(buf), fmt, args);
+   va_end(args);
+
+   return LLVMInsertBasicBlock(r, buf);
+}
+
+/* separate, because pg_attribute_printf(2, 3) can't appear in definition */
+static inline LLVMBasicBlockRef l_bb_append_v(LLVMValueRef f, const char *fmt,...) pg_attribute_printf(2, 3);
+
+/*
+ * Insert a new basic block after previous basic blocks, the name being
+ * determined by fmt and arguments.
+ */
+static inline LLVMBasicBlockRef
+l_bb_append_v(LLVMValueRef f, const char *fmt,...)
+{
+   char        buf[512];
+   va_list     args;
+
+   va_start(args, fmt);
+   vsnprintf(buf, sizeof(buf), fmt, args);
+   va_end(args);
+
+   return LLVMAppendBasicBlock(f, buf);
+}
+
+/*
+ * Mark a callsite as readonly.
+ */
+static inline void
+l_callsite_ro(LLVMValueRef f)
+{
+   const char  argname[] = "readonly";
+   LLVMAttributeRef ref;
+
+   ref = LLVMCreateStringAttribute(LLVMGetGlobalContext(),
+                                   argname,
+                                   sizeof(argname) - 1,
+                                   NULL, 0);
+
+   LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, ref);
+}
+
+/*
+ * Mark a callsite as alwaysinline.
+ */
+static inline void
+l_callsite_alwaysinline(LLVMValueRef f)
+{
+   const char  argname[] = "alwaysinline";
+   int         id;
+   LLVMAttributeRef attr;
+
+   id = LLVMGetEnumAttributeKindForName(argname,
+                                        sizeof(argname) - 1);
+   attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), id, 0);
+   LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, attr);
+}
+
+/*
+ * Emit code to switch memory context.
+ */
+static inline LLVMValueRef
+l_mcxt_switch(LLVMModuleRef mod, LLVMBuilderRef b, LLVMValueRef nc)
+{
+   const char *cmc = "CurrentMemoryContext";
+   LLVMValueRef cur;
+   LLVMValueRef ret;
+
+   if (!(cur = LLVMGetNamedGlobal(mod, cmc)))
+       cur = LLVMAddGlobal(mod, l_ptr(StructMemoryContextData), cmc);
+   ret = LLVMBuildLoad(b, cur, cmc);
+   LLVMBuildStore(b, nc, cur);
+
+   return ret;
+}
+#endif
index 63d8c634e2b4e8675f3762f52f95b1d1e312be9c..1ae5368367ac3de0c11836e07a8b4952d116b271 100644 (file)
@@ -1102,6 +1102,7 @@ LDAPMessage
 LDAPURLDesc
 LDAP_TIMEVAL
 LINE
+LLVMBuilderRef
 LLVMJitContext
 LLVMJitHandle
 LLVMTypeRef