Skip to content

Commit

Permalink
[mono] Add MethodImplOptions.NoOptimization support (mono#20265)
Browse files Browse the repository at this point in the history
Mono currently just ignores `MethodImplOptions.NoOptimization` flag, this PR adds support for it.

```csharp
static int Add(int a, int b) => a + b;

[MethodImpl(MethodImplOptions.NoOptimization)]
static int Test(int a, int b) => Add(a, b) * Add(a, b); // NoOpt means - don't inline Add here, don't do opts

static void Main(string[] args)
{
    Test(1, 2);
}
```
Codegen for Test:
```asm
0000000000000000 <gram_Test__int_int_>:
<BB>:2
   0:   48 83 ec 18             sub    $0x18,%rsp
   4:   4c 89 34 24             mov    %r14,(%rsp)
   8:   4c 89 7c 24 08          mov    %r15,0x8(%rsp)
   d:   4c 8b f7                mov    %rdi,%r14
  10:   4c 8b fe                mov    %rsi,%r15
  13:   e8 29 00 00 00          callq  41 <gram_Test__int_int_+0x41>
  18:   48 89 44 24 10          mov    %rax,0x10(%rsp)
  1d:   49 8b fe                mov    %r14,%rdi
  20:   49 8b f7                mov    %r15,%rsi
  23:   e8 19 00 00 00          callq  41 <gram_Test__int_int_+0x41>
  28:   48 8b c8                mov    %rax,%rcx
  2b:   48 8b 44 24 10          mov    0x10(%rsp),%rax
  30:   0f af c1                imul   %ecx,%eax
<BB>:1
  33:   4c 8b 34 24             mov    (%rsp),%r14
  37:   4c 8b 7c 24 08          mov    0x8(%rsp),%r15
  3c:   48 83 c4 18             add    $0x18,%rsp
  40:   c3                      retq
```
with llvm backend (emits `noopt` attribute for llvm function):
```asm
0000000000000000 <gram_Test__int_int_>:
<BB>:1
   0:   55                      push   %rbp
   1:   41 57                   push   %r15
   3:   41 56                   push   %r14
   5:   53                      push   %rbx
   6:   50                      push   %rax
   7:   41 89 f6                mov    %esi,%r14d
   a:   89 fd                   mov    %edi,%ebp
   c:   eb 00                   jmp    e <gram_Test__int_int_+0xe>
   e:   eb 00                   jmp    10 <gram_Test__int_int_+0x10>
  10:   49 bf c0 b6 7c 53 37    movabs $0x5637537cb6c0,%r15
  17:   56 00 00
  1a:   49 8b 07                mov    (%r15),%rax
  1d:   89 ef                   mov    %ebp,%edi
  1f:   44 89 f6                mov    %r14d,%esi
  22:   ff d0                   callq  *%rax
  24:   89 c3                   mov    %eax,%ebx
  26:   49 8b 07                mov    (%r15),%rax
  29:   89 ef                   mov    %ebp,%edi
  2b:   44 89 f6                mov    %r14d,%esi
  2e:   ff d0                   callq  *%rax
  30:   0f af d8                imul   %eax,%ebx
  33:   89 d8                   mov    %ebx,%eax
  35:   48 83 c4 08             add    $0x8,%rsp
  39:   5b                      pop    %rbx
  3a:   41 5e                   pop    %r14
  3c:   41 5f                   pop    %r15
  3e:   5d                      pop    %rbp
  3f:   c3                      retq
```
If I replace `LLVM_ATTR_OPTIMIZE_NONE` with `LLVM_ATTR_OPTIMIZE_FOR_SIZE` it becomes https://www.diffchecker.com/S02HEp0w for llvm.

Co-authored-by: EgorBo <[email protected]>
  • Loading branch information
monojenkins and EgorBo authored Aug 20, 2020
1 parent ef1589a commit f564c1d
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 2 deletions.
2 changes: 1 addition & 1 deletion mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -6083,7 +6083,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
MonoBitSet *seq_point_set_locs = NULL;
gboolean emitted_funccall_seq_point = FALSE;

cfg->disable_inline = is_jit_optimizer_disabled (method);
cfg->disable_inline = (method->iflags & METHOD_IMPL_ATTRIBUTE_NOOPTIMIZATION) || is_jit_optimizer_disabled (method);
cfg->current_method = method;

image = m_class_get_image (method->klass);
Expand Down
6 changes: 5 additions & 1 deletion mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -9609,10 +9609,14 @@ emit_method_inner (EmitContext *ctx)
}
}
}
if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
if (header->num_clauses || (cfg->method->iflags & (METHOD_IMPL_ATTRIBUTE_NOINLINING | METHOD_IMPL_ATTRIBUTE_NOOPTIMIZATION)) || cfg->no_inline)
/* We can't handle inlined methods with clauses */
mono_llvm_add_func_attr (method, LLVM_ATTR_NO_INLINE);

if (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOOPTIMIZATION)
// noopt requires noinline
mono_llvm_add_func_attr (method, LLVM_ATTR_OPTIMIZE_NONE);

if (linfo->rgctx_arg) {
ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
Expand Down

0 comments on commit f564c1d

Please sign in to comment.