summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r--compiler/optimizing/nodes.h81
1 files changed, 60 insertions, 21 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 8dd31bef86..486968cf9e 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -35,7 +35,6 @@
#include "offsets.h"
#include "primitive.h"
#include "utils/arena_bit_vector.h"
-#include "utils/growable_array.h"
namespace art {
@@ -370,13 +369,7 @@ class HGraph : public ArenaObject<kArenaAllocGraph> {
void SetHasTryCatch(bool value) { has_try_catch_ = value; }
private:
- void VisitBlockForDominatorTree(HBasicBlock* block,
- HBasicBlock* predecessor,
- ArenaVector<size_t>* visits);
void FindBackEdges(ArenaBitVector* visited);
- void VisitBlockForBackEdges(HBasicBlock* block,
- ArenaBitVector* visited,
- ArenaBitVector* visiting);
void RemoveInstructionsAsUsersFromDeadBlocks(const ArenaBitVector& visited) const;
void RemoveDeadBlocks(const ArenaBitVector& visited);
@@ -825,11 +818,17 @@ class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> {
return EndsWithTryBoundary() ? 1 : GetSuccessors().size();
}
+ // Create a new block between this block and its predecessors. The new block
+ // is added to the graph, all predecessor edges are relinked to it and an edge
+ // is created to `this`. Returns the new empty block. Reverse post order or
+ // loop and try/catch information are not updated.
+ HBasicBlock* CreateImmediateDominator();
+
// Split the block into two blocks just before `cursor`. Returns the newly
// created, latter block. Note that this method will add the block to the
// graph, create a Goto at the end of the former block and will create an edge
// between the blocks. It will not, however, update the reverse post order or
- // loop information.
+ // loop and try/catch information.
HBasicBlock* SplitBefore(HInstruction* cursor);
// Split the block into two blocks just after `cursor`. Returns the newly
@@ -940,6 +939,8 @@ class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> {
// the appropriate try entry will be returned.
const HTryBoundary* ComputeTryEntryOfSuccessors() const;
+ bool HasThrowingInstructions() const;
+
// Returns whether this block dominates the blocked passed as parameter.
bool Dominates(HBasicBlock* block) const;
@@ -949,7 +950,6 @@ class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> {
void SetLifetimeStart(size_t start) { lifetime_start_ = start; }
void SetLifetimeEnd(size_t end) { lifetime_end_ = end; }
-
bool EndsWithControlFlowInstruction() const;
bool EndsWithIf() const;
bool EndsWithTryBoundary() const;
@@ -1056,6 +1056,7 @@ class HLoopInformationOutwardIterator : public ValueObject {
M(NullConstant, Instruction) \
M(NullCheck, Instruction) \
M(Or, BinaryOperation) \
+ M(PackedSwitch, Instruction) \
M(ParallelMove, Instruction) \
M(ParameterValue, Instruction) \
M(Phi, Instruction) \
@@ -2402,6 +2403,40 @@ class HCurrentMethod : public HExpression<0> {
DISALLOW_COPY_AND_ASSIGN(HCurrentMethod);
};
+// PackedSwitch (jump table). A block ending with a PackedSwitch instruction will
+// have one successor for each entry in the switch table, and the final successor
+// will be the block containing the next Dex opcode.
+class HPackedSwitch : public HTemplateInstruction<1> {
+ public:
+ HPackedSwitch(int32_t start_value,
+ uint32_t num_entries,
+ HInstruction* input,
+ uint32_t dex_pc = kNoDexPc)
+ : HTemplateInstruction(SideEffects::None(), dex_pc),
+ start_value_(start_value),
+ num_entries_(num_entries) {
+ SetRawInputAt(0, input);
+ }
+
+ bool IsControlFlow() const OVERRIDE { return true; }
+
+ int32_t GetStartValue() const { return start_value_; }
+
+ uint32_t GetNumEntries() const { return num_entries_; }
+
+ HBasicBlock* GetDefaultBlock() const {
+ // Last entry is the default block.
+ return GetBlock()->GetSuccessor(num_entries_);
+ }
+ DECLARE_INSTRUCTION(PackedSwitch);
+
+ private:
+ const int32_t start_value_;
+ const uint32_t num_entries_;
+
+ DISALLOW_COPY_AND_ASSIGN(HPackedSwitch);
+};
+
class HUnaryOperation : public HExpression<1> {
public:
HUnaryOperation(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc)
@@ -5020,7 +5055,10 @@ static constexpr size_t kDefaultNumberOfMoves = 4;
class HParallelMove : public HTemplateInstruction<0> {
public:
explicit HParallelMove(ArenaAllocator* arena, uint32_t dex_pc = kNoDexPc)
- : HTemplateInstruction(SideEffects::None(), dex_pc), moves_(arena, kDefaultNumberOfMoves) {}
+ : HTemplateInstruction(SideEffects::None(), dex_pc),
+ moves_(arena->Adapter(kArenaAllocMoveOperands)) {
+ moves_.reserve(kDefaultNumberOfMoves);
+ }
void AddMove(Location source,
Location destination,
@@ -5030,15 +5068,15 @@ class HParallelMove : public HTemplateInstruction<0> {
DCHECK(destination.IsValid());
if (kIsDebugBuild) {
if (instruction != nullptr) {
- for (size_t i = 0, e = moves_.Size(); i < e; ++i) {
- if (moves_.Get(i).GetInstruction() == instruction) {
+ for (const MoveOperands& move : moves_) {
+ if (move.GetInstruction() == instruction) {
// Special case the situation where the move is for the spill slot
// of the instruction.
if ((GetPrevious() == instruction)
|| ((GetPrevious() == nullptr)
&& instruction->IsPhi()
&& instruction->GetBlock() == GetBlock())) {
- DCHECK_NE(destination.GetKind(), moves_.Get(i).GetDestination().GetKind())
+ DCHECK_NE(destination.GetKind(), move.GetDestination().GetKind())
<< "Doing parallel moves for the same instruction.";
} else {
DCHECK(false) << "Doing parallel moves for the same instruction.";
@@ -5046,26 +5084,27 @@ class HParallelMove : public HTemplateInstruction<0> {
}
}
}
- for (size_t i = 0, e = moves_.Size(); i < e; ++i) {
- DCHECK(!destination.OverlapsWith(moves_.Get(i).GetDestination()))
+ for (const MoveOperands& move : moves_) {
+ DCHECK(!destination.OverlapsWith(move.GetDestination()))
<< "Overlapped destination for two moves in a parallel move: "
- << moves_.Get(i).GetSource() << " ==> " << moves_.Get(i).GetDestination() << " and "
+ << move.GetSource() << " ==> " << move.GetDestination() << " and "
<< source << " ==> " << destination;
}
}
- moves_.Add(MoveOperands(source, destination, type, instruction));
+ moves_.emplace_back(source, destination, type, instruction);
}
- MoveOperands* MoveOperandsAt(size_t index) const {
- return moves_.GetRawStorage() + index;
+ MoveOperands* MoveOperandsAt(size_t index) {
+ DCHECK_LT(index, moves_.size());
+ return &moves_[index];
}
- size_t NumMoves() const { return moves_.Size(); }
+ size_t NumMoves() const { return moves_.size(); }
DECLARE_INSTRUCTION(ParallelMove);
private:
- GrowableArray<MoveOperands> moves_;
+ ArenaVector<MoveOperands> moves_;
DISALLOW_COPY_AND_ASSIGN(HParallelMove);
};