bool annotateCounters()

in lib/BPFCov.cpp [428:647]


    bool annotateCounters(Module &M)
    {
        bool Annotated = false;

        DIBuilder DIB(M);

        Module::debug_compile_units_iterator CUIterator = M.debug_compile_units_begin();
        auto *DebugCU = *CUIterator;
        auto *DebugFile = DebugCU->getFile();

        // Save the current list of globals from the CU debug info
        SmallVector<Metadata *> DebugGlobals;
        for (auto *DG : DebugCU->getGlobalVariables())
        {
            DebugGlobals.push_back(DG);
        }

        for (auto gv_iter = M.global_begin(); gv_iter != M.global_end(); gv_iter++)
        {
            GlobalVariable *GV = &*gv_iter;
            if (GV->hasName())
            {
                if (GV->getName().startswith("__profc") && GV->getValueType()->isArrayTy())
                {
                    // Change to DSO local
                    GV->setLinkage(GlobalValue::LinkageTypes::ExternalLinkage);
                    GV->setDSOLocal(true);

                    auto N = GV->getValueType()->getArrayNumElements();

                    auto *S64Ty = DIB.createBasicType("long long int", 64, dwarf::DW_ATE_signed);

                    auto *DebugArrayTy = DIB.createArrayType(
                        /*Size=*/N * 64,
                        /*AlignInBits=*/0,
                        /*Ty=*/S64Ty,
                        /*Subscripts=*/DIB.getOrCreateArray({DIB.getOrCreateSubrange(0, N)}));

                    auto *DebugGVE = DIB.createGlobalVariableExpression(
                        /*Context=*/DebugCU,
                        /*Name=*/GV->getName(),
                        /*LinkageName=*/"",
                        /*File=*/DebugFile,
                        /*LineNo=*/0,
                        /*Ty=*/DebugArrayTy,
                        /*IsLocalToUnit=*/GV->hasLocalLinkage(),
                        /*IsDefinition=*/true,
                        /*Expr=*/nullptr,
                        /*Decl=*/nullptr,
                        /*TemplateParams=*/nullptr,
                        /*AlignInBits=*/0);

                    GV->addDebugInfo(DebugGVE);
                    DebugGlobals.push_back(DebugGVE);

                    Annotated = true;
                }
                else if (GV->getName() == "__llvm_prf_nm" && GV->getValueType()->isArrayTy())
                {
                    // Change to DSO local
                    GV->setLinkage(GlobalValue::LinkageTypes::ExternalLinkage);
                    GV->setDSOLocal(true);

                    auto N = GV->getValueType()->getArrayNumElements();

                    auto *S8Ty = DIB.createBasicType("char", 8, dwarf::DW_ATE_signed_char);

                    auto *ConstS8Ty = DIB.createQualifiedType(dwarf::DW_TAG_const_type, S8Ty);

                    auto *DebugArrayTy = DIB.createArrayType(
                        /*Size=*/N * 8,
                        /*AlignInBits=*/0,
                        /*Ty=*/ConstS8Ty,
                        /*Subscripts=*/DIB.getOrCreateArray({DIB.getOrCreateSubrange(0, N)}));

                    auto *DebugGVE = DIB.createGlobalVariableExpression(
                        /*Context=*/DebugCU,
                        /*Name=*/GV->getName(),
                        /*LinkageName=*/"",
                        /*File=*/DebugFile,
                        /*LineNo=*/0,
                        /*Ty=*/DebugArrayTy,
                        /*IsLocalToUnit=*/GV->hasLocalLinkage(),
                        /*IsDefinition=*/true,
                        /*Expr=*/nullptr,
                        /*Decl=*/nullptr,
                        /*TemplateParams=*/nullptr,
                        /*AlignInBits=*/0);

                    GV->addDebugInfo(DebugGVE);
                    DebugGlobals.push_back(DebugGVE);

                    Annotated = true;
                }
                else if (GV->getName().startswith("__profd"))
                {
                    DIBasicType *Ty;
                    if (GV->getName().endswith(".0") || GV->getName().endswith(".1") || GV->getName().endswith(".2") || GV->getName().endswith(".3") || GV->getName().endswith(".4"))
                    {
                        Ty = DIB.createBasicType("long long int", 64, dwarf::DW_ATE_signed);
                    }
                    else if (GV->getName().endswith(".5") || GV->getName().endswith(".6"))
                    {
                        Ty = DIB.createBasicType("int", 32, dwarf::DW_ATE_signed);
                    }

                    auto *DebugGVE = DIB.createGlobalVariableExpression(
                        /*Context=*/DebugCU,
                        /*Name=*/GV->getName(),
                        /*LinkageName=*/"",
                        /*File=*/DebugFile,
                        /*LineNo=*/0,
                        /*Ty=*/Ty,
                        /*IsLocalToUnit=*/GV->hasLocalLinkage(),
                        /*IsDefinition=*/true,
                        /*Expr=*/nullptr,
                        /*Decl=*/nullptr,
                        /*TemplateParams=*/nullptr,
                        /*AlignInBits=*/0);

                    GV->addDebugInfo(DebugGVE);
                    DebugGlobals.push_back(DebugGVE);

                    Annotated = true;
                }
                else if (GV->getName().startswith("__covrec"))
                {
                    DIType *GVTy;
                    if (GV->getName().endswith(".0"))
                    {
                        auto *Ty = DIB.createBasicType("long long int", 64, dwarf::DW_ATE_signed);
                        GVTy = DIB.createQualifiedType(dwarf::DW_TAG_const_type, Ty);
                    }
                    if (GV->getName().endswith(".4"))
                    {
                        auto *Ty = DIB.createBasicType("char", 8, dwarf::DW_ATE_signed_char);
                        auto N = GV->getValueType()->getArrayNumElements();
                        GVTy = DIB.createArrayType(
                            /*Size=*/N * 8,
                            /*AlignInBits=*/0,
                            /*Ty=*/DIB.createQualifiedType(dwarf::DW_TAG_const_type, Ty),
                            /*Subscripts=*/DIB.getOrCreateArray({DIB.getOrCreateSubrange(0, N)}));
                    }

                    auto *DebugGVE = DIB.createGlobalVariableExpression(
                        /*Context=*/DebugCU,
                        /*Name=*/GV->getName(),
                        /*LinkageName=*/"",
                        /*File=*/DebugFile,
                        /*LineNo=*/0,
                        /*Ty=*/GVTy,
                        /*IsLocalToUnit=*/GV->hasLocalLinkage(),
                        /*IsDefinition=*/true,
                        /*Expr=*/nullptr,
                        /*Decl=*/nullptr,
                        /*TemplateParams=*/nullptr,
                        /*AlignInBits=*/0);

                    GV->addDebugInfo(DebugGVE);
                    DebugGlobals.push_back(DebugGVE);

                    Annotated = true;
                }
                else if (GV->getName().startswith("__llvm_coverage"))
                {
                    auto N = GV->getValueType()->getArrayNumElements();

                    auto Size = N;
                    DIBasicType *Ty;
                    if (GV->getName().endswith(".0"))
                    {
                        Ty = DIB.createBasicType("int", 32, dwarf::DW_ATE_signed);
                        Size *= 32;
                    }
                    if (GV->getName().endswith(".1"))
                    {
                        Ty = DIB.createBasicType("char", 8, dwarf::DW_ATE_signed_char);
                        Size *= 8;
                    }

                    auto *ConstTy = DIB.createQualifiedType(dwarf::DW_TAG_const_type, Ty);

                    auto *DebugArrayTy = DIB.createArrayType(
                        /*Size=*/Size,
                        /*AlignInBits=*/0,
                        /*Ty=*/ConstTy,
                        /*Subscripts=*/DIB.getOrCreateArray({DIB.getOrCreateSubrange(0, N)}));

                    auto *DebugGVE = DIB.createGlobalVariableExpression(
                        /*Context=*/DebugCU,
                        /*Name=*/GV->getName(),
                        /*LinkageName=*/"",
                        /*File=*/DebugFile,
                        /*LineNo=*/0,
                        /*Ty=*/DebugArrayTy,
                        /*IsLocalToUnit=*/GV->hasLocalLinkage(),
                        /*IsDefinition=*/true,
                        /*Expr=*/nullptr,
                        /*Decl=*/nullptr,
                        /*TemplateParams=*/nullptr,
                        /*AlignInBits=*/0);

                    GV->addDebugInfo(DebugGVE);
                    DebugGlobals.push_back(DebugGVE);

                    Annotated = true;
                }
            }
        }

        if (Annotated)
        {
            errs() << "updating compile unit's globals debug info\n";
            DebugCU->replaceGlobalVariables(MDTuple::get(M.getContext(), DebugGlobals));

            DIB.finalize();
        }

        return Annotated;
    }