12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034 |
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // ViewIdAnalysis.cpp //
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- // This file is distributed under the University of Illinois Open Source //
- // License. See LICENSE.TXT for details. //
- // //
- ///////////////////////////////////////////////////////////////////////////////
- #include "dxc/HLSL/ComputeViewIdState.h"
- #include "dxc/Support/Global.h"
- #include "dxc/HLSL/DxilModule.h"
- #include "dxc/HLSL/DxilOperations.h"
- #include "dxc/HLSL/DxilInstructions.h"
- #include "llvm/IR/LLVMContext.h"
- #include "llvm/IR/Module.h"
- #include "llvm/IR/Function.h"
- #include "llvm/IR/Operator.h"
- #include "llvm/Pass.h"
- #include "llvm/IR/LegacyPassManager.h"
- #include "llvm/Support/Debug.h"
- #include "llvm/IR/CFG.h"
- #include "llvm/Analysis/CallGraph.h"
- #include <algorithm>
- using namespace llvm;
- using namespace llvm::legacy;
- using namespace hlsl;
- using llvm::legacy::PassManager;
- using llvm::legacy::FunctionPassManager;
- using std::vector;
- using std::unordered_set;
- using std::unordered_map;
- #define DXILVIEWID_DBG 0
- #define DEBUG_TYPE "viewid"
- DxilViewIdState::DxilViewIdState(DxilModule *pDxilModule) : m_pModule(pDxilModule) {}
- unsigned DxilViewIdState::getNumInputSigScalars() const { return m_NumInputSigScalars; }
- unsigned DxilViewIdState::getNumOutputSigScalars(unsigned StreamId) const { return m_NumOutputSigScalars[StreamId]; }
- unsigned DxilViewIdState::getNumPCSigScalars() const { return m_NumPCSigScalars; }
- const DxilViewIdState::OutputsDependentOnViewIdType &DxilViewIdState::getOutputsDependentOnViewId(unsigned StreamId) const { return m_OutputsDependentOnViewId[StreamId]; }
- const DxilViewIdState::OutputsDependentOnViewIdType &DxilViewIdState::getPCOutputsDependentOnViewId() const { return m_PCOutputsDependentOnViewId; }
- const DxilViewIdState::InputsContributingToOutputType &DxilViewIdState::getInputsContributingToOutputs(unsigned StreamId) const { return m_InputsContributingToOutputs[StreamId]; }
- const DxilViewIdState::InputsContributingToOutputType &DxilViewIdState::getInputsContributingToPCOutputs() const { return m_InputsContributingToPCOutputs; }
- const DxilViewIdState::InputsContributingToOutputType &DxilViewIdState::getPCInputsContributingToOutputs() const { return m_PCInputsContributingToOutputs; }
- void DxilViewIdState::Compute() {
- Clear();
- const ShaderModel *pSM = m_pModule->GetShaderModel();
- m_bUsesViewId = m_pModule->m_ShaderFlags.GetViewID();
- // 1. Traverse signature MD to determine max packed location.
- DetermineMaxPackedLocation(m_pModule->GetInputSignature(), &m_NumInputSigScalars, 1);
- DetermineMaxPackedLocation(m_pModule->GetOutputSignature(), &m_NumOutputSigScalars[0], pSM->IsGS() ? kNumStreams : 1);
- DetermineMaxPackedLocation(m_pModule->GetPatchConstantSignature(), &m_NumPCSigScalars, 1);
- // 2. Collect sets of functions reachable from main and pc entries.
- CallGraphAnalysis CGA;
- CallGraph CG = CGA.run(m_pModule->GetModule());
- m_Entry.pEntryFunc = m_pModule->GetEntryFunction();
- m_PCEntry.pEntryFunc = m_pModule->GetPatchConstantFunction();
- ComputeReachableFunctionsRec(CG, CG[m_Entry.pEntryFunc], m_Entry.Functions);
- if (m_PCEntry.pEntryFunc) {
- DXASSERT_NOMSG(pSM->IsHS());
- ComputeReachableFunctionsRec(CG, CG[m_PCEntry.pEntryFunc], m_PCEntry.Functions);
- }
- // 3. Determine shape components that are dynamically accesses and collect all sig outputs.
- AnalyzeFunctions(m_Entry);
- if (m_PCEntry.pEntryFunc) {
- AnalyzeFunctions(m_PCEntry);
- }
- // 4. Collect sets of values contributing to outputs.
- CollectValuesContributingToOutputs(m_Entry);
- if (m_PCEntry.pEntryFunc) {
- CollectValuesContributingToOutputs(m_PCEntry);
- }
- // 5. Construct dependency sets.
- for (unsigned StreamId = 0; StreamId < (pSM->IsGS() ? kNumStreams : 1u); StreamId++) {
- CreateViewIdSets(m_Entry.ContributingInstructions[StreamId],
- m_OutputsDependentOnViewId[StreamId],
- m_InputsContributingToOutputs[StreamId], false);
- }
- if (pSM->IsHS()) {
- CreateViewIdSets(m_PCEntry.ContributingInstructions[0],
- m_PCOutputsDependentOnViewId,
- m_InputsContributingToPCOutputs, true);
- } else if (pSM->IsDS()) {
- OutputsDependentOnViewIdType OutputsDependentOnViewId;
- CreateViewIdSets(m_Entry.ContributingInstructions[0],
- OutputsDependentOnViewId,
- m_PCInputsContributingToOutputs, true);
- DXASSERT_NOMSG(OutputsDependentOnViewId == m_OutputsDependentOnViewId[0]);
- }
- // 6. Update dynamically indexed input/output component masks.
- UpdateDynamicIndexUsageState();
- #if DXILVIEWID_DBG
- PrintSets(dbgs());
- #endif
- }
- void DxilViewIdState::PrintSets(llvm::raw_ostream &OS) {
- const ShaderModel *pSM = m_pModule->GetShaderModel();
- OS << "ViewId state: \n";
- if (!pSM->IsGS()) {
- OS << "Number of inputs: " << m_NumInputSigScalars <<
- ", outputs: " << m_NumOutputSigScalars[0] <<
- ", patchconst: " << m_NumPCSigScalars << "\n";
- } else {
- OS << "Number of inputs: " << m_NumInputSigScalars <<
- ", outputs: { " << m_NumOutputSigScalars[0] << ", " << m_NumOutputSigScalars[1] << ", " <<
- m_NumOutputSigScalars[2] << ", " << m_NumOutputSigScalars[3] << " }" <<
- ", patchconst: " << m_NumPCSigScalars << "\n";
- }
- if (!pSM->IsGS()) {
- PrintOutputsDependentOnViewId(OS, "Outputs", m_NumOutputSigScalars[0], m_OutputsDependentOnViewId[0]);
- } else {
- PrintOutputsDependentOnViewId(OS, "Outputs for Stream0", m_NumOutputSigScalars[0], m_OutputsDependentOnViewId[0]);
- PrintOutputsDependentOnViewId(OS, "Outputs for Stream1", m_NumOutputSigScalars[1], m_OutputsDependentOnViewId[1]);
- PrintOutputsDependentOnViewId(OS, "Outputs for Stream2", m_NumOutputSigScalars[2], m_OutputsDependentOnViewId[2]);
- PrintOutputsDependentOnViewId(OS, "Outputs for Stream3", m_NumOutputSigScalars[3], m_OutputsDependentOnViewId[3]);
- }
- if (pSM->IsHS()) {
- PrintOutputsDependentOnViewId(OS, "PCOutputs", m_NumPCSigScalars, m_PCOutputsDependentOnViewId);
- }
- if (!pSM->IsGS()) {
- PrintInputsContributingToOutputs(OS, "Inputs", "Outputs", m_InputsContributingToOutputs[0]);
- } else {
- PrintInputsContributingToOutputs(OS, "Inputs", "Outputs for Stream0", m_InputsContributingToOutputs[0]);
- PrintInputsContributingToOutputs(OS, "Inputs", "Outputs for Stream1", m_InputsContributingToOutputs[1]);
- PrintInputsContributingToOutputs(OS, "Inputs", "Outputs for Stream2", m_InputsContributingToOutputs[2]);
- PrintInputsContributingToOutputs(OS, "Inputs", "Outputs for Stream3", m_InputsContributingToOutputs[3]);
- }
- if (pSM->IsHS()) {
- PrintInputsContributingToOutputs(OS, "Inputs", "PCOutputs", m_InputsContributingToPCOutputs);
- } else if (pSM->IsDS()) {
- PrintInputsContributingToOutputs(OS, "PCInputs", "Outputs", m_PCInputsContributingToOutputs);
- }
- OS << "\n";
- }
- void DxilViewIdState::PrintOutputsDependentOnViewId(llvm::raw_ostream &OS,
- llvm::StringRef SetName,
- unsigned NumOutputs,
- const OutputsDependentOnViewIdType &OutputsDependentOnViewId) {
- OS << SetName << " dependent on ViewId: { ";
- bool bFirst = true;
- for (unsigned i = 0; i < NumOutputs; i++) {
- if (OutputsDependentOnViewId[i]) {
- if (!bFirst) OS << ", ";
- OS << i;
- bFirst = false;
- }
- }
- OS << " }\n";
- }
- void DxilViewIdState::PrintInputsContributingToOutputs(llvm::raw_ostream &OS,
- llvm::StringRef InputSetName,
- llvm::StringRef OutputSetName,
- const InputsContributingToOutputType &InputsContributingToOutputs) {
- OS << InputSetName << " contributing to computation of " << OutputSetName << ":\n";
- for (auto &it : InputsContributingToOutputs) {
- unsigned outIdx = it.first;
- auto &Inputs = it.second;
- OS << "output " << outIdx << " depends on inputs: { ";
- bool bFirst = true;
- for (unsigned i : Inputs) {
- if (!bFirst) OS << ", ";
- OS << i;
- bFirst = false;
- }
- OS << " }\n";
- }
- }
- void DxilViewIdState::Clear() {
- m_bUsesViewId = false;
- m_NumInputSigScalars = 0;
- for (unsigned i = 0; i < kNumStreams; i++) {
- m_NumOutputSigScalars[i] = 0;
- m_OutputsDependentOnViewId[i].reset();
- m_InputsContributingToOutputs[i].clear();
- }
- m_NumPCSigScalars = 0;
- m_InpSigDynIdxElems.clear();
- m_OutSigDynIdxElems.clear();
- m_PCSigDynIdxElems.clear();
- m_PCOutputsDependentOnViewId.reset();
- m_InputsContributingToPCOutputs.clear();
- m_PCInputsContributingToOutputs.clear();
- m_Entry.Clear();
- m_PCEntry.Clear();
- m_FuncInfo.clear();
- m_ReachingDeclsCache.clear();
- m_SerializedState.clear();
- }
- void DxilViewIdState::EntryInfo::Clear() {
- pEntryFunc = nullptr;
- Functions.clear();
- Outputs.clear();
- for (unsigned i = 0; i < kNumStreams; i++)
- ContributingInstructions[i].clear();
- }
- void DxilViewIdState::FuncInfo::Clear() {
- Returns.clear();
- CtrlDep.Clear();
- pDomTree.reset();
- }
- void DxilViewIdState::DetermineMaxPackedLocation(DxilSignature &DxilSig,
- unsigned *pMaxSigLoc,
- unsigned NumStreams) {
- if (&DxilSig == nullptr) return;
- DXASSERT_NOMSG(NumStreams == 1 || NumStreams == kNumStreams);
- for (unsigned i = 0; i < NumStreams; i++) {
- pMaxSigLoc[i] = 0;
- }
- for (auto &E : DxilSig.GetElements()) {
- if (E->GetStartRow() == Semantic::kUndefinedRow) continue;
- unsigned StreamId = E->GetOutputStream();
- unsigned endLoc = GetLinearIndex(*E, E->GetRows() - 1, E->GetCols() - 1);
- pMaxSigLoc[StreamId] = std::max(pMaxSigLoc[StreamId], endLoc + 1);
- E->GetCols();
- }
- }
- void DxilViewIdState::ComputeReachableFunctionsRec(CallGraph &CG, CallGraphNode *pNode, FunctionSetType &FuncSet) {
- Function *F = pNode->getFunction();
- // Accumulate only functions with bodies.
- if (F->empty()) return;
- auto itIns = FuncSet.emplace(F);
- DXASSERT_NOMSG(itIns.second);
- for (auto it = pNode->begin(), itEnd = pNode->end(); it != itEnd; ++it) {
- CallGraphNode *pSuccNode = it->second;
- ComputeReachableFunctionsRec(CG, pSuccNode, FuncSet);
- }
- }
- static bool GetUnsignedVal(Value *V, uint32_t *pValue) {
- ConstantInt *CI = dyn_cast<ConstantInt>(V);
- if (!CI) return false;
- uint64_t u = CI->getZExtValue();
- if (u > UINT32_MAX) return false;
- *pValue = (uint32_t)u;
- return true;
- }
- void DxilViewIdState::AnalyzeFunctions(EntryInfo &Entry) {
- for (auto *F : Entry.Functions) {
- DXASSERT_NOMSG(!F->empty());
- auto itFI = m_FuncInfo.find(F);
- FuncInfo *pFuncInfo = nullptr;
- if (itFI != m_FuncInfo.end()) {
- pFuncInfo = itFI->second.get();
- } else {
- m_FuncInfo[F] = make_unique<FuncInfo>();
- pFuncInfo = m_FuncInfo[F].get();
- }
- for (auto itBB = F->begin(), endBB = F->end(); itBB != endBB; ++itBB) {
- BasicBlock *BB = itBB;
- for (auto itInst = BB->begin(), endInst = BB->end(); itInst != endInst; ++itInst) {
- if (ReturnInst *RI = dyn_cast<ReturnInst>(itInst)) {
- pFuncInfo->Returns.emplace(RI);
- continue;
- }
- CallInst *CI = dyn_cast<CallInst>(itInst);
- if (!CI) continue;
- DynamicallyIndexedElemsType *pDynIdxElems = nullptr;
- int row = Semantic::kUndefinedRow;
- unsigned id, col;
- if (DxilInst_LoadInput LI = DxilInst_LoadInput(CI)) {
- pDynIdxElems = &m_InpSigDynIdxElems;
- IFTBOOL(GetUnsignedVal(LI.get_inputSigId(), &id), DXC_E_GENERAL_INTERNAL_ERROR);
- GetUnsignedVal(LI.get_rowIndex(), (uint32_t*)&row);
- IFTBOOL(GetUnsignedVal(LI.get_colIndex(), &col), DXC_E_GENERAL_INTERNAL_ERROR);
- } else if (DxilInst_StoreOutput SO = DxilInst_StoreOutput(CI)) {
- pDynIdxElems = &m_OutSigDynIdxElems;
- IFTBOOL(GetUnsignedVal(SO.get_outputSigId(), &id), DXC_E_GENERAL_INTERNAL_ERROR);
- GetUnsignedVal(SO.get_rowIndex(), (uint32_t*)&row);
- IFTBOOL(GetUnsignedVal(SO.get_colIndex(), &col), DXC_E_GENERAL_INTERNAL_ERROR);
- Entry.Outputs.emplace(CI);
- } else if (DxilInst_LoadPatchConstant LPC = DxilInst_LoadPatchConstant(CI)) {
- if (m_pModule->GetShaderModel()->IsDS()) {
- pDynIdxElems = &m_PCSigDynIdxElems;
- IFTBOOL(GetUnsignedVal(LPC.get_inputSigId(), &id), DXC_E_GENERAL_INTERNAL_ERROR);
- GetUnsignedVal(LPC.get_row(), (uint32_t*)&row);
- IFTBOOL(GetUnsignedVal(LPC.get_col(), &col), DXC_E_GENERAL_INTERNAL_ERROR);
- } else {
- // Do nothing. This is an internal helper function for DXBC-2-DXIL converter.
- DXASSERT_NOMSG(m_pModule->GetShaderModel()->IsHS());
- }
- } else if (DxilInst_StorePatchConstant SPC = DxilInst_StorePatchConstant(CI)) {
- pDynIdxElems = &m_PCSigDynIdxElems;
- IFTBOOL(GetUnsignedVal(SPC.get_outputSigID(), &id), DXC_E_GENERAL_INTERNAL_ERROR);
- GetUnsignedVal(SPC.get_row(), (uint32_t*)&row);
- IFTBOOL(GetUnsignedVal(SPC.get_col(), &col), DXC_E_GENERAL_INTERNAL_ERROR);
- Entry.Outputs.emplace(CI);
- } else if (DxilInst_LoadOutputControlPoint LOCP = DxilInst_LoadOutputControlPoint(CI)) {
- if (m_pModule->GetShaderModel()->IsDS()) {
- pDynIdxElems = &m_InpSigDynIdxElems;
- IFTBOOL(GetUnsignedVal(LOCP.get_inputSigId(), &id), DXC_E_GENERAL_INTERNAL_ERROR);
- GetUnsignedVal(LOCP.get_row(), (uint32_t*)&row);
- IFTBOOL(GetUnsignedVal(LOCP.get_col(), &col), DXC_E_GENERAL_INTERNAL_ERROR);
- } else if (m_pModule->GetShaderModel()->IsHS()) {
- // Do nothings, as the information has been captured by the output signature of CP entry.
- } else {
- DXASSERT_NOMSG(false);
- }
- } else {
- continue;
- }
- // Record dynamic index usage.
- if (pDynIdxElems && row == Semantic::kUndefinedRow) {
- (*pDynIdxElems)[id] |= (1 << col);
- }
- }
- }
- // Compute dominator relation.
- pFuncInfo->pDomTree = make_unique<DominatorTreeBase<BasicBlock> >(false);
- pFuncInfo->pDomTree->recalculate(*F);
- #if DXILVIEWID_DBG
- pFuncInfo->pDomTree->print(dbgs());
- #endif
- // Compute postdominator relation.
- DominatorTreeBase<BasicBlock> PDR(true);
- PDR.recalculate(*F);
- #if DXILVIEWID_DBG
- PDR.print(dbgs());
- #endif
- // Compute control dependence.
- pFuncInfo->CtrlDep.Compute(F, PDR);
- #if DXILVIEWID_DBG
- pFuncInfo->CtrlDep.print(dbgs());
- #endif
- }
- }
- void DxilViewIdState::CollectValuesContributingToOutputs(EntryInfo &Entry) {
- for (auto *CI : Entry.Outputs) { // CI = call instruction
- DxilSignature *pDxilSig = nullptr;
- Value *pContributingValue = nullptr;
- unsigned id = (unsigned)-1;
- int startRow = Semantic::kUndefinedRow, endRow = Semantic::kUndefinedRow;
- unsigned col = (unsigned)-1;
- if (DxilInst_StoreOutput SO = DxilInst_StoreOutput(CI)) {
- pDxilSig = &m_pModule->GetOutputSignature();
- pContributingValue = SO.get_value();
- GetUnsignedVal(SO.get_outputSigId(), &id);
- GetUnsignedVal(SO.get_colIndex(), &col);
- GetUnsignedVal(SO.get_rowIndex(), (uint32_t*)&startRow);
- } else if (DxilInst_StorePatchConstant SPC = DxilInst_StorePatchConstant(CI)) {
- pDxilSig = &m_pModule->GetPatchConstantSignature();
- pContributingValue = SPC.get_value();
- GetUnsignedVal(SPC.get_outputSigID(), &id);
- GetUnsignedVal(SPC.get_row(), (uint32_t*)&startRow);
- GetUnsignedVal(SPC.get_col(), &col);
- } else {
- IFT(DXC_E_GENERAL_INTERNAL_ERROR);
- }
- DxilSignatureElement &SigElem = pDxilSig->GetElement(id);
- if (!SigElem.IsAllocated())
- continue;
- unsigned StreamId = SigElem.GetOutputStream();
- if (startRow != Semantic::kUndefinedRow) {
- endRow = startRow;
- } else {
- // The entire column is affected by value.
- DXASSERT_NOMSG(SigElem.GetID() == id && SigElem.GetStartRow() != Semantic::kUndefinedRow);
- startRow = 0;
- endRow = SigElem.GetRows() - 1;
- }
- InstructionSetType ContributingInstructionsAllRows;
- InstructionSetType *pContributingInstructions = &ContributingInstructionsAllRows;
- if (startRow == endRow) {
- // Scalar or indexable with known index.
- unsigned index = GetLinearIndex(SigElem, startRow, col);
- pContributingInstructions = &Entry.ContributingInstructions[StreamId][index];
- }
- CollectValuesContributingToOutputRec(Entry, pContributingValue, *pContributingInstructions);
- // Handle control dependence of this instruction BB.
- BasicBlock *pBB = CI->getParent();
- Function *F = pBB->getParent();
- FuncInfo *pFuncInfo = m_FuncInfo[F].get();
- const BasicBlockSet &CtrlDepSet = pFuncInfo->CtrlDep.GetCDBlocks(pBB);
- for (BasicBlock *B : CtrlDepSet) {
- CollectValuesContributingToOutputRec(Entry, B->getTerminator(), *pContributingInstructions);
- }
- if (pContributingInstructions == &ContributingInstructionsAllRows) {
- // Write dynamically indexed output contributions to all rows.
- for (int row = startRow; row <= endRow; row++) {
- unsigned index = GetLinearIndex(SigElem, row, col);
- Entry.ContributingInstructions[StreamId][index].insert(ContributingInstructionsAllRows.begin(), ContributingInstructionsAllRows.end());
- }
- }
- }
- }
- void DxilViewIdState::CollectValuesContributingToOutputRec(EntryInfo &Entry,
- Value *pContributingValue,
- InstructionSetType &ContributingInstructions) {
- if (Argument *pArg = dyn_cast<Argument>(pContributingValue)) {
- // This must be a leftover signature argument of an entry function.
- DXASSERT_NOMSG(Entry.pEntryFunc == m_pModule->GetEntryFunction() ||
- Entry.pEntryFunc == m_pModule->GetPatchConstantFunction());
- return;
- }
- Instruction *pContributingInst = dyn_cast<Instruction>(pContributingValue);
- if (pContributingInst == nullptr) {
- // Can be literal constant, global decl, branch target.
- DXASSERT_NOMSG(isa<Constant>(pContributingValue) || isa<BasicBlock>(pContributingValue));
- return;
- }
- auto itInst = ContributingInstructions.emplace(pContributingInst);
- // Already visited instruction.
- if (!itInst.second) return;
- // Handle special cases.
- if (PHINode *phi = dyn_cast<PHINode>(pContributingInst)) {
- CollectPhiCFValuesContributingToOutputRec(phi, Entry, ContributingInstructions);
- } else if (isa<LoadInst>(pContributingInst) ||
- isa<AtomicCmpXchgInst>(pContributingInst) ||
- isa<AtomicRMWInst>(pContributingInst)) {
- Value *pPtrValue = pContributingInst->getOperand(0);
- DXASSERT_NOMSG(pPtrValue->getType()->isPointerTy());
- const ValueSetType &ReachingDecls = CollectReachingDecls(pPtrValue);
- DXASSERT_NOMSG(ReachingDecls.size() > 0);
- for (Value *pDeclValue : ReachingDecls) {
- const ValueSetType &Stores = CollectStores(pDeclValue);
- for (Value *V : Stores) {
- CollectValuesContributingToOutputRec(Entry, V, ContributingInstructions);
- }
- }
- } else if (CallInst *CI = dyn_cast<CallInst>(pContributingInst)) {
- if (!hlsl::OP::IsDxilOpFuncCallInst(CI)) {
- Function *F = CI->getCalledFunction();
- if (!F->empty()) {
- // Return value of a user function.
- if (Entry.Functions.find(F) != Entry.Functions.end()) {
- const FuncInfo &FI = *m_FuncInfo[F];
- for (ReturnInst *pRetInst : FI.Returns) {
- CollectValuesContributingToOutputRec(Entry, pRetInst, ContributingInstructions);
- }
- }
- }
- }
- }
- // Handle instruction inputs.
- unsigned NumOps = pContributingInst->getNumOperands();
- for (unsigned i = 0; i < NumOps; i++) {
- Value *O = pContributingInst->getOperand(i);
- CollectValuesContributingToOutputRec(Entry, O, ContributingInstructions);
- }
- // Handle control dependence of this instruction BB.
- BasicBlock *pBB = pContributingInst->getParent();
- Function *F = pBB->getParent();
- FuncInfo *pFuncInfo = m_FuncInfo[F].get();
- const BasicBlockSet &CtrlDepSet = pFuncInfo->CtrlDep.GetCDBlocks(pBB);
- for (BasicBlock *B : CtrlDepSet) {
- CollectValuesContributingToOutputRec(Entry, B->getTerminator(), ContributingInstructions);
- }
- }
- // Only process control-dependent basic blocks for constant operands of the phi-function.
- // An obvious "definition" point for a constant operand is the predecessor along corresponding edge.
- // However, this may be too conservative and, as such, pick up extra control dependent BBs.
- // A better "definition" point is the highest dominator where it is still legal to "insert" constant assignment.
- // In this context, "legal" means that only one value "leaves" the dominator and reaches Phi.
- void DxilViewIdState::CollectPhiCFValuesContributingToOutputRec(PHINode *pPhi,
- EntryInfo &Entry,
- InstructionSetType &ContributingInstructions) {
- Function *F = pPhi->getParent()->getParent();
- FuncInfo *pFuncInfo = m_FuncInfo[F].get();
- unordered_map<DomTreeNodeBase<BasicBlock> *, Value *> DomTreeMarkers;
- // Mark predecessors of each value, so that there is a legal "definition" point.
- for (unsigned i = 0; i < pPhi->getNumOperands(); i++) {
- Value *pValue = pPhi->getIncomingValue(i);
- BasicBlock *pBB = pPhi->getIncomingBlock(i);
- DomTreeNodeBase<BasicBlock> *pDomNode = pFuncInfo->pDomTree->getNode(pBB);
- auto it = DomTreeMarkers.emplace(pDomNode, pValue);
- DXASSERT_NOMSG(it.second || it.first->second == pValue); it;
- }
- // Mark the dominator tree with "definition" values, walking up to the parent.
- for (unsigned i = 0; i < pPhi->getNumOperands(); i++) {
- Value *pValue = pPhi->getIncomingValue(i);
- BasicBlock *pDefBB = &F->getEntryBlock();
- if (Instruction *pDefInst = dyn_cast<Instruction>(pValue)) {
- pDefBB = pDefInst->getParent();
- }
- BasicBlock *pBB = pPhi->getIncomingBlock(i);
- if (pBB == pDefBB) {
- continue; // we already handled the predecessor.
- }
- DomTreeNodeBase<BasicBlock> *pDomNode = pFuncInfo->pDomTree->getNode(pBB);
- pDomNode = pDomNode->getIDom();
- while (pDomNode) {
- auto it = DomTreeMarkers.emplace(pDomNode, pValue);
- if (!it.second) {
- if (it.first->second != pValue && it.first->second != nullptr) {
- if (!isa<Constant>(it.first->second) || !isa<Constant>(pValue)) {
- // Unless both are different constants, mark the "definition" point as illegal.
- it.first->second = nullptr;
- // If both are constants, leave the marker of the first one.
- }
- }
- break;
- }
- // Do not go higher than a legal definition point.
- pBB = pDomNode->getBlock();
- if (pBB == pDefBB)
- break;
- pDomNode = pDomNode->getIDom();
- }
- }
- // Handle control dependence for Constant arguments of Phi.
- for (unsigned i = 0; i < pPhi->getNumOperands(); i++) {
- Value *pValue = pPhi->getIncomingValue(i);
- if (!isa<Constant>(pValue))
- continue;
- // Determine the higher legal "definition" point.
- BasicBlock *pBB = pPhi->getIncomingBlock(i);
- DomTreeNodeBase<BasicBlock> *pDomNode = pFuncInfo->pDomTree->getNode(pBB);
- DomTreeNodeBase<BasicBlock> *pDefDomNode = pDomNode;
- while (pDomNode) {
- auto it = DomTreeMarkers.find(pDomNode);
- DXASSERT_NOMSG(it != DomTreeMarkers.end());
- if (it->second != pValue) {
- DXASSERT_NOMSG(it->second == nullptr || isa<Constant>(it->second));
- break;
- }
- pDefDomNode = pDomNode;
- pDomNode = pDomNode->getIDom();
- }
- // Handle control dependence of this constant argument highest legal "definition" point.
- pBB = pDefDomNode->getBlock();
- const BasicBlockSet &CtrlDepSet = pFuncInfo->CtrlDep.GetCDBlocks(pBB);
- for (BasicBlock *B : CtrlDepSet) {
- CollectValuesContributingToOutputRec(Entry, B->getTerminator(), ContributingInstructions);
- }
- }
- }
- const DxilViewIdState::ValueSetType &DxilViewIdState::CollectReachingDecls(Value *pValue) {
- auto it = m_ReachingDeclsCache.emplace(pValue, ValueSetType());
- if (it.second) {
- // We have not seen this value before.
- ValueSetType Visited;
- CollectReachingDeclsRec(pValue, it.first->second, Visited);
- }
- return it.first->second;
- }
- void DxilViewIdState::CollectReachingDeclsRec(Value *pValue, ValueSetType &ReachingDecls, ValueSetType &Visited) {
- if (Visited.find(pValue) != Visited.end())
- return;
- bool bInitialValue = Visited.size() == 0;
- Visited.emplace(pValue);
- if (!bInitialValue) {
- auto it = m_ReachingDeclsCache.find(pValue);
- if (it != m_ReachingDeclsCache.end()) {
- ReachingDecls.insert(it->second.begin(), it->second.end());
- return;
- }
- }
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(pValue)) {
- ReachingDecls.emplace(pValue);
- return;
- }
- if (GetElementPtrInst *pGepInst = dyn_cast<GetElementPtrInst>(pValue)) {
- Value *pPtrValue = pGepInst->getPointerOperand();
- CollectReachingDeclsRec(pPtrValue, ReachingDecls, Visited);
- } else if (GEPOperator *pGepOp = dyn_cast<GEPOperator>(pValue)) {
- Value *pPtrValue = pGepOp->getPointerOperand();
- CollectReachingDeclsRec(pPtrValue, ReachingDecls, Visited);
- } else if (AllocaInst *AI = dyn_cast<AllocaInst>(pValue)) {
- ReachingDecls.emplace(pValue);
- } else if (PHINode *phi = dyn_cast<PHINode>(pValue)) {
- for (Value *pPtrValue : phi->operands()) {
- CollectReachingDeclsRec(pPtrValue, ReachingDecls, Visited);
- }
- } else if (Argument *pArg = dyn_cast<Argument>(pValue)) {
- ReachingDecls.emplace(pValue);
- } else {
- IFT(DXC_E_GENERAL_INTERNAL_ERROR);
- }
- }
- const DxilViewIdState::ValueSetType &DxilViewIdState::CollectStores(llvm::Value *pValue) {
- auto it = m_StoresPerDeclCache.emplace(pValue, ValueSetType());
- if (it.second) {
- // We have not seen this value before.
- ValueSetType Visited;
- CollectStoresRec(pValue, it.first->second, Visited);
- }
- return it.first->second;
- }
- void DxilViewIdState::CollectStoresRec(llvm::Value *pValue, ValueSetType &Stores, ValueSetType &Visited) {
- if (Visited.find(pValue) != Visited.end())
- return;
- bool bInitialValue = Visited.size() == 0;
- Visited.emplace(pValue);
- if (!bInitialValue) {
- auto it = m_StoresPerDeclCache.find(pValue);
- if (it != m_StoresPerDeclCache.end()) {
- Stores.insert(it->second.begin(), it->second.end());
- return;
- }
- }
- if (isa<LoadInst>(pValue)) {
- return;
- } else if (isa<StoreInst>(pValue) ||
- isa<AtomicCmpXchgInst>(pValue) ||
- isa<AtomicRMWInst>(pValue)) {
- Stores.emplace(pValue);
- return;
- }
- for (auto *U : pValue->users()) {
- CollectStoresRec(U, Stores, Visited);
- }
- }
- void DxilViewIdState::CreateViewIdSets(const std::unordered_map<unsigned, InstructionSetType> &ContributingInstructions,
- OutputsDependentOnViewIdType &OutputsDependentOnViewId,
- InputsContributingToOutputType &InputsContributingToOutputs,
- bool bPC) {
- const ShaderModel *pSM = m_pModule->GetShaderModel();
- for (auto &itOut : ContributingInstructions) {
- unsigned outIdx = itOut.first;
- for (Instruction *pInst : itOut.second) {
- // Set output dependence on ViewId.
- if (DxilInst_ViewID VID = DxilInst_ViewID(pInst)) {
- DXASSERT(m_bUsesViewId, "otherwise, DxilModule flag not set properly");
- OutputsDependentOnViewId[outIdx] = true;
- continue;
- }
- // Start setting output dependence on inputs.
- DxilSignatureElement *pSigElem = nullptr;
- bool bLoadOutputCPInHS = false;
- unsigned inpId = (unsigned)-1;
- int startRow = Semantic::kUndefinedRow, endRow = Semantic::kUndefinedRow;
- unsigned col = (unsigned)-1;
- if (DxilInst_LoadInput LI = DxilInst_LoadInput(pInst)) {
- GetUnsignedVal(LI.get_inputSigId(), &inpId);
- GetUnsignedVal(LI.get_colIndex(), &col);
- GetUnsignedVal(LI.get_rowIndex(), (uint32_t*)&startRow);
- pSigElem = &m_pModule->GetInputSignature().GetElement(inpId);
- if (pSM->IsDS() && bPC) {
- pSigElem = nullptr;
- }
- } else if (DxilInst_LoadOutputControlPoint LOCP = DxilInst_LoadOutputControlPoint(pInst)) {
- GetUnsignedVal(LOCP.get_inputSigId(), &inpId);
- GetUnsignedVal(LOCP.get_col(), &col);
- GetUnsignedVal(LOCP.get_row(), (uint32_t*)&startRow);
- if (pSM->IsHS()) {
- pSigElem = &m_pModule->GetOutputSignature().GetElement(inpId);
- bLoadOutputCPInHS = true;
- } else if (pSM->IsDS()) {
- if (!bPC) {
- pSigElem = &m_pModule->GetInputSignature().GetElement(inpId);
- }
- } else {
- DXASSERT_NOMSG(false);
- }
- } else if (DxilInst_LoadPatchConstant LPC = DxilInst_LoadPatchConstant(pInst)) {
- if (pSM->IsDS() && bPC) {
- GetUnsignedVal(LPC.get_inputSigId(), &inpId);
- GetUnsignedVal(LPC.get_col(), &col);
- GetUnsignedVal(LPC.get_row(), (uint32_t*)&startRow);
- pSigElem = &m_pModule->GetPatchConstantSignature().GetElement(inpId);
- }
- } else {
- continue;
- }
- // Finalize setting output dependence on inputs.
- if (pSigElem && pSigElem->IsAllocated()) {
- if (startRow != Semantic::kUndefinedRow) {
- endRow = startRow;
- } else {
- // The entire column contributes to output.
- startRow = 0;
- endRow = pSigElem->GetRows() - 1;
- }
- auto &ContributingInputs = InputsContributingToOutputs[outIdx];
- for (int row = startRow; row <= endRow; row++) {
- unsigned index = GetLinearIndex(*pSigElem, row, col);
- if (!bLoadOutputCPInHS) {
- ContributingInputs.emplace(index);
- } else {
- // This HS patch-constant output depends on an input value of LoadOutputControlPoint
- // that is the output value of the HS main (control-point) function.
- // Transitively update this (patch-constant) output dependence on main (control-point) output.
- DXASSERT_NOMSG(&OutputsDependentOnViewId == &m_PCOutputsDependentOnViewId);
- OutputsDependentOnViewId[outIdx] = OutputsDependentOnViewId[outIdx] || m_OutputsDependentOnViewId[0][index];
- const auto it = m_InputsContributingToOutputs[0].find(index);
- if (it != m_InputsContributingToOutputs[0].end()) {
- const std::set<unsigned> &LoadOutputCPInputsContributingToOutputs = it->second;
- ContributingInputs.insert(LoadOutputCPInputsContributingToOutputs.begin(),
- LoadOutputCPInputsContributingToOutputs.end());
- }
- }
- }
- }
- }
- }
- }
- unsigned DxilViewIdState::GetLinearIndex(DxilSignatureElement &SigElem, int row, unsigned col) const {
- DXASSERT_NOMSG(row >= 0 && col < kNumComps && SigElem.GetStartRow() != Semantic::kUndefinedRow);
- unsigned idx = (((unsigned)row) + SigElem.GetStartRow())*kNumComps + col + SigElem.GetStartCol();
- DXASSERT_NOMSG(idx < kMaxSigScalars);
- return idx;
- }
- void DxilViewIdState::UpdateDynamicIndexUsageState() const {
- UpdateDynamicIndexUsageStateForSig(m_pModule->GetInputSignature(), m_InpSigDynIdxElems);
- UpdateDynamicIndexUsageStateForSig(m_pModule->GetOutputSignature(), m_OutSigDynIdxElems);
- UpdateDynamicIndexUsageStateForSig(m_pModule->GetPatchConstantSignature(), m_PCSigDynIdxElems);
- }
- void DxilViewIdState::UpdateDynamicIndexUsageStateForSig(DxilSignature &Sig,
- const DynamicallyIndexedElemsType &DynIdxElems) const {
- for (auto it : DynIdxElems) {
- unsigned id = it.first;
- unsigned mask = it.second;
- DxilSignatureElement &E = Sig.GetElement(id);
- E.SetDynIdxCompMask(mask);
- }
- }
- static unsigned RoundUpToUINT(unsigned x) {
- return (x + 31)/32;
- }
- void DxilViewIdState::Serialize() {
- const ShaderModel *pSM = m_pModule->GetShaderModel();
- m_SerializedState.clear();
- // Compute serialized state size in UINTs.
- unsigned NumInputs = getNumInputSigScalars();
- unsigned NumStreams = pSM->IsGS()? kNumStreams : 1;
- unsigned Size = 0;
- Size += 1; // #Inputs.
- for (unsigned StreamId = 0; StreamId < NumStreams; StreamId++) {
- Size += 1; // #Outputs for stream StreamId.
- unsigned NumOutputs = getNumOutputSigScalars(StreamId);
- unsigned NumOutUINTs = RoundUpToUINT(NumOutputs);
- if (m_bUsesViewId) {
- Size += NumOutUINTs; // m_OutputsDependentOnViewId[StreamId]
- }
- Size += NumInputs * NumOutUINTs; // m_InputsContributingToOutputs[StreamId]
- }
- if (pSM->IsHS() || pSM->IsDS()) {
- Size += 1; // #PatchConstant.
- unsigned NumPCs = getNumPCSigScalars();
- unsigned NumPCUINTs = RoundUpToUINT(NumPCs);
- if (pSM->IsHS()) {
- if (m_bUsesViewId) {
- Size += NumPCUINTs; // m_PCOutputsDependentOnViewId
- }
- Size += NumInputs * NumPCUINTs; // m_InputsContributingToPCOutputs
- } else {
- unsigned NumOutputs = getNumOutputSigScalars(0);
- unsigned NumOutUINTs = RoundUpToUINT(NumOutputs);
- Size += NumPCs * NumOutUINTs; // m_PCInputsContributingToOutputs
- }
- }
- m_SerializedState.resize(Size);
- std::fill(m_SerializedState.begin(), m_SerializedState.end(), 0u);
- // Serialize ViewId state.
- unsigned *pData = &m_SerializedState[0];
- *pData++ = NumInputs;
- for (unsigned StreamId = 0; StreamId < NumStreams; StreamId++) {
- unsigned NumOutputs = getNumOutputSigScalars(StreamId);
- *pData++ = NumOutputs;
- if (m_bUsesViewId) {
- SerializeOutputsDependentOnViewId(NumOutputs, m_OutputsDependentOnViewId[StreamId], pData);
- }
- SerializeInputsContributingToOutput(NumInputs, NumOutputs, m_InputsContributingToOutputs[StreamId], pData);
- }
- if (pSM->IsHS() || pSM->IsDS()) {
- unsigned NumPCs = getNumPCSigScalars();
- *pData++ = NumPCs;
- if (pSM->IsHS()) {
- if (m_bUsesViewId) {
- SerializeOutputsDependentOnViewId(NumPCs, m_PCOutputsDependentOnViewId, pData);
- }
- SerializeInputsContributingToOutput(NumInputs, NumPCs, m_InputsContributingToPCOutputs, pData);
- } else {
- unsigned NumOutputs = getNumOutputSigScalars(0);
- SerializeInputsContributingToOutput(NumPCs, NumOutputs, m_PCInputsContributingToOutputs, pData);
- }
- }
- DXASSERT_NOMSG(pData == (&m_SerializedState[0] + Size));
- }
- const vector<unsigned> &DxilViewIdState::GetSerialized() {
- if (m_SerializedState.empty())
- Serialize();
- return m_SerializedState;
- }
- const vector<unsigned> &DxilViewIdState::GetSerialized() const {
- return m_SerializedState;
- }
- void DxilViewIdState::SerializeOutputsDependentOnViewId(unsigned NumOutputs,
- const OutputsDependentOnViewIdType &OutputsDependentOnViewId,
- unsigned *&pData) {
- unsigned NumOutUINTs = RoundUpToUINT(NumOutputs);
- // Serialize output dependence on ViewId.
- for (unsigned i = 0; i < NumOutUINTs; i++) {
- unsigned x = 0;
- for (unsigned j = 0; j < std::min(32u, NumOutputs - 32u*i); j++) {
- if (OutputsDependentOnViewId[i*32 + j]) {
- x |= (1u << j);
- }
- }
- *pData++ = x;
- }
- }
- void DxilViewIdState::SerializeInputsContributingToOutput(unsigned NumInputs, unsigned NumOutputs,
- const InputsContributingToOutputType &InputsContributingToOutputs,
- unsigned *&pData) {
- unsigned NumOutUINTs = RoundUpToUINT(NumOutputs);
- // Serialize output dependence on inputs.
- for (unsigned outputIdx = 0; outputIdx < NumOutputs; outputIdx++) {
- auto it = InputsContributingToOutputs.find(outputIdx);
- if (it != InputsContributingToOutputs.end()) {
- for (unsigned inputIdx : it->second) {
- unsigned w = outputIdx / 32;
- unsigned b = outputIdx % 32;
- pData[inputIdx*NumOutUINTs + w] |= (1u << b);
- }
- }
- }
- pData += NumInputs * NumOutUINTs;
- }
- void DxilViewIdState::Deserialize(const unsigned *pData, unsigned DataSizeInUINTs) {
- Clear();
- m_SerializedState.resize(DataSizeInUINTs);
- memcpy(m_SerializedState.data(), pData, DataSizeInUINTs * sizeof(unsigned));
- const ShaderModel *pSM = m_pModule->GetShaderModel();
- m_bUsesViewId = m_pModule->m_ShaderFlags.GetViewID();
- unsigned ConsumedUINTs = 0;
- IFTBOOL(DataSizeInUINTs-ConsumedUINTs >= 1, DXC_E_GENERAL_INTERNAL_ERROR);
- unsigned NumInputs = pData[ConsumedUINTs++];
- m_NumInputSigScalars = NumInputs;
- unsigned NumStreams = pSM->IsGS()? kNumStreams : 1;
- for (unsigned StreamId = 0; StreamId < NumStreams; StreamId++) {
- IFTBOOL(DataSizeInUINTs-ConsumedUINTs >= 1, DXC_E_GENERAL_INTERNAL_ERROR);
- unsigned NumOutputs = pData[ConsumedUINTs++];
- m_NumOutputSigScalars[StreamId] = NumOutputs;
- if (m_bUsesViewId) {
- ConsumedUINTs += DeserializeOutputsDependentOnViewId(NumOutputs,
- m_OutputsDependentOnViewId[StreamId],
- &pData[ConsumedUINTs],
- DataSizeInUINTs-ConsumedUINTs);
- }
- ConsumedUINTs += DeserializeInputsContributingToOutput(NumInputs, NumOutputs,
- m_InputsContributingToOutputs[StreamId],
- &pData[ConsumedUINTs],
- DataSizeInUINTs-ConsumedUINTs);
- }
- if (pSM->IsHS() || pSM->IsDS()) {
- IFTBOOL(DataSizeInUINTs-ConsumedUINTs >= 1, DXC_E_GENERAL_INTERNAL_ERROR);
- unsigned NumPCs = pData[ConsumedUINTs++];
- m_NumPCSigScalars = NumPCs;
- if (pSM->IsHS()) {
- if (m_bUsesViewId) {
- ConsumedUINTs += DeserializeOutputsDependentOnViewId(NumPCs,
- m_PCOutputsDependentOnViewId,
- &pData[ConsumedUINTs],
- DataSizeInUINTs-ConsumedUINTs);
- }
- ConsumedUINTs += DeserializeInputsContributingToOutput(NumInputs, NumPCs,
- m_InputsContributingToPCOutputs,
- &pData[ConsumedUINTs],
- DataSizeInUINTs-ConsumedUINTs);
- } else {
- unsigned NumOutputs = getNumOutputSigScalars(0);
- ConsumedUINTs += DeserializeInputsContributingToOutput(NumPCs, NumOutputs,
- m_PCInputsContributingToOutputs,
- &pData[ConsumedUINTs],
- DataSizeInUINTs-ConsumedUINTs);
- }
- }
- DXASSERT_NOMSG(ConsumedUINTs == DataSizeInUINTs);
- }
- unsigned DxilViewIdState::DeserializeOutputsDependentOnViewId(unsigned NumOutputs,
- OutputsDependentOnViewIdType &OutputsDependentOnViewId,
- const unsigned *pData, unsigned DataSize) {
- unsigned NumOutUINTs = RoundUpToUINT(NumOutputs);
- IFTBOOL(NumOutUINTs <= DataSize, DXC_E_GENERAL_INTERNAL_ERROR);
- // Deserialize output dependence on ViewId.
- for (unsigned i = 0; i < NumOutUINTs; i++) {
- unsigned x = *pData++;
- for (unsigned j = 0; j < std::min(32u, NumOutputs - 32u*i); j++) {
- if (x & (1u << j)) {
- OutputsDependentOnViewId[i*32 + j] = true;
- }
- }
- }
- return NumOutUINTs;
- }
- unsigned DxilViewIdState::DeserializeInputsContributingToOutput(unsigned NumInputs, unsigned NumOutputs,
- InputsContributingToOutputType &InputsContributingToOutputs,
- const unsigned *pData, unsigned DataSize) {
- unsigned NumOutUINTs = RoundUpToUINT(NumOutputs);
- unsigned Size = NumInputs * NumOutUINTs;
- IFTBOOL(Size <= DataSize, DXC_E_GENERAL_INTERNAL_ERROR);
- // Deserialize output dependence on inputs.
- for (unsigned inputIdx = 0; inputIdx < NumInputs; inputIdx++) {
- for (unsigned outputIdx = 0; outputIdx < NumOutputs; outputIdx++) {
- unsigned w = outputIdx / 32;
- unsigned b = outputIdx % 32;
- if (pData[inputIdx*NumOutUINTs + w] & (1u << b)) {
- InputsContributingToOutputs[outputIdx].insert(inputIdx);
- }
- }
- }
- return Size;
- }
- char ComputeViewIdState::ID = 0;
- INITIALIZE_PASS_BEGIN(ComputeViewIdState, "viewid-state",
- "Compute information related to ViewID", true, true)
- INITIALIZE_PASS_END(ComputeViewIdState, "viewid-state",
- "Compute information related to ViewID", true, true)
- ComputeViewIdState::ComputeViewIdState() : ModulePass(ID) {
- }
- bool ComputeViewIdState::runOnModule(Module &M) {
- DxilModule &DxilModule = M.GetOrCreateDxilModule();
- const ShaderModel *pSM = DxilModule.GetShaderModel();
- if (!pSM->IsCS() && !pSM->IsLib()) {
- DxilViewIdState &ViewIdState = DxilModule.GetViewIdState();
- ViewIdState.Compute();
- return true;
- }
- return false;
- }
- void ComputeViewIdState::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
- namespace llvm {
- ModulePass *createComputeViewIdStatePass() {
- return new ComputeViewIdState();
- }
- } // end of namespace llvm
|