blob: b91006be0dfd5c9b1d3c1acc1df720aa079bf2d9 [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* 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.
*/
#ifndef ART_COMPILER_OPTIMIZING_DEAD_CODE_ELIMINATION_H_
#define ART_COMPILER_OPTIMIZING_DEAD_CODE_ELIMINATION_H_
#include "base/macros.h"
#include "nodes.h"
#include "optimization.h"
#include "optimizing_compiler_stats.h"
namespace art HIDDEN {
/**
* Optimization pass performing dead code elimination (removal of
* unused variables/instructions) on the SSA form.
*/
class HDeadCodeElimination : public HOptimization {
public:
HDeadCodeElimination(HGraph* graph, OptimizingCompilerStats* stats, const char* name)
: HOptimization(graph, name, stats) {}
bool Run() override;
static constexpr const char* kDeadCodeEliminationPassName = "dead_code_elimination";
private:
void MaybeRecordDeadBlock(HBasicBlock* block);
void MaybeRecordSimplifyIf();
// If `force_recomputation` is true, we will recompute the dominance information even when we
// didn't delete any blocks. `force_loop_recomputation` is similar but it also forces the loop
// information recomputation.
bool RemoveDeadBlocks(bool force_recomputation = false, bool force_loop_recomputation = false);
void RemoveDeadInstructions();
bool SimplifyAlwaysThrows();
bool SimplifyIfs();
void ConnectSuccessiveBlocks();
// Updates the graph flags related to instructions (e.g. HasSIMD()) since we may have eliminated
// the relevant instructions. There's no need to update `SetHasTryCatch` since we do that in
// `ComputeTryBlockInformation`. Similarly with `HasLoops` and `HasIrreducibleLoops`: They are
// cleared in `ClearLoopInformation` and then set as true as part of `HLoopInformation::Populate`,
// if needed.
void UpdateGraphFlags();
// Helper struct to eliminate tries.
struct TryBelongingInformation;
// Disconnects `block`'s handlers and update its `TryBoundary` instruction to a `Goto`.
// Sets `any_block_in_loop` to true if any block is currently a loop to later update the loop
// information if needed.
void DisconnectHandlersAndUpdateTryBoundary(HBasicBlock* block,
/* out */ bool* any_block_in_loop);
// Returns true iff the try doesn't contain throwing instructions.
bool CanPerformTryRemoval(const TryBelongingInformation& try_belonging_info);
// Removes the try by disconnecting all try entries and exits from their handlers. Also updates
// the graph in the case that a `TryBoundary` instruction of kind `exit` has the Exit block as
// its successor.
void RemoveTry(HBasicBlock* try_entry,
const TryBelongingInformation& try_belonging_info,
bool* any_block_in_loop);
// Checks which tries (if any) are currently in the graph, coalesces the different try entries
// that are referencing the same try, and removes the tries which don't contain any throwing
// instructions.
bool RemoveUnneededTries();
DISALLOW_COPY_AND_ASSIGN(HDeadCodeElimination);
};
} // namespace art
#endif // ART_COMPILER_OPTIMIZING_DEAD_CODE_ELIMINATION_H_