Skip to content

Commit

Permalink
DXIL support for LLVM lifetime, invariant LLVM intrinsics
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Zorro666 committed Nov 21, 2024
1 parent 8019491 commit 7136385
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 27 deletions.
16 changes: 11 additions & 5 deletions renderdoc/driver/shaders/dxil/dxil_bytecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1397,7 +1402,7 @@ struct Function : public Value
AttachedMetadata attachedMeta;

FunctionFamily family = FunctionFamily::Unknown;
LLVMDbgOp llvmDbgOp = LLVMDbgOp::Unknown;
LLVMIntrinsicOp llvmIntrinsicOp = LLVMIntrinsicOp::Unknown;
};

class LLVMOrderAccumulator
Expand Down Expand Up @@ -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);

Expand All @@ -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);
15 changes: 8 additions & 7 deletions renderdoc/driver/shaders/dxil/dxil_debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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;
};
}
}
Expand Down Expand Up @@ -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
Expand Down
61 changes: 51 additions & 10 deletions renderdoc/driver/shaders/dxil/dxil_disassemble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;

if(funcCallName.beginsWith("llvm.dbg."))
{
family = FunctionFamily::LLVMDbg;

callFunc->family = FunctionFamily::LLVMDbg;
callFunc->llvmDbgOp = dbgOpCode;
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;
}
}
}
Expand Down Expand Up @@ -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);
Expand Down
11 changes: 10 additions & 1 deletion renderdoc/driver/shaders/dxil/dxil_reflect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

Expand Down Expand Up @@ -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());
Expand Down
12 changes: 8 additions & 4 deletions renderdoc/driver/shaders/dxil/dxil_stringise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down

0 comments on commit 7136385

Please sign in to comment.