LCOV - code coverage report
Current view: top level - src - codegen.cpp (source / functions) Hit Total Coverage
Test: [test only] commit 0f242327d2cc9bd130497f44b6350c924185606a Lines: 4656 5085 91.6 %
Date: 2022-07-16 23:42:53 Functions: 326 349 93.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2949 3714 79.4 %

           Branch data     Line data    Source code
       1                 :            : // This file is a part of Julia. License is MIT: https://julialang.org/license
       2                 :            : 
       3                 :            : #undef DEBUG
       4                 :            : #include "llvm-version.h"
       5                 :            : #include "platform.h"
       6                 :            : #if defined(_CPU_X86_)
       7                 :            : #define JL_NEED_FLOATTEMP_VAR 1
       8                 :            : #endif
       9                 :            : #if defined(_OS_WINDOWS_) || defined(_OS_FREEBSD_)
      10                 :            : #define JL_DISABLE_FPO
      11                 :            : #endif
      12                 :            : 
      13                 :            : #ifndef __STDC_LIMIT_MACROS
      14                 :            : #define __STDC_LIMIT_MACROS
      15                 :            : #define __STDC_CONSTANT_MACROS
      16                 :            : #endif
      17                 :            : 
      18                 :            : #include <setjmp.h>
      19                 :            : #include <string>
      20                 :            : #include <fstream>
      21                 :            : #include <map>
      22                 :            : #include <array>
      23                 :            : #include <vector>
      24                 :            : #include <set>
      25                 :            : #include <functional>
      26                 :            : 
      27                 :            : // target machine computation
      28                 :            : #include <llvm/CodeGen/TargetSubtargetInfo.h>
      29                 :            : #if JL_LLVM_VERSION >= 140000
      30                 :            : #include <llvm/MC/TargetRegistry.h>
      31                 :            : #else
      32                 :            : #include <llvm/Support/TargetRegistry.h>
      33                 :            : #endif
      34                 :            : #include <llvm/Target/TargetOptions.h>
      35                 :            : #include <llvm/Support/Host.h>
      36                 :            : #include <llvm/Support/TargetSelect.h>
      37                 :            : #include <llvm/Object/SymbolSize.h>
      38                 :            : 
      39                 :            : #include <llvm/InitializePasses.h>
      40                 :            : 
      41                 :            : // IR building
      42                 :            : #include <llvm/IR/IntrinsicInst.h>
      43                 :            : #include <llvm/Object/ObjectFile.h>
      44                 :            : #include <llvm/IR/DIBuilder.h>
      45                 :            : #include <llvm/AsmParser/Parser.h>
      46                 :            : #include <llvm/DebugInfo/DIContext.h>
      47                 :            : #include "llvm/IR/DebugInfoMetadata.h"
      48                 :            : #include <llvm/IR/DerivedTypes.h>
      49                 :            : #include <llvm/IR/Intrinsics.h>
      50                 :            : #include <llvm/IR/Attributes.h>
      51                 :            : #include <llvm/IR/IRBuilder.h>
      52                 :            : #include <llvm/IR/MDBuilder.h>
      53                 :            : 
      54                 :            : // support
      55                 :            : #include <llvm/ADT/SmallBitVector.h>
      56                 :            : #include <llvm/ADT/Optional.h>
      57                 :            : #include <llvm/ADT/Statistic.h>
      58                 :            : #include <llvm/Support/raw_ostream.h>
      59                 :            : #include <llvm/Support/FormattedStream.h>
      60                 :            : #include <llvm/Support/SourceMgr.h> // for llvmcall
      61                 :            : #include <llvm/Transforms/Utils/Cloning.h> // for llvmcall inlining
      62                 :            : #include <llvm/Transforms/Utils/BasicBlockUtils.h>
      63                 :            : #include <llvm/IR/Verifier.h> // for llvmcall validation
      64                 :            : #include <llvm/IR/PassTimingInfo.h>
      65                 :            : #include <llvm/Bitcode/BitcodeWriter.h>
      66                 :            : 
      67                 :            : // C API
      68                 :            : #include <llvm-c/Types.h>
      69                 :            : 
      70                 :            : // for configuration options
      71                 :            : #include <llvm/Support/PrettyStackTrace.h>
      72                 :            : #include <llvm/Support/CommandLine.h>
      73                 :            : #include <llvm/Support/Process.h>
      74                 :            : 
      75                 :            : #include <llvm/IR/InlineAsm.h>
      76                 :            : #if defined(_CPU_ARM_) || defined(_CPU_AARCH64_)
      77                 :            : #  include <sys/utsname.h>
      78                 :            : #endif
      79                 :            : #if defined(USE_POLLY)
      80                 :            : #include <polly/RegisterPasses.h>
      81                 :            : #include <polly/ScopDetection.h>
      82                 :            : #endif
      83                 :            : #include <llvm/Target/TargetMachine.h>
      84                 :            : 
      85                 :            : #include "llvm/Support/Path.h" // for llvm::sys::path
      86                 :            : #include <llvm/Bitcode/BitcodeReader.h>
      87                 :            : #include <llvm/Linker/Linker.h>
      88                 :            : 
      89                 :            : using namespace llvm;
      90                 :            : 
      91                 :            : //Drag some useful type functions into our namespace
      92                 :            : //to reduce verbosity of our code
      93                 :   22915600 : auto getInt1Ty(LLVMContext &ctxt) {
      94                 :   22915600 :     return Type::getInt1Ty(ctxt);
      95                 :            : }
      96                 :   26594700 : auto getInt8Ty(LLVMContext &ctxt) {
      97                 :   26594700 :     return Type::getInt8Ty(ctxt);
      98                 :            : }
      99                 :    1531270 : auto getInt16Ty(LLVMContext &ctxt) {
     100                 :    1531270 :     return Type::getInt16Ty(ctxt);
     101                 :            : }
     102                 :    2814980 : auto getInt32Ty(LLVMContext &ctxt) {
     103                 :    2814980 :     return Type::getInt32Ty(ctxt);
     104                 :            : }
     105                 :   32950300 : auto getInt64Ty(LLVMContext &ctxt) {
     106                 :   32950300 :     return Type::getInt64Ty(ctxt);
     107                 :            : }
     108                 :     110938 : auto getHalfTy(LLVMContext &ctxt) {
     109                 :     110938 :     return Type::getHalfTy(ctxt);
     110                 :            : }
     111                 :     984684 : auto getFloatTy(LLVMContext &ctxt) {
     112                 :     984684 :     return Type::getFloatTy(ctxt);
     113                 :            : }
     114                 :    2368450 : auto getDoubleTy(LLVMContext &ctxt) {
     115                 :    2368450 :     return Type::getDoubleTy(ctxt);
     116                 :            : }
     117                 :          0 : auto getFP128Ty(LLVMContext &ctxt) {
     118                 :          0 :     return Type::getFP128Ty(ctxt);
     119                 :            : }
     120                 :  120302000 : auto getVoidTy(LLVMContext &ctxt) {
     121                 :  120302000 :     return Type::getVoidTy(ctxt);
     122                 :            : }
     123                 :       1457 : auto getCharTy(LLVMContext &ctxt) {
     124                 :       1457 :     return getInt32Ty(ctxt);
     125                 :            : }
     126                 :    1676180 : auto getInt8PtrTy(LLVMContext &ctxt) {
     127                 :    1676180 :     return Type::getInt8PtrTy(ctxt);
     128                 :            : }
     129                 :        706 : auto getInt16PtrTy(LLVMContext &ctxt) {
     130                 :        706 :     return Type::getInt16PtrTy(ctxt);
     131                 :            : }
     132                 :       5918 : auto getInt32PtrTy(LLVMContext &ctxt) {
     133                 :       5918 :     return Type::getInt32PtrTy(ctxt);
     134                 :            : }
     135                 :     515124 : auto getInt64PtrTy(LLVMContext &ctxt) {
     136                 :     515124 :     return Type::getInt64PtrTy(ctxt);
     137                 :            : }
     138                 :          0 : auto getFloatPtrTy(LLVMContext &ctxt) {
     139                 :          0 :     return Type::getFloatPtrTy(ctxt);
     140                 :            : }
     141                 :          0 : auto getDoublePtrTy(LLVMContext &ctxt) {
     142                 :          0 :     return Type::getDoublePtrTy(ctxt);
     143                 :            : }
     144                 :     513857 : auto getSizePtrTy(LLVMContext &ctxt) {
     145                 :            :     if (sizeof(size_t) > sizeof(uint32_t)) {
     146                 :     513857 :         return getInt64PtrTy(ctxt);
     147                 :            :     } else {
     148                 :            :         return getInt32PtrTy(ctxt);
     149                 :            :     }
     150                 :            : }
     151                 :            : 
     152                 :            : typedef Instruction TerminatorInst;
     153                 :            : 
     154                 :            : #if defined(_OS_WINDOWS_) && !defined(NOMINMAX)
     155                 :            : #define NOMINMAX
     156                 :            : #endif
     157                 :            : 
     158                 :            : #include "julia.h"
     159                 :            : #include "julia_internal.h"
     160                 :            : #include "jitlayers.h"
     161                 :            : #include "codegen_shared.h"
     162                 :            : #include "processor.h"
     163                 :            : #include "julia_assert.h"
     164                 :            : 
     165                 :            : #undef DEBUG_TYPE //LLVM occasionally likes to set DEBUG_TYPE in a header...
     166                 :            : #define DEBUG_TYPE "julia_irgen_codegen"
     167                 :            : 
     168                 :            : STATISTIC(EmittedAllocas, "Number of allocas emitted");
     169                 :            : STATISTIC(EmittedIntToPtrs, "Number of inttoptrs emitted");
     170                 :            : STATISTIC(ModulesCreated, "Number of LLVM Modules created");
     171                 :            : STATISTIC(EmittedBoxCompares, "Number of box compares emitted");
     172                 :            : STATISTIC(EmittedBitsUnionCompares, "Number of bitsunion compares emitted");
     173                 :            : STATISTIC(EmittedBitsCompares, "Number of bits compares emitted");
     174                 :            : STATISTIC(EmittedEgals, "Number of egals emitted");
     175                 :            : STATISTIC(EmittedOpfields, "Number of opfields emitted");
     176                 :            : STATISTIC(EmittedBuiltinCalls, "Number of builtin calls emitted");
     177                 :            : STATISTIC(EmittedJLCalls, "Number of jlcalls emitted");
     178                 :            : STATISTIC(EmittedSpecfunCalls, "Number of specialized calls emitted");
     179                 :            : STATISTIC(EmittedInvokes, "Number of invokes emitted");
     180                 :            : STATISTIC(EmittedCalls, "Number of calls emitted");
     181                 :            : STATISTIC(EmittedUndefVarErrors, "Number of undef var errors emitted");
     182                 :            : STATISTIC(EmittedOpaqueClosureFunctions, "Number of opaque closures emitted");
     183                 :            : STATISTIC(EmittedToJLInvokes, "Number of tojlinvoke calls emitted");
     184                 :            : STATISTIC(EmittedCFuncInvalidates, "Number of C function invalidates emitted");
     185                 :            : STATISTIC(GeneratedCFuncWrappers, "Number of C function wrappers generated");
     186                 :            : STATISTIC(GeneratedCCallables, "Number of C-callable functions generated");
     187                 :            : STATISTIC(GeneratedInvokeWrappers, "Number of invoke wrappers generated");
     188                 :            : STATISTIC(EmittedFunctions, "Number of functions emitted");
     189                 :            : 
     190                 :            : extern "C" JL_DLLEXPORT
     191                 :          2 : void jl_dump_emitted_mi_name_impl(void *s)
     192                 :            : {
     193                 :          2 :     **jl_ExecutionEngine->get_dump_emitted_mi_name_stream() = (JL_STREAM*)s;
     194                 :          2 : }
     195                 :            : 
     196                 :            : extern "C" {
     197                 :            : 
     198                 :            : #include "builtin_proto.h"
     199                 :            : 
     200                 :            : extern void __stack_chk_fail();
     201                 :            : 
     202                 :            : #ifdef _OS_WINDOWS_
     203                 :            : #if defined(_CPU_X86_64_)
     204                 :            : #if defined(_COMPILER_GCC_)
     205                 :            : extern void ___chkstk_ms(void);
     206                 :            : #else
     207                 :            : extern void __chkstk(void);
     208                 :            : #endif
     209                 :            : #else
     210                 :            : #if defined(_COMPILER_GCC_)
     211                 :            : #undef _alloca
     212                 :            : extern void _alloca(void);
     213                 :            : #else
     214                 :            : extern void _chkstk(void);
     215                 :            : #endif
     216                 :            : #endif
     217                 :            : //void *force_chkstk(void) {
     218                 :            : //    return alloca(40960);
     219                 :            : //}
     220                 :            : #endif
     221                 :            : }
     222                 :            : 
     223                 :            : // shared llvm state
     224                 :            : #define jl_Module ctx.f->getParent()
     225                 :            : #define jl_builderModule(builder) (builder).GetInsertBlock()->getParent()->getParent()
     226                 :            : #define prepare_call(Callee) prepare_call_in(jl_Module, (Callee))
     227                 :            : 
     228                 :            : // types
     229                 :            : struct jl_typecache_t {
     230                 :            :     Type *T_jlvalue;
     231                 :            :     Type *T_pjlvalue;
     232                 :            :     Type *T_prjlvalue;
     233                 :            :     Type *T_ppjlvalue;
     234                 :            :     Type *T_pprjlvalue;
     235                 :            :     StructType *T_jlarray;
     236                 :            :     Type *T_pjlarray;
     237                 :            :     FunctionType *T_jlfunc;
     238                 :            :     FunctionType *T_jlfuncparams;
     239                 :            : 
     240                 :            :     IntegerType *T_sigatomic;
     241                 :            : 
     242                 :            :     Type *T_ppint8;
     243                 :            : 
     244                 :            :     bool initialized;
     245                 :            : 
     246                 :     709252 :     jl_typecache_t() :
     247                 :            :         T_jlvalue(nullptr), T_pjlvalue(nullptr), T_prjlvalue(nullptr),
     248                 :            :         T_ppjlvalue(nullptr), T_pprjlvalue(nullptr), T_jlarray(nullptr),
     249                 :            :         T_pjlarray(nullptr), T_jlfunc(nullptr), T_jlfuncparams(nullptr),
     250                 :     709252 :         T_sigatomic(nullptr), T_ppint8(nullptr), initialized(false) {}
     251                 :            : 
     252                 :  118411000 :     void initialize(LLVMContext &context) {
     253         [ +  + ]:  118411000 :         if (initialized) {
     254                 :  117702000 :             return;
     255                 :            :         }
     256                 :     708542 :         initialized = true;
     257                 :     708542 :         T_ppint8 = PointerType::get(getInt8PtrTy(context), 0);
     258                 :     708542 :         T_sigatomic = Type::getIntNTy(context, sizeof(sig_atomic_t) * 8);
     259                 :     708542 :         T_jlvalue = JuliaType::get_jlvalue_ty(context);
     260                 :     708542 :         T_pjlvalue = PointerType::get(T_jlvalue, 0);
     261                 :     708542 :         T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked);
     262                 :     708542 :         T_ppjlvalue = PointerType::get(T_pjlvalue, 0);
     263                 :     708542 :         T_pprjlvalue = PointerType::get(T_prjlvalue, 0);
     264                 :            : 
     265                 :     708542 :         T_jlfunc = JuliaType::get_jlfunc_ty(context);
     266         [ -  + ]:     708542 :         assert(T_jlfunc != NULL);
     267                 :     708542 :         T_jlfuncparams = JuliaType::get_jlfuncparams_ty(context);
     268         [ -  + ]:     708542 :         assert(T_jlfuncparams != NULL);
     269                 :            : 
     270                 :     708542 :         Type *vaelts[] = {PointerType::get(getInt8Ty(context), AddressSpace::Loaded)
     271                 :     708542 :                         , getSizeTy(context)
     272                 :     708542 :                         , getInt16Ty(context)
     273                 :     708542 :                         , getInt16Ty(context)
     274                 :     708542 :                         , getInt32Ty(context)
     275                 :     708542 :         };
     276                 :            :         static_assert(sizeof(jl_array_flags_t) == sizeof(int16_t),
     277                 :            :                     "Size of jl_array_flags_t is not the same as int16_t");
     278                 :     708542 :         T_jlarray = StructType::get(context, makeArrayRef(vaelts));
     279                 :     708542 :         T_pjlarray = PointerType::get(T_jlarray, 0);
     280                 :            :     }
     281                 :            : };
     282                 :            : 
     283                 :            : struct jl_tbaacache_t {
     284                 :            :     // type-based alias analysis nodes.  Indentation of comments indicates hierarchy.
     285                 :            :     MDNode *tbaa_root;     // Everything
     286                 :            :     MDNode *tbaa_gcframe;    // GC frame
     287                 :            :     // LLVM should have enough info for alias analysis of non-gcframe stack slot
     288                 :            :     // this is mainly a place holder for `jl_cgval_t::tbaa`
     289                 :            :     MDNode *tbaa_stack;      // stack slot
     290                 :            :     MDNode *tbaa_unionselbyte;   // a selector byte in isbits Union struct fields
     291                 :            :     MDNode *tbaa_data;       // Any user data that `pointerset/ref` are allowed to alias
     292                 :            :     MDNode *tbaa_binding;        // jl_binding_t::value
     293                 :            :     MDNode *tbaa_value;          // jl_value_t, that is not jl_array_t
     294                 :            :     MDNode *tbaa_mutab;              // mutable type
     295                 :            :     MDNode *tbaa_datatype;               // datatype
     296                 :            :     MDNode *tbaa_immut;              // immutable type
     297                 :            :     MDNode *tbaa_ptrarraybuf;    // Data in an array of boxed values
     298                 :            :     MDNode *tbaa_arraybuf;       // Data in an array of POD
     299                 :            :     MDNode *tbaa_array;      // jl_array_t
     300                 :            :     MDNode *tbaa_arrayptr;       // The pointer inside a jl_array_t
     301                 :            :     MDNode *tbaa_arraysize;      // A size in a jl_array_t
     302                 :            :     MDNode *tbaa_arraylen;       // The len in a jl_array_t
     303                 :            :     MDNode *tbaa_arrayflags;     // The flags in a jl_array_t
     304                 :            :     MDNode *tbaa_arrayoffset;     // The offset in a jl_array_t
     305                 :            :     MDNode *tbaa_arrayselbyte;   // a selector byte in a isbits Union jl_array_t
     306                 :            :     MDNode *tbaa_const;      // Memory that is immutable by the time LLVM can see it
     307                 :            :     bool initialized;
     308                 :            : 
     309                 :     709252 :     jl_tbaacache_t(): tbaa_root(nullptr), tbaa_gcframe(nullptr), tbaa_stack(nullptr),
     310                 :            :                     tbaa_unionselbyte(nullptr), tbaa_data(nullptr), tbaa_binding(nullptr),
     311                 :            :                     tbaa_value(nullptr), tbaa_mutab(nullptr), tbaa_datatype(nullptr),
     312                 :            :                     tbaa_immut(nullptr), tbaa_ptrarraybuf(nullptr), tbaa_arraybuf(nullptr),
     313                 :            :                     tbaa_array(nullptr), tbaa_arrayptr(nullptr), tbaa_arraysize(nullptr),
     314                 :            :                     tbaa_arraylen(nullptr), tbaa_arrayflags(nullptr), tbaa_arrayoffset(nullptr),
     315                 :     709252 :                     tbaa_arrayselbyte(nullptr), tbaa_const(nullptr), initialized(false) {}
     316                 :            : 
     317                 :   13320400 :     auto tbaa_make_child(MDBuilder &mbuilder, const char *name, MDNode *parent = nullptr, bool isConstant = false) {
     318         [ +  + ]:   13320400 :         MDNode *scalar = mbuilder.createTBAAScalarTypeNode(name, parent ? parent : tbaa_root);
     319                 :   13320400 :         MDNode *n = mbuilder.createTBAAStructTagNode(scalar, scalar, 0, isConstant);
     320                 :   13320400 :         return std::make_pair(n, scalar);
     321                 :            :     }
     322                 :            : 
     323                 :   55542600 :     void initialize(llvm::LLVMContext &context) {
     324         [ +  + ]:   55542600 :         if (initialized) {
     325         [ -  + ]:   54841600 :             assert(&tbaa_root->getContext() == &context);
     326                 :   54841600 :             return;
     327                 :            :         }
     328                 :     701072 :         initialized = true;
     329                 :     701072 :         MDBuilder mbuilder(context);
     330                 :     701072 :         MDNode *jtbaa = mbuilder.createTBAARoot("jtbaa");
     331                 :     701072 :         tbaa_root = mbuilder.createTBAAScalarTypeNode("jtbaa", jtbaa);
     332                 :     701072 :         tbaa_gcframe = tbaa_make_child(mbuilder, "jtbaa_gcframe").first;
     333                 :            :         MDNode *tbaa_stack_scalar;
     334                 :     701072 :         std::tie(tbaa_stack, tbaa_stack_scalar) = tbaa_make_child(mbuilder, "jtbaa_stack");
     335                 :     701072 :         tbaa_unionselbyte = tbaa_make_child(mbuilder, "jtbaa_unionselbyte", tbaa_stack_scalar).first;
     336                 :            :         MDNode *tbaa_data_scalar;
     337                 :     701072 :         std::tie(tbaa_data, tbaa_data_scalar) = tbaa_make_child(mbuilder, "jtbaa_data");
     338                 :     701072 :         tbaa_binding = tbaa_make_child(mbuilder, "jtbaa_binding", tbaa_data_scalar).first;
     339                 :            :         MDNode *tbaa_value_scalar;
     340                 :     701072 :         std::tie(tbaa_value, tbaa_value_scalar) =
     341                 :    1402140 :             tbaa_make_child(mbuilder, "jtbaa_value", tbaa_data_scalar);
     342                 :            :         MDNode *tbaa_mutab_scalar;
     343                 :     701072 :         std::tie(tbaa_mutab, tbaa_mutab_scalar) =
     344                 :    1402140 :             tbaa_make_child(mbuilder, "jtbaa_mutab", tbaa_value_scalar);
     345                 :     701072 :         tbaa_datatype = tbaa_make_child(mbuilder, "jtbaa_datatype", tbaa_mutab_scalar).first;
     346                 :     701072 :         tbaa_immut = tbaa_make_child(mbuilder, "jtbaa_immut", tbaa_value_scalar).first;
     347                 :     701072 :         tbaa_arraybuf = tbaa_make_child(mbuilder, "jtbaa_arraybuf", tbaa_data_scalar).first;
     348                 :     701072 :         tbaa_ptrarraybuf = tbaa_make_child(mbuilder, "jtbaa_ptrarraybuf", tbaa_data_scalar).first;
     349                 :            :         MDNode *tbaa_array_scalar;
     350                 :     701072 :         std::tie(tbaa_array, tbaa_array_scalar) = tbaa_make_child(mbuilder, "jtbaa_array");
     351                 :     701072 :         tbaa_arrayptr = tbaa_make_child(mbuilder, "jtbaa_arrayptr", tbaa_array_scalar).first;
     352                 :     701072 :         tbaa_arraysize = tbaa_make_child(mbuilder, "jtbaa_arraysize", tbaa_array_scalar).first;
     353                 :     701072 :         tbaa_arraylen = tbaa_make_child(mbuilder, "jtbaa_arraylen", tbaa_array_scalar).first;
     354                 :     701072 :         tbaa_arrayflags = tbaa_make_child(mbuilder, "jtbaa_arrayflags", tbaa_array_scalar).first;
     355                 :     701072 :         tbaa_arrayoffset = tbaa_make_child(mbuilder, "jtbaa_arrayoffset", tbaa_array_scalar).first;
     356                 :     701072 :         tbaa_const = tbaa_make_child(mbuilder, "jtbaa_const", nullptr, true).first;
     357                 :     701072 :         tbaa_arrayselbyte = tbaa_make_child(mbuilder, "jtbaa_arrayselbyte", tbaa_array_scalar).first;
     358                 :            :     }
     359                 :            : };
     360                 :            : 
     361                 :            : struct jl_debugcache_t {
     362                 :            :     // Basic DITypes
     363                 :            :     DIDerivedType *jl_pvalue_dillvmt;
     364                 :            :     DIDerivedType *jl_ppvalue_dillvmt;
     365                 :            :     DISubroutineType *jl_di_func_sig;
     366                 :            :     DISubroutineType *jl_di_func_null_sig;
     367                 :            :     bool initialized;
     368                 :            : 
     369                 :     364674 :     jl_debugcache_t()
     370                 :     364674 :     : jl_pvalue_dillvmt(nullptr), jl_ppvalue_dillvmt(nullptr),
     371                 :     364674 :     jl_di_func_sig(nullptr), jl_di_func_null_sig(nullptr), initialized(false) {}
     372                 :            : 
     373                 :            :     void initialize(Module *m);
     374                 :            : };
     375                 :            : 
     376                 :            : 
     377                 :            : // constants
     378                 :   77861200 : static bool type_is_ghost(Type *ty)
     379                 :            : {
     380   [ +  +  -  + ]:   77861200 :     return (ty == getVoidTy(ty->getContext()) || ty->isEmptyTy());
     381                 :            : }
     382                 :            : 
     383                 :            : // should agree with `Core.Compiler.hasuniquerep`
     384                 :     636185 : static bool type_has_unique_rep(jl_value_t *t)
     385                 :            : {
     386         [ -  + ]:     636185 :     if (t == (jl_value_t*)jl_typeofbottom_type)
     387                 :          0 :         return false;
     388         [ +  + ]:     636185 :     if (t == jl_bottom_type)
     389                 :         51 :         return true;
     390         [ +  + ]:     636134 :     if (jl_is_typevar(t))
     391                 :          3 :         return false;
     392         [ +  + ]:     636131 :     if (!jl_is_kind(jl_typeof(t)))
     393                 :      13006 :         return true;
     394         [ +  + ]:     623125 :     if (jl_is_concrete_type(t))
     395                 :     536524 :         return true;
     396         [ +  + ]:      86601 :     if (jl_is_datatype(t)) {
     397                 :      19248 :         jl_datatype_t *dt = (jl_datatype_t*)t;
     398         [ +  + ]:      19248 :         if (dt->name != jl_tuple_typename) {
     399         [ +  + ]:      43543 :             for (size_t i = 0; i < jl_nparams(dt); i++)
     400         [ +  + ]:      26565 :                 if (!type_has_unique_rep(jl_tparam(dt, i)))
     401                 :        117 :                     return false;
     402                 :      16978 :             return true;
     403                 :            :         }
     404                 :            :     }
     405                 :      69506 :     return false;
     406                 :            : }
     407                 :            : 
     408                 :   12305800 : static bool is_uniquerep_Type(jl_value_t *t)
     409                 :            : {
     410   [ +  +  +  + ]:   12305800 :     return jl_is_type_type(t) && type_has_unique_rep(jl_tparam0(t));
     411                 :            : }
     412                 :            : 
     413                 :            : class jl_codectx_t;
     414                 :            : struct JuliaVariable {
     415                 :            : public:
     416                 :            :     StringLiteral name;
     417                 :            :     bool isconst;
     418                 :            :     Type *(*_type)(LLVMContext &C);
     419                 :            : 
     420                 :            :     JuliaVariable(const JuliaVariable&) = delete;
     421                 :            :     JuliaVariable(const JuliaVariable&&) = delete;
     422                 :     930116 :     GlobalVariable *realize(Module *m) {
     423         [ +  + ]:     930116 :         if (GlobalValue *V = m->getNamedValue(name))
     424                 :     908373 :             return cast<GlobalVariable>(V);
     425                 :      21743 :         return new GlobalVariable(*m, _type(m->getContext()),
     426                 :      21743 :                 isconst, GlobalVariable::ExternalLinkage,
     427                 :      21743 :                 NULL, name);
     428                 :            :     }
     429                 :            :     GlobalVariable *realize(jl_codectx_t &ctx);
     430                 :            : };
     431                 :       1701 : static inline void add_named_global(JuliaVariable *name, void *addr)
     432                 :            : {
     433                 :       1701 :     add_named_global(name->name, addr);
     434                 :       1701 : }
     435                 :            : 
     436                 :            : struct JuliaFunction {
     437                 :            : public:
     438                 :            :     llvm::StringLiteral name;
     439                 :            :     llvm::FunctionType *(*_type)(llvm::LLVMContext &C);
     440                 :            :     llvm::AttributeList (*_attrs)(llvm::LLVMContext &C);
     441                 :            : 
     442                 :            :     JuliaFunction(const JuliaFunction&) = delete;
     443                 :            :     JuliaFunction(const JuliaFunction&&) = delete;
     444                 :    4743200 :     llvm::Function *realize(llvm::Module *m) {
     445         [ +  + ]:    4743200 :         if (llvm::GlobalValue *V = m->getNamedValue(name))
     446                 :    3235070 :             return llvm::cast<llvm::Function>(V);
     447                 :    1508130 :         llvm::Function *F = llvm::Function::Create(_type(m->getContext()),
     448                 :            :                          llvm::Function::ExternalLinkage,
     449                 :            :                          name, m);
     450         [ +  + ]:    1508130 :         if (_attrs)
     451                 :    1059000 :             F->setAttributes(_attrs(m->getContext()));
     452                 :    1508130 :         return F;
     453                 :            :     }
     454                 :            : };
     455                 :            : 
     456                 :            : template<typename T>
     457                 :      50463 : static inline void add_named_global(JuliaFunction *name, T *addr)
     458                 :            : {
     459                 :            :     // cast through integer to avoid c++ pedantic warning about casting between
     460                 :            :     // data and code pointers
     461                 :      50463 :     add_named_global(name->name, (void*)(uintptr_t)addr);
     462                 :      50463 : }
     463                 :            : template<typename T>
     464                 :       7371 : static inline void add_named_global(StringRef name, T *addr)
     465                 :            : {
     466                 :            :     // cast through integer to avoid c++ pedantic warning about casting between
     467                 :            :     // data and code pointers
     468                 :       7371 :     add_named_global(name, (void*)(uintptr_t)addr);
     469                 :       7371 : }
     470                 :            : 
     471                 :    2109000 : AttributeSet Attributes(LLVMContext &C, std::initializer_list<Attribute::AttrKind> attrkinds)
     472                 :            : {
     473                 :    4217990 :     SmallVector<Attribute, 8> attrs(attrkinds.size());
     474         [ +  + ]:    6233400 :     for (size_t i = 0; i < attrkinds.size(); i++)
     475                 :    4124400 :         attrs[i] = Attribute::get(C, attrkinds.begin()[i]);
     476                 :    2109000 :     return AttributeSet::get(C, makeArrayRef(attrs));
     477                 :            : }
     478                 :            : 
     479                 :      18745 : static Type *get_pjlvalue(LLVMContext &C) { return JuliaType::get_pjlvalue_ty(C); }
     480                 :            : 
     481                 :     653495 : static FunctionType *get_func_sig(LLVMContext &C) { return JuliaType::get_jlfunc_ty(C); }
     482                 :       3596 : static FunctionType *get_func2_sig(LLVMContext &C) { return JuliaType::get_jlfunc2_ty(C); }
     483                 :            : 
     484                 :          1 : static FunctionType *get_donotdelete_sig(LLVMContext &C) {
     485                 :          1 :     return FunctionType::get(getVoidTy(C), true);
     486                 :            : }
     487                 :            : 
     488                 :     542947 : static AttributeList get_func_attrs(LLVMContext &C)
     489                 :            : {
     490                 :            :     return AttributeList::get(C,
     491                 :            :             AttributeSet(),
     492                 :            :             Attributes(C, {Attribute::NonNull}),
     493                 :            :             {AttributeSet(),
     494                 :     542947 :              Attributes(C, {Attribute::NoAlias, Attribute::ReadOnly, Attribute::NoCapture, Attribute::NoUndef})});
     495                 :            : }
     496                 :            : 
     497                 :          1 : static AttributeList get_donotdelete_func_attrs(LLVMContext &C)
     498                 :            : {
     499                 :          1 :     AttributeSet FnAttrs = Attributes(C, {Attribute::InaccessibleMemOnly, Attribute::WillReturn, Attribute::NoUnwind});
     500                 :            :     return AttributeList::get(C,
     501                 :            :             FnAttrs,
     502                 :            :             Attributes(C, {}),
     503                 :          1 :             None);
     504                 :            : }
     505                 :            : 
     506                 :     311076 : static AttributeList get_attrs_noreturn(LLVMContext &C)
     507                 :            : {
     508                 :            :     return AttributeList::get(C,
     509                 :            :                 Attributes(C, {Attribute::NoReturn}),
     510                 :            :                 AttributeSet(),
     511                 :     311076 :                 None);
     512                 :            : }
     513                 :            : 
     514                 :     138406 : static AttributeList get_attrs_basic(LLVMContext &C)
     515                 :            : {
     516                 :            :     return AttributeList::get(C,
     517                 :            :                 AttributeSet(),
     518                 :            :                 Attributes(C, {Attribute::NonNull}),
     519                 :     138406 :                 None);
     520                 :            : }
     521                 :            : 
     522                 :      65343 : static AttributeList get_attrs_sext(LLVMContext &C)
     523                 :            : {
     524                 :            :     return AttributeList::get(C,
     525                 :            :                 AttributeSet(),
     526                 :            :                 Attributes(C, {Attribute::NonNull}),
     527                 :      65343 :                 {Attributes(C, {Attribute::SExt})});
     528                 :            : }
     529                 :            : 
     530                 :       7483 : static AttributeList get_attrs_zext(LLVMContext &C)
     531                 :            : {
     532                 :            :     return AttributeList::get(C,
     533                 :            :                 AttributeSet(),
     534                 :            :                 Attributes(C, {Attribute::NonNull}),
     535                 :       7483 :                 {Attributes(C, {Attribute::ZExt})});
     536                 :            : }
     537                 :            : 
     538                 :            : 
     539                 :            : // global vars
     540                 :            : static const auto jlRTLD_DEFAULT_var = new JuliaVariable{
     541                 :            :     XSTR(jl_RTLD_DEFAULT_handle),
     542                 :            :     true,
     543                 :       1273 :     [](LLVMContext &C) { return static_cast<llvm::Type*>(getInt8PtrTy(C)); },
     544                 :            : };
     545                 :            : #ifdef _OS_WINDOWS_
     546                 :            : static const auto jlexe_var = new JuliaVariable{
     547                 :            :     XSTR(jl_exe_handle),
     548                 :            :     true,
     549                 :            :     [](LLVMContext &C) { return static_cast<llvm::Type*>(getInt8PtrTy(C)); },
     550                 :            : };
     551                 :            : static const auto jldll_var = new JuliaVariable{
     552                 :            :     XSTR(jl_libjulia_handle),
     553                 :            :     true,
     554                 :            :     [](LLVMContext &C) { return static_cast<llvm::Type*>(getInt8PtrTy(C)); },
     555                 :            : };
     556                 :            : static const auto jldlli_var = new JuliaVariable{
     557                 :            :     XSTR(jl_libjulia_internal_handle),
     558                 :            :     true,
     559                 :            :     [](LLVMContext &C) { return static_cast<llvm::Type*>(getInt8PtrTy(C)); },
     560                 :            : };
     561                 :            : #endif //_OS_WINDOWS_
     562                 :            : 
     563                 :            : static const auto jlstack_chk_guard_var = new JuliaVariable{
     564                 :            :     XSTR(__stack_chk_guard),
     565                 :            :     true,
     566                 :            :     get_pjlvalue,
     567                 :            : };
     568                 :            : 
     569                 :            : static const auto jlgetworld_global = new JuliaVariable{
     570                 :            :     XSTR(jl_world_counter),
     571                 :            :     false,
     572                 :       1725 :     [](LLVMContext &C) { return (Type*)getSizeTy(C); },
     573                 :            : };
     574                 :            : 
     575                 :            : static const auto jlboxed_int8_cache = new JuliaVariable{
     576                 :            :     XSTR(jl_boxed_int8_cache),
     577                 :            :     true,
     578                 :        690 :     [](LLVMContext &C) { return (Type*)ArrayType::get(get_pjlvalue(C), 256); },
     579                 :            : };
     580                 :            : 
     581                 :            : static const auto jlboxed_uint8_cache = new JuliaVariable{
     582                 :            :     XSTR(jl_boxed_uint8_cache),
     583                 :            :     true,
     584                 :       1513 :     [](LLVMContext &C) { return (Type*)ArrayType::get(get_pjlvalue(C), 256); },
     585                 :            : };
     586                 :            : 
     587                 :            : static const auto jlpgcstack_func = new JuliaFunction{
     588                 :            :     "julia.get_pgcstack",
     589                 :     364680 :     [](LLVMContext &C) { return FunctionType::get(PointerType::get(JuliaType::get_ppjlvalue_ty(C), 0), false); },
     590                 :            :     nullptr,
     591                 :            : };
     592                 :            : 
     593                 :            : 
     594                 :            : 
     595                 :            : // important functions
     596                 :            : // Symbols are not gc-tracked, but we'll treat them as callee rooted anyway,
     597                 :            : // because they may come from a gc-rooted location
     598                 :            : static const auto jlnew_func = new JuliaFunction{
     599                 :            :     XSTR(jl_new_structv),
     600                 :            :     get_func_sig,
     601                 :            :     get_func_attrs,
     602                 :            : };
     603                 :            : static const auto jlsplatnew_func = new JuliaFunction{
     604                 :            :     XSTR(jl_new_structt),
     605                 :          3 :     [](LLVMContext &C) {
     606                 :          3 :         auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
     607                 :          6 :         return FunctionType::get(T_prjlvalue,
     608                 :          3 :             {T_prjlvalue, T_prjlvalue}, false);
     609                 :            :     },
     610                 :            :     get_attrs_basic,
     611                 :            : };
     612                 :            : static const auto jlthrow_func = new JuliaFunction{
     613                 :            :     XSTR(jl_throw),
     614                 :     307242 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     615                 :     307242 :             {PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::CalleeRooted)}, false); },
     616                 :            :     get_attrs_noreturn,
     617                 :            : };
     618                 :            : static const auto jlerror_func = new JuliaFunction{
     619                 :            :     XSTR(jl_error),
     620                 :       8012 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     621                 :       8012 :             {getInt8PtrTy(C)}, false); },
     622                 :            :     get_attrs_noreturn,
     623                 :            : };
     624                 :            : static const auto jlatomicerror_func = new JuliaFunction{
     625                 :            :     XSTR(jl_atomic_error),
     626                 :         24 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     627                 :         24 :             {getInt8PtrTy(C)}, false); },
     628                 :            :     get_attrs_noreturn,
     629                 :            : };
     630                 :            : static const auto jltypeerror_func = new JuliaFunction{
     631                 :            :     XSTR(jl_type_error),
     632                 :      52292 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     633                 :      52292 :             {getInt8PtrTy(C), JuliaType::get_prjlvalue_ty(C), PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::CalleeRooted)}, false); },
     634                 :            :     get_attrs_noreturn,
     635                 :            : };
     636                 :            : static const auto jlundefvarerror_func = new JuliaFunction{
     637                 :            :     XSTR(jl_undefined_var_error),
     638                 :      20640 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     639                 :      20640 :             {PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::CalleeRooted)}, false); },
     640                 :            :     get_attrs_noreturn,
     641                 :            : };
     642                 :            : static const auto jlboundserrorv_func = new JuliaFunction{
     643                 :            :     XSTR(jl_bounds_error_ints),
     644                 :     200226 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     645                 :     200226 :             {PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::CalleeRooted), getSizePtrTy(C), getSizeTy(C)}, false); },
     646                 :            :     get_attrs_noreturn,
     647                 :            : };
     648                 :            : static const auto jlboundserror_func = new JuliaFunction{
     649                 :            :     XSTR(jl_bounds_error_int),
     650                 :       7546 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     651                 :       7546 :             {PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::CalleeRooted), getSizeTy(C)}, false); },
     652                 :            :     get_attrs_noreturn,
     653                 :            : };
     654                 :            : static const auto jlvboundserror_func = new JuliaFunction{
     655                 :            :     XSTR(jl_bounds_error_tuple_int),
     656                 :       6530 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     657                 :       6530 :             {JuliaType::get_pprjlvalue_ty(C), getSizeTy(C), getSizeTy(C)}, false); },
     658                 :            :     get_attrs_noreturn,
     659                 :            : };
     660                 :            : static const auto jluboundserror_func = new JuliaFunction{
     661                 :            :     XSTR(jl_bounds_error_unboxed_int),
     662                 :      19640 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     663                 :      19640 :             {PointerType::get(getInt8Ty(C), AddressSpace::Derived), JuliaType::get_pjlvalue_ty(C), getSizeTy(C)}, false); },
     664                 :            :     get_attrs_noreturn,
     665                 :            : };
     666                 :            : static const auto jlcheckassign_func = new JuliaFunction{
     667                 :            :     XSTR(jl_checked_assignment),
     668                 :        180 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     669                 :        180 :             {JuliaType::get_pjlvalue_ty(C), PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::CalleeRooted)}, false); },
     670                 :            :     nullptr,
     671                 :            : };
     672                 :            : static const auto jldeclareconst_func = new JuliaFunction{
     673                 :            :     XSTR(jl_declare_constant),
     674                 :         42 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     675                 :         42 :             {JuliaType::get_pjlvalue_ty(C)}, false); },
     676                 :            :     nullptr,
     677                 :            : };
     678                 :            : static const auto jlgetbindingorerror_func = new JuliaFunction{
     679                 :            :     XSTR(jl_get_binding_or_error),
     680                 :        782 :     [](LLVMContext &C) {
     681                 :        782 :         auto T_pjlvalue = JuliaType::get_pjlvalue_ty(C);
     682                 :       1564 :         return FunctionType::get(T_pjlvalue,
     683                 :        782 :                 {T_pjlvalue, T_pjlvalue}, false);
     684                 :            :     },
     685                 :            :     nullptr,
     686                 :            : };
     687                 :            : static const auto jlgetbindingwrorerror_func = new JuliaFunction{
     688                 :            :     XSTR(jl_get_binding_wr_or_error),
     689                 :         78 :     [](LLVMContext &C) {
     690                 :         78 :         auto T_pjlvalue = JuliaType::get_pjlvalue_ty(C);
     691                 :        156 :         return FunctionType::get(T_pjlvalue,
     692                 :         78 :                 {T_pjlvalue, T_pjlvalue}, false);
     693                 :            :     },
     694                 :            :     nullptr,
     695                 :            : };
     696                 :            : static const auto jlboundp_func = new JuliaFunction{
     697                 :            :     XSTR(jl_boundp),
     698                 :         15 :     [](LLVMContext &C) {
     699                 :         15 :         auto T_pjlvalue = JuliaType::get_pjlvalue_ty(C);
     700                 :         30 :         return FunctionType::get(getInt32Ty(C),
     701                 :         15 :                 {T_pjlvalue, T_pjlvalue}, false);
     702                 :            :     },
     703                 :            :     nullptr,
     704                 :            : };
     705                 :            : static const auto jltopeval_func = new JuliaFunction{
     706                 :            :     XSTR(jl_toplevel_eval),
     707                 :         85 :     [](LLVMContext &C) {
     708                 :         85 :         auto T_pjlvalue = JuliaType::get_pjlvalue_ty(C);
     709                 :        170 :         return FunctionType::get(T_pjlvalue,
     710                 :         85 :                 {T_pjlvalue, T_pjlvalue}, false);
     711                 :            :     },
     712                 :         85 :     [](LLVMContext &C) { return AttributeList::get(C,
     713                 :            :             AttributeSet(),
     714                 :            :             Attributes(C, {Attribute::NonNull}),
     715                 :         85 :             None); },
     716                 :            : };
     717                 :            : static const auto jlcopyast_func = new JuliaFunction{
     718                 :            :     XSTR(jl_copy_ast),
     719                 :       1780 :     [](LLVMContext &C) {
     720                 :       1780 :         auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
     721                 :       3560 :         return FunctionType::get(T_prjlvalue,
     722                 :       1780 :                 {T_prjlvalue}, false);
     723                 :            :     },
     724                 :       1780 :     [](LLVMContext &C) { return AttributeList::get(C,
     725                 :            :             AttributeSet(),
     726                 :            :             Attributes(C, {Attribute::NonNull}),
     727                 :       1780 :             None); },
     728                 :            : };
     729                 :            : //static const auto jlnsvec_func = new JuliaFunction{
     730                 :            : //    XSTR(jl_svec),
     731                 :            : //    [](LLVMContext &C) { return FunctionType::get(T_prjlvalue,
     732                 :            : //                {getSizeTy(C)}, true); },
     733                 :            : //    [](LLVMContext &C) { return AttributeList::get(C,
     734                 :            : //            AttributeSet(),
     735                 :            : //            Attributes(C, {Attribute::NonNull}),
     736                 :            : //            None); },
     737                 :            : //};
     738                 :            : static const auto jlapplygeneric_func = new JuliaFunction{
     739                 :            :     XSTR(jl_apply_generic),
     740                 :            :     get_func_sig,
     741                 :            :     get_func_attrs,
     742                 :            : };
     743                 :            : static const auto jlinvoke_func = new JuliaFunction{
     744                 :            :     XSTR(jl_invoke),
     745                 :            :     get_func2_sig,
     746                 :       1869 :     [](LLVMContext &C) { return AttributeList::get(C,
     747                 :            :             AttributeSet(),
     748                 :            :             Attributes(C, {Attribute::NonNull}),
     749                 :            :             {AttributeSet(),
     750                 :       1869 :              Attributes(C, {Attribute::ReadOnly, Attribute::NoCapture})}); },
     751                 :            : };
     752                 :            : static const auto jlmethod_func = new JuliaFunction{
     753                 :            :     XSTR(jl_method_def),
     754                 :         66 :     [](LLVMContext &C) {
     755                 :         66 :         auto T_jlvalue = JuliaType::get_jlvalue_ty(C);
     756                 :         66 :         auto T_pjlvalue = PointerType::get(T_jlvalue, 0);
     757                 :         66 :         auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked);
     758                 :        132 :         return FunctionType::get(T_prjlvalue,
     759                 :         66 :                 {T_prjlvalue, T_prjlvalue, T_prjlvalue, T_pjlvalue}, false);
     760                 :            :     },
     761                 :            :     nullptr,
     762                 :            : };
     763                 :            : static const auto jlgenericfunction_func = new JuliaFunction{
     764                 :            :     XSTR(jl_generic_function_def),
     765                 :          3 :     [](LLVMContext &C) {
     766                 :          3 :         auto T_jlvalue = JuliaType::get_jlvalue_ty(C);
     767                 :          3 :         auto T_pjlvalue = PointerType::get(T_jlvalue, 0);
     768                 :          3 :         auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked);
     769                 :          3 :         auto T_pprjlvalue = PointerType::get(T_prjlvalue, 0);
     770                 :          6 :         return FunctionType::get(T_prjlvalue,
     771                 :          3 :                 {T_pjlvalue, T_pjlvalue, T_pprjlvalue, T_pjlvalue, T_pjlvalue}, false);
     772                 :            :     },
     773                 :            :     nullptr,
     774                 :            : };
     775                 :            : static const auto jllockvalue_func = new JuliaFunction{
     776                 :            :     XSTR(jl_lock_value),
     777                 :          8 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     778                 :          8 :             {PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::CalleeRooted)}, false); },
     779                 :          4 :     [](LLVMContext &C) { return AttributeList::get(C,
     780                 :            :             AttributeSet(),
     781                 :            :             AttributeSet(),
     782                 :          4 :             {Attributes(C, {Attribute::NoCapture})}); },
     783                 :            : };
     784                 :            : static const auto jlunlockvalue_func = new JuliaFunction{
     785                 :            :     XSTR(jl_unlock_value),
     786                 :          8 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     787                 :          8 :             {PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::CalleeRooted)}, false); },
     788                 :          4 :     [](LLVMContext &C) { return AttributeList::get(C,
     789                 :            :             AttributeSet(),
     790                 :            :             AttributeSet(),
     791                 :          4 :             {Attributes(C, {Attribute::NoCapture})}); },
     792                 :            : };
     793                 :            : static const auto jlenter_func = new JuliaFunction{
     794                 :            :     XSTR(jl_enter_handler),
     795                 :          0 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     796                 :          0 :             {getInt8PtrTy(C)}, false); },
     797                 :            :     nullptr,
     798                 :            : };
     799                 :            : static const auto jl_current_exception_func = new JuliaFunction{
     800                 :            :     XSTR(jl_current_exception),
     801                 :       5589 :     [](LLVMContext &C) { return FunctionType::get(JuliaType::get_prjlvalue_ty(C), false); },
     802                 :            :     nullptr,
     803                 :            : };
     804                 :            : static const auto jlleave_func = new JuliaFunction{
     805                 :            :     XSTR(jl_pop_handler),
     806                 :      28626 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     807                 :      28626 :             {getInt32Ty(C)}, false); },
     808                 :            :     nullptr,
     809                 :            : };
     810                 :            : static const auto jl_restore_excstack_func = new JuliaFunction{
     811                 :            :     XSTR(jl_restore_excstack),
     812                 :      12108 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     813                 :      12108 :             {getSizeTy(C)}, false); },
     814                 :            :     nullptr,
     815                 :            : };
     816                 :            : static const auto jl_excstack_state_func = new JuliaFunction{
     817                 :            :     XSTR(jl_excstack_state),
     818                 :      14313 :     [](LLVMContext &C) { return FunctionType::get(getSizeTy(C), false); },
     819                 :            :     nullptr,
     820                 :            : };
     821                 :            : static const auto jlegalx_func = new JuliaFunction{
     822                 :            :     XSTR(jl_egal__unboxed),
     823                 :       3475 :     [](LLVMContext &C) {
     824                 :       3475 :         Type *T = PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::Derived);
     825                 :       3475 :         return FunctionType::get(getInt32Ty(C), {T, T, JuliaType::get_prjlvalue_ty(C)}, false); },
     826                 :       3475 :     [](LLVMContext &C) { return AttributeList::get(C,
     827                 :            :             Attributes(C, {Attribute::ReadOnly, Attribute::NoUnwind, Attribute::ArgMemOnly}),
     828                 :            :             AttributeSet(),
     829                 :       3475 :             None); },
     830                 :            : };
     831                 :            : static const auto jl_alloc_obj_func = new JuliaFunction{
     832                 :            :     "julia.gc_alloc_obj",
     833                 :     183374 :     [](LLVMContext &C) {
     834                 :     183374 :         auto T_jlvalue = JuliaType::get_jlvalue_ty(C);
     835                 :     183374 :         auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked);
     836                 :     183374 :         auto T_ppjlvalue = PointerType::get(PointerType::get(T_jlvalue, 0), 0);
     837                 :     366748 :         return FunctionType::get(T_prjlvalue,
     838                 :     366748 :                 {T_ppjlvalue, getSizeTy(C), T_prjlvalue}, false);
     839                 :            :     },
     840                 :     183374 :     [](LLVMContext &C) { return AttributeList::get(C,
     841                 :     183374 :             AttributeSet::get(C, makeArrayRef({Attribute::getWithAllocSizeArgs(C, 1, None)})), // returns %1 bytes
     842                 :            :             Attributes(C, {Attribute::NoAlias, Attribute::NonNull}),
     843                 :     366748 :             None); },
     844                 :            : };
     845                 :            : static const auto jl_newbits_func = new JuliaFunction{
     846                 :            :     XSTR(jl_new_bits),
     847                 :          2 :     [](LLVMContext &C) {
     848                 :          2 :         auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
     849                 :          4 :         return FunctionType::get(T_prjlvalue,
     850                 :          4 :                 {T_prjlvalue, getInt8PtrTy(C)}, false);
     851                 :            :     },
     852                 :          2 :     [](LLVMContext &C) { return AttributeList::get(C,
     853                 :            :             AttributeSet(),
     854                 :            :             Attributes(C, {Attribute::NonNull}),
     855                 :          2 :             None); },
     856                 :            : };
     857                 :            : // `julia.typeof` does read memory, but it is effectively readnone before we lower
     858                 :            : // the allocation function. This is OK as long as we lower `julia.typeof` no later than
     859                 :            : // `julia.gc_alloc_obj`.
     860                 :            : static const auto jl_typeof_func = new JuliaFunction{
     861                 :            :     "julia.typeof",
     862                 :      47387 :     [](LLVMContext &C) {
     863                 :      47387 :         auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
     864                 :      94774 :         return FunctionType::get(T_prjlvalue,
     865                 :      47387 :                 {T_prjlvalue}, false);
     866                 :            :     },
     867                 :      47387 :     [](LLVMContext &C) { return AttributeList::get(C,
     868                 :            :             Attributes(C, {Attribute::ReadNone, Attribute::NoUnwind, Attribute::NoRecurse}),
     869                 :            :             Attributes(C, {Attribute::NonNull}),
     870                 :      47387 :             None); },
     871                 :            : };
     872                 :            : static const auto jl_loopinfo_marker_func = new JuliaFunction{
     873                 :            :     "julia.loopinfo_marker",
     874                 :      15198 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C), false); },
     875                 :      15198 :     [](LLVMContext &C) { return AttributeList::get(C,
     876                 :            :             Attributes(C, {Attribute::ReadOnly, Attribute::NoRecurse, Attribute::InaccessibleMemOnly}),
     877                 :            :             AttributeSet(),
     878                 :      15198 :             None); },
     879                 :            : };
     880                 :            : static const auto jl_write_barrier_func = new JuliaFunction{
     881                 :            :     "julia.write_barrier",
     882                 :      66770 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     883                 :      66770 :             {JuliaType::get_prjlvalue_ty(C)}, true); },
     884                 :      33385 :     [](LLVMContext &C) { return AttributeList::get(C,
     885                 :            :             Attributes(C, {Attribute::NoUnwind, Attribute::NoRecurse, Attribute::InaccessibleMemOnly}),
     886                 :            :             AttributeSet(),
     887                 :      33385 :             {Attributes(C, {Attribute::ReadOnly})}); },
     888                 :            : };
     889                 :            : static const auto jl_write_barrier_binding_func = new JuliaFunction{
     890                 :            :     "julia.write_barrier_binding",
     891                 :       2426 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
     892                 :       2426 :             {JuliaType::get_prjlvalue_ty(C)}, true); },
     893                 :       1213 :     [](LLVMContext &C) { return AttributeList::get(C,
     894                 :            :             Attributes(C, {Attribute::NoUnwind, Attribute::NoRecurse, Attribute::InaccessibleMemOnly}),
     895                 :            :             AttributeSet(),
     896                 :       1213 :             {Attributes(C, {Attribute::ReadOnly})}); },
     897                 :            : };
     898                 :            : static const auto jlisa_func = new JuliaFunction{
     899                 :            :     XSTR(jl_isa),
     900                 :       1728 :     [](LLVMContext &C) {
     901                 :       1728 :         auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
     902                 :       3456 :         return FunctionType::get(getInt32Ty(C),
     903                 :       1728 :             {T_prjlvalue, T_prjlvalue}, false);
     904                 :            :     },
     905                 :            :     nullptr,
     906                 :            : };
     907                 :            : 
     908                 :            : static const auto jlsubtype_func = new JuliaFunction{
     909                 :            :     XSTR(jl_subtype),
     910                 :       3718 :     [](LLVMContext &C) {
     911                 :       3718 :         auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
     912                 :       7436 :         return FunctionType::get(getInt32Ty(C),
     913                 :       3718 :             {T_prjlvalue, T_prjlvalue}, false);
     914                 :            :     },
     915                 :            :     nullptr,
     916                 :            : };
     917                 :            : static const auto jlapplytype_func = new JuliaFunction{
     918                 :            :     XSTR(jl_instantiate_type_in_env),
     919                 :          1 :     [](LLVMContext &C) {
     920                 :          1 :         auto T_jlvalue = JuliaType::get_jlvalue_ty(C);
     921                 :          1 :         auto T_pjlvalue = PointerType::get(T_jlvalue, 0);
     922                 :          1 :         auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked);
     923                 :          1 :         auto T_pprjlvalue = PointerType::get(T_prjlvalue, 0);
     924                 :          2 :         return FunctionType::get(T_prjlvalue,
     925                 :          1 :             {T_pjlvalue, T_pjlvalue, T_pprjlvalue}, false);
     926                 :            :     },
     927                 :          1 :     [](LLVMContext &C) {
     928                 :            :         return AttributeList::get(C,
     929                 :            :             AttributeSet(),
     930                 :          1 :             AttributeSet::get(C, makeArrayRef({Attribute::get(C, Attribute::NonNull),
     931                 :          1 :                                                Attribute::getWithAlignment(C, Align(16))})),
     932                 :          2 :             None);
     933                 :            :     },
     934                 :            : };
     935                 :            : static const auto jl_object_id__func = new JuliaFunction{
     936                 :            :     XSTR(jl_object_id_),
     937                 :       7562 :     [](LLVMContext &C) { return FunctionType::get(getSizeTy(C),
     938                 :       7562 :             {JuliaType::get_prjlvalue_ty(C), PointerType::get(getInt8Ty(C), AddressSpace::Derived)}, false); },
     939                 :            :     nullptr,
     940                 :            : };
     941                 :            : static const auto setjmp_func = new JuliaFunction{
     942                 :            :     jl_setjmp_name,
     943                 :          0 :     [](LLVMContext &C) { return FunctionType::get(getInt32Ty(C),
     944                 :          0 :             {getInt8PtrTy(C),
     945                 :            : #ifndef _OS_WINDOWS_
     946                 :          0 :             getInt32Ty(C),
     947                 :            : #endif
     948                 :          0 :             }, false); },
     949                 :          0 :     [](LLVMContext &C) { return AttributeList::get(C,
     950                 :            :             Attributes(C, {Attribute::ReturnsTwice}),
     951                 :            :             AttributeSet(),
     952                 :          0 :             None); },
     953                 :            : };
     954                 :            : static const auto memcmp_func = new JuliaFunction{
     955                 :            :     XSTR(memcmp),
     956                 :          4 :     [](LLVMContext &C) { return FunctionType::get(getInt32Ty(C),
     957                 :          4 :             {getInt8PtrTy(C), getInt8PtrTy(C), getSizeTy(C)}, false); },
     958                 :          2 :     [](LLVMContext &C) { return AttributeList::get(C,
     959                 :            :             Attributes(C, {Attribute::ReadOnly, Attribute::NoUnwind, Attribute::ArgMemOnly}),
     960                 :            :             AttributeSet(),
     961                 :          2 :             None); },
     962                 :            :     // TODO: inferLibFuncAttributes(*memcmp_func, TLI);
     963                 :            : };
     964                 :            : static const auto jldlsym_func = new JuliaFunction{
     965                 :            :     XSTR(jl_load_and_lookup),
     966                 :       5082 :     [](LLVMContext &C) { return FunctionType::get(JuliaType::get_pvoidfunc_ty(C),
     967                 :       5082 :             {getInt8PtrTy(C), getInt8PtrTy(C), PointerType::get(getInt8PtrTy(C), 0)}, false); },
     968                 :            :     nullptr,
     969                 :            : };
     970                 :            : static const auto jllazydlsym_func = new JuliaFunction{
     971                 :            :     XSTR(jl_lazy_load_and_lookup),
     972                 :          0 :     [](LLVMContext &C) { return FunctionType::get(JuliaType::get_pvoidfunc_ty(C),
     973                 :          0 :             {JuliaType::get_prjlvalue_ty(C), getInt8PtrTy(C)}, false); },
     974                 :            :     nullptr,
     975                 :            : };
     976                 :            : static const auto jltypeassert_func = new JuliaFunction{
     977                 :            :     XSTR(jl_typeassert),
     978                 :        890 :     [](LLVMContext &C) {
     979                 :        890 :         auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
     980                 :       1780 :         return FunctionType::get(getVoidTy(C),
     981                 :        890 :             {T_prjlvalue, T_prjlvalue}, false);
     982                 :            :     },
     983                 :            :     nullptr,
     984                 :            : };
     985                 :            : static const auto jlgetnthfieldchecked_func = new JuliaFunction{
     986                 :            :     XSTR(jl_get_nth_field_checked),
     987                 :         75 :     [](LLVMContext &C) {
     988                 :         75 :         auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
     989                 :        150 :         return FunctionType::get(T_prjlvalue,
     990                 :        150 :             {T_prjlvalue, getSizeTy(C)}, false);
     991                 :            :     },
     992                 :         75 :     [](LLVMContext &C) { return AttributeList::get(C,
     993                 :            :             AttributeSet(),
     994                 :            :             Attributes(C, {Attribute::NonNull}),
     995                 :         75 :             None); },
     996                 :            : };
     997                 :            : static const auto jlgetcfunctiontrampoline_func = new JuliaFunction{
     998                 :            :     XSTR(jl_get_cfunction_trampoline),
     999                 :         15 :     [](LLVMContext &C) {
    1000                 :         15 :         auto T_jlvalue = JuliaType::get_jlvalue_ty(C);
    1001                 :         15 :         auto T_pjlvalue = PointerType::get(T_jlvalue, 0);
    1002                 :         15 :         auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked);
    1003                 :         15 :         auto T_ppjlvalue = PointerType::get(T_pjlvalue, 0);
    1004                 :         15 :         auto T_pprjlvalue = PointerType::get(T_prjlvalue, 0);
    1005                 :         15 :         return FunctionType::get(T_prjlvalue,
    1006                 :            :             {
    1007                 :            :                 T_prjlvalue, // f (object)
    1008                 :            :                 T_pjlvalue, // result
    1009                 :         15 :                 getInt8PtrTy(C), // cache
    1010                 :            :                 T_pjlvalue, // fill
    1011                 :         30 :                 FunctionType::get(getInt8PtrTy(C), { getInt8PtrTy(C), T_ppjlvalue }, false)->getPointerTo(), // trampoline
    1012                 :            :                 T_pjlvalue, // env
    1013                 :            :                 T_pprjlvalue, // vals
    1014                 :         15 :             }, false);
    1015                 :            :     },
    1016                 :         15 :     [](LLVMContext &C) { return AttributeList::get(C,
    1017                 :            :             AttributeSet(),
    1018                 :            :             Attributes(C, {Attribute::NonNull}),
    1019                 :         15 :             None); },
    1020                 :            : };
    1021                 :            : static const auto diff_gc_total_bytes_func = new JuliaFunction{
    1022                 :            :     XSTR(jl_gc_diff_total_bytes),
    1023                 :         37 :     [](LLVMContext &C) { return FunctionType::get(getInt64Ty(C), false); },
    1024                 :            :     nullptr,
    1025                 :            : };
    1026                 :            : static const auto sync_gc_total_bytes_func = new JuliaFunction{
    1027                 :            :     XSTR(jl_gc_sync_total_bytes),
    1028                 :         74 :     [](LLVMContext &C) { return FunctionType::get(getInt64Ty(C),
    1029                 :         74 :             {getInt64Ty(C)}, false); },
    1030                 :            :     nullptr,
    1031                 :            : };
    1032                 :            : static const auto jlarray_data_owner_func = new JuliaFunction{
    1033                 :            :     XSTR(jl_array_data_owner),
    1034                 :          2 :     [](LLVMContext &C) {
    1035                 :          2 :         auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
    1036                 :          4 :         return FunctionType::get(T_prjlvalue,
    1037                 :          2 :             {T_prjlvalue}, false);
    1038                 :            :     },
    1039                 :          2 :     [](LLVMContext &C) { return AttributeList::get(C,
    1040                 :            :             Attributes(C, {Attribute::ReadOnly, Attribute::NoUnwind}),
    1041                 :            :             Attributes(C, {Attribute::NonNull}),
    1042                 :          2 :             None); },
    1043                 :            : };
    1044                 :            : #define BOX_FUNC(ct,at,attrs)                                                    \
    1045                 :            : static const auto box_##ct##_func = new JuliaFunction{                           \
    1046                 :            :     XSTR(jl_box_##ct),                                                           \
    1047                 :            :     [](LLVMContext &C) { return FunctionType::get(JuliaType::get_prjlvalue_ty(C),\
    1048                 :            :             {at}, false); },                                                     \
    1049                 :            :     attrs,                                                                       \
    1050                 :            : }
    1051                 :        573 : BOX_FUNC(int16, getInt16Ty(C), get_attrs_sext);
    1052                 :       1100 : BOX_FUNC(uint16, getInt16Ty(C), get_attrs_zext);
    1053                 :       2959 : BOX_FUNC(int32, getInt32Ty(C), get_attrs_sext);
    1054                 :       1572 : BOX_FUNC(uint32, getInt32Ty(C), get_attrs_zext);
    1055                 :      61811 : BOX_FUNC(int64, getInt64Ty(C), get_attrs_sext);
    1056                 :       3354 : BOX_FUNC(uint64, getInt64Ty(C), get_attrs_zext);
    1057                 :       1457 : BOX_FUNC(char, getCharTy(C), get_attrs_zext);
    1058                 :       3504 : BOX_FUNC(float32, getFloatTy(C), get_attrs_basic);
    1059                 :          0 : BOX_FUNC(float64, getDoubleTy(C), get_attrs_basic);
    1060                 :        585 : BOX_FUNC(ssavalue, getSizeTy(C), get_attrs_basic);
    1061                 :            : #undef BOX_FUNC
    1062                 :            : 
    1063                 :            : 
    1064                 :            : // placeholder functions
    1065                 :            : static const auto gcroot_flush_func = new JuliaFunction{
    1066                 :            :     "julia.gcroot_flush",
    1067                 :       1840 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C), false); },
    1068                 :            :     nullptr,
    1069                 :            : };
    1070                 :            : static const auto gc_preserve_begin_func = new JuliaFunction{
    1071                 :            :     "llvm.julia.gc_preserve_begin",
    1072                 :      14294 :     [](LLVMContext &C) { return FunctionType::get(Type::getTokenTy(C), true); },
    1073                 :            :     nullptr,
    1074                 :            : };
    1075                 :            : static const auto gc_preserve_end_func = new JuliaFunction {
    1076                 :            :     "llvm.julia.gc_preserve_end",
    1077                 :      14034 :     [](LLVMContext &C) { return FunctionType::get(getVoidTy(C), {Type::getTokenTy(C)}, false); },
    1078                 :            :     nullptr,
    1079                 :            : };
    1080                 :            : static const auto except_enter_func = new JuliaFunction{
    1081                 :            :     "julia.except_enter",
    1082                 :      14313 :     [](LLVMContext &C) { return FunctionType::get(getInt32Ty(C), false); },
    1083                 :      14313 :     [](LLVMContext &C) { return AttributeList::get(C,
    1084                 :      14313 :             AttributeSet::get(C, makeArrayRef({Attribute::get(C, Attribute::ReturnsTwice)})),
    1085                 :            :             AttributeSet(),
    1086                 :      28626 :             None); },
    1087                 :            : };
    1088                 :            : static const auto pointer_from_objref_func = new JuliaFunction{
    1089                 :            :     "julia.pointer_from_objref",
    1090                 :     112482 :     [](LLVMContext &C) { return FunctionType::get(JuliaType::get_pjlvalue_ty(C),
    1091                 :     112482 :             {PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::Derived)}, false); },
    1092                 :      56241 :     [](LLVMContext &C) { return AttributeList::get(C,
    1093                 :      56241 :             AttributeSet::get(C, makeArrayRef({Attribute::get(C, Attribute::ReadNone), Attribute::get(C, Attribute::NoUnwind)})),
    1094                 :            :             Attributes(C, {Attribute::NonNull}),
    1095                 :     112482 :             None); },
    1096                 :            : };
    1097                 :            : 
    1098                 :            : // julia.call represents a call with julia calling convention, it is used as
    1099                 :            : //
    1100                 :            : //   ptr julia.call(ptr %fptr, ptr %f, ptr %arg1, ptr %arg2, ...)
    1101                 :            : //
    1102                 :            : // In late lowering the call will then be rewritten as
    1103                 :            : //
    1104                 :            : //   ptr %fptr(ptr %f, ptr args, i64 nargs)
    1105                 :            : //
    1106                 :            : // with all the spelled out args appropriately moved into the argument stack buffer.
    1107                 :            : // By representing it this way rather than allocating the stack buffer earlier, we
    1108                 :            : // allow LLVM to make more aggressive optimizations on the call arguments.
    1109                 :            : static const auto julia_call = new JuliaFunction{
    1110                 :            :     "julia.call",
    1111                 :     132587 :     [](LLVMContext &C) {
    1112                 :     132587 :         auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
    1113                 :     265174 :         return FunctionType::get(T_prjlvalue,
    1114                 :            : #ifdef JL_LLVM_OPAQUE_POINTERS
    1115                 :            :             {PointerType::get(C, 0),
    1116                 :            : #else
    1117                 :     132587 :             {get_func_sig(C)->getPointerTo(),
    1118                 :            : #endif
    1119                 :            :              T_prjlvalue}, // %f
    1120                 :     132587 :             true); }, // %args
    1121                 :            :     get_attrs_basic,
    1122                 :            : };
    1123                 :            : 
    1124                 :            : // julia.call2 is like julia.call, except that %arg1 gets passed as a register
    1125                 :            : // argument at the end of the argument list.
    1126                 :            : static const auto julia_call2 = new JuliaFunction{
    1127                 :            :     "julia.call2",
    1128                 :       1727 :     [](LLVMContext &C) {
    1129                 :       1727 :         auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
    1130                 :       3454 :         return FunctionType::get(T_prjlvalue,
    1131                 :            : #ifdef JL_LLVM_OPAQUE_POINTERS
    1132                 :            :             {PointerType::get(C, 0),
    1133                 :            : #else
    1134                 :       1727 :             {get_func2_sig(C)->getPointerTo(),
    1135                 :            : #endif
    1136                 :            :              T_prjlvalue, // %arg1
    1137                 :            :              T_prjlvalue}, // %f
    1138                 :       1727 :             true); }, // %args
    1139                 :            :     get_attrs_basic,
    1140                 :            : };
    1141                 :            : 
    1142                 :            : static const auto jltuple_func = new JuliaFunction{XSTR(jl_f_tuple), get_func_sig, get_func_attrs};
    1143                 :     316055 : static const auto &builtin_func_map() {
    1144                 :            :     static std::map<jl_fptr_args_t, JuliaFunction*> builtins = {
    1145                 :       1701 :           { jl_f_is_addr,                 new JuliaFunction{XSTR(jl_f_is), get_func_sig, get_func_attrs} },
    1146                 :        567 :           { jl_f_typeof_addr,             new JuliaFunction{XSTR(jl_f_typeof), get_func_sig, get_func_attrs} },
    1147                 :        567 :           { jl_f_sizeof_addr,             new JuliaFunction{XSTR(jl_f_sizeof), get_func_sig, get_func_attrs} },
    1148                 :        567 :           { jl_f_issubtype_addr,          new JuliaFunction{XSTR(jl_f_issubtype), get_func_sig, get_func_attrs} },
    1149                 :        567 :           { jl_f_isa_addr,                new JuliaFunction{XSTR(jl_f_isa), get_func_sig, get_func_attrs} },
    1150                 :        567 :           { jl_f_typeassert_addr,         new JuliaFunction{XSTR(jl_f_typeassert), get_func_sig, get_func_attrs} },
    1151                 :        567 :           { jl_f_ifelse_addr,             new JuliaFunction{XSTR(jl_f_ifelse), get_func_sig, get_func_attrs} },
    1152                 :        567 :           { jl_f__apply_iterate_addr,     new JuliaFunction{XSTR(jl_f__apply_iterate), get_func_sig, get_func_attrs} },
    1153                 :        567 :           { jl_f__apply_pure_addr,        new JuliaFunction{XSTR(jl_f__apply_pure), get_func_sig, get_func_attrs} },
    1154                 :        567 :           { jl_f__call_latest_addr,       new JuliaFunction{XSTR(jl_f__call_latest), get_func_sig, get_func_attrs} },
    1155                 :        567 :           { jl_f__call_in_world_addr,     new JuliaFunction{XSTR(jl_f__call_in_world), get_func_sig, get_func_attrs} },
    1156                 :        567 :           { jl_f__call_in_world_total_addr, new JuliaFunction{XSTR(jl_f__call_in_world_total), get_func_sig, get_func_attrs} },
    1157                 :        567 :           { jl_f_throw_addr,              new JuliaFunction{XSTR(jl_f_throw), get_func_sig, get_func_attrs} },
    1158                 :            :           { jl_f_tuple_addr,              jltuple_func },
    1159                 :        567 :           { jl_f_svec_addr,               new JuliaFunction{XSTR(jl_f_svec), get_func_sig, get_func_attrs} },
    1160                 :        567 :           { jl_f_applicable_addr,         new JuliaFunction{XSTR(jl_f_applicable), get_func_sig, get_func_attrs} },
    1161                 :        567 :           { jl_f_invoke_addr,             new JuliaFunction{XSTR(jl_f_invoke), get_func_sig, get_func_attrs} },
    1162                 :        567 :           { jl_f_invoke_kwsorter_addr,    new JuliaFunction{XSTR(jl_f_invoke_kwsorter), get_func_sig, get_func_attrs} },
    1163                 :        567 :           { jl_f_isdefined_addr,          new JuliaFunction{XSTR(jl_f_isdefined), get_func_sig, get_func_attrs} },
    1164                 :        567 :           { jl_f_getfield_addr,           new JuliaFunction{XSTR(jl_f_getfield), get_func_sig, get_func_attrs} },
    1165                 :        567 :           { jl_f_setfield_addr,           new JuliaFunction{XSTR(jl_f_setfield), get_func_sig, get_func_attrs} },
    1166                 :        567 :           { jl_f_swapfield_addr,          new JuliaFunction{XSTR(jl_f_swapfield), get_func_sig, get_func_attrs} },
    1167                 :        567 :           { jl_f_modifyfield_addr,        new JuliaFunction{XSTR(jl_f_modifyfield), get_func_sig, get_func_attrs} },
    1168                 :        567 :           { jl_f_fieldtype_addr,          new JuliaFunction{XSTR(jl_f_fieldtype), get_func_sig, get_func_attrs} },
    1169                 :        567 :           { jl_f_nfields_addr,            new JuliaFunction{XSTR(jl_f_nfields), get_func_sig, get_func_attrs} },
    1170                 :        567 :           { jl_f__expr_addr,              new JuliaFunction{XSTR(jl_f__expr), get_func_sig, get_func_attrs} },
    1171                 :        567 :           { jl_f__typevar_addr,           new JuliaFunction{XSTR(jl_f__typevar), get_func_sig, get_func_attrs} },
    1172                 :        567 :           { jl_f_arrayref_addr,           new JuliaFunction{XSTR(jl_f_arrayref), get_func_sig, get_func_attrs} },
    1173                 :        567 :           { jl_f_const_arrayref_addr,     new JuliaFunction{XSTR(jl_f_const_arrayref), get_func_sig, get_func_attrs} },
    1174                 :        567 :           { jl_f_arrayset_addr,           new JuliaFunction{XSTR(jl_f_arrayset), get_func_sig, get_func_attrs} },
    1175                 :        567 :           { jl_f_arraysize_addr,          new JuliaFunction{XSTR(jl_f_arraysize), get_func_sig, get_func_attrs} },
    1176                 :        567 :           { jl_f_apply_type_addr,         new JuliaFunction{XSTR(jl_f_apply_type), get_func_sig, get_func_attrs} },
    1177                 :        567 :           { jl_f_donotdelete_addr,        new JuliaFunction{XSTR(jl_f_donotdelete), get_donotdelete_sig, get_donotdelete_func_attrs} },
    1178                 :        567 :           { jl_f_finalizer_addr,          new JuliaFunction{XSTR(jl_f_finalizer), get_func_sig, get_func_attrs} }
    1179   [ +  +  +  - ]:     334199 :         };
    1180                 :     316055 :     return builtins;
    1181                 :            : }
    1182                 :            : 
    1183                 :            : static const auto jl_new_opaque_closure_jlcall_func = new JuliaFunction{XSTR(jl_new_opaque_closure_jlcall), get_func_sig, get_func_attrs};
    1184                 :            : 
    1185                 :            : static std::atomic<int> globalUniqueGeneratedNames{0};
    1186                 :            : 
    1187                 :            : // --- code generation ---
    1188                 :            : extern "C" {
    1189                 :            :     jl_cgparams_t jl_default_cgparams = {1, 1, 0,
    1190                 :            : #ifdef _OS_WINDOWS_
    1191                 :            :         0,
    1192                 :            : #else
    1193                 :            :         1,
    1194                 :            : #endif
    1195                 :            :         (int) DICompileUnit::DebugEmissionKind::FullDebug,
    1196                 :            :         jl_rettype_inferred, NULL };
    1197                 :            : }
    1198                 :            : 
    1199                 :            : 
    1200                 :   39303900 : static MDNode *best_tbaa(jl_tbaacache_t &tbaa_cache, jl_value_t *jt) {
    1201                 :   39303900 :     jt = jl_unwrap_unionall(jt);
    1202   [ +  +  +  +  :   81295100 :     if (jt == (jl_value_t*)jl_datatype_type ||
                   +  + ]
    1203         [ +  + ]:   41991100 :         (jl_is_type_type(jt) && jl_is_datatype(jl_tparam0(jt))))
    1204                 :    3128650 :         return tbaa_cache.tbaa_datatype;
    1205         [ +  + ]:   36175300 :     if (!jl_is_datatype(jt))
    1206                 :     152844 :         return tbaa_cache.tbaa_value;
    1207         [ +  + ]:   36022400 :     if (jl_is_abstracttype(jt))
    1208                 :    1110800 :         return tbaa_cache.tbaa_value;
    1209                 :            :     // If we're here, we know all subtypes are (im)mutable, even if we
    1210                 :            :     // don't know what the exact type is
    1211         [ +  + ]:   34911600 :     return jl_is_mutable(jt) ? tbaa_cache.tbaa_mutab : tbaa_cache.tbaa_immut;
    1212                 :            : }
    1213                 :            : 
    1214                 :            : // tracks whether codegen is currently able to simply stack-allocate this type
    1215                 :            : // note that this includes jl_isbits, although codegen should work regardless
    1216                 :   90314900 : static bool jl_is_concrete_immutable(jl_value_t* t)
    1217                 :            : {
    1218   [ +  +  +  +  :   90314900 :     return jl_is_immutable_datatype(t) && ((jl_datatype_t*)t)->isconcretetype;
                   +  + ]
    1219                 :            : }
    1220                 :            : 
    1221                 :    8720190 : static bool jl_is_pointerfree(jl_value_t* t)
    1222                 :            : {
    1223         [ +  + ]:    8720190 :     if (!jl_is_concrete_immutable(t))
    1224                 :     222867 :         return 0;
    1225                 :    8497330 :     const jl_datatype_layout_t *layout = ((jl_datatype_t*)t)->layout;
    1226   [ +  -  +  + ]:    8497330 :     return layout && layout->npointers == 0;
    1227                 :            : }
    1228                 :            : 
    1229                 :            : // these queries are usually related, but we split them out here
    1230                 :            : // for convenience and clarity (and because it changes the calling convention)
    1231                 :            : // n.b. this must include jl_is_datatype_singleton (ghostType) and primitive types
    1232                 :   22956300 : static bool deserves_stack(jl_value_t* t)
    1233                 :            : {
    1234         [ +  + ]:   22956300 :     if (!jl_is_concrete_immutable(t))
    1235                 :    5880680 :         return false;
    1236                 :   17075600 :     jl_datatype_t *dt = (jl_datatype_t*)t;
    1237   [ +  +  +  + ]:   17075600 :     return jl_is_datatype_singleton(dt) || jl_datatype_isinlinealloc(dt, 0);
    1238                 :            : }
    1239                 :   16734700 : static bool deserves_argbox(jl_value_t* t)
    1240                 :            : {
    1241                 :   16734700 :     return !deserves_stack(t);
    1242                 :            : }
    1243                 :    2957800 : static bool deserves_retbox(jl_value_t* t)
    1244                 :            : {
    1245                 :    2957800 :     return deserves_argbox(t);
    1246                 :            : }
    1247                 :     496501 : static bool deserves_sret(jl_value_t *dt, Type *T)
    1248                 :            : {
    1249         [ -  + ]:     496501 :     assert(jl_is_datatype(dt));
    1250   [ +  +  +  -  :     496501 :     return (size_t)jl_datatype_size(dt) > sizeof(void*) && !T->isFloatingPointTy() && !T->isVectorTy();
                   +  + ]
    1251                 :            : }
    1252                 :            : 
    1253                 :            : 
    1254                 :            : // metadata tracking for a llvm Value* during codegen
    1255                 :            : struct jl_cgval_t {
    1256                 :            :     Value *V; // may be of type T* or T, or set to NULL if ghost (or if the value has not been initialized yet, for a variable definition)
    1257                 :            :     // For unions, we may need to keep a reference to the boxed part individually.
    1258                 :            :     // If this is non-NULL, then, at runtime, we satisfy the invariant that (for the corresponding
    1259                 :            :     // runtime values) if `(TIndex | 0x80) != 0`, then `Vboxed == V` (by value).
    1260                 :            :     // For convenience, we also set this value of isboxed values, in which case
    1261                 :            :     // it is equal (at compile time) to V.
    1262                 :            :     // If this is non-NULL, it is always of type `T_prjlvalue`
    1263                 :            :     Value *Vboxed;
    1264                 :            :     Value *TIndex; // if `V` is an unboxed (tagged) Union described by `typ`, this gives the DataType index (1-based, small int) as an i8
    1265                 :            :     jl_value_t *constant; // constant value (rooted in linfo.def.roots)
    1266                 :            :     jl_value_t *typ; // the original type of V, never NULL
    1267                 :            :     bool isboxed; // whether this value is a jl_value_t* allocated on the heap with the right type tag
    1268                 :            :     bool isghost; // whether this value is "ghost"
    1269                 :            :     MDNode *tbaa; // The related tbaa node. Non-NULL iff this holds an address.
    1270                 :            :     // If non-null, this memory location may be promoted on use, by hoisting the
    1271                 :            :     // destination memory above the promotion point.
    1272                 :            :     Instruction *promotion_point;
    1273                 :            :     // If promotion_ssa is non-null, the julia src ssa value that corresponds
    1274                 :            :     // to the promotion point. This is used for dominator analysis, since LLVM's
    1275                 :            :     // dominator analysis has algorithmic problems for large basic blocks.
    1276                 :            :     ssize_t promotion_ssa;
    1277                 :   57931600 :     bool ispointer() const
    1278                 :            :     {
    1279                 :            :         // whether this value is compatible with `data_pointer`
    1280                 :   57931600 :         return tbaa != nullptr;
    1281                 :            :     }
    1282                 :   19266000 :     jl_cgval_t(Value *Vval, jl_value_t *typ, Value *tindex) : // general value constructor
    1283                 :            :         V(Vval), // V is allowed to be NULL in a jl_varinfo_t context, but not during codegen contexts
    1284                 :            :         Vboxed(nullptr),
    1285                 :            :         TIndex(tindex),
    1286                 :            :         constant(NULL),
    1287                 :            :         typ(typ),
    1288                 :            :         isboxed(false),
    1289                 :            :         isghost(false),
    1290                 :            :         tbaa(nullptr),
    1291                 :            :         promotion_point(nullptr),
    1292                 :   19266000 :         promotion_ssa(-1)
    1293                 :            :     {
    1294   [ -  +  -  - ]:   19266000 :         assert(TIndex == NULL || TIndex->getType() == getInt8Ty(TIndex->getContext()));
    1295                 :   19266000 :     }
    1296                 :   43587100 :     jl_cgval_t(Value *Vptr, bool isboxed, jl_value_t *typ, Value *tindex, MDNode *tbaa) : // general pointer constructor
    1297                 :            :         V(Vptr),
    1298                 :   43587100 :         Vboxed(isboxed ? Vptr : nullptr),
    1299                 :            :         TIndex(tindex),
    1300                 :            :         constant(NULL),
    1301                 :            :         typ(typ),
    1302                 :            :         isboxed(isboxed),
    1303                 :            :         isghost(false),
    1304                 :            :         tbaa(tbaa),
    1305                 :            :         promotion_point(nullptr),
    1306         [ +  + ]:   43587100 :         promotion_ssa(-1)
    1307                 :            :     {
    1308         [ +  + ]:   43587100 :         if (Vboxed)
    1309         [ -  + ]:    5068600 :             assert(Vboxed->getType() == JuliaType::get_prjlvalue_ty(Vboxed->getContext()));
    1310         [ -  + ]:   43587100 :         assert(tbaa != NULL);
    1311   [ +  +  -  + ]:   43587100 :         assert(!(isboxed && TIndex != NULL));
    1312   [ +  +  -  + ]:   43587100 :         assert(TIndex == NULL || TIndex->getType() == getInt8Ty(TIndex->getContext()));
    1313                 :   43587100 :     }
    1314                 :   12313700 :     explicit jl_cgval_t(jl_value_t *typ) : // ghost value constructor
    1315                 :            :         // mark explicit to avoid being used implicitly for conversion from NULL (use jl_cgval_t() instead)
    1316                 :            :         V(NULL),
    1317                 :            :         Vboxed(NULL),
    1318                 :            :         TIndex(NULL),
    1319                 :   12313700 :         constant(((jl_datatype_t*)typ)->instance),
    1320                 :            :         typ(typ),
    1321                 :            :         isboxed(false),
    1322                 :            :         isghost(true),
    1323                 :            :         tbaa(nullptr),
    1324                 :            :         promotion_point(nullptr),
    1325                 :   12313700 :         promotion_ssa(-1)
    1326                 :            :     {
    1327         [ -  + ]:   12313700 :         assert(jl_is_datatype(typ));
    1328         [ -  + ]:   12313700 :         assert(constant);
    1329                 :   12313700 :     }
    1330                 :     504546 :     jl_cgval_t(const jl_cgval_t &v, jl_value_t *typ, Value *tindex) : // copy constructor with new type
    1331                 :     504546 :         V(v.V),
    1332                 :     504546 :         Vboxed(v.Vboxed),
    1333                 :            :         TIndex(tindex),
    1334                 :     504546 :         constant(v.constant),
    1335                 :            :         typ(typ),
    1336                 :     504546 :         isboxed(v.isboxed),
    1337                 :     504546 :         isghost(v.isghost),
    1338                 :     504546 :         tbaa(v.tbaa),
    1339                 :     504546 :         promotion_point(v.promotion_point),
    1340                 :     504546 :         promotion_ssa(v.promotion_ssa)
    1341                 :            :     {
    1342         [ +  + ]:     504546 :         if (Vboxed)
    1343         [ -  + ]:     470331 :             assert(Vboxed->getType() == JuliaType::get_prjlvalue_ty(Vboxed->getContext()));
    1344                 :            :         // this constructor expects we had a badly or equivalently typed version
    1345                 :            :         // make sure we aren't discarding the actual type information
    1346         [ +  + ]:     504546 :         if (v.TIndex) {
    1347         [ -  + ]:      57792 :             assert((TIndex == NULL) == jl_is_concrete_type(typ));
    1348                 :            :         }
    1349                 :            :         else {
    1350   [ +  +  +  +  :     446754 :             assert(isboxed || v.typ == typ || tindex);
                   -  + ]
    1351                 :            :         }
    1352                 :     504546 :     }
    1353                 :   52095600 :     explicit jl_cgval_t() : // undef / unreachable constructor
    1354                 :            :         V(NULL),
    1355                 :            :         Vboxed(NULL),
    1356                 :            :         TIndex(NULL),
    1357                 :            :         constant(NULL),
    1358                 :            :         typ(jl_bottom_type),
    1359                 :            :         isboxed(false),
    1360                 :            :         isghost(true),
    1361                 :            :         tbaa(nullptr),
    1362                 :            :         promotion_point(nullptr),
    1363                 :   52095600 :         promotion_ssa(-1)
    1364                 :            :     {
    1365                 :   52095600 :     }
    1366                 :            : };
    1367                 :            : 
    1368                 :            : // per-local-variable information
    1369                 :            : struct jl_varinfo_t {
    1370                 :            :     Instruction *boxroot; // an address, if the var might be in a jl_value_t** stack slot (marked ctx.tbaa().tbaa_const, if appropriate)
    1371                 :            :     jl_cgval_t value; // a stack slot or constant value
    1372                 :            :     Value *pTIndex; // i8* stack slot for the value.TIndex tag describing `value.V`
    1373                 :            :     DILocalVariable *dinfo;
    1374                 :            :     // if the variable might be used undefined and is not boxed
    1375                 :            :     // this i1 flag is true when it is defined
    1376                 :            :     Value *defFlag;
    1377                 :            :     bool isSA; // whether all stores dominate all uses
    1378                 :            :     bool isVolatile;
    1379                 :            :     bool isArgument;
    1380                 :            :     bool usedUndef;
    1381                 :            :     bool used;
    1382                 :            : 
    1383                 :     756220 :     jl_varinfo_t(LLVMContext &ctxt) : boxroot(NULL),
    1384                 :            :                      value(jl_cgval_t()),
    1385                 :            :                      pTIndex(NULL),
    1386                 :            :                      dinfo(NULL),
    1387                 :            :                      defFlag(NULL),
    1388                 :            :                      isSA(false),
    1389                 :            :                      isVolatile(false),
    1390                 :            :                      isArgument(false),
    1391                 :            :                      usedUndef(false),
    1392                 :     756220 :                      used(false)
    1393                 :            :     {
    1394                 :     756220 :     }
    1395                 :            : };
    1396                 :            : 
    1397                 :            : // information about the context of a piece of code: its enclosing
    1398                 :            : // function and module, and visible local variables and labels.
    1399                 :            : class jl_codectx_t {
    1400                 :            : public:
    1401                 :            :     IRBuilder<> builder;
    1402                 :            :     jl_codegen_params_t &emission_context;
    1403                 :            :     llvm::MapVector<jl_code_instance_t*, jl_codegen_call_target_t> call_targets;
    1404                 :            :     std::map<void*, GlobalVariable*> &global_targets;
    1405                 :            :     Function *f = NULL;
    1406                 :            :     // local var info. globals are not in here.
    1407                 :            :     std::vector<jl_varinfo_t> slots;
    1408                 :            :     std::map<int, jl_varinfo_t> phic_slots;
    1409                 :            :     std::vector<jl_cgval_t> SAvalues;
    1410                 :            :     std::vector<std::tuple<jl_cgval_t, BasicBlock *, AllocaInst *, PHINode *, jl_value_t *>> PhiNodes;
    1411                 :            :     std::vector<bool> ssavalue_assigned;
    1412                 :            :     std::vector<int> ssavalue_usecount;
    1413                 :            :     std::vector<orc::ThreadSafeModule> oc_modules;
    1414                 :            :     jl_module_t *module = NULL;
    1415                 :            :     jl_typecache_t type_cache;
    1416                 :            :     jl_tbaacache_t tbaa_cache;
    1417                 :            :     jl_method_instance_t *linfo = NULL;
    1418                 :            :     jl_value_t *rettype = NULL;
    1419                 :            :     jl_code_info_t *source = NULL;
    1420                 :            :     jl_array_t *code = NULL;
    1421                 :            :     size_t world = 0;
    1422                 :            :     jl_array_t *roots = NULL;
    1423                 :            :     const char *name = NULL;
    1424                 :            :     StringRef file{};
    1425                 :            :     ssize_t *line = NULL;
    1426                 :            :     Value *spvals_ptr = NULL;
    1427                 :            :     Value *argArray = NULL;
    1428                 :            :     Value *argCount = NULL;
    1429                 :            :     MDNode *aliasscope = NULL;
    1430                 :            :     std::string funcName;
    1431                 :            :     int vaSlot = -1;        // name of vararg argument
    1432                 :            :     int nReqArgs = 0;
    1433                 :            :     int nargs = 0;
    1434                 :            :     int nvargs = -1;
    1435                 :            :     bool is_opaque_closure = false;
    1436                 :            : 
    1437                 :            :     Value *pgcstack = NULL;
    1438                 :            :     Instruction *topalloca = NULL;
    1439                 :            : 
    1440                 :            :     bool debug_enabled = false;
    1441                 :            :     bool use_cache = false;
    1442                 :            :     const jl_cgparams_t *params = NULL;
    1443                 :            : 
    1444                 :            :     std::vector<orc::ThreadSafeModule> llvmcall_modules;
    1445                 :            : 
    1446                 :     709252 :     jl_codectx_t(LLVMContext &llvmctx, jl_codegen_params_t &params)
    1447                 :     709252 :       : builder(llvmctx),
    1448                 :            :         emission_context(params),
    1449                 :            :         call_targets(),
    1450                 :     709252 :         global_targets(params.globals),
    1451                 :     709252 :         world(params.world),
    1452                 :     709252 :         use_cache(params.cache),
    1453                 :     709252 :         params(params.params) { }
    1454                 :            : 
    1455                 :  118411000 :     jl_typecache_t &types() {
    1456                 :  118411000 :         type_cache.initialize(builder.getContext());
    1457                 :  118411000 :         return type_cache;
    1458                 :            :     }
    1459                 :            : 
    1460                 :   55542600 :     jl_tbaacache_t &tbaa() {
    1461                 :   55542600 :         tbaa_cache.initialize(builder.getContext());
    1462                 :   55542600 :         return tbaa_cache;
    1463                 :            :     }
    1464                 :            : 
    1465                 :     709242 :     ~jl_codectx_t() {
    1466         [ -  + ]:     709242 :         assert(this->roots == NULL);
    1467                 :            :         // Transfer local delayed calls to the global queue
    1468         [ +  + ]:     927224 :         for (auto call_target : call_targets)
    1469                 :     217982 :             emission_context.workqueue.push_back(call_target);
    1470                 :     709242 :     }
    1471                 :            : };
    1472                 :            : 
    1473                 :          0 : GlobalVariable *JuliaVariable::realize(jl_codectx_t &ctx) {
    1474                 :          0 :     return realize(jl_Module);
    1475                 :            : }
    1476                 :            : 
    1477                 :            : static Type *julia_type_to_llvm(jl_codectx_t &ctx, jl_value_t *jt, bool *isboxed = NULL);
    1478                 :            : static jl_returninfo_t get_specsig_function(jl_codectx_t &ctx, Module *M, StringRef name, jl_value_t *sig, jl_value_t *jlrettype, bool is_opaque_closure);
    1479                 :            : static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaval = -1);
    1480                 :            : static Value *global_binding_pointer(jl_codectx_t &ctx, jl_module_t *m, jl_sym_t *s,
    1481                 :            :                                      jl_binding_t **pbnd, bool assign);
    1482                 :            : static jl_cgval_t emit_checked_var(jl_codectx_t &ctx, Value *bp, jl_sym_t *name, bool isvol, MDNode *tbaa);
    1483                 :            : static jl_cgval_t emit_sparam(jl_codectx_t &ctx, size_t i);
    1484                 :            : static Value *emit_condition(jl_codectx_t &ctx, const jl_cgval_t &condV, const std::string &msg);
    1485                 :            : static void allocate_gc_frame(jl_codectx_t &ctx, BasicBlock *b0);
    1486                 :            : static Value *get_current_task(jl_codectx_t &ctx);
    1487                 :            : static Value *get_current_ptls(jl_codectx_t &ctx);
    1488                 :            : static Value *get_last_age_field(jl_codectx_t &ctx);
    1489                 :            : static Value *get_current_signal_page(jl_codectx_t &ctx);
    1490                 :            : static void CreateTrap(IRBuilder<> &irbuilder, bool create_new_block = true);
    1491                 :            : static CallInst *emit_jlcall(jl_codectx_t &ctx, Function *theFptr, Value *theF,
    1492                 :            :                              const jl_cgval_t *args, size_t nargs, JuliaFunction *trampoline);
    1493                 :            : static CallInst *emit_jlcall(jl_codectx_t &ctx, JuliaFunction *theFptr, Value *theF,
    1494                 :            :                              const jl_cgval_t *args, size_t nargs, JuliaFunction *trampoline);
    1495                 :            : static Value *emit_f_is(jl_codectx_t &ctx, const jl_cgval_t &arg1, const jl_cgval_t &arg2,
    1496                 :            :                         Value *nullcheck1 = nullptr, Value *nullcheck2 = nullptr);
    1497                 :            : static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t nargs, const jl_cgval_t *argv, bool is_promotable=false);
    1498                 :            : static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const jl_cgval_t *argv, size_t nargs, jl_value_t *rt);
    1499                 :            : 
    1500                 :            : static Value *literal_pointer_val(jl_codectx_t &ctx, jl_value_t *p);
    1501                 :            : static GlobalVariable *prepare_global_in(Module *M, GlobalVariable *G);
    1502                 :            : Instruction *tbaa_decorate(MDNode *md, Instruction *inst);
    1503                 :            : 
    1504                 :     930116 : static GlobalVariable *prepare_global_in(Module *M, JuliaVariable *G)
    1505                 :            : {
    1506                 :     930116 :     return G->realize(M);
    1507                 :            : }
    1508                 :            : 
    1509                 :    4743200 : static Function *prepare_call_in(Module *M, JuliaFunction *G)
    1510                 :            : {
    1511                 :    4743200 :     return G->realize(M);
    1512                 :            : }
    1513                 :            : 
    1514                 :      44022 : static inline GlobalVariable *prepare_global_in(Module *M, GlobalVariable *G)
    1515                 :            : {
    1516         [ +  + ]:      44022 :     if (G->getParent() == M)
    1517                 :       8304 :         return G;
    1518                 :      35718 :     GlobalValue *local = M->getNamedValue(G->getName());
    1519         [ +  + ]:      35718 :     if (!local) {
    1520                 :            :         // Copy the GlobalVariable, but without the initializer, so it becomes a declaration
    1521                 :      22692 :         GlobalVariable *proto = new GlobalVariable(*M, G->getValueType(),
    1522                 :      22692 :                 G->isConstant(), GlobalVariable::ExternalLinkage,
    1523                 :      22692 :                 nullptr, G->getName(), nullptr, G->getThreadLocalMode());
    1524                 :      22692 :         proto->copyAttributesFrom(G);
    1525                 :            :         // DLLImport only needs to be set for the shadow module
    1526                 :            :         // it just gets annoying in the JIT
    1527                 :      22692 :         proto->setDLLStorageClass(GlobalValue::DefaultStorageClass);
    1528                 :      22692 :         return proto;
    1529                 :            :     }
    1530                 :      13026 :     return cast<GlobalVariable>(local);
    1531                 :            : }
    1532                 :            : 
    1533                 :            : 
    1534                 :            : // --- convenience functions for tagging llvm values with julia types ---
    1535                 :            : 
    1536                 :     389618 : static GlobalVariable *get_pointer_to_constant(jl_codegen_params_t &emission_context, Constant *val, StringRef name, Module &M)
    1537                 :            : {
    1538                 :     389618 :     GlobalVariable *&gv = emission_context.mergedConstants[val];
    1539                 :     389618 :     StringRef localname;
    1540                 :     389618 :     std::string ssno;
    1541         [ +  + ]:     389618 :     if (gv == nullptr) {
    1542                 :      94798 :         raw_string_ostream(ssno) << name << emission_context.mergedConstants.size();
    1543                 :      94798 :         localname = StringRef(ssno);
    1544                 :            :     }
    1545                 :            :     else {
    1546                 :     294820 :         localname = gv->getName();
    1547         [ +  + ]:     294820 :         if (gv->getParent() != &M)
    1548                 :      48051 :             gv = cast_or_null<GlobalVariable>(M.getNamedValue(localname));
    1549                 :            :     }
    1550         [ +  + ]:     389618 :     if (gv == nullptr) {
    1551                 :     142800 :         gv = new GlobalVariable(
    1552                 :            :                 M,
    1553                 :     142800 :                 val->getType(),
    1554                 :            :                 true,
    1555                 :            :                 GlobalVariable::PrivateLinkage,
    1556                 :            :                 val,
    1557                 :     142800 :                 localname);
    1558                 :     142800 :         gv->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
    1559                 :            :     }
    1560         [ -  + ]:     389618 :     assert(localname == gv->getName());
    1561         [ -  + ]:     389618 :     assert(val == gv->getInitializer());
    1562                 :     389618 :     return gv;
    1563                 :            : }
    1564                 :            : 
    1565                 :    1674750 : static AllocaInst *emit_static_alloca(jl_codectx_t &ctx, Type *lty)
    1566                 :            : {
    1567                 :    1674750 :     ++EmittedAllocas;
    1568                 :    1674750 :     return new AllocaInst(lty, 0, "", /*InsertBefore=*/ctx.topalloca);
    1569                 :            : }
    1570                 :            : 
    1571                 :      67688 : static void undef_derived_strct(IRBuilder<> &irbuilder, Value *ptr, jl_datatype_t *sty, MDNode *tbaa)
    1572                 :            : {
    1573         [ -  + ]:      67688 :     assert(ptr->getType()->getPointerAddressSpace() != AddressSpace::Tracked);
    1574         [ +  + ]:      67688 :     size_t first_offset = sty->layout->nfields ? jl_field_offset(sty, 0) : 0;
    1575         [ +  + ]:      67688 :     if (first_offset != 0)
    1576                 :          6 :         irbuilder.CreateMemSet(ptr, ConstantInt::get(getInt8Ty(irbuilder.getContext()), 0), first_offset, MaybeAlign(0));
    1577                 :      67688 :     size_t i, np = sty->layout->npointers;
    1578         [ +  + ]:      67688 :     if (np == 0)
    1579                 :      32455 :         return;
    1580                 :      35233 :     auto T_prjlvalue = JuliaType::get_prjlvalue_ty(irbuilder.getContext());
    1581                 :      35233 :     ptr = irbuilder.CreateBitCast(ptr, T_prjlvalue->getPointerTo(ptr->getType()->getPointerAddressSpace()));
    1582         [ +  + ]:     121702 :     for (i = 0; i < np; i++) {
    1583                 :      86469 :         Value *fld = irbuilder.CreateConstInBoundsGEP1_32(T_prjlvalue, ptr, jl_ptr_offset(sty, i));
    1584                 :      86469 :         tbaa_decorate(tbaa, irbuilder.CreateStore(Constant::getNullValue(T_prjlvalue), fld));
    1585                 :            :     }
    1586                 :            : }
    1587                 :            : 
    1588                 :     120007 : static Value *emit_inttoptr(jl_codectx_t &ctx, Value *v, Type *ty)
    1589                 :            : {
    1590                 :            :     // Almost all of our inttoptr are generated due to representing `Ptr` with `getSizeTy(ctx.builder.getContext())`
    1591                 :            :     // in LLVM and most of these integers are generated from `ptrtoint` in the first place.
    1592         [ +  + ]:     120007 :     if (auto I = dyn_cast<PtrToIntInst>(v)) {
    1593                 :     106965 :         auto ptr = I->getOperand(0);
    1594         [ +  - ]:     106965 :         if (ty->getPointerAddressSpace() == ptr->getType()->getPointerAddressSpace())
    1595                 :     106965 :             return ctx.builder.CreateBitCast(ptr, ty);
    1596         [ #  # ]:          0 :         else if (cast<PointerType>(ty)->hasSameElementTypeAs(cast<PointerType>(ptr->getType())))
    1597                 :          0 :             return ctx.builder.CreateAddrSpaceCast(ptr, ty);
    1598                 :            :     }
    1599                 :      13042 :     ++EmittedIntToPtrs;
    1600                 :      13042 :     return ctx.builder.CreateIntToPtr(v, ty);
    1601                 :            : }
    1602                 :            : 
    1603                 :   12892700 : static inline jl_cgval_t ghostValue(jl_codectx_t &ctx, jl_value_t *typ)
    1604                 :            : {
    1605         [ +  + ]:   12892700 :     if (typ == jl_bottom_type)
    1606                 :     588998 :         return jl_cgval_t(); // Undef{}
    1607         [ +  + ]:   12303700 :     if (typ == (jl_value_t*)jl_typeofbottom_type) {
    1608                 :            :         // normalize TypeofBottom to Type{Union{}}
    1609                 :         10 :         typ = (jl_value_t*)jl_typeofbottom_type->super;
    1610                 :            :     }
    1611         [ +  + ]:   12303700 :     if (jl_is_type_type(typ)) {
    1612                 :            :         // replace T::Type{T} with T, by assuming that T must be a leaftype of some sort
    1613                 :      25837 :         jl_cgval_t constant(NULL, true, typ, NULL, best_tbaa(ctx.tbaa(), typ));
    1614                 :      25837 :         constant.constant = jl_tparam0(typ);
    1615                 :      25837 :         return constant;
    1616                 :            :     }
    1617                 :   12277900 :     return jl_cgval_t(typ);
    1618                 :            : }
    1619                 :      74318 : static inline jl_cgval_t ghostValue(jl_codectx_t &ctx, jl_datatype_t *typ)
    1620                 :            : {
    1621                 :      74318 :     return ghostValue(ctx, (jl_value_t*)typ);
    1622                 :            : }
    1623                 :            : 
    1624                 :   45805900 : static inline jl_cgval_t mark_julia_const(jl_codectx_t &ctx, jl_value_t *jv)
    1625                 :            : {
    1626                 :            :     jl_value_t *typ;
    1627         [ +  + ]:   45805900 :     if (jl_is_type(jv)) {
    1628                 :    2879780 :         typ = (jl_value_t*)jl_wrap_Type(jv); // TODO: gc-root this?
    1629                 :            :     }
    1630                 :            :     else {
    1631                 :   42926200 :         typ = jl_typeof(jv);
    1632         [ +  + ]:   42926200 :         if (jl_is_datatype_singleton((jl_datatype_t*)typ))
    1633                 :   11596900 :             return ghostValue(ctx, typ);
    1634                 :            :     }
    1635                 :   34209000 :     jl_cgval_t constant(NULL, true, typ, NULL, best_tbaa(ctx.tbaa(), typ));
    1636                 :   34209000 :     constant.constant = jv;
    1637                 :   34209000 :     return constant;
    1638                 :            : }
    1639                 :            : 
    1640                 :            : 
    1641                 :    4283670 : static inline jl_cgval_t mark_julia_slot(Value *v, jl_value_t *typ, Value *tindex, MDNode *tbaa)
    1642                 :            : {
    1643                 :            :     // this enables lazy-copying of immutable values and stack or argument slots
    1644                 :    4283670 :     jl_cgval_t tagval(v, false, typ, tindex, tbaa);
    1645                 :    4283670 :     return tagval;
    1646                 :            : }
    1647                 :            : 
    1648                 :     194484 : static bool valid_as_globalinit(const Value *v) {
    1649         [ +  + ]:     194484 :     if (isa<ConstantExpr>(v)) {
    1650                 :            :         // llvm can't handle all the things that could be inside a ConstantExpr
    1651                 :            :         // (such as addrspacecast), and we don't really mind losing this optimization
    1652                 :       1621 :         return false;
    1653                 :            :     }
    1654         [ +  + ]:     192863 :     if (const auto *CC = dyn_cast<ConstantAggregate>(v)) {
    1655         [ +  + ]:       2074 :         for (const Value *elem : CC->operand_values())
    1656         [ +  + ]:       2073 :             if (!valid_as_globalinit(elem))
    1657                 :       1660 :                 return false;
    1658                 :            :     }
    1659                 :     191203 :     return isa<Constant>(v);
    1660                 :            : }
    1661                 :            : 
    1662                 :     192411 : static inline jl_cgval_t value_to_pointer(jl_codectx_t &ctx, Value *v, jl_value_t *typ, Value *tindex)
    1663                 :            : {
    1664                 :            :     Value *loc;
    1665         [ +  + ]:     192411 :     if (valid_as_globalinit(v)) { // llvm can't handle all the things that could be inside a ConstantExpr
    1666                 :        508 :         loc = get_pointer_to_constant(ctx.emission_context, cast<Constant>(v), "_j_const", *jl_Module);
    1667                 :            :     }
    1668                 :            :     else {
    1669                 :     191903 :         loc = emit_static_alloca(ctx, v->getType());
    1670                 :     191903 :         ctx.builder.CreateStore(v, loc);
    1671                 :            :     }
    1672                 :     192411 :     return mark_julia_slot(loc, typ, tindex, ctx.tbaa().tbaa_stack);
    1673                 :            : }
    1674                 :     968733 : static inline jl_cgval_t value_to_pointer(jl_codectx_t &ctx, const jl_cgval_t &v)
    1675                 :            : {
    1676         [ +  + ]:     968733 :     if (v.ispointer())
    1677                 :     830654 :         return v;
    1678                 :     138079 :     return value_to_pointer(ctx, v.V, v.typ, v.TIndex);
    1679                 :            : }
    1680                 :            : 
    1681                 :   25422000 : static inline jl_cgval_t mark_julia_type(jl_codectx_t &ctx, Value *v, bool isboxed, jl_value_t *typ)
    1682                 :            : {
    1683   [ +  +  +  +  :   25422000 :     if (jl_is_datatype(typ) && jl_is_datatype_singleton((jl_datatype_t*)typ)) {
                   +  + ]
    1684                 :            :         // no need to explicitly load/store a constant/ghost value
    1685                 :     519273 :         return ghostValue(ctx, typ);
    1686                 :            :     }
    1687         [ +  + ]:   24902800 :     if (jl_is_type_type(typ)) {
    1688                 :      62537 :         jl_value_t *tp0 = jl_tparam0(typ);
    1689   [ +  +  +  +  :      62537 :         if (jl_is_concrete_type(tp0) || tp0 == jl_bottom_type) {
                   +  + ]
    1690                 :            :             // replace T::Type{T} with T
    1691                 :      25827 :             return ghostValue(ctx, typ);
    1692                 :            :         }
    1693                 :            :     }
    1694                 :   24876900 :     Type *T = julia_type_to_llvm(ctx, typ);
    1695         [ +  + ]:   24876900 :     if (type_is_ghost(T)) {
    1696                 :     587117 :         return ghostValue(ctx, typ);
    1697                 :            :     }
    1698   [ +  +  +  +  :   24289800 :     if (v && !isboxed && v->getType()->isAggregateType() && CountTrackedPointers(v->getType()).count == 0) {
          +  +  +  +  +  
                      + ]
    1699                 :            :         // eagerly put this back onto the stack
    1700                 :            :         // llvm mem2reg pass will remove this if unneeded
    1701                 :      51166 :         return value_to_pointer(ctx, v, typ, NULL);
    1702                 :            :     }
    1703         [ +  + ]:   24238700 :     if (isboxed)
    1704                 :    5052900 :         return jl_cgval_t(v, isboxed, typ, NULL, best_tbaa(ctx.tbaa(), typ));
    1705                 :   19185800 :     return jl_cgval_t(v, typ, NULL);
    1706                 :            : }
    1707                 :            : 
    1708                 :    2884060 : static inline jl_cgval_t mark_julia_type(jl_codectx_t &ctx, Value *v, bool isboxed, jl_datatype_t *typ)
    1709                 :            : {
    1710                 :    2884060 :     return mark_julia_type(ctx, v, isboxed, (jl_value_t*)typ);
    1711                 :            : }
    1712                 :            : 
    1713                 :            : // see if it might be profitable (and cheap) to change the type of v to typ
    1714                 :   25929000 : static inline jl_cgval_t update_julia_type(jl_codectx_t &ctx, const jl_cgval_t &v, jl_value_t *typ)
    1715                 :            : {
    1716   [ +  +  +  +  :   25929000 :     if (v.typ == jl_bottom_type || v.constant || typ == (jl_value_t*)jl_any_type || jl_egal(v.typ, typ))
          +  +  +  +  +  
                      + ]
    1717                 :   25669800 :         return v; // fast-path
    1718   [ +  +  +  +  :     259260 :     if (jl_is_concrete_type(v.typ) && !jl_is_kind(v.typ)) {
                   +  + ]
    1719   [ +  +  +  -  :      50987 :         if (jl_is_concrete_type(typ) && !jl_is_kind(typ)) {
                   +  + ]
    1720                 :            :             // type mismatch: changing from one leaftype to another
    1721                 :         28 :             CreateTrap(ctx.builder);
    1722                 :         28 :             return jl_cgval_t();
    1723                 :            :         }
    1724                 :      50959 :         return v; // doesn't improve type info
    1725                 :            :     }
    1726         [ +  + ]:     208273 :     if (v.TIndex) {
    1727                 :       8701 :         jl_value_t *utyp = jl_unwrap_unionall(typ);
    1728         [ +  + ]:       8701 :         if (jl_is_datatype(utyp)) {
    1729                 :            :             bool alwaysboxed;
    1730         [ +  + ]:       6241 :             if (jl_is_concrete_type(utyp))
    1731                 :       4222 :                 alwaysboxed = !jl_is_pointerfree(utyp);
    1732                 :            :             else
    1733   [ +  +  -  + ]:       2019 :                 alwaysboxed = !((jl_datatype_t*)utyp)->name->abstract && ((jl_datatype_t*)utyp)->name->mutabl;
    1734         [ +  + ]:       6241 :             if (alwaysboxed) {
    1735                 :            :                 // discovered that this union-split type must actually be isboxed
    1736         [ +  - ]:         80 :                 if (v.Vboxed) {
    1737                 :         80 :                     return jl_cgval_t(v.Vboxed, true, typ, NULL, best_tbaa(ctx.tbaa(), typ));
    1738                 :            :                 }
    1739                 :            :                 else {
    1740                 :            :                     // type mismatch (there weren't any boxed values in the union)
    1741                 :          0 :                     CreateTrap(ctx.builder);
    1742                 :          0 :                     return jl_cgval_t();
    1743                 :            :                 }
    1744                 :            :             }
    1745                 :            :         }
    1746         [ +  + ]:       8621 :         if (!jl_is_concrete_type(typ))
    1747                 :       4479 :             return v; // not generally worth trying to change type info (which would require recomputing tindex)
    1748                 :            :     }
    1749                 :     203714 :     Type *T = julia_type_to_llvm(ctx, typ);
    1750         [ +  + ]:     203714 :     if (type_is_ghost(T))
    1751                 :       3928 :         return ghostValue(ctx, typ);
    1752                 :     199786 :     return jl_cgval_t(v, typ, NULL);
    1753                 :            : }
    1754                 :            : 
    1755                 :            : static jl_cgval_t convert_julia_type(jl_codectx_t &ctx, const jl_cgval_t &v, jl_value_t *typ, Value **skip=nullptr);
    1756                 :            : 
    1757                 :            : // --- allocating local variables ---
    1758                 :            : 
    1759                 :    4737500 : static jl_sym_t *slot_symbol(jl_codectx_t &ctx, int s)
    1760                 :            : {
    1761                 :    4737500 :     return (jl_sym_t*)jl_array_ptr_ref(ctx.source->slotnames, s);
    1762                 :            : }
    1763                 :            : 
    1764                 :          0 : static void store_def_flag(jl_codectx_t &ctx, const jl_varinfo_t &vi, bool val)
    1765                 :            : {
    1766   [ #  #  #  # ]:          0 :     assert((!vi.boxroot || vi.pTIndex) && "undef check is null pointer for boxed things");
    1767   [ #  #  #  # ]:          0 :     assert(vi.usedUndef && vi.defFlag && "undef flag codegen corrupted");
    1768                 :          0 :     ctx.builder.CreateStore(ConstantInt::get(getInt1Ty(ctx.builder.getContext()), val), vi.defFlag, vi.isVolatile);
    1769                 :          0 : }
    1770                 :            : 
    1771                 :     131583 : static void alloc_def_flag(jl_codectx_t &ctx, jl_varinfo_t& vi)
    1772                 :            : {
    1773   [ -  +  -  - ]:     131583 :     assert((!vi.boxroot || vi.pTIndex) && "undef check is null pointer for boxed things");
    1774         [ -  + ]:     131583 :     if (vi.usedUndef) {
    1775                 :          0 :         vi.defFlag = emit_static_alloca(ctx, getInt1Ty(ctx.builder.getContext()));
    1776                 :          0 :         store_def_flag(ctx, vi, false);
    1777                 :            :     }
    1778                 :     131583 : }
    1779                 :            : 
    1780                 :            : 
    1781                 :            : // --- utilities ---
    1782                 :            : 
    1783                 :    7219740 : static Constant *undef_value_for_type(Type *T) {
    1784                 :    7219740 :     auto tracked = CountTrackedPointers(T);
    1785                 :            :     Constant *undef;
    1786         [ +  + ]:    7219740 :     if (tracked.count)
    1787                 :            :         // make sure gc pointers (including ptr_phi of union-split) are initialized to NULL
    1788                 :     168908 :         undef = Constant::getNullValue(T);
    1789                 :            :     else
    1790                 :    7050840 :         undef = UndefValue::get(T);
    1791                 :    7219740 :     return undef;
    1792                 :            : }
    1793                 :            : 
    1794                 :    1702260 : static void CreateTrap(IRBuilder<> &irbuilder, bool create_new_block)
    1795                 :            : {
    1796                 :    1702260 :     Function *f = irbuilder.GetInsertBlock()->getParent();
    1797                 :    1702260 :     Function *trap_func = Intrinsic::getDeclaration(
    1798                 :            :             f->getParent(),
    1799                 :            :             Intrinsic::trap);
    1800                 :    1702260 :     irbuilder.CreateCall(trap_func);
    1801                 :    1702260 :     irbuilder.CreateUnreachable();
    1802         [ +  + ]:    1702260 :     if (create_new_block) {
    1803                 :     854269 :         BasicBlock *newBB = BasicBlock::Create(irbuilder.getContext(), "after_noret", f);
    1804                 :     854269 :         irbuilder.SetInsertPoint(newBB);
    1805                 :            :     }
    1806                 :            :     else {
    1807                 :     847993 :         irbuilder.ClearInsertionPoint();
    1808                 :            :     }
    1809                 :    1702260 : }
    1810                 :            : 
    1811                 :            : #if 0 // this code is likely useful, but currently unused
    1812                 :            : #ifndef JL_NDEBUG
    1813                 :            : static void CreateConditionalAbort(IRBuilder<> &irbuilder, Value *test)
    1814                 :            : {
    1815                 :            :     Function *f = irbuilder.GetInsertBlock()->getParent();
    1816                 :            :     BasicBlock *abortBB = BasicBlock::Create(irbuilder.getContext(), "debug_abort", f);
    1817                 :            :     BasicBlock *postBB = BasicBlock::Create(irbuilder.getContext(), "post_abort", f);
    1818                 :            :     irbuilder.CreateCondBr(test, abortBB, postBB);
    1819                 :            :     irbuilder.SetInsertPoint(abortBB);
    1820                 :            :     Function *trap_func = Intrinsic::getDeclaration(
    1821                 :            :             f->getParent(),
    1822                 :            :             Intrinsic::trap);
    1823                 :            :     irbuilder.CreateCall(trap_func);
    1824                 :            :     irbuilder.CreateUnreachable();
    1825                 :            :     irbuilder.SetInsertPoint(postBB);
    1826                 :            : }
    1827                 :            : #endif
    1828                 :            : #endif
    1829                 :            : 
    1830                 :            : 
    1831                 :            : #include "cgutils.cpp"
    1832                 :            : 
    1833                 :        494 : static jl_cgval_t convert_julia_type_union(jl_codectx_t &ctx, const jl_cgval_t &v, jl_value_t *typ, Value **skip)
    1834                 :            : {
    1835                 :            :     // previous value was a split union, compute new index, or box
    1836                 :        494 :     Value *new_tindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80);
    1837                 :        988 :     SmallBitVector skip_box(1, true);
    1838                 :        494 :     Value *tindex = ctx.builder.CreateAnd(v.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x7f));
    1839         [ +  + ]:        494 :     if (jl_is_uniontype(typ)) {
    1840                 :            :         // compute the TIndex mapping from v.typ -> typ
    1841                 :        356 :         unsigned counter = 0;
    1842                 :        356 :         for_each_uniontype_small(
    1843                 :            :             // for each old union-split value
    1844                 :        731 :             [&](unsigned idx, jl_datatype_t *jt) {
    1845                 :        731 :                 unsigned new_idx = get_box_tindex(jt, typ);
    1846                 :            :                 bool t;
    1847         [ +  + ]:        731 :                 if (new_idx) {
    1848                 :            :                     // found a matching element,
    1849                 :            :                     // match it against either the unboxed index
    1850                 :        586 :                     Value *cmp = ctx.builder.CreateICmpEQ(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), idx));
    1851                 :        586 :                     new_tindex = ctx.builder.CreateSelect(cmp, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), new_idx), new_tindex);
    1852                 :        586 :                     t = true;
    1853                 :            :                 }
    1854         [ +  - ]:        145 :                 else if (!jl_subtype((jl_value_t*)jt, typ)) {
    1855                 :            :                     // new value doesn't need to be boxed
    1856                 :            :                     // since it isn't part of the new union
    1857                 :        145 :                     t = true;
    1858         [ +  - ]:        145 :                     if (skip) {
    1859                 :        145 :                         Value *skip1 = ctx.builder.CreateICmpEQ(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), idx));
    1860         [ -  + ]:        145 :                         *skip = *skip ? ctx.builder.CreateOr(*skip, skip1) : skip1;
    1861                 :            :                     }
    1862                 :            :                 }
    1863                 :            :                 else {
    1864                 :            :                     // will actually need to box this element
    1865                 :            :                     // since it appeared as a leaftype in the original type
    1866                 :            :                     // but not in the remark type
    1867                 :          0 :                     t = false;
    1868                 :            :                 }
    1869                 :        731 :                 skip_box.resize(idx + 1, t);
    1870                 :        731 :             },
    1871                 :        356 :             v.typ,
    1872                 :            :             counter);
    1873                 :            :     }
    1874                 :            : 
    1875                 :            :     // some of the values are still unboxed
    1876         [ +  + ]:        494 :     if (!isa<Constant>(new_tindex)) {
    1877                 :        329 :         Value *wasboxed = NULL;
    1878                 :            :         // If the old value was boxed and unknown (type tag 0x80),
    1879                 :            :         // it is possible that the tag was actually one of the types
    1880                 :            :         // that are now explicitly represented. To find out, we need
    1881                 :            :         // to compare typeof(v.Vboxed) (i.e. the type of the unknown
    1882                 :            :         // value) against all the types that are now explicitly
    1883                 :            :         // selected and select the appropriate one as our new tindex.
    1884         [ +  + ]:        329 :         if (v.Vboxed) {
    1885                 :        275 :             wasboxed = ctx.builder.CreateAnd(v.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80));
    1886                 :        275 :             new_tindex = ctx.builder.CreateOr(wasboxed, new_tindex);
    1887                 :        275 :             wasboxed = ctx.builder.CreateICmpNE(wasboxed, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0));
    1888                 :            : 
    1889                 :        275 :             BasicBlock *currBB = ctx.builder.GetInsertBlock();
    1890                 :            : 
    1891                 :            :             // We lazily create a BB for this, once we decide that we
    1892                 :            :             // actually need it.
    1893                 :        275 :             Value *union_box_dt = NULL;
    1894                 :        275 :             BasicBlock *union_isaBB = NULL;
    1895                 :        275 :             BasicBlock *post_union_isaBB = NULL;
    1896                 :        172 :             auto maybe_setup_union_isa = [&]() {
    1897         [ +  - ]:        172 :                 if (!union_isaBB) {
    1898                 :        172 :                     union_isaBB = BasicBlock::Create(ctx.builder.getContext(), "union_isa", ctx.f);
    1899                 :        172 :                     ctx.builder.SetInsertPoint(union_isaBB);
    1900                 :        172 :                     union_box_dt = emit_typeof(ctx, v.Vboxed, skip != NULL);
    1901                 :        172 :                     post_union_isaBB = ctx.builder.GetInsertBlock();
    1902                 :            :                 }
    1903                 :        447 :             };
    1904                 :            : 
    1905                 :            :             // If we don't find a match. The type remains unknown
    1906                 :            :             // (0x80). We could use `v.Tindex`, here, since we know
    1907                 :            :             // it has to be 0x80, but it seems likely the backend
    1908                 :            :             // will like the explicit constant better.
    1909                 :        275 :             Value *union_box_tindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80);
    1910                 :        275 :             unsigned counter = 0;
    1911                 :        275 :             for_each_uniontype_small(
    1912                 :            :                 // for each new union-split value
    1913                 :        630 :                 [&](unsigned idx, jl_datatype_t *jt) {
    1914                 :        630 :                     unsigned old_idx = get_box_tindex(jt, v.typ);
    1915         [ +  + ]:        630 :                     if (old_idx == 0) {
    1916                 :            :                         // didn't handle this item before, select its new union index
    1917                 :        172 :                         maybe_setup_union_isa();
    1918                 :        172 :                         Value *cmp = ctx.builder.CreateICmpEQ(track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)jt)), union_box_dt);
    1919                 :        172 :                         union_box_tindex = ctx.builder.CreateSelect(cmp, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80 | idx), union_box_tindex);
    1920                 :            :                     }
    1921                 :        630 :                 },
    1922                 :            :                 typ,
    1923                 :            :                 counter);
    1924         [ +  + ]:        275 :             if (union_box_dt) {
    1925                 :        172 :                 BasicBlock *postBB = BasicBlock::Create(ctx.builder.getContext(), "post_union_isa", ctx.f);
    1926                 :        172 :                 ctx.builder.CreateBr(postBB);
    1927                 :        172 :                 ctx.builder.SetInsertPoint(currBB);
    1928                 :        172 :                 Value *wasunknown = ctx.builder.CreateICmpEQ(v.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80));
    1929                 :        172 :                 ctx.builder.CreateCondBr(wasunknown, union_isaBB, postBB);
    1930                 :        172 :                 ctx.builder.SetInsertPoint(postBB);
    1931                 :        172 :                 PHINode *tindex_phi = ctx.builder.CreatePHI(getInt8Ty(ctx.builder.getContext()), 2);
    1932                 :        172 :                 tindex_phi->addIncoming(new_tindex, currBB);
    1933                 :        172 :                 tindex_phi->addIncoming(union_box_tindex, post_union_isaBB);
    1934                 :        172 :                 new_tindex = tindex_phi;
    1935                 :            :             }
    1936                 :            :         }
    1937         [ -  + ]:        329 :         if (!skip_box.all()) {
    1938                 :            :             // some values weren't unboxed in the new union
    1939                 :            :             // box them now (tindex above already selected 0x80 = box for them)
    1940                 :          0 :             Value *boxv = box_union(ctx, v, skip_box);
    1941         [ #  # ]:          0 :             if (v.Vboxed) {
    1942                 :            :                 // If the value is boxed both before and after, we don't need
    1943                 :            :                 // to touch it at all. Otherwise we're either transitioning
    1944                 :            :                 // unboxed->boxed, or leaving an unboxed value in place.
    1945                 :          0 :                 Value *isboxed = ctx.builder.CreateICmpNE(
    1946                 :          0 :                     ctx.builder.CreateAnd(new_tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80)),
    1947                 :          0 :                     ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0));
    1948                 :          0 :                 boxv = ctx.builder.CreateSelect(
    1949                 :          0 :                     ctx.builder.CreateAnd(wasboxed, isboxed), v.Vboxed, boxv);
    1950                 :            :             }
    1951                 :            :             Value *slotv;
    1952                 :            :             MDNode *tbaa;
    1953         [ #  # ]:          0 :             if (v.V == NULL) {
    1954                 :            :                 // v.V might be NULL if it was all ghost objects before
    1955                 :          0 :                 slotv = NULL;
    1956                 :          0 :                 tbaa = ctx.tbaa().tbaa_const;
    1957                 :            :             }
    1958                 :            :             else {
    1959                 :          0 :                 Value *isboxv = ctx.builder.CreateIsNotNull(boxv);
    1960                 :          0 :                 jl_cgval_t oldv = value_to_pointer(ctx, v);
    1961                 :          0 :                 slotv = oldv.V;
    1962                 :          0 :                 tbaa = oldv.tbaa;
    1963                 :          0 :                 slotv = ctx.builder.CreateSelect(isboxv,
    1964                 :            :                             decay_derived(ctx, boxv),
    1965                 :            :                             decay_derived(ctx, emit_bitcast(ctx, slotv, boxv->getType())));
    1966                 :            :             }
    1967                 :          0 :             jl_cgval_t newv = jl_cgval_t(slotv, false, typ, new_tindex, tbaa);
    1968         [ #  # ]:          0 :             assert(boxv->getType() == ctx.types().T_prjlvalue);
    1969                 :          0 :             newv.Vboxed = boxv;
    1970                 :          0 :             return newv;
    1971                 :            :         }
    1972                 :            :     }
    1973                 :            :     else {
    1974                 :        165 :         return jl_cgval_t(boxed(ctx, v), true, typ, NULL, best_tbaa(ctx.tbaa(), typ));
    1975                 :            :     }
    1976                 :        329 :     return jl_cgval_t(v, typ, new_tindex);
    1977                 :            : }
    1978                 :            : 
    1979                 :            : // given a value marked with type `v.typ`, compute the mapping and/or boxing to return a value of type `typ`
    1980                 :            : // TODO: should this set TIndex when trivial (such as 0x80 or concrete types) ?
    1981                 :    1026360 : static jl_cgval_t convert_julia_type(jl_codectx_t &ctx, const jl_cgval_t &v, jl_value_t *typ, Value **skip)
    1982                 :            : {
    1983         [ -  + ]:    1026360 :     if (typ == (jl_value_t*)jl_typeofbottom_type)
    1984                 :          0 :         return ghostValue(ctx, typ); // normalize TypeofBottom to Type{Union{}}
    1985   [ +  +  +  +  :    1026360 :     if (v.typ == jl_bottom_type || jl_egal(v.typ, typ))
                   +  + ]
    1986                 :     718017 :         return v; // fast-path
    1987                 :     308339 :     Type *T = julia_type_to_llvm(ctx, typ);
    1988         [ +  + ]:     308339 :     if (type_is_ghost(T))
    1989                 :       7256 :         return ghostValue(ctx, typ);
    1990                 :     301083 :     Value *new_tindex = NULL;
    1991         [ +  + ]:     301083 :     if (jl_is_concrete_type(typ)) {
    1992   [ +  +  +  +  :     213466 :         if (v.TIndex && !jl_is_pointerfree(typ)) {
                   +  + ]
    1993                 :            :             // discovered that this union-split type must actually be isboxed
    1994         [ +  - ]:       3000 :             if (v.Vboxed) {
    1995                 :       3000 :                 return jl_cgval_t(v.Vboxed, true, typ, NULL, best_tbaa(ctx.tbaa(), typ));
    1996                 :            :             }
    1997                 :            :             else {
    1998                 :            :                 // type mismatch: there weren't any boxed values in the union
    1999         [ #  # ]:          0 :                 if (skip)
    2000                 :          0 :                     *skip = ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 1);
    2001                 :            :                 else
    2002                 :          0 :                     CreateTrap(ctx.builder);
    2003                 :          0 :                 return jl_cgval_t();
    2004                 :            :             }
    2005                 :            :         }
    2006   [ +  +  +  -  :     210466 :         if (jl_is_concrete_type(v.typ) && !jl_is_kind(v.typ)) {
                   +  + ]
    2007   [ +  -  +  -  :         20 :             if (jl_is_concrete_type(typ) && !jl_is_kind(typ)) {
                   +  - ]
    2008                 :            :                 // type mismatch: changing from one leaftype to another
    2009         [ +  - ]:         20 :                 if (skip)
    2010                 :         20 :                     *skip = ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 1);
    2011                 :            :                 else
    2012                 :          0 :                     CreateTrap(ctx.builder);
    2013                 :         20 :                 return jl_cgval_t();
    2014                 :            :             }
    2015                 :            :         }
    2016                 :            :     }
    2017                 :            :     else {
    2018                 :      87617 :         bool makeboxed = false;
    2019         [ +  + ]:      87617 :         if (v.TIndex) {
    2020                 :        494 :             return convert_julia_type_union(ctx, v, typ, skip);
    2021                 :            :         }
    2022   [ +  +  +  + ]:      87123 :         else if (!v.isboxed && jl_is_uniontype(typ)) {
    2023                 :            :             // previous value was unboxed (leaftype), statically compute union tindex
    2024         [ -  + ]:      22365 :             assert(jl_is_concrete_type(v.typ));
    2025                 :      22365 :             unsigned new_idx = get_box_tindex((jl_datatype_t*)v.typ, typ);
    2026         [ +  + ]:      22365 :             if (new_idx) {
    2027                 :      19315 :                 new_tindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), new_idx);
    2028   [ +  +  +  +  :      19315 :                 if (v.V && !v.ispointer()) {
                   +  + ]
    2029                 :            :                     // TODO: remove this branch once all consumers of v.TIndex understand how to handle a non-ispointer value
    2030                 :       3166 :                     return value_to_pointer(ctx, v.V, typ, new_tindex);
    2031                 :            :                 }
    2032                 :            :             }
    2033         [ +  - ]:       3050 :             else if (jl_subtype(v.typ, typ)) {
    2034                 :       3050 :                 makeboxed = true;
    2035                 :            :             }
    2036         [ #  # ]:          0 :             else if (skip) {
    2037                 :            :                 // undef
    2038                 :          0 :                 *skip = ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 1);
    2039                 :          0 :                 return jl_cgval_t();
    2040                 :            :             }
    2041                 :            :             else {
    2042                 :            :                 // unreachable
    2043                 :          0 :                 CreateTrap(ctx.builder);
    2044                 :          0 :                 return jl_cgval_t();
    2045                 :      19199 :             }
    2046                 :            :         }
    2047         [ +  + ]:      64758 :         else if (!v.isboxed) {
    2048                 :       9400 :             makeboxed = true;
    2049                 :            :         }
    2050         [ +  + ]:      83957 :         if (makeboxed) {
    2051                 :            :             // convert to a simple isboxed value
    2052                 :      12450 :             return jl_cgval_t(boxed(ctx, v), true, typ, NULL, best_tbaa(ctx.tbaa(), typ));
    2053                 :            :         }
    2054                 :            :     }
    2055                 :     281953 :     return jl_cgval_t(v, typ, new_tindex);
    2056                 :            : }
    2057                 :            : 
    2058                 :     554479 : orc::ThreadSafeModule jl_create_llvm_module(StringRef name, orc::ThreadSafeContext context, bool imaging_mode, const DataLayout &DL, const Triple &triple)
    2059                 :            : {
    2060                 :     554479 :     ++ModulesCreated;
    2061                 :    1108960 :     auto lock = context.getLock();
    2062                 :     554479 :     Module *m = new Module(name, *context.getContext());
    2063                 :    1108960 :     orc::ThreadSafeModule TSM(std::unique_ptr<Module>(m), std::move(context));
    2064                 :            :     // Some linkers (*cough* OS X) don't understand DWARF v4, so we use v2 in
    2065                 :            :     // imaging mode. The structure of v4 is slightly nicer for debugging JIT
    2066                 :            :     // code.
    2067         [ +  - ]:     554479 :     if (!m->getModuleFlag("Dwarf Version")) {
    2068                 :     554479 :         int dwarf_version = 4;
    2069                 :            : #ifdef _OS_DARWIN_
    2070                 :            :         if (imaging_mode)
    2071                 :            :             dwarf_version = 2;
    2072                 :            : #endif
    2073                 :     554479 :         m->addModuleFlag(llvm::Module::Warning, "Dwarf Version", dwarf_version);
    2074                 :            :     }
    2075         [ +  - ]:     554479 :     if (!m->getModuleFlag("Debug Info Version"))
    2076                 :     554479 :         m->addModuleFlag(llvm::Module::Warning, "Debug Info Version",
    2077                 :            :             llvm::DEBUG_METADATA_VERSION);
    2078                 :     554479 :     m->setDataLayout(DL);
    2079                 :     554479 :     m->setTargetTriple(triple.str());
    2080                 :            : 
    2081                 :            : #if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_) && JL_LLVM_VERSION >= 130000
    2082                 :            :     // tell Win32 to assume the stack is always 16-byte aligned,
    2083                 :            :     // and to ensure that it is 16-byte aligned for out-going calls,
    2084                 :            :     // to ensure compatibility with GCC codes
    2085                 :            :     m->setOverrideStackAlignment(16);
    2086                 :            : #endif
    2087                 :            : #if defined(JL_DEBUG_BUILD) && JL_LLVM_VERSION >= 130000
    2088                 :     554479 :     m->setStackProtectorGuard("global");
    2089                 :            : #endif
    2090                 :     554479 :     return TSM;
    2091                 :            : }
    2092                 :            : 
    2093                 :    1832070 : static void jl_init_function(Function *F)
    2094                 :            : {
    2095                 :            :     // set any attributes that *must* be set on all functions
    2096                 :            : #if JL_LLVM_VERSION >= 140000
    2097                 :    3664130 :     AttrBuilder attr(F->getContext());
    2098                 :            : #else
    2099                 :            :     AttrBuilder attr;
    2100                 :            : #endif
    2101                 :            : #if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_)
    2102                 :            :     // tell Win32 to realign the stack to the next 16-byte boundary
    2103                 :            :     // upon entry to any function. This achieves compatibility
    2104                 :            :     // with both MinGW-GCC (which assumes an 16-byte-aligned stack) and
    2105                 :            :     // i686 Windows (which uses a 4-byte-aligned stack)
    2106                 :            :     attr.addStackAlignmentAttr(16);
    2107                 :            : #endif
    2108                 :            : #if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_)
    2109                 :            :     attr.addAttribute(Attribute::UWTable); // force NeedsWinEH
    2110                 :            : #endif
    2111                 :            : #ifdef JL_DISABLE_FPO
    2112                 :            :     attr.addAttribute("frame-pointer", "all");
    2113                 :            : #endif
    2114                 :            : #if !defined(_COMPILER_ASAN_ENABLED_) && !defined(_OS_WINDOWS_)
    2115                 :            :     // ASAN won't like us accessing undefined memory causing spurious issues,
    2116                 :            :     // and Windows has platform-specific handling which causes it to mishandle
    2117                 :            :     // this annotation. Other platforms should just ignore this if they don't
    2118                 :            :     // implement it.
    2119                 :    1832070 :     attr.addAttribute("probe-stack", "inline-asm");
    2120                 :            :     //attr.addAttribute("stack-probe-size", "4096"); // can use this to change the default
    2121                 :            : #endif
    2122                 :            : #if JL_LLVM_VERSION >= 140000
    2123                 :    1832070 :     F->addFnAttrs(attr);
    2124                 :            : #else
    2125                 :            :     F->addAttributes(AttributeList::FunctionIndex, attr);
    2126                 :            : #endif
    2127                 :    1832070 : }
    2128                 :            : 
    2129                 :    1943520 : static std::pair<bool, bool> uses_specsig(jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig)
    2130                 :            : {
    2131         [ +  + ]:    1943520 :     size_t nreq = jl_is_method(lam->def.method) ? lam->def.method->nargs : 0;
    2132                 :    1943520 :     int va = 0;
    2133   [ +  +  +  + ]:    1943520 :     if (nreq > 0 && lam->def.method->isva) {
    2134                 :     147289 :         nreq--;
    2135                 :     147289 :         va = 1;
    2136                 :            :     }
    2137                 :    1943520 :     jl_value_t *sig = lam->specTypes;
    2138                 :    1943520 :     bool needsparams = false;
    2139         [ +  + ]:    1943520 :     if (jl_is_method(lam->def.method)) {
    2140         [ +  + ]:    1942410 :         if ((size_t)jl_subtype_env_size(lam->def.method->sig) != jl_svec_len(lam->sparam_vals))
    2141                 :        183 :             needsparams = true;
    2142         [ +  + ]:    2408010 :         for (size_t i = 0; i < jl_svec_len(lam->sparam_vals); ++i) {
    2143         [ +  + ]:     465592 :             if (jl_is_typevar(jl_svecref(lam->sparam_vals, i)))
    2144                 :         28 :                 needsparams = true;
    2145                 :            :         }
    2146                 :            :     }
    2147         [ +  + ]:    1943520 :     if (needsparams)
    2148                 :        206 :         return std::make_pair(false, true);
    2149         [ -  + ]:    1943320 :     if (sig == (jl_value_t*)jl_anytuple_type)
    2150                 :          0 :         return std::make_pair(false, false);
    2151         [ -  + ]:    1943320 :     if (!jl_is_datatype(sig))
    2152                 :          0 :         return std::make_pair(false, false);
    2153         [ +  + ]:    1943320 :     if (jl_nparams(sig) == 0)
    2154                 :       1111 :         return std::make_pair(false, false);
    2155         [ +  + ]:    1942210 :     if (va) {
    2156         [ +  + ]:     147274 :         if (jl_is_vararg(jl_tparam(sig, jl_nparams(sig) - 1)))
    2157                 :      83700 :             return std::make_pair(false, false);
    2158                 :            :     }
    2159                 :            :     // not invalid, consider if specialized signature is worthwhile
    2160         [ -  + ]:    1858510 :     if (prefer_specsig)
    2161                 :          0 :         return std::make_pair(true, false);
    2162   [ +  +  +  +  :    1858510 :     if (!deserves_retbox(rettype) && !jl_is_datatype_singleton((jl_datatype_t*)rettype) && rettype != (jl_value_t*)jl_bool_type)
             +  +  +  + ]
    2163                 :     424047 :         return std::make_pair(true, false);
    2164         [ +  + ]:    1434460 :     if (jl_is_uniontype(rettype)) {
    2165                 :            :         bool allunbox;
    2166                 :            :         size_t nbytes, align, min_align;
    2167                 :      72179 :         union_alloca_type((jl_uniontype_t*)rettype, allunbox, nbytes, align, min_align);
    2168         [ +  + ]:      72179 :         if (nbytes > 0)
    2169                 :      19430 :             return std::make_pair(true, false); // some elements of the union could be returned unboxed avoiding allocation
    2170                 :            :     }
    2171         [ +  + ]:    1415030 :     if (jl_nparams(sig) <= 3) // few parameters == more efficient to pass directly
    2172                 :    1068640 :         return std::make_pair(true, false);
    2173                 :     346386 :     bool allSingleton = true;
    2174         [ +  + ]:    1181380 :     for (size_t i = 0; i < jl_nparams(sig); i++) {
    2175                 :    1143420 :         jl_value_t *sigt = jl_tparam(sig, i);
    2176   [ +  +  +  + ]:    1143420 :         bool issing = jl_is_datatype(sigt) && jl_is_datatype_singleton((jl_datatype_t*)sigt);
    2177                 :    1143420 :         allSingleton &= issing;
    2178   [ +  +  +  +  :    1143420 :         if (!deserves_argbox(sigt) && !issing) {
                   +  + ]
    2179                 :     308425 :             return std::make_pair(true, false);
    2180                 :            :         }
    2181                 :            :     }
    2182         [ +  + ]:      37961 :     if (allSingleton)
    2183                 :         44 :         return std::make_pair(true, false);
    2184                 :      37917 :     return std::make_pair(false, false); // jlcall sig won't require any box allocations
    2185                 :            : }
    2186                 :            : 
    2187                 :            : 
    2188                 :            : // Logging for code coverage and memory allocation
    2189                 :            : 
    2190                 :            : JL_DLLEXPORT void jl_coverage_alloc_line(StringRef filename, int line);
    2191                 :            : JL_DLLEXPORT uint64_t *jl_coverage_data_pointer(StringRef filename, int line);
    2192                 :            : JL_DLLEXPORT uint64_t *jl_malloc_data_pointer(StringRef filename, int line);
    2193                 :            : 
    2194                 :       1267 : static void visitLine(jl_codectx_t &ctx, uint64_t *ptr, Value *addend, const char *name)
    2195                 :            : {
    2196                 :       1267 :     Value *pv = ConstantExpr::getIntToPtr(
    2197                 :       1267 :         ConstantInt::get(getSizeTy(ctx.builder.getContext()), (uintptr_t)ptr),
    2198                 :       1267 :         getInt64PtrTy(ctx.builder.getContext()));
    2199                 :       1267 :     Value *v = ctx.builder.CreateLoad(getInt64Ty(ctx.builder.getContext()), pv, true, name);
    2200                 :       1267 :     v = ctx.builder.CreateAdd(v, addend);
    2201                 :       1267 :     ctx.builder.CreateStore(v, pv, true); // volatile, not atomic, so this might be an underestimate,
    2202                 :            :                                           // but it's faster this way
    2203                 :       1267 : }
    2204                 :            : 
    2205                 :            : // Code coverage
    2206                 :            : 
    2207                 :       1252 : static void coverageVisitLine(jl_codectx_t &ctx, StringRef filename, int line)
    2208                 :            : {
    2209         [ -  + ]:       1252 :     assert(!ctx.emission_context.imaging);
    2210   [ +  -  +  +  :       1252 :     if (filename == "" || filename == "none" || filename == "no file" || filename == "<missing>" || line < 0)
          +  -  +  -  -  
                +  +  + ]
    2211                 :          1 :         return;
    2212                 :       1251 :     visitLine(ctx, jl_coverage_data_pointer(filename, line), ConstantInt::get(getInt64Ty(ctx.builder.getContext()), 1), "lcnt");
    2213                 :            : }
    2214                 :            : 
    2215                 :            : // Memory allocation log (malloc_log)
    2216                 :            : 
    2217                 :         16 : static void mallocVisitLine(jl_codectx_t &ctx, StringRef filename, int line, Value *sync)
    2218                 :            : {
    2219         [ -  + ]:         16 :     assert(!ctx.emission_context.imaging);
    2220   [ +  -  +  -  :         16 :     if (filename == "" || filename == "none" || filename == "no file" || filename == "<missing>" || line < 0)
          +  -  +  -  -  
                +  -  + ]
    2221                 :          0 :         return;
    2222                 :            :     Value *addend = sync
    2223                 :          6 :         ? ctx.builder.CreateCall(prepare_call(sync_gc_total_bytes_func), {sync})
    2224         [ +  + ]:         16 :         : ctx.builder.CreateCall(prepare_call(diff_gc_total_bytes_func), {});
    2225                 :         16 :     visitLine(ctx, jl_malloc_data_pointer(filename, line), addend, "bytecnt");
    2226                 :            : }
    2227                 :            : 
    2228                 :            : // --- constant determination ---
    2229                 :            : 
    2230                 :          0 : static void show_source_loc(jl_codectx_t &ctx, JL_STREAM *out)
    2231                 :            : {
    2232                 :          0 :     jl_printf(out, "in %s at %s", ctx.name, ctx.file.str().c_str());
    2233                 :          0 : }
    2234                 :            : 
    2235                 :          0 : static void cg_bdw(jl_codectx_t &ctx, jl_binding_t *b)
    2236                 :            : {
    2237                 :          0 :     jl_binding_deprecation_warning(ctx.module, b);
    2238   [ #  #  #  # ]:          0 :     if (b->deprecated == 1 && jl_options.depwarn) {
    2239                 :          0 :         show_source_loc(ctx, JL_STDERR);
    2240                 :          0 :         jl_printf(JL_STDERR, "\n");
    2241                 :            :     }
    2242                 :          0 : }
    2243                 :            : 
    2244                 :      12118 : static jl_value_t *static_apply_type(jl_codectx_t &ctx, const jl_cgval_t *args, size_t nargs)
    2245                 :            : {
    2246         [ -  + ]:      12118 :     assert(nargs > 1);
    2247                 :      12118 :     jl_value_t **v = (jl_value_t**)alloca(sizeof(jl_value_t*) * nargs);
    2248         [ +  + ]:      38778 :     for (size_t i = 0; i < nargs; i++) {
    2249         [ +  + ]:      38203 :         if (!args[i].constant)
    2250                 :      11543 :             return NULL;
    2251                 :      26660 :         v[i] = args[i].constant;
    2252                 :            :     }
    2253         [ -  + ]:        575 :     assert(v[0] == jl_builtin_apply_type);
    2254                 :        575 :     size_t last_age = jl_current_task->world_age;
    2255                 :            :     // call apply_type, but ignore errors. we know that will work in world 1.
    2256                 :        575 :     jl_current_task->world_age = 1;
    2257                 :            :     jl_value_t *result;
    2258   [ +  +  +  + ]:       1143 :     JL_TRY {
    2259                 :        575 :         result = jl_apply(v, nargs);
    2260                 :            :     }
    2261         [ +  + ]:         14 :     JL_CATCH {
    2262                 :          7 :         result = NULL;
    2263                 :            :     }
    2264                 :        575 :     jl_current_task->world_age = last_age;
    2265                 :        575 :     return result;
    2266                 :            : }
    2267                 :            : 
    2268                 :            : // try to statically evaluate, NULL if not possible. note that this may allocate, and as
    2269                 :            : // such the resulting value should not be embedded directly in the generated code.
    2270                 :     629512 : static jl_value_t *static_eval(jl_codectx_t &ctx, jl_value_t *ex)
    2271                 :            : {
    2272         [ -  + ]:     629512 :     if (jl_is_symbol(ex)) {
    2273                 :          0 :         jl_sym_t *sym = (jl_sym_t*)ex;
    2274         [ #  # ]:          0 :         if (jl_is_const(ctx.module, sym))
    2275                 :          0 :             return jl_get_global(ctx.module, sym);
    2276                 :          0 :         return NULL;
    2277                 :            :     }
    2278   [ +  +  +  -  :     629512 :     if (jl_is_slot(ex) || jl_is_argument(ex))
                   +  + ]
    2279                 :         64 :         return NULL;
    2280         [ +  + ]:     629448 :     if (jl_is_ssavalue(ex)) {
    2281                 :         86 :         ssize_t idx = ((jl_ssavalue_t*)ex)->id - 1;
    2282         [ -  + ]:         86 :         assert(idx >= 0);
    2283         [ +  - ]:         86 :         if (ctx.ssavalue_assigned.at(idx)) {
    2284                 :         86 :             return ctx.SAvalues.at(idx).constant;
    2285                 :            :         }
    2286                 :          0 :         return NULL;
    2287                 :            :     }
    2288         [ +  + ]:     629362 :     if (jl_is_quotenode(ex))
    2289                 :     540098 :         return jl_fieldref(ex, 0);
    2290         [ -  + ]:      89264 :     if (jl_is_method_instance(ex))
    2291                 :          0 :         return NULL;
    2292                 :      89264 :     jl_module_t *m = NULL;
    2293                 :      89264 :     jl_sym_t *s = NULL;
    2294         [ +  + ]:      89264 :     if (jl_is_globalref(ex)) {
    2295                 :      31848 :         s = jl_globalref_name(ex);
    2296                 :      31848 :         jl_binding_t *b = jl_get_binding(jl_globalref_mod(ex), s);
    2297   [ +  -  +  - ]:      31848 :         if (b && b->constp) {
    2298         [ -  + ]:      31848 :             if (b->deprecated)
    2299                 :          0 :                 cg_bdw(ctx, b);
    2300                 :      31848 :             return b->value;
    2301                 :            :         }
    2302                 :          0 :         return NULL;
    2303                 :            :     }
    2304         [ +  + ]:      57416 :     if (jl_is_expr(ex)) {
    2305                 :      19572 :         jl_expr_t *e = (jl_expr_t*)ex;
    2306         [ +  + ]:      19572 :         if (e->head == jl_call_sym) {
    2307                 :      19571 :             jl_value_t *f = static_eval(ctx, jl_exprarg(e, 0));
    2308         [ +  - ]:      19571 :             if (f) {
    2309   [ +  -  +  -  :      19571 :                 if (jl_array_dim0(e->args) == 3 && (f == jl_builtin_getfield || f == jl_builtin_getglobal)) {
                   -  + ]
    2310                 :          0 :                     m = (jl_module_t*)static_eval(ctx, jl_exprarg(e, 1));
    2311                 :            :                     // Check the tag before evaluating `s` so that a value of random
    2312                 :            :                     // type won't be corrupted.
    2313   [ #  #  #  # ]:          0 :                     if (!m || !jl_is_module(m))
    2314                 :          0 :                         return NULL;
    2315                 :            :                     // Assumes that the module is rooted somewhere.
    2316                 :          0 :                     s = (jl_sym_t*)static_eval(ctx, jl_exprarg(e, 2));
    2317   [ #  #  #  # ]:          0 :                     if (s && jl_is_symbol(s)) {
    2318                 :          0 :                         jl_binding_t *b = jl_get_binding(m, s);
    2319   [ #  #  #  # ]:          0 :                         if (b && b->constp) {
    2320         [ #  # ]:          0 :                             if (b->deprecated)
    2321                 :          0 :                                 cg_bdw(ctx, b);
    2322                 :          0 :                             return b->value;
    2323                 :            :                         }
    2324                 :          0 :                     }
    2325                 :            :                 }
    2326   [ -  +  -  - ]:      19571 :                 else if (f==jl_builtin_tuple || f==jl_builtin_apply_type) {
    2327                 :            :                     size_t i;
    2328                 :      19571 :                     size_t n = jl_array_dim0(e->args)-1;
    2329   [ -  +  -  - ]:      19571 :                     if (n==0 && f==jl_builtin_tuple) return (jl_value_t*)jl_emptytuple;
    2330                 :            :                     jl_value_t **v;
    2331                 :      19571 :                     JL_GC_PUSHARGS(v, n+1);
    2332                 :      19571 :                     v[0] = f;
    2333         [ +  + ]:      58713 :                     for (i = 0; i < n; i++) {
    2334                 :      39142 :                         v[i+1] = static_eval(ctx, jl_exprarg(e, i+1));
    2335         [ -  + ]:      39142 :                         if (v[i+1] == NULL) {
    2336                 :          0 :                             JL_GC_POP();
    2337                 :          0 :                             return NULL;
    2338                 :            :                         }
    2339                 :            :                     }
    2340                 :      19571 :                     size_t last_age = jl_current_task->world_age;
    2341                 :            :                     // here we know we're calling specific builtin functions that work in world 1.
    2342                 :      19571 :                     jl_current_task->world_age = 1;
    2343                 :            :                     jl_value_t *result;
    2344   [ +  -  +  + ]:      39142 :                     JL_TRY {
    2345                 :      19571 :                         result = jl_apply(v, n+1);
    2346                 :            :                     }
    2347         [ #  # ]:          0 :                     JL_CATCH {
    2348                 :          0 :                         result = NULL;
    2349                 :            :                     }
    2350                 :      19571 :                     jl_current_task->world_age = last_age;
    2351                 :      19571 :                     JL_GC_POP();
    2352                 :      19571 :                     return result;
    2353                 :            :                 }
    2354                 :            :             }
    2355                 :            :         }
    2356         [ -  + ]:          1 :         else if (e->head == jl_static_parameter_sym) {
    2357                 :          0 :             size_t idx = jl_unbox_long(jl_exprarg(e, 0));
    2358         [ #  # ]:          0 :             if (idx <= jl_svec_len(ctx.linfo->sparam_vals)) {
    2359                 :          0 :                 jl_value_t *e = jl_svecref(ctx.linfo->sparam_vals, idx - 1);
    2360         [ #  # ]:          0 :                 if (jl_is_typevar(e))
    2361                 :          0 :                     return NULL;
    2362                 :          0 :                 return e;
    2363                 :            :             }
    2364                 :            :         }
    2365                 :          1 :         return NULL;
    2366                 :            :     }
    2367                 :      37844 :     return ex;
    2368                 :            : }
    2369                 :            : 
    2370                 :  107067000 : static bool slot_eq(jl_value_t *e, int sl)
    2371                 :            : {
    2372   [ +  +  +  -  :  107067000 :     return (jl_is_slot(e) || jl_is_argument(e)) && jl_slot_number(e)-1 == sl;
             -  +  +  + ]
    2373                 :            : }
    2374                 :            : 
    2375                 :            : // --- code gen for intrinsic functions ---
    2376                 :            : 
    2377                 :            : #include "intrinsics.cpp"
    2378                 :            : 
    2379                 :            : // --- find volatile variables ---
    2380                 :            : 
    2381                 :            : // assigned in a try block and used outside that try block
    2382                 :            : 
    2383                 :  107067000 : static bool local_var_occurs(jl_value_t *e, int sl)
    2384                 :            : {
    2385         [ +  + ]:  107067000 :     if (slot_eq(e, sl)) {
    2386                 :       3878 :         return true;
    2387                 :            :     }
    2388         [ +  + ]:  107063000 :     else if (jl_is_expr(e)) {
    2389                 :   29893800 :         jl_expr_t *ex = (jl_expr_t*)e;
    2390                 :   29893800 :         size_t alength = jl_array_dim0(ex->args);
    2391         [ +  + ]:   95188600 :         for(int i=0; i < (int)alength; i++) {
    2392         [ +  + ]:   65297100 :             if (local_var_occurs(jl_exprarg(ex,i),sl))
    2393                 :       2260 :                 return true;
    2394                 :            :         }
    2395                 :            :     }
    2396         [ +  + ]:   77169200 :     else if (jl_is_returnnode(e)) {
    2397                 :      14538 :         jl_value_t *retexpr = jl_returnnode_value(e);
    2398         [ +  - ]:      14538 :         if (retexpr != NULL)
    2399                 :      14538 :             return local_var_occurs(retexpr, sl);
    2400                 :            :     }
    2401         [ +  + ]:   77154600 :     else if (jl_is_gotoifnot(e)) {
    2402                 :    3287510 :         return local_var_occurs(jl_gotoifnot_cond(e), sl);
    2403                 :            :     }
    2404                 :  103759000 :     return false;
    2405                 :            : }
    2406                 :            : 
    2407                 :      35082 : static std::set<int> assigned_in_try(jl_array_t *stmts, int s, long l)
    2408                 :            : {
    2409                 :      35082 :     std::set<int> av;
    2410         [ +  + ]:    4375370 :     for(int i=s; i <= l; i++) {
    2411                 :    4340290 :         jl_value_t *st = jl_array_ptr_ref(stmts,i);
    2412         [ +  + ]:    4340290 :         if (jl_is_expr(st)) {
    2413         [ +  + ]:    1602010 :             if (((jl_expr_t*)st)->head == jl_assign_sym) {
    2414                 :      19433 :                 jl_value_t *ar = jl_exprarg(st, 0);
    2415   [ +  +  -  + ]:      19433 :                 if (jl_is_slot(ar)) {
    2416                 :      18316 :                     av.insert(jl_slot_number(ar)-1);
    2417                 :            :                 }
    2418                 :            :             }
    2419                 :            :         }
    2420                 :            :     }
    2421                 :      35082 :     return av;
    2422                 :            : }
    2423                 :            : 
    2424                 :     364674 : static void mark_volatile_vars(jl_array_t *stmts, std::vector<jl_varinfo_t> &slots)
    2425                 :            : {
    2426                 :     364674 :     size_t slength = jl_array_dim0(stmts);
    2427         [ +  + ]:   41060900 :     for (int i = 0; i < (int)slength; i++) {
    2428                 :   40696200 :         jl_value_t *st = jl_array_ptr_ref(stmts, i);
    2429         [ +  + ]:   40696200 :         if (jl_is_expr(st)) {
    2430         [ +  + ]:   22199200 :             if (((jl_expr_t*)st)->head == jl_enter_sym) {
    2431                 :      35082 :                 int last = jl_unbox_long(jl_exprarg(st, 0));
    2432                 :      70164 :                 std::set<int> as = assigned_in_try(stmts, i + 1, last);
    2433         [ +  + ]:   99378900 :                 for (int j = 0; j < (int)slength; j++) {
    2434   [ +  +  +  + ]:   99343800 :                     if (j < i || j > last) {
    2435                 :   94968400 :                         std::set<int>::iterator it = as.begin();
    2436         [ +  + ]:  133436000 :                         for (; it != as.end(); it++) {
    2437         [ +  + ]:   38467800 :                             if (local_var_occurs(jl_array_ptr_ref(stmts, j), *it)) {
    2438                 :       3878 :                                 jl_varinfo_t &vi = slots[*it];
    2439                 :       3878 :                                 vi.isVolatile = true;
    2440                 :            :                             }
    2441                 :            :                         }
    2442                 :            :                     }
    2443                 :            :                 }
    2444                 :            :             }
    2445                 :            :         }
    2446                 :            :     }
    2447                 :     364674 : }
    2448                 :            : 
    2449                 :            : // --- use analysis ---
    2450                 :            : 
    2451                 :            : // a very simple, conservative use analysis
    2452                 :            : // to eagerly remove slot assignments that are never read from
    2453                 :            : 
    2454                 :            : template <typename callback>
    2455                 :  249592000 : static void general_use_analysis(jl_codectx_t &ctx, jl_value_t *expr, callback &f)
    2456                 :            : {
    2457         [ +  + ]:  249592000 :     if (f(expr)) {
    2458                 :   39930490 :         return;
    2459                 :            :     }
    2460         [ +  + ]:  209661800 :     else if (jl_is_expr(expr)) {
    2461                 :   44478000 :         jl_expr_t *e = (jl_expr_t*)expr;
    2462         [ +  + ]:   44478000 :         if (e->head == jl_method_sym) {
    2463                 :        700 :             general_use_analysis(ctx, jl_exprarg(e, 0), f);
    2464         [ +  + ]:        700 :             if (jl_expr_nargs(e) > 1) {
    2465                 :        680 :                 general_use_analysis(ctx, jl_exprarg(e, 1), f);
    2466                 :        680 :                 general_use_analysis(ctx, jl_exprarg(e, 2), f);
    2467                 :            :             }
    2468                 :            :         }
    2469         [ +  + ]:   44477400 :         else if (e->head == jl_assign_sym) {
    2470                 :            :             // don't consider assignment LHS as a variable "use"
    2471                 :      43480 :             general_use_analysis(ctx, jl_exprarg(e, 1), f);
    2472                 :            :         }
    2473                 :            :         else {
    2474                 :   44433800 :             size_t i, elen = jl_array_dim0(e->args);
    2475         [ +  + ]:  187599000 :             for (i = 0; i < elen; i++) {
    2476                 :  143165000 :                 general_use_analysis(ctx, jl_exprarg(e, i), f);
    2477                 :            :             }
    2478                 :            :         }
    2479                 :            :     }
    2480         [ +  + ]:  165183900 :     else if (jl_is_returnnode(expr)) {
    2481                 :    2644060 :         jl_value_t *retexpr = jl_returnnode_value(expr);
    2482         [ +  + ]:    2644060 :         if (retexpr != NULL)
    2483                 :     933860 :             general_use_analysis(ctx, retexpr, f);
    2484                 :            :     }
    2485         [ +  + ]:  162539800 :     else if (jl_is_gotoifnot(expr)) {
    2486                 :    8136900 :         general_use_analysis(ctx, jl_gotoifnot_cond(expr), f);
    2487                 :            :     }
    2488         [ +  + ]:  154402900 :     else if (jl_is_pinode(expr)) {
    2489                 :     579464 :         general_use_analysis(ctx, jl_fieldref_noalloc(expr, 0), f);
    2490                 :            :     }
    2491         [ +  + ]:  153823400 :     else if (jl_is_upsilonnode(expr)) {
    2492                 :     428332 :         jl_value_t *val = jl_fieldref_noalloc(expr, 0);
    2493         [ +  + ]:     428332 :         if (val)
    2494                 :     411880 :             general_use_analysis(ctx, val, f);
    2495                 :            :     }
    2496         [ +  + ]:  153395100 :     else if (jl_is_phicnode(expr)) {
    2497                 :     391546 :         jl_array_t *values = (jl_array_t*)jl_fieldref_noalloc(expr, 0);
    2498                 :     391546 :         size_t i, elen = jl_array_len(values);
    2499         [ +  + ]:     819878 :         for (i = 0; i < elen; i++) {
    2500                 :     428332 :             jl_value_t *v = jl_array_ptr_ref(values, i);
    2501                 :     428332 :             general_use_analysis(ctx, v, f);
    2502                 :            :         }
    2503                 :            :     }
    2504         [ +  + ]:  153003500 :     else if (jl_is_phinode(expr)) {
    2505                 :    8082260 :         jl_array_t *values = (jl_array_t*)jl_fieldref_noalloc(expr, 1);
    2506                 :    8082260 :         size_t i, elen = jl_array_len(values);
    2507         [ +  + ]:   22588400 :         for (i = 0; i < elen; i++) {
    2508                 :   14506160 :             jl_value_t *v = jl_array_ptr_ref(values, i);
    2509         [ +  + ]:   14506160 :             if (v)
    2510                 :   14498780 :                 general_use_analysis(ctx, v, f);
    2511                 :            :         }
    2512                 :            :     }
    2513                 :            : }
    2514                 :            : 
    2515                 :   40696200 : static void simple_use_analysis(jl_codectx_t &ctx, jl_value_t *expr)
    2516                 :            : {
    2517                 :  124796000 :     auto scan_slot_arg = [&](jl_value_t *expr) {
    2518   [ +  +  +  -  :  124796000 :         if (jl_is_slot(expr) || jl_is_argument(expr)) {
                   +  + ]
    2519                 :    3457090 :             int i = jl_slot_number(expr) - 1;
    2520                 :    3457090 :             ctx.slots[i].used = true;
    2521                 :    3457090 :             return true;
    2522                 :            :         }
    2523                 :  121339000 :         return false;
    2524                 :   40696200 :     };
    2525                 :   40696200 :     return general_use_analysis(ctx, expr, scan_slot_arg);
    2526                 :            : }
    2527                 :            : 
    2528                 :            : // --- gc root utils ---
    2529                 :            : 
    2530                 :            : // ---- Get Element Pointer (GEP) instructions within the GC frame ----
    2531                 :            : 
    2532                 :   12904800 : static void jl_add_method_root(jl_codectx_t &ctx, jl_value_t *val)
    2533                 :            : {
    2534   [ +  +  +  +  :   24376700 :     if (jl_is_concrete_type(val) || jl_is_bool(val) || jl_is_symbol(val) || val == jl_nothing ||
                   +  + ]
    2535   [ +  +  +  +  :   24376700 :             val == (jl_value_t*)jl_any_type || val == (jl_value_t*)jl_bottom_type || val == (jl_value_t*)jl_core_module)
          +  +  +  +  +  
                      + ]
    2536                 :   11137200 :         return;
    2537                 :    3395020 :     JL_GC_PUSH1(&val);
    2538         [ +  + ]:    3395020 :     if (ctx.roots == NULL) {
    2539                 :     294273 :         ctx.roots = jl_alloc_vec_any(1);
    2540                 :     294273 :         jl_array_ptr_set(ctx.roots, 0, val);
    2541                 :            :     }
    2542                 :            :     else {
    2543                 :    3100750 :         size_t rlen = jl_array_dim0(ctx.roots);
    2544         [ +  + ]:   38884500 :         for (size_t i = 0; i < rlen; i++) {
    2545         [ +  + ]:   37411200 :             if (jl_array_ptr_ref(ctx.roots,i) == val) {
    2546                 :    1627390 :                 JL_GC_POP();
    2547                 :    1627390 :                 return;
    2548                 :            :             }
    2549                 :            :         }
    2550                 :    1473360 :         jl_array_ptr_1d_push(ctx.roots, val);
    2551                 :            :     }
    2552                 :    1767630 :     JL_GC_POP();
    2553                 :            : }
    2554                 :            : 
    2555                 :            : // --- generating function calls ---
    2556                 :            : 
    2557                 :   21913300 : static jl_cgval_t emit_globalref(jl_codectx_t &ctx, jl_module_t *mod, jl_sym_t *name, AtomicOrdering order)
    2558                 :            : {
    2559                 :   21913300 :     jl_binding_t *bnd = NULL;
    2560                 :   21913300 :     Value *bp = global_binding_pointer(ctx, mod, name, &bnd, false);
    2561         [ -  + ]:   21913300 :     if (bp == NULL)
    2562                 :          0 :         return jl_cgval_t();
    2563                 :   21913300 :     bp = julia_binding_pvalue(ctx, bp);
    2564   [ +  +  +  +  :   21913300 :     if (bnd && bnd->value != NULL) {
                   +  + ]
    2565         [ +  + ]:   21911500 :         if (bnd->constp) {
    2566                 :   21903700 :             return mark_julia_const(ctx, bnd->value);
    2567                 :            :         }
    2568                 :       7742 :         LoadInst *v = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*)));
    2569                 :       7742 :         v->setOrdering(order);
    2570                 :       7742 :         tbaa_decorate(ctx.tbaa().tbaa_binding, v);
    2571                 :       7742 :         return mark_julia_type(ctx, v, true, bnd->ty);
    2572                 :            :     }
    2573                 :            :     // todo: use type info to avoid undef check
    2574                 :       1834 :     return emit_checked_var(ctx, bp, name, false, ctx.tbaa().tbaa_binding);
    2575                 :            : }
    2576                 :            : 
    2577                 :       2534 : static void emit_globalset(jl_codectx_t &ctx, jl_binding_t *bnd, Value *bp, const jl_cgval_t &rval_info, AtomicOrdering Order)
    2578                 :            : {
    2579                 :       2534 :     Value *rval = boxed(ctx, rval_info);
    2580   [ +  +  +  -  :       2534 :     if (bnd && !bnd->constp && bnd->ty && jl_subtype(rval_info.typ, bnd->ty)) {
          +  +  +  +  +  
                      + ]
    2581                 :       2310 :         StoreInst *v = ctx.builder.CreateAlignedStore(rval, julia_binding_pvalue(ctx, bp), Align(sizeof(void*)));
    2582                 :       2310 :         v->setOrdering(Order);
    2583                 :       2310 :         tbaa_decorate(ctx.tbaa().tbaa_binding, v);
    2584                 :       2310 :         emit_write_barrier_binding(ctx, bp, rval);
    2585                 :            :     }
    2586                 :            :     else {
    2587                 :        224 :         ctx.builder.CreateCall(prepare_call(jlcheckassign_func), { bp, mark_callee_rooted(ctx, rval) });
    2588                 :            :     }
    2589                 :       2534 : }
    2590                 :            : 
    2591                 :      76118 : static Value *emit_box_compare(jl_codectx_t &ctx, const jl_cgval_t &arg1, const jl_cgval_t &arg2,
    2592                 :            :                                Value *nullcheck1, Value *nullcheck2)
    2593                 :            : {
    2594                 :      76118 :     ++EmittedBoxCompares;
    2595   [ +  +  +  +  :      76118 :     if (jl_pointer_egal(arg1.typ) || jl_pointer_egal(arg2.typ)) {
                   +  + ]
    2596                 :            :         // if we can be certain we won't try to load from the pointer (because
    2597                 :            :         // we know boxed is trivial), we can skip the separate null checks
    2598                 :            :         // and just do the ICmpEQ test
    2599   [ +  +  +  - ]:      69986 :         if (!arg1.TIndex && !arg2.TIndex)
    2600                 :      69708 :             nullcheck1 = nullcheck2 = nullptr;
    2601                 :            :     }
    2602                 :     152236 :     return emit_nullcheck_guard2(ctx, nullcheck1, nullcheck2, [&] {
    2603                 :      76118 :         Value *varg1 = decay_derived(ctx, boxed(ctx, arg1));
    2604                 :      76118 :         Value *varg2 = decay_derived(ctx, boxed(ctx, arg2));
    2605   [ +  +  +  +  :      76118 :         if (jl_pointer_egal(arg1.typ) || jl_pointer_egal(arg2.typ)) {
                   +  + ]
    2606                 :      69986 :             return ctx.builder.CreateICmpEQ(varg1, varg2);
    2607                 :            :         }
    2608                 :       6132 :         Value *neq = ctx.builder.CreateICmpNE(varg1, varg2);
    2609                 :      12264 :         return emit_guarded_test(ctx, neq, true, [&] {
    2610                 :       6132 :             Value *dtarg = emit_typeof_boxed(ctx, arg1);
    2611                 :       6132 :             Value *dt_eq = ctx.builder.CreateICmpEQ(dtarg, emit_typeof_boxed(ctx, arg2));
    2612                 :       6132 :             return emit_guarded_test(ctx, dt_eq, false, [&] {
    2613                 :      24528 :                 return ctx.builder.CreateTrunc(ctx.builder.CreateCall(prepare_call(jlegalx_func),
    2614                 :      24528 :                                                                       {varg1, varg2, dtarg}), getInt1Ty(ctx.builder.getContext()));
    2615                 :       6132 :             });
    2616                 :       6132 :         });
    2617                 :      76118 :     });
    2618                 :            : }
    2619                 :            : 
    2620                 :            : static Value *emit_bits_compare(jl_codectx_t &ctx, jl_cgval_t arg1, jl_cgval_t arg2);
    2621                 :            : 
    2622                 :        127 : static Value *emit_bitsunion_compare(jl_codectx_t &ctx, const jl_cgval_t &arg1, const jl_cgval_t &arg2)
    2623                 :            : {
    2624                 :        127 :     ++EmittedBitsUnionCompares;
    2625   [ +  -  +  -  :        127 :     assert(jl_egal(arg1.typ, arg2.typ) && arg1.TIndex && arg2.TIndex && jl_is_uniontype(arg1.typ) && "unimplemented");
             +  -  +  - ]
    2626                 :        127 :     Value *tindex = arg1.TIndex;
    2627                 :        127 :     tindex = ctx.builder.CreateAnd(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x7f));
    2628                 :        127 :     Value *tindex2 = arg2.TIndex;
    2629                 :        127 :     tindex2 = ctx.builder.CreateAnd(tindex2, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x7f));
    2630                 :        127 :     Value *typeeq = ctx.builder.CreateICmpEQ(tindex, tindex2);
    2631                 :        127 :     tindex = ctx.builder.CreateSelect(typeeq, tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x00));
    2632                 :        127 :     BasicBlock *defaultBB = BasicBlock::Create(ctx.builder.getContext(), "unionbits_is_boxed", ctx.f);
    2633                 :        127 :     SwitchInst *switchInst = ctx.builder.CreateSwitch(tindex, defaultBB);
    2634                 :        127 :     BasicBlock *postBB = BasicBlock::Create(ctx.builder.getContext(), "post_unionbits_is", ctx.f);
    2635                 :        127 :     ctx.builder.SetInsertPoint(postBB);
    2636                 :        127 :     PHINode *phi = ctx.builder.CreatePHI(getInt1Ty(ctx.builder.getContext()), 2);
    2637                 :        127 :     switchInst->addCase(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0), postBB);
    2638                 :        127 :     phi->addIncoming(ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0), switchInst->getParent());
    2639                 :        127 :     unsigned counter = 0;
    2640                 :        127 :     bool allunboxed = for_each_uniontype_small(
    2641                 :        257 :         [&](unsigned idx, jl_datatype_t *jt) {
    2642                 :        257 :             BasicBlock *tempBB = BasicBlock::Create(ctx.builder.getContext(), "unionbits_is", ctx.f);
    2643                 :        257 :             ctx.builder.SetInsertPoint(tempBB);
    2644                 :        257 :             switchInst->addCase(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), idx), tempBB);
    2645                 :        257 :             jl_cgval_t sel_arg1(arg1, (jl_value_t*)jt, NULL);
    2646                 :        257 :             jl_cgval_t sel_arg2(arg2, (jl_value_t*)jt, NULL);
    2647                 :        257 :             Value *cmp = emit_bits_compare(ctx, sel_arg1, sel_arg2);
    2648                 :        257 :             tempBB = ctx.builder.GetInsertBlock(); // could have changed
    2649                 :        257 :             phi->addIncoming(cmp, tempBB);
    2650                 :        257 :             ctx.builder.CreateBr(postBB);
    2651                 :        257 :         },
    2652                 :        127 :         arg1.typ,
    2653                 :            :         counter);
    2654         [ -  + ]:        127 :     assert(allunboxed); (void)allunboxed;
    2655                 :        127 :     ctx.builder.SetInsertPoint(defaultBB);
    2656                 :        254 :     Function *trap_func = Intrinsic::getDeclaration(
    2657                 :        127 :         ctx.f->getParent(),
    2658                 :            :         Intrinsic::trap);
    2659                 :        127 :     ctx.builder.CreateCall(trap_func);
    2660                 :        127 :     ctx.builder.CreateUnreachable();
    2661                 :        127 :     ctx.builder.SetInsertPoint(postBB);
    2662                 :        127 :     return phi;
    2663                 :            : }
    2664                 :            : 
    2665                 :    1267840 : static Value *emit_bits_compare(jl_codectx_t &ctx, jl_cgval_t arg1, jl_cgval_t arg2)
    2666                 :            : {
    2667                 :    1267840 :     ++EmittedBitsCompares;
    2668                 :            :     bool isboxed;
    2669                 :    1267840 :     Type *at = julia_type_to_llvm(ctx, arg1.typ, &isboxed);
    2670   [ +  -  +  -  :    1267840 :     assert(jl_is_datatype(arg1.typ) && arg1.typ == arg2.typ && !isboxed);
                   +  - ]
    2671                 :            : 
    2672         [ +  + ]:    1267840 :     if (type_is_ghost(at))
    2673                 :        129 :         return ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 1);
    2674                 :            : 
    2675   [ +  +  +  -  :    1267710 :     if (at->isIntegerTy() || at->isPointerTy() || at->isFloatingPointTy()) {
             +  +  +  + ]
    2676                 :    1248600 :         Type *at_int = INTT(at);
    2677                 :    1248600 :         Value *varg1 = emit_unbox(ctx, at_int, arg1, arg1.typ);
    2678                 :    1248600 :         Value *varg2 = emit_unbox(ctx, at_int, arg2, arg2.typ);
    2679                 :    1248600 :         return ctx.builder.CreateICmpEQ(varg1, varg2);
    2680                 :            :     }
    2681                 :            : 
    2682         [ +  + ]:      19107 :     if (at->isVectorTy()) {
    2683                 :          1 :         jl_svec_t *types = ((jl_datatype_t*)arg1.typ)->types;
    2684                 :          1 :         Value *answer = ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 1);
    2685                 :          1 :         Value *varg1 = emit_unbox(ctx, at, arg1, arg1.typ);
    2686                 :          1 :         Value *varg2 = emit_unbox(ctx, at, arg2, arg2.typ);
    2687         [ +  + ]:          3 :         for (size_t i = 0, l = jl_svec_len(types); i < l; i++) {
    2688                 :          2 :             jl_value_t *fldty = jl_svecref(types, i);
    2689                 :            :             Value *subAns, *fld1, *fld2;
    2690                 :          2 :             fld1 = ctx.builder.CreateExtractElement(varg1, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), i)),
    2691                 :          2 :             fld2 = ctx.builder.CreateExtractElement(varg2, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), i)),
    2692                 :          2 :             subAns = emit_bits_compare(ctx,
    2693                 :            :                     mark_julia_type(ctx, fld1, false, fldty),
    2694                 :            :                     mark_julia_type(ctx, fld2, false, fldty));
    2695                 :          2 :             answer = ctx.builder.CreateAnd(answer, subAns);
    2696                 :            :         }
    2697                 :          1 :         return answer;
    2698                 :            :     }
    2699                 :            : 
    2700         [ +  - ]:      19106 :     if (at->isAggregateType()) { // Struct or Array
    2701                 :      19106 :         jl_datatype_t *sty = (jl_datatype_t*)arg1.typ;
    2702                 :      19106 :         size_t sz = jl_datatype_size(sty);
    2703   [ +  +  +  - ]:      19106 :         if (sz > 512 && !sty->layout->haspadding) {
    2704         [ +  - ]:          2 :             Value *varg1 = arg1.ispointer() ? data_pointer(ctx, arg1) :
    2705                 :          0 :                 value_to_pointer(ctx, arg1).V;
    2706         [ +  - ]:          2 :             Value *varg2 = arg2.ispointer() ? data_pointer(ctx, arg2) :
    2707                 :          0 :                 value_to_pointer(ctx, arg2).V;
    2708                 :          2 :             varg1 = emit_pointer_from_objref(ctx, varg1);
    2709                 :          2 :             varg2 = emit_pointer_from_objref(ctx, varg2);
    2710                 :            :             Value *gc_uses[2];
    2711                 :          2 :             int nroots = 0;
    2712         [ +  + ]:          2 :             if ((gc_uses[nroots] = get_gc_root_for(arg1)))
    2713                 :          1 :                 nroots++;
    2714         [ -  + ]:          2 :             if ((gc_uses[nroots] = get_gc_root_for(arg2)))
    2715                 :          0 :                 nroots++;
    2716                 :          4 :             OperandBundleDef OpBundle("jl_roots", makeArrayRef(gc_uses, nroots));
    2717         [ +  + ]:          4 :             auto answer = ctx.builder.CreateCall(prepare_call(memcmp_func), {
    2718                 :          2 :                         ctx.builder.CreateBitCast(varg1, getInt8PtrTy(ctx.builder.getContext())),
    2719                 :          2 :                         ctx.builder.CreateBitCast(varg2, getInt8PtrTy(ctx.builder.getContext())),
    2720                 :          2 :                         ConstantInt::get(getSizeTy(ctx.builder.getContext()), sz) },
    2721                 :            :                     ArrayRef<OperandBundleDef>(&OpBundle, nroots ? 1 : 0));
    2722                 :          2 :             MDNode *tbaa = nullptr;
    2723         [ -  + ]:          2 :             if (!arg1.tbaa) {
    2724                 :          0 :                 tbaa = arg2.tbaa;
    2725                 :            :             }
    2726         [ -  + ]:          2 :             else if (!arg2.tbaa) {
    2727                 :          0 :                 tbaa = arg1.tbaa;
    2728                 :            :             }
    2729                 :            :             else {
    2730                 :          2 :                 tbaa = MDNode::getMostGenericTBAA(arg1.tbaa, arg2.tbaa);
    2731                 :            :             }
    2732         [ +  - ]:          2 :             if (tbaa)
    2733                 :          2 :                 tbaa_decorate(tbaa, answer);
    2734                 :          2 :             return ctx.builder.CreateICmpEQ(answer, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0));
    2735                 :            :         }
    2736                 :            :         else {
    2737                 :      19104 :             jl_svec_t *types = sty->types;
    2738                 :      19104 :             Value *answer = ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 1);
    2739         [ +  + ]:      53018 :             for (size_t i = 0, l = jl_svec_len(types); i < l; i++) {
    2740                 :      33914 :                 jl_value_t *fldty = jl_svecref(types, i);
    2741         [ +  + ]:      33914 :                 if (type_is_ghost(julia_type_to_llvm(ctx, fldty)))
    2742                 :         14 :                     continue;
    2743                 :      33900 :                 Value *nullcheck1 = nullptr;
    2744                 :      33900 :                 Value *nullcheck2 = nullptr;
    2745                 :      33900 :                 auto fld1 = emit_getfield_knownidx(ctx, arg1, i, sty, jl_memory_order_notatomic, &nullcheck1);
    2746                 :      33900 :                 auto fld2 = emit_getfield_knownidx(ctx, arg2, i, sty, jl_memory_order_notatomic, &nullcheck2);
    2747                 :            :                 Value *fld_answer;
    2748   [ +  +  +  +  :      33900 :                 if (jl_field_isptr(sty, i) && jl_is_concrete_immutable(fldty)) {
                   +  + ]
    2749                 :            :                     // concrete immutables that are !isinlinealloc might be reference cycles
    2750                 :            :                     // issue #37872
    2751                 :          1 :                     fld_answer = emit_box_compare(ctx, fld1, fld2, nullcheck1, nullcheck2);
    2752                 :            :                 }
    2753                 :            :                 else {
    2754                 :      33899 :                     fld_answer = emit_f_is(ctx, fld1, fld2, nullcheck1, nullcheck2);
    2755                 :            :                 }
    2756                 :      33900 :                 answer = ctx.builder.CreateAnd(answer, fld_answer);
    2757                 :            :             }
    2758                 :      19104 :             return answer;
    2759                 :            :         }
    2760                 :            :     }
    2761                 :          0 :     assert(0 && "what is this llvm type?");
    2762                 :            :     abort();
    2763                 :            : }
    2764                 :            : 
    2765                 :            : // emit code for is (===).
    2766                 :            : // If either `nullcheck1` or `nullcheck2` are non-NULL, they are pointer values
    2767                 :            : // representing the undef-ness of `arg1` and `arg2`.
    2768                 :            : // This can only happen when comparing two fields of the same time and the result should be
    2769                 :            : // true if both are NULL
    2770                 :            : // Like the runtime counterpart, this is codegen guaranteed to be non-allocating and to exclude safepoints
    2771                 :    1424830 : static Value *emit_f_is(jl_codectx_t &ctx, const jl_cgval_t &arg1, const jl_cgval_t &arg2,
    2772                 :            :                         Value *nullcheck1, Value *nullcheck2)
    2773                 :            : {
    2774                 :    1424830 :     ++EmittedEgals;
    2775                 :            :     // handle simple static expressions with no side-effects
    2776   [ +  +  +  + ]:    1424830 :     if (arg1.constant && arg2.constant)
    2777                 :      38249 :         return ConstantInt::get(getInt1Ty(ctx.builder.getContext()), jl_egal(arg1.constant, arg2.constant));
    2778                 :            : 
    2779                 :    1386580 :     jl_value_t *rt1 = arg1.typ;
    2780                 :    1386580 :     jl_value_t *rt2 = arg2.typ;
    2781   [ +  +  +  +  :    1386580 :     if (jl_is_concrete_type(rt1) && jl_is_concrete_type(rt2) && !jl_is_kind(rt1) && !jl_is_kind(rt2) && rt1 != rt2) {
          +  +  +  -  +  
                +  +  + ]
    2782                 :            :         // disjoint concrete leaf types are never equal (quick test)
    2783                 :          8 :         return ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0);
    2784                 :            :     }
    2785                 :            : 
    2786   [ +  +  +  +  :    1386570 :     if (arg1.isghost || arg2.isghost || arg1.constant == jl_bottom_type ||
                   +  - ]
    2787         [ +  + ]:    1350340 :         arg2.constant == jl_bottom_type) {
    2788                 :            :         // comparing to a singleton object, special case for value `jl_bottom_type`
    2789                 :            :         // since it is normalized to `::Type{Union{}}` instead...
    2790         [ +  + ]:      42123 :         if (arg1.TIndex)
    2791                 :      10440 :             return emit_nullcheck_guard(ctx, nullcheck1, [&] {
    2792                 :       5220 :                 return emit_exactly_isa(ctx, arg1, rt2); // rt2 is a singleton type
    2793                 :       5220 :             });
    2794         [ +  + ]:      36903 :         if (arg2.TIndex)
    2795                 :         34 :             return emit_nullcheck_guard(ctx, nullcheck2, [&] {
    2796                 :         17 :                 return emit_exactly_isa(ctx, arg2, rt1); // rt1 is a singleton type
    2797                 :         17 :             });
    2798   [ +  +  +  -  :      36886 :         if (!(arg1.isboxed || arg1.constant) || !(arg2.isboxed || arg2.constant))
             +  +  -  + ]
    2799                 :            :             // not TIndex && not boxed implies it is an unboxed value of a different type from this singleton
    2800                 :            :             // (which was probably caught above, but just to be safe, we repeat it here explicitly)
    2801                 :          0 :             return ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0);
    2802         [ +  + ]:      36886 :         Value *varg1 = arg1.constant ? literal_pointer_val(ctx, arg1.constant) : maybe_bitcast(ctx, arg1.Vboxed, ctx.types().T_pjlvalue);
    2803         [ +  + ]:      36886 :         Value *varg2 = arg2.constant ? literal_pointer_val(ctx, arg2.constant) : maybe_bitcast(ctx, arg2.Vboxed, ctx.types().T_pjlvalue);
    2804                 :            :         // rooting these values isn't needed since we won't load this pointer
    2805                 :            :         // and we know at least one of them is a unique Singleton
    2806                 :            :         // which is already enough to ensure pointer uniqueness for this test
    2807                 :            :         // even if the other pointer managed to get garbage collected
    2808                 :            :         // TODO: use emit_pointer_from_objref instead, per comment above
    2809                 :      36886 :         return ctx.builder.CreateICmpEQ(decay_derived(ctx, varg1), decay_derived(ctx, varg2));
    2810                 :            :     }
    2811                 :            : 
    2812         [ +  + ]:    1344450 :     if (jl_type_intersection(rt1, rt2) == (jl_value_t*)jl_bottom_type) // types are disjoint (exhaustive test)
    2813                 :          1 :         return ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0);
    2814                 :            : 
    2815                 :    1344450 :     bool justbits1 = jl_is_concrete_immutable(rt1);
    2816                 :    1344450 :     bool justbits2 = jl_is_concrete_immutable(rt2);
    2817   [ +  +  +  + ]:    1344450 :     if (justbits1 || justbits2) { // whether this type is unique'd by value
    2818                 :    2536410 :         return emit_nullcheck_guard2(ctx, nullcheck1, nullcheck2, [&] () -> Value* {
    2819         [ +  + ]:    1268200 :             jl_value_t *typ = justbits1 ? rt1 : rt2;
    2820         [ +  + ]:    1268200 :             if (typ == (jl_value_t*)jl_bool_type) { // aka jl_pointer_egal
    2821                 :            :                 // some optimizations for bool, since pointer comparison may be better
    2822   [ +  +  -  +  :     102317 :                 if ((arg1.isboxed || arg1.constant) && (arg2.isboxed || arg2.constant)) { // aka have-fast-pointer
             +  +  -  + ]
    2823         [ -  + ]:        627 :                     Value *varg1 = arg1.constant ? literal_pointer_val(ctx, arg1.constant) : maybe_bitcast(ctx, arg1.Vboxed, ctx.types().T_pjlvalue);
    2824         [ +  + ]:        627 :                     Value *varg2 = arg2.constant ? literal_pointer_val(ctx, arg2.constant) : maybe_bitcast(ctx, arg2.Vboxed, ctx.types().T_pjlvalue);
    2825                 :        627 :                     return ctx.builder.CreateICmpEQ(decay_derived(ctx, varg1), decay_derived(ctx, varg2));
    2826                 :            :                 }
    2827                 :            :             }
    2828         [ +  + ]:    1267580 :             if (rt1 == rt2)
    2829                 :    1264840 :                 return emit_bits_compare(ctx, arg1, arg2);
    2830         [ +  + ]:       2737 :             Value *same_type = emit_exactly_isa(ctx, (typ == rt2 ? arg1 : arg2), typ);
    2831                 :       2737 :             BasicBlock *currBB = ctx.builder.GetInsertBlock();
    2832                 :       2737 :             BasicBlock *isaBB = BasicBlock::Create(ctx.builder.getContext(), "is", ctx.f);
    2833                 :       2737 :             BasicBlock *postBB = BasicBlock::Create(ctx.builder.getContext(), "post_is", ctx.f);
    2834                 :       2737 :             ctx.builder.CreateCondBr(same_type, isaBB, postBB);
    2835                 :       2737 :             ctx.builder.SetInsertPoint(isaBB);
    2836                 :       2737 :             Value *bitcmp = emit_bits_compare(ctx, jl_cgval_t(arg1, typ, NULL),
    2837                 :            :                                               jl_cgval_t(arg2, typ, NULL));
    2838                 :       2737 :             isaBB = ctx.builder.GetInsertBlock(); // might have changed
    2839                 :       2737 :             ctx.builder.CreateBr(postBB);
    2840                 :       2737 :             ctx.builder.SetInsertPoint(postBB);
    2841                 :       2737 :             PHINode *cmp = ctx.builder.CreatePHI(getInt1Ty(ctx.builder.getContext()), 2);
    2842                 :       2737 :             cmp->addIncoming(ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0), currBB);
    2843                 :       2737 :             cmp->addIncoming(bitcmp, isaBB);
    2844                 :       2737 :             return cmp;
    2845                 :    1268200 :         });
    2846                 :            :     }
    2847                 :            : 
    2848                 :            :     // TODO: handle the case where arg1.typ is not exactly arg2.typ, or when
    2849                 :            :     // one of these isn't union, or when the union can be pointer
    2850   [ +  +  +  + ]:        412 :     if (arg1.TIndex && arg2.TIndex && jl_egal(arg1.typ, arg2.typ) &&
    2851   [ +  +  +  -  :      76656 :         jl_is_uniontype(arg1.typ) && is_uniontype_allunboxed(arg1.typ))
             +  +  +  + ]
    2852                 :        254 :         return emit_nullcheck_guard2(ctx, nullcheck1, nullcheck2, [&] {
    2853                 :        127 :             return emit_bitsunion_compare(ctx, arg1, arg2);
    2854                 :        127 :         });
    2855                 :            : 
    2856                 :      76117 :     return emit_box_compare(ctx, arg1, arg2, nullcheck1, nullcheck2);
    2857                 :            : }
    2858                 :            : 
    2859                 :        178 : static bool emit_f_opglobal(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
    2860                 :            :                             const jl_cgval_t *argv, size_t nargs, const jl_cgval_t *modifyop)
    2861                 :            : {
    2862                 :        178 :     const jl_cgval_t &mod = argv[1];
    2863                 :        178 :     const jl_cgval_t &sym = argv[2];
    2864                 :        178 :     const jl_cgval_t &val = argv[3];
    2865                 :        178 :     enum jl_memory_order order = jl_memory_order_unspecified;
    2866                 :            : 
    2867         [ +  + ]:        178 :     if (nargs == 4) {
    2868                 :         13 :         const jl_cgval_t &arg4 = argv[4];
    2869   [ +  +  +  - ]:         13 :         if (arg4.constant && jl_is_symbol(arg4.constant))
    2870                 :         12 :             order = jl_get_atomic_order((jl_sym_t*)arg4.constant, false, true);
    2871                 :            :         else
    2872                 :          1 :             return false;
    2873                 :            :     }
    2874                 :            :     else
    2875                 :        165 :         order = jl_memory_order_monotonic;
    2876                 :            : 
    2877   [ +  -  -  + ]:        177 :     if (order == jl_memory_order_invalid || order == jl_memory_order_notatomic) {
    2878         [ #  # ]:          0 :         emit_atomic_error(ctx, order == jl_memory_order_invalid ? "invalid atomic ordering" : "setglobal!: module binding cannot be written non-atomically");
    2879                 :          0 :         *ret = jl_cgval_t(); // unreachable
    2880                 :          0 :         return true;
    2881                 :            :     }
    2882                 :            : 
    2883   [ +  +  +  - ]:        177 :     if (sym.constant && jl_is_symbol(sym.constant)) {
    2884                 :        137 :         jl_sym_t *name = (jl_sym_t*)sym.constant;
    2885   [ +  +  +  - ]:        137 :         if (mod.constant && jl_is_module(mod.constant)) {
    2886                 :        125 :             jl_binding_t *bnd = NULL;
    2887                 :        125 :             Value *bp = global_binding_pointer(ctx, (jl_module_t*)mod.constant, name, &bnd, true);
    2888         [ +  - ]:        125 :             if (bp) {
    2889                 :        125 :                 emit_globalset(ctx, bnd, bp, val, get_llvm_atomic_order(order));
    2890                 :        125 :                 *ret = val;
    2891                 :            :             }
    2892                 :            :             else {
    2893                 :          0 :                 *ret = jl_cgval_t(); // unreachable
    2894                 :            :             }
    2895                 :        125 :             return true;
    2896                 :            :         }
    2897                 :            :     }
    2898                 :            : 
    2899                 :         52 :     return false;
    2900                 :            : }
    2901                 :            : 
    2902                 :     113674 : static bool emit_f_opfield(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
    2903                 :            :                            const jl_cgval_t *argv, size_t nargs, const jl_cgval_t *modifyop)
    2904                 :            : {
    2905                 :     113674 :     ++EmittedOpfields;
    2906                 :     113674 :     bool issetfield = f == jl_builtin_setfield;
    2907                 :     113674 :     bool isreplacefield = f == jl_builtin_replacefield;
    2908                 :     113674 :     bool isswapfield = f == jl_builtin_swapfield;
    2909                 :     113674 :     bool ismodifyfield = f == jl_builtin_modifyfield;
    2910                 :     113674 :     const jl_cgval_t undefval;
    2911                 :     113674 :     const jl_cgval_t &obj = argv[1];
    2912                 :     113674 :     const jl_cgval_t &fld = argv[2];
    2913   [ +  +  +  + ]:     113674 :     jl_cgval_t val = argv[isreplacefield || ismodifyfield ? 4 : 3];
    2914   [ +  +  +  + ]:     113674 :     const jl_cgval_t &cmp = isreplacefield || ismodifyfield ? argv[3] : undefval;
    2915                 :     113674 :     enum jl_memory_order order = jl_memory_order_notatomic;
    2916   [ +  +  +  +  :     227348 :     const std::string fname = issetfield ? "setfield!" : isreplacefield ? "replacefield!" : isswapfield ? "swapfield!" : "modifyfield!";
                   +  + ]
    2917   [ +  +  +  +  :     113674 :     if (nargs >= (isreplacefield || ismodifyfield ? 5 : 4)) {
                   +  + ]
    2918   [ +  +  +  + ]:      11504 :         const jl_cgval_t &ord = argv[isreplacefield || ismodifyfield ? 5 : 4];
    2919                 :      11504 :         emit_typecheck(ctx, ord, (jl_value_t*)jl_symbol_type, fname);
    2920         [ +  + ]:      11504 :         if (!ord.constant)
    2921                 :          4 :             return false;
    2922                 :      11500 :         order = jl_get_atomic_order((jl_sym_t*)ord.constant, !issetfield, true);
    2923                 :            :     }
    2924                 :     113670 :     enum jl_memory_order fail_order = order;
    2925   [ +  +  +  + ]:     113670 :     if (isreplacefield && nargs == 6) {
    2926                 :       6183 :         const jl_cgval_t &ord = argv[6];
    2927                 :       6183 :         emit_typecheck(ctx, ord, (jl_value_t*)jl_symbol_type, fname);
    2928         [ -  + ]:       6183 :         if (!ord.constant)
    2929                 :          0 :             return false;
    2930                 :       6183 :         fail_order = jl_get_atomic_order((jl_sym_t*)ord.constant, true, false);
    2931                 :            :     }
    2932   [ +  +  +  +  :     113670 :     if (order == jl_memory_order_invalid || fail_order == jl_memory_order_invalid || fail_order > order) {
                   +  + ]
    2933                 :        352 :         emit_atomic_error(ctx, "invalid atomic ordering");
    2934                 :        352 :         *ret = jl_cgval_t(); // unreachable
    2935                 :        352 :         return true;
    2936                 :            :     }
    2937                 :            : 
    2938                 :     113318 :     jl_datatype_t *uty = (jl_datatype_t*)jl_unwrap_unionall(obj.typ);
    2939   [ +  -  +  +  :     113318 :     if (jl_is_datatype(uty) && jl_struct_try_layout(uty)) {
                   +  + ]
    2940                 :     112859 :         ssize_t idx = -1;
    2941   [ +  +  +  + ]:     112859 :         if (fld.constant && jl_is_symbol(fld.constant)) {
    2942                 :     110484 :             idx = jl_field_index(uty, (jl_sym_t*)fld.constant, 0);
    2943                 :            :         }
    2944   [ +  +  +  - ]:       2375 :         else if (fld.constant && fld.typ == (jl_value_t*)jl_long_type) {
    2945                 :          5 :             ssize_t i = jl_unbox_long(fld.constant);
    2946   [ +  -  +  - ]:          5 :             if (i > 0 && i <= (ssize_t)jl_datatype_nfields(uty))
    2947                 :          5 :                 idx = i - 1;
    2948                 :            :         }
    2949         [ +  + ]:     112859 :         if (idx != -1) {
    2950                 :     110489 :             jl_value_t *ft = jl_field_type(uty, idx);
    2951         [ +  - ]:     110489 :             if (!jl_has_free_typevars(ft)) {
    2952         [ +  + ]:     110489 :                 if (!ismodifyfield) {
    2953                 :     110337 :                     emit_typecheck(ctx, val, ft, fname);
    2954                 :     110337 :                     val = update_julia_type(ctx, val, ft);
    2955         [ -  + ]:     110337 :                     if (val.typ == jl_bottom_type)
    2956                 :          0 :                         return true;
    2957                 :            :                 }
    2958                 :            :                 // TODO: attempt better codegen for approximate types
    2959                 :     110489 :                 bool isboxed = jl_field_isptr(uty, idx);
    2960                 :     110489 :                 bool isatomic = jl_field_isatomic(uty, idx);
    2961   [ +  +  +  +  :     110489 :                 bool needlock = isatomic && !isboxed && jl_datatype_size(jl_field_type(uty, idx)) > MAX_ATOMIC_SIZE;
                   +  + ]
    2962                 :     110489 :                 *ret = jl_cgval_t();
    2963         [ +  + ]:     110489 :                 if (isatomic == (order == jl_memory_order_notatomic)) {
    2964   [ +  +  +  + ]:        480 :                     emit_atomic_error(ctx,
    2965                 :            :                             issetfield ?
    2966                 :            :                             (isatomic ? "setfield!: atomic field cannot be written non-atomically"
    2967                 :            :                                       : "setfield!: non-atomic field cannot be written atomically") :
    2968   [ +  +  +  + ]:        350 :                             isreplacefield ?
    2969                 :            :                             (isatomic ? "replacefield!: atomic field cannot be written non-atomically"
    2970                 :            :                                       : "replacefield!: non-atomic field cannot be written atomically") :
    2971   [ +  +  +  +  :        140 :                             isswapfield ?
                   +  + ]
    2972                 :            :                             (isatomic ? "swapfield!: atomic field cannot be written non-atomically"
    2973                 :            :                                       : "swapfield!: non-atomic field cannot be written atomically") :
    2974                 :            :                             (isatomic ? "modifyfield!: atomic field cannot be written non-atomically"
    2975                 :            :                                       : "modifyfield!: non-atomic field cannot be written atomically"));
    2976                 :            :                 }
    2977         [ +  + ]:     110219 :                 else if (isatomic == (fail_order == jl_memory_order_notatomic)) {
    2978         [ +  - ]:         50 :                     emit_atomic_error(ctx,
    2979                 :            :                             (isatomic ? "replacefield!: atomic field cannot be accessed non-atomically"
    2980                 :            :                                       : "replacefield!: non-atomic field cannot be accessed atomically"));
    2981                 :            :                 }
    2982         [ -  + ]:     110169 :                 else if (!uty->name->mutabl) {
    2983                 :          0 :                     std::string msg = fname + ": immutable struct of type "
    2984                 :          0 :                         + std::string(jl_symbol_name(uty->name->name))
    2985                 :          0 :                         + " cannot be changed";
    2986                 :          0 :                     emit_error(ctx, msg);
    2987                 :            :                 }
    2988         [ +  + ]:     110169 :                 else if (jl_field_isconst(uty, idx)) {
    2989                 :          6 :                     std::string msg = fname + ": const field ."
    2990                 :         12 :                         + std::string(jl_symbol_name((jl_sym_t*)jl_svec_ref(jl_field_names(uty), idx)))
    2991                 :          6 :                         + " of type "
    2992                 :         12 :                         + std::string(jl_symbol_name(uty->name->name))
    2993                 :          6 :                         + " cannot be changed";
    2994                 :          3 :                     emit_error(ctx, msg);
    2995                 :            :                 }
    2996                 :            :                 else {
    2997                 :            :                     *ret = emit_setfield(ctx, uty, obj, idx, val, cmp, true,
    2998         [ +  + ]:     110142 :                             (needlock || order <= jl_memory_order_notatomic)
    2999                 :            :                                 ? AtomicOrdering::NotAtomic
    3000                 :      10700 :                                 : get_llvm_atomic_order(order),
    3001         [ +  + ]:     110142 :                             (needlock || fail_order <= jl_memory_order_notatomic)
    3002                 :            :                                 ? AtomicOrdering::NotAtomic
    3003                 :      10700 :                                 : get_llvm_atomic_order(fail_order),
    3004                 :            :                             needlock, issetfield, isreplacefield, isswapfield, ismodifyfield,
    3005   [ +  +  +  + ]:     330450 :                             modifyop, fname);
    3006                 :            :                 }
    3007                 :     110489 :                 return true;
    3008                 :            :             }
    3009                 :            :         }
    3010                 :            :     }
    3011                 :       2829 :     return false;
    3012                 :            : }
    3013                 :            : 
    3014                 :            : static jl_llvm_functions_t
    3015                 :            :     emit_function(
    3016                 :            :         orc::ThreadSafeModule &TSM,
    3017                 :            :         jl_method_instance_t *lam,
    3018                 :            :         jl_code_info_t *src,
    3019                 :            :         jl_value_t *jlrettype,
    3020                 :            :         jl_codegen_params_t &params);
    3021                 :            : 
    3022                 :    7963650 : static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
    3023                 :            :                               const jl_cgval_t *argv, size_t nargs, jl_value_t *rt,
    3024                 :            :                               jl_expr_t *ex, bool is_promotable)
    3025                 :            : // returns true if the call has been handled
    3026                 :            : {
    3027                 :    7963650 :     ++EmittedBuiltinCalls;
    3028   [ +  +  +  - ]:    7963650 :     if (f == jl_builtin_is && nargs == 2) {
    3029                 :            :         // emit comparison test
    3030                 :    1390830 :         Value *ans = emit_f_is(ctx, argv[1], argv[2]);
    3031                 :    1390830 :         *ret = mark_julia_type(ctx, ctx.builder.CreateZExt(ans, getInt8Ty(ctx.builder.getContext())), false, jl_bool_type);
    3032                 :    1390830 :         return true;
    3033                 :            :     }
    3034                 :            : 
    3035   [ +  +  +  - ]:    6572820 :     else if (f == jl_builtin_typeof && nargs == 1) {
    3036                 :      12693 :         *ret = emit_typeof(ctx, argv[1], false);
    3037                 :      12693 :         return true;
    3038                 :            :     }
    3039                 :            : 
    3040   [ +  +  +  - ]:    6560130 :     else if (f == jl_builtin_typeassert && nargs == 2) {
    3041                 :      37793 :         const jl_cgval_t &arg = argv[1];
    3042                 :      37793 :         const jl_cgval_t &ty = argv[2];
    3043   [ +  +  +  -  :      37793 :         if (jl_is_type_type(ty.typ) && !jl_has_free_typevars(ty.typ)) {
                   +  + ]
    3044                 :      37143 :             jl_value_t *tp0 = jl_tparam0(ty.typ);
    3045                 :      37143 :             emit_typecheck(ctx, arg, tp0, "typeassert");
    3046                 :      37143 :             *ret = update_julia_type(ctx, arg, tp0);
    3047                 :      37143 :             return true;
    3048                 :            :         }
    3049         [ +  + ]:        650 :         if (jl_subtype(ty.typ, (jl_value_t*)jl_type_type)) {
    3050                 :        548 :             Value *rt_arg = boxed(ctx, arg);
    3051                 :        548 :             Value *rt_ty = boxed(ctx, ty);
    3052                 :        548 :             ctx.builder.CreateCall(prepare_call(jltypeassert_func), {rt_arg, rt_ty});
    3053                 :        548 :             *ret = arg;
    3054                 :        548 :             return true;
    3055                 :        102 :         }
    3056                 :            :     }
    3057                 :            : 
    3058   [ +  +  +  - ]:    6522330 :     else if (f == jl_builtin_isa && nargs == 2) {
    3059                 :     206536 :         const jl_cgval_t &arg = argv[1];
    3060                 :     206536 :         const jl_cgval_t &ty = argv[2];
    3061   [ +  +  +  -  :     206536 :         if (jl_is_type_type(ty.typ) && !jl_has_free_typevars(ty.typ)) {
                   +  + ]
    3062                 :     205885 :             jl_value_t *tp0 = jl_tparam0(ty.typ);
    3063                 :     205885 :             Value *isa_result = emit_isa(ctx, arg, tp0, NULL).first;
    3064         [ +  - ]:     205885 :             if (isa_result->getType() == getInt1Ty(ctx.builder.getContext()))
    3065                 :     205885 :                 isa_result = ctx.builder.CreateZExt(isa_result, getInt8Ty(ctx.builder.getContext()));
    3066                 :     205885 :             *ret = mark_julia_type(ctx, isa_result, false, jl_bool_type);
    3067                 :     205885 :             return true;
    3068                 :        651 :         }
    3069                 :            :     }
    3070                 :            : 
    3071   [ +  +  +  - ]:    6315800 :     else if (f == jl_builtin_issubtype && nargs == 2) {
    3072                 :       5952 :         const jl_cgval_t &ta = argv[1];
    3073                 :       5952 :         const jl_cgval_t &tb = argv[2];
    3074   [ +  -  -  + ]:       6592 :         if (jl_is_type_type(ta.typ) && !jl_has_free_typevars(ta.typ) &&
    3075   [ +  +  -  -  :       6592 :             jl_is_type_type(tb.typ) && !jl_has_free_typevars(tb.typ)) {
                   -  + ]
    3076                 :          0 :             int issub = jl_subtype(jl_tparam0(ta.typ), jl_tparam0(tb.typ));
    3077                 :          0 :             *ret = mark_julia_type(ctx, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), issub), false, jl_bool_type);
    3078                 :          0 :             return true;
    3079                 :       5952 :         }
    3080                 :            :     }
    3081                 :            : 
    3082   [ +  +  +  +  :    6309850 :     else if ((f == jl_builtin__apply_iterate && nargs == 3) && ctx.vaSlot > 0) {
                   +  + ]
    3083                 :            :         // turn Core._apply_iterate(iter, f, Tuple) ==> f(Tuple...) using the jlcall calling convention if Tuple is the va allocation
    3084         [ +  + ]:       2471 :         if (LoadInst *load = dyn_cast_or_null<LoadInst>(argv[3].V)) {
    3085   [ +  -  +  -  :       1808 :             if (load->getPointerOperand() == ctx.slots[ctx.vaSlot].boxroot && ctx.argArray) {
                   +  - ]
    3086                 :       1808 :                 Value *theF = boxed(ctx, argv[2]);
    3087                 :       1808 :                 Value *nva = emit_n_varargs(ctx);
    3088                 :            : #ifdef _P64
    3089                 :       1808 :                 nva = ctx.builder.CreateTrunc(nva, getInt32Ty(ctx.builder.getContext()));
    3090                 :            : #endif
    3091                 :       1808 :                 Value *theArgs = ctx.builder.CreateInBoundsGEP(ctx.types().T_prjlvalue, ctx.argArray, ConstantInt::get(getSizeTy(ctx.builder.getContext()), ctx.nReqArgs));
    3092                 :       1808 :                 Value *r = ctx.builder.CreateCall(prepare_call(jlapplygeneric_func), { theF, theArgs, nva });
    3093                 :       1808 :                 *ret = mark_julia_type(ctx, r, true, jl_any_type);
    3094                 :       1808 :                 return true;
    3095                 :            :             }
    3096                 :        663 :         }
    3097                 :            :     }
    3098                 :            : 
    3099         [ +  + ]:    6307380 :     else if (f == jl_builtin_tuple) {
    3100         [ +  + ]:     458624 :         if (nargs == 0) {
    3101                 :        387 :             *ret = ghostValue(ctx, jl_emptytuple_type);
    3102                 :        387 :             return true;
    3103                 :            :         }
    3104   [ +  +  +  +  :     458237 :         if (jl_is_tuple_type(rt) && jl_is_concrete_type(rt) && nargs == jl_datatype_nfields(rt)) {
             +  -  +  + ]
    3105                 :     440957 :             *ret = emit_new_struct(ctx, rt, nargs, &argv[1], is_promotable);
    3106                 :     440957 :             return true;
    3107                 :            :         }
    3108                 :            :     }
    3109                 :            : 
    3110   [ +  +  +  - ]:    5848750 :     else if (f == jl_builtin_throw && nargs == 1) {
    3111                 :     294093 :         Value *arg1 = boxed(ctx, argv[1]);
    3112                 :     294093 :         raise_exception(ctx, arg1);
    3113                 :     294093 :         *ret = jl_cgval_t();
    3114                 :     294093 :         return true;
    3115                 :            :     }
    3116                 :            : 
    3117   [ +  +  +  - ]:    5554660 :     else if (f == jl_builtin_arraysize && nargs == 2) {
    3118                 :     551711 :         const jl_cgval_t &ary = argv[1];
    3119                 :     551711 :         const jl_cgval_t &idx = argv[2];
    3120                 :     551711 :         jl_value_t *aty = jl_unwrap_unionall(ary.typ);
    3121   [ +  -  +  +  :     551711 :         if (jl_is_array_type(aty) && idx.typ == (jl_value_t*)jl_long_type) {
                   +  + ]
    3122                 :     551710 :             jl_value_t *ndp = jl_tparam1(aty);
    3123         [ +  + ]:     551710 :             if (jl_is_long(ndp)) {
    3124                 :     551698 :                 size_t ndims = jl_unbox_long(ndp);
    3125         [ +  + ]:     551698 :                 if (idx.constant) {
    3126                 :     539387 :                     uint32_t idx_const = (uint32_t)jl_unbox_long(idx.constant);
    3127   [ +  -  +  + ]:     539387 :                     if (idx_const > 0 && idx_const <= ndims) {
    3128                 :     537664 :                         jl_value_t *ary_ex = jl_exprarg(ex, 1);
    3129                 :     537664 :                         *ret = mark_julia_type(ctx, emit_arraysize(ctx, ary, ary_ex, idx_const), false, jl_long_type);
    3130                 :     537664 :                         return true;
    3131                 :            :                     }
    3132         [ +  - ]:       1723 :                     else if (idx_const > ndims) {
    3133                 :       1723 :                         *ret = mark_julia_type(ctx, ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1), false, jl_long_type);
    3134                 :       1723 :                         return true;
    3135                 :            :                     }
    3136                 :            :                 }
    3137                 :            :                 else {
    3138                 :      12311 :                     Value *idx_dyn = emit_unbox(ctx, getSizeTy(ctx.builder.getContext()), idx, (jl_value_t*)jl_long_type);
    3139                 :      12311 :                     error_unless(ctx, ctx.builder.CreateICmpSGT(idx_dyn, Constant::getNullValue(getSizeTy(ctx.builder.getContext()))),
    3140                 :            :                                  "arraysize: dimension out of range");
    3141                 :      12311 :                     BasicBlock *outBB = BasicBlock::Create(ctx.builder.getContext(), "outofrange", ctx.f);
    3142                 :      12311 :                     BasicBlock *inBB = BasicBlock::Create(ctx.builder.getContext(), "inrange");
    3143                 :      12311 :                     BasicBlock *ansBB = BasicBlock::Create(ctx.builder.getContext(), "arraysize");
    3144                 :      24622 :                     ctx.builder.CreateCondBr(ctx.builder.CreateICmpSLE(idx_dyn,
    3145                 :      12311 :                                 ConstantInt::get(getSizeTy(ctx.builder.getContext()), ndims)),
    3146                 :            :                             inBB, outBB);
    3147                 :      12311 :                     ctx.builder.SetInsertPoint(outBB);
    3148                 :      12311 :                     Value *v_one = ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1);
    3149                 :      12311 :                     ctx.builder.CreateBr(ansBB);
    3150                 :      12311 :                     ctx.f->getBasicBlockList().push_back(inBB);
    3151                 :      12311 :                     ctx.builder.SetInsertPoint(inBB);
    3152                 :      12311 :                     Value *v_sz = emit_arraysize(ctx, ary, idx_dyn);
    3153                 :      12311 :                     ctx.builder.CreateBr(ansBB);
    3154                 :      12311 :                     inBB = ctx.builder.GetInsertBlock(); // could have changed
    3155                 :      12311 :                     ctx.f->getBasicBlockList().push_back(ansBB);
    3156                 :      12311 :                     ctx.builder.SetInsertPoint(ansBB);
    3157                 :      12311 :                     PHINode *result = ctx.builder.CreatePHI(getSizeTy(ctx.builder.getContext()), 2);
    3158                 :      12311 :                     result->addIncoming(v_one, outBB);
    3159                 :      12311 :                     result->addIncoming(v_sz, inBB);
    3160                 :      12311 :                     *ret = mark_julia_type(ctx, result, false, jl_long_type);
    3161                 :      12311 :                     return true;
    3162                 :            :                 }
    3163                 :            :             }
    3164                 :         13 :         }
    3165                 :            :     }
    3166                 :            : 
    3167   [ +  +  +  +  :    5002950 :     else if ((f == jl_builtin_arrayref || f == jl_builtin_const_arrayref) && nargs >= 3) {
                   +  - ]
    3168                 :     680383 :         const jl_cgval_t &ary = argv[2];
    3169                 :     680383 :         bool indices_ok = true;
    3170         [ +  + ]:    1676940 :         for (size_t i = 3; i <= nargs; i++) {
    3171         [ -  + ]:     996553 :             if (argv[i].typ != (jl_value_t*)jl_long_type) {
    3172                 :          0 :                 indices_ok = false;
    3173                 :          0 :                 break;
    3174                 :            :             }
    3175                 :            :         }
    3176                 :     680383 :         jl_value_t *aty_dt = jl_unwrap_unionall(ary.typ);
    3177   [ +  +  +  -  :     680383 :         if (jl_is_array_type(aty_dt) && indices_ok) {
                   +  + ]
    3178                 :     680376 :             jl_value_t *ety = jl_tparam0(aty_dt);
    3179                 :     680376 :             jl_value_t *ndp = jl_tparam1(aty_dt);
    3180   [ +  +  -  +  :     680376 :             if (!jl_has_free_typevars(ety) && (jl_is_long(ndp) || nargs == 3)) {
             -  -  +  + ]
    3181                 :     680375 :                 jl_value_t *ary_ex = jl_exprarg(ex, 2);
    3182                 :     680375 :                 size_t elsz = 0, al = 0;
    3183                 :     680375 :                 int union_max = jl_islayout_inline(ety, &elsz, &al);
    3184                 :     680375 :                 bool isboxed = (union_max == 0);
    3185         [ +  + ]:     680375 :                 if (isboxed)
    3186                 :      91783 :                     ety = (jl_value_t*)jl_any_type;
    3187         [ +  - ]:     680375 :                 ssize_t nd = jl_is_long(ndp) ? jl_unbox_long(ndp) : -1;
    3188                 :     680375 :                 jl_value_t *boundscheck = argv[1].constant;
    3189                 :     680375 :                 emit_typecheck(ctx, argv[1], (jl_value_t*)jl_bool_type, "arrayref");
    3190                 :     680375 :                 Value *idx = emit_array_nd_index(ctx, ary, ary_ex, nd, &argv[3], nargs - 2, boundscheck);
    3191   [ +  +  +  +  :     680375 :                 if (!isboxed && jl_is_datatype(ety) && jl_datatype_size(ety) == 0) {
                   +  + ]
    3192         [ -  + ]:       1437 :                     assert(((jl_datatype_t*)ety)->instance != NULL);
    3193                 :       1437 :                     *ret = ghostValue(ctx, ety);
    3194                 :            :                 }
    3195   [ +  +  +  + ]:     678938 :                 else if (!isboxed && jl_is_uniontype(ety)) {
    3196                 :       2018 :                     Value *data = emit_arrayptr(ctx, ary, ary_ex);
    3197                 :       2018 :                     Value *offset = emit_arrayoffset(ctx, ary, nd);
    3198                 :            :                     Value *ptindex;
    3199         [ -  + ]:       2018 :                     if (elsz == 0) {
    3200                 :          0 :                         ptindex = data;
    3201                 :            :                     }
    3202                 :            :                     else {
    3203                 :       2018 :                         Type *AT = ArrayType::get(IntegerType::get(ctx.builder.getContext(), 8 * al), (elsz + al - 1) / al);
    3204                 :       2018 :                         data = emit_bitcast(ctx, data, AT->getPointerTo());
    3205                 :            :                         // isbits union selector bytes are stored after a->maxsize
    3206         [ -  + ]:       2018 :                         Value *ndims = (nd == -1 ? emit_arrayndims(ctx, ary) : ConstantInt::get(getInt16Ty(ctx.builder.getContext()), nd));
    3207                 :       2018 :                         Value *is_vector = ctx.builder.CreateICmpEQ(ndims, ConstantInt::get(getInt16Ty(ctx.builder.getContext()), 1));
    3208                 :       2018 :                         Value *selidx_v = ctx.builder.CreateSub(emit_vectormaxsize(ctx, ary), ctx.builder.CreateZExt(offset, getSizeTy(ctx.builder.getContext())));
    3209                 :       2018 :                         Value *selidx_m = emit_arraylen(ctx, ary);
    3210                 :       2018 :                         Value *selidx = ctx.builder.CreateSelect(is_vector, selidx_v, selidx_m);
    3211                 :       2018 :                         ptindex = ctx.builder.CreateInBoundsGEP(AT, data, selidx);
    3212                 :       2018 :                         data = ctx.builder.CreateInBoundsGEP(AT, data, idx);
    3213                 :            :                     }
    3214                 :       2018 :                     ptindex = emit_bitcast(ctx, ptindex, getInt8PtrTy(ctx.builder.getContext()));
    3215                 :       2018 :                     ptindex = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), ptindex, offset);
    3216                 :       2018 :                     ptindex = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), ptindex, idx);
    3217                 :       2018 :                     *ret = emit_unionload(ctx, data, ptindex, ety, elsz, al, ctx.tbaa().tbaa_arraybuf, true, union_max, ctx.tbaa().tbaa_arrayselbyte);
    3218                 :            :                 }
    3219                 :            :                 else {
    3220         [ +  + ]:     676920 :                     MDNode *aliasscope = (f == jl_builtin_const_arrayref) ? ctx.aliasscope : nullptr;
    3221                 :            :                     *ret = typed_load(ctx,
    3222                 :            :                             emit_arrayptr(ctx, ary, ary_ex),
    3223                 :            :                             idx, ety,
    3224                 :     676920 :                             isboxed ? ctx.tbaa().tbaa_ptrarraybuf : ctx.tbaa().tbaa_arraybuf,
    3225                 :            :                             aliasscope,
    3226                 :            :                             isboxed,
    3227         [ +  + ]:    1353840 :                             AtomicOrdering::NotAtomic);
    3228                 :            :                 }
    3229                 :     680375 :                 return true;
    3230                 :            :             }
    3231                 :          8 :         }
    3232                 :            :     }
    3233                 :            : 
    3234   [ +  +  +  - ]:    4322560 :     else if (f == jl_builtin_arrayset && nargs >= 4) {
    3235                 :     198653 :         const jl_cgval_t &ary = argv[2];
    3236                 :     198653 :         jl_cgval_t val = argv[3];
    3237                 :     198653 :         bool indices_ok = true;
    3238         [ +  + ]:     455755 :         for (size_t i = 4; i <= nargs; i++) {
    3239         [ +  + ]:     257103 :             if (argv[i].typ != (jl_value_t*)jl_long_type) {
    3240                 :          1 :                 indices_ok = false;
    3241                 :          1 :                 break;
    3242                 :            :             }
    3243                 :            :         }
    3244                 :     198653 :         jl_value_t *aty_dt = jl_unwrap_unionall(ary.typ);
    3245   [ +  +  +  +  :     198653 :         if (jl_is_array_type(aty_dt) && indices_ok) {
                   +  + ]
    3246                 :     198648 :             jl_value_t *ety = jl_tparam0(aty_dt);
    3247                 :     198648 :             jl_value_t *ndp = jl_tparam1(aty_dt);
    3248   [ +  +  +  +  :     198648 :             if (!jl_has_free_typevars(ety) && (jl_is_long(ndp) || nargs == 4)) {
             +  -  +  + ]
    3249                 :     198647 :                 emit_typecheck(ctx, val, ety, "arrayset");
    3250                 :     198647 :                 val = update_julia_type(ctx, val, ety);
    3251         [ +  + ]:     198647 :                 if (val.typ == jl_bottom_type)
    3252                 :          1 :                     return true;
    3253                 :     198646 :                 size_t elsz = 0, al = 0;
    3254                 :     198646 :                 int union_max = jl_islayout_inline(ety, &elsz, &al);
    3255                 :     198646 :                 bool isboxed = (union_max == 0);
    3256         [ +  + ]:     198646 :                 if (isboxed)
    3257                 :      41176 :                     ety = (jl_value_t*)jl_any_type;
    3258                 :     198646 :                 jl_value_t *ary_ex = jl_exprarg(ex, 2);
    3259         [ +  + ]:     198646 :                 ssize_t nd = jl_is_long(ndp) ? jl_unbox_long(ndp) : -1;
    3260                 :     198646 :                 jl_value_t *boundscheck = argv[1].constant;
    3261                 :     198646 :                 emit_typecheck(ctx, argv[1], (jl_value_t*)jl_bool_type, "arrayset");
    3262                 :     198646 :                 Value *idx = emit_array_nd_index(ctx, ary, ary_ex, nd, &argv[4], nargs - 3, boundscheck);
    3263   [ +  +  +  +  :     198646 :                 if (!isboxed && jl_is_datatype(ety) && jl_datatype_size(ety) == 0) {
                   +  + ]
    3264                 :            :                     // no-op
    3265                 :            :                 }
    3266                 :            :                 else {
    3267                 :     196473 :                     PHINode *data_owner = NULL; // owner object against which the write barrier must check
    3268   [ +  +  +  +  :     196473 :                     if (isboxed || (jl_is_datatype(ety) && ((jl_datatype_t*)ety)->layout->npointers > 0)) { // if elements are just bits, don't need a write barrier
                   +  + ]
    3269                 :      51160 :                         Value *aryv = boxed(ctx, ary);
    3270                 :      51160 :                         Value *flags = emit_arrayflags(ctx, ary);
    3271                 :            :                         // the owner of the data is ary itself except if ary->how == 3
    3272                 :      51160 :                         flags = ctx.builder.CreateAnd(flags, 3);
    3273                 :      51160 :                         Value *is_owned = ctx.builder.CreateICmpEQ(flags, ConstantInt::get(getInt16Ty(ctx.builder.getContext()), 3));
    3274                 :      51160 :                         BasicBlock *curBB = ctx.builder.GetInsertBlock();
    3275                 :      51160 :                         BasicBlock *ownedBB = BasicBlock::Create(ctx.builder.getContext(), "array_owned", ctx.f);
    3276                 :      51160 :                         BasicBlock *mergeBB = BasicBlock::Create(ctx.builder.getContext(), "merge_own", ctx.f);
    3277                 :      51160 :                         ctx.builder.CreateCondBr(is_owned, ownedBB, mergeBB);
    3278                 :      51160 :                         ctx.builder.SetInsertPoint(ownedBB);
    3279                 :            :                         // load owner pointer
    3280                 :            :                         Instruction *own_ptr;
    3281         [ +  + ]:      51160 :                         if (jl_is_long(ndp)) {
    3282                 :     204632 :                             own_ptr = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue,
    3283                 :      51158 :                                     ctx.builder.CreateConstInBoundsGEP1_32(ctx.types().T_prjlvalue,
    3284                 :      51158 :                                         emit_bitcast(ctx, decay_derived(ctx, aryv), ctx.types().T_pprjlvalue),
    3285                 :      51158 :                                         jl_array_data_owner_offset(nd) / sizeof(jl_value_t*)),
    3286                 :      51158 :                                     Align(sizeof(void*)));
    3287                 :      51158 :                             tbaa_decorate(ctx.tbaa().tbaa_const, maybe_mark_load_dereferenceable(own_ptr, false, (jl_value_t*)jl_array_any_type));
    3288                 :            :                         }
    3289                 :            :                         else {
    3290                 :          4 :                             own_ptr = ctx.builder.CreateCall(
    3291                 :          2 :                                 prepare_call(jlarray_data_owner_func),
    3292                 :            :                                 {aryv});
    3293                 :            :                         }
    3294                 :      51160 :                         ctx.builder.CreateBr(mergeBB);
    3295                 :      51160 :                         ctx.builder.SetInsertPoint(mergeBB);
    3296                 :      51160 :                         data_owner = ctx.builder.CreatePHI(ctx.types().T_prjlvalue, 2);
    3297                 :      51160 :                         data_owner->addIncoming(aryv, curBB);
    3298                 :      51160 :                         data_owner->addIncoming(own_ptr, ownedBB);
    3299                 :            :                     }
    3300   [ +  +  +  + ]:     196473 :                     if (!isboxed && jl_is_uniontype(ety)) {
    3301                 :       2022 :                         Type *AT = ArrayType::get(IntegerType::get(ctx.builder.getContext(), 8 * al), (elsz + al - 1) / al);
    3302                 :       2022 :                         Value *data = emit_bitcast(ctx, emit_arrayptr(ctx, ary, ary_ex), AT->getPointerTo());
    3303                 :       2022 :                         Value *offset = emit_arrayoffset(ctx, ary, nd);
    3304                 :            :                         // compute tindex from val
    3305                 :       2022 :                         jl_cgval_t rhs_union = convert_julia_type(ctx, val, ety);
    3306                 :       2022 :                         Value *tindex = compute_tindex_unboxed(ctx, rhs_union, ety);
    3307                 :       2022 :                         tindex = ctx.builder.CreateNUWSub(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 1));
    3308                 :            :                         Value *ptindex;
    3309         [ +  + ]:       2022 :                         if (elsz == 0) {
    3310                 :         11 :                             ptindex = data;
    3311                 :            :                         }
    3312                 :            :                         else {
    3313         [ -  + ]:       2011 :                             Value *ndims = (nd == -1 ? emit_arrayndims(ctx, ary) : ConstantInt::get(getInt16Ty(ctx.builder.getContext()), nd));
    3314                 :       2011 :                             Value *is_vector = ctx.builder.CreateICmpEQ(ndims, ConstantInt::get(getInt16Ty(ctx.builder.getContext()), 1));
    3315                 :       2011 :                             Value *selidx_v = ctx.builder.CreateSub(emit_vectormaxsize(ctx, ary), ctx.builder.CreateZExt(offset, getSizeTy(ctx.builder.getContext())));
    3316                 :       2011 :                             Value *selidx_m = emit_arraylen(ctx, ary);
    3317                 :       2011 :                             Value *selidx = ctx.builder.CreateSelect(is_vector, selidx_v, selidx_m);
    3318                 :       2011 :                             ptindex = ctx.builder.CreateInBoundsGEP(AT, data, selidx);
    3319                 :       2011 :                             data = ctx.builder.CreateInBoundsGEP(AT, data, idx);
    3320                 :            :                         }
    3321                 :       2022 :                         ptindex = emit_bitcast(ctx, ptindex, getInt8PtrTy(ctx.builder.getContext()));
    3322                 :       2022 :                         ptindex = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), ptindex, offset);
    3323                 :       2022 :                         ptindex = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), ptindex, idx);
    3324                 :       2022 :                         tbaa_decorate(ctx.tbaa().tbaa_arrayselbyte, ctx.builder.CreateStore(tindex, ptindex));
    3325   [ +  +  +  -  :       2022 :                         if (elsz > 0 && (!jl_is_datatype(val.typ) || jl_datatype_size(val.typ) > 0)) {
                   +  + ]
    3326                 :            :                             // copy data (if any)
    3327                 :       1246 :                             emit_unionmove(ctx, data, ctx.tbaa().tbaa_arraybuf, val, nullptr);
    3328                 :       2022 :                         }
    3329                 :            :                     }
    3330                 :            :                     else {
    3331                 :     194451 :                         typed_store(ctx,
    3332                 :            :                                     emit_arrayptr(ctx, ary, ary_ex, isboxed),
    3333                 :            :                                     idx, val, jl_cgval_t(), ety,
    3334                 :     194451 :                                     isboxed ? ctx.tbaa().tbaa_ptrarraybuf : ctx.tbaa().tbaa_arraybuf,
    3335                 :            :                                     ctx.aliasscope,
    3336                 :            :                                     data_owner,
    3337                 :            :                                     isboxed,
    3338                 :            :                                     isboxed ? AtomicOrdering::Release : AtomicOrdering::NotAtomic, // TODO: we should do this for anything with CountTrackedPointers(elty).count > 0
    3339                 :            :                                     /*FailOrder*/AtomicOrdering::NotAtomic, // TODO: we should do this for anything with CountTrackedPointers(elty).count > 0
    3340                 :            :                                     0,
    3341                 :            :                                     false,
    3342                 :            :                                     true,
    3343                 :            :                                     false,
    3344                 :            :                                     false,
    3345                 :            :                                     false,
    3346                 :            :                                     false,
    3347                 :            :                                     nullptr,
    3348   [ +  +  +  + ]:     388902 :                                     "");
    3349                 :            :                     }
    3350                 :            :                 }
    3351                 :     198646 :                 *ret = ary;
    3352                 :     198646 :                 return true;
    3353                 :            :             }
    3354                 :          6 :         }
    3355                 :            :     }
    3356                 :            : 
    3357   [ +  +  +  +  :    4123910 :     else if (f == jl_builtin_getfield && (nargs == 2 || nargs == 3 || nargs == 4)) {
             +  +  +  + ]
    3358                 :    3869520 :         const jl_cgval_t &obj = argv[1];
    3359                 :    3869520 :         const jl_cgval_t &fld = argv[2];
    3360                 :    3869520 :         enum jl_memory_order order = jl_memory_order_unspecified;
    3361                 :    3869520 :         jl_value_t *boundscheck = jl_true;
    3362                 :            : 
    3363         [ +  + ]:    3869520 :         if (nargs == 4) {
    3364                 :          1 :             const jl_cgval_t &ord = argv[3];
    3365                 :          1 :             const jl_cgval_t &inb = argv[4];
    3366                 :          1 :             emit_typecheck(ctx, ord, (jl_value_t*)jl_symbol_type, "getfield");
    3367                 :          1 :             emit_typecheck(ctx, inb, (jl_value_t*)jl_bool_type, "getfield");
    3368         [ -  + ]:          1 :             if (!ord.constant)
    3369                 :          0 :                 return false;
    3370                 :          1 :             order = jl_get_atomic_order((jl_sym_t*)ord.constant, true, false);
    3371         [ -  + ]:          1 :             if (inb.constant == jl_false)
    3372                 :          0 :                 boundscheck = jl_false;
    3373                 :            :         }
    3374         [ +  + ]:    3869520 :         else if (nargs == 3) {
    3375                 :     241812 :             const jl_cgval_t &arg3 = argv[3];
    3376   [ +  +  +  + ]:     241812 :             if (arg3.constant && jl_is_symbol(arg3.constant))
    3377                 :      13333 :                 order = jl_get_atomic_order((jl_sym_t*)arg3.constant, true, false);
    3378         [ +  + ]:     228479 :             else if (arg3.constant == jl_false)
    3379                 :      13810 :                 boundscheck = jl_false;
    3380         [ +  + ]:     214669 :             else if (arg3.typ != (jl_value_t*)jl_bool_type)
    3381                 :          1 :                 return false;
    3382                 :            :         }
    3383         [ +  + ]:    3869520 :         if (order == jl_memory_order_invalid) {
    3384                 :         66 :             emit_atomic_error(ctx, "invalid atomic ordering");
    3385                 :         66 :             *ret = jl_cgval_t(); // unreachable
    3386                 :         66 :             return true;
    3387                 :            :         }
    3388                 :            : 
    3389                 :    3869450 :         jl_datatype_t *utt = (jl_datatype_t*)jl_unwrap_unionall(obj.typ);
    3390   [ +  +  +  +  :    3869450 :         if (jl_is_type_type((jl_value_t*)utt) && jl_is_concrete_type(jl_tparam0(utt)))
                   +  + ]
    3391                 :      48000 :             utt = (jl_datatype_t*)jl_typeof(jl_tparam0(utt));
    3392                 :            : 
    3393   [ +  +  +  + ]:    3869450 :         if (fld.constant && jl_is_symbol(fld.constant)) {
    3394                 :    3209600 :             jl_sym_t *name = (jl_sym_t*)fld.constant;
    3395   [ +  +  +  + ]:    3209600 :             if (obj.constant && jl_is_module(obj.constant)) {
    3396         [ -  + ]:        578 :                 *ret = emit_globalref(ctx, (jl_module_t*)obj.constant, name, order == jl_memory_order_unspecified ? AtomicOrdering::Unordered : get_llvm_atomic_order(order));
    3397                 :        578 :                 return true;
    3398                 :            :             }
    3399                 :            : 
    3400   [ +  +  +  +  :    3209020 :             if (jl_is_datatype(utt) && jl_struct_try_layout(utt)) {
                   +  + ]
    3401                 :    3200880 :                 ssize_t idx = jl_field_index(utt, name, 0);
    3402   [ +  +  +  +  :    3200880 :                 if (idx != -1 && !jl_has_free_typevars(jl_field_type(utt, idx))) {
                   +  + ]
    3403                 :    3199630 :                     *ret = emit_getfield_knownidx(ctx, obj, idx, utt, order);
    3404                 :    3199630 :                     return true;
    3405                 :            :                 }
    3406                 :       9391 :             }
    3407                 :            :         }
    3408         [ +  + ]:     659848 :         else if (fld.typ == (jl_value_t*)jl_long_type) {
    3409         [ +  + ]:     657851 :             if (ctx.vaSlot > 0) {
    3410                 :            :                 // optimize VA tuple
    3411         [ +  + ]:     112121 :                 if (LoadInst *load = dyn_cast_or_null<LoadInst>(obj.V)) {
    3412   [ +  +  +  +  :      15708 :                     if (load->getPointerOperand() == ctx.slots[ctx.vaSlot].boxroot && ctx.argArray) {
                   +  + ]
    3413                 :       8892 :                         Value *valen = emit_n_varargs(ctx);
    3414                 :            :                         jl_cgval_t va_ary( // fake instantiation of a cgval, in order to call emit_bounds_check (it only checks the `.V` field)
    3415                 :       8892 :                                 ctx.builder.CreateInBoundsGEP(ctx.types().T_prjlvalue, ctx.argArray, ConstantInt::get(getSizeTy(ctx.builder.getContext()), ctx.nReqArgs)),
    3416                 :      17784 :                                 NULL, NULL);
    3417                 :       8892 :                         Value *idx = emit_unbox(ctx, getSizeTy(ctx.builder.getContext()), fld, (jl_value_t*)jl_long_type);
    3418                 :       8892 :                         idx = emit_bounds_check(ctx, va_ary, NULL, idx, valen, boundscheck);
    3419                 :       8892 :                         idx = ctx.builder.CreateAdd(idx, ConstantInt::get(getSizeTy(ctx.builder.getContext()), ctx.nReqArgs));
    3420                 :       8892 :                         Instruction *v = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, ctx.builder.CreateInBoundsGEP(ctx.types().T_prjlvalue, ctx.argArray, idx), Align(sizeof(void*)));
    3421                 :            :                         // if we know the result type of this load, we will mark that information here too
    3422                 :       8892 :                         tbaa_decorate(ctx.tbaa().tbaa_value, maybe_mark_load_dereferenceable(v, false, rt));
    3423                 :       8892 :                         *ret = mark_julia_type(ctx, v, /*boxed*/ true, rt);
    3424                 :       8892 :                         return true;
    3425                 :            :                     }
    3426                 :            :                 }
    3427                 :            :             }
    3428                 :            : 
    3429         [ +  + ]:     648959 :             if (jl_is_datatype(utt)) {
    3430         [ +  + ]:     648941 :                 if (jl_struct_try_layout(utt)) {
    3431                 :     630155 :                     size_t nfields = jl_datatype_nfields(utt);
    3432                 :            :                     // integer index
    3433                 :            :                     size_t idx;
    3434   [ +  +  +  +  :     630155 :                     if (fld.constant && (idx = jl_unbox_long(fld.constant) - 1) < nfields) {
                   +  + ]
    3435         [ +  - ]:     574776 :                         if (!jl_has_free_typevars(jl_field_type(utt, idx))) {
    3436                 :            :                             // known index
    3437                 :     574776 :                             *ret = emit_getfield_knownidx(ctx, obj, idx, utt, order);
    3438                 :     574776 :                             return true;
    3439                 :            :                         }
    3440                 :            :                     }
    3441                 :            :                     else {
    3442                 :            :                         // unknown index
    3443                 :      55379 :                         Value *vidx = emit_unbox(ctx, getSizeTy(ctx.builder.getContext()), fld, (jl_value_t*)jl_long_type);
    3444         [ +  + ]:      55379 :                         if (emit_getfield_unknownidx(ctx, ret, obj, vidx, utt, boundscheck, order)) {
    3445                 :      34845 :                             return true;
    3446                 :            :                         }
    3447                 :            :                     }
    3448                 :            :                 }
    3449   [ +  +  +  +  :      39320 :                 if (jl_is_tuple_type(utt) && is_tupletype_homogeneous(utt->parameters, true)) {
                   +  + ]
    3450                 :            :                     // For tuples, we can emit code even if we don't know the exact
    3451                 :            :                     // type (e.g. because we don't know the length). This is possible
    3452                 :            :                     // as long as we know that all elements are of the same (leaf) type.
    3453         [ +  - ]:        646 :                     if (obj.ispointer()) {
    3454   [ +  -  -  + ]:        646 :                         if (order != jl_memory_order_notatomic && order != jl_memory_order_unspecified) {
    3455                 :          0 :                             emit_atomic_error(ctx, "getfield: non-atomic field cannot be accessed atomically");
    3456                 :          0 :                             *ret = jl_cgval_t(); // unreachable
    3457                 :          0 :                             return true;
    3458                 :            :                         }
    3459                 :            :                         // Determine which was the type that was homogenous
    3460                 :        646 :                         jl_value_t *jt = jl_tparam0(utt);
    3461         [ +  + ]:        646 :                         if (jl_is_vararg(jt))
    3462                 :        466 :                             jt = jl_unwrap_vararg(jt);
    3463         [ -  + ]:        646 :                         assert(jl_is_datatype(jt));
    3464                 :        646 :                         Value *vidx = emit_unbox(ctx, getSizeTy(ctx.builder.getContext()), fld, (jl_value_t*)jl_long_type);
    3465                 :            :                         // This is not necessary for correctness, but allows to omit
    3466                 :            :                         // the extra code for getting the length of the tuple
    3467         [ +  + ]:        646 :                         if (!bounds_check_enabled(ctx, boundscheck)) {
    3468                 :        202 :                             vidx = ctx.builder.CreateSub(vidx, ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1));
    3469                 :            :                         } else {
    3470                 :        444 :                             vidx = emit_bounds_check(ctx, obj, (jl_value_t*)obj.typ, vidx,
    3471                 :            :                                 emit_datatype_nfields(ctx, emit_typeof_boxed(ctx, obj)),
    3472                 :            :                                 jl_true);
    3473                 :            :                         }
    3474                 :        646 :                         bool isboxed = !jl_datatype_isinlinealloc((jl_datatype_t*)jt, 0);
    3475                 :        646 :                         Value *ptr = data_pointer(ctx, obj);
    3476                 :            :                         *ret = typed_load(ctx, ptr, vidx,
    3477                 :            :                                 isboxed ? (jl_value_t*)jl_any_type : jt,
    3478         [ +  + ]:        646 :                                 obj.tbaa, nullptr, isboxed, AtomicOrdering::NotAtomic, false);
    3479                 :        646 :                         return true;
    3480                 :            :                     }
    3481                 :            :                 }
    3482                 :            :             }
    3483                 :            :         }
    3484                 :            :         // TODO: generic getfield func with more efficient calling convention
    3485                 :      50080 :         return false;
    3486                 :            :     }
    3487                 :            : 
    3488   [ +  +  -  +  :     254395 :     else if (f == jl_builtin_getglobal && (nargs == 2 || nargs == 3)) {
                   -  - ]
    3489                 :       1838 :         const jl_cgval_t &mod = argv[1];
    3490                 :       1838 :         const jl_cgval_t &sym = argv[2];
    3491                 :       1838 :         enum jl_memory_order order = jl_memory_order_unspecified;
    3492                 :            : 
    3493         [ -  + ]:       1838 :         if (nargs == 3) {
    3494                 :          0 :             const jl_cgval_t &arg3 = argv[3];
    3495   [ #  #  #  # ]:          0 :             if (arg3.constant && jl_is_symbol(arg3.constant))
    3496                 :          0 :                 order = jl_get_atomic_order((jl_sym_t*)arg3.constant, true, false);
    3497                 :            :             else
    3498                 :          0 :                 return false;
    3499                 :            :         }
    3500                 :            :         else
    3501                 :       1838 :             order = jl_memory_order_monotonic;
    3502                 :            : 
    3503   [ +  -  -  + ]:       1838 :         if (order == jl_memory_order_invalid || order == jl_memory_order_notatomic) {
    3504         [ #  # ]:          0 :             emit_atomic_error(ctx, order == jl_memory_order_invalid ? "invalid atomic ordering" : "getglobal: module binding cannot be read non-atomically");
    3505                 :          0 :             *ret = jl_cgval_t(); // unreachable
    3506                 :          0 :             return true;
    3507                 :            :         }
    3508                 :            : 
    3509   [ +  +  +  - ]:       1838 :         if (sym.constant && jl_is_symbol(sym.constant)) {
    3510                 :       1172 :             jl_sym_t *name = (jl_sym_t*)sym.constant;
    3511   [ +  +  +  - ]:       1172 :             if (mod.constant && jl_is_module(mod.constant)) {
    3512                 :        502 :                 *ret = emit_globalref(ctx, (jl_module_t*)mod.constant, name, get_llvm_atomic_order(order));
    3513                 :        502 :                 return true;
    3514                 :            :             }
    3515                 :            :         }
    3516                 :            : 
    3517                 :       1336 :         return false;
    3518                 :            :     }
    3519                 :            : 
    3520   [ +  +  +  +  :     252557 :     else if (f == jl_builtin_setglobal && (nargs == 3 || nargs == 4)) {
                   +  - ]
    3521                 :        178 :         return emit_f_opglobal(ctx, ret, f, argv, nargs, nullptr);
    3522                 :            :     }
    3523                 :            : 
    3524   [ +  +  +  +  :     252379 :     else if ((f == jl_builtin_setfield && (nargs == 3 || nargs == 4)) ||
                   -  + ]
    3525   [ +  +  +  +  :     147848 :              (f == jl_builtin_swapfield && (nargs == 3 || nargs == 4)) ||
                   -  + ]
    3526   [ +  +  +  +  :     145159 :              (f == jl_builtin_replacefield && (nargs == 4 || nargs == 5 || nargs == 6)) ||
             +  +  -  + ]
    3527   [ +  +  +  +  :     138918 :              (f == jl_builtin_modifyfield && (nargs == 4 || nargs == 5))) {
                   +  - ]
    3528                 :     113659 :         return emit_f_opfield(ctx, ret, f, argv, nargs, nullptr);
    3529                 :            :     }
    3530                 :            : 
    3531   [ +  +  +  - ]:     138720 :     else if (f == jl_builtin_nfields && nargs == 1) {
    3532                 :       7505 :         const jl_cgval_t &obj = argv[1];
    3533         [ +  + ]:       7505 :         if (ctx.vaSlot > 0) {
    3534                 :            :             // optimize VA tuple
    3535         [ +  + ]:       5247 :             if (LoadInst *load = dyn_cast_or_null<LoadInst>(obj.V)) {
    3536         [ +  + ]:       5226 :                 if (load->getPointerOperand() == ctx.slots[ctx.vaSlot].boxroot) {
    3537                 :       5188 :                     *ret = mark_julia_type(ctx, emit_n_varargs(ctx), false, jl_long_type);
    3538                 :       5188 :                     return true;
    3539                 :            :                 }
    3540                 :            :             }
    3541                 :            :         }
    3542                 :       2317 :         ssize_t nf = -1;
    3543         [ -  + ]:       2317 :         if (obj.constant) {
    3544                 :          0 :             nf = jl_datatype_nfields(jl_typeof(obj.constant));
    3545                 :            :         }
    3546         [ -  + ]:       2317 :         else if (jl_is_type_type(obj.typ)) {
    3547                 :          0 :             jl_value_t *tp0 = jl_tparam0(obj.typ);
    3548   [ #  #  #  #  :          0 :             if (jl_is_datatype(tp0) && jl_is_datatype_singleton((jl_datatype_t*)tp0))
                   #  # ]
    3549                 :          0 :                 nf = jl_datatype_nfields((jl_value_t*)jl_datatype_type);
    3550                 :            :         }
    3551         [ -  + ]:       2317 :         else if (jl_is_concrete_type(obj.typ)) {
    3552                 :          0 :             nf = jl_datatype_nfields(obj.typ);
    3553                 :            :         }
    3554                 :            :         Value *sz;
    3555         [ -  + ]:       2317 :         if (nf != -1)
    3556                 :          0 :             sz = ConstantInt::get(getSizeTy(ctx.builder.getContext()), nf);
    3557                 :            :         else
    3558                 :       2317 :             sz = emit_datatype_nfields(ctx, emit_typeof_boxed(ctx, obj));
    3559                 :       2317 :         *ret = mark_julia_type(ctx, sz, false, jl_long_type);
    3560                 :       2317 :         return true;
    3561                 :            :     }
    3562                 :            : 
    3563   [ +  +  -  +  :     131215 :     else if (f == jl_builtin_fieldtype && (nargs == 2 || nargs == 3)) {
                   -  - ]
    3564                 :       5821 :         const jl_cgval_t &typ = argv[1];
    3565                 :       5821 :         const jl_cgval_t &fld = argv[2];
    3566   [ +  +  +  +  :       6613 :         if ((jl_is_type_type(typ.typ) && jl_is_concrete_type(jl_tparam0(typ.typ))) ||
                   +  + ]
    3567   [ +  +  -  + ]:        792 :                 (typ.constant && jl_is_concrete_type(typ.constant))) {
    3568         [ +  + ]:       5029 :             if (fld.typ == (jl_value_t*)jl_long_type) {
    3569         [ -  + ]:       2358 :                 assert(typ.isboxed);
    3570                 :       2358 :                 Value *tyv = boxed(ctx, typ);
    3571                 :       2358 :                 Value *types_svec = emit_datatype_types(ctx, tyv);
    3572                 :       2358 :                 Value *types_len = emit_datatype_nfields(ctx, tyv);
    3573                 :       2358 :                 Value *idx = emit_unbox(ctx, getSizeTy(ctx.builder.getContext()), fld, (jl_value_t*)jl_long_type);
    3574         [ -  + ]:       2358 :                 jl_value_t *boundscheck = (nargs == 3 ? argv[3].constant : jl_true);
    3575         [ -  + ]:       2358 :                 if (nargs == 3)
    3576                 :          0 :                     emit_typecheck(ctx, argv[3], (jl_value_t*)jl_bool_type, "fieldtype");
    3577                 :       2358 :                 emit_bounds_check(ctx, typ, (jl_value_t*)jl_datatype_type, idx, types_len, boundscheck);
    3578                 :       2358 :                 Value *fieldtyp_p = ctx.builder.CreateInBoundsGEP(ctx.types().T_prjlvalue, decay_derived(ctx, emit_bitcast(ctx, types_svec, ctx.types().T_pprjlvalue)), idx);
    3579                 :       2358 :                 Value *fieldtyp = tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, fieldtyp_p, Align(sizeof(void*))));
    3580                 :       2358 :                 *ret = mark_julia_type(ctx, fieldtyp, true, (jl_value_t*)jl_type_type);
    3581                 :       2358 :                 return true;
    3582                 :            :             }
    3583                 :       3463 :         }
    3584                 :            :     }
    3585                 :            : 
    3586   [ +  +  +  - ]:     125394 :     else if (f == jl_builtin_sizeof && nargs == 1) {
    3587                 :      38950 :         const jl_cgval_t &obj = argv[1];
    3588                 :      38950 :         jl_datatype_t *sty = (jl_datatype_t*)jl_unwrap_unionall(obj.typ);
    3589         [ -  + ]:      38950 :         assert(jl_string_type->name->mutabl);
    3590   [ +  +  +  + ]:      38950 :         if (sty == jl_string_type || sty == jl_simplevector_type) {
    3591         [ +  + ]:      37240 :             if (obj.constant) {
    3592                 :            :                 size_t sz;
    3593         [ +  - ]:       7754 :                 if (sty == jl_string_type) {
    3594                 :       7754 :                     sz = jl_string_len(obj.constant);
    3595                 :            :                 }
    3596                 :            :                 else {
    3597                 :          0 :                     sz = (1 + jl_svec_len(obj.constant)) * sizeof(void*);
    3598                 :            :                 }
    3599                 :       7754 :                 *ret = mark_julia_type(ctx, ConstantInt::get(getSizeTy(ctx.builder.getContext()), sz), false, jl_long_type);
    3600                 :       7754 :                 return true;
    3601                 :            :             }
    3602                 :            :             // String and SimpleVector's length fields have the same layout
    3603                 :      29486 :             auto ptr = emit_bitcast(ctx, boxed(ctx, obj), getSizePtrTy(ctx.builder.getContext()));
    3604                 :      29486 :             Value *len = tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(getSizeTy(ctx.builder.getContext()), ptr, Align(sizeof(size_t))));
    3605                 :      29486 :             MDBuilder MDB(ctx.builder.getContext());
    3606         [ +  + ]:      29486 :             if (sty == jl_simplevector_type) {
    3607                 :          3 :                 auto rng = MDB.createRange(
    3608                 :          3 :                     Constant::getNullValue(getSizeTy(ctx.builder.getContext())), ConstantInt::get(getSizeTy(ctx.builder.getContext()), INTPTR_MAX / sizeof(void*) - 1));
    3609                 :          3 :                 cast<LoadInst>(len)->setMetadata(LLVMContext::MD_range, rng);
    3610                 :          3 :                 len = ctx.builder.CreateMul(len, ConstantInt::get(getSizeTy(ctx.builder.getContext()), sizeof(void*)));
    3611                 :          3 :                 len = ctx.builder.CreateAdd(len, ConstantInt::get(getSizeTy(ctx.builder.getContext()), sizeof(void*)));
    3612                 :            :             }
    3613                 :            :             else {
    3614                 :      29483 :                 auto rng = MDB.createRange(Constant::getNullValue(getSizeTy(ctx.builder.getContext())), ConstantInt::get(getSizeTy(ctx.builder.getContext()), INTPTR_MAX));
    3615                 :      29483 :                 cast<LoadInst>(len)->setMetadata(LLVMContext::MD_range, rng);
    3616                 :            :             }
    3617                 :      29486 :             *ret = mark_julia_type(ctx, len, false, jl_long_type);
    3618                 :      29486 :             return true;
    3619                 :            :         }
    3620         [ +  + ]:       1710 :         else if (jl_is_array_type(sty)) {
    3621                 :       1272 :             auto len = emit_arraylen(ctx, obj);
    3622                 :            :             Value *elsize;
    3623                 :            :             size_t elsz;
    3624         [ +  + ]:       1272 :             if (arraytype_constelsize(sty, &elsz)) {
    3625                 :       1270 :                 elsize = ConstantInt::get(getSizeTy(ctx.builder.getContext()), elsz);
    3626                 :            :             }
    3627                 :            :             else {
    3628                 :          2 :                 elsize = ctx.builder.CreateZExt(emit_arrayelsize(ctx, obj), getSizeTy(ctx.builder.getContext()));
    3629                 :            :             }
    3630                 :       1272 :             *ret = mark_julia_type(ctx, ctx.builder.CreateMul(len, elsize), false, jl_long_type);
    3631                 :       1272 :             return true;
    3632                 :        438 :         }
    3633                 :            :     }
    3634                 :            : 
    3635   [ +  +  +  - ]:      86444 :     else if (f == jl_builtin_apply_type && nargs > 0) {
    3636         [ +  + ]:      13392 :         if (jl_is_method(ctx.linfo->def.method)) {
    3637                 :            :             // don't bother codegen constant-folding for toplevel.
    3638                 :      12118 :             jl_value_t *ty = static_apply_type(ctx, argv, nargs + 1);
    3639         [ +  + ]:      12118 :             if (ty != NULL) {
    3640                 :        568 :                 jl_add_method_root(ctx, ty);
    3641                 :        568 :                 *ret = mark_julia_const(ctx, ty);
    3642                 :        568 :                 return true;
    3643                 :            :             }
    3644                 :      12824 :         }
    3645                 :            :     }
    3646                 :            : 
    3647   [ +  +  +  +  :      73052 :     else if (f == jl_builtin_isdefined && (nargs == 2 || nargs == 3)) {
                   +  - ]
    3648                 :      14107 :         const jl_cgval_t &obj = argv[1];
    3649                 :      14107 :         const jl_cgval_t &fld = argv[2];
    3650                 :      14107 :         jl_datatype_t *stt = (jl_datatype_t*)obj.typ;
    3651         [ -  + ]:      14107 :         if (jl_is_type_type((jl_value_t*)stt)) {
    3652                 :            :             // the representation type of Type{T} is either typeof(T), or unknown
    3653                 :            :             // TODO: could use `issingletontype` predicate here, providing better type knowledge
    3654                 :            :             // than only handling DataType
    3655         [ #  # ]:          0 :             if (jl_is_concrete_type(jl_tparam0(stt)))
    3656                 :          0 :                 stt = (jl_datatype_t*)jl_typeof(jl_tparam0(stt));
    3657                 :            :             else
    3658                 :          0 :                 return false;
    3659                 :            :         }
    3660   [ +  +  +  -  :      27470 :         if (!jl_is_concrete_type((jl_value_t*)stt) || jl_is_array_type(stt) ||
                   +  + ]
    3661         [ +  + ]:      13363 :             stt == jl_module_type) { // TODO: use ->layout here instead of concrete_type
    3662                 :       3069 :             return false;
    3663                 :            :         }
    3664         [ -  + ]:      11038 :         assert(jl_is_datatype(stt));
    3665                 :            : 
    3666                 :      11038 :         ssize_t fieldidx = -1;
    3667   [ +  +  +  + ]:      11038 :         if (fld.constant && jl_is_symbol(fld.constant)) {
    3668                 :      11005 :             jl_sym_t *sym = (jl_sym_t*)fld.constant;
    3669                 :      11005 :             fieldidx = jl_field_index(stt, sym, 0);
    3670                 :            :         }
    3671   [ +  +  +  - ]:         33 :         else if (fld.constant && fld.typ == (jl_value_t*)jl_long_type) {
    3672                 :          1 :             fieldidx = jl_unbox_long(fld.constant) - 1;
    3673                 :            :         }
    3674                 :            :         else {
    3675                 :         32 :             return false;
    3676                 :            :         }
    3677                 :      11006 :         enum jl_memory_order order = jl_memory_order_unspecified;
    3678         [ +  + ]:      11006 :         if (nargs == 3) {
    3679                 :        160 :             const jl_cgval_t &ord = argv[3];
    3680                 :        160 :             emit_typecheck(ctx, ord, (jl_value_t*)jl_symbol_type, "isdefined");
    3681         [ -  + ]:        160 :             if (!ord.constant)
    3682                 :          0 :                 return false;
    3683                 :        160 :             order = jl_get_atomic_order((jl_sym_t*)ord.constant, true, false);
    3684                 :            :         }
    3685         [ +  + ]:      11006 :         if (order == jl_memory_order_invalid) {
    3686                 :         60 :             emit_atomic_error(ctx, "invalid atomic ordering");
    3687                 :         60 :             *ret = jl_cgval_t(); // unreachable
    3688                 :         60 :             return true;
    3689                 :            :         }
    3690                 :      10946 :         ssize_t nf = jl_datatype_nfields(stt);
    3691   [ +  -  -  + ]:      10946 :         if (fieldidx < 0 || fieldidx >= nf) {
    3692         [ #  # ]:          0 :             if (order != jl_memory_order_unspecified) {
    3693                 :          0 :                 emit_atomic_error(ctx, "isdefined: atomic ordering cannot be specified for nonexistent field");
    3694                 :          0 :                 *ret = jl_cgval_t(); // unreachable
    3695                 :          0 :                 return true;
    3696                 :            :             }
    3697                 :          0 :             *ret = mark_julia_const(ctx, jl_false);
    3698                 :          0 :             return true;
    3699                 :            :         }
    3700                 :      10946 :         bool isatomic = jl_field_isatomic(stt, fieldidx);
    3701   [ +  +  +  +  :      10946 :         if (!isatomic && order != jl_memory_order_notatomic && order != jl_memory_order_unspecified) {
                   +  + ]
    3702                 :         40 :             emit_atomic_error(ctx, "isdefined: non-atomic field cannot be accessed atomically");
    3703                 :         40 :             *ret = jl_cgval_t(); // unreachable
    3704                 :         40 :             return true;
    3705                 :            :         }
    3706   [ +  +  +  + ]:      10906 :         if (isatomic && order == jl_memory_order_notatomic) {
    3707                 :         10 :             emit_atomic_error(ctx, "isdefined: atomic field cannot be accessed non-atomically");
    3708                 :         10 :             *ret = jl_cgval_t(); // unreachable
    3709                 :         10 :             return true;
    3710                 :            :         }
    3711         [ -  + ]:      10896 :         else if (fieldidx < nf - stt->name->n_uninitialized) {
    3712                 :          0 :             *ret = mark_julia_const(ctx, jl_true);
    3713                 :            :         }
    3714   [ +  +  +  +  :      10896 :         else if (jl_field_isptr(stt, fieldidx) || jl_type_hasptr(jl_field_type(stt, fieldidx))) {
                   +  + ]
    3715                 :            :             Value *fldv;
    3716                 :      10867 :             size_t offs = jl_field_offset(stt, fieldidx) / sizeof(jl_value_t*);
    3717                 :      10867 :             auto tbaa = obj.tbaa;
    3718   [ +  +  +  -  :      10867 :             if (tbaa == ctx.tbaa().tbaa_datatype && offs != offsetof(jl_datatype_t, types))
                   +  + ]
    3719                 :        121 :                 tbaa = ctx.tbaa().tbaa_const;
    3720         [ +  - ]:      10867 :             if (obj.ispointer()) {
    3721         [ +  + ]:      10867 :                 if (!jl_field_isptr(stt, fieldidx))
    3722                 :         95 :                     offs += ((jl_datatype_t*)jl_field_type(stt, fieldidx))->layout->first_ptr;
    3723                 :      10867 :                 Value *ptr = emit_bitcast(ctx, data_pointer(ctx, obj), ctx.types().T_pprjlvalue);
    3724                 :      10867 :                 Value *addr = ctx.builder.CreateConstInBoundsGEP1_32(ctx.types().T_prjlvalue, ptr, offs);
    3725                 :            :                 // emit this using the same type as emit_getfield_knownidx
    3726                 :            :                 // so that LLVM may be able to load-load forward them and fold the result
    3727                 :      10867 :                 fldv = tbaa_decorate(tbaa, ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, addr, Align(sizeof(size_t))));
    3728         [ +  + ]:      10867 :                 cast<LoadInst>(fldv)->setOrdering(order <= jl_memory_order_notatomic ? AtomicOrdering::Unordered : get_llvm_atomic_order(order));
    3729                 :            :             }
    3730                 :            :             else {
    3731                 :          0 :                 fldv = ctx.builder.CreateExtractValue(obj.V, offs);
    3732         [ #  # ]:          0 :                 if (!jl_field_isptr(stt, fieldidx)) {
    3733                 :          0 :                     fldv = extract_first_ptr(ctx, fldv);
    3734         [ #  # ]:          0 :                     assert(fldv);
    3735                 :            :                 }
    3736                 :            :             }
    3737                 :      10867 :             Value *isdef = ctx.builder.CreateIsNotNull(fldv);
    3738                 :      10867 :             *ret = mark_julia_type(ctx, isdef, false, jl_bool_type);
    3739                 :            :         }
    3740                 :            :         else {
    3741                 :         29 :             *ret = mark_julia_const(ctx, jl_true);
    3742                 :            :         }
    3743   [ +  +  +  + ]:      10896 :         if (order > jl_memory_order_monotonic && ret->constant) {
    3744                 :            :             // fence instructions may only have acquire, release, acq_rel, or seq_cst ordering.
    3745                 :         10 :             ctx.builder.CreateFence(get_llvm_atomic_order(order));
    3746                 :            :         }
    3747                 :      10896 :         return true;
    3748                 :            :     }
    3749                 :            : 
    3750         [ +  + ]:      58945 :     else if (f == jl_builtin_donotdelete) {
    3751                 :            :         // For now we emit this as a vararg call to the builtin
    3752                 :            :         // (which doesn't look at the arguments). In the future,
    3753                 :            :         // this should be an LLVM builtin.
    3754                 :          1 :         auto it = builtin_func_map().find(jl_f_donotdelete_addr);
    3755         [ -  + ]:          1 :         if (it == builtin_func_map().end()) {
    3756                 :          0 :             return false;
    3757                 :            :         }
    3758                 :            : 
    3759                 :          1 :         *ret = mark_julia_const(ctx, jl_nothing);
    3760                 :          1 :         FunctionType *Fty = FunctionType::get(getVoidTy(ctx.builder.getContext()), true);
    3761                 :          1 :         Function *dnd = prepare_call(it->second);
    3762                 :          1 :         SmallVector<Value*, 1> call_args;
    3763                 :            : 
    3764         [ +  + ]:          2 :         for (size_t i = 1; i <= nargs; ++i) {
    3765                 :          1 :             const jl_cgval_t &obj = argv[i];
    3766         [ +  - ]:          1 :             if (obj.V) {
    3767                 :            :                 // TODO is this strong enough to constitute a read of any contained
    3768                 :            :                 // pointers?
    3769                 :          1 :                 Value *V = obj.V;
    3770         [ +  - ]:          1 :                 if (obj.isboxed) {
    3771                 :          1 :                     V = emit_pointer_from_objref(ctx, V);
    3772                 :            :                 }
    3773                 :          1 :                 call_args.push_back(V);
    3774                 :            :             }
    3775                 :            :         }
    3776                 :          1 :         ctx.builder.CreateCall(Fty, dnd, call_args);
    3777                 :          1 :         return true;
    3778                 :            :     }
    3779                 :            : 
    3780                 :     100344 :     return false;
    3781                 :            : }
    3782                 :            : 
    3783                 :            : // Returns ctx.types().T_prjlvalue
    3784                 :     605035 : static CallInst *emit_jlcall(jl_codectx_t &ctx, Function *theFptr, Value *theF,
    3785                 :            :                              const jl_cgval_t *argv, size_t nargs, JuliaFunction *trampoline)
    3786                 :            : {
    3787                 :     605035 :     ++EmittedJLCalls;
    3788                 :     605035 :     Function *TheTrampoline = prepare_call(trampoline);
    3789                 :            :     // emit arguments
    3790                 :     605035 :     SmallVector<Value*, 4> theArgs;
    3791                 :     605035 :     theArgs.push_back(theFptr);
    3792         [ +  + ]:     605035 :     if (theF)
    3793                 :     161309 :         theArgs.push_back(theF);
    3794         [ +  + ]:    2557770 :     for (size_t i = 0; i < nargs; i++) {
    3795                 :    1952730 :         Value *arg = boxed(ctx, argv[i]);
    3796                 :    1952730 :         theArgs.push_back(arg);
    3797                 :            :     }
    3798                 :     605035 :     CallInst *result = ctx.builder.CreateCall(TheTrampoline, theArgs);
    3799                 :     605035 :     result->setAttributes(TheTrampoline->getAttributes());
    3800                 :            :     // TODO: we could add readonly attributes in many cases to the args
    3801                 :     605035 :     return result;
    3802                 :            : }
    3803                 :            : 
    3804                 :            : // Returns ctx.types().T_prjlvalue
    3805                 :     500872 : static CallInst *emit_jlcall(jl_codectx_t &ctx, JuliaFunction *theFptr, Value *theF,
    3806                 :            :                              const jl_cgval_t *argv, size_t nargs, JuliaFunction *trampoline)
    3807                 :            : {
    3808                 :     500872 :     return emit_jlcall(ctx, prepare_call(theFptr), theF, argv, nargs, trampoline);
    3809                 :            : }
    3810                 :            : 
    3811                 :            : 
    3812                 :    1482800 : static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, jl_method_instance_t *mi, jl_value_t *jlretty, StringRef specFunctionObject,
    3813                 :            :                                           const jl_cgval_t *argv, size_t nargs, jl_returninfo_t::CallingConv *cc, unsigned *return_roots, jl_value_t *inferred_retty)
    3814                 :            : {
    3815                 :    1482800 :     ++EmittedSpecfunCalls;
    3816                 :            :     // emit specialized call site
    3817   [ +  -  +  + ]:    1482800 :     bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure;
    3818                 :    1482800 :     jl_returninfo_t returninfo = get_specsig_function(ctx, jl_Module, specFunctionObject, mi->specTypes, jlretty, is_opaque_closure);
    3819                 :    1482800 :     FunctionType *cft = returninfo.decl->getFunctionType();
    3820                 :    1482800 :     *cc = returninfo.cc;
    3821                 :    1482800 :     *return_roots = returninfo.return_roots;
    3822                 :            : 
    3823                 :    1482800 :     size_t nfargs = cft->getNumParams();
    3824                 :    1482800 :     Value **argvals = (Value**)alloca(nfargs * sizeof(Value*));
    3825                 :    1482800 :     unsigned idx = 0;
    3826                 :            :     AllocaInst *result;
    3827   [ +  +  +  - ]:    1482800 :     switch (returninfo.cc) {
    3828                 :    1341770 :     case jl_returninfo_t::Boxed:
    3829                 :            :     case jl_returninfo_t::Register:
    3830                 :            :     case jl_returninfo_t::Ghosts:
    3831                 :    1341770 :         break;
    3832                 :     126995 :     case jl_returninfo_t::SRet:
    3833                 :     126995 :         result = emit_static_alloca(ctx, getAttributeAtIndex(returninfo.decl->getAttributes(), 1, Attribute::StructRet).getValueAsType());
    3834         [ -  + ]:     126995 :         assert(cast<PointerType>(result->getType())->hasSameElementTypeAs(cast<PointerType>(cft->getParamType(0))));
    3835                 :     126995 :         argvals[idx] = result;
    3836                 :     126995 :         idx++;
    3837                 :     126995 :         break;
    3838                 :      14038 :     case jl_returninfo_t::Union:
    3839                 :      14038 :         result = emit_static_alloca(ctx, ArrayType::get(getInt8Ty(ctx.builder.getContext()), returninfo.union_bytes));
    3840         [ +  + ]:      14038 :         if (returninfo.union_align > 1)
    3841                 :      12490 :             result->setAlignment(Align(returninfo.union_align));
    3842                 :      14038 :         argvals[idx] = result;
    3843                 :      14038 :         idx++;
    3844                 :      14038 :         break;
    3845                 :            :     }
    3846                 :            : 
    3847         [ +  + ]:    1482800 :     if (returninfo.return_roots) {
    3848                 :      55813 :         AllocaInst *return_roots = emit_static_alloca(ctx, ArrayType::get(ctx.types().T_prjlvalue, returninfo.return_roots));
    3849                 :      55813 :         argvals[idx] = return_roots;
    3850                 :      55813 :         idx++;
    3851                 :            :     }
    3852                 :            : 
    3853         [ +  + ]:    6275670 :     for (size_t i = 0; i < nargs; i++) {
    3854   [ +  +  +  + ]:    4792860 :         jl_value_t *jt = (is_opaque_closure && i == 0) ? (jl_value_t*)jl_any_type :
    3855                 :    4792860 :             jl_nth_slot_type(mi->specTypes, i);
    3856         [ +  + ]:    4792860 :         if (is_uniquerep_Type(jt))
    3857                 :    1758510 :             continue;
    3858                 :    4567470 :         bool isboxed = deserves_argbox(jt);
    3859         [ +  + ]:    4567470 :         Type *et = isboxed ?  ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, jt);
    3860         [ +  + ]:    4567470 :         if (type_is_ghost(et))
    3861                 :    1533110 :             continue;
    3862         [ -  + ]:    3034360 :         assert(idx < nfargs);
    3863                 :    3034360 :         Type *at = cft->getParamType(idx);
    3864                 :    3034360 :         jl_cgval_t arg = argv[i];
    3865         [ +  + ]:    3034360 :         if (isboxed) {
    3866   [ +  -  +  - ]:    1129140 :             assert(at == ctx.types().T_prjlvalue && et == ctx.types().T_prjlvalue);
    3867                 :    1129140 :             argvals[idx] = boxed(ctx, arg);
    3868                 :            :         }
    3869         [ +  + ]:    1905220 :         else if (et->isAggregateType()) {
    3870                 :     966896 :             arg = value_to_pointer(ctx, arg);
    3871                 :            :             // can lazy load on demand, no copy needed
    3872         [ -  + ]:     966896 :             assert(at == PointerType::get(et, AddressSpace::Derived));
    3873                 :     966896 :             argvals[idx] = decay_derived(ctx, maybe_bitcast(ctx, data_pointer(ctx, arg), at));
    3874                 :            :         }
    3875                 :            :         else {
    3876         [ -  + ]:     938323 :             assert(at == et);
    3877                 :     938323 :             Value *val = emit_unbox(ctx, et, arg, jt);
    3878         [ -  + ]:     938323 :             if (!val) {
    3879                 :            :                 // There was a type mismatch of some sort - exit early
    3880                 :          0 :                 CreateTrap(ctx.builder);
    3881                 :          0 :                 return jl_cgval_t();
    3882                 :            :             }
    3883                 :     938323 :             argvals[idx] = val;
    3884                 :            :         }
    3885                 :    3034360 :         idx++;
    3886                 :            :     }
    3887         [ -  + ]:    1482800 :     assert(idx == nfargs);
    3888                 :    1482800 :     CallInst *call = ctx.builder.CreateCall(returninfo.decl, ArrayRef<Value*>(&argvals[0], nfargs));
    3889                 :    1482800 :     call->setAttributes(returninfo.decl->getAttributes());
    3890                 :            : 
    3891                 :    1482800 :     jl_cgval_t retval;
    3892   [ +  +  +  +  :    1482800 :     switch (returninfo.cc) {
                   +  - ]
    3893                 :     507569 :         case jl_returninfo_t::Boxed:
    3894                 :     507569 :             retval = mark_julia_type(ctx, call, true, jlretty);
    3895                 :     507569 :             break;
    3896                 :     833004 :         case jl_returninfo_t::Register:
    3897                 :     833004 :             retval = mark_julia_type(ctx, call, false, jlretty);
    3898                 :     833004 :             break;
    3899                 :     126995 :         case jl_returninfo_t::SRet:
    3900                 :     126995 :             retval = mark_julia_slot(result, jlretty, NULL, ctx.tbaa().tbaa_stack);
    3901                 :     126995 :             break;
    3902                 :      14038 :         case jl_returninfo_t::Union: {
    3903                 :      14038 :             Value *box = ctx.builder.CreateExtractValue(call, 0);
    3904                 :      14038 :             Value *tindex = ctx.builder.CreateExtractValue(call, 1);
    3905                 :      56152 :             Value *derived = ctx.builder.CreateSelect(
    3906                 :            :                 ctx.builder.CreateICmpEQ(
    3907                 :      14038 :                         ctx.builder.CreateAnd(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80)),
    3908                 :      14038 :                         ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0)),
    3909                 :      14038 :                 decay_derived(ctx, ctx.builder.CreateBitCast(argvals[0], ctx.types().T_pjlvalue)),
    3910                 :            :                 decay_derived(ctx, box)
    3911                 :            :             );
    3912                 :            :             retval = mark_julia_slot(derived,
    3913                 :            :                                      jlretty,
    3914                 :            :                                      tindex,
    3915                 :      14038 :                                      ctx.tbaa().tbaa_stack);
    3916                 :      14038 :             retval.Vboxed = box;
    3917                 :      14038 :             break;
    3918                 :            :         }
    3919                 :       1195 :         case jl_returninfo_t::Ghosts:
    3920                 :       1195 :             retval = mark_julia_slot(NULL, jlretty, call, ctx.tbaa().tbaa_stack);
    3921                 :       1195 :             break;
    3922                 :            :     }
    3923                 :            :     // see if inference has a different / better type for the call than the lambda
    3924                 :    1482800 :     return update_julia_type(ctx, retval, inferred_retty);
    3925                 :            : }
    3926                 :            : 
    3927                 :     103281 : static jl_cgval_t emit_call_specfun_boxed(jl_codectx_t &ctx, jl_value_t *jlretty, StringRef specFunctionObject,
    3928                 :            :                                           const jl_cgval_t *argv, size_t nargs, jl_value_t *inferred_retty)
    3929                 :            : {
    3930                 :     103281 :     auto theFptr = cast<Function>(
    3931                 :     103281 :         jl_Module->getOrInsertFunction(specFunctionObject, ctx.types().T_jlfunc).getCallee());
    3932                 :     103281 :     addRetAttr(theFptr, Attribute::NonNull);
    3933                 :     103281 :     Value *ret = emit_jlcall(ctx, theFptr, nullptr, argv, nargs, julia_call);
    3934                 :     103281 :     return update_julia_type(ctx, mark_julia_type(ctx, ret, true, jlretty), inferred_retty);
    3935                 :            : }
    3936                 :            : 
    3937                 :    1589370 : static jl_cgval_t emit_invoke(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt)
    3938                 :            : {
    3939                 :    1589370 :     jl_value_t **args = (jl_value_t**)jl_array_data(ex->args);
    3940                 :    1589370 :     size_t arglen = jl_array_dim0(ex->args);
    3941                 :    1589370 :     size_t nargs = arglen - 1;
    3942         [ -  + ]:    1589370 :     assert(arglen >= 2);
    3943                 :            : 
    3944                 :    1589370 :     jl_cgval_t lival = emit_expr(ctx, args[0]);
    3945                 :    1589370 :     jl_cgval_t *argv = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * nargs);
    3946         [ +  + ]:    6862160 :     for (size_t i = 0; i < nargs; ++i) {
    3947                 :    5272790 :         argv[i] = emit_expr(ctx, args[i + 1]);
    3948         [ +  + ]:    5272790 :         if (argv[i].typ == jl_bottom_type)
    3949                 :          3 :             return jl_cgval_t();
    3950                 :            :     }
    3951                 :    1589370 :     return emit_invoke(ctx, lival, argv, nargs, rt);
    3952                 :            : }
    3953                 :            : 
    3954                 :    1589380 : static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const jl_cgval_t *argv, size_t nargs, jl_value_t *rt)
    3955                 :            : {
    3956                 :    1589380 :     ++EmittedInvokes;
    3957                 :    1589380 :     bool handled = false;
    3958                 :    1589380 :     jl_cgval_t result;
    3959         [ +  - ]:    1589380 :     if (lival.constant) {
    3960                 :    1589380 :         jl_method_instance_t *mi = (jl_method_instance_t*)lival.constant;
    3961         [ -  + ]:    1589380 :         assert(jl_is_method_instance(mi));
    3962         [ +  + ]:    1589380 :         if (mi == ctx.linfo) {
    3963                 :            :             // handle self-recursion specially
    3964                 :       7231 :             jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed;
    3965                 :       7231 :             FunctionType *ft = ctx.f->getFunctionType();
    3966                 :       7231 :             StringRef protoname = ctx.f->getName();
    3967         [ +  + ]:       7231 :             if (ft == ctx.types().T_jlfunc) {
    3968                 :        100 :                 result = emit_call_specfun_boxed(ctx, ctx.rettype, protoname, argv, nargs, rt);
    3969                 :        100 :                 handled = true;
    3970                 :            :             }
    3971         [ +  - ]:       7131 :             else if (ft != ctx.types().T_jlfuncparams) {
    3972                 :       7131 :                 unsigned return_roots = 0;
    3973                 :       7131 :                 result = emit_call_specfun_other(ctx, mi, ctx.rettype, protoname, argv, nargs, &cc, &return_roots, rt);
    3974                 :       7131 :                 handled = true;
    3975                 :            :             }
    3976                 :            :         }
    3977                 :            :         else {
    3978                 :    1582150 :             jl_value_t *ci = ctx.params->lookup(mi, ctx.world, ctx.world); // TODO: need to use the right pair world here
    3979                 :    1582150 :             jl_code_instance_t *codeinst = (jl_code_instance_t*)ci;
    3980         [ +  + ]:    1582150 :             if (ci != jl_nothing) {
    3981                 :    1578870 :                 auto invoke = jl_atomic_load_relaxed(&codeinst->invoke);
    3982                 :            :                  // check if we know how to handle this specptr
    3983         [ +  + ]:    1578870 :                 if (invoke == jl_fptr_const_return_addr) {
    3984                 :         19 :                     result = mark_julia_const(ctx, codeinst->rettype_const);
    3985                 :         19 :                     handled = true;
    3986                 :            :                 }
    3987         [ +  - ]:    1578850 :                 else if (invoke != jl_fptr_sparam_addr) {
    3988                 :            :                     bool specsig, needsparams;
    3989                 :    1578850 :                     std::tie(specsig, needsparams) = uses_specsig(mi, codeinst->rettype, ctx.params->prefer_specsig);
    3990                 :    3157700 :                     std::string name;
    3991                 :    1578850 :                     StringRef protoname;
    3992                 :    1578850 :                     bool need_to_emit = true;
    3993         [ +  + ]:    1578850 :                     if (ctx.use_cache) {
    3994                 :            :                         // optimization: emit the correct name immediately, if we know it
    3995                 :            :                         // TODO: use `emitted` map here too to try to consolidate names?
    3996                 :    1523090 :                         auto invoke = jl_atomic_load_relaxed(&codeinst->invoke);
    3997                 :    1523090 :                         auto fptr = jl_atomic_load_relaxed(&codeinst->specptr.fptr);
    3998         [ +  + ]:    1523090 :                         if (fptr) {
    3999   [ +  +  +  - ]:    1285770 :                             if (specsig ? codeinst->isspecsig : invoke == jl_fptr_args_addr) {
    4000                 :    1285770 :                                 protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, codeinst);
    4001                 :    1285770 :                                 need_to_emit = false;
    4002                 :            :                             }
    4003                 :            :                         }
    4004                 :            :                     }
    4005                 :    1578850 :                     auto it = ctx.call_targets.find(codeinst);
    4006   [ +  +  +  +  :    1578850 :                     if (need_to_emit && it != ctx.call_targets.end()) {
                   +  + ]
    4007                 :      75095 :                         protoname = std::get<2>(it->second)->getName();
    4008                 :      75095 :                         need_to_emit = false;
    4009                 :            :                     }
    4010         [ +  + ]:    1578850 :                     if (need_to_emit) {
    4011         [ +  + ]:     217982 :                         raw_string_ostream(name) << (specsig ? "j_" : "j1_") << name_from_method_instance(mi) << "_" << globalUniqueGeneratedNames++;
    4012                 :     217982 :                         protoname = StringRef(name);
    4013                 :            :                     }
    4014                 :    1578850 :                     jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed;
    4015                 :    1578850 :                     unsigned return_roots = 0;
    4016         [ +  + ]:    1578850 :                     if (specsig)
    4017                 :    1475670 :                         result = emit_call_specfun_other(ctx, mi, codeinst->rettype, protoname, argv, nargs, &cc, &return_roots, rt);
    4018                 :            :                     else
    4019                 :     103181 :                         result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, argv, nargs, rt);
    4020                 :    1578850 :                     handled = true;
    4021         [ +  + ]:    1578850 :                     if (need_to_emit) {
    4022                 :     217982 :                         Function *trampoline_decl = cast<Function>(jl_Module->getNamedValue(protoname));
    4023                 :     217982 :                         ctx.call_targets[codeinst] = std::make_tuple(cc, return_roots, trampoline_decl, specsig);
    4024                 :            :                     }
    4025                 :            :                 }
    4026                 :            :             }
    4027                 :            :         }
    4028                 :            :     }
    4029         [ +  + ]:    1589380 :     if (!handled) {
    4030                 :       3284 :         Value *r = emit_jlcall(ctx, jlinvoke_func, boxed(ctx, lival), argv, nargs, julia_call2);
    4031                 :       3284 :         result = mark_julia_type(ctx, r, true, rt);
    4032                 :            :     }
    4033         [ +  + ]:    1589380 :     if (result.typ == jl_bottom_type)
    4034                 :     554079 :         CreateTrap(ctx.builder);
    4035                 :    1589380 :     return result;
    4036                 :            : }
    4037                 :            : 
    4038                 :         15 : static jl_cgval_t emit_invoke_modify(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt)
    4039                 :            : {
    4040                 :         15 :     ++EmittedInvokes;
    4041                 :         15 :     jl_value_t **args = (jl_value_t**)jl_array_data(ex->args);
    4042                 :         15 :     size_t arglen = jl_array_dim0(ex->args);
    4043                 :         15 :     size_t nargs = arglen - 1;
    4044         [ -  + ]:         15 :     assert(arglen >= 2);
    4045                 :         15 :     jl_cgval_t lival = emit_expr(ctx, args[0]);
    4046                 :         15 :     jl_cgval_t *argv = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * nargs);
    4047         [ +  + ]:        105 :     for (size_t i = 0; i < nargs; ++i) {
    4048                 :         90 :         argv[i] = emit_expr(ctx, args[i + 1]);
    4049         [ -  + ]:         90 :         if (argv[i].typ == jl_bottom_type)
    4050                 :          0 :             return jl_cgval_t();
    4051                 :            :     }
    4052                 :         15 :     const jl_cgval_t &f = argv[0];
    4053                 :         15 :     jl_cgval_t ret;
    4054   [ +  -  +  - ]:         15 :     if (f.constant && f.constant == jl_builtin_modifyfield) {
    4055         [ +  - ]:         15 :         if (emit_f_opfield(ctx, &ret, jl_builtin_modifyfield, argv, nargs - 1, &lival))
    4056                 :         15 :             return ret;
    4057                 :          0 :         auto it = builtin_func_map().find(jl_f_modifyfield_addr);
    4058         [ #  # ]:          0 :         assert(it != builtin_func_map().end());
    4059                 :          0 :         Value *oldnew = emit_jlcall(ctx, it->second, Constant::getNullValue(ctx.types().T_prjlvalue), &argv[1], nargs - 1, julia_call);
    4060                 :          0 :         return mark_julia_type(ctx, oldnew, true, rt);
    4061                 :            :     }
    4062   [ #  #  #  # ]:          0 :     if (f.constant && jl_typeis(f.constant, jl_intrinsic_type)) {
    4063                 :          0 :         JL_I::intrinsic fi = (intrinsic)*(uint32_t*)jl_data_ptr(f.constant);
    4064   [ #  #  #  #  :          0 :         if (fi == JL_I::atomic_pointermodify && jl_intrinsic_nargs((int)fi) == nargs - 1)
                   #  # ]
    4065                 :          0 :             return emit_atomic_pointerop(ctx, fi, argv, nargs - 1, &lival);
    4066                 :            :     }
    4067                 :            : 
    4068                 :            :     // emit function and arguments
    4069                 :          0 :     Value *callval = emit_jlcall(ctx, jlapplygeneric_func, nullptr, argv, nargs, julia_call);
    4070                 :          0 :     return mark_julia_type(ctx, callval, true, rt);
    4071                 :            : }
    4072                 :            : 
    4073                 :   19086400 : static jl_cgval_t emit_call(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt, bool is_promotable)
    4074                 :            : {
    4075                 :   19086400 :     ++EmittedCalls;
    4076                 :   19086400 :     jl_value_t **args = (jl_value_t**)jl_array_data(ex->args);
    4077                 :   19086400 :     size_t nargs = jl_array_dim0(ex->args);
    4078         [ -  + ]:   19086400 :     assert(nargs >= 1);
    4079                 :   19086400 :     jl_cgval_t f = emit_expr(ctx, args[0]);
    4080                 :            : 
    4081   [ +  +  +  + ]:   19086400 :     if (f.constant && jl_typeis(f.constant, jl_intrinsic_type)) {
    4082                 :    9866340 :         JL_I::intrinsic fi = (intrinsic)*(uint32_t*)jl_data_ptr(f.constant);
    4083                 :    9866340 :         return emit_intrinsic(ctx, fi, args, nargs - 1);
    4084                 :            :     }
    4085                 :            : 
    4086         [ -  + ]:    9220080 :     jl_value_t *context = ctx.params->generic_context == jl_nothing ? nullptr : ctx.params->generic_context;
    4087         [ -  + ]:    9220080 :     size_t n_generic_args = nargs + (context ? 1 : 0);
    4088                 :            : 
    4089                 :    9220080 :     jl_cgval_t *generic_argv = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * n_generic_args);
    4090                 :    9220080 :     jl_cgval_t *argv = generic_argv;
    4091         [ -  + ]:    9220080 :     if (context) {
    4092                 :          0 :         generic_argv[0] = mark_julia_const(ctx, context);
    4093                 :          0 :         argv = &generic_argv[1];
    4094                 :            :     }
    4095                 :    9220080 :     argv[0] = f;
    4096         [ +  + ]:   30138500 :     for (size_t i = 1; i < nargs; ++i) {
    4097                 :   20918600 :         argv[i] = emit_expr(ctx, args[i]);
    4098         [ +  + ]:   20918600 :         if (argv[i].typ == jl_bottom_type)
    4099                 :        176 :             return jl_cgval_t(); // anything past here is unreachable
    4100                 :            :     }
    4101                 :            : 
    4102   [ +  +  +  +  :    9219910 :     if (f.constant && jl_isa(f.constant, (jl_value_t*)jl_builtin_type)) {
                   +  + ]
    4103   [ +  +  +  - ]:    8885260 :         if (f.constant == jl_builtin_ifelse && nargs == 4)
    4104                 :    8883740 :             return emit_ifelse(ctx, argv[1], argv[2], argv[3], rt);
    4105                 :    7963650 :         jl_cgval_t result;
    4106                 :    7963650 :         bool handled = emit_builtin_call(ctx, &result, f.constant, argv, nargs - 1, rt, ex, is_promotable);
    4107         [ +  + ]:    7963650 :         if (handled) {
    4108                 :    7805910 :             return result;
    4109                 :            :         }
    4110                 :            : 
    4111                 :            :         // special case for known builtin not handled by emit_builtin_call
    4112                 :     157748 :         auto it = builtin_func_map().find(jl_get_builtin_fptr(f.constant));
    4113         [ +  + ]:     157738 :         if (it != builtin_func_map().end()) {
    4114                 :     156227 :             Value *ret = emit_jlcall(ctx, it->second, Constant::getNullValue(ctx.types().T_prjlvalue), &argv[1], nargs - 1, julia_call);
    4115                 :     156227 :             return mark_julia_type(ctx, ret, true, rt);
    4116                 :            :         }
    4117                 :            :     }
    4118                 :            : 
    4119                 :            :     // emit function and arguments
    4120                 :     336155 :     Value *callval = emit_jlcall(ctx, jlapplygeneric_func, nullptr, generic_argv, n_generic_args, julia_call);
    4121                 :     336155 :     return mark_julia_type(ctx, callval, true, rt);
    4122                 :            : }
    4123                 :            : 
    4124                 :            : // --- accessing and assigning variables ---
    4125                 :            : 
    4126                 :      54003 : static void undef_var_error_ifnot(jl_codectx_t &ctx, Value *ok, jl_sym_t *name)
    4127                 :            : {
    4128                 :      54003 :     ++EmittedUndefVarErrors;
    4129                 :      54003 :     BasicBlock *err = BasicBlock::Create(ctx.builder.getContext(), "err", ctx.f);
    4130                 :      54003 :     BasicBlock *ifok = BasicBlock::Create(ctx.builder.getContext(), "ok");
    4131                 :      54003 :     ctx.builder.CreateCondBr(ok, ifok, err);
    4132                 :      54003 :     ctx.builder.SetInsertPoint(err);
    4133                 :     108006 :     ctx.builder.CreateCall(prepare_call(jlundefvarerror_func),
    4134                 :      54003 :         mark_callee_rooted(ctx, literal_pointer_val(ctx, (jl_value_t*)name)));
    4135                 :      54003 :     ctx.builder.CreateUnreachable();
    4136                 :      54003 :     ctx.f->getBasicBlockList().push_back(ifok);
    4137                 :      54003 :     ctx.builder.SetInsertPoint(ifok);
    4138                 :      54003 : }
    4139                 :            : 
    4140                 :            : // returns a jl_ppvalue_t location for the global variable m.s
    4141                 :            : // if the reference currently bound or assign == true,
    4142                 :            : //   pbnd will also be assigned with the binding address
    4143                 :   21915900 : static Value *global_binding_pointer(jl_codectx_t &ctx, jl_module_t *m, jl_sym_t *s,
    4144                 :            :                                      jl_binding_t **pbnd, bool assign)
    4145                 :            : {
    4146                 :   21915900 :     jl_binding_t *b = NULL;
    4147         [ +  + ]:   21915900 :     if (assign)
    4148                 :       2571 :         b = jl_get_binding_wr(m, s, 0);
    4149                 :            :     else
    4150                 :   21913300 :         b = jl_get_binding(m, s);
    4151         [ +  + ]:   21915900 :     if (b == NULL) {
    4152                 :            :         // var not found. switch to delayed lookup.
    4153                 :       2011 :         Constant *initnul = Constant::getNullValue(ctx.types().T_pjlvalue);
    4154                 :       2011 :         GlobalVariable *bindinggv = new GlobalVariable(*ctx.f->getParent(), ctx.types().T_pjlvalue,
    4155                 :       2011 :                 false, GlobalVariable::PrivateLinkage, initnul);
    4156                 :       2011 :         LoadInst *cachedval = ctx.builder.CreateAlignedLoad(ctx.types().T_pjlvalue, bindinggv, Align(sizeof(void*)));
    4157                 :       2011 :         cachedval->setOrdering(AtomicOrdering::Unordered);
    4158                 :       2011 :         BasicBlock *have_val = BasicBlock::Create(ctx.builder.getContext(), "found");
    4159                 :       2011 :         BasicBlock *not_found = BasicBlock::Create(ctx.builder.getContext(), "notfound");
    4160                 :       2011 :         BasicBlock *currentbb = ctx.builder.GetInsertBlock();
    4161                 :       2011 :         ctx.builder.CreateCondBr(ctx.builder.CreateICmpNE(cachedval, initnul), have_val, not_found);
    4162                 :       2011 :         ctx.f->getBasicBlockList().push_back(not_found);
    4163                 :       2011 :         ctx.builder.SetInsertPoint(not_found);
    4164         [ +  + ]:       4022 :         Value *bval = ctx.builder.CreateCall(prepare_call(assign ? jlgetbindingwrorerror_func : jlgetbindingorerror_func),
    4165                 :       2011 :                 { literal_pointer_val(ctx, (jl_value_t*)m),
    4166                 :       2011 :                   literal_pointer_val(ctx, (jl_value_t*)s) });
    4167                 :       2011 :         ctx.builder.CreateAlignedStore(bval, bindinggv, Align(sizeof(void*)))->setOrdering(AtomicOrdering::Release);
    4168                 :       2011 :         ctx.builder.CreateBr(have_val);
    4169                 :       2011 :         ctx.f->getBasicBlockList().push_back(have_val);
    4170                 :       2011 :         ctx.builder.SetInsertPoint(have_val);
    4171                 :       2011 :         PHINode *p = ctx.builder.CreatePHI(ctx.types().T_pjlvalue, 2);
    4172                 :       2011 :         p->addIncoming(cachedval, currentbb);
    4173                 :       2011 :         p->addIncoming(bval, not_found);
    4174                 :       2011 :         return p;
    4175                 :            :     }
    4176         [ +  + ]:   21913900 :     if (assign) {
    4177         [ +  + ]:       2330 :         if (b->owner != m) {
    4178                 :            :             char *msg;
    4179                 :          2 :             (void)asprintf(&msg, "cannot assign a value to imported variable %s.%s from module %s",
    4180                 :          1 :                     jl_symbol_name(b->owner->name), jl_symbol_name(s), jl_symbol_name(m->name));
    4181                 :          1 :             emit_error(ctx, msg);
    4182                 :          1 :             free(msg);
    4183                 :          1 :             return NULL;
    4184                 :            :         }
    4185                 :            :     }
    4186                 :            :     else {
    4187         [ -  + ]:   21911500 :         if (b->deprecated)
    4188                 :          0 :             cg_bdw(ctx, b);
    4189                 :            :     }
    4190                 :   21913900 :     *pbnd = b;
    4191                 :   21913900 :     return julia_binding_gv(ctx, b);
    4192                 :            : }
    4193                 :            : 
    4194                 :       1834 : static jl_cgval_t emit_checked_var(jl_codectx_t &ctx, Value *bp, jl_sym_t *name, bool isvol, MDNode *tbaa)
    4195                 :            : {
    4196                 :       1834 :     LoadInst *v = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*)));
    4197         [ -  + ]:       1834 :     if (isvol)
    4198                 :          0 :         v->setVolatile(true);
    4199                 :       1834 :     v->setOrdering(AtomicOrdering::Unordered);
    4200         [ +  - ]:       1834 :     if (tbaa)
    4201                 :       1834 :         tbaa_decorate(tbaa, v);
    4202                 :       1834 :     undef_var_error_ifnot(ctx, ctx.builder.CreateIsNotNull(v), name);
    4203                 :       1834 :     return mark_julia_type(ctx, v, true, jl_any_type);
    4204                 :            : }
    4205                 :            : 
    4206                 :      10873 : static jl_cgval_t emit_sparam(jl_codectx_t &ctx, size_t i)
    4207                 :            : {
    4208         [ +  + ]:      10873 :     if (jl_svec_len(ctx.linfo->sparam_vals) > 0) {
    4209                 :      10669 :         jl_value_t *e = jl_svecref(ctx.linfo->sparam_vals, i);
    4210         [ +  + ]:      10669 :         if (!jl_is_typevar(e)) {
    4211                 :      10628 :             return mark_julia_const(ctx, e);
    4212                 :            :         }
    4213                 :            :     }
    4214         [ -  + ]:        245 :     assert(ctx.spvals_ptr != NULL);
    4215                 :        490 :     Value *bp = ctx.builder.CreateConstInBoundsGEP1_32(
    4216                 :        245 :             ctx.types().T_prjlvalue,
    4217                 :            :             ctx.spvals_ptr,
    4218                 :            :             i + sizeof(jl_svec_t) / sizeof(jl_value_t*));
    4219                 :        245 :     Value *sp = tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*))));
    4220                 :        245 :     Value *isnull = ctx.builder.CreateICmpNE(emit_typeof(ctx, sp, false),
    4221                 :            :             track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)jl_tvar_type)));
    4222                 :        245 :     jl_unionall_t *sparam = (jl_unionall_t*)ctx.linfo->def.method->sig;
    4223         [ +  + ]:        314 :     for (size_t j = 0; j < i; j++) {
    4224                 :         69 :         sparam = (jl_unionall_t*)sparam->body;
    4225         [ -  + ]:         69 :         assert(jl_is_unionall(sparam));
    4226                 :            :     }
    4227                 :        245 :     undef_var_error_ifnot(ctx, isnull, sparam->var->name);
    4228                 :        245 :     return mark_julia_type(ctx, sp, true, jl_any_type);
    4229                 :            : }
    4230                 :            : 
    4231                 :          0 : static jl_cgval_t emit_global(jl_codectx_t &ctx, jl_sym_t *sym)
    4232                 :            : {
    4233                 :          0 :     jl_binding_t *jbp = NULL;
    4234                 :          0 :     Value *bp = global_binding_pointer(ctx, ctx.module, sym, &jbp, false);
    4235         [ #  # ]:          0 :     if (bp == NULL)
    4236                 :          0 :         return jl_cgval_t();
    4237   [ #  #  #  #  :          0 :     if (jbp && jbp->value != NULL) {
                   #  # ]
    4238         [ #  # ]:          0 :         if (jbp->constp)
    4239                 :          0 :             return mark_julia_const(ctx, jbp->value);
    4240                 :            :         // double-check that a global variable is actually defined. this
    4241                 :            :         // can be a problem in parallel when a definition is missing on
    4242                 :            :         // one machine.
    4243                 :          0 :         LoadInst *v = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*)));
    4244                 :          0 :         v->setOrdering(AtomicOrdering::Unordered);
    4245                 :          0 :         tbaa_decorate(ctx.tbaa().tbaa_binding, v);
    4246                 :          0 :         return mark_julia_type(ctx, v, true, jl_any_type);
    4247                 :            :     }
    4248                 :          0 :     return emit_checked_var(ctx, bp, sym, false, ctx.tbaa().tbaa_binding);
    4249                 :            : }
    4250                 :            : 
    4251                 :         52 : static jl_cgval_t emit_isdefined(jl_codectx_t &ctx, jl_value_t *sym)
    4252                 :            : {
    4253                 :         52 :     Value *isnull = NULL;
    4254   [ +  +  +  -  :         52 :     if (jl_is_slot(sym) || jl_is_argument(sym)) {
                   -  + ]
    4255                 :          2 :         size_t sl = jl_slot_number(sym) - 1;
    4256                 :          2 :         jl_varinfo_t &vi = ctx.slots[sl];
    4257         [ -  + ]:          2 :         if (!vi.usedUndef)
    4258                 :          0 :             return mark_julia_const(ctx, jl_true);
    4259   [ +  -  -  + ]:          2 :         if (vi.boxroot == NULL || vi.pTIndex != NULL) {
    4260         [ #  # ]:          0 :             assert(vi.defFlag);
    4261                 :          0 :             isnull = ctx.builder.CreateAlignedLoad(getInt1Ty(ctx.builder.getContext()), vi.defFlag, Align(1), vi.isVolatile);
    4262                 :            :         }
    4263         [ +  - ]:          2 :         if (vi.boxroot != NULL) {
    4264                 :          2 :             Value *boxed = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, vi.boxroot, Align(sizeof(void*)), vi.isVolatile);
    4265                 :          2 :             Value *box_isnull = ctx.builder.CreateICmpNE(boxed, Constant::getNullValue(ctx.types().T_prjlvalue));
    4266         [ -  + ]:          2 :             if (vi.pTIndex) {
    4267                 :            :                 // value is either boxed in the stack slot, or unboxed in value
    4268                 :            :                 // as indicated by testing (pTIndex & 0x80)
    4269                 :          0 :                 Value *tindex = ctx.builder.CreateAlignedLoad(getInt8Ty(ctx.builder.getContext()), vi.pTIndex, Align(sizeof(void*)), vi.isVolatile);
    4270                 :          0 :                 Value *load_unbox = ctx.builder.CreateICmpEQ(
    4271                 :          0 :                             ctx.builder.CreateAnd(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80)),
    4272                 :          0 :                             ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0));
    4273                 :          0 :                 isnull = ctx.builder.CreateSelect(load_unbox, isnull, box_isnull);
    4274                 :            :             }
    4275                 :            :             else {
    4276                 :          2 :                 isnull = box_isnull;
    4277                 :            :             }
    4278                 :          2 :         }
    4279                 :            :     }
    4280         [ +  + ]:         50 :     else if (jl_is_expr(sym)) {
    4281         [ -  + ]:         21 :         assert(((jl_expr_t*)sym)->head == jl_static_parameter_sym && "malformed isdefined expression");
    4282                 :         21 :         size_t i = jl_unbox_long(jl_exprarg(sym, 0)) - 1;
    4283         [ +  + ]:         21 :         if (jl_svec_len(ctx.linfo->sparam_vals) > 0) {
    4284                 :         18 :             jl_value_t *e = jl_svecref(ctx.linfo->sparam_vals, i);
    4285         [ +  + ]:         18 :             if (!jl_is_typevar(e)) {
    4286                 :          6 :                 return mark_julia_const(ctx, jl_true);
    4287                 :            :             }
    4288                 :            :         }
    4289         [ -  + ]:         15 :         assert(ctx.spvals_ptr != NULL);
    4290                 :         30 :         Value *bp = ctx.builder.CreateConstInBoundsGEP1_32(
    4291                 :         15 :                 ctx.types().T_prjlvalue,
    4292                 :            :                 ctx.spvals_ptr,
    4293                 :            :                 i + sizeof(jl_svec_t) / sizeof(jl_value_t*));
    4294                 :         15 :         Value *sp = tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*))));
    4295                 :         15 :         isnull = ctx.builder.CreateICmpNE(emit_typeof(ctx, sp, false),
    4296                 :            :             track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)jl_tvar_type)));
    4297                 :            :     }
    4298                 :            :     else {
    4299                 :            :         jl_module_t *modu;
    4300                 :            :         jl_sym_t *name;
    4301         [ +  - ]:         29 :         if (jl_is_globalref(sym)) {
    4302                 :         29 :             modu = jl_globalref_mod(sym);
    4303                 :         29 :             name = jl_globalref_name(sym);
    4304                 :            :         }
    4305                 :            :         else {
    4306         [ #  # ]:          0 :             assert(jl_is_symbol(sym) && "malformed isdefined expression");
    4307                 :          0 :             modu = ctx.module;
    4308                 :          0 :             name = (jl_sym_t*)sym;
    4309                 :            :         }
    4310                 :         29 :         jl_binding_t *bnd = jl_get_binding(modu, name);
    4311         [ +  + ]:         29 :         if (bnd) {
    4312         [ +  - ]:          8 :             if (bnd->value != NULL)
    4313                 :          8 :                 return mark_julia_const(ctx, jl_true);
    4314                 :          0 :             Value *bp = julia_binding_gv(ctx, bnd);
    4315                 :          0 :             bp = julia_binding_pvalue(ctx, bp);
    4316                 :          0 :             LoadInst *v = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*)));
    4317                 :          0 :             tbaa_decorate(ctx.tbaa().tbaa_binding, v);
    4318                 :          0 :             v->setOrdering(AtomicOrdering::Unordered);
    4319                 :          0 :             isnull = ctx.builder.CreateICmpNE(v, Constant::getNullValue(ctx.types().T_prjlvalue));
    4320                 :            :         }
    4321                 :            :         else {
    4322                 :         42 :             Value *v = ctx.builder.CreateCall(prepare_call(jlboundp_func), {
    4323                 :         21 :                     literal_pointer_val(ctx, (jl_value_t*)modu),
    4324                 :         21 :                     literal_pointer_val(ctx, (jl_value_t*)name)
    4325                 :            :                 });
    4326                 :         21 :             isnull = ctx.builder.CreateICmpNE(v, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0));
    4327                 :            :         }
    4328                 :            :     }
    4329                 :         38 :     return mark_julia_type(ctx, isnull, false, jl_bool_type);
    4330                 :            : }
    4331                 :            : 
    4332                 :    3652680 : static jl_cgval_t emit_varinfo(jl_codectx_t &ctx, jl_varinfo_t &vi, jl_sym_t *varname, jl_value_t *better_typ=NULL) {
    4333         [ +  - ]:    3652680 :     jl_value_t *typ = better_typ ? better_typ : vi.value.typ;
    4334                 :    3652680 :     jl_cgval_t v;
    4335                 :    3652680 :     Value *isnull = NULL;
    4336   [ +  +  +  + ]:    3652680 :     if (vi.boxroot == NULL || vi.pTIndex != NULL) {
    4337   [ +  +  -  +  :    2313610 :         if ((!vi.isVolatile && vi.isSA) || vi.isArgument || vi.value.constant || !vi.value.V) {
          +  -  +  +  +  
                      + ]
    4338                 :    2257900 :             v = vi.value;
    4339         [ +  + ]:    2257900 :             if (vi.pTIndex)
    4340                 :        204 :                 v.TIndex = ctx.builder.CreateAlignedLoad(getInt8Ty(ctx.builder.getContext()), vi.pTIndex, Align(1));
    4341                 :            :         }
    4342                 :            :         else {
    4343                 :            :             // copy value to a non-mutable (non-volatile SSA) location
    4344                 :      55705 :             AllocaInst *varslot = cast<AllocaInst>(vi.value.V);
    4345                 :      55705 :             Type *T = varslot->getAllocatedType();
    4346         [ +  - ]:      55705 :             assert(!varslot->isArrayAllocation() && "variables not expected to be VLA");
    4347                 :      55705 :             AllocaInst *ssaslot = cast<AllocaInst>(varslot->clone());
    4348                 :      55705 :             ssaslot->insertAfter(varslot);
    4349         [ +  - ]:      55705 :             if (vi.isVolatile) {
    4350                 :     111410 :                 Value *unbox = ctx.builder.CreateAlignedLoad(ssaslot->getAllocatedType(), varslot,
    4351                 :      55705 :                         varslot->getAlign(),
    4352                 :            :                         true);
    4353                 :      55705 :                 ctx.builder.CreateAlignedStore(unbox, ssaslot, ssaslot->getAlign());
    4354                 :            :             }
    4355                 :            :             else {
    4356                 :          0 :                 const DataLayout &DL = jl_Module->getDataLayout();
    4357                 :          0 :                 uint64_t sz = DL.getTypeStoreSize(T);
    4358                 :          0 :                 emit_memcpy(ctx, ssaslot, ctx.tbaa().tbaa_stack, vi.value, sz, ssaslot->getAlign().value());
    4359                 :            :             }
    4360                 :      55705 :             Value *tindex = NULL;
    4361         [ +  + ]:      55705 :             if (vi.pTIndex)
    4362                 :        285 :                 tindex = ctx.builder.CreateAlignedLoad(getInt8Ty(ctx.builder.getContext()), vi.pTIndex, Align(1), vi.isVolatile);
    4363                 :      55705 :             v = mark_julia_slot(ssaslot, vi.value.typ, tindex, ctx.tbaa().tbaa_stack);
    4364                 :            :         }
    4365         [ +  + ]:    2313610 :         if (vi.boxroot == NULL)
    4366                 :    2313540 :             v = update_julia_type(ctx, v, typ);
    4367         [ -  + ]:    2313610 :         if (vi.usedUndef) {
    4368         [ #  # ]:          0 :             assert(vi.defFlag);
    4369                 :          0 :             isnull = ctx.builder.CreateAlignedLoad(getInt1Ty(ctx.builder.getContext()), vi.defFlag, Align(1), vi.isVolatile);
    4370                 :            :         }
    4371                 :            :     }
    4372         [ +  + ]:    3652680 :     if (vi.boxroot != NULL) {
    4373                 :    1339140 :         Instruction *boxed = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, vi.boxroot, Align(sizeof(void*)), vi.isVolatile);
    4374                 :    1339140 :         Value *box_isnull = NULL;
    4375         [ +  + ]:    1339140 :         if (vi.usedUndef)
    4376                 :      30841 :             box_isnull = ctx.builder.CreateICmpNE(boxed, Constant::getNullValue(ctx.types().T_prjlvalue));
    4377   [ +  +  +  + ]:    1339140 :         maybe_mark_load_dereferenceable(boxed, vi.usedUndef || vi.pTIndex, typ);
    4378         [ +  + ]:    1339140 :         if (vi.pTIndex) {
    4379                 :            :             // value is either boxed in the stack slot, or unboxed in value
    4380                 :            :             // as indicated by testing (pTIndex & 0x80)
    4381                 :        207 :             Value *load_unbox = ctx.builder.CreateICmpEQ(
    4382                 :         69 :                         ctx.builder.CreateAnd(v.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80)),
    4383                 :         69 :                         ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0));
    4384         [ -  + ]:         69 :             if (vi.usedUndef)
    4385                 :          0 :                 isnull = ctx.builder.CreateSelect(load_unbox, isnull, box_isnull);
    4386         [ +  - ]:         69 :             if (v.V) { // v.V will be null if it is a union of all ghost values
    4387                 :         69 :                 v.V = ctx.builder.CreateSelect(load_unbox, emit_bitcast(ctx,
    4388                 :            :                     decay_derived(ctx, v.V), boxed->getType()), decay_derived(ctx, boxed));
    4389                 :            :             } else
    4390                 :          0 :                 v.V = boxed;
    4391                 :         69 :             v.Vboxed = boxed;
    4392                 :         69 :             v = update_julia_type(ctx, v, typ);
    4393                 :            :         }
    4394                 :            :         else {
    4395                 :    1339070 :             v = mark_julia_type(ctx, boxed, true, typ);
    4396         [ +  + ]:    1339070 :             if (vi.usedUndef)
    4397                 :      30841 :                 isnull = box_isnull;
    4398                 :            :         }
    4399                 :            :     }
    4400         [ +  + ]:    3652680 :     if (isnull)
    4401                 :      30841 :         undef_var_error_ifnot(ctx, isnull, varname);
    4402                 :    3652680 :     return v;
    4403                 :            : }
    4404                 :            : 
    4405                 :    3456900 : static jl_cgval_t emit_local(jl_codectx_t &ctx, jl_value_t *slotload)
    4406                 :            : {
    4407                 :    3456900 :     size_t sl = jl_slot_number(slotload) - 1;
    4408                 :    3456900 :     jl_varinfo_t &vi = ctx.slots[sl];
    4409                 :    3456900 :     jl_sym_t *sym = slot_symbol(ctx, sl);
    4410                 :    3456900 :     jl_value_t *typ = NULL;
    4411         [ -  + ]:    3456900 :     if (jl_typeis(slotload, jl_typedslot_type)) {
    4412                 :            :         // use the better type from inference for this load
    4413                 :          0 :         typ = jl_typedslot_get_type(slotload);
    4414         [ #  # ]:          0 :         if (jl_is_typevar(typ))
    4415                 :          0 :             typ = ((jl_tvar_t*)typ)->ub;
    4416                 :            :     }
    4417                 :    3456900 :     return emit_varinfo(ctx, vi, sym, typ);
    4418                 :            : }
    4419                 :            : 
    4420                 :     110627 : static void emit_vi_assignment_unboxed(jl_codectx_t &ctx, jl_varinfo_t &vi, Value *isboxed, jl_cgval_t rval_info)
    4421                 :            : {
    4422         [ -  + ]:     110627 :     if (vi.usedUndef)
    4423                 :          0 :         store_def_flag(ctx, vi, true);
    4424                 :            : 
    4425         [ +  + ]:     110627 :     if (!vi.value.constant) { // check that this is not a virtual store
    4426   [ +  +  +  -  :      84604 :         assert(vi.value.ispointer() || (vi.pTIndex && vi.value.V == NULL));
                   +  - ]
    4427                 :            :         // store value
    4428         [ +  + ]:      84604 :         if (vi.value.V == NULL) {
    4429                 :            :             // all ghost values in destination - nothing to copy or store
    4430                 :            :         }
    4431   [ +  +  +  +  :      84400 :         else if (rval_info.constant || !rval_info.ispointer()) {
                   +  + ]
    4432         [ +  + ]:      69147 :             if (rval_info.isghost) {
    4433                 :            :                 // all ghost values in source - nothing to copy or store
    4434                 :            :             }
    4435                 :            :             else {
    4436   [ -  +  -  -  :      69140 :                 if (rval_info.typ != vi.value.typ && !vi.pTIndex && !rval_info.TIndex) {
                   -  - ]
    4437                 :            :                     // isbits cast-on-assignment is invalid. this branch should be dead-code.
    4438                 :          0 :                     CreateTrap(ctx.builder);
    4439                 :            :                 }
    4440                 :            :                 else {
    4441                 :      69140 :                     Value *dest = vi.value.V;
    4442         [ +  + ]:      69140 :                     if (vi.pTIndex)
    4443                 :         13 :                         ctx.builder.CreateStore(UndefValue::get(cast<AllocaInst>(vi.value.V)->getAllocatedType()), vi.value.V);
    4444         [ +  + ]:      69140 :                     Type *store_ty = julia_type_to_llvm(ctx, rval_info.constant ? jl_typeof(rval_info.constant) : rval_info.typ);
    4445                 :      69140 :                     Type *dest_ty = store_ty->getPointerTo();
    4446         [ +  + ]:      69140 :                     if (dest_ty != dest->getType())
    4447                 :         13 :                         dest = emit_bitcast(ctx, dest, dest_ty);
    4448                 :      69140 :                     tbaa_decorate(ctx.tbaa().tbaa_stack, ctx.builder.CreateStore(
    4449                 :            :                                       emit_unbox(ctx, store_ty, rval_info, rval_info.typ),
    4450                 :            :                                       dest,
    4451                 :      69140 :                                       vi.isVolatile));
    4452                 :            :                 }
    4453                 :            :             }
    4454                 :            :         }
    4455                 :            :         else {
    4456         [ +  + ]:      15253 :             if (vi.pTIndex == NULL) {
    4457         [ -  + ]:      14968 :                 assert(jl_is_concrete_type(vi.value.typ));
    4458                 :            :                 // Sometimes we can get into situations where the LHS and RHS
    4459                 :            :                 // are the same slot. We're not allowed to memcpy in that case
    4460                 :            :                 // due to LLVM bugs.
    4461                 :            :                 // This check should probably mostly catch the relevant situations.
    4462         [ +  - ]:      14968 :                 if (vi.value.V != rval_info.V) {
    4463                 :      14968 :                     Value *copy_bytes = ConstantInt::get(getInt32Ty(ctx.builder.getContext()), jl_datatype_size(vi.value.typ));
    4464                 :      14968 :                     emit_memcpy(ctx, vi.value.V, ctx.tbaa().tbaa_stack, rval_info, copy_bytes,
    4465                 :      14968 :                                 julia_alignment(rval_info.typ), vi.isVolatile);
    4466                 :            :                 }
    4467                 :            :             }
    4468                 :            :             else {
    4469                 :        285 :                 emit_unionmove(ctx, vi.value.V, ctx.tbaa().tbaa_stack, rval_info, /*skip*/isboxed, vi.isVolatile);
    4470                 :            :             }
    4471                 :            :         }
    4472                 :            :     }
    4473                 :            :     else {
    4474         [ -  + ]:      26023 :         assert(vi.pTIndex == NULL);
    4475                 :            :     }
    4476                 :     110627 : }
    4477                 :            : 
    4478                 :    4034850 : static void emit_phinode_assign(jl_codectx_t &ctx, ssize_t idx, jl_value_t *r)
    4479                 :            : {
    4480                 :    4034850 :     jl_value_t *ssavalue_types = (jl_value_t*)ctx.source->ssavaluetypes;
    4481                 :    4034850 :     jl_value_t *phiType = NULL;
    4482         [ +  - ]:    4034850 :     if (jl_is_array(ssavalue_types)) {
    4483                 :    4034850 :         phiType = jl_array_ptr_ref(ssavalue_types, idx);
    4484                 :            :     } else {
    4485                 :          0 :         phiType = (jl_value_t*)jl_any_type;
    4486                 :            :     }
    4487                 :    4034850 :     jl_array_t *edges = (jl_array_t*)jl_fieldref_noalloc(r, 0);
    4488                 :    4034850 :     BasicBlock *BB = ctx.builder.GetInsertBlock();
    4489                 :    4034850 :     auto InsertPt = BB->getFirstInsertionPt();
    4490         [ +  + ]:    4034850 :     if (phiType == jl_bottom_type) {
    4491                 :       2120 :         return;
    4492                 :            :     }
    4493                 :    4032730 :     AllocaInst *dest = nullptr;
    4494                 :            :     // N.B.: For any memory space, used as a phi,
    4495                 :            :     // we need to emit space twice here. The reason for this is that
    4496                 :            :     // phi nodes may be arguments of other phi nodes, so if we don't
    4497                 :            :     // have two buffers, one may be overwritten before its value is
    4498                 :            :     // used. Hopefully LLVM will be able to fold this back where legal.
    4499         [ +  + ]:    4032730 :     if (jl_is_uniontype(phiType)) {
    4500                 :            :         bool allunbox;
    4501                 :            :         size_t min_align, nbytes;
    4502                 :      53892 :         dest = try_emit_union_alloca(ctx, ((jl_uniontype_t*)phiType), allunbox, min_align, nbytes);
    4503         [ +  + ]:      53892 :         if (dest) {
    4504                 :      24302 :             Instruction *phi = dest->clone();
    4505                 :      24302 :             phi->insertAfter(dest);
    4506                 :      24302 :             PHINode *Tindex_phi = PHINode::Create(getInt8Ty(ctx.builder.getContext()), jl_array_len(edges), "tindex_phi");
    4507                 :      24302 :             BB->getInstList().insert(InsertPt, Tindex_phi);
    4508                 :      24302 :             PHINode *ptr_phi = PHINode::Create(ctx.types().T_prjlvalue, jl_array_len(edges), "ptr_phi");
    4509                 :      24302 :             BB->getInstList().insert(InsertPt, ptr_phi);
    4510                 :      72906 :             Value *isboxed = ctx.builder.CreateICmpNE(
    4511                 :      24302 :                     ctx.builder.CreateAnd(Tindex_phi, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80)),
    4512                 :      24302 :                     ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0));
    4513                 :      24302 :             ctx.builder.CreateMemCpy(phi, MaybeAlign(min_align), dest, MaybeAlign(0), nbytes, false);
    4514                 :      24302 :             ctx.builder.CreateLifetimeEnd(dest);
    4515                 :      72906 :             Value *ptr = ctx.builder.CreateSelect(isboxed,
    4516                 :      24302 :                 maybe_bitcast(ctx, decay_derived(ctx, ptr_phi), getInt8PtrTy(ctx.builder.getContext())),
    4517                 :      24302 :                 maybe_bitcast(ctx, decay_derived(ctx, phi), getInt8PtrTy(ctx.builder.getContext())));
    4518                 :      24302 :             jl_cgval_t val = mark_julia_slot(ptr, phiType, Tindex_phi, ctx.tbaa().tbaa_stack); // XXX: this TBAA is wrong for ptr_phi
    4519                 :      24302 :             val.Vboxed = ptr_phi;
    4520                 :      24302 :             ctx.PhiNodes.push_back(std::make_tuple(val, BB, dest, ptr_phi, r));
    4521                 :      24302 :             ctx.SAvalues.at(idx) = val;
    4522                 :      24302 :             ctx.ssavalue_assigned.at(idx) = true;
    4523                 :      24302 :             return;
    4524                 :            :         }
    4525         [ +  + ]:      29590 :         else if (allunbox) {
    4526                 :       1449 :             PHINode *Tindex_phi = PHINode::Create(getInt8Ty(ctx.builder.getContext()), jl_array_len(edges), "tindex_phi");
    4527                 :       1449 :             BB->getInstList().insert(InsertPt, Tindex_phi);
    4528                 :       1449 :             jl_cgval_t val = mark_julia_slot(NULL, phiType, Tindex_phi, ctx.tbaa().tbaa_stack);
    4529                 :       1449 :             ctx.PhiNodes.push_back(std::make_tuple(val, BB, dest, (PHINode*)NULL, r));
    4530                 :       1449 :             ctx.SAvalues.at(idx) = val;
    4531                 :       1449 :             ctx.ssavalue_assigned.at(idx) = true;
    4532                 :       1449 :             return;
    4533                 :            :         }
    4534                 :            :     }
    4535                 :    4006980 :     bool isboxed = !deserves_stack(phiType);
    4536         [ +  + ]:    4006980 :     Type *vtype = isboxed ? ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, phiType);
    4537                 :            :     // The frontend should really not emit this, but we allow it
    4538                 :            :     // for convenience.
    4539         [ +  + ]:    4006980 :     if (type_is_ghost(vtype)) {
    4540   [ +  -  +  - ]:      32843 :         assert(jl_is_datatype(phiType) && ((jl_datatype_t*)phiType)->instance);
    4541                 :            :         // Skip adding it to the PhiNodes list, since we didn't create one.
    4542                 :      32843 :         ctx.SAvalues.at(idx) = mark_julia_const(ctx, ((jl_datatype_t*)phiType)->instance);
    4543                 :      32843 :         ctx.ssavalue_assigned.at(idx) = true;
    4544                 :      32843 :         return;
    4545                 :            :     }
    4546                 :    3974140 :     jl_cgval_t slot;
    4547                 :    3974140 :     PHINode *value_phi = NULL;
    4548   [ +  +  +  +  :    3974140 :     if (vtype->isAggregateType() && CountTrackedPointers(vtype).count == 0) {
                   +  + ]
    4549                 :            :         // the value will be moved into dest in the predecessor critical block.
    4550                 :            :         // here it's moved into phi in the successor (from dest)
    4551                 :     176941 :         dest = emit_static_alloca(ctx, vtype);
    4552                 :     176941 :         Value *phi = emit_static_alloca(ctx, vtype);
    4553                 :     176941 :         ctx.builder.CreateMemCpy(phi, MaybeAlign(julia_alignment(phiType)),
    4554                 :            :              dest, MaybeAlign(0),
    4555                 :     176941 :              jl_datatype_size(phiType), false);
    4556                 :     176941 :         ctx.builder.CreateLifetimeEnd(dest);
    4557                 :     176941 :         slot = mark_julia_slot(phi, phiType, NULL, ctx.tbaa().tbaa_stack);
    4558                 :            :     }
    4559                 :            :     else {
    4560                 :    3797200 :         value_phi = PHINode::Create(vtype, jl_array_len(edges), "value_phi");
    4561                 :    3797200 :         BB->getInstList().insert(InsertPt, value_phi);
    4562                 :    3797200 :         slot = mark_julia_type(ctx, value_phi, isboxed, phiType);
    4563                 :            :     }
    4564                 :    3974140 :     ctx.PhiNodes.push_back(std::make_tuple(slot, BB, dest, value_phi, r));
    4565                 :    3974140 :     ctx.SAvalues.at(idx) = slot;
    4566                 :    3974140 :     ctx.ssavalue_assigned.at(idx) = true;
    4567                 :    3974140 :     return;
    4568                 :            : }
    4569                 :            : 
    4570                 :   28619100 : static void emit_ssaval_assign(jl_codectx_t &ctx, ssize_t ssaidx_0based, jl_value_t *r)
    4571                 :            : {
    4572         [ -  + ]:   28619100 :     assert(!ctx.ssavalue_assigned.at(ssaidx_0based));
    4573         [ +  + ]:   28619100 :     if (jl_is_phinode(r)) {
    4574                 :    4034850 :         return emit_phinode_assign(ctx, ssaidx_0based, r);
    4575                 :            :     }
    4576                 :            : 
    4577                 :   24584200 :     jl_cgval_t slot;
    4578         [ +  + ]:   24584200 :     if (jl_is_phicnode(r)) {
    4579                 :     195773 :         auto it = ctx.phic_slots.find(ssaidx_0based);
    4580         [ -  + ]:     195773 :         if (it == ctx.phic_slots.end()) {
    4581                 :          0 :             it = ctx.phic_slots.emplace(ssaidx_0based, jl_varinfo_t(ctx.builder.getContext())).first;
    4582                 :            :         }
    4583                 :     195773 :         slot = emit_varinfo(ctx, it->second, jl_symbol("phic"));
    4584                 :            :     } else {
    4585                 :   24388500 :         slot = emit_expr(ctx, r, ssaidx_0based); // slot could be a jl_value_t (unboxed) or jl_value_t* (ispointer)
    4586                 :            :     }
    4587   [ +  +  +  + ]:   24584200 :     if (slot.isboxed || slot.TIndex) {
    4588                 :            :         // see if inference suggested a different type for the ssavalue than the expression
    4589                 :            :         // e.g. sometimes the information is inconsistent after inlining getfield on a Tuple
    4590                 :    3484240 :         jl_value_t *ssavalue_types = (jl_value_t*)ctx.source->ssavaluetypes;
    4591         [ +  + ]:    3484240 :         if (jl_is_array(ssavalue_types)) {
    4592                 :    3427890 :             jl_value_t *declType = jl_array_ptr_ref(ssavalue_types, ssaidx_0based);
    4593         [ +  + ]:    3427890 :             if (declType != slot.typ) {
    4594                 :     222218 :                 slot = update_julia_type(ctx, slot, declType);
    4595                 :            :             }
    4596                 :            :         }
    4597                 :            :     }
    4598                 :   24584200 :     ctx.SAvalues.at(ssaidx_0based) = slot; // now SAvalues[ssaidx_0based] contains the SAvalue
    4599                 :   24584200 :     ctx.ssavalue_assigned.at(ssaidx_0based) = true;
    4600                 :            : }
    4601                 :            : 
    4602                 :     244792 : static void emit_varinfo_assign(jl_codectx_t &ctx, jl_varinfo_t &vi, jl_cgval_t rval_info, jl_value_t *l=NULL)
    4603                 :            : {
    4604   [ +  +  -  + ]:     244792 :     if (!vi.used || vi.value.typ == jl_bottom_type)
    4605                 :         47 :         return;
    4606                 :            : 
    4607                 :            :     // convert rval-type to lval-type
    4608                 :     244745 :     jl_value_t *slot_type = vi.value.typ;
    4609                 :     244745 :     rval_info = convert_julia_type(ctx, rval_info, slot_type);
    4610         [ +  + ]:     244745 :     if (rval_info.typ == jl_bottom_type)
    4611                 :          3 :         return;
    4612                 :            : 
    4613                 :            :     // compute / store tindex info
    4614         [ +  + ]:     244742 :     if (vi.pTIndex) {
    4615                 :            :         Value *tindex;
    4616         [ +  + ]:        509 :         if (rval_info.TIndex) {
    4617                 :        491 :             tindex = rval_info.TIndex;
    4618         [ +  + ]:        491 :             if (!vi.boxroot)
    4619                 :        422 :                 tindex = ctx.builder.CreateAnd(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x7f));
    4620                 :            :         }
    4621                 :            :         else {
    4622   [ -  +  -  - ]:         18 :             assert(rval_info.isboxed || rval_info.constant);
    4623                 :         18 :             tindex = compute_tindex_unboxed(ctx, rval_info, vi.value.typ);
    4624         [ -  + ]:         18 :             if (vi.boxroot)
    4625                 :          0 :                 tindex = ctx.builder.CreateOr(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80));
    4626                 :            :             else
    4627                 :         18 :                 rval_info.TIndex = tindex;
    4628                 :            :         }
    4629                 :        509 :         ctx.builder.CreateStore(tindex, vi.pTIndex, vi.isVolatile);
    4630                 :            :     }
    4631                 :            : 
    4632                 :            :     // store boxed variables
    4633                 :     244742 :     Value *isboxed = NULL;
    4634         [ +  + ]:     244742 :     if (vi.boxroot) {
    4635                 :            :         Value *rval;
    4636   [ +  +  +  - ]:     134184 :         if (vi.pTIndex && rval_info.TIndex) {
    4637                 :         69 :             ctx.builder.CreateStore(rval_info.TIndex, vi.pTIndex, vi.isVolatile);
    4638                 :        207 :             isboxed = ctx.builder.CreateICmpNE(
    4639                 :         69 :                     ctx.builder.CreateAnd(rval_info.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80)),
    4640                 :         69 :                     ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0));
    4641         [ +  - ]:         69 :             rval = rval_info.Vboxed ? rval_info.Vboxed : Constant::getNullValue(ctx.types().T_prjlvalue);
    4642         [ -  + ]:         69 :             assert(rval->getType() == ctx.types().T_prjlvalue);
    4643         [ -  + ]:         69 :             assert(!vi.value.constant);
    4644                 :            :         }
    4645                 :            :         else {
    4646   [ -  +  -  -  :     134115 :             assert(!vi.pTIndex || rval_info.isboxed || rval_info.constant);
                   -  - ]
    4647                 :     134115 :             rval = boxed(ctx, rval_info);
    4648                 :            :         }
    4649                 :     134184 :         ctx.builder.CreateStore(rval, vi.boxroot, vi.isVolatile);
    4650                 :            :     }
    4651                 :            : 
    4652                 :            :     // store unboxed variables
    4653   [ +  +  +  +  :     244742 :     if (!vi.boxroot || (vi.pTIndex && rval_info.TIndex)) {
                   +  - ]
    4654                 :     110627 :         emit_vi_assignment_unboxed(ctx, vi, isboxed, rval_info);
    4655                 :            :     }
    4656                 :            : }
    4657                 :            : 
    4658                 :      21736 : static void emit_assignment(jl_codectx_t &ctx, jl_value_t *l, jl_value_t *r, ssize_t ssaval)
    4659                 :            : {
    4660         [ -  + ]:      21736 :     assert(!jl_is_ssavalue(l));
    4661                 :      21736 :     jl_cgval_t rval_info = emit_expr(ctx, r, ssaval);
    4662                 :            : 
    4663   [ +  +  -  + ]:      21736 :     if (jl_is_slot(l)) {
    4664                 :      19326 :         int sl = jl_slot_number(l) - 1;
    4665                 :            :         // it's a local variable
    4666                 :      19326 :         jl_varinfo_t &vi = ctx.slots[sl];
    4667                 :      19326 :         return emit_varinfo_assign(ctx, vi, rval_info, l);
    4668                 :            :     }
    4669                 :            : 
    4670                 :       2410 :     jl_binding_t *bnd = NULL;
    4671                 :       2410 :     Value *bp = NULL;
    4672         [ -  + ]:       2410 :     if (jl_is_symbol(l))
    4673                 :          0 :         bp = global_binding_pointer(ctx, ctx.module, (jl_sym_t*)l, &bnd, true);
    4674                 :            :     else {
    4675         [ -  + ]:       2410 :         assert(jl_is_globalref(l));
    4676                 :       2410 :         bp = global_binding_pointer(ctx, jl_globalref_mod(l), jl_globalref_name(l), &bnd, true);
    4677                 :            :     }
    4678         [ +  + ]:       2410 :     if (bp != NULL) {
    4679                 :       2409 :         emit_globalset(ctx, bnd, bp, rval_info, AtomicOrdering::Unordered);
    4680                 :            :         // Global variable. Does not need debug info because the debugger knows about
    4681                 :            :         // its memory location.
    4682                 :            :     }
    4683                 :       2410 :     return;
    4684                 :            : }
    4685                 :            : 
    4686                 :     214166 : static void emit_upsilonnode(jl_codectx_t &ctx, ssize_t phic, jl_value_t *val)
    4687                 :            : {
    4688                 :     214166 :     auto it = ctx.phic_slots.find(phic);
    4689         [ -  + ]:     214166 :     if (it == ctx.phic_slots.end()) {
    4690                 :          0 :         it = ctx.phic_slots.emplace(phic, jl_varinfo_t(ctx.builder.getContext())).first;
    4691                 :            :     }
    4692                 :     214166 :     jl_varinfo_t &vi = it->second;
    4693                 :            :     // If the val is null, we can ignore the store.
    4694                 :            :     // The middle end guarantees that the value from this
    4695                 :            :     // upsilon node is not dynamically observed.
    4696         [ +  + ]:     214166 :     if (val) {
    4697                 :     205940 :         jl_cgval_t rval_info = emit_expr(ctx, val);
    4698         [ +  + ]:     205940 :         if (rval_info.typ == jl_bottom_type)
    4699                 :            :             // as a special case, PhiC nodes are allowed to use undefined
    4700                 :            :             // values, since they are just copy operations, so we need to
    4701                 :            :             // ignore the store (it will not by dynamically observed), while
    4702                 :            :             // normally, for any other operation result, we'd assume this store
    4703                 :            :             // was unreachable and dead
    4704                 :        726 :             val = NULL;
    4705                 :            :         else
    4706                 :     205214 :             emit_varinfo_assign(ctx, vi, rval_info);
    4707                 :            :     }
    4708         [ +  + ]:     214166 :     if (!val) {
    4709         [ +  + ]:       8952 :         if (vi.boxroot) {
    4710                 :            :             // memory optimization: eagerly clear this gc-root now
    4711                 :       7204 :             ctx.builder.CreateAlignedStore(Constant::getNullValue(ctx.types().T_prjlvalue), vi.boxroot, Align(sizeof(void*)), true);
    4712                 :            :         }
    4713         [ +  + ]:       8952 :         if (vi.pTIndex) {
    4714                 :            :             // We don't care what the contents of the variable are, but it
    4715                 :            :             // does need to satisfy the union invariants (i.e. inbounds
    4716                 :            :             // tindex).
    4717                 :        100 :             ctx.builder.CreateAlignedStore(
    4718         [ +  + ]:         50 :                 vi.boxroot ? ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80) :
    4719                 :         27 :                              ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x01),
    4720                 :        100 :                 vi.pTIndex, Align(1), true);
    4721                 :            :         }
    4722   [ +  +  +  -  :       8902 :         else if (vi.value.V && !vi.value.constant && vi.value.typ != jl_bottom_type) {
                   +  - ]
    4723         [ -  + ]:       1094 :             assert(vi.value.ispointer());
    4724                 :       1094 :             Type *T = cast<AllocaInst>(vi.value.V)->getAllocatedType();
    4725         [ +  + ]:       1094 :             if (CountTrackedPointers(T).count) {
    4726                 :            :                 // make sure gc pointers (including ptr_phi of union-split) are initialized to NULL
    4727                 :        233 :                 ctx.builder.CreateStore(Constant::getNullValue(T), vi.value.V, true);
    4728                 :            :             }
    4729                 :            :         }
    4730                 :            :     }
    4731                 :     214166 : }
    4732                 :            : 
    4733                 :            : // --- convert expression to code ---
    4734                 :            : 
    4735                 :            : static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, const jl_cgval_t &fexpr, jl_value_t *rt, jl_svec_t *argt);
    4736                 :            : 
    4737                 :    4990060 : static Value *emit_condition(jl_codectx_t &ctx, const jl_cgval_t &condV, const std::string &msg)
    4738                 :            : {
    4739                 :    4990060 :     bool isbool = (condV.typ == (jl_value_t*)jl_bool_type);
    4740         [ +  + ]:    4990060 :     if (!isbool) {
    4741         [ +  + ]:      17362 :         if (condV.TIndex) {
    4742                 :            :             // check whether this might be bool
    4743                 :        375 :             isbool = jl_subtype((jl_value_t*)jl_bool_type, condV.typ);
    4744                 :            :         }
    4745                 :      17362 :         emit_typecheck(ctx, condV, (jl_value_t*)jl_bool_type, msg);
    4746                 :            :     }
    4747         [ +  + ]:    4990060 :     if (isbool) {
    4748                 :    4973070 :         Value *cond = emit_unbox(ctx, getInt8Ty(ctx.builder.getContext()), condV, (jl_value_t*)jl_bool_type);
    4749         [ -  + ]:    4973070 :         assert(cond->getType() == getInt8Ty(ctx.builder.getContext()));
    4750                 :    4973070 :         return ctx.builder.CreateXor(ctx.builder.CreateTrunc(cond, getInt1Ty(ctx.builder.getContext())), ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 1));
    4751                 :            :     }
    4752         [ +  + ]:      16987 :     if (condV.isboxed) {
    4753                 :      33574 :         return ctx.builder.CreateICmpEQ(boxed(ctx, condV),
    4754                 :      16787 :             track_pjlvalue(ctx, literal_pointer_val(ctx, jl_false)));
    4755                 :            :     }
    4756                 :            :     // not a boolean
    4757                 :        200 :     return ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0); // TODO: replace with Undef
    4758                 :            : }
    4759                 :            : 
    4760                 :    4068450 : static Value *emit_condition(jl_codectx_t &ctx, jl_value_t *cond, const std::string &msg)
    4761                 :            : {
    4762                 :    4068450 :     return emit_condition(ctx, emit_expr(ctx, cond), msg);
    4763                 :            : }
    4764                 :            : 
    4765                 :   28719700 : static void emit_stmtpos(jl_codectx_t &ctx, jl_value_t *expr, int ssaval_result)
    4766                 :            : {
    4767   [ -  +  -  - ]:   28719700 :     if (jl_is_ssavalue(expr) && ssaval_result == -1)
    4768                 :          0 :         return; // value not used, no point in attempting codegen for it
    4769   [ +  +  -  +  :   28719700 :     if (jl_is_slot(expr) && ssaval_result == -1) {
                   -  + ]
    4770                 :          0 :         size_t sl = jl_slot_number(expr) - 1;
    4771                 :          0 :         jl_varinfo_t &vi = ctx.slots[sl];
    4772         [ #  # ]:          0 :         if (vi.usedUndef)
    4773                 :          0 :             (void)emit_expr(ctx, expr);
    4774                 :          0 :         return;
    4775                 :            :     }
    4776   [ -  +  -  - ]:   28719700 :     if (jl_is_argument(expr) && ssaval_result == -1) {
    4777                 :          0 :         return;
    4778                 :            :     }
    4779         [ +  + ]:   28719700 :     if (jl_is_newvarnode(expr)) {
    4780                 :       3649 :         jl_value_t *var = jl_fieldref(expr, 0);
    4781   [ -  +  -  - ]:       3649 :         assert(jl_is_slot(var));
    4782                 :       3649 :         jl_varinfo_t &vi = ctx.slots[jl_slot_number(var)-1];
    4783         [ +  + ]:       3649 :         if (vi.usedUndef) {
    4784                 :            :             // create a new uninitialized variable
    4785                 :       3623 :             Value *lv = vi.boxroot;
    4786         [ +  - ]:       3623 :             if (lv != NULL)
    4787                 :       3623 :                 ctx.builder.CreateStore(Constant::getNullValue(ctx.types().T_prjlvalue), lv);
    4788   [ +  -  -  + ]:       3623 :             if (lv == NULL || vi.pTIndex != NULL)
    4789                 :          0 :                 store_def_flag(ctx, vi, false);
    4790                 :            :         }
    4791                 :       3649 :         return;
    4792                 :            :     }
    4793         [ +  + ]:   28716000 :     if (!jl_is_expr(expr)) {
    4794         [ -  + ]:    6578540 :         assert(ssaval_result != -1);
    4795                 :    6578540 :         emit_ssaval_assign(ctx, ssaval_result, expr);
    4796                 :    6578540 :         return;
    4797                 :            :     }
    4798                 :   22137500 :     jl_expr_t *ex = (jl_expr_t*)expr;
    4799                 :   22137500 :     jl_value_t **args = (jl_value_t**)jl_array_data(ex->args);
    4800                 :   22137500 :     jl_sym_t *head = ex->head;
    4801   [ +  +  +  -  :   22137500 :     if (head == jl_meta_sym || head == jl_inbounds_sym || head == jl_coverageeffect_sym
                   +  + ]
    4802   [ +  +  +  +  :   22136600 :             || head == jl_aliasscope_sym || head == jl_popaliasscope_sym || head == jl_inline_sym || head == jl_noinline_sym) {
             +  -  -  + ]
    4803                 :            :         // some expression types are metadata and can be ignored
    4804                 :            :         // in statement position
    4805                 :        828 :         return;
    4806                 :            :     }
    4807         [ +  + ]:   22136600 :     else if (head == jl_leave_sym) {
    4808         [ -  + ]:      70148 :         assert(jl_is_long(args[0]));
    4809                 :     140296 :         ctx.builder.CreateCall(prepare_call(jlleave_func),
    4810                 :     140296 :                            ConstantInt::get(getInt32Ty(ctx.builder.getContext()), jl_unbox_long(args[0])));
    4811                 :            :     }
    4812         [ +  + ]:   22066500 :     else if (head == jl_pop_exception_sym) {
    4813                 :      25946 :         jl_cgval_t excstack_state = emit_expr(ctx, jl_exprarg(expr, 0));
    4814   [ +  -  +  - ]:      25946 :         assert(excstack_state.V && excstack_state.V->getType() == getSizeTy(ctx.builder.getContext()));
    4815                 :      25946 :         ctx.builder.CreateCall(prepare_call(jl_restore_excstack_func), excstack_state.V);
    4816                 :      25946 :         return;
    4817                 :            :     }
    4818                 :            :     else {
    4819         [ -  + ]:   22040500 :         assert(ssaval_result != -1);
    4820                 :   22040500 :         emit_ssaval_assign(ctx, ssaval_result, expr);
    4821                 :            :     }
    4822                 :            : }
    4823                 :            : 
    4824                 :         19 : static std::pair<Function*, Function*> get_oc_function(jl_codectx_t &ctx, jl_method_t *closure_method, jl_tupletype_t *env_t, jl_tupletype_t *argt_typ, jl_value_t *rettype)
    4825                 :            : {
    4826                 :         19 :     jl_svec_t *sig_args = NULL;
    4827                 :         19 :     jl_value_t *sigtype = NULL;
    4828                 :         19 :     jl_code_info_t *ir = NULL;
    4829                 :         19 :     JL_GC_PUSH3(&sig_args, &sigtype, &ir);
    4830                 :            : 
    4831                 :         19 :     size_t nsig = 1 + jl_svec_len(argt_typ->parameters);
    4832                 :         19 :     sig_args = jl_alloc_svec_uninit(nsig);
    4833                 :         19 :     jl_svecset(sig_args, 0, env_t);
    4834         [ +  + ]:         25 :     for (size_t i = 0; i < jl_svec_len(argt_typ->parameters); ++i) {
    4835                 :          6 :         jl_svecset(sig_args, 1+i, jl_svecref(argt_typ->parameters, i));
    4836                 :            :     }
    4837                 :         19 :     sigtype = (jl_value_t*)jl_apply_tuple_type_v(jl_svec_data(sig_args), nsig);
    4838                 :            : 
    4839                 :         19 :     jl_method_instance_t *mi = jl_specializations_get_linfo(closure_method, sigtype, jl_emptysvec);
    4840                 :         19 :     jl_code_instance_t *ci = (jl_code_instance_t*)jl_rettype_inferred(mi, ctx.world, ctx.world);
    4841                 :            : 
    4842   [ +  -  +  +  :         19 :     if (ci == NULL || (jl_value_t*)ci == jl_nothing || ci->inferred == NULL || ci->inferred == jl_nothing) {
             +  -  +  + ]
    4843                 :         10 :         JL_GC_POP();
    4844                 :         10 :         return std::make_pair((Function*)NULL, (Function*)NULL);
    4845                 :            :     }
    4846                 :          9 :     ++EmittedOpaqueClosureFunctions;
    4847                 :            : 
    4848                 :          9 :     ir = jl_uncompress_ir(closure_method, ci, (jl_array_t*)ci->inferred);
    4849                 :            : 
    4850                 :            :     // TODO: Emit this inline and outline it late using LLVM's coroutine support.
    4851                 :            :     orc::ThreadSafeModule closure_m = jl_create_llvm_module(
    4852                 :          9 :             name_from_method_instance(mi), ctx.emission_context.tsctx,
    4853                 :          9 :             ctx.emission_context.imaging,
    4854                 :         18 :             jl_Module->getDataLayout(), Triple(jl_Module->getTargetTriple()));
    4855                 :         18 :     jl_llvm_functions_t closure_decls = emit_function(closure_m, mi, ir, rettype, ctx.emission_context);
    4856                 :            : 
    4857         [ -  + ]:          9 :     assert(closure_decls.functionObject != "jl_fptr_sparam");
    4858                 :          9 :     bool isspecsig = closure_decls.functionObject != "jl_fptr_args";
    4859                 :            : 
    4860                 :          9 :     Function *F = NULL;
    4861                 :            :     std::string fname = isspecsig ?
    4862                 :            :         closure_decls.functionObject :
    4863         [ +  - ]:         18 :         closure_decls.specFunctionObject;
    4864         [ -  + ]:          9 :     if (GlobalValue *V = jl_Module->getNamedValue(fname)) {
    4865                 :          0 :         F = cast<Function>(V);
    4866                 :            :     } else {
    4867                 :          9 :         F = Function::Create(get_func_sig(ctx.builder.getContext()),
    4868                 :            :                              Function::ExternalLinkage,
    4869                 :          9 :                              fname, jl_Module);
    4870                 :          9 :         jl_init_function(F);
    4871                 :          9 :         F->setAttributes(AttributeList::get(ctx.builder.getContext(), {get_func_attrs(ctx.builder.getContext()), F->getAttributes()}));
    4872                 :            :     }
    4873                 :          9 :     Function *specF = NULL;
    4874         [ -  + ]:          9 :     if (!isspecsig) {
    4875                 :          0 :         specF = F;
    4876                 :            :     } else {
    4877                 :            :         //emission context holds context lock so can get module
    4878                 :          9 :         specF = closure_m.getModuleUnlocked()->getFunction(closure_decls.specFunctionObject);
    4879         [ +  - ]:          9 :         if (specF) {
    4880                 :          9 :             jl_returninfo_t returninfo = get_specsig_function(ctx, jl_Module,
    4881                 :          9 :                 closure_decls.specFunctionObject, sigtype, rettype, true);
    4882                 :          9 :             specF = returninfo.decl;
    4883                 :            :         }
    4884                 :            :     }
    4885                 :          9 :     ctx.oc_modules.push_back(std::move(closure_m));
    4886                 :          9 :     JL_GC_POP();
    4887                 :          9 :     return std::make_pair(F, specF);
    4888                 :            : }
    4889                 :            : 
    4890                 :            : // `expr` is not clobbered in JL_TRY
    4891                 :            : JL_GCC_IGNORE_START("-Wclobbered")
    4892                 :  105115000 : static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_0based)
    4893                 :            : {
    4894         [ -  + ]:  105115000 :     if (jl_is_symbol(expr)) {
    4895                 :          0 :         jl_sym_t *sym = (jl_sym_t*)expr;
    4896                 :          0 :         return emit_global(ctx, sym);
    4897                 :            :     }
    4898   [ +  +  +  -  :  105115000 :     if (jl_is_slot(expr) || jl_is_argument(expr)) {
                   +  + ]
    4899                 :    3456900 :         return emit_local(ctx, expr);
    4900                 :            :     }
    4901         [ +  + ]:  101658000 :     if (jl_is_ssavalue(expr)) {
    4902                 :   36193400 :         ssize_t idx = ((jl_ssavalue_t*)expr)->id - 1;
    4903         [ -  + ]:   36193400 :         assert(idx >= 0);
    4904         [ +  + ]:   36193400 :         if (!ctx.ssavalue_assigned.at(idx)) {
    4905                 :       1034 :             ctx.ssavalue_assigned.at(idx) = true; // (assignment, not comparison test)
    4906                 :       1034 :             return jl_cgval_t(); // dead code branch
    4907                 :            :         }
    4908                 :            :         else {
    4909                 :   36192400 :             return ctx.SAvalues.at(idx); // at this point, SAvalues[idx] actually contains the SAvalue
    4910                 :            :         }
    4911                 :            :     }
    4912         [ +  + ]:   65465000 :     if (jl_is_globalref(expr)) {
    4913                 :   21912200 :         return emit_globalref(ctx, jl_globalref_mod(expr), jl_globalref_name(expr), AtomicOrdering::Unordered);
    4914                 :            :     }
    4915         [ -  + ]:   43552700 :     if (jl_is_linenode(expr)) {
    4916                 :          0 :         jl_error("LineNumberNode in value position");
    4917                 :            :     }
    4918         [ -  + ]:   43552700 :     if (jl_is_gotonode(expr)) {
    4919                 :          0 :         jl_error("GotoNode in value position");
    4920                 :            :     }
    4921         [ -  + ]:   43552700 :     if (jl_is_gotoifnot(expr)) {
    4922                 :          0 :         jl_error("GotoIfNot in value position");
    4923                 :            :     }
    4924         [ +  + ]:   43552700 :     if (jl_is_pinode(expr)) {
    4925                 :     289732 :         Value *skip = NULL;
    4926                 :     579464 :         return convert_julia_type(ctx, emit_expr(ctx, jl_fieldref_noalloc(expr, 0)), jl_fieldref_noalloc(expr, 1), &skip);
    4927                 :            :     }
    4928         [ +  + ]:   43263000 :     if (!jl_is_expr(expr)) {
    4929                 :   21202200 :         int needroot = true;
    4930         [ +  + ]:   21202200 :         if (jl_is_quotenode(expr)) {
    4931                 :    3916440 :             expr = jl_fieldref_noalloc(expr,0);
    4932                 :            :         }
    4933                 :            :         // numeric literals
    4934         [ +  + ]:   21202200 :         if (jl_is_int32(expr)) {
    4935                 :      31949 :             int32_t val = jl_unbox_int32(expr);
    4936         [ +  + ]:      31949 :             if ((uint32_t)(val+512) < 1024) {
    4937                 :            :                 // this can be gotten from the box cache
    4938                 :      28426 :                 needroot = false;
    4939                 :      28426 :                 expr = jl_box_int32(val);
    4940                 :            :             }
    4941                 :            :         }
    4942         [ +  + ]:   21170300 :         else if (jl_is_int64(expr)) {
    4943                 :    7679060 :             uint64_t val = jl_unbox_uint64(expr);
    4944         [ +  + ]:    7679060 :             if ((uint64_t)(val+512) < 1024) {
    4945                 :            :                 // this can be gotten from the box cache
    4946                 :    7641720 :                 needroot = false;
    4947                 :    7641720 :                 expr = jl_box_int64(val);
    4948                 :            :             }
    4949                 :            :         }
    4950         [ +  + ]:   13491200 :         else if (jl_is_uint8(expr)) {
    4951                 :     209892 :             expr = jl_box_uint8(jl_unbox_uint8(expr));
    4952                 :     209892 :             needroot = false;
    4953                 :            :         }
    4954   [ +  +  +  + ]:   21202200 :         if (needroot && jl_is_method(ctx.linfo->def.method)) { // toplevel exprs and some integers are already rooted
    4955                 :   12903900 :             jl_add_method_root(ctx, expr);
    4956                 :            :         }
    4957                 :   21202200 :         return mark_julia_const(ctx, expr);
    4958                 :            :     }
    4959                 :            : 
    4960                 :   22060800 :     jl_expr_t *ex = (jl_expr_t*)expr;
    4961                 :   22060800 :     jl_value_t **args = (jl_value_t**)jl_array_data(ex->args);
    4962                 :   22060800 :     size_t nargs = jl_array_len(ex->args);
    4963                 :   22060800 :     jl_sym_t *head = ex->head;
    4964                 :            :     // this is object-disoriented.
    4965                 :            :     // however, this is a good way to do it because it should *not* be easy
    4966                 :            :     // to add new node types.
    4967         [ +  + ]:   22060800 :     if (head == jl_isdefined_sym) {
    4968         [ -  + ]:         52 :         assert(nargs == 1);
    4969                 :         52 :         return emit_isdefined(ctx, args[0]);
    4970                 :            :     }
    4971         [ +  + ]:   22060700 :     else if (head == jl_throw_undef_if_not_sym) {
    4972         [ -  + ]:      21083 :         assert(nargs == 2);
    4973                 :      21083 :         jl_sym_t *var = (jl_sym_t*)args[0];
    4974                 :      21083 :         Value *cond = ctx.builder.CreateTrunc(emit_unbox(ctx, getInt8Ty(ctx.builder.getContext()), emit_expr(ctx, args[1]), (jl_value_t*)jl_bool_type), getInt1Ty(ctx.builder.getContext()));
    4975         [ -  + ]:      21083 :         if (var == jl_getfield_undefref_sym) {
    4976                 :          0 :             raise_exception_unless(ctx, cond,
    4977                 :            :                 literal_pointer_val(ctx, jl_undefref_exception));
    4978                 :            :         }
    4979                 :            :         else {
    4980                 :      21083 :             undef_var_error_ifnot(ctx, cond, var);
    4981                 :            :         }
    4982                 :      21083 :         return ghostValue(ctx, jl_nothing_type);
    4983                 :            :     }
    4984         [ +  + ]:   22039600 :     else if (head == jl_invoke_sym) {
    4985         [ -  + ]:    1589370 :         assert(ssaidx_0based >= 0);
    4986         [ +  - ]:    1589370 :         jl_value_t *expr_t = jl_is_long(ctx.source->ssavaluetypes) ? (jl_value_t*)jl_any_type :
    4987                 :    1589370 :             jl_array_ptr_ref(ctx.source->ssavaluetypes, ssaidx_0based);
    4988                 :    1589370 :         return emit_invoke(ctx, ex, expr_t);
    4989                 :            :     }
    4990         [ +  + ]:   20450300 :     else if (head == jl_invoke_modify_sym) {
    4991         [ -  + ]:         15 :         assert(ssaidx_0based >= 0);
    4992         [ +  - ]:         15 :         jl_value_t *expr_t = jl_is_long(ctx.source->ssavaluetypes) ? (jl_value_t*)jl_any_type :
    4993                 :         15 :             jl_array_ptr_ref(ctx.source->ssavaluetypes, ssaidx_0based);
    4994                 :         15 :         return emit_invoke_modify(ctx, ex, expr_t);
    4995                 :            :     }
    4996         [ +  + ]:   20450200 :     else if (head == jl_call_sym) {
    4997                 :            :         jl_value_t *expr_t;
    4998                 :   19086400 :         bool is_promotable = false;
    4999         [ -  + ]:   19086400 :         if (ssaidx_0based < 0)
    5000                 :            :             // TODO: this case is needed for the call to emit_expr in emit_llvmcall
    5001                 :          0 :             expr_t = (jl_value_t*)jl_any_type;
    5002                 :            :         else {
    5003         [ +  + ]:   19086400 :             expr_t = jl_is_long(ctx.source->ssavaluetypes) ? (jl_value_t*)jl_any_type : jl_array_ptr_ref(ctx.source->ssavaluetypes, ssaidx_0based);
    5004                 :   19086400 :             is_promotable = ctx.ssavalue_usecount[ssaidx_0based] == 1;
    5005                 :            :         }
    5006                 :   19086400 :         jl_cgval_t res = emit_call(ctx, ex, expr_t, is_promotable);
    5007                 :            :         // some intrinsics (e.g. typeassert) can return a wider type
    5008                 :            :         // than what's actually possible
    5009   [ +  +  +  + ]:   19086400 :         if (is_promotable && res.promotion_point) {
    5010                 :     368764 :             res.promotion_ssa = ssaidx_0based;
    5011                 :            :         }
    5012                 :   19086400 :         res = update_julia_type(ctx, res, expr_t);
    5013   [ +  +  +  + ]:   19086400 :         if (res.typ == jl_bottom_type || expr_t == jl_bottom_type) {
    5014                 :     300128 :             CreateTrap(ctx.builder);
    5015                 :            :         }
    5016                 :   19086400 :         return res;
    5017                 :            :     }
    5018         [ +  + ]:    1363830 :     else if (head == jl_foreigncall_sym) {
    5019                 :     548345 :         return emit_ccall(ctx, args, jl_array_dim0(ex->args));
    5020                 :            :     }
    5021         [ +  + ]:     815486 :     else if (head == jl_cfunction_sym) {
    5022         [ -  + ]:        864 :         assert(nargs == 5);
    5023                 :        864 :         jl_cgval_t fexpr_rt = emit_expr(ctx, args[1]);
    5024                 :        864 :         return emit_cfunction(ctx, args[0], fexpr_rt, args[2], (jl_svec_t*)args[3]);
    5025                 :            :     }
    5026         [ +  + ]:     814622 :     else if (head == jl_assign_sym) {
    5027         [ -  + ]:      21736 :         assert(nargs == 2);
    5028                 :      21736 :         emit_assignment(ctx, args[0], args[1], ssaidx_0based);
    5029                 :      21736 :         return ghostValue(ctx, jl_nothing_type);
    5030                 :            :     }
    5031         [ +  + ]:     792886 :     else if (head == jl_static_parameter_sym) {
    5032         [ -  + ]:      10630 :         assert(nargs == 1);
    5033                 :      10630 :         return emit_sparam(ctx, jl_unbox_long(args[0]) - 1);
    5034                 :            :     }
    5035         [ +  + ]:     782256 :     else if (head == jl_method_sym) {
    5036         [ +  + ]:        350 :         if (nargs == 1) {
    5037                 :         10 :             jl_value_t *mn = args[0];
    5038   [ -  +  -  -  :         10 :             assert(jl_is_symbol(mn) || jl_is_slot(mn));
                   -  - ]
    5039                 :            : 
    5040                 :         10 :             Value *bp = NULL, *name, *bp_owner = Constant::getNullValue(ctx.types().T_pjlvalue);
    5041                 :         10 :             jl_binding_t *bnd = NULL;
    5042                 :         10 :             bool issym = jl_is_symbol(mn);
    5043   [ -  +  -  - ]:         10 :             bool isglobalref = !issym && jl_is_globalref(mn);
    5044                 :         10 :             jl_module_t *mod = ctx.module;
    5045   [ -  +  -  - ]:         10 :             if (issym || isglobalref) {
    5046         [ -  + ]:         10 :                 if (isglobalref) {
    5047                 :          0 :                     mod = jl_globalref_mod(mn);
    5048                 :          0 :                     mn = (jl_value_t*)jl_globalref_name(mn);
    5049                 :            :                 }
    5050   [ +  -  +  + ]:         20 :                 JL_TRY {
    5051         [ -  + ]:         10 :                     if (jl_symbol_name((jl_sym_t*)mn)[0] == '@')
    5052                 :          0 :                         jl_errorf("macro definition not allowed inside a local scope");
    5053                 :         10 :                     name = literal_pointer_val(ctx, mn);
    5054                 :         10 :                     bnd = jl_get_binding_for_method_def(mod, (jl_sym_t*)mn);
    5055                 :            :                 }
    5056         [ #  # ]:          0 :                 JL_CATCH {
    5057                 :          0 :                     jl_value_t *e = jl_current_exception();
    5058                 :            :                     // errors. boo. root it somehow :(
    5059                 :          0 :                     bnd = jl_get_binding_wr(ctx.module, (jl_sym_t*)jl_gensym(), 1);
    5060                 :          0 :                     bnd->value = e;
    5061                 :          0 :                     bnd->constp = 1;
    5062                 :          0 :                     raise_exception(ctx, literal_pointer_val(ctx, e));
    5063                 :          0 :                     return ghostValue(ctx, jl_nothing_type);
    5064                 :            :                 }
    5065                 :         10 :                 bp = julia_binding_gv(ctx, bnd);
    5066                 :         10 :                 bp = julia_binding_pvalue(ctx, bp);
    5067                 :         10 :                 bp_owner = literal_pointer_val(ctx, (jl_value_t*)mod);
    5068                 :            :             }
    5069   [ #  #  #  #  :          0 :             else if (jl_is_slot(mn) || jl_is_argument(mn)) {
                   #  # ]
    5070                 :          0 :                 int sl = jl_slot_number(mn)-1;
    5071                 :          0 :                 jl_varinfo_t &vi = ctx.slots[sl];
    5072                 :          0 :                 bp = vi.boxroot;
    5073                 :          0 :                 name = literal_pointer_val(ctx, (jl_value_t*)slot_symbol(ctx, sl));
    5074                 :            :             }
    5075         [ +  - ]:         10 :             if (bp) {
    5076                 :         20 :                 Value *mdargs[5] = { name, literal_pointer_val(ctx, (jl_value_t*)mod), bp,
    5077                 :         10 :                                     bp_owner, literal_pointer_val(ctx, bnd) };
    5078                 :            :                 jl_cgval_t gf = mark_julia_type(
    5079                 :            :                         ctx,
    5080                 :         10 :                         ctx.builder.CreateCall(prepare_call(jlgenericfunction_func), makeArrayRef(mdargs)),
    5081                 :            :                         true,
    5082                 :         20 :                         jl_function_type);
    5083                 :         10 :                 return gf;
    5084                 :            :             }
    5085                 :          0 :             emit_error(ctx, "method: invalid declaration");
    5086                 :          0 :             return jl_cgval_t();
    5087                 :            :         }
    5088         [ -  + ]:        340 :         assert(nargs == 3);
    5089                 :        340 :         Value *a1 = boxed(ctx, emit_expr(ctx, args[1]));
    5090                 :        340 :         Value *a2 = boxed(ctx, emit_expr(ctx, args[2]));
    5091                 :            :         Value *mdargs[4] = {
    5092                 :            :             /*argdata*/a1,
    5093                 :        340 :             ConstantPointerNull::get(cast<PointerType>(ctx.types().T_prjlvalue)),
    5094                 :            :             /*code*/a2,
    5095                 :        680 :             /*module*/literal_pointer_val(ctx, (jl_value_t*)ctx.module)
    5096                 :        680 :         };
    5097                 :            :         jl_cgval_t meth = mark_julia_type(
    5098                 :            :             ctx,
    5099                 :        340 :             ctx.builder.CreateCall(prepare_call(jlmethod_func), makeArrayRef(mdargs)),
    5100                 :            :             true,
    5101                 :        680 :             jl_method_type);
    5102                 :        340 :         return meth;
    5103                 :            :     }
    5104         [ +  + ]:     781906 :     else if (head == jl_const_sym) {
    5105         [ -  + ]:         36 :         assert(nargs == 1);
    5106                 :         36 :         jl_sym_t *sym = (jl_sym_t*)args[0];
    5107                 :         36 :         jl_module_t *mod = ctx.module;
    5108         [ -  + ]:         36 :         if (jl_is_globalref(sym)) {
    5109                 :          0 :             mod = jl_globalref_mod(sym);
    5110                 :          0 :             sym = jl_globalref_name(sym);
    5111                 :            :         }
    5112         [ +  - ]:         36 :         if (jl_is_symbol(sym)) {
    5113                 :         36 :             jl_binding_t *bnd = NULL;
    5114                 :         36 :             Value *bp = global_binding_pointer(ctx, mod, sym, &bnd, true);
    5115         [ +  - ]:         36 :             if (bp)
    5116                 :         36 :                 ctx.builder.CreateCall(prepare_call(jldeclareconst_func), bp);
    5117                 :            :         }
    5118                 :            :     }
    5119         [ +  + ]:     781870 :     else if (head == jl_new_sym) {
    5120                 :     652071 :         bool is_promotable = false;
    5121         [ +  - ]:     652071 :         if (ssaidx_0based >= 0) {
    5122                 :     652071 :             is_promotable = ctx.ssavalue_usecount[ssaidx_0based] == 1;
    5123                 :            :         }
    5124         [ -  + ]:     652071 :         assert(nargs > 0);
    5125                 :     652071 :         jl_cgval_t *argv = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * nargs);
    5126         [ +  + ]:    2479180 :         for (size_t i = 0; i < nargs; ++i) {
    5127                 :    1827110 :             argv[i] = emit_expr(ctx, args[i]);
    5128                 :            :         }
    5129                 :     652071 :         jl_value_t *ty = argv[0].typ;
    5130                 :     652071 :         if (jl_is_type_type(ty) &&
    5131   [ +  +  +  -  :    1301000 :                 jl_is_datatype(jl_tparam0(ty)) &&
                   +  + ]
    5132         [ +  + ]:     648924 :                 jl_is_concrete_type(jl_tparam0(ty))) {
    5133         [ -  + ]:     648914 :             assert(nargs <= jl_datatype_nfields(jl_tparam0(ty)) + 1);
    5134                 :     648914 :             jl_cgval_t res = emit_new_struct(ctx, jl_tparam0(ty), nargs - 1, &argv[1], is_promotable);
    5135   [ +  +  +  +  :     648914 :             if (is_promotable && res.promotion_point && res.promotion_ssa==-1)
                   +  + ]
    5136                 :     224722 :                 res.promotion_ssa = ssaidx_0based;
    5137                 :     648914 :             return res;
    5138                 :            :         }
    5139                 :       3157 :         Value *val = emit_jlcall(ctx, jlnew_func, nullptr, argv, nargs, julia_call);
    5140                 :            :         // temporarily mark as `Any`, expecting `emit_ssaval_assign` to update
    5141                 :            :         // it to the inferred type.
    5142                 :       3157 :         return mark_julia_type(ctx, val, true, (jl_value_t*)jl_any_type);
    5143                 :            :     }
    5144         [ +  + ]:     129799 :     else if (head == jl_splatnew_sym) {
    5145                 :          3 :         jl_cgval_t argv[2] = {jl_cgval_t(), jl_cgval_t()};
    5146         [ -  + ]:          3 :         assert(nargs == 2);
    5147                 :          3 :         argv[0] = emit_expr(ctx, args[0]);
    5148                 :          3 :         argv[1] = emit_expr(ctx, args[1]);
    5149                 :          3 :         Value *typ = boxed(ctx, argv[0]);
    5150                 :          3 :         Value *tup = boxed(ctx, argv[1]);
    5151                 :          3 :         Value *val = ctx.builder.CreateCall(prepare_call(jlsplatnew_func), { typ, tup });
    5152                 :            :         // temporarily mark as `Any`, expecting `emit_ssaval_assign` to update
    5153                 :            :         // it to the inferred type.
    5154                 :          3 :         return mark_julia_type(ctx, val, true, (jl_value_t*)jl_any_type);
    5155                 :            :     }
    5156         [ +  + ]:     129796 :     else if (head == jl_new_opaque_closure_sym) {
    5157         [ -  + ]:         20 :         assert(nargs >= 4 && "Not enough arguments in new_opaque_closure");
    5158                 :         40 :         SmallVector<jl_cgval_t, 4> argv(nargs, jl_cgval_t());
    5159         [ +  + ]:        112 :         for (size_t i = 0; i < nargs; ++i) {
    5160                 :         92 :             argv[i] = emit_expr(ctx, args[i]);
    5161                 :            :         }
    5162                 :         20 :         const jl_cgval_t &argt = argv[0];
    5163                 :         20 :         const jl_cgval_t &lb = argv[1];
    5164                 :         20 :         const jl_cgval_t &ub = argv[2];
    5165                 :         20 :         const jl_cgval_t &source = argv[3];
    5166         [ -  + ]:         20 :         if (source.constant == NULL) {
    5167                 :            :             // For now, we require non-constant source to be handled by using
    5168                 :            :             // eval. This should probably be a verifier error and an abort here.
    5169                 :          0 :             emit_error(ctx, "(internal error) invalid IR: opaque closure source be constant");
    5170                 :          0 :             return jl_cgval_t();
    5171                 :            :         }
    5172   [ +  -  +  - ]:         19 :         bool can_optimize = argt.constant != NULL && lb.constant != NULL && ub.constant != NULL &&
    5173         [ +  - ]:         19 :             jl_is_tuple_type(argt.constant) &&
    5174   [ +  -  +  -  :         19 :             jl_is_type(lb.constant) && jl_is_type(ub.constant) && jl_is_method(source.constant) &&
                   +  - ]
    5175   [ +  +  +  - ]:         58 :             ((jl_method_t*)source.constant)->nargs > 0 &&
    5176         [ +  - ]:         19 :             jl_is_valid_oc_argtype((jl_tupletype_t*)argt.constant, (jl_method_t*)source.constant);
    5177                 :            : 
    5178         [ +  + ]:         20 :         if (can_optimize) {
    5179                 :         19 :             jl_value_t *closure_t = NULL;
    5180                 :         19 :             jl_tupletype_t *env_t = NULL;
    5181                 :         19 :             JL_GC_PUSH2(&closure_t, &env_t);
    5182                 :            : 
    5183                 :         19 :             jl_value_t **env_component_ts = (jl_value_t**)alloca(sizeof(jl_value_t*) * (nargs-4));
    5184         [ +  + ]:         31 :             for (size_t i = 0; i < nargs - 4; ++i) {
    5185                 :         12 :                 env_component_ts[i] = argv[4+i].typ;
    5186                 :            :             }
    5187                 :            : 
    5188                 :         19 :             env_t = jl_apply_tuple_type_v(env_component_ts, nargs-4);
    5189                 :            :             // we need to know the full env type to look up the right specialization
    5190         [ +  - ]:         19 :             if (jl_is_concrete_type((jl_value_t*)env_t)) {
    5191                 :         19 :                 jl_tupletype_t *argt_typ = (jl_tupletype_t*)argt.constant;
    5192                 :            :                 Function *F, *specF;
    5193                 :         19 :                 std::tie(F, specF) = get_oc_function(ctx, (jl_method_t*)source.constant, env_t, argt_typ, ub.constant);
    5194         [ +  + ]:         19 :                 if (F) {
    5195                 :          9 :                     jl_cgval_t jlcall_ptr = mark_julia_type(ctx, F, false, jl_voidpointer_type);
    5196                 :            :                     jl_cgval_t world_age = mark_julia_type(ctx,
    5197                 :          9 :                                       tbaa_decorate(ctx.tbaa().tbaa_gcframe,
    5198                 :          9 :                                       ctx.builder.CreateAlignedLoad(getSizeTy(ctx.builder.getContext()), get_last_age_field(ctx), Align(sizeof(size_t)))),
    5199                 :            :                         false,
    5200                 :         18 :                         jl_long_type);
    5201                 :          9 :                     jl_cgval_t fptr;
    5202         [ +  - ]:          9 :                     if (specF)
    5203                 :          9 :                         fptr = mark_julia_type(ctx, specF, false, jl_voidpointer_type);
    5204                 :            :                     else
    5205                 :          0 :                         fptr = mark_julia_type(ctx, (llvm::Value*)Constant::getNullValue(getSizeTy(ctx.builder.getContext())), false, jl_voidpointer_type);
    5206                 :            : 
    5207                 :            :                     // TODO: Inline the env at the end of the opaque closure and generate a descriptor for GC
    5208                 :          9 :                     jl_cgval_t env = emit_new_struct(ctx, (jl_value_t*)env_t, nargs-4, &argv.data()[4]);
    5209                 :            : 
    5210                 :            :                     jl_cgval_t closure_fields[5] = {
    5211                 :            :                         env,
    5212                 :            :                         world_age,
    5213                 :            :                         source,
    5214                 :            :                         jlcall_ptr,
    5215                 :            :                         fptr
    5216                 :          9 :                     };
    5217                 :            : 
    5218                 :          9 :                     closure_t = jl_apply_type2((jl_value_t*)jl_opaque_closure_type, (jl_value_t*)argt_typ, ub.constant);
    5219                 :          9 :                     jl_cgval_t ret = emit_new_struct(ctx, closure_t, 5, closure_fields);
    5220                 :            : 
    5221                 :          9 :                     JL_GC_POP();
    5222                 :          9 :                     return ret;
    5223                 :            :                 }
    5224                 :            :             }
    5225                 :         10 :             JL_GC_POP();
    5226                 :            :         }
    5227                 :            : 
    5228                 :            :         return mark_julia_type(ctx,
    5229                 :         11 :                 emit_jlcall(ctx, jl_new_opaque_closure_jlcall_func, Constant::getNullValue(ctx.types().T_prjlvalue), argv.data(), nargs, julia_call),
    5230                 :         22 :                 true, jl_any_type);
    5231                 :            :     }
    5232         [ +  + ]:     129776 :     else if (head == jl_exc_sym) {
    5233         [ -  + ]:      24390 :         assert(nargs == 0);
    5234                 :            :         return mark_julia_type(ctx,
    5235                 :      48780 :                 ctx.builder.CreateCall(prepare_call(jl_current_exception_func)),
    5236                 :      48780 :                 true, jl_any_type);
    5237                 :            :     }
    5238         [ +  + ]:     105386 :     else if (head == jl_copyast_sym) {
    5239         [ -  + ]:       5379 :         assert(nargs == 1);
    5240                 :       5379 :         jl_cgval_t ast = emit_expr(ctx, args[0]);
    5241   [ +  +  +  - ]:       5379 :         if (ast.typ != (jl_value_t*)jl_expr_type && ast.typ != (jl_value_t*)jl_any_type) {
    5242                 :            :             // elide call to jl_copy_ast when possible
    5243                 :        383 :             return ast;
    5244                 :            :         }
    5245                 :            :         return mark_julia_type(ctx,
    5246                 :       4996 :                 ctx.builder.CreateCall(prepare_call(jlcopyast_func),
    5247                 :      14988 :                                        boxed(ctx, ast)), true, jl_expr_type);
    5248                 :            :     }
    5249         [ +  + ]:     100007 :     else if (head == jl_loopinfo_sym) {
    5250                 :            :         // parse Expr(:loopinfo, "julia.simdloop", ("llvm.loop.vectorize.width", 4))
    5251                 :      41550 :         SmallVector<Metadata *, 8> MDs;
    5252         [ +  + ]:      62325 :         for (int i = 0, ie = nargs; i < ie; ++i) {
    5253                 :      41550 :             Metadata *MD = to_md_tree(args[i], ctx.builder.getContext());
    5254         [ +  + ]:      41550 :             if (MD)
    5255                 :      20779 :                 MDs.push_back(MD);
    5256                 :            :         }
    5257                 :            : 
    5258                 :      20775 :         MDNode* MD = MDNode::get(ctx.builder.getContext(), MDs);
    5259                 :      20775 :         CallInst *I = ctx.builder.CreateCall(prepare_call(jl_loopinfo_marker_func));
    5260                 :      20775 :         I->setMetadata("julia.loopinfo", MD);
    5261                 :      20775 :         return jl_cgval_t();
    5262                 :            :     }
    5263   [ +  -  +  - ]:      79232 :     else if (head == jl_leave_sym || head == jl_coverageeffect_sym
    5264   [ +  -  +  -  :      79232 :             || head == jl_pop_exception_sym || head == jl_enter_sym || head == jl_inbounds_sym
                   +  - ]
    5265   [ +  -  +  -  :      79232 :             || head == jl_aliasscope_sym || head == jl_popaliasscope_sym || head == jl_inline_sym || head == jl_noinline_sym) {
             +  -  -  + ]
    5266                 :          0 :         jl_errorf("Expr(:%s) in value position", jl_symbol_name(head));
    5267                 :            :     }
    5268         [ +  + ]:      79232 :     else if (head == jl_boundscheck_sym) {
    5269         [ +  + ]:       6790 :         return mark_julia_const(ctx, bounds_check_enabled(ctx, jl_true) ? jl_true : jl_false);
    5270                 :            :     }
    5271         [ +  + ]:      72442 :     else if (head == jl_gc_preserve_begin_sym) {
    5272                 :      36296 :         jl_cgval_t *argv = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * nargs);
    5273         [ +  + ]:      74449 :         for (size_t i = 0; i < nargs; ++i) {
    5274                 :      38153 :             argv[i] = emit_expr(ctx, args[i]);
    5275                 :            :         }
    5276                 :      36296 :         std::vector<Value*> vals;
    5277         [ +  + ]:      74449 :         for (size_t i = 0; i < nargs; ++i) {
    5278                 :      38153 :             const jl_cgval_t &ai = argv[i];
    5279   [ +  +  -  + ]:      38153 :             if (ai.constant || ai.typ == jl_bottom_type)
    5280                 :       7762 :                 continue;
    5281         [ +  + ]:      30391 :             if (ai.isboxed) {
    5282                 :      29166 :                 vals.push_back(ai.Vboxed);
    5283                 :            :             }
    5284   [ +  +  +  +  :       1225 :             else if (jl_is_concrete_immutable(ai.typ) && !jl_is_pointerfree(ai.typ)) {
                   +  + ]
    5285                 :       1193 :                 Type *at = julia_type_to_llvm(ctx, ai.typ);
    5286                 :       1193 :                 vals.push_back(emit_unbox(ctx, at, ai, ai.typ));
    5287                 :            :             }
    5288                 :            :         }
    5289                 :      36296 :         Value *token = vals.empty()
    5290         [ +  + ]:      36296 :             ? (Value*)ConstantTokenNone::get(ctx.builder.getContext())
    5291                 :      28510 :             : ctx.builder.CreateCall(prepare_call(gc_preserve_begin_func), vals);
    5292                 :      36296 :         jl_cgval_t tok(token, (jl_value_t*)jl_nothing_type, NULL);
    5293                 :      36296 :         return tok;
    5294                 :            :     }
    5295         [ +  + ]:      36146 :     else if (head == jl_gc_preserve_end_sym) {
    5296                 :            :         // We only support ssa values as the argument. Everything else will
    5297                 :            :         // fall back to the default behavior of preserving the argument value
    5298                 :            :         // until the end of the scope, which is correct, but not optimal.
    5299         [ +  + ]:      35844 :         if (!jl_is_ssavalue(args[0])) {
    5300                 :          2 :             return jl_cgval_t((jl_value_t*)jl_nothing_type);
    5301                 :            :         }
    5302                 :      35842 :         jl_cgval_t token = emit_expr(ctx, args[0]);
    5303         [ -  + ]:      35842 :         assert(token.V->getType()->isTokenTy());
    5304         [ +  + ]:      35842 :         if (!isa<ConstantTokenNone>(token.V))
    5305                 :      28056 :             ctx.builder.CreateCall(prepare_call(gc_preserve_end_func), {token.V});
    5306                 :      35842 :         return jl_cgval_t((jl_value_t*)jl_nothing_type);
    5307                 :            :     }
    5308                 :            :     else {
    5309   [ +  -  +  - ]:        604 :         if (jl_is_toplevel_only_expr(expr) &&
    5310         [ +  - ]:        302 :             !jl_is_method(ctx.linfo->def.method)) {
    5311                 :            :             // call interpreter to run a toplevel expr from inside a
    5312                 :            :             // compiled toplevel thunk.
    5313                 :            :             Value *args[2] = {
    5314                 :        302 :                 literal_pointer_val(ctx, (jl_value_t*)ctx.module),
    5315                 :        604 :                 literal_pointer_val(ctx, expr)
    5316                 :        302 :             };
    5317                 :        302 :             ctx.builder.CreateCall(prepare_call(jltopeval_func), args);
    5318                 :        302 :             return ghostValue(ctx, jl_nothing_type);
    5319                 :            :         }
    5320                 :          0 :         jl_errorf("unsupported or misplaced expression \"%s\" in function %s",
    5321                 :            :                   jl_symbol_name(head), ctx.name);
    5322                 :            :     }
    5323                 :         36 :     return jl_cgval_t();
    5324                 :            : }
    5325                 :            : JL_GCC_IGNORE_STOP
    5326                 :            : 
    5327                 :            : // --- generate function bodies ---
    5328                 :            : 
    5329                 :            : // gc frame emission
    5330                 :     709061 : static void allocate_gc_frame(jl_codectx_t &ctx, BasicBlock *b0)
    5331                 :            : {
    5332                 :            :     // allocate a placeholder gc instruction
    5333                 :            :     // this will require the runtime, but it gets deleted later if unused
    5334                 :     709061 :     ctx.topalloca = ctx.builder.CreateCall(prepare_call(jlpgcstack_func));
    5335                 :     709061 :     ctx.pgcstack = ctx.topalloca;
    5336                 :     709061 : }
    5337                 :            : 
    5338                 :     863385 : static Value *get_current_task(jl_codectx_t &ctx)
    5339                 :            : {
    5340                 :     863385 :     const int ptls_offset = offsetof(jl_task_t, gcstack);
    5341                 :    3453540 :     return ctx.builder.CreateInBoundsGEP(
    5342                 :    1726770 :         ctx.types().T_pjlvalue, emit_bitcast(ctx, ctx.pgcstack, ctx.types().T_ppjlvalue),
    5343                 :     863385 :         ConstantInt::get(getSizeTy(ctx.builder.getContext()), -(ptls_offset / sizeof(void *))),
    5344                 :     863385 :         "current_task");
    5345                 :            : }
    5346                 :            : 
    5347                 :            : // Get PTLS through current task.
    5348                 :      10371 : static Value *get_current_ptls(jl_codectx_t &ctx)
    5349                 :            : {
    5350                 :      10371 :     return get_current_ptls_from_task(ctx.builder, get_current_task(ctx), ctx.tbaa().tbaa_gcframe);
    5351                 :            : }
    5352                 :            : 
    5353                 :            : // Get the address of the world age of the current task
    5354                 :     365553 : static Value *get_last_age_field(jl_codectx_t &ctx)
    5355                 :            : {
    5356                 :     365553 :     Value *ct = get_current_task(ctx);
    5357                 :    1827760 :     return ctx.builder.CreateInBoundsGEP(
    5358                 :     365553 :             getSizeTy(ctx.builder.getContext()),
    5359                 :     365553 :             ctx.builder.CreateBitCast(ct, getSizePtrTy(ctx.builder.getContext())),
    5360                 :     365553 :             ConstantInt::get(getSizeTy(ctx.builder.getContext()), offsetof(jl_task_t, world_age) / sizeof(size_t)),
    5361                 :     365553 :             "world_age");
    5362                 :            : }
    5363                 :            : 
    5364                 :            : // Get signal page through current task.
    5365                 :       2287 : static Value *get_current_signal_page(jl_codectx_t &ctx)
    5366                 :            : {
    5367                 :            :     // return ctx.builder.CreateCall(prepare_call(reuse_signal_page_func));
    5368                 :       2287 :     Value *ptls = get_current_ptls(ctx);
    5369                 :       2287 :     int nthfield = offsetof(jl_tls_states_t, safepoint) / sizeof(void *);
    5370                 :       2287 :     return emit_nthptr_recast(ctx, ptls, nthfield, ctx.tbaa().tbaa_const, getSizePtrTy(ctx.builder.getContext()));
    5371                 :            : }
    5372                 :            : 
    5373                 :        191 : static Function *emit_tojlinvoke(jl_code_instance_t *codeinst, Module *M, jl_codegen_params_t &params)
    5374                 :            : {
    5375                 :        191 :     ++EmittedToJLInvokes;
    5376                 :        382 :     jl_codectx_t ctx(M->getContext(), params);
    5377                 :        191 :     std::string name;
    5378                 :        191 :     raw_string_ostream(name) << "tojlinvoke" << globalUniqueGeneratedNames++;
    5379                 :        191 :     Function *f = Function::Create(ctx.types().T_jlfunc,
    5380                 :            :             GlobalVariable::InternalLinkage,
    5381                 :            :             name, M);
    5382                 :        191 :     jl_init_function(f);
    5383                 :            :     //f->setAlwaysInline();
    5384                 :        191 :     ctx.f = f; // for jl_Module
    5385                 :        191 :     BasicBlock *b0 = BasicBlock::Create(ctx.builder.getContext(), "top", f);
    5386                 :        191 :     ctx.builder.SetInsertPoint(b0);
    5387                 :            :     Function *theFunc;
    5388                 :            :     Value *theFarg;
    5389                 :        191 :     auto invoke = jl_atomic_load_relaxed(&codeinst->invoke);
    5390   [ +  +  -  + ]:        191 :     if (params.cache && invoke != NULL) {
    5391                 :          0 :         StringRef theFptrName = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)invoke, codeinst);
    5392                 :          0 :         theFunc = cast<Function>(
    5393                 :          0 :             M->getOrInsertFunction(theFptrName, jlinvoke_func->_type(ctx.builder.getContext())).getCallee());
    5394                 :          0 :         theFarg = literal_pointer_val(ctx, (jl_value_t*)codeinst);
    5395                 :            :     }
    5396                 :            :     else {
    5397                 :        191 :         theFunc = prepare_call(jlinvoke_func);
    5398                 :        191 :         theFarg = literal_pointer_val(ctx, (jl_value_t*)codeinst->def);
    5399                 :            :     }
    5400                 :        191 :     theFarg = track_pjlvalue(ctx, theFarg);
    5401                 :        191 :     auto args = f->arg_begin();
    5402                 :        191 :     CallInst *r = ctx.builder.CreateCall(theFunc, { &*args, &*++args, &*++args, theFarg });
    5403                 :        191 :     r->setAttributes(theFunc->getAttributes());
    5404                 :        191 :     ctx.builder.CreateRet(r);
    5405                 :        191 :     return f;
    5406                 :            : }
    5407                 :            : 
    5408                 :     116800 : static Type *get_returnroots_type(jl_codectx_t &ctx, unsigned rootcount) {
    5409                 :     116800 :     return ArrayType::get(ctx.types().T_prjlvalue, rootcount);
    5410                 :            : }
    5411                 :            : 
    5412                 :          1 : static Type *get_unionbytes_type(LLVMContext &C, unsigned unionbytes) {
    5413                 :          1 :     return ArrayType::get(getInt8Ty(C), unionbytes);
    5414                 :            : }
    5415                 :            : 
    5416                 :        882 : static void emit_cfunc_invalidate(
    5417                 :            :         Function *gf_thunk, jl_returninfo_t::CallingConv cc, unsigned return_roots,
    5418                 :            :         jl_value_t *calltype, jl_value_t *rettype,
    5419                 :            :         size_t nargs,
    5420                 :            :         jl_codegen_params_t &params,
    5421                 :            :         Function *target)
    5422                 :            : {
    5423                 :        882 :     ++EmittedCFuncInvalidates;
    5424                 :       1764 :     jl_codectx_t ctx(gf_thunk->getParent()->getContext(), params);
    5425                 :        882 :     ctx.f = gf_thunk;
    5426                 :            : 
    5427                 :        882 :     BasicBlock *b0 = BasicBlock::Create(ctx.builder.getContext(), "top", gf_thunk);
    5428                 :        882 :     ctx.builder.SetInsertPoint(b0);
    5429                 :        882 :     DebugLoc noDbg;
    5430                 :        882 :     ctx.builder.SetCurrentDebugLocation(noDbg);
    5431                 :        882 :     allocate_gc_frame(ctx, b0);
    5432                 :            : 
    5433                 :        882 :     Function::arg_iterator AI = gf_thunk->arg_begin();
    5434                 :        882 :     jl_cgval_t *myargs = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * nargs);
    5435   [ +  +  +  + ]:        882 :     if (cc == jl_returninfo_t::SRet || cc == jl_returninfo_t::Union)
    5436                 :         59 :         ++AI;
    5437         [ +  + ]:        882 :     if (return_roots)
    5438                 :         31 :         ++AI;
    5439         [ +  + ]:       4198 :     for (size_t i = 0; i < nargs; i++) {
    5440                 :       3316 :         jl_value_t *jt = jl_nth_slot_type(calltype, i);
    5441                 :       3316 :         bool isboxed = deserves_argbox(jt);
    5442         [ +  + ]:       3316 :         Type *et = isboxed ?  ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, jt);
    5443         [ -  + ]:       3316 :         if (is_uniquerep_Type(jt)) {
    5444                 :          0 :             myargs[i] = mark_julia_const(ctx, jl_tparam0(jt));
    5445                 :            :         }
    5446         [ +  + ]:       3316 :         else if (type_is_ghost(et)) {
    5447   [ +  -  +  - ]:        904 :             assert(jl_is_datatype(jt) && ((jl_datatype_t*)jt)->instance);
    5448                 :        904 :             myargs[i] = mark_julia_const(ctx, ((jl_datatype_t*)jt)->instance);
    5449                 :            :         }
    5450                 :            :         else {
    5451                 :       2412 :             Value *arg_v = &*AI;
    5452                 :       2412 :             ++AI;
    5453                 :       2412 :             Type *at = arg_v->getType();
    5454   [ +  +  +  +  :       2412 :             if (!isboxed && et->isAggregateType()) {
                   +  + ]
    5455                 :        190 :                 myargs[i] = mark_julia_slot(arg_v, jt, NULL, ctx.tbaa().tbaa_const);
    5456                 :            :             }
    5457                 :            :             else {
    5458         [ -  + ]:       2222 :                 assert(at == et);
    5459                 :       2222 :                 myargs[i] = mark_julia_type(ctx, arg_v, isboxed, jt);
    5460                 :            :             }
    5461                 :            :             (void)at;
    5462                 :            :         }
    5463                 :            :     }
    5464         [ -  + ]:        882 :     assert(AI == gf_thunk->arg_end());
    5465                 :        882 :     Value *gf_ret = emit_jlcall(ctx, target, nullptr, myargs, nargs, julia_call);
    5466                 :        882 :     jl_cgval_t gf_retbox = mark_julia_type(ctx, gf_ret, true, jl_any_type);
    5467         [ +  + ]:        882 :     if (cc != jl_returninfo_t::Boxed) {
    5468                 :        798 :         emit_typecheck(ctx, gf_retbox, rettype, "cfunction");
    5469                 :            :     }
    5470                 :            : 
    5471   [ +  +  +  +  :        882 :     switch (cc) {
                   -  - ]
    5472                 :         84 :     case jl_returninfo_t::Boxed:
    5473                 :         84 :         ctx.builder.CreateRet(gf_ret);
    5474                 :         84 :         break;
    5475                 :        739 :     case jl_returninfo_t::Register: {
    5476                 :        739 :         Type *gfrt = gf_thunk->getReturnType();
    5477         [ +  + ]:        739 :         if (gfrt->isVoidTy()) {
    5478                 :        619 :             ctx.builder.CreateRetVoid();
    5479                 :            :         }
    5480                 :            :         else {
    5481                 :        120 :             gf_ret = emit_bitcast(ctx, gf_ret, gfrt->getPointerTo());
    5482                 :        120 :             ctx.builder.CreateRet(ctx.builder.CreateAlignedLoad(gfrt, gf_ret, Align(julia_alignment(rettype))));
    5483                 :            :         }
    5484                 :        739 :         break;
    5485                 :            :     }
    5486                 :         58 :     case jl_returninfo_t::SRet: {
    5487         [ +  + ]:         58 :         if (return_roots) {
    5488                 :         31 :             Value *root1 = gf_thunk->arg_begin() + 1; // root1 has type [n x {}*]*
    5489         [ -  + ]:         31 :             assert(cast<PointerType>(root1->getType())->isOpaqueOrPointeeTypeMatches(get_returnroots_type(ctx, return_roots)));
    5490                 :         31 :             root1 = ctx.builder.CreateConstInBoundsGEP2_32(get_returnroots_type(ctx, return_roots), root1, 0, 0);
    5491                 :         31 :             ctx.builder.CreateStore(gf_ret, root1);
    5492                 :            :         }
    5493                 :         58 :         emit_memcpy(ctx, &*gf_thunk->arg_begin(), nullptr, gf_ret, nullptr, jl_datatype_size(rettype), julia_alignment(rettype));
    5494                 :         58 :         ctx.builder.CreateRetVoid();
    5495                 :         58 :         break;
    5496                 :            :     }
    5497                 :          1 :     case jl_returninfo_t::Union: {
    5498                 :          1 :         Type *retty = gf_thunk->getReturnType();
    5499                 :          1 :         Value *gf_retval = UndefValue::get(retty);
    5500                 :          1 :         Value *tindex = compute_box_tindex(ctx, emit_typeof_boxed(ctx, gf_retbox), (jl_value_t*)jl_any_type, rettype);
    5501                 :          1 :         tindex = ctx.builder.CreateOr(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80));
    5502                 :          1 :         gf_retval = ctx.builder.CreateInsertValue(gf_retval, gf_ret, 0);
    5503                 :          1 :         gf_retval = ctx.builder.CreateInsertValue(gf_retval, tindex, 1);
    5504                 :          1 :         ctx.builder.CreateRet(gf_retval);
    5505                 :          1 :         break;
    5506                 :            :     }
    5507                 :          0 :     case jl_returninfo_t::Ghosts: {
    5508                 :          0 :         Value *gf_retval = compute_tindex_unboxed(ctx, gf_retbox, rettype);
    5509                 :          0 :         ctx.builder.CreateRet(gf_retval);
    5510                 :          0 :         break;
    5511                 :            :     }
    5512                 :            :     }
    5513                 :        882 : }
    5514                 :            : 
    5515                 :        701 : static void emit_cfunc_invalidate(
    5516                 :            :         Function *gf_thunk, jl_returninfo_t::CallingConv cc, unsigned return_roots,
    5517                 :            :         jl_value_t *calltype, jl_value_t *rettype,
    5518                 :            :         size_t nargs,
    5519                 :            :         jl_codegen_params_t &params)
    5520                 :            : {
    5521                 :        701 :     emit_cfunc_invalidate(gf_thunk, cc, return_roots, calltype, rettype, nargs, params,
    5522                 :            :         prepare_call_in(gf_thunk->getParent(), jlapplygeneric_func));
    5523                 :        701 : }
    5524                 :            : 
    5525                 :        870 : static Function* gen_cfun_wrapper(
    5526                 :            :     Module *into, jl_codegen_params_t &params,
    5527                 :            :     const function_sig_t &sig, jl_value_t *ff, const char *aliasname,
    5528                 :            :     jl_value_t *declrt, jl_method_instance_t *lam,
    5529                 :            :     jl_unionall_t *unionall_env, jl_svec_t *sparam_vals, jl_array_t **closure_types)
    5530                 :            : {
    5531                 :        870 :     ++GeneratedCFuncWrappers;
    5532                 :            :     // Generate a c-callable wrapper
    5533         [ -  + ]:        870 :     assert(into);
    5534                 :        870 :     size_t nargs = sig.nccallargs;
    5535                 :        870 :     const char *name = "cfunction";
    5536                 :        870 :     size_t world = jl_atomic_load_acquire(&jl_world_counter);
    5537                 :        870 :     jl_code_instance_t *codeinst = NULL;
    5538   [ +  +  +  + ]:        870 :     bool nest = (!ff || unionall_env);
    5539                 :        870 :     jl_value_t *astrt = (jl_value_t*)jl_any_type;
    5540                 :        870 :     void *callptr = NULL;
    5541                 :        870 :     int calltype = 0;
    5542         [ +  + ]:        870 :     if (aliasname)
    5543                 :          6 :         name = aliasname;
    5544         [ +  + ]:        864 :     else if (lam)
    5545                 :        741 :         name = jl_symbol_name(lam->def.method->name);
    5546   [ +  +  +  + ]:        870 :     if (lam && params.cache) {
    5547                 :            :         // TODO: this isn't ideal to be unconditionally calling type inference (and compile) from here
    5548                 :        703 :         codeinst = jl_compile_method_internal(lam, world);
    5549         [ -  + ]:        703 :         assert(codeinst->invoke);
    5550         [ -  + ]:        703 :         if (codeinst->invoke == jl_fptr_args_addr) {
    5551                 :          0 :             callptr = codeinst->specptr.fptr;
    5552                 :          0 :             calltype = 1;
    5553                 :            :         }
    5554         [ +  + ]:        703 :         else if (codeinst->invoke == jl_fptr_const_return_addr) {
    5555                 :            :             // don't need the fptr
    5556                 :          2 :             callptr = (void*)codeinst->rettype_const;
    5557                 :          2 :             calltype = 2;
    5558                 :            :         }
    5559         [ +  - ]:        701 :         else if (codeinst->isspecsig) {
    5560                 :        701 :             callptr = codeinst->specptr.fptr;
    5561                 :        701 :             calltype = 3;
    5562                 :            :         }
    5563                 :        703 :         astrt = codeinst->rettype;
    5564   [ +  +  -  + ]:       1405 :         if (astrt != (jl_value_t*)jl_bottom_type &&
    5565         [ -  + ]:        702 :             jl_type_intersection(astrt, declrt) == jl_bottom_type) {
    5566                 :            :             // Do not warn if the function never returns since it is
    5567                 :            :             // occasionally required by the C API (typically error callbacks)
    5568                 :            :             // even though we're likely to encounter memory errors in that case
    5569                 :          0 :             jl_printf(JL_STDERR, "WARNING: cfunction: return type of %s does not match\n", name);
    5570                 :            :         }
    5571                 :            :     }
    5572                 :            : 
    5573                 :       1740 :     std::string funcName;
    5574                 :        870 :     raw_string_ostream(funcName) << "jlcapi_" << name << "_" << globalUniqueGeneratedNames++;
    5575                 :            : 
    5576                 :        870 :     Module *M = into; // Safe because ctx lock is held by params
    5577                 :        870 :     AttributeList attributes = sig.attributes;
    5578                 :            :     FunctionType *functype;
    5579         [ +  + ]:        870 :     if (nest) {
    5580                 :            :         // add nest parameter (pointer to jl_value_t* data array) after sret arg
    5581         [ -  + ]:         27 :         assert(closure_types);
    5582                 :         54 :         std::vector<Type*> fargt_sig(sig.fargt_sig);
    5583                 :            : 
    5584                 :         27 :         fargt_sig.insert(fargt_sig.begin() + sig.sret, JuliaType::get_pprjlvalue_ty(M->getContext()));
    5585                 :            : 
    5586                 :            :         // Shift LLVM attributes for parameters one to the right, as
    5587                 :            :         // we are adding the extra nest parameter after sret arg.
    5588                 :         54 :         std::vector<std::pair<unsigned, AttributeSet>> newAttributes;
    5589                 :         27 :         newAttributes.reserve(attributes.getNumAttrSets() + 1);
    5590                 :            : #if JL_LLVM_VERSION >= 140000
    5591                 :         27 :         auto it = *attributes.indexes().begin();
    5592                 :         27 :         const auto it_end = *attributes.indexes().end();
    5593                 :            : #else
    5594                 :            :         auto it = attributes.index_begin();
    5595                 :            :         const auto it_end = attributes.index_end();
    5596                 :            : #endif
    5597                 :            : 
    5598                 :            :         // Skip past FunctionIndex
    5599         [ +  - ]:         27 :         if (it == AttributeList::AttrIndex::FunctionIndex) {
    5600                 :         27 :             ++it;
    5601                 :            :         }
    5602                 :            : 
    5603                 :            :         // Move past ReturnValue and parameter return value
    5604         [ +  + ]:         54 :         for (;it < AttributeList::AttrIndex::FirstArgIndex + sig.sret; ++it) {
    5605         [ +  + ]:         27 :             if (hasAttributesAtIndex(attributes, it)) {
    5606                 :         24 :                 newAttributes.emplace_back(it, attributes.getAttributes(it));
    5607                 :            :             }
    5608                 :            :         }
    5609                 :            : 
    5610                 :            :         // Add the new nest attribute
    5611                 :            : #if JL_LLVM_VERSION >= 140000
    5612                 :         27 :         AttrBuilder attrBuilder(M->getContext());
    5613                 :            : #else
    5614                 :            :         AttrBuilder attrBuilder;
    5615                 :            : #endif
    5616                 :         27 :         attrBuilder.addAttribute(Attribute::Nest);
    5617                 :         27 :         newAttributes.emplace_back(it, AttributeSet::get(M->getContext(), attrBuilder));
    5618                 :            : 
    5619                 :            :         // Shift forward the rest of the attributes
    5620         [ +  + ]:         27 :         if (attributes.getNumAttrSets() > 0) { // without this check the loop range below is invalid
    5621         [ +  + ]:         26 :             for(; it != it_end; ++it) {
    5622         [ +  - ]:          1 :                 if (hasAttributesAtIndex(attributes, it)) {
    5623                 :          1 :                     newAttributes.emplace_back(it + 1, attributes.getAttributes(it));
    5624                 :            :                 }
    5625                 :            :             }
    5626                 :            :         }
    5627                 :            : 
    5628                 :            :         // Remember to add back FunctionIndex
    5629         [ -  + ]:         27 :         if (hasAttributesAtIndex(attributes, AttributeList::AttrIndex::FunctionIndex)) {
    5630                 :          0 :             newAttributes.emplace_back(AttributeList::AttrIndex::FunctionIndex,
    5631                 :          0 :                                        getFnAttrs(attributes));
    5632                 :            :         }
    5633                 :            : 
    5634                 :            :         // Create the new AttributeList
    5635                 :         27 :         attributes = AttributeList::get(M->getContext(), newAttributes);
    5636         [ -  + ]:         27 :         functype = FunctionType::get(sig.sret ? getVoidTy(M->getContext()) : sig.prt, fargt_sig, /*isVa*/false);
    5637                 :            :     }
    5638                 :            :     else {
    5639                 :        843 :         functype = sig.functype(M->getContext());
    5640                 :            :     }
    5641                 :        870 :     Function *cw = Function::Create(functype,
    5642                 :            :             GlobalVariable::ExternalLinkage,
    5643                 :            :             funcName, M);
    5644                 :        870 :     jl_init_function(cw);
    5645                 :        870 :     cw->setAttributes(AttributeList::get(M->getContext(), {attributes, cw->getAttributes()}));
    5646                 :            : 
    5647                 :       1740 :     jl_codectx_t ctx(M->getContext(), params);
    5648                 :        870 :     ctx.f = cw;
    5649                 :        870 :     ctx.world = world;
    5650                 :        870 :     ctx.name = name;
    5651                 :        870 :     ctx.funcName = name;
    5652                 :            : 
    5653                 :        870 :     BasicBlock *b0 = BasicBlock::Create(ctx.builder.getContext(), "top", cw);
    5654                 :        870 :     ctx.builder.SetInsertPoint(b0);
    5655                 :       1740 :     DebugLoc noDbg;
    5656                 :        870 :     ctx.builder.SetCurrentDebugLocation(noDbg);
    5657                 :        870 :     allocate_gc_frame(ctx, b0);
    5658                 :            : 
    5659                 :        870 :     Value *dummy_world = ctx.builder.CreateAlloca(getSizeTy(ctx.builder.getContext()));
    5660                 :        870 :     Value *have_tls = ctx.builder.CreateIsNotNull(ctx.pgcstack);
    5661                 :            :     // TODO: in the future, initialize a full TLS context here
    5662                 :        870 :     Value *world_age_field = get_last_age_field(ctx);
    5663                 :        870 :     world_age_field = ctx.builder.CreateSelect(have_tls, world_age_field, dummy_world);
    5664                 :        870 :     Value *last_age = tbaa_decorate(ctx.tbaa().tbaa_gcframe,
    5665                 :        870 :             ctx.builder.CreateAlignedLoad(getSizeTy(ctx.builder.getContext()), world_age_field, Align(sizeof(size_t))));
    5666                 :        870 :     Value *last_gc_state = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), JL_GC_STATE_SAFE);
    5667                 :        870 :     last_gc_state = emit_guarded_test(ctx, have_tls, last_gc_state, [&] {
    5668                 :        870 :         return emit_gc_unsafe_enter(ctx);
    5669                 :            :     });
    5670                 :            : 
    5671                 :       2610 :     Value *world_v = ctx.builder.CreateAlignedLoad(getSizeTy(ctx.builder.getContext()),
    5672                 :       1740 :         prepare_global_in(jl_Module, jlgetworld_global), Align(sizeof(size_t)));
    5673                 :        870 :     cast<LoadInst>(world_v)->setOrdering(AtomicOrdering::Acquire);
    5674                 :            : 
    5675                 :        870 :     Value *age_ok = NULL;
    5676         [ +  + ]:        870 :     if (calltype) {
    5677                 :       3515 :         LoadInst *lam_max = ctx.builder.CreateAlignedLoad(
    5678                 :        703 :                 getSizeTy(ctx.builder.getContext()),
    5679                 :            :                 ctx.builder.CreateConstInBoundsGEP1_32(
    5680                 :        703 :                     getSizeTy(ctx.builder.getContext()),
    5681                 :        703 :                     emit_bitcast(ctx, literal_pointer_val(ctx, (jl_value_t*)codeinst), getSizePtrTy(ctx.builder.getContext())),
    5682                 :            :                     offsetof(jl_code_instance_t, max_world) / sizeof(size_t)),
    5683                 :        703 :                 Align(sizeof(size_t)));
    5684                 :            :         // XXX: age is always OK if we don't have a TLS. This is a hack required due to `@threadcall` abuse.
    5685                 :            :         // and adds quite a bit of complexity here, even though it's still wrong
    5686                 :            :         // (anything that tries to interact with the runtime will fault)
    5687                 :        703 :         age_ok = ctx.builder.CreateICmpUGE(lam_max, world_v);
    5688                 :        703 :         world_v = ctx.builder.CreateSelect(ctx.builder.CreateOr(have_tls, age_ok), world_v, lam_max);
    5689                 :        703 :         age_ok = ctx.builder.CreateOr(ctx.builder.CreateNot(have_tls), age_ok);
    5690                 :            :     }
    5691                 :        870 :     ctx.builder.CreateStore(world_v, world_age_field);
    5692                 :            : 
    5693                 :            :     // first emit code to record the arguments
    5694                 :        870 :     Function::arg_iterator AI = cw->arg_begin();
    5695         [ -  + ]:        870 :     Value *sretPtr = sig.sret ? &*AI++ : NULL;
    5696         [ +  + ]:        870 :     Value *nestPtr = nest ? &*AI++ : NULL;
    5697                 :        870 :     jl_cgval_t *inputargs = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * (nargs + 1));
    5698         [ +  + ]:        870 :     if (ff) {
    5699                 :            :         // we need to pass the function object even if (even though) it is a singleton
    5700                 :        845 :         inputargs[0] = mark_julia_const(ctx, ff);
    5701                 :            :     }
    5702                 :            :     else {
    5703   [ +  -  +  - ]:         25 :         assert(nest && nestPtr);
    5704                 :         25 :         Value *ff = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, nestPtr, Align(sizeof(void*)));
    5705                 :         25 :         inputargs[0] = mark_julia_type(ctx, ff, true, jl_any_type);
    5706                 :            :     }
    5707                 :            :     // XXX: these values may need to be rooted until the end of the function
    5708                 :        870 :     jl_value_t *rt1 = NULL;
    5709                 :        870 :     jl_value_t *rt2 = NULL;
    5710                 :        870 :     JL_GC_PUSH2(&rt1, &rt2);
    5711         [ +  + ]:       3173 :     for (size_t i = 0; i < nargs; ++i, ++AI) {
    5712                 :            :         // figure out how to unpack this argument type
    5713                 :       2303 :         Value *val = &*AI;
    5714         [ -  + ]:       2303 :         assert(sig.fargt_sig.at(i + sig.sret) == val->getType());
    5715                 :       2303 :         jl_cgval_t &inputarg = inputargs[i + 1];
    5716                 :       2303 :         jl_value_t *jargty = jl_svecref(sig.at, i);
    5717                 :       2303 :         bool aref = jl_is_abstract_ref_type(jargty);
    5718         [ +  + ]:       2303 :         if (aref) // a pointer to a value
    5719                 :         87 :             jargty = jl_tparam0(jargty);
    5720                 :            : 
    5721                 :            :         // if we know the outer function sparams, try to fill those in now
    5722                 :            :         // so that the julia_to_native type checks are more likely to be doable (e.g. concrete types) at compile-time
    5723                 :       2303 :         jl_value_t *jargty_proper = jargty;
    5724   [ +  +  -  + ]:       2303 :         bool static_at = !(unionall_env && jl_has_typevar_from_unionall(jargty, unionall_env));
    5725         [ +  + ]:       2303 :         if (!static_at) {
    5726         [ +  + ]:         24 :             if (sparam_vals) {
    5727                 :         20 :                 jargty_proper = rt1 = jl_instantiate_type_in_env(jargty, unionall_env, jl_svec_data(sparam_vals));
    5728         [ -  + ]:         20 :                 assert(jargty_proper != jargty);
    5729                 :         20 :                 jargty = jargty_proper;
    5730                 :         20 :                 static_at = true;
    5731                 :            :             }
    5732                 :            :             else {
    5733                 :          4 :                 jargty_proper = rt1 = jl_rewrap_unionall(jargty, (jl_value_t*)unionall_env);
    5734                 :            :             }
    5735                 :            :         }
    5736                 :            : 
    5737         [ +  + ]:       2303 :         if (aref) {
    5738         [ +  + ]:         87 :             if (jargty == (jl_value_t*)jl_any_type) {
    5739                 :            :                 inputarg = mark_julia_type(ctx,
    5740                 :         74 :                         ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, emit_bitcast(ctx, val, ctx.types().T_pprjlvalue), Align(sizeof(void*))),
    5741                 :         74 :                         true, jl_any_type);
    5742                 :            :             }
    5743   [ +  +  +  +  :         50 :             else if (static_at && jl_is_concrete_immutable(jargty)) { // anything that could be stored unboxed
                   +  + ]
    5744                 :            :                 bool isboxed;
    5745                 :         28 :                 Type *T = julia_type_to_llvm(ctx, jargty, &isboxed);
    5746         [ -  + ]:         28 :                 assert(!isboxed);
    5747                 :            :                 // a T* (of unknown origin)
    5748         [ +  + ]:         28 :                 if (type_is_ghost(T)) {
    5749                 :          3 :                     inputarg = ghostValue(ctx, jargty);
    5750                 :            :                 }
    5751                 :            :                 else {
    5752                 :         25 :                     val = emit_bitcast(ctx, val, T->getPointerTo());
    5753                 :         25 :                     val = ctx.builder.CreateAlignedLoad(T, val, Align(1)); // make no alignment assumption about pointer from C
    5754                 :         25 :                     inputarg = mark_julia_type(ctx, val, false, jargty);
    5755                 :            :                 }
    5756                 :            :             }
    5757   [ +  +  -  +  :         22 :             else if (static_at || (!jl_is_typevar(jargty) && !jl_is_immutable_datatype(jargty))) {
             -  -  -  - ]
    5758                 :            :                 // must be a jl_value_t* (because it's mutable or contains gc roots)
    5759                 :         18 :                 inputarg = mark_julia_type(ctx, maybe_decay_untracked(ctx, emit_bitcast(ctx, val, ctx.types().T_prjlvalue)), true, jargty_proper);
    5760                 :            :             }
    5761                 :            :             else {
    5762                 :            :                 // allocate val into a new box, if it might not be boxed
    5763                 :            :                 // otherwise preserve / reuse the existing box identity
    5764                 :            :                 // TODO: could inspect `jargty` and eliminate some of these cases
    5765         [ +  - ]:          4 :                 if (!*closure_types)
    5766                 :          4 :                     *closure_types = jl_alloc_vec_any(0);
    5767                 :          4 :                 jl_array_ptr_1d_push(*closure_types, jargty);
    5768                 :         12 :                 Value *runtime_dt = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue,
    5769                 :          4 :                         ctx.builder.CreateConstInBoundsGEP1_32(ctx.types().T_prjlvalue, nestPtr, jl_array_len(*closure_types)),
    5770                 :          4 :                         Align(sizeof(void*)));
    5771                 :          4 :                 BasicBlock *boxedBB = BasicBlock::Create(ctx.builder.getContext(), "isboxed", cw);
    5772                 :          4 :                 BasicBlock *loadBB = BasicBlock::Create(ctx.builder.getContext(), "need-load", cw);
    5773                 :          4 :                 BasicBlock *unboxedBB = BasicBlock::Create(ctx.builder.getContext(), "maybe-unboxed", cw);
    5774                 :          4 :                 BasicBlock *isanyBB = BasicBlock::Create(ctx.builder.getContext(), "any", cw);
    5775                 :          4 :                 BasicBlock *afterBB = BasicBlock::Create(ctx.builder.getContext(), "after", cw);
    5776                 :          4 :                 Value *isrtboxed = ctx.builder.CreateIsNull(val);
    5777                 :          4 :                 ctx.builder.CreateCondBr(isrtboxed, boxedBB, loadBB);
    5778                 :          4 :                 ctx.builder.SetInsertPoint(boxedBB);
    5779                 :          4 :                 Value *p1 = ctx.builder.CreateBitCast(val, ctx.types().T_pjlvalue);
    5780                 :          4 :                 p1 = track_pjlvalue(ctx, p1);
    5781                 :          4 :                 ctx.builder.CreateBr(afterBB);
    5782                 :          4 :                 ctx.builder.SetInsertPoint(loadBB);
    5783                 :          8 :                 Value *isrtany = ctx.builder.CreateICmpEQ(
    5784                 :            :                         literal_pointer_val(ctx, (jl_value_t*)jl_any_type),
    5785                 :          4 :                         ctx.builder.CreateBitCast(val, ctx.types().T_pjlvalue));
    5786                 :          4 :                 ctx.builder.CreateCondBr(isrtany, isanyBB, unboxedBB);
    5787                 :          4 :                 ctx.builder.SetInsertPoint(isanyBB);
    5788                 :          4 :                 Value *p2 = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, ctx.builder.CreateBitCast(val, ctx.types().T_pprjlvalue), Align(sizeof(void*)));
    5789                 :          4 :                 ctx.builder.CreateBr(afterBB);
    5790                 :          4 :                 ctx.builder.SetInsertPoint(unboxedBB);
    5791                 :          4 :                 Value *p3 = emit_new_bits(ctx, runtime_dt, val);
    5792                 :          4 :                 unboxedBB = ctx.builder.GetInsertBlock(); // could have changed
    5793                 :          4 :                 ctx.builder.CreateBr(afterBB);
    5794                 :          4 :                 ctx.builder.SetInsertPoint(afterBB);
    5795                 :          4 :                 PHINode *p = ctx.builder.CreatePHI(ctx.types().T_prjlvalue, 3);
    5796                 :          4 :                 p->addIncoming(p1, boxedBB);
    5797                 :          4 :                 p->addIncoming(p2, isanyBB);
    5798                 :          4 :                 p->addIncoming(p3, unboxedBB);
    5799                 :          4 :                 inputarg = mark_julia_type(ctx, p, true, jargty_proper);
    5800                 :            :             }
    5801                 :            :         }
    5802                 :            :         else {
    5803                 :       2216 :             bool argboxed = sig.fargt_isboxed.at(i);
    5804         [ +  + ]:       2216 :             if (argboxed) {
    5805                 :            :                 // a jl_value_t*, even when represented as a struct
    5806                 :         67 :                 inputarg = mark_julia_type(ctx, val, true, jargty_proper);
    5807                 :            :             }
    5808                 :            :             else {
    5809                 :            :                 // something of type T
    5810                 :            :                 // undo whatever we might have done to this poor argument
    5811         [ -  + ]:       2149 :                 assert(jl_is_datatype(jargty));
    5812         [ +  + ]:       2149 :                 if (sig.byRefList.at(i)) {
    5813                 :          1 :                     val = ctx.builder.CreateAlignedLoad(sig.fargt[i], val, Align(1)); // unknown alignment from C
    5814                 :            :                 }
    5815                 :            :                 else {
    5816   [ +  -  +  + ]:       2148 :                     bool issigned = jl_signed_type && jl_subtype(jargty_proper, (jl_value_t*)jl_signed_type);
    5817                 :       2148 :                     val = llvm_type_rewrite(ctx, val, sig.fargt[i], issigned);
    5818                 :            :                 }
    5819                 :            :                 // passed an unboxed T, but may need something boxed (not valid to be unboxed)
    5820         [ +  - ]:       2149 :                 if (static_at) {
    5821                 :            :                     bool isboxed;
    5822         [ -  + ]:       2149 :                     assert(jargty == jargty_proper);
    5823                 :       2149 :                     (void)julia_type_to_llvm(ctx, jargty, &isboxed);
    5824         [ +  + ]:       2149 :                     if (isboxed)
    5825                 :            :                         inputarg = mark_julia_type(ctx,
    5826                 :            :                                 box_ccall_result(ctx, val, literal_pointer_val(ctx, jargty), jargty),
    5827                 :          2 :                                 true, jargty_proper);
    5828                 :            :                     else
    5829                 :       2147 :                         inputarg = mark_julia_type(ctx, val, false, jargty);
    5830                 :            :                 }
    5831                 :            :                 else {
    5832         [ #  # ]:          0 :                     if (!*closure_types)
    5833                 :          0 :                         *closure_types = jl_alloc_vec_any(0);
    5834                 :          0 :                     jl_array_ptr_1d_push(*closure_types, jargty);
    5835                 :          0 :                     Value *runtime_dt = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue,
    5836                 :          0 :                             ctx.builder.CreateConstInBoundsGEP1_32(ctx.types().T_prjlvalue, nestPtr, jl_array_len(*closure_types)),
    5837                 :          0 :                             Align(sizeof(void*)));
    5838                 :          0 :                     Value *strct = box_ccall_result(ctx, val, runtime_dt, jargty);
    5839                 :          0 :                     inputarg = mark_julia_type(ctx, strct, true, jargty_proper);
    5840                 :            :                 }
    5841                 :            :             }
    5842                 :            :         }
    5843                 :            :     }
    5844                 :        870 :     JL_GC_POP();
    5845         [ -  + ]:        870 :     assert(AI == cw->arg_end());
    5846                 :            : 
    5847                 :            :     // Create the call
    5848                 :            :     bool jlfunc_sret;
    5849                 :        870 :     jl_cgval_t retval;
    5850         [ +  + ]:        870 :     if (calltype == 2) {
    5851                 :          2 :         nargs = 0; // arguments not needed -- TODO: not really true, should emit an age_ok test and jlcall
    5852                 :          2 :         jlfunc_sret = false;
    5853                 :          2 :         retval = mark_julia_const(ctx, (jl_value_t*)callptr);
    5854                 :            :     }
    5855   [ +  +  -  + ]:        868 :     else if (calltype == 0 || calltype == 1) {
    5856                 :            :         // emit a jlcall
    5857                 :        167 :         jlfunc_sret = false;
    5858                 :        167 :         Function *theFptr = NULL;
    5859         [ -  + ]:        167 :         if (calltype == 1) {
    5860                 :          0 :             StringRef fname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)callptr, codeinst);
    5861                 :          0 :             theFptr = cast_or_null<Function>(jl_Module->getNamedValue(fname));
    5862         [ #  # ]:          0 :             if (!theFptr) {
    5863                 :          0 :                 theFptr = Function::Create(ctx.types().T_jlfunc, GlobalVariable::ExternalLinkage,
    5864                 :          0 :                                            fname, jl_Module);
    5865                 :          0 :                 jl_init_function(theFptr);
    5866                 :          0 :                 addRetAttr(theFptr, Attribute::NonNull);
    5867                 :            :             }
    5868                 :            :             else {
    5869         [ #  # ]:          0 :                 assert(theFptr->getFunctionType() == ctx.types().T_jlfunc);
    5870                 :            :             }
    5871                 :            :         }
    5872                 :            :         BasicBlock *b_generic, *b_jlcall, *b_after;
    5873                 :            :         Value *ret_jlcall;
    5874         [ -  + ]:        167 :         if (age_ok) {
    5875         [ #  # ]:          0 :             assert(theFptr);
    5876                 :          0 :             b_generic = BasicBlock::Create(ctx.builder.getContext(), "generic", cw);
    5877                 :          0 :             b_jlcall = BasicBlock::Create(ctx.builder.getContext(), "apply", cw);
    5878                 :          0 :             b_after = BasicBlock::Create(ctx.builder.getContext(), "after", cw);
    5879                 :          0 :             ctx.builder.CreateCondBr(age_ok, b_jlcall, b_generic);
    5880                 :          0 :             ctx.builder.SetInsertPoint(b_jlcall);
    5881                 :            :             // for jlcall, we need to pass the function object even if it is a ghost.
    5882                 :          0 :             Value *theF = boxed(ctx, inputargs[0]);
    5883         [ #  # ]:          0 :             assert(theF);
    5884                 :          0 :             ret_jlcall = emit_jlcall(ctx, theFptr, theF, &inputargs[1], nargs, julia_call);
    5885                 :          0 :             ctx.builder.CreateBr(b_after);
    5886                 :          0 :             ctx.builder.SetInsertPoint(b_generic);
    5887                 :            :         }
    5888                 :        167 :         Value *ret = emit_jlcall(ctx, jlapplygeneric_func, NULL, inputargs, nargs + 1, julia_call);
    5889         [ -  + ]:        167 :         if (age_ok) {
    5890                 :          0 :             ctx.builder.CreateBr(b_after);
    5891                 :          0 :             ctx.builder.SetInsertPoint(b_after);
    5892                 :          0 :             PHINode *retphi = ctx.builder.CreatePHI(ctx.types().T_prjlvalue, 2);
    5893                 :          0 :             retphi->addIncoming(ret_jlcall, b_jlcall);
    5894                 :          0 :             retphi->addIncoming(ret, b_generic);
    5895                 :          0 :             ret = retphi;
    5896                 :            :         }
    5897                 :        167 :         retval = mark_julia_type(ctx, ret, true, astrt);
    5898                 :            :     }
    5899                 :            :     else {
    5900   [ +  -  -  + ]:        701 :         bool is_opaque_closure = jl_is_method(lam->def.value) && lam->def.method->is_for_opaque_closure;
    5901         [ -  + ]:        701 :         assert(calltype == 3);
    5902                 :            :         // emit a specsig call
    5903                 :        701 :         StringRef protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)callptr, codeinst);
    5904                 :        701 :         jl_returninfo_t returninfo = get_specsig_function(ctx, M, protoname, lam->specTypes, astrt, is_opaque_closure);
    5905                 :        701 :         FunctionType *cft = returninfo.decl->getFunctionType();
    5906                 :        701 :         jlfunc_sret = (returninfo.cc == jl_returninfo_t::SRet);
    5907                 :            : 
    5908                 :            :         // TODO: Can use use emit_call_specfun_other here?
    5909                 :       1402 :         std::vector<Value*> args;
    5910                 :            :         Value *result;
    5911   [ +  +  +  + ]:        701 :         if (jlfunc_sret || returninfo.cc == jl_returninfo_t::Union) {
    5912                 :            :             // fuse the two sret together, or emit an alloca to hold it
    5913   [ -  +  -  - ]:         11 :             if (sig.sret && jlfunc_sret) {
    5914                 :          0 :                 result = emit_bitcast(ctx, sretPtr, cft->getParamType(0));
    5915                 :            :             }
    5916                 :            :             else {
    5917         [ +  + ]:         11 :                 if (jlfunc_sret) {
    5918                 :         10 :                     result = emit_static_alloca(ctx, getAttributeAtIndex(returninfo.decl->getAttributes(), 1, Attribute::StructRet).getValueAsType());
    5919         [ -  + ]:         10 :                     assert(cast<PointerType>(result->getType())->hasSameElementTypeAs(cast<PointerType>(cft->getParamType(0))));
    5920                 :            :                 } else {
    5921                 :          1 :                     result = emit_static_alloca(ctx, get_unionbytes_type(ctx.builder.getContext(), returninfo.union_bytes));
    5922         [ -  + ]:          1 :                     assert(cast<PointerType>(result->getType())->hasSameElementTypeAs(cast<PointerType>(cft->getParamType(0))));
    5923                 :            :                 }
    5924                 :            :             }
    5925                 :         11 :             args.push_back(result);
    5926                 :            :         }
    5927         [ -  + ]:        701 :         if (returninfo.return_roots) {
    5928                 :          0 :             AllocaInst *return_roots = emit_static_alloca(ctx, get_returnroots_type(ctx, returninfo.return_roots));
    5929                 :          0 :             args.push_back(return_roots);
    5930                 :            :         }
    5931         [ +  + ]:       3215 :         for (size_t i = 0; i < nargs + 1; i++) {
    5932                 :            :             // figure out how to repack the arguments
    5933                 :       2514 :             jl_cgval_t &inputarg = inputargs[i];
    5934                 :            :             Value *arg;
    5935   [ +  +  +  - ]:       2514 :             jl_value_t *spect = (i == 0 && is_opaque_closure) ? (jl_value_t*)jl_any_type :
    5936                 :       2514 :                 jl_nth_slot_type(lam->specTypes, i);
    5937                 :       2514 :             bool isboxed = deserves_argbox(spect);
    5938         [ +  + ]:       2514 :             Type *T = isboxed ? ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, spect);
    5939         [ -  + ]:       2514 :             if (is_uniquerep_Type(spect)) {
    5940                 :        704 :                 continue;
    5941                 :            :             }
    5942         [ +  + ]:       2514 :             else if (isboxed) {
    5943                 :         10 :                 arg = boxed(ctx, inputarg);
    5944                 :            :             }
    5945         [ +  + ]:       2504 :             else if (type_is_ghost(T)) {
    5946                 :        704 :                 continue; // ghost types are skipped by the specsig method signature
    5947                 :            :             }
    5948         [ +  + ]:       1800 :             else if (T->isAggregateType()) {
    5949                 :            :                 // aggregate types are passed by pointer
    5950                 :         26 :                 inputarg = value_to_pointer(ctx, inputarg);
    5951                 :         26 :                 arg = maybe_bitcast(ctx, decay_derived(ctx, data_pointer(ctx, inputarg)),
    5952                 :         26 :                     T->getPointerTo());
    5953                 :            :             }
    5954                 :            :             else {
    5955                 :       1774 :                 arg = emit_unbox(ctx, T, inputarg, spect);
    5956         [ -  + ]:       1774 :                 assert(!isa<UndefValue>(arg));
    5957                 :            :             }
    5958                 :            : 
    5959                 :            :             // add to argument list
    5960                 :       1810 :             args.push_back(arg);
    5961                 :            :         }
    5962                 :        701 :         Value *theFptr = returninfo.decl;
    5963         [ -  + ]:        701 :         assert(theFptr);
    5964         [ +  - ]:        701 :         if (age_ok) {
    5965                 :        701 :             funcName += "_gfthunk";
    5966                 :        701 :             Function *gf_thunk = Function::Create(returninfo.decl->getFunctionType(),
    5967                 :            :                     GlobalVariable::InternalLinkage, funcName, M);
    5968                 :        701 :             jl_init_function(gf_thunk);
    5969                 :        701 :             gf_thunk->setAttributes(AttributeList::get(M->getContext(), {returninfo.decl->getAttributes(), gf_thunk->getAttributes()}));
    5970                 :            :             // build a  specsig -> jl_apply_generic converter thunk
    5971                 :            :             // this builds a method that calls jl_apply_generic (as a closure over a singleton function pointer),
    5972                 :            :             // but which has the signature of a specsig
    5973                 :        701 :             emit_cfunc_invalidate(gf_thunk, returninfo.cc, returninfo.return_roots, lam->specTypes, codeinst->rettype, nargs + 1, ctx.emission_context);
    5974                 :        701 :             theFptr = ctx.builder.CreateSelect(age_ok, theFptr, gf_thunk);
    5975                 :            :         }
    5976         [ -  + ]:        701 :         assert(cast<PointerType>(theFptr->getType())->isOpaqueOrPointeeTypeMatches(returninfo.decl->getFunctionType()));
    5977                 :       1402 :         CallInst *call = ctx.builder.CreateCall(
    5978                 :        701 :             cast<FunctionType>(returninfo.decl->getFunctionType()),
    5979                 :            :             theFptr, ArrayRef<Value*>(args));
    5980                 :        701 :         call->setAttributes(returninfo.decl->getAttributes());
    5981   [ +  +  +  +  :        701 :         switch (returninfo.cc) {
                   -  - ]
    5982                 :          8 :             case jl_returninfo_t::Boxed:
    5983                 :          8 :                 retval = mark_julia_type(ctx, call, true, astrt);
    5984                 :          8 :                 break;
    5985                 :        682 :             case jl_returninfo_t::Register:
    5986                 :        682 :                 retval = mark_julia_type(ctx, call, false, astrt);
    5987                 :        682 :                 break;
    5988                 :         10 :             case jl_returninfo_t::SRet:
    5989                 :         10 :                 retval = mark_julia_slot(result, astrt, NULL, ctx.tbaa().tbaa_stack);
    5990                 :         10 :                 break;
    5991                 :          1 :             case jl_returninfo_t::Union: {
    5992                 :          1 :                 Value *box = ctx.builder.CreateExtractValue(call, 0);
    5993                 :          1 :                 Value *tindex = ctx.builder.CreateExtractValue(call, 1);
    5994                 :          4 :                 Value *derived = ctx.builder.CreateSelect(
    5995                 :            :                     ctx.builder.CreateICmpEQ(
    5996                 :          1 :                             ctx.builder.CreateAnd(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80)),
    5997                 :          1 :                             ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0)),
    5998                 :          1 :                     decay_derived(ctx, ctx.builder.CreateBitCast(result, ctx.types().T_pjlvalue)),
    5999                 :            :                     decay_derived(ctx, box));
    6000                 :            :                 retval = mark_julia_slot(derived,
    6001                 :            :                                          astrt,
    6002                 :            :                                          tindex,
    6003                 :          1 :                                          ctx.tbaa().tbaa_stack);
    6004         [ -  + ]:          1 :                 assert(box->getType() == ctx.types().T_prjlvalue);
    6005                 :          1 :                 retval.Vboxed = box;
    6006                 :          1 :                 break;
    6007                 :            :             }
    6008                 :          0 :             case jl_returninfo_t::Ghosts:
    6009                 :          0 :                 retval = mark_julia_slot(NULL, astrt, call, ctx.tbaa().tbaa_stack);
    6010                 :          0 :                 break;
    6011                 :            :         }
    6012                 :            :     }
    6013                 :            : 
    6014                 :            :     // inline a call to typeassert here, if required
    6015                 :        870 :     emit_typecheck(ctx, retval, declrt, "cfunction");
    6016                 :        870 :     retval = update_julia_type(ctx, retval, declrt);
    6017                 :            : 
    6018                 :            :     // Prepare the return value
    6019                 :            :     Value *r;
    6020         [ +  + ]:        870 :     if (sig.retboxed) {
    6021         [ -  + ]:         73 :         assert(!sig.sret);
    6022                 :            :         // return a jl_value_t*
    6023                 :         73 :         r = boxed(ctx, retval);
    6024                 :            :     }
    6025   [ -  +  -  - ]:        797 :     else if (sig.sret && jlfunc_sret) {
    6026                 :            :         // nothing to do
    6027                 :          0 :         r = NULL;
    6028                 :            :     }
    6029         [ +  + ]:        797 :     else if (!type_is_ghost(sig.lrt)) {
    6030                 :        192 :         Type *prt = sig.prt;
    6031         [ -  + ]:        192 :         if (sig.sret)
    6032                 :          0 :             prt = sig.fargt_sig[0]->getContainedType(0); // sret is a PointerType
    6033   [ +  -  +  + ]:        192 :         bool issigned = jl_signed_type && jl_subtype(declrt, (jl_value_t*)jl_signed_type);
    6034                 :        192 :         Value *v = emit_unbox(ctx, sig.lrt, retval, retval.typ);
    6035                 :        192 :         r = llvm_type_rewrite(ctx, v, prt, issigned);
    6036         [ -  + ]:        192 :         if (sig.sret) {
    6037                 :          0 :             ctx.builder.CreateStore(r, sretPtr);
    6038                 :          0 :             r = NULL;
    6039                 :            :         }
    6040                 :            :     }
    6041                 :            :     else {
    6042                 :        605 :         r = NULL;
    6043                 :            :     }
    6044                 :            : 
    6045                 :        870 :     ctx.builder.CreateStore(last_age, world_age_field);
    6046         [ +  + ]:        870 :     if (!sig.retboxed) {
    6047                 :        797 :         emit_guarded_test(ctx, have_tls, nullptr, [&] {
    6048                 :        797 :             emit_gc_unsafe_leave(ctx, last_gc_state);
    6049                 :        797 :             return nullptr;
    6050                 :            :         });
    6051                 :            :     }
    6052                 :        870 :     ctx.builder.CreateRet(r);
    6053                 :            : 
    6054                 :        870 :     ctx.builder.SetCurrentDebugLocation(noDbg);
    6055                 :        870 :     ctx.builder.ClearInsertionPoint();
    6056                 :            : 
    6057         [ +  + ]:        870 :     if (aliasname) {
    6058                 :          6 :         GlobalAlias::create(cw->getValueType(), cw->getType()->getAddressSpace(),
    6059                 :            :                             GlobalValue::ExternalLinkage, aliasname, cw, M);
    6060                 :            :     }
    6061                 :            : 
    6062         [ +  + ]:        870 :     if (nest) {
    6063                 :         27 :         funcName += "make";
    6064                 :         54 :         Function *cw_make = Function::Create(
    6065                 :         27 :                 FunctionType::get(getInt8PtrTy(ctx.builder.getContext()), { getInt8PtrTy(ctx.builder.getContext()), ctx.types().T_ppjlvalue }, false),
    6066                 :            :                 GlobalVariable::ExternalLinkage,
    6067                 :            :                 funcName, M);
    6068                 :         27 :         jl_init_function(cw_make);
    6069                 :         27 :         BasicBlock *b0 = BasicBlock::Create(ctx.builder.getContext(), "top", cw_make);
    6070                 :         27 :         IRBuilder<> cwbuilder(b0);
    6071                 :         27 :         Function::arg_iterator AI = cw_make->arg_begin();
    6072                 :         27 :         Argument *Tramp = &*AI; ++AI;
    6073                 :         27 :         Argument *NVal = &*AI; ++AI;
    6074                 :         27 :         Function *init_trampoline = Intrinsic::getDeclaration(cw_make->getParent(), Intrinsic::init_trampoline);
    6075                 :         27 :         Function *adjust_trampoline = Intrinsic::getDeclaration(cw_make->getParent(), Intrinsic::adjust_trampoline);
    6076                 :         54 :         cwbuilder.CreateCall(init_trampoline, {
    6077                 :            :                 Tramp,
    6078                 :         27 :                 cwbuilder.CreateBitCast(cw, getInt8PtrTy(ctx.builder.getContext())),
    6079                 :         27 :                 cwbuilder.CreateBitCast(NVal, getInt8PtrTy(ctx.builder.getContext()))
    6080                 :            :             });
    6081                 :         27 :         cwbuilder.CreateRet(cwbuilder.CreateCall(adjust_trampoline, { Tramp }));
    6082                 :         27 :         cw = cw_make;
    6083                 :            :     }
    6084                 :            : 
    6085                 :        870 :     return cw;
    6086                 :            : }
    6087                 :            : 
    6088                 :            : // Get the LLVM Function* for the C-callable entry point for a certain function
    6089                 :            : // and argument types.
    6090                 :            : // here argt does not include the leading function type argument
    6091                 :        864 : static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, const jl_cgval_t &fexpr_rt, jl_value_t *declrt, jl_svec_t *argt)
    6092                 :            : {
    6093         [ +  + ]:        798 :     jl_unionall_t *unionall_env = (jl_is_method(ctx.linfo->def.method) && jl_is_unionall(ctx.linfo->def.method->sig))
    6094         [ +  + ]:       1662 :         ? (jl_unionall_t*)ctx.linfo->def.method->sig
    6095                 :            :         : NULL;
    6096                 :        864 :     jl_svec_t *sparam_vals = NULL;
    6097   [ +  +  +  + ]:        864 :     if (ctx.spvals_ptr == NULL && jl_svec_len(ctx.linfo->sparam_vals) > 0)
    6098                 :         30 :         sparam_vals = ctx.linfo->sparam_vals;
    6099                 :            : 
    6100                 :        864 :     jl_value_t *rt = declrt;
    6101         [ +  + ]:        864 :     if (jl_is_abstract_ref_type(declrt)) {
    6102                 :         48 :         declrt = jl_tparam0(declrt);
    6103         [ -  + ]:         48 :         if (!verify_ref_type(ctx, declrt, unionall_env, 0, "cfunction")) {
    6104                 :          0 :             return jl_cgval_t();
    6105                 :            :         }
    6106         [ +  + ]:         48 :         if (unionall_env)
    6107                 :         18 :             declrt = jl_rewrap_unionall(declrt, (jl_value_t*)unionall_env);
    6108                 :         48 :         rt = (jl_value_t*)jl_any_type; // convert return type to jl_value_t*
    6109                 :            :     }
    6110                 :            : 
    6111                 :            :     // some sanity checking and check whether there's a vararg
    6112                 :        864 :     size_t nargt = jl_svec_len(argt);
    6113   [ +  +  -  + ]:        864 :     bool isVa = (nargt > 0 && jl_is_vararg(jl_svecref(argt, nargt - 1)));
    6114         [ -  + ]:        864 :     assert(!isVa); (void)isVa;
    6115                 :            : 
    6116                 :        864 :     jl_array_t *closure_types = NULL;
    6117                 :        864 :     jl_value_t *sigt = NULL; // dispatch-sig = type signature with Ref{} annotations removed and applied to the env
    6118                 :        864 :     JL_GC_PUSH4(&declrt, &sigt, &rt, &closure_types);
    6119                 :            :     Type *lrt;
    6120                 :            :     bool retboxed;
    6121                 :            :     bool static_rt;
    6122                 :            :     const std::string err = verify_ccall_sig(
    6123                 :            :             /* inputs:  */
    6124                 :            :             rt, (jl_value_t*)argt, unionall_env,
    6125                 :            :             sparam_vals,
    6126                 :        864 :             &ctx.emission_context,
    6127                 :            :             /* outputs: */
    6128                 :            :             lrt, ctx.builder.getContext(),
    6129                 :       1728 :             retboxed, static_rt);
    6130         [ -  + ]:        864 :     if (!err.empty()) {
    6131                 :          0 :         emit_error(ctx, "cfunction " + err);
    6132                 :          0 :         JL_GC_POP();
    6133                 :          0 :         return jl_cgval_t();
    6134                 :            :     }
    6135   [ +  +  -  + ]:        864 :     if (rt != declrt && rt != (jl_value_t*)jl_any_type)
    6136                 :          0 :         jl_add_method_root(ctx, rt);
    6137                 :            : 
    6138                 :       1728 :     function_sig_t sig("cfunction", lrt, rt, retboxed, argt, unionall_env, false, CallingConv::C, false, &ctx.emission_context);
    6139         [ -  + ]:        864 :     assert(sig.fargt.size() + sig.sret == sig.fargt_sig.size());
    6140         [ -  + ]:        864 :     if (!sig.err_msg.empty()) {
    6141                 :          0 :         emit_error(ctx, sig.err_msg);
    6142                 :          0 :         JL_GC_POP();
    6143                 :          0 :         return jl_cgval_t();
    6144                 :            :     }
    6145                 :            : 
    6146                 :            :     // compute+verify the dispatch signature, and see if it depends on the environment sparams
    6147                 :        864 :     bool approx = false;
    6148                 :        864 :     sigt = (jl_value_t*)jl_alloc_svec(nargt + 1);
    6149                 :        864 :     jl_svecset(sigt, 0, fexpr_rt.typ);
    6150   [ +  +  +  +  :        864 :     if (!fexpr_rt.constant && (!jl_is_concrete_type(fexpr_rt.typ) || jl_is_kind(fexpr_rt.typ)))
             -  +  +  + ]
    6151                 :         22 :         approx = true;
    6152         [ +  + ]:       3163 :     for (size_t i = 0; i < nargt; i++) {
    6153                 :       2299 :         jl_value_t *jargty = jl_svecref(argt, i);
    6154         [ +  + ]:       2299 :         if (jl_is_abstract_ref_type(jargty)) {
    6155                 :         87 :             jargty = jl_tparam0(jargty);
    6156         [ -  + ]:         87 :             if (!verify_ref_type(ctx, jargty, unionall_env, i + 1, "cfunction")) {
    6157                 :          0 :                 JL_GC_POP();
    6158                 :          0 :                 return jl_cgval_t();
    6159                 :            :             }
    6160                 :            :         }
    6161   [ +  +  +  +  :       2299 :         if (unionall_env && jl_has_typevar_from_unionall(jargty, unionall_env)) {
                   +  + ]
    6162         [ +  + ]:         30 :             if (sparam_vals)
    6163                 :         26 :                 jargty = jl_instantiate_type_in_env(jargty, unionall_env, jl_svec_data(sparam_vals));
    6164                 :            :             else
    6165                 :          4 :                 approx = true;
    6166                 :            :         }
    6167                 :       2299 :         jl_svecset(sigt, i + 1, jargty);
    6168                 :            :     }
    6169         [ +  + ]:        864 :     if (approx) {
    6170                 :         24 :         sigt = NULL;
    6171                 :            :     }
    6172                 :            :     else {
    6173                 :        840 :         sigt = (jl_value_t*)jl_apply_tuple_type((jl_svec_t*)sigt);
    6174                 :            :     }
    6175   [ +  +  +  +  :        864 :     if (sigt && !(unionall_env && jl_has_typevar_from_unionall(rt, unionall_env))) {
             +  -  +  + ]
    6176                 :        840 :         unionall_env = NULL;
    6177                 :            :     }
    6178                 :            : 
    6179   [ +  +  +  + ]:        864 :     bool nest = (!fexpr_rt.constant || unionall_env);
    6180                 :            : #if defined(_CPU_AARCH64_) || defined(_CPU_ARM_) || defined(_CPU_PPC64_)
    6181                 :            :     if (nest) {
    6182                 :            :         emit_error(ctx, "cfunction: closures are not supported on this platform");
    6183                 :            :         return jl_cgval_t();
    6184                 :            :     }
    6185                 :            : #endif
    6186                 :        864 :     size_t world = jl_atomic_load_acquire(&jl_world_counter);
    6187                 :        864 :     size_t min_valid = 0;
    6188                 :        864 :     size_t max_valid = ~(size_t)0;
    6189                 :            :     // try to look up this function for direct invoking
    6190         [ +  + ]:        864 :     jl_method_instance_t *lam = sigt ? jl_get_specialization1((jl_tupletype_t*)sigt, world, &min_valid, &max_valid, 0) : NULL;
    6191                 :        864 :     Value *F = gen_cfun_wrapper(
    6192                 :        864 :             jl_Module, ctx.emission_context,
    6193                 :        864 :             sig, fexpr_rt.constant, NULL,
    6194                 :            :             declrt, lam,
    6195                 :            :             unionall_env, sparam_vals, &closure_types);
    6196                 :            :     bool outboxed;
    6197         [ +  + ]:        864 :     if (nest) {
    6198                 :            :         // F is actually an init_trampoline function that returns the real address
    6199                 :            :         // Now fill in the nest parameters
    6200                 :         27 :         Value *fobj = boxed(ctx, fexpr_rt);
    6201                 :         27 :         jl_svec_t *fill = jl_emptysvec;
    6202         [ +  + ]:         27 :         if (closure_types) {
    6203         [ -  + ]:          4 :             assert(ctx.spvals_ptr);
    6204                 :          4 :             size_t n = jl_array_len(closure_types);
    6205                 :          4 :             jl_svec_t *fill = jl_alloc_svec_uninit(n);
    6206         [ +  + ]:          8 :             for (size_t i = 0; i < n; i++) {
    6207                 :          4 :                 jl_svecset(fill, i, jl_array_ptr_ref(closure_types, i));
    6208                 :            :             }
    6209                 :          4 :             jl_add_method_root(ctx, (jl_value_t*)fill);
    6210                 :            :         }
    6211                 :         27 :         Type *T_htable = ArrayType::get(getSizeTy(ctx.builder.getContext()), sizeof(htable_t) / sizeof(void*));
    6212                 :         27 :         Value *cache = new GlobalVariable(*jl_Module, T_htable, false,
    6213                 :            :                                GlobalVariable::PrivateLinkage,
    6214                 :         27 :                                ConstantAggregateZero::get(T_htable));
    6215                 :         54 :         F = ctx.builder.CreateCall(prepare_call(jlgetcfunctiontrampoline_func), {
    6216                 :            :                  fobj,
    6217                 :         27 :                  literal_pointer_val(ctx, output_type),
    6218                 :         27 :                  ctx.builder.CreateBitCast(cache, getInt8PtrTy(ctx.builder.getContext())),
    6219                 :         27 :                  literal_pointer_val(ctx, (jl_value_t*)fill),
    6220                 :            :                  F,
    6221         [ +  + ]:         27 :                  closure_types ? literal_pointer_val(ctx, (jl_value_t*)unionall_env) : Constant::getNullValue(ctx.types().T_pjlvalue),
    6222         [ +  + ]:         27 :                  closure_types ? ctx.spvals_ptr : ConstantPointerNull::get(cast<PointerType>(ctx.types().T_pprjlvalue))
    6223                 :            :              });
    6224                 :         27 :         outboxed = true;
    6225                 :            :     }
    6226                 :            :     else {
    6227                 :        837 :         F = ctx.builder.CreatePtrToInt(F, getSizeTy(ctx.builder.getContext()));
    6228                 :        837 :         outboxed = (output_type != (jl_value_t*)jl_voidpointer_type);
    6229         [ +  + ]:        837 :         if (outboxed) {
    6230         [ -  + ]:          4 :             assert(jl_datatype_size(output_type) == sizeof(void*) * 4);
    6231                 :          4 :             Value *strct = emit_allocobj(ctx, jl_datatype_size(output_type),
    6232                 :            :                                          literal_pointer_val(ctx, (jl_value_t*)output_type));
    6233                 :          4 :             Value *derived_strct = emit_bitcast(ctx, decay_derived(ctx, strct), getSizePtrTy(ctx.builder.getContext()));
    6234                 :          4 :             MDNode *tbaa = best_tbaa(ctx.tbaa(), output_type);
    6235                 :          4 :             tbaa_decorate(tbaa, ctx.builder.CreateStore(F, derived_strct));
    6236                 :         12 :             tbaa_decorate(tbaa, ctx.builder.CreateStore(
    6237                 :          4 :                 ctx.builder.CreatePtrToInt(literal_pointer_val(ctx, fexpr_rt.constant), getSizeTy(ctx.builder.getContext())),
    6238                 :          4 :                 ctx.builder.CreateConstInBoundsGEP1_32(getSizeTy(ctx.builder.getContext()), derived_strct, 1)));
    6239                 :          8 :             tbaa_decorate(tbaa, ctx.builder.CreateStore(Constant::getNullValue(getSizeTy(ctx.builder.getContext())),
    6240                 :          4 :                     ctx.builder.CreateConstInBoundsGEP1_32(getSizeTy(ctx.builder.getContext()), derived_strct, 2)));
    6241                 :          8 :             tbaa_decorate(tbaa, ctx.builder.CreateStore(Constant::getNullValue(getSizeTy(ctx.builder.getContext())),
    6242                 :          4 :                     ctx.builder.CreateConstInBoundsGEP1_32(getSizeTy(ctx.builder.getContext()), derived_strct, 3)));
    6243                 :          4 :             F = strct;
    6244                 :            :         }
    6245                 :            :     }
    6246                 :        864 :     JL_GC_POP();
    6247                 :        864 :     return mark_julia_type(ctx, F, outboxed, output_type);
    6248                 :            : }
    6249                 :            : 
    6250                 :            : // do codegen to create a C-callable alias/wrapper, or if sysimg_handle is set,
    6251                 :            : // restore one from a loaded system image.
    6252                 :          6 : const char *jl_generate_ccallable(LLVMOrcThreadSafeModuleRef llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t &params)
    6253                 :            : {
    6254                 :          6 :     ++GeneratedCCallables;
    6255                 :          6 :     jl_datatype_t *ft = (jl_datatype_t*)jl_tparam0(sigt);
    6256                 :          6 :     jl_value_t *ff = ft->instance;
    6257         [ -  + ]:          6 :     assert(ff);
    6258                 :          6 :     const char *name = jl_symbol_name(ft->name->mt->name);
    6259                 :          6 :     jl_value_t *crt = declrt;
    6260         [ -  + ]:          6 :     if (jl_is_abstract_ref_type(declrt)) {
    6261                 :          0 :         declrt = jl_tparam0(declrt);
    6262                 :          0 :         crt = (jl_value_t*)jl_any_type;
    6263                 :            :     }
    6264                 :            :     bool toboxed;
    6265                 :          6 :     Type *lcrt = _julia_struct_to_llvm(&params, *params.tsctx.getContext(), crt, &toboxed);
    6266         [ -  + ]:          6 :     if (toboxed)
    6267                 :          0 :         lcrt = JuliaType::get_prjlvalue_ty(lcrt->getContext());
    6268                 :          6 :     size_t nargs = jl_nparams(sigt)-1;
    6269                 :          6 :     jl_svec_t *argtypes = NULL;
    6270                 :          6 :     JL_GC_PUSH1(&argtypes);
    6271                 :          6 :     argtypes = jl_alloc_svec(nargs);
    6272         [ +  + ]:         10 :     for (size_t i = 0; i < nargs; i++) {
    6273                 :          4 :         jl_svecset(argtypes, i, jl_tparam(sigt, i+1));
    6274                 :            :     }
    6275                 :            :     jl_value_t *err;
    6276                 :            :     { // scope block for sig
    6277                 :            :         function_sig_t sig("cfunction", lcrt, crt, toboxed,
    6278                 :          6 :                            argtypes, NULL, false, CallingConv::C, false, &params);
    6279         [ +  - ]:          6 :         if (sig.err_msg.empty()) {
    6280                 :          6 :             size_t world = jl_atomic_load_acquire(&jl_world_counter);
    6281                 :          6 :             size_t min_valid = 0;
    6282                 :          6 :             size_t max_valid = ~(size_t)0;
    6283         [ -  + ]:          6 :             if (sysimg_handle) {
    6284                 :            :                 // restore a ccallable from the system image
    6285                 :            :                 void *addr;
    6286                 :          0 :                 int found = jl_dlsym(sysimg_handle, name, &addr, 0);
    6287         [ #  # ]:          0 :                 if (found)
    6288                 :          0 :                     add_named_global(name, addr);
    6289                 :            :             }
    6290                 :            :             else {
    6291                 :          6 :                 jl_method_instance_t *lam = jl_get_specialization1((jl_tupletype_t*)sigt, world, &min_valid, &max_valid, 0);
    6292                 :            :                 //Safe b/c params holds context lock
    6293                 :          6 :                 gen_cfun_wrapper(unwrap(llvmmod)->getModuleUnlocked(), params, sig, ff, name, declrt, lam, NULL, NULL, NULL);
    6294                 :            :             }
    6295                 :          6 :             JL_GC_POP();
    6296                 :          6 :             return name;
    6297                 :            :         }
    6298                 :          0 :         err = jl_get_exceptionf(jl_errorexception_type, "%s", sig.err_msg.c_str());
    6299                 :            :     }
    6300                 :          0 :     jl_throw(err);
    6301                 :            : }
    6302                 :            : 
    6303                 :            : // generate a julia-callable function that calls f (AKA lam)
    6304                 :     342635 : static Function *gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlretty, const jl_returninfo_t &f, int retarg, StringRef funcName,
    6305                 :            :         Module *M, jl_codegen_params_t &params)
    6306                 :            : {
    6307                 :     342635 :     ++GeneratedInvokeWrappers;
    6308                 :     342635 :     Function *w = Function::Create(get_func_sig(M->getContext()), GlobalVariable::ExternalLinkage, funcName, M);
    6309                 :     342635 :     jl_init_function(w);
    6310                 :     342635 :     w->setAttributes(AttributeList::get(M->getContext(), {get_func_attrs(M->getContext()), w->getAttributes()}));
    6311                 :     342635 :     Function::arg_iterator AI = w->arg_begin();
    6312                 :     342635 :     Value *funcArg = &*AI++;
    6313                 :     342635 :     Value *argArray = &*AI++;
    6314                 :     342635 :     Value *argCount = &*AI++; (void)argCount; // unused
    6315                 :            :     //Value *mfunc = &*AI++; (void)mfunc; // unused
    6316         [ -  + ]:     342635 :     assert(AI == w->arg_end());
    6317                 :            : 
    6318                 :     685270 :     jl_codectx_t ctx(M->getContext(), params);
    6319                 :     342635 :     ctx.f = w;
    6320                 :     342635 :     ctx.linfo = lam;
    6321                 :     342635 :     ctx.rettype = jlretty;
    6322                 :     342635 :     ctx.world = 0;
    6323                 :            : 
    6324                 :     342635 :     BasicBlock *b0 = BasicBlock::Create(ctx.builder.getContext(), "top", w);
    6325                 :     342635 :     ctx.builder.SetInsertPoint(b0);
    6326                 :     685270 :     DebugLoc noDbg;
    6327                 :     342635 :     ctx.builder.SetCurrentDebugLocation(noDbg);
    6328                 :     342635 :     allocate_gc_frame(ctx, b0);
    6329                 :            : 
    6330                 :            :     // TODO: replace this with emit_call_specfun_other?
    6331                 :     342635 :     FunctionType *ftype = f.decl->getFunctionType();
    6332                 :     342635 :     size_t nfargs = ftype->getNumParams();
    6333                 :     342635 :     Value **args = (Value**) alloca(nfargs * sizeof(Value*));
    6334                 :     342635 :     unsigned idx = 0;
    6335                 :     342635 :     AllocaInst *result = NULL;
    6336   [ +  +  +  - ]:     342635 :     switch (f.cc) {
    6337                 :     282464 :     case jl_returninfo_t::Boxed:
    6338                 :            :     case jl_returninfo_t::Register:
    6339                 :            :     case jl_returninfo_t::Ghosts:
    6340                 :     282464 :         break;
    6341                 :      54700 :     case jl_returninfo_t::SRet:
    6342         [ -  + ]:      54700 :         assert(cast<PointerType>(ftype->getParamType(0))->isOpaqueOrPointeeTypeMatches(getAttributeAtIndex(f.decl->getAttributes(), 1, Attribute::StructRet).getValueAsType()));
    6343                 :      54700 :         result = ctx.builder.CreateAlloca(getAttributeAtIndex(f.decl->getAttributes(), 1, Attribute::StructRet).getValueAsType());
    6344                 :      54700 :         args[idx] = result;
    6345                 :      54700 :         idx++;
    6346                 :      54700 :         break;
    6347                 :       5471 :     case jl_returninfo_t::Union:
    6348                 :       5471 :         result = ctx.builder.CreateAlloca(ArrayType::get(getInt8Ty(ctx.builder.getContext()), f.union_bytes));
    6349         [ +  + ]:       5471 :         if (f.union_align > 1)
    6350                 :       4068 :             result->setAlignment(Align(f.union_align));
    6351                 :       5471 :         args[idx] = result;
    6352                 :       5471 :         idx++;
    6353                 :       5471 :         break;
    6354                 :            :     }
    6355         [ +  + ]:     342635 :     if (f.return_roots) {
    6356                 :      27542 :         AllocaInst *return_roots = emit_static_alloca(ctx, ArrayType::get(ctx.types().T_prjlvalue, f.return_roots));
    6357                 :      27542 :         args[idx] = return_roots;
    6358                 :      27542 :         idx++;
    6359                 :            :     }
    6360                 :            : 
    6361   [ +  -  +  + ]:     342635 :     bool is_opaque_closure = jl_is_method(lam->def.value) && lam->def.method->is_for_opaque_closure;
    6362   [ +  +  +  + ]:    1466570 :     for (size_t i = 0; i < jl_nparams(lam->specTypes) && idx < nfargs; ++i) {
    6363   [ +  +  +  + ]:    1123940 :         jl_value_t *ty = ((i == 0) && is_opaque_closure) ? (jl_value_t*)jl_any_type :
    6364                 :    1123900 :             jl_nth_slot_type(lam->specTypes, i);
    6365                 :    1123940 :         bool isboxed = deserves_argbox(ty);
    6366         [ +  + ]:    1123940 :         Type *lty = isboxed ?  ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, ty);
    6367   [ +  +  +  +  :    1123940 :         if (type_is_ghost(lty) || is_uniquerep_Type(ty))
                   +  + ]
    6368                 :     377863 :             continue;
    6369                 :            :         Value *theArg;
    6370         [ +  + ]:     746075 :         if (i == 0) {
    6371                 :      20657 :             theArg = funcArg;
    6372                 :            :         }
    6373                 :            :         else {
    6374                 :     725418 :             Value *argPtr = ctx.builder.CreateConstInBoundsGEP1_32(ctx.types().T_prjlvalue, argArray, i - 1);
    6375                 :     725418 :             theArg = tbaa_decorate(ctx.tbaa().tbaa_const, maybe_mark_load_dereferenceable(
    6376                 :    1450840 :                     ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, argPtr, Align(sizeof(void*))),
    6377                 :            :                     false,
    6378                 :            :                     ty));
    6379                 :            :         }
    6380         [ +  + ]:     746075 :         if (!isboxed) {
    6381                 :     488274 :             theArg = decay_derived(ctx, emit_bitcast(ctx, theArg, PointerType::get(lty, 0)));
    6382         [ +  + ]:     488274 :             if (!lty->isAggregateType()) // keep "aggregate" type values in place as pointers
    6383                 :     169536 :                 theArg = ctx.builder.CreateAlignedLoad(lty, theArg, Align(julia_alignment(ty)));
    6384                 :            :         }
    6385         [ -  + ]:     746075 :         assert(dyn_cast<UndefValue>(theArg) == NULL);
    6386                 :     746075 :         args[idx] = theArg;
    6387                 :     746075 :         idx++;
    6388                 :            :     }
    6389                 :     342635 :     CallInst *call = ctx.builder.CreateCall(f.decl, ArrayRef<Value*>(&args[0], nfargs));
    6390                 :     342635 :     call->setAttributes(f.decl->getAttributes());
    6391                 :            : 
    6392                 :     342635 :     jl_cgval_t retval;
    6393         [ +  + ]:     342635 :     if (retarg != -1) {
    6394                 :            :         Value *theArg;
    6395         [ -  + ]:      36470 :         if (retarg == 0)
    6396                 :          0 :             theArg = funcArg;
    6397                 :            :         else
    6398                 :     109410 :             theArg = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue,
    6399                 :      36470 :                     ctx.builder.CreateConstInBoundsGEP1_32(ctx.types().T_prjlvalue, argArray, retarg - 1),
    6400                 :      72940 :                     Align(sizeof(void*)));
    6401                 :      36470 :         retval = mark_julia_type(ctx, theArg, true, jl_any_type);
    6402                 :            :     }
    6403                 :            :     else {
    6404   [ +  +  +  +  :     306165 :         switch (f.cc) {
                   +  - ]
    6405                 :     118408 :         case jl_returninfo_t::Boxed:
    6406                 :     118408 :             retval = mark_julia_type(ctx, call, true, jlretty);
    6407                 :     118408 :             break;
    6408                 :     135067 :         case jl_returninfo_t::Register:
    6409                 :     135067 :             retval = mark_julia_type(ctx, call, false, jlretty);
    6410                 :     135067 :             break;
    6411                 :      46796 :         case jl_returninfo_t::SRet:
    6412                 :      46796 :             retval = mark_julia_slot(result, jlretty, NULL, ctx.tbaa().tbaa_stack);
    6413                 :      46796 :             break;
    6414                 :       5471 :         case jl_returninfo_t::Union:
    6415                 :            :             // result is technically not right here, but `boxed` will only look at it
    6416                 :            :             // for the unboxed values, so it's ok.
    6417                 :            :             retval = mark_julia_slot(result,
    6418                 :            :                                      jlretty,
    6419                 :      10942 :                                      ctx.builder.CreateExtractValue(call, 1),
    6420                 :       5471 :                                      ctx.tbaa().tbaa_stack);
    6421                 :       5471 :             retval.Vboxed = ctx.builder.CreateExtractValue(call, 0);
    6422         [ -  + ]:       5471 :             assert(retval.Vboxed->getType() == ctx.types().T_prjlvalue);
    6423                 :       5471 :             break;
    6424                 :        423 :         case jl_returninfo_t::Ghosts:
    6425                 :        423 :             retval = mark_julia_slot(NULL, jlretty, call, ctx.tbaa().tbaa_stack);
    6426                 :        423 :             break;
    6427                 :            :         }
    6428                 :            :     }
    6429                 :     342635 :     ctx.builder.CreateRet(boxed(ctx, retval));
    6430         [ -  + ]:     342635 :     assert(!ctx.roots);
    6431                 :     342635 :     return w;
    6432                 :            : }
    6433                 :            : 
    6434                 :    1826150 : static jl_returninfo_t get_specsig_function(jl_codectx_t &ctx, Module *M, StringRef name, jl_value_t *sig, jl_value_t *jlrettype, bool is_opaque_closure)
    6435                 :            : {
    6436                 :    1826150 :     jl_returninfo_t props = {};
    6437                 :    3652290 :     SmallVector<Type*, 8> fsig;
    6438                 :    1826150 :     Type *rt = NULL;
    6439                 :    1826150 :     Type *srt = NULL;
    6440         [ +  + ]:    1826150 :     if (jlrettype == (jl_value_t*)jl_bottom_type) {
    6441                 :     577021 :         rt = getVoidTy(ctx.builder.getContext());
    6442                 :     577021 :         props.cc = jl_returninfo_t::Register;
    6443                 :            :     }
    6444   [ +  +  +  +  :    1249120 :     else if (jl_is_structtype(jlrettype) && jl_is_datatype_singleton((jl_datatype_t*)jlrettype)) {
                   +  + ]
    6445                 :      81859 :         rt = getVoidTy(ctx.builder.getContext());
    6446                 :      81859 :         props.cc = jl_returninfo_t::Register;
    6447                 :            :     }
    6448         [ +  + ]:    1167270 :     else if (jl_is_uniontype(jlrettype)) {
    6449                 :            :         bool allunbox;
    6450                 :      67970 :         union_alloca_type((jl_uniontype_t*)jlrettype, allunbox, props.union_bytes, props.union_align, props.union_minalign);
    6451         [ +  + ]:      67970 :         if (props.union_bytes) {
    6452                 :      19510 :             props.cc = jl_returninfo_t::Union;
    6453                 :      19510 :             Type *AT = ArrayType::get(getInt8Ty(ctx.builder.getContext()), props.union_bytes);
    6454                 :      19510 :             fsig.push_back(AT->getPointerTo());
    6455                 :      19510 :             Type *pair[] = { ctx.types().T_prjlvalue, getInt8Ty(ctx.builder.getContext()) };
    6456                 :      19510 :             rt = StructType::get(ctx.builder.getContext(), makeArrayRef(pair));
    6457                 :            :         }
    6458         [ +  + ]:      48460 :         else if (allunbox) {
    6459                 :       1618 :             props.cc = jl_returninfo_t::Ghosts;
    6460                 :       1618 :             rt = getInt8Ty(ctx.builder.getContext());
    6461                 :            :         }
    6462                 :            :         else {
    6463                 :      46842 :             rt = ctx.types().T_prjlvalue;
    6464                 :            :         }
    6465                 :            :     }
    6466         [ +  + ]:    1099300 :     else if (!deserves_retbox(jlrettype)) {
    6467                 :            :         bool retboxed;
    6468                 :     496501 :         rt = julia_type_to_llvm(ctx, jlrettype, &retboxed);
    6469         [ -  + ]:     496501 :         assert(!retboxed);
    6470   [ +  -  +  +  :     496501 :         if (rt != getVoidTy(ctx.builder.getContext()) && deserves_sret(jlrettype, rt)) {
                   +  + ]
    6471                 :     181705 :             auto tracked = CountTrackedPointers(rt);
    6472         [ -  + ]:     181705 :             assert(!tracked.derived);
    6473   [ +  +  +  + ]:     181705 :             if (tracked.count && !tracked.all)
    6474                 :      83355 :                 props.return_roots = tracked.count;
    6475                 :     181705 :             props.cc = jl_returninfo_t::SRet;
    6476                 :     181705 :             fsig.push_back(rt->getPointerTo());
    6477                 :     181705 :             srt = rt;
    6478                 :     181705 :             rt = getVoidTy(ctx.builder.getContext());
    6479                 :            :         }
    6480                 :            :         else {
    6481                 :     314796 :             props.cc = jl_returninfo_t::Register;
    6482                 :            :         }
    6483                 :            :     }
    6484                 :            :     else {
    6485                 :     602795 :         rt = ctx.types().T_prjlvalue;
    6486                 :            :     }
    6487                 :            : 
    6488                 :    3652290 :     SmallVector<AttributeSet, 8> attrs; // function declaration attributes
    6489         [ +  + ]:    1826150 :     if (props.cc == jl_returninfo_t::SRet) {
    6490         [ -  + ]:     181705 :         assert(srt);
    6491                 :            : #if JL_LLVM_VERSION >= 140000
    6492                 :     363410 :         AttrBuilder param(ctx.builder.getContext());
    6493                 :            : #else
    6494                 :            :         AttrBuilder param;
    6495                 :            : #endif
    6496                 :     181705 :         param.addStructRetAttr(srt);
    6497                 :     181705 :         param.addAttribute(Attribute::NoAlias);
    6498                 :     181705 :         param.addAttribute(Attribute::NoCapture);
    6499                 :     181705 :         param.addAttribute(Attribute::NoUndef);
    6500                 :     181705 :         attrs.push_back(AttributeSet::get(ctx.builder.getContext(), param));
    6501         [ -  + ]:     181705 :         assert(fsig.size() == 1);
    6502                 :            :     }
    6503         [ +  + ]:    1826150 :     if (props.cc == jl_returninfo_t::Union) {
    6504                 :            : #if JL_LLVM_VERSION >= 140000
    6505                 :      39020 :         AttrBuilder param(ctx.builder.getContext());
    6506                 :            : #else
    6507                 :            :         AttrBuilder param;
    6508                 :            : #endif
    6509                 :      19510 :         param.addAttribute(Attribute::NoAlias);
    6510                 :      19510 :         param.addAttribute(Attribute::NoCapture);
    6511                 :      19510 :         param.addAttribute(Attribute::NoUndef);
    6512                 :      19510 :         attrs.push_back(AttributeSet::get(ctx.builder.getContext(), param));
    6513         [ -  + ]:      19510 :         assert(fsig.size() == 1);
    6514                 :            :     }
    6515                 :            : 
    6516         [ +  + ]:    1826150 :     if (props.return_roots) {
    6517                 :            : #if JL_LLVM_VERSION >= 140000
    6518                 :     166710 :         AttrBuilder param(ctx.builder.getContext());
    6519                 :            : #else
    6520                 :            :         AttrBuilder param;
    6521                 :            : #endif
    6522                 :      83355 :         param.addAttribute(Attribute::NoAlias);
    6523                 :      83355 :         param.addAttribute(Attribute::NoCapture);
    6524                 :      83355 :         param.addAttribute(Attribute::NoUndef);
    6525                 :      83355 :         attrs.push_back(AttributeSet::get(ctx.builder.getContext(), param));
    6526                 :      83355 :         fsig.push_back(get_returnroots_type(ctx, props.return_roots)->getPointerTo(0));
    6527                 :            :     }
    6528                 :            : 
    6529         [ +  + ]:    7785440 :     for (size_t i = 0; i < jl_nparams(sig); i++) {
    6530                 :    5959290 :         jl_value_t *jt = jl_tparam(sig, i);
    6531   [ +  +  +  + ]:    5959290 :         if (i == 0 && is_opaque_closure) {
    6532                 :         43 :             jt = (jl_value_t*)jl_any_type;
    6533                 :            :         }
    6534         [ +  + ]:    5959290 :         if (is_uniquerep_Type(jt))
    6535                 :    2177040 :             continue;
    6536                 :    5701050 :         bool isboxed = deserves_argbox(jt);
    6537         [ +  + ]:    5701050 :         Type *ty = isboxed ? ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, jt);
    6538         [ +  + ]:    5701050 :         if (type_is_ghost(ty))
    6539                 :    1918800 :             continue;
    6540                 :            : #if JL_LLVM_VERSION >= 140000
    6541                 :    7564500 :         AttrBuilder param(ctx.builder.getContext());
    6542                 :            : #else
    6543                 :            :         AttrBuilder param;
    6544                 :            : #endif
    6545         [ +  + ]:    3782250 :         if (ty->isAggregateType()) { // aggregate types are passed by pointer
    6546                 :    1285660 :             param.addAttribute(Attribute::NoCapture);
    6547                 :    1285660 :             param.addAttribute(Attribute::ReadOnly);
    6548                 :    1285660 :             ty = PointerType::get(ty, AddressSpace::Derived);
    6549                 :            :         }
    6550   [ +  +  +  +  :    2496590 :         else if (isboxed && jl_is_immutable_datatype(jt)) {
                   +  + ]
    6551                 :     247262 :             param.addAttribute(Attribute::ReadOnly);
    6552                 :            :         }
    6553   [ +  +  +  +  :    2249330 :         else if (jl_is_primitivetype(jt) && ty->isIntegerTy()) {
                   +  + ]
    6554   [ +  -  +  + ]:    1016840 :             bool issigned = jl_signed_type && jl_subtype(jt, (jl_value_t*)jl_signed_type);
    6555         [ +  + ]:    1016840 :             Attribute::AttrKind attr = issigned ? Attribute::SExt : Attribute::ZExt;
    6556                 :    1016840 :             param.addAttribute(attr);
    6557                 :            :         }
    6558                 :    3782250 :         attrs.push_back(AttributeSet::get(ctx.builder.getContext(), param));
    6559                 :    3782250 :         fsig.push_back(ty);
    6560                 :            :     }
    6561                 :            : 
    6562                 :    1826150 :     AttributeSet FnAttrs;
    6563                 :    1826150 :     AttributeSet RetAttrs;
    6564         [ +  + ]:    1826150 :     if (jlrettype == (jl_value_t*)jl_bottom_type)
    6565                 :     577021 :         FnAttrs = FnAttrs.addAttribute(ctx.builder.getContext(), Attribute::NoReturn);
    6566         [ +  + ]:    1249120 :     else if (rt == ctx.types().T_prjlvalue)
    6567                 :     649637 :         RetAttrs = RetAttrs.addAttribute(ctx.builder.getContext(), Attribute::NonNull);
    6568                 :    1826150 :     AttributeList attributes = AttributeList::get(ctx.builder.getContext(), FnAttrs, RetAttrs, attrs);
    6569                 :    1826150 :     FunctionType *ftype = FunctionType::get(rt, fsig, false);
    6570         [ +  - ]:    1826150 :     Function *f = M ? cast_or_null<Function>(M->getNamedValue(name)) : NULL;
    6571         [ +  + ]:    1826150 :     if (f == NULL) {
    6572                 :    1122780 :         f = Function::Create(ftype, GlobalVariable::ExternalLinkage, name, M);
    6573                 :    1122780 :         jl_init_function(f);
    6574                 :    1122780 :         f->setAttributes(AttributeList::get(f->getContext(), {attributes, f->getAttributes()}));
    6575                 :            :     }
    6576                 :            :     else {
    6577         [ -  + ]:     703368 :         assert(f->getFunctionType() == ftype);
    6578                 :            :     }
    6579                 :    1826150 :     props.decl = f;
    6580                 :    1826150 :     return props;
    6581                 :            : }
    6582                 :            : 
    6583                 :      33383 : static void emit_sret_roots(jl_codectx_t &ctx, bool isptr, Value *Src, Type *T, Value *Shadow, Type *ShadowT, unsigned count)
    6584                 :            : {
    6585   [ +  +  +  +  :      33383 :     if (isptr && !cast<PointerType>(Src->getType())->isOpaqueOrPointeeTypeMatches(T))
                   +  + ]
    6586                 :       1114 :         Src = ctx.builder.CreateBitCast(Src, T->getPointerTo(Src->getType()->getPointerAddressSpace()));
    6587                 :      33383 :     unsigned emitted = TrackWithShadow(Src, T, isptr, Shadow, ShadowT, ctx.builder); //This comes from Late-GC-Lowering??
    6588         [ -  + ]:      33383 :     assert(emitted == count); (void)emitted; (void)count;
    6589                 :      33383 : }
    6590                 :            : 
    6591                 :            : static DISubroutineType *
    6592                 :     325389 : get_specsig_di(jl_codectx_t &ctx, jl_debugcache_t &debuginfo, jl_value_t *rt, jl_value_t *sig, DIBuilder &dbuilder)
    6593                 :            : {
    6594                 :     325389 :     size_t nargs = jl_nparams(sig); // TODO: if this is a Varargs function, our debug info for the `...` var may be misleading
    6595                 :     325389 :     std::vector<Metadata*> ditypes(nargs + 1);
    6596                 :     325389 :     ditypes[0] = julia_type_to_di(ctx, debuginfo, rt, &dbuilder, false);
    6597         [ +  + ]:    1434530 :     for (size_t i = 0; i < nargs; i++) {
    6598                 :    1109140 :         jl_value_t *jt = jl_tparam(sig, i);
    6599                 :    1109140 :         ditypes[i + 1] = julia_type_to_di(ctx, debuginfo, jt, &dbuilder, false);
    6600                 :            :     }
    6601                 :     325389 :     return dbuilder.createSubroutineType(dbuilder.getOrCreateTypeArray(ditypes));
    6602                 :            : }
    6603                 :            : 
    6604                 :      24945 : static jl_datatype_t *compute_va_type(jl_method_instance_t *lam, size_t nreq)
    6605                 :            : {
    6606                 :      24945 :     size_t nvargs = jl_nparams(lam->specTypes)-nreq;
    6607                 :      24945 :     jl_svec_t *tupargs = jl_alloc_svec(nvargs);
    6608                 :      24945 :     JL_GC_PUSH1(&tupargs);
    6609         [ +  + ]:      63646 :     for (size_t i = nreq; i < jl_nparams(lam->specTypes); ++i) {
    6610                 :      38701 :         jl_value_t *argType = jl_nth_slot_type(lam->specTypes, i);
    6611                 :      38701 :         jl_svecset(tupargs, i-nreq, argType);
    6612                 :            :     }
    6613                 :      24945 :     jl_datatype_t *typ = jl_apply_tuple_type(tupargs);
    6614                 :      24945 :     JL_GC_POP();
    6615                 :      24945 :     return typ;
    6616                 :            : }
    6617                 :            : 
    6618                 :            : 
    6619                 :            : // Compile to LLVM IR, using a specialized signature if applicable.
    6620                 :            : static jl_llvm_functions_t
    6621                 :     364674 :     emit_function(
    6622                 :            :         orc::ThreadSafeModule &TSM,
    6623                 :            :         jl_method_instance_t *lam,
    6624                 :            :         jl_code_info_t *src,
    6625                 :            :         jl_value_t *jlrettype,
    6626                 :            :         jl_codegen_params_t &params)
    6627                 :            : {
    6628                 :     364674 :     ++EmittedFunctions;
    6629                 :            :     // step 1. unpack AST and allocate codegen context for this function
    6630                 :     364674 :     jl_llvm_functions_t declarations;
    6631                 :     729338 :     jl_codectx_t ctx(*params.tsctx.getContext(), params);
    6632                 :     364674 :     jl_datatype_t *vatyp = NULL;
    6633                 :     364674 :     JL_GC_PUSH3(&ctx.code, &ctx.roots, &vatyp);
    6634                 :     364674 :     ctx.code = src->code;
    6635                 :            : 
    6636                 :     729338 :     std::map<int, BasicBlock*> labels;
    6637                 :     364674 :     bool toplevel = false;
    6638         [ +  + ]:     364674 :     ctx.module = jl_is_method(lam->def.method) ? lam->def.method->module : lam->def.module;
    6639                 :     364674 :     ctx.linfo = lam;
    6640                 :     364674 :     ctx.name = TSM.getModuleUnlocked()->getModuleIdentifier().data();
    6641                 :     364674 :     size_t nreq = 0;
    6642                 :     364674 :     int va = 0;
    6643         [ +  + ]:     364674 :     if (jl_is_method(lam->def.method)) {
    6644                 :     363563 :         ctx.nargs = nreq = lam->def.method->nargs;
    6645                 :     363563 :         ctx.is_opaque_closure = lam->def.method->is_for_opaque_closure;
    6646   [ +  -  +  -  :     363563 :         if ((nreq > 0 && jl_is_method(lam->def.value) && lam->def.method->isva)) {
                   +  + ]
    6647         [ -  + ]:      35549 :             assert(nreq > 0);
    6648                 :      35549 :             nreq--;
    6649                 :      35549 :             va = 1;
    6650                 :            :         }
    6651                 :            :     }
    6652                 :            :     else {
    6653                 :       1111 :         ctx.nargs = 0;
    6654                 :            :     }
    6655                 :     364674 :     ctx.nReqArgs = nreq;
    6656         [ +  + ]:     364674 :     if (va) {
    6657                 :      35549 :         jl_sym_t *vn = (jl_sym_t*)jl_array_ptr_ref(src->slotnames, ctx.nargs - 1);
    6658         [ +  + ]:      35549 :         if (vn != jl_unused_sym)
    6659                 :      35532 :             ctx.vaSlot = ctx.nargs - 1;
    6660                 :            :     }
    6661                 :     364674 :     toplevel = !jl_is_method(lam->def.method);
    6662                 :     364674 :     ctx.rettype = jlrettype;
    6663                 :     364674 :     ctx.source = src;
    6664                 :     364674 :     ctx.funcName = ctx.name;
    6665                 :     364674 :     ctx.spvals_ptr = NULL;
    6666                 :     364674 :     jl_array_t *stmts = ctx.code;
    6667                 :     364674 :     size_t stmtslen = jl_array_dim0(stmts);
    6668                 :            : 
    6669                 :            :     // step 1b. unpack debug information
    6670                 :     364674 :     int coverage_mode = jl_options.code_coverage;
    6671                 :     364674 :     int malloc_log_mode = jl_options.malloc_log;
    6672         [ -  + ]:     364674 :     if (!JL_FEAT_TEST(ctx, code_coverage))
    6673                 :          0 :         coverage_mode = JL_LOG_NONE;
    6674         [ -  + ]:     364674 :     if (!JL_FEAT_TEST(ctx, track_allocations))
    6675                 :          0 :         malloc_log_mode = JL_LOG_NONE;
    6676                 :            : 
    6677                 :     364674 :     StringRef dbgFuncName = ctx.name;
    6678                 :     364674 :     int toplineno = -1;
    6679   [ +  -  +  + ]:     364674 :     if (lam && jl_is_method(lam->def.method)) {
    6680                 :     363563 :         toplineno = lam->def.method->line;
    6681                 :     363563 :         ctx.file = jl_symbol_name(lam->def.method->file);
    6682                 :            :     }
    6683         [ +  - ]:       1111 :     else if (jl_array_len(src->linetable) > 0) {
    6684                 :       1111 :         jl_value_t *locinfo = jl_array_ptr_ref(src->linetable, 0);
    6685                 :       1111 :         ctx.file = jl_symbol_name((jl_sym_t*)jl_fieldref_noalloc(locinfo, 2));
    6686                 :       1111 :         toplineno = jl_unbox_int32(jl_fieldref(locinfo, 3));
    6687                 :            :     }
    6688         [ +  + ]:     364674 :     if (ctx.file.empty())
    6689                 :         12 :         ctx.file = "<missing>";
    6690                 :            :     // jl_printf(JL_STDERR, "\n*** compiling %s at %s:%d\n\n",
    6691                 :            :     //           jl_symbol_name(ctx.name), ctx.file.str().c_str(), toplineno);
    6692                 :            : 
    6693                 :     364674 :     ctx.debug_enabled = true;
    6694         [ -  + ]:     364674 :     if (dbgFuncName.empty()) // Should never happen anymore?
    6695                 :          0 :         ctx.debug_enabled = 0;
    6696         [ +  + ]:     364674 :     if (jl_options.debug_level == 0)
    6697                 :       7174 :         ctx.debug_enabled = 0;
    6698                 :            : 
    6699                 :            :     // step 2. process var-info lists to see what vars need boxing
    6700         [ +  + ]:     364674 :     int n_ssavalues = jl_is_long(src->ssavaluetypes) ? jl_unbox_long(src->ssavaluetypes) : jl_array_len(src->ssavaluetypes);
    6701                 :     364674 :     size_t vinfoslen = jl_array_dim0(src->slotflags);
    6702                 :     364674 :     ctx.slots.resize(vinfoslen, jl_varinfo_t(ctx.builder.getContext()));
    6703         [ -  + ]:     364674 :     assert(lam->specTypes); // the specTypes field should always be assigned
    6704                 :            : 
    6705                 :            : 
    6706                 :            :     // create SAvalue locations for SSAValue objects
    6707                 :     364674 :     ctx.ssavalue_assigned.assign(n_ssavalues, false);
    6708                 :     364674 :     ctx.SAvalues.assign(n_ssavalues, jl_cgval_t());
    6709                 :     364674 :     ctx.ssavalue_usecount.assign(n_ssavalues, 0);
    6710                 :            : 
    6711                 :            :     bool specsig, needsparams;
    6712                 :     364674 :     std::tie(specsig, needsparams) = uses_specsig(lam, jlrettype, params.params->prefer_specsig);
    6713         [ +  + ]:     364674 :     if (!src->inferred)
    6714                 :       3137 :         specsig = false;
    6715                 :            : 
    6716                 :            :     // step 3. some variable analysis
    6717                 :            :     size_t i;
    6718         [ +  + ]:    1562370 :     for (i = 0; i < nreq; i++) {
    6719                 :    1197690 :         jl_varinfo_t &varinfo = ctx.slots[i];
    6720                 :    1197690 :         varinfo.isArgument = true;
    6721                 :    1197690 :         jl_sym_t *argname = (jl_sym_t*)jl_array_ptr_ref(src->slotnames, i);
    6722         [ +  + ]:    1197690 :         if (argname == jl_unused_sym)
    6723                 :      36377 :             continue;
    6724                 :    1161320 :         jl_value_t *ty = jl_nth_slot_type(lam->specTypes, i);
    6725                 :            :         // OpaqueClosure implicitly loads the env
    6726   [ +  +  +  + ]:    1161320 :         if (i == 0 && ctx.is_opaque_closure) {
    6727         [ +  - ]:         37 :             if (jl_is_array(src->slottypes)) {
    6728                 :         37 :                 ty = jl_arrayref((jl_array_t*)src->slottypes, i);
    6729                 :            :             }
    6730                 :            :             else {
    6731                 :          0 :                 ty = (jl_value_t*)jl_any_type;
    6732                 :            :             }
    6733                 :            :         }
    6734                 :    1161320 :         varinfo.value = mark_julia_type(ctx, (Value*)NULL, false, ty);
    6735                 :            :     }
    6736   [ +  +  +  + ]:     364674 :     if (va && ctx.vaSlot != -1) {
    6737                 :      35532 :         jl_varinfo_t &varinfo = ctx.slots[ctx.vaSlot];
    6738                 :      35532 :         varinfo.isArgument = true;
    6739         [ +  + ]:      35532 :         vatyp = specsig ? compute_va_type(lam, nreq) : (jl_tuple_type);
    6740                 :      35532 :         varinfo.value = mark_julia_type(ctx, (Value*)NULL, false, vatyp);
    6741                 :            :     }
    6742                 :            : 
    6743         [ +  + ]:    1611230 :     for (i = 0; i < vinfoslen; i++) {
    6744                 :    1246550 :         jl_varinfo_t &varinfo = ctx.slots[i];
    6745                 :    1246550 :         uint8_t flags = jl_array_uint8_ref(src->slotflags, i);
    6746   [ +  +  +  + ]:    1246550 :         varinfo.isSA = (jl_vinfo_sa(flags) != 0) || varinfo.isArgument;
    6747   [ +  +  +  +  :    1246550 :         varinfo.usedUndef = (jl_vinfo_usedundef(flags) != 0) || (!varinfo.isArgument && !src->inferred);
                   +  + ]
    6748         [ +  + ]:    1246550 :         if (!varinfo.isArgument) {
    6749                 :      13330 :             varinfo.value = mark_julia_type(ctx, (Value*)NULL, false, (jl_value_t*)jl_any_type);
    6750                 :            :         }
    6751                 :            :     }
    6752                 :            : 
    6753                 :            :     // finish recording variable use info
    6754         [ +  + ]:   41060900 :     for (i = 0; i < stmtslen; i++)
    6755                 :   40696200 :         simple_use_analysis(ctx, jl_array_ptr_ref(stmts, i));
    6756                 :            : 
    6757                 :            :     // determine which vars need to be volatile
    6758                 :     364674 :     mark_volatile_vars(stmts, ctx.slots);
    6759                 :            : 
    6760                 :            :     // step 4. determine function signature
    6761         [ +  + ]:     364674 :     if (!specsig)
    6762                 :      22039 :         ctx.nReqArgs--;  // function not part of argArray in jlcall
    6763                 :            : 
    6764                 :     729338 :     std::string _funcName;
    6765                 :     729338 :     raw_string_ostream funcName(_funcName);
    6766                 :            :     // try to avoid conflicts in the global symbol table
    6767         [ +  + ]:     364674 :     if (specsig)
    6768                 :     342635 :         funcName << "julia_"; // api 5
    6769         [ +  + ]:      22039 :     else if (needsparams)
    6770                 :        206 :         funcName << "japi3_";
    6771                 :            :     else
    6772                 :      21833 :         funcName << "japi1_";
    6773                 :     364674 :     const char* unadorned_name = ctx.name;
    6774                 :            : #if defined(_OS_LINUX_)
    6775         [ +  + ]:     364674 :     if (unadorned_name[0] == '@')
    6776                 :       1524 :         unadorned_name++;
    6777                 :            : #endif
    6778                 :     364674 :     funcName << unadorned_name << "_" << globalUniqueGeneratedNames++;
    6779                 :     364674 :     declarations.specFunctionObject = funcName.str();
    6780                 :            : 
    6781                 :            :     // allocate Function declarations and wrapper objects
    6782                 :            :     //Safe because params holds ctx lock
    6783                 :     364674 :     Module *M = TSM.getModuleUnlocked();
    6784                 :     364674 :     jl_debugcache_t debuginfo;
    6785                 :     364674 :     debuginfo.initialize(M);
    6786                 :     364674 :     jl_returninfo_t returninfo = {};
    6787                 :     364674 :     Function *f = NULL;
    6788                 :     364674 :     bool has_sret = false;
    6789         [ +  + ]:     364674 :     if (specsig) { // assumes !va and !needsparams
    6790                 :     342635 :         returninfo = get_specsig_function(ctx, M, declarations.specFunctionObject, lam->specTypes, jlrettype, ctx.is_opaque_closure);
    6791                 :     342635 :         f = returninfo.decl;
    6792   [ +  +  +  + ]:     342635 :         has_sret = (returninfo.cc == jl_returninfo_t::SRet || returninfo.cc == jl_returninfo_t::Union);
    6793                 :     342635 :         jl_init_function(f);
    6794                 :            : 
    6795                 :            :         // common pattern: see if all return statements are an argument in that
    6796                 :            :         // case the apply-generic call can re-use the original box for the return
    6797                 :   62695400 :         int retarg = [stmts, nreq]() {
    6798                 :     342635 :             int retarg = -1;
    6799         [ +  + ]:   31184800 :             for (size_t i = 0; i < jl_array_len(stmts); ++i) {
    6800                 :   31120600 :                 jl_value_t *stmt = jl_array_ptr_ref(stmts, i);
    6801         [ +  + ]:   31120600 :                 if (jl_is_returnnode(stmt)) {
    6802                 :     985124 :                     stmt = jl_returnnode_value(stmt);
    6803         [ +  + ]:     985124 :                     if (stmt == NULL)
    6804                 :     659613 :                         continue;
    6805         [ +  + ]:     325511 :                     if (!jl_is_argument(stmt))
    6806                 :     278204 :                         return -1;
    6807                 :      47307 :                     unsigned sl = jl_slot_number(stmt) - 1;
    6808         [ +  + ]:      47307 :                     if (sl >= nreq)
    6809                 :        178 :                         return -1;
    6810         [ +  + ]:      47129 :                     if (retarg == -1)
    6811                 :      41476 :                         retarg = sl;
    6812         [ +  + ]:       5653 :                     else if ((unsigned)retarg != sl)
    6813                 :         66 :                         return -1;
    6814                 :            :                 }
    6815                 :            :             }
    6816                 :      64187 :             return retarg;
    6817                 :     342635 :         }();
    6818                 :            : 
    6819                 :     342635 :         std::string wrapName;
    6820                 :     342635 :         raw_string_ostream(wrapName) << "jfptr_" << unadorned_name << "_" << globalUniqueGeneratedNames++;
    6821                 :     342635 :         declarations.functionObject = wrapName;
    6822                 :     342635 :         (void)gen_invoke_wrapper(lam, jlrettype, returninfo, retarg, declarations.functionObject, M, ctx.emission_context);
    6823                 :            :         // TODO: add attributes: maybe_mark_argument_dereferenceable(Arg, argType)
    6824                 :            :         // TODO: add attributes: dereferenceable<sizeof(void*) * nreq>
    6825                 :            :         // TODO: (if needsparams) add attributes: dereferenceable<sizeof(void*) * length(sp)>, readonly, nocapture
    6826                 :            :     }
    6827                 :            :     else {
    6828         [ +  + ]:      22039 :         f = Function::Create(needsparams ? ctx.types().T_jlfuncparams : ctx.types().T_jlfunc,
    6829                 :            :                              GlobalVariable::ExternalLinkage,
    6830                 :      22039 :                              declarations.specFunctionObject, M);
    6831                 :      22039 :         jl_init_function(f);
    6832                 :      22039 :         f->setAttributes(AttributeList::get(ctx.builder.getContext(), {get_func_attrs(ctx.builder.getContext()), f->getAttributes()}));
    6833                 :      22039 :         returninfo.decl = f;
    6834         [ +  + ]:      22039 :         declarations.functionObject = needsparams ? "jl_fptr_sparam" : "jl_fptr_args";
    6835                 :            :     }
    6836                 :            : 
    6837                 :            : #if JL_LLVM_VERSION >= 140000
    6838                 :     729338 :     AttrBuilder FnAttrs(ctx.builder.getContext(), f->getAttributes().getFnAttrs());
    6839                 :            : #else
    6840                 :            :     AttrBuilder FnAttrs(f->getAttributes().getFnAttributes());
    6841                 :            : #endif
    6842                 :            : #if JL_LLVM_VERSION >= 140000
    6843                 :     729338 :     AttrBuilder RetAttrs(ctx.builder.getContext(), f->getAttributes().getRetAttrs());
    6844                 :            : #else
    6845                 :            :     AttrBuilder RetAttrs(f->getAttributes().getRetAttributes());
    6846                 :            : #endif
    6847                 :            : 
    6848         [ +  + ]:     364674 :     if (jlrettype == (jl_value_t*)jl_bottom_type)
    6849                 :      28324 :         FnAttrs.addAttribute(Attribute::NoReturn);
    6850                 :            : 
    6851                 :            : #ifdef USE_POLLY
    6852                 :            :     if (!jl_has_meta(stmts, jl_polly_sym) || jl_options.polly == JL_OPTIONS_POLLY_OFF)
    6853                 :            :         FnAttrs.addAttribute(polly::PollySkipFnAttr);
    6854                 :            : #endif
    6855                 :            : 
    6856         [ +  + ]:     364674 :     if (jl_has_meta(stmts, jl_noinline_sym))
    6857                 :      26451 :         FnAttrs.addAttribute(Attribute::NoInline);
    6858                 :            : 
    6859                 :            : #ifdef JL_DEBUG_BUILD
    6860                 :     364674 :     FnAttrs.addAttribute(Attribute::StackProtectStrong);
    6861                 :            : #endif
    6862                 :            : 
    6863                 :            : #ifdef _COMPILER_TSAN_ENABLED_
    6864                 :            :     // TODO: enable this only when a argument like `-race` is passed to Julia
    6865                 :            :     //       add a macro for no_sanitize_thread
    6866                 :            :     FnAttrs.addAttribute(llvm::Attribute::SanitizeThread);
    6867                 :            : #endif
    6868                 :            : 
    6869                 :            :     // add the optimization level specified for this module, if any
    6870                 :     364674 :     int optlevel = jl_get_module_optlevel(ctx.module);
    6871   [ +  +  +  - ]:     364674 :     if (optlevel >= 0 && optlevel <= 3) {
    6872                 :            :         static const char* const optLevelStrings[] = { "0", "1", "2", "3" };
    6873                 :       2724 :         FnAttrs.addAttribute("julia-optimization-level", optLevelStrings[optlevel]);
    6874                 :            :     }
    6875                 :            : 
    6876                 :     364674 :     ctx.f = f;
    6877                 :            : 
    6878                 :            :     // Step 4b. determine debug info signature and other type info for locals
    6879                 :     729338 :     DIBuilder dbuilder(*M);
    6880                 :     364674 :     DIFile *topfile = NULL;
    6881                 :     364674 :     DISubprogram *SP = NULL;
    6882                 :     364664 :     DebugLoc noDbg, topdebugloc;
    6883         [ +  + ]:     364674 :     if (ctx.debug_enabled) {
    6884                 :     357500 :         DICompileUnit::DebugEmissionKind emissionKind = (DICompileUnit::DebugEmissionKind) ctx.params->debug_info_kind;
    6885                 :            :         DICompileUnit::DebugNameTableKind tableKind;
    6886                 :            : 
    6887         [ +  - ]:     357500 :         if (JL_FEAT_TEST(ctx, gnu_pubnames)) {
    6888                 :     357500 :             tableKind = DICompileUnit::DebugNameTableKind::GNU;
    6889                 :            :         }
    6890                 :            :         else {
    6891                 :          0 :             tableKind = DICompileUnit::DebugNameTableKind::None;
    6892                 :            :         }
    6893                 :     357500 :         topfile = dbuilder.createFile(ctx.file, ".");
    6894                 :            :         DICompileUnit *CU =
    6895                 :     357500 :             dbuilder.createCompileUnit(llvm::dwarf::DW_LANG_Julia
    6896                 :            :                                        ,topfile      // File
    6897                 :            :                                        ,"julia"      // Producer
    6898                 :            :                                        ,true         // isOptimized
    6899                 :            :                                        ,""           // Flags
    6900                 :            :                                        ,0            // RuntimeVersion
    6901                 :            :                                        ,""           // SplitName
    6902                 :            :                                        ,emissionKind // Kind
    6903                 :            :                                        ,0            // DWOId
    6904                 :            :                                        ,true         // SplitDebugInlining
    6905                 :            :                                        ,false        // DebugInfoForProfiling
    6906                 :            :                                        ,tableKind    // NameTableKind
    6907                 :            :                                        );
    6908                 :            : 
    6909                 :            :         DISubroutineType *subrty;
    6910         [ +  + ]:     357500 :         if (jl_options.debug_level <= 1) {
    6911                 :      13418 :             subrty = debuginfo.jl_di_func_null_sig;
    6912                 :            :         }
    6913         [ +  + ]:     344082 :         else if (!specsig) {
    6914                 :      18693 :             subrty = debuginfo.jl_di_func_sig;
    6915                 :            :         }
    6916                 :            :         else {
    6917                 :     325389 :             subrty = get_specsig_di(ctx, debuginfo, jlrettype, lam->specTypes, dbuilder);
    6918                 :            :         }
    6919                 :     357500 :         SP = dbuilder.createFunction(CU
    6920                 :            :                                      ,dbgFuncName      // Name
    6921                 :            :                                      ,f->getName()     // LinkageName
    6922                 :            :                                      ,topfile          // File
    6923                 :            :                                      ,toplineno        // LineNo
    6924                 :            :                                      ,subrty           // Ty
    6925                 :            :                                      ,toplineno        // ScopeLine
    6926                 :            :                                      ,DINode::FlagZero // Flags
    6927                 :            :                                      ,DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized // SPFlags
    6928                 :            :                                      ,nullptr          // Template Parameters
    6929                 :            :                                      ,nullptr          // Template Declaration
    6930                 :            :                                      ,nullptr          // ThrownTypes
    6931                 :            :                                      );
    6932                 :     357500 :         topdebugloc = DILocation::get(ctx.builder.getContext(), toplineno, 0, SP, NULL);
    6933                 :     357500 :         f->setSubprogram(SP);
    6934         [ +  + ]:     357500 :         if (jl_options.debug_level >= 2) {
    6935                 :     344082 :             const bool AlwaysPreserve = true;
    6936                 :            :             // Go over all arguments and local variables and initialize their debug information
    6937         [ +  + ]:    1477350 :             for (i = 0; i < nreq; i++) {
    6938                 :    1133270 :                 jl_sym_t *argname = (jl_sym_t*)jl_array_ptr_ref(src->slotnames, i);
    6939         [ +  + ]:    1133270 :                 if (argname == jl_unused_sym)
    6940                 :      33065 :                     continue;
    6941                 :    1100200 :                 jl_varinfo_t &varinfo = ctx.slots[i];
    6942         [ +  - ]:    2200400 :                 varinfo.dinfo = dbuilder.createParameterVariable(
    6943                 :            :                     SP,                                 // Scope (current function will be fill in later)
    6944                 :    1100200 :                     jl_symbol_name(argname),            // Variable name
    6945                 :    1100200 :                     has_sret + i + 1,                   // Argument number (1-based)
    6946                 :            :                     topfile,                            // File
    6947                 :            :                     toplineno == -1 ? 0 : toplineno,    // Line
    6948                 :            :                     // Variable type
    6949                 :            :                     julia_type_to_di(ctx, debuginfo, varinfo.value.typ, &dbuilder, false),
    6950                 :            :                     AlwaysPreserve,                     // May be deleted if optimized out
    6951                 :            :                     DINode::FlagZero);                  // Flags (TODO: Do we need any)
    6952                 :            :             }
    6953   [ +  +  +  + ]:     344082 :             if (va && ctx.vaSlot != -1) {
    6954         [ +  - ]:     102120 :                 ctx.slots[ctx.vaSlot].dinfo = dbuilder.createParameterVariable(
    6955                 :            :                     SP,                                 // Scope (current function will be fill in later)
    6956                 :      68080 :                     std::string(jl_symbol_name(slot_symbol(ctx, ctx.vaSlot))) + "...",  // Variable name
    6957                 :      34040 :                     has_sret + nreq + 1,                // Argument number (1-based)
    6958                 :            :                     topfile,                            // File
    6959                 :            :                     toplineno == -1 ? 0 : toplineno,    // Line (for now, use lineno of the function)
    6960                 :      34040 :                     julia_type_to_di(ctx, debuginfo, ctx.slots[ctx.vaSlot].value.typ, &dbuilder, false),
    6961                 :            :                     AlwaysPreserve,                     // May be deleted if optimized out
    6962                 :            :                     DINode::FlagZero);                  // Flags (TODO: Do we need any)
    6963                 :            :             }
    6964         [ +  + ]:    1520530 :             for (i = 0; i < vinfoslen; i++) {
    6965                 :    1176450 :                 jl_sym_t *s = (jl_sym_t*)jl_array_ptr_ref(src->slotnames, i);
    6966                 :    1176450 :                 jl_varinfo_t &varinfo = ctx.slots[i];
    6967   [ +  +  +  +  :    1176450 :                 if (varinfo.isArgument || s == jl_empty_sym || s == jl_unused_sym)
                   +  + ]
    6968                 :    1170480 :                     continue;
    6969                 :            :                 // LLVM 4.0: Assume the variable has default alignment
    6970         [ +  - ]:      11926 :                 varinfo.dinfo = dbuilder.createAutoVariable(
    6971                 :            :                     SP,                      // Scope (current function will be fill in later)
    6972                 :       5963 :                     jl_symbol_name(s),       // Variable name
    6973                 :            :                     topfile,                 // File
    6974                 :            :                     toplineno == -1 ? 0 : toplineno, // Line (for now, use lineno of the function)
    6975                 :            :                     julia_type_to_di(ctx, debuginfo, varinfo.value.typ, &dbuilder, false), // Variable type
    6976                 :            :                     AlwaysPreserve,          // May be deleted if optimized out
    6977                 :            :                     DINode::FlagZero         // Flags (TODO: Do we need any)
    6978                 :            :                     );
    6979                 :            :             }
    6980                 :            :         }
    6981                 :            :     }
    6982                 :            : 
    6983                 :            :     // step 5. create first basic block
    6984                 :     364674 :     BasicBlock *b0 = BasicBlock::Create(ctx.builder.getContext(), "top", f);
    6985                 :     364674 :     ctx.builder.SetInsertPoint(b0);
    6986                 :     364674 :     ctx.builder.SetCurrentDebugLocation(noDbg);
    6987                 :            : 
    6988                 :            :     // spill arguments into stack slots
    6989                 :            :     // so it is more likely to be possible to find them when debugging
    6990                 :     364674 :     Value *fArg=NULL, *argArray=NULL, *pargArray=NULL, *argCount=NULL;
    6991         [ +  + ]:     364674 :     if (!specsig) {
    6992                 :      22039 :         Function::arg_iterator AI = f->arg_begin();
    6993                 :      22039 :         fArg = &*AI++;
    6994                 :      22039 :         argArray = &*AI++;
    6995                 :      22039 :         pargArray = ctx.builder.CreateAlloca(argArray->getType());
    6996                 :      22039 :         ctx.builder.CreateStore(argArray, pargArray, true/*volatile store to prevent removal of this alloca*/);
    6997                 :      22039 :         argCount = &*AI++;
    6998                 :      22039 :         ctx.argArray = argArray;
    6999                 :      22039 :         ctx.argCount = argCount;
    7000         [ +  + ]:      22039 :         if (needsparams) {
    7001                 :        206 :             ctx.spvals_ptr = &*AI++;
    7002                 :            :         }
    7003                 :            :     }
    7004                 :            : 
    7005                 :            :     // step 6. set up GC frame
    7006                 :     364674 :     allocate_gc_frame(ctx, b0);
    7007                 :     364674 :     Value *last_age = NULL;
    7008                 :     364674 :     Value *world_age_field = get_last_age_field(ctx);
    7009   [ +  +  +  + ]:     364674 :     if (toplevel || ctx.is_opaque_closure) {
    7010                 :       3444 :         last_age = tbaa_decorate(ctx.tbaa().tbaa_gcframe, ctx.builder.CreateAlignedLoad(
    7011                 :       3444 :             getSizeTy(ctx.builder.getContext()), world_age_field, Align(sizeof(size_t))));
    7012                 :            :     }
    7013                 :            : 
    7014                 :            :     // step 7. allocate local variables slots
    7015                 :            :     // must be in the first basic block for the llvm mem2reg pass to work
    7016                 :     971609 :     auto allocate_local = [&](jl_varinfo_t &varinfo, jl_sym_t *s) {
    7017                 :     971609 :         jl_value_t *jt = varinfo.value.typ;
    7018         [ -  + ]:     971609 :         assert(!varinfo.boxroot); // variables shouldn't have memory locs already
    7019         [ +  + ]:     971609 :         if (varinfo.value.constant) {
    7020                 :            :             // no need to explicitly load/store a constant/ghost value
    7021                 :      57209 :             alloc_def_flag(ctx, varinfo);
    7022                 :      57209 :             return;
    7023                 :            :         }
    7024   [ +  +  +  +  :     914400 :         else if (varinfo.isArgument && !(specsig && i == (size_t)ctx.vaSlot)) {
                   +  + ]
    7025                 :            :             // if we can unbox it, just use the input pointer
    7026   [ +  +  +  +  :     711147 :             if (i != (size_t)ctx.vaSlot && jl_is_concrete_immutable(jt))
                   +  + ]
    7027                 :     454604 :                 return;
    7028                 :            :         }
    7029         [ +  + ]:     203253 :         else if (jl_is_uniontype(jt)) {
    7030                 :            :             bool allunbox;
    7031                 :            :             size_t align, nbytes;
    7032                 :       3726 :             Value *lv = try_emit_union_alloca(ctx, (jl_uniontype_t*)jt, allunbox, align, nbytes);
    7033         [ +  + ]:       3726 :             if (lv) {
    7034                 :        285 :                 lv->setName(jl_symbol_name(s));
    7035                 :        285 :                 varinfo.value = mark_julia_slot(lv, jt, NULL, ctx.tbaa().tbaa_stack);
    7036                 :        285 :                 varinfo.pTIndex = emit_static_alloca(ctx, getInt8Ty(ctx.builder.getContext()));
    7037                 :            :             }
    7038         [ +  + ]:       3441 :             else if (allunbox) {
    7039                 :            :                 // all ghost values just need a selector allocated
    7040                 :        204 :                 AllocaInst *lv = emit_static_alloca(ctx, getInt8Ty(ctx.builder.getContext()));
    7041                 :        204 :                 lv->setName(jl_symbol_name(s));
    7042                 :        204 :                 varinfo.pTIndex = lv;
    7043                 :        204 :                 varinfo.value.tbaa = NULL;
    7044                 :        204 :                 varinfo.value.isboxed = false;
    7045                 :            :             }
    7046   [ +  +  +  + ]:       3726 :             if (lv || allunbox)
    7047                 :        489 :                 alloc_def_flag(ctx, varinfo);
    7048         [ +  + ]:       3726 :             if (allunbox)
    7049                 :        420 :                 return;
    7050                 :            :         }
    7051         [ +  + ]:     199527 :         else if (deserves_stack(jt)) {
    7052                 :            :             bool isboxed;
    7053                 :      73885 :             Type *vtype = julia_type_to_llvm(ctx, jt, &isboxed);
    7054         [ -  + ]:      73885 :             assert(!isboxed);
    7055         [ +  - ]:      73885 :             assert(!type_is_ghost(vtype) && "constants should already be handled");
    7056                 :      73885 :             Value *lv = new AllocaInst(vtype, 0, jl_symbol_name(s), /*InsertBefore*/ctx.topalloca);
    7057         [ +  + ]:      73885 :             if (CountTrackedPointers(vtype).count) {
    7058                 :      17634 :                 StoreInst *SI = new StoreInst(Constant::getNullValue(vtype), lv, false, Align(sizeof(void*)));
    7059                 :      17634 :                 SI->insertAfter(ctx.topalloca);
    7060                 :            :             }
    7061                 :      73885 :             varinfo.value = mark_julia_slot(lv, jt, NULL, ctx.tbaa().tbaa_stack);
    7062                 :      73885 :             alloc_def_flag(ctx, varinfo);
    7063   [ +  +  +  + ]:      73885 :             if (ctx.debug_enabled && varinfo.dinfo) {
    7064         [ -  + ]:      17932 :                 assert((Metadata*)varinfo.dinfo->getType() != debuginfo.jl_pvalue_dillvmt);
    7065                 :      35864 :                 dbuilder.insertDeclare(lv, varinfo.dinfo, dbuilder.createExpression(),
    7066                 :     240530 :                                        topdebugloc,
    7067                 :      17932 :                                        ctx.builder.GetInsertBlock());
    7068                 :            :             }
    7069                 :      73885 :             return;
    7070                 :            :         }
    7071         [ +  + ]:     385491 :         if (!varinfo.isArgument || // always need a slot if the variable is assigned
    7072         [ +  + ]:     258330 :             specsig || // for arguments, give them stack slots if they aren't in `argArray` (otherwise, will use that pointer)
    7073   [ +  +  +  + ]:      37621 :             (va && (int)i == ctx.vaSlot) || // or it's the va arg tuple
    7074         [ +  + ]:      27493 :             i == 0) { // or it is the first argument (which isn't in `argArray`)
    7075                 :     358064 :             AllocaInst *av = new AllocaInst(ctx.types().T_prjlvalue, 0,
    7076                 :     358064 :                 jl_symbol_name(s), /*InsertBefore*/ctx.topalloca);
    7077                 :     358064 :             StoreInst *SI = new StoreInst(Constant::getNullValue(ctx.types().T_prjlvalue), av, false, Align(sizeof(void*)));
    7078                 :     358064 :             SI->insertAfter(ctx.topalloca);
    7079                 :     358064 :             varinfo.boxroot = av;
    7080   [ +  +  +  + ]:     358064 :             if (ctx.debug_enabled && varinfo.dinfo) {
    7081                 :            :                 DIExpression *expr;
    7082         [ +  + ]:     222598 :                 if ((Metadata*)varinfo.dinfo->getType() == debuginfo.jl_pvalue_dillvmt) {
    7083                 :      37967 :                     expr = dbuilder.createExpression();
    7084                 :            :                 }
    7085                 :            :                 else {
    7086                 :     184631 :                     SmallVector<uint64_t, 8> addr;
    7087                 :     184631 :                     addr.push_back(llvm::dwarf::DW_OP_deref);
    7088                 :     184631 :                     expr = dbuilder.createExpression(addr);
    7089                 :            :                 }
    7090                 :     445196 :                 dbuilder.insertDeclare(av, varinfo.dinfo, expr,
    7091                 :            :                                             topdebugloc,
    7092                 :     222598 :                                 ctx.builder.GetInsertBlock());
    7093                 :            :             }
    7094                 :            :         }
    7095                 :     364674 :     };
    7096                 :            : 
    7097                 :            :     // get pointers for locals stored in the gc frame array (argTemp)
    7098         [ +  + ]:    1611230 :     for (i = 0; i < vinfoslen; i++) {
    7099                 :    1246550 :         jl_sym_t *s = slot_symbol(ctx, i);
    7100         [ +  + ]:    1246550 :         if (s == jl_unused_sym)
    7101                 :      36394 :             continue;
    7102                 :    1210160 :         jl_varinfo_t &varinfo = ctx.slots[i];
    7103         [ +  + ]:    1210160 :         if (!varinfo.used) {
    7104                 :     434324 :             varinfo.usedUndef = false;
    7105                 :     434324 :             continue;
    7106                 :            :         }
    7107                 :     775836 :         allocate_local(varinfo, s);
    7108                 :            :     }
    7109                 :            : 
    7110                 :     729338 :     std::map<int, int> upsilon_to_phic;
    7111                 :            : 
    7112                 :            :     // Scan for PhiC nodes, emit their slots and record which upsilon nodes
    7113                 :            :     // yield to them.
    7114                 :            :     // Also count ssavalue uses.
    7115                 :            :     {
    7116         [ +  + ]:   41060900 :         for (size_t i = 0; i < jl_array_len(stmts); ++i) {
    7117                 :   40696200 :             jl_value_t *stmt = jl_array_ptr_ref(stmts, i);
    7118                 :            : 
    7119                 :  124796000 :             auto scan_ssavalue = [&](jl_value_t *val) {
    7120         [ +  + ]:  124796000 :                 if (jl_is_ssavalue(val)) {
    7121                 :   36473400 :                     ctx.ssavalue_usecount[((jl_ssavalue_t*)val)->id-1] += 1;
    7122                 :   36473400 :                     return true;
    7123                 :            :                 }
    7124                 :   88322800 :                 return false;
    7125                 :   40696200 :             };
    7126                 :   40696200 :             general_use_analysis(ctx, stmt, scan_ssavalue);
    7127                 :            : 
    7128         [ +  + ]:   40696200 :             if (jl_is_phicnode(stmt)) {
    7129                 :     195773 :                 jl_array_t *values = (jl_array_t*)jl_fieldref_noalloc(stmt, 0);
    7130         [ +  + ]:     409939 :                 for (size_t j = 0; j < jl_array_len(values); ++j) {
    7131                 :     214166 :                     jl_value_t *val = jl_array_ptr_ref(values, j);
    7132         [ -  + ]:     214166 :                     assert(jl_is_ssavalue(val));
    7133                 :     214166 :                     upsilon_to_phic[((jl_ssavalue_t*)val)->id] = i;
    7134                 :            :                 }
    7135                 :     195773 :                 jl_varinfo_t &vi = (ctx.phic_slots.emplace(i, jl_varinfo_t(ctx.builder.getContext())).first->second =
    7136                 :     195773 :                                     jl_varinfo_t(ctx.builder.getContext()));
    7137                 :     195773 :                 jl_value_t *typ = jl_array_ptr_ref(src->ssavaluetypes, i);
    7138                 :     195773 :                 vi.used = true;
    7139                 :     195773 :                 vi.isVolatile = true;
    7140                 :     195773 :                 vi.value = mark_julia_type(ctx, (Value*)NULL, false, typ);
    7141                 :     195773 :                 allocate_local(vi, jl_symbol("phic"));
    7142                 :            :             }
    7143                 :            :         }
    7144                 :            :     }
    7145                 :            : 
    7146                 :            :     // step 8. move args into local variables
    7147                 :     364674 :     Function::arg_iterator AI = f->arg_begin();
    7148                 :     729338 :     std::vector<AttributeSet> attrs(f->arg_size()); // function declaration attributes
    7149                 :            : 
    7150                 :     744347 :     auto get_specsig_arg = [&](jl_value_t *argType, Type *llvmArgType, bool isboxed) {
    7151         [ +  + ]:     744347 :         if (type_is_ghost(llvmArgType)) { // this argument is not actually passed
    7152                 :        273 :             return ghostValue(ctx, argType);
    7153                 :            :         }
    7154         [ +  + ]:     744074 :         else if (is_uniquerep_Type(argType)) {
    7155                 :       1086 :             return mark_julia_const(ctx, jl_tparam0(argType));
    7156                 :            :         }
    7157                 :     742988 :         Argument *Arg = &*AI;
    7158                 :     742988 :         ++AI;
    7159                 :            : #if JL_LLVM_VERSION >= 140000
    7160                 :     742988 :         AttrBuilder param(ctx.builder.getContext(), f->getAttributes().getParamAttrs(Arg->getArgNo()));
    7161                 :            : #else
    7162                 :            :         AttrBuilder param(f->getAttributes().getParamAttributes(Arg->getArgNo()));
    7163                 :            : #endif
    7164                 :     742988 :         jl_cgval_t theArg;
    7165         [ +  + ]:     742988 :         if (llvmArgType->isAggregateType()) {
    7166                 :     318263 :             maybe_mark_argument_dereferenceable(param, argType);
    7167                 :     318263 :             theArg = mark_julia_slot(Arg, argType, NULL, ctx.tbaa().tbaa_const); // this argument is by-pointer
    7168                 :            :         }
    7169                 :            :         else {
    7170         [ +  + ]:     424725 :             if (isboxed) // e.g. is-pointer
    7171                 :     255739 :                 maybe_mark_argument_dereferenceable(param, argType);
    7172                 :     424725 :             theArg = mark_julia_type(ctx, Arg, isboxed, argType);
    7173         [ +  + ]:     424725 :             if (theArg.tbaa == ctx.tbaa().tbaa_immut)
    7174                 :       4353 :                 theArg.tbaa = ctx.tbaa().tbaa_const;
    7175                 :            :         }
    7176                 :     742988 :         attrs.at(Arg->getArgNo()) = AttributeSet::get(Arg->getContext(), param); // function declaration attributes
    7177                 :     742988 :         return theArg;
    7178                 :     364674 :     };
    7179                 :            : 
    7180         [ +  + ]:     364674 :     if (has_sret) {
    7181                 :      60171 :         Argument *Arg = &*AI;
    7182                 :      60171 :         ++AI;
    7183                 :            : #if JL_LLVM_VERSION >= 140000
    7184                 :     120342 :         AttrBuilder param(ctx.builder.getContext(), f->getAttributes().getParamAttrs(Arg->getArgNo()));
    7185                 :            : #else
    7186                 :            :         AttrBuilder param(f->getAttributes().getParamAttributes(Arg->getArgNo()));
    7187                 :            : #endif
    7188         [ +  + ]:      60171 :         if (returninfo.cc == jl_returninfo_t::Union) {
    7189                 :       5471 :             param.addAttribute(Attribute::NonNull);
    7190                 :            :             // The `dereferencable` below does not imply `nonnull` for non addrspace(0) pointers.
    7191                 :       5471 :             param.addDereferenceableAttr(returninfo.union_bytes);
    7192                 :       5471 :             param.addAlignmentAttr(returninfo.union_align);
    7193                 :            :         }
    7194                 :            :         else {
    7195                 :      54700 :             const DataLayout &DL = jl_Module->getDataLayout();
    7196                 :      54700 :             Type *RT = Arg->getParamStructRetType();
    7197                 :      54700 :             TypeSize sz = DL.getTypeAllocSize(RT);
    7198                 :      54700 :             Align al = DL.getPrefTypeAlign(RT);
    7199                 :      54700 :             param.addAttribute(Attribute::NonNull);
    7200                 :            :             // The `dereferencable` below does not imply `nonnull` for non addrspace(0) pointers.
    7201                 :      54700 :             param.addDereferenceableAttr(sz);
    7202                 :      54700 :             param.addAlignmentAttr(al);
    7203                 :            :         }
    7204                 :      60171 :         attrs.at(Arg->getArgNo()) = AttributeSet::get(Arg->getContext(), param); // function declaration attributes
    7205                 :            :     }
    7206         [ +  + ]:     364674 :     if (returninfo.return_roots) {
    7207                 :      27542 :         Argument *Arg = &*AI;
    7208                 :      27542 :         ++AI;
    7209                 :            : #if JL_LLVM_VERSION >= 140000
    7210                 :      55084 :         AttrBuilder param(ctx.builder.getContext(), f->getAttributes().getParamAttrs(Arg->getArgNo()));
    7211                 :            : #else
    7212                 :            :         AttrBuilder param(f->getAttributes().getParamAttributes(Arg->getArgNo()));
    7213                 :            : #endif
    7214                 :      27542 :         param.addAttribute(Attribute::NonNull);
    7215                 :            :         // The `dereferencable` below does not imply `nonnull` for non addrspace(0) pointers.
    7216                 :      27542 :         size_t size = returninfo.return_roots * sizeof(jl_value_t*);
    7217                 :      27542 :         param.addDereferenceableAttr(size);
    7218                 :      27542 :         param.addAlignmentAttr(Align(sizeof(jl_value_t*)));
    7219                 :      27542 :         attrs.at(Arg->getArgNo()) = AttributeSet::get(Arg->getContext(), param); // function declaration attributes
    7220                 :            :     }
    7221         [ +  + ]:    1562370 :     for (i = 0; i < nreq; i++) {
    7222                 :    1197690 :         jl_sym_t *s = (jl_sym_t*)jl_array_ptr_ref(src->slotnames, i);
    7223   [ +  +  +  + ]:    1197690 :         jl_value_t *argType = (i == 0 && ctx.is_opaque_closure) ? (jl_value_t*)jl_any_type :
    7224                 :    1197660 :             jl_nth_slot_type(lam->specTypes, i);
    7225                 :    1197690 :         bool isboxed = deserves_argbox(argType);
    7226         [ +  + ]:    1197690 :         Type *llvmArgType = isboxed ? ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, argType);
    7227         [ +  + ]:    1197690 :         if (s == jl_unused_sym) {
    7228   [ +  +  +  +  :      36377 :             if (specsig && !type_is_ghost(llvmArgType) && !is_uniquerep_Type(argType))
             +  +  +  + ]
    7229                 :       2261 :                 ++AI;
    7230                 :      36377 :             continue;
    7231                 :            :         }
    7232                 :    1161320 :         jl_varinfo_t &vi = ctx.slots[i];
    7233                 :    1161320 :         jl_cgval_t theArg;
    7234   [ +  -  +  + ]:    1161320 :         if (s == jl_unused_sym || vi.value.constant) {
    7235         [ -  + ]:     415614 :             assert(vi.boxroot == NULL);
    7236   [ +  +  +  +  :     415614 :             if (specsig && !type_is_ghost(llvmArgType) && !is_uniquerep_Type(argType))
             +  +  +  + ]
    7237                 :          6 :                 ++AI;
    7238                 :            :         }
    7239                 :            :         else {
    7240         [ +  + ]:     745701 :             if (specsig) {
    7241                 :     706804 :                 theArg = get_specsig_arg(argType, llvmArgType, isboxed);
    7242                 :            :             }
    7243                 :            :             else {
    7244         [ +  + ]:      38897 :                 if (i == 0) {
    7245                 :            :                     // first (function) arg is separate in jlcall
    7246                 :        441 :                     theArg = mark_julia_type(ctx, fArg, true, ctx.is_opaque_closure ?
    7247         [ +  + ]:        441 :                         argType : vi.value.typ);
    7248                 :            :                 }
    7249                 :            :                 else {
    7250                 :      38456 :                     Value *argPtr = ctx.builder.CreateConstInBoundsGEP1_32(ctx.types().T_prjlvalue, argArray, i - 1);
    7251                 :      38456 :                     Value *load = tbaa_decorate(ctx.tbaa().tbaa_const, maybe_mark_load_dereferenceable(
    7252                 :      38456 :                             ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, argPtr, Align(sizeof(void*))),
    7253                 :            :                             false, vi.value.typ));
    7254                 :      38456 :                     theArg = mark_julia_type(ctx, load, true, vi.value.typ);
    7255   [ +  +  +  +  :      38456 :                     if (ctx.debug_enabled && vi.dinfo && !vi.boxroot && !vi.value.V) {
             +  -  +  - ]
    7256                 :      31867 :                         SmallVector<uint64_t, 8> addr;
    7257                 :      31867 :                         addr.push_back(llvm::dwarf::DW_OP_deref);
    7258                 :      31867 :                         addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
    7259                 :      31867 :                         addr.push_back((i - 1) * sizeof(void*));
    7260         [ +  + ]:      31867 :                         if ((Metadata*)vi.dinfo->getType() != debuginfo.jl_pvalue_dillvmt)
    7261                 :      24676 :                             addr.push_back(llvm::dwarf::DW_OP_deref);
    7262                 :      63734 :                         dbuilder.insertDeclare(pargArray, vi.dinfo, dbuilder.createExpression(addr),
    7263                 :            :                                         topdebugloc,
    7264                 :      31867 :                                         ctx.builder.GetInsertBlock());
    7265                 :            :                     }
    7266                 :            :                 }
    7267                 :            :             }
    7268                 :            : 
    7269                 :            :             // If this is an opaque closure, implicitly load the env and switch
    7270                 :            :             // the world age.
    7271   [ +  +  +  + ]:     745701 :             if (i == 0 && ctx.is_opaque_closure) {
    7272                 :            :                 // Load closure world
    7273                 :         31 :                 Value *argaddr = emit_bitcast(ctx, data_pointer(ctx, theArg), getInt8PtrTy(ctx.builder.getContext()));
    7274                 :         62 :                 Value *worldaddr = ctx.builder.CreateInBoundsGEP(
    7275                 :         31 :                         getInt8Ty(ctx.builder.getContext()), argaddr,
    7276                 :         31 :                         ConstantInt::get(getSizeTy(ctx.builder.getContext()), offsetof(jl_opaque_closure_t, world)));
    7277                 :            : 
    7278                 :            :                 jl_cgval_t closure_world = typed_load(ctx, worldaddr, NULL, (jl_value_t*)jl_long_type,
    7279                 :         31 :                     theArg.tbaa, nullptr, false, AtomicOrdering::NotAtomic, false, sizeof(size_t));
    7280                 :         31 :                 emit_unbox_store(ctx, closure_world, world_age_field, ctx.tbaa().tbaa_gcframe, sizeof(size_t));
    7281                 :            : 
    7282                 :            :                 // Load closure env
    7283                 :         62 :                 Value *envaddr = ctx.builder.CreateInBoundsGEP(
    7284                 :         31 :                         getInt8Ty(ctx.builder.getContext()), argaddr,
    7285                 :         31 :                         ConstantInt::get(getSizeTy(ctx.builder.getContext()), offsetof(jl_opaque_closure_t, captures)));
    7286                 :            : 
    7287                 :            :                 jl_cgval_t closure_env = typed_load(ctx, envaddr, NULL, (jl_value_t*)jl_any_type,
    7288                 :         31 :                     theArg.tbaa, nullptr, true, AtomicOrdering::NotAtomic, false, sizeof(void*));
    7289                 :         31 :                 theArg = convert_julia_type(ctx, closure_env, vi.value.typ);
    7290                 :            :             }
    7291                 :            : 
    7292         [ +  + ]:     745701 :             if (vi.boxroot == NULL) {
    7293         [ -  + ]:     526713 :                 assert(vi.value.V == NULL && "unexpected variable slot created for argument");
    7294                 :            :                 // keep track of original (possibly boxed) value to avoid re-boxing or moving
    7295                 :     526713 :                 vi.value = theArg;
    7296   [ +  +  +  +  :     526713 :                 if (specsig && theArg.V && ctx.debug_enabled && vi.dinfo) {
             +  +  +  + ]
    7297                 :     468093 :                     SmallVector<uint64_t, 8> addr;
    7298                 :            :                     Value *parg;
    7299         [ +  + ]:     468093 :                     if (theArg.ispointer()) {
    7300                 :     319617 :                         parg = theArg.V;
    7301         [ +  + ]:     319617 :                         if ((Metadata*)vi.dinfo->getType() != debuginfo.jl_pvalue_dillvmt)
    7302                 :     304943 :                             addr.push_back(llvm::dwarf::DW_OP_deref);
    7303                 :            :                     }
    7304                 :            :                     else {
    7305                 :     148476 :                         parg = ctx.builder.CreateAlloca(theArg.V->getType(), NULL, jl_symbol_name(s));
    7306                 :     148476 :                         ctx.builder.CreateStore(theArg.V, parg);
    7307                 :            :                     }
    7308                 :     936186 :                     dbuilder.insertDeclare(parg, vi.dinfo, dbuilder.createExpression(addr),
    7309                 :            :                                                 topdebugloc,
    7310                 :     468093 :                                                 ctx.builder.GetInsertBlock());
    7311                 :            :                 }
    7312                 :            :             }
    7313                 :            :             else {
    7314                 :     218988 :                 Value *argp = boxed(ctx, theArg);
    7315                 :     218988 :                 ctx.builder.CreateStore(argp, vi.boxroot);
    7316                 :            :             }
    7317                 :            :         }
    7318                 :            :     }
    7319                 :            : 
    7320                 :            :     // step 9. allocate rest argument
    7321                 :     364674 :     CallInst *restTuple = NULL;
    7322   [ +  +  +  + ]:     364674 :     if (va && ctx.vaSlot != -1) {
    7323                 :      35532 :         jl_varinfo_t &vi = ctx.slots[ctx.vaSlot];
    7324   [ +  +  +  + ]:      35532 :         if (vi.value.constant || !vi.used) {
    7325         [ -  + ]:       5152 :             assert(vi.boxroot == NULL);
    7326                 :            :         }
    7327         [ +  + ]:      30380 :         else if (specsig) {
    7328                 :      20252 :             ctx.nvargs = jl_nparams(lam->specTypes) - nreq;
    7329                 :      20252 :             jl_cgval_t *vargs = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * ctx.nvargs);
    7330         [ +  + ]:      57795 :             for (size_t i = nreq; i < jl_nparams(lam->specTypes); ++i) {
    7331                 :      37543 :                 jl_value_t *argType = jl_nth_slot_type(lam->specTypes, i);
    7332                 :      37543 :                 bool isboxed = deserves_argbox(argType);
    7333         [ +  + ]:      37543 :                 Type *llvmArgType = isboxed ?  ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, argType);
    7334                 :      37543 :                 vargs[i - nreq] = get_specsig_arg(argType, llvmArgType, isboxed);
    7335                 :            :             }
    7336         [ +  + ]:      20252 :             if (jl_is_concrete_type(vi.value.typ)) {
    7337                 :      18465 :                 jl_cgval_t tuple = emit_new_struct(ctx, vi.value.typ, ctx.nvargs, vargs);
    7338                 :      18465 :                 emit_varinfo_assign(ctx, vi, tuple);
    7339                 :            :             }
    7340                 :            :             else {
    7341                 :       1787 :                 restTuple = emit_jlcall(ctx, jltuple_func, Constant::getNullValue(ctx.types().T_prjlvalue),
    7342                 :       1787 :                     vargs, ctx.nvargs, julia_call);
    7343                 :       1787 :                 jl_cgval_t tuple = mark_julia_type(ctx, restTuple, true, vi.value.typ);
    7344                 :       1787 :                 emit_varinfo_assign(ctx, vi, tuple);
    7345                 :            :             }
    7346                 :            :         }
    7347                 :            :         else {
    7348                 :            :             // restarg = jl_f_tuple(NULL, &args[nreq], nargs - nreq)
    7349                 :      10128 :             Function *F = prepare_call(jltuple_func);
    7350                 :            :             restTuple =
    7351                 :      20256 :                 ctx.builder.CreateCall(F,
    7352                 :      10128 :                         { Constant::getNullValue(ctx.types().T_prjlvalue),
    7353                 :      20256 :                           ctx.builder.CreateInBoundsGEP(ctx.types().T_prjlvalue, argArray,
    7354                 :      10128 :                                   ConstantInt::get(getSizeTy(ctx.builder.getContext()), nreq - 1)),
    7355                 :      20256 :                           ctx.builder.CreateSub(argCount,
    7356                 :      10128 :                                   ConstantInt::get(getInt32Ty(ctx.builder.getContext()), nreq - 1)) });
    7357                 :      10128 :             restTuple->setAttributes(F->getAttributes());
    7358                 :      10128 :             ctx.builder.CreateStore(restTuple, vi.boxroot);
    7359                 :            :         }
    7360                 :            :     }
    7361                 :            : 
    7362                 :     364674 :     AttributeList attributes = AttributeList::get(ctx.builder.getContext(), AttributeSet::get(f->getContext(), FnAttrs), AttributeSet::get(f->getContext(), RetAttrs), attrs);
    7363                 :            :     // attributes should be a superset of f->getAttributes() based on how we constructed it, but we merge just in case it isn't
    7364                 :     364674 :     f->setAttributes(AttributeList::get(ctx.builder.getContext(), {attributes, f->getAttributes()}));
    7365                 :            : 
    7366                 :            :     // step 10. Compute properties for each statements
    7367                 :            :     //     This needs to be computed by iterating in the IR order
    7368                 :            :     //     instead of control flow order.
    7369                 :   51885000 :     auto in_user_mod = [] (jl_module_t *mod) {
    7370   [ +  +  +  + ]:   55084200 :         return (!jl_is_submodule(mod, jl_base_module) &&
    7371                 :   55084200 :                 !jl_is_submodule(mod, jl_core_module));
    7372                 :            :     };
    7373                 :   78312400 :     auto in_tracked_path = [] (StringRef file) {
    7374   [ +  +  +  + ]:   78312400 :         return jl_options.tracked_path != NULL && file.startswith(jl_options.tracked_path);
    7375                 :            :     };
    7376                 :     364674 :     bool mod_is_user_mod = in_user_mod(ctx.module);
    7377                 :     364674 :     bool mod_is_tracked = in_tracked_path(ctx.file);
    7378                 :            :     struct DebugLineTable {
    7379                 :            :         DebugLoc loc;
    7380                 :            :         StringRef file;
    7381                 :            :         ssize_t line;
    7382                 :            :         bool is_user_code;
    7383                 :            :         bool is_tracked; // falls within an explicitly set file or directory
    7384                 :            :         unsigned inlined_at;
    7385                 :     364674 :         bool operator ==(const DebugLineTable &other) const {
    7386   [ +  +  +  -  :     364674 :             return other.loc == loc && other.file == file && other.line == line && other.is_user_code == is_user_code && other.is_tracked == is_tracked && other.inlined_at == inlined_at;
          +  +  +  -  +  
                -  +  - ]
    7387                 :            :         }
    7388                 :            :     };
    7389                 :     729338 :     std::vector<DebugLineTable> linetable;
    7390                 :            :     { // populate the linetable data format
    7391         [ -  + ]:     364674 :         assert(jl_is_array(src->linetable));
    7392                 :     364674 :         size_t nlocs = jl_array_len(src->linetable);
    7393                 :     729348 :         std::map<std::tuple<StringRef, StringRef>, DISubprogram*> subprograms;
    7394                 :     364674 :         linetable.resize(nlocs + 1);
    7395                 :     364674 :         DebugLineTable &topinfo = linetable[0];
    7396                 :     364674 :         topinfo.file = ctx.file;
    7397                 :     364674 :         topinfo.line = toplineno;
    7398                 :     364674 :         topinfo.is_user_code = mod_is_user_mod;
    7399                 :     364674 :         topinfo.is_tracked = mod_is_tracked;
    7400                 :     364674 :         topinfo.inlined_at = 0;
    7401                 :     364674 :         topinfo.loc = topdebugloc;
    7402         [ +  + ]:   78312400 :         for (size_t i = 0; i < nlocs; i++) {
    7403                 :            :             // LineInfoNode(mod::Module, method::Any, file::Symbol, line::Int32, inlined_at::Int32)
    7404                 :   77947700 :             jl_value_t *locinfo = jl_array_ptr_ref(src->linetable, i);
    7405                 :   77947700 :             DebugLineTable &info = linetable[i + 1];
    7406         [ -  + ]:   77947700 :             assert(jl_typeis(locinfo, jl_lineinfonode_type));
    7407                 :   77947700 :             jl_module_t *module = (jl_module_t*)jl_fieldref_noalloc(locinfo, 0);
    7408                 :   77947700 :             jl_value_t *method = jl_fieldref_noalloc(locinfo, 1);
    7409                 :   77947700 :             jl_sym_t *filesym = (jl_sym_t*)jl_fieldref_noalloc(locinfo, 2);
    7410                 :   77947700 :             info.line = jl_unbox_int32(jl_fieldref(locinfo, 3));
    7411                 :   77947700 :             info.inlined_at = jl_unbox_int32(jl_fieldref(locinfo, 4));
    7412         [ -  + ]:   77947700 :             assert(info.inlined_at <= i);
    7413                 :   77947700 :             info.file = jl_symbol_name(filesym);
    7414         [ -  + ]:   77947700 :             if (info.file.empty())
    7415                 :          0 :                 info.file = "<missing>";
    7416         [ +  + ]:   77947700 :             if (module == ctx.module)
    7417                 :   26427400 :                 info.is_user_code = mod_is_user_mod;
    7418                 :            :             else
    7419                 :   51520300 :                 info.is_user_code = in_user_mod(module);
    7420                 :   77947700 :             info.is_tracked = in_tracked_path(info.file);
    7421         [ +  + ]:   77947700 :             if (ctx.debug_enabled) {
    7422                 :   77647500 :                 StringRef fname;
    7423         [ -  + ]:   77647500 :                 if (jl_is_method_instance(method))
    7424                 :          0 :                     method = ((jl_method_instance_t*)method)->def.value;
    7425         [ -  + ]:   77647500 :                 if (jl_is_method(method))
    7426                 :          0 :                     method = (jl_value_t*)((jl_method_t*)method)->name;
    7427         [ +  - ]:   77647500 :                 if (jl_is_symbol(method))
    7428                 :   77647500 :                     fname = jl_symbol_name((jl_sym_t*)method);
    7429         [ -  + ]:   77647500 :                 if (fname.empty())
    7430                 :          0 :                     fname = "macro expansion";
    7431   [ +  +  +  +  :   77647500 :                 if (info.inlined_at == 0 && info.file == ctx.file) { // if everything matches, emit a toplevel line number
                   +  + ]
    7432                 :    2445690 :                     info.loc = DILocation::get(ctx.builder.getContext(), info.line, 0, SP, NULL);
    7433                 :            :                 }
    7434                 :            :                 else { // otherwise, describe this as an inlining frame
    7435                 :   75201800 :                     DISubprogram *&inl_SP = subprograms[std::make_tuple(fname, info.file)];
    7436         [ +  + ]:   75201800 :                     if (inl_SP == NULL) {
    7437                 :    8965050 :                         DIFile *difile = dbuilder.createFile(info.file, ".");
    7438                 :   17930100 :                         inl_SP = dbuilder.createFunction(difile
    7439                 :   17930100 :                                                      ,std::string(fname) + ";" // Name
    7440                 :            :                                                      ,fname            // LinkageName
    7441                 :            :                                                      ,difile           // File
    7442                 :            :                                                      ,0                // LineNo
    7443                 :            :                                                      ,debuginfo.jl_di_func_null_sig // Ty
    7444                 :            :                                                      ,0                // ScopeLine
    7445                 :            :                                                      ,DINode::FlagZero // Flags
    7446                 :            :                                                      ,DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized // SPFlags
    7447                 :            :                                                      ,nullptr          // Template Parameters
    7448                 :            :                                                      ,nullptr          // Template Declaration
    7449                 :            :                                                      ,nullptr          // ThrownTypes
    7450                 :            :                                                      );
    7451                 :            :                     }
    7452         [ +  + ]:   75201800 :                     DebugLoc inl_loc = (info.inlined_at == 0) ? DebugLoc(DILocation::get(ctx.builder.getContext(), 0, 0, SP, NULL)) : linetable.at(info.inlined_at).loc;
    7453                 :   75201800 :                     info.loc = DILocation::get(ctx.builder.getContext(), info.line, 0, inl_SP, inl_loc);
    7454                 :            :                 }
    7455                 :            :             }
    7456                 :            :         }
    7457                 :            :     }
    7458                 :            : 
    7459                 :     729338 :     std::vector<MDNode*> aliasscopes;
    7460                 :     364674 :     MDNode* current_aliasscope = nullptr;
    7461                 :     729338 :     std::vector<Metadata*> scope_stack;
    7462                 :     729338 :     std::vector<MDNode*> scope_list_stack;
    7463                 :            :     {
    7464                 :     364674 :         size_t nstmts = jl_array_len(stmts);
    7465                 :     364674 :         aliasscopes.resize(nstmts + 1, nullptr);
    7466                 :     364674 :         MDBuilder mbuilder(ctx.builder.getContext());
    7467                 :     364674 :         MDNode *alias_domain = mbuilder.createAliasScopeDomain(ctx.name);
    7468         [ +  + ]:   41060900 :         for (i = 0; i < nstmts; i++) {
    7469                 :   40696200 :             jl_value_t *stmt = jl_array_ptr_ref(stmts, i);
    7470         [ +  + ]:   40696200 :             jl_expr_t *expr = jl_is_expr(stmt) ? (jl_expr_t*)stmt : nullptr;
    7471         [ +  + ]:   40696200 :             if (expr) {
    7472         [ +  + ]:   22199200 :                 if (expr->head == jl_aliasscope_sym) {
    7473                 :          1 :                     MDNode *scope = mbuilder.createAliasScope("aliasscope", alias_domain);
    7474                 :          1 :                     scope_stack.push_back(scope);
    7475                 :          1 :                     MDNode *scope_list = MDNode::get(ctx.builder.getContext(), ArrayRef<Metadata*>(scope_stack));
    7476                 :          1 :                     scope_list_stack.push_back(scope_list);
    7477                 :          1 :                     current_aliasscope = scope_list;
    7478         [ +  + ]:   22199200 :                 } else if (expr->head == jl_popaliasscope_sym) {
    7479                 :          1 :                     scope_stack.pop_back();
    7480                 :          1 :                     scope_list_stack.pop_back();
    7481         [ +  - ]:          1 :                     if (scope_list_stack.empty()) {
    7482                 :          1 :                         current_aliasscope = NULL;
    7483                 :            :                     } else {
    7484                 :          0 :                         current_aliasscope = scope_list_stack.back();
    7485                 :            :                     }
    7486                 :            :                 }
    7487                 :            :             }
    7488                 :   40696200 :             aliasscopes[i+1] = current_aliasscope;
    7489                 :            :         }
    7490                 :            :     }
    7491                 :            : 
    7492                 :     364674 :     Instruction &prologue_end = ctx.builder.GetInsertBlock()->back();
    7493                 :            : 
    7494                 :            : 
    7495                 :            :     // step 11. Do codegen in control flow order
    7496                 :     729338 :     std::vector<int> workstack;
    7497                 :     729338 :     std::map<int, BasicBlock*> BB;
    7498                 :     729338 :     std::map<size_t, BasicBlock*> come_from_bb;
    7499                 :     364674 :     int cursor = 0;
    7500                 :   41020700 :     auto find_next_stmt = [&] (int seq_next) {
    7501                 :            :         // new style ir is always in dominance order, but frontend IR might not be
    7502                 :            :         // `seq_next` is the next statement we want to emit
    7503                 :            :         // i.e. if it exists, it's the next one following control flow and
    7504                 :            :         // should be emitted into the current insert point.
    7505   [ +  +  +  - ]:   41020700 :         if (seq_next >= 0 && (unsigned)seq_next < stmtslen) {
    7506                 :   39705900 :             workstack.push_back(seq_next);
    7507                 :            :         }
    7508   [ +  +  -  +  :    1314750 :         else if (ctx.builder.GetInsertBlock() && !ctx.builder.GetInsertBlock()->getTerminator()) {
                   -  + ]
    7509                 :          0 :             CreateTrap(ctx.builder, false);
    7510                 :            :         }
    7511         [ +  + ]:   44174100 :         while (!workstack.empty()) {
    7512                 :   43809500 :             int item = workstack.back();
    7513                 :   43809500 :             workstack.pop_back();
    7514                 :   43809500 :             auto nextbb = BB.find(item + 1);
    7515         [ +  + ]:   43809500 :             if (nextbb == BB.end()) {
    7516                 :   41834900 :                 cursor = item;
    7517                 :   40656000 :                 return;
    7518                 :            :             }
    7519   [ +  +  +  -  :   15290100 :             if (seq_next != -1 && ctx.builder.GetInsertBlock() && !ctx.builder.GetInsertBlock()->getTerminator()) {
             +  +  +  + ]
    7520                 :     814247 :                 come_from_bb[cursor + 1] = ctx.builder.GetInsertBlock();
    7521                 :     814247 :                 ctx.builder.CreateBr(nextbb->second);
    7522                 :            :             }
    7523                 :   15290100 :             seq_next = -1;
    7524                 :            :             // if this BB is non-empty, we've visited it before so skip it
    7525         [ +  + ]:   15290100 :             if (!nextbb->second->getTerminator()) {
    7526                 :   12136700 :                 ctx.builder.SetInsertPoint(nextbb->second);
    7527                 :   12136700 :                 cursor = item;
    7528                 :   12136700 :                 return;
    7529                 :            :             }
    7530                 :            :         }
    7531                 :     364664 :         cursor = -1;
    7532                 :     364674 :     };
    7533                 :            : 
    7534                 :   44174500 :     auto do_coverage = [&] (bool in_user_code, bool is_tracked) {
    7535         [ +  + ]:   44171900 :         return (coverage_mode == JL_LOG_ALL ||
    7536   [ +  +  +  +  :   88346400 :                 (in_user_code && coverage_mode == JL_LOG_USER) ||
                   +  + ]
    7537         [ +  - ]:   44174500 :                 (is_tracked && coverage_mode == JL_LOG_PATH));
    7538                 :     364674 :     };
    7539                 :   66874300 :     auto do_malloc_log = [&] (bool in_user_code, bool is_tracked) {
    7540         [ +  + ]:   66874300 :         return (malloc_log_mode == JL_LOG_ALL ||
    7541   [ +  -  +  +  :  133749000 :                 (in_user_code && malloc_log_mode == JL_LOG_USER) ||
                   +  + ]
    7542         [ -  + ]:   66874500 :                 (is_tracked && malloc_log_mode == JL_LOG_PATH));
    7543                 :     364674 :     };
    7544                 :     729338 :     std::vector<unsigned> current_lineinfo, new_lineinfo;
    7545                 :   40023900 :     auto coverageVisitStmt = [&] (size_t dbg) {
    7546   [ +  -  -  +  :   40023900 :         if (dbg == 0 || dbg >= linetable.size())
                   -  + ]
    7547                 :          0 :             return;
    7548                 :            :         // Compute inlining stack for current line, inner frame first
    7549         [ +  + ]:  250744000 :         while (dbg) {
    7550                 :  210720000 :             new_lineinfo.push_back(dbg);
    7551                 :  210720000 :             dbg = linetable.at(dbg).inlined_at;
    7552                 :            :         }
    7553                 :            :         // Visit frames which differ from previous statement as tracked in
    7554                 :            :         // current_lineinfo (tracked outer frame first).
    7555                 :   40023900 :         current_lineinfo.resize(new_lineinfo.size(), 0);
    7556         [ +  + ]:  250744000 :         for (dbg = 0; dbg < new_lineinfo.size(); dbg++) {
    7557                 :  210720000 :             unsigned newdbg = new_lineinfo[new_lineinfo.size() - dbg - 1];
    7558         [ +  + ]:  210720000 :             if (newdbg != current_lineinfo[dbg]) {
    7559                 :   43799100 :                 current_lineinfo[dbg] = newdbg;
    7560                 :   43799100 :                 const auto &info = linetable.at(newdbg);
    7561         [ +  + ]:   43799100 :                 if (do_coverage(info.is_user_code, info.is_tracked))
    7562                 :       1189 :                     coverageVisitLine(ctx, info.file, info.line);
    7563                 :            :             }
    7564                 :            :         }
    7565                 :   40023900 :         new_lineinfo.clear();
    7566                 :     364674 :     };
    7567                 :   33254800 :     auto mallocVisitStmt = [&] (unsigned dbg, Value *sync) {
    7568   [ +  +  -  +  :   33254800 :         if (!do_malloc_log(mod_is_user_mod, mod_is_tracked) || dbg == 0) {
                   +  + ]
    7569   [ +  +  +  +  :   33254800 :             if (do_malloc_log(true, mod_is_tracked) && sync)
                   +  + ]
    7570                 :         34 :                 ctx.builder.CreateCall(prepare_call(sync_gc_total_bytes_func), {sync});
    7571                 :   33254800 :             return;
    7572                 :            :         }
    7573         [ +  + ]:         30 :         while (linetable.at(dbg).inlined_at)
    7574                 :         14 :             dbg = linetable.at(dbg).inlined_at;
    7575                 :         16 :         mallocVisitLine(ctx, ctx.file, linetable.at(dbg).line, sync);
    7576                 :     364674 :     };
    7577         [ +  + ]:     364674 :     if (coverage_mode != JL_LOG_NONE) {
    7578                 :            :         // record all lines that could be covered
    7579         [ +  + ]:      10851 :         for (const auto &info : linetable)
    7580         [ +  + ]:      10690 :             if (do_coverage(info.is_user_code, info.is_tracked))
    7581                 :       1518 :                 jl_coverage_alloc_line(info.file, info.line);
    7582                 :            :     }
    7583                 :            : 
    7584                 :     364674 :     come_from_bb[0] = ctx.builder.GetInsertBlock();
    7585                 :            : 
    7586                 :            :     // First go through and collect all branch targets, so we know where to
    7587                 :            :     // split basic blocks.
    7588                 :     729338 :     std::set<int> branch_targets; // 1-indexed
    7589                 :            :     {
    7590         [ +  + ]:   41060900 :         for (size_t i = 0; i < stmtslen; ++i) {
    7591                 :   40696200 :             jl_value_t *stmt = jl_array_ptr_ref(stmts, i);
    7592         [ +  + ]:   40696200 :             if (jl_is_gotoifnot(stmt)) {
    7593                 :    4068450 :                 int dest = jl_gotoifnot_label(stmt);
    7594                 :    4068450 :                 branch_targets.insert(dest);
    7595                 :            :                 // The next 1-indexed statement
    7596                 :    4068450 :                 branch_targets.insert(i + 2);
    7597         [ +  + ]:   36627800 :             } else if (jl_is_returnnode(stmt)) {
    7598                 :            :                 // We don't do dead branch elimination before codegen
    7599                 :            :                 // so we need to make sure to start a BB after any
    7600                 :            :                 // return node, even if they aren't otherwise branch
    7601                 :            :                 // targets.
    7602         [ +  + ]:    1322030 :                 if (i + 2 <= stmtslen)
    7603                 :     985178 :                     branch_targets.insert(i + 2);
    7604         [ +  + ]:   35305800 :             } else if (jl_is_expr(stmt)) {
    7605         [ +  + ]:   22199200 :                 if (((jl_expr_t*)stmt)->head == jl_enter_sym) {
    7606                 :      35082 :                     branch_targets.insert(i + 1);
    7607         [ +  - ]:      35082 :                     if (i + 2 <= stmtslen)
    7608                 :      35082 :                         branch_targets.insert(i + 2);
    7609                 :      35082 :                     int dest = jl_unbox_long(jl_array_ptr_ref(((jl_expr_t*)stmt)->args, 0));
    7610                 :      35082 :                     branch_targets.insert(dest);
    7611                 :            :                 }
    7612         [ +  + ]:   13106600 :             } else if (jl_is_gotonode(stmt)) {
    7613                 :    6303930 :                 int dest = jl_gotonode_label(stmt);
    7614                 :    6303930 :                 branch_targets.insert(dest);
    7615         [ +  + ]:    6303930 :                 if (i + 2 <= stmtslen)
    7616                 :    6302690 :                     branch_targets.insert(i + 2);
    7617         [ +  + ]:    6802640 :             } else if (jl_is_phinode(stmt)) {
    7618                 :    4041130 :                 jl_array_t *edges = (jl_array_t*)jl_fieldref_noalloc(stmt, 0);
    7619         [ +  + ]:   11294200 :                 for (size_t j = 0; j < jl_array_len(edges); ++j) {
    7620                 :    7253080 :                     size_t edge = ((int32_t*)jl_array_data(edges))[j];
    7621         [ +  + ]:    7253080 :                     if (edge == i)
    7622                 :    1651880 :                         branch_targets.insert(i + 1);
    7623                 :            :                 }
    7624                 :            :             }
    7625                 :            :         }
    7626                 :            :     }
    7627                 :            : 
    7628         [ +  + ]:   12535200 :     for (int label : branch_targets) {
    7629                 :   12170600 :         BasicBlock *bb = BasicBlock::Create(ctx.builder.getContext(),
    7630                 :   24341100 :             "L" + std::to_string(label), f);
    7631                 :   12170600 :         BB[label] = bb;
    7632                 :            :     }
    7633                 :            : 
    7634                 :     364674 :     Value *sync_bytes = nullptr;
    7635         [ +  + ]:     364674 :     if (do_malloc_log(true, mod_is_tracked))
    7636                 :         37 :         sync_bytes = ctx.builder.CreateCall(prepare_call(diff_gc_total_bytes_func), {});
    7637                 :            :     { // coverage for the function definition line number
    7638                 :     364674 :         const auto &topinfo = linetable.at(0);
    7639         [ +  - ]:     364674 :         if (linetable.size() > 1) {
    7640         [ +  + ]:     364674 :             if (topinfo == linetable.at(1))
    7641                 :     170000 :                 current_lineinfo.push_back(1);
    7642                 :            :         }
    7643         [ +  + ]:     364674 :         if (do_coverage(topinfo.is_user_code, topinfo.is_tracked))
    7644                 :         63 :             coverageVisitLine(ctx, topinfo.file, topinfo.line);
    7645                 :            :     }
    7646                 :            : 
    7647                 :     364674 :     find_next_stmt(0);
    7648         [ +  + ]:   41020700 :     while (cursor != -1) {
    7649                 :   40656000 :         int32_t debuginfoloc = ((int32_t*)jl_array_data(src->codelocs))[cursor];
    7650         [ +  + ]:   40656000 :         if (debuginfoloc > 0) {
    7651         [ +  + ]:   40023900 :             if (ctx.debug_enabled)
    7652                 :   39723200 :                 ctx.builder.SetCurrentDebugLocation(linetable.at(debuginfoloc).loc);
    7653                 :   40023900 :             coverageVisitStmt(debuginfoloc);
    7654                 :            :         }
    7655                 :   40656000 :         ctx.aliasscope = aliasscopes[cursor];
    7656                 :   40656000 :         jl_value_t *stmt = jl_array_ptr_ref(stmts, cursor);
    7657         [ +  + ]:   40656000 :         jl_expr_t *expr = jl_is_expr(stmt) ? (jl_expr_t*)stmt : nullptr;
    7658         [ +  + ]:   40656000 :         if (jl_is_returnnode(stmt)) {
    7659                 :    1314750 :             jl_value_t *retexpr = jl_returnnode_value(stmt);
    7660         [ +  + ]:    1314750 :             if (retexpr == NULL) {
    7661                 :     847829 :                 CreateTrap(ctx.builder, false);
    7662                 :     847829 :                 find_next_stmt(-1);
    7663                 :     847829 :                 continue;
    7664                 :            :             }
    7665                 :            :             // this is basically a copy of emit_assignment,
    7666                 :            :             // but where the assignment slot is the retval
    7667                 :     466919 :             jl_cgval_t retvalinfo = emit_expr(ctx, retexpr);
    7668                 :     466919 :             retvalinfo = convert_julia_type(ctx, retvalinfo, jlrettype);
    7669         [ +  + ]:     466919 :             if (retvalinfo.typ == jl_bottom_type) {
    7670                 :        164 :                 CreateTrap(ctx.builder, false);
    7671                 :        164 :                 find_next_stmt(-1);
    7672                 :        164 :                 continue;
    7673                 :            :             }
    7674                 :            : 
    7675                 :     466755 :             Value *isboxed_union = NULL;
    7676                 :     466755 :             Value *retval = NULL;
    7677         [ +  + ]:     466755 :             Value *sret = has_sret ? f->arg_begin() : NULL;
    7678                 :     466755 :             Type *retty = f->getReturnType();
    7679   [ +  +  +  +  :     466755 :             switch (returninfo.cc) {
                   +  - ]
    7680                 :     221835 :             case jl_returninfo_t::Boxed:
    7681                 :     221835 :                 retval = boxed(ctx, retvalinfo); // skip the gcroot on the return path
    7682                 :     221835 :                 break;
    7683                 :     161956 :             case jl_returninfo_t::Register:
    7684         [ +  + ]:     161956 :                 if (type_is_ghost(retty))
    7685                 :      34699 :                     retval = NULL;
    7686                 :            :                 else
    7687                 :     127257 :                     retval = emit_unbox(ctx, retty, retvalinfo, jlrettype);
    7688                 :     161956 :                 break;
    7689                 :      69935 :             case jl_returninfo_t::SRet:
    7690                 :      69935 :                 retval = NULL;
    7691                 :      69935 :                 break;
    7692                 :      12605 :             case jl_returninfo_t::Union: {
    7693                 :            :                 Value *data, *tindex;
    7694         [ +  + ]:      12605 :                 if (retvalinfo.TIndex) {
    7695                 :       9037 :                     tindex = retvalinfo.TIndex;
    7696                 :       9037 :                     data = Constant::getNullValue(ctx.types().T_prjlvalue);
    7697         [ +  + ]:       9037 :                     if (retvalinfo.V == NULL) {
    7698                 :            :                         // treat this as a simple Ghosts
    7699                 :       4244 :                         sret = NULL;
    7700                 :            :                     }
    7701         [ +  + ]:       4793 :                     else if (retvalinfo.Vboxed) {
    7702                 :            :                         // also need to account for the possibility the return object is boxed
    7703                 :            :                         // and avoid / skip copying it to the stack
    7704                 :       3984 :                         isboxed_union = ctx.builder.CreateICmpNE(
    7705                 :       1328 :                             ctx.builder.CreateAnd(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80)),
    7706                 :       1328 :                             ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0));
    7707                 :       1328 :                         data = ctx.builder.CreateSelect(isboxed_union, retvalinfo.Vboxed, data);
    7708                 :            :                     }
    7709                 :            :                 }
    7710                 :            :                 else {
    7711                 :            :                     // treat this as a simple boxed returninfo
    7712                 :            :                     //assert(retvalinfo.isboxed);
    7713                 :       3568 :                     tindex = compute_tindex_unboxed(ctx, retvalinfo, jlrettype);
    7714                 :       3568 :                     tindex = ctx.builder.CreateOr(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80));
    7715                 :       3568 :                     data = boxed(ctx, retvalinfo);
    7716                 :       3568 :                     sret = NULL;
    7717                 :            :                 }
    7718                 :      12605 :                 retval = UndefValue::get(retty);
    7719                 :      12605 :                 retval = ctx.builder.CreateInsertValue(retval, data, 0);
    7720                 :      12605 :                 retval = ctx.builder.CreateInsertValue(retval, tindex, 1);
    7721                 :      12605 :                 break;
    7722                 :            :             }
    7723                 :        424 :             case jl_returninfo_t::Ghosts:
    7724                 :        424 :                 retval = compute_tindex_unboxed(ctx, retvalinfo, jlrettype);
    7725                 :        424 :                 break;
    7726                 :            :             }
    7727         [ +  + ]:     466755 :             if (sret) {
    7728         [ +  + ]:      74728 :                 if (retvalinfo.ispointer()) {
    7729         [ +  + ]:      49438 :                     if (returninfo.return_roots) {
    7730                 :      16924 :                         Type *store_ty = julia_type_to_llvm(ctx, retvalinfo.typ);
    7731                 :      16924 :                         emit_sret_roots(ctx, true, data_pointer(ctx, retvalinfo), store_ty, f->arg_begin() + 1, get_returnroots_type(ctx, returninfo.return_roots), returninfo.return_roots);
    7732                 :            :                     }
    7733         [ +  + ]:      49438 :                     if (returninfo.cc == jl_returninfo_t::SRet) {
    7734         [ -  + ]:      44645 :                         assert(jl_is_concrete_type(jlrettype));
    7735                 :      44645 :                         emit_memcpy(ctx, sret, nullptr, retvalinfo, jl_datatype_size(jlrettype),
    7736                 :            :                                     julia_alignment(jlrettype));
    7737                 :            :                     }
    7738                 :            :                     else { // must be jl_returninfo_t::Union
    7739                 :       4793 :                         emit_unionmove(ctx, sret, nullptr, retvalinfo, /*skip*/isboxed_union);
    7740                 :            :                     }
    7741                 :            :                 }
    7742                 :            :                 else {
    7743                 :      25290 :                     Type *store_ty = retvalinfo.V->getType();
    7744                 :      25290 :                     Type *dest_ty = store_ty->getPointerTo();
    7745                 :      25290 :                     Value *Val = retvalinfo.V;
    7746         [ +  + ]:      25290 :                     if (returninfo.return_roots) {
    7747         [ -  + ]:      16459 :                         assert(julia_type_to_llvm(ctx, retvalinfo.typ) == store_ty);
    7748                 :      16459 :                         emit_sret_roots(ctx, false, Val, store_ty, f->arg_begin() + 1, get_returnroots_type(ctx, returninfo.return_roots), returninfo.return_roots);
    7749                 :            :                     }
    7750         [ -  + ]:      25290 :                     if (dest_ty != sret->getType())
    7751                 :          0 :                         sret = emit_bitcast(ctx, sret, dest_ty);
    7752                 :      25290 :                     ctx.builder.CreateAlignedStore(Val, sret, Align(julia_alignment(retvalinfo.typ)));
    7753         [ -  + ]:      25290 :                     assert(retvalinfo.TIndex == NULL && "unreachable"); // unimplemented representation
    7754                 :            :                 }
    7755                 :            :             }
    7756                 :            : 
    7757                 :     466755 :             mallocVisitStmt(debuginfoloc, sync_bytes);
    7758   [ +  +  +  + ]:     466755 :             if (toplevel || ctx.is_opaque_closure)
    7759                 :       1169 :                 ctx.builder.CreateStore(last_age, world_age_field);
    7760   [ +  +  +  -  :     466755 :             assert(type_is_ghost(retty) || returninfo.cc == jl_returninfo_t::SRet ||
                   -  + ]
    7761                 :            :                 retval->getType() == ctx.f->getReturnType());
    7762                 :     466755 :             ctx.builder.CreateRet(retval);
    7763                 :     466755 :             find_next_stmt(-1);
    7764                 :     466755 :             continue;
    7765                 :            :         }
    7766         [ +  + ]:   39341300 :         if (jl_is_gotonode(stmt)) {
    7767                 :    6303910 :             int lname = jl_gotonode_label(stmt);
    7768                 :    6303910 :             come_from_bb[cursor+1] = ctx.builder.GetInsertBlock();
    7769                 :    6303910 :             ctx.builder.CreateBr(BB[lname]);
    7770                 :    6303910 :             find_next_stmt(lname - 1);
    7771                 :    6303910 :             continue;
    7772                 :            :         }
    7773         [ +  + ]:   33037300 :         if (jl_is_upsilonnode(stmt)) {
    7774                 :     214166 :             emit_upsilonnode(ctx, upsilon_to_phic[cursor + 1], jl_fieldref_noalloc(stmt, 0));
    7775                 :     214166 :             find_next_stmt(cursor + 1);
    7776                 :     214166 :             continue;
    7777                 :            :         }
    7778         [ +  + ]:   32823200 :         if (jl_is_gotoifnot(stmt)) {
    7779                 :    4068450 :             jl_value_t *cond = jl_gotoifnot_cond(stmt);
    7780                 :    4068450 :             int lname = jl_gotoifnot_label(stmt);
    7781                 :    4068450 :             Value *isfalse = emit_condition(ctx, cond, "if");
    7782                 :    4068450 :             mallocVisitStmt(debuginfoloc, nullptr);
    7783                 :    4068450 :             come_from_bb[cursor+1] = ctx.builder.GetInsertBlock();
    7784                 :    4068450 :             workstack.push_back(lname - 1);
    7785                 :    4068450 :             BasicBlock *ifnot = BB[lname];
    7786                 :    4068450 :             BasicBlock *ifso = BB[cursor+2];
    7787         [ +  + ]:    4068450 :             if (ifnot == ifso)
    7788                 :          2 :                 ctx.builder.CreateBr(ifnot);
    7789                 :            :             else
    7790                 :    4068450 :                 ctx.builder.CreateCondBr(isfalse, ifnot, ifso);
    7791                 :    4068450 :             find_next_stmt(cursor + 1);
    7792                 :    4068450 :             continue;
    7793                 :            :         }
    7794   [ +  +  +  + ]:   28754700 :         else if (expr && expr->head == jl_enter_sym) {
    7795                 :      35082 :             jl_value_t **args = (jl_value_t**)jl_array_data(expr->args);
    7796                 :            : 
    7797         [ -  + ]:      35082 :             assert(jl_is_long(args[0]));
    7798                 :      35082 :             int lname = jl_unbox_long(args[0]);
    7799                 :            :             // Save exception stack depth at enter for use in pop_exception
    7800                 :            :             Value *excstack_state =
    7801                 :      35082 :                 ctx.builder.CreateCall(prepare_call(jl_excstack_state_func));
    7802         [ -  + ]:      35082 :             assert(!ctx.ssavalue_assigned.at(cursor));
    7803                 :      35082 :             ctx.SAvalues.at(cursor) = jl_cgval_t(excstack_state, (jl_value_t*)jl_ulong_type, NULL);
    7804                 :      35082 :             ctx.ssavalue_assigned.at(cursor) = true;
    7805                 :      35082 :             CallInst *sj = ctx.builder.CreateCall(prepare_call(except_enter_func));
    7806                 :            :             // We need to mark this on the call site as well. See issue #6757
    7807                 :      35082 :             sj->setCanReturnTwice();
    7808                 :      35082 :             Value *isz = ctx.builder.CreateICmpEQ(sj, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0));
    7809                 :      35082 :             BasicBlock *tryblk = BasicBlock::Create(ctx.builder.getContext(), "try", f);
    7810                 :      35082 :             BasicBlock *handlr = NULL;
    7811                 :      35082 :             handlr = BB[lname];
    7812                 :      35082 :             workstack.push_back(lname - 1);
    7813                 :      35082 :             come_from_bb[cursor + 1] = ctx.builder.GetInsertBlock();
    7814                 :      35082 :             ctx.builder.CreateCondBr(isz, tryblk, handlr);
    7815                 :      35082 :             ctx.builder.SetInsertPoint(tryblk);
    7816                 :            :         }
    7817                 :            :         else {
    7818   [ +  +  +  - ]:   28719700 :             if (!jl_is_method(ctx.linfo->def.method) && !ctx.is_opaque_closure) {
    7819                 :            :                 // TODO: inference is invalid if this has any effect (which it often does)
    7820                 :    2544330 :                 LoadInst *world = ctx.builder.CreateAlignedLoad(getSizeTy(ctx.builder.getContext()),
    7821                 :    1696220 :                     prepare_global_in(jl_Module, jlgetworld_global), Align(sizeof(size_t)));
    7822                 :     848110 :                 world->setOrdering(AtomicOrdering::Acquire);
    7823                 :     848110 :                 ctx.builder.CreateAlignedStore(world, world_age_field, Align(sizeof(size_t)));
    7824                 :            :             }
    7825                 :   28719700 :             emit_stmtpos(ctx, stmt, cursor);
    7826                 :   28719600 :             mallocVisitStmt(debuginfoloc, nullptr);
    7827                 :            :         }
    7828                 :   28754700 :         find_next_stmt(cursor + 1);
    7829                 :            :     }
    7830                 :            : 
    7831                 :            :     // Delete any unreachable blocks
    7832         [ +  + ]:   12535200 :     for (auto &item : BB) {
    7833         [ +  + ]:   12170600 :         if (!item.second->getTerminator())
    7834                 :      33872 :             item.second->eraseFromParent();
    7835                 :            :     }
    7836                 :            : 
    7837                 :     364664 :     ctx.builder.SetCurrentDebugLocation(noDbg);
    7838                 :     364664 :     ctx.builder.ClearInsertionPoint();
    7839                 :            : 
    7840                 :            :     // Codegen Phi nodes
    7841                 :     729328 :     std::map<std::pair<BasicBlock*, BasicBlock*>, BasicBlock*> BB_rewrite_map;
    7842                 :     729328 :     std::vector<llvm::PHINode*> ToDelete;
    7843         [ +  + ]:    4364550 :     for (auto &tup : ctx.PhiNodes) {
    7844                 :    3999890 :         jl_cgval_t phi_result;
    7845                 :            :         PHINode *VN;
    7846                 :            :         jl_value_t *r;
    7847                 :            :         AllocaInst *dest;
    7848                 :            :         BasicBlock *PhiBB;
    7849                 :    3999890 :         std::tie(phi_result, PhiBB, dest, VN, r) = tup;
    7850                 :    3999890 :         jl_value_t *phiType = phi_result.typ;
    7851                 :    3999890 :         jl_array_t *edges = (jl_array_t*)jl_fieldref_noalloc(r, 0);
    7852                 :    3999890 :         jl_array_t *values = (jl_array_t*)jl_fieldref_noalloc(r, 1);
    7853                 :    3999890 :         PHINode *TindexN = cast_or_null<PHINode>(phi_result.TIndex);
    7854                 :    3999890 :         DenseSet<BasicBlock*> preds;
    7855         [ +  + ]:   11181600 :         for (size_t i = 0; i < jl_array_len(edges); ++i) {
    7856                 :    7181680 :             size_t edge = ((int32_t*)jl_array_data(edges))[i];
    7857                 :    7181680 :             jl_value_t *value = jl_array_ptr_ref(values, i);
    7858                 :            :             // This edge value is undef, handle it the same as if the edge wasn't listed at all
    7859         [ +  + ]:    7181680 :             if (!value)
    7860                 :       2241 :                 continue;
    7861                 :    7179430 :             BasicBlock *FromBB = come_from_bb[edge];
    7862                 :            :             // This edge was statically unreachable. Don't codegen it.
    7863         [ -  + ]:    7179430 :             if (!FromBB)
    7864                 :          0 :                 continue;
    7865                 :            :             // see if this edge has already been rewritten
    7866                 :            :             // (we'll continue appending blocks to the current end)
    7867                 :    7179430 :             std::pair<BasicBlock*, BasicBlock*> LookupKey(FromBB, PhiBB);
    7868         [ +  + ]:    7179430 :             if (BB_rewrite_map.count(LookupKey)) {
    7869                 :     896714 :                 FromBB = BB_rewrite_map[LookupKey];
    7870                 :            :             }
    7871         [ -  + ]:    7179430 :             if (!preds.insert(FromBB).second) {
    7872                 :            :                 // Only codegen this branch once for each PHI (the expression must be the same on all branches)
    7873                 :            : #ifndef NDEBUG
    7874                 :            :                 for (size_t j = 0; j < i; ++j) {
    7875                 :            :                     size_t j_edge = ((int32_t*)jl_array_data(edges))[j];
    7876                 :            :                     if (j_edge == edge) {
    7877                 :            :                         assert(jl_egal(value, jl_array_ptr_ref(values, j)));
    7878                 :            :                     }
    7879                 :            :                 }
    7880                 :            : #endif
    7881                 :          0 :                 continue;
    7882                 :            :             }
    7883         [ -  + ]:    7179430 :             assert(std::find(pred_begin(PhiBB), pred_end(PhiBB), FromBB) != pred_end(PhiBB)); // consistency check
    7884                 :    7179430 :             TerminatorInst *terminator = FromBB->getTerminator();
    7885         [ +  + ]:    7179430 :             if (!terminator->getParent()->getUniqueSuccessor()) {
    7886                 :            :                 // Can't use `llvm::SplitCriticalEdge` here because
    7887                 :            :                 // we may have invalid phi nodes in the destination.
    7888                 :     359258 :                 BasicBlock *NewBB = BasicBlock::Create(terminator->getContext(),
    7889                 :     359258 :                    FromBB->getName() + "." + PhiBB->getName() + "_crit_edge");
    7890                 :     359258 :                 Function::iterator FBBI = FromBB->getIterator();
    7891                 :     359258 :                 ctx.f->getBasicBlockList().insert(++FBBI, NewBB); // insert after existing block
    7892                 :     359258 :                 terminator->replaceSuccessorWith(PhiBB, NewBB);
    7893                 :     718516 :                 DebugLoc Loc = terminator->getDebugLoc();
    7894                 :     359258 :                 terminator = BranchInst::Create(PhiBB);
    7895                 :     359258 :                 terminator->setDebugLoc(Loc);
    7896                 :     359258 :                 ctx.builder.SetInsertPoint(NewBB);
    7897                 :            :             }
    7898                 :            :             else {
    7899                 :    6820180 :                 terminator->removeFromParent();
    7900                 :    6820180 :                 ctx.builder.SetInsertPoint(FromBB);
    7901                 :            :             }
    7902         [ +  + ]:    7179430 :             if (dest)
    7903                 :     364510 :                 ctx.builder.CreateLifetimeStart(dest);
    7904                 :    7179430 :             jl_cgval_t val = emit_expr(ctx, value);
    7905         [ +  + ]:    7179430 :             if (val.constant)
    7906                 :    2634720 :                 val = mark_julia_const(ctx, val.constant); // be over-conservative at making sure `.typ` is set concretely, not tindex
    7907   [ +  +  +  + ]:    7179430 :             if (!jl_is_uniontype(phiType) || !TindexN) {
    7908         [ +  + ]:    7125870 :                 if (VN) {
    7909                 :            :                     Value *V;
    7910         [ +  + ]:    6811950 :                     if (val.typ == (jl_value_t*)jl_bottom_type) {
    7911                 :       4192 :                         V = undef_value_for_type(VN->getType());
    7912                 :            :                     }
    7913         [ +  + ]:    6807760 :                     else if (VN->getType() == ctx.types().T_prjlvalue) {
    7914                 :            :                         // Includes the jl_is_uniontype(phiType) && !TindexN case
    7915                 :            :                         // TODO: if convert_julia_type says it is wasted effort and to skip it, is it worth using Constant::getNullValue(ctx.types().T_prjlvalue) (dynamically)?
    7916                 :     781357 :                         V = boxed(ctx, val);
    7917                 :            :                     }
    7918                 :            :                     else {
    7919                 :            :                         // must be careful to emit undef here (rather than a bitcast or
    7920                 :            :                         // load of val) if the runtime type of val isn't phiType
    7921                 :    6026400 :                         Value *isvalid = emit_isa_and_defined(ctx, val, phiType);
    7922                 :    6026400 :                         V = emit_guarded_test(ctx, isvalid, undef_value_for_type(VN->getType()), [&] {
    7923                 :    6026400 :                             return emit_unbox(ctx, VN->getType(), val, phiType);
    7924                 :            :                         });
    7925                 :            :                     }
    7926                 :    6811950 :                     VN->addIncoming(V, ctx.builder.GetInsertBlock());
    7927         [ -  + ]:    6811950 :                     assert(!TindexN);
    7928                 :            :                 }
    7929   [ +  -  +  + ]:     313918 :                 else if (dest && val.typ != (jl_value_t*)jl_bottom_type) {
    7930                 :            :                     // must be careful to emit undef here (rather than a bitcast or
    7931                 :            :                     // load of val) if the runtime type of val isn't phiType
    7932                 :     311299 :                     Value *isvalid = emit_isa_and_defined(ctx, val, phiType);
    7933                 :     311299 :                     emit_guarded_test(ctx, isvalid, nullptr, [&] {
    7934                 :     311299 :                         emit_unbox_store(ctx, update_julia_type(ctx, val, phiType), dest, ctx.tbaa().tbaa_stack, julia_alignment(phiType));
    7935                 :     311299 :                         return nullptr;
    7936                 :            :                     });
    7937                 :    7125870 :                 }
    7938                 :            :             }
    7939                 :            :             else {
    7940                 :            :                 Value *RTindex;
    7941                 :            :                 // The branch below is a bit too complex for GCC to realize that
    7942                 :            :                 // `V` is always initialized when it is used.
    7943                 :            :                 // Ref https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96629
    7944                 :      53568 :                 Value *V = nullptr;
    7945         [ +  + ]:      53568 :                 if (val.typ == (jl_value_t*)jl_bottom_type) {
    7946         [ +  + ]:         45 :                     if (VN)
    7947                 :         43 :                         V = undef_value_for_type(VN->getType());
    7948                 :         45 :                     RTindex = UndefValue::get(getInt8Ty(ctx.builder.getContext()));
    7949                 :            :                 }
    7950   [ +  +  -  +  :      53523 :                 else if (jl_is_concrete_type(val.typ) || val.constant) {
                   +  + ]
    7951                 :      37287 :                     size_t tindex = get_box_tindex((jl_datatype_t*)val.typ, phiType);
    7952         [ +  + ]:      37287 :                     if (tindex == 0) {
    7953         [ +  - ]:       1988 :                         if (VN)
    7954                 :       1988 :                             V = boxed(ctx, val);
    7955                 :       1988 :                         RTindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80);
    7956                 :            :                     }
    7957                 :            :                     else {
    7958         [ +  + ]:      35299 :                         if (VN)
    7959                 :      33063 :                             V = Constant::getNullValue(ctx.types().T_prjlvalue);
    7960         [ +  + ]:      35299 :                         if (dest)
    7961                 :      33063 :                             emit_unbox_store(ctx, val, dest, ctx.tbaa().tbaa_stack, julia_alignment(val.typ));
    7962                 :      35299 :                         RTindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), tindex);
    7963                 :            :                     }
    7964                 :            :                 }
    7965                 :            :                 else {
    7966                 :      16236 :                     Value *skip = NULL;
    7967                 :            :                     // must compute skip here, since the runtime type of val might not be in phiType
    7968                 :            :                     // caution: only Phi and PhiC are allowed to do this (and maybe sometimes Pi)
    7969                 :      16236 :                     jl_cgval_t new_union = convert_julia_type(ctx, val, phiType, &skip);
    7970                 :      16236 :                     RTindex = new_union.TIndex;
    7971         [ +  + ]:      16236 :                     if (!RTindex) {
    7972   [ +  -  +  - ]:       2333 :                         assert(new_union.isboxed && new_union.Vboxed && "convert_julia_type failed");
    7973                 :       2333 :                         RTindex = compute_tindex_unboxed(ctx, new_union, phiType, true);
    7974         [ +  + ]:       2333 :                         if (dest) {
    7975                 :            :                             // If dest is not set, this is a ghost union, the recipient of which
    7976                 :            :                             // is often not prepared to handle a boxed representation of the ghost.
    7977                 :       2286 :                             RTindex = ctx.builder.CreateOr(RTindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80));
    7978                 :            :                         }
    7979                 :       2333 :                         new_union.TIndex = RTindex;
    7980                 :            :                     }
    7981         [ +  + ]:      16236 :                     if (VN)
    7982         [ +  + ]:      15498 :                         V = new_union.Vboxed ? new_union.Vboxed : Constant::getNullValue(ctx.types().T_prjlvalue);
    7983         [ +  + ]:      16236 :                     if (dest) { // basically, if !ghost union
    7984         [ +  + ]:      15498 :                         if (new_union.Vboxed != nullptr) {
    7985                 :      43761 :                             Value *isboxed = ctx.builder.CreateICmpNE( // if 0x80 is set, we won't select this slot anyways
    7986                 :      14587 :                                     ctx.builder.CreateAnd(RTindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80)),
    7987                 :      14587 :                                     ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0));
    7988         [ +  + ]:      14587 :                             skip = skip ? ctx.builder.CreateOr(isboxed, skip) : isboxed;
    7989                 :            :                         }
    7990                 :      15498 :                         emit_unionmove(ctx, dest, ctx.tbaa().tbaa_arraybuf, new_union, skip);
    7991                 :            :                     }
    7992                 :            :                 }
    7993         [ +  + ]:      53568 :                 if (VN)
    7994                 :      50592 :                     VN->addIncoming(V, ctx.builder.GetInsertBlock());
    7995         [ +  - ]:      53568 :                 if (TindexN)
    7996                 :      53568 :                     TindexN->addIncoming(RTindex, ctx.builder.GetInsertBlock());
    7997                 :            :             }
    7998                 :            :             // put the branch back at the end of our current basic block
    7999                 :    7179430 :             ctx.builder.Insert(terminator);
    8000                 :            :             // Record the current tail of this Phi edge in the rewrite map and
    8001                 :            :             // check any phi nodes in the Phi block to see if by emitting on the edges
    8002                 :            :             // we made things inconsistent.
    8003                 :    7179430 :             BasicBlock *NewBB = ctx.builder.GetInsertBlock();
    8004         [ +  + ]:    7179430 :             if (FromBB != NewBB) {
    8005                 :     793235 :                 BB_rewrite_map[LookupKey] = NewBB;
    8006                 :     793235 :                 preds.insert(NewBB);
    8007                 :     793235 :                 PhiBB->replacePhiUsesWith(FromBB, NewBB);
    8008                 :            :             }
    8009                 :    7179430 :             ctx.builder.ClearInsertionPoint();
    8010                 :            :         }
    8011                 :            :         // In LLVM IR it is illegal to have phi nodes without incoming values, even if
    8012                 :            :         // there are no operands (no incoming branches), so delete any such phi nodes
    8013         [ -  + ]:    3999890 :         if (pred_empty(PhiBB)) {
    8014         [ #  # ]:          0 :             if (VN)
    8015                 :          0 :                 ToDelete.push_back(VN);
    8016         [ #  # ]:          0 :             if (TindexN)
    8017                 :          0 :                 ToDelete.push_back(TindexN);
    8018                 :          0 :             continue;
    8019                 :            :         }
    8020                 :            :         // Julia PHINodes may be incomplete with respect to predecessors, LLVM's may not
    8021         [ +  + ]:   12461000 :         for (auto *FromBB : predecessors(PhiBB)) {
    8022         [ +  + ]:    8461150 :             if (preds.count(FromBB))
    8023                 :    7179430 :                 continue;
    8024                 :    1281720 :             ctx.builder.SetInsertPoint(FromBB->getTerminator());
    8025                 :            :             // PHI is undef on this branch. But still may need to put a valid pointer in place.
    8026         [ +  + ]:    1281720 :             Value *RTindex = TindexN ? UndefValue::get(getInt8Ty(ctx.builder.getContext())) : NULL;
    8027         [ +  + ]:    1281720 :             if (VN) {
    8028                 :    1189110 :                 Value *undef = undef_value_for_type(VN->getType());
    8029                 :    1189110 :                 VN->addIncoming(undef, FromBB);
    8030         [ +  + ]:    1189110 :                 if (TindexN) // let the runtime / optimizer know this is unknown / boxed / null, so that it won't try to union_move / copy it later
    8031                 :       3280 :                     RTindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80);
    8032                 :            :             }
    8033         [ +  + ]:    1281720 :             if (TindexN)
    8034                 :       3499 :                 TindexN->addIncoming(RTindex, FromBB);
    8035         [ +  + ]:    1281720 :             if (dest) {
    8036                 :      95667 :                 ctx.builder.CreateLifetimeStart(dest);
    8037         [ -  + ]:      95667 :                 if (CountTrackedPointers(dest->getAllocatedType()).count)
    8038                 :          0 :                     ctx.builder.CreateStore(Constant::getNullValue(dest->getAllocatedType()), dest);
    8039                 :            :             }
    8040                 :    1281720 :             ctx.builder.ClearInsertionPoint();
    8041                 :            :         }
    8042                 :            :     }
    8043                 :            : 
    8044         [ -  + ]:     364664 :     for (PHINode *PN : ToDelete) {
    8045                 :          0 :         PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
    8046                 :          0 :         PN->eraseFromParent();
    8047                 :            :     }
    8048                 :            : 
    8049                 :            :     // step 12. Perform any delayed instantiations
    8050         [ +  + ]:     364664 :     if (ctx.debug_enabled) {
    8051                 :     357490 :         bool in_prologue = true;
    8052         [ +  + ]:   19014800 :         for (auto &BB : *ctx.f) {
    8053         [ +  + ]:  134353000 :             for (auto &I : BB) {
    8054                 :  115696000 :                 CallBase *call = dyn_cast<CallBase>(&I);
    8055   [ +  +  +  +  :  115696000 :                 if (call && !I.getDebugLoc()) {
                   +  + ]
    8056                 :            :                     // LLVM Verifier: inlinable function call in a function with debug info must have a !dbg location
    8057                 :            :                     // make sure that anything we attempt to call has some inlining info, just in case optimization messed up
    8058                 :            :                     // (except if we know that it is an intrinsic used in our prologue, which should never have its own debug subprogram)
    8059                 :     574234 :                     Function *F = call->getCalledFunction();
    8060   [ +  +  +  -  :     574234 :                     if (!in_prologue || !F || !(F->isIntrinsic() || F->getName().startswith("julia.") || &I == restTuple)) {
          +  +  +  +  +  
                +  +  + ]
    8061                 :     194214 :                         I.setDebugLoc(topdebugloc);
    8062                 :            :                     }
    8063                 :            :                 }
    8064         [ +  + ]:  115696000 :                 if (&I == &prologue_end)
    8065                 :     357490 :                     in_prologue = false;
    8066                 :            :             }
    8067                 :            :         }
    8068                 :     357490 :         dbuilder.finalize();
    8069                 :            :     }
    8070                 :            : 
    8071         [ +  + ]:     364664 :     if (ctx.vaSlot > 0) {
    8072                 :            :         // remove VA allocation if we never referenced it
    8073                 :      35522 :         Instruction *root = cast_or_null<Instruction>(ctx.slots[ctx.vaSlot].boxroot);
    8074         [ +  + ]:      35522 :         if (root) {
    8075                 :      11915 :             Instruction *store_value = NULL;
    8076                 :      11915 :             bool have_real_use = false;
    8077         [ +  + ]:      34166 :             for (Use &U : root->uses()) {
    8078                 :      29938 :                 User *RU = U.getUser();
    8079         [ +  + ]:      29938 :                 if (StoreInst *SRU = dyn_cast<StoreInst>(RU)) {
    8080         [ +  + ]:       8456 :                     if (!store_value)
    8081                 :       4228 :                         store_value = dyn_cast<Instruction>(SRU->getValueOperand());
    8082                 :            :                 }
    8083         [ +  - ]:      21482 :                 else if (isa<DbgInfoIntrinsic>(RU)) {
    8084                 :            :                 }
    8085   [ +  -  +  +  :      21482 :                 else if (isa<LoadInst>(RU) && RU->use_empty()) {
                   +  + ]
    8086                 :            :                 }
    8087                 :            :                 else {
    8088                 :       7687 :                     have_real_use = true;
    8089                 :       7687 :                     break;
    8090                 :            :                 }
    8091                 :            :             }
    8092         [ +  + ]:      11915 :             if (!have_real_use) {
    8093                 :       4228 :                 Instruction *use = NULL;
    8094         [ +  + ]:      25716 :                 for (Use &U : root->uses()) {
    8095         [ +  + ]:      21488 :                     if (use) // erase after the iterator moves on
    8096                 :      17260 :                         use->eraseFromParent();
    8097                 :      21488 :                     User *RU = U.getUser();
    8098                 :      21488 :                     use = cast<Instruction>(RU);
    8099                 :            :                 }
    8100         [ +  - ]:       4228 :                 if (use)
    8101                 :       4228 :                     use->eraseFromParent();
    8102                 :       4228 :                 root->eraseFromParent();
    8103   [ +  -  -  + ]:       4228 :                 assert(!store_value || store_value == restTuple);
    8104                 :       4228 :                 restTuple->eraseFromParent();
    8105                 :            :             }
    8106                 :            :         }
    8107                 :            :     }
    8108                 :            : 
    8109                 :            :     // copy ctx.roots into m->roots
    8110                 :            :     // if we created any new roots during codegen
    8111         [ +  + ]:     364664 :     if (ctx.roots) {
    8112                 :     294273 :         jl_method_t *m = lam->def.method;
    8113                 :     294273 :         JL_LOCK(&m->writelock);
    8114         [ +  + ]:     294273 :         if (m->roots == NULL) {
    8115                 :         22 :             m->roots = ctx.roots;
    8116                 :         22 :             jl_gc_wb(m, m->roots);
    8117                 :            :         }
    8118                 :            :         else {
    8119                 :     294251 :             size_t i, ilen = jl_array_dim0(ctx.roots);
    8120                 :     294251 :             size_t j, jlen = jl_array_dim0(m->roots);
    8121         [ +  + ]:    2061860 :             for (i = 0; i < ilen; i++) {
    8122                 :    1767610 :                 jl_value_t *ival = jl_array_ptr_ref(ctx.roots, i);
    8123         [ +  + ]:  274432000 :                 for (j = 0; j < jlen; j++) {
    8124                 :  274290000 :                     jl_value_t *jval = jl_array_ptr_ref(m->roots, j);
    8125         [ +  + ]:  274290000 :                     if (ival == jval)
    8126                 :    1626410 :                         break;
    8127                 :            :                 }
    8128         [ +  + ]:    1767610 :                 if (j == jlen) // not found - add to array
    8129                 :     141203 :                     jl_add_method_root(m, jl_precompile_toplevel_module, ival);
    8130                 :            :             }
    8131                 :            :         }
    8132                 :     294273 :         ctx.roots = NULL;
    8133                 :     294273 :         JL_UNLOCK(&m->writelock);
    8134                 :            :     }
    8135                 :            : 
    8136                 :            :     // link the dependent llvmcall modules, but switch their function's linkage to internal
    8137                 :            :     // so that they don't conflict when they show up in the execution engine.
    8138         [ +  + ]:     366931 :     for (auto &TSMod : ctx.llvmcall_modules) {
    8139                 :       4534 :         SmallVector<std::string, 1> Exports;
    8140                 :       2267 :         TSMod.withModuleDo([&](Module &Mod) {
    8141         [ +  + ]:       4545 :             for (const auto &F: Mod.functions())
    8142         [ +  + ]:       2278 :                 if (!F.isDeclaration())
    8143                 :       2267 :                     Exports.push_back(F.getName().str());
    8144                 :       2267 :         });
    8145                 :       2267 :         jl_merge_module(TSM, std::move(TSMod));
    8146         [ +  + ]:       4534 :         for (auto FN: Exports)
    8147                 :       2267 :             jl_Module->getFunction(FN)->setLinkage(GlobalVariable::InternalLinkage);
    8148                 :            :     }
    8149                 :            : 
    8150                 :            :     // link in opaque closure modules
    8151         [ +  + ]:     364673 :     for (auto &TSMod : ctx.oc_modules) {
    8152                 :         18 :         SmallVector<std::string, 1> Exports;
    8153                 :          9 :         TSMod.withModuleDo([&](Module &Mod) {
    8154         [ +  + ]:         59 :             for (const auto &F: Mod.functions())
    8155         [ +  + ]:         50 :                 if (!F.isDeclaration())
    8156                 :         18 :                     Exports.push_back(F.getName().str());
    8157                 :          9 :         });
    8158                 :          9 :         jl_merge_module(TSM, std::move(TSMod));
    8159         [ +  + ]:         27 :         for (auto FN: Exports)
    8160                 :         18 :             jl_Module->getFunction(FN)->setLinkage(GlobalVariable::InternalLinkage);
    8161                 :            :     }
    8162                 :            : 
    8163                 :     364664 :     JL_GC_POP();
    8164                 :     364664 :     return declarations;
    8165                 :            : }
    8166                 :            : 
    8167                 :            : // --- entry point ---
    8168                 :            : 
    8169                 :            : void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL);
    8170                 :            : 
    8171                 :            : JL_GCC_IGNORE_START("-Wclobbered")
    8172                 :     364665 : jl_llvm_functions_t jl_emit_code(
    8173                 :            :         orc::ThreadSafeModule &m,
    8174                 :            :         jl_method_instance_t *li,
    8175                 :            :         jl_code_info_t *src,
    8176                 :            :         jl_value_t *jlrettype,
    8177                 :            :         jl_codegen_params_t &params)
    8178                 :            : {
    8179                 :            :     JL_TIMING(CODEGEN);
    8180                 :            :     // caller must hold codegen_lock
    8181                 :     364665 :     jl_llvm_functions_t decls = {};
    8182   [ +  +  -  +  :     364665 :     assert((params.params == &jl_default_cgparams /* fast path */ || !params.cache ||
                   -  - ]
    8183                 :            :         compare_cgparams(params.params, &jl_default_cgparams)) &&
    8184                 :            :         "functions compiled with custom codegen params must not be cached");
    8185   [ +  -  +  + ]:     729320 :     JL_TRY {
    8186                 :     364665 :         decls = emit_function(m, li, src, jlrettype, params);
    8187                 :     729310 :         auto stream = *jl_ExecutionEngine->get_dump_emitted_mi_name_stream();
    8188         [ +  + ]:     364655 :         if (stream) {
    8189                 :          1 :             jl_printf(stream, "%s\t", decls.specFunctionObject.c_str());
    8190                 :            :             // NOTE: We print the Type Tuple without surrounding quotes, because the quotes
    8191                 :            :             // break CSV parsing if there are any internal quotes in the Type name (e.g. in
    8192                 :            :             // Symbol("...")). The \t delineator should be enough to ensure whitespace is
    8193                 :            :             // handled correctly. (And we don't need to worry about any tabs in the printed
    8194                 :            :             // string, because tabs are printed as "\t" by `show`.)
    8195                 :          1 :             jl_static_show(stream, li->specTypes);
    8196                 :          1 :             jl_printf(stream, "\n");
    8197                 :            :         }
    8198                 :            :     }
    8199         [ #  # ]:          0 :     JL_CATCH {
    8200                 :            :         // Something failed! This is very, very bad.
    8201                 :            :         // Try to pretend that it isn't and attempt to recover.
    8202                 :          0 :         const char *mname = m.getModuleUnlocked()->getModuleIdentifier().data();
    8203                 :          0 :         m = orc::ThreadSafeModule();
    8204                 :          0 :         decls.functionObject = "";
    8205                 :          0 :         decls.specFunctionObject = "";
    8206                 :          0 :         jl_printf((JL_STREAM*)STDERR_FILENO, "Internal error: encountered unexpected error during compilation of %s:\n", mname);
    8207                 :          0 :         jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception());
    8208                 :          0 :         jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
    8209                 :          0 :         jlbacktrace(); // written to STDERR_FILENO
    8210                 :            :     }
    8211                 :            : 
    8212                 :     364655 :     return decls;
    8213                 :            : }
    8214                 :            : 
    8215                 :     337552 : jl_llvm_functions_t jl_emit_codeinst(
    8216                 :            :         orc::ThreadSafeModule &m,
    8217                 :            :         jl_code_instance_t *codeinst,
    8218                 :            :         jl_code_info_t *src,
    8219                 :            :         jl_codegen_params_t &params)
    8220                 :            : {
    8221                 :            :     JL_TIMING(CODEGEN);
    8222                 :     337552 :     JL_GC_PUSH1(&src);
    8223         [ +  + ]:     337552 :     if (!src) {
    8224                 :     149232 :         src = (jl_code_info_t*)codeinst->inferred;
    8225                 :     149232 :         jl_method_t *def = codeinst->def->def.method;
    8226   [ +  -  +  +  :     149232 :         if (src && (jl_value_t*)src != jl_nothing && jl_is_method(def))
                   +  - ]
    8227                 :     149041 :             src = jl_uncompress_ir(def, codeinst, (jl_array_t*)src);
    8228   [ +  -  +  + ]:     149232 :         if (!src || !jl_is_code_info(src)) {
    8229                 :        191 :             JL_GC_POP();
    8230                 :        191 :             m = orc::ThreadSafeModule();
    8231                 :        191 :             return jl_llvm_functions_t(); // failed
    8232                 :            :         }
    8233                 :            :     }
    8234                 :     674712 :     jl_llvm_functions_t decls = jl_emit_code(m, codeinst->def, src, codeinst->rettype, params);
    8235                 :            : 
    8236                 :     337351 :     const std::string &specf = decls.specFunctionObject;
    8237                 :     337351 :     const std::string &f = decls.functionObject;
    8238   [ +  +  +  -  :     337351 :     if (params.cache && !f.empty()) {
                   +  + ]
    8239                 :            :         // Prepare debug info to receive this function
    8240                 :            :         // record that this function name came from this linfo,
    8241                 :            :         // so we can build a reverse mapping for debug-info.
    8242                 :     337216 :         bool toplevel = !jl_is_method(codeinst->def->def.method);
    8243         [ +  + ]:     337216 :         if (!toplevel) {
    8244                 :            :             //Safe b/c params holds context lock
    8245                 :     336105 :             const DataLayout &DL = m.getModuleUnlocked()->getDataLayout();
    8246                 :            :             // but don't remember toplevel thunks because
    8247                 :            :             // they may not be rooted in the gc for the life of the program,
    8248                 :            :             // and the runtime doesn't notify us when the code becomes unreachable :(
    8249         [ +  - ]:     336105 :             if (!specf.empty())
    8250                 :     336105 :                 jl_add_code_in_flight(specf, codeinst, DL);
    8251   [ +  -  +  +  :     336105 :             if (!f.empty() && f != "jl_fptr_args" && f != "jl_fptr_sparam")
             +  +  +  + ]
    8252                 :     317975 :                 jl_add_code_in_flight(f, codeinst, DL);
    8253                 :            :         }
    8254                 :            : 
    8255                 :     337216 :         if (// don't alter `inferred` when the code is not directly being used
    8256         [ +  - ]:     337216 :             params.world &&
    8257                 :            :             // don't change inferred state
    8258         [ +  + ]:     337216 :             codeinst->inferred) {
    8259                 :     334078 :             jl_method_t *def = codeinst->def->def.method;
    8260                 :     334078 :             if (// keep code when keeping everything
    8261                 :            :                 !(JL_DELETE_NON_INLINEABLE) ||
    8262                 :            :                 // aggressively keep code when debugging level >= 2
    8263         [ +  + ]:     334078 :                 jl_options.debug_level > 1) {
    8264                 :            :                 // update the stored code
    8265         [ +  + ]:     327480 :                 if (codeinst->inferred != (jl_value_t*)src) {
    8266         [ +  - ]:     326488 :                     if (jl_is_method(def)) {
    8267                 :     326488 :                         src = (jl_code_info_t*)jl_compress_ir(def, src);
    8268         [ -  + ]:     326488 :                         assert(jl_typeis(src, jl_array_uint8_type));
    8269                 :     326488 :                         codeinst->relocatability = ((uint8_t*)jl_array_data(src))[jl_array_len(src)-1];
    8270                 :            :                     }
    8271                 :     326488 :                     codeinst->inferred = (jl_value_t*)src;
    8272                 :     326488 :                     jl_gc_wb(codeinst, src);
    8273                 :            :                 }
    8274                 :            :             }
    8275                 :       6598 :             else if (// don't delete toplevel code
    8276                 :      13168 :                      jl_is_method(def) &&
    8277                 :            :                      // and there is something to delete (test this before calling jl_ir_flag_inlineable)
    8278         [ +  + ]:       6570 :                      codeinst->inferred != jl_nothing &&
    8279                 :            :                      // don't delete inlineable code, unless it is constant
    8280   [ +  +  +  -  :      16318 :                      (codeinst->invoke == jl_fptr_const_return_addr || !jl_ir_flag_inlineable((jl_array_t*)codeinst->inferred)) &&
             +  +  +  + ]
    8281                 :            :                      // don't delete code when generating a precompile file
    8282   [ +  +  +  - ]:       3150 :                      !(params.imaging || jl_options.incremental)) {
    8283                 :            :                 // if not inlineable, code won't be needed again
    8284                 :         46 :                 codeinst->inferred = jl_nothing;
    8285                 :            :             }
    8286                 :            :         }
    8287                 :            :     }
    8288                 :     337351 :     JL_GC_POP();
    8289                 :     337351 :     return decls;
    8290                 :            : }
    8291                 :            : 
    8292                 :            : 
    8293                 :     188316 : void jl_compile_workqueue(
    8294                 :            :     jl_workqueue_t &emitted,
    8295                 :            :     Module &original,
    8296                 :            :     jl_codegen_params_t &params, CompilationPolicy policy)
    8297                 :            : {
    8298                 :            :     JL_TIMING(CODEGEN);
    8299                 :     188316 :     jl_code_info_t *src = NULL;
    8300                 :     188316 :     JL_GC_PUSH1(&src);
    8301         [ +  + ]:     406248 :     while (!params.workqueue.empty()) {
    8302                 :            :         jl_code_instance_t *codeinst;
    8303                 :            :         Function *protodecl;
    8304                 :            :         jl_returninfo_t::CallingConv proto_cc;
    8305                 :            :         bool proto_specsig;
    8306                 :            :         unsigned proto_return_roots;
    8307                 :     217932 :         auto it = params.workqueue.back();
    8308                 :     217932 :         codeinst = it.first;
    8309                 :     217932 :         std::tie(proto_cc, proto_return_roots, protodecl, proto_specsig) = it.second;
    8310                 :     217932 :         params.workqueue.pop_back();
    8311                 :            :         // try to emit code for this item from the workqueue
    8312   [ +  -  +  - ]:     217932 :         assert(codeinst->min_world <= params.world && codeinst->max_world >= params.world &&
    8313                 :            :             "invalid world for code-instance");
    8314                 :     217932 :         StringRef preal_decl = "";
    8315                 :     217932 :         bool preal_specsig = false;
    8316                 :     217932 :         auto invoke = jl_atomic_load_relaxed(&codeinst->invoke);
    8317   [ +  +  -  + ]:     217932 :         if (params.cache && invoke != NULL) {
    8318                 :          0 :             auto fptr = jl_atomic_load_relaxed(&codeinst->specptr.fptr);
    8319         [ #  # ]:          0 :             if (invoke == jl_fptr_args_addr) {
    8320                 :          0 :                 preal_decl = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, codeinst);
    8321                 :            :             }
    8322         [ #  # ]:          0 :             else if (codeinst->isspecsig) {
    8323                 :          0 :                 preal_decl = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, codeinst);
    8324                 :          0 :                 preal_specsig = true;
    8325                 :          0 :             }
    8326                 :            :         }
    8327                 :            :         else {
    8328                 :     217932 :             auto &result = emitted[codeinst];
    8329                 :     217932 :             jl_llvm_functions_t *decls = NULL;
    8330         [ +  + ]:     217932 :             if (std::get<0>(result)) {
    8331                 :      68700 :                 decls = &std::get<1>(result);
    8332                 :            :             }
    8333                 :            :             else {
    8334                 :            :                 // Reinfer the function. The JIT came along and removed the inferred
    8335                 :            :                 // method body. See #34993
    8336         [ -  + ]:     149232 :                 if (policy != CompilationPolicy::Default &&
    8337   [ #  #  #  # ]:          0 :                     codeinst->inferred && codeinst->inferred == jl_nothing) {
    8338                 :          0 :                     src = jl_type_infer(codeinst->def, jl_atomic_load_acquire(&jl_world_counter), 0);
    8339         [ #  # ]:          0 :                     if (src) {
    8340                 :            :                         orc::ThreadSafeModule result_m =
    8341                 :            :                         jl_create_llvm_module(name_from_method_instance(codeinst->def),
    8342                 :          0 :                             params.tsctx, params.imaging,
    8343                 :          0 :                             original.getDataLayout(), Triple(original.getTargetTriple()));
    8344                 :          0 :                         result.second = jl_emit_code(result_m, codeinst->def, src, src->rettype, params);
    8345                 :          0 :                         result.first = std::move(result_m);
    8346                 :          0 :                     }
    8347                 :            :                 }
    8348                 :            :                 else {
    8349                 :            :                     orc::ThreadSafeModule result_m =
    8350                 :            :                         jl_create_llvm_module(name_from_method_instance(codeinst->def),
    8351                 :     149232 :                             params.tsctx, params.imaging,
    8352                 :     298464 :                             original.getDataLayout(), Triple(original.getTargetTriple()));
    8353                 :     149232 :                     result.second = jl_emit_codeinst(result_m, codeinst, NULL, params);
    8354                 :     149232 :                     result.first = std::move(result_m);
    8355                 :            :                 }
    8356         [ +  + ]:     149232 :                 if (std::get<0>(result))
    8357                 :     149041 :                     decls = &std::get<1>(result);
    8358                 :            :                 else
    8359                 :        191 :                     emitted.erase(codeinst); // undo the insert above
    8360                 :            :             }
    8361         [ +  + ]:     217932 :             if (decls) {
    8362         [ +  + ]:     217741 :                 if (decls->functionObject == "jl_fptr_args") {
    8363                 :      10648 :                     preal_decl = decls->specFunctionObject;
    8364                 :            :                 }
    8365         [ +  - ]:     207093 :                 else if (decls->functionObject != "jl_fptr_sparam") {
    8366                 :     207093 :                     preal_decl = decls->specFunctionObject;
    8367                 :     207093 :                     preal_specsig = true;
    8368                 :            :                 }
    8369                 :            :             }
    8370                 :            :         }
    8371                 :            :         // patch up the prototype we emitted earlier
    8372                 :     217932 :         Module *mod = protodecl->getParent();
    8373         [ -  + ]:     217932 :         assert(protodecl->isDeclaration());
    8374         [ +  + ]:     217932 :         if (proto_specsig) {
    8375                 :            :             // expected specsig
    8376         [ +  + ]:     207274 :             if (!preal_specsig) {
    8377                 :            :                 // emit specsig-to-(jl)invoke conversion
    8378                 :        181 :                 Function *preal = emit_tojlinvoke(codeinst, mod, params);
    8379                 :        181 :                 protodecl->setLinkage(GlobalVariable::InternalLinkage);
    8380                 :            :                 //protodecl->setAlwaysInline();
    8381                 :        181 :                 jl_init_function(protodecl);
    8382                 :        181 :                 size_t nrealargs = jl_nparams(codeinst->def->specTypes); // number of actual arguments being passed
    8383                 :            :                 // TODO: maybe this can be cached in codeinst->specfptr?
    8384                 :        181 :                 emit_cfunc_invalidate(protodecl, proto_cc, proto_return_roots, codeinst->def->specTypes, codeinst->rettype, nrealargs, params, preal);
    8385                 :        181 :                 preal_decl = ""; // no need to fixup the name
    8386                 :            :             }
    8387                 :            :             else {
    8388         [ -  + ]:     207093 :                 assert(!preal_decl.empty());
    8389                 :            :             }
    8390                 :            :         }
    8391                 :            :         else {
    8392                 :            :             // expected non-specsig
    8393   [ +  +  -  +  :      10658 :             if (preal_decl.empty() || preal_specsig) {
                   +  + ]
    8394                 :            :                 // emit jlcall1-to-(jl)invoke conversion
    8395                 :         10 :                 preal_decl = emit_tojlinvoke(codeinst, mod, params)->getName();
    8396                 :            :             }
    8397                 :            :         }
    8398         [ +  + ]:     217932 :         if (!preal_decl.empty()) {
    8399                 :            :             // merge and/or rename this prototype to the real function
    8400         [ +  + ]:     217751 :             if (Value *specfun = mod->getNamedValue(preal_decl)) {
    8401         [ +  - ]:         10 :                 if (protodecl != specfun)
    8402                 :         10 :                     protodecl->replaceAllUsesWith(specfun);
    8403                 :            :             }
    8404                 :            :             else {
    8405                 :     217741 :                 protodecl->setName(preal_decl);
    8406                 :            :             }
    8407                 :            :         }
    8408                 :            :     }
    8409                 :     188316 :     JL_GC_POP();
    8410                 :     188316 : }
    8411                 :            : 
    8412                 :            : 
    8413                 :            : // --- initialization ---
    8414                 :            : std::vector<std::pair<jl_value_t**, JuliaVariable*>> gv_for_global;
    8415                 :       3402 : static void global_jlvalue_to_llvm(JuliaVariable *var, jl_value_t **addr)
    8416                 :            : {
    8417                 :       3402 :     gv_for_global.push_back(std::make_pair(addr, var));
    8418                 :       3402 : }
    8419                 :     362975 : static JuliaVariable *julia_const_gv(jl_value_t *val)
    8420                 :            : {
    8421         [ +  + ]:    2422570 :     for (auto &kv : gv_for_global) {
    8422         [ +  + ]:    2104860 :         if (*kv.first == val)
    8423                 :      45262 :             return kv.second;
    8424                 :            :     }
    8425                 :     317713 :     return nullptr;
    8426                 :            : }
    8427                 :            : 
    8428                 :        567 : static void init_jit_functions(void)
    8429                 :            : {
    8430                 :        567 :     add_named_global(jlstack_chk_guard_var, &__stack_chk_guard);
    8431                 :        567 :     add_named_global(jlRTLD_DEFAULT_var, &jl_RTLD_DEFAULT_handle);
    8432                 :            : #ifdef _OS_WINDOWS_
    8433                 :            :     add_named_global(jlexe_var, &jl_exe_handle);
    8434                 :            :     add_named_global(jldll_var, &jl_libjulia_handle);
    8435                 :            :     add_named_global(jldlli_var, &jl_libjulia_internal_handle);
    8436                 :            : #endif
    8437                 :        567 :     global_jlvalue_to_llvm(new JuliaVariable{"jl_true", true, get_pjlvalue}, &jl_true);
    8438                 :        567 :     global_jlvalue_to_llvm(new JuliaVariable{"jl_false", true, get_pjlvalue}, &jl_false);
    8439                 :        567 :     global_jlvalue_to_llvm(new JuliaVariable{"jl_emptysvec", true, get_pjlvalue}, (jl_value_t**)&jl_emptysvec);
    8440                 :        567 :     global_jlvalue_to_llvm(new JuliaVariable{"jl_emptytuple", true, get_pjlvalue}, &jl_emptytuple);
    8441                 :        567 :     global_jlvalue_to_llvm(new JuliaVariable{"jl_diverror_exception", true, get_pjlvalue}, &jl_diverror_exception);
    8442                 :        567 :     global_jlvalue_to_llvm(new JuliaVariable{"jl_undefref_exception", true, get_pjlvalue}, &jl_undefref_exception);
    8443                 :        567 :     add_named_global(jlgetworld_global, &jl_world_counter);
    8444                 :        567 :     add_named_global("__stack_chk_fail", &__stack_chk_fail);
    8445                 :        567 :     add_named_global(jlpgcstack_func, (void*)NULL);
    8446                 :        567 :     add_named_global(jlerror_func, &jl_error);
    8447                 :        567 :     add_named_global(jlatomicerror_func, &jl_atomic_error);
    8448                 :        567 :     add_named_global(jlthrow_func, &jl_throw);
    8449                 :        567 :     add_named_global(jlundefvarerror_func, &jl_undefined_var_error);
    8450                 :        567 :     add_named_global(jlboundserrorv_func, &jl_bounds_error_ints);
    8451                 :        567 :     add_named_global(jlboundserror_func, &jl_bounds_error_int);
    8452                 :        567 :     add_named_global(jlvboundserror_func, &jl_bounds_error_tuple_int);
    8453                 :        567 :     add_named_global(jluboundserror_func, &jl_bounds_error_unboxed_int);
    8454                 :        567 :     add_named_global(jlnew_func, &jl_new_structv);
    8455                 :        567 :     add_named_global(jlsplatnew_func, &jl_new_structt);
    8456                 :        567 :     add_named_global(setjmp_func, &jl_setjmp_f);
    8457                 :        567 :     add_named_global(memcmp_func, &memcmp);
    8458                 :        567 :     add_named_global(jltypeerror_func, &jl_type_error);
    8459                 :        567 :     add_named_global(jlcheckassign_func, &jl_checked_assignment);
    8460                 :        567 :     add_named_global(jldeclareconst_func, &jl_declare_constant);
    8461                 :        567 :     add_named_global(jlgetbindingorerror_func, &jl_get_binding_or_error);
    8462                 :        567 :     add_named_global(jlgetbindingwrorerror_func, &jl_get_binding_wr_or_error);
    8463                 :        567 :     add_named_global(jlboundp_func, &jl_boundp);
    8464         [ +  + ]:      19845 :     for (auto it : builtin_func_map())
    8465                 :      19278 :         add_named_global(it.second, it.first);
    8466                 :        567 :     add_named_global(jlapplygeneric_func, &jl_apply_generic);
    8467                 :        567 :     add_named_global(jlinvoke_func, &jl_invoke);
    8468                 :        567 :     add_named_global(jltopeval_func, &jl_toplevel_eval);
    8469                 :        567 :     add_named_global(jlcopyast_func, &jl_copy_ast);
    8470                 :            :     //add_named_global(jlnsvec_func, &jl_svec);
    8471                 :        567 :     add_named_global(jlmethod_func, &jl_method_def);
    8472                 :        567 :     add_named_global(jlgenericfunction_func, &jl_generic_function_def);
    8473                 :        567 :     add_named_global(jlenter_func, &jl_enter_handler);
    8474                 :        567 :     add_named_global(jl_current_exception_func, &jl_current_exception);
    8475                 :        567 :     add_named_global(jlleave_func, &jl_pop_handler);
    8476                 :        567 :     add_named_global(jl_restore_excstack_func, &jl_restore_excstack);
    8477                 :        567 :     add_named_global(jl_excstack_state_func, &jl_excstack_state);
    8478                 :        567 :     add_named_global(jlegalx_func, &jl_egal__unboxed);
    8479                 :        567 :     add_named_global(jlisa_func, &jl_isa);
    8480                 :        567 :     add_named_global(jlsubtype_func, &jl_subtype);
    8481                 :        567 :     add_named_global(jltypeassert_func, &jl_typeassert);
    8482                 :        567 :     add_named_global(jlapplytype_func, &jl_instantiate_type_in_env);
    8483                 :        567 :     add_named_global(jl_object_id__func, &jl_object_id_);
    8484                 :        567 :     add_named_global(jl_alloc_obj_func, (void*)NULL);
    8485                 :        567 :     add_named_global(jl_newbits_func, (void*)jl_new_bits);
    8486                 :        567 :     add_named_global(jl_loopinfo_marker_func, (void*)NULL);
    8487                 :        567 :     add_named_global(jl_typeof_func, (void*)NULL);
    8488                 :        567 :     add_named_global(jl_write_barrier_func, (void*)NULL);
    8489                 :        567 :     add_named_global(jl_write_barrier_binding_func, (void*)NULL);
    8490                 :        567 :     add_named_global(jldlsym_func, &jl_load_and_lookup);
    8491                 :        567 :     add_named_global(jlgetcfunctiontrampoline_func, &jl_get_cfunction_trampoline);
    8492                 :        567 :     add_named_global(jlgetnthfieldchecked_func, &jl_get_nth_field_checked);
    8493                 :        567 :     add_named_global(diff_gc_total_bytes_func, &jl_gc_diff_total_bytes);
    8494                 :        567 :     add_named_global(sync_gc_total_bytes_func, &jl_gc_sync_total_bytes);
    8495                 :        567 :     add_named_global(jlarray_data_owner_func, &jl_array_data_owner);
    8496                 :        567 :     add_named_global(gcroot_flush_func, (void*)NULL);
    8497                 :        567 :     add_named_global(gc_preserve_begin_func, (void*)NULL);
    8498                 :        567 :     add_named_global(gc_preserve_end_func, (void*)NULL);
    8499                 :        567 :     add_named_global(pointer_from_objref_func, (void*)NULL);
    8500                 :        567 :     add_named_global(except_enter_func, (void*)NULL);
    8501                 :        567 :     add_named_global(julia_call, (void*)NULL);
    8502                 :        567 :     add_named_global(julia_call2, (void*)NULL);
    8503                 :            : 
    8504                 :            : #ifdef _OS_WINDOWS_
    8505                 :            : #if defined(_CPU_X86_64_)
    8506                 :            : #if defined(_COMPILER_GCC_)
    8507                 :            :     add_named_global("___chkstk_ms", &___chkstk_ms);
    8508                 :            : #else
    8509                 :            :     add_named_global("__chkstk", &__chkstk);
    8510                 :            : #endif
    8511                 :            : #else
    8512                 :            : #if defined(_COMPILER_GCC_)
    8513                 :            :     add_named_global("_alloca", &_alloca);
    8514                 :            : #else
    8515                 :            :     add_named_global("_chkstk", &_chkstk);
    8516                 :            : #endif
    8517                 :            : #endif
    8518                 :            : #endif
    8519                 :            : 
    8520                 :            : #define BOX_F(ct) add_named_global(XSTR(jl_box_##ct), &jl_box_##ct);
    8521                 :        567 :     BOX_F(int8); BOX_F(uint8);
    8522                 :        567 :     BOX_F(int16); BOX_F(uint16);
    8523                 :        567 :     BOX_F(int32); BOX_F(uint32);
    8524                 :        567 :     BOX_F(int64); BOX_F(uint64);
    8525                 :        567 :     BOX_F(float32); BOX_F(float64);
    8526                 :        567 :     BOX_F(char); BOX_F(ssavalue);
    8527                 :            : #undef BOX_F
    8528                 :        567 : }
    8529                 :            : 
    8530                 :            : #ifdef JL_USE_INTEL_JITEVENTS
    8531                 :            : char jl_using_intel_jitevents; // Non-zero if running under Intel VTune Amplifier
    8532                 :            : #endif
    8533                 :            : 
    8534                 :            : #ifdef JL_USE_OPROFILE_JITEVENTS
    8535                 :            : char jl_using_oprofile_jitevents = 0; // Non-zero if running under OProfile
    8536                 :            : #endif
    8537                 :            : 
    8538                 :            : #ifdef JL_USE_PERF_JITEVENTS
    8539                 :            : char jl_using_perf_jitevents = 0;
    8540                 :            : #endif
    8541                 :            : 
    8542                 :        568 : extern "C" void jl_init_llvm(void)
    8543                 :            : {
    8544                 :        568 :     jl_page_size = jl_getpagesize();
    8545                 :        568 :     jl_default_debug_info_kind = (int) DICompileUnit::DebugEmissionKind::FullDebug;
    8546                 :        568 :     jl_default_cgparams.generic_context = jl_nothing;
    8547                 :            : 
    8548                 :        568 :     InitializeNativeTarget();
    8549                 :        568 :     InitializeNativeTargetAsmPrinter();
    8550                 :        568 :     InitializeNativeTargetAsmParser();
    8551                 :        568 :     InitializeNativeTargetDisassembler();
    8552                 :            : 
    8553                 :            :     // Initialize passes
    8554                 :        568 :     PassRegistry &Registry = *PassRegistry::getPassRegistry();
    8555                 :        568 :     initializeCore(Registry);
    8556                 :        568 :     initializeCoroutines(Registry);
    8557                 :        568 :     initializeScalarOpts(Registry);
    8558                 :        568 :     initializeVectorization(Registry);
    8559                 :        568 :     initializeAnalysis(Registry);
    8560                 :        568 :     initializeTransformUtils(Registry);
    8561                 :        568 :     initializeInstCombine(Registry);
    8562                 :        568 :     initializeAggressiveInstCombine(Registry);
    8563                 :        568 :     initializeInstrumentation(Registry);
    8564                 :        568 :     initializeTarget(Registry);
    8565                 :            : #ifdef USE_POLLY
    8566                 :            :     polly::initializePollyPasses(Registry);
    8567                 :            : #endif
    8568                 :            : 
    8569                 :            :     // Parse command line flags after initialization
    8570                 :        568 :     StringMap<cl::Option*> &llvmopts = cl::getRegisteredOptions();
    8571                 :        568 :     const char *const argv[1] = {"julia"};
    8572                 :        568 :     cl::ParseCommandLineOptions(1, argv, "", nullptr, "JULIA_LLVM_ARGS");
    8573                 :            : 
    8574                 :            :     // Set preferred non-default options
    8575                 :            :     cl::Option *clopt;
    8576                 :        567 :     clopt = llvmopts.lookup("enable-tail-merge"); // NOO TOUCHIE; NO TOUCH! See #922
    8577         [ +  + ]:        567 :     if (clopt->getNumOccurrences() == 0)
    8578                 :        566 :         cl::ProvidePositionalOption(clopt, "0", 1);
    8579                 :            :     // if the patch adding this option has been applied, lower its limit to provide
    8580                 :            :     // better DAGCombiner performance.
    8581                 :        567 :     clopt = llvmopts.lookup("combiner-store-merge-dependence-limit");
    8582   [ +  -  +  +  :        567 :     if (clopt && clopt->getNumOccurrences() == 0)
                   +  + ]
    8583                 :        566 :         cl::ProvidePositionalOption(clopt, "4", 1);
    8584                 :            : 
    8585                 :        567 :     jl_ExecutionEngine = new JuliaOJIT();
    8586                 :            : 
    8587                 :        567 :     bool jl_using_gdb_jitevents = false;
    8588                 :            :     // Register GDB event listener
    8589                 :            : #if defined(JL_DEBUG_BUILD)
    8590                 :        567 :     jl_using_gdb_jitevents = true;
    8591                 :            : # else
    8592                 :            :     const char *jit_gdb = getenv("ENABLE_GDBLISTENER");
    8593                 :            :     if (jit_gdb && atoi(jit_gdb)) {
    8594                 :            :         jl_using_gdb_jitevents = true;
    8595                 :            :     }
    8596                 :            : #endif
    8597         [ +  - ]:        567 :     if (jl_using_gdb_jitevents)
    8598                 :        567 :         jl_ExecutionEngine->enableJITDebuggingSupport();
    8599                 :            : 
    8600                 :            : #if defined(JL_USE_INTEL_JITEVENTS) || \
    8601                 :            :     defined(JL_USE_OPROFILE_JITEVENTS) || \
    8602                 :            :     defined(JL_USE_PERF_JITEVENTS)
    8603                 :            : #ifdef JL_USE_JITLINK
    8604                 :            : #error "JIT profiling support (JL_USE_*_JITEVENTS) not yet available on platforms that use JITLink"
    8605                 :            : #else
    8606                 :        567 :     const char *jit_profiling = getenv("ENABLE_JITPROFILING");
    8607                 :            : 
    8608                 :            : #if defined(JL_USE_INTEL_JITEVENTS)
    8609                 :            :     if (jit_profiling && atoi(jit_profiling)) {
    8610                 :            :         jl_using_intel_jitevents = 1;
    8611                 :            :     }
    8612                 :            : #endif
    8613                 :            : 
    8614                 :            : #if defined(JL_USE_OPROFILE_JITEVENTS)
    8615                 :            :     if (jit_profiling && atoi(jit_profiling)) {
    8616                 :            :         jl_using_oprofile_jitevents = 1;
    8617                 :            :     }
    8618                 :            : #endif
    8619                 :            : 
    8620                 :            : #if defined(JL_USE_PERF_JITEVENTS)
    8621   [ -  +  -  - ]:        567 :     if (jit_profiling && atoi(jit_profiling)) {
    8622                 :          0 :         jl_using_perf_jitevents= 1;
    8623                 :            :     }
    8624                 :            : #endif
    8625                 :            : 
    8626                 :            : #ifdef JL_USE_INTEL_JITEVENTS
    8627                 :            :     if (jl_using_intel_jitevents)
    8628                 :            :         jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createIntelJITEventListener());
    8629                 :            : #endif
    8630                 :            : 
    8631                 :            : #ifdef JL_USE_OPROFILE_JITEVENTS
    8632                 :            :     if (jl_using_oprofile_jitevents)
    8633                 :            :         jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createOProfileJITEventListener());
    8634                 :            : #endif
    8635                 :            : 
    8636                 :            : #ifdef JL_USE_PERF_JITEVENTS
    8637         [ -  + ]:        567 :     if (jl_using_perf_jitevents)
    8638                 :          0 :         jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createPerfJITEventListener());
    8639                 :            : #endif
    8640                 :            : #endif
    8641                 :            : #endif
    8642                 :            : 
    8643                 :        567 :     cl::PrintOptionValues();
    8644                 :        567 : }
    8645                 :            : 
    8646                 :        568 : extern "C" JL_DLLEXPORT void jl_init_codegen_impl(void)
    8647                 :            : {
    8648                 :        568 :     jl_init_llvm();
    8649                 :            :     // Now that the execution engine exists, initialize all modules
    8650                 :        567 :     init_jit_functions();
    8651                 :        567 : }
    8652                 :            : 
    8653                 :        572 : extern "C" JL_DLLEXPORT void jl_teardown_codegen_impl()
    8654                 :            : {
    8655                 :            :     // output LLVM timings and statistics
    8656                 :        572 :     reportAndResetTimings();
    8657                 :        572 :     PrintStatistics();
    8658                 :        572 : }
    8659                 :            : 
    8660                 :            : // the rest of this file are convenience functions
    8661                 :            : // that are exported for assisting with debugging from gdb
    8662                 :          0 : extern "C" void jl_dump_llvm_value(void *v)
    8663                 :            : {
    8664                 :          0 :     llvm_dump((Value*)v);
    8665                 :          0 : }
    8666                 :            : 
    8667                 :          0 : extern "C" void jl_dump_llvm_inst_function(void *v)
    8668                 :            : {
    8669                 :          0 :     llvm_dump(cast<Instruction>(((Value*)v))->getParent()->getParent());
    8670                 :          0 : }
    8671                 :            : 
    8672                 :          0 : extern "C" void jl_dump_llvm_type(void *v)
    8673                 :            : {
    8674                 :          0 :     llvm_dump((Type*)v);
    8675                 :          0 : }
    8676                 :            : 
    8677                 :          0 : extern "C" void jl_dump_llvm_module(void *v)
    8678                 :            : {
    8679                 :          0 :     llvm_dump((Module*)v);
    8680                 :          0 : }
    8681                 :            : 
    8682                 :          0 : extern "C" void jl_dump_llvm_metadata(void *v)
    8683                 :            : {
    8684                 :          0 :     llvm_dump((Metadata*)v);
    8685                 :          0 : }
    8686                 :            : 
    8687                 :          0 : extern "C" void jl_dump_llvm_debugloc(void *v)
    8688                 :            : {
    8689                 :          0 :     llvm_dump((DebugLoc*)v);
    8690                 :          0 : }
    8691                 :            : 
    8692                 :            : namespace llvm {
    8693                 :            :     class MachineBasicBlock;
    8694                 :            :     class MachineFunction;
    8695                 :            :     raw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB);
    8696                 :            :     void printMIR(raw_ostream &OS, const MachineFunction &MF);
    8697                 :            : }
    8698                 :          0 : extern "C" void jl_dump_llvm_mbb(void *v)
    8699                 :            : {
    8700                 :          0 :     errs() << *(llvm::MachineBasicBlock*)v;
    8701                 :          0 : }
    8702                 :          0 : extern "C" void jl_dump_llvm_mfunction(void *v)
    8703                 :            : {
    8704                 :          0 :     llvm::printMIR(errs(), *(llvm::MachineFunction*)v);
    8705                 :          0 : }
    8706                 :            : 
    8707                 :            : 
    8708                 :          0 : extern void jl_write_bitcode_func(void *F, char *fname) {
    8709                 :          0 :     std::error_code EC;
    8710                 :          0 :     raw_fd_ostream OS(fname, EC, sys::fs::OF_None);
    8711                 :          0 :     llvm::WriteBitcodeToFile(*((llvm::Function*)F)->getParent(), OS);
    8712                 :          0 : }
    8713                 :            : 
    8714                 :          0 : extern void jl_write_bitcode_module(void *M, char *fname) {
    8715                 :          0 :     std::error_code EC;
    8716                 :          0 :     raw_fd_ostream OS(fname, EC, sys::fs::OF_None);
    8717                 :          0 :     llvm::WriteBitcodeToFile(*(llvm::Module*)M, OS);
    8718                 :          0 : }
    8719                 :            : 
    8720                 :            : #ifdef _OS_WINDOWS_
    8721                 :            : #include <psapi.h>
    8722                 :            : #else
    8723                 :            : #include <dlfcn.h>
    8724                 :            : #endif
    8725                 :            : 
    8726                 :            : #include <llvm-c/Core.h>
    8727                 :            : 
    8728                 :          2 : extern "C" JL_DLLEXPORT jl_value_t *jl_get_libllvm_impl(void) JL_NOTSAFEPOINT
    8729                 :            : {
    8730                 :            : #if defined(_OS_WINDOWS_)
    8731                 :            :     HMODULE mod;
    8732                 :            :     if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)&llvm::DebugFlag, &mod))
    8733                 :            :         return jl_nothing;
    8734                 :            : 
    8735                 :            :     char path[MAX_PATH];
    8736                 :            :     if (!GetModuleFileNameA(mod, path, sizeof(path)))
    8737                 :            :         return jl_nothing;
    8738                 :            :     return (jl_value_t*) jl_symbol(path);
    8739                 :            : #else
    8740                 :            :     Dl_info dli;
    8741         [ -  + ]:          2 :     if (!dladdr((void*)LLVMContextCreate, &dli))
    8742                 :          0 :         return jl_nothing;
    8743                 :          2 :     return (jl_value_t*) jl_symbol(dli.dli_fname);
    8744                 :            : #endif
    8745                 :            : }

Generated by: LCOV version 1.14