LCOV - differential code coverage report
Current view: top level - src/backend/jit/llvm - llvmjit.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 90.1 % 354 319 2 33 1 318 2 1
Current Date: 2023-04-08 17:13:01 Functions: 92.3 % 26 24 2 2 22
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 0.0 % 2 0 2
Legend: Lines: hit not hit (60,120] days: 0.0 % 1 0 1
(180,240] days: 100.0 % 1 1 1
(240..) days: 90.9 % 350 318 32 318
Function coverage date bins:
(240..) days: 92.3 % 26 24 2 2 22

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * llvmjit.c
                                  4                 :  *    Core part of the LLVM JIT provider.
                                  5                 :  *
                                  6                 :  * Copyright (c) 2016-2023, PostgreSQL Global Development Group
                                  7                 :  *
                                  8                 :  * IDENTIFICATION
                                  9                 :  *    src/backend/jit/llvm/llvmjit.c
                                 10                 :  *
                                 11                 :  *-------------------------------------------------------------------------
                                 12                 :  */
                                 13                 : 
                                 14                 : #include "postgres.h"
                                 15                 : 
                                 16                 : #include <llvm-c/Analysis.h>
                                 17                 : #include <llvm-c/BitReader.h>
                                 18                 : #include <llvm-c/BitWriter.h>
                                 19                 : #include <llvm-c/Core.h>
                                 20                 : #include <llvm-c/ExecutionEngine.h>
                                 21                 : #if LLVM_VERSION_MAJOR > 11
                                 22                 : #include <llvm-c/Orc.h>
                                 23                 : #include <llvm-c/OrcEE.h>
                                 24                 : #include <llvm-c/LLJIT.h>
                                 25                 : #else
                                 26                 : #include <llvm-c/OrcBindings.h>
                                 27                 : #endif
                                 28                 : #include <llvm-c/Support.h>
                                 29                 : #include <llvm-c/Target.h>
                                 30                 : #include <llvm-c/Transforms/IPO.h>
                                 31                 : #include <llvm-c/Transforms/PassManagerBuilder.h>
                                 32                 : #include <llvm-c/Transforms/Scalar.h>
                                 33                 : #if LLVM_VERSION_MAJOR > 6
                                 34                 : #include <llvm-c/Transforms/Utils.h>
                                 35                 : #endif
                                 36                 : 
                                 37                 : #include "jit/llvmjit.h"
                                 38                 : #include "jit/llvmjit_emit.h"
                                 39                 : #include "miscadmin.h"
                                 40                 : #include "portability/instr_time.h"
                                 41                 : #include "storage/ipc.h"
                                 42                 : #include "utils/memutils.h"
                                 43                 : #include "utils/resowner_private.h"
                                 44                 : 
                                 45                 : /* Handle of a module emitted via ORC JIT */
                                 46                 : typedef struct LLVMJitHandle
                                 47                 : {
                                 48                 : #if LLVM_VERSION_MAJOR > 11
                                 49                 :     LLVMOrcLLJITRef lljit;
                                 50                 :     LLVMOrcResourceTrackerRef resource_tracker;
                                 51                 : #else
                                 52                 :     LLVMOrcJITStackRef stack;
                                 53                 :     LLVMOrcModuleHandle orc_handle;
                                 54                 : #endif
                                 55                 : } LLVMJitHandle;
                                 56                 : 
                                 57                 : 
                                 58                 : /* types & functions commonly needed for JITing */
                                 59                 : LLVMTypeRef TypeSizeT;
                                 60                 : LLVMTypeRef TypeParamBool;
                                 61                 : LLVMTypeRef TypeStorageBool;
                                 62                 : LLVMTypeRef TypePGFunction;
                                 63                 : LLVMTypeRef StructNullableDatum;
                                 64                 : LLVMTypeRef StructHeapTupleFieldsField3;
                                 65                 : LLVMTypeRef StructHeapTupleFields;
                                 66                 : LLVMTypeRef StructHeapTupleHeaderData;
                                 67                 : LLVMTypeRef StructHeapTupleDataChoice;
                                 68                 : LLVMTypeRef StructHeapTupleData;
                                 69                 : LLVMTypeRef StructMinimalTupleData;
                                 70                 : LLVMTypeRef StructItemPointerData;
                                 71                 : LLVMTypeRef StructBlockId;
                                 72                 : LLVMTypeRef StructFormPgAttribute;
                                 73                 : LLVMTypeRef StructTupleConstr;
                                 74                 : LLVMTypeRef StructTupleDescData;
                                 75                 : LLVMTypeRef StructTupleTableSlot;
                                 76                 : LLVMTypeRef StructHeapTupleTableSlot;
                                 77                 : LLVMTypeRef StructMinimalTupleTableSlot;
                                 78                 : LLVMTypeRef StructMemoryContextData;
                                 79                 : LLVMTypeRef StructPGFinfoRecord;
                                 80                 : LLVMTypeRef StructFmgrInfo;
                                 81                 : LLVMTypeRef StructFunctionCallInfoData;
                                 82                 : LLVMTypeRef StructExprContext;
                                 83                 : LLVMTypeRef StructExprEvalStep;
                                 84                 : LLVMTypeRef StructExprState;
                                 85                 : LLVMTypeRef StructAggState;
                                 86                 : LLVMTypeRef StructAggStatePerGroupData;
                                 87                 : LLVMTypeRef StructAggStatePerTransData;
                                 88                 : 
                                 89                 : LLVMValueRef AttributeTemplate;
                                 90                 : 
                                 91                 : LLVMModuleRef llvm_types_module = NULL;
                                 92                 : 
                                 93                 : static bool llvm_session_initialized = false;
                                 94                 : static size_t llvm_generation = 0;
                                 95                 : static const char *llvm_triple = NULL;
                                 96                 : static const char *llvm_layout = NULL;
                                 97                 : 
                                 98                 : 
                                 99                 : static LLVMTargetRef llvm_targetref;
                                100                 : #if LLVM_VERSION_MAJOR > 11
                                101                 : static LLVMOrcThreadSafeContextRef llvm_ts_context;
                                102                 : static LLVMOrcLLJITRef llvm_opt0_orc;
                                103                 : static LLVMOrcLLJITRef llvm_opt3_orc;
                                104                 : #else                           /* LLVM_VERSION_MAJOR > 11 */
                                105                 : static LLVMOrcJITStackRef llvm_opt0_orc;
                                106                 : static LLVMOrcJITStackRef llvm_opt3_orc;
                                107                 : #endif                          /* LLVM_VERSION_MAJOR > 11 */
                                108                 : 
                                109                 : 
                                110                 : static void llvm_release_context(JitContext *context);
                                111                 : static void llvm_session_initialize(void);
                                112                 : static void llvm_shutdown(int code, Datum arg);
                                113                 : static void llvm_compile_module(LLVMJitContext *context);
                                114                 : static void llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module);
                                115                 : 
                                116                 : static void llvm_create_types(void);
                                117                 : static uint64_t llvm_resolve_symbol(const char *name, void *ctx);
                                118                 : 
                                119                 : #if LLVM_VERSION_MAJOR > 11
                                120                 : static LLVMOrcLLJITRef llvm_create_jit_instance(LLVMTargetMachineRef tm);
                                121                 : static char *llvm_error_message(LLVMErrorRef error);
                                122                 : #endif                          /* LLVM_VERSION_MAJOR > 11 */
                                123                 : 
 1845 andres                    124 CBC         987 : PG_MODULE_MAGIC;
                                125                 : 
                                126                 : 
                                127                 : /*
                                128                 :  * Initialize LLVM JIT provider.
                                129                 :  */
                                130                 : void
                                131             393 : _PG_jit_provider_init(JitProviderCallbacks *cb)
                                132                 : {
                                133             393 :     cb->reset_after_error = llvm_reset_after_error;
                                134             393 :     cb->release_context = llvm_release_context;
 1846                           135             393 :     cb->compile_expr = llvm_compile_expr;
 1845                           136             393 : }
                                137                 : 
                                138                 : /*
                                139                 :  * Create a context for JITing work.
                                140                 :  *
                                141                 :  * The context, including subsidiary resources, will be cleaned up either when
                                142                 :  * the context is explicitly released, or when the lifetime of
                                143                 :  * CurrentResourceOwner ends (usually the end of the current [sub]xact).
                                144                 :  */
                                145                 : LLVMJitContext *
                                146             839 : llvm_create_context(int jitFlags)
                                147                 : {
                                148                 :     LLVMJitContext *context;
                                149                 : 
                                150             839 :     llvm_assert_in_fatal_section();
                                151                 : 
                                152             839 :     llvm_session_initialize();
                                153                 : 
                                154             839 :     ResourceOwnerEnlargeJIT(CurrentResourceOwner);
                                155                 : 
                                156             839 :     context = MemoryContextAllocZero(TopMemoryContext,
                                157                 :                                      sizeof(LLVMJitContext));
                                158             839 :     context->base.flags = jitFlags;
                                159                 : 
                                160                 :     /* ensure cleanup */
                                161             839 :     context->base.resowner = CurrentResourceOwner;
                                162             839 :     ResourceOwnerRememberJIT(CurrentResourceOwner, PointerGetDatum(context));
                                163                 : 
                                164             839 :     return context;
                                165                 : }
                                166                 : 
                                167                 : /*
                                168                 :  * Release resources required by one llvm context.
                                169                 :  */
                                170                 : static void
                                171             839 : llvm_release_context(JitContext *context)
                                172                 : {
 1844                           173             839 :     LLVMJitContext *llvm_context = (LLVMJitContext *) context;
                                174                 :     ListCell   *lc;
                                175                 : 
                                176                 :     /*
                                177                 :      * When this backend is exiting, don't clean up LLVM. As an error might
                                178                 :      * have occurred from within LLVM, we do not want to risk reentering. All
                                179                 :      * resource cleanup is going to happen through process exit.
                                180                 :      */
  881                           181             839 :     if (proc_exit_inprogress)
  881 andres                    182 UBC           0 :         return;
                                183                 : 
  573 andres                    184 CBC         839 :     llvm_enter_fatal_on_oom();
                                185                 : 
  881                           186             839 :     if (llvm_context->module)
                                187                 :     {
                                188             235 :         LLVMDisposeModule(llvm_context->module);
                                189             235 :         llvm_context->module = NULL;
                                190                 :     }
                                191                 : 
  524 tgl                       192            1512 :     foreach(lc, llvm_context->handles)
                                193                 :     {
                                194             673 :         LLVMJitHandle *jit_handle = (LLVMJitHandle *) lfirst(lc);
                                195                 : 
                                196                 : #if LLVM_VERSION_MAJOR > 11
                                197                 :         {
                                198                 :             LLVMOrcExecutionSessionRef ee;
                                199                 :             LLVMOrcSymbolStringPoolRef sp;
                                200                 : 
  881 andres                    201             673 :             LLVMOrcResourceTrackerRemove(jit_handle->resource_tracker);
                                202             673 :             LLVMOrcReleaseResourceTracker(jit_handle->resource_tracker);
                                203                 : 
                                204                 :             /*
                                205                 :              * Without triggering cleanup of the string pool, we'd leak
                                206                 :              * memory. It'd be sufficient to do this far less often, but in
                                207                 :              * experiments the required time was small enough to just always
                                208                 :              * do it.
                                209                 :              */
                                210             673 :             ee = LLVMOrcLLJITGetExecutionSession(jit_handle->lljit);
                                211             673 :             sp = LLVMOrcExecutionSessionGetSymbolStringPool(ee);
                                212             673 :             LLVMOrcSymbolStringPoolClearDeadEntries(sp);
                                213                 :         }
                                214                 : #else                           /* LLVM_VERSION_MAJOR > 11 */
                                215                 :         {
                                216                 :             LLVMOrcRemoveModule(jit_handle->stack, jit_handle->orc_handle);
                                217                 :         }
                                218                 : #endif                          /* LLVM_VERSION_MAJOR > 11 */
                                219                 : 
                                220             673 :         pfree(jit_handle);
                                221                 :     }
  524 tgl                       222             839 :     list_free(llvm_context->handles);
                                223             839 :     llvm_context->handles = NIL;
                                224                 : }
                                225                 : 
                                226                 : /*
                                227                 :  * Return module which may be modified, e.g. by creating new functions.
                                228                 :  */
                                229                 : LLVMModuleRef
 1844 andres                    230            8310 : llvm_mutable_module(LLVMJitContext *context)
                                231                 : {
                                232            8310 :     llvm_assert_in_fatal_section();
                                233                 : 
                                234                 :     /*
                                235                 :      * If there's no in-progress module, create a new one.
                                236                 :      */
                                237            8310 :     if (!context->module)
                                238                 :     {
                                239             908 :         context->compiled = false;
                                240             908 :         context->module_generation = llvm_generation++;
                                241             908 :         context->module = LLVMModuleCreateWithName("pg");
                                242             908 :         LLVMSetTarget(context->module, llvm_triple);
                                243             908 :         LLVMSetDataLayout(context->module, llvm_layout);
                                244                 :     }
                                245                 : 
                                246            8310 :     return context->module;
                                247                 : }
                                248                 : 
                                249                 : /*
                                250                 :  * Expand function name to be non-conflicting. This should be used by code
                                251                 :  * generating code, when adding new externally visible function definitions to
                                252                 :  * a Module.
                                253                 :  */
                                254                 : char *
                                255            8310 : llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
                                256                 : {
                                257            8310 :     Assert(context->module != NULL);
                                258                 : 
 1657                           259            8310 :     context->base.instr.created_functions++;
                                260                 : 
                                261                 :     /*
                                262                 :      * Previously we used dots to separate, but turns out some tools, e.g.
                                263                 :      * GDB, don't like that and truncate name.
                                264                 :      */
 1844                           265           16620 :     return psprintf("%s_%zu_%d",
                                266                 :                     basename,
                                267                 :                     context->module_generation,
                                268            8310 :                     context->counter++);
                                269                 : }
                                270                 : 
                                271                 : /*
                                272                 :  * Return pointer to function funcname, which has to exist. If there's pending
                                273                 :  * code to be optimized and emitted, do so first.
                                274                 :  */
                                275                 : void *
                                276            3135 : llvm_get_function(LLVMJitContext *context, const char *funcname)
                                277                 : {
                                278                 : #if LLVM_VERSION_MAJOR > 11 || \
                                279                 :     defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
                                280                 :     ListCell   *lc;
                                281                 : #endif
                                282                 : 
                                283            3135 :     llvm_assert_in_fatal_section();
                                284                 : 
                                285                 :     /*
                                286                 :      * If there is a pending / not emitted module, compile and emit now.
                                287                 :      * Otherwise we might not find the [correct] function.
                                288                 :      */
                                289            3135 :     if (!context->compiled)
                                290                 :     {
                                291             673 :         llvm_compile_module(context);
                                292                 :     }
                                293                 : 
                                294                 :     /*
                                295                 :      * ORC's symbol table is of *unmangled* symbols. Therefore we don't need
                                296                 :      * to mangle here.
                                297                 :      */
                                298                 : 
                                299                 : #if LLVM_VERSION_MAJOR > 11
  881                           300            3135 :     foreach(lc, context->handles)
                                301                 :     {
                                302            3135 :         LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc);
                                303                 :         instr_time  starttime;
                                304                 :         instr_time  endtime;
                                305                 :         LLVMErrorRef error;
                                306                 :         LLVMOrcJITTargetAddress addr;
                                307                 : 
                                308            3135 :         INSTR_TIME_SET_CURRENT(starttime);
                                309                 : 
                                310            3135 :         addr = 0;
                                311            3135 :         error = LLVMOrcLLJITLookup(handle->lljit, &addr, funcname);
                                312            3135 :         if (error)
  881 andres                    313 UBC           0 :             elog(ERROR, "failed to look up symbol \"%s\": %s",
                                314                 :                  funcname, llvm_error_message(error));
                                315                 : 
                                316                 :         /*
                                317                 :          * LLJIT only actually emits code the first time a symbol is
                                318                 :          * referenced. Thus add lookup time to emission time. That's counting
                                319                 :          * a bit more than with older LLVM versions, but unlikely to ever
                                320                 :          * matter.
                                321                 :          */
  881 andres                    322 CBC        3135 :         INSTR_TIME_SET_CURRENT(endtime);
                                323            3135 :         INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter,
                                324                 :                               endtime, starttime);
                                325                 : 
                                326            3135 :         if (addr)
                                327            3135 :             return (void *) (uintptr_t) addr;
                                328                 :     }
                                329                 : #elif defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
                                330                 :     foreach(lc, context->handles)
                                331                 :     {
                                332                 :         LLVMOrcTargetAddress addr;
                                333                 :         LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc);
                                334                 : 
                                335                 :         addr = 0;
                                336                 :         if (LLVMOrcGetSymbolAddressIn(handle->stack, &addr, handle->orc_handle, funcname))
                                337                 :             elog(ERROR, "failed to look up symbol \"%s\"", funcname);
                                338                 :         if (addr)
                                339                 :             return (void *) (uintptr_t) addr;
                                340                 :     }
                                341                 : #elif LLVM_VERSION_MAJOR < 5
                                342                 :     {
                                343                 :         LLVMOrcTargetAddress addr;
                                344                 : 
                                345                 :         if ((addr = LLVMOrcGetSymbolAddress(llvm_opt0_orc, funcname)))
                                346                 :             return (void *) (uintptr_t) addr;
                                347                 :         if ((addr = LLVMOrcGetSymbolAddress(llvm_opt3_orc, funcname)))
                                348                 :             return (void *) (uintptr_t) addr;
                                349                 :     }
                                350                 : #else
                                351                 :     {
                                352                 :         LLVMOrcTargetAddress addr;
                                353                 : 
                                354                 :         if (LLVMOrcGetSymbolAddress(llvm_opt0_orc, &addr, funcname))
                                355                 :             elog(ERROR, "failed to look up symbol \"%s\"", funcname);
                                356                 :         if (addr)
                                357                 :             return (void *) (uintptr_t) addr;
                                358                 :         if (LLVMOrcGetSymbolAddress(llvm_opt3_orc, &addr, funcname))
                                359                 :             elog(ERROR, "failed to look up symbol \"%s\"", funcname);
                                360                 :         if (addr)
                                361                 :             return (void *) (uintptr_t) addr;
                                362                 :     }
                                363                 : #endif
                                364                 : 
 1844 andres                    365 UBC           0 :     elog(ERROR, "failed to JIT: %s", funcname);
                                366                 : 
                                367                 :     return NULL;
                                368                 : }
                                369                 : 
                                370                 : /*
                                371                 :  * Return type of a variable in llvmjit_types.c. This is useful to keep types
                                372                 :  * in sync between plain C and JIT related code.
                                373                 :  */
                                374                 : LLVMTypeRef
  853 andres                    375 CBC       11916 : llvm_pg_var_type(const char *varname)
                                376                 : {
                                377                 :     LLVMValueRef v_srcvar;
                                378                 :     LLVMTypeRef typ;
                                379                 : 
                                380                 :     /* this'll return a *pointer* to the global */
                                381           11916 :     v_srcvar = LLVMGetNamedGlobal(llvm_types_module, varname);
                                382           11916 :     if (!v_srcvar)
  853 andres                    383 UBC           0 :         elog(ERROR, "variable %s not in llvmjit_types.c", varname);
                                384                 : 
                                385                 :     /* look at the contained type */
  853 andres                    386 CBC       11916 :     typ = LLVMTypeOf(v_srcvar);
                                387           11916 :     Assert(typ != NULL && LLVMGetTypeKind(typ) == LLVMPointerTypeKind);
                                388           11916 :     typ = LLVMGetElementType(typ);
                                389           11916 :     Assert(typ != NULL);
                                390                 : 
                                391           11916 :     return typ;
                                392                 : }
                                393                 : 
                                394                 : /*
                                395                 :  * Return function type of a variable in llvmjit_types.c. This is useful to
                                396                 :  * keep function types in sync between C and JITed code.
                                397                 :  */
                                398                 : LLVMTypeRef
                                399            5235 : llvm_pg_var_func_type(const char *varname)
                                400                 : {
                                401            5235 :     LLVMTypeRef typ = llvm_pg_var_type(varname);
                                402                 : 
                                403                 :     /* look at the contained type */
                                404            5235 :     Assert(LLVMGetTypeKind(typ) == LLVMPointerTypeKind);
                                405            5235 :     typ = LLVMGetElementType(typ);
                                406            5235 :     Assert(typ != NULL && LLVMGetTypeKind(typ) == LLVMFunctionTypeKind);
                                407                 : 
                                408            5235 :     return typ;
                                409                 : }
                                410                 : 
                                411                 : /*
                                412                 :  * Return declaration for a function referenced in llvmjit_types.c, adding it
                                413                 :  * to the module if necessary.
                                414                 :  *
                                415                 :  * This is used to make functions discovered via llvm_create_types() known to
                                416                 :  * the module that's currently being worked on.
                                417                 :  */
                                418                 : LLVMValueRef
 1158                           419            6754 : llvm_pg_func(LLVMModuleRef mod, const char *funcname)
                                420                 : {
                                421                 :     LLVMValueRef v_srcfn;
                                422                 :     LLVMValueRef v_fn;
                                423                 : 
                                424                 :     /* don't repeatedly add function */
                                425            6754 :     v_fn = LLVMGetNamedFunction(mod, funcname);
 1844                           426            6754 :     if (v_fn)
                                427            4873 :         return v_fn;
                                428                 : 
 1158                           429            1881 :     v_srcfn = LLVMGetNamedFunction(llvm_types_module, funcname);
                                430                 : 
                                431            1881 :     if (!v_srcfn)
 1158 andres                    432 UBC           0 :         elog(ERROR, "function %s not in llvmjit_types.c", funcname);
                                433                 : 
 1844 andres                    434 CBC        1881 :     v_fn = LLVMAddFunction(mod,
                                435                 :                            funcname,
                                436                 :                            LLVMGetElementType(LLVMTypeOf(v_srcfn)));
 1158                           437            1881 :     llvm_copy_attributes(v_srcfn, v_fn);
                                438                 : 
 1844                           439            1881 :     return v_fn;
                                440                 : }
                                441                 : 
                                442                 : /*
                                443                 :  * Copy attributes from one function to another, for a specific index (an
                                444                 :  * index can reference return value, function and parameter attributes).
                                445                 :  */
                                446                 : static void
  906                           447           33330 : llvm_copy_attributes_at_index(LLVMValueRef v_from, LLVMValueRef v_to, uint32 index)
                                448                 : {
                                449                 :     int         num_attributes;
                                450                 :     LLVMAttributeRef *attrs;
                                451                 : 
                                452           33330 :     num_attributes = LLVMGetAttributeCountAtIndexPG(v_from, index);
                                453                 : 
                                454                 :     /*
                                455                 :      * Not just for efficiency: LLVM <= 3.9 crashes when
                                456                 :      * LLVMGetAttributesAtIndex() is called for an index with 0 attributes.
                                457                 :      */
                                458           33330 :     if (num_attributes == 0)
                                459           10190 :         return;
                                460                 : 
 1844                           461           23140 :     attrs = palloc(sizeof(LLVMAttributeRef) * num_attributes);
  906                           462           23140 :     LLVMGetAttributesAtIndex(v_from, index, attrs);
                                463                 : 
                                464          188675 :     for (int attno = 0; attno < num_attributes; attno++)
                                465          165535 :         LLVMAddAttributeAtIndex(v_to, index, attrs[attno]);
                                466                 : 
                                467           23140 :     pfree(attrs);
                                468                 : }
                                469                 : 
                                470                 : /*
                                471                 :  * Copy all attributes from one function to another. I.e. function, return and
                                472                 :  * parameters will be copied.
                                473                 :  */
                                474                 : void
                                475           10191 : llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
                                476                 : {
                                477                 :     uint32      param_count;
                                478                 : 
                                479                 :     /* copy function attributes */
                                480           10191 :     llvm_copy_attributes_at_index(v_from, v_to, LLVMAttributeFunctionIndex);
                                481                 : 
                                482                 :     /* and the return value attributes */
                                483           10191 :     llvm_copy_attributes_at_index(v_from, v_to, LLVMAttributeReturnIndex);
                                484                 : 
                                485                 :     /* and each function parameter's attribute */
                                486           10191 :     param_count = LLVMCountParams(v_from);
                                487                 : 
                                488           23139 :     for (int paramidx = 1; paramidx <= param_count; paramidx++)
                                489           12948 :         llvm_copy_attributes_at_index(v_from, v_to, paramidx);
 1844                           490           10191 : }
                                491                 : 
                                492                 : /*
                                493                 :  * Return a callable LLVMValueRef for fcinfo.
                                494                 :  */
                                495                 : LLVMValueRef
 1846                           496            2800 : llvm_function_reference(LLVMJitContext *context,
                                497                 :                         LLVMBuilderRef builder,
                                498                 :                         LLVMModuleRef mod,
                                499                 :                         FunctionCallInfo fcinfo)
                                500                 : {
                                501                 :     char       *modname;
                                502                 :     char       *basename;
                                503                 :     char       *funcname;
                                504                 : 
                                505                 :     LLVMValueRef v_fn;
                                506                 : 
                                507            2800 :     fmgr_symbol(fcinfo->flinfo->fn_oid, &modname, &basename);
                                508                 : 
                                509            2800 :     if (modname != NULL && basename != NULL)
                                510                 :     {
                                511                 :         /* external function in loadable library */
                                512              18 :         funcname = psprintf("pgextern.%s.%s", modname, basename);
                                513                 :     }
                                514            2782 :     else if (basename != NULL)
                                515                 :     {
                                516                 :         /* internal function */
  215 drowley                   517 GNC        2770 :         funcname = pstrdup(basename);
                                518                 :     }
                                519                 :     else
                                520                 :     {
                                521                 :         /*
                                522                 :          * Function we don't know to handle, return pointer. We do so by
                                523                 :          * creating a global constant containing a pointer to the function.
                                524                 :          * Makes IR more readable.
                                525                 :          */
                                526                 :         LLVMValueRef v_fn_addr;
                                527                 : 
 1846 andres                    528 CBC          12 :         funcname = psprintf("pgoidextern.%u",
                                529              12 :                             fcinfo->flinfo->fn_oid);
                                530              12 :         v_fn = LLVMGetNamedGlobal(mod, funcname);
                                531              12 :         if (v_fn != 0)
 1846 andres                    532 UBC           0 :             return LLVMBuildLoad(builder, v_fn, "");
                                533                 : 
 1846 andres                    534 CBC          12 :         v_fn_addr = l_ptr_const(fcinfo->flinfo->fn_addr, TypePGFunction);
                                535                 : 
                                536              12 :         v_fn = LLVMAddGlobal(mod, TypePGFunction, funcname);
                                537              12 :         LLVMSetInitializer(v_fn, v_fn_addr);
                                538              12 :         LLVMSetGlobalConstant(v_fn, true);
  881                           539              12 :         LLVMSetLinkage(v_fn, LLVMPrivateLinkage);
                                540              12 :         LLVMSetUnnamedAddr(v_fn, true);
                                541                 : 
 1846                           542              12 :         return LLVMBuildLoad(builder, v_fn, "");
                                543                 :     }
                                544                 : 
                                545                 :     /* check if function already has been added */
                                546            2788 :     v_fn = LLVMGetNamedFunction(mod, funcname);
                                547            2788 :     if (v_fn != 0)
                                548            1192 :         return v_fn;
                                549                 : 
                                550            1596 :     v_fn = LLVMAddFunction(mod, funcname, LLVMGetElementType(TypePGFunction));
                                551                 : 
                                552            1596 :     return v_fn;
                                553                 : }
                                554                 : 
                                555                 : /*
                                556                 :  * Optimize code in module using the flags set in context.
                                557                 :  */
                                558                 : static void
 1844                           559             673 : llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module)
                                560                 : {
                                561                 :     LLVMPassManagerBuilderRef llvm_pmb;
                                562                 :     LLVMPassManagerRef llvm_mpm;
                                563                 :     LLVMPassManagerRef llvm_fpm;
                                564                 :     LLVMValueRef func;
                                565                 :     int         compile_optlevel;
                                566                 : 
                                567             673 :     if (context->base.flags & PGJIT_OPT3)
                                568             500 :         compile_optlevel = 3;
                                569                 :     else
                                570             173 :         compile_optlevel = 0;
                                571                 : 
                                572                 :     /*
                                573                 :      * Have to create a new pass manager builder every pass through, as the
                                574                 :      * inliner has some per-builder state. Otherwise one ends up only inlining
                                575                 :      * a function the first time though.
                                576                 :      */
                                577             673 :     llvm_pmb = LLVMPassManagerBuilderCreate();
                                578             673 :     LLVMPassManagerBuilderSetOptLevel(llvm_pmb, compile_optlevel);
                                579             673 :     llvm_fpm = LLVMCreateFunctionPassManagerForModule(module);
                                580                 : 
                                581             673 :     if (context->base.flags & PGJIT_OPT3)
                                582                 :     {
                                583                 :         /* TODO: Unscientifically determined threshold */
                                584             500 :         LLVMPassManagerBuilderUseInlinerWithThreshold(llvm_pmb, 512);
                                585                 :     }
                                586                 :     else
                                587                 :     {
                                588                 :         /* we rely on mem2reg heavily, so emit even in the O0 case */
                                589             173 :         LLVMAddPromoteMemoryToRegisterPass(llvm_fpm);
                                590                 :     }
                                591                 : 
                                592             673 :     LLVMPassManagerBuilderPopulateFunctionPassManager(llvm_pmb, llvm_fpm);
                                593                 : 
                                594                 :     /*
                                595                 :      * Do function level optimization. This could be moved to the point where
                                596                 :      * functions are emitted, to reduce memory usage a bit.
                                597                 :      */
                                598             673 :     LLVMInitializeFunctionPassManager(llvm_fpm);
                                599             673 :     for (func = LLVMGetFirstFunction(context->module);
                                600           17455 :          func != NULL;
                                601           16782 :          func = LLVMGetNextFunction(func))
                                602           16782 :         LLVMRunFunctionPassManager(llvm_fpm, func);
                                603             673 :     LLVMFinalizeFunctionPassManager(llvm_fpm);
                                604             673 :     LLVMDisposePassManager(llvm_fpm);
                                605                 : 
                                606                 :     /*
                                607                 :      * Perform module level optimization. We do so even in the non-optimized
                                608                 :      * case, so always-inline functions etc get inlined. It's cheap enough.
                                609                 :      */
                                610             673 :     llvm_mpm = LLVMCreatePassManager();
                                611             673 :     LLVMPassManagerBuilderPopulateModulePassManager(llvm_pmb,
                                612                 :                                                     llvm_mpm);
                                613                 :     /* always use always-inliner pass */
                                614             673 :     if (!(context->base.flags & PGJIT_OPT3))
                                615             173 :         LLVMAddAlwaysInlinerPass(llvm_mpm);
                                616                 :     /* if doing inlining, but no expensive optimization, add inlining pass */
 1838                           617             673 :     if (context->base.flags & PGJIT_INLINE
                                618             500 :         && !(context->base.flags & PGJIT_OPT3))
 1838 andres                    619 UBC           0 :         LLVMAddFunctionInliningPass(llvm_mpm);
 1844 andres                    620 CBC         673 :     LLVMRunPassManager(llvm_mpm, context->module);
                                621             673 :     LLVMDisposePassManager(llvm_mpm);
                                622                 : 
                                623             673 :     LLVMPassManagerBuilderDispose(llvm_pmb);
                                624             673 : }
                                625                 : 
                                626                 : /*
                                627                 :  * Emit code for the currently pending module.
                                628                 :  */
                                629                 : static void
                                630             673 : llvm_compile_module(LLVMJitContext *context)
                                631                 : {
                                632                 :     LLVMJitHandle *handle;
                                633                 :     MemoryContext oldcontext;
                                634                 :     instr_time  starttime;
                                635                 :     instr_time  endtime;
                                636                 : #if LLVM_VERSION_MAJOR > 11
                                637                 :     LLVMOrcLLJITRef compile_orc;
                                638                 : #else
                                639                 :     LLVMOrcJITStackRef compile_orc;
                                640                 : #endif
                                641                 : 
                                642             673 :     if (context->base.flags & PGJIT_OPT3)
                                643             500 :         compile_orc = llvm_opt3_orc;
                                644                 :     else
                                645             173 :         compile_orc = llvm_opt0_orc;
                                646                 : 
                                647                 :     /* perform inlining */
 1838                           648             673 :     if (context->base.flags & PGJIT_INLINE)
                                649                 :     {
                                650             500 :         INSTR_TIME_SET_CURRENT(starttime);
                                651             500 :         llvm_inline(context->module);
                                652             500 :         INSTR_TIME_SET_CURRENT(endtime);
 1657                           653             500 :         INSTR_TIME_ACCUM_DIFF(context->base.instr.inlining_counter,
                                654                 :                               endtime, starttime);
                                655                 :     }
                                656                 : 
 1844                           657             673 :     if (jit_dump_bitcode)
                                658                 :     {
                                659                 :         char       *filename;
                                660                 : 
   30 peter                     661 UNC           0 :         filename = psprintf("%d.%zu.bc",
                                662                 :                             MyProcPid,
                                663                 :                             context->module_generation);
 1844 andres                    664 UBC           0 :         LLVMWriteBitcodeToFile(context->module, filename);
                                665               0 :         pfree(filename);
                                666                 :     }
                                667                 : 
                                668                 : 
                                669                 :     /* optimize according to the chosen optimization settings */
 1844 andres                    670 CBC         673 :     INSTR_TIME_SET_CURRENT(starttime);
                                671             673 :     llvm_optimize_module(context, context->module);
                                672             673 :     INSTR_TIME_SET_CURRENT(endtime);
 1657                           673             673 :     INSTR_TIME_ACCUM_DIFF(context->base.instr.optimization_counter,
                                674                 :                           endtime, starttime);
                                675                 : 
 1844                           676             673 :     if (jit_dump_bitcode)
                                677                 :     {
                                678                 :         char       *filename;
                                679                 : 
   30 peter                     680 UNC           0 :         filename = psprintf("%d.%zu.optimized.bc",
                                681                 :                             MyProcPid,
                                682                 :                             context->module_generation);
 1844 andres                    683 UBC           0 :         LLVMWriteBitcodeToFile(context->module, filename);
                                684               0 :         pfree(filename);
                                685                 :     }
                                686                 : 
                                687                 :     handle = (LLVMJitHandle *)
  881 andres                    688 CBC         673 :         MemoryContextAlloc(TopMemoryContext, sizeof(LLVMJitHandle));
                                689                 : 
                                690                 :     /*
                                691                 :      * Emit the code. Note that this can, depending on the optimization
                                692                 :      * settings, take noticeable resources as code emission executes low-level
                                693                 :      * instruction combining/selection passes etc. Without optimization a
                                694                 :      * faster instruction selection mechanism is used.
                                695                 :      */
 1844                           696             673 :     INSTR_TIME_SET_CURRENT(starttime);
                                697                 : #if LLVM_VERSION_MAJOR > 11
                                698                 :     {
                                699                 :         LLVMOrcThreadSafeModuleRef ts_module;
                                700                 :         LLVMErrorRef error;
  881                           701             673 :         LLVMOrcJITDylibRef jd = LLVMOrcLLJITGetMainJITDylib(compile_orc);
                                702                 : 
                                703             673 :         ts_module = LLVMOrcCreateNewThreadSafeModule(context->module, llvm_ts_context);
                                704                 : 
                                705             673 :         handle->lljit = compile_orc;
                                706             673 :         handle->resource_tracker = LLVMOrcJITDylibCreateResourceTracker(jd);
                                707                 : 
                                708                 :         /*
                                709                 :          * NB: This doesn't actually emit code. That happens lazily the first
                                710                 :          * time a symbol defined in the module is requested. Due to that
                                711                 :          * llvm_get_function() also accounts for emission time.
                                712                 :          */
                                713                 : 
                                714             673 :         context->module = NULL; /* will be owned by LLJIT */
                                715             673 :         error = LLVMOrcLLJITAddLLVMIRModuleWithRT(compile_orc,
                                716                 :                                                   handle->resource_tracker,
                                717                 :                                                   ts_module);
                                718                 : 
                                719             673 :         if (error)
  881 andres                    720 UBC           0 :             elog(ERROR, "failed to JIT module: %s",
                                721                 :                  llvm_error_message(error));
                                722                 : 
  881 andres                    723 CBC         673 :         handle->lljit = compile_orc;
                                724                 : 
                                725                 :         /* LLVMOrcLLJITAddLLVMIRModuleWithRT takes ownership of the module */
                                726                 :     }
                                727                 : #elif LLVM_VERSION_MAJOR > 6
                                728                 :     {
                                729                 :         handle->stack = compile_orc;
                                730                 :         if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, context->module,
                                731                 :                                         llvm_resolve_symbol, NULL))
                                732                 :             elog(ERROR, "failed to JIT module");
                                733                 : 
                                734                 :         /* LLVMOrcAddEagerlyCompiledIR takes ownership of the module */
                                735                 :     }
                                736                 : #elif LLVM_VERSION_MAJOR > 4
                                737                 :     {
                                738                 :         LLVMSharedModuleRef smod;
                                739                 : 
                                740                 :         smod = LLVMOrcMakeSharedModule(context->module);
                                741                 :         handle->stack = compile_orc;
                                742                 :         if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, smod,
                                743                 :                                         llvm_resolve_symbol, NULL))
                                744                 :             elog(ERROR, "failed to JIT module");
                                745                 : 
                                746                 :         LLVMOrcDisposeSharedModuleRef(smod);
                                747                 :     }
                                748                 : #else                           /* LLVM 4.0 and 3.9 */
                                749                 :     {
                                750                 :         handle->stack = compile_orc;
                                751                 :         handle->orc_handle = LLVMOrcAddEagerlyCompiledIR(compile_orc, context->module,
                                752                 :                                                          llvm_resolve_symbol, NULL);
                                753                 : 
                                754                 :         LLVMDisposeModule(context->module);
                                755                 :     }
                                756                 : #endif
                                757                 : 
 1844                           758             673 :     INSTR_TIME_SET_CURRENT(endtime);
 1657                           759             673 :     INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter,
                                760                 :                           endtime, starttime);
                                761                 : 
 1844                           762             673 :     context->module = NULL;
                                763             673 :     context->compiled = true;
                                764                 : 
                                765                 :     /* remember emitted code for cleanup and lookups */
                                766             673 :     oldcontext = MemoryContextSwitchTo(TopMemoryContext);
  881                           767             673 :     context->handles = lappend(context->handles, handle);
 1844                           768             673 :     MemoryContextSwitchTo(oldcontext);
                                769                 : 
                                770             673 :     ereport(DEBUG1,
                                771                 :             (errmsg_internal("time to inline: %.3fs, opt: %.3fs, emit: %.3fs",
                                772                 :                              INSTR_TIME_GET_DOUBLE(context->base.instr.inlining_counter),
                                773                 :                              INSTR_TIME_GET_DOUBLE(context->base.instr.optimization_counter),
                                774                 :                              INSTR_TIME_GET_DOUBLE(context->base.instr.emission_counter)),
                                775                 :              errhidestmt(true),
                                776                 :              errhidecontext(true)));
 1845                           777             673 : }
                                778                 : 
                                779                 : /*
                                780                 :  * Per session initialization.
                                781                 :  */
                                782                 : static void
                                783             839 : llvm_session_initialize(void)
                                784                 : {
                                785                 :     MemoryContext oldcontext;
 1844                           786             839 :     char       *error = NULL;
                                787             839 :     char       *cpu = NULL;
                                788             839 :     char       *features = NULL;
                                789                 :     LLVMTargetMachineRef opt0_tm;
                                790                 :     LLVMTargetMachineRef opt3_tm;
                                791                 : 
 1845                           792             839 :     if (llvm_session_initialized)
                                793             446 :         return;
                                794                 : 
                                795             393 :     oldcontext = MemoryContextSwitchTo(TopMemoryContext);
                                796                 : 
                                797             393 :     LLVMInitializeNativeTarget();
                                798             393 :     LLVMInitializeNativeAsmPrinter();
                                799             393 :     LLVMInitializeNativeAsmParser();
                                800                 : 
                                801                 :     /*
                                802                 :      * When targeting an LLVM version with opaque pointers enabled by
                                803                 :      * default, turn them off for the context we build our code in.  We don't
                                804                 :      * need to do so for other contexts (e.g. llvm_ts_context).  Once the IR is
                                805                 :      * generated, it carries the necessary information.
                                806                 :      */
                                807                 : #if LLVM_VERSION_MAJOR > 14
                                808                 :     LLVMContextSetOpaquePointers(LLVMGetGlobalContext(), false);
                                809                 : #endif
                                810                 : 
                                811                 :     /*
                                812                 :      * Synchronize types early, as that also includes inferring the target
                                813                 :      * triple.
                                814                 :      */
 1844                           815             393 :     llvm_create_types();
                                816                 : 
                                817             393 :     if (LLVMGetTargetFromTriple(llvm_triple, &llvm_targetref, &error) != 0)
                                818                 :     {
   96 michael                   819 UBC           0 :         elog(FATAL, "failed to query triple %s", error);
                                820                 :     }
                                821                 : 
                                822                 :     /*
                                823                 :      * We want the generated code to use all available features. Therefore
                                824                 :      * grab the host CPU string and detect features of the current CPU. The
                                825                 :      * latter is needed because some CPU architectures default to enabling
                                826                 :      * features not all CPUs have (weird, huh).
                                827                 :      */
 1844 andres                    828 CBC         393 :     cpu = LLVMGetHostCPUName();
                                829             393 :     features = LLVMGetHostCPUFeatures();
                                830             393 :     elog(DEBUG2, "LLVMJIT detected CPU \"%s\", with features \"%s\"",
                                831                 :          cpu, features);
                                832                 : 
                                833                 :     opt0_tm =
                                834             393 :         LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
                                835                 :                                 LLVMCodeGenLevelNone,
                                836                 :                                 LLVMRelocDefault,
                                837                 :                                 LLVMCodeModelJITDefault);
                                838                 :     opt3_tm =
                                839             393 :         LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
                                840                 :                                 LLVMCodeGenLevelAggressive,
                                841                 :                                 LLVMRelocDefault,
                                842                 :                                 LLVMCodeModelJITDefault);
                                843                 : 
                                844             393 :     LLVMDisposeMessage(cpu);
                                845             393 :     cpu = NULL;
                                846             393 :     LLVMDisposeMessage(features);
                                847             393 :     features = NULL;
                                848                 : 
                                849                 :     /* force symbols in main binary to be loaded */
                                850             393 :     LLVMLoadLibraryPermanently(NULL);
                                851                 : 
                                852                 : #if LLVM_VERSION_MAJOR > 11
                                853                 :     {
  881                           854             393 :         llvm_ts_context = LLVMOrcCreateNewThreadSafeContext();
                                855                 : 
                                856             393 :         llvm_opt0_orc = llvm_create_jit_instance(opt0_tm);
                                857             393 :         opt0_tm = 0;
                                858                 : 
                                859             393 :         llvm_opt3_orc = llvm_create_jit_instance(opt3_tm);
                                860             393 :         opt3_tm = 0;
                                861                 :     }
                                862                 : #else                           /* LLVM_VERSION_MAJOR > 11 */
                                863                 :     {
                                864                 :         llvm_opt0_orc = LLVMOrcCreateInstance(opt0_tm);
                                865                 :         llvm_opt3_orc = LLVMOrcCreateInstance(opt3_tm);
                                866                 : 
                                867                 : #if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
                                868                 :         if (jit_debugging_support)
                                869                 :         {
                                870                 :             LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener();
                                871                 : 
                                872                 :             LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
                                873                 :             LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
                                874                 :         }
                                875                 : #endif
                                876                 : #if defined(HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER) && HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER
                                877                 :         if (jit_profiling_support)
                                878                 :         {
                                879                 :             LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener();
                                880                 : 
                                881                 :             LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
                                882                 :             LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
                                883                 :         }
                                884                 : #endif
                                885                 :     }
                                886                 : #endif                          /* LLVM_VERSION_MAJOR > 11 */
                                887                 : 
  976 rhaas                     888             393 :     on_proc_exit(llvm_shutdown, 0);
                                889                 : 
 1845 andres                    890             393 :     llvm_session_initialized = true;
                                891                 : 
                                892             393 :     MemoryContextSwitchTo(oldcontext);
                                893                 : }
                                894                 : 
                                895                 : static void
                                896             393 : llvm_shutdown(int code, Datum arg)
                                897                 : {
                                898                 :     /*
                                899                 :      * If llvm_shutdown() is reached while in a fatal-on-oom section an error
                                900                 :      * has occurred in the middle of LLVM code. It is not safe to call back
                                901                 :      * into LLVM (which is why a FATAL error was thrown).
                                902                 :      *
                                903                 :      * We do need to shutdown LLVM in other shutdown cases, otherwise e.g.
                                904                 :      * profiling data won't be written out.
                                905                 :      */
  573                           906             393 :     if (llvm_in_fatal_on_oom())
                                907                 :     {
                                908             343 :         Assert(proc_exit_inprogress);
                                909             343 :         return;
                                910                 :     }
                                911                 : 
                                912                 : #if LLVM_VERSION_MAJOR > 11
                                913                 :     {
  881                           914              50 :         if (llvm_opt3_orc)
                                915                 :         {
                                916              50 :             LLVMOrcDisposeLLJIT(llvm_opt3_orc);
                                917              50 :             llvm_opt3_orc = NULL;
                                918                 :         }
                                919              50 :         if (llvm_opt0_orc)
                                920                 :         {
                                921              50 :             LLVMOrcDisposeLLJIT(llvm_opt0_orc);
                                922              50 :             llvm_opt0_orc = NULL;
                                923                 :         }
                                924              50 :         if (llvm_ts_context)
                                925                 :         {
                                926              50 :             LLVMOrcDisposeThreadSafeContext(llvm_ts_context);
                                927              50 :             llvm_ts_context = NULL;
                                928                 :         }
                                929                 :     }
                                930                 : #else                           /* LLVM_VERSION_MAJOR > 11 */
                                931                 :     {
                                932                 :         /* unregister profiling support, needs to be flushed to be useful */
                                933                 : 
                                934                 :         if (llvm_opt3_orc)
                                935                 :         {
                                936                 : #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
                                937                 :             if (jit_profiling_support)
                                938                 :                 LLVMOrcUnregisterPerf(llvm_opt3_orc);
                                939                 : #endif
                                940                 :             LLVMOrcDisposeInstance(llvm_opt3_orc);
                                941                 :             llvm_opt3_orc = NULL;
                                942                 :         }
                                943                 : 
                                944                 :         if (llvm_opt0_orc)
                                945                 :         {
                                946                 : #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
                                947                 :             if (jit_profiling_support)
                                948                 :                 LLVMOrcUnregisterPerf(llvm_opt0_orc);
                                949                 : #endif
                                950                 :             LLVMOrcDisposeInstance(llvm_opt0_orc);
                                951                 :             llvm_opt0_orc = NULL;
                                952                 :         }
                                953                 :     }
                                954                 : #endif                          /* LLVM_VERSION_MAJOR > 11 */
                                955                 : }
                                956                 : 
                                957                 : /* helper for llvm_create_types, returning a function's return type */
                                958                 : static LLVMTypeRef
 1844                           959             393 : load_return_type(LLVMModuleRef mod, const char *name)
                                960                 : {
                                961                 :     LLVMValueRef value;
                                962                 :     LLVMTypeRef typ;
                                963                 : 
                                964                 :     /* this'll return a *pointer* to the function */
                                965             393 :     value = LLVMGetNamedFunction(mod, name);
                                966             393 :     if (!value)
 1844 andres                    967 UBC           0 :         elog(ERROR, "function %s is unknown", name);
                                968                 : 
                                969                 :     /* get type of function pointer */
 1844 andres                    970 CBC         393 :     typ = LLVMTypeOf(value);
                                971             393 :     Assert(typ != NULL);
                                972                 :     /* dereference pointer */
                                973             393 :     typ = LLVMGetElementType(typ);
                                974             393 :     Assert(typ != NULL);
                                975                 :     /* and look at return type */
                                976             393 :     typ = LLVMGetReturnType(typ);
                                977             393 :     Assert(typ != NULL);
                                978                 : 
                                979             393 :     return typ;
                                980                 : }
                                981                 : 
                                982                 : /*
                                983                 :  * Load required information, types, function signatures from llvmjit_types.c
                                984                 :  * and make them available in global variables.
                                985                 :  *
                                986                 :  * Those global variables are then used while emitting code.
                                987                 :  */
                                988                 : static void
                                989             393 : llvm_create_types(void)
                                990                 : {
                                991                 :     char        path[MAXPGPATH];
                                992                 :     LLVMMemoryBufferRef buf;
                                993                 :     char       *msg;
                                994                 : 
                                995             393 :     snprintf(path, MAXPGPATH, "%s/%s", pkglib_path, "llvmjit_types.bc");
                                996                 : 
                                997                 :     /* open file */
                                998             393 :     if (LLVMCreateMemoryBufferWithContentsOfFile(path, &buf, &msg))
                                999                 :     {
 1844 andres                   1000 UBC           0 :         elog(ERROR, "LLVMCreateMemoryBufferWithContentsOfFile(%s) failed: %s",
                               1001                 :              path, msg);
                               1002                 :     }
                               1003                 : 
                               1004                 :     /* eagerly load contents, going to need it all */
 1158 andres                   1005 CBC         393 :     if (LLVMParseBitcode2(buf, &llvm_types_module))
                               1006                 :     {
 1844 andres                   1007 UBC           0 :         elog(ERROR, "LLVMParseBitcode2 of %s failed", path);
                               1008                 :     }
 1844 andres                   1009 CBC         393 :     LLVMDisposeMemoryBuffer(buf);
                               1010                 : 
                               1011                 :     /*
                               1012                 :      * Load triple & layout from clang emitted file so we're guaranteed to be
                               1013                 :      * compatible.
                               1014                 :      */
 1158                          1015             393 :     llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module));
                               1016             393 :     llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module));
                               1017                 : 
  853                          1018             393 :     TypeSizeT = llvm_pg_var_type("TypeSizeT");
 1158                          1019             393 :     TypeParamBool = load_return_type(llvm_types_module, "FunctionReturningBool");
  853                          1020             393 :     TypeStorageBool = llvm_pg_var_type("TypeStorageBool");
                               1021             393 :     TypePGFunction = llvm_pg_var_type("TypePGFunction");
                               1022             393 :     StructNullableDatum = llvm_pg_var_type("StructNullableDatum");
                               1023             393 :     StructExprContext = llvm_pg_var_type("StructExprContext");
                               1024             393 :     StructExprEvalStep = llvm_pg_var_type("StructExprEvalStep");
                               1025             393 :     StructExprState = llvm_pg_var_type("StructExprState");
                               1026             393 :     StructFunctionCallInfoData = llvm_pg_var_type("StructFunctionCallInfoData");
                               1027             393 :     StructMemoryContextData = llvm_pg_var_type("StructMemoryContextData");
                               1028             393 :     StructTupleTableSlot = llvm_pg_var_type("StructTupleTableSlot");
                               1029             393 :     StructHeapTupleTableSlot = llvm_pg_var_type("StructHeapTupleTableSlot");
                               1030             393 :     StructMinimalTupleTableSlot = llvm_pg_var_type("StructMinimalTupleTableSlot");
                               1031             393 :     StructHeapTupleData = llvm_pg_var_type("StructHeapTupleData");
                               1032             393 :     StructTupleDescData = llvm_pg_var_type("StructTupleDescData");
                               1033             393 :     StructAggState = llvm_pg_var_type("StructAggState");
                               1034             393 :     StructAggStatePerGroupData = llvm_pg_var_type("StructAggStatePerGroupData");
                               1035             393 :     StructAggStatePerTransData = llvm_pg_var_type("StructAggStatePerTransData");
                               1036                 : 
 1158                          1037             393 :     AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate");
 1844                          1038             393 : }
                               1039                 : 
                               1040                 : /*
                               1041                 :  * Split a symbol into module / function parts.  If the function is in the
                               1042                 :  * main binary (or an external library) *modname will be NULL.
                               1043                 :  */
                               1044                 : void
                               1045           17623 : llvm_split_symbol_name(const char *name, char **modname, char **funcname)
                               1046                 : {
                               1047           17623 :     *modname = NULL;
                               1048           17623 :     *funcname = NULL;
                               1049                 : 
                               1050                 :     /*
                               1051                 :      * Module function names are pgextern.$module.$funcname
                               1052                 :      */
                               1053           17623 :     if (strncmp(name, "pgextern.", strlen("pgextern.")) == 0)
                               1054                 :     {
                               1055                 :         /*
                               1056                 :          * Symbol names cannot contain a ., therefore we can split based on
                               1057                 :          * first and last occurrence of one.
                               1058                 :          */
                               1059              42 :         *funcname = rindex(name, '.');
                               1060              42 :         (*funcname)++;          /* jump over . */
                               1061                 : 
                               1062              84 :         *modname = pnstrdup(name + strlen("pgextern."),
                               1063              42 :                             *funcname - name - strlen("pgextern.") - 1);
                               1064              42 :         Assert(funcname);
                               1065                 : 
                               1066              42 :         *funcname = pstrdup(*funcname);
                               1067                 :     }
                               1068                 :     else
                               1069                 :     {
                               1070           17581 :         *modname = NULL;
                               1071           17581 :         *funcname = pstrdup(name);
                               1072                 :     }
                               1073           17623 : }
                               1074                 : 
                               1075                 : /*
                               1076                 :  * Attempt to resolve symbol, so LLVM can emit a reference to it.
                               1077                 :  */
                               1078                 : static uint64_t
                               1079               8 : llvm_resolve_symbol(const char *symname, void *ctx)
                               1080                 : {
                               1081                 :     uintptr_t   addr;
                               1082                 :     char       *funcname;
                               1083                 :     char       *modname;
                               1084                 : 
                               1085                 :     /*
                               1086                 :      * macOS prefixes all object level symbols with an underscore. But neither
                               1087                 :      * dlsym() nor PG's inliner expect that. So undo.
                               1088                 :      */
                               1089                 : #if defined(__darwin__)
                               1090                 :     if (symname[0] != '_')
                               1091                 :         elog(ERROR, "expected prefixed symbol name, but got \"%s\"", symname);
                               1092                 :     symname++;
                               1093                 : #endif
                               1094                 : 
                               1095               8 :     llvm_split_symbol_name(symname, &modname, &funcname);
                               1096                 : 
                               1097                 :     /* functions that aren't resolved to names shouldn't ever get here */
                               1098               8 :     Assert(funcname);
                               1099                 : 
                               1100               8 :     if (modname)
                               1101               8 :         addr = (uintptr_t) load_external_function(modname, funcname,
                               1102                 :                                                   true, NULL);
                               1103                 :     else
 1844 andres                   1104 UBC           0 :         addr = (uintptr_t) LLVMSearchForAddressOfSymbol(symname);
                               1105                 : 
 1844 andres                   1106 CBC           8 :     pfree(funcname);
                               1107               8 :     if (modname)
                               1108               8 :         pfree(modname);
                               1109                 : 
                               1110                 :     /* let LLVM will error out - should never happen */
                               1111               8 :     if (!addr)
 1844 andres                   1112 UBC           0 :         elog(WARNING, "failed to resolve name %s", symname);
                               1113                 : 
 1844 andres                   1114 CBC           8 :     return (uint64_t) addr;
                               1115                 : }
                               1116                 : 
                               1117                 : #if LLVM_VERSION_MAJOR > 11
                               1118                 : 
                               1119                 : static LLVMErrorRef
  881                          1120               8 : llvm_resolve_symbols(LLVMOrcDefinitionGeneratorRef GeneratorObj, void *Ctx,
                               1121                 :                      LLVMOrcLookupStateRef * LookupState, LLVMOrcLookupKind Kind,
                               1122                 :                      LLVMOrcJITDylibRef JD, LLVMOrcJITDylibLookupFlags JDLookupFlags,
                               1123                 :                      LLVMOrcCLookupSet LookupSet, size_t LookupSetSize)
                               1124                 : {
                               1125                 : #if LLVM_VERSION_MAJOR > 14
                               1126                 :     LLVMOrcCSymbolMapPairs symbols = palloc0(sizeof(LLVMOrcCSymbolMapPair) * LookupSetSize);
                               1127                 : #else
                               1128               8 :     LLVMOrcCSymbolMapPairs symbols = palloc0(sizeof(LLVMJITCSymbolMapPair) * LookupSetSize);
                               1129                 : #endif
                               1130                 :     LLVMErrorRef error;
                               1131                 :     LLVMOrcMaterializationUnitRef mu;
                               1132                 : 
                               1133              16 :     for (int i = 0; i < LookupSetSize; i++)
                               1134                 :     {
                               1135               8 :         const char *name = LLVMOrcSymbolStringPoolEntryStr(LookupSet[i].Name);
                               1136                 : 
                               1137                 : #if LLVM_VERSION_MAJOR > 12
  653 tmunro                   1138               8 :         LLVMOrcRetainSymbolStringPoolEntry(LookupSet[i].Name);
                               1139                 : #endif
  881 andres                   1140               8 :         symbols[i].Name = LookupSet[i].Name;
                               1141               8 :         symbols[i].Sym.Address = llvm_resolve_symbol(name, NULL);
                               1142               8 :         symbols[i].Sym.Flags.GenericFlags = LLVMJITSymbolGenericFlagsExported;
                               1143                 :     }
                               1144                 : 
                               1145               8 :     mu = LLVMOrcAbsoluteSymbols(symbols, LookupSetSize);
                               1146               8 :     error = LLVMOrcJITDylibDefine(JD, mu);
                               1147               8 :     if (error != LLVMErrorSuccess)
  881 andres                   1148 UBC           0 :         LLVMOrcDisposeMaterializationUnit(mu);
                               1149                 : 
  881 andres                   1150 CBC           8 :     pfree(symbols);
                               1151                 : 
                               1152               8 :     return error;
                               1153                 : }
                               1154                 : 
                               1155                 : /*
                               1156                 :  * We cannot throw errors through LLVM (without causing a FATAL at least), so
                               1157                 :  * just use WARNING here. That's OK anyway, as the error is also reported at
                               1158                 :  * the top level action (with less detail) and there might be multiple
                               1159                 :  * invocations of errors with details.
                               1160                 :  *
                               1161                 :  * This doesn't really happen during normal operation, but in cases like
                               1162                 :  * symbol resolution breakage. So just using elog(WARNING) is fine.
                               1163                 :  */
                               1164                 : static void
  881 andres                   1165 UBC           0 : llvm_log_jit_error(void *ctx, LLVMErrorRef error)
                               1166                 : {
                               1167               0 :     elog(WARNING, "error during JITing: %s",
                               1168                 :          llvm_error_message(error));
                               1169               0 : }
                               1170                 : 
                               1171                 : /*
                               1172                 :  * Create our own object layer, so we can add event listeners.
                               1173                 :  */
                               1174                 : static LLVMOrcObjectLayerRef
  881 andres                   1175 CBC         786 : llvm_create_object_layer(void *Ctx, LLVMOrcExecutionSessionRef ES, const char *Triple)
                               1176                 : {
                               1177                 :     LLVMOrcObjectLayerRef objlayer =
                               1178             786 :     LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(ES);
                               1179                 : 
                               1180                 : #if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
                               1181             786 :     if (jit_debugging_support)
                               1182                 :     {
  881 andres                   1183 UBC           0 :         LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener();
                               1184                 : 
                               1185               0 :         LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(objlayer, l);
                               1186                 :     }
                               1187                 : #endif
                               1188                 : 
                               1189                 : #if defined(HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER) && HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER
  881 andres                   1190 CBC         786 :     if (jit_profiling_support)
                               1191                 :     {
  881 andres                   1192 UBC           0 :         LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener();
                               1193                 : 
                               1194               0 :         LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(objlayer, l);
                               1195                 :     }
                               1196                 : #endif
                               1197                 : 
  881 andres                   1198 CBC         786 :     return objlayer;
                               1199                 : }
                               1200                 : 
                               1201                 : /*
                               1202                 :  * Create LLJIT instance, using the passed in target machine. Note that the
                               1203                 :  * target machine afterwards is owned by the LLJIT instance.
                               1204                 :  */
                               1205                 : static LLVMOrcLLJITRef
                               1206             786 : llvm_create_jit_instance(LLVMTargetMachineRef tm)
                               1207                 : {
                               1208                 :     LLVMOrcLLJITRef lljit;
                               1209                 :     LLVMOrcJITTargetMachineBuilderRef tm_builder;
                               1210                 :     LLVMOrcLLJITBuilderRef lljit_builder;
                               1211                 :     LLVMErrorRef error;
                               1212                 :     LLVMOrcDefinitionGeneratorRef main_gen;
                               1213                 :     LLVMOrcDefinitionGeneratorRef ref_gen;
                               1214                 : 
                               1215             786 :     lljit_builder = LLVMOrcCreateLLJITBuilder();
                               1216             786 :     tm_builder = LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(tm);
                               1217             786 :     LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(lljit_builder, tm_builder);
                               1218                 : 
                               1219             786 :     LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(lljit_builder,
                               1220                 :                                                     llvm_create_object_layer,
                               1221                 :                                                     NULL);
                               1222                 : 
                               1223             786 :     error = LLVMOrcCreateLLJIT(&lljit, lljit_builder);
                               1224             786 :     if (error)
  881 andres                   1225 UBC           0 :         elog(ERROR, "failed to create lljit instance: %s",
                               1226                 :              llvm_error_message(error));
                               1227                 : 
  881 andres                   1228 CBC         786 :     LLVMOrcExecutionSessionSetErrorReporter(LLVMOrcLLJITGetExecutionSession(lljit),
                               1229                 :                                             llvm_log_jit_error, NULL);
                               1230                 : 
                               1231                 :     /*
                               1232                 :      * Symbol resolution support for symbols in the postgres binary /
                               1233                 :      * libraries already loaded.
                               1234                 :      */
                               1235             786 :     error = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(&main_gen,
                               1236             786 :                                                                  LLVMOrcLLJITGetGlobalPrefix(lljit),
                               1237                 :                                                                  0, NULL);
                               1238             786 :     if (error)
  881 andres                   1239 UBC           0 :         elog(ERROR, "failed to create generator: %s",
                               1240                 :              llvm_error_message(error));
  881 andres                   1241 CBC         786 :     LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(lljit), main_gen);
                               1242                 : 
                               1243                 :     /*
                               1244                 :      * Symbol resolution support for "special" functions, e.g. a call into an
                               1245                 :      * SQL callable function.
                               1246                 :      */
                               1247                 : #if LLVM_VERSION_MAJOR > 14
                               1248                 :     ref_gen = LLVMOrcCreateCustomCAPIDefinitionGenerator(llvm_resolve_symbols, NULL, NULL);
                               1249                 : #else
                               1250             786 :     ref_gen = LLVMOrcCreateCustomCAPIDefinitionGenerator(llvm_resolve_symbols, NULL);
                               1251                 : #endif
                               1252             786 :     LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(lljit), ref_gen);
                               1253                 : 
                               1254             786 :     return lljit;
                               1255                 : }
                               1256                 : 
                               1257                 : static char *
  881 andres                   1258 UBC           0 : llvm_error_message(LLVMErrorRef error)
                               1259                 : {
                               1260               0 :     char       *orig = LLVMGetErrorMessage(error);
                               1261               0 :     char       *msg = pstrdup(orig);
                               1262                 : 
                               1263               0 :     LLVMDisposeErrorMessage(orig);
                               1264                 : 
                               1265               0 :     return msg;
                               1266                 : }
                               1267                 : 
                               1268                 : #endif                          /* LLVM_VERSION_MAJOR > 11 */
        

Generated by: LCOV version v1.16-55-g56c0a2a