blob: 8304c30c2e06163473af6f73eb8974831288f08f [file] [log] [blame]
// Copyright (c) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/reduce/conditional_branch_to_simple_conditional_branch_reduction_opportunity.h"
#include "source/reduce/reduction_util.h"
namespace spvtools {
namespace reduce {
ConditionalBranchToSimpleConditionalBranchReductionOpportunity::
ConditionalBranchToSimpleConditionalBranchReductionOpportunity(
opt::IRContext* context,
opt::Instruction* conditional_branch_instruction, bool redirect_to_true)
: context_(context),
conditional_branch_instruction_(conditional_branch_instruction),
redirect_to_true_(redirect_to_true) {}
bool ConditionalBranchToSimpleConditionalBranchReductionOpportunity::
PreconditionHolds() {
// Another opportunity may have already simplified this conditional branch,
// which should disable this opportunity.
return conditional_branch_instruction_->GetSingleWordInOperand(
kTrueBranchOperandIndex) !=
conditional_branch_instruction_->GetSingleWordInOperand(
kFalseBranchOperandIndex);
}
void ConditionalBranchToSimpleConditionalBranchReductionOpportunity::Apply() {
uint32_t operand_to_modify =
redirect_to_true_ ? kFalseBranchOperandIndex : kTrueBranchOperandIndex;
uint32_t operand_to_copy =
redirect_to_true_ ? kTrueBranchOperandIndex : kFalseBranchOperandIndex;
auto old_successor_block_id =
conditional_branch_instruction_->GetSingleWordInOperand(
operand_to_modify);
// Do the branch redirection.
conditional_branch_instruction_->SetInOperand(
operand_to_modify,
{conditional_branch_instruction_->GetSingleWordInOperand(
operand_to_copy)});
// The old successor block may have phi instructions; these will need to
// respect the change in edges.
AdaptPhiInstructionsForRemovedEdge(
context_->get_instr_block(conditional_branch_instruction_)->id(),
context_->cfg()->block(old_successor_block_id));
// We have changed the CFG.
context_->InvalidateAnalysesExceptFor(
opt::IRContext::Analysis::kAnalysisNone);
}
} // namespace reduce
} // namespace spvtools