Consider atomics that load when analyzing live stores in ADCE (#1956) (#1958)

Consider atomics that load when analyzing live stores in ADCE.

Previously it asserted that the base of an OpImageTexelPointer should
be an image. It is actually a pointer to an image, so IsValidBasePointer
should suffice.
This commit is contained in:
greg-lunarg 2018-10-12 06:46:35 -06:00 committed by Steven Perron
parent 1c128aa9ef
commit e545564887
6 changed files with 21 additions and 5 deletions

View File

@ -391,10 +391,9 @@ bool spvOpcodeIsBranch(SpvOp opcode) {
}
}
bool spvOpcodeIsAtomicOp(const SpvOp opcode) {
bool spvOpcodeIsAtomicWithLoad(const SpvOp opcode) {
switch (opcode) {
case SpvOpAtomicLoad:
case SpvOpAtomicStore:
case SpvOpAtomicExchange:
case SpvOpAtomicCompareExchange:
case SpvOpAtomicCompareExchangeWeak:
@ -410,13 +409,17 @@ bool spvOpcodeIsAtomicOp(const SpvOp opcode) {
case SpvOpAtomicOr:
case SpvOpAtomicXor:
case SpvOpAtomicFlagTestAndSet:
case SpvOpAtomicFlagClear:
return true;
default:
return false;
}
}
bool spvOpcodeIsAtomicOp(const SpvOp opcode) {
return (spvOpcodeIsAtomicWithLoad(opcode) || opcode == SpvOpAtomicStore ||
opcode == SpvOpAtomicFlagClear);
}
bool spvOpcodeIsReturn(SpvOp opcode) {
switch (opcode) {
case SpvOpReturn:

View File

@ -100,6 +100,10 @@ bool spvOpcodeIsDecoration(const SpvOp opcode);
// function only considers core instructions.
bool spvOpcodeIsLoad(const SpvOp opcode);
// Returns true if the opcode is an atomic operation that uses the original
// value.
bool spvOpcodeIsAtomicWithLoad(const SpvOp opcode);
// Returns true if the opcode is an atomic operation.
bool spvOpcodeIsAtomicOp(const SpvOp opcode);

View File

@ -439,7 +439,7 @@ bool AggressiveDCEPass::AggressiveDCE(Function* func) {
AddBreaksAndContinuesToWorklist(mergeInst);
}
// If local load, add all variable's stores if variable not already live
if (liveInst->opcode() == SpvOpLoad) {
if (liveInst->opcode() == SpvOpLoad || liveInst->IsAtomicWithLoad()) {
uint32_t varId;
(void)GetPtr(liveInst, &varId);
if (varId != 0) {

View File

@ -187,6 +187,7 @@ Instruction* Instruction::GetBaseAddress() const {
case SpvOpStore:
case SpvOpAccessChain:
case SpvOpInBoundsAccessChain:
case SpvOpImageTexelPointer:
case SpvOpCopyObject:
// A load or store through a pointer.
assert(base_inst->IsValidBasePointer() &&

View File

@ -349,6 +349,10 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
// uniform buffer.
bool IsVulkanUniformBuffer() const;
// Returns true if the instruction is an atom operation that uses original
// value.
inline bool IsAtomicWithLoad() const;
// Returns true if the instruction is an atom operation.
inline bool IsAtomicOp() const;
@ -728,6 +732,10 @@ bool Instruction::IsDecoration() const {
bool Instruction::IsLoad() const { return spvOpcodeIsLoad(opcode()); }
bool Instruction::IsAtomicWithLoad() const {
return spvOpcodeIsAtomicWithLoad(opcode());
}
bool Instruction::IsAtomicOp() const { return spvOpcodeIsAtomicOp(opcode()); }
bool Instruction::IsConstant() const {

View File

@ -119,7 +119,7 @@ Instruction* MemPass::GetPtr(uint32_t ptrId, uint32_t* varId) {
Instruction* MemPass::GetPtr(Instruction* ip, uint32_t* varId) {
assert(ip->opcode() == SpvOpStore || ip->opcode() == SpvOpLoad ||
ip->opcode() == SpvOpImageTexelPointer);
ip->opcode() == SpvOpImageTexelPointer || ip->IsAtomicWithLoad());
// All of these opcode place the pointer in position 0.
const uint32_t ptrId = ip->GetSingleWordInOperand(0);