ART: Move exception clearing into own instruction

Runtime delivers exceptions only to catch blocks which begin with a
MOVE_EXCEPTION instruction (in DEX). In that case, the catch block is
expected to clear the thread-local exception storage after having
read the exception reference.

This patch changes Optimizing to represent MOVE_EXCEPTION with two
instructions - HLoadException and HClearException - instead of one.
If the exception reference is not used, HLoadException can be safely
removed, saving a memory load without breaking the runtime behaviour.

Change-Id: Idad8a714467bf9d9d5fccefbc43c0bd8ae13ddba
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 9b8521d..638ac95 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -961,6 +961,7 @@
   M(BoundsCheck, Instruction)                                           \
   M(BoundType, Instruction)                                             \
   M(CheckCast, Instruction)                                             \
+  M(ClearException, Instruction)                                        \
   M(ClinitCheck, Instruction)                                           \
   M(Compare, BinaryOperation)                                           \
   M(Condition, BinaryOperation)                                         \
@@ -4142,6 +4143,18 @@
   DISALLOW_COPY_AND_ASSIGN(HLoadException);
 };
 
+// Implicit part of move-exception which clears thread-local exception storage.
+// Must not be removed because the runtime expects the TLS to get cleared.
+class HClearException : public HTemplateInstruction<0> {
+ public:
+  HClearException() : HTemplateInstruction(SideEffects::AllWrites()) {}
+
+  DECLARE_INSTRUCTION(ClearException);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(HClearException);
+};
+
 class HThrow : public HTemplateInstruction<1> {
  public:
   HThrow(HInstruction* exception, uint32_t dex_pc)