Skip to content

Commit

Permalink
Refine InOutLocationMapManager
Browse files Browse the repository at this point in the history
-Add a new interface `createLocationInfoMap` to hide the implementations
-`addSpan` and `buildLocationMap`.
-Rename variable names with `location*` to `locationInfo*` to emphasize
that it represents a compound information.
  • Loading branch information
xuechen417 authored and JaxLinAMD committed Dec 3, 2020
1 parent a88ebb7 commit 764ee20
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 35 deletions.
55 changes: 33 additions & 22 deletions lgc/patch/PatchResourceCollect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ ModulePass *createPatchResourceCollect() {
// =====================================================================================================================
PatchResourceCollect::PatchResourceCollect()
: Patch(ID), m_hasDynIndexedInput(false), m_hasDynIndexedOutput(false), m_resUsage(nullptr) {
m_locationMapManager = std::make_unique<InOutLocationMapManager>();
m_locationInfoMapManager = std::make_unique<InOutLocationInfoMapManager>();
}

// =====================================================================================================================
Expand Down Expand Up @@ -1297,8 +1297,6 @@ void PatchResourceCollect::visitCallInst(CallInst &callInst) {
if (isPackIn && !m_hasDynIndexedInput && !isDeadCall &&
(mangledName.startswith(lgcName::InputImportGeneric) ||
mangledName.startswith(lgcName::InputImportInterpolant))) {
// Collect LocationSpans according to each TCS or FS input call
m_locationMapManager->addSpan(&callInst, m_shaderStage);
m_inOutCalls.push_back(&callInst);
} else if (isPackOut && mangledName.startswith(lgcName::OutputExportGeneric)) {
// Collect outputs of VS or TES
Expand Down Expand Up @@ -2525,8 +2523,6 @@ void PatchResourceCollect::mapGsBuiltInOutput(unsigned builtInId, unsigned elemC
// The process of packing input/output
void PatchResourceCollect::packInOutLocation() {
if (m_shaderStage == ShaderStageFragment || m_shaderStage == ShaderStageTessControl) {
// Build location map based on FS (VS-FS, TES-FS) and TCS spans
m_locationMapManager->buildLocationMap(m_shaderStage == ShaderStageFragment);
fillInOutLocInfoMap();
} else {
reassembleOutputExportCalls();
Expand All @@ -2551,6 +2547,9 @@ void PatchResourceCollect::fillInOutLocInfoMap() {

assert(m_shaderStage == ShaderStageFragment || m_shaderStage == ShaderStageTessControl);

// Create locationInfoMap according to the packed calls
m_locationInfoMapManager->createMap(m_inOutCalls, m_shaderStage);

auto &inOutUsage = m_pipelineState->getShaderResourceUsage(m_shaderStage)->inOutUsage;
auto &inputLocInfoMap = inOutUsage.inputLocInfoMap;
inputLocInfoMap.clear();
Expand All @@ -2575,16 +2574,16 @@ void PatchResourceCollect::fillInOutLocInfoMap() {
origLocInfo.setLocation(cast<ConstantInt>(call->getOperand(0))->getZExtValue() + locOffset);
origLocInfo.setComponent(cast<ConstantInt>(call->getOperand(compIdxArgIdx))->getZExtValue());

// Get the packed InOutLocationInfo from locationMap
// Get the packed InOutLocationInfo from locationInfoMap
InOutLocationInfoMap::const_iterator mapIter;
assert(m_locationMapManager->findMap(origLocInfo, mapIter));
m_locationMapManager->findMap(origLocInfo, mapIter);
assert(m_locationInfoMapManager->findMap(origLocInfo, mapIter));
m_locationInfoMapManager->findMap(origLocInfo, mapIter);
inputLocInfoMap.insert({origLocInfo, mapIter->second});
}
}

// =====================================================================================================================
// Re-assemble output export functions based on the locationMap
// Re-assemble output export functions based on the locationInfoMap
void PatchResourceCollect::reassembleOutputExportCalls() {
if (m_inOutCalls.empty())
return;
Expand Down Expand Up @@ -2613,7 +2612,7 @@ void PatchResourceCollect::reassembleOutputExportCalls() {
origLocInfo.setComponent(cast<ConstantInt>(call->getOperand(1))->getZExtValue());

InOutLocationInfoMap::const_iterator mapIter;
if (!m_locationMapManager->findMap(origLocInfo, mapIter)) {
if (!m_locationInfoMapManager->findMap(origLocInfo, mapIter)) {
// An unused export call
continue;
}
Expand Down Expand Up @@ -2920,12 +2919,24 @@ void PatchResourceCollect::scalarizeGenericOutput(CallInst *call) {
call->eraseFromParent();
}

// =====================================================================================================================
// Create a locationInfo map for the given shader stage
//
// @param call : Call to process
// @param shaderStage : Shader stage
void InOutLocationInfoMapManager::createMap(const std::vector<CallInst *> &calls, ShaderStage shaderStage) {
for (auto call : calls)
addSpan(call, shaderStage);
// Build locationInfoMap according to the collected LocationSpans
buildMap(shaderStage);
}

// =====================================================================================================================
// Fill the locationSpan container by constructing a LocationSpan from each input import call
//
// @param call : Call to process
// @param shaderStage : Shader stage
void InOutLocationMapManager::addSpan(CallInst *call, ShaderStage shaderStage) {
void InOutLocationInfoMapManager::addSpan(CallInst *call, ShaderStage shaderStage) {
const bool isTcs = shaderStage == ShaderStageTessControl;
const bool isInterpolant = !isTcs && call->getNumArgOperands() != 4;
unsigned locOffset = 0;
Expand All @@ -2937,8 +2948,8 @@ void InOutLocationMapManager::addSpan(CallInst *call, ShaderStage shaderStage) {
}

LocationSpan span = {};
span.firstLocation.setLocation(cast<ConstantInt>(call->getOperand(0))->getZExtValue() + locOffset);
span.firstLocation.setComponent(cast<ConstantInt>(call->getOperand(compIdxArgIdx))->getZExtValue());
span.firstLocationInfo.setLocation(cast<ConstantInt>(call->getOperand(0))->getZExtValue() + locOffset);
span.firstLocationInfo.setComponent(cast<ConstantInt>(call->getOperand(compIdxArgIdx))->getZExtValue());

unsigned bitWidth = call->getType()->getScalarSizeInBits();
if (isTcs && bitWidth < 32)
Expand All @@ -2965,13 +2976,13 @@ void InOutLocationMapManager::addSpan(CallInst *call, ShaderStage shaderStage) {
// Build the map between orignal InOutLocationInfo and packed InOutLocationInfo based on sorted locaiton spans
//
// @param checkCompatibility : whether to check compatibilty between two spans to start a new location
void InOutLocationMapManager::buildLocationMap(bool checkCompatibility) {
void InOutLocationInfoMapManager::buildMap(bool checkCompatibility) {
if (m_locationSpans.empty())
return;
// Sort m_locationSpans based on LocationSpan::GetCompatibilityKey() and InOutLocationInfo::AsIndex()
std::sort(m_locationSpans.begin(), m_locationSpans.end());

m_locationMap.clear();
m_locationInfoMap.clear();

// Map original InOutLocationInfo to new InOutLocationInfo
unsigned consectiveLocation = 0;
Expand Down Expand Up @@ -3001,27 +3012,27 @@ void InOutLocationMapManager::buildLocationMap(bool checkCompatibility) {
newLocInfo.setLocation(consectiveLocation);
newLocInfo.setComponent(compIdx);
newLocInfo.setHighHalf(isHighHalf);
m_locationMap.insert({spanIt->firstLocation, newLocInfo});
m_locationInfoMap.insert({spanIt->firstLocationInfo, newLocInfo});

// Update component index
if ((spanIt->compatibilityInfo.is16Bit && isHighHalf) || !spanIt->compatibilityInfo.is16Bit)
++compIdx;
assert(compIdx <= 4);
}

// Exists temporarily for computing m_locationMap
// Exists temporarily for computing m_locationInfoMap
m_locationSpans.clear();
}

// =====================================================================================================================
// Output a mapped InOutLocationInfo from a given InOutLocationInfo if the mapping exists
//
// @param origLocInfo : The original InOutLocationInfo
// @param [out] mapIt : Iterator to an element of m_locationMap with key equivalent to the given InOutLocationInfo
bool InOutLocationMapManager::findMap(const InOutLocationInfo &origLocInfo,
InOutLocationInfoMap::const_iterator &mapIt) {
mapIt = m_locationMap.find(origLocInfo);
return mapIt != m_locationMap.end();
// @param [out] mapIt : Iterator to an element of m_locationInfoMap with key equivalent to the given InOutLocationInfo
bool InOutLocationInfoMapManager::findMap(const InOutLocationInfo &origLocInfo,
InOutLocationInfoMap::const_iterator &mapIt) {
mapIt = m_locationInfoMap.find(origLocInfo);
return mapIt != m_locationInfoMap.end();
}

} // namespace lgc
Expand Down
28 changes: 15 additions & 13 deletions lgc/patch/PatchResourceCollect.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

namespace lgc {

class InOutLocationMapManager;
class InOutLocationInfoMapManager;
typedef std::map<InOutLocationInfo, InOutLocationInfo> InOutLocationInfoMap;

// =====================================================================================================================
Expand Down Expand Up @@ -112,7 +112,8 @@ class PatchResourceCollect : public Patch, public llvm::InstVisitor<PatchResourc
bool m_hasDynIndexedOutput; // Whether dynamic indices are used in generic output addressing (valid
// for tessellation control shader)
ResourceUsage *m_resUsage; // Pointer to shader resource usage
std::unique_ptr<InOutLocationMapManager> m_locationMapManager; // Pointer to InOutLocationMapManager instance
std::unique_ptr<InOutLocationInfoMapManager>
m_locationInfoMapManager; // Pointer to InOutLocationInfoMapManager instance
};

// Represents the compatibility info of input/output
Expand All @@ -128,39 +129,40 @@ union InOutCompatibilityInfo {
};

// =====================================================================================================================
// Represents the manager of input/output locationMap generation
class InOutLocationMapManager {
// Represents the manager of input/output locationInfoMap generation
class InOutLocationInfoMapManager {
public:
InOutLocationMapManager() {}

void addSpan(llvm::CallInst *call, ShaderStage shaderStage);
void buildLocationMap(bool checkCompatibility);
InOutLocationInfoMapManager() {}

void createMap(const std::vector<llvm::CallInst *> &calls, ShaderStage shaderStage);
bool findMap(const InOutLocationInfo &origLocInfo, InOutLocationInfoMap::const_iterator &mapIt);

struct LocationSpan {
uint16_t getCompatibilityKey() const { return compatibilityInfo.u16All; }

unsigned asIndex() const { return ((getCompatibilityKey() << 16) | firstLocation.getData()); }
unsigned asIndex() const { return ((getCompatibilityKey() << 16) | firstLocationInfo.getData()); }

bool operator==(const LocationSpan &rhs) const { return this->asIndex() == rhs.asIndex(); }

bool operator<(const LocationSpan &rhs) const { return this->asIndex() < rhs.asIndex(); }

InOutLocationInfo firstLocation;
InOutLocationInfo firstLocationInfo;
InOutCompatibilityInfo compatibilityInfo;
};

private:
InOutLocationMapManager(const InOutLocationMapManager &) = delete;
InOutLocationMapManager &operator=(const InOutLocationMapManager &) = delete;
InOutLocationInfoMapManager(const InOutLocationInfoMapManager &) = delete;
InOutLocationInfoMapManager &operator=(const InOutLocationInfoMapManager &) = delete;

void addSpan(llvm::CallInst *call, ShaderStage shaderStage);
void buildMap(bool checkCompatibility);

bool isCompatible(const LocationSpan &rSpan, const LocationSpan &lSpan) const {
return rSpan.getCompatibilityKey() == lSpan.getCompatibilityKey();
}

std::vector<LocationSpan> m_locationSpans; // Tracks spans of contiguous components in the generic input space
InOutLocationInfoMap m_locationMap; // The map between original location and new location
InOutLocationInfoMap m_locationInfoMap; // The map between original location and new location
};

} // namespace lgc

0 comments on commit 764ee20

Please sign in to comment.