LCOV - code coverage report
Current view: top level - src - cgutils.cpp (source / functions) Hit Total Coverage
Test: [build process] commit ef510b1f346f4c9f9d86eaceace5ca54961a1dbc Lines: 1999 2455 81.4 %
Date: 2022-07-17 01:01:28 Functions: 178 216 82.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1213 1740 69.7 %

           Branch data     Line data    Source code
       1                 :            : // This file is a part of Julia. License is MIT: https://julialang.org/license
       2                 :            : 
       3                 :            : // utility procedures used in code generation
       4                 :            : 
       5                 :            : // Mark our stats as being from cgutils
       6                 :            : #undef DEBUG_TYPE
       7                 :            : #define DEBUG_TYPE "julia_irgen_cgutils"
       8                 :            : 
       9                 :            : STATISTIC(EmittedPointerFromObjref, "Number of emitted pointer_from_objref calls");
      10                 :            : STATISTIC(EmittedPointerBitcast, "Number of emitted pointer bitcasts");
      11                 :            : STATISTIC(EmittedNthPtrAddr, "Number of emitted nth pointer address instructions");
      12                 :            : STATISTIC(EmittedTypeof, "Number of emitted typeof instructions");
      13                 :            : STATISTIC(EmittedErrors, "Number of emitted errors");
      14                 :            : STATISTIC(EmittedConditionalErrors, "Number of emitted conditional errors");
      15                 :            : STATISTIC(EmittedExceptions, "Number of emitted exceptions");
      16                 :            : STATISTIC(EmittedConditionalExceptions, "Number of emitted conditional exceptions");
      17                 :            : STATISTIC(EmittedNullchecks, "Number of emitted nullchecks");
      18                 :            : STATISTIC(EmittedGuards, "Number of emitted guards");
      19                 :            : STATISTIC(EmittedIsaUnions, "Number of emitted isa-union checks");
      20                 :            : STATISTIC(EmittedIsa, "Number of emitted isa checks");
      21                 :            : STATISTIC(EmittedTypechecks, "Number of emitted typechecks");
      22                 :            : STATISTIC(EmittedConcretechecks, "Number of emitted concrete checks");
      23                 :            : STATISTIC(EmittedBoundschecks, "Number of emitted boundschecks");
      24                 :            : STATISTIC(EmittedLockstates, "Number of emitted lockstate value calls");
      25                 :            : STATISTIC(EmittedMemcpys, "Number of emitted memcpy instructions");
      26                 :            : STATISTIC(SkippedMemcpys, "Number of skipped memcpy instructions");
      27                 :            : STATISTIC(EmittedGetfieldUnknowns, "Number of unknown getfield calls emitted");
      28                 :            : STATISTIC(EmittedGetfieldKnowns, "Number of known getfield calls emitted");
      29                 :            : STATISTIC(EmittedSetfield, "Number of setfield calls emitted");
      30                 :            : STATISTIC(EmittedUnionLoads, "Number of union loads emitted");
      31                 :            : STATISTIC(EmittedVarargsLength, "Number of varargs length calls emitted");
      32                 :            : STATISTIC(EmittedArraysize, "Number of arraysize calls emitted");
      33                 :            : STATISTIC(EmittedArraylen, "Number of array length calls emitted");
      34                 :            : STATISTIC(EmittedArrayptr, "Number of array data pointer loads emitted");
      35                 :            : STATISTIC(EmittedArrayflags, "Number of arrayflags calls emitted");
      36                 :            : STATISTIC(EmittedArrayNDims, "Number of array ndims calls emitted");
      37                 :            : STATISTIC(EmittedArrayElsize, "Number of array elsize calls emitted");
      38                 :            : STATISTIC(EmittedArrayOffset, "Number of array offset calls emitted");
      39                 :            : STATISTIC(EmittedArrayNdIndex, "Number of array nd index calls emitted");
      40                 :            : STATISTIC(EmittedBoxes, "Number of box operations emitted");
      41                 :            : STATISTIC(EmittedCPointerChecks, "Number of C pointer checks emitted");
      42                 :            : STATISTIC(EmittedAllocObjs, "Number of object allocations emitted");
      43                 :            : STATISTIC(EmittedWriteBarriers, "Number of write barriers emitted");
      44                 :            : STATISTIC(EmittedNewStructs, "Number of new structs emitted");
      45                 :            : STATISTIC(EmittedSignalFences, "Number of signal fences emitted");
      46                 :            : STATISTIC(EmittedDeferSignal, "Number of deferred signals emitted");
      47                 :            : 
      48                 :     685439 : static Value *track_pjlvalue(jl_codectx_t &ctx, Value *V)
      49                 :            : {
      50         [ -  + ]:     685439 :     assert(V->getType() == ctx.types().T_pjlvalue);
      51                 :     685439 :     return ctx.builder.CreateAddrSpaceCast(V, ctx.types().T_prjlvalue);
      52                 :            : }
      53                 :            : 
      54                 :            : // Take an arbitrary untracked value and make it gc-tracked
      55                 :     182284 : static Value *maybe_decay_untracked(jl_codectx_t &ctx, Value *V)
      56                 :            : {
      57         [ +  + ]:     182284 :     if (V->getType() == ctx.types().T_pjlvalue)
      58                 :     106561 :         return ctx.builder.CreateAddrSpaceCast(V, ctx.types().T_prjlvalue);
      59         [ -  + ]:      75723 :     assert(V->getType() == ctx.types().T_prjlvalue);
      60                 :      75723 :     return V;
      61                 :            : }
      62                 :            : 
      63                 :            : // Take any value and mark that it may be derived from a rooted value
      64                 :     782581 : static Value *decay_derived(jl_codectx_t &ctx, Value *V)
      65                 :            : {
      66                 :     782581 :     Type *T = V->getType();
      67         [ +  + ]:     782581 :     if (cast<PointerType>(T)->getAddressSpace() == AddressSpace::Derived)
      68                 :      42658 :         return V;
      69                 :            :     // Once llvm deletes pointer element types, we won't need it here any more either.
      70                 :     739923 :     Type *NewT = PointerType::getWithSamePointeeType(cast<PointerType>(T), AddressSpace::Derived);
      71                 :     739923 :     return ctx.builder.CreateAddrSpaceCast(V, NewT);
      72                 :            : }
      73                 :            : 
      74                 :            : // Take any value and make it safe to pass to GEP
      75                 :     722420 : static Value *maybe_decay_tracked(jl_codectx_t &ctx, Value *V)
      76                 :            : {
      77                 :     722420 :     Type *T = V->getType();
      78         [ +  + ]:     722420 :     if (cast<PointerType>(T)->getAddressSpace() != AddressSpace::Tracked)
      79                 :     338297 :         return V;
      80                 :     384123 :     Type *NewT = PointerType::getWithSamePointeeType(cast<PointerType>(T), AddressSpace::Derived);
      81                 :     384123 :     return ctx.builder.CreateAddrSpaceCast(V, NewT);
      82                 :            : }
      83                 :            : 
      84                 :     278580 : static Value *mark_callee_rooted(jl_codectx_t &ctx, Value *V)
      85                 :            : {
      86   [ +  +  -  + ]:     278580 :     assert(V->getType() == ctx.types().T_pjlvalue || V->getType() == ctx.types().T_prjlvalue);
      87                 :     835740 :     return ctx.builder.CreateAddrSpaceCast(V,
      88                 :     557160 :         PointerType::get(ctx.types().T_jlvalue, AddressSpace::CalleeRooted));
      89                 :            : }
      90                 :            : 
      91                 :      97006 : AtomicOrdering get_llvm_atomic_order(enum jl_memory_order order)
      92                 :            : {
      93   [ +  +  +  +  :      97006 :     switch (order) {
             +  +  +  - ]
      94                 :      87480 :     case jl_memory_order_notatomic: return AtomicOrdering::NotAtomic;
      95                 :       3346 :     case jl_memory_order_unordered: return AtomicOrdering::Unordered;
      96                 :       3916 :     case jl_memory_order_monotonic: return AtomicOrdering::Monotonic;
      97                 :        568 :     case jl_memory_order_acquire:   return AtomicOrdering::Acquire;
      98                 :       1616 :     case jl_memory_order_release:   return AtomicOrdering::Release;
      99                 :         40 :     case jl_memory_order_acq_rel:   return AtomicOrdering::AcquireRelease;
     100                 :         40 :     case jl_memory_order_seq_cst:   return AtomicOrdering::SequentiallyConsistent;
     101                 :          0 :     default:
     102                 :            :         assert("invalid atomic ordering");
     103                 :          0 :         abort();
     104                 :            :     }
     105                 :            : }
     106                 :            : 
     107                 :            : // --- language feature checks ---
     108                 :            : 
     109                 :            : #define JL_FEAT_TEST(ctx, feature) ((ctx).params->feature)
     110                 :            : 
     111                 :            : 
     112                 :            : // --- string constants ---
     113                 :      34825 : static Value *stringConstPtr(
     114                 :            :         jl_codegen_params_t &emission_context,
     115                 :            :         IRBuilder<> &irbuilder,
     116                 :            :         const std::string &txt)
     117                 :            : {
     118                 :      34825 :     Module *M = jl_builderModule(irbuilder);
     119                 :      34825 :     StringRef ctxt(txt.c_str(), txt.size() + 1);
     120                 :      34825 :     Constant *Data = ConstantDataArray::get(irbuilder.getContext(), arrayRefFromStringRef(ctxt));
     121                 :      34825 :     GlobalVariable *gv = get_pointer_to_constant(emission_context, Data, "_j_str", *M);
     122                 :      34825 :     Value *zero = ConstantInt::get(Type::getInt32Ty(irbuilder.getContext()), 0);
     123                 :      34825 :     Value *Args[] = { zero, zero };
     124                 :      34825 :     return irbuilder.CreateInBoundsGEP(gv->getValueType(), gv, Args);
     125                 :            : }
     126                 :            : 
     127                 :            : 
     128                 :            : // --- MDNode ---
     129                 :       1020 : Metadata *to_md_tree(jl_value_t *val, LLVMContext &ctxt) {
     130         [ +  + ]:       1020 :     if (val == jl_nothing)
     131                 :        510 :         return nullptr;
     132                 :        510 :     Metadata *MD = nullptr;
     133         [ +  - ]:        510 :     if (jl_is_symbol(val)) {
     134                 :        510 :         MD = MDString::get(ctxt, jl_symbol_name((jl_sym_t*)val));
     135         [ #  # ]:          0 :     } else if (jl_is_bool(val)) {
     136                 :          0 :         MD = ConstantAsMetadata::get(ConstantInt::get(getInt1Ty(ctxt), jl_unbox_bool(val)));
     137         [ #  # ]:          0 :     } else if (jl_is_long(val)) {
     138                 :          0 :         MD = ConstantAsMetadata::get(ConstantInt::get(getInt64Ty(ctxt), jl_unbox_long(val)));
     139         [ #  # ]:          0 :     } else if (jl_is_tuple(val)) {
     140                 :          0 :         SmallVector<Metadata *, 8> MDs;
     141         [ #  # ]:          0 :         for (int f = 0, nf = jl_nfields(val); f < nf; ++f) {
     142                 :          0 :             MD = to_md_tree(jl_fieldref(val, f), ctxt);
     143         [ #  # ]:          0 :             if (MD)
     144                 :          0 :                 MDs.push_back(MD);
     145                 :            :         }
     146                 :          0 :         MD = MDNode::get(ctxt, MDs);
     147                 :            :     } else {
     148                 :          0 :         jl_error("LLVM metadata needs to Symbol/Bool/Int or Tuple thereof");
     149                 :            :     }
     150                 :        510 :     return MD;
     151                 :            : }
     152                 :            : 
     153                 :            : // --- Debug info ---
     154                 :            : 
     155                 :     552642 : static DIType *_julia_type_to_di(jl_codegen_params_t *ctx, jl_debugcache_t &debuginfo, jl_value_t *jt, DIBuilder *dbuilder, bool isboxed)
     156                 :            : {
     157                 :     552642 :     jl_datatype_t *jdt = (jl_datatype_t*)jt;
     158   [ +  -  +  +  :     552642 :     if (isboxed || !jl_is_datatype(jt) || !jdt->isconcretetype)
                   +  + ]
     159                 :      59774 :         return debuginfo.jl_pvalue_dillvmt;
     160         [ -  + ]:     492868 :     assert(jdt->layout);
     161                 :     492868 :     DIType* _ditype = NULL;
     162         [ +  + ]:     492868 :     DIType* &ditype = (ctx ? ctx->ditypes[jdt] : _ditype);
     163         [ +  + ]:     492868 :     if (ditype)
     164                 :     333975 :         return ditype;
     165                 :     158893 :     const char *tname = jl_symbol_name(jdt->name->name);
     166         [ +  + ]:     158893 :     if (jl_is_primitivetype(jt)) {
     167                 :     101615 :         uint64_t SizeInBits = jl_datatype_nbits(jdt);
     168                 :     101615 :         ditype = dbuilder->createBasicType(tname, SizeInBits, llvm::dwarf::DW_ATE_unsigned);
     169                 :            :     }
     170   [ +  -  +  +  :      57278 :     else if (jl_is_structtype(jt) && !jl_is_layout_opaque(jdt->layout)) {
                   +  + ]
     171                 :      52980 :         size_t ntypes = jl_datatype_nfields(jdt);
     172                 :     105960 :         std::vector<llvm::Metadata*> Elements(ntypes);
     173         [ +  + ]:     139960 :         for (unsigned i = 0; i < ntypes; i++) {
     174                 :      86980 :             jl_value_t *el = jl_field_type_concrete(jdt, i);
     175                 :            :             DIType *di;
     176         [ +  + ]:      86980 :             if (jl_field_isptr(jdt, i))
     177                 :      32380 :                 di = debuginfo.jl_pvalue_dillvmt;
     178                 :            :             // TODO: elseif jl_islayout_inline
     179                 :            :             else
     180                 :      54600 :                 di = _julia_type_to_di(ctx, debuginfo, el, dbuilder, false);
     181                 :      86980 :             Elements[i] = di;
     182                 :            :         }
     183                 :      52980 :         DINodeArray ElemArray = dbuilder->getOrCreateArray(Elements);
     184                 :      52980 :         std::string unique_name;
     185                 :      52980 :         raw_string_ostream(unique_name) << (uintptr_t)jdt;
     186                 :     105960 :         ditype = dbuilder->createStructType(
     187                 :            :                 NULL,                       // Scope
     188                 :            :                 tname,                      // Name
     189                 :            :                 NULL,                       // File
     190                 :            :                 0,                          // LineNumber
     191                 :      52980 :                 jl_datatype_nbits(jdt),     // SizeInBits
     192                 :      52980 :                 8 * jl_datatype_align(jdt), // AlignInBits
     193                 :            :                 DINode::FlagZero,           // Flags
     194                 :            :                 NULL,                       // DerivedFrom
     195                 :            :                 ElemArray,                  // Elements
     196                 :            :                 dwarf::DW_LANG_Julia,       // RuntimeLanguage
     197                 :            :                 nullptr,                    // VTableHolder
     198                 :            :                 unique_name                 // UniqueIdentifier
     199                 :            :                 );
     200                 :            :     }
     201                 :            :     else {
     202                 :            :         // return a typealias for types with hidden content
     203                 :       4298 :         ditype = dbuilder->createTypedef(debuginfo.jl_pvalue_dillvmt, tname, NULL, 0, NULL);
     204                 :            :     }
     205                 :     158893 :     return ditype;
     206                 :            : }
     207                 :            : 
     208                 :     407727 : static DIType *julia_type_to_di(jl_codectx_t &ctx, jl_debugcache_t &debuginfo, jl_value_t *jt, DIBuilder *dbuilder, bool isboxed)
     209                 :            : {
     210                 :     407727 :     return _julia_type_to_di(&ctx.emission_context, debuginfo, jt, dbuilder, isboxed);
     211                 :            : }
     212                 :            : 
     213                 :      90315 : void jl_debugcache_t::initialize(Module *m) {
     214         [ -  + ]:      90315 :     if (initialized) {
     215                 :          0 :         return;
     216                 :            :     }
     217                 :      90315 :     initialized = true;
     218                 :            :     // add needed base debugging definitions to our LLVM environment
     219                 :     180630 :     DIBuilder dbuilder(*m);
     220                 :      90315 :     DIFile *julia_h = dbuilder.createFile("julia.h", "");
     221                 :      90315 :     DICompositeType *jl_value_dillvmt = dbuilder.createStructType(nullptr,
     222                 :            :         "jl_value_t",
     223                 :            :         julia_h,
     224                 :            :         71, // At the time of this writing. Not sure if it's worth it to keep this in sync
     225                 :            :         0 * 8, // sizeof(jl_value_t) * 8,
     226                 :            :         __alignof__(void*) * 8, // __alignof__(jl_value_t) * 8,
     227                 :            :         DINode::FlagZero, // Flags
     228                 :            :         nullptr,    // Derived from
     229                 :      90315 :         nullptr);  // Elements - will be corrected later
     230                 :            : 
     231                 :      90315 :     jl_pvalue_dillvmt = dbuilder.createPointerType(jl_value_dillvmt, sizeof(jl_value_t*) * 8,
     232                 :            :                                                 __alignof__(jl_value_t*) * 8);
     233                 :            : 
     234                 :     180630 :     SmallVector<llvm::Metadata *, 1> Elts;
     235                 :      90315 :     std::vector<Metadata*> diargs(0);
     236                 :      90315 :     Elts.push_back(jl_pvalue_dillvmt);
     237                 :      90315 :     dbuilder.replaceArrays(jl_value_dillvmt,
     238                 :            :     dbuilder.getOrCreateArray(Elts));
     239                 :            : 
     240                 :      90315 :     jl_ppvalue_dillvmt = dbuilder.createPointerType(jl_pvalue_dillvmt, sizeof(jl_value_t**) * 8,
     241                 :            :                                                     __alignof__(jl_value_t**) * 8);
     242                 :            : 
     243                 :      90315 :     diargs.push_back(jl_pvalue_dillvmt);    // Return Type (ret value)
     244                 :      90315 :     diargs.push_back(jl_pvalue_dillvmt);    // First Argument (function)
     245                 :      90315 :     diargs.push_back(jl_ppvalue_dillvmt);   // Second Argument (argv)
     246                 :            :     // Third argument (length(argv))
     247                 :      90315 :     diargs.push_back(_julia_type_to_di(NULL, *this, (jl_value_t*)jl_int32_type, &dbuilder, false));
     248                 :            : 
     249                 :      90315 :     jl_di_func_sig = dbuilder.createSubroutineType(
     250                 :            :         dbuilder.getOrCreateTypeArray(diargs));
     251                 :      90315 :     jl_di_func_null_sig = dbuilder.createSubroutineType(
     252                 :            :         dbuilder.getOrCreateTypeArray(None));
     253                 :            : }
     254                 :            : 
     255                 :      38471 : static Value *emit_pointer_from_objref(jl_codectx_t &ctx, Value *V)
     256                 :            : {
     257                 :      38471 :     unsigned AS = cast<PointerType>(V->getType())->getAddressSpace();
     258   [ +  +  -  + ]:      38471 :     if (AS != AddressSpace::Tracked && AS != AddressSpace::Derived)
     259                 :          0 :         return V;
     260                 :      38471 :     V = decay_derived(ctx, V);
     261                 :      38471 :     Type *T = PointerType::get(ctx.types().T_jlvalue, AddressSpace::Derived);
     262         [ -  + ]:      38471 :     if (V->getType() != T)
     263                 :          0 :         V = ctx.builder.CreateBitCast(V, T);
     264                 :      38471 :     Function *F = prepare_call(pointer_from_objref_func);
     265                 :      38471 :     CallInst *Call = ctx.builder.CreateCall(F, V);
     266                 :      38471 :     Call->setAttributes(F->getAttributes());
     267                 :      38471 :     ++EmittedPointerFromObjref;
     268                 :      38471 :     return Call;
     269                 :            : }
     270                 :            : 
     271                 :      98416 : static Value *get_gc_root_for(const jl_cgval_t &x)
     272                 :            : {
     273         [ +  + ]:      98416 :     if (x.Vboxed)
     274                 :      11464 :         return x.Vboxed;
     275   [ +  +  +  +  :      86952 :     if (x.ispointer() && !x.constant) {
                   +  + ]
     276         [ -  + ]:       1841 :         assert(x.V);
     277         [ +  - ]:       1841 :         if (PointerType *T = dyn_cast<PointerType>(x.V->getType())) {
     278   [ +  -  +  +  :       3682 :             if (T->getAddressSpace() == AddressSpace::Tracked ||
                   +  + ]
     279                 :       1841 :                 T->getAddressSpace() == AddressSpace::Derived) {
     280                 :       1300 :                 return x.V;
     281                 :            :             }
     282                 :            :         }
     283                 :            :     }
     284                 :      85652 :     return nullptr;
     285                 :            : }
     286                 :            : 
     287                 :            : // --- emitting pointers directly into code ---
     288                 :            : 
     289                 :            : 
     290                 :            : static inline Constant *literal_static_pointer_val(const void *p, Type *T);
     291                 :            : 
     292                 :    2979340 : static Value *julia_pgv(jl_codectx_t &ctx, const char *cname, void *addr)
     293                 :            : {
     294                 :            :     // emit a GlobalVariable for a jl_value_t named "cname"
     295                 :            :     // store the name given so we can reuse it (facilitating merging later)
     296                 :            :     // so first see if there already is a GlobalVariable for this address
     297                 :    2979340 :     GlobalVariable* &gv = ctx.global_targets[addr];
     298                 :    2979340 :     Module *M = jl_Module;
     299                 :    2979340 :     StringRef localname;
     300                 :    2979340 :     std::string gvname;
     301         [ +  + ]:    2979340 :     if (!gv) {
     302                 :     205146 :         raw_string_ostream(gvname) << cname << ctx.global_targets.size();
     303                 :     205146 :         localname = StringRef(gvname);
     304                 :            :     }
     305                 :            :     else {
     306                 :    2774190 :         localname = gv->getName();
     307         [ +  + ]:    2774190 :         if (gv->getParent() != M)
     308                 :     749201 :             gv = cast_or_null<GlobalVariable>(M->getNamedValue(localname));
     309                 :            :     }
     310         [ +  + ]:    2979340 :     if (gv == nullptr)
     311                 :    1908680 :         gv = new GlobalVariable(*M, ctx.types().T_pjlvalue,
     312                 :            :                                 false, GlobalVariable::PrivateLinkage,
     313                 :     954339 :                                 NULL, localname);
     314                 :            :     // LLVM passes sometimes strip metadata when moving load around
     315                 :            :     // since the load at the new location satisfy the same condition as the original one.
     316                 :            :     // Mark the global as constant to LLVM code using our own metadata
     317                 :            :     // which is much less likely to be striped.
     318                 :    2979340 :     gv->setMetadata("julia.constgv", MDNode::get(gv->getContext(), None));
     319         [ -  + ]:    2979340 :     assert(localname == gv->getName());
     320         [ -  + ]:    2979340 :     assert(!gv->hasInitializer());
     321                 :    2979340 :     return gv;
     322                 :            : }
     323                 :            : 
     324                 :    2746280 : static Value *julia_pgv(jl_codectx_t &ctx, const char *prefix, jl_sym_t *name, jl_module_t *mod, void *addr)
     325                 :            : {
     326                 :            :     // emit a GlobalVariable for a jl_value_t, using the prefix, name, and module to
     327                 :            :     // to create a readable name of the form prefixModA.ModB.name
     328                 :    2746280 :     size_t len = strlen(jl_symbol_name(name)) + strlen(prefix) + 1;
     329                 :    2746280 :     jl_module_t *parent = mod, *prev = NULL;
     330   [ +  +  +  + ]:    6893410 :     while (parent != NULL && parent != prev) {
     331                 :    4147140 :         len += strlen(jl_symbol_name(parent->name))+1;
     332                 :    4147140 :         prev = parent;
     333                 :    4147140 :         parent = parent->parent;
     334                 :            :     }
     335                 :    2746280 :     char *fullname = (char*)alloca(len);
     336                 :    2746280 :     strcpy(fullname, prefix);
     337                 :    2746280 :     len -= strlen(jl_symbol_name(name)) + 1;
     338                 :    2746280 :     strcpy(fullname + len, jl_symbol_name(name));
     339                 :    2746280 :     parent = mod;
     340                 :    2746280 :     prev = NULL;
     341   [ +  +  +  + ]:    6893410 :     while (parent != NULL && parent != prev) {
     342                 :    4147140 :         size_t part = strlen(jl_symbol_name(parent->name)) + 1;
     343                 :    4147140 :         strcpy(fullname + len - part, jl_symbol_name(parent->name));
     344                 :    4147140 :         fullname[len - 1] = '.';
     345                 :    4147140 :         len -= part;
     346                 :    4147140 :         prev = parent;
     347                 :    4147140 :         parent = parent->parent;
     348                 :            :     }
     349                 :    2746280 :     return julia_pgv(ctx, fullname, addr);
     350                 :            : }
     351                 :            : 
     352                 :            : static JuliaVariable *julia_const_gv(jl_value_t *val);
     353                 :     636996 : static Value *literal_pointer_val_slot(jl_codectx_t &ctx, jl_value_t *p)
     354                 :            : {
     355                 :            :     // emit a pointer to a jl_value_t* which will allow it to be valid across reloading code
     356                 :            :     // also, try to give it a nice name for gdb, for easy identification
     357         [ -  + ]:     636996 :     if (!ctx.emission_context.imaging) {
     358                 :            :         // TODO: this is an optimization, but is it useful or premature
     359                 :            :         // (it'll block any attempt to cache these, but can be simply deleted)
     360                 :          0 :         Module *M = jl_Module;
     361                 :            :         GlobalVariable *gv = new GlobalVariable(
     362                 :          0 :                 *M, ctx.types().T_pjlvalue, true, GlobalVariable::PrivateLinkage,
     363                 :          0 :                 literal_static_pointer_val(p, ctx.types().T_pjlvalue));
     364                 :          0 :         gv->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
     365                 :          0 :         return gv;
     366                 :            :     }
     367         [ +  + ]:     636996 :     if (JuliaVariable *gv = julia_const_gv(p)) {
     368                 :            :         // if this is a known special object, use the existing GlobalValue
     369                 :      80293 :         return prepare_global_in(jl_Module, gv);
     370                 :            :     }
     371         [ +  + ]:     556703 :     if (jl_is_datatype(p)) {
     372                 :     237892 :         jl_datatype_t *addr = (jl_datatype_t*)p;
     373                 :            :         // DataTypes are prefixed with a +
     374                 :     237892 :         return julia_pgv(ctx, "+", addr->name->name, addr->name->module, p);
     375                 :            :     }
     376         [ -  + ]:     318811 :     if (jl_is_method(p)) {
     377                 :          0 :         jl_method_t *m = (jl_method_t*)p;
     378                 :            :         // functions are prefixed with a -
     379                 :          0 :         return julia_pgv(ctx, "-", m->name, m->module, p);
     380                 :            :     }
     381         [ +  + ]:     318811 :     if (jl_is_method_instance(p)) {
     382                 :        294 :         jl_method_instance_t *linfo = (jl_method_instance_t*)p;
     383                 :            :         // Type-inferred functions are also prefixed with a -
     384         [ +  - ]:        294 :         if (jl_is_method(linfo->def.method))
     385                 :        294 :             return julia_pgv(ctx, "-", linfo->def.method->name, linfo->def.method->module, p);
     386                 :            :     }
     387         [ +  + ]:     318517 :     if (jl_is_symbol(p)) {
     388                 :      85455 :         jl_sym_t *addr = (jl_sym_t*)p;
     389                 :            :         // Symbols are prefixed with jl_sym#
     390                 :      85455 :         return julia_pgv(ctx, "jl_sym#", addr, NULL, p);
     391                 :            :     }
     392                 :            :     // something else gets just a generic name
     393                 :     233062 :     return julia_pgv(ctx, "jl_global#", p);
     394                 :            : }
     395                 :            : 
     396                 :    1634580 : static size_t dereferenceable_size(jl_value_t *jt)
     397                 :            : {
     398         [ +  + ]:    1634580 :     if (jl_is_array_type(jt)) {
     399                 :            :         // Array has at least this much data
     400                 :     255194 :         return sizeof(jl_array_t);
     401                 :            :     }
     402   [ +  +  +  +  :    1379390 :     else if (jl_is_datatype(jt) && jl_struct_try_layout((jl_datatype_t*)jt)) {
                   +  + ]
     403                 :    1156050 :         return jl_datatype_size(jt);
     404                 :            :     }
     405                 :     223333 :     return 0;
     406                 :            : }
     407                 :            : 
     408                 :            : // Return the min required / expected alignment of jltype (on the stack or heap)
     409                 :    1360690 : static unsigned julia_alignment(jl_value_t *jt)
     410                 :            : {
     411         [ +  + ]:    1360690 :     if (jl_is_array_type(jt)) {
     412                 :            :         // Array always has this alignment
     413                 :     255194 :         return JL_SMALL_BYTE_ALIGNMENT;
     414                 :            :     }
     415         [ +  + ]:    1105500 :     if (jt == (jl_value_t*)jl_datatype_type) {
     416                 :            :         // types are never allocated in julia code/on the stack
     417                 :            :         // and this is the guarantee we have for the GC bits
     418                 :     235708 :         return 16;
     419                 :            :     }
     420   [ +  -  +  - ]:     869790 :     assert(jl_is_datatype(jt) && jl_struct_try_layout((jl_datatype_t*)jt));
     421                 :     869790 :     unsigned alignment = jl_datatype_align(jt);
     422         [ +  + ]:     869790 :     if (alignment > JL_HEAP_ALIGNMENT)
     423                 :        126 :         return JL_HEAP_ALIGNMENT;
     424                 :     869664 :     return alignment;
     425                 :            : }
     426                 :            : 
     427                 :     118151 : static inline void maybe_mark_argument_dereferenceable(AttrBuilder &B, jl_value_t *jt)
     428                 :            : {
     429                 :     118151 :     B.addAttribute(Attribute::NonNull);
     430                 :     118151 :     B.addAttribute(Attribute::NoUndef);
     431                 :            :     // The `dereferencable` below does not imply `nonnull` for non addrspace(0) pointers.
     432                 :     118151 :     size_t size = dereferenceable_size(jt);
     433         [ +  + ]:     118151 :     if (size) {
     434                 :      79775 :         B.addDereferenceableAttr(size);
     435                 :      79775 :         B.addAlignmentAttr(julia_alignment(jt));
     436                 :            :     }
     437                 :     118151 : }
     438                 :            : 
     439                 :    1515770 : static inline Instruction *maybe_mark_load_dereferenceable(Instruction *LI, bool can_be_null,
     440                 :            :                                                            size_t size, size_t align)
     441                 :            : {
     442         [ +  - ]:    1515770 :     if (isa<PointerType>(LI->getType())) {
     443         [ +  + ]:    1515770 :         if (!can_be_null)
     444                 :            :             // The `dereferencable` below does not imply `nonnull` for non addrspace(0) pointers.
     445                 :    1438580 :             LI->setMetadata(LLVMContext::MD_nonnull, MDNode::get(LI->getContext(), None));
     446         [ +  + ]:    1515770 :         if (size) {
     447                 :     893507 :             Metadata *OP = ConstantAsMetadata::get(ConstantInt::get(getInt64Ty(LI->getContext()), size));
     448         [ +  + ]:     893507 :             LI->setMetadata(can_be_null ? LLVMContext::MD_dereferenceable_or_null : LLVMContext::MD_dereferenceable,
     449                 :     893507 :                             MDNode::get(LI->getContext(), { OP }));
     450         [ +  - ]:     893507 :             if (align >= 1) {
     451                 :     893507 :                 Metadata *OP = ConstantAsMetadata::get(ConstantInt::get(getInt64Ty(LI->getContext()), align));
     452                 :     893507 :                 LI->setMetadata(LLVMContext::MD_align, MDNode::get(LI->getContext(), { OP }));
     453                 :            :             }
     454                 :            :         }
     455                 :            :     }
     456                 :    1515770 :     return LI;
     457                 :            : }
     458                 :            : 
     459                 :    1511390 : static inline Instruction *maybe_mark_load_dereferenceable(Instruction *LI, bool can_be_null, jl_value_t *jt)
     460                 :            : {
     461                 :    1511390 :     size_t size = dereferenceable_size(jt);
     462                 :    1511390 :     unsigned alignment = 1;
     463         [ +  + ]:    1511390 :     if (size > 0)
     464                 :     893213 :         alignment = julia_alignment(jt);
     465                 :    1511390 :     return maybe_mark_load_dereferenceable(LI, can_be_null, size, alignment);
     466                 :            : }
     467                 :            : 
     468                 :            : // Returns ctx.types().T_pjlvalue
     469                 :     947084 : static Value *literal_pointer_val(jl_codectx_t &ctx, jl_value_t *p)
     470                 :            : {
     471         [ -  + ]:     947084 :     if (p == NULL)
     472                 :          0 :         return Constant::getNullValue(ctx.types().T_pjlvalue);
     473         [ +  + ]:     947084 :     if (!ctx.emission_context.imaging)
     474                 :     315764 :         return literal_static_pointer_val(p, ctx.types().T_pjlvalue);
     475                 :     631320 :     Value *pgv = literal_pointer_val_slot(ctx, p);
     476                 :     631320 :     return tbaa_decorate(ctx.tbaa().tbaa_const, maybe_mark_load_dereferenceable(
     477                 :    1262640 :             ctx.builder.CreateAlignedLoad(ctx.types().T_pjlvalue, pgv, Align(sizeof(void*))),
     478                 :    1262640 :             false, jl_typeof(p)));
     479                 :            : }
     480                 :            : 
     481                 :            : // Returns ctx.types().T_pjlvalue
     482                 :         16 : static Value *literal_pointer_val(jl_codectx_t &ctx, jl_binding_t *p)
     483                 :            : {
     484                 :            :     // emit a pointer to any jl_value_t which will be valid across reloading code
     485         [ -  + ]:         16 :     if (p == NULL)
     486                 :          0 :         return Constant::getNullValue(ctx.types().T_pjlvalue);
     487         [ -  + ]:         16 :     if (!ctx.emission_context.imaging)
     488                 :          0 :         return literal_static_pointer_val(p, ctx.types().T_pjlvalue);
     489                 :            :     // bindings are prefixed with jl_bnd#
     490                 :         16 :     Value *pgv = julia_pgv(ctx, "jl_bnd#", p->name, p->owner, p);
     491                 :         16 :     return tbaa_decorate(ctx.tbaa().tbaa_const, maybe_mark_load_dereferenceable(
     492                 :         32 :             ctx.builder.CreateAlignedLoad(ctx.types().T_pjlvalue, pgv, Align(sizeof(void*))),
     493                 :         16 :             false, sizeof(jl_binding_t), alignof(jl_binding_t)));
     494                 :            : }
     495                 :            : 
     496                 :            : // bitcast a value, but preserve its address space when dealing with pointer types
     497                 :    5819500 : static Value *emit_bitcast(jl_codectx_t &ctx, Value *v, Type *jl_value)
     498                 :            : {
     499   [ +  +  +  +  :   11636400 :     if (isa<PointerType>(jl_value) &&
                   +  + ]
     500                 :    5816860 :         v->getType()->getPointerAddressSpace() != jl_value->getPointerAddressSpace()) {
     501                 :            :         // Cast to the proper address space
     502                 :    1462240 :         Type *jl_value_addr = PointerType::getWithSamePointeeType(cast<PointerType>(jl_value), v->getType()->getPointerAddressSpace());
     503                 :    1462240 :         ++EmittedPointerBitcast;
     504                 :    1462240 :         return ctx.builder.CreateBitCast(v, jl_value_addr);
     505                 :            :     }
     506                 :            :     else {
     507                 :    4357260 :         return ctx.builder.CreateBitCast(v, jl_value);
     508                 :            :     }
     509                 :            : }
     510                 :            : 
     511                 :     788208 : static Value *maybe_bitcast(jl_codectx_t &ctx, Value *V, Type *to) {
     512         [ +  + ]:     788208 :     if (to != V->getType())
     513                 :     601580 :         return emit_bitcast(ctx, V, to);
     514                 :     186628 :     return V;
     515                 :            : }
     516                 :            : 
     517                 :    3808240 : static Value *julia_binding_pvalue(jl_codectx_t &ctx, Value *bv)
     518                 :            : {
     519                 :    3808240 :     bv = emit_bitcast(ctx, bv, ctx.types().T_pprjlvalue);
     520                 :    3808240 :     Value *offset = ConstantInt::get(getSizeTy(ctx.builder.getContext()), offsetof(jl_binding_t, value) / sizeof(size_t));
     521                 :    3808240 :     return ctx.builder.CreateInBoundsGEP(ctx.types().T_prjlvalue, bv, offset);
     522                 :            : }
     523                 :            : 
     524                 :    3806990 : static Value *julia_binding_gv(jl_codectx_t &ctx, jl_binding_t *b)
     525                 :            : {
     526                 :            :     // emit a literal_pointer_val to a jl_binding_t
     527                 :            :     // binding->value are prefixed with *
     528         [ +  + ]:    3806990 :     if (ctx.emission_context.imaging)
     529                 :    4845240 :         return tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(ctx.types().T_pjlvalue,
     530                 :    4845240 :                     julia_pgv(ctx, "*", b->name, b->owner, b), Align(sizeof(void*))));
     531                 :            :     else
     532                 :    1384370 :         return literal_static_pointer_val(b, ctx.types().T_pjlvalue);
     533                 :            : }
     534                 :            : 
     535                 :            : // --- mapping between julia and llvm types ---
     536                 :            : 
     537                 :      53099 : static bool type_is_permalloc(jl_value_t *typ)
     538                 :            : {
     539                 :            :     // Singleton should almost always be handled by the later optimization passes.
     540                 :            :     // Also do it here since it is cheap and save some effort in LLVM passes.
     541   [ +  +  +  +  :      53099 :     if (jl_is_datatype(typ) && jl_is_datatype_singleton((jl_datatype_t*)typ))
                   +  + ]
     542                 :      10490 :         return true;
     543                 :      81714 :     return typ == (jl_value_t*)jl_symbol_type ||
     544   [ +  +  +  - ]:      81714 :         typ == (jl_value_t*)jl_int8_type ||
     545         [ +  + ]:      81714 :         typ == (jl_value_t*)jl_uint8_type;
     546                 :            : }
     547                 :            : 
     548                 :     214917 : static unsigned convert_struct_offset(const llvm::DataLayout &DL, Type *lty, unsigned byte_offset)
     549                 :            : {
     550                 :     214917 :     const StructLayout *SL = DL.getStructLayout(cast<StructType>(lty));
     551                 :     214917 :     unsigned idx = SL->getElementContainingOffset(byte_offset);
     552         [ -  + ]:     214917 :     assert(SL->getElementOffset(idx) == byte_offset);
     553                 :     214917 :     return idx;
     554                 :            : }
     555                 :            : 
     556                 :     199618 : static unsigned convert_struct_offset(jl_codectx_t &ctx, Type *lty, unsigned byte_offset)
     557                 :            : {
     558                 :     199618 :     return convert_struct_offset(ctx.builder.GetInsertBlock()->getModule()->getDataLayout(), lty, byte_offset);
     559                 :            : }
     560                 :            : 
     561                 :     104959 : static Value *emit_struct_gep(jl_codectx_t &ctx, Type *lty, Value *base, unsigned byte_offset)
     562                 :            : {
     563                 :     104959 :     unsigned idx = convert_struct_offset(ctx, lty, byte_offset);
     564                 :     104959 :     return ctx.builder.CreateConstInBoundsGEP2_32(lty, base, 0, idx);
     565                 :            : }
     566                 :            : 
     567                 :            : static Type *_julia_struct_to_llvm(jl_codegen_params_t *ctx, LLVMContext &ctxt, jl_value_t *jt, bool *isboxed, bool llvmcall=false);
     568                 :            : 
     569                 :    9670260 : static Type *_julia_type_to_llvm(jl_codegen_params_t *ctx, LLVMContext &ctxt, jl_value_t *jt, bool *isboxed)
     570                 :            : {
     571                 :            :     // this function converts a Julia Type into the equivalent LLVM type
     572         [ +  + ]:    9670260 :     if (isboxed) *isboxed = false;
     573         [ +  + ]:    9670260 :     if (jt == (jl_value_t*)jl_bottom_type)
     574                 :      66818 :         return getVoidTy(ctxt);
     575         [ +  + ]:    9603440 :     if (jl_is_concrete_immutable(jt)) {
     576         [ +  + ]:    7408190 :         if (jl_datatype_nbits(jt) == 0)
     577                 :     793007 :             return getVoidTy(ctxt);
     578                 :    6615180 :         Type *t = _julia_struct_to_llvm(ctx, ctxt, jt, isboxed);
     579         [ -  + ]:    6615180 :         assert(t != NULL);
     580                 :    6615180 :         return t;
     581                 :            :     }
     582         [ +  + ]:    2195250 :     if (isboxed) *isboxed = true;
     583                 :    2195250 :     return JuliaType::get_prjlvalue_ty(ctxt);
     584                 :            : }
     585                 :            : 
     586                 :    9670260 : static Type *julia_type_to_llvm(jl_codectx_t &ctx, jl_value_t *jt, bool *isboxed)
     587                 :            : {
     588                 :    9670260 :     return _julia_type_to_llvm(&ctx.emission_context, ctx.builder.getContext(), jt, isboxed);
     589                 :            : }
     590                 :            : 
     591                 :            : extern "C" JL_DLLEXPORT
     592                 :          0 : Type *jl_type_to_llvm_impl(jl_value_t *jt, LLVMContextRef ctxt, bool *isboxed)
     593                 :            : {
     594                 :          0 :     return _julia_type_to_llvm(NULL, *unwrap(ctxt), jt, isboxed);
     595                 :            : }
     596                 :            : 
     597                 :            : 
     598                 :            : // converts a julia bitstype into the equivalent LLVM bitstype
     599                 :    8763260 : static Type *bitstype_to_llvm(jl_value_t *bt, LLVMContext &ctxt, bool llvmcall = false)
     600                 :            : {
     601         [ -  + ]:    8763260 :     assert(jl_is_primitivetype(bt));
     602         [ +  + ]:    8763260 :     if (bt == (jl_value_t*)jl_bool_type)
     603         [ +  + ]:    1890650 :         return llvmcall ? getInt1Ty(ctxt) : getInt8Ty(ctxt);
     604         [ +  + ]:    6872600 :     if (bt == (jl_value_t*)jl_int32_type)
     605                 :     125271 :         return getInt32Ty(ctxt);
     606         [ +  + ]:    6747330 :     if (bt == (jl_value_t*)jl_int64_type)
     607                 :    3920000 :         return getInt64Ty(ctxt);
     608         [ +  + ]:    2827330 :     if (bt == (jl_value_t*)jl_float16_type)
     609                 :        724 :         return getHalfTy(ctxt);
     610         [ +  + ]:    2826610 :     if (bt == (jl_value_t*)jl_float32_type)
     611                 :       1943 :         return getFloatTy(ctxt);
     612         [ +  + ]:    2824660 :     if (bt == (jl_value_t*)jl_float64_type)
     613                 :      58631 :         return getDoubleTy(ctxt);
     614         [ -  + ]:    2766030 :     if (jl_is_llvmpointer_type(bt)) {
     615                 :          0 :         jl_value_t *as_param = jl_tparam1(bt);
     616                 :            :         int as;
     617         [ #  # ]:          0 :         if (jl_is_int32(as_param))
     618                 :          0 :             as = jl_unbox_int32(as_param);
     619         [ #  # ]:          0 :         else if (jl_is_int64(as_param))
     620                 :          0 :             as = jl_unbox_int64(as_param);
     621                 :            :         else
     622                 :          0 :             jl_error("invalid pointer address space");
     623                 :          0 :         return PointerType::get(getInt8Ty(ctxt), as);
     624                 :            :     }
     625                 :    2766030 :     int nb = jl_datatype_size(bt);
     626                 :    2766030 :     return Type::getIntNTy(ctxt, nb * 8);
     627                 :            : }
     628                 :            : 
     629                 :        671 : static bool jl_type_hasptr(jl_value_t* typ)
     630                 :            : { // assumes that jl_stored_inline(typ) is true (and therefore that layout is defined)
     631   [ +  -  +  + ]:        671 :     return jl_is_datatype(typ) && ((jl_datatype_t*)typ)->layout->npointers > 0;
     632                 :            : }
     633                 :            : 
     634                 :     247819 : static unsigned jl_field_align(jl_datatype_t *dt, size_t i)
     635                 :            : {
     636                 :     247819 :     unsigned al = jl_field_offset(dt, i);
     637                 :     247819 :     al |= 16;
     638                 :     247819 :     al &= -al;
     639                 :     247819 :     return std::min({al, (unsigned)jl_datatype_align(dt), (unsigned)JL_HEAP_ALIGNMENT});
     640                 :            : }
     641                 :            : 
     642                 :    8325870 : static Type *_julia_struct_to_llvm(jl_codegen_params_t *ctx, LLVMContext &ctxt, jl_value_t *jt, bool *isboxed, bool llvmcall)
     643                 :            : {
     644                 :            :     // this function converts a Julia Type into the equivalent LLVM struct
     645                 :            :     // use this where C-compatible (unboxed) structs are desired
     646                 :            :     // use julia_type_to_llvm directly when you want to preserve Julia's type semantics
     647         [ +  + ]:    8325870 :     if (isboxed) *isboxed = false;
     648         [ +  + ]:    8325870 :     if (jt == (jl_value_t*)jl_bottom_type)
     649                 :         50 :         return getVoidTy(ctxt);
     650         [ +  + ]:    8325820 :     if (jl_is_primitivetype(jt))
     651                 :    6922040 :         return bitstype_to_llvm(jt, ctxt, llvmcall);
     652                 :    1403770 :     jl_datatype_t *jst = (jl_datatype_t*)jt;
     653   [ +  +  +  -  :    1403770 :     if (jl_is_structtype(jt) && !(jst->layout && jl_is_layout_opaque(jst->layout))) {
             +  -  +  + ]
     654                 :    1257210 :         bool isTuple = jl_is_tuple_type(jt);
     655         [ +  - ]:    1257210 :         jl_svec_t *ftypes = jl_get_fieldtypes(jst);
     656                 :    1257210 :         size_t i, ntypes = jl_svec_len(ftypes);
     657         [ -  + ]:    1257210 :         if (!jl_struct_try_layout(jst)) {
     658                 :          0 :             assert(0 && "caller should have checked jl_type_mappable_to_c already");
     659                 :            :             abort();
     660                 :            :         }
     661   [ +  +  +  + ]:    1257210 :         if (ntypes == 0 || jl_datatype_nbits(jst) == 0)
     662                 :      44234 :             return getVoidTy(ctxt);
     663                 :    1212980 :         Type *_struct_decl = NULL;
     664                 :            :         // TODO: we should probably make a temporary root for `jst` somewhere
     665                 :            :         // don't use pre-filled struct_decl for llvmcall (f16, etc. may be different)
     666   [ +  -  +  + ]:    1212980 :         Type *&struct_decl = (ctx && !llvmcall ? ctx->llvmtypes[jst] : _struct_decl);
     667         [ +  + ]:    1212980 :         if (struct_decl)
     668                 :    1169540 :             return struct_decl;
     669                 :      43443 :         std::vector<Type*> latypes(0);
     670                 :      43443 :         bool isarray = true;
     671                 :      43443 :         bool isvector = true;
     672                 :      43443 :         jl_value_t *jlasttype = NULL;
     673                 :      43443 :         Type *lasttype = NULL;
     674                 :      43443 :         bool allghost = true;
     675         [ +  + ]:     199134 :         for (i = 0; i < ntypes; i++) {
     676                 :     155691 :             jl_value_t *ty = jl_svecref(ftypes, i);
     677   [ +  +  +  + ]:     155691 :             if (jlasttype != NULL && ty != jlasttype)
     678                 :      42667 :                 isvector = false;
     679                 :     155691 :             jlasttype = ty;
     680         [ -  + ]:     155691 :             if (jl_field_isatomic(jst, i)) {
     681                 :            :                 // TODO: eventually support this?
     682                 :            :                 // though it's a bit unclear how the implicit load should be interpreted
     683                 :          0 :                 assert(0 && "caller should have checked jl_type_mappable_to_c already");
     684                 :            :                 abort();
     685                 :            :             }
     686                 :            :             Type *lty;
     687         [ +  + ]:     155691 :             if (jl_field_isptr(jst, i)) {
     688                 :      47253 :                 lty = JuliaType::get_prjlvalue_ty(ctxt);
     689                 :      47253 :                 isvector = false;
     690                 :            :             }
     691         [ +  + ]:     108438 :             else if (ty == (jl_value_t*)jl_bool_type) {
     692                 :       7934 :                 lty = getInt8Ty(ctxt);
     693                 :            :             }
     694         [ +  + ]:     100504 :             else if (jl_is_uniontype(ty)) {
     695                 :            :                 // pick an Integer type size such that alignment will generally be correct,
     696                 :            :                 // and always end with an Int8 (selector byte).
     697                 :            :                 // We may need to insert padding first to get to the right offset
     698                 :        255 :                 size_t fsz = 0, al = 0;
     699                 :        255 :                 bool isptr = !jl_islayout_inline(ty, &fsz, &al);
     700   [ +  -  +  - ]:        255 :                 assert(!isptr && fsz == jl_field_size(jst, i) - 1); (void)isptr;
     701         [ +  - ]:        255 :                 if (fsz > 0) {
     702         [ -  + ]:        255 :                     if (al > MAX_ALIGN) {
     703                 :            :                         Type *AlignmentType;
     704                 :          0 :                         AlignmentType = ArrayType::get(FixedVectorType::get(getInt8Ty(ctxt), al), 0);
     705                 :          0 :                         latypes.push_back(AlignmentType);
     706                 :          0 :                         al = MAX_ALIGN;
     707                 :            :                     }
     708                 :        255 :                     Type *AlignmentType = IntegerType::get(ctxt, 8 * al);
     709                 :        255 :                     unsigned NumATy = fsz / al;
     710                 :        255 :                     unsigned remainder = fsz % al;
     711   [ +  +  -  + ]:        255 :                     assert(al == 1 || NumATy > 0);
     712         [ +  + ]:        906 :                     while (NumATy--)
     713                 :        651 :                         latypes.push_back(AlignmentType);
     714         [ -  + ]:        255 :                     while (remainder--)
     715                 :          0 :                         latypes.push_back(getInt8Ty(ctxt));
     716                 :            :                 }
     717                 :        255 :                 latypes.push_back(getInt8Ty(ctxt));
     718                 :        255 :                 isarray = false;
     719                 :        255 :                 allghost = false;
     720                 :        255 :                 continue;
     721                 :            :             }
     722                 :            :             else {
     723                 :            :                 bool isptr;
     724                 :     100249 :                 lty = _julia_struct_to_llvm(ctx, ctxt, ty, &isptr, llvmcall);
     725   [ +  -  +  - ]:     100249 :                 assert(lty && !isptr);
     726                 :            :             }
     727   [ +  +  +  + ]:     155436 :             if (lasttype != NULL && lasttype != lty)
     728                 :      31081 :                 isarray = false;
     729                 :     155436 :             lasttype = lty;
     730         [ +  + ]:     155436 :             if (!type_is_ghost(lty)) {
     731                 :     149444 :                 allghost = false;
     732                 :     149444 :                 latypes.push_back(lty);
     733                 :            :             }
     734                 :            :         }
     735         [ -  + ]:      43443 :         if (allghost) {
     736         [ #  # ]:          0 :             assert(jst->layout == NULL); // otherwise should have been caught above
     737                 :          0 :             struct_decl = getVoidTy(ctxt);
     738                 :            :         }
     739   [ +  +  +  -  :      43443 :         else if (jl_is_vecelement_type(jt) && !jl_is_uniontype(jl_svecref(ftypes, 0))) {
                   +  + ]
     740                 :            :             // VecElement type is unwrapped in LLVM (when possible)
     741                 :        146 :             struct_decl = latypes[0];
     742                 :            :         }
     743   [ +  +  +  -  :      43297 :         else if (isarray && !type_is_ghost(lasttype)) {
                   +  + ]
     744   [ +  +  +  +  :      24841 :             if (isTuple && isvector && jl_special_vector_alignment(ntypes, jlasttype) != 0)
             +  +  +  + ]
     745                 :         26 :                 struct_decl = FixedVectorType::get(lasttype, ntypes);
     746   [ +  +  +  - ]:      24815 :             else if (isTuple || !llvmcall)
     747                 :      24815 :                 struct_decl = ArrayType::get(lasttype, ntypes);
     748                 :            :             else
     749                 :          0 :                 struct_decl = StructType::get(ctxt, latypes);
     750                 :            :         }
     751                 :            :         else {
     752                 :            : #if 0 // stress-test code that tries to assume julia-index == llvm-index
     753                 :            :       // (also requires change to emit_new_struct to not assume 0 == 0)
     754                 :            :             if (!isTuple && latypes.size() > 1) {
     755                 :            :                 Type *NoopType = ArrayType::get(getInt1Ty(ctxt), 0);
     756                 :            :                 latypes.insert(latypes.begin(), NoopType);
     757                 :            :             }
     758                 :            : #endif
     759                 :      18456 :             struct_decl = StructType::get(ctxt, latypes);
     760                 :            :         }
     761                 :      43443 :         return struct_decl;
     762                 :            :     }
     763                 :            :     // TODO: enable this (with tests) to change ccall calling convention for Union:
     764                 :            :     // if (jl_is_uniontype(ty)) {
     765                 :            :     //  // pick an Integer type size such that alignment will be correct
     766                 :            :     //  // and always end with an Int8 (selector byte)
     767                 :            :     //  lty = ArrayType::get(IntegerType::get(lty->getContext(), 8 * al), fsz / al);
     768                 :            :     //  std::vector<Type*> Elements(2);
     769                 :            :     //  Elements[0] = lty;
     770                 :            :     //  Elements[1] = getInt8Ty(ctxt);
     771                 :            :     //  unsigned remainder = fsz % al;
     772                 :            :     //  while (remainder--)
     773                 :            :     //      Elements.push_back(getInt8Ty(ctxt));
     774                 :            :     //  lty = StructType::get(lty->getContext(), makeArrayRef(Elements));
     775                 :            :     // }
     776         [ +  - ]:     146558 :     if (isboxed) *isboxed = true;
     777                 :     146558 :     return JuliaType::get_prjlvalue_ty(ctxt);
     778                 :            : }
     779                 :            : 
     780                 :    1238200 : static Type *julia_struct_to_llvm(jl_codectx_t &ctx, jl_value_t *jt, bool *isboxed)
     781                 :            : {
     782                 :    1238200 :     return _julia_struct_to_llvm(&ctx.emission_context, ctx.builder.getContext(), jt, isboxed);
     783                 :            : }
     784                 :            : 
     785                 :       9552 : static bool is_datatype_all_pointers(jl_datatype_t *dt)
     786                 :            : {
     787                 :       9552 :     size_t i, l = jl_datatype_nfields(dt);
     788         [ +  + ]:      34808 :     for (i = 0; i < l; i++) {
     789         [ +  + ]:      29890 :         if (!jl_field_isptr(dt, i)) {
     790                 :       4634 :             return false;
     791                 :            :         }
     792                 :            :     }
     793                 :       4918 :     return true;
     794                 :            : }
     795                 :            : 
     796                 :      12049 : static bool is_tupletype_homogeneous(jl_svec_t *t, bool allow_va = false)
     797                 :            : {
     798                 :      12049 :     size_t i, l = jl_svec_len(t);
     799         [ +  - ]:      12049 :     if (l > 0) {
     800                 :      12049 :         jl_value_t *t0 = jl_svecref(t, 0);
     801         [ +  + ]:      12049 :         if (!jl_is_concrete_type(t0)) {
     802   [ +  +  +  +  :       4018 :             if (allow_va && jl_is_vararg(t0) &&
             +  +  +  + ]
     803                 :        713 :                   jl_is_concrete_type(jl_unwrap_vararg(t0)))
     804                 :        429 :                 return true;
     805                 :       2876 :             return false;
     806                 :            :         }
     807         [ +  + ]:      68530 :         for (i = 1; i < l; i++) {
     808   [ +  +  +  +  :      66358 :             if (allow_va && i == l - 1 && jl_is_vararg(jl_svecref(t, i))) {
             -  +  -  + ]
     809         [ #  # ]:          0 :                 if (t0 != jl_unwrap_vararg(jl_svecref(t, i)))
     810                 :          0 :                     return false;
     811                 :          0 :                 continue;
     812                 :            :             }
     813         [ +  + ]:      66358 :             if (t0 != jl_svecref(t, i))
     814                 :       6572 :                 return false;
     815                 :            :         }
     816                 :            :     }
     817                 :       2172 :     return true;
     818                 :            : }
     819                 :            : 
     820                 :     427760 : static bool for_each_uniontype_small(
     821                 :            :         std::function<void(unsigned, jl_datatype_t*)> f,
     822                 :            :         jl_value_t *ty,
     823                 :            :         unsigned &counter)
     824                 :            : {
     825         [ -  + ]:     427760 :     if (counter > 127)
     826                 :          0 :         return false;
     827         [ +  + ]:     427760 :     if (jl_is_uniontype(ty)) {
     828                 :     145755 :         bool allunbox = for_each_uniontype_small(f, ((jl_uniontype_t*)ty)->a, counter);
     829                 :     145755 :         allunbox &= for_each_uniontype_small(f, ((jl_uniontype_t*)ty)->b, counter);
     830                 :     145755 :         return allunbox;
     831                 :            :     }
     832         [ +  + ]:     282005 :     else if (jl_is_pointerfree(ty)) {
     833                 :     216031 :         f(++counter, (jl_datatype_t*)ty);
     834                 :     216031 :         return true;
     835                 :            :     }
     836                 :      65974 :     return false;
     837                 :            : }
     838                 :            : 
     839                 :       4764 : static bool is_uniontype_allunboxed(jl_value_t *typ)
     840                 :            : {
     841                 :       4764 :     unsigned counter = 0;
     842                 :       4764 :     return for_each_uniontype_small([&](unsigned, jl_datatype_t*) {}, typ, counter);
     843                 :            : }
     844                 :            : 
     845                 :            : static Value *emit_typeof_boxed(jl_codectx_t &ctx, const jl_cgval_t &p, bool maybenull=false);
     846                 :            : 
     847                 :      51315 : static unsigned get_box_tindex(jl_datatype_t *jt, jl_value_t *ut)
     848                 :            : {
     849                 :      51315 :     unsigned new_idx = 0;
     850                 :      51315 :     unsigned new_counter = 0;
     851                 :      51315 :     for_each_uniontype_small(
     852                 :            :             // find the corresponding index in the new union-type
     853                 :      92435 :             [&](unsigned new_idx_, jl_datatype_t *new_jt) {
     854         [ +  + ]:      92435 :                 if (jt == new_jt)
     855                 :      45533 :                     new_idx = new_idx_;
     856                 :      92435 :             },
     857                 :            :             ut,
     858                 :            :             new_counter);
     859                 :      51315 :     return new_idx;
     860                 :            : }
     861                 :            : 
     862                 :            : 
     863                 :            : // --- generating various field accessors ---
     864                 :            : 
     865                 :            : static Constant *julia_const_to_llvm(jl_codectx_t &ctx, jl_value_t *e);
     866                 :            : 
     867                 :     784375 : static Value *data_pointer(jl_codectx_t &ctx, const jl_cgval_t &x)
     868                 :            : {
     869         [ -  + ]:     784375 :     assert(x.ispointer());
     870                 :            :     Value *data;
     871         [ +  + ]:     784375 :     if (x.constant) {
     872                 :      64832 :         Constant *val = julia_const_to_llvm(ctx, x.constant);
     873         [ +  + ]:      64832 :         if (val)
     874                 :      51475 :             data = get_pointer_to_constant(ctx.emission_context, val, "_j_const", *jl_Module);
     875                 :            :         else
     876                 :      13357 :             data = literal_pointer_val(ctx, x.constant);
     877                 :            :     }
     878         [ -  + ]:     719543 :     else if (x.V == NULL) {
     879                 :            :         // might be a ghost union with tindex but no actual pointer
     880                 :          0 :         data = NULL;
     881                 :            :     }
     882                 :            :     else {
     883                 :     719543 :         data = maybe_decay_tracked(ctx, x.V);
     884                 :            :     }
     885                 :     784375 :     return data;
     886                 :            : }
     887                 :            : 
     888                 :     155618 : static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, MDNode *tbaa_dst, Value *src, MDNode *tbaa_src,
     889                 :            :                              uint64_t sz, unsigned align, bool is_volatile)
     890                 :            : {
     891         [ -  + ]:     155618 :     if (sz == 0)
     892                 :          0 :         return;
     893         [ -  + ]:     155618 :     assert(align && "align must be specified");
     894                 :            :     // If the types are small and simple, use load and store directly.
     895                 :            :     // Going through memcpy can cause LLVM (e.g. SROA) to create bitcasts between float and int
     896                 :            :     // that interferes with other optimizations.
     897                 :            : #ifndef JL_LLVM_OPAQUE_POINTERS
     898                 :            :     // TODO: Restore this for opaque pointers? Needs extra type information from the caller.
     899         [ +  + ]:     155618 :     if (sz <= 64) {
     900                 :            :         // The size limit is arbitrary but since we mainly care about floating points and
     901                 :            :         // machine size vectors this should be enough.
     902                 :     153036 :         const DataLayout &DL = jl_Module->getDataLayout();
     903                 :     153036 :         auto srcty = cast<PointerType>(src->getType());
     904                 :            :         //TODO unsafe nonopaque pointer
     905                 :     153036 :         auto srcel = srcty->getPointerElementType();
     906                 :     153036 :         auto dstty = cast<PointerType>(dst->getType());
     907                 :            :         //TODO unsafe nonopaque pointer
     908                 :     153036 :         auto dstel = dstty->getPointerElementType();
     909   [ +  +  +  +  :     188398 :         while (srcel->isArrayTy() && srcel->getArrayNumElements() == 1) {
                   +  + ]
     910                 :      35362 :             src = ctx.builder.CreateConstInBoundsGEP2_32(srcel, src, 0, 0);
     911                 :      35362 :             srcel = srcel->getArrayElementType();
     912                 :      35362 :             srcty = srcel->getPointerTo();
     913                 :            :         }
     914   [ +  +  +  +  :     181679 :         while (dstel->isArrayTy() && dstel->getArrayNumElements() == 1) {
                   +  + ]
     915                 :      28643 :             dst = ctx.builder.CreateConstInBoundsGEP2_32(dstel, dst, 0, 0);
     916                 :      28643 :             dstel = dstel->getArrayElementType();
     917                 :      28643 :             dstty = dstel->getPointerTo();
     918                 :            :         }
     919                 :            : 
     920                 :     153036 :         llvm::Type *directel = nullptr;
     921   [ +  -  +  +  :     153036 :         if (srcel->isSized() && srcel->isSingleValueType() && DL.getTypeStoreSize(srcel) == sz) {
             +  +  +  + ]
     922                 :      74893 :             directel = srcel;
     923                 :      74893 :             dst = emit_bitcast(ctx, dst, srcty);
     924                 :            :         }
     925   [ +  -  +  +  :      91268 :         else if (dstel->isSized() && dstel->isSingleValueType() &&
                   +  + ]
     926         [ +  + ]:      91268 :                  DL.getTypeStoreSize(dstel) == sz) {
     927                 :       2204 :             directel = dstel;
     928                 :       2204 :             src = emit_bitcast(ctx, src, dstty);
     929                 :            :         }
     930         [ +  + ]:     153036 :         if (directel) {
     931                 :      77097 :             auto val = tbaa_decorate(tbaa_src, ctx.builder.CreateAlignedLoad(directel, src, Align(align), is_volatile));
     932                 :      77097 :             tbaa_decorate(tbaa_dst, ctx.builder.CreateAlignedStore(val, dst, Align(align), is_volatile));
     933                 :      77097 :             ++SkippedMemcpys;
     934                 :      77097 :             return;
     935                 :            :         }
     936                 :            :     }
     937                 :            : #endif
     938                 :            :     // the memcpy intrinsic does not allow to specify different alias tags
     939                 :            :     // for the load part (x.tbaa) and the store part (ctx.tbaa().tbaa_stack).
     940                 :            :     // since the tbaa lattice has to be a tree we have unfortunately
     941                 :            :     // x.tbaa ∪ ctx.tbaa().tbaa_stack = tbaa_root if x.tbaa != ctx.tbaa().tbaa_stack
     942                 :      78521 :     ++EmittedMemcpys;
     943                 :      78521 :     ctx.builder.CreateMemCpy(dst, MaybeAlign(align), src, MaybeAlign(0), sz, is_volatile, MDNode::getMostGenericTBAA(tbaa_dst, tbaa_src));
     944                 :            : }
     945                 :            : 
     946                 :       2574 : static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, MDNode *tbaa_dst, Value *src, MDNode *tbaa_src,
     947                 :            :                              Value *sz, unsigned align, bool is_volatile)
     948                 :            : {
     949         [ +  + ]:       2574 :     if (auto const_sz = dyn_cast<ConstantInt>(sz)) {
     950                 :       2572 :         emit_memcpy_llvm(ctx, dst, tbaa_dst, src, tbaa_src, const_sz->getZExtValue(), align, is_volatile);
     951                 :       2572 :         return;
     952                 :            :     }
     953                 :          2 :     ++EmittedMemcpys;
     954                 :          2 :     ctx.builder.CreateMemCpy(dst, MaybeAlign(align), src, MaybeAlign(0), sz, is_volatile, MDNode::getMostGenericTBAA(tbaa_dst, tbaa_src));
     955                 :            : }
     956                 :            : 
     957                 :            : template<typename T1>
     958                 :     111497 : static void emit_memcpy(jl_codectx_t &ctx, Value *dst, MDNode *tbaa_dst, Value *src, MDNode *tbaa_src,
     959                 :            :                         T1 &&sz, unsigned align, bool is_volatile=false)
     960                 :            : {
     961                 :     111497 :     emit_memcpy_llvm(ctx, dst, tbaa_dst, src, tbaa_src, sz, align, is_volatile);
     962                 :     111497 : }
     963                 :            : 
     964                 :            : template<typename T1>
     965                 :      44123 : static void emit_memcpy(jl_codectx_t &ctx, Value *dst, MDNode *tbaa_dst, const jl_cgval_t &src,
     966                 :            :                         T1 &&sz, unsigned align, bool is_volatile=false)
     967                 :            : {
     968                 :      44123 :     emit_memcpy_llvm(ctx, dst, tbaa_dst, data_pointer(ctx, src), src.tbaa, sz, align, is_volatile);
     969                 :      44123 : }
     970                 :            : 
     971                 :       1570 : static Value *emit_nthptr_addr(jl_codectx_t &ctx, Value *v, ssize_t n, bool gctracked = true)
     972                 :            : {
     973                 :       1570 :     ++EmittedNthPtrAddr;
     974                 :       6280 :     return ctx.builder.CreateInBoundsGEP(
     975                 :       1570 :             ctx.types().T_prjlvalue,
     976                 :       1570 :             emit_bitcast(ctx, maybe_decay_tracked(ctx, v), ctx.types().T_pprjlvalue),
     977                 :       3140 :             ConstantInt::get(getSizeTy(ctx.builder.getContext()), n));
     978                 :            : }
     979                 :            : 
     980                 :       1307 : static Value *emit_nthptr_addr(jl_codectx_t &ctx, Value *v, Value *idx)
     981                 :            : {
     982                 :       1307 :     ++EmittedNthPtrAddr;
     983                 :       5228 :     return ctx.builder.CreateInBoundsGEP(
     984                 :       1307 :             ctx.types().T_prjlvalue,
     985                 :       1307 :             emit_bitcast(ctx, maybe_decay_tracked(ctx, v), ctx.types().T_pprjlvalue),
     986                 :       1307 :             idx);
     987                 :            : }
     988                 :            : 
     989                 :       1307 : static LoadInst *emit_nthptr_recast(jl_codectx_t &ctx, Value *v, Value *idx, MDNode *tbaa, Type *type)
     990                 :            : {
     991                 :            :     // p = (jl_value_t**)v; *(type*)&p[n]
     992                 :       1307 :     Value *vptr = emit_nthptr_addr(ctx, v, idx);
     993                 :       3921 :     return cast<LoadInst>(tbaa_decorate(tbaa, ctx.builder.CreateLoad(type,
     994                 :       2614 :         emit_bitcast(ctx, vptr, PointerType::get(type, 0)))));
     995                 :            : }
     996                 :            : 
     997                 :        304 : static LoadInst *emit_nthptr_recast(jl_codectx_t &ctx, Value *v, ssize_t n, MDNode *tbaa, Type *type)
     998                 :            : {
     999                 :            :     // p = (jl_value_t**)v; *(type*)&p[n]
    1000                 :        304 :     Value *vptr = emit_nthptr_addr(ctx, v, n);
    1001                 :        912 :     return cast<LoadInst>(tbaa_decorate(tbaa, ctx.builder.CreateLoad(type,
    1002                 :        608 :         emit_bitcast(ctx, vptr, PointerType::get(type, 0)))));
    1003                 :            :  }
    1004                 :            : 
    1005                 :            : static Value *boxed(jl_codectx_t &ctx, const jl_cgval_t &v);
    1006                 :            : static Value *emit_typeof(jl_codectx_t &ctx, Value *v, bool maybenull);
    1007                 :            : 
    1008                 :     158714 : static jl_cgval_t emit_typeof(jl_codectx_t &ctx, const jl_cgval_t &p, bool maybenull)
    1009                 :            : {
    1010                 :            :     // given p, compute its type
    1011         [ +  + ]:     158714 :     if (p.constant)
    1012                 :       2585 :         return mark_julia_const(ctx, jl_typeof(p.constant));
    1013   [ +  +  +  +  :     156129 :     if (p.isboxed && !jl_is_concrete_type(p.typ)) {
                   +  + ]
    1014         [ -  + ]:     148619 :         if (jl_is_type_type(p.typ)) {
    1015                 :          0 :             jl_value_t *tp = jl_tparam0(p.typ);
    1016   [ #  #  #  #  :          0 :             if (!jl_is_type(tp) || jl_is_concrete_type(tp)) {
                   #  # ]
    1017                 :            :                 // convert 1::Type{1} ==> typeof(1) ==> Int
    1018                 :          0 :                 return mark_julia_const(ctx, jl_typeof(tp));
    1019                 :            :             }
    1020                 :            :         }
    1021                 :     148619 :         return mark_julia_type(ctx, emit_typeof(ctx, p.V, maybenull), true, jl_datatype_type);
    1022                 :            :     }
    1023         [ +  + ]:       7510 :     if (p.TIndex) {
    1024                 :       4590 :         Value *tindex = ctx.builder.CreateAnd(p.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x7f));
    1025                 :       4590 :         bool allunboxed = is_uniontype_allunboxed(p.typ);
    1026         [ +  + ]:       4590 :         Value *datatype_or_p = ctx.emission_context.imaging ? Constant::getNullValue(ctx.types().T_ppjlvalue) : Constant::getNullValue(ctx.types().T_prjlvalue);
    1027                 :       4590 :         unsigned counter = 0;
    1028                 :       4590 :         for_each_uniontype_small(
    1029                 :       9024 :             [&](unsigned idx, jl_datatype_t *jt) {
    1030                 :       9024 :                 Value *cmp = ctx.builder.CreateICmpEQ(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), idx));
    1031                 :            :                 Value *ptr;
    1032         [ +  + ]:       9024 :                 if (ctx.emission_context.imaging) {
    1033                 :       5676 :                     ptr = literal_pointer_val_slot(ctx, (jl_value_t*)jt);
    1034                 :            :                 }
    1035                 :            :                 else {
    1036                 :       3348 :                     ptr = track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)jt));
    1037                 :            :                 }
    1038                 :       9024 :                 datatype_or_p = ctx.builder.CreateSelect(cmp, ptr, datatype_or_p);
    1039                 :       9024 :             },
    1040                 :       4590 :             p.typ,
    1041                 :            :             counter);
    1042                 :       4590 :         auto emit_unboxty = [&] () -> Value* {
    1043         [ +  + ]:       4590 :             if (ctx.emission_context.imaging)
    1044                 :       2888 :                 return track_pjlvalue(
    1045                 :       5776 :                     ctx, tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(ctx.types().T_pjlvalue, datatype_or_p, Align(sizeof(void*)))));
    1046                 :       1702 :             return datatype_or_p;
    1047                 :       4590 :         };
    1048                 :            :         Value *res;
    1049         [ +  + ]:       4590 :         if (!allunboxed) {
    1050                 :        186 :             Value *isnull = ctx.builder.CreateIsNull(datatype_or_p);
    1051                 :        186 :             BasicBlock *boxBB = BasicBlock::Create(ctx.builder.getContext(), "boxed", ctx.f);
    1052                 :        186 :             BasicBlock *unboxBB = BasicBlock::Create(ctx.builder.getContext(), "unboxed", ctx.f);
    1053                 :        186 :             BasicBlock *mergeBB = BasicBlock::Create(ctx.builder.getContext(), "merge", ctx.f);
    1054                 :        186 :             ctx.builder.CreateCondBr(isnull, boxBB, unboxBB);
    1055                 :        186 :             ctx.builder.SetInsertPoint(boxBB);
    1056                 :        186 :             auto boxTy = emit_typeof(ctx, p.Vboxed, maybenull);
    1057                 :        186 :             ctx.builder.CreateBr(mergeBB);
    1058                 :        186 :             boxBB = ctx.builder.GetInsertBlock(); // could have changed
    1059                 :        186 :             ctx.builder.SetInsertPoint(unboxBB);
    1060                 :        186 :             auto unboxTy = emit_unboxty();
    1061                 :        186 :             ctx.builder.CreateBr(mergeBB);
    1062                 :        186 :             unboxBB = ctx.builder.GetInsertBlock(); // could have changed
    1063                 :        186 :             ctx.builder.SetInsertPoint(mergeBB);
    1064                 :        186 :             auto phi = ctx.builder.CreatePHI(ctx.types().T_prjlvalue, 2);
    1065                 :        186 :             phi->addIncoming(boxTy, boxBB);
    1066                 :        186 :             phi->addIncoming(unboxTy, unboxBB);
    1067                 :        186 :             res = phi;
    1068                 :            :         }
    1069                 :            :         else {
    1070                 :       4404 :             res = emit_unboxty();
    1071                 :            :         }
    1072                 :       4590 :         return mark_julia_type(ctx, res, true, jl_datatype_type);
    1073                 :            :     }
    1074                 :       2920 :     return mark_julia_const(ctx, p.typ);
    1075                 :            : }
    1076                 :            : 
    1077                 :            : // Returns ctx.types().T_prjlvalue
    1078                 :     154463 : static Value *emit_typeof_boxed(jl_codectx_t &ctx, const jl_cgval_t &p, bool maybenull)
    1079                 :            : {
    1080                 :     154463 :     return boxed(ctx, emit_typeof(ctx, p, maybenull));
    1081                 :            : }
    1082                 :            : 
    1083                 :       1563 : static Value *emit_datatype_types(jl_codectx_t &ctx, Value *dt)
    1084                 :            : {
    1085                 :       1563 :     Value *Ptr = emit_bitcast(ctx, decay_derived(ctx, dt), ctx.types().T_ppjlvalue);
    1086                 :       1563 :     Value *Idx = ConstantInt::get(getSizeTy(ctx.builder.getContext()), offsetof(jl_datatype_t, types) / sizeof(void*));
    1087                 :       6252 :     return tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(
    1088                 :       6252 :                 ctx.types().T_pjlvalue, ctx.builder.CreateInBoundsGEP(ctx.types().T_pjlvalue, Ptr, Idx), Align(sizeof(void*))));
    1089                 :            : }
    1090                 :            : 
    1091                 :       1349 : static Value *emit_datatype_nfields(jl_codectx_t &ctx, Value *dt)
    1092                 :            : {
    1093                 :       1349 :     Value *type_svec = emit_bitcast(ctx, emit_datatype_types(ctx, dt), getSizePtrTy(ctx.builder.getContext()));
    1094                 :       1349 :     return tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(getSizeTy(ctx.builder.getContext()), type_svec, Align(sizeof(void*))));
    1095                 :            : }
    1096                 :            : 
    1097                 :         16 : static Value *emit_datatype_size(jl_codectx_t &ctx, Value *dt)
    1098                 :            : {
    1099                 :         16 :     Value *Ptr = emit_bitcast(ctx, decay_derived(ctx, dt), getInt32PtrTy(ctx.builder.getContext()));
    1100                 :         16 :     Value *Idx = ConstantInt::get(getSizeTy(ctx.builder.getContext()), offsetof(jl_datatype_t, size) / sizeof(int));
    1101                 :         16 :     return tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(getInt32Ty(ctx.builder.getContext()), ctx.builder.CreateInBoundsGEP(getInt32Ty(ctx.builder.getContext()), Ptr, Idx), Align(sizeof(int32_t))));
    1102                 :            : }
    1103                 :            : 
    1104                 :            : /* this is valid code, it's simply unused
    1105                 :            : static Value *emit_sizeof(jl_codectx_t &ctx, const jl_cgval_t &p)
    1106                 :            : {
    1107                 :            :     if (p.TIndex) {
    1108                 :            :         Value *tindex = ctx.builder.CreateAnd(p.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x7f));
    1109                 :            :         Value *size = ConstantInt::get(getInt32Ty(ctx.builder.getContext()), -1);
    1110                 :            :         unsigned counter = 0;
    1111                 :            :         bool allunboxed = for_each_uniontype_small(
    1112                 :            :                 [&](unsigned idx, jl_datatype_t *jt) {
    1113                 :            :                     Value *cmp = ctx.builder.CreateICmpEQ(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), idx));
    1114                 :            :                     size = ctx.builder.CreateSelect(cmp, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), jl_datatype_size(jt)), size);
    1115                 :            :                 },
    1116                 :            :                 p.typ,
    1117                 :            :                 counter);
    1118                 :            :         if (!allunboxed && p.ispointer() && p.V && !isa<AllocaInst>(p.V)) {
    1119                 :            :             BasicBlock *currBB = ctx.builder.GetInsertBlock();
    1120                 :            :             BasicBlock *dynloadBB = BasicBlock::Create(ctx.builder.getContext(), "dyn_sizeof", ctx.f);
    1121                 :            :             BasicBlock *postBB = BasicBlock::Create(ctx.builder.getContext(), "post_sizeof", ctx.f);
    1122                 :            :             Value *isboxed = ctx.builder.CreateICmpNE(
    1123                 :            :                     ctx.builder.CreateAnd(p.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80)),
    1124                 :            :                     ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0));
    1125                 :            :             ctx.builder.CreateCondBr(isboxed, dynloadBB, postBB);
    1126                 :            :             ctx.builder.SetInsertPoint(dynloadBB);
    1127                 :            :             Value *datatype = emit_typeof(p.V);
    1128                 :            :             Value *dyn_size = emit_datatype_size(ctx, datatype);
    1129                 :            :             ctx.builder.CreateBr(postBB);
    1130                 :            :             dynloadBB = ctx.builder.GetInsertBlock(); // could have changed
    1131                 :            :             ctx.builder.SetInsertPoint(postBB);
    1132                 :            :             PHINode *sizeof_merge = ctx.builder.CreatePHI(getInt32Ty(ctx.builder.getContext()), 2);
    1133                 :            :             sizeof_merge->addIncoming(dyn_size, dynloadBB);
    1134                 :            :             sizeof_merge->addIncoming(size, currBB);
    1135                 :            :             size = sizeof_merge;
    1136                 :            :         }
    1137                 :            : #ifndef NDEBUG
    1138                 :            :         // try to catch codegen errors early, before it uses this to memcpy over the entire stack
    1139                 :            :         CreateConditionalAbort(ctx.builder, ctx.builder.CreateICmpEQ(size, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), -1)));
    1140                 :            : #endif
    1141                 :            :         return size;
    1142                 :            :     }
    1143                 :            :     else if (jl_is_concrete_type(p.typ)) {
    1144                 :            :         return ConstantInt::get(getInt32Ty(ctx.builder.getContext()), jl_datatype_size(p.typ));
    1145                 :            :     }
    1146                 :            :     else {
    1147                 :            :         Value *datatype = emit_typeof_boxed(ctx, p);
    1148                 :            :         Value *dyn_size = emit_datatype_size(ctx, datatype);
    1149                 :            :         return dyn_size;
    1150                 :            :     }
    1151                 :            : }
    1152                 :            : */
    1153                 :            : 
    1154                 :          7 : static Value *emit_datatype_mutabl(jl_codectx_t &ctx, Value *dt)
    1155                 :            : {
    1156                 :          7 :     Value *Ptr = emit_bitcast(ctx, decay_derived(ctx, dt), ctx.types().T_ppint8);
    1157                 :          7 :     Value *Idx = ConstantInt::get(getSizeTy(ctx.builder.getContext()), offsetof(jl_datatype_t, name));
    1158                 :          7 :     Value *Nam = tbaa_decorate(ctx.tbaa().tbaa_const,
    1159                 :          7 :             ctx.builder.CreateAlignedLoad(getInt8PtrTy(ctx.builder.getContext()), ctx.builder.CreateInBoundsGEP(getInt8PtrTy(ctx.builder.getContext()), Ptr, Idx), Align(sizeof(int8_t*))));
    1160                 :          7 :     Value *Idx2 = ConstantInt::get(getSizeTy(ctx.builder.getContext()), offsetof(jl_typename_t, n_uninitialized) + sizeof(((jl_typename_t*)nullptr)->n_uninitialized));
    1161                 :          7 :     Value *mutabl = tbaa_decorate(ctx.tbaa().tbaa_const,
    1162                 :          7 :             ctx.builder.CreateAlignedLoad(getInt8Ty(ctx.builder.getContext()), ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), Nam, Idx2), Align(1)));
    1163                 :          7 :     mutabl = ctx.builder.CreateLShr(mutabl, 1);
    1164                 :          7 :     return ctx.builder.CreateTrunc(mutabl, getInt1Ty(ctx.builder.getContext()));
    1165                 :            : }
    1166                 :            : 
    1167                 :          7 : static Value *emit_datatype_isprimitivetype(jl_codectx_t &ctx, Value *dt)
    1168                 :            : {
    1169                 :          7 :     Value *immut = ctx.builder.CreateNot(emit_datatype_mutabl(ctx, dt));
    1170                 :          7 :     Value *nofields = ctx.builder.CreateICmpEQ(emit_datatype_nfields(ctx, dt), Constant::getNullValue(getSizeTy(ctx.builder.getContext())));
    1171                 :          7 :     Value *sized = ctx.builder.CreateICmpSGT(emit_datatype_size(ctx, dt), ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0));
    1172                 :          7 :     return ctx.builder.CreateAnd(immut, ctx.builder.CreateAnd(nofields, sized));
    1173                 :            : }
    1174                 :            : 
    1175                 :       1266 : static Value *emit_datatype_name(jl_codectx_t &ctx, Value *dt)
    1176                 :            : {
    1177                 :       1266 :     Value *vptr = emit_nthptr_addr(ctx, dt, (ssize_t)(offsetof(jl_datatype_t, name) / sizeof(char*)));
    1178                 :       1266 :     return tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, vptr, Align(sizeof(void*))));
    1179                 :            : }
    1180                 :            : 
    1181                 :            : // --- generating various error checks ---
    1182                 :            : // Do not use conditional throw for cases that type inference can know
    1183                 :            : // the error is always thrown. This may cause non dominated use
    1184                 :            : // of SSA value error in the verifier.
    1185                 :            : 
    1186                 :        116 : static void just_emit_error(jl_codectx_t &ctx, Function *F, const std::string &txt)
    1187                 :            : {
    1188                 :        116 :     ++EmittedErrors;
    1189                 :        116 :     ctx.builder.CreateCall(F, stringConstPtr(ctx.emission_context, ctx.builder, txt));
    1190                 :        116 : }
    1191                 :            : 
    1192                 :          0 : static void emit_error(jl_codectx_t &ctx, Function *F, const std::string &txt)
    1193                 :            : {
    1194                 :          0 :     just_emit_error(ctx, F, txt);
    1195                 :          0 :     ctx.builder.CreateUnreachable();
    1196                 :          0 :     BasicBlock *cont = BasicBlock::Create(ctx.builder.getContext(), "after_error", ctx.f);
    1197                 :          0 :     ctx.builder.SetInsertPoint(cont);
    1198                 :          0 : }
    1199                 :            : 
    1200                 :          0 : static void emit_error(jl_codectx_t &ctx, const std::string &txt)
    1201                 :            : {
    1202                 :          0 :     emit_error(ctx, prepare_call(jlerror_func), txt);
    1203                 :          0 : }
    1204                 :            : 
    1205                 :            : // DO NOT PASS IN A CONST CONDITION!
    1206                 :        116 : static void error_unless(jl_codectx_t &ctx, Value *cond, const std::string &msg)
    1207                 :            : {
    1208                 :        116 :     ++EmittedConditionalErrors;
    1209                 :        116 :     BasicBlock *failBB = BasicBlock::Create(ctx.builder.getContext(), "fail", ctx.f);
    1210                 :        116 :     BasicBlock *passBB = BasicBlock::Create(ctx.builder.getContext(), "pass");
    1211                 :        116 :     ctx.builder.CreateCondBr(cond, passBB, failBB);
    1212                 :        116 :     ctx.builder.SetInsertPoint(failBB);
    1213                 :        116 :     just_emit_error(ctx, prepare_call(jlerror_func), msg);
    1214                 :        116 :     ctx.builder.CreateUnreachable();
    1215                 :        116 :     ctx.f->getBasicBlockList().push_back(passBB);
    1216                 :        116 :     ctx.builder.SetInsertPoint(passBB);
    1217                 :        116 : }
    1218                 :            : 
    1219                 :     162767 : static void raise_exception(jl_codectx_t &ctx, Value *exc,
    1220                 :            :                             BasicBlock *contBB=nullptr)
    1221                 :            : {
    1222                 :     162767 :     ++EmittedExceptions;
    1223                 :     162767 :     ctx.builder.CreateCall(prepare_call(jlthrow_func), { mark_callee_rooted(ctx, exc) });
    1224                 :     162767 :     ctx.builder.CreateUnreachable();
    1225         [ +  + ]:     162767 :     if (!contBB) {
    1226                 :      79237 :         contBB = BasicBlock::Create(ctx.builder.getContext(), "after_throw", ctx.f);
    1227                 :            :     }
    1228                 :            :     else {
    1229                 :      83530 :         ctx.f->getBasicBlockList().push_back(contBB);
    1230                 :            :     }
    1231                 :     162767 :     ctx.builder.SetInsertPoint(contBB);
    1232                 :     162767 : }
    1233                 :            : 
    1234                 :            : // DO NOT PASS IN A CONST CONDITION!
    1235                 :      83530 : static void raise_exception_unless(jl_codectx_t &ctx, Value *cond, Value *exc)
    1236                 :            : {
    1237                 :      83530 :     ++EmittedConditionalExceptions;
    1238                 :      83530 :     BasicBlock *failBB = BasicBlock::Create(ctx.builder.getContext(),"fail",ctx.f);
    1239                 :      83530 :     BasicBlock *passBB = BasicBlock::Create(ctx.builder.getContext(),"pass");
    1240                 :      83530 :     ctx.builder.CreateCondBr(cond, passBB, failBB);
    1241                 :      83530 :     ctx.builder.SetInsertPoint(failBB);
    1242                 :      83530 :     raise_exception(ctx, exc, passBB);
    1243                 :      83530 : }
    1244                 :            : 
    1245                 :     135518 : static Value *null_pointer_cmp(jl_codectx_t &ctx, Value *v)
    1246                 :            : {
    1247                 :     135518 :     ++EmittedNullchecks;
    1248                 :     135518 :     return ctx.builder.CreateICmpNE(v, Constant::getNullValue(v->getType()));
    1249                 :            : }
    1250                 :            : 
    1251                 :            : 
    1252                 :            : // If `nullcheck` is not NULL and a pointer NULL check is necessary
    1253                 :            : // store the pointer to be checked in `*nullcheck` instead of checking it
    1254                 :      76778 : static void null_pointer_check(jl_codectx_t &ctx, Value *v, Value **nullcheck = nullptr)
    1255                 :            : {
    1256         [ +  + ]:      76778 :     if (nullcheck) {
    1257                 :          8 :         *nullcheck = v;
    1258                 :          8 :         return;
    1259                 :            :     }
    1260                 :      76770 :     raise_exception_unless(ctx, null_pointer_cmp(ctx, v),
    1261                 :            :             literal_pointer_val(ctx, jl_undefref_exception));
    1262                 :            : }
    1263                 :            : 
    1264                 :            : template<typename Func>
    1265                 :    1169436 : static Value *emit_guarded_test(jl_codectx_t &ctx, Value *ifnot, Value *defval, Func &&func)
    1266                 :            : {
    1267         [ +  + ]:    1169436 :     if (auto Cond = dyn_cast<ConstantInt>(ifnot)) {
    1268         [ -  + ]:    1041235 :         if (Cond->isZero())
    1269                 :          0 :             return defval;
    1270                 :    1041235 :         return func();
    1271                 :            :     }
    1272                 :     128206 :     ++EmittedGuards;
    1273                 :     128206 :     BasicBlock *currBB = ctx.builder.GetInsertBlock();
    1274                 :     128206 :     BasicBlock *passBB = BasicBlock::Create(ctx.builder.getContext(), "guard_pass", ctx.f);
    1275                 :     128206 :     BasicBlock *exitBB = BasicBlock::Create(ctx.builder.getContext(), "guard_exit", ctx.f);
    1276                 :     128206 :     ctx.builder.CreateCondBr(ifnot, passBB, exitBB);
    1277                 :     128206 :     ctx.builder.SetInsertPoint(passBB);
    1278                 :     128206 :     auto res = func();
    1279                 :     128206 :     passBB = ctx.builder.GetInsertBlock();
    1280                 :     128206 :     ctx.builder.CreateBr(exitBB);
    1281                 :     128206 :     ctx.builder.SetInsertPoint(exitBB);
    1282         [ +  + ]:     128206 :     if (defval == nullptr)
    1283                 :      21387 :         return nullptr;
    1284                 :     106819 :     PHINode *phi = ctx.builder.CreatePHI(defval->getType(), 2);
    1285                 :     106819 :     phi->addIncoming(defval, currBB);
    1286                 :     106819 :     phi->addIncoming(res, passBB);
    1287                 :     106819 :     return phi;
    1288                 :            : }
    1289                 :            : 
    1290                 :            : template<typename Func>
    1291                 :      69824 : static Value *emit_guarded_test(jl_codectx_t &ctx, Value *ifnot, bool defval, Func &&func)
    1292                 :            : {
    1293                 :      69824 :     return emit_guarded_test(ctx, ifnot, ConstantInt::get(getInt1Ty(ctx.builder.getContext()), defval), func);
    1294                 :            : }
    1295                 :            : 
    1296                 :            : template<typename Func>
    1297                 :    1334401 : static Value *emit_nullcheck_guard(jl_codectx_t &ctx, Value *nullcheck, Func &&func)
    1298                 :            : {
    1299         [ +  + ]:    1334401 :     if (!nullcheck)
    1300                 :    1277381 :         return func();
    1301                 :      57016 :     return emit_guarded_test(ctx, null_pointer_cmp(ctx, nullcheck), false, func);
    1302                 :            : }
    1303                 :            : 
    1304                 :            : template<typename Func>
    1305                 :     232833 : static Value *emit_nullcheck_guard2(jl_codectx_t &ctx, Value *nullcheck1,
    1306                 :            :                                     Value *nullcheck2, Func &&func)
    1307                 :            : {
    1308         [ +  + ]:     232833 :     if (!nullcheck1)
    1309                 :     232829 :         return emit_nullcheck_guard(ctx, nullcheck2, func);
    1310         [ -  + ]:          4 :     if (!nullcheck2)
    1311                 :          0 :         return emit_nullcheck_guard(ctx, nullcheck1, func);
    1312                 :          4 :     nullcheck1 = null_pointer_cmp(ctx, nullcheck1);
    1313                 :          4 :     nullcheck2 = null_pointer_cmp(ctx, nullcheck2);
    1314                 :            :     // If both are NULL, return true.
    1315                 :         20 :     return emit_guarded_test(ctx, ctx.builder.CreateOr(nullcheck1, nullcheck2), true, [&] {
    1316                 :          8 :         return emit_guarded_test(ctx, ctx.builder.CreateAnd(nullcheck1, nullcheck2),
    1317                 :          4 :                                  false, func);
    1318                 :          4 :     });
    1319                 :            : }
    1320                 :            : 
    1321                 :            : // Returns typeof(v), or null if v is a null pointer at run time and maybenull is true.
    1322                 :            : // This is used when the value might have come from an undefined value (a PhiNode),
    1323                 :            : // yet we try to read its type to compute a union index when moving the value (a PiNode).
    1324                 :            : // Returns a ctx.types().T_prjlvalue typed Value
    1325                 :     151002 : static Value *emit_typeof(jl_codectx_t &ctx, Value *v, bool maybenull)
    1326                 :            : {
    1327                 :     151002 :     ++EmittedTypeof;
    1328   [ +  -  +  - ]:     151002 :     assert(v != NULL && !isa<AllocaInst>(v) && "expected a conditionally boxed value");
    1329                 :     151002 :     Function *typeof = prepare_call(jl_typeof_func);
    1330         [ +  + ]:     151002 :     if (maybenull)
    1331                 :       3448 :         return emit_guarded_test(ctx, null_pointer_cmp(ctx, v), Constant::getNullValue(typeof->getReturnType()), [&] {
    1332                 :            :             // e.g. emit_typeof(ctx, v)
    1333                 :       1724 :             return ctx.builder.CreateCall(typeof, {v});
    1334                 :       1724 :         });
    1335                 :     149278 :     return ctx.builder.CreateCall(typeof, {v});
    1336                 :            : }
    1337                 :            : 
    1338                 :            : 
    1339                 :      23370 : static void emit_type_error(jl_codectx_t &ctx, const jl_cgval_t &x, Value *type, const std::string &msg)
    1340                 :            : {
    1341                 :      23370 :     Value *msg_val = stringConstPtr(ctx.emission_context, ctx.builder, msg);
    1342                 :      46740 :     ctx.builder.CreateCall(prepare_call(jltypeerror_func),
    1343                 :      23370 :                        { msg_val, maybe_decay_untracked(ctx, type), mark_callee_rooted(ctx, boxed(ctx, x))});
    1344                 :      23370 : }
    1345                 :            : 
    1346                 :            : // Should agree with `emit_isa` below
    1347                 :      13386 : static bool _can_optimize_isa(jl_value_t *type, int &counter)
    1348                 :            : {
    1349         [ -  + ]:      13386 :     if (counter > 127)
    1350                 :          0 :         return false;
    1351         [ +  + ]:      13386 :     if (jl_is_uniontype(type)) {
    1352                 :       1473 :         counter++;
    1353   [ +  +  +  + ]:       2910 :         return (_can_optimize_isa(((jl_uniontype_t*)type)->a, counter) &&
    1354                 :       2910 :                 _can_optimize_isa(((jl_uniontype_t*)type)->b, counter));
    1355                 :            :     }
    1356   [ -  +  -  -  :      11913 :     if (jl_is_type_type(type) && jl_pointer_egal(type))
                   -  + ]
    1357                 :          0 :         return true;
    1358         [ -  + ]:      11913 :     if (jl_has_intersect_type_not_kind(type))
    1359                 :          0 :         return false;
    1360         [ +  + ]:      11913 :     if (jl_is_concrete_type(type))
    1361                 :      11828 :         return true;
    1362                 :         85 :     jl_datatype_t *dt = (jl_datatype_t*)jl_unwrap_unionall(type);
    1363   [ +  -  +  +  :         85 :     if (jl_is_datatype(dt) && !dt->name->abstract && jl_subtype(dt->name->wrapper, type))
             +  +  +  + ]
    1364                 :         17 :         return true;
    1365                 :         68 :     return false;
    1366                 :            : }
    1367                 :            : 
    1368                 :       5250 : static bool can_optimize_isa_union(jl_uniontype_t *type)
    1369                 :            : {
    1370                 :       5250 :     int counter = 1;
    1371   [ +  +  +  + ]:       5250 :     return (_can_optimize_isa(type->a, counter) && _can_optimize_isa(type->b, counter));
    1372                 :            : }
    1373                 :            : 
    1374                 :            : // a simple case of emit_isa that is obvious not to include a safe-point
    1375                 :     132843 : static Value *emit_exactly_isa(jl_codectx_t &ctx, const jl_cgval_t &arg, jl_value_t *dt)
    1376                 :            : {
    1377         [ -  + ]:     132843 :     assert(jl_is_concrete_type(dt));
    1378                 :     265686 :     return ctx.builder.CreateICmpEQ(
    1379                 :            :             emit_typeof_boxed(ctx, arg),
    1380                 :     132843 :             track_pjlvalue(ctx, literal_pointer_val(ctx, dt)));
    1381                 :            : }
    1382                 :            : 
    1383                 :            : static std::pair<Value*, bool> emit_isa(jl_codectx_t &ctx, const jl_cgval_t &x,
    1384                 :            :                                         jl_value_t *type, const std::string *msg);
    1385                 :            : 
    1386                 :      18356 : static void emit_isa_union(jl_codectx_t &ctx, const jl_cgval_t &x, jl_value_t *type,
    1387                 :            :                            SmallVectorImpl<std::pair<std::pair<BasicBlock*,BasicBlock*>,Value*>> &bbs)
    1388                 :            : {
    1389                 :      18356 :     ++EmittedIsaUnions;
    1390         [ +  + ]:      18356 :     if (jl_is_uniontype(type)) {
    1391                 :       6587 :         emit_isa_union(ctx, x, ((jl_uniontype_t*)type)->a, bbs);
    1392                 :       6587 :         emit_isa_union(ctx, x, ((jl_uniontype_t*)type)->b, bbs);
    1393                 :       6587 :         return;
    1394                 :            :     }
    1395                 :      11769 :     BasicBlock *enter = ctx.builder.GetInsertBlock();
    1396                 :      11769 :     Value *v = emit_isa(ctx, x, type, nullptr).first;
    1397                 :      11769 :     BasicBlock *exit = ctx.builder.GetInsertBlock();
    1398                 :      11769 :     bbs.emplace_back(std::make_pair(enter, exit), v);
    1399                 :      11769 :     BasicBlock *isaBB = BasicBlock::Create(ctx.builder.getContext(), "isa", ctx.f);
    1400                 :      11769 :     ctx.builder.SetInsertPoint(isaBB);
    1401                 :            : }
    1402                 :            : 
    1403                 :            : // Should agree with `_can_optimize_isa` above
    1404                 :    1767180 : static std::pair<Value*, bool> emit_isa(jl_codectx_t &ctx, const jl_cgval_t &x, jl_value_t *type, const std::string *msg)
    1405                 :            : {
    1406                 :    1767180 :     ++EmittedIsa;
    1407                 :            :     // TODO: The subtype check below suffers from incorrectness issues due to broken
    1408                 :            :     // subtyping for kind types (see https://github.com/JuliaLang/julia/issues/27078). For
    1409                 :            :     // actual `isa` calls, this optimization should already have been performed upstream
    1410                 :            :     // anyway, but having this optimization in codegen might still be beneficial for
    1411                 :            :     // `typeassert`s if we can make it correct.
    1412                 :    1767180 :     Optional<bool> known_isa;
    1413                 :    1767180 :     jl_value_t *intersected_type = type;
    1414         [ +  + ]:    1767180 :     if (x.constant)
    1415                 :     714410 :         known_isa = jl_isa(x.constant, type);
    1416   [ +  +  +  +  :    1052770 :     else if (jl_is_not_broken_subtype(x.typ, type) && jl_subtype(x.typ, type)) {
                   +  + ]
    1417                 :     895784 :         known_isa = true;
    1418                 :            :     } else {
    1419                 :     156988 :         intersected_type = jl_type_intersection(x.typ, type);
    1420         [ +  + ]:     156988 :         if (intersected_type == (jl_value_t*)jl_bottom_type)
    1421                 :         48 :             known_isa = false;
    1422                 :            :     }
    1423         [ +  + ]:    1767180 :     if (known_isa) {
    1424   [ +  +  +  +  :    1610240 :         if (!*known_isa && msg) {
                   +  + ]
    1425                 :        262 :             emit_type_error(ctx, x, literal_pointer_val(ctx, type), *msg);
    1426                 :        262 :             ctx.builder.CreateUnreachable();
    1427                 :        262 :             BasicBlock *failBB = BasicBlock::Create(ctx.builder.getContext(), "fail", ctx.f);
    1428                 :        262 :             ctx.builder.SetInsertPoint(failBB);
    1429                 :            :         }
    1430                 :    1610240 :         return std::make_pair(ConstantInt::get(getInt1Ty(ctx.builder.getContext()), *known_isa), true);
    1431                 :            :     }
    1432                 :            : 
    1433   [ +  +  +  +  :     156940 :     if (jl_is_type_type(intersected_type) && jl_pointer_egal(intersected_type)) {
                   +  + ]
    1434                 :            :         // Use the check in `jl_pointer_egal` to see if the type enclosed
    1435                 :            :         // has unique pointer value.
    1436                 :        506 :         auto ptr = track_pjlvalue(ctx, literal_pointer_val(ctx, jl_tparam0(intersected_type)));
    1437                 :        506 :         return {ctx.builder.CreateICmpEQ(boxed(ctx, x), ptr), false};
    1438                 :            :     }
    1439                 :            :     // intersection with Type needs to be handled specially
    1440   [ +  +  +  +  :     156434 :     if (jl_has_intersect_type_not_kind(type) || jl_has_intersect_type_not_kind(intersected_type)) {
                   +  + ]
    1441                 :       4762 :         Value *vx = boxed(ctx, x);
    1442                 :       4762 :         Value *vtyp = track_pjlvalue(ctx, literal_pointer_val(ctx, type));
    1443   [ +  +  +  +  :       4762 :         if (msg && *msg == "typeassert") {
                   +  + ]
    1444                 :       1069 :             ctx.builder.CreateCall(prepare_call(jltypeassert_func), { vx, vtyp });
    1445                 :       1069 :             return std::make_pair(ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 1), true);
    1446                 :            :         }
    1447                 :       3693 :         return std::make_pair(ctx.builder.CreateICmpNE(
    1448                 :       3693 :                 ctx.builder.CreateCall(prepare_call(jlisa_func), { vx, vtyp }),
    1449                 :       7386 :                 ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0)), false);
    1450                 :            :     }
    1451                 :            :     // tests for isa concretetype can be handled with pointer comparisons
    1452         [ +  + ]:     151672 :     if (jl_is_concrete_type(intersected_type)) {
    1453         [ +  + ]:     141638 :         if (x.TIndex) {
    1454                 :      14312 :             unsigned tindex = get_box_tindex((jl_datatype_t*)intersected_type, x.typ);
    1455         [ +  + ]:      14312 :             if (tindex > 0) {
    1456                 :            :                 // optimize more when we know that this is a split union-type where tindex = 0 is invalid
    1457                 :      12504 :                 Value *xtindex = ctx.builder.CreateAnd(x.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x7f));
    1458                 :      12504 :                 return std::make_pair(ctx.builder.CreateICmpEQ(xtindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), tindex)), false);
    1459                 :            :             }
    1460         [ +  - ]:       1808 :             else if (x.Vboxed) {
    1461                 :            :                 // test for (x.TIndex == 0x80 && typeof(x.V) == type)
    1462                 :       1808 :                 Value *isboxed = ctx.builder.CreateICmpEQ(x.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80));
    1463                 :       1808 :                 BasicBlock *currBB = ctx.builder.GetInsertBlock();
    1464                 :       1808 :                 BasicBlock *isaBB = BasicBlock::Create(ctx.builder.getContext(), "isa", ctx.f);
    1465                 :       1808 :                 BasicBlock *postBB = BasicBlock::Create(ctx.builder.getContext(), "post_isa", ctx.f);
    1466                 :       1808 :                 ctx.builder.CreateCondBr(isboxed, isaBB, postBB);
    1467                 :       1808 :                 ctx.builder.SetInsertPoint(isaBB);
    1468                 :       1808 :                 Value *istype_boxed = ctx.builder.CreateICmpEQ(emit_typeof(ctx, x.Vboxed, false),
    1469                 :            :                     track_pjlvalue(ctx, literal_pointer_val(ctx, intersected_type)));
    1470                 :       1808 :                 ctx.builder.CreateBr(postBB);
    1471                 :       1808 :                 isaBB = ctx.builder.GetInsertBlock(); // could have changed
    1472                 :       1808 :                 ctx.builder.SetInsertPoint(postBB);
    1473                 :       1808 :                 PHINode *istype = ctx.builder.CreatePHI(getInt1Ty(ctx.builder.getContext()), 2);
    1474                 :       1808 :                 istype->addIncoming(ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0), currBB);
    1475                 :       1808 :                 istype->addIncoming(istype_boxed, isaBB);
    1476                 :       1808 :                 return std::make_pair(istype, false);
    1477                 :            :             } else {
    1478                 :            :                 // handle the case where we know that `x` is unboxed (but of unknown type), but that concrete type `type` cannot be unboxed
    1479                 :          0 :                 return std::make_pair(ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0), false);
    1480                 :            :             }
    1481                 :            :         }
    1482                 :     127326 :         return std::make_pair(emit_exactly_isa(ctx, x, intersected_type), false);
    1483                 :            :     }
    1484                 :      10034 :     jl_datatype_t *dt = (jl_datatype_t*)jl_unwrap_unionall(intersected_type);
    1485   [ +  +  +  +  :      10034 :     if (jl_is_datatype(dt) && !dt->name->abstract && jl_subtype(dt->name->wrapper, type)) {
             +  +  +  + ]
    1486                 :            :         // intersection is a supertype of all instances of its constructor,
    1487                 :            :         // so the isa test reduces to a comparison of the typename by pointer
    1488                 :            :         return std::make_pair(
    1489                 :       1258 :                 ctx.builder.CreateICmpEQ(
    1490                 :            :                     mark_callee_rooted(ctx, emit_datatype_name(ctx, emit_typeof_boxed(ctx, x))),
    1491                 :       1258 :                     mark_callee_rooted(ctx, literal_pointer_val(ctx, (jl_value_t*)dt->name))),
    1492                 :       2516 :                 false);
    1493                 :            :     }
    1494   [ +  +  +  +  :      14026 :     if (jl_is_uniontype(intersected_type) &&
                   +  + ]
    1495                 :       5250 :         can_optimize_isa_union((jl_uniontype_t*)intersected_type)) {
    1496                 :       5182 :         SmallVector<std::pair<std::pair<BasicBlock*,BasicBlock*>,Value*>,4> bbs;
    1497                 :       5182 :         emit_isa_union(ctx, x, intersected_type, bbs);
    1498                 :       5182 :         int nbbs = bbs.size();
    1499                 :       5182 :         BasicBlock *currBB = ctx.builder.GetInsertBlock();
    1500                 :       5182 :         PHINode *res = ctx.builder.CreatePHI(getInt1Ty(ctx.builder.getContext()), nbbs);
    1501         [ +  + ]:      16951 :         for (int i = 0; i < nbbs; i++) {
    1502                 :      11769 :             auto bb = bbs[i].first.second;
    1503                 :      11769 :             ctx.builder.SetInsertPoint(bb);
    1504         [ +  + ]:      11769 :             if (i + 1 < nbbs) {
    1505                 :       6587 :                 ctx.builder.CreateCondBr(bbs[i].second, currBB, bbs[i + 1].first.first);
    1506                 :       6587 :                 res->addIncoming(ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 1), bb);
    1507                 :            :             }
    1508                 :            :             else {
    1509                 :       5182 :                 ctx.builder.CreateBr(currBB);
    1510                 :       5182 :                 res->addIncoming(bbs[i].second, bb);
    1511                 :            :             }
    1512                 :            :         }
    1513                 :       5182 :         ctx.builder.SetInsertPoint(currBB);
    1514                 :       5182 :         return {res, false};
    1515                 :            :     }
    1516                 :            :     // everything else can be handled via subtype tests
    1517                 :       3594 :     return std::make_pair(ctx.builder.CreateICmpNE(
    1518                 :       7188 :             ctx.builder.CreateCall(prepare_call(jlsubtype_func),
    1519                 :       3594 :               { emit_typeof_boxed(ctx, x),
    1520                 :       3594 :                 track_pjlvalue(ctx, literal_pointer_val(ctx, type)) }),
    1521                 :       7188 :             ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0)), false);
    1522                 :            : }
    1523                 :            : 
    1524                 :            : // If this might have been sourced from a PhiNode object, it is possible our
    1525                 :            : // Vboxed pointer itself is null (undef) at runtime even if we thought we should
    1526                 :            : // know exactly the type of the bytes that should have been inside.
    1527                 :            : //
    1528                 :            : // n.b. It is also possible the value is a ghost of some sort, and we will
    1529                 :            : // declare that the pointer is legal (for zero bytes) even though it might be undef.
    1530                 :    1097480 : static Value *emit_isa_and_defined(jl_codectx_t &ctx, const jl_cgval_t &val, jl_value_t *typ)
    1531                 :            : {
    1532         [ +  + ]:    2194960 :     return emit_nullcheck_guard(ctx, val.ispointer() ? val.V : nullptr, [&] {
    1533                 :    1097480 :         return emit_isa(ctx, val, typ, nullptr).first;
    1534                 :    1097480 :     });
    1535                 :            : }
    1536                 :            : 
    1537                 :            : 
    1538                 :     538602 : static void emit_typecheck(jl_codectx_t &ctx, const jl_cgval_t &x, jl_value_t *type, const std::string &msg)
    1539                 :            : {
    1540                 :            :     Value *istype;
    1541                 :            :     bool handled_msg;
    1542                 :     538602 :     std::tie(istype, handled_msg) = emit_isa(ctx, x, type, &msg);
    1543         [ +  + ]:     538602 :     if (!handled_msg) {
    1544                 :      23100 :         ++EmittedTypechecks;
    1545                 :      23100 :         BasicBlock *failBB = BasicBlock::Create(ctx.builder.getContext(), "fail", ctx.f);
    1546                 :      23100 :         BasicBlock *passBB = BasicBlock::Create(ctx.builder.getContext(), "pass");
    1547                 :      23100 :         ctx.builder.CreateCondBr(istype, passBB, failBB);
    1548                 :      23100 :         ctx.builder.SetInsertPoint(failBB);
    1549                 :            : 
    1550                 :      23100 :         emit_type_error(ctx, x, literal_pointer_val(ctx, type), msg);
    1551                 :      23100 :         ctx.builder.CreateUnreachable();
    1552                 :            : 
    1553                 :      23100 :         ctx.f->getBasicBlockList().push_back(passBB);
    1554                 :      23100 :         ctx.builder.SetInsertPoint(passBB);
    1555                 :            :     }
    1556                 :     538602 : }
    1557                 :            : 
    1558                 :          1 : static Value *emit_isconcrete(jl_codectx_t &ctx, Value *typ)
    1559                 :            : {
    1560                 :            :     Value *isconcrete;
    1561                 :          1 :     isconcrete = ctx.builder.CreateConstInBoundsGEP1_32(getInt8Ty(ctx.builder.getContext()), emit_bitcast(ctx, decay_derived(ctx, typ), getInt8PtrTy(ctx.builder.getContext())), offsetof(jl_datatype_t, hash) + sizeof(((jl_datatype_t*)nullptr)->hash));
    1562                 :          1 :     isconcrete = tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(getInt8Ty(ctx.builder.getContext()), isconcrete, Align(1)));
    1563                 :          1 :     isconcrete = ctx.builder.CreateLShr(isconcrete, 1);
    1564                 :          1 :     isconcrete = ctx.builder.CreateTrunc(isconcrete, getInt1Ty(ctx.builder.getContext()));
    1565                 :          1 :     return isconcrete;
    1566                 :            : }
    1567                 :            : 
    1568                 :          1 : static void emit_concretecheck(jl_codectx_t &ctx, Value *typ, const std::string &msg)
    1569                 :            : {
    1570                 :          1 :     ++EmittedConcretechecks;
    1571         [ -  + ]:          1 :     assert(typ->getType() == ctx.types().T_prjlvalue);
    1572                 :          1 :     emit_typecheck(ctx, mark_julia_type(ctx, typ, true, jl_any_type), (jl_value_t*)jl_datatype_type, msg);
    1573                 :          1 :     error_unless(ctx, emit_isconcrete(ctx, typ), msg);
    1574                 :          1 : }
    1575                 :            : 
    1576                 :            : #define CHECK_BOUNDS 1
    1577                 :     173451 : static bool bounds_check_enabled(jl_codectx_t &ctx, jl_value_t *inbounds) {
    1578                 :            : #if CHECK_BOUNDS==1
    1579         [ -  + ]:     173451 :     if (jl_options.check_bounds == JL_OPTIONS_CHECK_BOUNDS_ON)
    1580                 :          0 :         return 1;
    1581         [ -  + ]:     173451 :     if (jl_options.check_bounds == JL_OPTIONS_CHECK_BOUNDS_OFF)
    1582                 :          0 :         return 0;
    1583         [ +  + ]:     173451 :     if (inbounds == jl_false)
    1584                 :      97786 :         return 0;
    1585                 :      75665 :     return 1;
    1586                 :            : #else
    1587                 :            :     return 0;
    1588                 :            : #endif
    1589                 :            : }
    1590                 :            : 
    1591                 :      12034 : static Value *emit_bounds_check(jl_codectx_t &ctx, const jl_cgval_t &ainfo, jl_value_t *ty, Value *i, Value *len, jl_value_t *boundscheck)
    1592                 :            : {
    1593                 :      12034 :     Value *im1 = ctx.builder.CreateSub(i, ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1));
    1594                 :            : #if CHECK_BOUNDS==1
    1595         [ +  + ]:      12034 :     if (bounds_check_enabled(ctx, boundscheck)) {
    1596                 :       6025 :         ++EmittedBoundschecks;
    1597                 :       6025 :         Value *ok = ctx.builder.CreateICmpULT(im1, len);
    1598                 :       6025 :         BasicBlock *failBB = BasicBlock::Create(ctx.builder.getContext(), "fail", ctx.f);
    1599                 :       6025 :         BasicBlock *passBB = BasicBlock::Create(ctx.builder.getContext(), "pass");
    1600                 :       6025 :         ctx.builder.CreateCondBr(ok, passBB, failBB);
    1601                 :       6025 :         ctx.builder.SetInsertPoint(failBB);
    1602         [ +  + ]:       6025 :         if (!ty) { // jl_value_t** tuple (e.g. the vararg)
    1603                 :        772 :             ctx.builder.CreateCall(prepare_call(jlvboundserror_func), { ainfo.V, len, i });
    1604                 :            :         }
    1605         [ +  + ]:       5253 :         else if (ainfo.isboxed) { // jl_datatype_t or boxed jl_value_t
    1606                 :        323 :             ctx.builder.CreateCall(prepare_call(jlboundserror_func), { mark_callee_rooted(ctx, boxed(ctx, ainfo)), i });
    1607                 :            :         }
    1608                 :            :         else { // unboxed jl_value_t*
    1609                 :       4930 :             Value *a = ainfo.V;
    1610         [ +  + ]:       4930 :             if (ainfo.isghost) {
    1611                 :          4 :                 a = Constant::getNullValue(getInt8PtrTy(ctx.builder.getContext()));
    1612                 :            :             }
    1613         [ +  + ]:       4926 :             else if (!ainfo.ispointer()) {
    1614                 :            :                 // CreateAlloca is OK here since we are on an error branch
    1615                 :        164 :                 Value *tempSpace = ctx.builder.CreateAlloca(a->getType());
    1616                 :        164 :                 ctx.builder.CreateStore(a, tempSpace);
    1617                 :        164 :                 a = tempSpace;
    1618                 :            :             }
    1619                 :       9860 :             ctx.builder.CreateCall(prepare_call(jluboundserror_func), {
    1620                 :       4930 :                     emit_bitcast(ctx, decay_derived(ctx, a), getInt8PtrTy(ctx.builder.getContext())),
    1621                 :       4930 :                     literal_pointer_val(ctx, ty),
    1622                 :            :                     i });
    1623                 :            :         }
    1624                 :       6025 :         ctx.builder.CreateUnreachable();
    1625                 :       6025 :         ctx.f->getBasicBlockList().push_back(passBB);
    1626                 :       6025 :         ctx.builder.SetInsertPoint(passBB);
    1627                 :            :     }
    1628                 :            : #endif
    1629                 :      12034 :     return im1;
    1630                 :            : }
    1631                 :            : 
    1632                 :            : static Value *emit_unbox(jl_codectx_t &ctx, Type *to, const jl_cgval_t &x, jl_value_t *jt);
    1633                 :            : static void emit_unbox_store(jl_codectx_t &ctx, const jl_cgval_t &x, Value* dest, MDNode *tbaa_dest, unsigned alignment, bool isVolatile=false);
    1634                 :            : 
    1635                 :            : static void emit_write_barrier(jl_codectx_t&, Value*, ArrayRef<Value*>);
    1636                 :            : static void emit_write_barrier(jl_codectx_t&, Value*, Value*);
    1637                 :            : static void emit_write_multibarrier(jl_codectx_t&, Value*, Value*, jl_value_t*);
    1638                 :            : 
    1639                 :     127397 : std::vector<unsigned> first_ptr(Type *T)
    1640                 :            : {
    1641   [ +  +  +  +  :     127397 :     if (isa<StructType>(T) || isa<ArrayType>(T) || isa<VectorType>(T)) {
             -  +  +  + ]
    1642         [ +  + ]:      22494 :         if (!isa<StructType>(T)) {
    1643                 :            :             uint64_t num_elements;
    1644         [ +  - ]:      11562 :             if (auto *AT = dyn_cast<ArrayType>(T))
    1645                 :      11562 :                 num_elements = AT->getNumElements();
    1646                 :            :             else {
    1647                 :          0 :                 VectorType *VT = cast<VectorType>(T);
    1648                 :            : #if JL_LLVM_VERSION >= 120000
    1649                 :          0 :                 ElementCount EC = VT->getElementCount();
    1650                 :          0 :                 num_elements = EC.getKnownMinValue();
    1651                 :            : #else
    1652                 :            :                 num_elements = VT->getNumElements();
    1653                 :            : #endif
    1654                 :            :             }
    1655         [ -  + ]:      11562 :             if (num_elements == 0)
    1656                 :      11073 :                 return {};
    1657                 :            :         }
    1658                 :      22494 :         unsigned i = 0;
    1659         [ +  + ]:      72798 :         for (Type *ElTy : T->subtypes()) {
    1660   [ +  +  +  -  :      61377 :             if (isa<PointerType>(ElTy) && ElTy->getPointerAddressSpace() == AddressSpace::Tracked) {
                   +  + ]
    1661                 :       9820 :                 return std::vector<unsigned>{i};
    1662                 :            :             }
    1663                 :      51557 :             auto path = first_ptr(ElTy);
    1664         [ +  + ]:      51557 :             if (!path.empty()) {
    1665                 :       1253 :                 path.push_back(i);
    1666                 :       1253 :                 return path;
    1667                 :            :             }
    1668                 :      50304 :             i++;
    1669                 :            :         }
    1670                 :            :     }
    1671                 :     116324 :     return {};
    1672                 :            : }
    1673                 :      75840 : Value *extract_first_ptr(jl_codectx_t &ctx, Value *V)
    1674                 :            : {
    1675                 :     151680 :     auto path = first_ptr(V->getType());
    1676         [ +  + ]:      75840 :     if (path.empty())
    1677                 :      66020 :         return NULL;
    1678                 :       9820 :     std::reverse(std::begin(path), std::end(path));
    1679                 :       9820 :     return ctx.builder.CreateExtractValue(V, path);
    1680                 :            : }
    1681                 :            : 
    1682                 :            : 
    1683                 :          0 : static void emit_lockstate_value(jl_codectx_t &ctx, Value *strct, bool newstate)
    1684                 :            : {
    1685                 :          0 :     ++EmittedLockstates;
    1686                 :          0 :     Value *v = mark_callee_rooted(ctx, strct);
    1687         [ #  # ]:          0 :     ctx.builder.CreateCall(prepare_call(newstate ? jllockvalue_func : jlunlockvalue_func), v);
    1688                 :          0 : }
    1689                 :          0 : static void emit_lockstate_value(jl_codectx_t &ctx, const jl_cgval_t &strct, bool newstate)
    1690                 :            : {
    1691         [ #  # ]:          0 :     assert(strct.isboxed);
    1692                 :          0 :     emit_lockstate_value(ctx, boxed(ctx, strct), newstate);
    1693                 :          0 : }
    1694                 :            : 
    1695                 :            : 
    1696                 :            : // If `nullcheck` is not NULL and a pointer NULL check is necessary
    1697                 :            : // store the pointer to be checked in `*nullcheck` instead of checking it
    1698                 :     207870 : static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, jl_value_t *jltype,
    1699                 :            :                              MDNode *tbaa, MDNode *aliasscope, bool isboxed, AtomicOrdering Order,
    1700                 :            :                              bool maybe_null_if_boxed = true, unsigned alignment = 0,
    1701                 :            :                              Value **nullcheck = nullptr)
    1702                 :            : {
    1703                 :            :     // TODO: we should use unordered loads for anything with CountTrackedPointers(elty).count > 0 (if not otherwise locked)
    1704         [ +  + ]:     207870 :     Type *elty = isboxed ? ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, jltype);
    1705         [ -  + ]:     207870 :     if (type_is_ghost(elty))
    1706                 :          0 :         return ghostValue(ctx, jltype);
    1707         [ +  + ]:     207870 :     unsigned nb = isboxed ? sizeof(void*) : jl_datatype_size(jltype);
    1708                 :            :     // note that nb == jl_Module->getDataLayout().getTypeAllocSize(elty) or getTypeStoreSize, depending on whether it is a struct or primitive type
    1709                 :     207870 :     AllocaInst *intcast = NULL;
    1710         [ +  + ]:     207870 :     if (Order == AtomicOrdering::NotAtomic) {
    1711   [ +  +  +  -  :     204722 :         if (!isboxed && !aliasscope && elty->isAggregateType() && !CountTrackedPointers(elty).count)
          +  +  +  +  +  
                      + ]
    1712                 :       8829 :             intcast = emit_static_alloca(ctx, elty);
    1713                 :            :     }
    1714                 :            :     else {
    1715   [ +  -  -  +  :       3148 :         if (!isboxed && !elty->isIntOrPtrTy()) {
                   -  + ]
    1716                 :          0 :             intcast = emit_static_alloca(ctx, elty);
    1717                 :          0 :             elty = Type::getIntNTy(ctx.builder.getContext(), 8 * nb);
    1718                 :            :         }
    1719                 :            :     }
    1720                 :     207870 :     Type *realelty = elty;
    1721   [ +  +  +  -  :     207870 :     if (Order != AtomicOrdering::NotAtomic && isa<IntegerType>(elty)) {
                   +  + ]
    1722                 :       3148 :         unsigned nb2 = PowerOf2Ceil(nb);
    1723         [ -  + ]:       3148 :         if (nb != nb2)
    1724                 :          0 :             elty = Type::getIntNTy(ctx.builder.getContext(), 8 * nb2);
    1725                 :            :     }
    1726                 :     207870 :     Type *ptrty = PointerType::get(elty, ptr->getType()->getPointerAddressSpace());
    1727                 :            :     Value *data;
    1728         [ +  + ]:     207870 :     if (ptr->getType() != ptrty)
    1729                 :     168165 :         data = emit_bitcast(ctx, ptr, ptrty);
    1730                 :            :     else
    1731                 :      39705 :         data = ptr;
    1732         [ +  + ]:     207870 :     if (idx_0based)
    1733                 :     117242 :         data = ctx.builder.CreateInBoundsGEP(elty, data, idx_0based);
    1734                 :     207870 :     Value *instr = nullptr;
    1735         [ +  + ]:     207870 :     if (isboxed)
    1736                 :      52047 :         alignment = sizeof(void*);
    1737         [ +  + ]:     155823 :     else if (!alignment)
    1738                 :      54467 :         alignment = julia_alignment(jltype);
    1739   [ +  +  +  - ]:     207870 :     if (intcast && Order == AtomicOrdering::NotAtomic) {
    1740                 :       8829 :         emit_memcpy(ctx, intcast, ctx.tbaa().tbaa_stack, data, tbaa, nb, alignment);
    1741                 :            :     }
    1742                 :            :     else {
    1743                 :     199041 :         LoadInst *load = ctx.builder.CreateAlignedLoad(elty, data, Align(alignment), false);
    1744                 :     199041 :         load->setOrdering(Order);
    1745         [ -  + ]:     199041 :         if (aliasscope)
    1746                 :          0 :             load->setMetadata("alias.scope", aliasscope);
    1747         [ +  + ]:     199041 :         if (isboxed)
    1748                 :      52047 :             maybe_mark_load_dereferenceable(load, true, jltype);
    1749         [ +  - ]:     199041 :         if (tbaa)
    1750                 :     199041 :             tbaa_decorate(tbaa, load);
    1751                 :     199041 :         instr = load;
    1752         [ -  + ]:     199041 :         if (elty != realelty)
    1753                 :          0 :             instr = ctx.builder.CreateTrunc(instr, realelty);
    1754         [ -  + ]:     199041 :         if (intcast) {
    1755                 :          0 :             ctx.builder.CreateStore(instr, ctx.builder.CreateBitCast(intcast, instr->getType()->getPointerTo()));
    1756                 :          0 :             instr = nullptr;
    1757                 :            :         }
    1758                 :            :     }
    1759         [ +  + ]:     207870 :     if (maybe_null_if_boxed) {
    1760         [ +  + ]:     127530 :         if (intcast)
    1761                 :       7234 :             instr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast);
    1762         [ +  + ]:     127530 :         Value *first_ptr = isboxed ? instr : extract_first_ptr(ctx, instr);
    1763         [ +  + ]:     127530 :         if (first_ptr)
    1764                 :      61510 :             null_pointer_check(ctx, first_ptr, nullcheck);
    1765   [ +  +  +  - ]:     127530 :         if (intcast && !first_ptr)
    1766                 :       7234 :             instr = nullptr;
    1767                 :            :     }
    1768         [ +  + ]:     207870 :     if (jltype == (jl_value_t*)jl_bool_type) { // "freeze" undef memory to a valid value
    1769                 :            :         // NOTE: if we zero-initialize arrays, this optimization should become valid
    1770                 :            :         //load->setMetadata(LLVMContext::MD_range, MDNode::get(ctx.builder.getContext(), {
    1771                 :            :         //    ConstantAsMetadata::get(ConstantInt::get(T_int8, 0)),
    1772                 :            :         //    ConstantAsMetadata::get(ConstantInt::get(T_int8, 2)) }));
    1773         [ -  + ]:       6030 :         if (intcast)
    1774                 :          0 :             instr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast);
    1775                 :       6030 :         instr = ctx.builder.CreateTrunc(instr, getInt1Ty(ctx.builder.getContext()));
    1776                 :            :     }
    1777         [ +  + ]:     207870 :     if (instr)
    1778                 :     199041 :         return mark_julia_type(ctx, instr, isboxed, jltype);
    1779                 :            :     else
    1780                 :       8829 :         return mark_julia_slot(intcast, jltype, NULL, ctx.tbaa().tbaa_stack);
    1781                 :            : }
    1782                 :            : 
    1783                 :     144723 : static jl_cgval_t typed_store(jl_codectx_t &ctx,
    1784                 :            :         Value *ptr, Value *idx_0based, jl_cgval_t rhs, jl_cgval_t cmp,
    1785                 :            :         jl_value_t *jltype, MDNode *tbaa, MDNode *aliasscope,
    1786                 :            :         Value *parent,  // for the write barrier, NULL if no barrier needed
    1787                 :            :         bool isboxed, AtomicOrdering Order, AtomicOrdering FailOrder, unsigned alignment,
    1788                 :            :         bool needlock, bool issetfield, bool isreplacefield, bool isswapfield, bool ismodifyfield,
    1789                 :            :         bool maybe_null_if_boxed, const jl_cgval_t *modifyop, const std::string &fname)
    1790                 :            : {
    1791                 :          0 :     auto newval = [&](const jl_cgval_t &lhs) {
    1792                 :          0 :         const jl_cgval_t argv[3] = { cmp, lhs, rhs };
    1793                 :          0 :         jl_cgval_t ret;
    1794         [ #  # ]:          0 :         if (modifyop) {
    1795                 :          0 :             ret = emit_invoke(ctx, *modifyop, argv, 3, (jl_value_t*)jl_any_type);
    1796                 :            :         }
    1797                 :            :         else {
    1798                 :          0 :             Value *callval = emit_jlcall(ctx, jlapplygeneric_func, nullptr, argv, 3, julia_call);
    1799                 :          0 :             ret = mark_julia_type(ctx, callval, true, jl_any_type);
    1800                 :            :         }
    1801                 :          0 :         emit_typecheck(ctx, ret, jltype, fname);
    1802                 :          0 :         ret = update_julia_type(ctx, ret, jltype);
    1803                 :          0 :         return ret;
    1804                 :     144723 :     };
    1805   [ -  +  -  - ]:     144723 :     assert(!needlock || parent != nullptr);
    1806         [ +  + ]:     144723 :     Type *elty = isboxed ? ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, jltype);
    1807         [ +  + ]:     144723 :     if (type_is_ghost(elty)) {
    1808         [ -  + ]:          2 :         if (isStrongerThanMonotonic(Order))
    1809                 :          0 :             ctx.builder.CreateFence(Order);
    1810         [ +  - ]:          2 :         if (issetfield) {
    1811                 :          2 :             return rhs;
    1812                 :            :         }
    1813         [ #  # ]:          0 :         else if (isreplacefield) {
    1814                 :          0 :             Value *Success = emit_f_is(ctx, cmp, ghostValue(ctx, jltype));
    1815                 :          0 :             Success = ctx.builder.CreateZExt(Success, getInt8Ty(ctx.builder.getContext()));
    1816                 :          0 :             const jl_cgval_t argv[2] = {ghostValue(ctx, jltype), mark_julia_type(ctx, Success, false, jl_bool_type)};
    1817                 :          0 :             jl_datatype_t *rettyp = jl_apply_cmpswap_type(jltype);
    1818                 :          0 :             return emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv);
    1819                 :            :         }
    1820         [ #  # ]:          0 :         else if (isswapfield) {
    1821                 :          0 :             return ghostValue(ctx, jltype);
    1822                 :            :         }
    1823                 :            :         else { // modifyfield
    1824                 :          0 :             jl_cgval_t oldval = ghostValue(ctx, jltype);
    1825                 :          0 :             const jl_cgval_t argv[2] = { oldval, newval(oldval) };
    1826                 :          0 :             jl_datatype_t *rettyp = jl_apply_modify_type(jltype);
    1827                 :          0 :             return emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv);
    1828                 :            :         }
    1829                 :            :     }
    1830         [ +  + ]:     144721 :     unsigned nb = isboxed ? sizeof(void*) : jl_datatype_size(jltype);
    1831                 :     144721 :     AllocaInst *intcast = nullptr;
    1832   [ +  +  +  +  :     144721 :     if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy()) {
             -  +  -  + ]
    1833         [ #  # ]:          0 :         if (!issetfield)
    1834                 :          0 :             intcast = emit_static_alloca(ctx, elty);
    1835                 :          0 :         elty = Type::getIntNTy(ctx.builder.getContext(), 8 * nb);
    1836                 :            :     }
    1837                 :     144721 :     Type *realelty = elty;
    1838   [ +  +  +  +  :     144721 :     if (Order != AtomicOrdering::NotAtomic && isa<IntegerType>(elty)) {
                   +  + ]
    1839                 :       1256 :         unsigned nb2 = PowerOf2Ceil(nb);
    1840         [ -  + ]:       1256 :         if (nb != nb2)
    1841                 :          0 :             elty = Type::getIntNTy(ctx.builder.getContext(), 8 * nb2);
    1842                 :            :     }
    1843                 :     144721 :     Value *r = nullptr;
    1844   [ +  +  +  +  :     144721 :     if (issetfield || isswapfield || isreplacefield)  {
                   +  - ]
    1845         [ +  + ]:     144721 :         if (isboxed)
    1846                 :      56373 :             r = boxed(ctx, rhs);
    1847   [ +  -  +  +  :      88348 :         else if (aliasscope || Order != AtomicOrdering::NotAtomic || CountTrackedPointers(realelty).count) {
             +  +  +  + ]
    1848                 :       7963 :             r = emit_unbox(ctx, realelty, rhs, jltype);
    1849         [ -  + ]:       7963 :             if (realelty != elty)
    1850                 :          0 :                 r = ctx.builder.CreateZExt(r, elty);
    1851                 :            :         }
    1852                 :            :     }
    1853                 :     144721 :     Type *ptrty = PointerType::get(elty, ptr->getType()->getPointerAddressSpace());
    1854         [ +  + ]:     144721 :     if (ptr->getType() != ptrty)
    1855                 :     105300 :         ptr = ctx.builder.CreateBitCast(ptr, ptrty);
    1856         [ +  + ]:     144721 :     if (idx_0based)
    1857                 :      53899 :         ptr = ctx.builder.CreateInBoundsGEP(elty, ptr, idx_0based);
    1858         [ +  + ]:     144721 :     if (isboxed)
    1859                 :      56373 :         alignment = sizeof(void*);
    1860         [ +  + ]:      88348 :     else if (!alignment)
    1861                 :      27902 :         alignment = julia_alignment(jltype);
    1862                 :     144721 :     Value *instr = nullptr;
    1863                 :     144721 :     Value *Compare = nullptr;
    1864                 :     144721 :     Value *Success = nullptr;
    1865                 :     144721 :     BasicBlock *DoneBB = nullptr;
    1866         [ -  + ]:     144721 :     if (needlock)
    1867                 :          0 :         emit_lockstate_value(ctx, parent, true);
    1868                 :     144721 :     jl_cgval_t oldval = rhs;
    1869   [ +  +  +  +  :     144721 :     if (issetfield || (Order == AtomicOrdering::NotAtomic && isswapfield)) {
                   +  - ]
    1870         [ +  + ]:     143887 :         if (isswapfield) {
    1871                 :         32 :             auto *load = ctx.builder.CreateAlignedLoad(elty, ptr, Align(alignment));
    1872         [ -  + ]:         32 :             if (isboxed)
    1873                 :          0 :                 load->setOrdering(AtomicOrdering::Unordered);
    1874         [ -  + ]:         32 :             if (aliasscope)
    1875                 :          0 :                 load->setMetadata("noalias", aliasscope);
    1876         [ +  - ]:         32 :             if (tbaa)
    1877                 :         32 :                 tbaa_decorate(tbaa, load);
    1878         [ -  + ]:         32 :             assert(realelty == elty);
    1879                 :         32 :             instr = load;
    1880                 :            :         }
    1881         [ +  + ]:     143887 :         if (r) {
    1882                 :      63502 :             StoreInst *store = ctx.builder.CreateAlignedStore(r, ptr, Align(alignment));
    1883   [ +  +  +  + ]:      63502 :             store->setOrdering(Order == AtomicOrdering::NotAtomic && isboxed ? AtomicOrdering::Release : Order);
    1884         [ -  + ]:      63502 :             if (aliasscope)
    1885                 :          0 :                 store->setMetadata("noalias", aliasscope);
    1886         [ +  - ]:      63502 :             if (tbaa)
    1887                 :      63502 :                 tbaa_decorate(tbaa, store);
    1888                 :            :         }
    1889                 :            :         else {
    1890   [ +  -  +  -  :      80385 :             assert(Order == AtomicOrdering::NotAtomic && !isboxed && rhs.typ == jltype);
                   +  - ]
    1891                 :      80385 :             emit_unbox_store(ctx, rhs, ptr, tbaa, alignment);
    1892                 :     143887 :         }
    1893                 :            :     }
    1894   [ +  +  +  - ]:        834 :     else if (isswapfield && !isboxed) {
    1895   [ +  -  +  - ]:        788 :         assert(Order != AtomicOrdering::NotAtomic && r);
    1896                 :            :         // we can't handle isboxed here as a workaround for really bad LLVM
    1897                 :            :         // design issue: plain Xchg only works with integers
    1898                 :            : #if JL_LLVM_VERSION >= 130000
    1899                 :        788 :         auto *store = ctx.builder.CreateAtomicRMW(AtomicRMWInst::Xchg, ptr, r, Align(alignment), Order);
    1900                 :            : #else
    1901                 :            :         auto *store = ctx.builder.CreateAtomicRMW(AtomicRMWInst::Xchg, ptr, r, Order);
    1902                 :            :         store->setAlignment(Align(alignment));
    1903                 :            : #endif
    1904         [ -  + ]:        788 :         if (aliasscope)
    1905                 :          0 :             store->setMetadata("noalias", aliasscope);
    1906         [ +  - ]:        788 :         if (tbaa)
    1907                 :        788 :             tbaa_decorate(tbaa, store);
    1908                 :        788 :         instr = store;
    1909                 :            :     }
    1910                 :            :     else {
    1911                 :            :         // replacefield, modifyfield, or swapfield (isboxed && atomic)
    1912                 :         46 :         DoneBB = BasicBlock::Create(ctx.builder.getContext(), "done_xchg", ctx.f);
    1913                 :            :         bool needloop;
    1914                 :         46 :         PHINode *Succ = nullptr, *Current = nullptr;
    1915         [ +  - ]:         46 :         if (isreplacefield) {
    1916         [ -  + ]:         46 :             if (Order == AtomicOrdering::NotAtomic) {
    1917                 :          0 :                 needloop = false;
    1918                 :            :             }
    1919         [ +  + ]:         46 :             else if (!isboxed) {
    1920         [ -  + ]:         32 :                 assert(jl_is_concrete_type(jltype));
    1921                 :         32 :                 needloop = ((jl_datatype_t*)jltype)->layout->haspadding;
    1922                 :         32 :                 Value *SameType = emit_isa(ctx, cmp, jltype, nullptr).first;
    1923         [ -  + ]:         32 :                 if (SameType != ConstantInt::getTrue(ctx.builder.getContext())) {
    1924                 :          0 :                     BasicBlock *SkipBB = BasicBlock::Create(ctx.builder.getContext(), "skip_xchg", ctx.f);
    1925                 :          0 :                     BasicBlock *BB = BasicBlock::Create(ctx.builder.getContext(), "ok_xchg", ctx.f);
    1926                 :          0 :                     ctx.builder.CreateCondBr(SameType, BB, SkipBB);
    1927                 :          0 :                     ctx.builder.SetInsertPoint(SkipBB);
    1928                 :          0 :                     LoadInst *load = ctx.builder.CreateAlignedLoad(elty, ptr, Align(alignment));
    1929   [ #  #  #  # ]:          0 :                     load->setOrdering(FailOrder == AtomicOrdering::NotAtomic && isboxed ? AtomicOrdering::Monotonic : FailOrder);
    1930         [ #  # ]:          0 :                     if (aliasscope)
    1931                 :          0 :                         load->setMetadata("noalias", aliasscope);
    1932         [ #  # ]:          0 :                     if (tbaa)
    1933                 :          0 :                         tbaa_decorate(tbaa, load);
    1934                 :          0 :                     instr = load;
    1935                 :          0 :                     ctx.builder.CreateBr(DoneBB);
    1936                 :          0 :                     ctx.builder.SetInsertPoint(DoneBB);
    1937                 :          0 :                     Succ = ctx.builder.CreatePHI(getInt1Ty(ctx.builder.getContext()), 2);
    1938                 :          0 :                     Succ->addIncoming(ConstantInt::get(getInt1Ty(ctx.builder.getContext()), false), SkipBB);
    1939                 :          0 :                     Current = ctx.builder.CreatePHI(instr->getType(), 2);
    1940                 :          0 :                     Current->addIncoming(instr, SkipBB);
    1941                 :          0 :                     ctx.builder.SetInsertPoint(BB);
    1942                 :            :                 }
    1943                 :         32 :                 Compare = emit_unbox(ctx, realelty, cmp, jltype);
    1944         [ -  + ]:         32 :                 if (realelty != elty)
    1945                 :          0 :                     Compare = ctx.builder.CreateZExt(Compare, elty);
    1946                 :            :             }
    1947   [ +  -  -  +  :         14 :             else if (cmp.isboxed || cmp.constant || jl_pointer_egal(jltype)) {
             -  -  +  - ]
    1948                 :         14 :                 Compare = boxed(ctx, cmp);
    1949   [ +  -  -  + ]:         14 :                 needloop = !jl_pointer_egal(jltype) && !jl_pointer_egal(cmp.typ);
    1950   [ -  +  -  - ]:         14 :                 if (needloop && !cmp.isboxed) // try to use the same box in the compare now and later
    1951                 :          0 :                     cmp = mark_julia_type(ctx, Compare, true, cmp.typ);
    1952                 :            :             }
    1953                 :            :             else {
    1954                 :          0 :                 Compare = Constant::getNullValue(ctx.types().T_prjlvalue); // TODO: does this need to be an invalid bit pattern?
    1955                 :          0 :                 needloop = true;
    1956                 :            :             }
    1957                 :            :         }
    1958                 :            :         else { // swap or modify
    1959                 :          0 :             LoadInst *Current = ctx.builder.CreateAlignedLoad(elty, ptr, Align(alignment));
    1960   [ #  #  #  # ]:          0 :             Current->setOrdering(Order == AtomicOrdering::NotAtomic && !isboxed ? Order : AtomicOrdering::Monotonic);
    1961         [ #  # ]:          0 :             if (aliasscope)
    1962                 :          0 :                 Current->setMetadata("noalias", aliasscope);
    1963         [ #  # ]:          0 :             if (tbaa)
    1964                 :          0 :                 tbaa_decorate(tbaa, Current);
    1965                 :          0 :             Compare = Current;
    1966   [ #  #  #  # ]:          0 :             needloop = !isswapfield || Order != AtomicOrdering::NotAtomic;
    1967                 :            :         }
    1968                 :         46 :         BasicBlock *BB = NULL;
    1969                 :         46 :         PHINode *CmpPhi = NULL;
    1970         [ -  + ]:         46 :         if (needloop) {
    1971                 :          0 :             BasicBlock *From = ctx.builder.GetInsertBlock();
    1972                 :          0 :             BB = BasicBlock::Create(ctx.builder.getContext(), "xchg", ctx.f);
    1973                 :          0 :             ctx.builder.CreateBr(BB);
    1974                 :          0 :             ctx.builder.SetInsertPoint(BB);
    1975                 :          0 :             CmpPhi = ctx.builder.CreatePHI(elty, 2);
    1976                 :          0 :             CmpPhi->addIncoming(Compare, From);
    1977                 :          0 :             Compare = CmpPhi;
    1978                 :            :         }
    1979         [ -  + ]:         46 :         if (ismodifyfield) {
    1980         [ #  # ]:          0 :             if (needlock)
    1981                 :          0 :                 emit_lockstate_value(ctx, parent, false);
    1982                 :          0 :             Value *realCompare = Compare;
    1983         [ #  # ]:          0 :             if (realelty != elty)
    1984                 :          0 :                 realCompare = ctx.builder.CreateTrunc(realCompare, realelty);
    1985         [ #  # ]:          0 :             if (intcast) {
    1986                 :          0 :                 ctx.builder.CreateStore(realCompare, ctx.builder.CreateBitCast(intcast, realCompare->getType()->getPointerTo()));
    1987         [ #  # ]:          0 :                 if (maybe_null_if_boxed)
    1988                 :          0 :                     realCompare = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast);
    1989                 :            :             }
    1990         [ #  # ]:          0 :             if (maybe_null_if_boxed) {
    1991         [ #  # ]:          0 :                 Value *first_ptr = isboxed ? Compare : extract_first_ptr(ctx, Compare);
    1992         [ #  # ]:          0 :                 if (first_ptr)
    1993                 :          0 :                     null_pointer_check(ctx, first_ptr, nullptr);
    1994                 :            :             }
    1995         [ #  # ]:          0 :             if (intcast)
    1996                 :          0 :                 oldval = mark_julia_slot(intcast, jltype, NULL, ctx.tbaa().tbaa_stack);
    1997                 :            :             else
    1998                 :          0 :                 oldval = mark_julia_type(ctx, realCompare, isboxed, jltype);
    1999                 :          0 :             rhs = newval(oldval);
    2000         [ #  # ]:          0 :             if (isboxed) {
    2001                 :          0 :                 r = boxed(ctx, rhs);
    2002                 :            :             }
    2003   [ #  #  #  #  :          0 :             else if (Order != AtomicOrdering::NotAtomic || CountTrackedPointers(realelty).count) {
                   #  # ]
    2004                 :          0 :                 r = emit_unbox(ctx, realelty, rhs, jltype);
    2005         [ #  # ]:          0 :                 if (realelty != elty)
    2006                 :          0 :                     r = ctx.builder.CreateZExt(r, elty);
    2007                 :            :             }
    2008         [ #  # ]:          0 :             if (needlock)
    2009                 :          0 :                 emit_lockstate_value(ctx, parent, true);
    2010                 :          0 :             cmp = oldval;
    2011                 :            :         }
    2012                 :            :         Value *Done;
    2013         [ -  + ]:         46 :         if (Order == AtomicOrdering::NotAtomic) {
    2014                 :            :             // modifyfield or replacefield
    2015   [ #  #  #  # ]:          0 :             assert(elty == realelty && !intcast);
    2016                 :          0 :             auto *load = ctx.builder.CreateAlignedLoad(elty, ptr, Align(alignment));
    2017         [ #  # ]:          0 :             if (isboxed)
    2018                 :          0 :                 load->setOrdering(AtomicOrdering::Monotonic);
    2019         [ #  # ]:          0 :             if (aliasscope)
    2020                 :          0 :                 load->setMetadata("noalias", aliasscope);
    2021         [ #  # ]:          0 :             if (tbaa)
    2022                 :          0 :                 tbaa_decorate(tbaa, load);
    2023                 :          0 :             Value *first_ptr = nullptr;
    2024   [ #  #  #  # ]:          0 :             if (maybe_null_if_boxed && !ismodifyfield)
    2025         [ #  # ]:          0 :                 first_ptr = isboxed ? load : extract_first_ptr(ctx, load);
    2026                 :          0 :             oldval = mark_julia_type(ctx, load, isboxed, jltype);
    2027                 :          0 :             Success = emit_nullcheck_guard(ctx, first_ptr, [&] {
    2028                 :          0 :                 return emit_f_is(ctx, oldval, cmp);
    2029                 :            :             });
    2030   [ #  #  #  # ]:          0 :             if (needloop && ismodifyfield)
    2031                 :          0 :                 CmpPhi->addIncoming(load, ctx.builder.GetInsertBlock());
    2032         [ #  # ]:          0 :             assert(Succ == nullptr);
    2033                 :          0 :             BasicBlock *XchgBB = BasicBlock::Create(ctx.builder.getContext(), "xchg", ctx.f);
    2034   [ #  #  #  # ]:          0 :             ctx.builder.CreateCondBr(Success, XchgBB, needloop && ismodifyfield ? BB : DoneBB);
    2035                 :          0 :             ctx.builder.SetInsertPoint(XchgBB);
    2036         [ #  # ]:          0 :             if (r) {
    2037                 :          0 :                 auto *store = ctx.builder.CreateAlignedStore(r, ptr, Align(alignment));
    2038         [ #  # ]:          0 :                 if (aliasscope)
    2039                 :          0 :                     store->setMetadata("noalias", aliasscope);
    2040         [ #  # ]:          0 :                 if (tbaa)
    2041                 :          0 :                     tbaa_decorate(tbaa, store);
    2042                 :            :             }
    2043                 :            :             else {
    2044   [ #  #  #  # ]:          0 :                 assert(!isboxed && rhs.typ == jltype);
    2045                 :          0 :                 emit_unbox_store(ctx, rhs, ptr, tbaa, alignment);
    2046                 :            :             }
    2047                 :          0 :             ctx.builder.CreateBr(DoneBB);
    2048                 :          0 :             instr = load;
    2049                 :            :         }
    2050                 :            :         else {
    2051         [ -  + ]:         46 :             assert(r);
    2052         [ -  + ]:         46 :             if (Order == AtomicOrdering::Unordered)
    2053                 :          0 :                 Order = AtomicOrdering::Monotonic;
    2054   [ -  +  -  - ]:         46 :             if (Order == AtomicOrdering::Monotonic && isboxed)
    2055                 :          0 :                 Order = AtomicOrdering::Release;
    2056         [ -  + ]:         46 :             if (!isreplacefield)
    2057                 :          0 :                 FailOrder = AtomicOrdering::Monotonic;
    2058         [ -  + ]:         46 :             else if (FailOrder == AtomicOrdering::Unordered)
    2059                 :          0 :                 FailOrder = AtomicOrdering::Monotonic;
    2060                 :            : #if JL_LLVM_VERSION >= 130000
    2061                 :         46 :             auto *store = ctx.builder.CreateAtomicCmpXchg(ptr, Compare, r, Align(alignment), Order, FailOrder);
    2062                 :            : #else
    2063                 :            :             auto *store = ctx.builder.CreateAtomicCmpXchg(ptr, Compare, r, Order, FailOrder);
    2064                 :            :             store->setAlignment(Align(alignment));
    2065                 :            : #endif
    2066         [ -  + ]:         46 :             if (aliasscope)
    2067                 :          0 :                 store->setMetadata("noalias", aliasscope);
    2068         [ +  - ]:         46 :             if (tbaa)
    2069                 :         46 :                 tbaa_decorate(tbaa, store);
    2070                 :         46 :             instr = ctx.builder.Insert(ExtractValueInst::Create(store, 0));
    2071                 :         46 :             Success = ctx.builder.Insert(ExtractValueInst::Create(store, 1));
    2072                 :         46 :             Done = Success;
    2073   [ +  -  -  + ]:         46 :             if (isreplacefield && needloop) {
    2074                 :          0 :                 Value *realinstr = instr;
    2075         [ #  # ]:          0 :                 if (realelty != elty)
    2076                 :          0 :                     realinstr = ctx.builder.CreateTrunc(realinstr, realelty);
    2077         [ #  # ]:          0 :                 if (intcast) {
    2078                 :          0 :                     ctx.builder.CreateStore(realinstr, ctx.builder.CreateBitCast(intcast, realinstr->getType()->getPointerTo()));
    2079                 :          0 :                     oldval = mark_julia_slot(intcast, jltype, NULL, ctx.tbaa().tbaa_stack);
    2080         [ #  # ]:          0 :                     if (maybe_null_if_boxed)
    2081                 :          0 :                         realinstr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast);
    2082                 :            :                 }
    2083                 :            :                 else {
    2084                 :          0 :                     oldval = mark_julia_type(ctx, realinstr, isboxed, jltype);
    2085                 :            :                 }
    2086                 :          0 :                 Done = emit_guarded_test(ctx, ctx.builder.CreateNot(Success), false, [&] {
    2087                 :          0 :                     Value *first_ptr = nullptr;
    2088         [ #  # ]:          0 :                     if (maybe_null_if_boxed)
    2089         [ #  # ]:          0 :                         first_ptr = isboxed ? realinstr : extract_first_ptr(ctx, realinstr);
    2090                 :          0 :                     return emit_nullcheck_guard(ctx, first_ptr, [&] {
    2091                 :          0 :                         return emit_f_is(ctx, oldval, cmp);
    2092                 :          0 :                     });
    2093                 :            :                 });
    2094                 :          0 :                 Done = ctx.builder.CreateNot(Done);
    2095                 :            :             }
    2096         [ -  + ]:         46 :             if (needloop)
    2097                 :          0 :                 ctx.builder.CreateCondBr(Done, DoneBB, BB);
    2098                 :            :             else
    2099                 :         46 :                 ctx.builder.CreateBr(DoneBB);
    2100         [ -  + ]:         46 :             if (needloop)
    2101                 :          0 :                 CmpPhi->addIncoming(instr, ctx.builder.GetInsertBlock());
    2102                 :            :         }
    2103         [ -  + ]:         46 :         if (Succ != nullptr) {
    2104                 :          0 :             Current->addIncoming(instr, ctx.builder.GetInsertBlock());
    2105                 :          0 :             instr = Current;
    2106                 :          0 :             Succ->addIncoming(Success, ctx.builder.GetInsertBlock());
    2107                 :          0 :             Success = Succ;
    2108                 :            :         }
    2109                 :            :     }
    2110         [ +  + ]:     144721 :     if (DoneBB)
    2111                 :         46 :         ctx.builder.SetInsertPoint(DoneBB);
    2112         [ -  + ]:     144721 :     if (needlock)
    2113                 :          0 :         emit_lockstate_value(ctx, parent, false);
    2114         [ +  + ]:     144721 :     if (parent != NULL) {
    2115         [ +  + ]:      82259 :         if (isreplacefield) {
    2116                 :            :             // TOOD: avoid this branch if we aren't making a write barrier
    2117                 :         46 :             BasicBlock *BB = BasicBlock::Create(ctx.builder.getContext(), "xchg_wb", ctx.f);
    2118                 :         46 :             DoneBB = BasicBlock::Create(ctx.builder.getContext(), "done_xchg_wb", ctx.f);
    2119                 :         46 :             ctx.builder.CreateCondBr(Success, BB, DoneBB);
    2120                 :         46 :             ctx.builder.SetInsertPoint(BB);
    2121                 :            :         }
    2122         [ +  + ]:      82259 :         if (r) {
    2123         [ +  + ]:      48688 :             if (!isboxed)
    2124                 :       6952 :                 emit_write_multibarrier(ctx, parent, r, rhs.typ);
    2125         [ +  + ]:      41736 :             else if (!type_is_permalloc(rhs.typ))
    2126                 :      29459 :                 emit_write_barrier(ctx, parent, r);
    2127                 :            :         }
    2128         [ +  + ]:      82259 :         if (isreplacefield) {
    2129                 :         46 :             ctx.builder.CreateBr(DoneBB);
    2130                 :         46 :             ctx.builder.SetInsertPoint(DoneBB);
    2131                 :            :         }
    2132                 :            :     }
    2133         [ -  + ]:     144721 :     if (ismodifyfield) {
    2134                 :          0 :         const jl_cgval_t argv[2] = { oldval, rhs };
    2135                 :          0 :         jl_datatype_t *rettyp = jl_apply_modify_type(jltype);
    2136                 :          0 :         oldval = emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv);
    2137                 :            :     }
    2138         [ +  + ]:     144721 :     else if (!issetfield) { // swapfield or replacefield
    2139         [ -  + ]:        866 :         if (realelty != elty)
    2140                 :          0 :             instr = ctx.builder.Insert(CastInst::Create(Instruction::Trunc, instr, realelty));
    2141         [ -  + ]:        866 :         if (intcast) {
    2142                 :          0 :             ctx.builder.CreateStore(instr, ctx.builder.CreateBitCast(intcast, instr->getType()->getPointerTo()));
    2143                 :          0 :             instr = nullptr;
    2144                 :            :         }
    2145         [ -  + ]:        866 :         if (maybe_null_if_boxed) {
    2146         [ #  # ]:          0 :             if (intcast)
    2147                 :          0 :                 instr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast);
    2148         [ #  # ]:          0 :             Value *first_ptr = isboxed ? instr : extract_first_ptr(ctx, instr);
    2149         [ #  # ]:          0 :             if (first_ptr)
    2150                 :          0 :                 null_pointer_check(ctx, first_ptr, nullptr);
    2151   [ #  #  #  # ]:          0 :             if (intcast && !first_ptr)
    2152                 :          0 :                 instr = nullptr;
    2153                 :            :         }
    2154         [ +  - ]:        866 :         if (instr)
    2155                 :        866 :             oldval = mark_julia_type(ctx, instr, isboxed, jltype);
    2156                 :            :         else
    2157                 :          0 :             oldval = mark_julia_slot(intcast, jltype, NULL, ctx.tbaa().tbaa_stack);
    2158         [ +  + ]:        866 :         if (isreplacefield) {
    2159                 :         46 :             Success = ctx.builder.CreateZExt(Success, getInt8Ty(ctx.builder.getContext()));
    2160                 :         46 :             const jl_cgval_t argv[2] = {oldval, mark_julia_type(ctx, Success, false, jl_bool_type)};
    2161                 :         46 :             jl_datatype_t *rettyp = jl_apply_cmpswap_type(jltype);
    2162                 :         46 :             oldval = emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv);
    2163                 :            :         }
    2164                 :            :     }
    2165                 :     144721 :     return oldval;
    2166                 :            : }
    2167                 :            : 
    2168                 :            : // --- convert boolean value to julia ---
    2169                 :            : 
    2170                 :            : // Returns ctx.types().T_pjlvalue
    2171                 :      10144 : static Value *julia_bool(jl_codectx_t &ctx, Value *cond)
    2172                 :            : {
    2173                 :      20288 :     return ctx.builder.CreateSelect(cond, literal_pointer_val(ctx, jl_true),
    2174                 :      10144 :                                           literal_pointer_val(ctx, jl_false));
    2175                 :            : }
    2176                 :            : 
    2177                 :            : // --- accessing the representations of built-in data types ---
    2178                 :            : 
    2179                 :          0 : static void emit_atomic_error(jl_codectx_t &ctx, const std::string &msg)
    2180                 :            : {
    2181                 :          0 :     emit_error(ctx, prepare_call(jlatomicerror_func), msg);
    2182                 :          0 : }
    2183                 :            : 
    2184                 :            : static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &strct,
    2185                 :            :                                          unsigned idx, jl_datatype_t *jt,
    2186                 :            :                                          enum jl_memory_order order, Value **nullcheck=nullptr);
    2187                 :            : 
    2188                 :      10780 : static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
    2189                 :            :         jl_cgval_t *ret, jl_cgval_t strct,
    2190                 :            :         Value *idx, jl_datatype_t *stt, jl_value_t *inbounds,
    2191                 :            :         enum jl_memory_order order)
    2192                 :            : {
    2193                 :      10780 :     ++EmittedGetfieldUnknowns;
    2194                 :      10780 :     size_t nfields = jl_datatype_nfields(stt);
    2195                 :      10780 :     bool maybe_null = (unsigned)stt->name->n_uninitialized != 0;
    2196                 :       7792 :     auto idx0 = [&]() {
    2197                 :       7792 :         return emit_bounds_check(ctx, strct, (jl_value_t*)stt, idx, ConstantInt::get(getSizeTy(ctx.builder.getContext()), nfields), inbounds);
    2198                 :      10780 :     };
    2199         [ -  + ]:      10780 :     if (nfields == 0) {
    2200                 :          0 :         (void)idx0();
    2201                 :          0 :         *ret = jl_cgval_t();
    2202                 :          0 :         return true;
    2203                 :            :     }
    2204         [ +  + ]:      10780 :     if (nfields == 1) {
    2205         [ -  + ]:       1236 :         if (jl_has_free_typevars(jl_field_type(stt, 0))) {
    2206                 :          0 :             return false;
    2207                 :            :         }
    2208                 :       1236 :         (void)idx0();
    2209                 :       1236 :         *ret = emit_getfield_knownidx(ctx, strct, 0, stt, order);
    2210                 :       1236 :         return true;
    2211                 :            :     }
    2212         [ -  + ]:       9544 :     assert(!jl_is_vecelement_type((jl_value_t*)stt));
    2213                 :            : 
    2214         [ +  + ]:       9544 :     if (!strct.ispointer()) { // unboxed
    2215         [ -  + ]:        710 :         assert(jl_is_concrete_immutable((jl_value_t*)stt));
    2216                 :        710 :         bool isboxed = is_datatype_all_pointers(stt);
    2217                 :        710 :         jl_svec_t *types = stt->types;
    2218                 :        710 :         bool issame = is_tupletype_homogeneous(types);
    2219         [ +  + ]:        710 :         if (issame) {
    2220                 :        592 :             jl_value_t *jft = jl_svecref(types, 0);
    2221         [ +  + ]:        592 :             if (strct.isghost) {
    2222                 :         18 :                 (void)idx0();
    2223                 :         18 :                 *ret = ghostValue(ctx, jft);
    2224                 :         18 :                 return true;
    2225                 :            :             }
    2226         [ -  + ]:        574 :             if (isa<VectorType>(strct.V->getType())) {
    2227         [ #  # ]:          0 :                 assert(stt->layout->npointers == 0); // we could, but don't emit this
    2228                 :          0 :                 idx = idx0();
    2229                 :            :                 if (sizeof(void*) != sizeof(int))
    2230                 :          0 :                     idx = ctx.builder.CreateTrunc(idx, getInt32Ty(ctx.builder.getContext())); // llvm3.3 requires this, harmless elsewhere
    2231                 :          0 :                 Value *fld = ctx.builder.CreateExtractElement(strct.V, idx);
    2232                 :          0 :                 *ret = mark_julia_type(ctx, fld, isboxed, jft);
    2233                 :          0 :                 return true;
    2234                 :            :             }
    2235         [ +  - ]:        574 :             else if (isa<ArrayType>(strct.V->getType())) {
    2236   [ +  +  +  + ]:        574 :                 if (!isboxed && nfields > 3) {
    2237                 :            :                     // For small objects and tracked pointers, emit a set of Select statements,
    2238                 :            :                     // otherwise emit as a stack load. This keeps LLVM from becoming unhappy
    2239                 :            :                     // about seeing loads of tracked pointers.
    2240                 :          8 :                     strct = value_to_pointer(ctx, strct);
    2241         [ -  + ]:          8 :                     assert(strct.ispointer());
    2242                 :            :                 }
    2243                 :            :                 // fall-through to next branch, where we'll handle it
    2244                 :            :             }
    2245                 :            :             else {
    2246                 :          0 :                 llvm_unreachable("homogeneous struct should have had a homogeneous type");
    2247                 :            :             }
    2248                 :            :         }
    2249   [ +  +  +  +  :        692 :         if (isboxed || (issame && isa<ArrayType>(strct.V->getType()))) {
             +  +  +  + ]
    2250         [ -  + ]:        602 :             assert((cast<ArrayType>(strct.V->getType())->getElementType() == ctx.types().T_prjlvalue) == isboxed);
    2251                 :        602 :             Value *idx = idx0();
    2252                 :        602 :             unsigned i = 0;
    2253                 :        602 :             Value *fld = ctx.builder.CreateExtractValue(strct.V, makeArrayRef(i));
    2254         [ +  + ]:       1796 :             for (i = 1; i < nfields; i++) {
    2255                 :       2388 :                 fld = ctx.builder.CreateSelect(
    2256                 :       1194 :                         ctx.builder.CreateICmpEQ(idx, ConstantInt::get(idx->getType(), i)),
    2257                 :            :                         ctx.builder.CreateExtractValue(strct.V, makeArrayRef(i)),
    2258                 :            :                         fld);
    2259                 :            :             }
    2260         [ +  + ]:        602 :             jl_value_t *jft = issame ? jl_svecref(types, 0) : (jl_value_t*)jl_any_type;
    2261   [ +  +  -  + ]:        602 :             if (isboxed && maybe_null)
    2262                 :          0 :                 null_pointer_check(ctx, fld);
    2263                 :        602 :             *ret = mark_julia_type(ctx, fld, isboxed, jft);
    2264                 :        602 :             return true;
    2265                 :            :         }
    2266                 :            :     }
    2267                 :            : 
    2268                 :       8924 :     bool maybeatomic = stt->name->atomicfields != NULL;
    2269   [ +  +  +  -  :       8924 :     if (strct.ispointer() && !maybeatomic) { // boxed or stack
                   +  + ]
    2270   [ +  -  -  + ]:       8842 :         if (order != jl_memory_order_notatomic && order != jl_memory_order_unspecified) {
    2271                 :          0 :             emit_atomic_error(ctx, "getfield: non-atomic field cannot be accessed atomically");
    2272                 :          0 :             *ret = jl_cgval_t(); // unreachable
    2273                 :          0 :             return true;
    2274                 :            :         }
    2275         [ +  + ]:       8842 :         if (is_datatype_all_pointers(stt)) {
    2276                 :       4356 :             size_t minimum_field_size = std::numeric_limits<size_t>::max();
    2277                 :       4356 :             size_t minimum_align = JL_HEAP_ALIGNMENT;
    2278         [ +  + ]:       5314 :             for (size_t i = 0; i < nfields; ++i) {
    2279                 :       5036 :                 jl_value_t *ft = jl_field_type(stt, i);
    2280                 :       5036 :                 minimum_field_size = std::min(minimum_field_size,
    2281                 :       5036 :                     dereferenceable_size(ft));
    2282         [ +  + ]:       5036 :                 if (minimum_field_size == 0) {
    2283                 :       4078 :                     minimum_align = 1;
    2284                 :       4078 :                     break;
    2285                 :            :                 }
    2286                 :        958 :                 minimum_align = std::min(minimum_align,
    2287                 :        958 :                     (size_t)julia_alignment(ft));
    2288                 :            :             }
    2289                 :      13068 :             Value *fldptr = ctx.builder.CreateInBoundsGEP(
    2290                 :       4356 :                     ctx.types().T_prjlvalue,
    2291                 :       4356 :                     emit_bitcast(ctx, data_pointer(ctx, strct), ctx.types().T_pprjlvalue),
    2292                 :            :                     idx0());
    2293                 :       4356 :             LoadInst *fld = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, fldptr, Align(sizeof(void*)));
    2294                 :       4356 :             fld->setOrdering(AtomicOrdering::Unordered);
    2295                 :       4356 :             tbaa_decorate(strct.tbaa, fld);
    2296                 :       4356 :             maybe_mark_load_dereferenceable(fld, maybe_null, minimum_field_size, minimum_align);
    2297         [ -  + ]:       4356 :             if (maybe_null)
    2298                 :          0 :                 null_pointer_check(ctx, fld);
    2299                 :       4356 :             *ret = mark_julia_type(ctx, fld, true, jl_any_type);
    2300                 :       4356 :             return true;
    2301                 :            :         }
    2302   [ +  -  +  + ]:       4486 :         else if (is_tupletype_homogeneous(jl_get_fieldtypes(stt))) {
    2303         [ -  + ]:       1580 :             assert(nfields > 0); // nf == 0 trapped by all_pointers case
    2304                 :       1580 :             jl_value_t *jft = jl_svecref(stt->types, 0); // n.b. jl_get_fieldtypes assigned stt->types for here
    2305         [ -  + ]:       1580 :             assert(jl_is_concrete_type(jft));
    2306                 :       1580 :             idx = idx0();
    2307                 :       1580 :             Value *ptr = data_pointer(ctx, strct);
    2308   [ +  -  -  +  :       1580 :             if (!stt->name->mutabl && !(maybe_null && (jft == (jl_value_t*)jl_bool_type ||
                   -  - ]
    2309         [ #  # ]:          0 :                                                  ((jl_datatype_t*)jft)->layout->npointers))) {
    2310                 :            :                 // just compute the pointer and let user load it when necessary
    2311                 :       1580 :                 Type *fty = julia_type_to_llvm(ctx, jft);
    2312                 :       1580 :                 Value *addr = ctx.builder.CreateInBoundsGEP(fty, emit_bitcast(ctx, ptr, PointerType::get(fty, 0)), idx);
    2313                 :       1580 :                 *ret = mark_julia_slot(addr, jft, NULL, strct.tbaa);
    2314                 :       1580 :                 return true;
    2315                 :            :             }
    2316                 :          0 :             *ret = typed_load(ctx, ptr, idx, jft, strct.tbaa, nullptr, false, AtomicOrdering::NotAtomic, maybe_null);
    2317                 :          0 :             return true;
    2318                 :            :         }
    2319         [ +  + ]:       2906 :         else if (strct.isboxed) {
    2320                 :         20 :             idx = ctx.builder.CreateSub(idx, ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1));
    2321                 :         20 :             Value *fld = ctx.builder.CreateCall(prepare_call(jlgetnthfieldchecked_func), { boxed(ctx, strct), idx });
    2322                 :         20 :             *ret = mark_julia_type(ctx, fld, true, jl_any_type);
    2323                 :         20 :             return true;
    2324                 :            :         }
    2325                 :            :     }
    2326                 :       2968 :     return false;
    2327                 :            : }
    2328                 :            : 
    2329                 :       3059 : static jl_cgval_t emit_unionload(jl_codectx_t &ctx, Value *addr, Value *ptindex,
    2330                 :            :         jl_value_t *jfty, size_t fsz, size_t al, MDNode *tbaa, bool mutabl,
    2331                 :            :         unsigned union_max, MDNode *tbaa_ptindex)
    2332                 :            : {
    2333                 :       3059 :     ++EmittedUnionLoads;
    2334                 :       3059 :     Instruction *tindex0 = tbaa_decorate(tbaa_ptindex, ctx.builder.CreateAlignedLoad(getInt8Ty(ctx.builder.getContext()), ptindex, Align(1)));
    2335                 :       3059 :     tindex0->setMetadata(LLVMContext::MD_range, MDNode::get(ctx.builder.getContext(), {
    2336                 :       3059 :         ConstantAsMetadata::get(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0)),
    2337                 :       3059 :         ConstantAsMetadata::get(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), union_max)) }));
    2338                 :       3059 :     Value *tindex = ctx.builder.CreateNUWAdd(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 1), tindex0);
    2339   [ +  -  +  + ]:       3059 :     if (fsz > 0 && mutabl) {
    2340                 :            :         // move value to an immutable stack slot (excluding tindex)
    2341                 :       1836 :         Type *AT = ArrayType::get(IntegerType::get(ctx.builder.getContext(), 8 * al), (fsz + al - 1) / al);
    2342                 :       1836 :         AllocaInst *lv = emit_static_alloca(ctx, AT);
    2343         [ +  + ]:       1836 :         if (al > 1)
    2344                 :       1642 :             lv->setAlignment(Align(al));
    2345                 :       1836 :         emit_memcpy(ctx, lv, tbaa, addr, tbaa, fsz, al);
    2346                 :       1836 :         addr = lv;
    2347                 :            :     }
    2348         [ +  - ]:       3059 :     return mark_julia_slot(fsz > 0 ? addr : nullptr, jfty, tindex, tbaa);
    2349                 :            : }
    2350                 :            : 
    2351                 :            : // If `nullcheck` is not NULL and a pointer NULL check is necessary
    2352                 :            : // store the pointer to be checked in `*nullcheck` instead of checking it
    2353                 :     500303 : static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &strct,
    2354                 :            :                                          unsigned idx, jl_datatype_t *jt,
    2355                 :            :                                          enum jl_memory_order order, Value **nullcheck)
    2356                 :            : {
    2357                 :     500303 :     jl_value_t *jfty = jl_field_type(jt, idx);
    2358                 :     500303 :     bool isatomic = jl_field_isatomic(jt, idx);
    2359   [ +  +  +  +  :     500303 :     bool needlock = isatomic && !jl_field_isptr(jt, idx) && jl_datatype_size(jfty) > MAX_ATOMIC_SIZE;
                   -  + ]
    2360   [ +  +  +  +  :     500303 :     if (!isatomic && order != jl_memory_order_notatomic && order != jl_memory_order_unspecified) {
                   -  + ]
    2361                 :          0 :         emit_atomic_error(ctx, "getfield: non-atomic field cannot be accessed atomically");
    2362                 :          0 :         return jl_cgval_t(); // unreachable
    2363                 :            :     }
    2364   [ +  +  -  + ]:     500303 :     if (isatomic && order == jl_memory_order_notatomic) {
    2365                 :          0 :         emit_atomic_error(ctx, "getfield: atomic field cannot be accessed non-atomically");
    2366                 :          0 :         return jl_cgval_t(); // unreachable
    2367                 :            :     }
    2368         [ +  + ]:     500303 :     if (order == jl_memory_order_unspecified) {
    2369         [ +  + ]:     472861 :         order = isatomic ? jl_memory_order_unordered : jl_memory_order_notatomic;
    2370                 :            :     }
    2371         [ -  + ]:     500303 :     if (jfty == jl_bottom_type) {
    2372                 :          0 :         raise_exception(ctx, literal_pointer_val(ctx, jl_undefref_exception));
    2373                 :          0 :         return jl_cgval_t(); // unreachable
    2374                 :            :     }
    2375         [ +  + ]:     500303 :     if (type_is_ghost(julia_type_to_llvm(ctx, jfty)))
    2376                 :        809 :         return ghostValue(ctx, jfty);
    2377                 :     499494 :     size_t nfields = jl_datatype_nfields(jt);
    2378                 :     499494 :     bool maybe_null = idx >= nfields - (unsigned)jt->name->n_uninitialized;
    2379                 :     499494 :     size_t byte_offset = jl_field_offset(jt, idx);
    2380                 :     499494 :     auto tbaa = strct.tbaa;
    2381   [ +  +  +  -  :     499494 :     if (tbaa == ctx.tbaa().tbaa_datatype && byte_offset != offsetof(jl_datatype_t, types))
                   +  + ]
    2382                 :       3150 :         tbaa = ctx.tbaa().tbaa_const;
    2383         [ +  + ]:     499494 :     if (strct.ispointer()) {
    2384                 :     463621 :         Value *staddr = data_pointer(ctx, strct);
    2385                 :            :         bool isboxed;
    2386                 :     463621 :         Type *lt = julia_type_to_llvm(ctx, (jl_value_t*)jt, &isboxed);
    2387                 :            :         Value *addr;
    2388         [ +  + ]:     463621 :         if (isboxed) {
    2389                 :            :             // byte_offset == 0 is an important special case here, e.g.
    2390                 :            :             // for single field wrapper types. Introducing the bitcast
    2391                 :            :             // can pessimize mem2reg
    2392         [ +  + ]:     229116 :             if (byte_offset > 0) {
    2393                 :     456108 :                 addr = ctx.builder.CreateInBoundsGEP(
    2394                 :     152036 :                         getInt8Ty(ctx.builder.getContext()),
    2395                 :     152036 :                         emit_bitcast(ctx, staddr, getInt8PtrTy(ctx.builder.getContext())),
    2396                 :     152036 :                         ConstantInt::get(getSizeTy(ctx.builder.getContext()), byte_offset));
    2397                 :            :             }
    2398                 :            :             else {
    2399                 :      77080 :                 addr = staddr;
    2400                 :            :             }
    2401                 :            :         }
    2402                 :            :         else {
    2403                 :     234505 :             staddr = maybe_bitcast(ctx, staddr, lt->getPointerTo());
    2404         [ -  + ]:     234505 :             if (jl_is_vecelement_type((jl_value_t*)jt))
    2405                 :          0 :                 addr = staddr; // VecElement types are unwrapped in LLVM.
    2406         [ +  + ]:     234505 :             else if (isa<StructType>(lt))
    2407                 :     103736 :                 addr = emit_struct_gep(ctx, lt, staddr, byte_offset);
    2408                 :            :             else
    2409                 :     130769 :                 addr = ctx.builder.CreateConstInBoundsGEP2_32(lt, staddr, 0, idx);
    2410                 :            :         }
    2411         [ +  + ]:     463621 :         if (jl_field_isptr(jt, idx)) {
    2412                 :     231348 :             LoadInst *Load = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, maybe_bitcast(ctx, addr, ctx.types().T_pprjlvalue), Align(sizeof(void*)));
    2413         [ +  + ]:     231348 :             Load->setOrdering(order <= jl_memory_order_notatomic ? AtomicOrdering::Unordered : get_llvm_atomic_order(order));
    2414                 :     231348 :             maybe_mark_load_dereferenceable(Load, maybe_null, jl_field_type(jt, idx));
    2415                 :     231348 :             Value *fldv = tbaa_decorate(tbaa, Load);
    2416         [ +  + ]:     231348 :             if (maybe_null)
    2417                 :      10366 :                 null_pointer_check(ctx, fldv, nullcheck);
    2418                 :     231348 :             return mark_julia_type(ctx, fldv, true, jfty);
    2419                 :            :         }
    2420         [ +  + ]:     232273 :         else if (jl_is_uniontype(jfty)) {
    2421                 :       2773 :             size_t fsz = 0, al = 0;
    2422                 :       2773 :             int union_max = jl_islayout_inline(jfty, &fsz, &al);
    2423                 :       2773 :             bool isptr = (union_max == 0);
    2424   [ +  -  +  - ]:       2773 :             assert(!isptr && fsz == jl_field_size(jt, idx) - 1); (void)isptr;
    2425                 :            :             Value *ptindex;
    2426         [ +  + ]:       2773 :             if (isboxed) {
    2427                 :       4650 :                 ptindex = ctx.builder.CreateConstInBoundsGEP1_32(
    2428                 :       3100 :                     getInt8Ty(ctx.builder.getContext()), emit_bitcast(ctx, staddr, getInt8PtrTy(ctx.builder.getContext())), byte_offset + fsz);
    2429                 :            :             }
    2430                 :            :             else {
    2431                 :       1223 :                 ptindex = emit_struct_gep(ctx, cast<StructType>(lt), staddr, byte_offset + fsz);
    2432                 :            :             }
    2433                 :       2773 :             return emit_unionload(ctx, addr, ptindex, jfty, fsz, al, tbaa, !jl_field_isconst(jt, idx), union_max, ctx.tbaa().tbaa_unionselbyte);
    2434                 :            :         }
    2435         [ -  + ]:     229500 :         assert(jl_is_concrete_type(jfty));
    2436   [ +  +  +  +  :     230587 :         if (jl_field_isconst(jt, idx) && !(maybe_null && (jfty == (jl_value_t*)jl_bool_type ||
             +  -  +  + ]
    2437         [ +  - ]:       1087 :                                             ((jl_datatype_t*)jfty)->layout->npointers))) {
    2438                 :            :             // just compute the pointer and let user load it when necessary
    2439                 :     140750 :             return mark_julia_slot(addr, jfty, NULL, tbaa);
    2440                 :            :         }
    2441                 :      88750 :         unsigned align = jl_field_align(jt, idx);
    2442         [ -  + ]:      88750 :         if (needlock)
    2443                 :          0 :             emit_lockstate_value(ctx, strct, true);
    2444                 :            :         jl_cgval_t ret = typed_load(ctx, addr, NULL, jfty, tbaa, nullptr, false,
    2445                 :      88750 :                 needlock ? AtomicOrdering::NotAtomic : get_llvm_atomic_order(order),
    2446         [ -  + ]:     177500 :                 maybe_null, align, nullcheck);
    2447         [ -  + ]:      88750 :         if (needlock)
    2448                 :          0 :             emit_lockstate_value(ctx, strct, false);
    2449                 :      88750 :         return ret;
    2450                 :            :     }
    2451         [ -  + ]:      35873 :     else if (isa<UndefValue>(strct.V)) {
    2452                 :          0 :         return jl_cgval_t();
    2453                 :            :     }
    2454                 :            :     else {
    2455                 :      35873 :         Value *obj = strct.V; // aka emit_unbox
    2456                 :      35873 :         Type *T = obj->getType();
    2457                 :            :         Value *fldv;
    2458         [ -  + ]:      35873 :         if (jl_is_vecelement_type((jl_value_t*)jt)) {
    2459                 :            :             // VecElement types are unwrapped in LLVM.
    2460                 :          0 :             fldv = obj;
    2461                 :            :         }
    2462         [ -  + ]:      35873 :         else if (isa<VectorType>(T)) {
    2463                 :          0 :             fldv = ctx.builder.CreateExtractElement(obj, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), idx));
    2464                 :            :         }
    2465   [ +  +  +  +  :      35873 :         else if (!jl_field_isptr(jt, idx) && jl_is_uniontype(jfty)) {
                   +  + ]
    2466                 :        636 :             int fsz = jl_field_size(jt, idx) - 1;
    2467                 :        636 :             unsigned ptindex = convert_struct_offset(ctx, T, byte_offset + fsz);
    2468                 :        636 :             AllocaInst *lv = NULL;
    2469         [ +  - ]:        636 :             if (fsz > 0) {
    2470                 :        636 :                 unsigned st_idx = convert_struct_offset(ctx, T, byte_offset);
    2471                 :        636 :                 IntegerType *ET = cast<IntegerType>(T->getStructElementType(st_idx));
    2472                 :        636 :                 unsigned align = (ET->getBitWidth() + 7) / 8;
    2473                 :        636 :                 lv = emit_static_alloca(ctx, ET);
    2474                 :        636 :                 lv->setOperand(0, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), (fsz + align - 1) / align));
    2475                 :            :                 // emit all of the align-sized words
    2476                 :        636 :                 unsigned i = 0;
    2477         [ +  + ]:       1820 :                 for (; i < fsz / align; i++) {
    2478                 :       1184 :                     unsigned fld = st_idx + i;
    2479                 :       1184 :                     Value *fldv = ctx.builder.CreateExtractValue(obj, makeArrayRef(fld));
    2480                 :       1184 :                     Value *fldp = ctx.builder.CreateConstInBoundsGEP1_32(ET, lv, i);
    2481                 :       1184 :                     ctx.builder.CreateAlignedStore(fldv, fldp, Align(align));
    2482                 :            :                 }
    2483                 :            :                 // emit remaining bytes up to tindex
    2484         [ -  + ]:        636 :                 if (i < ptindex - st_idx) {
    2485                 :          0 :                     Value *staddr = ctx.builder.CreateConstInBoundsGEP1_32(ET, lv, i);
    2486                 :          0 :                     staddr = ctx.builder.CreateBitCast(staddr, getInt8PtrTy(ctx.builder.getContext()));
    2487         [ #  # ]:          0 :                     for (; i < ptindex - st_idx; i++) {
    2488                 :          0 :                         Value *fldv = ctx.builder.CreateExtractValue(obj, makeArrayRef(st_idx + i));
    2489                 :          0 :                         Value *fldp = ctx.builder.CreateConstInBoundsGEP1_32(getInt8Ty(ctx.builder.getContext()), staddr, i);
    2490                 :          0 :                         ctx.builder.CreateAlignedStore(fldv, fldp, Align(1));
    2491                 :            :                     }
    2492                 :            :                 }
    2493                 :            :             }
    2494                 :        636 :             Value *tindex0 = ctx.builder.CreateExtractValue(obj, makeArrayRef(ptindex));
    2495                 :        636 :             Value *tindex = ctx.builder.CreateNUWAdd(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 1), tindex0);
    2496                 :        636 :             return mark_julia_slot(lv, jfty, tindex, ctx.tbaa().tbaa_stack);
    2497                 :            :         }
    2498                 :            :         else {
    2499                 :            :             unsigned st_idx;
    2500         [ +  + ]:      35237 :             if (isa<ArrayType>(T))
    2501                 :      12722 :                 st_idx = idx;
    2502         [ +  - ]:      22515 :             else if (isa<StructType>(T))
    2503                 :      22515 :                 st_idx = convert_struct_offset(ctx, T, byte_offset);
    2504                 :            :             else
    2505                 :          0 :                 llvm_unreachable("encountered incompatible type for a struct");
    2506                 :      35237 :             fldv = ctx.builder.CreateExtractValue(obj, makeArrayRef(st_idx));
    2507                 :            :         }
    2508         [ -  + ]:      35237 :         if (maybe_null) {
    2509         [ #  # ]:          0 :             Value *first_ptr = jl_field_isptr(jt, idx) ? fldv : extract_first_ptr(ctx, fldv);
    2510         [ #  # ]:          0 :             if (first_ptr)
    2511                 :          0 :                 null_pointer_check(ctx, first_ptr, nullcheck);
    2512                 :            :         }
    2513                 :      35237 :         return mark_julia_type(ctx, fldv, jl_field_isptr(jt, idx), jfty);
    2514                 :            :     }
    2515                 :            : }
    2516                 :            : 
    2517                 :            : // emit length of vararg tuple
    2518                 :       7440 : static Value *emit_n_varargs(jl_codectx_t &ctx)
    2519                 :            : {
    2520                 :       7440 :     ++EmittedVarargsLength;
    2521                 :       7440 :     Value *valen = NULL;
    2522         [ -  + ]:       7440 :     if (ctx.nvargs != -1) {
    2523                 :          0 :         valen = ConstantInt::get(getInt32Ty(ctx.builder.getContext()), ctx.nvargs);
    2524                 :            :     } else {
    2525         [ -  + ]:       7440 :         assert(ctx.argCount);
    2526                 :       7440 :         int nreq = ctx.nReqArgs;
    2527                 :      14880 :         valen = ctx.builder.CreateSub((Value*)ctx.argCount,
    2528                 :       7440 :                                         ConstantInt::get(getInt32Ty(ctx.builder.getContext()), nreq));
    2529                 :            :     }
    2530                 :            : #ifdef _P64
    2531                 :       7440 :     return ctx.builder.CreateSExt(valen, getInt64Ty(ctx.builder.getContext()));
    2532                 :            : #else
    2533                 :            :     return valen;
    2534                 :            : #endif
    2535                 :            : }
    2536                 :            : 
    2537                 :     361409 : static bool arraytype_constdim(jl_value_t *ty, size_t *dim)
    2538                 :            : {
    2539   [ +  +  +  -  :     361409 :     if (jl_is_array_type(ty) && jl_is_long(jl_tparam1(ty))) {
                   +  + ]
    2540                 :     361339 :         *dim = jl_unbox_long(jl_tparam1(ty));
    2541                 :     361339 :         return true;
    2542                 :            :     }
    2543                 :         70 :     return false;
    2544                 :            : }
    2545                 :            : 
    2546                 :     171136 : static bool arraytype_constshape(jl_value_t *ty)
    2547                 :            : {
    2548                 :            :     size_t dim;
    2549         [ +  + ]:     171136 :     if (!arraytype_constdim(ty, &dim))
    2550                 :          2 :         return false;
    2551                 :     171134 :     return dim != 1;
    2552                 :            : }
    2553                 :            : 
    2554                 :     169034 : static bool arraytype_constelsize(jl_datatype_t *ty, size_t *elsz)
    2555                 :            : {
    2556         [ -  + ]:     169034 :     assert(jl_is_array_type(ty));
    2557                 :     169034 :     jl_value_t *ety = jl_tparam0(ty);
    2558         [ +  + ]:     169034 :     if (jl_has_free_typevars(ety))
    2559                 :          1 :         return false;
    2560                 :            :     // `jl_islayout_inline` requires `*elsz` and `al` to be initialized.
    2561                 :     169033 :     size_t al = 0;
    2562                 :     169033 :     *elsz = 0;
    2563                 :     169033 :     int union_max = jl_islayout_inline(ety, elsz, &al);
    2564                 :     169033 :     bool isboxed = (union_max == 0);
    2565         [ +  + ]:     169033 :     if (isboxed) {
    2566                 :      91474 :         *elsz = sizeof(void*);
    2567                 :            :     }
    2568         [ +  + ]:      77559 :     else if (jl_is_primitivetype(ety)) {
    2569                 :            :         // Primitive types should use the array element size, but
    2570                 :            :         // this can be different from the type's size
    2571                 :      51843 :         *elsz = LLT_ALIGN(*elsz, al);
    2572                 :            :     }
    2573                 :     169033 :     return true;
    2574                 :            : }
    2575                 :            : 
    2576                 :     168899 : static intptr_t arraytype_maxsize(jl_value_t *ty)
    2577                 :            : {
    2578         [ +  + ]:     168899 :     if (!jl_is_array_type(ty))
    2579                 :         68 :         return INTPTR_MAX;
    2580                 :            :     size_t elsz;
    2581   [ -  +  -  -  :     168831 :     if (arraytype_constelsize((jl_datatype_t*)ty, &elsz) || elsz == 0)
                   +  - ]
    2582                 :     168831 :         return INTPTR_MAX;
    2583                 :          0 :     return INTPTR_MAX / elsz;
    2584                 :            : }
    2585                 :            : 
    2586                 :            : static Value *emit_arraylen(jl_codectx_t &ctx, const jl_cgval_t &tinfo);
    2587                 :            : 
    2588                 :      22665 : static Value *emit_arraysize(jl_codectx_t &ctx, const jl_cgval_t &tinfo, Value *dim)
    2589                 :            : {
    2590                 :            :     size_t ndim;
    2591                 :      22665 :     MDNode *tbaa = ctx.tbaa().tbaa_arraysize;
    2592         [ +  + ]:      22665 :     if (arraytype_constdim(tinfo.typ, &ndim)) {
    2593         [ -  + ]:      22632 :         if (ndim == 0)
    2594                 :          0 :             return ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1);
    2595         [ +  + ]:      22632 :         if (ndim == 1) {
    2596         [ +  + ]:      21996 :             if (auto d = dyn_cast<ConstantInt>(dim)) {
    2597         [ +  + ]:      21978 :                 if (d->getZExtValue() == 1) {
    2598                 :      21358 :                     return emit_arraylen(ctx, tinfo);
    2599                 :            :                 }
    2600                 :            :             }
    2601                 :            :         }
    2602         [ +  + ]:       1274 :         if (ndim > 1) {
    2603   [ -  +  -  -  :        636 :             if (tinfo.constant && isa<ConstantInt>(dim)) {
                   -  + ]
    2604                 :          0 :                 auto n = cast<ConstantInt>(dim)->getZExtValue() - 1;
    2605                 :          0 :                 return ConstantInt::get(getSizeTy(ctx.builder.getContext()), jl_array_dim(tinfo.constant, n));
    2606                 :            :             }
    2607                 :        636 :             tbaa = ctx.tbaa().tbaa_const;
    2608                 :            :         }
    2609                 :            :     }
    2610                 :       1307 :     ++EmittedArraysize;
    2611                 :       1307 :     Value *t = boxed(ctx, tinfo);
    2612                 :       1307 :     int o = offsetof(jl_array_t, nrows) / sizeof(void*) - 1;
    2613                 :       2614 :     auto load = emit_nthptr_recast(ctx,
    2614                 :            :             t,
    2615                 :       1307 :             ctx.builder.CreateAdd(dim, ConstantInt::get(dim->getType(), o)),
    2616                 :       1307 :             tbaa, getSizeTy(ctx.builder.getContext()));
    2617                 :       1307 :     MDBuilder MDB(ctx.builder.getContext());
    2618                 :       1307 :     auto rng = MDB.createRange(Constant::getNullValue(getSizeTy(ctx.builder.getContext())), ConstantInt::get(getSizeTy(ctx.builder.getContext()), arraytype_maxsize(tinfo.typ)));
    2619                 :       1307 :     load->setMetadata(LLVMContext::MD_range, rng);
    2620                 :       1307 :     return load;
    2621                 :            : }
    2622                 :            : 
    2623                 :      22615 : static Value *emit_arraysize(jl_codectx_t &ctx, const jl_cgval_t &tinfo, int dim)
    2624                 :            : {
    2625                 :      22615 :     return emit_arraysize(ctx, tinfo, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), dim));
    2626                 :            : }
    2627                 :            : 
    2628                 :        620 : static Value *emit_vectormaxsize(jl_codectx_t &ctx, const jl_cgval_t &ary)
    2629                 :            : {
    2630                 :        620 :     return emit_arraysize(ctx, ary, 2); // maxsize aliases ncols in memory layout for vector
    2631                 :            : }
    2632                 :            : 
    2633                 :     167608 : static Value *emit_arraylen_prim(jl_codectx_t &ctx, const jl_cgval_t &tinfo)
    2634                 :            : {
    2635                 :            :     size_t ndim;
    2636                 :     167608 :     jl_value_t *ty = tinfo.typ;
    2637                 :     167608 :     MDNode *tbaa = ctx.tbaa().tbaa_arraylen;
    2638         [ +  + ]:     167608 :     if (arraytype_constdim(ty, &ndim)) {
    2639         [ +  + ]:     167573 :         if (ndim == 0)
    2640                 :         16 :             return ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1);
    2641         [ +  + ]:     167557 :         if (ndim != 1) {
    2642         [ -  + ]:         54 :             if (tinfo.constant)
    2643                 :          0 :                 return ConstantInt::get(getSizeTy(ctx.builder.getContext()), jl_array_len(tinfo.constant));
    2644                 :         54 :             tbaa = ctx.tbaa().tbaa_const;
    2645                 :            :         }
    2646                 :            :     }
    2647                 :     167592 :     ++EmittedArraylen;
    2648                 :     167592 :     Value *t = boxed(ctx, tinfo);
    2649                 :     335184 :     Value *addr = ctx.builder.CreateStructGEP(ctx.types().T_jlarray,
    2650                 :     167592 :             emit_bitcast(ctx, decay_derived(ctx, t), ctx.types().T_pjlarray),
    2651                 :            :             1); //index (not offset) of length field in ctx.types().T_pjlarray
    2652                 :     167592 :     LoadInst *len = ctx.builder.CreateAlignedLoad(getSizeTy(ctx.builder.getContext()), addr, Align(sizeof(size_t)));
    2653                 :     167592 :     len->setOrdering(AtomicOrdering::NotAtomic);
    2654                 :     167592 :     MDBuilder MDB(ctx.builder.getContext());
    2655                 :     167592 :     auto rng = MDB.createRange(Constant::getNullValue(getSizeTy(ctx.builder.getContext())), ConstantInt::get(getSizeTy(ctx.builder.getContext()), arraytype_maxsize(tinfo.typ)));
    2656                 :     167592 :     len->setMetadata(LLVMContext::MD_range, rng);
    2657                 :     167592 :     return tbaa_decorate(tbaa, len);
    2658                 :            : }
    2659                 :            : 
    2660                 :     167608 : static Value *emit_arraylen(jl_codectx_t &ctx, const jl_cgval_t &tinfo)
    2661                 :            : {
    2662                 :     167608 :     return emit_arraylen_prim(ctx, tinfo);
    2663                 :            : }
    2664                 :            : 
    2665                 :     171136 : static Value *emit_arrayptr_internal(jl_codectx_t &ctx, const jl_cgval_t &tinfo, Value *t, unsigned AS, bool isboxed)
    2666                 :            : {
    2667                 :     171136 :     ++EmittedArrayptr;
    2668                 :     342272 :     Value *addr = ctx.builder.CreateStructGEP(ctx.types().T_jlarray,
    2669                 :     171136 :                                               emit_bitcast(ctx, t, ctx.types().T_pjlarray), 0);
    2670                 :            :     // Normally allocated array of 0 dimension always have a inline pointer.
    2671                 :            :     // However, we can't rely on that here since arrays can also be constructed from C pointers.
    2672                 :     171136 :     PointerType *PT = cast<PointerType>(addr->getType());
    2673                 :     171136 :     PointerType *PPT = cast<PointerType>(ctx.types().T_jlarray->getElementType(0));
    2674                 :     171136 :     PointerType *LoadT = PPT;
    2675                 :            : 
    2676         [ +  + ]:     171136 :     if (isboxed) {
    2677                 :      23631 :         LoadT = PointerType::get(ctx.types().T_prjlvalue, AS);
    2678                 :            :     }
    2679         [ +  + ]:     147505 :     else if (AS != PPT->getAddressSpace()) {
    2680                 :      11748 :         LoadT = PointerType::getWithSamePointeeType(PPT, AS);
    2681                 :            :     }
    2682         [ +  + ]:     171136 :     if (LoadT != PPT) {
    2683                 :      35379 :         const auto Ty = PointerType::get(LoadT, PT->getAddressSpace());
    2684                 :      35379 :         addr = ctx.builder.CreateBitCast(addr, Ty);
    2685                 :            :     }
    2686                 :            : 
    2687                 :     171136 :     LoadInst *LI = ctx.builder.CreateAlignedLoad(LoadT, addr, Align(sizeof(char *)));
    2688                 :     171136 :     LI->setOrdering(AtomicOrdering::NotAtomic);
    2689                 :     171136 :     LI->setMetadata(LLVMContext::MD_nonnull, MDNode::get(ctx.builder.getContext(), None));
    2690         [ +  + ]:     171136 :     tbaa_decorate(arraytype_constshape(tinfo.typ) ? ctx.tbaa().tbaa_const : ctx.tbaa().tbaa_arrayptr, LI);
    2691                 :     171136 :     return LI;
    2692                 :            : }
    2693                 :            : 
    2694                 :     159388 : static Value *emit_arrayptr(jl_codectx_t &ctx, const jl_cgval_t &tinfo, bool isboxed = false)
    2695                 :            : {
    2696                 :     159388 :     Value *t = boxed(ctx, tinfo);
    2697                 :     159388 :     return emit_arrayptr_internal(ctx, tinfo, decay_derived(ctx, t), AddressSpace::Loaded, isboxed);
    2698                 :            : }
    2699                 :            : 
    2700                 :      11748 : static Value *emit_unsafe_arrayptr(jl_codectx_t &ctx, const jl_cgval_t &tinfo, bool isboxed = false)
    2701                 :            : {
    2702                 :      11748 :     Value *t = boxed(ctx, tinfo);
    2703                 :      11748 :     t = emit_pointer_from_objref(ctx, decay_derived(ctx, t));
    2704                 :      11748 :     return emit_arrayptr_internal(ctx, tinfo, t, 0, isboxed);
    2705                 :            : }
    2706                 :            : 
    2707                 :     159388 : static Value *emit_arrayptr(jl_codectx_t &ctx, const jl_cgval_t &tinfo, jl_value_t *ex, bool isboxed = false)
    2708                 :            : {
    2709                 :     159388 :     return emit_arrayptr(ctx, tinfo, isboxed);
    2710                 :            : }
    2711                 :            : 
    2712                 :      21995 : static Value *emit_arraysize(jl_codectx_t &ctx, const jl_cgval_t &tinfo, jl_value_t *ex, int dim)
    2713                 :            : {
    2714                 :      21995 :     return emit_arraysize(ctx, tinfo, dim);
    2715                 :            : }
    2716                 :            : 
    2717                 :      29144 : static Value *emit_arrayflags(jl_codectx_t &ctx, const jl_cgval_t &tinfo)
    2718                 :            : {
    2719                 :      29144 :     ++EmittedArrayflags;
    2720                 :      29144 :     Value *t = boxed(ctx, tinfo);
    2721                 :      29144 :     int arrayflag_field = 2;
    2722                 :      58288 :     Value *addr = ctx.builder.CreateStructGEP(
    2723                 :      29144 :             ctx.types().T_jlarray,
    2724                 :      29144 :             emit_bitcast(ctx, decay_derived(ctx, t), ctx.types().T_pjlarray),
    2725                 :            :             arrayflag_field);
    2726                 :      29144 :     return tbaa_decorate(ctx.tbaa().tbaa_arrayflags, ctx.builder.CreateAlignedLoad(getInt16Ty(ctx.builder.getContext()), addr, Align(sizeof(int16_t))));
    2727                 :            : }
    2728                 :            : 
    2729                 :          0 : static Value *emit_arrayndims(jl_codectx_t &ctx, const jl_cgval_t &ary)
    2730                 :            : {
    2731                 :          0 :     ++EmittedArrayNDims;
    2732                 :          0 :     Value *flags = emit_arrayflags(ctx, ary);
    2733                 :          0 :     cast<LoadInst>(flags)->setMetadata(LLVMContext::MD_invariant_load, MDNode::get(ctx.builder.getContext(), None));
    2734                 :          0 :     flags = ctx.builder.CreateLShr(flags, 2);
    2735                 :          0 :     flags = ctx.builder.CreateAnd(flags, 0x1FF); // (1<<9) - 1
    2736                 :          0 :     return flags;
    2737                 :            : }
    2738                 :            : 
    2739                 :          1 : static Value *emit_arrayelsize(jl_codectx_t &ctx, const jl_cgval_t &tinfo)
    2740                 :            : {
    2741                 :          1 :     ++EmittedArrayElsize;
    2742                 :          1 :     Value *t = boxed(ctx, tinfo);
    2743                 :          1 :     int elsize_field = 3;
    2744                 :          2 :     Value *addr = ctx.builder.CreateStructGEP(ctx.types().T_jlarray,
    2745                 :          1 :             emit_bitcast(ctx, decay_derived(ctx, t), ctx.types().T_pjlarray),
    2746                 :            :             elsize_field);
    2747                 :          1 :     return tbaa_decorate(ctx.tbaa().tbaa_const, ctx.builder.CreateAlignedLoad(getInt16Ty(ctx.builder.getContext()), addr, Align(sizeof(int16_t))));
    2748                 :            : }
    2749                 :            : 
    2750                 :        620 : static Value *emit_arrayoffset(jl_codectx_t &ctx, const jl_cgval_t &tinfo, int nd)
    2751                 :            : {
    2752                 :        620 :     ++EmittedArrayOffset;
    2753   [ +  -  -  + ]:        620 :     if (nd != -1 && nd != 1) // only Vector can have an offset
    2754                 :          0 :         return ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0);
    2755                 :        620 :     Value *t = boxed(ctx, tinfo);
    2756                 :        620 :     int offset_field = 4;
    2757                 :            : 
    2758                 :       1240 :     Value *addr = ctx.builder.CreateStructGEP(
    2759                 :        620 :             ctx.types().T_jlarray,
    2760                 :        620 :             emit_bitcast(ctx, decay_derived(ctx, t), ctx.types().T_pjlarray),
    2761                 :            :             offset_field);
    2762                 :        620 :     return tbaa_decorate(ctx.tbaa().tbaa_arrayoffset, ctx.builder.CreateAlignedLoad(getInt32Ty(ctx.builder.getContext()), addr, Align(sizeof(int32_t))));
    2763                 :            : }
    2764                 :            : 
    2765                 :            : // Returns the size of the array represented by `tinfo` for the given dimension `dim` if
    2766                 :            : // `dim` is a valid dimension, otherwise returns constant one.
    2767                 :        410 : static Value *emit_arraysize_for_unsafe_dim(jl_codectx_t &ctx,
    2768                 :            :         const jl_cgval_t &tinfo, jl_value_t *ex, size_t dim, size_t nd)
    2769                 :            : {
    2770         [ +  + ]:        410 :     return dim > nd ? ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1) : emit_arraysize(ctx, tinfo, ex, dim);
    2771                 :            : }
    2772                 :            : 
    2773                 :            : // `nd == -1` means the dimension is unknown.
    2774                 :     159174 : static Value *emit_array_nd_index(
    2775                 :            :         jl_codectx_t &ctx, const jl_cgval_t &ainfo, jl_value_t *ex, ssize_t nd,
    2776                 :            :         const jl_cgval_t *argv, size_t nidxs, jl_value_t *inbounds)
    2777                 :            : {
    2778                 :     159174 :     ++EmittedArrayNdIndex;
    2779                 :     159174 :     Value *a = boxed(ctx, ainfo);
    2780                 :     159174 :     Value *i = Constant::getNullValue(getSizeTy(ctx.builder.getContext()));
    2781                 :     159174 :     Value *stride = ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1);
    2782                 :            : #if CHECK_BOUNDS==1
    2783                 :     159174 :     bool bc = bounds_check_enabled(ctx, inbounds);
    2784                 :     159174 :     BasicBlock *failBB = NULL, *endBB = NULL;
    2785         [ +  + ]:     159174 :     if (bc) {
    2786                 :      67781 :         failBB = BasicBlock::Create(ctx.builder.getContext(), "oob");
    2787                 :      67781 :         endBB = BasicBlock::Create(ctx.builder.getContext(), "idxend");
    2788                 :            :     }
    2789                 :            : #endif
    2790                 :     159174 :     Value **idxs = (Value**)alloca(sizeof(Value*) * nidxs);
    2791         [ +  + ]:     318726 :     for (size_t k = 0; k < nidxs; k++) {
    2792                 :     159552 :         idxs[k] = emit_unbox(ctx, getSizeTy(ctx.builder.getContext()), argv[k], (jl_value_t*)jl_long_type); // type asserted by caller
    2793                 :            :     }
    2794                 :     159174 :     Value *ii = NULL;
    2795         [ +  + ]:     318726 :     for (size_t k = 0; k < nidxs; k++) {
    2796                 :     159552 :         ii = ctx.builder.CreateSub(idxs[k], ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1));
    2797                 :     159552 :         i = ctx.builder.CreateAdd(i, ctx.builder.CreateMul(ii, stride));
    2798         [ +  + ]:     159552 :         if (k < nidxs - 1) {
    2799         [ -  + ]:        378 :             assert(nd >= 0);
    2800                 :        378 :             Value *d = emit_arraysize_for_unsafe_dim(ctx, ainfo, ex, k + 1, nd);
    2801                 :            : #if CHECK_BOUNDS==1
    2802         [ +  + ]:        378 :             if (bc) {
    2803                 :         32 :                 BasicBlock *okBB = BasicBlock::Create(ctx.builder.getContext(), "ib");
    2804                 :            :                 // if !(i < d) goto error
    2805                 :         32 :                 ctx.builder.CreateCondBr(ctx.builder.CreateICmpULT(ii, d), okBB, failBB);
    2806                 :         32 :                 ctx.f->getBasicBlockList().push_back(okBB);
    2807                 :         32 :                 ctx.builder.SetInsertPoint(okBB);
    2808                 :            :             }
    2809                 :            : #endif
    2810                 :        378 :             stride = ctx.builder.CreateMul(stride, d);
    2811                 :            :         }
    2812                 :            :     }
    2813                 :            : #if CHECK_BOUNDS==1
    2814         [ +  + ]:     159174 :     if (bc) {
    2815                 :            :         // We have already emitted a bounds check for each index except for
    2816                 :            :         // the last one which we therefore have to do here.
    2817         [ +  + ]:      67781 :         if (nidxs == 1) {
    2818                 :            :             // Linear indexing: Check against the entire linear span of the array
    2819                 :      67749 :             Value *alen = emit_arraylen(ctx, ainfo);
    2820                 :      67749 :             ctx.builder.CreateCondBr(ctx.builder.CreateICmpULT(i, alen), endBB, failBB);
    2821         [ +  - ]:         32 :         } else if (nidxs >= (size_t)nd){
    2822                 :            :             // No dimensions were omitted; just check the last remaining index
    2823         [ -  + ]:         32 :             assert(nd >= 0);
    2824                 :         32 :             Value *last_index = ii;
    2825                 :         32 :             Value *last_dimension = emit_arraysize_for_unsafe_dim(ctx, ainfo, ex, nidxs, nd);
    2826                 :         32 :             ctx.builder.CreateCondBr(ctx.builder.CreateICmpULT(last_index, last_dimension), endBB, failBB);
    2827                 :            :         } else {
    2828                 :            :             // There were fewer indices than dimensions; check the last remaining index
    2829                 :          0 :             BasicBlock *checktrailingdimsBB = BasicBlock::Create(ctx.builder.getContext(), "dimsib");
    2830         [ #  # ]:          0 :             assert(nd >= 0);
    2831                 :          0 :             Value *last_index = ii;
    2832                 :          0 :             Value *last_dimension = emit_arraysize_for_unsafe_dim(ctx, ainfo, ex, nidxs, nd);
    2833                 :          0 :             ctx.builder.CreateCondBr(ctx.builder.CreateICmpULT(last_index, last_dimension), checktrailingdimsBB, failBB);
    2834                 :          0 :             ctx.f->getBasicBlockList().push_back(checktrailingdimsBB);
    2835                 :          0 :             ctx.builder.SetInsertPoint(checktrailingdimsBB);
    2836                 :            :             // And then also make sure that all dimensions that weren't explicitly
    2837                 :            :             // indexed into have size 1
    2838         [ #  # ]:          0 :             for (size_t k = nidxs+1; k < (size_t)nd; k++) {
    2839                 :          0 :                 BasicBlock *dimsokBB = BasicBlock::Create(ctx.builder.getContext(), "dimsok");
    2840                 :          0 :                 Value *dim = emit_arraysize_for_unsafe_dim(ctx, ainfo, ex, k, nd);
    2841                 :          0 :                 ctx.builder.CreateCondBr(ctx.builder.CreateICmpEQ(dim, ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1)), dimsokBB, failBB);
    2842                 :          0 :                 ctx.f->getBasicBlockList().push_back(dimsokBB);
    2843                 :          0 :                 ctx.builder.SetInsertPoint(dimsokBB);
    2844                 :            :             }
    2845                 :          0 :             Value *dim = emit_arraysize_for_unsafe_dim(ctx, ainfo, ex, nd, nd);
    2846                 :          0 :             ctx.builder.CreateCondBr(ctx.builder.CreateICmpEQ(dim, ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1)), endBB, failBB);
    2847                 :            :         }
    2848                 :            : 
    2849                 :      67781 :         ctx.f->getBasicBlockList().push_back(failBB);
    2850                 :      67781 :         ctx.builder.SetInsertPoint(failBB);
    2851                 :            :         // CreateAlloca is OK here since we are on an error branch
    2852                 :      67781 :         Value *tmp = ctx.builder.CreateAlloca(getSizeTy(ctx.builder.getContext()), ConstantInt::get(getSizeTy(ctx.builder.getContext()), nidxs));
    2853         [ +  + ]:     135594 :         for (size_t k = 0; k < nidxs; k++) {
    2854                 :      67813 :             ctx.builder.CreateAlignedStore(idxs[k], ctx.builder.CreateInBoundsGEP(getSizeTy(ctx.builder.getContext()), tmp, ConstantInt::get(getSizeTy(ctx.builder.getContext()), k)), Align(sizeof(size_t)));
    2855                 :            :         }
    2856                 :     135562 :         ctx.builder.CreateCall(prepare_call(jlboundserrorv_func),
    2857                 :      67781 :             { mark_callee_rooted(ctx, a), tmp, ConstantInt::get(getSizeTy(ctx.builder.getContext()), nidxs) });
    2858                 :      67781 :         ctx.builder.CreateUnreachable();
    2859                 :            : 
    2860                 :      67781 :         ctx.f->getBasicBlockList().push_back(endBB);
    2861                 :      67781 :         ctx.builder.SetInsertPoint(endBB);
    2862                 :            :     }
    2863                 :            : #endif
    2864                 :            : 
    2865                 :     159174 :     return i;
    2866                 :            : }
    2867                 :            : 
    2868                 :            : // --- boxing ---
    2869                 :            : 
    2870                 :            : static Value *emit_allocobj(jl_codectx_t &ctx, size_t static_size, Value *jt);
    2871                 :            : 
    2872                 :      35256 : static void init_bits_value(jl_codectx_t &ctx, Value *newv, Value *v, MDNode *tbaa,
    2873                 :            :                             unsigned alignment = sizeof(void*)) // min alignment in julia's gc is pointer-aligned
    2874                 :            : {
    2875                 :            :     // newv should already be tagged
    2876                 :      70512 :     tbaa_decorate(tbaa, ctx.builder.CreateAlignedStore(v, emit_bitcast(ctx, newv,
    2877                 :      70512 :         PointerType::get(v->getType(), 0)), Align(alignment)));
    2878                 :      35256 : }
    2879                 :            : 
    2880                 :      67335 : static void init_bits_cgval(jl_codectx_t &ctx, Value *newv, const jl_cgval_t& v, MDNode *tbaa)
    2881                 :            : {
    2882                 :            :     // newv should already be tagged
    2883         [ +  + ]:      67335 :     if (v.ispointer()) {
    2884                 :      32080 :         emit_memcpy(ctx, newv, tbaa, v, jl_datatype_size(v.typ), sizeof(void*));
    2885                 :            :     }
    2886                 :            :     else {
    2887                 :      35255 :         init_bits_value(ctx, newv, v.V, tbaa);
    2888                 :            :     }
    2889                 :      67335 : }
    2890                 :            : 
    2891                 :       6203 : static jl_value_t *static_constant_instance(const llvm::DataLayout &DL, Constant *constant, jl_value_t *jt)
    2892                 :            : {
    2893   [ +  -  +  - ]:       6203 :     assert(constant != NULL && jl_is_concrete_type(jt));
    2894                 :       6203 :     jl_datatype_t *jst = (jl_datatype_t*)jt;
    2895                 :            : 
    2896         [ -  + ]:       6203 :     if (isa<UndefValue>(constant))
    2897                 :          0 :         return NULL;
    2898                 :            : 
    2899         [ +  + ]:       6203 :     if (ConstantInt *cint = dyn_cast<ConstantInt>(constant)) {
    2900         [ -  + ]:         71 :         if (jst == jl_bool_type)
    2901         [ #  # ]:          0 :             return cint->isZero() ? jl_false : jl_true;
    2902                 :         71 :         return jl_new_bits(jt,
    2903                 :        142 :             const_cast<uint64_t *>(cint->getValue().getRawData()));
    2904                 :            :     }
    2905                 :            : 
    2906         [ -  + ]:       6132 :     if (ConstantFP *cfp = dyn_cast<ConstantFP>(constant)) {
    2907                 :          0 :         return jl_new_bits(jt,
    2908                 :          0 :             const_cast<uint64_t *>(cfp->getValueAPF().bitcastToAPInt().getRawData()));
    2909                 :            :     }
    2910                 :            : 
    2911         [ -  + ]:       6132 :     if (isa<ConstantPointerNull>(constant)) {
    2912                 :          0 :         uint64_t val = 0;
    2913                 :          0 :         return jl_new_bits(jt, &val);
    2914                 :            :     }
    2915                 :            : 
    2916                 :            :     // issue #8464
    2917         [ +  + ]:       6132 :     if (ConstantExpr *ce = dyn_cast<ConstantExpr>(constant)) {
    2918                 :         48 :         unsigned OpCode = ce->getOpcode();
    2919   [ +  -  -  +  :         48 :         if (OpCode == Instruction::BitCast || OpCode == Instruction::PtrToInt || OpCode == Instruction::IntToPtr) {
                   -  - ]
    2920                 :         48 :             return static_constant_instance(DL, ce->getOperand(0), jt);
    2921                 :            :         }
    2922                 :          0 :         return NULL;
    2923                 :            :     }
    2924                 :            : 
    2925         [ +  + ]:       6084 :     if (isa<GlobalValue>(constant))
    2926                 :         48 :         return NULL;
    2927                 :            : 
    2928                 :            :     size_t nargs;
    2929         [ +  - ]:       6036 :     if (const auto *CC = dyn_cast<ConstantAggregate>(constant))
    2930                 :       6036 :         nargs = CC->getNumOperands();
    2931         [ #  # ]:          0 :     else if (const auto *CAZ = dyn_cast<ConstantAggregateZero>(constant)) {
    2932                 :            : #if JL_LLVM_VERSION >= 130000
    2933                 :            :         // SVE: Elsewhere we use `getMinKownValue`
    2934                 :          0 :         nargs = CAZ->getElementCount().getFixedValue();
    2935                 :            : #else
    2936                 :            :         nargs = CAZ->getNumElements();
    2937                 :            : #endif
    2938                 :            :     }
    2939         [ #  # ]:          0 :     else if (const auto *CDS = dyn_cast<ConstantDataSequential>(constant))
    2940                 :          0 :         nargs = CDS->getNumElements();
    2941                 :            :     else
    2942                 :          0 :         return NULL;
    2943   [ +  -  +  - ]:       6036 :     assert(nargs > 0 && jst->instance == NULL);
    2944         [ +  + ]:       6036 :     if (nargs != jl_datatype_nfields(jst))
    2945                 :         40 :         return NULL;
    2946                 :            : 
    2947                 :            :     jl_value_t **flds;
    2948                 :       5996 :     JL_GC_PUSHARGS(flds, nargs);
    2949         [ +  - ]:       5998 :     for (size_t i = 0; i < nargs; i++) {
    2950                 :       5998 :         jl_value_t *ft = jl_field_type(jst, i);
    2951   [ +  +  -  +  :       5998 :         if (jl_field_isptr(jst, i) || jl_is_uniontype(ft)) {
                   +  + ]
    2952                 :       5996 :             JL_GC_POP();
    2953                 :       5996 :             return NULL; // TODO: handle this?
    2954                 :            :         }
    2955                 :          2 :         unsigned llvm_idx = i;
    2956   [ -  +  -  -  :          2 :         if (i > 0 && isa<StructType>(constant->getType()))
                   -  + ]
    2957                 :          0 :             llvm_idx = convert_struct_offset(DL, constant->getType(), jl_field_offset(jst, i));
    2958                 :          2 :         Constant *fld = constant->getAggregateElement(llvm_idx);
    2959                 :          2 :         flds[i] = static_constant_instance(DL, fld, ft);
    2960         [ -  + ]:          2 :         if (flds[i] == NULL) {
    2961                 :          0 :             JL_GC_POP();
    2962                 :          0 :             return NULL; // must have been unreachable
    2963                 :            :         }
    2964                 :            :     }
    2965                 :          0 :     jl_value_t *obj = jl_new_structv(jst, flds, nargs);
    2966                 :          0 :     JL_GC_POP();
    2967                 :          0 :     return obj;
    2968                 :            : }
    2969                 :            : 
    2970                 :      37088 : static Value *call_with_attrs(jl_codectx_t &ctx, JuliaFunction *intr, Value *v)
    2971                 :            : {
    2972                 :      37088 :     Function *F = prepare_call(intr);
    2973                 :      37088 :     CallInst *Call = ctx.builder.CreateCall(F, v);
    2974                 :      37088 :     Call->setAttributes(F->getAttributes());
    2975                 :      37088 :     return Call;
    2976                 :            : }
    2977                 :            : 
    2978                 :            : static void jl_add_method_root(jl_codectx_t &ctx, jl_value_t *val);
    2979                 :            : 
    2980                 :      47934 : static Value *as_value(jl_codectx_t &ctx, Type *to, const jl_cgval_t &v)
    2981                 :            : {
    2982         [ -  + ]:      47934 :     assert(!v.isboxed);
    2983                 :      47934 :     return emit_unbox(ctx, to, v, v.typ);
    2984                 :            : }
    2985                 :            : 
    2986                 :        560 : static Value *load_i8box(jl_codectx_t &ctx, Value *v, jl_datatype_t *ty)
    2987                 :            : {
    2988         [ +  + ]:        560 :     auto jvar = ty == jl_int8_type ? jlboxed_int8_cache : jlboxed_uint8_cache;
    2989                 :        560 :     GlobalVariable *gv = prepare_global_in(jl_Module, jvar);
    2990                 :        560 :     Value *idx[] = {ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0), ctx.builder.CreateZExt(v, getInt32Ty(ctx.builder.getContext()))};
    2991                 :        560 :     auto slot = ctx.builder.CreateInBoundsGEP(gv->getValueType(), gv, idx);
    2992                 :        560 :     return tbaa_decorate(ctx.tbaa().tbaa_const, maybe_mark_load_dereferenceable(
    2993                 :       1120 :             ctx.builder.CreateAlignedLoad(ctx.types().T_pjlvalue, slot, Align(sizeof(void*))), false,
    2994                 :        560 :             (jl_value_t*)ty));
    2995                 :            : }
    2996                 :            : 
    2997                 :            : // some types have special boxing functions with small-value caches
    2998                 :            : // Returns ctx.types().T_prjlvalue
    2999                 :     117012 : static Value *_boxed_special(jl_codectx_t &ctx, const jl_cgval_t &vinfo, Type *t)
    3000                 :            : {
    3001                 :     117012 :     jl_value_t *jt = vinfo.typ;
    3002         [ +  + ]:     117012 :     if (jt == (jl_value_t*)jl_bool_type)
    3003                 :      10144 :         return track_pjlvalue(ctx, julia_bool(ctx, ctx.builder.CreateTrunc(as_value(ctx, t, vinfo), getInt1Ty(ctx.builder.getContext()))));
    3004         [ -  + ]:     106868 :     if (t == getInt1Ty(ctx.builder.getContext()))
    3005                 :          0 :         return track_pjlvalue(ctx, julia_bool(ctx, as_value(ctx, t, vinfo)));
    3006                 :            : 
    3007   [ +  +  +  +  :     106868 :     if (ctx.linfo && jl_is_method(ctx.linfo->def.method) && !vinfo.ispointer()) { // don't bother codegen pre-boxing for toplevel
             +  +  +  + ]
    3008         [ +  + ]:      66414 :         if (Constant *c = dyn_cast<Constant>(vinfo.V)) {
    3009                 :       6153 :             jl_value_t *s = static_constant_instance(jl_Module->getDataLayout(), c, jt);
    3010         [ +  + ]:       6153 :             if (s) {
    3011                 :         69 :                 jl_add_method_root(ctx, s);
    3012                 :         69 :                 return track_pjlvalue(ctx, literal_pointer_val(ctx, s));
    3013                 :            :             }
    3014                 :            :         }
    3015                 :            :     }
    3016                 :            : 
    3017                 :     106799 :     jl_datatype_t *jb = (jl_datatype_t*)jt;
    3018         [ -  + ]:     106799 :     assert(jl_is_datatype(jb));
    3019                 :     106799 :     Value *box = NULL;
    3020         [ +  + ]:     106799 :     if (jb == jl_int8_type)
    3021                 :         79 :         box = track_pjlvalue(ctx, load_i8box(ctx, as_value(ctx, t, vinfo), jb));
    3022         [ +  + ]:     106720 :     else if (jb == jl_int16_type)
    3023                 :         56 :         box = call_with_attrs(ctx, box_int16_func, as_value(ctx, t, vinfo));
    3024         [ +  + ]:     106664 :     else if (jb == jl_int32_type)
    3025                 :       1460 :         box = call_with_attrs(ctx, box_int32_func, as_value(ctx, t, vinfo));
    3026         [ +  + ]:     105204 :     else if (jb == jl_int64_type)
    3027                 :      29493 :         box = call_with_attrs(ctx, box_int64_func, as_value(ctx, t, vinfo));
    3028         [ +  + ]:      75711 :     else if (jb == jl_float32_type)
    3029                 :        142 :         box = ctx.builder.CreateCall(prepare_call(box_float32_func), as_value(ctx, t, vinfo));
    3030                 :            :     //if (jb == jl_float64_type)
    3031                 :            :     //  box = ctx.builder.CreateCall(box_float64_func, as_value(ctx, t, vinfo);
    3032                 :            :     // for Float64, fall through to generic case below, to inline alloc & init of Float64 box. cheap, I know.
    3033         [ +  + ]:      75569 :     else if (jb == jl_uint8_type)
    3034                 :        481 :         box = track_pjlvalue(ctx, load_i8box(ctx, as_value(ctx, t, vinfo), jb));
    3035         [ +  + ]:      75088 :     else if (jb == jl_uint16_type)
    3036                 :        226 :         box = call_with_attrs(ctx, box_uint16_func, as_value(ctx, t, vinfo));
    3037         [ +  + ]:      74862 :     else if (jb == jl_uint32_type)
    3038                 :       1178 :         box = call_with_attrs(ctx, box_uint32_func, as_value(ctx, t, vinfo));
    3039         [ +  + ]:      73684 :     else if (jb == jl_uint64_type)
    3040                 :       2187 :         box = call_with_attrs(ctx, box_uint64_func, as_value(ctx, t, vinfo));
    3041         [ +  + ]:      71497 :     else if (jb == jl_char_type)
    3042                 :        842 :         box = call_with_attrs(ctx, box_char_func, as_value(ctx, t, vinfo));
    3043         [ +  + ]:      70655 :     else if (jb == jl_ssavalue_type) {
    3044                 :       1646 :         unsigned zero = 0;
    3045                 :       1646 :         Value *v = as_value(ctx, t, vinfo);
    3046         [ -  + ]:       1646 :         assert(v->getType() == ctx.emission_context.llvmtypes[jl_ssavalue_type]);
    3047                 :       1646 :         v = ctx.builder.CreateExtractValue(v, makeArrayRef(&zero, 1));
    3048                 :       1646 :         box = call_with_attrs(ctx, box_ssavalue_func, v);
    3049                 :            :     }
    3050   [ +  -  -  + ]:      69009 :     else if (!jb->name->abstract && jl_datatype_nbits(jb) == 0) {
    3051                 :            :         // singleton
    3052         [ #  # ]:          0 :         assert(jb->instance != NULL);
    3053                 :          0 :         return track_pjlvalue(ctx, literal_pointer_val(ctx, jb->instance));
    3054                 :            :     }
    3055                 :     106799 :     return box;
    3056                 :            : }
    3057                 :            : 
    3058                 :       2625 : static Value *compute_box_tindex(jl_codectx_t &ctx, Value *datatype, jl_value_t *supertype, jl_value_t *ut)
    3059                 :            : {
    3060                 :       2625 :     Value *tindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0);
    3061                 :       2625 :     unsigned counter = 0;
    3062                 :       2625 :     for_each_uniontype_small(
    3063                 :       4300 :             [&](unsigned idx, jl_datatype_t *jt) {
    3064         [ +  - ]:       4300 :                 if (jl_subtype((jl_value_t*)jt, supertype)) {
    3065                 :       4300 :                     Value *cmp = ctx.builder.CreateICmpEQ(track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)jt)), datatype);
    3066                 :       4300 :                     tindex = ctx.builder.CreateSelect(cmp, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), idx), tindex);
    3067                 :            :                 }
    3068                 :       4300 :             },
    3069                 :            :             ut,
    3070                 :            :             counter);
    3071                 :       2625 :     return tindex;
    3072                 :            : }
    3073                 :            : 
    3074                 :            : // get the runtime tindex value, assuming val is already converted to type typ if it has a TIndex
    3075                 :       9862 : static Value *compute_tindex_unboxed(jl_codectx_t &ctx, const jl_cgval_t &val, jl_value_t *typ, bool maybenull=false)
    3076                 :            : {
    3077         [ -  + ]:       9862 :     if (val.typ == jl_bottom_type)
    3078                 :          0 :         return UndefValue::get(getInt8Ty(ctx.builder.getContext()));
    3079         [ +  + ]:       9862 :     if (val.constant)
    3080                 :       5611 :         return ConstantInt::get(getInt8Ty(ctx.builder.getContext()), get_box_tindex((jl_datatype_t*)jl_typeof(val.constant), typ));
    3081         [ +  + ]:       4251 :     if (val.TIndex)
    3082                 :       1626 :         return ctx.builder.CreateAnd(val.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x7f));
    3083                 :       2625 :     Value *typof = emit_typeof_boxed(ctx, val, maybenull);
    3084                 :       2625 :     return compute_box_tindex(ctx, typof, val.typ, typ);
    3085                 :            : }
    3086                 :            : 
    3087                 :      56936 : static void union_alloca_type(jl_uniontype_t *ut,
    3088                 :            :         bool &allunbox, size_t &nbytes, size_t &align, size_t &min_align)
    3089                 :            : {
    3090                 :      56936 :     nbytes = 0;
    3091                 :      56936 :     align = 0;
    3092                 :      56936 :     min_align = MAX_ALIGN;
    3093                 :            :     // compute the size of the union alloca that could hold this type
    3094                 :      56936 :     unsigned counter = 0;
    3095                 :      56936 :     allunbox = for_each_uniontype_small(
    3096                 :      71803 :             [&](unsigned idx, jl_datatype_t *jt) {
    3097         [ +  + ]:      71803 :                 if (!jl_is_datatype_singleton(jt)) {
    3098                 :      29805 :                     size_t nb1 = jl_datatype_size(jt);
    3099                 :      29805 :                     size_t align1 = jl_datatype_align(jt);
    3100         [ +  + ]:      29805 :                     if (nb1 > nbytes)
    3101                 :      28085 :                         nbytes = nb1;
    3102         [ +  + ]:      29805 :                     if (align1 > align)
    3103                 :      27703 :                         align = align1;
    3104         [ +  + ]:      29805 :                     if (align1 < min_align)
    3105                 :       7280 :                         min_align = align1;
    3106                 :            :                 }
    3107                 :      71803 :             },
    3108                 :            :             (jl_value_t*)ut,
    3109                 :            :             counter);
    3110                 :      56936 : }
    3111                 :            : 
    3112                 :      20390 : static AllocaInst *try_emit_union_alloca(jl_codectx_t &ctx, jl_uniontype_t *ut, bool &allunbox, size_t &min_align, size_t &nbytes)
    3113                 :            : {
    3114                 :            :     size_t align;
    3115                 :      20390 :     union_alloca_type(ut, allunbox, nbytes, align, min_align);
    3116         [ +  + ]:      20390 :     if (nbytes > 0) {
    3117                 :            :         // at least some of the values can live on the stack
    3118                 :            :         // try to pick an Integer type size such that SROA will emit reasonable code
    3119                 :      10283 :         Type *AT = ArrayType::get(IntegerType::get(ctx.builder.getContext(), 8 * min_align), (nbytes + min_align - 1) / min_align);
    3120                 :      10283 :         AllocaInst *lv = emit_static_alloca(ctx, AT);
    3121         [ +  + ]:      10283 :         if (align > 1)
    3122                 :       9235 :             lv->setAlignment(Align(align));
    3123                 :      10283 :         return lv;
    3124                 :            :     }
    3125                 :      10107 :     return NULL;
    3126                 :            : }
    3127                 :            : 
    3128                 :            : /*
    3129                 :            :  * Box unboxed values in a union. Optionally, skip certain unboxed values,
    3130                 :            :  * returning `Constant::getNullValue(ctx.types().T_pjlvalue)` in one of the skipped cases. If `skip` is not empty,
    3131                 :            :  * skip[0] (corresponding to unknown boxed) must always be set. In that
    3132                 :            :  * case, the calling code must separately deal with the case where
    3133                 :            :  * `vinfo` is already an unknown boxed union (union tag 0x80).
    3134                 :            :  */
    3135                 :            : // Returns ctx.types().T_prjlvalue
    3136                 :       5341 : static Value *box_union(jl_codectx_t &ctx, const jl_cgval_t &vinfo, const SmallBitVector &skip)
    3137                 :            : {
    3138                 :            :     // given vinfo::Union{T, S}, emit IR of the form:
    3139                 :            :     //   ...
    3140                 :            :     //   switch <tindex>, label <box_union_isboxed> [ 1, label <box_union_1>
    3141                 :            :     //                                                2, label <box_union_2> ]
    3142                 :            :     // box_union_1:
    3143                 :            :     //   box1 = create_box(T)
    3144                 :            :     //   br post_box_union
    3145                 :            :     // box_union_2:
    3146                 :            :     //   box2 = create_box(S)
    3147                 :            :     //   br post_box_union
    3148                 :            :     // box_union_isboxed:
    3149                 :            :     //   br post_box_union
    3150                 :            :     // post_box_union:
    3151                 :            :     //   box = phi [ box1, box_union_1 ], [ box2, box_union_2 ], [ vinfo, box_union_isboxed ]
    3152                 :            :     //   ...
    3153                 :       5341 :     Value *tindex = vinfo.TIndex;
    3154                 :       5341 :     BasicBlock *defaultBB = BasicBlock::Create(ctx.builder.getContext(), "box_union_isboxed", ctx.f);
    3155                 :       5341 :     SwitchInst *switchInst = ctx.builder.CreateSwitch(tindex, defaultBB);
    3156                 :       5341 :     BasicBlock *postBB = BasicBlock::Create(ctx.builder.getContext(), "post_box_union", ctx.f);
    3157                 :       5341 :     ctx.builder.SetInsertPoint(postBB);
    3158                 :       5341 :     PHINode *box_merge = ctx.builder.CreatePHI(ctx.types().T_prjlvalue, 2);
    3159                 :       5341 :     unsigned counter = 0;
    3160                 :       5341 :     for_each_uniontype_small(
    3161                 :       9499 :             [&](unsigned idx, jl_datatype_t *jt) {
    3162   [ -  +  -  -  :       9499 :                 if (idx < skip.size() && skip[idx])
                   -  + ]
    3163                 :          0 :                     return;
    3164                 :       9499 :                 Type *t = julia_type_to_llvm(ctx, (jl_value_t*)jt);
    3165                 :       9499 :                 BasicBlock *tempBB = BasicBlock::Create(ctx.builder.getContext(), "box_union", ctx.f);
    3166                 :       9499 :                 ctx.builder.SetInsertPoint(tempBB);
    3167                 :       9499 :                 switchInst->addCase(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), idx), tempBB);
    3168                 :            :                 Value *box;
    3169         [ +  + ]:       9499 :                 if (type_is_ghost(t)) {
    3170                 :       3485 :                     box = track_pjlvalue(ctx, literal_pointer_val(ctx, jt->instance));
    3171                 :            :                 }
    3172                 :            :                 else {
    3173                 :       6014 :                     jl_cgval_t vinfo_r = jl_cgval_t(vinfo, (jl_value_t*)jt, NULL);
    3174                 :       6014 :                     box = _boxed_special(ctx, vinfo_r, t);
    3175         [ +  + ]:       6014 :                     if (!box) {
    3176                 :       2821 :                         box = emit_allocobj(ctx, jl_datatype_size(jt), literal_pointer_val(ctx, (jl_value_t*)jt));
    3177         [ -  + ]:       2821 :                         init_bits_cgval(ctx, box, vinfo_r, jl_is_mutable(jt) ? ctx.tbaa().tbaa_mutab : ctx.tbaa().tbaa_immut);
    3178                 :            :                     }
    3179                 :            :                 }
    3180                 :       9499 :                 tempBB = ctx.builder.GetInsertBlock(); // could have changed
    3181                 :       9499 :                 box_merge->addIncoming(box, tempBB);
    3182                 :       9499 :                 ctx.builder.CreateBr(postBB);
    3183                 :            :             },
    3184                 :       5341 :             vinfo.typ,
    3185                 :            :             counter);
    3186                 :       5341 :     ctx.builder.SetInsertPoint(defaultBB);
    3187         [ -  + ]:       5341 :     if (skip.size() > 0) {
    3188         [ #  # ]:          0 :         assert(skip[0]);
    3189                 :          0 :         box_merge->addIncoming(Constant::getNullValue(ctx.types().T_prjlvalue), defaultBB);
    3190                 :          0 :         ctx.builder.CreateBr(postBB);
    3191                 :            :     }
    3192         [ +  + ]:       5341 :     else if (!vinfo.Vboxed) {
    3193                 :        802 :         Function *trap_func = Intrinsic::getDeclaration(
    3194                 :        401 :                 ctx.f->getParent(),
    3195                 :            :                 Intrinsic::trap);
    3196                 :        401 :         ctx.builder.CreateCall(trap_func);
    3197                 :        401 :         ctx.builder.CreateUnreachable();
    3198                 :            :     }
    3199                 :            :     else {
    3200                 :       4940 :         box_merge->addIncoming(vinfo.Vboxed, defaultBB);
    3201                 :       4940 :         ctx.builder.CreateBr(postBB);
    3202                 :            :     }
    3203                 :       5341 :     ctx.builder.SetInsertPoint(postBB);
    3204                 :       5341 :     return box_merge;
    3205                 :            : }
    3206                 :            : 
    3207                 :       4641 : static void recursively_adjust_ptr_type(llvm::Value *Val, unsigned FromAS, unsigned ToAS)
    3208                 :            : {
    3209         [ +  + ]:      10323 :     for (auto *User : Val->users()) {
    3210         [ +  + ]:       5682 :         if (isa<GetElementPtrInst>(User)) {
    3211                 :       2921 :             GetElementPtrInst *Inst = cast<GetElementPtrInst>(User);
    3212                 :       2921 :             Inst->mutateType(PointerType::getWithSamePointeeType(cast<PointerType>(Inst->getType()), ToAS));
    3213                 :       2921 :             recursively_adjust_ptr_type(Inst, FromAS, ToAS);
    3214                 :            :         }
    3215         [ +  + ]:       2761 :         else if (isa<IntrinsicInst>(User)) {
    3216                 :         46 :             IntrinsicInst *II = cast<IntrinsicInst>(User);
    3217                 :         46 :             SmallVector<Type*, 3> ArgTys;
    3218                 :         46 :             Intrinsic::getIntrinsicSignature(II->getCalledFunction(), ArgTys);
    3219         [ -  + ]:         46 :             assert(ArgTys.size() <= II->arg_size());
    3220         [ +  + ]:        184 :             for (size_t i = 0; i < ArgTys.size(); ++i)
    3221                 :        138 :                 ArgTys[i] = II->getArgOperand(i)->getType();
    3222                 :         46 :             II->setCalledFunction(Intrinsic::getDeclaration(II->getModule(), II->getIntrinsicID(), ArgTys));
    3223                 :            :         }
    3224                 :            : #ifndef JL_LLVM_OPAQUE_POINTERS
    3225         [ +  + ]:       2715 :         else if (isa<BitCastInst>(User)) {
    3226                 :         46 :             BitCastInst *Inst = cast<BitCastInst>(User);
    3227                 :         46 :             Inst->mutateType(PointerType::getWithSamePointeeType(cast<PointerType>(Inst->getType()), ToAS));
    3228                 :         46 :             recursively_adjust_ptr_type(Inst, FromAS, ToAS);
    3229                 :            :         }
    3230                 :            : #endif
    3231                 :            :     }
    3232                 :       4641 : }
    3233                 :            : 
    3234                 :            : // this is used to wrap values for generic contexts, where a
    3235                 :            : // dynamically-typed value is required (e.g. argument to unknown function).
    3236                 :            : // if it's already a pointer it's left alone.
    3237                 :            : // Returns ctx.types().T_prjlvalue
    3238                 :    2458190 : static Value *boxed(jl_codectx_t &ctx, const jl_cgval_t &vinfo)
    3239                 :            : {
    3240                 :    2458190 :     jl_value_t *jt = vinfo.typ;
    3241   [ +  +  -  + ]:    2458190 :     if (jt == jl_bottom_type || jt == NULL)
    3242                 :            :         // We have an undef value on a (hopefully) dead branch
    3243                 :       3755 :         return UndefValue::get(ctx.types().T_prjlvalue);
    3244         [ +  + ]:    2454440 :     if (vinfo.constant)
    3245                 :     508845 :         return track_pjlvalue(ctx, literal_pointer_val(ctx, vinfo.constant));
    3246                 :            :     // This can happen in early bootstrap for `gc_preserve_begin` return value.
    3247         [ +  + ]:    1945590 :     if (jt == (jl_value_t*)jl_nothing_type)
    3248                 :          2 :         return track_pjlvalue(ctx, literal_pointer_val(ctx, jl_nothing));
    3249         [ +  + ]:    1945590 :     if (vinfo.isboxed) {
    3250   [ +  -  +  - ]:    1829250 :         assert(vinfo.V == vinfo.Vboxed && vinfo.V != nullptr);
    3251         [ -  + ]:    1829250 :         assert(vinfo.V->getType() == ctx.types().T_prjlvalue);
    3252                 :    1829250 :         return vinfo.V;
    3253                 :            :     }
    3254                 :            : 
    3255                 :            :     Value *box;
    3256         [ +  + ]:     116339 :     if (vinfo.TIndex) {
    3257                 :       5341 :         SmallBitVector skip_none;
    3258                 :       5341 :         box = box_union(ctx, vinfo, skip_none);
    3259                 :            :     }
    3260                 :            :     else {
    3261         [ -  + ]:     110998 :         assert(vinfo.V && "Missing data for unboxed value.");
    3262         [ +  - ]:     110998 :         assert(jl_is_concrete_immutable(jt) && "This type shouldn't have been unboxed.");
    3263                 :     110998 :         Type *t = julia_type_to_llvm(ctx, jt);
    3264         [ -  + ]:     110998 :         assert(!type_is_ghost(t)); // ghost values should have been handled by vinfo.constant above!
    3265                 :     110998 :         box = _boxed_special(ctx, vinfo, t);
    3266         [ +  + ]:     110998 :         if (!box) {
    3267                 :      66188 :             bool do_promote = vinfo.promotion_point;
    3268         [ +  + ]:      66188 :             if (do_promote) {
    3269                 :       1674 :                 auto IP = ctx.builder.saveIP();
    3270                 :       1674 :                 ctx.builder.SetInsertPoint(vinfo.promotion_point);
    3271                 :       1674 :                 box = emit_allocobj(ctx, jl_datatype_size(jt), literal_pointer_val(ctx, (jl_value_t*)jt));
    3272                 :       1674 :                 Value *decayed = decay_derived(ctx, box);
    3273                 :       1674 :                 AllocaInst *originalAlloca = cast<AllocaInst>(vinfo.V);
    3274                 :            : #ifndef JL_LLVM_OPAQUE_POINTERS
    3275                 :       1674 :                 decayed = maybe_bitcast(ctx, decayed, PointerType::get(originalAlloca->getType()->getPointerElementType(), AddressSpace::Derived));
    3276                 :            : #endif
    3277                 :            :                 // Warning: Very illegal IR here temporarily
    3278                 :       1674 :                 originalAlloca->mutateType(decayed->getType());
    3279                 :       1674 :                 recursively_adjust_ptr_type(originalAlloca, 0, AddressSpace::Derived);
    3280                 :       1674 :                 originalAlloca->replaceAllUsesWith(decayed);
    3281                 :            :                 // end illegal IR
    3282                 :       1674 :                 cast<Instruction>(vinfo.V)->eraseFromParent();
    3283                 :       1674 :                 ctx.builder.restoreIP(IP);
    3284                 :            :             } else {
    3285                 :      64514 :                 box = emit_allocobj(ctx, jl_datatype_size(jt), literal_pointer_val(ctx, (jl_value_t*)jt));
    3286         [ -  + ]:      64514 :                 init_bits_cgval(ctx, box, vinfo, jl_is_mutable(jt) ? ctx.tbaa().tbaa_mutab : ctx.tbaa().tbaa_immut);
    3287                 :            :             }
    3288                 :            :         }
    3289                 :            :     }
    3290                 :     116339 :     return box;
    3291                 :            : }
    3292                 :            : 
    3293                 :            : // copy src to dest, if src is justbits. if skip is true, the value of dest is undefined
    3294                 :      11381 : static void emit_unionmove(jl_codectx_t &ctx, Value *dest, MDNode *tbaa_dst, const jl_cgval_t &src, Value *skip, bool isVolatile=false)
    3295                 :            : {
    3296         [ +  + ]:      11381 :     if (AllocaInst *ai = dyn_cast<AllocaInst>(dest))
    3297                 :            :         // TODO: make this a lifetime_end & dereferencable annotation?
    3298                 :       8288 :         ctx.builder.CreateAlignedStore(UndefValue::get(ai->getAllocatedType()), ai, ai->getAlign());
    3299   [ +  +  -  +  :      11381 :     if (jl_is_concrete_type(src.typ) || src.constant) {
                   +  + ]
    3300         [ +  + ]:       1408 :         jl_value_t *typ = src.constant ? jl_typeof(src.constant) : src.typ;
    3301   [ +  -  -  + ]:       1408 :         assert(skip || jl_is_pointerfree(typ));
    3302         [ +  - ]:       1408 :         if (jl_is_pointerfree(typ)) {
    3303                 :       1408 :             unsigned alignment = julia_alignment(typ);
    3304   [ +  +  +  +  :       1408 :             if (!src.ispointer() || src.constant) {
                   +  + ]
    3305                 :        768 :                 emit_unbox_store(ctx, src, dest, tbaa_dst, alignment, isVolatile);
    3306                 :            :             }
    3307                 :            :             else {
    3308                 :        640 :                 Value *src_ptr = data_pointer(ctx, src);
    3309                 :        640 :                 unsigned nb = jl_datatype_size(typ);
    3310                 :            :                 // TODO: this branch may be bad for performance, but is necessary to work around LLVM bugs with the undef option that we want to use:
    3311                 :            :                 //   select copy dest -> dest to simulate an undef value / conditional copy
    3312                 :            :                 // if (skip) src_ptr = ctx.builder.CreateSelect(skip, dest, src_ptr);
    3313                 :        640 :                 auto f = [&] {
    3314                 :        640 :                     (void)emit_memcpy(ctx, dest, tbaa_dst, src_ptr, src.tbaa, nb, alignment, isVolatile);
    3315                 :        640 :                     return nullptr;
    3316                 :        640 :                 };
    3317         [ -  + ]:        640 :                 if (skip)
    3318                 :          0 :                     emit_guarded_test(ctx, skip, nullptr, f);
    3319                 :            :                 else
    3320                 :        640 :                     f();
    3321                 :            :             }
    3322                 :            :         }
    3323                 :            :     }
    3324         [ +  + ]:       9973 :     else if (src.TIndex) {
    3325                 :       9971 :         Value *tindex = ctx.builder.CreateAnd(src.TIndex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x7f));
    3326         [ +  + ]:       9971 :         if (skip)
    3327                 :       7359 :             tindex = ctx.builder.CreateSelect(skip, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0), tindex);
    3328                 :       9971 :         Value *src_ptr = data_pointer(ctx, src);
    3329         [ +  - ]:       9971 :         src_ptr = src_ptr ? maybe_bitcast(ctx, src_ptr, getInt8PtrTy(ctx.builder.getContext())) : src_ptr;
    3330                 :       9971 :         dest = maybe_bitcast(ctx, dest, getInt8PtrTy(ctx.builder.getContext()));
    3331                 :       9971 :         BasicBlock *defaultBB = BasicBlock::Create(ctx.builder.getContext(), "union_move_skip", ctx.f);
    3332                 :       9971 :         SwitchInst *switchInst = ctx.builder.CreateSwitch(tindex, defaultBB);
    3333                 :       9971 :         BasicBlock *postBB = BasicBlock::Create(ctx.builder.getContext(), "post_union_move", ctx.f);
    3334                 :       9971 :         unsigned counter = 0;
    3335                 :       9971 :         bool allunboxed = for_each_uniontype_small(
    3336                 :      18084 :                 [&](unsigned idx, jl_datatype_t *jt) {
    3337                 :      18084 :                     unsigned nb = jl_datatype_size(jt);
    3338                 :      18084 :                     unsigned alignment = julia_alignment((jl_value_t*)jt);
    3339                 :      18084 :                     BasicBlock *tempBB = BasicBlock::Create(ctx.builder.getContext(), "union_move", ctx.f);
    3340                 :      18084 :                     ctx.builder.SetInsertPoint(tempBB);
    3341                 :      18084 :                     switchInst->addCase(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), idx), tempBB);
    3342         [ +  + ]:      18084 :                     if (nb > 0) {
    3343         [ -  + ]:      12253 :                         if (!src_ptr) {
    3344                 :            :                             Function *trap_func =
    3345                 :          0 :                                 Intrinsic::getDeclaration(ctx.f->getParent(), Intrinsic::trap);
    3346                 :          0 :                             ctx.builder.CreateCall(trap_func);
    3347                 :          0 :                             ctx.builder.CreateUnreachable();
    3348                 :          0 :                             return;
    3349                 :            :                         } else {
    3350                 :      12253 :                             emit_memcpy(ctx, dest, tbaa_dst, src_ptr,
    3351                 :      12253 :                                         src.tbaa, nb, alignment, isVolatile);
    3352                 :            :                         }
    3353                 :            :                     }
    3354                 :      18084 :                     ctx.builder.CreateBr(postBB);
    3355                 :            :                 },
    3356                 :       9971 :                 src.typ,
    3357                 :            :                 counter);
    3358                 :       9971 :         ctx.builder.SetInsertPoint(defaultBB);
    3359   [ +  +  +  +  :       9971 :         if (!skip && allunboxed && (src.V == NULL || isa<AllocaInst>(src.V))) {
          +  -  +  +  +  
                      + ]
    3360                 :       3688 :             Function *trap_func = Intrinsic::getDeclaration(
    3361                 :       1844 :                     ctx.f->getParent(),
    3362                 :            :                     Intrinsic::trap);
    3363                 :       1844 :             ctx.builder.CreateCall(trap_func);
    3364                 :       1844 :             ctx.builder.CreateUnreachable();
    3365                 :            :         }
    3366                 :            :         else {
    3367                 :       8127 :             ctx.builder.CreateBr(postBB);
    3368                 :            :         }
    3369                 :       9971 :         ctx.builder.SetInsertPoint(postBB);
    3370                 :            :     }
    3371                 :            :     else {
    3372         [ -  + ]:          2 :         assert(src.isboxed && "expected boxed value for sizeof/alignment computation");
    3373                 :          2 :         auto f = [&] {
    3374                 :          2 :             Value *datatype = emit_typeof_boxed(ctx, src);
    3375                 :          2 :             Value *copy_bytes = emit_datatype_size(ctx, datatype);
    3376                 :          2 :             emit_memcpy(ctx, dest, tbaa_dst, src, copy_bytes, /*TODO: min-align*/1, isVolatile);
    3377                 :          2 :             return nullptr;
    3378                 :          2 :         };
    3379         [ -  + ]:          2 :         if (skip)
    3380                 :          0 :             emit_guarded_test(ctx, skip, nullptr, f);
    3381                 :            :         else
    3382                 :          2 :             f();
    3383                 :            :     }
    3384                 :      11381 : }
    3385                 :            : 
    3386                 :            : 
    3387                 :          8 : static void emit_cpointercheck(jl_codectx_t &ctx, const jl_cgval_t &x, const std::string &msg)
    3388                 :            : {
    3389                 :          8 :     ++EmittedCPointerChecks;
    3390                 :          8 :     Value *t = emit_typeof_boxed(ctx, x);
    3391                 :          8 :     emit_typecheck(ctx, mark_julia_type(ctx, t, true, jl_any_type), (jl_value_t*)jl_datatype_type, msg);
    3392                 :            : 
    3393                 :            :     Value *istype =
    3394                 :          8 :         ctx.builder.CreateICmpEQ(mark_callee_rooted(ctx, emit_datatype_name(ctx, t)),
    3395                 :            :                                  mark_callee_rooted(ctx, literal_pointer_val(ctx, (jl_value_t*)jl_pointer_typename)));
    3396                 :          8 :     BasicBlock *failBB = BasicBlock::Create(ctx.builder.getContext(),"fail",ctx.f);
    3397                 :          8 :     BasicBlock *passBB = BasicBlock::Create(ctx.builder.getContext(),"pass");
    3398                 :          8 :     ctx.builder.CreateCondBr(istype, passBB, failBB);
    3399                 :          8 :     ctx.builder.SetInsertPoint(failBB);
    3400                 :            : 
    3401                 :          8 :     emit_type_error(ctx, x, literal_pointer_val(ctx, (jl_value_t*)jl_pointer_type), msg);
    3402                 :          8 :     ctx.builder.CreateUnreachable();
    3403                 :            : 
    3404                 :          8 :     ctx.f->getBasicBlockList().push_back(passBB);
    3405                 :          8 :     ctx.builder.SetInsertPoint(passBB);
    3406                 :          8 : }
    3407                 :            : 
    3408                 :            : // allocation for known size object
    3409                 :            : // returns a prjlvalue
    3410                 :      82435 : static Value *emit_allocobj(jl_codectx_t &ctx, size_t static_size, Value *jt)
    3411                 :            : {
    3412                 :      82435 :     ++EmittedAllocObjs;
    3413                 :      82435 :     Value *current_task = get_current_task(ctx);
    3414                 :      82435 :     Function *F = prepare_call(jl_alloc_obj_func);
    3415                 :      82435 :     auto call = ctx.builder.CreateCall(F, {current_task, ConstantInt::get(getSizeTy(ctx.builder.getContext()), static_size), maybe_decay_untracked(ctx, jt)});
    3416                 :      82435 :     call->setAttributes(F->getAttributes());
    3417                 :      82435 :     return call;
    3418                 :            : }
    3419                 :            : 
    3420                 :            : // allocation for unknown object from an untracked pointer
    3421                 :          0 : static Value *emit_new_bits(jl_codectx_t &ctx, Value *jt, Value *pval)
    3422                 :            : {
    3423                 :          0 :     pval = ctx.builder.CreateBitCast(pval, getInt8PtrTy(ctx.builder.getContext()));
    3424                 :          0 :     Function *F = prepare_call(jl_newbits_func);
    3425                 :          0 :     auto call = ctx.builder.CreateCall(F, { jt, pval });
    3426                 :          0 :     call->setAttributes(F->getAttributes());
    3427                 :          0 :     return call;
    3428                 :            : }
    3429                 :            : 
    3430                 :            : // if ptr is NULL this emits a write barrier _back_
    3431                 :      29459 : static void emit_write_barrier(jl_codectx_t &ctx, Value *parent, Value *ptr)
    3432                 :            : {
    3433                 :      29459 :     emit_write_barrier(ctx, parent, makeArrayRef(ptr));
    3434                 :      29459 : }
    3435                 :            : 
    3436                 :      36411 : static void emit_write_barrier(jl_codectx_t &ctx, Value *parent, ArrayRef<Value*> ptrs)
    3437                 :            : {
    3438                 :      36411 :     ++EmittedWriteBarriers;
    3439                 :            :     // if there are no child objects we can skip emission
    3440         [ +  + ]:      36411 :     if (ptrs.empty())
    3441                 :       1432 :         return;
    3442                 :      34979 :     SmallVector<Value*, 8> decay_ptrs;
    3443                 :      34979 :     decay_ptrs.push_back(maybe_decay_untracked(ctx, emit_bitcast(ctx, parent, ctx.types().T_prjlvalue)));
    3444         [ +  + ]:      74975 :     for (auto ptr : ptrs) {
    3445                 :      39996 :         decay_ptrs.push_back(maybe_decay_untracked(ctx, emit_bitcast(ctx, ptr, ctx.types().T_prjlvalue)));
    3446                 :            :     }
    3447                 :      34979 :     ctx.builder.CreateCall(prepare_call(jl_write_barrier_func), decay_ptrs);
    3448                 :            : }
    3449                 :            : 
    3450                 :        747 : static void emit_write_barrier_binding(jl_codectx_t &ctx, Value *parent, Value *ptr)
    3451                 :            : {
    3452                 :        747 :     SmallVector<Value*, 8> decay_ptrs;
    3453                 :        747 :     decay_ptrs.push_back(maybe_decay_untracked(ctx, emit_bitcast(ctx, parent, ctx.types().T_prjlvalue)));
    3454                 :        747 :     decay_ptrs.push_back(maybe_decay_untracked(ctx, emit_bitcast(ctx, ptr, ctx.types().T_prjlvalue)));
    3455                 :        747 :     ctx.builder.CreateCall(prepare_call(jl_write_barrier_binding_func), decay_ptrs);
    3456                 :        747 : }
    3457                 :            : 
    3458                 :      13015 : static void find_perm_offsets(jl_datatype_t *typ, SmallVector<unsigned,4> &res, unsigned offset)
    3459                 :            : {
    3460                 :            :     // This is a inlined field at `offset`.
    3461   [ +  -  +  + ]:      13015 :     if (!typ->layout || typ->layout->npointers == 0)
    3462                 :       6203 :         return;
    3463         [ +  - ]:       6812 :     jl_svec_t *types = jl_get_fieldtypes(typ);
    3464                 :       6812 :     size_t nf = jl_svec_len(types);
    3465         [ +  + ]:      25699 :     for (size_t i = 0; i < nf; i++) {
    3466                 :      18887 :         jl_value_t *_fld = jl_svecref(types, i);
    3467         [ +  + ]:      18887 :         if (!jl_is_datatype(_fld))
    3468                 :       1461 :             continue;
    3469                 :      17426 :         jl_datatype_t *fld = (jl_datatype_t*)_fld;
    3470         [ +  + ]:      17426 :         if (jl_field_isptr(typ, i)) {
    3471                 :            :             // pointer field, check if field is perm-alloc
    3472         [ +  + ]:      11363 :             if (type_is_permalloc((jl_value_t*)fld))
    3473                 :       1722 :                 res.push_back(offset + jl_field_offset(typ, i));
    3474                 :      11363 :             continue;
    3475                 :            :         }
    3476                 :            :         // inline field
    3477                 :       6063 :         find_perm_offsets(fld, res, offset + jl_field_offset(typ, i));
    3478                 :            :     }
    3479                 :            : }
    3480                 :            : 
    3481                 :       6952 : static void emit_write_multibarrier(jl_codectx_t &ctx, Value *parent, Value *agg,
    3482                 :            :                                     jl_value_t *jltype)
    3483                 :            : {
    3484                 :      13904 :     SmallVector<unsigned,4> perm_offsets;
    3485   [ +  -  +  -  :       6952 :     if (jltype && jl_is_datatype(jltype) && ((jl_datatype_t*)jltype)->layout)
                   +  - ]
    3486                 :       6952 :         find_perm_offsets((jl_datatype_t*)jltype, perm_offsets, 0);
    3487                 :       6952 :     auto ptrs = ExtractTrackedValues(agg, agg->getType(), false, ctx.builder, perm_offsets);
    3488                 :       6952 :     emit_write_barrier(ctx, parent, ptrs);
    3489                 :       6952 : }
    3490                 :            : 
    3491                 :      94556 : static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
    3492                 :            :         jl_datatype_t *sty, const jl_cgval_t &strct, size_t idx0,
    3493                 :            :         jl_cgval_t rhs, jl_cgval_t cmp,
    3494                 :            :         bool wb, AtomicOrdering Order, AtomicOrdering FailOrder,
    3495                 :            :         bool needlock, bool issetfield, bool isreplacefield, bool isswapfield, bool ismodifyfield,
    3496                 :            :         const jl_cgval_t *modifyop, const std::string &fname)
    3497                 :            : {
    3498                 :      94556 :     ++EmittedSetfield;
    3499         [ -  + ]:      94556 :     assert(strct.ispointer());
    3500                 :      94556 :     size_t byte_offset = jl_field_offset(sty, idx0);
    3501                 :      94556 :     Value *addr = data_pointer(ctx, strct);
    3502         [ +  + ]:      94556 :     if (byte_offset > 0) {
    3503                 :     230040 :         addr = ctx.builder.CreateInBoundsGEP(
    3504                 :      76680 :                 getInt8Ty(ctx.builder.getContext()),
    3505                 :      76680 :                 emit_bitcast(ctx, addr, getInt8PtrTy(ctx.builder.getContext())),
    3506                 :      76680 :                 ConstantInt::get(getSizeTy(ctx.builder.getContext()), byte_offset)); // TODO: use emit_struct_gep
    3507                 :            :     }
    3508                 :      94556 :     jl_value_t *jfty = jl_field_type(sty, idx0);
    3509   [ +  +  +  +  :      94556 :     if (!jl_field_isptr(sty, idx0) && jl_is_uniontype(jfty)) {
                   +  + ]
    3510                 :       3732 :         size_t fsz = 0, al = 0;
    3511                 :       3732 :         int union_max = jl_islayout_inline(jfty, &fsz, &al);
    3512                 :       3732 :         bool isptr = (union_max == 0);
    3513   [ +  -  +  - ]:       3732 :         assert(!isptr && fsz == jl_field_size(sty, idx0) - 1); (void)isptr;
    3514                 :            :         // compute tindex from rhs
    3515                 :       3732 :         jl_cgval_t rhs_union = convert_julia_type(ctx, rhs, jfty);
    3516         [ -  + ]:       3732 :         if (rhs_union.typ == jl_bottom_type)
    3517                 :          0 :             return jl_cgval_t();
    3518                 :       7464 :         Value *ptindex = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()),
    3519                 :       3732 :                 emit_bitcast(ctx, addr, getInt8PtrTy(ctx.builder.getContext())),
    3520                 :       3732 :                 ConstantInt::get(getSizeTy(ctx.builder.getContext()), fsz));
    3521         [ -  + ]:       3732 :         if (needlock)
    3522                 :          0 :             emit_lockstate_value(ctx, strct, true);
    3523                 :       3732 :         BasicBlock *ModifyBB = NULL;
    3524         [ -  + ]:       3732 :         if (ismodifyfield) {
    3525                 :          0 :             ModifyBB = BasicBlock::Create(ctx.builder.getContext(), "modify_xchg", ctx.f);
    3526                 :          0 :             ctx.builder.CreateBr(ModifyBB);
    3527                 :          0 :             ctx.builder.SetInsertPoint(ModifyBB);
    3528                 :            :         }
    3529                 :       3732 :         jl_cgval_t oldval = rhs;
    3530         [ -  + ]:       3732 :         if (!issetfield)
    3531                 :          0 :             oldval = emit_unionload(ctx, addr, ptindex, jfty, fsz, al, strct.tbaa, true, union_max, ctx.tbaa().tbaa_unionselbyte);
    3532                 :       3732 :         Value *Success = NULL;
    3533                 :       3732 :         BasicBlock *DoneBB = NULL;
    3534   [ +  -  -  + ]:       3732 :         if (isreplacefield || ismodifyfield) {
    3535         [ #  # ]:          0 :             if (ismodifyfield) {
    3536         [ #  # ]:          0 :                 if (needlock)
    3537                 :          0 :                     emit_lockstate_value(ctx, strct, false);
    3538                 :          0 :                 const jl_cgval_t argv[3] = { cmp, oldval, rhs };
    3539         [ #  # ]:          0 :                 if (modifyop) {
    3540                 :          0 :                     rhs = emit_invoke(ctx, *modifyop, argv, 3, (jl_value_t*)jl_any_type);
    3541                 :            :                 }
    3542                 :            :                 else {
    3543                 :          0 :                     Value *callval = emit_jlcall(ctx, jlapplygeneric_func, nullptr, argv, 3, julia_call);
    3544                 :          0 :                     rhs = mark_julia_type(ctx, callval, true, jl_any_type);
    3545                 :            :                 }
    3546                 :          0 :                 emit_typecheck(ctx, rhs, jfty, fname);
    3547                 :          0 :                 rhs = update_julia_type(ctx, rhs, jfty);
    3548                 :          0 :                 rhs_union = convert_julia_type(ctx, rhs, jfty);
    3549         [ #  # ]:          0 :                 if (rhs_union.typ == jl_bottom_type)
    3550                 :          0 :                     return jl_cgval_t();
    3551         [ #  # ]:          0 :                 if (needlock)
    3552                 :          0 :                     emit_lockstate_value(ctx, strct, true);
    3553                 :          0 :                 cmp = oldval;
    3554                 :          0 :                 oldval = emit_unionload(ctx, addr, ptindex, jfty, fsz, al, strct.tbaa, true, union_max, ctx.tbaa().tbaa_unionselbyte);
    3555                 :            :             }
    3556                 :          0 :             BasicBlock *XchgBB = BasicBlock::Create(ctx.builder.getContext(), "xchg", ctx.f);
    3557                 :          0 :             DoneBB = BasicBlock::Create(ctx.builder.getContext(), "done_xchg", ctx.f);
    3558                 :          0 :             Success = emit_f_is(ctx, oldval, cmp);
    3559         [ #  # ]:          0 :             ctx.builder.CreateCondBr(Success, XchgBB, ismodifyfield ? ModifyBB : DoneBB);
    3560                 :          0 :             ctx.builder.SetInsertPoint(XchgBB);
    3561                 :            :         }
    3562                 :       3732 :         Value *tindex = compute_tindex_unboxed(ctx, rhs_union, jfty);
    3563                 :       3732 :         tindex = ctx.builder.CreateNUWSub(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 1));
    3564                 :       3732 :         tbaa_decorate(ctx.tbaa().tbaa_unionselbyte, ctx.builder.CreateAlignedStore(tindex, ptindex, Align(1)));
    3565                 :            :         // copy data
    3566         [ +  + ]:       3732 :         if (!rhs.isghost) {
    3567                 :        414 :             emit_unionmove(ctx, addr, strct.tbaa, rhs, nullptr);
    3568                 :            :         }
    3569   [ +  -  -  + ]:       3732 :         if (isreplacefield || ismodifyfield) {
    3570                 :          0 :             ctx.builder.CreateBr(DoneBB);
    3571                 :          0 :             ctx.builder.SetInsertPoint(DoneBB);
    3572                 :            :         }
    3573         [ -  + ]:       3732 :         if (needlock)
    3574                 :          0 :             emit_lockstate_value(ctx, strct, false);
    3575         [ -  + ]:       3732 :         if (isreplacefield) {
    3576                 :          0 :             Success = ctx.builder.CreateZExt(Success, getInt8Ty(ctx.builder.getContext()));
    3577                 :          0 :             jl_cgval_t argv[2] = {oldval, mark_julia_type(ctx, Success, false, jl_bool_type)};
    3578                 :          0 :             jl_datatype_t *rettyp = jl_apply_cmpswap_type(jfty);
    3579                 :          0 :             oldval = emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv);
    3580                 :            :         }
    3581         [ -  + ]:       3732 :         else if (ismodifyfield) {
    3582                 :          0 :             jl_cgval_t argv[2] = {oldval, rhs};
    3583                 :          0 :             jl_datatype_t *rettyp = jl_apply_modify_type(jfty);
    3584                 :          0 :             oldval = emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv);
    3585                 :            :         }
    3586                 :       3732 :         return oldval;
    3587                 :            :     }
    3588                 :            :     else {
    3589                 :      90824 :         unsigned align = jl_field_align(sty, idx0);
    3590                 :      90824 :         bool isboxed = jl_field_isptr(sty, idx0);
    3591                 :      90824 :         size_t nfields = jl_datatype_nfields(sty);
    3592                 :      90824 :         bool maybe_null = idx0 >= nfields - (unsigned)sty->name->n_uninitialized;
    3593                 :      90824 :         return typed_store(ctx, addr, NULL, rhs, cmp, jfty, strct.tbaa, nullptr,
    3594                 :      53115 :             wb ? boxed(ctx, strct) : nullptr,
    3595                 :            :             isboxed, Order, FailOrder, align,
    3596         [ +  + ]:     143939 :             needlock, issetfield, isreplacefield, isswapfield, ismodifyfield, maybe_null, modifyop, fname);
    3597                 :            :     }
    3598                 :            : }
    3599                 :            : 
    3600                 :     119222 : 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)
    3601                 :            : {
    3602                 :     119222 :     ++EmittedNewStructs;
    3603         [ -  + ]:     119222 :     assert(jl_is_datatype(ty));
    3604         [ -  + ]:     119222 :     assert(jl_is_concrete_type(ty));
    3605                 :     119222 :     jl_datatype_t *sty = (jl_datatype_t*)ty;
    3606                 :     119222 :     size_t nf = jl_datatype_nfields(sty);
    3607   [ +  +  +  + ]:     119222 :     if (nf > 0 || sty->name->mutabl) {
    3608         [ +  + ]:     114592 :         if (deserves_stack(ty)) {
    3609                 :     101193 :             Type *lt = julia_type_to_llvm(ctx, ty);
    3610         [ -  + ]:     101193 :             unsigned na = nargs < nf ? nargs : nf;
    3611                 :            : 
    3612                 :            :             // whether we should perform the initialization with the struct as a IR value
    3613                 :            :             // or instead initialize the stack buffer with stores
    3614                 :     101193 :             auto tracked = CountTrackedPointers(lt);
    3615                 :     101193 :             bool init_as_value = false;
    3616   [ +  +  +  +  :     101193 :             if (lt->isVectorTy() || jl_is_vecelement_type(ty)) { // maybe also check the size ?
                   +  + ]
    3617                 :         82 :                 init_as_value = true;
    3618                 :            :             }
    3619         [ +  + ]:     101111 :             else if (tracked.count) {
    3620                 :      62630 :                 init_as_value = true;
    3621                 :            :             }
    3622                 :            : 
    3623                 :     101193 :             Instruction *promotion_point = nullptr;
    3624                 :     101193 :             ssize_t promotion_ssa = -1;
    3625                 :            :             Value *strct;
    3626         [ +  + ]:     101193 :             if (type_is_ghost(lt)) {
    3627                 :        266 :                 strct = NULL;
    3628                 :            :             }
    3629         [ +  + ]:     100927 :             else if (init_as_value) {
    3630         [ +  + ]:      62712 :                 if (tracked.count)
    3631                 :      62630 :                     strct = Constant::getNullValue(lt);
    3632                 :            :                 else
    3633                 :         82 :                     strct = UndefValue::get(lt);
    3634                 :            :             }
    3635                 :            :             else {
    3636                 :      38215 :                 strct = emit_static_alloca(ctx, lt);
    3637         [ -  + ]:      38215 :                 if (tracked.count)
    3638                 :          0 :                     undef_derived_strct(ctx.builder, strct, sty, ctx.tbaa().tbaa_stack);
    3639                 :            :             }
    3640                 :            : 
    3641         [ +  + ]:     305595 :             for (unsigned i = 0; i < na; i++) {
    3642                 :     204402 :                 jl_value_t *jtype = jl_svecref(sty->types, i); // n.b. ty argument must be concrete
    3643                 :     204402 :                 jl_cgval_t fval_info = argv[i];
    3644                 :            : 
    3645                 :     204402 :                 IRBuilderBase::InsertPoint savedIP;
    3646                 :     204402 :                 emit_typecheck(ctx, fval_info, jtype, "new");
    3647                 :     204402 :                 fval_info = update_julia_type(ctx, fval_info, jtype);
    3648         [ -  + ]:     204402 :                 if (fval_info.typ == jl_bottom_type)
    3649                 :          0 :                     return jl_cgval_t();
    3650                 :            :                 // TODO: Use (post-)domination instead.
    3651         [ +  + ]:      72238 :                 bool field_promotable = !init_as_value && fval_info.promotion_ssa != -1 &&
    3652   [ +  +  +  -  :     276640 :                     fval_info.promotion_point && fval_info.promotion_point->getParent() == ctx.builder.GetInsertBlock();
                   +  + ]
    3653         [ +  + ]:     204402 :                 if (field_promotable) {
    3654                 :       2384 :                     savedIP = ctx.builder.saveIP();
    3655                 :       2384 :                     ctx.builder.SetInsertPoint(fval_info.promotion_point);
    3656                 :            :                 }
    3657         [ +  + ]:     204402 :                 if (type_is_ghost(lt))
    3658                 :       6343 :                     continue;
    3659                 :     203970 :                 Type *fty = julia_type_to_llvm(ctx, jtype);
    3660         [ +  + ]:     203970 :                 if (type_is_ghost(fty))
    3661                 :       5911 :                     continue;
    3662                 :     198059 :                 Value *dest = NULL;
    3663                 :     198059 :                 unsigned offs = jl_field_offset(sty, i);
    3664   [ +  +  +  + ]:     198059 :                 unsigned llvm_idx = (i > 0 && isa<StructType>(lt)) ? convert_struct_offset(ctx, lt, offs) : i;
    3665         [ +  + ]:     198059 :                 if (!init_as_value) {
    3666                 :            :                     // avoid unboxing the argument explicitly
    3667                 :            :                     // and use memcpy instead
    3668                 :            :                     Instruction *inst;
    3669                 :            : #ifndef JL_LLVM_OPAQUE_POINTERS
    3670                 :      70629 :                     dest = inst = cast<Instruction>(ctx.builder.CreateConstInBoundsGEP2_32(lt, strct, 0, llvm_idx));
    3671                 :            : #else
    3672                 :            :                     dest = inst = cast<Instruction>(ctx.builder.CreateConstInBoundsGEP1_32(getInt8Ty(ctx.builder.getContext()), strct, offs));
    3673                 :            : #endif
    3674                 :            :                     // Our promotion point needs to come before
    3675                 :            :                     //  A) All of our arguments' promotion points
    3676                 :            :                     //  B) Any instructions we insert at any of our arguments' promotion points
    3677                 :            :                     // N.B.: Do not use Instruction::comesBefore here. LLVM invalidates its instruction numbering after
    3678                 :            :                     // every insert, so querying it here makes code generation accidentally quadartic.
    3679         [ +  + ]:      70629 :                     if (field_promotable) {
    3680   [ +  +  -  + ]:       2384 :                         if (promotion_ssa == -1 || fval_info.promotion_ssa < promotion_ssa) {
    3681                 :       2160 :                             promotion_point = inst;
    3682                 :       2160 :                             promotion_ssa = fval_info.promotion_ssa;
    3683                 :            :                         }
    3684         [ +  + ]:      68245 :                     } else if (!promotion_point) {
    3685                 :      36207 :                         promotion_point = inst;
    3686                 :            :                     }
    3687                 :            :                 }
    3688                 :     198059 :                 Value *fval = NULL;
    3689         [ +  + ]:     198059 :                 if (jl_field_isptr(sty, i)) {
    3690                 :      84485 :                     fval = boxed(ctx, fval_info);
    3691         [ -  + ]:      84485 :                     if (!init_as_value)
    3692                 :          0 :                         cast<StoreInst>(tbaa_decorate(ctx.tbaa().tbaa_stack,
    3693                 :          0 :                                     ctx.builder.CreateAlignedStore(fval, dest, Align(jl_field_align(sty, i)))))
    3694                 :          0 :                                 ->setOrdering(AtomicOrdering::Unordered);
    3695                 :            :                 }
    3696         [ +  + ]:     113574 :                 else if (jl_is_uniontype(jtype)) {
    3697         [ -  + ]:       1870 :                     assert(!field_promotable);
    3698                 :            :                     // compute tindex from rhs
    3699                 :       1870 :                     jl_cgval_t rhs_union = convert_julia_type(ctx, fval_info, jtype);
    3700         [ -  + ]:       1870 :                     if (rhs_union.typ == jl_bottom_type)
    3701                 :          0 :                         return jl_cgval_t();
    3702                 :       1870 :                     Value *tindex = compute_tindex_unboxed(ctx, rhs_union, jtype);
    3703                 :       1870 :                     tindex = ctx.builder.CreateNUWSub(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 1));
    3704                 :       1870 :                     size_t fsz = 0, al = 0;
    3705                 :       1870 :                     bool isptr = !jl_islayout_inline(jtype, &fsz, &al);
    3706   [ +  -  +  - ]:       1870 :                     assert(!isptr && fsz == jl_field_size(sty, i) - 1); (void)isptr;
    3707         [ +  - ]:       1870 :                     if (init_as_value) {
    3708                 :            :                         // If you wanted to implement init_as_value,
    3709                 :            :                         // would need to emit the union-move into temporary memory,
    3710                 :            :                         // then load it and combine with the tindex.
    3711                 :            :                         // But more efficient to just store it directly.
    3712                 :       1870 :                         unsigned ptindex = convert_struct_offset(ctx, lt, offs + fsz);
    3713   [ +  -  +  + ]:       1870 :                         if (fsz > 0 && !fval_info.isghost) {
    3714                 :       1168 :                             Type *ET = IntegerType::get(ctx.builder.getContext(), 8 * al);
    3715         [ -  + ]:       1168 :                             assert(lt->getStructElementType(llvm_idx) == ET);
    3716                 :       1168 :                             AllocaInst *lv = emit_static_alloca(ctx, ET);
    3717                 :       1168 :                             lv->setOperand(0, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), (fsz + al - 1) / al));
    3718                 :       1168 :                             emit_unionmove(ctx, lv, ctx.tbaa().tbaa_stack, fval_info, nullptr);
    3719                 :            :                             // emit all of the align-sized words
    3720                 :       1168 :                             unsigned i = 0;
    3721         [ +  + ]:       2746 :                             for (; i < fsz / al; i++) {
    3722                 :       1578 :                                 Value *fldp = ctx.builder.CreateConstInBoundsGEP1_32(ET, lv, i);
    3723                 :       1578 :                                 Value *fldv = tbaa_decorate(ctx.tbaa().tbaa_stack, ctx.builder.CreateAlignedLoad(ET, fldp, Align(al)));
    3724                 :       1578 :                                 strct = ctx.builder.CreateInsertValue(strct, fldv, makeArrayRef(llvm_idx + i));
    3725                 :            :                             }
    3726                 :            :                             // emit remaining bytes up to tindex
    3727         [ -  + ]:       1168 :                             if (i < ptindex - llvm_idx) {
    3728                 :          0 :                                 Value *staddr = ctx.builder.CreateConstInBoundsGEP1_32(ET, lv, i);
    3729                 :          0 :                                 staddr = ctx.builder.CreateBitCast(staddr, getInt8PtrTy(ctx.builder.getContext()));
    3730         [ #  # ]:          0 :                                 for (; i < ptindex - llvm_idx; i++) {
    3731                 :          0 :                                     Value *fldp = ctx.builder.CreateConstInBoundsGEP1_32(getInt8Ty(ctx.builder.getContext()), staddr, i);
    3732                 :          0 :                                     Value *fldv = tbaa_decorate(ctx.tbaa().tbaa_stack, ctx.builder.CreateAlignedLoad(getInt8Ty(ctx.builder.getContext()), fldp, Align(1)));
    3733                 :          0 :                                     strct = ctx.builder.CreateInsertValue(strct, fldv, makeArrayRef(llvm_idx + i));
    3734                 :            :                                 }
    3735                 :            :                             }
    3736                 :            :                         }
    3737                 :       1870 :                         llvm_idx = ptindex;
    3738                 :       1870 :                         fval = tindex;
    3739         [ -  + ]:       1870 :                         if (jl_is_vecelement_type(ty))
    3740                 :          0 :                             fval = ctx.builder.CreateInsertValue(strct, fval, makeArrayRef(llvm_idx));
    3741                 :            :                     }
    3742                 :            :                     else {
    3743                 :          0 :                         Value *ptindex = emit_struct_gep(ctx, lt, strct, offs + fsz);
    3744                 :          0 :                         tbaa_decorate(ctx.tbaa().tbaa_unionselbyte, ctx.builder.CreateAlignedStore(tindex, ptindex, Align(1)));
    3745         [ #  # ]:          0 :                         if (!rhs_union.isghost)
    3746                 :          0 :                             emit_unionmove(ctx, dest, ctx.tbaa().tbaa_stack, fval_info, nullptr);
    3747                 :            :                     }
    3748                 :            :                 }
    3749                 :            :                 else {
    3750         [ +  + ]:     111704 :                     if (field_promotable) {
    3751                 :       2384 :                         fval_info.V->replaceAllUsesWith(dest);
    3752                 :       2384 :                         cast<Instruction>(fval_info.V)->eraseFromParent();
    3753         [ +  + ]:     109320 :                     } else if (init_as_value) {
    3754                 :      41075 :                         fval = emit_unbox(ctx, fty, fval_info, jtype);
    3755                 :            :                     } else {
    3756                 :      68245 :                         emit_unbox_store(ctx, fval_info, dest, ctx.tbaa().tbaa_stack, jl_field_align(sty, i));
    3757                 :            :                     }
    3758                 :            :                 }
    3759         [ +  + ]:     198059 :                 if (init_as_value) {
    3760         [ -  + ]:     127430 :                     assert(fval);
    3761         [ +  + ]:     127430 :                     if (jl_is_vecelement_type(ty))
    3762                 :         74 :                         strct = fval;  // VecElement type comes unwrapped in LLVM.
    3763         [ +  + ]:     127356 :                     else if (lt->isVectorTy())
    3764                 :         64 :                         strct = ctx.builder.CreateInsertElement(strct, fval, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), llvm_idx));
    3765         [ +  - ]:     127292 :                     else if (lt->isAggregateType())
    3766                 :     127292 :                         strct = ctx.builder.CreateInsertValue(strct, fval, makeArrayRef(llvm_idx));
    3767                 :            :                     else
    3768                 :          0 :                         assert(false);
    3769                 :            :                 }
    3770         [ +  + ]:     198059 :                 if (field_promotable) {
    3771                 :       2384 :                     ctx.builder.restoreIP(savedIP);
    3772                 :            :                 }
    3773                 :            :             }
    3774         [ -  + ]:     101193 :             for (size_t i = nargs; i < nf; i++) {
    3775   [ #  #  #  #  :          0 :                 if (!jl_field_isptr(sty, i) && jl_is_uniontype(jl_field_type(sty, i))) {
                   #  # ]
    3776                 :          0 :                     unsigned offs = jl_field_offset(sty, i);
    3777                 :          0 :                     int fsz = jl_field_size(sty, i) - 1;
    3778                 :          0 :                     unsigned llvm_idx = convert_struct_offset(ctx, cast<StructType>(lt), offs + fsz);
    3779         [ #  # ]:          0 :                     if (init_as_value)
    3780                 :          0 :                         strct = ctx.builder.CreateInsertValue(strct, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0), makeArrayRef(llvm_idx));
    3781                 :            :                     else
    3782                 :          0 :                         tbaa_decorate(ctx.tbaa().tbaa_unionselbyte, ctx.builder.CreateAlignedStore(
    3783                 :          0 :                                 ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0),
    3784                 :            :                                 ctx.builder.CreateConstInBoundsGEP2_32(lt, strct, 0, llvm_idx),
    3785                 :          0 :                                 Align(1)));
    3786                 :            :                 }
    3787                 :            :             }
    3788         [ +  + ]:     101193 :             if (type_is_ghost(lt))
    3789                 :        266 :                 return mark_julia_const(ctx, sty->instance);
    3790         [ +  + ]:     100927 :             else if (init_as_value)
    3791                 :      62712 :                 return mark_julia_type(ctx, strct, false, ty);
    3792                 :            :             else {
    3793                 :      38215 :                 jl_cgval_t ret = mark_julia_slot(strct, ty, NULL, ctx.tbaa().tbaa_stack);
    3794   [ +  +  +  - ]:      38215 :                 if (is_promotable && promotion_point) {
    3795                 :      36025 :                     ret.promotion_point = promotion_point;
    3796                 :      36025 :                     ret.promotion_ssa = promotion_ssa;
    3797                 :            :                 }
    3798                 :      38215 :                 return ret;
    3799                 :            :             }
    3800                 :            :         }
    3801                 :      13399 :         Value *strct = emit_allocobj(ctx, jl_datatype_size(sty),
    3802                 :            :                                      literal_pointer_val(ctx, (jl_value_t*)ty));
    3803                 :      13399 :         jl_cgval_t strctinfo = mark_julia_type(ctx, strct, true, ty);
    3804                 :      13399 :         strct = decay_derived(ctx, strct);
    3805                 :      13399 :         undef_derived_strct(ctx.builder, strct, sty, strctinfo.tbaa);
    3806         [ +  + ]:      15043 :         for (size_t i = nargs; i < nf; i++) {
    3807   [ +  +  -  +  :       1644 :             if (!jl_field_isptr(sty, i) && jl_is_uniontype(jl_field_type(sty, i))) {
                   -  + ]
    3808                 :          0 :                 tbaa_decorate(ctx.tbaa().tbaa_unionselbyte, ctx.builder.CreateAlignedStore(
    3809                 :          0 :                         ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0),
    3810                 :          0 :                         ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), emit_bitcast(ctx, strct, getInt8PtrTy(ctx.builder.getContext())),
    3811                 :          0 :                                 ConstantInt::get(getSizeTy(ctx.builder.getContext()), jl_field_offset(sty, i) + jl_field_size(sty, i) - 1)),
    3812                 :          0 :                         Align(1)));
    3813                 :            :             }
    3814                 :            :         }
    3815                 :            :         // TODO: verify that nargs <= nf (currently handled by front-end)
    3816         [ +  + ]:      63442 :         for (size_t i = 0; i < nargs; i++) {
    3817                 :      50043 :             jl_cgval_t rhs = argv[i];
    3818                 :            :             bool need_wb; // set to true if the store might cause the allocation of a box newer than the struct
    3819         [ +  + ]:      50043 :             if (jl_field_isptr(sty, i))
    3820                 :      23583 :                 need_wb = !rhs.isboxed;
    3821                 :            :             else
    3822                 :      26460 :                 need_wb = false;
    3823                 :      50043 :             jl_value_t *ft = jl_svecref(sty->types, i);
    3824                 :      50043 :             emit_typecheck(ctx, rhs, ft, "new"); // n.b. ty argument must be concrete
    3825                 :      50043 :             rhs = update_julia_type(ctx, rhs, ft);
    3826         [ -  + ]:      50043 :             if (rhs.typ == jl_bottom_type)
    3827                 :          0 :                 return jl_cgval_t();
    3828                 :      50043 :             emit_setfield(ctx, sty, strctinfo, i, rhs, jl_cgval_t(), need_wb, AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, false, true, false, false, false, nullptr, "");
    3829                 :            :         }
    3830                 :      13399 :         return strctinfo;
    3831                 :            :     }
    3832                 :            :     else {
    3833                 :            :         // 0 fields, ghost or bitstype
    3834         [ +  - ]:       4630 :         if (jl_datatype_nbits(sty) == 0)
    3835                 :       4630 :             return ghostValue(ctx, sty);
    3836                 :            :         bool isboxed;
    3837                 :          0 :         Type *lt = julia_type_to_llvm(ctx, ty, &isboxed);
    3838         [ #  # ]:          0 :         assert(!isboxed);
    3839                 :          0 :         return mark_julia_type(ctx, UndefValue::get(lt), false, ty);
    3840                 :            :     }
    3841                 :            : }
    3842                 :            : 
    3843                 :        582 : static void emit_signal_fence(jl_codectx_t &ctx)
    3844                 :            : {
    3845                 :        582 :     ++EmittedSignalFences;
    3846                 :        582 :     ctx.builder.CreateFence(AtomicOrdering::SequentiallyConsistent, SyncScope::SingleThread);
    3847                 :        582 : }
    3848                 :            : 
    3849                 :         74 : static Value *emit_defer_signal(jl_codectx_t &ctx)
    3850                 :            : {
    3851                 :         74 :     ++EmittedDeferSignal;
    3852                 :         74 :     Value *ptls = emit_bitcast(ctx, get_current_ptls(ctx),
    3853                 :         74 :                                PointerType::get(ctx.types().T_sigatomic, 0));
    3854                 :         74 :     Constant *offset = ConstantInt::getSigned(getInt32Ty(ctx.builder.getContext()),
    3855                 :            :             offsetof(jl_tls_states_t, defer_signal) / sizeof(sig_atomic_t));
    3856                 :         74 :     return ctx.builder.CreateInBoundsGEP(ctx.types().T_sigatomic, ptls, ArrayRef<Value*>(offset), "jl_defer_signal");
    3857                 :            : }
    3858                 :            : 
    3859                 :        254 : static void emit_gc_safepoint(jl_codectx_t &ctx)
    3860                 :            : {
    3861                 :        254 :     ctx.builder.CreateCall(prepare_call(gcroot_flush_func));
    3862                 :        254 :     emit_signal_fence(ctx);
    3863                 :        254 :     ctx.builder.CreateLoad(getSizeTy(ctx.builder.getContext()), get_current_signal_page(ctx), true);
    3864                 :        254 :     emit_signal_fence(ctx);
    3865                 :        254 : }
    3866                 :            : 
    3867                 :        412 : static Value *emit_gc_state_set(jl_codectx_t &ctx, Value *state, Value *old_state)
    3868                 :            : {
    3869                 :        412 :     Type *T_int8 = state->getType();
    3870                 :        412 :     Value *ptls = emit_bitcast(ctx, get_current_ptls(ctx), getInt8PtrTy(ctx.builder.getContext()));
    3871                 :        412 :     Constant *offset = ConstantInt::getSigned(getInt32Ty(ctx.builder.getContext()), offsetof(jl_tls_states_t, gc_state));
    3872                 :        412 :     Value *gc_state = ctx.builder.CreateInBoundsGEP(T_int8, ptls, ArrayRef<Value*>(offset), "gc_state");
    3873         [ +  + ]:        412 :     if (old_state == nullptr) {
    3874                 :        206 :         old_state = ctx.builder.CreateLoad(T_int8, gc_state);
    3875                 :        206 :         cast<LoadInst>(old_state)->setOrdering(AtomicOrdering::Monotonic);
    3876                 :            :     }
    3877                 :        412 :     ctx.builder.CreateAlignedStore(state, gc_state, Align(sizeof(void*)))->setOrdering(AtomicOrdering::Release);
    3878         [ +  + ]:        412 :     if (auto *C = dyn_cast<ConstantInt>(old_state))
    3879         [ +  - ]:        206 :         if (C->isZero())
    3880                 :        206 :             return old_state;
    3881         [ +  - ]:        206 :     if (auto *C = dyn_cast<ConstantInt>(state))
    3882         [ -  + ]:        206 :         if (!C->isZero())
    3883                 :          0 :             return old_state;
    3884                 :        206 :     BasicBlock *passBB = BasicBlock::Create(ctx.builder.getContext(), "safepoint", ctx.f);
    3885                 :        206 :     BasicBlock *exitBB = BasicBlock::Create(ctx.builder.getContext(), "after_safepoint", ctx.f);
    3886                 :        206 :     Constant *zero8 = ConstantInt::get(T_int8, 0);
    3887                 :        206 :     ctx.builder.CreateCondBr(ctx.builder.CreateAnd(ctx.builder.CreateICmpNE(old_state, zero8), // if (old_state && !state)
    3888                 :            :                                                    ctx.builder.CreateICmpEQ(state, zero8)),
    3889                 :            :                              passBB, exitBB);
    3890                 :        206 :     ctx.builder.SetInsertPoint(passBB);
    3891                 :        206 :     emit_gc_safepoint(ctx);
    3892                 :        206 :     ctx.builder.CreateBr(exitBB);
    3893                 :        206 :     ctx.builder.SetInsertPoint(exitBB);
    3894                 :        206 :     return old_state;
    3895                 :            : }
    3896                 :            : 
    3897                 :        206 : static Value *emit_gc_unsafe_enter(jl_codectx_t &ctx)
    3898                 :            : {
    3899                 :        206 :     Value *state = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0);
    3900                 :        206 :     return emit_gc_state_set(ctx, state, nullptr);
    3901                 :            : }
    3902                 :            : 
    3903                 :        206 : static Value *emit_gc_unsafe_leave(jl_codectx_t &ctx, Value *state)
    3904                 :            : {
    3905                 :        206 :     Value *old_state = ConstantInt::get(state->getType(), 0);
    3906                 :        206 :     return emit_gc_state_set(ctx, state, old_state);
    3907                 :            : }
    3908                 :            : 
    3909                 :            : //static Value *emit_gc_safe_enter(jl_codectx_t &ctx)
    3910                 :            : //{
    3911                 :            : //    Value *state = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), JL_GC_STATE_SAFE);
    3912                 :            : //    return emit_gc_state_set(ctx, state, nullptr);
    3913                 :            : //}
    3914                 :            : //
    3915                 :            : //static Value *emit_gc_safe_leave(jl_codectx_t &ctx, Value *state)
    3916                 :            : //{
    3917                 :            : //    Value *old_state = ConstantInt::get(state->getType(), JL_GC_STATE_SAFE);
    3918                 :            : //    return emit_gc_state_set(ctx, state, old_state);
    3919                 :            : //}
    3920                 :            : 
    3921                 :            : 
    3922                 :            : 
    3923                 :            : #ifndef JL_NDEBUG
    3924                 :          0 : static int compare_cgparams(const jl_cgparams_t *a, const jl_cgparams_t *b)
    3925                 :            : {
    3926                 :            :     return
    3927                 :          0 :            (a->track_allocations == b->track_allocations) &&
    3928         [ #  # ]:          0 :            (a->code_coverage == b->code_coverage) &&
    3929         [ #  # ]:          0 :            (a->prefer_specsig == b->prefer_specsig) &&
    3930         [ #  # ]:          0 :            (a->gnu_pubnames == b->gnu_pubnames) &&
    3931         [ #  # ]:          0 :            (a->debug_info_kind == b->debug_info_kind) &&
    3932   [ #  #  #  # ]:          0 :            (a->lookup == b->lookup) &&
    3933         [ #  # ]:          0 :            (a->generic_context == b->generic_context);
    3934                 :            : }
    3935                 :            : #endif
    3936                 :            : 
    3937                 :            : // Reset us back to codegen debug type
    3938                 :            : #undef DEBUG_TYPE
    3939                 :            : #define DEBUG_TYPE "julia_irgen_codegen"

Generated by: LCOV version 1.14