Refactor safepoints in register allocator.
This is in preparation for adding logic around callee/caller
saved in the register allocator.
Change-Id: I4204169f0a6a01074880538833144be7b0810882
diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h
index d2da84c..b6e4028 100644
--- a/compiler/optimizing/ssa_liveness_analysis.h
+++ b/compiler/optimizing/ssa_liveness_analysis.h
@@ -149,6 +149,39 @@
DISALLOW_COPY_AND_ASSIGN(UsePosition);
};
+class SafepointPosition : public ArenaObject<kArenaAllocMisc> {
+ public:
+ explicit SafepointPosition(HInstruction* instruction)
+ : instruction_(instruction),
+ next_(nullptr) {}
+
+ void SetNext(SafepointPosition* next) {
+ next_ = next;
+ }
+
+ size_t GetPosition() const {
+ return instruction_->GetLifetimePosition();
+ }
+
+ SafepointPosition* GetNext() const {
+ return next_;
+ }
+
+ LocationSummary* GetLocations() const {
+ return instruction_->GetLocations();
+ }
+
+ HInstruction* GetInstruction() const {
+ return instruction_;
+ }
+
+ private:
+ HInstruction* const instruction_;
+ SafepointPosition* next_;
+
+ DISALLOW_COPY_AND_ASSIGN(SafepointPosition);
+};
+
/**
* An interval is a list of disjoint live ranges where an instruction is live.
* Each instruction that has uses gets an interval.
@@ -703,6 +736,22 @@
UNREACHABLE();
}
+ void AddSafepoint(HInstruction* instruction) {
+ SafepointPosition* safepoint = new (allocator_) SafepointPosition(instruction);
+ if (first_safepoint_ == nullptr) {
+ first_safepoint_ = last_safepoint_ = safepoint;
+ } else {
+ DCHECK_LT(last_safepoint_->GetPosition(), safepoint->GetPosition());
+ last_safepoint_->SetNext(safepoint);
+ last_safepoint_ = safepoint;
+ }
+ }
+
+ SafepointPosition* GetFirstSafepoint() const {
+ DCHECK_EQ(GetParent(), this) << "Only the first sibling lists safepoints";
+ return first_safepoint_;
+ }
+
private:
LiveInterval(ArenaAllocator* allocator,
Primitive::Type type,
@@ -715,6 +764,8 @@
: allocator_(allocator),
first_range_(nullptr),
last_range_(nullptr),
+ first_safepoint_(nullptr),
+ last_safepoint_(nullptr),
last_visited_range_(nullptr),
first_use_(nullptr),
type_(type),
@@ -771,6 +822,10 @@
LiveRange* first_range_;
LiveRange* last_range_;
+ // Safepoints where this interval is live. Only set in the parent interval.
+ SafepointPosition* first_safepoint_;
+ SafepointPosition* last_safepoint_;
+
// Last visited range. This is a range search optimization leveraging the fact
// that the register allocator does a linear scan through the intervals.
LiveRange* last_visited_range_;