/////////////////////////////////////////////////////////////////////////////// // // // ComputeViewIdSets.h // // Copyright (C) Microsoft Corporation. All rights reserved. // // This file is distributed under the University of Illinois Open Source // // License. See LICENSE.TXT for details. // // // // Computes output registers dependent on ViewID. // // Computes sets of input registers on which output registers depend. // // Computes which input/output shapes are dynamically indexed. // // // /////////////////////////////////////////////////////////////////////////////// #pragma once #include "llvm/Pass.h" #include "dxc/HLSL/ControlDependence.h" #include "llvm/Support/GenericDomTree.h" #include #include #include #include #include #include namespace llvm { class Module; class Function; class BasicBlock; class Instruction; class ReturnInst; class Value; class PHINode; class AnalysisUsage; class CallGraph; class CallGraphNode; class ModulePass; class raw_ostream; } namespace hlsl { class DxilModule; class DxilSignature; class DxilSignatureElement; class DxilViewIdState { static const unsigned kNumComps = 4; static const unsigned kMaxSigScalars = 32*4; public: using OutputsDependentOnViewIdType = std::bitset; using InputsContributingToOutputType = std::map>; DxilViewIdState(DxilModule *pDxilModule); unsigned getNumInputSigScalars() const; unsigned getNumOutputSigScalars(unsigned StreamId) const; unsigned getNumPCSigScalars() const; const OutputsDependentOnViewIdType &getOutputsDependentOnViewId(unsigned StreamId) const; const OutputsDependentOnViewIdType &getPCOutputsDependentOnViewId() const; const InputsContributingToOutputType &getInputsContributingToOutputs(unsigned StreamId) const; const InputsContributingToOutputType &getInputsContributingToPCOutputs() const; const InputsContributingToOutputType &getPCInputsContributingToOutputs() const; void Compute(); void Serialize(); const std::vector &GetSerialized(); const std::vector &GetSerialized() const; // returns previously serialized data void Deserialize(const unsigned *pData, unsigned DataSizeInUINTs); void PrintSets(llvm::raw_ostream &OS); private: static const unsigned kNumStreams = 4; DxilModule *m_pModule; bool m_bUsesViewId = false; unsigned m_NumInputSigScalars = 0; unsigned m_NumOutputSigScalars[kNumStreams] = {0,0,0,0}; unsigned m_NumPCSigScalars = 0; // Dynamically indexed components of signature elements. using DynamicallyIndexedElemsType = std::unordered_map; DynamicallyIndexedElemsType m_InpSigDynIdxElems; DynamicallyIndexedElemsType m_OutSigDynIdxElems; DynamicallyIndexedElemsType m_PCSigDynIdxElems; // Set of scalar outputs dependent on ViewID. OutputsDependentOnViewIdType m_OutputsDependentOnViewId[kNumStreams]; OutputsDependentOnViewIdType m_PCOutputsDependentOnViewId; // Set of scalar inputs contributing to computation of scalar outputs. InputsContributingToOutputType m_InputsContributingToOutputs[kNumStreams]; InputsContributingToOutputType m_InputsContributingToPCOutputs; // HS PC only. InputsContributingToOutputType m_PCInputsContributingToOutputs; // DS only. // Information per entry point. using FunctionSetType = std::unordered_set; using InstructionSetType = std::unordered_set; struct EntryInfo { llvm::Function *pEntryFunc = nullptr; // Sets of functions that may be reachable from an entry. FunctionSetType Functions; // Outputs to analyze. InstructionSetType Outputs; // Contributing instructions per output. std::unordered_map ContributingInstructions[kNumStreams]; void Clear(); }; EntryInfo m_Entry; EntryInfo m_PCEntry; // Information per function. using FunctionReturnSet = std::unordered_set; struct FuncInfo { FunctionReturnSet Returns; ControlDependence CtrlDep; std::unique_ptr > pDomTree; void Clear(); }; std::unordered_map> m_FuncInfo; // Cache of decls (global/alloca) reaching a pointer value. using ValueSetType = std::unordered_set; std::unordered_map m_ReachingDeclsCache; // Cache of stores for each decl. std::unordered_map m_StoresPerDeclCache; // Serialized form. std::vector m_SerializedState; void Clear(); void DetermineMaxPackedLocation(DxilSignature &DxilSig, unsigned *pMaxSigLoc, unsigned NumStreams); void ComputeReachableFunctionsRec(llvm::CallGraph &CG, llvm::CallGraphNode *pNode, FunctionSetType &FuncSet); void AnalyzeFunctions(EntryInfo &Entry); void CollectValuesContributingToOutputs(EntryInfo &Entry); void CollectValuesContributingToOutputRec(EntryInfo &Entry, llvm::Value *pContributingValue, InstructionSetType &ContributingInstructions); void CollectPhiCFValuesContributingToOutputRec(llvm::PHINode *pPhi, EntryInfo &Entry, InstructionSetType &ContributingInstructions); const ValueSetType &CollectReachingDecls(llvm::Value *pValue); void CollectReachingDeclsRec(llvm::Value *pValue, ValueSetType &ReachingDecls, ValueSetType &Visited); const ValueSetType &CollectStores(llvm::Value *pValue); void CollectStoresRec(llvm::Value *pValue, ValueSetType &Stores, ValueSetType &Visited); void UpdateDynamicIndexUsageState() const; void CreateViewIdSets(const std::unordered_map &ContributingInstructions, OutputsDependentOnViewIdType &OutputsDependentOnViewId, InputsContributingToOutputType &InputsContributingToOutputs, bool bPC); void UpdateDynamicIndexUsageStateForSig(DxilSignature &Sig, const DynamicallyIndexedElemsType &DynIdxElems) const; void SerializeOutputsDependentOnViewId(unsigned NumOutputs, const OutputsDependentOnViewIdType &OutputsDependentOnViewId, unsigned *&pData); void SerializeInputsContributingToOutput(unsigned NumInputs, unsigned NumOutputs, const InputsContributingToOutputType &InputsContributingToOutputs, unsigned *&pData); unsigned DeserializeOutputsDependentOnViewId(unsigned NumOutputs, OutputsDependentOnViewIdType &OutputsDependentOnViewId, const unsigned *pData, unsigned DataSize); unsigned DeserializeInputsContributingToOutput(unsigned NumInputs, unsigned NumOutputs, InputsContributingToOutputType &InputsContributingToOutputs, const unsigned *pData, unsigned DataSize); unsigned GetLinearIndex(DxilSignatureElement &SigElem, int row, unsigned col) const; void PrintOutputsDependentOnViewId(llvm::raw_ostream &OS, llvm::StringRef SetName, unsigned NumOutputs, const OutputsDependentOnViewIdType &OutputsDependentOnViewId); void PrintInputsContributingToOutputs(llvm::raw_ostream &OS, llvm::StringRef InputSetName, llvm::StringRef OutputSetName, const InputsContributingToOutputType &InputsContributingToOutputs); }; } // end of hlsl namespace namespace llvm { class ComputeViewIdState : public ModulePass { public: static char ID; // Pass ID, replacement for typeid ComputeViewIdState(); bool runOnModule(Module &M) override; void getAnalysisUsage(AnalysisUsage &AU) const override; }; void initializeComputeViewIdStatePass(llvm::PassRegistry &); llvm::ModulePass *createComputeViewIdStatePass(); } // end of llvm namespace