How to create a reference to a argument in a function

Here I am trying to replace function A with function B. The difference between them is like below:

void A(self-type a)
void B(self-type &a)

But in LLVM IR, I can see the signatures of them are like

void A(i8 * )
void B(i8 **)

So, if I want to replace function A with B, I need to get the argument of callInst about A and turn it into the type of i8 **, what should I do to get the right argument of function B(value and type)?
Because I am a little confused that why a reference will work like a nested pointer? This is supposed to be done by compiler in a way that programmer cannot see and modify. If I insert a instruction to get the address of run-time argument in A, and set it as the value of run-time argument of function B, it may not work like a reference but like a truly pointer.

Any answer or discussion will be highly appreciated, thank you!

as you see, a reference is just a pointer to a value and has differing semantics mostly on a C++ language level. In LLVM IR references are represented as pointers, although IIRC, they are marked as dereferencable, as that’s part of the C++ reference semantics.
As the self-type seems to be a pointer (or reference?) on it’s own already you get a nested pointer for the reference. Thus it could be questioned how useful the change is in this case, but I’ll try to explain what can be done anyway.

To transform from A → B, I see two possible cases: 1. A’s a is directly loaded from a pointer such as alloca / global variable / getelementptr, then you could just hand the pointer into B instead of loading from it first, 2. A’s argument isn’t (easily) correlatable to a memory location, in this case you’d probably add an alloca instruction in the calling function, store a to that alloca and use the alloca as parameter to B.

In either of the above cases, using an existing pointer to e.g. alloca or creating an alloca should have the correct type for B already.

Thanks for your detailed reply. In fact, my encountering case is the first one case you mentioned, so I need to use alloca to define a new nested pointer pointing to the argument in A, right? But how can I get the address of the argument used by function A to init the new pointer?