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
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
hi,
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
Hi,
Other than:
%x = add i32 5,0 ; suppose I want to assign 5 to %xis 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.
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.
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.
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
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
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
Thanks Eli,
I now have to understand why it does not seem to be running in my case
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.
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
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.
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.
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 ----
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.
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
From: llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu]
On Behalf Of leledumbo
Sent: 20 October 2010 14:39
To: llvmdev@cs.uiuc.edu
Subject: Re: [LLVMdev] Re : How to assign a constant to a register?> 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 0where 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