2019-01-10 19:09:43 +03:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// //
|
|
|
|
// DxilAnnotateWithVirtualRegister.cpp //
|
|
|
|
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
|
|
|
// This file is distributed under the University of Illinois Open Source //
|
2020-04-22 20:00:21 +03:00
|
|
|
// This file is distributed under the University of Illinois Open Source //
|
2019-01-10 19:09:43 +03:00
|
|
|
// License. See LICENSE.TXT for details. //
|
|
|
|
// //
|
|
|
|
// Annotates the llvm instructions with a virtual register number to be used //
|
|
|
|
// during PIX debugging. //
|
|
|
|
// //
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
#include "dxc/DXIL/DxilModule.h"
|
2019-03-19 21:46:10 +03:00
|
|
|
#include "dxc/DxilPIXPasses/DxilPIXPasses.h"
|
|
|
|
#include "dxc/DxilPIXPasses/DxilPIXVirtualRegisters.h"
|
2019-01-10 19:09:43 +03:00
|
|
|
#include "dxc/Support/Global.h"
|
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
#include "llvm/IR/Constant.h"
|
|
|
|
#include "llvm/IR/Constants.h"
|
2020-04-22 20:00:21 +03:00
|
|
|
#include "llvm/IR/DebugInfo.h"
|
|
|
|
#include "llvm/IR/DebugInfoMetadata.h"
|
2019-12-02 22:22:54 +03:00
|
|
|
#include "llvm/IR/IRBuilder.h"
|
2019-01-10 19:09:43 +03:00
|
|
|
#include "llvm/IR/InstIterator.h"
|
|
|
|
#include "llvm/IR/Instruction.h"
|
|
|
|
#include "llvm/IR/Instructions.h"
|
2020-04-22 20:00:21 +03:00
|
|
|
#include "llvm/IR/IntrinsicInst.h"
|
2019-01-10 19:09:43 +03:00
|
|
|
#include "llvm/IR/Module.h"
|
2019-04-19 23:40:27 +03:00
|
|
|
#include "llvm/IR/ModuleSlotTracker.h"
|
2019-01-10 19:09:43 +03:00
|
|
|
#include "llvm/IR/Type.h"
|
|
|
|
#include "llvm/Pass.h"
|
|
|
|
#include "llvm/Support/Casting.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
|
|
|
|
#define DEBUG_TYPE "dxil-annotate-with-virtual-regs"
|
|
|
|
|
2020-04-22 20:00:21 +03:00
|
|
|
uint32_t CountStructMembers(llvm::Type const *pType) {
|
|
|
|
uint32_t Count = 0;
|
|
|
|
|
|
|
|
if (auto *ST = llvm::dyn_cast<llvm::StructType>(pType)) {
|
|
|
|
for (auto &El : ST->elements()) {
|
|
|
|
Count += CountStructMembers(El);
|
|
|
|
}
|
|
|
|
} else if (auto *AT = llvm::dyn_cast<llvm::ArrayType>(pType)) {
|
|
|
|
Count = CountStructMembers(AT->getArrayElementType()) *
|
|
|
|
AT->getArrayNumElements();
|
|
|
|
} else {
|
|
|
|
Count = 1;
|
|
|
|
}
|
|
|
|
return Count;
|
|
|
|
}
|
|
|
|
|
2019-01-10 19:09:43 +03:00
|
|
|
namespace {
|
|
|
|
using namespace pix_dxil;
|
|
|
|
|
2020-04-22 20:00:21 +03:00
|
|
|
static bool IsInstrumentableFundamentalType(llvm::Type *pAllocaTy) {
|
|
|
|
return
|
|
|
|
pAllocaTy->isFloatingPointTy() || pAllocaTy->isIntegerTy();
|
|
|
|
}
|
|
|
|
|
2019-01-10 19:09:43 +03:00
|
|
|
class DxilAnnotateWithVirtualRegister : public llvm::ModulePass {
|
|
|
|
public:
|
|
|
|
static char ID;
|
|
|
|
DxilAnnotateWithVirtualRegister() : llvm::ModulePass(ID) {}
|
|
|
|
|
|
|
|
bool runOnModule(llvm::Module &M) override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
void AnnotateValues(llvm::Instruction *pI);
|
|
|
|
void AnnotateStore(llvm::Instruction *pI);
|
2019-12-02 22:22:54 +03:00
|
|
|
bool IsAllocaRegisterWrite(llvm::Value *V, llvm::AllocaInst **pAI,
|
|
|
|
llvm::Value **pIdx);
|
2019-01-10 19:09:43 +03:00
|
|
|
void AnnotateAlloca(llvm::AllocaInst *pAlloca);
|
|
|
|
void AnnotateGeneric(llvm::Instruction *pI);
|
|
|
|
void AssignNewDxilRegister(llvm::Instruction *pI);
|
2020-04-22 20:00:21 +03:00
|
|
|
void PrintSingleRegister(llvm::Instruction* pI, uint32_t Register);
|
|
|
|
void AssignNewAllocaRegister(llvm::AllocaInst* pAlloca, std::uint32_t C);
|
|
|
|
void PrintAllocaMember(llvm::AllocaInst* pAlloca, uint32_t Base, uint32_t Offset);
|
2019-01-10 19:09:43 +03:00
|
|
|
|
2020-04-22 20:00:21 +03:00
|
|
|
hlsl::DxilModule* m_DM;
|
2019-01-10 19:09:43 +03:00
|
|
|
std::uint32_t m_uVReg;
|
2019-12-02 22:22:54 +03:00
|
|
|
std::unique_ptr<llvm::ModuleSlotTracker> m_MST;
|
2019-01-10 19:09:43 +03:00
|
|
|
void Init(llvm::Module &M) {
|
|
|
|
m_DM = &M.GetOrCreateDxilModule();
|
|
|
|
m_uVReg = 0;
|
2019-04-19 23:40:27 +03:00
|
|
|
m_MST.reset(new llvm::ModuleSlotTracker(&M));
|
|
|
|
m_MST->incorporateFunction(*m_DM->GetEntryFunction());
|
2019-01-10 19:09:43 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
char DxilAnnotateWithVirtualRegister::ID = 0;
|
|
|
|
|
|
|
|
bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
|
|
|
|
Init(M);
|
|
|
|
if (m_DM == nullptr) {
|
|
|
|
return false;
|
|
|
|
}
|
2020-04-22 20:00:21 +03:00
|
|
|
unsigned int Major = 0;
|
|
|
|
unsigned int Minor = 0;
|
|
|
|
m_DM->GetDxilVersion(Major, Minor);
|
2020-06-25 11:57:41 +03:00
|
|
|
if (Major < 6 || (Major == 6 && Minor <= 4)) {
|
2020-04-22 20:00:21 +03:00
|
|
|
m_DM->SetValidatorVersion(1, 4);
|
|
|
|
}
|
2019-01-10 19:09:43 +03:00
|
|
|
|
2019-01-29 16:42:54 +03:00
|
|
|
std::uint32_t InstNum = 0;
|
|
|
|
for (llvm::Instruction &I : llvm::inst_range(m_DM->GetEntryFunction())) {
|
2020-04-22 20:00:21 +03:00
|
|
|
if (!llvm::isa<llvm::DbgDeclareInst>(&I)) {
|
2020-02-26 04:50:23 +03:00
|
|
|
pix_dxil::PixDxilInstNum::AddMD(M.getContext(), &I, InstNum++);
|
|
|
|
}
|
2019-03-19 21:46:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (OSOverride != nullptr) {
|
2019-04-19 23:40:27 +03:00
|
|
|
*OSOverride << "\nInstructionCount:" << InstNum << "\n";
|
2019-03-19 21:46:10 +03:00
|
|
|
}
|
|
|
|
|
2019-04-19 23:40:27 +03:00
|
|
|
if (OSOverride != nullptr) {
|
|
|
|
*OSOverride << "\nEnd - instruction ID to line\n";
|
|
|
|
}
|
2019-03-19 21:46:10 +03:00
|
|
|
|
|
|
|
if (OSOverride != nullptr) {
|
|
|
|
*OSOverride << "\nBegin - dxil values to virtual register mapping\n";
|
2019-01-29 16:42:54 +03:00
|
|
|
}
|
|
|
|
|
2019-01-10 19:09:43 +03:00
|
|
|
for (llvm::Instruction &I : llvm::inst_range(m_DM->GetEntryFunction())) {
|
|
|
|
AnnotateValues(&I);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (llvm::Instruction &I : llvm::inst_range(m_DM->GetEntryFunction())) {
|
|
|
|
AnnotateStore(&I);
|
|
|
|
}
|
|
|
|
|
2019-01-10 23:48:29 +03:00
|
|
|
if (OSOverride != nullptr) {
|
|
|
|
*OSOverride << "\nEnd - dxil values to virtual register mapping\n";
|
|
|
|
}
|
|
|
|
|
2019-01-10 19:09:43 +03:00
|
|
|
m_DM = nullptr;
|
|
|
|
return m_uVReg > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DxilAnnotateWithVirtualRegister::AnnotateValues(llvm::Instruction *pI) {
|
2020-04-22 20:00:21 +03:00
|
|
|
if (auto* pAlloca = llvm::dyn_cast<llvm::AllocaInst>(pI)) {
|
2019-01-10 19:09:43 +03:00
|
|
|
AnnotateAlloca(pAlloca);
|
2020-04-22 20:00:21 +03:00
|
|
|
} else if (!pI->getType()->isPointerTy()) {
|
|
|
|
AnnotateGeneric(pI);
|
2019-01-10 19:09:43 +03:00
|
|
|
} else if (!pI->getType()->isVoidTy()) {
|
|
|
|
AnnotateGeneric(pI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DxilAnnotateWithVirtualRegister::AnnotateStore(llvm::Instruction *pI) {
|
|
|
|
auto *pSt = llvm::dyn_cast<llvm::StoreInst>(pI);
|
|
|
|
if (pSt == nullptr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::AllocaInst *Alloca;
|
|
|
|
llvm::Value *Index;
|
|
|
|
if (!IsAllocaRegisterWrite(pSt->getPointerOperand(), &Alloca, &Index)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::MDNode *AllocaReg = Alloca->getMetadata(PixAllocaReg::MDName);
|
|
|
|
if (AllocaReg == nullptr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
PixAllocaRegWrite::AddMD(m_DM->GetCtx(), pSt, AllocaReg, Index);
|
|
|
|
}
|
|
|
|
|
2020-04-22 20:00:21 +03:00
|
|
|
static uint32_t GetStructOffset(
|
|
|
|
llvm::GetElementPtrInst* pGEP,
|
|
|
|
uint32_t& GEPOperandIndex,
|
|
|
|
llvm::Type* pElementType)
|
|
|
|
{
|
|
|
|
if (IsInstrumentableFundamentalType(pElementType)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (auto* pArray = llvm::dyn_cast<llvm::ArrayType>(pElementType))
|
|
|
|
{
|
|
|
|
// 1D-array example:
|
|
|
|
//
|
|
|
|
// When referring to the zeroth member of the array in this struct:
|
|
|
|
// struct smallPayload {
|
|
|
|
// uint32_t Array[2];
|
|
|
|
// };
|
|
|
|
// getelementptr inbounds% struct.smallPayload, % struct.smallPayload*% p,
|
|
|
|
// i32 0, i32 0, i32 0 The zeros above are:
|
|
|
|
// -The zeroth element in the array pointed to (so, the actual struct)
|
|
|
|
// -The zeroth element in the struct (which is the array)
|
|
|
|
// -The zeroth element in that array
|
|
|
|
|
|
|
|
auto* pArrayIndex =
|
|
|
|
llvm::dyn_cast<llvm::ConstantInt>(pGEP->getOperand(GEPOperandIndex++));
|
|
|
|
|
|
|
|
if (pArrayIndex == nullptr) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t ArrayIndex = pArrayIndex->getLimitedValue();
|
|
|
|
auto pArrayElementType = pArray->getArrayElementType();
|
|
|
|
uint32_t MemberIndex = ArrayIndex * CountStructMembers(pArrayElementType);
|
|
|
|
return MemberIndex + GetStructOffset(pGEP, GEPOperandIndex, pArrayElementType);
|
|
|
|
}
|
|
|
|
else if (auto* pStruct = llvm::dyn_cast<llvm::StructType>(pElementType))
|
|
|
|
{
|
|
|
|
DXASSERT(GEPOperandIndex < pGEP->getNumOperands(), "Unexpectedly read too many GetElementPtrInst operands");
|
|
|
|
|
|
|
|
auto* pMemberIndex =
|
|
|
|
llvm::dyn_cast<llvm::ConstantInt>(pGEP->getOperand(GEPOperandIndex++));
|
|
|
|
|
|
|
|
if (pMemberIndex == nullptr) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t MemberIndex = pMemberIndex->getLimitedValue();
|
|
|
|
|
|
|
|
uint32_t MemberOffset = 0;
|
|
|
|
for (uint32_t i = 0; i < MemberIndex; ++i)
|
|
|
|
{
|
|
|
|
MemberOffset += CountStructMembers(pStruct->getElementType(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
return MemberOffset +
|
|
|
|
GetStructOffset(pGEP, GEPOperandIndex, pStruct->getElementType(MemberIndex));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-12-02 22:22:54 +03:00
|
|
|
bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite(
|
|
|
|
llvm::Value *V, llvm::AllocaInst **pAI, llvm::Value **pIdx) {
|
2019-01-10 19:09:43 +03:00
|
|
|
llvm::IRBuilder<> B(m_DM->GetCtx());
|
|
|
|
|
|
|
|
*pAI = nullptr;
|
|
|
|
*pIdx = nullptr;
|
|
|
|
|
|
|
|
if (auto *pGEP = llvm::dyn_cast<llvm::GetElementPtrInst>(V)) {
|
2020-04-22 20:00:21 +03:00
|
|
|
uint32_t precedingMemberCount = 0;
|
2019-01-10 19:09:43 +03:00
|
|
|
auto *Alloca = llvm::dyn_cast<llvm::AllocaInst>(pGEP->getPointerOperand());
|
|
|
|
if (Alloca == nullptr) {
|
2020-04-22 20:00:21 +03:00
|
|
|
// In the case of vector types (floatN, matrixNxM), the pointer operand will actually
|
|
|
|
// point to another element pointer instruction. But this isn't a recursive thing-
|
|
|
|
// we only need to check these two levels.
|
|
|
|
if (auto* pPointerGEP = llvm::dyn_cast<llvm::GetElementPtrInst>(pGEP->getPointerOperand())) {
|
|
|
|
Alloca =
|
|
|
|
llvm::dyn_cast<llvm::AllocaInst>(pPointerGEP->getPointerOperand());
|
|
|
|
if (Alloca == nullptr) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// And of course the member we're after might not be at the beginning of the struct:
|
|
|
|
auto* pStructType = llvm::dyn_cast<llvm::StructType>(pPointerGEP->getPointerOperandType()->getPointerElementType());
|
|
|
|
auto* pStructMember = llvm::dyn_cast<llvm::ConstantInt>(pPointerGEP->getOperand(2));
|
|
|
|
uint64_t memberIndex = pStructMember->getLimitedValue();
|
|
|
|
for(uint64_t i = 0; i < memberIndex; ++i)
|
|
|
|
{
|
|
|
|
precedingMemberCount += CountStructMembers(pStructType->getStructElementType(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2019-01-10 19:09:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-04-22 20:00:21 +03:00
|
|
|
// Deref pointer type to get struct type:
|
|
|
|
llvm::Type *pStructType = pGEP->getPointerOperandType();
|
|
|
|
pStructType = pStructType->getContainedType(0);
|
2019-12-02 22:22:54 +03:00
|
|
|
|
2020-04-22 20:00:21 +03:00
|
|
|
// The 1th operand is an index into the array of the above type. In DXIL derived from HLSL,
|
|
|
|
// we always expect this to be 0 (since llvm structs are only used for single-valued
|
|
|
|
// objects in HLSL, such as the amplification-to-mesh or TraceRays payloads).
|
|
|
|
uint32_t GEPOperandIndex = 1;
|
|
|
|
auto *pBaseArrayIndex =
|
|
|
|
llvm::dyn_cast<llvm::ConstantInt>(pGEP->getOperand(GEPOperandIndex++));
|
2020-06-25 11:57:41 +03:00
|
|
|
DXASSERT_LOCALVAR(pBaseArrayIndex, pBaseArrayIndex != nullptr,
|
|
|
|
"null base array index pointer");
|
|
|
|
DXASSERT_LOCALVAR(pBaseArrayIndex, pBaseArrayIndex->getLimitedValue() == 0,
|
|
|
|
"unexpected >0 array index");
|
2020-04-22 20:00:21 +03:00
|
|
|
|
|
|
|
// From here on, the indices always come in groups: first, the type
|
|
|
|
// referenced in the current struct. If that type is an (n-dimensional)
|
|
|
|
// array, then there follow n indices.
|
|
|
|
|
|
|
|
|
|
|
|
auto offset = GetStructOffset(
|
|
|
|
pGEP,
|
|
|
|
GEPOperandIndex,
|
|
|
|
pStructType);
|
|
|
|
|
|
|
|
llvm::Value* IndexValue = B.getInt32(offset + precedingMemberCount);
|
|
|
|
|
|
|
|
if (IndexValue != nullptr)
|
|
|
|
{
|
|
|
|
*pAI = Alloca;
|
|
|
|
*pIdx = IndexValue;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2019-01-10 19:09:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (auto *pAlloca = llvm::dyn_cast<llvm::AllocaInst>(V)) {
|
|
|
|
llvm::Type *pAllocaTy = pAlloca->getType()->getElementType();
|
2020-04-22 20:00:21 +03:00
|
|
|
if (!IsInstrumentableFundamentalType(pAllocaTy)) {
|
2019-01-10 19:09:43 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pAI = pAlloca;
|
|
|
|
*pIdx = B.getInt32(0);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-12-02 22:22:54 +03:00
|
|
|
void DxilAnnotateWithVirtualRegister::AnnotateAlloca(
|
|
|
|
llvm::AllocaInst *pAlloca) {
|
2019-01-10 19:09:43 +03:00
|
|
|
llvm::Type *pAllocaTy = pAlloca->getType()->getElementType();
|
2020-04-22 20:00:21 +03:00
|
|
|
if (IsInstrumentableFundamentalType(pAllocaTy)) {
|
2019-01-10 19:09:43 +03:00
|
|
|
AssignNewAllocaRegister(pAlloca, 1);
|
|
|
|
} else if (auto *AT = llvm::dyn_cast<llvm::ArrayType>(pAllocaTy)) {
|
|
|
|
AssignNewAllocaRegister(pAlloca, AT->getNumElements());
|
2020-04-22 20:00:21 +03:00
|
|
|
} else if (auto *ST = llvm::dyn_cast<llvm::StructType>(pAllocaTy)) {
|
|
|
|
AssignNewAllocaRegister(pAlloca, CountStructMembers(ST));
|
2019-01-10 19:09:43 +03:00
|
|
|
} else {
|
|
|
|
DXASSERT_ARGS(false, "Unhandled alloca kind: %d", pAllocaTy->getTypeID());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DxilAnnotateWithVirtualRegister::AnnotateGeneric(llvm::Instruction *pI) {
|
2020-04-22 20:00:21 +03:00
|
|
|
if (auto *GEP = llvm::dyn_cast<llvm::GetElementPtrInst>(pI)) {
|
|
|
|
// https://llvm.org/docs/LangRef.html#getelementptr-instruction
|
|
|
|
DXASSERT(!GEP->getOperand(1)->getType()->isVectorTy(),
|
|
|
|
"struct vectors not supported");
|
|
|
|
llvm::AllocaInst *StructAlloca =
|
|
|
|
llvm::dyn_cast<llvm::AllocaInst>(GEP->getOperand(0));
|
|
|
|
if (StructAlloca != nullptr) {
|
|
|
|
// This is the case of a pointer to a struct member.
|
|
|
|
// We treat it as an alias of the actual member in the alloca.
|
|
|
|
std::uint32_t baseStructRegNum = 0;
|
|
|
|
std::uint32_t regSize = 0;
|
|
|
|
if (pix_dxil::PixAllocaReg::FromInst(StructAlloca, &baseStructRegNum, & regSize)) {
|
|
|
|
llvm::ConstantInt *OffsetAsInt =
|
|
|
|
llvm::dyn_cast<llvm::ConstantInt>(GEP->getOperand(2));
|
2020-04-23 00:40:08 +03:00
|
|
|
if (OffsetAsInt != nullptr)
|
|
|
|
{
|
|
|
|
std::uint32_t Offset = static_cast<std::uint32_t>(
|
2020-04-22 20:00:21 +03:00
|
|
|
OffsetAsInt->getValue().getLimitedValue());
|
2020-04-23 00:40:08 +03:00
|
|
|
DXASSERT(Offset < regSize,
|
|
|
|
"Structure member offset out of expected range");
|
|
|
|
PixDxilReg::AddMD(m_DM->GetCtx(), pI, baseStructRegNum + Offset);
|
|
|
|
}
|
2020-04-22 20:00:21 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!IsInstrumentableFundamentalType(pI->getType())) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
AssignNewDxilRegister(pI);
|
2019-01-10 19:09:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 22:22:54 +03:00
|
|
|
void DxilAnnotateWithVirtualRegister::AssignNewDxilRegister(
|
|
|
|
llvm::Instruction *pI) {
|
2019-01-10 19:09:43 +03:00
|
|
|
PixDxilReg::AddMD(m_DM->GetCtx(), pI, m_uVReg);
|
2020-04-22 20:00:21 +03:00
|
|
|
PrintSingleRegister(pI, m_uVReg);
|
2019-01-10 19:09:43 +03:00
|
|
|
m_uVReg++;
|
|
|
|
}
|
|
|
|
|
2019-12-02 22:22:54 +03:00
|
|
|
void DxilAnnotateWithVirtualRegister::AssignNewAllocaRegister(
|
|
|
|
llvm::AllocaInst *pAlloca, std::uint32_t C) {
|
2019-01-10 19:09:43 +03:00
|
|
|
PixAllocaReg::AddMD(m_DM->GetCtx(), pAlloca, m_uVReg, C);
|
2020-04-22 20:00:21 +03:00
|
|
|
PrintAllocaMember(pAlloca, m_uVReg, C);
|
|
|
|
m_uVReg += C;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DxilAnnotateWithVirtualRegister::PrintSingleRegister(
|
|
|
|
llvm::Instruction* pI, uint32_t Register) {
|
|
|
|
if (OSOverride != nullptr) {
|
|
|
|
static constexpr bool DontPrintType = false;
|
|
|
|
pI->printAsOperand(*OSOverride, DontPrintType, *m_MST.get());
|
|
|
|
*OSOverride << " dxil " << Register << "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DxilAnnotateWithVirtualRegister::PrintAllocaMember(llvm::AllocaInst* pAlloca,
|
|
|
|
uint32_t Base,
|
|
|
|
uint32_t Offset) {
|
2019-01-10 19:09:43 +03:00
|
|
|
if (OSOverride != nullptr) {
|
|
|
|
static constexpr bool DontPrintType = false;
|
2019-04-19 23:40:27 +03:00
|
|
|
pAlloca->printAsOperand(*OSOverride, DontPrintType, *m_MST.get());
|
2020-04-22 20:00:21 +03:00
|
|
|
*OSOverride << " alloca " << Base << " " << Offset << "\n";
|
2019-01-10 19:09:43 +03:00
|
|
|
}
|
|
|
|
}
|
2020-04-22 20:00:21 +03:00
|
|
|
|
2019-12-02 22:22:54 +03:00
|
|
|
} // namespace
|
2019-01-10 19:09:43 +03:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2019-12-02 22:22:54 +03:00
|
|
|
INITIALIZE_PASS(DxilAnnotateWithVirtualRegister, DEBUG_TYPE,
|
|
|
|
"Annotates each instruction in the DXIL module with a virtual "
|
|
|
|
"register number",
|
|
|
|
false, false)
|
2019-01-10 19:09:43 +03:00
|
|
|
|
|
|
|
ModulePass *llvm::createDxilAnnotateWithVirtualRegisterPass() {
|
|
|
|
return new DxilAnnotateWithVirtualRegister();
|
|
|
|
}
|