CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
190 lines
6.8 KiB
C++
190 lines
6.8 KiB
C++
//===--- DXILDebugInfo.cpp - analysis&lowering for Debug info -*- C++ -*- ---=//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "DXILDebugInfo.h"
|
|
#include "llvm/BinaryFormat/Dwarf.h"
|
|
#include "llvm/IR/DebugInfo.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
#include "llvm/IR/IntrinsicsDirectX.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
|
|
|
#define DEBUG_TYPE "dx-debug-info"
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::dxil;
|
|
|
|
// llvm.dbg.value has an additional "offset" operand in DXIL.
|
|
static void replaceDbgVariableIntr(DbgVariableIntrinsic *DVI, Function *NewF,
|
|
DXILDebugInfoMap &Res) {
|
|
if (DVI->getIntrinsicID() != Intrinsic::dbg_value) {
|
|
return;
|
|
}
|
|
|
|
Type *Int64Ty = Type::getInt64Ty(DVI->getContext());
|
|
Constant *ZeroOffset = ConstantInt::get(Int64Ty, 0);
|
|
|
|
Value *NewOps[] = {
|
|
DVI->getOperand(0),
|
|
ZeroOffset,
|
|
DVI->getOperand(1),
|
|
DVI->getOperand(2),
|
|
};
|
|
|
|
CallInst *NewI = CallInst::Create(NewF->getFunctionType(), NewF, NewOps);
|
|
NewI->setTailCall(DVI->isTailCall());
|
|
NewI->setDebugLoc(DVI->getDebugLoc());
|
|
Res.InstReplace.insert({DVI, decltype(Res.InstReplace)::mapped_type(NewI)});
|
|
}
|
|
|
|
static void replaceDbgValue(Module &M, DXILDebugInfoMap &Res) {
|
|
Function *F = getDeclarationIfExists(&M, Intrinsic::dbg_value);
|
|
if (!F)
|
|
return;
|
|
|
|
FunctionType *FT = F->getFunctionType();
|
|
Type *Int64Ty = Type::getInt64Ty(F->getContext());
|
|
FunctionType *NewFT = FunctionType::get(
|
|
FT->getReturnType(),
|
|
{FT->getParamType(0), Int64Ty, FT->getParamType(1), FT->getParamType(2)},
|
|
/*isVarArg=*/false);
|
|
Function *NewF = Function::Create(NewFT, F->getLinkage(), F->getName());
|
|
NewF->copyAttributesFrom(F);
|
|
Res.FuncReplace.insert({F, decltype(Res.FuncReplace)::mapped_type(NewF)});
|
|
|
|
for (User *U : F->users()) {
|
|
auto *DVI = cast<DbgVariableIntrinsic>(U);
|
|
replaceDbgVariableIntr(DVI, NewF, Res);
|
|
}
|
|
}
|
|
|
|
DXILDebugInfoMap DXILDebugInfoPass::run(Module &M) {
|
|
DXILDebugInfoMap Res;
|
|
DebugInfoFinder DIF;
|
|
DIF.processModule(M);
|
|
|
|
for (auto &F : M) {
|
|
for (auto &BB : F) {
|
|
for (auto &I : make_early_inc_range(reverse(BB))) {
|
|
if (auto *DL = dyn_cast<DbgLabelInst>(&I)) {
|
|
DL->eraseFromParent();
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (DISubprogram *SP : DIF.subprograms()) {
|
|
if (MDTuple *RN = cast_or_null<MDTuple>(SP->getRawRetainedNodes())) {
|
|
SmallVector<Metadata *> MDs(RN->operands());
|
|
MDs.erase(std::remove_if(MDs.begin(), MDs.end(),
|
|
[](Metadata *M) { return isa<DILabel>(M); }),
|
|
MDs.end());
|
|
SP->replaceRetainedNodes(MDTuple::get(M.getContext(), MDs));
|
|
}
|
|
}
|
|
|
|
// Re-scan the module to account for removed metadata.
|
|
DIF.reset();
|
|
DIF.processModule(M);
|
|
|
|
// Replace llvm.dbg.value with equivalent DXIL intrinsics.
|
|
replaceDbgValue(M, Res);
|
|
|
|
for (DICompileUnit *CU : DIF.compile_units()) {
|
|
DISourceLanguageName Lang = CU->getSourceLanguage();
|
|
if (Lang.hasVersionedName()) {
|
|
auto LangName = static_cast<dwarf::SourceLanguageName>(Lang.getName());
|
|
Lang = dwarf::toDW_LANG(LangName, Lang.getVersion())
|
|
.value_or(dwarf::SourceLanguage{});
|
|
auto *NewCU = DICompileUnit::getDistinct(
|
|
M.getContext(), Lang, CU->getFile(), CU->getProducer(),
|
|
CU->isOptimized(), CU->getFlags(), CU->getRuntimeVersion(),
|
|
CU->getSplitDebugFilename(), CU->getEmissionKind(),
|
|
CU->getEnumTypes(), CU->getRetainedTypes(), CU->getGlobalVariables(),
|
|
CU->getImportedEntities(), CU->getMacros(), CU->getDWOId(),
|
|
CU->getSplitDebugInlining(), CU->getDebugInfoForProfiling(),
|
|
CU->getNameTableKind(), CU->getRangesBaseAddress(), CU->getSysRoot(),
|
|
CU->getSDK());
|
|
Res.MDReplace.insert({CU, NewCU});
|
|
}
|
|
}
|
|
|
|
std::vector<std::pair<const DICompileUnit *, const Metadata *>> CUSubprograms;
|
|
|
|
for (const Function &F : M) {
|
|
if (const DISubprogram *SP = F.getSubprogram()) {
|
|
auto *FunctionMD = ConstantAsMetadata::get(const_cast<Function *>(&F));
|
|
Res.MDExtra.insert({SP, FunctionMD});
|
|
}
|
|
}
|
|
|
|
for (const DISubprogram *SP : DIF.subprograms()) {
|
|
const DISubprogram *NewSP = SP;
|
|
|
|
static constexpr auto SupportedDIFlags =
|
|
static_cast<DISubprogram::DIFlags>(DISubprogram::FlagExportSymbols - 1);
|
|
static constexpr auto SupportedDISPFlags =
|
|
static_cast<DISubprogram::DISPFlags>(DISubprogram::SPFlagPure - 1);
|
|
if (SP->isDistinct() || SP->getFlags() & ~SupportedDIFlags ||
|
|
SP->getSPFlags() & ~SupportedDISPFlags) {
|
|
NewSP = DISubprogram::get(
|
|
M.getContext(), SP->getScope(), SP->getName(), SP->getLinkageName(),
|
|
SP->getFile(), SP->getLine(), SP->getType(), SP->getScopeLine(),
|
|
SP->getContainingType(), SP->getVirtualIndex(),
|
|
SP->getThisAdjustment(), SP->getFlags() & SupportedDIFlags,
|
|
SP->getSPFlags() & SupportedDISPFlags, SP->getUnit(),
|
|
SP->getTemplateParams(), SP->getDeclaration(), SP->getRetainedNodes(),
|
|
SP->getThrownTypes(), SP->getAnnotations(), SP->getTargetFuncName(),
|
|
SP->getKeyInstructionsEnabled());
|
|
|
|
Res.MDReplace.insert({SP, NewSP});
|
|
|
|
if (auto It = Res.MDExtra.find(SP); It != Res.MDExtra.end()) {
|
|
const Metadata *FunctionMD = It->second;
|
|
Res.MDExtra.erase(It);
|
|
Res.MDExtra.insert({NewSP, FunctionMD});
|
|
}
|
|
}
|
|
|
|
if (SP->getUnit())
|
|
CUSubprograms.push_back(
|
|
{SP->getUnit(), static_cast<const Metadata *>(SP)});
|
|
}
|
|
|
|
std::stable_sort(
|
|
CUSubprograms.begin(), CUSubprograms.end(), [](auto &&A, auto &&B) {
|
|
return std::less<const DICompileUnit *>()(A.first, B.first);
|
|
});
|
|
for (auto It = CUSubprograms.begin(), End = CUSubprograms.end(); It != End;) {
|
|
const DICompileUnit *CU = It->first;
|
|
const DICompileUnit *NewCU =
|
|
cast<DICompileUnit>(Res.MDReplace.lookup_or(CU, CU));
|
|
SmallVector<Metadata *, 16> Subprograms;
|
|
do {
|
|
Subprograms.push_back(const_cast<Metadata *>(It->second));
|
|
} while (++It != End && It->first == CU);
|
|
const auto *SubprogramsMD = MDTuple::get(M.getContext(), Subprograms);
|
|
Res.MDExtra.insert({NewCU, SubprogramsMD});
|
|
}
|
|
|
|
for (DIType *T : DIF.types()) {
|
|
if (auto *SR = dyn_cast<DISubrangeType>(T)) {
|
|
DIType *BT = SR->getBaseType();
|
|
if (!BT)
|
|
BT = DIBasicType::get(
|
|
SR->getContext(), dwarf::DW_TAG_base_type, SR->getName(),
|
|
SR->getSizeInBits(), SR->getAlignInBits(), dwarf::DW_ATE_unsigned,
|
|
SR->getNumExtraInhabitants(), /*DataSizeInBits=*/0, SR->getFlags());
|
|
Res.MDReplace.insert({T, BT});
|
|
}
|
|
}
|
|
|
|
return Res;
|
|
}
|