Remove `spvOpcodeTerminatesExecution` (#4931)
* Remove `spvOpcodeTerminatesExecution` This function is the same as `spvOpcodeIsAbort` except for OpUnreachable. The names are so close in meaning that it is hard to distinguish them. I've removed `spvOpcodeTerminatesExecution` since it is used in only a single place. I've special cased OpUnreachable in that location. At the same time, I fixed up some comments related to the use of the TerminatesExecution and IsAbort functions. Following up on #4930. * Fix comments
This commit is contained in:
Родитель
21146c1b4b
Коммит
f98473ceeb
|
@ -468,19 +468,6 @@ bool spvOpcodeIsBlockTerminator(SpvOp opcode) {
|
|||
return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
|
||||
}
|
||||
|
||||
bool spvOpcodeTerminatesExecution(SpvOp opcode) {
|
||||
switch (opcode) {
|
||||
case SpvOpKill:
|
||||
case SpvOpTerminateInvocation:
|
||||
case SpvOpTerminateRayKHR:
|
||||
case SpvOpIgnoreIntersectionKHR:
|
||||
case SpvOpEmitMeshTasksEXT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool spvOpcodeIsBaseOpaqueType(SpvOp opcode) {
|
||||
switch (opcode) {
|
||||
case SpvOpTypeImage:
|
||||
|
|
|
@ -110,18 +110,16 @@ bool spvOpcodeIsBranch(SpvOp opcode);
|
|||
// Returns true if the given opcode is a return instruction.
|
||||
bool spvOpcodeIsReturn(SpvOp opcode);
|
||||
|
||||
// Returns true if the given opcode aborts execution.
|
||||
// Returns true if the given opcode aborts execution. To abort means that after
|
||||
// executing that instruction, no other instructions will be executed regardless
|
||||
// of the context in which the instruction appears. Note that `OpUnreachable`
|
||||
// is considered an abort even if its behaviour is undefined.
|
||||
bool spvOpcodeIsAbort(SpvOp opcode);
|
||||
|
||||
// Returns true if the given opcode is a return instruction or it aborts
|
||||
// execution.
|
||||
bool spvOpcodeIsReturnOrAbort(SpvOp opcode);
|
||||
|
||||
// Returns true if the given opcode is a kill instruction or it terminates
|
||||
// execution. Note that branches, returns, and unreachables do not terminate
|
||||
// execution.
|
||||
bool spvOpcodeTerminatesExecution(SpvOp opcode);
|
||||
|
||||
// Returns true if the given opcode is a basic block terminator.
|
||||
bool spvOpcodeIsBlockTerminator(SpvOp opcode);
|
||||
|
||||
|
|
|
@ -794,22 +794,25 @@ bool InlinePass::IsInlinableFunction(Function* func) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Do not inline functions with an OpKill if they are called from a continue
|
||||
// construct. If it is inlined into a continue construct it will generate
|
||||
// invalid code.
|
||||
// Do not inline functions with an abort instruction if they are called from a
|
||||
// continue construct. If it is inlined into a continue construct the backedge
|
||||
// will no longer post-dominate the continue target, which is invalid. An
|
||||
// `OpUnreachable` is acceptable because it will not change post-dominance if
|
||||
// it is statically unreachable.
|
||||
bool func_is_called_from_continue =
|
||||
funcs_called_from_continue_.count(func->result_id()) != 0;
|
||||
|
||||
if (func_is_called_from_continue && ContainsKillOrTerminateInvocation(func)) {
|
||||
if (func_is_called_from_continue && ContainsAbortOtherThanUnreachable(func)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InlinePass::ContainsKillOrTerminateInvocation(Function* func) const {
|
||||
bool InlinePass::ContainsAbortOtherThanUnreachable(Function* func) const {
|
||||
return !func->WhileEachInst([](Instruction* inst) {
|
||||
return !spvOpcodeTerminatesExecution(inst->opcode());
|
||||
return inst->opcode() == SpvOpUnreachable ||
|
||||
!spvOpcodeIsAbort(inst->opcode());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -139,9 +139,9 @@ class InlinePass : public Pass {
|
|||
// Return true if |func| is a function that can be inlined.
|
||||
bool IsInlinableFunction(Function* func);
|
||||
|
||||
// Returns true if |func| contains an OpKill or OpTerminateInvocation
|
||||
// instruction.
|
||||
bool ContainsKillOrTerminateInvocation(Function* func) const;
|
||||
// Returns true if |func| contains an abort instruction that is not an
|
||||
// `OpUnreachable` instruction.
|
||||
bool ContainsAbortOtherThanUnreachable(Function* func) const;
|
||||
|
||||
// Update phis in succeeding blocks to point to new last block
|
||||
void UpdateSucceedingPhis(
|
||||
|
|
Загрузка…
Ссылка в новой задаче