Subzero: Use register availability during lowering to improve the code.

The problem is that given code like this:

  a = b + c
  d = a + e
  ...
  ... (use of a) ...

Lowering may produce code like this, at least on x86:

  T1 = b
  T1 += c
  a = T1
  T2 = a
  T2 += e
  d = T2
  ...
  ... (use of a) ...

If "a" has a long live range, it may not get a register, resulting in clumsy code in the middle of the sequence like "a=reg; reg=a".  Normally one might expect store forwarding to make the clumsy code fast, but it does presumably add an extra instruction-retirement cycle to the critical path in a pointer-chasing loop, and makes a big difference on some benchmarks.

The simple fix here is, at the end of lowering "a=b+c", keep track of the final "a=T1" assignment.  Then, when lowering "d=a+e" and we look up "a", we can substitute "T1".  This slightly increases the live range of T1, but it does a great job of avoiding the redundant reload of the register from the stack location.

A more general fix (in the future) might be to do live range splitting and let the register allocator handle it.

BUG= https://code.google.com/p/nativeclient/issues/detail?id=4095
R=kschimpf@google.com

Review URL: https://codereview.chromium.org/1385433002 .
diff --git a/src/IceTargetLowering.h b/src/IceTargetLowering.h
index 0095a39..f35983f 100644
--- a/src/IceTargetLowering.h
+++ b/src/IceTargetLowering.h
@@ -65,6 +65,9 @@
   void setNext(InstList::iterator N) { Next = N; }
   void rewind();
   void setInsertPoint(const InstList::iterator &Position) { Next = Position; }
+  void availabilityReset();
+  void availabilityUpdate();
+  Variable *availabilityGet(Operand *Src) const;
 
 private:
   /// Node is the argument to Inst::updateVars().
@@ -85,6 +88,11 @@
   InstList::iterator Begin;
   /// End is a copy of Insts.end(), used if Next needs to be advanced.
   InstList::iterator End;
+  /// LastDest and LastSrc capture the parameters of the last "Dest=Src" simple
+  /// assignment inserted (provided Src is a variable).  This is used for simple
+  /// availability analysis.
+  Variable *LastDest = nullptr;
+  Variable *LastSrc = nullptr;
 
   void skipDeleted(InstList::iterator &I) const;
   void advanceForward(InstList::iterator &I) const;