[llvm-dev] In ISel, where Constant<0> comes from?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] In ISel, where Constant<0> comes from?

Chris Lattner via llvm-dev
Hello, LLVM devs.

I'm compiling the following simple IR:

define dso_local i32 @main(i32 %argc, i8** %argv) {
entry:
  %retval = alloca i32, align 4
  %argc.addr = alloca i32, align 4
  %argv.addr = alloca i8**, align 8
  store i32 0, i32* %retval, align 4
  store i32 %argc, i32* %argc.addr, align 4
  store i8** %argv, i8*** %argv.addr, align 8
  ret i32 0
}

using `llc -march=sparc -debug-only=isel`.

In the Initial selection DAG I see

t19: ch,glue = CopyToReg t17, Register:i32 $i0, Constant:i32<0>

line. The same "Constant:i32<0>" node I see in my toy backend, which forces me to add a pattern that lowers it using "xor reg,reg". Much like "or g0,g0" pattern in SPARC.

However, I don't see that Constant node when compiling using X86 backend. How does it achieve this? And why initial DAGs are different at all? I got impression that initial DAG is fully target-independent, so these DAG should be the same before starting ISel. Am I wrong?

Thanks in advance.

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] In ISel, where Constant<0> comes from?

Chris Lattner via llvm-dev
On 12/17/2018 8:08 AM, Gleb Popov via llvm-dev wrote:
>
> However, I don't see that Constant node when compiling using X86
> backend. How does it achieve this? And why initial DAGs are different at
> all? I got impression that initial DAG is fully target-independent, so
> these DAG should be the same before starting ISel. Am I wrong?

The selection DAG is very much target-specific. The differences in the
initial DAG usually come from lowering function arguments and return
values, and from lowering calls to other functions. This is where
different calling conventions are applied, so the initial DAG may be
different even for the same target if you change the calling convention.

Later on more differences appear from legalization (which each target
needs to customize to match its needs), and custom DAG combines. All of
this happens before the actual selection process starts.

-Krzysztof

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] In ISel, where Constant<0> comes from?

Chris Lattner via llvm-dev
In reply to this post by Chris Lattner via llvm-dev
On 12/17/2018 8:08 AM, Gleb Popov via llvm-dev wrote:
>
> In the Initial selection DAG I see
>
> t19: ch,glue = CopyToReg t17, Register:i32 $i0, Constant:i32<0>

To answer this---this seems to be a part of the return sequence, i.e.
the part of the calling convention that dictates how a function passes
return values to its caller. This is handled via LowerReturn in the
target lowering object. Check SparcTargetLowering::LowerReturn for the
Sparc implementation.

-Krzysztof

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] In ISel, where Constant<0> comes from?

Chris Lattner via llvm-dev
In reply to this post by Chris Lattner via llvm-dev
Thanks Tim and Krzysztof for pointing me in the right direction.

Indeed, when I started my backend I just blindly copied LowerFormalArguments and LowerReturn from SPARC backend, and that's where these FrameIndex'es and Constant's are coming from.

However, I haven't managed to get a "Constant<>" in the DAG when compiling for X86. I'm interested in how it is lowered. Can you please give me some guidance on this?

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] In ISel, where Constant<0> comes from?

Chris Lattner via llvm-dev
On Tue, 18 Dec 2018 at 07:11, Gleb Popov via llvm-dev
<[hidden email]> wrote:
> However, I haven't managed to get a "Constant<>" in the DAG when compiling for X86. I'm interested in how it is lowered. Can you please give me some guidance on this?

How are you looking? When I run "llc -mtriple=x86_64-linux-gnu
-debug-only=isel" on your IR I get multiple instances of Constants. At
the very start is:

Initial selection DAG: %bb.0 'main:entry'
SelectionDAG has 18 nodes:
 t0: ch = EntryToken
 t7: i64 = Constant<0>
       t9: ch = store<(store 4 into %ir.retval)> t0, Constant:i32<0>,
FrameIndex:i64<0>, undef:i64
       t2: i32,ch = CopyFromReg t0, Register:i32 %0
     t11: ch = store<(store 4 into %ir.argc.addr)> t9, t2,
FrameIndex:i64<1>, undef:i64
     t4: i64,ch = CopyFromReg t0, Register:i64 %1
   t13: ch = store<(store 8 into %ir.argv.addr)> t11, t4,
FrameIndex:i64<2>, undef:i64
 t16: ch,glue = CopyToReg t13, Register:i32 $eax, Constant:i32<0>
 t17: ch = X86ISD::RET_FLAG t16, TargetConstant:i32<0>, Register:i32 $eax, t16:1

where the t16 line corresponds to what you've seen on SPARC.

Cheers.

Tim.
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] In ISel, where Constant<0> comes from?

Chris Lattner via llvm-dev


On Tue, Dec 18, 2018 at 1:03 PM Tim Northover <[hidden email]> wrote:
On Tue, 18 Dec 2018 at 07:11, Gleb Popov via llvm-dev
<[hidden email]> wrote:
> However, I haven't managed to get a "Constant<>" in the DAG when compiling for X86. I'm interested in how it is lowered. Can you please give me some guidance on this?

How are you looking? When I run "llc -mtriple=x86_64-linux-gnu
-debug-only=isel" on your IR I get multiple instances of Constants. At
the very start is:

Initial selection DAG: %bb.0 'main:entry'
SelectionDAG has 18 nodes:
 t0: ch = EntryToken
 t7: i64 = Constant<0>
       t9: ch = store<(store 4 into %ir.retval)> t0, Constant:i32<0>,
FrameIndex:i64<0>, undef:i64
       t2: i32,ch = CopyFromReg t0, Register:i32 %0
     t11: ch = store<(store 4 into %ir.argc.addr)> t9, t2,
FrameIndex:i64<1>, undef:i64
     t4: i64,ch = CopyFromReg t0, Register:i64 %1
   t13: ch = store<(store 8 into %ir.argv.addr)> t11, t4,
FrameIndex:i64<2>, undef:i64
 t16: ch,glue = CopyToReg t13, Register:i32 $eax, Constant:i32<0>
 t17: ch = X86ISD::RET_FLAG t16, TargetConstant:i32<0>, Register:i32 $eax, t16:1

where the t16 line corresponds to what you've seen on SPARC.

Cheers.

Tim.

Strange. Even using exactly the same command line gives me following output:

# bin/llc -debug-only=isel -mtriple=x86_64-linux-gnu 1.ll

Changing optimization level for Function main
        Before: -O2 ; After: -O0
        FastISel is enabled



=== main
Enabling fast-isel
Total amount of phi nodes to update: 0
*** MachineFunction at end of ISel ***
# Machine code for function main: IsSSA, TracksLiveness
Frame Objects:
  fi#0: size=4, align=4, at location [SP+8]
  fi#1: size=4, align=4, at location [SP+8]
  fi#2: size=8, align=8, at location [SP+8]
Function Live Ins: %edi in %0, %rsi in %2

%bb.0: derived from LLVM BB %entry
    Live Ins: %edi %rsi
        %2:gr64 = COPY %rsi; GR64:%2
        %0:gr32 = COPY %edi; GR32:%0
        %1:gr32 = COPY killed %0; GR32:%1,%0
        %3:gr64 = COPY killed %2; GR64:%3,%2
        %4:gr32 = MOV32r0 implicit-def %eflags; GR32:%4
        MOV32mi %stack.0.retval, 1, %noreg, 0, %noreg, 0; mem:ST4[%retval]
        MOV32mr %stack.1.argc.addr, 1, %noreg, 0, %noreg, %1; mem:ST4[%argc.addr] GR32:%1
        MOV64mr %stack.2.argv.addr, 1, %noreg, 0, %noreg, %3; mem:ST8[%argv.addr] GR64:%3
        %eax = COPY %4; GR32:%4
        RETQ implicit %eax

# End machine code for function main.


Restoring optimization level for Function main
        Before: -O0 ; After: -O2

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] In ISel, where Constant<0> comes from?

Chris Lattner via llvm-dev
On Tue, 18 Dec 2018 at 09:41, Gleb Popov <[hidden email]> wrote:
> Changing optimization level for Function main
>         Before: -O2 ; After: -O0
>         FastISel is enabled

Ah, I think I can guess what's happening. I assume your 1.ll is
Clang's output, and you used the default optimization level (which is
-O0).

That means your function is actually tagged as "optnone" and LLVM
tries to use a different instruction selector called "FastISel" rather
than create a DAG at all. This speeds up compilation and improve the
debug experience, but not all targets support it. SPARC falls back to
the DAG because FastISel can't handle the function, but x86 is getting
through it ever creating a DAG.

To see the X86 DAG you can either remove the "optnone" attribute from
the .ll file or override the selector on the llc command-line:
-fast-isel=0.

Cheers.

Tim.
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] In ISel, where Constant<0> comes from?

Chris Lattner via llvm-dev


On Tue, Dec 18, 2018 at 2:21 PM Tim Northover <[hidden email]> wrote:
On Tue, 18 Dec 2018 at 09:41, Gleb Popov <[hidden email]> wrote:
> Changing optimization level for Function main
>         Before: -O2 ; After: -O0
>         FastISel is enabled

Ah, I think I can guess what's happening. I assume your 1.ll is
Clang's output, and you used the default optimization level (which is
-O0).

That means your function is actually tagged as "optnone" and LLVM
tries to use a different instruction selector called "FastISel" rather
than create a DAG at all. This speeds up compilation and improve the
debug experience, but not all targets support it. SPARC falls back to
the DAG because FastISel can't handle the function, but x86 is getting
through it ever creating a DAG.

To see the X86 DAG you can either remove the "optnone" attribute from
the .ll file or override the selector on the llc command-line:
-fast-isel=0.

Cheers.

Tim.

You're absolutely right. Thanks a ton for your insights!

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev