Patrik Hägglund H
2012-Mar-12 10:38 UTC
[LLVMdev] Assignment of large objects, optimization?
Hi,
My fronted generates (bad) code, which I see that LLVM is unable to optimize.
For example, code similar to:
%a = type [32 x i16]
declare void @set_obj(%a*)
declare void @use_obj(%a*)
define void @foo() {
entry:
%a1 = alloca %a
%a2 = alloca %a
call void @set_obj(%a* %a2)
%a3 = load %a* %a2
store %a %a3, %a* %a1
call void @use_obj(%a* %a1)
ret void
}
(Or with load/store replaced with memcpy).
In C pseudo-code this is similar to:
a a1;
a a2 = set_obj();
a1 = a2;
use_obj(a1);
and the corresponding LLVM IR in foo() can be simplified to:
%a1 = alloca %a
call void @set_obj(%a* %a1)
call void @use_obj(%a* %a1)
Is it unreasonable to expect LLVM to do this kind of simplifications?
On a side note: Why isn't there an assignment operator in the LLVM IR? Other
compilers I have seen have some kind of assignment operator in the IR.
/Patrik Hägglund
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20120312/e3a795df/attachment.html>
Hi Patrik,> My fronted generates (bad) code, which I see that LLVM is unable to optimize. > For example, code similar to: > %a = type [32 x i16] > declare void @set_obj(%a*) > declare void @use_obj(%a*) > define void @foo() { > entry: > %a1 = alloca %a > %a2 = alloca %a > call void @set_obj(%a* %a2) > %a3 = load %a* %a2 > store %a %a3, %a* %a1 > call void @use_obj(%a* %a1) > ret void > } > (Or with load/store replaced with memcpy). > In C pseudo-code this is similar to: > a a1; > a a2 = set_obj(); > a1 = a2; > use_obj(a1); > and the corresponding LLVM IR in foo() can be simplified to: > %a1 = alloca %a > call void @set_obj(%a* %a1) > call void @use_obj(%a* %a1)no it can't. That's because set_obj may have remembered the address passed to it, for example by storing it in a global variable. Then use_obj might compare the address passed to it with the address that set_obj stashes away, and make decisions based on whether they compare equal or not.> Is it unreasonable to expect LLVM to do this kind of simplifications?Try adding the nocapture attribute to the argument of set_obj.> On a side note: Why isn't there an assignment operator in the LLVM IR? Other > compilers I have seen have some kind of assignment operator in the IR.That's because LLVM IR is always in SSA form. SSA form makes assignments pointless. For example, suppose you could write %x := %y (assignment). Thanks to SSA form, you know that %x can only get a value once, and thus %y is that value: %x is equal to %y throughout the function. But then what's the point of %x? You might as well just use %y wherever you see %x. Ciao, Duncan.
Patrik Hägglund H
2012-Mar-13 12:10 UTC
[LLVMdev] Assignment of large objects, optimization?
Hi Duncan,> Try adding the nocapture attribute to the argument of set_obj.Thanks! My fault. However, that don't seems to make any difference in this example. Adding nocapture in use_obj as well does the trick, but I don't think that can be applied to the code from my front-end. (And it don't seems to work when replacing load+store with memcpy). Here is corresponding C code: typedef struct obj { unsigned arr[32]; } obj_t; void use_obj(obj_t *a1); obj_t set_obj(void); void foo() { obj_t a1, a2 = set_obj(); a1 = a2; use_obj(&a1); } (Both clang-trunk and gcc-4.6.2 retain the a1 = a2 copying. But one of our other compilers, partly developed in-house, seems to remove the copying.)> SSA form makes assignments pointless.At the LLVM assembler level (the interface for the front-end), redundancies are sometimes helpful, and therefore not completely pointless. For example, being able to do such things as %x = add %y, 0 (which implies %x := %y), may be convenient. However, in this case, I mostly thought of memory objects, i.e. *a := *b instead of using memcpy (or load+store). (For example, byval parameters seems to be constructed by targets using memcpy nodes.) I found another example (simple, but contrived), using Clang, where the reasoning about memory copies seems suboptimal: typedef struct obj { unsigned arr[32]; } obj_t; obj_t a; obj_t bar(void) { obj_t b = a, c = b; return b; // ignoring c! } Using clang -c -Os (on x86-64) I get far from space optimized code (due to memcpy replaced with load+store). /Patrik Hägglund -----Original Message----- From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] On Behalf Of Duncan Sands Sent: den 12 mars 2012 16:25 To: llvmdev at cs.uiuc.edu Subject: Re: [LLVMdev] Assignment of large objects, optimization? Hi Patrik,> My fronted generates (bad) code, which I see that LLVM is unable to optimize. > For example, code similar to: > %a = type [32 x i16] > declare void @set_obj(%a*) > declare void @use_obj(%a*) > define void @foo() { > entry: > %a1 = alloca %a > %a2 = alloca %a > call void @set_obj(%a* %a2) > %a3 = load %a* %a2 > store %a %a3, %a* %a1 > call void @use_obj(%a* %a1) > ret void > } > (Or with load/store replaced with memcpy). > In C pseudo-code this is similar to: > a a1; > a a2 = set_obj(); > a1 = a2; > use_obj(a1); > and the corresponding LLVM IR in foo() can be simplified to: > %a1 = alloca %a > call void @set_obj(%a* %a1) > call void @use_obj(%a* %a1)no it can't. That's because set_obj may have remembered the address passed to it, for example by storing it in a global variable. Then use_obj might compare the address passed to it with the address that set_obj stashes away, and make decisions based on whether they compare equal or not.> Is it unreasonable to expect LLVM to do this kind of simplifications?Try adding the nocapture attribute to the argument of set_obj.> On a side note: Why isn't there an assignment operator in the LLVM IR? Other > compilers I have seen have some kind of assignment operator in the IR.That's because LLVM IR is always in SSA form. SSA form makes assignments pointless. For example, suppose you could write %x := %y (assignment). Thanks to SSA form, you know that %x can only get a value once, and thus %y is that value: %x is equal to %y throughout the function. But then what's the point of %x? You might as well just use %y wherever you see %x. Ciao, Duncan. _______________________________________________ LLVM Developers mailing list LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Apparently Analagous Threads
- [LLVMdev] Assignment of large objects, optimization?
- [LLVMdev] register allocation problems in trunk with IMPLICIT_DEF
- SLP example not being vectorized
- [LLVMdev] register allocation problems in trunk with IMPLICIT_DEF
- [LLVMdev] register allocation problems in trunk with IMPLICIT_DEF