Implement the 1.8 unsafe memory fences directly in HIR.

Rationale:
More efficient since it exposes full semantics to
all operations on the graph and allows for proper
code generation for all architectures.

bug=26264765

Change-Id: Ic435886cf0645927a101a8502f0623fa573989ff
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index f8a9a94..b95ece5 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -94,6 +94,7 @@
   void SimplifyCompare(HInvoke* invoke, bool has_zero_op);
   void SimplifyIsNaN(HInvoke* invoke);
   void SimplifyFP2Int(HInvoke* invoke);
+  void SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind);
 
   OptimizingCompilerStats* stats_;
   bool simplification_occurred_ = false;
@@ -1594,6 +1595,12 @@
   invoke->ReplaceWithExceptInReplacementAtIndex(select, 0);  // false at index 0
 }
 
+void InstructionSimplifierVisitor::SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind) {
+  uint32_t dex_pc = invoke->GetDexPc();
+  HMemoryBarrier* mem_barrier = new (GetGraph()->GetArena()) HMemoryBarrier(barrier_kind, dex_pc);
+  invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, mem_barrier);
+}
+
 void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
   switch (instruction->GetIntrinsic()) {
     case Intrinsics::kStringEquals:
@@ -1626,6 +1633,15 @@
     case Intrinsics::kDoubleDoubleToLongBits:
       SimplifyFP2Int(instruction);
       break;
+    case Intrinsics::kUnsafeLoadFence:
+      SimplifyMemBarrier(instruction, MemBarrierKind::kLoadAny);
+      break;
+    case Intrinsics::kUnsafeStoreFence:
+      SimplifyMemBarrier(instruction, MemBarrierKind::kAnyStore);
+      break;
+    case Intrinsics::kUnsafeFullFence:
+      SimplifyMemBarrier(instruction, MemBarrierKind::kAnyAny);
+      break;
     default:
       break;
   }
diff --git a/compiler/optimizing/intrinsics.h b/compiler/optimizing/intrinsics.h
index 0cec5cc..3da8285 100644
--- a/compiler/optimizing/intrinsics.h
+++ b/compiler/optimizing/intrinsics.h
@@ -231,7 +231,10 @@
 UNREACHABLE_INTRINSIC(Arch, IntegerCompare)         \
 UNREACHABLE_INTRINSIC(Arch, LongCompare)            \
 UNREACHABLE_INTRINSIC(Arch, IntegerSignum)          \
-UNREACHABLE_INTRINSIC(Arch, LongSignum)
+UNREACHABLE_INTRINSIC(Arch, LongSignum)             \
+UNREACHABLE_INTRINSIC(Arch, UnsafeLoadFence)        \
+UNREACHABLE_INTRINSIC(Arch, UnsafeStoreFence)       \
+UNREACHABLE_INTRINSIC(Arch, UnsafeFullFence)
 
 }  // namespace art
 
diff --git a/compiler/optimizing/intrinsics_arm.cc b/compiler/optimizing/intrinsics_arm.cc
index b599d42..c7d9a0d 100644
--- a/compiler/optimizing/intrinsics_arm.cc
+++ b/compiler/optimizing/intrinsics_arm.cc
@@ -2008,9 +2008,6 @@
 UNIMPLEMENTED_INTRINSIC(ARM, UnsafeGetAndSetInt)
 UNIMPLEMENTED_INTRINSIC(ARM, UnsafeGetAndSetLong)
 UNIMPLEMENTED_INTRINSIC(ARM, UnsafeGetAndSetObject)
-UNIMPLEMENTED_INTRINSIC(ARM, UnsafeLoadFence)
-UNIMPLEMENTED_INTRINSIC(ARM, UnsafeStoreFence)
-UNIMPLEMENTED_INTRINSIC(ARM, UnsafeFullFence)
 
 UNREACHABLE_INTRINSICS(ARM)
 
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc
index ccbbd43..8a44441 100644
--- a/compiler/optimizing/intrinsics_arm64.cc
+++ b/compiler/optimizing/intrinsics_arm64.cc
@@ -1959,9 +1959,6 @@
 UNIMPLEMENTED_INTRINSIC(ARM64, UnsafeGetAndSetInt)
 UNIMPLEMENTED_INTRINSIC(ARM64, UnsafeGetAndSetLong)
 UNIMPLEMENTED_INTRINSIC(ARM64, UnsafeGetAndSetObject)
-UNIMPLEMENTED_INTRINSIC(ARM64, UnsafeLoadFence)
-UNIMPLEMENTED_INTRINSIC(ARM64, UnsafeStoreFence)
-UNIMPLEMENTED_INTRINSIC(ARM64, UnsafeFullFence)
 
 UNREACHABLE_INTRINSICS(ARM64)
 
diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc
index 697b8fe..e159701 100644
--- a/compiler/optimizing/intrinsics_mips.cc
+++ b/compiler/optimizing/intrinsics_mips.cc
@@ -1838,9 +1838,6 @@
 UNIMPLEMENTED_INTRINSIC(MIPS, UnsafeGetAndSetInt)
 UNIMPLEMENTED_INTRINSIC(MIPS, UnsafeGetAndSetLong)
 UNIMPLEMENTED_INTRINSIC(MIPS, UnsafeGetAndSetObject)
-UNIMPLEMENTED_INTRINSIC(MIPS, UnsafeLoadFence)
-UNIMPLEMENTED_INTRINSIC(MIPS, UnsafeStoreFence)
-UNIMPLEMENTED_INTRINSIC(MIPS, UnsafeFullFence)
 
 UNREACHABLE_INTRINSICS(MIPS)
 
diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc
index 83dff33..0dc602f 100644
--- a/compiler/optimizing/intrinsics_mips64.cc
+++ b/compiler/optimizing/intrinsics_mips64.cc
@@ -1735,9 +1735,6 @@
 UNIMPLEMENTED_INTRINSIC(MIPS64, UnsafeGetAndSetInt)
 UNIMPLEMENTED_INTRINSIC(MIPS64, UnsafeGetAndSetLong)
 UNIMPLEMENTED_INTRINSIC(MIPS64, UnsafeGetAndSetObject)
-UNIMPLEMENTED_INTRINSIC(MIPS64, UnsafeLoadFence)
-UNIMPLEMENTED_INTRINSIC(MIPS64, UnsafeStoreFence)
-UNIMPLEMENTED_INTRINSIC(MIPS64, UnsafeFullFence)
 
 UNREACHABLE_INTRINSICS(MIPS64)
 
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc
index 048590e..4c802c0 100644
--- a/compiler/optimizing/intrinsics_x86.cc
+++ b/compiler/optimizing/intrinsics_x86.cc
@@ -2643,9 +2643,6 @@
 UNIMPLEMENTED_INTRINSIC(X86, UnsafeGetAndSetInt)
 UNIMPLEMENTED_INTRINSIC(X86, UnsafeGetAndSetLong)
 UNIMPLEMENTED_INTRINSIC(X86, UnsafeGetAndSetObject)
-UNIMPLEMENTED_INTRINSIC(X86, UnsafeLoadFence)
-UNIMPLEMENTED_INTRINSIC(X86, UnsafeStoreFence)
-UNIMPLEMENTED_INTRINSIC(X86, UnsafeFullFence)
 
 UNREACHABLE_INTRINSICS(X86)
 
diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc
index 35e13a6..41095cd 100644
--- a/compiler/optimizing/intrinsics_x86_64.cc
+++ b/compiler/optimizing/intrinsics_x86_64.cc
@@ -2721,9 +2721,6 @@
 UNIMPLEMENTED_INTRINSIC(X86_64, UnsafeGetAndSetInt)
 UNIMPLEMENTED_INTRINSIC(X86_64, UnsafeGetAndSetLong)
 UNIMPLEMENTED_INTRINSIC(X86_64, UnsafeGetAndSetObject)
-UNIMPLEMENTED_INTRINSIC(X86_64, UnsafeLoadFence)
-UNIMPLEMENTED_INTRINSIC(X86_64, UnsafeStoreFence)
-UNIMPLEMENTED_INTRINSIC(X86_64, UnsafeFullFence)
 
 UNREACHABLE_INTRINSICS(X86_64)
 
diff --git a/test/004-checker-UnsafeTest18/src/Main.java b/test/004-checker-UnsafeTest18/src/Main.java
index bb6de2e..bb020b9 100644
--- a/test/004-checker-UnsafeTest18/src/Main.java
+++ b/test/004-checker-UnsafeTest18/src/Main.java
@@ -87,18 +87,36 @@
 
   /// CHECK-START: void Main.load() intrinsics_recognition (after)
   /// CHECK-DAG: InvokeVirtual intrinsic:UnsafeLoadFence
+  //
+  /// CHECK-START: void Main.load() instruction_simplifier (after)
+  /// CHECK-NOT: InvokeVirtual intrinsic:UnsafeLoadFence
+  //
+  /// CHECK-START: void Main.load() instruction_simplifier (after)
+  /// CHECK-DAG: MemoryBarrier kind:LoadAny
   private static void load() {
     unsafe.loadFence();
   }
 
   /// CHECK-START: void Main.store() intrinsics_recognition (after)
   /// CHECK-DAG: InvokeVirtual intrinsic:UnsafeStoreFence
+  //
+  /// CHECK-START: void Main.store() instruction_simplifier (after)
+  /// CHECK-NOT: InvokeVirtual intrinsic:UnsafeStoreFence
+  //
+  /// CHECK-START: void Main.store() instruction_simplifier (after)
+  /// CHECK-DAG: MemoryBarrier kind:AnyStore
   private static void store() {
     unsafe.storeFence();
   }
 
   /// CHECK-START: void Main.full() intrinsics_recognition (after)
   /// CHECK-DAG: InvokeVirtual intrinsic:UnsafeFullFence
+  //
+  /// CHECK-START: void Main.full() instruction_simplifier (after)
+  /// CHECK-NOT: InvokeVirtual intrinsic:UnsafeFullFence
+  //
+  /// CHECK-START: void Main.full() instruction_simplifier (after)
+  /// CHECK-DAG: MemoryBarrier kind:AnyAny
   private static void full() {
     unsafe.fullFence();
   }