Add dex_pc to all HInstructions in builder.

Optimizing compiler generates minimum debug line info that
is built using the dex_pc information about suspend points.
This is not enough for performance and debugging needs.

This patch makes all HInstructions contain
dex_pc and all allocations in the builder define this value.

Change-Id: I1d14aefe075189b7b1b41b4384c3499474c19afc
Signed-off-by: Yevgeny Rouban <yevgeny.y.rouban@intel.com>
Signed-off-by: Serdjuk, Nikolay Y <nikolay.y.serdjuk@intel.com>
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index fef6f21..d939a80 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -77,6 +77,8 @@
 
 static constexpr InvokeType kInvalidInvokeType = static_cast<InvokeType>(-1);
 
+static constexpr uint32_t kNoDexPc = -1;
+
 enum IfCondition {
   kCondEQ,
   kCondNE,
@@ -316,24 +318,24 @@
   // Returns a constant of the given type and value. If it does not exist
   // already, it is created and inserted into the graph. This method is only for
   // integral types.
-  HConstant* GetConstant(Primitive::Type type, int64_t value);
+  HConstant* GetConstant(Primitive::Type type, int64_t value, uint32_t dex_pc = kNoDexPc);
 
   // TODO: This is problematic for the consistency of reference type propagation
   // because it can be created anytime after the pass and thus it will be left
   // with an invalid type.
-  HNullConstant* GetNullConstant();
+  HNullConstant* GetNullConstant(uint32_t dex_pc = kNoDexPc);
 
-  HIntConstant* GetIntConstant(int32_t value) {
-    return CreateConstant(value, &cached_int_constants_);
+  HIntConstant* GetIntConstant(int32_t value, uint32_t dex_pc = kNoDexPc) {
+    return CreateConstant(value, &cached_int_constants_, dex_pc);
   }
-  HLongConstant* GetLongConstant(int64_t value) {
-    return CreateConstant(value, &cached_long_constants_);
+  HLongConstant* GetLongConstant(int64_t value, uint32_t dex_pc = kNoDexPc) {
+    return CreateConstant(value, &cached_long_constants_, dex_pc);
   }
-  HFloatConstant* GetFloatConstant(float value) {
-    return CreateConstant(bit_cast<int32_t, float>(value), &cached_float_constants_);
+  HFloatConstant* GetFloatConstant(float value, uint32_t dex_pc = kNoDexPc) {
+    return CreateConstant(bit_cast<int32_t, float>(value), &cached_float_constants_, dex_pc);
   }
-  HDoubleConstant* GetDoubleConstant(double value) {
-    return CreateConstant(bit_cast<int64_t, double>(value), &cached_double_constants_);
+  HDoubleConstant* GetDoubleConstant(double value, uint32_t dex_pc = kNoDexPc) {
+    return CreateConstant(bit_cast<int64_t, double>(value), &cached_double_constants_, dex_pc);
   }
 
   HCurrentMethod* GetCurrentMethod();
@@ -372,7 +374,8 @@
 
   template <class InstructionType, typename ValueType>
   InstructionType* CreateConstant(ValueType value,
-                                  ArenaSafeMap<ValueType, InstructionType*>* cache) {
+                                  ArenaSafeMap<ValueType, InstructionType*>* cache,
+                                  uint32_t dex_pc = kNoDexPc) {
     // Try to find an existing constant of the given value.
     InstructionType* constant = nullptr;
     auto cached_constant = cache->find(value);
@@ -383,7 +386,7 @@
     // If not found or previously deleted, create and cache a new instruction.
     // Don't bother reviving a previously deleted instruction, for simplicity.
     if (constant == nullptr || constant->GetBlock() == nullptr) {
-      constant = new (arena_) InstructionType(value);
+      constant = new (arena_) InstructionType(value, dex_pc);
       cache->Overwrite(value, constant);
       InsertConstant(constant);
     }
@@ -618,7 +621,6 @@
 };
 
 static constexpr size_t kNoLifetime = -1;
-static constexpr uint32_t kNoDexPc = -1;
 
 // A block in a method. Contains the list of instructions represented
 // as a double linked list. Each block knows its predecessors and
@@ -626,7 +628,7 @@
 
 class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> {
  public:
-  explicit HBasicBlock(HGraph* graph, uint32_t dex_pc = kNoDexPc)
+  HBasicBlock(HGraph* graph, uint32_t dex_pc = kNoDexPc)
       : graph_(graph),
         predecessors_(graph->GetArena(), kDefaultNumberOfPredecessors),
         successors_(graph->GetArena(), kDefaultNumberOfSuccessors),
@@ -683,6 +685,7 @@
 
   int GetBlockId() const { return block_id_; }
   void SetBlockId(int id) { block_id_ = id; }
+  uint32_t GetDexPc() const { return dex_pc_; }
 
   HBasicBlock* GetDominator() const { return dominator_; }
   void SetDominator(HBasicBlock* dominator) { dominator_ = dominator; }
@@ -943,7 +946,6 @@
   void SetLifetimeStart(size_t start) { lifetime_start_ = start; }
   void SetLifetimeEnd(size_t end) { lifetime_end_ = end; }
 
-  uint32_t GetDexPc() const { return dex_pc_; }
 
   bool EndsWithControlFlowInstruction() const;
   bool EndsWithIf() const;
@@ -1689,10 +1691,11 @@
 
 class HInstruction : public ArenaObject<kArenaAllocInstruction> {
  public:
-  explicit HInstruction(SideEffects side_effects)
+  HInstruction(SideEffects side_effects, uint32_t dex_pc = kNoDexPc)
       : previous_(nullptr),
         next_(nullptr),
         block_(nullptr),
+        dex_pc_(dex_pc),
         id_(-1),
         ssa_index_(-1),
         environment_(nullptr),
@@ -1735,9 +1738,9 @@
   }
 
   virtual bool NeedsEnvironment() const { return false; }
-  virtual uint32_t GetDexPc() const {
-    return kNoDexPc;
-  }
+
+  uint32_t GetDexPc() const { return dex_pc_; }
+
   virtual bool IsControlFlow() const { return false; }
 
   virtual bool CanThrow() const { return false; }
@@ -1940,6 +1943,7 @@
   HInstruction* previous_;
   HInstruction* next_;
   HBasicBlock* block_;
+  const uint32_t dex_pc_;
 
   // An instruction gets an id when it is added to the graph.
   // It reflects creation order. A negative id means the instruction
@@ -2044,8 +2048,8 @@
 template<size_t N>
 class HTemplateInstruction: public HInstruction {
  public:
-  HTemplateInstruction<N>(SideEffects side_effects)
-      : HInstruction(side_effects), inputs_() {}
+  HTemplateInstruction<N>(SideEffects side_effects, uint32_t dex_pc = kNoDexPc)
+      : HInstruction(side_effects, dex_pc), inputs_() {}
   virtual ~HTemplateInstruction() {}
 
   size_t InputCount() const OVERRIDE { return N; }
@@ -2071,7 +2075,9 @@
 template<>
 class HTemplateInstruction<0>: public HInstruction {
  public:
-  explicit HTemplateInstruction(SideEffects side_effects) : HInstruction(side_effects) {}
+  explicit HTemplateInstruction<0>(SideEffects side_effects, uint32_t dex_pc = kNoDexPc)
+      : HInstruction(side_effects, dex_pc) {}
+
   virtual ~HTemplateInstruction() {}
 
   size_t InputCount() const OVERRIDE { return 0; }
@@ -2095,8 +2101,8 @@
 template<intptr_t N>
 class HExpression : public HTemplateInstruction<N> {
  public:
-  HExpression<N>(Primitive::Type type, SideEffects side_effects)
-      : HTemplateInstruction<N>(side_effects), type_(type) {}
+  HExpression<N>(Primitive::Type type, SideEffects side_effects, uint32_t dex_pc = kNoDexPc)
+      : HTemplateInstruction<N>(side_effects, dex_pc), type_(type) {}
   virtual ~HExpression() {}
 
   Primitive::Type GetType() const OVERRIDE { return type_; }
@@ -2109,7 +2115,8 @@
 // instruction that branches to the exit block.
 class HReturnVoid : public HTemplateInstruction<0> {
  public:
-  HReturnVoid() : HTemplateInstruction(SideEffects::None()) {}
+  explicit HReturnVoid(uint32_t dex_pc = kNoDexPc)
+      : HTemplateInstruction(SideEffects::None(), dex_pc) {}
 
   bool IsControlFlow() const OVERRIDE { return true; }
 
@@ -2123,7 +2130,8 @@
 // instruction that branches to the exit block.
 class HReturn : public HTemplateInstruction<1> {
  public:
-  explicit HReturn(HInstruction* value) : HTemplateInstruction(SideEffects::None()) {
+  explicit HReturn(HInstruction* value, uint32_t dex_pc = kNoDexPc)
+      : HTemplateInstruction(SideEffects::None(), dex_pc) {
     SetRawInputAt(0, value);
   }
 
@@ -2140,7 +2148,7 @@
 // exit block.
 class HExit : public HTemplateInstruction<0> {
  public:
-  HExit() : HTemplateInstruction(SideEffects::None()) {}
+  explicit HExit(uint32_t dex_pc = kNoDexPc) : HTemplateInstruction(SideEffects::None(), dex_pc) {}
 
   bool IsControlFlow() const OVERRIDE { return true; }
 
@@ -2153,7 +2161,7 @@
 // Jumps from one block to another.
 class HGoto : public HTemplateInstruction<0> {
  public:
-  HGoto() : HTemplateInstruction(SideEffects::None()) {}
+  explicit HGoto(uint32_t dex_pc = kNoDexPc) : HTemplateInstruction(SideEffects::None(), dex_pc) {}
 
   bool IsControlFlow() const OVERRIDE { return true; }
 
@@ -2169,7 +2177,8 @@
 
 class HConstant : public HExpression<0> {
  public:
-  explicit HConstant(Primitive::Type type) : HExpression(type, SideEffects::None()) {}
+  explicit HConstant(Primitive::Type type, uint32_t dex_pc = kNoDexPc)
+      : HExpression(type, SideEffects::None(), dex_pc) {}
 
   bool CanBeMoved() const OVERRIDE { return true; }
 
@@ -2194,7 +2203,7 @@
   DECLARE_INSTRUCTION(NullConstant);
 
  private:
-  HNullConstant() : HConstant(Primitive::kPrimNot) {}
+  explicit HNullConstant(uint32_t dex_pc = kNoDexPc) : HConstant(Primitive::kPrimNot, dex_pc) {}
 
   friend class HGraph;
   DISALLOW_COPY_AND_ASSIGN(HNullConstant);
@@ -2220,8 +2229,10 @@
   DECLARE_INSTRUCTION(IntConstant);
 
  private:
-  explicit HIntConstant(int32_t value) : HConstant(Primitive::kPrimInt), value_(value) {}
-  explicit HIntConstant(bool value) : HConstant(Primitive::kPrimInt), value_(value ? 1 : 0) {}
+  explicit HIntConstant(int32_t value, uint32_t dex_pc = kNoDexPc)
+      : HConstant(Primitive::kPrimInt, dex_pc), value_(value) {}
+  explicit HIntConstant(bool value, uint32_t dex_pc = kNoDexPc)
+      : HConstant(Primitive::kPrimInt, dex_pc), value_(value ? 1 : 0) {}
 
   const int32_t value_;
 
@@ -2249,7 +2260,8 @@
   DECLARE_INSTRUCTION(LongConstant);
 
  private:
-  explicit HLongConstant(int64_t value) : HConstant(Primitive::kPrimLong), value_(value) {}
+  explicit HLongConstant(int64_t value, uint32_t dex_pc = kNoDexPc)
+      : HConstant(Primitive::kPrimLong, dex_pc), value_(value) {}
 
   const int64_t value_;
 
@@ -2261,7 +2273,8 @@
 // two successors.
 class HIf : public HTemplateInstruction<1> {
  public:
-  explicit HIf(HInstruction* input) : HTemplateInstruction(SideEffects::None()) {
+  explicit HIf(HInstruction* input, uint32_t dex_pc = kNoDexPc)
+      : HTemplateInstruction(SideEffects::None(), dex_pc) {
     SetRawInputAt(0, input);
   }
 
@@ -2294,8 +2307,8 @@
     kExit,
   };
 
-  explicit HTryBoundary(BoundaryKind kind)
-      : HTemplateInstruction(SideEffects::None()), kind_(kind) {}
+  explicit HTryBoundary(BoundaryKind kind, uint32_t dex_pc = kNoDexPc)
+      : HTemplateInstruction(SideEffects::None(), dex_pc), kind_(kind) {}
 
   bool IsControlFlow() const OVERRIDE { return true; }
 
@@ -2352,21 +2365,17 @@
 // Deoptimize to interpreter, upon checking a condition.
 class HDeoptimize : public HTemplateInstruction<1> {
  public:
-  HDeoptimize(HInstruction* cond, uint32_t dex_pc)
-      : HTemplateInstruction(SideEffects::None()),
-        dex_pc_(dex_pc) {
+  explicit HDeoptimize(HInstruction* cond, uint32_t dex_pc)
+      : HTemplateInstruction(SideEffects::None(), dex_pc) {
     SetRawInputAt(0, cond);
   }
 
   bool NeedsEnvironment() const OVERRIDE { return true; }
   bool CanThrow() const OVERRIDE { return true; }
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
 
   DECLARE_INSTRUCTION(Deoptimize);
 
  private:
-  uint32_t dex_pc_;
-
   DISALLOW_COPY_AND_ASSIGN(HDeoptimize);
 };
 
@@ -2375,7 +2384,8 @@
 // instructions that work with the dex cache.
 class HCurrentMethod : public HExpression<0> {
  public:
-  explicit HCurrentMethod(Primitive::Type type) : HExpression(type, SideEffects::None()) {}
+  explicit HCurrentMethod(Primitive::Type type, uint32_t dex_pc = kNoDexPc)
+      : HExpression(type, SideEffects::None(), dex_pc) {}
 
   DECLARE_INSTRUCTION(CurrentMethod);
 
@@ -2385,8 +2395,8 @@
 
 class HUnaryOperation : public HExpression<1> {
  public:
-  HUnaryOperation(Primitive::Type result_type, HInstruction* input)
-      : HExpression(result_type, SideEffects::None()) {
+  HUnaryOperation(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc)
+      : HExpression(result_type, SideEffects::None(), dex_pc) {
     SetRawInputAt(0, input);
   }
 
@@ -2419,8 +2429,9 @@
   HBinaryOperation(Primitive::Type result_type,
                    HInstruction* left,
                    HInstruction* right,
-                   SideEffects side_effects = SideEffects::None())
-      : HExpression(result_type, side_effects) {
+                   SideEffects side_effects = SideEffects::None(),
+                   uint32_t dex_pc = kNoDexPc)
+      : HExpression(result_type, side_effects, dex_pc) {
     SetRawInputAt(0, left);
     SetRawInputAt(1, right);
   }
@@ -2512,8 +2523,8 @@
 
 class HCondition : public HBinaryOperation {
  public:
-  HCondition(HInstruction* first, HInstruction* second)
-      : HBinaryOperation(Primitive::kPrimBoolean, first, second),
+  HCondition(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
+      : HBinaryOperation(Primitive::kPrimBoolean, first, second, SideEffects::None(), dex_pc),
         needs_materialization_(true),
         bias_(ComparisonBias::kNoBias) {}
 
@@ -2564,18 +2575,20 @@
 // Instruction to check if two inputs are equal to each other.
 class HEqual : public HCondition {
  public:
-  HEqual(HInstruction* first, HInstruction* second)
-      : HCondition(first, second) {}
+  HEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
+      : HCondition(first, second, dex_pc) {}
 
   bool IsCommutative() const OVERRIDE { return true; }
 
   template <typename T> bool Compute(T x, T y) const { return x == y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(Equal);
@@ -2594,18 +2607,20 @@
 
 class HNotEqual : public HCondition {
  public:
-  HNotEqual(HInstruction* first, HInstruction* second)
-      : HCondition(first, second) {}
+  HNotEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
+      : HCondition(first, second, dex_pc) {}
 
   bool IsCommutative() const OVERRIDE { return true; }
 
   template <typename T> bool Compute(T x, T y) const { return x != y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(NotEqual);
@@ -2624,16 +2639,18 @@
 
 class HLessThan : public HCondition {
  public:
-  HLessThan(HInstruction* first, HInstruction* second)
-      : HCondition(first, second) {}
+  HLessThan(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
+      : HCondition(first, second, dex_pc) {}
 
   template <typename T> bool Compute(T x, T y) const { return x < y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(LessThan);
@@ -2652,16 +2669,18 @@
 
 class HLessThanOrEqual : public HCondition {
  public:
-  HLessThanOrEqual(HInstruction* first, HInstruction* second)
-      : HCondition(first, second) {}
+  HLessThanOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
+      : HCondition(first, second, dex_pc) {}
 
   template <typename T> bool Compute(T x, T y) const { return x <= y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(LessThanOrEqual);
@@ -2680,16 +2699,18 @@
 
 class HGreaterThan : public HCondition {
  public:
-  HGreaterThan(HInstruction* first, HInstruction* second)
-      : HCondition(first, second) {}
+  HGreaterThan(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
+      : HCondition(first, second, dex_pc) {}
 
   template <typename T> bool Compute(T x, T y) const { return x > y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(GreaterThan);
@@ -2708,16 +2729,18 @@
 
 class HGreaterThanOrEqual : public HCondition {
  public:
-  HGreaterThanOrEqual(HInstruction* first, HInstruction* second)
-      : HCondition(first, second) {}
+  HGreaterThanOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
+      : HCondition(first, second, dex_pc) {}
 
   template <typename T> bool Compute(T x, T y) const { return x >= y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(GreaterThanOrEqual);
@@ -2744,9 +2767,12 @@
            HInstruction* second,
            ComparisonBias bias,
            uint32_t dex_pc)
-      : HBinaryOperation(Primitive::kPrimInt, first, second, SideEffectsForArchRuntimeCalls(type)),
-        bias_(bias),
-        dex_pc_(dex_pc) {
+      : HBinaryOperation(Primitive::kPrimInt,
+                         first,
+                         second,
+                         SideEffectsForArchRuntimeCalls(type),
+                         dex_pc),
+        bias_(bias) {
     DCHECK_EQ(type, first->GetType());
     DCHECK_EQ(type, second->GetType());
   }
@@ -2755,10 +2781,12 @@
   int32_t Compute(T x, T y) const { return x == y ? 0 : x > y ? 1 : -1; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
@@ -2769,7 +2797,6 @@
 
   bool IsGtBias() { return bias_ == ComparisonBias::kGtBias; }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
 
   static SideEffects SideEffectsForArchRuntimeCalls(Primitive::Type type) {
     // MIPS64 uses a runtime call for FP comparisons.
@@ -2780,7 +2807,6 @@
 
  private:
   const ComparisonBias bias_;
-  const uint32_t dex_pc_;
 
   DISALLOW_COPY_AND_ASSIGN(HCompare);
 };
@@ -2789,7 +2815,7 @@
 class HLocal : public HTemplateInstruction<0> {
  public:
   explicit HLocal(uint16_t reg_number)
-      : HTemplateInstruction(SideEffects::None()), reg_number_(reg_number) {}
+      : HTemplateInstruction(SideEffects::None(), kNoDexPc), reg_number_(reg_number) {}
 
   DECLARE_INSTRUCTION(Local);
 
@@ -2805,8 +2831,8 @@
 // Load a given local. The local is an input of this instruction.
 class HLoadLocal : public HExpression<1> {
  public:
-  HLoadLocal(HLocal* local, Primitive::Type type)
-      : HExpression(type, SideEffects::None()) {
+  HLoadLocal(HLocal* local, Primitive::Type type, uint32_t dex_pc = kNoDexPc)
+      : HExpression(type, SideEffects::None(), dex_pc) {
     SetRawInputAt(0, local);
   }
 
@@ -2822,7 +2848,8 @@
 // and the local.
 class HStoreLocal : public HTemplateInstruction<2> {
  public:
-  HStoreLocal(HLocal* local, HInstruction* value) : HTemplateInstruction(SideEffects::None()) {
+  HStoreLocal(HLocal* local, HInstruction* value, uint32_t dex_pc = kNoDexPc)
+      : HTemplateInstruction(SideEffects::None(), dex_pc) {
     SetRawInputAt(0, local);
     SetRawInputAt(1, value);
   }
@@ -2863,9 +2890,10 @@
   DECLARE_INSTRUCTION(FloatConstant);
 
  private:
-  explicit HFloatConstant(float value) : HConstant(Primitive::kPrimFloat), value_(value) {}
-  explicit HFloatConstant(int32_t value)
-      : HConstant(Primitive::kPrimFloat), value_(bit_cast<float, int32_t>(value)) {}
+  explicit HFloatConstant(float value, uint32_t dex_pc = kNoDexPc)
+      : HConstant(Primitive::kPrimFloat, dex_pc), value_(value) {}
+  explicit HFloatConstant(int32_t value, uint32_t dex_pc = kNoDexPc)
+      : HConstant(Primitive::kPrimFloat, dex_pc), value_(bit_cast<float, int32_t>(value)) {}
 
   const float value_;
 
@@ -2903,9 +2931,10 @@
   DECLARE_INSTRUCTION(DoubleConstant);
 
  private:
-  explicit HDoubleConstant(double value) : HConstant(Primitive::kPrimDouble), value_(value) {}
-  explicit HDoubleConstant(int64_t value)
-      : HConstant(Primitive::kPrimDouble), value_(bit_cast<double, int64_t>(value)) {}
+  explicit HDoubleConstant(double value, uint32_t dex_pc = kNoDexPc)
+      : HConstant(Primitive::kPrimDouble, dex_pc), value_(value) {}
+  explicit HDoubleConstant(int64_t value, uint32_t dex_pc = kNoDexPc)
+      : HConstant(Primitive::kPrimDouble, dex_pc), value_(bit_cast<double, int64_t>(value)) {}
 
   const double value_;
 
@@ -2952,7 +2981,6 @@
 
   Primitive::Type GetType() const OVERRIDE { return return_type_; }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
 
   uint32_t GetDexMethodIndex() const { return dex_method_index_; }
   const DexFile& GetDexFile() const { return GetEnvironment()->GetDexFile(); }
@@ -2985,11 +3013,10 @@
           uint32_t dex_method_index,
           InvokeType original_invoke_type)
     : HInstruction(
-          SideEffects::AllExceptGCDependency()),  // Assume write/read on all fields/arrays.
+          SideEffects::AllExceptGCDependency(), dex_pc),  // Assume write/read on all fields/arrays.
       number_of_arguments_(number_of_arguments),
       inputs_(arena, number_of_arguments),
       return_type_(return_type),
-      dex_pc_(dex_pc),
       dex_method_index_(dex_method_index),
       original_invoke_type_(original_invoke_type),
       intrinsic_(Intrinsics::kNone),
@@ -3006,7 +3033,6 @@
   uint32_t number_of_arguments_;
   GrowableArray<HUserRecord<HInstruction*> > inputs_;
   const Primitive::Type return_type_;
-  const uint32_t dex_pc_;
   const uint32_t dex_method_index_;
   const InvokeType original_invoke_type_;
   Intrinsics intrinsic_;
@@ -3307,15 +3333,13 @@
                uint16_t type_index,
                const DexFile& dex_file,
                QuickEntrypointEnum entrypoint)
-      : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC()),
-        dex_pc_(dex_pc),
+      : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC(), dex_pc),
         type_index_(type_index),
         dex_file_(dex_file),
         entrypoint_(entrypoint) {
     SetRawInputAt(0, current_method);
   }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   uint16_t GetTypeIndex() const { return type_index_; }
   const DexFile& GetDexFile() const { return dex_file_; }
 
@@ -3334,7 +3358,6 @@
   DECLARE_INSTRUCTION(NewInstance);
 
  private:
-  const uint32_t dex_pc_;
   const uint16_t type_index_;
   const DexFile& dex_file_;
   const QuickEntrypointEnum entrypoint_;
@@ -3344,16 +3367,16 @@
 
 class HNeg : public HUnaryOperation {
  public:
-  HNeg(Primitive::Type result_type, HInstruction* input)
-      : HUnaryOperation(result_type, input) {}
+  HNeg(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc)
+      : HUnaryOperation(result_type, input, dex_pc) {}
 
   template <typename T> T Compute(T x) const { return -x; }
 
   HConstant* Evaluate(HIntConstant* x) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(Neg);
@@ -3370,8 +3393,7 @@
             uint16_t type_index,
             const DexFile& dex_file,
             QuickEntrypointEnum entrypoint)
-      : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC()),
-        dex_pc_(dex_pc),
+      : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC(), dex_pc),
         type_index_(type_index),
         dex_file_(dex_file),
         entrypoint_(entrypoint) {
@@ -3379,7 +3401,6 @@
     SetRawInputAt(1, current_method);
   }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   uint16_t GetTypeIndex() const { return type_index_; }
   const DexFile& GetDexFile() const { return dex_file_; }
 
@@ -3396,7 +3417,6 @@
   DECLARE_INSTRUCTION(NewArray);
 
  private:
-  const uint32_t dex_pc_;
   const uint16_t type_index_;
   const DexFile& dex_file_;
   const QuickEntrypointEnum entrypoint_;
@@ -3406,18 +3426,23 @@
 
 class HAdd : public HBinaryOperation {
  public:
-  HAdd(Primitive::Type result_type, HInstruction* left, HInstruction* right)
-      : HBinaryOperation(result_type, left, right) {}
+  HAdd(Primitive::Type result_type,
+       HInstruction* left,
+       HInstruction* right,
+       uint32_t dex_pc = kNoDexPc)
+      : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {}
 
   bool IsCommutative() const OVERRIDE { return true; }
 
   template <typename T> T Compute(T x, T y) const { return x + y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(Add);
@@ -3428,16 +3453,21 @@
 
 class HSub : public HBinaryOperation {
  public:
-  HSub(Primitive::Type result_type, HInstruction* left, HInstruction* right)
-      : HBinaryOperation(result_type, left, right) {}
+  HSub(Primitive::Type result_type,
+       HInstruction* left,
+       HInstruction* right,
+       uint32_t dex_pc = kNoDexPc)
+      : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {}
 
   template <typename T> T Compute(T x, T y) const { return x - y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(Sub);
@@ -3448,18 +3478,23 @@
 
 class HMul : public HBinaryOperation {
  public:
-  HMul(Primitive::Type result_type, HInstruction* left, HInstruction* right)
-      : HBinaryOperation(result_type, left, right) {}
+  HMul(Primitive::Type result_type,
+       HInstruction* left,
+       HInstruction* right,
+       uint32_t dex_pc = kNoDexPc)
+      : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {}
 
   bool IsCommutative() const OVERRIDE { return true; }
 
   template <typename T> T Compute(T x, T y) const { return x * y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(Mul);
@@ -3470,9 +3505,11 @@
 
 class HDiv : public HBinaryOperation {
  public:
-  HDiv(Primitive::Type result_type, HInstruction* left, HInstruction* right, uint32_t dex_pc)
-      : HBinaryOperation(result_type, left, right, SideEffectsForArchRuntimeCalls()),
-        dex_pc_(dex_pc) {}
+  HDiv(Primitive::Type result_type,
+       HInstruction* left,
+       HInstruction* right,
+       uint32_t dex_pc)
+      : HBinaryOperation(result_type, left, right, SideEffectsForArchRuntimeCalls(), dex_pc) {}
 
   template <typename T>
   T Compute(T x, T y) const {
@@ -3484,14 +3521,14 @@
   }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
-
   static SideEffects SideEffectsForArchRuntimeCalls() {
     // The generated code can use a runtime call.
     return SideEffects::CanTriggerGC();
@@ -3500,16 +3537,16 @@
   DECLARE_INSTRUCTION(Div);
 
  private:
-  const uint32_t dex_pc_;
-
   DISALLOW_COPY_AND_ASSIGN(HDiv);
 };
 
 class HRem : public HBinaryOperation {
  public:
-  HRem(Primitive::Type result_type, HInstruction* left, HInstruction* right, uint32_t dex_pc)
-      : HBinaryOperation(result_type, left, right, SideEffectsForArchRuntimeCalls()),
-        dex_pc_(dex_pc) {}
+  HRem(Primitive::Type result_type,
+       HInstruction* left,
+       HInstruction* right,
+       uint32_t dex_pc)
+      : HBinaryOperation(result_type, left, right, SideEffectsForArchRuntimeCalls(), dex_pc) {}
 
   template <typename T>
   T Compute(T x, T y) const {
@@ -3521,13 +3558,14 @@
   }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
 
   static SideEffects SideEffectsForArchRuntimeCalls() {
     return SideEffects::CanTriggerGC();
@@ -3536,15 +3574,13 @@
   DECLARE_INSTRUCTION(Rem);
 
  private:
-  const uint32_t dex_pc_;
-
   DISALLOW_COPY_AND_ASSIGN(HRem);
 };
 
 class HDivZeroCheck : public HExpression<1> {
  public:
   HDivZeroCheck(HInstruction* value, uint32_t dex_pc)
-      : HExpression(value->GetType(), SideEffects::None()), dex_pc_(dex_pc) {
+      : HExpression(value->GetType(), SideEffects::None(), dex_pc) {
     SetRawInputAt(0, value);
   }
 
@@ -3560,20 +3596,19 @@
   bool NeedsEnvironment() const OVERRIDE { return true; }
   bool CanThrow() const OVERRIDE { return true; }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
-
   DECLARE_INSTRUCTION(DivZeroCheck);
 
  private:
-  const uint32_t dex_pc_;
-
   DISALLOW_COPY_AND_ASSIGN(HDivZeroCheck);
 };
 
 class HShl : public HBinaryOperation {
  public:
-  HShl(Primitive::Type result_type, HInstruction* left, HInstruction* right)
-      : HBinaryOperation(result_type, left, right) {}
+  HShl(Primitive::Type result_type,
+       HInstruction* left,
+       HInstruction* right,
+       uint32_t dex_pc = kNoDexPc)
+      : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {}
 
   template <typename T, typename U, typename V>
   T Compute(T x, U y, V max_shift_value) const {
@@ -3584,17 +3619,17 @@
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
     return GetBlock()->GetGraph()->GetIntConstant(
-        Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue));
+        Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue), GetDexPc());
   }
   // There is no `Evaluate(HIntConstant* x, HLongConstant* y)`, as this
   // case is handled as `x << static_cast<int>(y)`.
   HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE {
     return GetBlock()->GetGraph()->GetLongConstant(
-        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue));
+        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
     return GetBlock()->GetGraph()->GetLongConstant(
-        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue));
+        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(Shl);
@@ -3605,8 +3640,11 @@
 
 class HShr : public HBinaryOperation {
  public:
-  HShr(Primitive::Type result_type, HInstruction* left, HInstruction* right)
-      : HBinaryOperation(result_type, left, right) {}
+  HShr(Primitive::Type result_type,
+       HInstruction* left,
+       HInstruction* right,
+       uint32_t dex_pc = kNoDexPc)
+      : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {}
 
   template <typename T, typename U, typename V>
   T Compute(T x, U y, V max_shift_value) const {
@@ -3617,17 +3655,17 @@
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
     return GetBlock()->GetGraph()->GetIntConstant(
-        Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue));
+        Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue), GetDexPc());
   }
   // There is no `Evaluate(HIntConstant* x, HLongConstant* y)`, as this
   // case is handled as `x >> static_cast<int>(y)`.
   HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE {
     return GetBlock()->GetGraph()->GetLongConstant(
-        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue));
+        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
     return GetBlock()->GetGraph()->GetLongConstant(
-        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue));
+        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(Shr);
@@ -3638,8 +3676,11 @@
 
 class HUShr : public HBinaryOperation {
  public:
-  HUShr(Primitive::Type result_type, HInstruction* left, HInstruction* right)
-      : HBinaryOperation(result_type, left, right) {}
+  HUShr(Primitive::Type result_type,
+        HInstruction* left,
+        HInstruction* right,
+        uint32_t dex_pc = kNoDexPc)
+      : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {}
 
   template <typename T, typename U, typename V>
   T Compute(T x, U y, V max_shift_value) const {
@@ -3651,17 +3692,17 @@
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
     return GetBlock()->GetGraph()->GetIntConstant(
-        Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue));
+        Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue), GetDexPc());
   }
   // There is no `Evaluate(HIntConstant* x, HLongConstant* y)`, as this
   // case is handled as `x >>> static_cast<int>(y)`.
   HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE {
     return GetBlock()->GetGraph()->GetLongConstant(
-        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue));
+        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
     return GetBlock()->GetGraph()->GetLongConstant(
-        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue));
+        Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(UShr);
@@ -3672,8 +3713,11 @@
 
 class HAnd : public HBinaryOperation {
  public:
-  HAnd(Primitive::Type result_type, HInstruction* left, HInstruction* right)
-      : HBinaryOperation(result_type, left, right) {}
+  HAnd(Primitive::Type result_type,
+       HInstruction* left,
+       HInstruction* right,
+       uint32_t dex_pc = kNoDexPc)
+      : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {}
 
   bool IsCommutative() const OVERRIDE { return true; }
 
@@ -3681,16 +3725,20 @@
   auto Compute(T x, U y) const -> decltype(x & y) { return x & y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HIntConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(And);
@@ -3701,8 +3749,11 @@
 
 class HOr : public HBinaryOperation {
  public:
-  HOr(Primitive::Type result_type, HInstruction* left, HInstruction* right)
-      : HBinaryOperation(result_type, left, right) {}
+  HOr(Primitive::Type result_type,
+      HInstruction* left,
+      HInstruction* right,
+      uint32_t dex_pc = kNoDexPc)
+      : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {}
 
   bool IsCommutative() const OVERRIDE { return true; }
 
@@ -3710,16 +3761,20 @@
   auto Compute(T x, U y) const -> decltype(x | y) { return x | y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HIntConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(Or);
@@ -3730,8 +3785,11 @@
 
 class HXor : public HBinaryOperation {
  public:
-  HXor(Primitive::Type result_type, HInstruction* left, HInstruction* right)
-      : HBinaryOperation(result_type, left, right) {}
+  HXor(Primitive::Type result_type,
+       HInstruction* left,
+       HInstruction* right,
+       uint32_t dex_pc = kNoDexPc)
+      : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {}
 
   bool IsCommutative() const OVERRIDE { return true; }
 
@@ -3739,16 +3797,20 @@
   auto Compute(T x, U y) const -> decltype(x ^ y) { return x ^ y; }
 
   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HIntConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(
+        Compute(x->GetValue(), y->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(Xor);
@@ -3761,8 +3823,10 @@
 // the calling convention.
 class HParameterValue : public HExpression<0> {
  public:
-  HParameterValue(uint8_t index, Primitive::Type parameter_type, bool is_this = false)
-      : HExpression(parameter_type, SideEffects::None()),
+  HParameterValue(uint8_t index,
+                  Primitive::Type parameter_type,
+                  bool is_this = false)
+      : HExpression(parameter_type, SideEffects::None(), kNoDexPc),
         index_(index),
         is_this_(is_this),
         can_be_null_(!is_this) {}
@@ -3791,8 +3855,8 @@
 
 class HNot : public HUnaryOperation {
  public:
-  HNot(Primitive::Type result_type, HInstruction* input)
-      : HUnaryOperation(result_type, input) {}
+  HNot(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc)
+      : HUnaryOperation(result_type, input, dex_pc) {}
 
   bool CanBeMoved() const OVERRIDE { return true; }
   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
@@ -3803,10 +3867,10 @@
   template <typename T> T Compute(T x) const { return ~x; }
 
   HConstant* Evaluate(HIntConstant* x) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()));
+    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()), GetDexPc());
   }
 
   DECLARE_INSTRUCTION(Not);
@@ -3817,8 +3881,8 @@
 
 class HBooleanNot : public HUnaryOperation {
  public:
-  explicit HBooleanNot(HInstruction* input)
-      : HUnaryOperation(Primitive::Type::kPrimBoolean, input) {}
+  explicit HBooleanNot(HInstruction* input, uint32_t dex_pc = kNoDexPc)
+      : HUnaryOperation(Primitive::Type::kPrimBoolean, input, dex_pc) {}
 
   bool CanBeMoved() const OVERRIDE { return true; }
   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
@@ -3832,7 +3896,7 @@
   }
 
   HConstant* Evaluate(HIntConstant* x) const OVERRIDE {
-    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()));
+    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc());
   }
   HConstant* Evaluate(HLongConstant* x ATTRIBUTE_UNUSED) const OVERRIDE {
     LOG(FATAL) << DebugName() << " is not defined for long values";
@@ -3849,8 +3913,9 @@
  public:
   // Instantiate a type conversion of `input` to `result_type`.
   HTypeConversion(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc)
-      : HExpression(result_type, SideEffectsForArchRuntimeCalls(input->GetType(), result_type)),
-        dex_pc_(dex_pc) {
+      : HExpression(result_type,
+                    SideEffectsForArchRuntimeCalls(input->GetType(), result_type),
+                    dex_pc) {
     SetRawInputAt(0, input);
     DCHECK_NE(input->GetType(), result_type);
   }
@@ -3861,7 +3926,6 @@
 
   // Required by the x86 and ARM code generators when producing calls
   // to the runtime.
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
 
   bool CanBeMoved() const OVERRIDE { return true; }
   bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { return true; }
@@ -3885,8 +3949,6 @@
   DECLARE_INSTRUCTION(TypeConversion);
 
  private:
-  const uint32_t dex_pc_;
-
   DISALLOW_COPY_AND_ASSIGN(HTypeConversion);
 };
 
@@ -3894,8 +3956,12 @@
 
 class HPhi : public HInstruction {
  public:
-  HPhi(ArenaAllocator* arena, uint32_t reg_number, size_t number_of_inputs, Primitive::Type type)
-      : HInstruction(SideEffects::None()),
+  HPhi(ArenaAllocator* arena,
+       uint32_t reg_number,
+       size_t number_of_inputs,
+       Primitive::Type type,
+       uint32_t dex_pc = kNoDexPc)
+      : HInstruction(SideEffects::None(), dex_pc),
         inputs_(arena, number_of_inputs),
         reg_number_(reg_number),
         type_(type),
@@ -3973,7 +4039,7 @@
 class HNullCheck : public HExpression<1> {
  public:
   HNullCheck(HInstruction* value, uint32_t dex_pc)
-      : HExpression(value->GetType(), SideEffects::None()), dex_pc_(dex_pc) {
+      : HExpression(value->GetType(), SideEffects::None(), dex_pc) {
     SetRawInputAt(0, value);
   }
 
@@ -3989,13 +4055,10 @@
 
   bool CanBeNull() const OVERRIDE { return false; }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
 
   DECLARE_INSTRUCTION(NullCheck);
 
  private:
-  const uint32_t dex_pc_;
-
   DISALLOW_COPY_AND_ASSIGN(HNullCheck);
 };
 
@@ -4038,10 +4101,11 @@
                     bool is_volatile,
                     uint32_t field_idx,
                     const DexFile& dex_file,
-                    Handle<mirror::DexCache> dex_cache)
+                    Handle<mirror::DexCache> dex_cache,
+                    uint32_t dex_pc = kNoDexPc)
       : HExpression(
             field_type,
-            SideEffects::FieldReadOfType(field_type, is_volatile)),
+            SideEffects::FieldReadOfType(field_type, is_volatile), dex_pc),
         field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache) {
     SetRawInputAt(0, value);
   }
@@ -4083,9 +4147,10 @@
                     bool is_volatile,
                     uint32_t field_idx,
                     const DexFile& dex_file,
-                    Handle<mirror::DexCache> dex_cache)
+                    Handle<mirror::DexCache> dex_cache,
+                    uint32_t dex_pc = kNoDexPc)
       : HTemplateInstruction(
-          SideEffects::FieldWriteOfType(field_type, is_volatile)),
+          SideEffects::FieldWriteOfType(field_type, is_volatile), dex_pc),
         field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache),
         value_can_be_null_(true) {
     SetRawInputAt(0, object);
@@ -4115,8 +4180,11 @@
 
 class HArrayGet : public HExpression<2> {
  public:
-  HArrayGet(HInstruction* array, HInstruction* index, Primitive::Type type)
-      : HExpression(type, SideEffects::ArrayReadOfType(type)) {
+  HArrayGet(HInstruction* array,
+            HInstruction* index,
+            Primitive::Type type,
+            uint32_t dex_pc = kNoDexPc)
+      : HExpression(type, SideEffects::ArrayReadOfType(type), dex_pc) {
     SetRawInputAt(0, array);
     SetRawInputAt(1, index);
   }
@@ -4156,8 +4224,7 @@
             uint32_t dex_pc)
       : HTemplateInstruction(
             SideEffects::ArrayWriteOfType(expected_component_type).Union(
-                SideEffectsForArchRuntimeCalls(value->GetType()))),
-        dex_pc_(dex_pc),
+                SideEffectsForArchRuntimeCalls(value->GetType())), dex_pc),
         expected_component_type_(expected_component_type),
         needs_type_check_(value->GetType() == Primitive::kPrimNot),
         value_can_be_null_(true) {
@@ -4192,8 +4259,6 @@
   bool GetValueCanBeNull() const { return value_can_be_null_; }
   bool NeedsTypeCheck() const { return needs_type_check_; }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
-
   HInstruction* GetArray() const { return InputAt(0); }
   HInstruction* GetIndex() const { return InputAt(1); }
   HInstruction* GetValue() const { return InputAt(2); }
@@ -4216,7 +4281,6 @@
   DECLARE_INSTRUCTION(ArraySet);
 
  private:
-  const uint32_t dex_pc_;
   const Primitive::Type expected_component_type_;
   bool needs_type_check_;
   bool value_can_be_null_;
@@ -4226,8 +4290,8 @@
 
 class HArrayLength : public HExpression<1> {
  public:
-  explicit HArrayLength(HInstruction* array)
-      : HExpression(Primitive::kPrimInt, SideEffects::None()) {
+  explicit HArrayLength(HInstruction* array, uint32_t dex_pc = kNoDexPc)
+      : HExpression(Primitive::kPrimInt, SideEffects::None(), dex_pc) {
     // Note that arrays do not change length, so the instruction does not
     // depend on any write.
     SetRawInputAt(0, array);
@@ -4251,7 +4315,7 @@
 class HBoundsCheck : public HExpression<2> {
  public:
   HBoundsCheck(HInstruction* index, HInstruction* length, uint32_t dex_pc)
-      : HExpression(index->GetType(), SideEffects::None()), dex_pc_(dex_pc) {
+      : HExpression(index->GetType(), SideEffects::None(), dex_pc) {
     DCHECK(index->GetType() == Primitive::kPrimInt);
     SetRawInputAt(0, index);
     SetRawInputAt(1, length);
@@ -4267,13 +4331,10 @@
 
   bool CanThrow() const OVERRIDE { return true; }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
 
   DECLARE_INSTRUCTION(BoundsCheck);
 
  private:
-  const uint32_t dex_pc_;
-
   DISALLOW_COPY_AND_ASSIGN(HBoundsCheck);
 };
 
@@ -4286,7 +4347,8 @@
  */
 class HTemporary : public HTemplateInstruction<0> {
  public:
-  explicit HTemporary(size_t index) : HTemplateInstruction(SideEffects::None()), index_(index) {}
+  explicit HTemporary(size_t index, uint32_t dex_pc = kNoDexPc)
+      : HTemplateInstruction(SideEffects::None(), dex_pc), index_(index) {}
 
   size_t GetIndex() const { return index_; }
 
@@ -4300,28 +4362,24 @@
 
  private:
   const size_t index_;
-
   DISALLOW_COPY_AND_ASSIGN(HTemporary);
 };
 
 class HSuspendCheck : public HTemplateInstruction<0> {
  public:
   explicit HSuspendCheck(uint32_t dex_pc)
-      : HTemplateInstruction(SideEffects::CanTriggerGC()), dex_pc_(dex_pc), slow_path_(nullptr) {}
+      : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc), slow_path_(nullptr) {}
 
   bool NeedsEnvironment() const OVERRIDE {
     return true;
   }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   void SetSlowPath(SlowPathCode* slow_path) { slow_path_ = slow_path; }
   SlowPathCode* GetSlowPath() const { return slow_path_; }
 
   DECLARE_INSTRUCTION(SuspendCheck);
 
  private:
-  const uint32_t dex_pc_;
-
   // Only used for code generation, in order to share the same slow path between back edges
   // of a same loop.
   SlowPathCode* slow_path_;
@@ -4339,11 +4397,10 @@
              const DexFile& dex_file,
              bool is_referrers_class,
              uint32_t dex_pc)
-      : HExpression(Primitive::kPrimNot, SideEffectsForArchRuntimeCalls()),
+      : HExpression(Primitive::kPrimNot, SideEffectsForArchRuntimeCalls(), dex_pc),
         type_index_(type_index),
         dex_file_(dex_file),
         is_referrers_class_(is_referrers_class),
-        dex_pc_(dex_pc),
         generate_clinit_check_(false),
         loaded_class_rti_(ReferenceTypeInfo::CreateInvalid()) {
     SetRawInputAt(0, current_method);
@@ -4357,7 +4414,6 @@
 
   size_t ComputeHashCode() const OVERRIDE { return type_index_; }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   uint16_t GetTypeIndex() const { return type_index_; }
   bool IsReferrersClass() const { return is_referrers_class_; }
   bool CanBeNull() const OVERRIDE { return false; }
@@ -4410,7 +4466,6 @@
   const uint16_t type_index_;
   const DexFile& dex_file_;
   const bool is_referrers_class_;
-  const uint32_t dex_pc_;
   // Whether this instruction must generate the initialization check.
   // Used for code generation.
   bool generate_clinit_check_;
@@ -4423,9 +4478,8 @@
 class HLoadString : public HExpression<1> {
  public:
   HLoadString(HCurrentMethod* current_method, uint32_t string_index, uint32_t dex_pc)
-      : HExpression(Primitive::kPrimNot, SideEffectsForArchRuntimeCalls()),
-        string_index_(string_index),
-        dex_pc_(dex_pc) {
+      : HExpression(Primitive::kPrimNot, SideEffectsForArchRuntimeCalls(), dex_pc),
+        string_index_(string_index) {
     SetRawInputAt(0, current_method);
   }
 
@@ -4437,7 +4491,6 @@
 
   size_t ComputeHashCode() const OVERRIDE { return string_index_; }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   uint32_t GetStringIndex() const { return string_index_; }
 
   // TODO: Can we deopt or debug when we resolve a string?
@@ -4453,7 +4506,6 @@
 
  private:
   const uint32_t string_index_;
-  const uint32_t dex_pc_;
 
   DISALLOW_COPY_AND_ASSIGN(HLoadString);
 };
@@ -4466,8 +4518,8 @@
   HClinitCheck(HLoadClass* constant, uint32_t dex_pc)
       : HExpression(
             Primitive::kPrimNot,
-            SideEffects::AllChanges()),  // Assume write/read on all fields/arrays.
-        dex_pc_(dex_pc) {
+            SideEffects::AllChanges(),  // Assume write/read on all fields/arrays.
+            dex_pc) {
     SetRawInputAt(0, constant);
   }
 
@@ -4482,15 +4534,12 @@
     return true;
   }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
 
   HLoadClass* GetLoadClass() const { return InputAt(0)->AsLoadClass(); }
 
   DECLARE_INSTRUCTION(ClinitCheck);
 
  private:
-  const uint32_t dex_pc_;
-
   DISALLOW_COPY_AND_ASSIGN(HClinitCheck);
 };
 
@@ -4502,10 +4551,11 @@
                   bool is_volatile,
                   uint32_t field_idx,
                   const DexFile& dex_file,
-                  Handle<mirror::DexCache> dex_cache)
+                  Handle<mirror::DexCache> dex_cache,
+                  uint32_t dex_pc = kNoDexPc)
       : HExpression(
             field_type,
-            SideEffects::FieldReadOfType(field_type, is_volatile)),
+            SideEffects::FieldReadOfType(field_type, is_volatile), dex_pc),
         field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache) {
     SetRawInputAt(0, cls);
   }
@@ -4544,9 +4594,10 @@
                   bool is_volatile,
                   uint32_t field_idx,
                   const DexFile& dex_file,
-                  Handle<mirror::DexCache> dex_cache)
+                  Handle<mirror::DexCache> dex_cache,
+                  uint32_t dex_pc = kNoDexPc)
       : HTemplateInstruction(
-          SideEffects::FieldWriteOfType(field_type, is_volatile)),
+          SideEffects::FieldWriteOfType(field_type, is_volatile), dex_pc),
         field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache),
         value_can_be_null_(true) {
     SetRawInputAt(0, cls);
@@ -4574,7 +4625,8 @@
 // Implement the move-exception DEX instruction.
 class HLoadException : public HExpression<0> {
  public:
-  HLoadException() : HExpression(Primitive::kPrimNot, SideEffects::None()) {}
+  explicit HLoadException(uint32_t dex_pc = kNoDexPc)
+      : HExpression(Primitive::kPrimNot, SideEffects::None(), dex_pc) {}
 
   bool CanBeNull() const OVERRIDE { return false; }
 
@@ -4588,7 +4640,8 @@
 // Must not be removed because the runtime expects the TLS to get cleared.
 class HClearException : public HTemplateInstruction<0> {
  public:
-  HClearException() : HTemplateInstruction(SideEffects::AllWrites()) {}
+  explicit HClearException(uint32_t dex_pc = kNoDexPc)
+      : HTemplateInstruction(SideEffects::AllWrites(), dex_pc) {}
 
   DECLARE_INSTRUCTION(ClearException);
 
@@ -4599,7 +4652,7 @@
 class HThrow : public HTemplateInstruction<1> {
  public:
   HThrow(HInstruction* exception, uint32_t dex_pc)
-      : HTemplateInstruction(SideEffects::CanTriggerGC()), dex_pc_(dex_pc) {
+      : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc) {
     SetRawInputAt(0, exception);
   }
 
@@ -4609,13 +4662,10 @@
 
   bool CanThrow() const OVERRIDE { return true; }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
 
   DECLARE_INSTRUCTION(Throw);
 
  private:
-  const uint32_t dex_pc_;
-
   DISALLOW_COPY_AND_ASSIGN(HThrow);
 };
 
@@ -4625,10 +4675,11 @@
               HLoadClass* constant,
               bool class_is_final,
               uint32_t dex_pc)
-      : HExpression(Primitive::kPrimBoolean, SideEffectsForArchRuntimeCalls(class_is_final)),
+      : HExpression(Primitive::kPrimBoolean,
+                    SideEffectsForArchRuntimeCalls(class_is_final),
+                    dex_pc),
         class_is_final_(class_is_final),
-        must_do_null_check_(true),
-        dex_pc_(dex_pc) {
+        must_do_null_check_(true) {
     SetRawInputAt(0, object);
     SetRawInputAt(1, constant);
   }
@@ -4643,8 +4694,6 @@
     return false;
   }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
-
   bool IsClassFinal() const { return class_is_final_; }
 
   // Used only in code generation.
@@ -4660,7 +4709,6 @@
  private:
   const bool class_is_final_;
   bool must_do_null_check_;
-  const uint32_t dex_pc_;
 
   DISALLOW_COPY_AND_ASSIGN(HInstanceOf);
 };
@@ -4669,8 +4717,11 @@
  public:
   // Constructs an HBoundType with the given upper_bound.
   // Ensures that the upper_bound is valid.
-  HBoundType(HInstruction* input, ReferenceTypeInfo upper_bound, bool upper_can_be_null)
-      : HExpression(Primitive::kPrimNot, SideEffects::None()),
+  HBoundType(HInstruction* input,
+             ReferenceTypeInfo upper_bound,
+             bool upper_can_be_null,
+             uint32_t dex_pc = kNoDexPc)
+      : HExpression(Primitive::kPrimNot, SideEffects::None(), dex_pc),
         upper_bound_(upper_bound),
         upper_can_be_null_(upper_can_be_null),
         can_be_null_(upper_can_be_null) {
@@ -4714,10 +4765,9 @@
              HLoadClass* constant,
              bool class_is_final,
              uint32_t dex_pc)
-      : HTemplateInstruction(SideEffects::CanTriggerGC()),
+      : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc),
         class_is_final_(class_is_final),
-        must_do_null_check_(true),
-        dex_pc_(dex_pc) {
+        must_do_null_check_(true) {
     SetRawInputAt(0, object);
     SetRawInputAt(1, constant);
   }
@@ -4738,7 +4788,6 @@
   bool MustDoNullCheck() const { return must_do_null_check_; }
   void ClearMustDoNullCheck() { must_do_null_check_ = false; }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
 
   bool IsClassFinal() const { return class_is_final_; }
 
@@ -4747,16 +4796,15 @@
  private:
   const bool class_is_final_;
   bool must_do_null_check_;
-  const uint32_t dex_pc_;
 
   DISALLOW_COPY_AND_ASSIGN(HCheckCast);
 };
 
 class HMemoryBarrier : public HTemplateInstruction<0> {
  public:
-  explicit HMemoryBarrier(MemBarrierKind barrier_kind)
+  explicit HMemoryBarrier(MemBarrierKind barrier_kind, uint32_t dex_pc = kNoDexPc)
       : HTemplateInstruction(
-            SideEffects::AllWritesAndReads()),  // Assume write/read on all fields/arrays.
+            SideEffects::AllWritesAndReads(), dex_pc),  // Assume write/read on all fields/arrays.
         barrier_kind_(barrier_kind) {}
 
   MemBarrierKind GetBarrierKind() { return barrier_kind_; }
@@ -4778,8 +4826,8 @@
 
   HMonitorOperation(HInstruction* object, OperationKind kind, uint32_t dex_pc)
     : HTemplateInstruction(
-          SideEffects::AllExceptGCDependency()),  // Assume write/read on all fields/arrays.
-      kind_(kind), dex_pc_(dex_pc) {
+          SideEffects::AllExceptGCDependency(), dex_pc),  // Assume write/read on all fields/arrays.
+      kind_(kind) {
     SetRawInputAt(0, object);
   }
 
@@ -4793,7 +4841,6 @@
     return IsEnter();
   }
 
-  uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
 
   bool IsEnter() const { return kind_ == kEnter; }
 
@@ -4801,7 +4848,6 @@
 
  private:
   const OperationKind kind_;
-  const uint32_t dex_pc_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(HMonitorOperation);
@@ -4816,7 +4862,8 @@
  */
 class HFakeString : public HTemplateInstruction<0> {
  public:
-  HFakeString() : HTemplateInstruction(SideEffects::None()) {}
+  explicit HFakeString(uint32_t dex_pc = kNoDexPc)
+      : HTemplateInstruction(SideEffects::None(), dex_pc) {}
 
   Primitive::Type GetType() const OVERRIDE { return Primitive::kPrimNot; }
 
@@ -4904,8 +4951,8 @@
 
 class HParallelMove : public HTemplateInstruction<0> {
  public:
-  explicit HParallelMove(ArenaAllocator* arena)
-      : HTemplateInstruction(SideEffects::None()), moves_(arena, kDefaultNumberOfMoves) {}
+  explicit HParallelMove(ArenaAllocator* arena, uint32_t dex_pc = kNoDexPc)
+      : HTemplateInstruction(SideEffects::None(), dex_pc), moves_(arena, kDefaultNumberOfMoves) {}
 
   void AddMove(Location source,
                Location destination,