mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-29 01:46:38 +00:00
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
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user