Support fields in optimizing compiler.
- Required support for temporaries, to be only used by baseline compiler.
- Also fixed a few invalid assumptions around locations and instructions
that don't need materialization. These instructions should not have an Out.
Change-Id: Idc4a30dd95dd18015137300d36bec55fc024cf62
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 9292084..4036a8d 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -18,6 +18,7 @@
#define ART_COMPILER_OPTIMIZING_NODES_H_
#include "locations.h"
+#include "offsets.h"
#include "utils/allocation.h"
#include "utils/arena_bit_vector.h"
#include "utils/growable_array.h"
@@ -75,6 +76,7 @@
maximum_number_of_out_vregs_(0),
number_of_vregs_(0),
number_of_in_vregs_(0),
+ number_of_temporaries_(0),
current_instruction_id_(0) {}
ArenaAllocator* GetArena() const { return arena_; }
@@ -112,6 +114,14 @@
maximum_number_of_out_vregs_ = std::max(new_value, maximum_number_of_out_vregs_);
}
+ void UpdateNumberOfTemporaries(size_t count) {
+ number_of_temporaries_ = std::max(count, number_of_temporaries_);
+ }
+
+ size_t GetNumberOfTemporaries() const {
+ return number_of_temporaries_;
+ }
+
void SetNumberOfVRegs(uint16_t number_of_vregs) {
number_of_vregs_ = number_of_vregs;
}
@@ -163,6 +173,9 @@
// The number of virtual registers used by parameters of this method.
uint16_t number_of_in_vregs_;
+ // The number of temporaries that will be needed for the baseline compiler.
+ size_t number_of_temporaries_;
+
// The current id to assign to a newly added instruction. See HInstruction.id_.
int current_instruction_id_;
@@ -415,6 +428,10 @@
M(StoreLocal) \
M(Sub) \
M(Compare) \
+ M(InstanceFieldGet) \
+ M(InstanceFieldSet) \
+ M(NullCheck) \
+ M(Temporary) \
#define FORWARD_DECLARATION(type) class H##type;
@@ -1254,6 +1271,96 @@
DISALLOW_COPY_AND_ASSIGN(HPhi);
};
+class HNullCheck : public HExpression<1> {
+ public:
+ HNullCheck(HInstruction* value, uint32_t dex_pc)
+ : HExpression(value->GetType()), dex_pc_(dex_pc) {
+ SetRawInputAt(0, value);
+ }
+
+ virtual bool NeedsEnvironment() const { return true; }
+
+ uint32_t GetDexPc() const { return dex_pc_; }
+
+ DECLARE_INSTRUCTION(NullCheck);
+
+ private:
+ const uint32_t dex_pc_;
+
+ DISALLOW_COPY_AND_ASSIGN(HNullCheck);
+};
+
+class FieldInfo : public ValueObject {
+ public:
+ explicit FieldInfo(MemberOffset field_offset)
+ : field_offset_(field_offset) {}
+
+ MemberOffset GetFieldOffset() const { return field_offset_; }
+
+ private:
+ const MemberOffset field_offset_;
+};
+
+class HInstanceFieldGet : public HExpression<1> {
+ public:
+ HInstanceFieldGet(HInstruction* value,
+ Primitive::Type field_type,
+ MemberOffset field_offset)
+ : HExpression(field_type), field_info_(field_offset) {
+ SetRawInputAt(0, value);
+ }
+
+ MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); }
+
+ DECLARE_INSTRUCTION(InstanceFieldGet);
+
+ private:
+ const FieldInfo field_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(HInstanceFieldGet);
+};
+
+class HInstanceFieldSet : public HTemplateInstruction<2> {
+ public:
+ HInstanceFieldSet(HInstruction* object,
+ HInstruction* value,
+ MemberOffset field_offset)
+ : field_info_(field_offset) {
+ SetRawInputAt(0, object);
+ SetRawInputAt(1, value);
+ }
+
+ MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); }
+
+ DECLARE_INSTRUCTION(InstanceFieldSet);
+
+ private:
+ const FieldInfo field_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(HInstanceFieldSet);
+};
+
+/**
+ * Some DEX instructions are folded into multiple HInstructions that need
+ * to stay live until the last HInstruction. This class
+ * is used as a marker for the baseline compiler to ensure its preceding
+ * HInstruction stays live. `index` is the temporary number that is used
+ * for knowing the stack offset where to store the instruction.
+ */
+class HTemporary : public HTemplateInstruction<0> {
+ public:
+ explicit HTemporary(size_t index) : index_(index) {}
+
+ size_t GetIndex() const { return index_; }
+
+ DECLARE_INSTRUCTION(Temporary);
+
+ private:
+ const size_t index_;
+
+ DISALLOW_COPY_AND_ASSIGN(HTemporary);
+};
+
class MoveOperands : public ArenaObject {
public:
MoveOperands(Location source, Location destination)