[LLVMdev] How to assign a constant to a register?

1,104 views
Skip to first unread message

leledumbo

unread,
Oct 18, 2010, 12:39:58 AM10/18/10
to llv...@cs.uiuc.edu

Other than:
%x = add i32 5,0 ; suppose I want to assign 5 to %x

is there any other way? Something like x86's mov instruction

--
View this message in context: http://old.nabble.com/How-to-assign-a-constant-to-a-register--tp29987387p29987387.html
Sent from the LLVM - Dev mailing list archive at Nabble.com.

_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

ether zhhb

unread,
Oct 18, 2010, 7:49:06 AM10/18/10
to leledumbo, llv...@cs.uiuc.edu
hi,

On Mon, Oct 18, 2010 at 12:39 PM, leledumbo <leledum...@yahoo.co.id> wrote:
>
> Other than:
> %x = add i32 5,0 ; suppose I want to assign 5 to %x

you do not need to do this at the level of LLVM IR, or do you mind to
tell us the reason for this?

best regards
ether

Duncan Sands

unread,
Oct 18, 2010, 8:18:48 AM10/18/10
to llv...@cs.uiuc.edu
Hi,

> Other than:
> %x = add i32 5,0 ; suppose I want to assign 5 to %x
>
> is there any other way? Something like x86's mov instruction

let me say that in general doing this is pointless. Due to SSA form, if %x is
set to 5 you can't set it to something else later. Thus everywhere that you
use %x you might as well just directly use 5 there instead. A common situation
is that you have a register %x, and due to performing optimizations you discover
that in fact %x will always have the value 5. You can use RAUW (aka the
replaceAllUsesWith method) to replace %x with 5 everywhere.

Ciao,

Duncan.

Alasdair Grant

unread,
Oct 18, 2010, 8:35:49 AM10/18/10
to Duncan Sands, llv...@cs.uiuc.edu
> let me say that in general doing this is pointless. Due to SSA form,
> if %x is
> set to 5 you can't set it to something else later. Thus everywhere
> that you
> use %x you might as well just directly use 5 there instead.

But the cost of doing that might be greater than the costs
of keeping it in a register. Suppose the code was ORing a value
with 5 and the target only had OR-register and not OR-immediate.
You would expect local code generation to handle OR-immediate by
locally materialising the constant into a spare register.
But if the usage was in a loop it would be better (at the cost of
register pressure) to materialise 5 into a register outside of the
loop and use the register repeatedly in the loop.

Al

-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

ether zhhb

unread,
Oct 18, 2010, 9:05:53 AM10/18/10
to Duncan Sands, Alasdair Grant, llv...@cs.uiuc.edu
hi,

Well, there is no "Register" at the level of LLVM IR,

%x = add i32 %y, %z

means you define a value "x" by adding value "y" and value "z" together.

best regards
ether

Duncan Sands

unread,
Oct 18, 2010, 8:51:30 AM10/18/10
to Alasdair Grant, llv...@cs.uiuc.edu
Hi Alasdair,

> But the cost of doing that might be greater than the costs
> of keeping it in a register. Suppose the code was ORing a value
> with 5 and the target only had OR-register and not OR-immediate.
> You would expect local code generation to handle OR-immediate by
> locally materialising the constant into a spare register.
> But if the usage was in a loop it would be better (at the cost of
> register pressure) to materialise 5 into a register outside of the
> loop and use the register repeatedly in the loop.

it is up to the code generators to take care of this kind of thing.
I don't see how having (at the IR level) a register called %x which
contains the value 5 makes it easier for the code generators to perform
this optimization than if you directly use 5 everywhere %x would occur.

Ciao,

Duncan.

leledumbo

unread,
Oct 19, 2010, 12:22:23 AM10/19/10
to llv...@cs.uiuc.edu

> let me say that in general doing this is pointless. Due to SSA form, if %x
is
> set to 5 you can't set it to something else later. Thus everywhere that
> you
> use %x you might as well just directly use 5 there instead.

My bad... I should've started thinking in SSA way all the time. I got it
mixed with common assembly language. So I must hold the initial value until
the first operation that deals with it has come, right?
--
View this message in context: http://old.nabble.com/How-to-assign-a-constant-to-a-register--tp29987387p29996865.html


Sent from the LLVM - Dev mailing list archive at Nabble.com.

_______________________________________________

Eric Christopher

unread,
Oct 19, 2010, 1:17:46 AM10/19/10
to leledumbo, llv...@cs.uiuc.edu

On Oct 18, 2010, at 9:22 PM, leledumbo wrote:

>
>> let me say that in general doing this is pointless. Due to SSA form, if %x
> is
>> set to 5 you can't set it to something else later. Thus everywhere that
>> you
>> use %x you might as well just directly use 5 there instead.
>
> My bad... I should've started thinking in SSA way all the time. I got it
> mixed with common assembly language. So I must hold the initial value until
> the first operation that deals with it has come, right?

No, you could throw it into a global if you know you're going to want to use 5 at some point in the future randomly.

-eric

Arnaud Allard de Grandmaison

unread,
Oct 19, 2010, 3:19:59 AM10/19/10
to llv...@cs.uiuc.edu
> But if the usage was in a loop it would be better (at the cost of
> register pressure) to materialise 5 into a register outside of the
> loop and use the register repeatedly in the loop.

Bouncing on this subject: you can not know before isel is over if the constants have to materialize into registers or not, as this is really dependent on the target's instruction set. Do we have any pass hoisting the constant loading out of the (inner) loops after isel ? I guess this could be beneficial for most targets --- assuming the pass does not increase the register pressure to some unreasonnable level.

--
Arnaud de Grandmaison

Eli Friedman

unread,
Oct 19, 2010, 3:40:37 AM10/19/10
to Arnaud Allard de Grandmaison, llv...@cs.uiuc.edu
On Tue, Oct 19, 2010 at 12:19 AM, Arnaud Allard de Grandmaison
<Arnaud.Allard...@dibcom.com> wrote:
>> But if the usage was in a loop it would be better (at the cost of
>> register pressure) to materialise 5 into a register outside of the
>> loop and use the register repeatedly in the loop.
>
> Bouncing on this subject: you can not know before isel is over if the constants have to materialize into registers or not, as this is really dependent on the target's instruction set. Do we have any pass hoisting the constant loading out of the (inner) loops after isel ? I guess this could be beneficial for most targets --- assuming the pass does not increase the register pressure to some unreasonnable level.

Yes; see lib/CodeGen/MachineLICM.cpp.

-Eli

Duncan Sands

unread,
Oct 19, 2010, 3:56:49 AM10/19/10
to llv...@cs.uiuc.edu
Hi leledumbo,

> My bad... I should've started thinking in SSA way all the time. I got it
> mixed with common assembly language. So I must hold the initial value until
> the first operation that deals with it has come, right?

I'm not sure exactly what the problem you are trying to solve is, but it sounds
like it may be analogous to a problem dragonegg had to solve: it converts gimple
in SSA form to LLVM IR, with "SSA names" being converted to "registers", but as
it doesn't visit basic blocks in dominator order it may visit uses of an SSA
name before encountering the SSA name's definition. When this happens it
creates a fake "place holder" value which it later replaces with the real value,
once it has it. The trick here is that the fake value is an instruction with no
parent, so it can be easily distinguished from non-fake instructions, which
always have a parent. Here's the code:

/// getSSAPlaceholder - A fake value associated with an SSA name when the name
/// is used before being defined (this can occur because basic blocks are not
/// output in dominator order). Replaced with the correct value when the SSA
/// name's definition is encountered.
static Value *GetSSAPlaceholder(const Type *Ty) {
// Cannot use a constant, since there is no way to distinguish a fake value
// from a real value. So use an instruction with no parent. This needs to
// be an instruction that can return a struct type, since the SSA name might
// be a complex number. It could be a PHINode, except that the GCC phi node
// conversion logic also constructs phi nodes with no parent. A SelectInst
// would work, but a LoadInst seemed neater.
return new LoadInst(UndefValue::get(Ty->getPointerTo()), NULL);
}

Ciao,

Duncan.

Arnaud Allard de Grandmaison

unread,
Oct 19, 2010, 3:55:29 AM10/19/10
to llv...@cs.uiuc.edu
Thanks Eli,
I now have to understand why it does not seem to be running in my case :)
--
Arnaud de Grandmaison

leledumbo

unread,
Oct 20, 2010, 3:52:47 AM10/20/10
to llv...@cs.uiuc.edu

> No, you could throw it into a global if you know you're going to want to
use 5 at some point in the future randomly.

OK, I guess that's the way I should treat it. Load from global to register,
do operations, store it back.
--
View this message in context: http://old.nabble.com/How-to-assign-a-constant-to-a-register--tp29987387p30007489.html


Sent from the LLVM - Dev mailing list archive at Nabble.com.

_______________________________________________

Eric Christopher

unread,
Oct 20, 2010, 3:56:13 AM10/20/10
to leledumbo, llv...@cs.uiuc.edu

On Oct 20, 2010, at 12:52 AM, leledumbo wrote:

>>
>> No, you could throw it into a global if you know you're going to want to
> use 5 at some point in the future randomly.
>
> OK, I guess that's the way I should treat it. Load from global to register,
> do operations, store it back.

I suppose, it'd be no different than doing this in a C file:

static const int five = 5;

and then using "five" all over the place instead of 5.

Why not just use ConstantInt::get() when you want the number 5?

-eric

leledumbo

unread,
Oct 20, 2010, 5:37:05 AM10/20/10
to llv...@cs.uiuc.edu

> Why not just use ConstantInt::get() when you want the number 5?

Because I'm not using LLVM libraries, I'm generating LLVM assembly myself.
--
View this message in context: http://old.nabble.com/How-to-assign-a-constant-to-a-register--tp29987387p30008156.html


Sent from the LLVM - Dev mailing list archive at Nabble.com.

_______________________________________________

Duncan Sands

unread,
Oct 20, 2010, 5:59:32 AM10/20/10
to llv...@cs.uiuc.edu
On 20/10/10 11:37, leledumbo wrote:
>
>> Why not just use ConstantInt::get() when you want the number 5?
>
> Because I'm not using LLVM libraries, I'm generating LLVM assembly myself.

In that case, why not output '5' when you want 5?

Ciao,

Duncan.

leledumbo

unread,
Oct 20, 2010, 6:56:30 AM10/20/10
to llv...@cs.uiuc.edu

> In that case, why not output '5' when you want 5?

Like I said before, I'm used to common assembly language like x86. Usually I
assign an initial value to a register, then manipulate it.
--
View this message in context: http://old.nabble.com/How-to-assign-a-constant-to-a-register--tp29987387p30008689.html


Sent from the LLVM - Dev mailing list archive at Nabble.com.

_______________________________________________

Matthieu Wipliez

unread,
Oct 20, 2010, 7:31:01 AM10/20/10
to llv...@cs.uiuc.edu
leledumbo,

from what you say, I assume you have some kind of representation (AST or a
lower-level intermediate representation) from which you generate LLVM assembly.
Is this representation in SSA form?
If it is, you might want to do a "copy propagation" transformation that replaces
the uses of all variables that are assigned a constant value by their
definitions.
Example:

x = 5
y = x + 1
z = x * y

becomes

y = 5 + 1
z = 5 * y

Cheers
Matthieu

----- Message d'origine ----
> De : Duncan Sands <bald...@free.fr>
> À : llv...@cs.uiuc.edu
> Envoyé le : Mer 20 octobre 2010, 11h 59min 32s
> Objet : Re: [LLVMdev] How to assign a constant to a register?

leledumbo

unread,
Oct 20, 2010, 9:39:28 AM10/20/10
to llv...@cs.uiuc.edu

> from what you say, I assume you have some kind of representation (AST or a
> lower-level intermediate representation) from which you generate LLVM
> assembly.
> Is this representation in SSA form?

Yes, the representation is an AST. It's not in SSA yet, as it's a direct
representation of the input. I'm confused for this node:
:=
/ \
x 0

where x is a local variable.

> If it is, you might want to do a "copy propagation" transformation that
> replaces
> the uses of all variables that are assigned a constant value by their
> definitions.

I'll consider it, it would useful for constant expression.

--
View this message in context: http://old.nabble.com/How-to-assign-a-constant-to-a-register--tp29987387p30009972.html


Sent from the LLVM - Dev mailing list archive at Nabble.com.

_______________________________________________

James Molloy

unread,
Oct 20, 2010, 9:48:22 AM10/20/10
to leledumbo, llv...@cs.uiuc.edu
Hi,

If x is a local variable, it will be stored on the stack. So you need an
alloca for it:

%x = alloca i8 ; <i8*>

Then you can just perform a store:

Store i8* %x, i8 0

Cheers,

James

--
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

_______________________________________________

leledumbo

unread,
Oct 21, 2010, 2:19:53 AM10/21/10
to llv...@cs.uiuc.edu

> If x is a local variable, it will be stored on the stack. So you need an
> alloca for it:

Aha, I remember this in Kaleidoscope tutorial. So, after the alloca %x can
be modified freely (e.g. without adding suffix)?
--
View this message in context: http://old.nabble.com/How-to-assign-a-constant-to-a-register--tp29987387p30016496.html

James Molloy

unread,
Oct 21, 2010, 3:51:27 AM10/21/10
to leledumbo, llv...@cs.uiuc.edu
Hi,

After the alloca, %x is of type i8* (i.e. a pointer to whatever type x
is in your HLL). It can be mutated using the 'store' instruction.

Note that if you want to read its value, you will have to perform a
'load' to a temporary - for example to increment 'x' by one:

Load i8 %x.tmp1, i8* %x
Add i8 %x.tmp2, i8 %x.tmp1, i8 1
Store i8* %x, %x.tmp2

Think of the LLVM architecture as like a load/store RISC machine, apart
from it has infinite registers and each register can only be written to
once.

Cheers,

James

> -----Original Message-----
> From: llvmdev...@cs.uiuc.edu [mailto:llvmdev...@cs.uiuc.edu]
> On Behalf Of leledumbo
> Sent: 21 October 2010 07:20
> To: llv...@cs.uiuc.edu
> Subject: Re: [LLVMdev] Re : How to assign a constant to a register?
>
>

--
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

_______________________________________________

Matthieu Wipliez

unread,
Oct 21, 2010, 4:13:15 AM10/21/10
to llv...@cs.uiuc.edu
Yes, because an alloca allocates stack memory for %x, so this means that %x is a
pointer, not a register in SSA form.
So you need to use "load" and "store" to access the contents of the variable and
to modify it respectively (as shown in the "Memory in LLVM" section:
http://llvm.org/docs/tutorial/LangImpl7.html#memory )
Using local registers is less verbose (because you do not have all those
load/store operations), and is not too hard to generate if you already have a
representation in SSA form.
On the other hand, using loads and stores does not require the SSA form, and the
code will use registers anyway once the mem2reg pass is run.

Matthieu

----- Message d'origine ----

> De : leledumbo <leledum...@yahoo.co.id>
> À : llv...@cs.uiuc.edu
> Envoyé le : Jeu 21 octobre 2010, 8h 19min 53s
> Objet : Re: [LLVMdev] Re : How to assign a constant to a register?

Reply all
Reply to author
Forward
0 new messages