mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 16:02:37 +00:00
shader: batch dependent folds to avoid repeated SSA graph walks
This commit is contained in:
1 parent
b82512be06
commit
f6f1ac8b40
1 file changed
+29
-23
@@ -51,11 +51,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QueueUsers(const std::vector<Use>& users) {
|
void QueueUsers(const std::vector<Use>& users) {
|
||||||
++generation;
|
|
||||||
affected.clear();
|
|
||||||
for (const auto& use: users) affected.push_back(use.user);
|
for (const auto& use: users) affected.push_back(use.user);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlushUsers() {
|
||||||
|
++generation;
|
||||||
// Pattern folds inspect nested operands even when intermediate operations
|
// Pattern folds inspect nested operands even when intermediate operations
|
||||||
// stay dynamic. Visit consumers once per change, including cyclic Phi edges.
|
// stay dynamic. Visit their union once per drain, including cyclic Phi edges.
|
||||||
for (size_t i = 0; i < affected.size(); ++i) {
|
for (size_t i = 0; i < affected.size(); ++i) {
|
||||||
auto* inst = affected[i];
|
auto* inst = affected[i];
|
||||||
const auto found = locations.find(inst);
|
const auto found = locations.find(inst);
|
||||||
@@ -64,6 +66,7 @@ public:
|
|||||||
Queue(inst);
|
Queue(inst);
|
||||||
for (const auto& use: inst->Uses()) affected.push_back(use.user);
|
for (const auto& use: inst->Uses()) affected.push_back(use.user);
|
||||||
}
|
}
|
||||||
|
affected.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Block::iterator Prepend(Block& block, Block::iterator before, ValueOpcode opcode,
|
Block::iterator Prepend(Block& block, Block::iterator before, ValueOpcode opcode,
|
||||||
@@ -977,27 +980,30 @@ void ConstantPropagationPass(const BlockList& blocks, uint32_t wave_size) {
|
|||||||
std::vector<Use> users;
|
std::vector<Use> users;
|
||||||
std::vector<Value> operands;
|
std::vector<Value> operands;
|
||||||
const auto drain = [&] {
|
const auto drain = [&] {
|
||||||
for (size_t i = 0; i < worklist.pending.size(); ++i) {
|
do {
|
||||||
auto* inst = worklist.pending[i];
|
for (size_t i = 0; i < worklist.pending.size(); ++i) {
|
||||||
auto& location = worklist.locations.at(inst);
|
auto* inst = worklist.pending[i];
|
||||||
location.queued = false;
|
auto& location = worklist.locations.at(inst);
|
||||||
const auto opcode = inst->GetOpcode();
|
location.queued = false;
|
||||||
if (opcode == ValueOpcode::Identity || opcode == ValueOpcode::Void) continue;
|
const auto opcode = inst->GetOpcode();
|
||||||
const auto where = location.instruction;
|
if (opcode == ValueOpcode::Identity || opcode == ValueOpcode::Void) continue;
|
||||||
users.assign(inst->Uses().begin(), inst->Uses().end());
|
const auto where = location.instruction;
|
||||||
operands.clear();
|
users.assign(inst->Uses().begin(), inst->Uses().end());
|
||||||
for (size_t arg = 0; arg < inst->NumArgs(); ++arg) operands.push_back(inst->Arg(arg));
|
operands.clear();
|
||||||
mask_projection.Fold(*inst, wave_size);
|
for (size_t arg = 0; arg < inst->NumArgs(); ++arg) operands.push_back(inst->Arg(arg));
|
||||||
FoldInstruction(*inst->Parent(), where, worklist);
|
mask_projection.Fold(*inst, wave_size);
|
||||||
bool changed = opcode != inst->GetOpcode() || operands.size() != inst->NumArgs();
|
FoldInstruction(*inst->Parent(), where, worklist);
|
||||||
for (size_t arg = 0; !changed && arg < operands.size(); ++arg)
|
bool changed = opcode != inst->GetOpcode() || operands.size() != inst->NumArgs();
|
||||||
changed = operands[arg] != inst->Arg(arg);
|
for (size_t arg = 0; !changed && arg < operands.size(); ++arg)
|
||||||
if (changed) {
|
changed = operands[arg] != inst->Arg(arg);
|
||||||
worklist.QueueUsers(users);
|
if (changed) {
|
||||||
worklist.Queue(inst);
|
worklist.QueueUsers(users);
|
||||||
|
worklist.Queue(inst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
worklist.pending.clear();
|
||||||
worklist.pending.clear();
|
worklist.FlushUsers();
|
||||||
|
} while (!worklist.pending.empty());
|
||||||
};
|
};
|
||||||
drain();
|
drain();
|
||||||
// Normalize retained PHI/select values only after every supported field read has
|
// Normalize retained PHI/select values only after every supported field read has
|
||||||
|
|||||||
Reference in new issue
Block a user