LCOV - code coverage report
Current view: top level - src/include/jit - llvmjit_emit.h (source / functions) Hit Total Coverage
Test: PostgreSQL 16beta1 Lines: 61 63 96.8 %
Date: 2023-06-01 13:12:25 Functions: 18 19 94.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14