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.h23
1 files changed, 23 insertions, 0 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index afb995d438..12ea059d3f 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -650,6 +650,7 @@ class HLoopInformation : public ArenaObject<kArenaAllocLoopInfo> {
: header_(header),
suspend_check_(nullptr),
irreducible_(false),
+ contains_irreducible_loop_(false),
back_edges_(graph->GetArena()->Adapter(kArenaAllocLoopInfoBackEdges)),
// Make bit vector growable, as the number of blocks may change.
blocks_(graph->GetArena(), graph->GetBlocks().size(), true, kArenaAllocLoopInfoBackEdges) {
@@ -657,6 +658,7 @@ class HLoopInformation : public ArenaObject<kArenaAllocLoopInfo> {
}
bool IsIrreducible() const { return irreducible_; }
+ bool ContainsIrreducibleLoop() const { return contains_irreducible_loop_; }
void Dump(std::ostream& os);
@@ -725,6 +727,12 @@ class HLoopInformation : public ArenaObject<kArenaAllocLoopInfo> {
blocks_.ClearAllBits();
}
+ bool HasBackEdgeNotDominatedByHeader() const;
+
+ bool IsPopulated() const {
+ return blocks_.GetHighestBitSet() != -1;
+ }
+
private:
// Internal recursive implementation of `Populate`.
void PopulateRecursive(HBasicBlock* block);
@@ -733,6 +741,7 @@ class HLoopInformation : public ArenaObject<kArenaAllocLoopInfo> {
HBasicBlock* header_;
HSuspendCheck* suspend_check_;
bool irreducible_;
+ bool contains_irreducible_loop_;
ArenaVector<HBasicBlock*> back_edges_;
ArenaBitVector blocks_;
@@ -5226,9 +5235,22 @@ class HArrayLength : public HExpression<1> {
return obj == InputAt(0);
}
+ void MarkAsStringLength() { SetPackedFlag<kFlagIsStringLength>(); }
+ bool IsStringLength() const { return GetPackedFlag<kFlagIsStringLength>(); }
+
DECLARE_INSTRUCTION(ArrayLength);
private:
+ // We treat a String as an array, creating the HArrayLength from String.length()
+ // or String.isEmpty() intrinsic in the instruction simplifier. We can always
+ // determine whether a particular HArrayLength is actually a String.length() by
+ // looking at the type of the input but that requires holding the mutator lock, so
+ // we prefer to use a flag, so that code generators don't need to do the locking.
+ static constexpr size_t kFlagIsStringLength = kNumberOfExpressionPackedBits;
+ static constexpr size_t kNumberOfArrayLengthPackedBits = kFlagIsStringLength + 1;
+ static_assert(kNumberOfArrayLengthPackedBits <= HInstruction::kMaxNumberOfPackedBits,
+ "Too many packed fields.");
+
DISALLOW_COPY_AND_ASSIGN(HArrayLength);
};
@@ -5530,6 +5552,7 @@ class HLoadString : public HExpression<1> {
SetPackedFlag<kFlagIsInDexCache>(true);
DCHECK(!NeedsEnvironment());
RemoveEnvironment();
+ SetSideEffects(SideEffects::None());
}
size_t InputCount() const OVERRIDE {