LCOV - code coverage report
Current view: top level - src - codegen_shared.h (source / functions) Hit Total Coverage
Test: [test only] commit 0f242327d2cc9bd130497f44b6350c924185606a Lines: 81 105 77.1 %
Date: 2022-07-16 23:42:53 Functions: 24 30 80.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 12 16 75.0 %

           Branch data     Line data    Source code
       1                 :            : // This file is a part of Julia. License is MIT: https://julialang.org/license
       2                 :            : 
       3                 :            : #include <utility>
       4                 :            : #include <llvm/ADT/ArrayRef.h>
       5                 :            : #include <llvm/Support/Debug.h>
       6                 :            : #include <llvm/IR/DebugLoc.h>
       7                 :            : #include <llvm/IR/IRBuilder.h>
       8                 :            : #include <llvm/IR/MDBuilder.h>
       9                 :            : #include "julia.h"
      10                 :            : 
      11                 :            : #define STR(csym)           #csym
      12                 :            : #define XSTR(csym)          STR(csym)
      13                 :            : 
      14                 :            : enum AddressSpace {
      15                 :            :     Generic = 0,
      16                 :            :     Tracked = 10,
      17                 :            :     Derived = 11,
      18                 :            :     CalleeRooted = 12,
      19                 :            :     Loaded = 13,
      20                 :            :     FirstSpecial = Tracked,
      21                 :            :     LastSpecial = Loaded,
      22                 :            : };
      23                 :            : 
      24                 :   45336573 : static inline auto getSizeTy(llvm::LLVMContext &ctxt) {
      25                 :            :     if (sizeof(size_t) > sizeof(uint32_t)) {
      26                 :   45336573 :         return llvm::Type::getInt64Ty(ctxt);
      27                 :            :     } else {
      28                 :            :         return llvm::Type::getInt32Ty(ctxt);
      29                 :            :     }
      30                 :            : }
      31                 :            : 
      32                 :            : namespace JuliaType {
      33                 :   22930368 :     static inline llvm::StructType* get_jlvalue_ty(llvm::LLVMContext &C) {
      34                 :   22930368 :         return llvm::StructType::get(C);
      35                 :            :     }
      36                 :            : 
      37                 :    1925057 :     static inline llvm::PointerType* get_pjlvalue_ty(llvm::LLVMContext &C) {
      38                 :    1925057 :         return llvm::PointerType::get(get_jlvalue_ty(C), 0);
      39                 :            :     }
      40                 :            : 
      41                 :   19759511 :     static inline llvm::PointerType* get_prjlvalue_ty(llvm::LLVMContext &C) {
      42                 :   19759511 :         return llvm::PointerType::get(get_jlvalue_ty(C), AddressSpace::Tracked);
      43                 :            :     }
      44                 :            : 
      45                 :    1059383 :     static inline llvm::PointerType* get_ppjlvalue_ty(llvm::LLVMContext &C) {
      46                 :    1059383 :         return llvm::PointerType::get(get_pjlvalue_ty(C), 0);
      47                 :            :     }
      48                 :            : 
      49                 :       3292 :     static inline llvm::PointerType* get_pprjlvalue_ty(llvm::LLVMContext &C) {
      50                 :       3292 :         return llvm::PointerType::get(get_prjlvalue_ty(C), 0);
      51                 :            :     }
      52                 :            : 
      53                 :    1916117 :     static inline auto get_jlfunc_ty(llvm::LLVMContext &C) {
      54                 :    1916117 :         auto T_prjlvalue = get_prjlvalue_ty(C);
      55                 :    1916117 :         auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0);
      56                 :    3832220 :         return llvm::FunctionType::get(T_prjlvalue, {
      57                 :            :                 T_prjlvalue,  // function
      58                 :            :                 T_pprjlvalue, // args[]
      59                 :    1916117 :                 llvm::Type::getInt32Ty(C)}, // nargs
      60                 :    1916117 :             false);
      61                 :            :     }
      62                 :            : 
      63                 :       6870 :     static inline auto get_jlfunc2_ty(llvm::LLVMContext &C) {
      64                 :       6870 :         auto T_prjlvalue = get_prjlvalue_ty(C);
      65                 :       6870 :         auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0);
      66                 :      13740 :         return llvm::FunctionType::get(T_prjlvalue, {
      67                 :            :                 T_prjlvalue,  // function
      68                 :            :                 T_pprjlvalue, // args[]
      69                 :       6870 :                 llvm::Type::getInt32Ty(C),
      70                 :            :                 T_prjlvalue,  // linfo
      71                 :            :                 }, // nargs
      72                 :       6870 :             false);
      73                 :            :     }
      74                 :            : 
      75                 :     708542 :     static inline auto get_jlfuncparams_ty(llvm::LLVMContext &C) {
      76                 :     708542 :         auto T_prjlvalue = get_prjlvalue_ty(C);
      77                 :     708542 :         auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0);
      78                 :    1417080 :         return llvm::FunctionType::get(T_prjlvalue, {
      79                 :            :                 T_prjlvalue,  // function
      80                 :            :                 T_pprjlvalue, // args[]
      81                 :     708542 :                 llvm::Type::getInt32Ty(C),
      82                 :            :                 T_pprjlvalue,  // linfo->sparam_vals
      83                 :            :                 }, // nargs
      84                 :     708542 :             false);
      85                 :            :     }
      86                 :            : 
      87                 :      18530 :     static inline auto get_voidfunc_ty(llvm::LLVMContext &C) {
      88                 :      18530 :         return llvm::FunctionType::get(llvm::Type::getVoidTy(C), /*isVarArg*/false);
      89                 :            :     }
      90                 :            : 
      91                 :      18530 :     static inline auto get_pvoidfunc_ty(llvm::LLVMContext &C) {
      92                 :      18530 :         return get_voidfunc_ty(C)->getPointerTo();
      93                 :            :     }
      94                 :            : }
      95                 :            : 
      96                 :            : // return how many Tracked pointers are in T (count > 0),
      97                 :            : // and if there is anything else in T (all == false)
      98                 :            : struct CountTrackedPointers {
      99                 :            :     unsigned count = 0;
     100                 :            :     bool all = true;
     101                 :            :     bool derived = false;
     102                 :            :     CountTrackedPointers(llvm::Type *T);
     103                 :            : };
     104                 :            : 
     105                 :            : unsigned TrackWithShadow(llvm::Value *Src, llvm::Type *T, bool isptr, llvm::Value *Dst, llvm::Type *DTy, llvm::IRBuilder<> &irbuilder);
     106                 :            : std::vector<llvm::Value*> ExtractTrackedValues(llvm::Value *Src, llvm::Type *STy, bool isptr, llvm::IRBuilder<> &irbuilder, llvm::ArrayRef<unsigned> perm_offsets={});
     107                 :            : 
     108                 :          0 : static inline void llvm_dump(llvm::Value *v)
     109                 :            : {
     110                 :          0 :     v->print(llvm::dbgs(), true);
     111                 :          0 :     llvm::dbgs() << "\n";
     112                 :          0 : }
     113                 :            : 
     114                 :          0 : static inline void llvm_dump(llvm::Type *v)
     115                 :            : {
     116                 :          0 :     v->print(llvm::dbgs(), true);
     117                 :          0 :     llvm::dbgs() << "\n";
     118                 :          0 : }
     119                 :            : 
     120                 :          0 : static inline void llvm_dump(llvm::Function *f)
     121                 :            : {
     122                 :          0 :     f->print(llvm::dbgs(), nullptr, false, true);
     123                 :          0 : }
     124                 :            : 
     125                 :          0 : static inline void llvm_dump(llvm::Module *m)
     126                 :            : {
     127                 :          0 :     m->print(llvm::dbgs(), nullptr);
     128                 :          0 : }
     129                 :            : 
     130                 :          0 : static inline void llvm_dump(llvm::Metadata *m)
     131                 :            : {
     132                 :          0 :     m->print(llvm::dbgs());
     133                 :          0 :     llvm::dbgs() << "\n";
     134                 :          0 : }
     135                 :            : 
     136                 :          0 : static inline void llvm_dump(llvm::DebugLoc *dbg)
     137                 :            : {
     138                 :          0 :     dbg->print(llvm::dbgs());
     139                 :          0 :     llvm::dbgs() << "\n";
     140                 :          0 : }
     141                 :            : 
     142                 :   21338806 : static inline std::pair<llvm::MDNode*,llvm::MDNode*> tbaa_make_child_with_context(llvm::LLVMContext &ctxt, const char *name, llvm::MDNode *parent=nullptr, bool isConstant=false)
     143                 :            : {
     144                 :   21338806 :     llvm::MDBuilder mbuilder(ctxt);
     145                 :   21338806 :     llvm::MDNode *jtbaa = mbuilder.createTBAARoot("jtbaa");
     146                 :   21338806 :     llvm::MDNode *tbaa_root = mbuilder.createTBAAScalarTypeNode("jtbaa", jtbaa);
     147         [ +  + ]:   21338806 :     llvm::MDNode *scalar = mbuilder.createTBAAScalarTypeNode(name, parent ? parent : tbaa_root);
     148                 :   21338806 :     llvm::MDNode *n = mbuilder.createTBAAStructTagNode(scalar, scalar, 0, isConstant);
     149                 :   21338806 :     return std::make_pair(n, scalar);
     150                 :            : }
     151                 :            : 
     152                 :   10604399 : static inline llvm::MDNode *get_tbaa_const(llvm::LLVMContext &ctxt) {
     153                 :   10604399 :     return tbaa_make_child_with_context(ctxt, "jtbaa_const", nullptr, true).first;
     154                 :            : }
     155                 :            : 
     156                 :   12434399 : static inline llvm::Instruction *tbaa_decorate(llvm::MDNode *md, llvm::Instruction *inst)
     157                 :            : {
     158                 :   12434399 :     inst->setMetadata(llvm::LLVMContext::MD_tbaa, md);
     159   [ +  +  +  -  :   12434399 :     if (llvm::isa<llvm::LoadInst>(inst) && md && md == get_tbaa_const(md->getContext()))
             +  +  +  + ]
     160                 :    6216160 :         inst->setMetadata(llvm::LLVMContext::MD_invariant_load, llvm::MDNode::get(md->getContext(), llvm::None));
     161                 :   12434399 :     return inst;
     162                 :            : }
     163                 :            : 
     164                 :            : // bitcast a value, but preserve its address space when dealing with pointer types
     165                 :     415670 : static inline llvm::Value *emit_bitcast_with_builder(llvm::IRBuilder<> &builder, llvm::Value *v, llvm::Type *jl_value)
     166                 :            : {
     167                 :            :     using namespace llvm;
     168   [ +  -  -  +  :     831340 :     if (isa<PointerType>(jl_value) &&
                   -  + ]
     169                 :     415670 :         v->getType()->getPointerAddressSpace() != jl_value->getPointerAddressSpace()) {
     170                 :            :         // Cast to the proper address space
     171                 :          0 :         Type *jl_value_addr = PointerType::getWithSamePointeeType(cast<PointerType>(jl_value), v->getType()->getPointerAddressSpace());
     172                 :          0 :         return builder.CreateBitCast(v, jl_value_addr);
     173                 :            :     }
     174                 :            :     else {
     175                 :     415670 :         return builder.CreateBitCast(v, jl_value);
     176                 :            :     }
     177                 :            : }
     178                 :            : 
     179                 :            : // Get PTLS through current task.
     180                 :     415670 : static inline llvm::Value *get_current_ptls_from_task(llvm::IRBuilder<> &builder, llvm::Value *current_task, llvm::MDNode *tbaa)
     181                 :            : {
     182                 :            :     using namespace llvm;
     183                 :     415670 :     auto T_ppjlvalue = JuliaType::get_ppjlvalue_ty(builder.getContext());
     184                 :     415670 :     auto T_pjlvalue = JuliaType::get_pjlvalue_ty(builder.getContext());
     185                 :     415670 :     auto T_size = builder.GetInsertBlock()->getModule()->getDataLayout().getIntPtrType(builder.getContext());
     186                 :     415670 :     const int ptls_offset = offsetof(jl_task_t, ptls);
     187                 :     831340 :     llvm::Value *pptls = builder.CreateInBoundsGEP(
     188                 :            :         T_pjlvalue, current_task,
     189                 :     415670 :         ConstantInt::get(T_size, ptls_offset / sizeof(void *)),
     190                 :            :         "ptls_field");
     191                 :     415670 :     LoadInst *ptls_load = builder.CreateAlignedLoad(T_pjlvalue,
     192                 :     415670 :         emit_bitcast_with_builder(builder, pptls, T_ppjlvalue), Align(sizeof(void *)), "ptls_load");
     193                 :            :     // Note: Corresponding store (`t->ptls = ptls`) happens in `ctx_switch` of tasks.c.
     194                 :     415670 :     tbaa_decorate(tbaa, ptls_load);
     195                 :            :     // Using `CastInst::Create` to get an `Instruction*` without explicit cast:
     196                 :     415670 :     auto ptls = CastInst::Create(Instruction::BitCast, ptls_load, T_ppjlvalue, "ptls");
     197                 :     415670 :     builder.Insert(ptls);
     198                 :     415670 :     return ptls;
     199                 :            : }
     200                 :            : 
     201                 :            : // Compatibility shims for LLVM attribute APIs that were renamed in LLVM 14.
     202                 :            : //
     203                 :            : // Once we no longer support LLVM < 14, these can be mechanically removed by
     204                 :            : // translating foo(Bar, …) into Bar->foo(…) resp. Bar.foo(…).
     205                 :            : namespace {
     206                 :            : using namespace llvm;
     207                 :            : 
     208                 :      36588 : inline void addFnAttr(CallInst *Target, Attribute::AttrKind Attr)
     209                 :            : {
     210                 :            : #if JL_LLVM_VERSION >= 140000
     211                 :      36588 :     Target->addFnAttr(Attr);
     212                 :            : #else
     213                 :            :     Target->addAttribute(AttributeList::FunctionIndex, Attr);
     214                 :            : #endif
     215                 :      36588 : }
     216                 :            : 
     217                 :            : template<class T, class A>
     218                 :    2226492 : inline void addRetAttr(T *Target, A Attr)
     219                 :            : {
     220                 :            : #if JL_LLVM_VERSION >= 140000
     221                 :    2226492 :     Target->addRetAttr(Attr);
     222                 :            : #else
     223                 :            :     Target->addAttribute(AttributeList::ReturnIndex, Attr);
     224                 :            : #endif
     225                 :    2226492 : }
     226                 :            : 
     227                 :            : inline void addAttributeAtIndex(Function *F, unsigned Index, Attribute Attr)
     228                 :            : {
     229                 :            : #if JL_LLVM_VERSION >= 140000
     230                 :            :     F->addAttributeAtIndex(Index, Attr);
     231                 :            : #else
     232                 :            :     F->addAttribute(Index, Attr);
     233                 :            : #endif
     234                 :            : }
     235                 :            : 
     236                 :     558789 : inline AttributeSet getFnAttrs(const AttributeList &Attrs)
     237                 :            : {
     238                 :            : #if JL_LLVM_VERSION >= 140000
     239                 :     558789 :     return Attrs.getFnAttrs();
     240                 :            : #else
     241                 :            :     return Attrs.getFnAttributes();
     242                 :            : #endif
     243                 :            : }
     244                 :            : 
     245                 :     558789 : inline AttributeSet getRetAttrs(const AttributeList &Attrs)
     246                 :            : {
     247                 :            : #if JL_LLVM_VERSION >= 140000
     248                 :     558789 :     return Attrs.getRetAttrs();
     249                 :            : #else
     250                 :            :     return Attrs.getRetAttributes();
     251                 :            : #endif
     252                 :            : }
     253                 :            : 
     254                 :       4152 : inline bool hasFnAttr(const AttributeList &L, Attribute::AttrKind Kind)
     255                 :            : {
     256                 :            : #if JL_LLVM_VERSION >= 140000
     257                 :       4152 :     return L.hasFnAttr(Kind);
     258                 :            : #else
     259                 :            :     return L.hasAttribute(AttributeList::FunctionIndex, Kind);
     260                 :            : #endif
     261                 :            : }
     262                 :            : 
     263                 :            : inline AttributeList addAttributeAtIndex(const AttributeList &L, LLVMContext &C,
     264                 :            :                                          unsigned Index, Attribute::AttrKind Kind)
     265                 :            : {
     266                 :            : #if JL_LLVM_VERSION >= 140000
     267                 :            :     return L.addAttributeAtIndex(C, Index, Kind);
     268                 :            : #else
     269                 :            :     return L.addAttribute(C, Index, Kind);
     270                 :            : #endif
     271                 :            : }
     272                 :            : 
     273                 :            : inline AttributeList addAttributeAtIndex(const AttributeList &L, LLVMContext &C,
     274                 :            :                                          unsigned Index, Attribute Attr)
     275                 :            : {
     276                 :            : #if JL_LLVM_VERSION >= 140000
     277                 :            :     return L.addAttributeAtIndex(C, Index, Attr);
     278                 :            : #else
     279                 :            :     return L.addAttribute(C, Index, Attr);
     280                 :            : #endif
     281                 :            : }
     282                 :            : 
     283                 :            : inline AttributeList addAttributesAtIndex(const AttributeList &L, LLVMContext &C,
     284                 :            :                                           unsigned Index, const AttrBuilder &Builder)
     285                 :            : {
     286                 :            : #if JL_LLVM_VERSION >= 140000
     287                 :            :     return L.addAttributesAtIndex(C, Index, Builder);
     288                 :            : #else
     289                 :            :     return L.addAttributes(C, Index, Builder);
     290                 :            : #endif
     291                 :            : }
     292                 :            : 
     293                 :            : inline AttributeList addFnAttribute(const AttributeList &L, LLVMContext &C,
     294                 :            :                                     Attribute::AttrKind Kind)
     295                 :            : {
     296                 :            : #if JL_LLVM_VERSION >= 140000
     297                 :            :     return L.addFnAttribute(C, Kind);
     298                 :            : #else
     299                 :            :     return L.addAttribute(C, AttributeList::FunctionIndex, Kind);
     300                 :            : #endif
     301                 :            : }
     302                 :            : 
     303                 :            : inline AttributeList addRetAttribute(const AttributeList &L, LLVMContext &C,
     304                 :            :                                      Attribute::AttrKind Kind)
     305                 :            : {
     306                 :            : #if JL_LLVM_VERSION >= 140000
     307                 :            :     return L.addRetAttribute(C, Kind);
     308                 :            : #else
     309                 :            :     return L.addAttribute(C, AttributeList::ReturnIndex, Kind);
     310                 :            : #endif
     311                 :            : }
     312                 :            : 
     313                 :         55 : inline bool hasAttributesAtIndex(const AttributeList &L, unsigned Index)
     314                 :            : {
     315                 :            : #if JL_LLVM_VERSION >= 140000
     316                 :         55 :     return L.hasAttributesAtIndex(Index);
     317                 :            : #else
     318                 :            :     return L.hasAttributes(Index);
     319                 :            : #endif
     320                 :            : }
     321                 :            : 
     322                 :     595247 : inline Attribute getAttributeAtIndex(const AttributeList &L, unsigned Index, Attribute::AttrKind Kind)
     323                 :            : {
     324                 :            : #if JL_LLVM_VERSION >= 140000
     325                 :     595247 :     return L.getAttributeAtIndex(Index, Kind);
     326                 :            : #else
     327                 :            :     return L.getAttribute(Index, Kind);
     328                 :            : #endif
     329                 :            : }
     330                 :            : 
     331                 :            : }

Generated by: LCOV version 1.14