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.h137
1 files changed, 128 insertions, 9 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 3e4028ed7f..30d869d026 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -17,6 +17,7 @@
#ifndef ART_COMPILER_OPTIMIZING_NODES_H_
#define ART_COMPILER_OPTIMIZING_NODES_H_
+#include "entrypoints/quick/quick_entrypoints_enum.h"
#include "invoke_type.h"
#include "locations.h"
#include "offsets.h"
@@ -72,6 +73,15 @@ class HInstructionList {
bool FoundBefore(const HInstruction* instruction1,
const HInstruction* instruction2) const;
+ bool IsEmpty() const { return first_instruction_ == nullptr; }
+ void Clear() { first_instruction_ = last_instruction_ = nullptr; }
+
+ // Update the block of all instructions to be `block`.
+ void SetBlockOfInstructions(HBasicBlock* block) const;
+
+ void AddAfter(HInstruction* cursor, const HInstructionList& instruction_list);
+ void Add(const HInstructionList& instruction_list);
+
private:
HInstruction* first_instruction_;
HInstruction* last_instruction_;
@@ -240,6 +250,10 @@ class HLoopInformation : public ArenaObject<kArenaAllocMisc> {
return header_;
}
+ void SetHeader(HBasicBlock* block) {
+ header_ = block;
+ }
+
HSuspendCheck* GetSuspendCheck() const { return suspend_check_; }
void SetSuspendCheck(HSuspendCheck* check) { suspend_check_ = check; }
bool HasSuspendCheck() const { return suspend_check_ != nullptr; }
@@ -287,6 +301,8 @@ class HLoopInformation : public ArenaObject<kArenaAllocMisc> {
const ArenaBitVector& GetBlocks() const { return blocks_; }
+ void Add(HBasicBlock* block);
+
private:
// Internal recursive implementation of `Populate`.
void PopulateRecursive(HBasicBlock* block);
@@ -350,6 +366,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> {
}
HGraph* GetGraph() const { return graph_; }
+ void SetGraph(HGraph* graph) { graph_ = graph; }
int GetBlockId() const { return block_id_; }
void SetBlockId(int id) { block_id_ = id; }
@@ -357,6 +374,16 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> {
HBasicBlock* GetDominator() const { return dominator_; }
void SetDominator(HBasicBlock* dominator) { dominator_ = dominator; }
void AddDominatedBlock(HBasicBlock* block) { dominated_blocks_.Add(block); }
+ void ReplaceDominatedBlock(HBasicBlock* existing, HBasicBlock* new_block) {
+ for (size_t i = 0, e = dominated_blocks_.Size(); i < e; ++i) {
+ if (dominated_blocks_.Get(i) == existing) {
+ dominated_blocks_.Put(i, new_block);
+ return;
+ }
+ }
+ LOG(FATAL) << "Unreachable";
+ UNREACHABLE();
+ }
int NumberOfBackEdges() const {
return loop_information_ == nullptr
@@ -383,10 +410,22 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> {
successors_.Put(successor_index, new_block);
}
+ void ReplacePredecessor(HBasicBlock* existing, HBasicBlock* new_block) {
+ size_t predecessor_index = GetPredecessorIndexOf(existing);
+ DCHECK_NE(predecessor_index, static_cast<size_t>(-1));
+ existing->RemoveSuccessor(this);
+ new_block->successors_.Add(this);
+ predecessors_.Put(predecessor_index, new_block);
+ }
+
void RemovePredecessor(HBasicBlock* block) {
predecessors_.Delete(block);
}
+ void RemoveSuccessor(HBasicBlock* block) {
+ successors_.Delete(block);
+ }
+
void ClearAllPredecessors() {
predecessors_.Reset();
}
@@ -421,6 +460,26 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> {
return -1;
}
+ // Split the block into two blocks just after `cursor`. Returns the newly
+ // created block. Note that this method just updates raw block information,
+ // like predecessors, successors, dominators, and instruction list. It does not
+ // update the graph, reverse post order, loop information, nor make sure the
+ // blocks are consistent (for example ending with a control flow instruction).
+ HBasicBlock* SplitAfter(HInstruction* cursor);
+
+ // Merge `other` at the end of `this`. Successors and dominated blocks of
+ // `other` are changed to be successors and dominated blocks of `this`. Note
+ // that this method does not update the graph, reverse post order, loop
+ // information, nor make sure the blocks are consistent (for example ending
+ // with a control flow instruction).
+ void MergeWith(HBasicBlock* other);
+
+ // Replace `this` with `other`. Predecessors, successors, and dominated blocks
+ // of `this` are moved to `other`.
+ // Note that this method does not update the graph, reverse post order, loop
+ // information, nor make sure the blocks are consistent (for example ending
+ void ReplaceWith(HBasicBlock* other);
+
void AddInstruction(HInstruction* instruction);
void RemoveInstruction(HInstruction* instruction);
void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor);
@@ -445,8 +504,9 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> {
return loop_information_;
}
- // Set the loop_information_ on this block. This method overrides the current
+ // Set the loop_information_ on this block. Overrides the current
// loop_information if it is an outer loop of the passed loop information.
+ // Note that this method is called while creating the loop information.
void SetInLoop(HLoopInformation* info) {
if (IsLoopHeader()) {
// Nothing to do. This just means `info` is an outer loop.
@@ -464,6 +524,11 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> {
}
}
+ // Raw update of the loop information.
+ void SetLoopInformation(HLoopInformation* info) {
+ loop_information_ = info;
+ }
+
bool IsInLoop() const { return loop_information_ != nullptr; }
// Returns wheter this block dominates the blocked passed as parameter.
@@ -481,7 +546,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> {
void SetIsCatchBlock() { is_catch_block_ = true; }
private:
- HGraph* const graph_;
+ HGraph* graph_;
GrowableArray<HBasicBlock*> predecessors_;
GrowableArray<HBasicBlock*> successors_;
HInstructionList instructions_;
@@ -899,8 +964,8 @@ class HInstruction : public ArenaObject<kArenaAllocMisc> {
void ReplaceWith(HInstruction* instruction);
void ReplaceInput(HInstruction* replacement, size_t index);
- // Insert `this` instruction in `cursor`'s graph, just before `cursor`.
- void InsertBefore(HInstruction* cursor);
+ // Move `this` instruction before `cursor`.
+ void MoveBefore(HInstruction* cursor);
#define INSTRUCTION_TYPE_CHECK(type, super) \
bool Is##type() const { return (As##type() != nullptr); } \
@@ -1794,10 +1859,11 @@ class HInvokeInterface : public HInvoke {
class HNewInstance : public HExpression<0> {
public:
- HNewInstance(uint32_t dex_pc, uint16_t type_index)
+ HNewInstance(uint32_t dex_pc, uint16_t type_index, QuickEntrypointEnum entrypoint)
: HExpression(Primitive::kPrimNot, SideEffects::None()),
dex_pc_(dex_pc),
- type_index_(type_index) {}
+ type_index_(type_index),
+ entrypoint_(entrypoint) {}
uint32_t GetDexPc() const { return dex_pc_; }
uint16_t GetTypeIndex() const { return type_index_; }
@@ -1812,11 +1878,14 @@ class HNewInstance : public HExpression<0> {
bool CanBeNull() const OVERRIDE { return false; }
+ QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; }
+
DECLARE_INSTRUCTION(NewInstance);
private:
const uint32_t dex_pc_;
const uint16_t type_index_;
+ const QuickEntrypointEnum entrypoint_;
DISALLOW_COPY_AND_ASSIGN(HNewInstance);
};
@@ -1837,10 +1906,14 @@ class HNeg : public HUnaryOperation {
class HNewArray : public HExpression<1> {
public:
- HNewArray(HInstruction* length, uint32_t dex_pc, uint16_t type_index)
+ HNewArray(HInstruction* length,
+ uint32_t dex_pc,
+ uint16_t type_index,
+ QuickEntrypointEnum entrypoint)
: HExpression(Primitive::kPrimNot, SideEffects::None()),
dex_pc_(dex_pc),
- type_index_(type_index) {
+ type_index_(type_index),
+ entrypoint_(entrypoint) {
SetRawInputAt(0, length);
}
@@ -1852,11 +1925,14 @@ class HNewArray : public HExpression<1> {
bool CanBeNull() const OVERRIDE { return false; }
+ QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; }
+
DECLARE_INSTRUCTION(NewArray);
private:
const uint32_t dex_pc_;
const uint16_t type_index_;
+ const QuickEntrypointEnum entrypoint_;
DISALLOW_COPY_AND_ASSIGN(HNewArray);
};
@@ -2168,6 +2244,8 @@ class HTypeConversion : public HExpression<1> {
DISALLOW_COPY_AND_ASSIGN(HTypeConversion);
};
+static constexpr uint32_t kNoRegNumber = -1;
+
class HPhi : public HInstruction {
public:
HPhi(ArenaAllocator* arena, uint32_t reg_number, size_t number_of_inputs, Primitive::Type type)
@@ -2562,6 +2640,12 @@ class HLoadClass : public HExpression<0> {
return MustGenerateClinitCheck() || !is_referrers_class_;
}
+ bool CanThrow() const OVERRIDE {
+ // May call runtime and and therefore can throw.
+ // TODO: finer grain decision.
+ return !is_referrers_class_;
+ }
+
DECLARE_INSTRUCTION(LoadClass);
private:
@@ -2726,12 +2810,14 @@ class HThrow : public HTemplateInstruction<1> {
bool NeedsEnvironment() const OVERRIDE { return true; }
+ bool CanThrow() const OVERRIDE { return true; }
+
uint32_t GetDexPc() const { return dex_pc_; }
DECLARE_INSTRUCTION(Throw);
private:
- uint32_t dex_pc_;
+ const uint32_t dex_pc_;
DISALLOW_COPY_AND_ASSIGN(HThrow);
};
@@ -3063,6 +3149,39 @@ class HPostOrderIterator : public ValueObject {
DISALLOW_COPY_AND_ASSIGN(HPostOrderIterator);
};
+// Iterator over the blocks that art part of the loop. Includes blocks part
+// of an inner loop. The order in which the blocks are iterated is on their
+// block id.
+class HBlocksInLoopIterator : public ValueObject {
+ public:
+ explicit HBlocksInLoopIterator(const HLoopInformation& info)
+ : blocks_in_loop_(info.GetBlocks()),
+ blocks_(info.GetHeader()->GetGraph()->GetBlocks()),
+ index_(0) {
+ if (!blocks_in_loop_.IsBitSet(index_)) {
+ Advance();
+ }
+ }
+
+ bool Done() const { return index_ == blocks_.Size(); }
+ HBasicBlock* Current() const { return blocks_.Get(index_); }
+ void Advance() {
+ ++index_;
+ for (size_t e = blocks_.Size(); index_ < e; ++index_) {
+ if (blocks_in_loop_.IsBitSet(index_)) {
+ break;
+ }
+ }
+ }
+
+ private:
+ const BitVector& blocks_in_loop_;
+ const GrowableArray<HBasicBlock*>& blocks_;
+ size_t index_;
+
+ DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopIterator);
+};
+
} // namespace art
#endif // ART_COMPILER_OPTIMIZING_NODES_H_