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.h92
1 files changed, 84 insertions, 8 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 41c2f17cd9..d90c1fb335 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -1011,6 +1011,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> {
// Replace instruction `initial` with `replacement` within this block.
void ReplaceAndRemoveInstructionWith(HInstruction* initial,
HInstruction* replacement);
+ void MoveInstructionBefore(HInstruction* insn, HInstruction* cursor);
void AddPhi(HPhi* phi);
void InsertPhiAfter(HPhi* instruction, HPhi* cursor);
// RemoveInstruction and RemovePhi delete a given instruction from the respective
@@ -1161,6 +1162,7 @@ class HLoopInformationOutwardIterator : public ValueObject {
M(BoundsCheck, Instruction) \
M(BoundType, Instruction) \
M(CheckCast, Instruction) \
+ M(ClassTableGet, Instruction) \
M(ClearException, Instruction) \
M(ClinitCheck, Instruction) \
M(Compare, BinaryOperation) \
@@ -1220,6 +1222,7 @@ class HLoopInformationOutwardIterator : public ValueObject {
M(UnresolvedInstanceFieldSet, Instruction) \
M(UnresolvedStaticFieldGet, Instruction) \
M(UnresolvedStaticFieldSet, Instruction) \
+ M(Select, Instruction) \
M(StoreLocal, Instruction) \
M(Sub, BinaryOperation) \
M(SuspendCheck, Instruction) \
@@ -1819,6 +1822,7 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {
dex_pc_(dex_pc),
id_(-1),
ssa_index_(-1),
+ emitted_at_use_site_(false),
environment_(nullptr),
locations_(nullptr),
live_interval_(nullptr),
@@ -2081,6 +2085,9 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {
// The caller must ensure that this is safe to do.
void RemoveEnvironmentUsers();
+ bool IsEmittedAtUseSite() const { return emitted_at_use_site_; }
+ void MarkEmittedAtUseSite() { emitted_at_use_site_ = true; }
+
protected:
virtual const HUserRecord<HInstruction*> InputRecordAt(size_t i) const = 0;
virtual void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) = 0;
@@ -2102,6 +2109,10 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {
// When doing liveness analysis, instructions that have uses get an SSA index.
int ssa_index_;
+ // If set, the machine code for this instruction is assumed to be generated by
+ // its users. Used by liveness analysis to compute use positions accordingly.
+ bool emitted_at_use_site_;
+
// List of instructions that have this instruction as input.
HUseList<HInstruction*> uses_;
@@ -2542,6 +2553,44 @@ class HCurrentMethod : public HExpression<0> {
DISALLOW_COPY_AND_ASSIGN(HCurrentMethod);
};
+// Fetches an ArtMethod from the virtual table or the interface method table
+// of a class.
+class HClassTableGet : public HExpression<1> {
+ public:
+ enum TableKind {
+ kVTable,
+ kIMTable,
+ };
+ HClassTableGet(HInstruction* cls,
+ Primitive::Type type,
+ TableKind kind,
+ size_t index,
+ uint32_t dex_pc)
+ : HExpression(type, SideEffects::None(), dex_pc),
+ index_(index),
+ table_kind_(kind) {
+ SetRawInputAt(0, cls);
+ }
+
+ bool CanBeMoved() const OVERRIDE { return true; }
+ bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
+ return other->AsClassTableGet()->GetIndex() == index_ &&
+ other->AsClassTableGet()->GetTableKind() == table_kind_;
+ }
+
+ TableKind GetTableKind() const { return table_kind_; }
+ size_t GetIndex() const { return index_; }
+
+ DECLARE_INSTRUCTION(ClassTableGet);
+
+ private:
+ // The index of the ArtMethod in the table.
+ const size_t index_;
+ const TableKind table_kind_;
+
+ DISALLOW_COPY_AND_ASSIGN(HClassTableGet);
+};
+
// 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.
@@ -2711,12 +2760,8 @@ class HCondition : public HBinaryOperation {
public:
HCondition(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
: HBinaryOperation(Primitive::kPrimBoolean, first, second, SideEffects::None(), dex_pc),
- needs_materialization_(true),
bias_(ComparisonBias::kNoBias) {}
- bool NeedsMaterialization() const { return needs_materialization_; }
- void ClearNeedsMaterialization() { needs_materialization_ = false; }
-
// For code generation purposes, returns whether this instruction is just before
// `instruction`, and disregard moves in between.
bool IsBeforeWhenDisregardMoves(HInstruction* instruction) const;
@@ -2748,10 +2793,6 @@ class HCondition : public HBinaryOperation {
}
private:
- // For register allocation purposes, returns whether this instruction needs to be
- // materialized (that is, not just be in the processor flags).
- bool needs_materialization_;
-
// Needed if we merge a HCompare into a HCondition.
ComparisonBias bias_;
@@ -5586,6 +5627,41 @@ class HMonitorOperation : public HTemplateInstruction<1> {
DISALLOW_COPY_AND_ASSIGN(HMonitorOperation);
};
+class HSelect : public HExpression<3> {
+ public:
+ HSelect(HInstruction* condition,
+ HInstruction* true_value,
+ HInstruction* false_value,
+ uint32_t dex_pc)
+ : HExpression(HPhi::ToPhiType(true_value->GetType()), SideEffects::None(), dex_pc) {
+ DCHECK_EQ(HPhi::ToPhiType(true_value->GetType()), HPhi::ToPhiType(false_value->GetType()));
+
+ // First input must be `true_value` or `false_value` to allow codegens to
+ // use the SameAsFirstInput allocation policy. We make it `false_value`, so
+ // that architectures which implement HSelect as a conditional move also
+ // will not need to invert the condition.
+ SetRawInputAt(0, false_value);
+ SetRawInputAt(1, true_value);
+ SetRawInputAt(2, condition);
+ }
+
+ HInstruction* GetFalseValue() const { return InputAt(0); }
+ HInstruction* GetTrueValue() const { return InputAt(1); }
+ HInstruction* GetCondition() const { return InputAt(2); }
+
+ bool CanBeMoved() const OVERRIDE { return true; }
+ bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { return true; }
+
+ bool CanBeNull() const OVERRIDE {
+ return GetTrueValue()->CanBeNull() || GetFalseValue()->CanBeNull();
+ }
+
+ DECLARE_INSTRUCTION(Select);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HSelect);
+};
+
class MoveOperands : public ArenaObject<kArenaAllocMoveOperands> {
public:
MoveOperands(Location source,