diff --git a/compiler/optimizing/register_allocator_graph_color.cc b/compiler/optimizing/register_allocator_graph_color.cc
index 4f043f5..79ca5a0 100644
--- a/compiler/optimizing/register_allocator_graph_color.cc
+++ b/compiler/optimizing/register_allocator_graph_color.cc
@@ -37,158 +37,6 @@
 // intervals are split when coloring fails.
 static constexpr size_t kMaxGraphColoringAttemptsDebug = 100;
 
-// We always want to avoid spilling inside loops.
-static constexpr size_t kLoopSpillWeightMultiplier = 10;
-
-// If we avoid moves in single jump blocks, we can avoid jumps to jumps.
-static constexpr size_t kSingleJumpBlockWeightMultiplier = 2;
-
-// We avoid moves in blocks that dominate the exit block, since these blocks will
-// be executed on every path through the method.
-static constexpr size_t kDominatesExitBlockWeightMultiplier = 2;
-
-enum class CoalesceKind {
-  kAdjacentSibling,       // Prevents moves at interval split points.
-  kFixedOutputSibling,    // Prevents moves from a fixed output location.
-  kFixedInput,            // Prevents moves into a fixed input location.
-  kNonlinearControlFlow,  // Prevents moves between blocks.
-  kPhi,                   // Prevents phi resolution moves.
-  kFirstInput,            // Prevents a single input move.
-  kAnyInput,              // May lead to better instruction selection / smaller encodings.
-};
-
-std::ostream& operator<<(std::ostream& os, const CoalesceKind& kind) {
-  return os << static_cast<typename std::underlying_type<CoalesceKind>::type>(kind);
-}
-
-static size_t LoopDepthAt(HBasicBlock* block) {
-  HLoopInformation* loop_info = block->GetLoopInformation();
-  size_t depth = 0;
-  while (loop_info != nullptr) {
-    ++depth;
-    loop_info = loop_info->GetPreHeader()->GetLoopInformation();
-  }
-  return depth;
-}
-
-// Return the runtime cost of inserting a move instruction at the specified location.
-static size_t CostForMoveAt(size_t position, const SsaLivenessAnalysis& liveness) {
-  HBasicBlock* block = liveness.GetBlockFromPosition(position / 2);
-  DCHECK(block != nullptr);
-  size_t cost = 1;
-  if (block->IsSingleJump()) {
-    cost *= kSingleJumpBlockWeightMultiplier;
-  }
-  if (block->Dominates(block->GetGraph()->GetExitBlock())) {
-    cost *= kDominatesExitBlockWeightMultiplier;
-  }
-  for (size_t loop_depth = LoopDepthAt(block); loop_depth > 0; --loop_depth) {
-    cost *= kLoopSpillWeightMultiplier;
-  }
-  return cost;
-}
-
-// In general, we estimate coalesce priority by whether it will definitely avoid a move,
-// and by how likely it is to create an interference graph that's harder to color.
-static size_t ComputeCoalescePriority(CoalesceKind kind,
-                                      size_t position,
-                                      const SsaLivenessAnalysis& liveness) {
-  if (kind == CoalesceKind::kAnyInput) {
-    // This type of coalescing can affect instruction selection, but not moves, so we
-    // give it the lowest priority.
-    return 0;
-  } else {
-    return CostForMoveAt(position, liveness);
-  }
-}
-
-enum class CoalesceStage {
-  kWorklist,  // Currently in the iterative coalescing worklist.
-  kActive,    // Not in a worklist, but could be considered again during iterative coalescing.
-  kInactive,  // No longer considered until last-chance coalescing.
-  kDefunct,   // Either the two nodes interfere, or have already been coalesced.
-};
-
-std::ostream& operator<<(std::ostream& os, const CoalesceStage& stage) {
-  return os << static_cast<typename std::underlying_type<CoalesceStage>::type>(stage);
-}
-
-// Represents a coalesce opportunity between two nodes.
-struct CoalesceOpportunity : public ArenaObject<kArenaAllocRegisterAllocator> {
-  CoalesceOpportunity(InterferenceNode* a,
-                      InterferenceNode* b,
-                      CoalesceKind kind,
-                      size_t position,
-                      const SsaLivenessAnalysis& liveness)
-        : node_a(a),
-          node_b(b),
-          stage(CoalesceStage::kWorklist),
-          priority(ComputeCoalescePriority(kind, position, liveness)) {}
-
-  InterferenceNode* const node_a;
-  InterferenceNode* const node_b;
-
-  // The current stage of this coalesce opportunity, indicating whether it is in a worklist,
-  // and whether it should still be considered.
-  CoalesceStage stage;
-
-  // The priority of this coalesce opportunity, based on heuristics.
-  const size_t priority;
-};
-
-enum class NodeStage {
-  kInitial,           // Uninitialized.
-  kPrecolored,        // Marks fixed nodes.
-  kSafepoint,         // Marks safepoint nodes.
-  kPrunable,          // Marks uncolored nodes in the interference graph.
-  kSimplifyWorklist,  // Marks non-move-related nodes with degree less than the number of registers.
-  kFreezeWorklist,    // Marks move-related nodes with degree less than the number of registers.
-  kSpillWorklist,     // Marks nodes with degree greater or equal to the number of registers.
-  kPruned             // Marks nodes already pruned from the interference graph.
-};
-
-std::ostream& operator<<(std::ostream& os, const NodeStage& stage) {
-  return os << static_cast<typename std::underlying_type<NodeStage>::type>(stage);
-}
-
-// Returns the estimated cost of spilling a particular live interval.
-static float ComputeSpillWeight(LiveInterval* interval, const SsaLivenessAnalysis& liveness) {
-  if (interval->HasRegister()) {
-    // Intervals with a fixed register cannot be spilled.
-    return std::numeric_limits<float>::min();
-  }
-
-  size_t length = interval->GetLength();
-  if (length == 1) {
-    // Tiny intervals should have maximum priority, since they cannot be split any further.
-    return std::numeric_limits<float>::max();
-  }
-
-  size_t use_weight = 0;
-  if (interval->GetDefinedBy() != nullptr && interval->DefinitionRequiresRegister()) {
-    // Cost for spilling at a register definition point.
-    use_weight += CostForMoveAt(interval->GetStart() + 1, liveness);
-  }
-
-  UsePosition* use = interval->GetFirstUse();
-  while (use != nullptr && use->GetPosition() <= interval->GetStart()) {
-    // Skip uses before the start of this live interval.
-    use = use->GetNext();
-  }
-
-  while (use != nullptr && use->GetPosition() <= interval->GetEnd()) {
-    if (use->GetUser() != nullptr && use->RequiresRegister()) {
-      // Cost for spilling at a register use point.
-      use_weight += CostForMoveAt(use->GetUser()->GetLifetimePosition() - 1, liveness);
-    }
-    use = use->GetNext();
-  }
-
-  // We divide by the length of the interval because we want to prioritize
-  // short intervals; we do not benefit much if we split them further.
-  return static_cast<float>(use_weight) / static_cast<float>(length);
-}
-
 // Interference nodes make up the interference graph, which is the primary data structure in
 // graph coloring register allocation. Each node represents a single live interval, and contains
 // a set of adjacent nodes corresponding to intervals overlapping with its own. To save memory,
@@ -210,70 +58,42 @@
 // and thus whether it is safe to prune it from the interference graph early on.
 class InterferenceNode : public ArenaObject<kArenaAllocRegisterAllocator> {
  public:
-  InterferenceNode(ArenaAllocator* allocator,
-                   LiveInterval* interval,
-                   size_t id,
-                   const SsaLivenessAnalysis& liveness)
-        : stage(NodeStage::kInitial),
-          interval_(interval),
-          adjacent_nodes_(allocator->Adapter(kArenaAllocRegisterAllocator)),
-          coalesce_opportunities_(allocator->Adapter(kArenaAllocRegisterAllocator)),
-          out_degree_(interval->HasRegister() ? std::numeric_limits<size_t>::max() : 0),
-          id_(id),
-          alias_(this),
-          spill_weight_(ComputeSpillWeight(interval, liveness)),
-          requires_color_(interval->RequiresRegister()) {
-    DCHECK(!interval->IsHighInterval()) << "Pair nodes should be represented by the low interval";
+  InterferenceNode(ArenaAllocator* allocator, LiveInterval* interval, size_t id)
+        : interval_(interval),
+          adjacent_nodes_(CmpPtr, allocator->Adapter(kArenaAllocRegisterAllocator)),
+          out_degree_(0),
+          id_(id) {}
+
+  // Used to maintain determinism when storing InterferenceNode pointers in sets.
+  static bool CmpPtr(const InterferenceNode* lhs, const InterferenceNode* rhs) {
+    return lhs->id_ < rhs->id_;
   }
 
-  void AddInterference(InterferenceNode* other, bool guaranteed_not_interfering_yet) {
-    DCHECK(!IsPrecolored()) << "To save memory, fixed nodes should not have outgoing interferences";
-    DCHECK_NE(this, other) << "Should not create self loops in the interference graph";
-    DCHECK_EQ(this, alias_) << "Should not add interferences to a node that aliases another";
-    DCHECK_NE(stage, NodeStage::kPruned);
-    DCHECK_NE(other->stage, NodeStage::kPruned);
-    if (guaranteed_not_interfering_yet) {
-      DCHECK(std::find(adjacent_nodes_.begin(), adjacent_nodes_.end(), other)
-             == adjacent_nodes_.end());
-      adjacent_nodes_.push_back(other);
+  void AddInterference(InterferenceNode* other) {
+    if (adjacent_nodes_.insert(other).second) {
       out_degree_ += EdgeWeightWith(other);
-    } else {
-      auto it = std::find(adjacent_nodes_.begin(), adjacent_nodes_.end(), other);
-      if (it == adjacent_nodes_.end()) {
-        adjacent_nodes_.push_back(other);
-        out_degree_ += EdgeWeightWith(other);
-      }
     }
   }
 
   void RemoveInterference(InterferenceNode* other) {
-    DCHECK_EQ(this, alias_) << "Should not remove interferences from a coalesced node";
-    DCHECK_EQ(other->stage, NodeStage::kPruned) << "Should only remove interferences when pruning";
-    auto it = std::find(adjacent_nodes_.begin(), adjacent_nodes_.end(), other);
-    if (it != adjacent_nodes_.end()) {
-      adjacent_nodes_.erase(it);
+    if (adjacent_nodes_.erase(other) > 0) {
       out_degree_ -= EdgeWeightWith(other);
     }
   }
 
   bool ContainsInterference(InterferenceNode* other) const {
-    DCHECK(!IsPrecolored()) << "Should not query fixed nodes for interferences";
-    DCHECK_EQ(this, alias_) << "Should not query a coalesced node for interferences";
-    auto it = std::find(adjacent_nodes_.begin(), adjacent_nodes_.end(), other);
-    return it != adjacent_nodes_.end();
+    return adjacent_nodes_.count(other) > 0;
   }
 
   LiveInterval* GetInterval() const {
     return interval_;
   }
 
-  const ArenaVector<InterferenceNode*>& GetAdjacentNodes() const {
+  const ArenaSet<InterferenceNode*, decltype(&CmpPtr)>& GetAdjacentNodes() const {
     return adjacent_nodes_;
   }
 
   size_t GetOutDegree() const {
-    // Pre-colored nodes have infinite degree.
-    DCHECK(!IsPrecolored() || out_degree_ == std::numeric_limits<size_t>::max());
     return out_degree_;
   }
 
@@ -281,109 +101,41 @@
     return id_;
   }
 
-  void AddCoalesceOpportunity(CoalesceOpportunity* opportunity) {
-    coalesce_opportunities_.push_back(opportunity);
-  }
-
-  void ClearCoalesceOpportunities() {
-    coalesce_opportunities_.clear();
-  }
-
-  bool IsMoveRelated() const {
-    for (CoalesceOpportunity* opportunity : coalesce_opportunities_) {
-      if (opportunity->stage == CoalesceStage::kWorklist ||
-          opportunity->stage == CoalesceStage::kActive) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  // Return whether this node already has a color.
-  // Used to find fixed nodes in the interference graph before coloring.
-  bool IsPrecolored() const {
-    return interval_->HasRegister();
-  }
-
-  bool IsPair() const {
-    return interval_->HasHighInterval();
-  }
-
-  void SetAlias(InterferenceNode* rep) {
-    DCHECK_NE(rep->stage, NodeStage::kPruned);
-    DCHECK_EQ(this, alias_) << "Should only set a node's alias once";
-    alias_ = rep;
-  }
-
-  InterferenceNode* GetAlias() {
-    if (alias_ != this) {
-      // Recurse in order to flatten tree of alias pointers.
-      alias_ = alias_->GetAlias();
-    }
-    return alias_;
-  }
-
-  const ArenaVector<CoalesceOpportunity*>& GetCoalesceOpportunities() const {
-    return coalesce_opportunities_;
-  }
-
-  float GetSpillWeight() const {
-    return spill_weight_;
-  }
-
-  bool RequiresColor() const {
-    return requires_color_;
-  }
-
+ private:
   // We give extra weight to edges adjacent to pair nodes. See the general comment on the
   // interference graph above.
-  size_t EdgeWeightWith(const InterferenceNode* other) const {
-    return (IsPair() || other->IsPair()) ? 2 : 1;
+  size_t EdgeWeightWith(InterferenceNode* other) const {
+    return (interval_->HasHighInterval() || other->interval_->HasHighInterval()) ? 2 : 1;
   }
 
-  // The current stage of this node, indicating which worklist it belongs to.
-  NodeStage stage;
-
- private:
   // The live interval that this node represents.
   LiveInterval* const interval_;
 
   // All nodes interfering with this one.
-  // We use an unsorted vector as a set, since a tree or hash set is too heavy for the
-  // set sizes that we encounter. Using a vector leads to much better performance.
-  ArenaVector<InterferenceNode*> adjacent_nodes_;
-
-  // Interference nodes that this node should be coalesced with to reduce moves.
-  ArenaVector<CoalesceOpportunity*> coalesce_opportunities_;
+  // TODO: There is potential to use a cheaper data structure here, especially since
+  //       adjacency sets will usually be small.
+  ArenaSet<InterferenceNode*, decltype(&CmpPtr)> adjacent_nodes_;
 
   // The maximum number of colors with which this node could interfere. This could be more than
   // the number of adjacent nodes if this is a pair node, or if some adjacent nodes are pair nodes.
   // We use "out" degree because incoming edges come from nodes already pruned from the graph,
   // and do not affect the coloring of this node.
-  // Pre-colored nodes are treated as having infinite degree.
   size_t out_degree_;
 
   // A unique identifier for this node, used to maintain determinism when storing
   // interference nodes in sets.
   const size_t id_;
 
-  // The node representing this node in the interference graph.
-  // Initially set to `this`, and only changed if this node is coalesced into another.
-  InterferenceNode* alias_;
-
-  // The cost of splitting and spilling this interval to the stack.
-  // Nodes with a higher spill weight should be prioritized when assigning registers.
-  // This is essentially based on use density and location; short intervals with many uses inside
-  // deeply nested loops have a high spill weight.
-  const float spill_weight_;
-
-  const bool requires_color_;
+  // TODO: We could cache the result of interval_->RequiresRegister(), since it
+  //       will not change for the lifetime of this node. (Currently, RequiresRegister() requires
+  //       iterating through all uses of a live interval.)
 
   DISALLOW_COPY_AND_ASSIGN(InterferenceNode);
 };
 
 static bool IsCoreInterval(LiveInterval* interval) {
-  return !Primitive::IsFloatingPointType(interval->GetType());
+  return interval->GetType() != Primitive::kPrimFloat
+      && interval->GetType() != Primitive::kPrimDouble;
 }
 
 static size_t ComputeReservedArtMethodSlots(const CodeGenerator& codegen) {
@@ -392,16 +144,14 @@
 
 RegisterAllocatorGraphColor::RegisterAllocatorGraphColor(ArenaAllocator* allocator,
                                                          CodeGenerator* codegen,
-                                                         const SsaLivenessAnalysis& liveness,
-                                                         bool iterative_move_coalescing)
+                                                         const SsaLivenessAnalysis& liveness)
       : RegisterAllocator(allocator, codegen, liveness),
-        iterative_move_coalescing_(iterative_move_coalescing),
         core_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
         fp_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
         temp_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
         safepoints_(allocator->Adapter(kArenaAllocRegisterAllocator)),
-        physical_core_nodes_(allocator->Adapter(kArenaAllocRegisterAllocator)),
-        physical_fp_nodes_(allocator->Adapter(kArenaAllocRegisterAllocator)),
+        physical_core_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
+        physical_fp_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
         int_spill_slot_counter_(0),
         double_spill_slot_counter_(0),
         float_spill_slot_counter_(0),
@@ -413,27 +163,16 @@
         number_of_globally_blocked_fp_regs_(0),
         max_safepoint_live_core_regs_(0),
         max_safepoint_live_fp_regs_(0),
-        coloring_attempt_allocator_(nullptr),
-        node_id_counter_(0),
-        interval_node_map_(allocator->Adapter(kArenaAllocRegisterAllocator)),
-        prunable_nodes_(allocator->Adapter(kArenaAllocRegisterAllocator)),
-        pruned_nodes_(allocator->Adapter(kArenaAllocRegisterAllocator)),
-        simplify_worklist_(allocator->Adapter(kArenaAllocRegisterAllocator)),
-        freeze_worklist_(allocator->Adapter(kArenaAllocRegisterAllocator)),
-        spill_worklist_(HasGreaterNodePriority, allocator->Adapter(kArenaAllocRegisterAllocator)),
-        coalesce_worklist_(CmpCoalesceOpportunity,
-                           allocator->Adapter(kArenaAllocRegisterAllocator)) {
+        coloring_attempt_allocator_(nullptr) {
   // Before we ask for blocked registers, set them up in the code generator.
   codegen->SetupBlockedRegisters();
 
   // Initialize physical core register live intervals and blocked registers.
   // This includes globally blocked registers, such as the stack pointer.
-  physical_core_nodes_.resize(codegen_->GetNumberOfCoreRegisters(), nullptr);
-  for (size_t i = 0; i < codegen_->GetNumberOfCoreRegisters(); ++i) {
+  physical_core_intervals_.resize(codegen->GetNumberOfCoreRegisters(), nullptr);
+  for (size_t i = 0; i < codegen->GetNumberOfCoreRegisters(); ++i) {
     LiveInterval* interval = LiveInterval::MakeFixedInterval(allocator_, i, Primitive::kPrimInt);
-    physical_core_nodes_[i] =
-        new (allocator_) InterferenceNode(allocator_, interval, node_id_counter_++, liveness);
-    physical_core_nodes_[i]->stage = NodeStage::kPrecolored;
+    physical_core_intervals_[i] = interval;
     core_intervals_.push_back(interval);
     if (codegen_->IsBlockedCoreRegister(i)) {
       ++number_of_globally_blocked_core_regs_;
@@ -441,12 +180,10 @@
     }
   }
   // Initialize physical floating point register live intervals and blocked registers.
-  physical_fp_nodes_.resize(codegen_->GetNumberOfFloatingPointRegisters(), nullptr);
-  for (size_t i = 0; i < codegen_->GetNumberOfFloatingPointRegisters(); ++i) {
+  physical_fp_intervals_.resize(codegen->GetNumberOfFloatingPointRegisters(), nullptr);
+  for (size_t i = 0; i < codegen->GetNumberOfFloatingPointRegisters(); ++i) {
     LiveInterval* interval = LiveInterval::MakeFixedInterval(allocator_, i, Primitive::kPrimFloat);
-    physical_fp_nodes_[i] =
-        new (allocator_) InterferenceNode(allocator_, interval, node_id_counter_++, liveness);
-    physical_fp_nodes_[i]->stage = NodeStage::kPrecolored;
+    physical_fp_intervals_[i] = interval;
     fp_intervals_.push_back(interval);
     if (codegen_->IsBlockedFloatingPointRegister(i)) {
       ++number_of_globally_blocked_fp_regs_;
@@ -476,58 +213,24 @@
           << "which could be caused by prioritizing the wrong live intervals. (Short intervals "
           << "should be prioritized over long ones, because they cannot be split further.)";
 
-      // Reset the allocator and fixed nodes for the next coloring attempt.
+      // Reset the allocator for the next coloring attempt.
       ArenaAllocator coloring_attempt_allocator(allocator_->GetArenaPool());
       coloring_attempt_allocator_ = &coloring_attempt_allocator;
-      for (InterferenceNode* node : physical_core_nodes_) {
-        node->ClearCoalesceOpportunities();
-      }
-      for (InterferenceNode* node : physical_fp_nodes_) {
-        node->ClearCoalesceOpportunities();
-      }
 
-      // Clear data structures.
-      // TODO: One alternative idea is to create a separate struct that contains all of these
-      //       data structures, and is passed around to each graph coloring function.
-      interval_node_map_ = ArenaHashMap<LiveInterval*, InterferenceNode*>(
+      // (2) Build the interference graph.
+      ArenaVector<InterferenceNode*> prunable_nodes(
           coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
-      prunable_nodes_ = ArenaVector<InterferenceNode*>(
-          coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
-      pruned_nodes_ = ArenaStdStack<InterferenceNode*>(
-          coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
-      simplify_worklist_ = ArenaDeque<InterferenceNode*>(
-          coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
-      freeze_worklist_ = ArenaDeque<InterferenceNode*>(
-          coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
-      spill_worklist_ = ArenaPriorityQueue<InterferenceNode*, decltype(&HasGreaterNodePriority)>(
-          HasGreaterNodePriority, coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
-      coalesce_worklist_ =
-          ArenaPriorityQueue<CoalesceOpportunity*, decltype(&CmpCoalesceOpportunity)>(
-              CmpCoalesceOpportunity,
-              coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
-
-      // (2) Build the interference graph. Also gather safepoints and build the interval node map.
       ArenaVector<InterferenceNode*> safepoints(
           coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
-      ArenaVector<InterferenceNode*>& physical_nodes = processing_core_regs
-          ? physical_core_nodes_
-          : physical_fp_nodes_;
-      BuildInterferenceGraph(intervals, physical_nodes, &safepoints);
+      BuildInterferenceGraph(intervals, &prunable_nodes, &safepoints);
 
-      // (3) Add coalesce opportunities.
-      //     If we have tried coloring the graph a suspiciously high number of times, give
-      //     up on move coalescing, just in case the coalescing heuristics are not conservative.
-      //     (This situation will be caught if DCHECKs are turned on.)
-      if (iterative_move_coalescing_ && attempt <= kMaxGraphColoringAttemptsDebug) {
-        FindCoalesceOpportunities();
-      }
+      // (3) Prune all uncolored nodes from interference graph.
+      ArenaStdStack<InterferenceNode*> pruned_nodes(
+          coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
+      PruneInterferenceGraph(prunable_nodes, num_registers, &pruned_nodes);
 
-      // (4) Prune all uncolored nodes from interference graph.
-      PruneInterferenceGraph(num_registers);
-
-      // (5) Color pruned nodes based on interferences.
-      bool successful = ColorInterferenceGraph(num_registers,
-                                               processing_core_regs);
+      // (4) Color pruned nodes based on interferences.
+      bool successful = ColorInterferenceGraph(&pruned_nodes, num_registers);
 
       if (successful) {
         // Compute the maximum number of live registers across safepoints.
@@ -547,7 +250,7 @@
         // We only look at prunable_nodes because we already told the code generator about
         // fixed intervals while processing instructions. We also ignore the fixed intervals
         // placed at the top of catch blocks.
-        for (InterferenceNode* node : prunable_nodes_) {
+        for (InterferenceNode* node : prunable_nodes) {
           LiveInterval* interval = node->GetInterval();
           if (interval->HasRegister()) {
             Location low_reg = processing_core_regs
@@ -572,7 +275,7 @@
     }  // while unsuccessful
   }  // for processing_core_instructions
 
-  // (6) Resolve locations and deconstruct SSA form.
+  // (5) Resolve locations and deconstruct SSA form.
   RegisterAllocationResolver(allocator_, codegen_, liveness_)
       .Resolve(max_safepoint_live_core_regs_,
                max_safepoint_live_fp_regs_,
@@ -601,12 +304,11 @@
       }
     }
 
-    ArenaVector<InterferenceNode*>& physical_nodes = processing_core_regs
-        ? physical_core_nodes_
-        : physical_fp_nodes_;
-    for (InterferenceNode* fixed : physical_nodes) {
-      LiveInterval* interval = fixed->GetInterval();
-      if (interval->GetFirstRange() != nullptr) {
+    ArenaVector<LiveInterval*>& physical_intervals = processing_core_regs
+        ? physical_core_intervals_
+        : physical_fp_intervals_;
+    for (LiveInterval* fixed : physical_intervals) {
+      if (fixed->GetFirstRange() != nullptr) {
         // Ideally we would check fixed ranges as well, but currently there are times when
         // two fixed intervals for the same register will overlap. For example, a fixed input
         // and a fixed output may sometimes share the same register, in which there will be two
@@ -656,8 +358,7 @@
       ProcessInstruction(phi_it.Current());
     }
 
-    if (block->IsCatchBlock()
-        || (block->IsLoopHeader() && block->GetLoopInformation()->IsIrreducible())) {
+    if (block->IsCatchBlock() || (block->IsLoopHeader() && block->GetLoopInformation()->IsIrreducible())) {
       // By blocking all registers at the top of each catch block or irreducible loop, we force
       // intervals belonging to the live-in set of the catch/header block to be spilled.
       // TODO(ngeoffray): Phis in this block could be allocated in register.
@@ -734,9 +435,7 @@
   // TODO: Ideally we would coalesce the physical register with the register
   //       allocated to the input value, but this can be tricky if, e.g., there
   //       could be multiple physical register uses of the same value at the
-  //       same instruction. Furthermore, there's currently no distinction between
-  //       fixed inputs to a call (which will be clobbered) and other fixed inputs (which
-  //       may not be clobbered).
+  //       same instruction. Need to think about it more.
   LocationSummary* locations = instruction->GetLocations();
   size_t position = instruction->GetLifetimePosition();
   for (size_t i = 0; i < locations->GetInputCount(); ++i) {
@@ -940,8 +639,8 @@
   DCHECK(location.IsRegister() || location.IsFpuRegister());
   int reg = location.reg();
   LiveInterval* interval = location.IsRegister()
-      ? physical_core_nodes_[reg]->GetInterval()
-      : physical_fp_nodes_[reg]->GetInterval();
+      ? physical_core_intervals_[reg]
+      : physical_fp_intervals_[reg];
   DCHECK(interval->GetRegister() == reg);
   bool blocked_by_codegen = location.IsRegister()
       ? codegen_->IsBlockedCoreRegister(reg)
@@ -967,104 +666,28 @@
   }
 }
 
-void RegisterAllocatorGraphColor::AddPotentialInterference(InterferenceNode* from,
-                                                           InterferenceNode* to,
-                                                           bool guaranteed_not_interfering_yet,
-                                                           bool both_directions) {
-  if (from->IsPrecolored()) {
+// Add an interference edge, but only if necessary.
+static void AddPotentialInterference(InterferenceNode* from, InterferenceNode* to) {
+  if (from->GetInterval()->HasRegister()) {
     // We save space by ignoring outgoing edges from fixed nodes.
   } else if (to->GetInterval()->IsSlowPathSafepoint()) {
     // Safepoint intervals are only there to count max live registers,
     // so no need to give them incoming interference edges.
     // This is also necessary for correctness, because we don't want nodes
     // to remove themselves from safepoint adjacency sets when they're pruned.
-  } else if (to->IsPrecolored()) {
-    // It is important that only a single node represents a given fixed register in the
-    // interference graph. We retrieve that node here.
-    const ArenaVector<InterferenceNode*>& physical_nodes =
-        to->GetInterval()->IsFloatingPoint() ? physical_fp_nodes_ : physical_core_nodes_;
-    InterferenceNode* physical_node = physical_nodes[to->GetInterval()->GetRegister()];
-    from->AddInterference(physical_node, /*guaranteed_not_interfering_yet*/ false);
-    DCHECK_EQ(to->GetInterval()->GetRegister(), physical_node->GetInterval()->GetRegister());
-    DCHECK_EQ(to->GetAlias(), physical_node) << "Fixed nodes should alias the canonical fixed node";
-
-    // If a node interferes with a fixed pair node, the weight of the edge may
-    // be inaccurate after using the alias of the pair node, because the alias of the pair node
-    // is a singular node.
-    // We could make special pair fixed nodes, but that ends up being too conservative because
-    // a node could then interfere with both {r1} and {r1,r2}, leading to a degree of
-    // three rather than two.
-    // Instead, we explicitly add an interference with the high node of the fixed pair node.
-    // TODO: This is too conservative at time for pair nodes, but the fact that fixed pair intervals
-    //       can be unaligned on x86 complicates things.
-    if (to->IsPair()) {
-      InterferenceNode* high_node =
-          physical_nodes[to->GetInterval()->GetHighInterval()->GetRegister()];
-      DCHECK_EQ(to->GetInterval()->GetHighInterval()->GetRegister(),
-                high_node->GetInterval()->GetRegister());
-      from->AddInterference(high_node, /*guaranteed_not_interfering_yet*/ false);
-    }
   } else {
-    // Standard interference between two uncolored nodes.
-    from->AddInterference(to, guaranteed_not_interfering_yet);
-  }
-
-  if (both_directions) {
-    AddPotentialInterference(to, from, guaranteed_not_interfering_yet, /*both_directions*/ false);
+    from->AddInterference(to);
   }
 }
 
-// Returns true if `in_node` represents an input interval of `out_node`, and the output interval
-// is allowed to have the same register as the input interval.
-// TODO: Ideally we should just produce correct intervals in liveness analysis.
-//       We would need to refactor the current live interval layout to do so, which is
-//       no small task.
-static bool CheckInputOutputCanOverlap(InterferenceNode* in_node, InterferenceNode* out_node) {
-  LiveInterval* output_interval = out_node->GetInterval();
-  HInstruction* defined_by = output_interval->GetDefinedBy();
-  if (defined_by == nullptr) {
-    // This must not be a definition point.
-    return false;
-  }
-
-  LocationSummary* locations = defined_by->GetLocations();
-  if (locations->OutputCanOverlapWithInputs()) {
-    // This instruction does not allow the output to reuse a register from an input.
-    return false;
-  }
-
-  LiveInterval* input_interval = in_node->GetInterval();
-  LiveInterval* next_sibling = input_interval->GetNextSibling();
-  size_t def_position = defined_by->GetLifetimePosition();
-  size_t use_position = def_position + 1;
-  if (next_sibling != nullptr && next_sibling->GetStart() == use_position) {
-    // The next sibling starts at the use position, so reusing the input register in the output
-    // would clobber the input before it's moved into the sibling interval location.
-    return false;
-  }
-
-  if (!input_interval->IsDeadAt(use_position) && input_interval->CoversSlow(use_position)) {
-    // The input interval is live after the use position.
-    return false;
-  }
-
-  HInputsRef inputs = defined_by->GetInputs();
-  for (size_t i = 0; i < inputs.size(); ++i) {
-    if (inputs[i]->GetLiveInterval()->GetSiblingAt(def_position) == input_interval) {
-      DCHECK(input_interval->SameRegisterKind(*output_interval));
-      return true;
-    }
-  }
-
-  // The input interval was not an input for this instruction.
-  return false;
-}
-
+// TODO: See locations->OutputCanOverlapWithInputs(); we may want to consider
+//       this when building the interference graph.
 void RegisterAllocatorGraphColor::BuildInterferenceGraph(
     const ArenaVector<LiveInterval*>& intervals,
-    const ArenaVector<InterferenceNode*>& physical_nodes,
+    ArenaVector<InterferenceNode*>* prunable_nodes,
     ArenaVector<InterferenceNode*>* safepoints) {
-  DCHECK(interval_node_map_.Empty() && prunable_nodes_.empty());
+  size_t interval_id_counter = 0;
+
   // Build the interference graph efficiently by ordering range endpoints
   // by position and doing a linear sweep to find interferences. (That is, we
   // jump from endpoint to endpoint, maintaining a set of intervals live at each
@@ -1079,33 +702,20 @@
   // Tuple contents: (position, is_range_beginning, node).
   ArenaVector<std::tuple<size_t, bool, InterferenceNode*>> range_endpoints(
       coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
-
-  // We reserve plenty of space to avoid excessive copying.
-  range_endpoints.reserve(4 * prunable_nodes_.size());
-
   for (LiveInterval* parent : intervals) {
     for (LiveInterval* sibling = parent; sibling != nullptr; sibling = sibling->GetNextSibling()) {
       LiveRange* range = sibling->GetFirstRange();
       if (range != nullptr) {
         InterferenceNode* node = new (coloring_attempt_allocator_) InterferenceNode(
-            coloring_attempt_allocator_, sibling, node_id_counter_++, liveness_);
-        interval_node_map_.Insert(std::make_pair(sibling, node));
-
+            coloring_attempt_allocator_, sibling, interval_id_counter++);
         if (sibling->HasRegister()) {
-          // Fixed nodes should alias the canonical node for the corresponding register.
-          node->stage = NodeStage::kPrecolored;
-          InterferenceNode* physical_node = physical_nodes[sibling->GetRegister()];
-          node->SetAlias(physical_node);
-          DCHECK_EQ(node->GetInterval()->GetRegister(),
-                    physical_node->GetInterval()->GetRegister());
+          // Fixed nodes will never be pruned, so no need to keep track of them.
         } else if (sibling->IsSlowPathSafepoint()) {
           // Safepoint intervals are synthesized to count max live registers.
           // They will be processed separately after coloring.
-          node->stage = NodeStage::kSafepoint;
           safepoints->push_back(node);
         } else {
-          node->stage = NodeStage::kPrunable;
-          prunable_nodes_.push_back(node);
+          prunable_nodes->push_back(node);
         }
 
         while (range != nullptr) {
@@ -1118,18 +728,11 @@
   }
 
   // Sort the endpoints.
-  // We explicitly ignore the third entry of each tuple (the node pointer) in order
-  // to maintain determinism.
-  std::sort(range_endpoints.begin(), range_endpoints.end(),
-            [] (const std::tuple<size_t, bool, InterferenceNode*>& lhs,
-                const std::tuple<size_t, bool, InterferenceNode*>& rhs) {
-    return std::tie(std::get<0>(lhs), std::get<1>(lhs))
-         < std::tie(std::get<0>(rhs), std::get<1>(rhs));
-  });
+  std::sort(range_endpoints.begin(), range_endpoints.end());
 
   // Nodes live at the current position in the linear sweep.
-  ArenaVector<InterferenceNode*> live(
-      coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
+  ArenaSet<InterferenceNode*, decltype(&InterferenceNode::CmpPtr)> live(
+      InterferenceNode::CmpPtr, coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
 
   // Linear sweep. When we encounter the beginning of a range, we add the corresponding node to the
   // live set. When we encounter the end of a range, we remove the corresponding node
@@ -1137,537 +740,131 @@
   for (auto it = range_endpoints.begin(); it != range_endpoints.end(); ++it) {
     bool is_range_beginning;
     InterferenceNode* node;
-    size_t position;
     // Extract information from the tuple, including the node this tuple represents.
-    std::tie(position, is_range_beginning, node) = *it;
+    std::tie(std::ignore, is_range_beginning, node) = *it;
 
     if (is_range_beginning) {
-      bool guaranteed_not_interfering_yet = position == node->GetInterval()->GetStart();
       for (InterferenceNode* conflicting : live) {
         DCHECK_NE(node, conflicting);
-        if (CheckInputOutputCanOverlap(conflicting, node)) {
-          // We do not add an interference, because the instruction represented by `node` allows
-          // its output to share a register with an input, represented here by `conflicting`.
-        } else {
-          AddPotentialInterference(node, conflicting, guaranteed_not_interfering_yet);
-        }
+        AddPotentialInterference(node, conflicting);
+        AddPotentialInterference(conflicting, node);
       }
-      DCHECK(std::find(live.begin(), live.end(), node) == live.end());
-      live.push_back(node);
+      DCHECK_EQ(live.count(node), 0u);
+      live.insert(node);
     } else {
       // End of range.
-      auto live_it = std::find(live.begin(), live.end(), node);
-      DCHECK(live_it != live.end());
-      live.erase(live_it);
+      DCHECK_EQ(live.count(node), 1u);
+      live.erase(node);
     }
   }
   DCHECK(live.empty());
 }
 
-void RegisterAllocatorGraphColor::CreateCoalesceOpportunity(InterferenceNode* a,
-                                                            InterferenceNode* b,
-                                                            CoalesceKind kind,
-                                                            size_t position) {
-  DCHECK_EQ(a->IsPair(), b->IsPair())
-      << "Nodes of different memory widths should never be coalesced";
-  CoalesceOpportunity* opportunity =
-      new (coloring_attempt_allocator_) CoalesceOpportunity(a, b, kind, position, liveness_);
-  a->AddCoalesceOpportunity(opportunity);
-  b->AddCoalesceOpportunity(opportunity);
-  coalesce_worklist_.push(opportunity);
-}
-
-// When looking for coalesce opportunities, we use the interval_node_map_ to find the node
-// corresponding to an interval. Note that not all intervals are in this map, notably the parents
-// of constants and stack arguments. (However, these interval should not be involved in coalesce
-// opportunities anyway, because they're not going to be in registers.)
-void RegisterAllocatorGraphColor::FindCoalesceOpportunities() {
-  DCHECK(coalesce_worklist_.empty());
-
-  for (InterferenceNode* node : prunable_nodes_) {
-    LiveInterval* interval = node->GetInterval();
-
-    // Coalesce siblings.
-    LiveInterval* next_sibling = interval->GetNextSibling();
-    if (next_sibling != nullptr && interval->GetEnd() == next_sibling->GetStart()) {
-      auto it = interval_node_map_.Find(next_sibling);
-      if (it != interval_node_map_.end()) {
-        InterferenceNode* sibling_node = it->second;
-        CreateCoalesceOpportunity(node,
-                                  sibling_node,
-                                  CoalesceKind::kAdjacentSibling,
-                                  interval->GetEnd());
-      }
-    }
-
-    // Coalesce fixed outputs with this interval if this interval is an adjacent sibling.
-    LiveInterval* parent = interval->GetParent();
-    if (parent->HasRegister()
-        && parent->GetNextSibling() == interval
-        && parent->GetEnd() == interval->GetStart()) {
-      auto it = interval_node_map_.Find(parent);
-      if (it != interval_node_map_.end()) {
-        InterferenceNode* parent_node = it->second;
-        CreateCoalesceOpportunity(node,
-                                  parent_node,
-                                  CoalesceKind::kFixedOutputSibling,
-                                  parent->GetEnd());
-      }
-    }
-
-    // Try to prevent moves across blocks.
-    // Note that this does not lead to many succeeding coalesce attempts, so could be removed
-    // if found to add to compile time.
-    if (interval->IsSplit() && liveness_.IsAtBlockBoundary(interval->GetStart() / 2)) {
-      // If the start of this interval is at a block boundary, we look at the
-      // location of the interval in blocks preceding the block this interval
-      // starts at. This can avoid a move between the two blocks.
-      HBasicBlock* block = liveness_.GetBlockFromPosition(interval->GetStart() / 2);
-      for (HBasicBlock* predecessor : block->GetPredecessors()) {
-        size_t position = predecessor->GetLifetimeEnd() - 1;
-        LiveInterval* existing = interval->GetParent()->GetSiblingAt(position);
-        if (existing != nullptr) {
-          auto it = interval_node_map_.Find(existing);
-          if (it != interval_node_map_.end()) {
-            InterferenceNode* existing_node = it->second;
-            CreateCoalesceOpportunity(node,
-                                      existing_node,
-                                      CoalesceKind::kNonlinearControlFlow,
-                                      position);
-          }
-        }
-      }
-    }
-
-    // Coalesce phi inputs with the corresponding output.
-    HInstruction* defined_by = interval->GetDefinedBy();
-    if (defined_by != nullptr && defined_by->IsPhi()) {
-      const ArenaVector<HBasicBlock*>& predecessors = defined_by->GetBlock()->GetPredecessors();
-      HInputsRef inputs = defined_by->GetInputs();
-
-      for (size_t i = 0, e = inputs.size(); i < e; ++i) {
-        // We want the sibling at the end of the appropriate predecessor block.
-        size_t position = predecessors[i]->GetLifetimeEnd() - 1;
-        LiveInterval* input_interval = inputs[i]->GetLiveInterval()->GetSiblingAt(position);
-
-        auto it = interval_node_map_.Find(input_interval);
-        if (it != interval_node_map_.end()) {
-          InterferenceNode* input_node = it->second;
-          CreateCoalesceOpportunity(node, input_node, CoalesceKind::kPhi, position);
-        }
-      }
-    }
-
-    // Coalesce output with first input when policy is kSameAsFirstInput.
-    if (defined_by != nullptr) {
-      Location out = defined_by->GetLocations()->Out();
-      if (out.IsUnallocated() && out.GetPolicy() == Location::kSameAsFirstInput) {
-        LiveInterval* input_interval
-            = defined_by->InputAt(0)->GetLiveInterval()->GetSiblingAt(interval->GetStart() - 1);
-        // TODO: Could we consider lifetime holes here?
-        if (input_interval->GetEnd() == interval->GetStart()) {
-          auto it = interval_node_map_.Find(input_interval);
-          if (it != interval_node_map_.end()) {
-            InterferenceNode* input_node = it->second;
-            CreateCoalesceOpportunity(node,
-                                      input_node,
-                                      CoalesceKind::kFirstInput,
-                                      interval->GetStart());
-          }
-        }
-      }
-    }
-
-    // An interval that starts an instruction (that is, it is not split), may
-    // re-use the registers used by the inputs of that instruction, based on the
-    // location summary.
-    if (defined_by != nullptr) {
-      DCHECK(!interval->IsSplit());
-      LocationSummary* locations = defined_by->GetLocations();
-      if (!locations->OutputCanOverlapWithInputs()) {
-        HInputsRef inputs = defined_by->GetInputs();
-        for (size_t i = 0; i < inputs.size(); ++i) {
-          size_t def_point = defined_by->GetLifetimePosition();
-          // TODO: Getting the sibling at the def_point might not be quite what we want
-          //       for fixed inputs, since the use will be *at* the def_point rather than after.
-          LiveInterval* input_interval = inputs[i]->GetLiveInterval()->GetSiblingAt(def_point);
-          if (input_interval != nullptr &&
-              input_interval->HasHighInterval() == interval->HasHighInterval()) {
-            auto it = interval_node_map_.Find(input_interval);
-            if (it != interval_node_map_.end()) {
-              InterferenceNode* input_node = it->second;
-              CreateCoalesceOpportunity(node,
-                                        input_node,
-                                        CoalesceKind::kAnyInput,
-                                        interval->GetStart());
-            }
-          }
-        }
-      }
-    }
-
-    // Try to prevent moves into fixed input locations.
-    UsePosition* use = interval->GetFirstUse();
-    for (; use != nullptr && use->GetPosition() <= interval->GetStart(); use = use->GetNext()) {
-      // Skip past uses before the start of this interval.
-    }
-    for (; use != nullptr && use->GetPosition() <= interval->GetEnd(); use = use->GetNext()) {
-      HInstruction* user = use->GetUser();
-      if (user == nullptr) {
-        // User may be null for certain intervals, such as temp intervals.
-        continue;
-      }
-      LocationSummary* locations = user->GetLocations();
-      Location input = locations->InAt(use->GetInputIndex());
-      if (input.IsRegister() || input.IsFpuRegister()) {
-        // TODO: Could try to handle pair interval too, but coalescing with fixed pair nodes
-        //       is currently not supported.
-        InterferenceNode* fixed_node = input.IsRegister()
-            ? physical_core_nodes_[input.reg()]
-            : physical_fp_nodes_[input.reg()];
-        CreateCoalesceOpportunity(node,
-                                  fixed_node,
-                                  CoalesceKind::kFixedInput,
-                                  user->GetLifetimePosition());
-      }
-    }
-  }  // for node in prunable_nodes
-}
-
-// The order in which we color nodes is important. To guarantee forward progress,
-// we prioritize intervals that require registers, and after that we prioritize
-// short intervals. That way, if we fail to color a node, it either won't require a
-// register, or it will be a long interval that can be split in order to make the
+// The order in which we color nodes is vital to both correctness (forward
+// progress) and code quality. Specifically, we must prioritize intervals
+// that require registers, and after that we must prioritize short intervals.
+// That way, if we fail to color a node, it either won't require a register,
+// or it will be a long interval that can be split in order to make the
 // interference graph sparser.
-// To improve code quality, we prioritize intervals used frequently in deeply nested loops.
-// (This metric is secondary to the forward progress requirements above.)
 // TODO: May also want to consider:
+// - Loop depth
 // - Constants (since they can be rematerialized)
 // - Allocated spill slots
-bool RegisterAllocatorGraphColor::HasGreaterNodePriority(const InterferenceNode* lhs,
-                                                         const InterferenceNode* rhs) {
-  // (1) Prioritize the node that requires a color.
-  if (lhs->RequiresColor() != rhs->RequiresColor()) {
-    return lhs->RequiresColor();
+static bool GreaterNodePriority(const InterferenceNode* lhs,
+                                const InterferenceNode* rhs) {
+  LiveInterval* lhs_interval = lhs->GetInterval();
+  LiveInterval* rhs_interval = rhs->GetInterval();
+
+  // (1) Choose the interval that requires a register.
+  if (lhs_interval->RequiresRegister() != rhs_interval->RequiresRegister()) {
+    return lhs_interval->RequiresRegister();
   }
 
-  // (2) Prioritize the interval that has a higher spill weight.
-  return lhs->GetSpillWeight() > rhs->GetSpillWeight();
+  // (2) Choose the interval that has a shorter life span.
+  if (lhs_interval->GetLength() != rhs_interval->GetLength()) {
+    return lhs_interval->GetLength() < rhs_interval->GetLength();
+  }
+
+  // (3) Just choose the interval based on a deterministic ordering.
+  return InterferenceNode::CmpPtr(lhs, rhs);
 }
 
-bool RegisterAllocatorGraphColor::CmpCoalesceOpportunity(const CoalesceOpportunity* lhs,
-                                                         const CoalesceOpportunity* rhs) {
-  return lhs->priority < rhs->priority;
-}
-
-static bool IsLowDegreeNode(InterferenceNode* node, size_t num_regs) {
-  return node->GetOutDegree() < num_regs;
-}
-
-static bool IsHighDegreeNode(InterferenceNode* node, size_t num_regs) {
-  return !IsLowDegreeNode(node, num_regs);
-}
-
-void RegisterAllocatorGraphColor::PruneInterferenceGraph(size_t num_regs) {
-  DCHECK(pruned_nodes_.empty()
-      && simplify_worklist_.empty()
-      && freeze_worklist_.empty()
-      && spill_worklist_.empty());
+void RegisterAllocatorGraphColor::PruneInterferenceGraph(
+      const ArenaVector<InterferenceNode*>& prunable_nodes,
+      size_t num_regs,
+      ArenaStdStack<InterferenceNode*>* pruned_nodes) {
   // When pruning the graph, we refer to nodes with degree less than num_regs as low degree nodes,
   // and all others as high degree nodes. The distinction is important: low degree nodes are
   // guaranteed a color, while high degree nodes are not.
 
-  // Build worklists. Note that the coalesce worklist has already been
-  // filled by FindCoalesceOpportunities().
-  for (InterferenceNode* node : prunable_nodes_) {
-    DCHECK(!node->IsPrecolored()) << "Fixed nodes should never be pruned";
-    DCHECK(!node->GetInterval()->IsSlowPathSafepoint()) << "Safepoint nodes should never be pruned";
-    if (IsLowDegreeNode(node, num_regs)) {
-      if (node->GetCoalesceOpportunities().empty()) {
-        // Simplify Worklist.
-        node->stage = NodeStage::kSimplifyWorklist;
-        simplify_worklist_.push_back(node);
-      } else {
-        // Freeze Worklist.
-        node->stage = NodeStage::kFreezeWorklist;
-        freeze_worklist_.push_back(node);
-      }
+  // Low-degree nodes are guaranteed a color, so worklist order does not matter.
+  ArenaDeque<InterferenceNode*> low_degree_worklist(
+      coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
+
+  // If we have to prune from the high-degree worklist, we cannot guarantee
+  // the pruned node a color. So, we order the worklist by priority.
+  ArenaSet<InterferenceNode*, decltype(&GreaterNodePriority)> high_degree_worklist(
+      GreaterNodePriority, coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
+
+  // Build worklists.
+  for (InterferenceNode* node : prunable_nodes) {
+    DCHECK(!node->GetInterval()->HasRegister())
+        << "Fixed nodes should never be pruned";
+    DCHECK(!node->GetInterval()->IsSlowPathSafepoint())
+        << "Safepoint nodes should never be pruned";
+    if (node->GetOutDegree() < num_regs) {
+      low_degree_worklist.push_back(node);
     } else {
-      // Spill worklist.
-      node->stage = NodeStage::kSpillWorklist;
-      spill_worklist_.push(node);
+      high_degree_worklist.insert(node);
     }
   }
 
+  // Helper function to prune an interval from the interference graph,
+  // which includes updating the worklists.
+  auto prune_node = [this,
+                     num_regs,
+                     &pruned_nodes,
+                     &low_degree_worklist,
+                     &high_degree_worklist] (InterferenceNode* node) {
+    DCHECK(!node->GetInterval()->HasRegister());
+    pruned_nodes->push(node);
+    for (InterferenceNode* adjacent : node->GetAdjacentNodes()) {
+      DCHECK(!adjacent->GetInterval()->IsSlowPathSafepoint())
+          << "Nodes should never interfere with synthesized safepoint nodes";
+      if (adjacent->GetInterval()->HasRegister()) {
+        // No effect on pre-colored nodes; they're never pruned.
+      } else {
+        bool was_high_degree = adjacent->GetOutDegree() >= num_regs;
+        DCHECK(adjacent->ContainsInterference(node))
+            << "Missing incoming interference edge from non-fixed node";
+        adjacent->RemoveInterference(node);
+        if (was_high_degree && adjacent->GetOutDegree() < num_regs) {
+          // This is a transition from high degree to low degree.
+          DCHECK_EQ(high_degree_worklist.count(adjacent), 1u);
+          high_degree_worklist.erase(adjacent);
+          low_degree_worklist.push_back(adjacent);
+        }
+      }
+    }
+  };
+
   // Prune graph.
-  // Note that we do not remove a node from its current worklist if it moves to another, so it may
-  // be in multiple worklists at once; the node's `phase` says which worklist it is really in.
-  while (true) {
-    if (!simplify_worklist_.empty()) {
-      // Prune low-degree nodes.
-      // TODO: pop_back() should work as well, but it didn't; we get a
+  while (!low_degree_worklist.empty() || !high_degree_worklist.empty()) {
+    while (!low_degree_worklist.empty()) {
+      InterferenceNode* node = low_degree_worklist.front();
+      // TODO: pop_back() should work as well, but it doesn't; we get a
       //       failed check while pruning. We should look into this.
-      InterferenceNode* node = simplify_worklist_.front();
-      simplify_worklist_.pop_front();
-      DCHECK_EQ(node->stage, NodeStage::kSimplifyWorklist) << "Cannot move from simplify list";
-      DCHECK_LT(node->GetOutDegree(), num_regs) << "Nodes in simplify list should be low degree";
-      DCHECK(!node->IsMoveRelated()) << "Nodes in simplify list should not be move related";
-      PruneNode(node, num_regs);
-    } else if (!coalesce_worklist_.empty()) {
-      // Coalesce.
-      CoalesceOpportunity* opportunity = coalesce_worklist_.top();
-      coalesce_worklist_.pop();
-      if (opportunity->stage == CoalesceStage::kWorklist) {
-        Coalesce(opportunity, num_regs);
-      }
-    } else if (!freeze_worklist_.empty()) {
-      // Freeze moves and prune a low-degree move-related node.
-      InterferenceNode* node = freeze_worklist_.front();
-      freeze_worklist_.pop_front();
-      if (node->stage == NodeStage::kFreezeWorklist) {
-        DCHECK_LT(node->GetOutDegree(), num_regs) << "Nodes in freeze list should be low degree";
-        DCHECK(node->IsMoveRelated()) << "Nodes in freeze list should be move related";
-        FreezeMoves(node, num_regs);
-        PruneNode(node, num_regs);
-      }
-    } else if (!spill_worklist_.empty()) {
-      // We spill the lowest-priority node, because pruning a node earlier
+      low_degree_worklist.pop_front();
+      prune_node(node);
+    }
+    if (!high_degree_worklist.empty()) {
+      // We prune the lowest-priority node, because pruning a node earlier
       // gives it a higher chance of being spilled.
-      InterferenceNode* node = spill_worklist_.top();
-      spill_worklist_.pop();
-      if (node->stage == NodeStage::kSpillWorklist) {
-        DCHECK_GE(node->GetOutDegree(), num_regs) << "Nodes in spill list should be high degree";
-        FreezeMoves(node, num_regs);
-        PruneNode(node, num_regs);
-      }
-    } else {
-      // Pruning complete.
-      break;
+      InterferenceNode* node = *high_degree_worklist.rbegin();
+      high_degree_worklist.erase(node);
+      prune_node(node);
     }
   }
-  DCHECK_EQ(prunable_nodes_.size(), pruned_nodes_.size());
-}
-
-void RegisterAllocatorGraphColor::EnableCoalesceOpportunities(InterferenceNode* node) {
-  for (CoalesceOpportunity* opportunity : node->GetCoalesceOpportunities()) {
-    if (opportunity->stage == CoalesceStage::kActive) {
-      opportunity->stage = CoalesceStage::kWorklist;
-      coalesce_worklist_.push(opportunity);
-    }
-  }
-}
-
-void RegisterAllocatorGraphColor::PruneNode(InterferenceNode* node,
-                                            size_t num_regs) {
-  DCHECK_NE(node->stage, NodeStage::kPruned);
-  DCHECK(!node->IsPrecolored());
-  node->stage = NodeStage::kPruned;
-  pruned_nodes_.push(node);
-
-  for (InterferenceNode* adj : node->GetAdjacentNodes()) {
-    DCHECK(!adj->GetInterval()->IsSlowPathSafepoint())
-        << "Nodes should never interfere with synthesized safepoint nodes";
-    DCHECK_NE(adj->stage, NodeStage::kPruned) << "Should be no interferences with pruned nodes";
-
-    if (adj->IsPrecolored()) {
-      // No effect on pre-colored nodes; they're never pruned.
-    } else {
-      // Remove the interference.
-      bool was_high_degree = IsHighDegreeNode(adj, num_regs);
-      DCHECK(adj->ContainsInterference(node))
-          << "Missing reflexive interference from non-fixed node";
-      adj->RemoveInterference(node);
-
-      // Handle transitions from high degree to low degree.
-      if (was_high_degree && IsLowDegreeNode(adj, num_regs)) {
-        EnableCoalesceOpportunities(adj);
-        for (InterferenceNode* adj_adj : adj->GetAdjacentNodes()) {
-          EnableCoalesceOpportunities(adj_adj);
-        }
-
-        DCHECK_EQ(adj->stage, NodeStage::kSpillWorklist);
-        if (adj->IsMoveRelated()) {
-          adj->stage = NodeStage::kFreezeWorklist;
-          freeze_worklist_.push_back(adj);
-        } else {
-          adj->stage = NodeStage::kSimplifyWorklist;
-          simplify_worklist_.push_back(adj);
-        }
-      }
-    }
-  }
-}
-
-void RegisterAllocatorGraphColor::CheckTransitionFromFreezeWorklist(InterferenceNode* node,
-                                                                    size_t num_regs) {
-  if (IsLowDegreeNode(node, num_regs) && !node->IsMoveRelated()) {
-    DCHECK_EQ(node->stage, NodeStage::kFreezeWorklist);
-    node->stage = NodeStage::kSimplifyWorklist;
-    simplify_worklist_.push_back(node);
-  }
-}
-
-void RegisterAllocatorGraphColor::FreezeMoves(InterferenceNode* node,
-                                              size_t num_regs) {
-  for (CoalesceOpportunity* opportunity : node->GetCoalesceOpportunities()) {
-    if (opportunity->stage == CoalesceStage::kDefunct) {
-      // Constrained moves should remain constrained, since they will not be considered
-      // during last-chance coalescing.
-    } else {
-      opportunity->stage = CoalesceStage::kInactive;
-    }
-    InterferenceNode* other = opportunity->node_a->GetAlias() == node
-        ? opportunity->node_b->GetAlias()
-        : opportunity->node_a->GetAlias();
-    if (other != node && other->stage == NodeStage::kFreezeWorklist) {
-      DCHECK(IsLowDegreeNode(node, num_regs));
-      CheckTransitionFromFreezeWorklist(other, num_regs);
-    }
-  }
-}
-
-bool RegisterAllocatorGraphColor::PrecoloredHeuristic(InterferenceNode* from,
-                                                      InterferenceNode* into,
-                                                      size_t num_regs) {
-  if (!into->IsPrecolored()) {
-    // The uncolored heuristic will cover this case.
-    return false;
-  }
-  if (from->IsPair() || into->IsPair()) {
-    // TODO: Merging from a pair node is currently not supported, since fixed pair nodes
-    //       are currently represented as two single fixed nodes in the graph, and `into` is
-    //       only one of them. (We may lose the implicit connections to the second one in a merge.)
-    return false;
-  }
-
-  // If all adjacent nodes of `from` are "ok", then we can conservatively merge with `into`.
-  // Reasons an adjacent node `adj` can be "ok":
-  // (1) If `adj` is low degree, interference with `into` will not affect its existing
-  //     colorable guarantee. (Notice that coalescing cannot increase its degree.)
-  // (2) If `adj` is pre-colored, it already interferes with `into`. See (3).
-  // (3) If there's already an interference with `into`, coalescing will not add interferences.
-  for (InterferenceNode* adj : from->GetAdjacentNodes()) {
-    if (IsLowDegreeNode(adj, num_regs) || adj->IsPrecolored() || adj->ContainsInterference(into)) {
-      // Ok.
-    } else {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool RegisterAllocatorGraphColor::UncoloredHeuristic(InterferenceNode* from,
-                                                     InterferenceNode* into,
-                                                     size_t num_regs) {
-  if (into->IsPrecolored()) {
-    // The pre-colored heuristic will handle this case.
-    return false;
-  }
-
-  // Arbitrary cap to improve compile time. Tests show that this has negligible affect
-  // on generated code.
-  if (from->GetOutDegree() + into->GetOutDegree() > 2 * num_regs) {
-    return false;
-  }
-
-  // It's safe to coalesce two nodes if the resulting node has fewer than `num_regs` neighbors
-  // of high degree. (Low degree neighbors can be ignored, because they will eventually be
-  // pruned from the interference graph in the simplify stage.)
-  size_t high_degree_interferences = 0;
-  for (InterferenceNode* adj : from->GetAdjacentNodes()) {
-    if (IsHighDegreeNode(adj, num_regs)) {
-      high_degree_interferences += from->EdgeWeightWith(adj);
-    }
-  }
-  for (InterferenceNode* adj : into->GetAdjacentNodes()) {
-    if (IsHighDegreeNode(adj, num_regs)) {
-      if (from->ContainsInterference(adj)) {
-        // We've already counted this adjacent node.
-        // Furthermore, its degree will decrease if coalescing succeeds. Thus, it's possible that
-        // we should not have counted it at all. (This extends the textbook Briggs coalescing test,
-        // but remains conservative.)
-        if (adj->GetOutDegree() - into->EdgeWeightWith(adj) < num_regs) {
-          high_degree_interferences -= from->EdgeWeightWith(adj);
-        }
-      } else {
-        high_degree_interferences += into->EdgeWeightWith(adj);
-      }
-    }
-  }
-
-  return high_degree_interferences < num_regs;
-}
-
-void RegisterAllocatorGraphColor::Combine(InterferenceNode* from,
-                                          InterferenceNode* into,
-                                          size_t num_regs) {
-  from->SetAlias(into);
-
-  // Add interferences.
-  for (InterferenceNode* adj : from->GetAdjacentNodes()) {
-    bool was_low_degree = IsLowDegreeNode(adj, num_regs);
-    AddPotentialInterference(adj, into, /*guaranteed_not_interfering_yet*/ false);
-    if (was_low_degree && IsHighDegreeNode(adj, num_regs)) {
-      // This is a (temporary) transition to a high degree node. Its degree will decrease again
-      // when we prune `from`, but it's best to be consistent about the current worklist.
-      adj->stage = NodeStage::kSpillWorklist;
-      spill_worklist_.push(adj);
-    }
-  }
-
-  // Add coalesce opportunities.
-  for (CoalesceOpportunity* opportunity : from->GetCoalesceOpportunities()) {
-    if (opportunity->stage != CoalesceStage::kDefunct) {
-      into->AddCoalesceOpportunity(opportunity);
-    }
-  }
-  EnableCoalesceOpportunities(from);
-
-  // Prune and update worklists.
-  PruneNode(from, num_regs);
-  if (IsLowDegreeNode(into, num_regs)) {
-    // Coalesce(...) takes care of checking for a transition to the simplify worklist.
-    DCHECK_EQ(into->stage, NodeStage::kFreezeWorklist);
-  } else if (into->stage == NodeStage::kFreezeWorklist) {
-    // This is a transition to a high degree node.
-    into->stage = NodeStage::kSpillWorklist;
-    spill_worklist_.push(into);
-  } else {
-    DCHECK(into->stage == NodeStage::kSpillWorklist || into->stage == NodeStage::kPrecolored);
-  }
-}
-
-void RegisterAllocatorGraphColor::Coalesce(CoalesceOpportunity* opportunity,
-                                           size_t num_regs) {
-  InterferenceNode* from = opportunity->node_a->GetAlias();
-  InterferenceNode* into = opportunity->node_b->GetAlias();
-  DCHECK_NE(from->stage, NodeStage::kPruned);
-  DCHECK_NE(into->stage, NodeStage::kPruned);
-
-  if (from->IsPrecolored()) {
-    // If we have one pre-colored node, make sure it's the `into` node.
-    std::swap(from, into);
-  }
-
-  if (from == into) {
-    // These nodes have already been coalesced.
-    opportunity->stage = CoalesceStage::kDefunct;
-    CheckTransitionFromFreezeWorklist(from, num_regs);
-  } else if (from->IsPrecolored() || from->ContainsInterference(into)) {
-    // These nodes interfere.
-    opportunity->stage = CoalesceStage::kDefunct;
-    CheckTransitionFromFreezeWorklist(from, num_regs);
-    CheckTransitionFromFreezeWorklist(into, num_regs);
-  } else if (PrecoloredHeuristic(from, into, num_regs)
-          || UncoloredHeuristic(from, into, num_regs)) {
-    // We can coalesce these nodes.
-    opportunity->stage = CoalesceStage::kDefunct;
-    Combine(from, into, num_regs);
-    CheckTransitionFromFreezeWorklist(into, num_regs);
-  } else {
-    // We cannot coalesce, but we may be able to later.
-    opportunity->stage = CoalesceStage::kActive;
-  }
 }
 
 // Build a mask with a bit set for each register assigned to some
@@ -1691,113 +888,32 @@
   return conflict_mask;
 }
 
-bool RegisterAllocatorGraphColor::IsCallerSave(size_t reg, bool processing_core_regs) {
-  return processing_core_regs
-      ? !codegen_->IsCoreCalleeSaveRegister(reg)
-      : !codegen_->IsCoreCalleeSaveRegister(reg);
-}
-
-static bool RegisterIsAligned(size_t reg) {
-  return reg % 2 == 0;
-}
-
-static size_t FindFirstZeroInConflictMask(std::bitset<kMaxNumRegs> conflict_mask) {
-  // We use CTZ (count trailing zeros) to quickly find the lowest 0 bit.
-  // Note that CTZ is undefined if all bits are 0, so we special-case it.
-  return conflict_mask.all() ? conflict_mask.size() : CTZ(~conflict_mask.to_ulong());
-}
-
-bool RegisterAllocatorGraphColor::ColorInterferenceGraph(size_t num_regs,
-                                                         bool processing_core_regs) {
+bool RegisterAllocatorGraphColor::ColorInterferenceGraph(
+      ArenaStdStack<InterferenceNode*>* pruned_nodes,
+      size_t num_regs) {
   DCHECK_LE(num_regs, kMaxNumRegs) << "kMaxNumRegs is too small";
   ArenaVector<LiveInterval*> colored_intervals(
       coloring_attempt_allocator_->Adapter(kArenaAllocRegisterAllocator));
   bool successful = true;
 
-  while (!pruned_nodes_.empty()) {
-    InterferenceNode* node = pruned_nodes_.top();
-    pruned_nodes_.pop();
+  while (!pruned_nodes->empty()) {
+    InterferenceNode* node = pruned_nodes->top();
+    pruned_nodes->pop();
     LiveInterval* interval = node->GetInterval();
-    size_t reg = 0;
 
-    InterferenceNode* alias = node->GetAlias();
-    if (alias != node) {
-      // This node was coalesced with another.
-      LiveInterval* alias_interval = alias->GetInterval();
-      if (alias_interval->HasRegister()) {
-        reg = alias_interval->GetRegister();
-        DCHECK(!BuildConflictMask(node->GetAdjacentNodes())[reg])
-            << "This node conflicts with the register it was coalesced with";
-      } else {
-        DCHECK(false) << node->GetOutDegree() << " " << alias->GetOutDegree() << " "
-            << "Move coalescing was not conservative, causing a node to be coalesced "
-            << "with another node that could not be colored";
-        if (interval->RequiresRegister()) {
-          successful = false;
-        }
+    // Search for free register(s).
+    // Note that the graph coloring allocator assumes that pair intervals are aligned here,
+    // excluding pre-colored pair intervals (which can currently be unaligned on x86).
+    std::bitset<kMaxNumRegs> conflict_mask = BuildConflictMask(node->GetAdjacentNodes());
+    size_t reg = 0;
+    if (interval->HasHighInterval()) {
+      while (reg < num_regs - 1 && (conflict_mask[reg] || conflict_mask[reg + 1])) {
+        reg += 2;
       }
     } else {
-      // Search for free register(s).
-      std::bitset<kMaxNumRegs> conflict_mask = BuildConflictMask(node->GetAdjacentNodes());
-      if (interval->HasHighInterval()) {
-        // Note that the graph coloring allocator assumes that pair intervals are aligned here,
-        // excluding pre-colored pair intervals (which can currently be unaligned on x86). If we
-        // change the alignment requirements here, we will have to update the algorithm (e.g.,
-        // be more conservative about the weight of edges adjacent to pair nodes.)
-        while (reg < num_regs - 1 && (conflict_mask[reg] || conflict_mask[reg + 1])) {
-          reg += 2;
-        }
-
-        // Try to use a caller-save register first.
-        for (size_t i = 0; i < num_regs - 1; i += 2) {
-          bool low_caller_save  = IsCallerSave(i, processing_core_regs);
-          bool high_caller_save = IsCallerSave(i + 1, processing_core_regs);
-          if (!conflict_mask[i] && !conflict_mask[i + 1]) {
-            if (low_caller_save && high_caller_save) {
-              reg = i;
-              break;
-            } else if (low_caller_save || high_caller_save) {
-              reg = i;
-              // Keep looking to try to get both parts in caller-save registers.
-            }
-          }
-        }
-      } else {
-        // Not a pair interval.
-        reg = FindFirstZeroInConflictMask(conflict_mask);
-
-        // Try to use caller-save registers first.
-        for (size_t i = 0; i < num_regs; ++i) {
-          if (!conflict_mask[i] && IsCallerSave(i, processing_core_regs)) {
-            reg = i;
-            break;
-          }
-        }
-      }
-
-      // Last-chance coalescing.
-      for (CoalesceOpportunity* opportunity : node->GetCoalesceOpportunities()) {
-        if (opportunity->stage == CoalesceStage::kDefunct) {
-          continue;
-        }
-        LiveInterval* other_interval = opportunity->node_a->GetAlias() == node
-            ? opportunity->node_b->GetAlias()->GetInterval()
-            : opportunity->node_a->GetAlias()->GetInterval();
-        if (other_interval->HasRegister()) {
-          size_t coalesce_register = other_interval->GetRegister();
-          if (interval->HasHighInterval()) {
-            if (!conflict_mask[coalesce_register] &&
-                !conflict_mask[coalesce_register + 1] &&
-                RegisterIsAligned(coalesce_register)) {
-              reg = coalesce_register;
-              break;
-            }
-          } else if (!conflict_mask[coalesce_register]) {
-            reg = coalesce_register;
-            break;
-          }
-        }
-      }
+      // We use CTZ (count trailing zeros) to quickly find the lowest available register.
+      // Note that CTZ is undefined for 0, so we special-case it.
+      reg = conflict_mask.all() ? conflict_mask.size() : CTZ(~conflict_mask.to_ulong());
     }
 
     if (reg < (interval->HasHighInterval() ? num_regs - 1 : num_regs)) {
diff --git a/compiler/optimizing/register_allocator_graph_color.h b/compiler/optimizing/register_allocator_graph_color.h
index 4052766..0b5af96 100644
--- a/compiler/optimizing/register_allocator_graph_color.h
+++ b/compiler/optimizing/register_allocator_graph_color.h
@@ -34,8 +34,6 @@
 class Location;
 class SsaLivenessAnalysis;
 class InterferenceNode;
-struct CoalesceOpportunity;
-enum class CoalesceKind;
 
 /**
  * A graph coloring register allocator.
@@ -62,25 +60,6 @@
  *       sparser, so that future coloring attempts may succeed.
  *     - If the node does not require a register, we simply assign it a location on the stack.
  *
- * If iterative move coalescing is enabled, the algorithm also attempts to conservatively
- * combine nodes in the graph that would prefer to have the same color. (For example, the output
- * of a phi instruction would prefer to have the same register as at least one of its inputs.)
- * There are several additional steps involved with this:
- * - We look for coalesce opportunities by examining each live interval, a step similar to that
- *   used by linear scan when looking for register hints.
- * - When pruning the graph, we maintain a worklist of coalesce opportunities, as well as a worklist
- *   of low degree nodes that have associated coalesce opportunities. Only when we run out of
- *   coalesce opportunities do we start pruning coalesce-associated nodes.
- * - When pruning a node, if any nodes transition from high degree to low degree, we add
- *   associated coalesce opportunities to the worklist, since these opportunities may now succeed.
- * - Whether two nodes can be combined is decided by two different heuristics--one used when
- *   coalescing uncolored nodes, and one used for coalescing an uncolored node with a colored node.
- *   It is vital that we only combine two nodes if the node that remains is guaranteed to receive
- *   a color. This is because additionally spilling is more costly than failing to coalesce.
- * - Even if nodes are not coalesced while pruning, we keep the coalesce opportunities around
- *   to be used as last-chance register hints when coloring. If nothing else, we try to use
- *   caller-save registers before callee-save registers.
- *
  * A good reference for graph coloring register allocation is
  * "Modern Compiler Implementation in Java" (Andrew W. Appel, 2nd Edition).
  */
@@ -88,8 +67,7 @@
  public:
   RegisterAllocatorGraphColor(ArenaAllocator* allocator,
                               CodeGenerator* codegen,
-                              const SsaLivenessAnalysis& analysis,
-                              bool iterative_move_coalescing = true);
+                              const SsaLivenessAnalysis& analysis);
   ~RegisterAllocatorGraphColor() OVERRIDE {}
 
   void AllocateRegisters() OVERRIDE;
@@ -138,20 +116,12 @@
   void BlockRegister(Location location, size_t start, size_t end);
   void BlockRegisters(size_t start, size_t end, bool caller_save_only = false);
 
-  static bool HasGreaterNodePriority(const InterferenceNode* lhs, const InterferenceNode* rhs);
-
-  // Compare two coalesce opportunities based on their priority.
-  // Return true if lhs has a lower priority than that of rhs.
-  static bool CmpCoalesceOpportunity(const CoalesceOpportunity* lhs,
-                                     const CoalesceOpportunity* rhs);
-
   // Use the intervals collected from instructions to construct an
   // interference graph mapping intervals to adjacency lists.
   // Also, collect synthesized safepoint nodes, used to keep
   // track of live intervals across safepoints.
-  // TODO: Should build safepoints elsewhere.
   void BuildInterferenceGraph(const ArenaVector<LiveInterval*>& intervals,
-                              const ArenaVector<InterferenceNode*>& physical_nodes,
+                              ArenaVector<InterferenceNode*>* prunable_nodes,
                               ArenaVector<InterferenceNode*>* safepoints);
 
   // Prune nodes from the interference graph to be colored later. Build
@@ -161,61 +131,11 @@
                               size_t num_registers,
                               ArenaStdStack<InterferenceNode*>* pruned_nodes);
 
-  // Add an edge in the interference graph, if valid.
-  // Note that `guaranteed_not_interfering_yet` is used to optimize adjacency set insertion
-  // when possible.
-  void AddPotentialInterference(InterferenceNode* from,
-                                InterferenceNode* to,
-                                bool guaranteed_not_interfering_yet,
-                                bool both_directions = true);
-
-  // Create a coalesce opportunity between two nodes.
-  void CreateCoalesceOpportunity(InterferenceNode* a,
-                                 InterferenceNode* b,
-                                 CoalesceKind kind,
-                                 size_t position);
-
-  // Add coalesce opportunities to interference nodes.
-  void FindCoalesceOpportunities();
-
-  // Prune nodes from the interference graph to be colored later. Returns
-  // a stack containing these intervals in an order determined by various
-  // heuristics.
-  // Also performs iterative conservative coalescing, based on Modern Compiler Implementation
-  // in Java, 2nd ed. (Andrew Appel, Cambridge University Press.)
-  void PruneInterferenceGraph(size_t num_registers);
-
-  // Invalidate all coalesce opportunities this node has, so that it (and possibly its neighbors)
-  // may be pruned from the interference graph.
-  void FreezeMoves(InterferenceNode* node, size_t num_regs);
-
-  // Prune a node from the interference graph, updating worklists if necessary.
-  void PruneNode(InterferenceNode* node, size_t num_regs);
-
-  // Add coalesce opportunities associated with this node to the coalesce worklist.
-  void EnableCoalesceOpportunities(InterferenceNode* node);
-
-  // If needed, from `node` from the freeze worklist to the simplify worklist.
-  void CheckTransitionFromFreezeWorklist(InterferenceNode* node, size_t num_regs);
-
-  // Return true if `into` is colored, and `from` can be coalesced with `into` conservatively.
-  bool PrecoloredHeuristic(InterferenceNode* from, InterferenceNode* into, size_t num_regs);
-
-  // Return true if `from` and `into` are uncolored, and can be coalesced conservatively.
-  bool UncoloredHeuristic(InterferenceNode* from, InterferenceNode* into, size_t num_regs);
-
-  void Coalesce(CoalesceOpportunity* opportunity, size_t num_regs);
-
-  // Merge `from` into `into` in the interference graph.
-  void Combine(InterferenceNode* from, InterferenceNode* into, size_t num_regs);
-
-  bool IsCallerSave(size_t reg, bool processing_core_regs);
-
-  // Process pruned_intervals_ to color the interference graph, spilling when
-  // necessary. Returns true if successful. Else, some intervals have been
-  // split, and the interference graph should be rebuilt for another attempt.
-  bool ColorInterferenceGraph(size_t num_registers,
-                              bool processing_core_regs);
+  // Process pruned_intervals to color the interference graph, spilling when
+  // necessary. Return true if successful. Else, split some intervals to make
+  // the interference graph sparser.
+  bool ColorInterferenceGraph(ArenaStdStack<InterferenceNode*>* pruned_nodes,
+                              size_t num_registers);
 
   // Return the maximum number of registers live at safepoints,
   // based on the outgoing interference edges of safepoint nodes.
@@ -225,10 +145,6 @@
   // and make sure it's ready to be spilled to the stack.
   void AllocateSpillSlotFor(LiveInterval* interval);
 
-  // Whether iterative move coalescing should be performed. Iterative move coalescing
-  // improves code quality, but increases compile time.
-  const bool iterative_move_coalescing_;
-
   // Live intervals, split by kind (core and floating point).
   // These should not contain high intervals, as those are represented by
   // the corresponding low interval throughout register allocation.
@@ -241,10 +157,10 @@
   // Safepoints, saved for special handling while processing instructions.
   ArenaVector<HInstruction*> safepoints_;
 
-  // Interference nodes representing specific registers. These are "pre-colored" nodes
+  // Live intervals for specific registers. These become pre-colored nodes
   // in the interference graph.
-  ArenaVector<InterferenceNode*> physical_core_nodes_;
-  ArenaVector<InterferenceNode*> physical_fp_nodes_;
+  ArenaVector<LiveInterval*> physical_core_intervals_;
+  ArenaVector<LiveInterval*> physical_fp_intervals_;
 
   // Allocated stack slot counters.
   size_t int_spill_slot_counter_;
@@ -273,36 +189,6 @@
   // total memory usage by using a new arena allocator for each attempt.
   ArenaAllocator* coloring_attempt_allocator_;
 
-  // A monotonically increasing counter for assigning unique IDs to interference nodes.
-  // Unique IDs are used to maintain determinism when storing interference nodes in certain
-  // data structure, such as sets.
-  size_t node_id_counter_;
-
-  // A map from live intervals to interference nodes.
-  ArenaHashMap<LiveInterval*, InterferenceNode*> interval_node_map_;
-
-  // Uncolored nodes that should be pruned from the interference graph.
-  ArenaVector<InterferenceNode*> prunable_nodes_;
-
-  // A stack of nodes pruned from the interference graph, waiting to be pruned.
-  ArenaStdStack<InterferenceNode*> pruned_nodes_;
-
-  // A queue containing low degree, non-move-related nodes that can pruned immediately.
-  ArenaDeque<InterferenceNode*> simplify_worklist_;
-
-  // A queue containing low degree, move-related nodes.
-  ArenaDeque<InterferenceNode*> freeze_worklist_;
-
-  // A queue containing high degree nodes.
-  // If we have to prune from the spill worklist, we cannot guarantee
-  // the pruned node a color, so we order the worklist by priority.
-  ArenaPriorityQueue<InterferenceNode*, decltype(&HasGreaterNodePriority)> spill_worklist_;
-
-  // A queue containing coalesce opportunities.
-  // We order the coalesce worklist by priority, since some coalesce opportunities (e.g., those
-  // inside of loops) are more important than others.
-  ArenaPriorityQueue<CoalesceOpportunity*, decltype(&CmpCoalesceOpportunity)> coalesce_worklist_;
-
   DISALLOW_COPY_AND_ASSIGN(RegisterAllocatorGraphColor);
 };
 
diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h
index 92788fe..346753b 100644
--- a/compiler/optimizing/ssa_liveness_analysis.h
+++ b/compiler/optimizing/ssa_liveness_analysis.h
@@ -514,9 +514,7 @@
 
   // Whether the interval requires a register rather than a stack location.
   // If needed for performance, this could be cached.
-  bool RequiresRegister() const {
-    return !HasRegister() && FirstRegisterUse() != kNoLifetime;
-  }
+  bool RequiresRegister() const { return FirstRegisterUse() != kNoLifetime; }
 
   size_t FirstUseAfter(size_t position) const {
     if (is_temp_) {
