Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPIR-V] Reland Encode debug info producer in SPIR-V #4082

Merged
merged 3 commits into from
Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions llvm-spirv/lib/SPIRV/LLVMToSPIRVDbgTran.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ LLVMToSPIRVDbgTran::transDbgCompilationUnit(const DICompileUnit *CU) {
Ops[DWARFVersionIdx] = M->getDwarfVersion();
Ops[SourceIdx] = getSource(CU)->getId();
Ops[LanguageIdx] = CU->getSourceLanguage();
BM->addModuleProcessed(SPIRVDebug::ProducerPrefix + CU->getProducer().str());
// Cache CU in a member.
SPIRVCU = static_cast<SPIRVExtInst *>(
BM->addDebugInfo(SPIRVDebug::CompilationUnit, getVoidTy(), Ops));
Expand Down
15 changes: 13 additions & 2 deletions llvm-spirv/lib/SPIRV/SPIRVToLLVMDbgTran.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@ SPIRVToLLVMDbgTran::transCompileUnit(const SPIRVExtInst *DebugInst) {
assert(Ops.size() == OperandCount && "Invalid number of operands");
M->addModuleFlag(llvm::Module::Max, "Dwarf Version", Ops[DWARFVersionIdx]);
unsigned SourceLang = Ops[LanguageIdx];
CU = Builder.createCompileUnit(SourceLang, getFile(Ops[SourceIdx]), "spirv", false,
"", 0);
auto Producer = findModuleProducer();
CU = Builder.createCompileUnit(SourceLang, getFile(Ops[SourceIdx]), Producer,
false, "", 0);
return CU;
}

Expand Down Expand Up @@ -1051,6 +1052,16 @@ SPIRVToLLVMDbgTran::SplitFileName::SplitFileName(const string &FileName) {
}
}

std::string SPIRVToLLVMDbgTran::findModuleProducer() {
for (const auto &I : BM->getModuleProcessedVec()) {
if (I->getProcessStr().find(SPIRVDebug::ProducerPrefix) !=
std::string::npos) {
return I->getProcessStr().substr(SPIRVDebug::ProducerPrefix.size());
}
}
return "spirv";
}

Optional<DIFile::ChecksumInfo<StringRef>>
SPIRVToLLVMDbgTran::ParseChecksum(StringRef Text) {
// Example of "Text" variable:
Expand Down
1 change: 1 addition & 0 deletions llvm-spirv/lib/SPIRV/SPIRVToLLVMDbgTran.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class SPIRVToLLVMDbgTran {
return nullptr;
}
const std::string &getString(const SPIRVId Id);
std::string findModuleProducer();
Optional<DIFile::ChecksumInfo<StringRef>> ParseChecksum(StringRef Text);
};
} // namespace SPIRV
Expand Down
1 change: 1 addition & 0 deletions llvm-spirv/lib/SPIRV/libSPIRV/SPIRV.debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace SPIRVDebug {

const unsigned int DebugInfoVersion = 0x00010000;
static const std::string ProducerPrefix = {"Debug info producer: "};
static const std::string ChecksumKindPrefx = {"//__CSK_"};

// clang-format off
Expand Down
16 changes: 16 additions & 0 deletions llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,4 +742,20 @@ SPIRVType *SPIRVTypeStructContinuedINTEL::getMemberType(size_t I) const {
return static_cast<SPIRVType *>(SPIRVEntry::getEntry(Elements[I]));
}

void SPIRVModuleProcessed::validate() const {
assert(WordCount == FixedWC + getSizeInWords(ProcessStr) &&
"Incorrect word count in OpModuleProcessed");
}

void SPIRVModuleProcessed::encode(spv_ostream &O) const {
getEncoder(O) << ProcessStr;
}

void SPIRVModuleProcessed::decode(std::istream &I) {
getDecoder(I) >> ProcessStr;
Module->addModuleProcessed(ProcessStr);
}

std::string SPIRVModuleProcessed::getProcessStr() { return ProcessStr; }

} // namespace SPIRV
21 changes: 21 additions & 0 deletions llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,27 @@ template <> struct InstToContinued<OpSpecConstantComposite> {
constexpr static spv::Op OpCode = OpSpecConstantCompositeContinuedINTEL;
};

class SPIRVModuleProcessed : public SPIRVEntryNoId<OpModuleProcessed> {
public:
SPIRVModuleProcessed(SPIRVModule *M, const std::string &Process)
: SPIRVEntryNoId(M, FixedWC + getSizeInWords(Process)),
ProcessStr(Process) {
updateModuleVersion();
}
SPIRVModuleProcessed() { updateModuleVersion(); }
_SPIRV_DCL_ENCDEC
void validate() const override;
SPIRVWord getRequiredSPIRVVersion() const override {
return static_cast<SPIRVWord>(VersionNumber::SPIRV_1_1);
}

std::string getProcessStr();

private:
std::string ProcessStr;
static const SPIRVWord FixedWC = 1;
};

// ToDo: The following typedef's are place holders for SPIRV entity classes
// to be implemented.
// Each time a new class is implemented, remove the corresponding typedef.
Expand Down
19 changes: 17 additions & 2 deletions llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ class SPIRVModuleImpl : public SPIRVModule {
SPIRVInstruction * = nullptr) override;
SPIRVEntry *addDebugInfo(SPIRVWord, SPIRVType *TheType,
const std::vector<SPIRVWord> &) override;
SPIRVEntry *addModuleProcessed(const std::string &) override;
std::vector<SPIRVModuleProcessed *> getModuleProcessedVec() override;
SPIRVInstruction *addBinaryInst(Op, SPIRVType *, SPIRVValue *, SPIRVValue *,
SPIRVBasicBlock *) override;
SPIRVInstruction *addCallInst(SPIRVFunction *, const std::vector<SPIRVWord> &,
Expand Down Expand Up @@ -526,6 +528,7 @@ class SPIRVModuleImpl : public SPIRVModule {
std::map<unsigned, SPIRVTypeInt *> IntTypeMap;
std::map<unsigned, SPIRVConstant *> LiteralMap;
std::vector<SPIRVExtInst *> DebugInstVec;
std::vector<SPIRVModuleProcessed *> ModuleProcessedVec;
SPIRVAliasInstMDVec AliasInstMDVec;
SPIRVAliasInstMDMap AliasInstMDMap;

Expand All @@ -541,6 +544,9 @@ SPIRVModuleImpl::~SPIRVModuleImpl() {

for (auto C : CapMap)
delete C.second;

for (auto *M : ModuleProcessedVec)
delete M;
}

const std::shared_ptr<const SPIRVLine> &
Expand Down Expand Up @@ -1279,6 +1285,15 @@ SPIRVEntry *SPIRVModuleImpl::addDebugInfo(SPIRVWord InstId, SPIRVType *TheType,
ExtInstSetIds[getDebugInfoEIS()], InstId, Args));
}

SPIRVEntry *SPIRVModuleImpl::addModuleProcessed(const std::string &Process) {
ModuleProcessedVec.push_back(new SPIRVModuleProcessed(this, Process));
return ModuleProcessedVec.back();
}

std::vector<SPIRVModuleProcessed *> SPIRVModuleImpl::getModuleProcessedVec() {
return ModuleProcessedVec;
}

SPIRVInstruction *
SPIRVModuleImpl::addCallInst(SPIRVFunction *TheFunction,
const std::vector<SPIRVWord> &TheArguments,
Expand Down Expand Up @@ -1840,8 +1855,8 @@ spv_ostream &operator<<(spv_ostream &O, SPIRVModule &M) {
TopologicalSort TS(MI.TypeVec, MI.ConstVec, MI.VariableVec,
MI.ForwardPointerVec);

O << MI.MemberNameVec << MI.DecGroupVec << MI.DecorateSet << MI.GroupDecVec
<< MI.ForwardPointerVec << TS;
O << MI.MemberNameVec << MI.ModuleProcessedVec << MI.DecGroupVec
<< MI.DecorateSet << MI.GroupDecVec << MI.ForwardPointerVec << TS;

if (M.isAllowedToUseExtension(ExtensionID::SPV_INTEL_inline_assembly)) {
O << SPIRVNL() << MI.AsmTargetVec << MI.AsmVec;
Expand Down
3 changes: 3 additions & 0 deletions llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ class SPIRVModule {
SPIRVInstruction * = nullptr) = 0;
virtual SPIRVEntry *addDebugInfo(SPIRVWord, SPIRVType *,
const std::vector<SPIRVWord> &) = 0;
virtual SPIRVEntry *addModuleProcessed(const std::string &) = 0;
virtual void addCapability(SPIRVCapabilityKind) = 0;
template <typename T> void addCapabilities(const T &Caps) {
for (auto I : Caps)
Expand Down Expand Up @@ -487,6 +488,8 @@ class SPIRVModule {
return TranslationOpts.isGenArgNameMDEnabled();
}

virtual std::vector<SPIRVModuleProcessed *> getModuleProcessedVec() = 0;

bool getSpecializationConstant(SPIRVWord SpecId, uint64_t &ConstValue) {
return TranslationOpts.getSpecializationConstant(SpecId, ConstValue);
}
Expand Down
1 change: 1 addition & 0 deletions llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ _SPIRV_OP(AtomicFlagClear, 319)
_SPIRV_OP(TypePipeStorage, 322)
_SPIRV_OP(ConstantPipeStorage, 323)
_SPIRV_OP(CreatePipeFromPipeStorage, 324)
_SPIRV_OP(ModuleProcessed, 330)
_SPIRV_OP(DecorateId, 332)
_SPIRV_OP(GroupNonUniformElect, 333)
_SPIRV_OP(GroupNonUniformAll, 334)
Expand Down
60 changes: 60 additions & 0 deletions llvm-spirv/test/DebugInfo/DebugInfoProducer.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
; Test checks debug info of producer is preserved from LLVM IR to spirv
; and spirv to LLVM IR translation.

; Original .cpp source:
;
; int main() {
; return 0;
; }

; Command line:
; ./clang -cc1 -debug-info-kind=standalone -v s.cpp -S -emit-llvm -triple spir

; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s --check-prefix CHECK-SPIRV
; RUN: llvm-spirv %t.bc -o %t.spv
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
; RUN: FileCheck %s --input-file %t.rev.ll --check-prefix CHECK-LLVM

; ModuleID = 's.bc'
source_filename = "s.cpp"
target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
target triple = "spir"

; Function Attrs: noinline norecurse nounwind optnone
define i32 @main() #0 !dbg !8 {
entry:
%retval = alloca i32, align 4
store i32 0, i32* %retval, align 4
ret i32 0, !dbg !13
}

attributes #0 = { noinline norecurse nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5, !6}
!opencl.used.extensions = !{!2}
!opencl.used.optional.core.features = !{!2}
!opencl.compiler.options = !{!2}
!llvm.ident = !{!7}

; CHECK-LLVM: !DICompileUnit
; CHECK-LLVM-SAME: producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 16a50c9e642fd085e5ceb68c403b71b5b2e0607c)"
; CHECK-LLVM-NOT: producer: "spirv"
; CHECK-SPIRV: ModuleProcessed "Debug info producer: clang version 13.0.0 (https://github.com/llvm/llvm-project.git 16a50c9e642fd085e5ceb68c403b71b5b2e0607c)"

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 16a50c9e642fd085e5ceb68c403b71b5b2e0607c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
!1 = !DIFile(filename: "<stdin>", directory: "oneAPI")
!2 = !{}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 1, !"wchar_size", i32 4}
!5 = !{i32 1, !"ThinLTO", i32 0}
!6 = !{i32 1, !"EnableSplitLTOUnit", i32 1}
!7 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 16a50c9e642fd085e5ceb68c403b71b5b2e0607c)"}
!8 = distinct !DISubprogram(name: "main", scope: !9, file: !9, line: 1, type: !10, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!9 = !DIFile(filename: "s.cpp", directory: "C:\\")
!10 = !DISubroutineType(types: !11)
!11 = !{!12}
!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!13 = !DILocation(line: 2, column: 2, scope: !8)