| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // 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 <memory>
- #include <bitset>
- #include <unordered_set>
- #include <unordered_map>
- #include <set>
- #include <map>
- 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<kMaxSigScalars>;
- using InputsContributingToOutputType = std::map<unsigned, std::set<unsigned>>;
- 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<unsigned> &GetSerialized();
- const std::vector<unsigned> &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<unsigned, unsigned>;
- 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<llvm::Function *>;
- using InstructionSetType = std::unordered_set<llvm::Instruction *>;
- 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<unsigned, InstructionSetType> ContributingInstructions[kNumStreams];
- void Clear();
- };
- EntryInfo m_Entry;
- EntryInfo m_PCEntry;
- // Information per function.
- using FunctionReturnSet = std::unordered_set<llvm::ReturnInst *>;
- struct FuncInfo {
- FunctionReturnSet Returns;
- ControlDependence CtrlDep;
- std::unique_ptr<llvm::DominatorTreeBase<llvm::BasicBlock> > pDomTree;
- void Clear();
- };
- std::unordered_map<llvm::Function *, std::unique_ptr<FuncInfo>> m_FuncInfo;
- // Cache of decls (global/alloca) reaching a pointer value.
- using ValueSetType = std::unordered_set<llvm::Value *>;
- std::unordered_map<llvm::Value *, ValueSetType> m_ReachingDeclsCache;
- // Cache of stores for each decl.
- std::unordered_map<llvm::Value *, ValueSetType> m_StoresPerDeclCache;
- // Serialized form.
- std::vector<unsigned> 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<unsigned, InstructionSetType> &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
|