#is converting parameters to a const pointer bad?

1 messages · Page 1 of 1 (latest)

coarse forge
#

where did you read that?

#

the biggest downside i can think of (but i'm not sure if this is the one that you were reading about) is that making a parameter a pointer requires that the value be in memory

#

for small values that fit in registers, where in optimized code the caller probably already has it in registers rather than in memory, it's usually cheaper to keep the value in registers rather than store it in memory, calculate the address, pass that, and then have the callee load it

cloud meadow
#

Main thing I can think of that would make this less performant is the compiler having to deal with aliasing

#

Since Zig doesn’t have a strict aliasing rule as far as I know, every pointer parameter can alias which would make this worse

coarse forge
#

yeah, you can specify noalias but most code doesn't

agile vine
cloud meadow
#

I love optimizers

coarse forge
#

wait noinline is broken HUH

agile vine
#

lolwut

#

thats super weird tho

coarse forge
#

silly llvm

midnight sonnet
#

it's a pretty annoying distinction, but it's there

coarse forge
#

so it's zig's fault?

midnight sonnet
#

no, it's no-ones fault, this is how noinline works right now

#

if you were to put side-effects into two, it couldnt inline the call

coarse forge
#

well so noinline is designed incorrectly?

midnight sonnet
#

no, it works fine

#

noinline is not make_sure_the_call_exists

#

it means do not inline the call, if it exists

#

the optimizer is allowed to just remove the call

#

if you make two take a *volatile const u8, then it'll have side-effects when loading, and it wont be able to remove the call

coarse forge
agile vine
#

the call isnt doing anything

midnight sonnet
#

it's a bit stupid, but this is how llvm gets away with this "technically" correct optimization

#

so like,

fn foo(x: u32, y: u32) u32 {
  return x + y;
}
foo(10, 20)
->
fn foo() u32 {
  return 30;
}
foo()
->
30

is not inlining, while

fn foo(x: u32, y: u32) u32 {
  return x + y;
}
foo(10, 20);
->
10 + 20
->
30

is inlining

coarse forge
#

how is replacing foo() with 30 not inlining when replacing foo(10, 20) with 10 + 20 is

midnight sonnet
coarse forge
#

i think i see the distinction you're drawing but i still think the end result is probably unfaithful to the intent of the programmer

midnight sonnet
#

skill issue, moar optimization

#

it's all to please the shareholders

coarse forge
#

anecdotally, i appreciate that zig's inline keyword is a guarantee, unlike in other languages, even if that probably allows people to use it to write worse code sometimes. i was expecting noinline to be similar, especially given the text "If the call is otherwise required to be inlined, a compile error is emitted instead." (technically that is not listed for noinline but rather for the .never_inline call modifier, but i was able to reproduce the same optimization using only .never_inline on a regular function). i'm sad noinline is not as powerful a tool as i thought to control the code that gets generated.