Inlining support in optimizing.
Currently only inlines simple things that don't require an
environment, such as:
- Returning a constant.
- Returning a parameter.
- Returning an arithmetic operation.
Change-Id: Ie844950cb44f69e104774a3cf7a8dea66bc85661
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 8a25de1..c963b70 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 "invoke_type.h"
#include "locations.h"
#include "offsets.h"
#include "primitive.h"
@@ -30,6 +31,7 @@
class HEnvironment;
class HInstruction;
class HIntConstant;
+class HInvoke;
class HGraphVisitor;
class HPhi;
class HSuspendCheck;
@@ -75,6 +77,8 @@
HInstruction* last_instruction_;
friend class HBasicBlock;
+ friend class HGraph;
+ friend class HInstruction;
friend class HInstructionIterator;
friend class HBackwardInstructionIterator;
@@ -84,7 +88,7 @@
// Control-flow graph of a method. Contains a list of basic blocks.
class HGraph : public ArenaObject<kArenaAllocMisc> {
public:
- explicit HGraph(ArenaAllocator* arena)
+ HGraph(ArenaAllocator* arena, int start_instruction_id = 0)
: arena_(arena),
blocks_(arena, kDefaultNumberOfBlocks),
reverse_post_order_(arena, kDefaultNumberOfBlocks),
@@ -94,7 +98,7 @@
number_of_vregs_(0),
number_of_in_vregs_(0),
temporaries_vreg_slots_(0),
- current_instruction_id_(0) {}
+ current_instruction_id_(start_instruction_id) {}
ArenaAllocator* GetArena() const { return arena_; }
const GrowableArray<HBasicBlock*>& GetBlocks() const { return blocks_; }
@@ -108,8 +112,16 @@
void AddBlock(HBasicBlock* block);
+ // Try building the SSA form of this graph, with dominance computation and loop
+ // recognition. Returns whether it was successful in doing all these steps.
+ bool TryBuildingSsa() {
+ BuildDominatorTree();
+ TransformToSsa();
+ return AnalyzeNaturalLoops();
+ }
+
void BuildDominatorTree();
- void TransformToSSA();
+ void TransformToSsa();
void SimplifyCFG();
// Analyze all natural loops in this graph. Returns false if one
@@ -117,19 +129,31 @@
// back edge.
bool AnalyzeNaturalLoops() const;
+ // Inline this graph in `outer_graph`, replacing the given `invoke` instruction.
+ void InlineInto(HGraph* outer_graph, HInvoke* invoke);
+
void SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor);
void SimplifyLoop(HBasicBlock* header);
- int GetNextInstructionId() {
+ int32_t GetNextInstructionId() {
+ DCHECK_NE(current_instruction_id_, INT32_MAX);
return current_instruction_id_++;
}
+ int32_t GetCurrentInstructionId() const {
+ return current_instruction_id_;
+ }
+
+ void SetCurrentInstructionId(int32_t id) {
+ current_instruction_id_ = id;
+ }
+
uint16_t GetMaximumNumberOfOutVRegs() const {
return maximum_number_of_out_vregs_;
}
- void UpdateMaximumNumberOfOutVRegs(uint16_t new_value) {
- maximum_number_of_out_vregs_ = std::max(new_value, maximum_number_of_out_vregs_);
+ void SetMaximumNumberOfOutVRegs(uint16_t new_value) {
+ maximum_number_of_out_vregs_ = new_value;
}
void UpdateTemporariesVRegSlots(size_t slots) {
@@ -152,10 +176,6 @@
number_of_in_vregs_ = value;
}
- uint16_t GetNumberOfInVRegs() const {
- return number_of_in_vregs_;
- }
-
uint16_t GetNumberOfLocalVRegs() const {
return number_of_vregs_ - number_of_in_vregs_;
}
@@ -200,8 +220,9 @@
size_t temporaries_vreg_slots_;
// The current id to assign to a newly added instruction. See HInstruction.id_.
- int current_instruction_id_;
+ int32_t current_instruction_id_;
+ ART_FRIEND_TEST(GraphTest, IfSuccessorSimpleJoinBlock1);
DISALLOW_COPY_AND_ASSIGN(HGraph);
};
@@ -474,6 +495,9 @@
size_t lifetime_end_;
bool is_catch_block_;
+ friend class HGraph;
+ friend class HInstruction;
+
DISALLOW_COPY_AND_ASSIGN(HBasicBlock);
};
@@ -503,7 +527,7 @@
M(InstanceOf, Instruction) \
M(IntConstant, Constant) \
M(InvokeInterface, Invoke) \
- M(InvokeStatic, Invoke) \
+ M(InvokeStaticOrDirect, Invoke) \
M(InvokeVirtual, Invoke) \
M(LessThan, Condition) \
M(LessThanOrEqual, Condition) \
@@ -748,6 +772,9 @@
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);
+
bool HasOnlyOneUse() const {
return uses_ != nullptr && uses_->GetTail() == nullptr;
}
@@ -836,6 +863,7 @@
const SideEffects side_effects_;
friend class HBasicBlock;
+ friend class HGraph;
friend class HInstructionList;
DISALLOW_COPY_AND_ASSIGN(HInstruction);
@@ -1595,24 +1623,28 @@
DISALLOW_COPY_AND_ASSIGN(HInvoke);
};
-class HInvokeStatic : public HInvoke {
+class HInvokeStaticOrDirect : public HInvoke {
public:
- HInvokeStatic(ArenaAllocator* arena,
- uint32_t number_of_arguments,
- Primitive::Type return_type,
- uint32_t dex_pc,
- uint32_t index_in_dex_cache)
+ HInvokeStaticOrDirect(ArenaAllocator* arena,
+ uint32_t number_of_arguments,
+ Primitive::Type return_type,
+ uint32_t dex_pc,
+ uint32_t index_in_dex_cache,
+ InvokeType invoke_type)
: HInvoke(arena, number_of_arguments, return_type, dex_pc),
- index_in_dex_cache_(index_in_dex_cache) {}
+ index_in_dex_cache_(index_in_dex_cache),
+ invoke_type_(invoke_type) {}
uint32_t GetIndexInDexCache() const { return index_in_dex_cache_; }
+ InvokeType GetInvokeType() const { return invoke_type_; }
- DECLARE_INSTRUCTION(InvokeStatic);
+ DECLARE_INSTRUCTION(InvokeStaticOrDirect);
private:
const uint32_t index_in_dex_cache_;
+ const InvokeType invoke_type_;
- DISALLOW_COPY_AND_ASSIGN(HInvokeStatic);
+ DISALLOW_COPY_AND_ASSIGN(HInvokeStaticOrDirect);
};
class HInvokeVirtual : public HInvoke {
@@ -2425,7 +2457,7 @@
DISALLOW_COPY_AND_ASSIGN(HLoadString);
};
-// TODO: Pass this check to HInvokeStatic nodes.
+// TODO: Pass this check to HInvokeStaticOrDirect nodes.
/**
* Performs an initialization check on its Class object input.
*/