Add a write barrier elimination pass

We can eliminate redundant write barriers as we don't need several
for the same receiver. For example:

```
MyObject o;
o.inner_obj = io;
o.inner_obj2 = io2;
o.inner_obj3 = io3;
```

We can keep the write barrier for `inner_obj` and remove the other
two.

Note that we cannot perform this optimization across
invokes, suspend check, or instructions that can throw.

Local improvements (pixel 5, speed compile):
 * System server: -280KB (-0.56%)
 * SystemUIGoogle: -330KB (-1.16%)
 * AGSA: -3876KB (-1.19%)

Bug: 260843353
Fixes: 260843353
Change-Id: Ibf98efbe891ee00e46125853c3e97ae30aa3ff30
diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h
index ffc2641..1fac62f 100644
--- a/compiler/optimizing/code_generator_x86_64.h
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -251,7 +251,8 @@
                       bool is_volatile,
                       bool is_atomic,
                       bool value_can_be_null,
-                      bool byte_swap = false);
+                      bool byte_swap,
+                      WriteBarrierKind write_barrier_kind);
 
   void Bswap(Location value, DataType::Type type, CpuRegister* temp = nullptr);
 
@@ -274,7 +275,8 @@
 
   void HandleFieldSet(HInstruction* instruction,
                       const FieldInfo& field_info,
-                      bool value_can_be_null);
+                      bool value_can_be_null,
+                      WriteBarrierKind write_barrier_kind);
   void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
 
   void GenerateMinMaxInt(LocationSummary* locations, bool is_min, DataType::Type type);
@@ -436,7 +438,7 @@
                   CpuRegister card,
                   CpuRegister object,
                   CpuRegister value,
-                  bool value_can_be_null);
+                  bool emit_null_check);
 
   void GenerateMemoryBarrier(MemBarrierKind kind);