[interp] Remove unconditional branches to next instruction (mono/mono#15939)
authorVlad Brezae <brezaevlad@gmail.com>
Fri, 2 Aug 2019 09:16:07 +0000 (12:16 +0300)
committermonojenkins <jo.shields+jenkins@xamarin.com>
Fri, 2 Aug 2019 09:16:07 +0000 (05:16 -0400)
[interp] Remove unconditional branches to next instruction

These are very common, at least in debug builds. Optimize them away so it doesn't distort performance numbers.

Commit migrated from https://github.com/mono/mono/commit/4883b56c10a077e4c82feff604172d6994994e1a

src/mono/mono/mini/interp/transform.c

index 87ad5da..0092747 100644 (file)
@@ -3441,16 +3441,24 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
                        }
                        break;
                }
-               case CEE_BR:
-                       INLINE_FAILURE;
-                       handle_branch (td, MINT_BR_S, MINT_BR, 5 + read32 (td->ip + 1));
+               case CEE_BR: {
+                       int offset = read32 (td->ip + 1);
+                       if (offset) {
+                               INLINE_FAILURE;
+                               handle_branch (td, MINT_BR_S, MINT_BR, 5 + offset);
+                       }
                        td->ip += 5;
                        break;
-               case CEE_BR_S:
-                       INLINE_FAILURE;
-                       handle_branch (td, MINT_BR_S, MINT_BR, 2 + (gint8)td->ip [1]);
+               }
+               case CEE_BR_S: {
+                       int offset = (gint8)td->ip [1];
+                       if (offset) {
+                               INLINE_FAILURE;
+                               handle_branch (td, MINT_BR_S, MINT_BR, 2 + (gint8)td->ip [1]);
+                       }
                        td->ip += 2;
                        break;
+               }
                case CEE_BRFALSE:
                        INLINE_FAILURE;
                        one_arg_branch (td, MINT_BRFALSE_I4, 5 + read32 (td->ip + 1));
@@ -4239,6 +4247,8 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
                                        td->last_ins->data [0] = get_data_item_index (td, mono_interp_get_imethod (domain, m, error));
                                }
                                goto_if_nok (error, exit);
+                               /* The constructor was not inlined, abort inlining of current method */
+                               INLINE_FAILURE;
 
                                td->sp -= csignature->param_count;
                                if (mint_type (m_class_get_byval_arg (klass)) == MINT_TYPE_VT) {