LCOV - differential code coverage report
Current view: top level - src/include/jit - llvmjit_emit.h (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 96.8 % 63 61 2 61
Current Date: 2023-04-08 15:15:32 Functions: 94.7 % 19 18 1 18
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  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 CBC       62678 : l_ptr_const(void *ptr, LLVMTypeRef type)
      28                 : {
      29           62678 :     LLVMValueRef c = LLVMConstInt(TypeSizeT, (uintptr_t) ptr, false);
      30                 : 
      31           62678 :     return LLVMConstIntToPtr(c, type);
      32                 : }
      33                 : 
      34                 : /*
      35                 :  * Emit pointer.
      36                 :  */
      37                 : static inline LLVMTypeRef
      38           77036 : l_ptr(LLVMTypeRef t)
      39                 : {
      40           77036 :     return LLVMPointerType(t, 0);
      41                 : }
      42                 : 
      43                 : /*
      44                 :  * Emit constant integer.
      45                 :  */
      46                 : static inline LLVMValueRef
      47           25756 : l_int8_const(int8 i)
      48                 : {
      49           25756 :     return LLVMConstInt(LLVMInt8Type(), i, false);
      50                 : }
      51                 : 
      52                 : /*
      53                 :  * Emit constant integer.
      54                 :  */
      55                 : static inline LLVMValueRef
      56           36196 : l_int16_const(int16 i)
      57                 : {
      58           36196 :     return LLVMConstInt(LLVMInt16Type(), i, false);
      59                 : }
      60                 : 
      61                 : /*
      62                 :  * Emit constant integer.
      63                 :  */
      64                 : static inline LLVMValueRef
      65           22969 : l_int32_const(int32 i)
      66                 : {
      67           22969 :     return LLVMConstInt(LLVMInt32Type(), i, false);
      68                 : }
      69                 : 
      70                 : /*
      71                 :  * Emit constant integer.
      72                 :  */
      73                 : static inline LLVMValueRef
      74            5360 : l_int64_const(int64 i)
      75                 : {
      76            5360 :     return LLVMConstInt(LLVMInt64Type(), i, false);
      77                 : }
      78                 : 
      79                 : /*
      80                 :  * Emit constant integer.
      81                 :  */
      82                 : static inline LLVMValueRef
      83           28016 : l_sizet_const(size_t i)
      84                 : {
      85           28016 :     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           14316 : l_sbool_const(bool i)
      93                 : {
      94           14316 :     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          104906 : l_load_struct_gep(LLVMBuilderRef b, LLVMValueRef v, int32 idx, const char *name)
     111                 : {
     112          104906 :     LLVMValueRef v_ptr = LLVMBuildStructGEP(b, v, idx, "");
     113                 : 
     114          104906 :     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           21538 : l_load_gep1(LLVMBuilderRef b, LLVMValueRef v, LLVMValueRef idx, const char *name)
     122                 : {
     123           21538 :     LLVMValueRef v_ptr = LLVMBuildGEP(b, v, &idx, 1, "");
     124                 : 
     125           21538 :     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           13614 : l_bb_before_v(LLVMBasicBlockRef r, const char *fmt,...)
     137                 : {
     138                 :     char        buf[512];
     139                 :     va_list     args;
     140                 : 
     141           13614 :     va_start(args, fmt);
     142           13614 :     vsnprintf(buf, sizeof(buf), fmt, args);
     143           13614 :     va_end(args);
     144                 : 
     145           13614 :     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           65573 : l_bb_append_v(LLVMValueRef f, const char *fmt,...)
     157                 : {
     158                 :     char        buf[512];
     159                 :     va_list     args;
     160                 : 
     161           65573 :     va_start(args, fmt);
     162           65573 :     vsnprintf(buf, sizeof(buf), fmt, args);
     163           65573 :     va_end(args);
     164                 : 
     165           65573 :     return LLVMAppendBasicBlock(f, buf);
     166                 : }
     167                 : 
     168                 : /*
     169                 :  * Mark a callsite as readonly.
     170                 :  */
     171                 : static inline void
     172            1024 : l_callsite_ro(LLVMValueRef f)
     173                 : {
     174            1024 :     const char  argname[] = "readonly";
     175                 :     LLVMAttributeRef ref;
     176                 : 
     177            1024 :     ref = LLVMCreateStringAttribute(LLVMGetGlobalContext(),
     178                 :                                     argname,
     179                 :                                     sizeof(argname) - 1,
     180                 :                                     NULL, 0);
     181                 : 
     182            1024 :     LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, ref);
     183            1024 : }
     184                 : 
     185                 : /*
     186                 :  * Mark a callsite as alwaysinline.
     187                 :  */
     188                 : static inline void
     189            1024 : l_callsite_alwaysinline(LLVMValueRef f)
     190                 : {
     191            1024 :     const char  argname[] = "alwaysinline";
     192                 :     int         id;
     193                 :     LLVMAttributeRef attr;
     194                 : 
     195            1024 :     id = LLVMGetEnumAttributeKindForName(argname,
     196                 :                                          sizeof(argname) - 1);
     197            1024 :     attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), id, 0);
     198            1024 :     LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, attr);
     199            1024 : }
     200                 : 
     201                 : /*
     202                 :  * Emit code to switch memory context.
     203                 :  */
     204                 : static inline LLVMValueRef
     205            1577 : l_mcxt_switch(LLVMModuleRef mod, LLVMBuilderRef b, LLVMValueRef nc)
     206                 : {
     207            1577 :     const char *cmc = "CurrentMemoryContext";
     208                 :     LLVMValueRef cur;
     209                 :     LLVMValueRef ret;
     210                 : 
     211            1577 :     if (!(cur = LLVMGetNamedGlobal(mod, cmc)))
     212             238 :         cur = LLVMAddGlobal(mod, l_ptr(StructMemoryContextData), cmc);
     213            1577 :     ret = LLVMBuildLoad(b, cur, cmc);
     214            1577 :     LLVMBuildStore(b, nc, cur);
     215                 : 
     216            1577 :     return ret;
     217                 : }
     218                 : 
     219                 : /*
     220                 :  * Return pointer to the argno'th argument nullness.
     221                 :  */
     222                 : static inline LLVMValueRef
     223            4485 : l_funcnullp(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
     224                 : {
     225                 :     LLVMValueRef v_args;
     226                 :     LLVMValueRef v_argn;
     227                 : 
     228            4485 :     v_args = LLVMBuildStructGEP(b,
     229                 :                                 v_fcinfo,
     230                 :                                 FIELDNO_FUNCTIONCALLINFODATA_ARGS,
     231                 :                                 "");
     232            4485 :     v_argn = LLVMBuildStructGEP(b, v_args, argno, "");
     233                 : 
     234            4485 :     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             838 : l_funcvaluep(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
     242                 : {
     243                 :     LLVMValueRef v_args;
     244                 :     LLVMValueRef v_argn;
     245                 : 
     246             838 :     v_args = LLVMBuildStructGEP(b,
     247                 :                                 v_fcinfo,
     248                 :                                 FIELDNO_FUNCTIONCALLINFODATA_ARGS,
     249                 :                                 "");
     250             838 :     v_argn = LLVMBuildStructGEP(b, v_args, argno, "");
     251                 : 
     252             838 :     return LLVMBuildStructGEP(b, v_argn, FIELDNO_NULLABLE_DATUM_DATUM, "");
     253                 : }
     254                 : 
     255                 : /*
     256                 :  * Return argno'th argument nullness.
     257                 :  */
     258                 : static inline LLVMValueRef
     259            3647 : l_funcnull(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
     260                 : {
     261            3647 :     return LLVMBuildLoad(b, l_funcnullp(b, v_fcinfo, argno), "");
     262                 : }
     263                 : 
     264                 : /*
     265                 :  * Return argno'th argument datum.
     266                 :  */
     267                 : static inline LLVMValueRef
     268 UBC           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 v1.16-55-g56c0a2a