From 7136385bb15cc1895be979ee7c7dab2619d7024e Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Thu, 21 Nov 2024 06:22:18 +0000 Subject: [PATCH] DXIL support for LLVM lifetime, invariant LLVM intrinsics Treated as nops by the debugger and disassembler Extended Function call classification to support LLVM intrinsics Renamed enum LLVMDbgOp -> LLVMIntrinsicOp Extended the enum to handle LLVM intrinsics: * llvm.lifetime.start * llvm.lifetime.end * llvm.invariant.start * llvm.invariant.end --- renderdoc/driver/shaders/dxil/dxil_bytecode.h | 16 +++-- renderdoc/driver/shaders/dxil/dxil_debug.cpp | 15 ++--- .../driver/shaders/dxil/dxil_disassemble.cpp | 61 ++++++++++++++++--- .../driver/shaders/dxil/dxil_reflect.cpp | 11 +++- .../driver/shaders/dxil/dxil_stringise.cpp | 12 ++-- 5 files changed, 88 insertions(+), 27 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index abc67ca00..b8f32ce29 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -60,13 +60,18 @@ enum class FunctionFamily : uint8_t LLVM, DXOp, LLVMDbg, + LLVMInstrinsic, }; -enum class LLVMDbgOp : uint8_t +enum class LLVMIntrinsicOp : uint8_t { Unknown = 0, - Declare, - Value, + DbgDeclare, + DbgValue, + LifetimeStart, + LifetimeEnd, + InvariantStart, + InvariantEnd, }; struct BumpAllocator @@ -1397,7 +1402,7 @@ struct Function : public Value AttachedMetadata attachedMeta; FunctionFamily family = FunctionFamily::Unknown; - LLVMDbgOp llvmDbgOp = LLVMDbgOp::Unknown; + LLVMIntrinsicOp llvmIntrinsicOp = LLVMIntrinsicOp::Unknown; }; class LLVMOrderAccumulator @@ -1745,6 +1750,7 @@ bool IsSSA(const Value *dxilValue); DXILDebug::Id GetSSAId(const DXIL::Value *value); bool IsDXCNop(const Instruction &inst); bool IsLLVMDebugCall(const Instruction &inst); +bool IsLLVMIntrinsicCall(const Instruction &inst); bool isUndef(const Value *v); @@ -1759,7 +1765,7 @@ DECLARE_STRINGISE_TYPE(DXIL::Operation); DECLARE_STRINGISE_TYPE(DXIL::DXOp); DECLARE_STRINGISE_TYPE(DXIL::Type::TypeKind); DECLARE_STRINGISE_TYPE(DXIL::Type::ScalarKind); -DECLARE_STRINGISE_TYPE(DXIL::LLVMDbgOp); +DECLARE_STRINGISE_TYPE(DXIL::LLVMIntrinsicOp); DECLARE_STRINGISE_TYPE(DXIL::DIBase::Type); DECLARE_STRINGISE_TYPE(DXIL::ValueKind); DECLARE_STRINGISE_TYPE(DXIL::BarrierMode); diff --git a/renderdoc/driver/shaders/dxil/dxil_debug.cpp b/renderdoc/driver/shaders/dxil/dxil_debug.cpp index 38b0cae2f..e9156a8de 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debug.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_debug.cpp @@ -1534,6 +1534,8 @@ bool IsNopInstruction(const Instruction &inst) const Function *callFunc = inst.getFuncCall(); if(callFunc->family == FunctionFamily::LLVMDbg) return true; + if(callFunc->family == FunctionFamily::LLVMInstrinsic) + return true; } if(IsDXCNop(inst)) @@ -5320,13 +5322,12 @@ void Debugger::ParseDebugData() } const Function *dbgFunc = inst.getFuncCall(); - switch(dbgFunc->llvmDbgOp) + switch(dbgFunc->llvmIntrinsicOp) { - case LLVMDbgOp::Declare: ParseDbgOpDeclare(inst, activeInstructionIndex); break; - case LLVMDbgOp::Value: ParseDbgOpValue(inst, activeInstructionIndex); break; - case LLVMDbgOp::Unknown: - RDCASSERT("Unsupported LLVM debug operation", dbgFunc->llvmDbgOp); - break; + case LLVMIntrinsicOp::DbgDeclare: ParseDbgOpDeclare(inst, activeInstructionIndex); break; + case LLVMIntrinsicOp::DbgValue: ParseDbgOpValue(inst, activeInstructionIndex); break; + case LLVMIntrinsicOp::Unknown: + default: RDCASSERT("Unsupported LLVM debug operation", dbgFunc->llvmIntrinsicOp); break; }; } } @@ -6151,7 +6152,7 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain for(uint32_t i = 0; i < countInstructions; ++i) { const Instruction &inst = *(f->instructions[i]); - if(DXIL::IsDXCNop(inst) || DXIL::IsLLVMDebugCall(inst)) + if(DXIL::IsDXCNop(inst) || IsLLVMDebugCall(inst) || DXIL::IsLLVMIntrinsicCall(inst)) continue; // Stack allocations last until the end of the function diff --git a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp index c7d76402f..61e826d37 100644 --- a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp @@ -105,6 +105,12 @@ bool DXIL::IsLLVMDebugCall(const Instruction &inst) return ((inst.op == Operation::Call) && (inst.getFuncCall()->family == FunctionFamily::LLVMDbg)); } +bool DXIL::IsLLVMIntrinsicCall(const Instruction &inst) +{ + return ((inst.op == Operation::Call) && + (inst.getFuncCall()->family == FunctionFamily::LLVMInstrinsic)); +} + // true if the Value is an SSA value i.e. from an instruction, not a constant etc. bool DXIL::IsSSA(const Value *dxilValue) { @@ -1160,18 +1166,50 @@ void Program::SettleIDs() RDCASSERT(funcCallName.beginsWith(dxOpFunctionNames[(uint32_t)dxOpCode])); callFunc->family = FunctionFamily::DXOp; } - else if(funcCallName.beginsWith("llvm.dbg.")) + else if(funcCallName.beginsWith("llvm.")) { - LLVMDbgOp dbgOpCode = LLVMDbgOp::Unknown; - if(funcCallName == "llvm.dbg.declare") - dbgOpCode = LLVMDbgOp::Declare; - else if(funcCallName == "llvm.dbg.value") - dbgOpCode = LLVMDbgOp::Value; - else - RDCERR("Unknown llv.dbg call: ", funcCallName.c_str()); + LLVMIntrinsicOp intrinsicOp = LLVMIntrinsicOp::Unknown; + FunctionFamily family = FunctionFamily::Unknown; - callFunc->family = FunctionFamily::LLVMDbg; - callFunc->llvmDbgOp = dbgOpCode; + if(funcCallName.beginsWith("llvm.dbg.")) + { + family = FunctionFamily::LLVMDbg; + + if(funcCallName == "llvm.dbg.declare") + intrinsicOp = LLVMIntrinsicOp::DbgDeclare; + else if(funcCallName == "llvm.dbg.value") + intrinsicOp = LLVMIntrinsicOp::DbgValue; + else + RDCERR("Unknown llvm.dbg call: ", funcCallName.c_str()); + } + else if(funcCallName.beginsWith("llvm.lifetime.")) + { + family = FunctionFamily::LLVMInstrinsic; + + if(funcCallName == "llvm.lifetime.start") + intrinsicOp = LLVMIntrinsicOp::LifetimeStart; + else if(funcCallName == "llvm.lifetime.end") + intrinsicOp = LLVMIntrinsicOp::LifetimeEnd; + else + RDCERR("Unknown llvm.lifetime call: ", funcCallName.c_str()); + } + else if(funcCallName.beginsWith("llvm.invariant")) + { + family = FunctionFamily::LLVMInstrinsic; + + if(funcCallName == "llvm.invariant.start") + intrinsicOp = LLVMIntrinsicOp::InvariantStart; + else if(funcCallName == "llvm.invariant.end") + intrinsicOp = LLVMIntrinsicOp::InvariantEnd; + else + RDCERR("Unknown llvm.invariant call: ", funcCallName.c_str()); + } + else + { + RDCERR("Unknown llvm. call: ", funcCallName.c_str()); + } + callFunc->family = family; + callFunc->llvmIntrinsicOp = intrinsicOp; } } } @@ -4128,6 +4166,9 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection) else if(callFunc->family == FunctionFamily::LLVMDbg) { } + else if(callFunc->family == FunctionFamily::LLVMInstrinsic) + { + } else { lineStr += escapeStringIfNeeded(callFunc->name); diff --git a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp index 281a03a12..d02311339 100644 --- a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp @@ -1772,7 +1772,8 @@ rdcstr Program::GetDebugStatus() // Only support "dx.op" external functions if(f.external) { - if(!f.name.beginsWith("dx.op.") && !f.name.beginsWith("llvm.dbg.")) + if(!f.name.beginsWith("dx.op.") && !f.name.beginsWith("llvm.dbg.") && + !f.name.beginsWith("llvm.lifetime.") && !f.name.beginsWith("llvm.invariant.")) return StringFormat::Fmt("Unsupported external function '%s'", f.name.c_str()); } @@ -1983,6 +1984,14 @@ rdcstr Program::GetDebugStatus() { break; } + else if(funcCallName.beginsWith("llvm.lifetime.")) + { + break; + } + else if(funcCallName.beginsWith("llvm.invariant.")) + { + break; + } else { return StringFormat::Fmt("Unsupported function call '%s'", ToStr(callFunc->name).c_str()); diff --git a/renderdoc/driver/shaders/dxil/dxil_stringise.cpp b/renderdoc/driver/shaders/dxil/dxil_stringise.cpp index 38eb5fbb0..3591a8304 100644 --- a/renderdoc/driver/shaders/dxil/dxil_stringise.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_stringise.cpp @@ -524,13 +524,17 @@ rdcstr DoStringise(const DXIL::Type::ScalarKind &el) } template <> -rdcstr DoStringise(const DXIL::LLVMDbgOp &el) +rdcstr DoStringise(const DXIL::LLVMIntrinsicOp &el) { - BEGIN_ENUM_STRINGISE(DXIL::LLVMDbgOp); + BEGIN_ENUM_STRINGISE(DXIL::LLVMIntrinsicOp); { - STRINGISE_ENUM_CLASS(Declare); - STRINGISE_ENUM_CLASS(Value); STRINGISE_ENUM_CLASS(Unknown); + STRINGISE_ENUM_CLASS(DbgDeclare); + STRINGISE_ENUM_CLASS(DbgValue); + STRINGISE_ENUM_CLASS(LifetimeStart); + STRINGISE_ENUM_CLASS(LifetimeEnd); + STRINGISE_ENUM_CLASS(InvariantStart); + STRINGISE_ENUM_CLASS(InvariantEnd); } END_ENUM_STRINGISE(); }