Merge "ART: Change GenPCUseDefEncoding(), turn on Load Hoisting for ARM64"
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index 711743d..d097500 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -96,7 +96,6 @@
     ~0U,
     // 2 = kArm64.     TODO(Arm64): enable optimizations once backend is mature enough.
     (1 << kLoadStoreElimination) |
-    (1 << kLoadHoisting) |
     0,
     // 3 = kThumb2.
     0,
diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc
index ef9dbdd..be3cd8e 100644
--- a/compiler/dex/quick/arm64/target_arm64.cc
+++ b/compiler/dex/quick/arm64/target_arm64.cc
@@ -158,7 +158,6 @@
 }
 
 ResourceMask Arm64Mir2Lir::GetPCUseDefEncoding() const {
-  LOG(FATAL) << "Unexpected call to GetPCUseDefEncoding for Arm64";
   return kEncodeNone;
 }
 
diff --git a/compiler/dex/quick/local_optimizations.cc b/compiler/dex/quick/local_optimizations.cc
index b97ff2a..2893157 100644
--- a/compiler/dex/quick/local_optimizations.cc
+++ b/compiler/dex/quick/local_optimizations.cc
@@ -121,20 +121,22 @@
     }
 
     ResourceMask stop_def_reg_mask = this_lir->u.m.def_mask->Without(kEncodeMem);
-    ResourceMask stop_use_reg_mask;
-    if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64) {
+
+    /*
+     * Add pc to the resource mask to prevent this instruction
+     * from sinking past branch instructions. Also take out the memory
+     * region bits since stop_mask is used to check data/control
+     * dependencies.
+     *
+     * Note: on x86(-64) and Arm64 we use the IsBranch bit, as the PC is not exposed.
+     */
+    ResourceMask pc_encoding = GetPCUseDefEncoding();
+    if (pc_encoding == kEncodeNone) {
       // TODO: Stop the abuse of kIsBranch as a bit specification for ResourceMask.
-      stop_use_reg_mask = ResourceMask::Bit(kIsBranch).Union(*this_lir->u.m.use_mask).Without(
-          kEncodeMem);
-    } else {
-      /*
-       * Add pc to the resource mask to prevent this instruction
-       * from sinking past branch instructions. Also take out the memory
-       * region bits since stop_mask is used to check data/control
-       * dependencies.
-       */
-      stop_use_reg_mask = GetPCUseDefEncoding().Union(*this_lir->u.m.use_mask).Without(kEncodeMem);
+      pc_encoding = ResourceMask::Bit(kIsBranch);
     }
+    ResourceMask  stop_use_reg_mask = pc_encoding.Union(*this_lir->u.m.use_mask).
+        Without(kEncodeMem);
 
     for (check_lir = NEXT_LIR(this_lir); check_lir != tail_lir; check_lir = NEXT_LIR(check_lir)) {
       /*
@@ -310,16 +312,17 @@
 
     ResourceMask stop_use_all_mask = *this_lir->u.m.use_mask;
 
-    if (cu_->instruction_set != kX86 && cu_->instruction_set != kX86_64) {
-      /*
-       * Branches for null/range checks are marked with the true resource
-       * bits, and loads to Dalvik registers, constant pools, and non-alias
-       * locations are safe to be hoisted. So only mark the heap references
-       * conservatively here.
-       */
-      if (stop_use_all_mask.HasBit(ResourceMask::kHeapRef)) {
-        stop_use_all_mask.SetBits(GetPCUseDefEncoding());
-      }
+    /*
+     * Branches for null/range checks are marked with the true resource
+     * bits, and loads to Dalvik registers, constant pools, and non-alias
+     * locations are safe to be hoisted. So only mark the heap references
+     * conservatively here.
+     *
+     * Note: on x86(-64) and Arm64 this will add kEncodeNone.
+     * TODO: Sanity check. LoadStoreElimination uses kBranchBit to fake a PC.
+     */
+    if (stop_use_all_mask.HasBit(ResourceMask::kHeapRef)) {
+      stop_use_all_mask.SetBits(GetPCUseDefEncoding());
     }
 
     /* Similar as above, but just check for pure register dependency */
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 87509b6..d1e83c2 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -1263,6 +1263,9 @@
     virtual const char* GetTargetInstFmt(int opcode) = 0;
     virtual const char* GetTargetInstName(int opcode) = 0;
     virtual std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr) = 0;
+
+    // Note: This may return kEncodeNone on architectures that do not expose a PC. The caller must
+    //       take care of this.
     virtual ResourceMask GetPCUseDefEncoding() const = 0;
     virtual uint64_t GetTargetInstFlags(int opcode) = 0;
     virtual size_t GetInsnSize(LIR* lir) = 0;
diff --git a/compiler/dex/quick/resource_mask.h b/compiler/dex/quick/resource_mask.h
index 12ce98a..436cdb5 100644
--- a/compiler/dex/quick/resource_mask.h
+++ b/compiler/dex/quick/resource_mask.h
@@ -63,6 +63,11 @@
   ResourceMask(const ResourceMask& other) = default;
   ResourceMask& operator=(const ResourceMask& other) = default;
 
+  // Comparable by content.
+  bool operator==(const ResourceMask& other) {
+    return masks_[0] == other.masks_[0] && masks_[1] == other.masks_[1];
+  }
+
   static constexpr ResourceMask RawMask(uint64_t mask1, uint64_t mask2) {
     return ResourceMask(mask1, mask2);
   }
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index 4310525..0083128 100755
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -246,11 +246,6 @@
 }
 
 ResourceMask X86Mir2Lir::GetPCUseDefEncoding() const {
-  /*
-   * FIXME: might make sense to use a virtual resource encoding bit for pc.  Might be
-   * able to clean up some of the x86/Arm_Mips differences
-   */
-  LOG(FATAL) << "Unexpected call to GetPCUseDefEncoding for x86";
   return kEncodeNone;
 }