Regarding ARM CodeGen

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

Regarding ARM CodeGen

kapil anand-2
Hi all,

I am using LLVM compiler and CodeGen  for generating ARM binaries.

I was going through the code for ARM backend. I noticed that the ARM Condition field( Bits 31-28) is generated by converting the conditions used in icmp and branch. For example, if I have following C Code

int a,b,c,d;
c = a+b;

if(c==0)
     d = a + 10;


Then I get ( Assembly Instructions with opcodes only)

add
cmp
addeq


( basically converting branch to the predicate condition field)

I have a few questions regarding the above operation.
1. If I use GCC on above code, then I get following .s output:
   adds
   addeq

I don't  get the intermediate compare instruction, which I got when I used LLVM. So, does LLVM ARM Backend assume that only "cmp" and "test" instructions can set the Status flags and not the usual arithmetic instructions. Is there any way of specifying to Backend that add can also modify status flag through "s" bit.

2. Also, when I looked at ISelLowering file, I noticed that conditions used in "icmp" instructions are converted to ARM Predicate Condition fields. Icmp has only "10" conditions, which map to corresponding "10" conditions in ARM Condition field but ARM can have fourteen conditions. If we consider the mapping shown in ISelLowering File, then following four conditions are left:
"VS": Overflow Set
"VC" : Overflow Clear
"MI" : Minus
"PL": Plus

So, does this mean that it is not possible to obtain the above conditions are predicate if we use LLVM Compiler framework.

Thanks

Regards,
Kapil Anand



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Regarding ARM CodeGen

Evan Cheng-2

On Jul 14, 2008, at 12:59 PM, kapil anand wrote:

Hi all,

I am using LLVM compiler and CodeGen  for generating ARM binaries.

I was going through the code for ARM backend. I noticed that the ARM Condition field( Bits 31-28) is generated by converting the conditions used in icmp and branch. For example, if I have following C Code

int a,b,c,d;
c = a+b;

if(c==0)
     d = a + 10;


Then I get ( Assembly Instructions with opcodes only)

add
cmp
addeq


( basically converting branch to the predicate condition field)

I have a few questions regarding the above operation.
1. If I use GCC on above code, then I get following .s output:
   adds
   addeq

I don't  get the intermediate compare instruction, which I got when I used LLVM. So, does LLVM ARM Backend assume that only "cmp" and "test" instructions can set the Status flags and not the usual arithmetic instructions. Is there any way of specifying to Backend that add can also modify status flag through "s" bit.

Right. X86 backend has the same issue. It's not taking advantage of the fact that instructions can set the condition register bits. It's a known codegen deficiency. On x86 it's generally not a *huge* issue but I have no idea what its impact is on various ARM implementations.



2. Also, when I looked at ISelLowering file, I noticed that conditions used in "icmp" instructions are converted to ARM Predicate Condition fields. Icmp has only "10" conditions, which map to corresponding "10" conditions in ARM Condition field but ARM can have fourteen conditions. If we consider the mapping shown in ISelLowering File, then following four conditions are left:
"VS": Overflow Set
"VC" : Overflow Clear
"MI" : Minus
"PL": Plus

So, does this mean that it is not possible to obtain the above conditions are predicate if we use LLVM Compiler framework.

It's not clear to me how those are modeled in the llvm level.

Evan



Thanks

Regards,
Kapil Anand


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Regarding ARM CodeGen

kapil anand-2
Hi Evan,

Thanks for the answers. I had few more queries though.

1. As far as I was able to understand the Codegen infrastructure, ARMInstrInfo.td file has complete description of the instructions which modify the status flags. For example, we have description for both ADD and ADDS. But the problem is that in LLVM, we have a single "ADD" Instruction. Thus when we do getDesc(add), we get the descripiton corresponding to "ADD". When I was reading the code, I got a feeling that if we are able to modify this selection of "ADD" to "ADDS"( provided we somehow determine that we need ADDS here), then everything else related to ARM instruction generation has been handled in current infrastructure. Is this correct or do we need to modify other things also?

2. In file ARMISelLowering.cpp, inside function FPCCtoARMCC, condition ISD::SETO generates ARMCC::VC ( Overflow clear) condition. Thus, if we are able to appropriately generate ISD::SETO inside SDNode for overflow clear and then map it to ARMCC::VC instruction in IntCCtoARMCC, then will that be enough to generate the an instruction like "addvc"?

Thanks

Regards,
Kapil Anand

On Mon, Jul 14, 2008 at 6:10 PM, Evan Cheng <[hidden email]> wrote:

On Jul 14, 2008, at 12:59 PM, kapil anand wrote:

Hi all,

I am using LLVM compiler and CodeGen  for generating ARM binaries.

I was going through the code for ARM backend. I noticed that the ARM Condition field( Bits 31-28) is generated by converting the conditions used in icmp and branch. For example, if I have following C Code

int a,b,c,d;
c = a+b;

if(c==0)
     d = a + 10;


Then I get ( Assembly Instructions with opcodes only)

add
cmp
addeq


( basically converting branch to the predicate condition field)

I have a few questions regarding the above operation.
1. If I use GCC on above code, then I get following .s output:
   adds
   addeq

I don't  get the intermediate compare instruction, which I got when I used LLVM. So, does LLVM ARM Backend assume that only "cmp" and "test" instructions can set the Status flags and not the usual arithmetic instructions. Is there any way of specifying to Backend that add can also modify status flag through "s" bit.

Right. X86 backend has the same issue. It's not taking advantage of the fact that instructions can set the condition register bits. It's a known codegen deficiency. On x86 it's generally not a *huge* issue but I have no idea what its impact is on various ARM implementations.



2. Also, when I looked at ISelLowering file, I noticed that conditions used in "icmp" instructions are converted to ARM Predicate Condition fields. Icmp has only "10" conditions, which map to corresponding "10" conditions in ARM Condition field but ARM can have fourteen conditions. If we consider the mapping shown in ISelLowering File, then following four conditions are left:
"VS": Overflow Set
"VC" : Overflow Clear
"MI" : Minus
"PL": Plus

So, does this mean that it is not possible to obtain the above conditions are predicate if we use LLVM Compiler framework.

It's not clear to me how those are modeled in the llvm level.

Evan



Thanks

Regards,
Kapil Anand


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Regarding ARM CodeGen

Evan Cheng-2

On Jul 14, 2008, at 5:10 PM, kapil anand wrote:

Hi Evan,

Thanks for the answers. I had few more queries though.

1. As far as I was able to understand the Codegen infrastructure, ARMInstrInfo.td file has complete description of the instructions which modify the status flags. For example, we have description for both ADD and ADDS. But the problem is that in LLVM, we have a single "ADD" Instruction. Thus when we do getDesc(add), we get the descripiton corresponding to "ADD". When I was reading the code, I got a feeling that if we are able to modify this selection of "ADD" to "ADDS"( provided we somehow determine that we need ADDS here), then everything else related to ARM instruction generation has been handled in current infrastructure. Is this correct or do we need to modify other things also?

The short answer is we'll need to modify other things. It's possible to custom lower setcc / select_cc, etc. to handle some the cases and enable selection of ADDS. But it won't be a very generic fix. The right fix is to add a pass to optimize away the cmp instruction by *folding* it in the preceding add when it's legal. Ideally this will be a target independent pass that x86 and other targets can take advantage of as well.



2. In file ARMISelLowering.cpp, inside function FPCCtoARMCC, condition ISD::SETO generates ARMCC::VC ( Overflow clear) condition. Thus, if we are able to appropriately generate ISD::SETO inside SDNode for overflow clear and then map it to ARMCC::VC instruction in IntCCtoARMCC, then will that be enough to generate the an instruction like "addvc"?

addvc means "executing the add when overflow clear"? Then yes, that will happen as a result of if conversion if the incoming instruction selection input looks like that.

Evan



Thanks

Regards,
Kapil Anand

On Mon, Jul 14, 2008 at 6:10 PM, Evan Cheng <[hidden email]> wrote:

On Jul 14, 2008, at 12:59 PM, kapil anand wrote:

Hi all,

I am using LLVM compiler and CodeGen  for generating ARM binaries.

I was going through the code for ARM backend. I noticed that the ARM Condition field( Bits 31-28) is generated by converting the conditions used in icmp and branch. For example, if I have following C Code

int a,b,c,d;
c = a+b;

if(c==0)
     d = a + 10;


Then I get ( Assembly Instructions with opcodes only)

add
cmp
addeq


( basically converting branch to the predicate condition field)

I have a few questions regarding the above operation.
1. If I use GCC on above code, then I get following .s output:
   adds
   addeq

I don't  get the intermediate compare instruction, which I got when I used LLVM. So, does LLVM ARM Backend assume that only "cmp" and "test" instructions can set the Status flags and not the usual arithmetic instructions. Is there any way of specifying to Backend that add can also modify status flag through "s" bit.

Right. X86 backend has the same issue. It's not taking advantage of the fact that instructions can set the condition register bits. It's a known codegen deficiency. On x86 it's generally not a *huge* issue but I have no idea what its impact is on various ARM implementations.



2. Also, when I looked at ISelLowering file, I noticed that conditions used in "icmp" instructions are converted to ARM Predicate Condition fields. Icmp has only "10" conditions, which map to corresponding "10" conditions in ARM Condition field but ARM can have fourteen conditions. If we consider the mapping shown in ISelLowering File, then following four conditions are left:
"VS": Overflow Set
"VC" : Overflow Clear
"MI" : Minus
"PL": Plus

So, does this mean that it is not possible to obtain the above conditions are predicate if we use LLVM Compiler framework.

It's not clear to me how those are modeled in the llvm level.

Evan



Thanks

Regards,
Kapil Anand


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Regarding ARM CodeGen

kapil anand-2
Hi,

I have one more query regarding the LLVM representations. In LLVM Infrastructure, "label" is defined as Primitive type. So, is there any way of using a variable of Type Label in some arithmetic operation or in "bitcast" instruction.

I tried the following code:



label %X1:
X1:
   %y = bitcast label %X1 to i32
    %tmp1 = add i32 %y,2



llvm-as gave me an error that: "Basic block can't be used in line 3" (Bitcast)

Is there any other way to use label in arithmetic operations. I am trying this to represent Program counter in LLVM, since in ARM, we can have various instructions which operate on PC , eg.

R2 = ADD PC,10
  

Thanks

Regards,
Kapil

On Mon, Jul 14, 2008 at 8:52 PM, Evan Cheng <[hidden email]> wrote:

On Jul 14, 2008, at 5:10 PM, kapil anand wrote:

Hi Evan,

Thanks for the answers. I had few more queries though.

1. As far as I was able to understand the Codegen infrastructure, ARMInstrInfo.td file has complete description of the instructions which modify the status flags. For example, we have description for both ADD and ADDS. But the problem is that in LLVM, we have a single "ADD" Instruction. Thus when we do getDesc(add), we get the descripiton corresponding to "ADD". When I was reading the code, I got a feeling that if we are able to modify this selection of "ADD" to "ADDS"( provided we somehow determine that we need ADDS here), then everything else related to ARM instruction generation has been handled in current infrastructure. Is this correct or do we need to modify other things also?

The short answer is we'll need to modify other things. It's possible to custom lower setcc / select_cc, etc. to handle some the cases and enable selection of ADDS. But it won't be a very generic fix. The right fix is to add a pass to optimize away the cmp instruction by *folding* it in the preceding add when it's legal. Ideally this will be a target independent pass that x86 and other targets can take advantage of as well.



2. In file ARMISelLowering.cpp, inside function FPCCtoARMCC, condition ISD::SETO generates ARMCC::VC ( Overflow clear) condition. Thus, if we are able to appropriately generate ISD::SETO inside SDNode for overflow clear and then map it to ARMCC::VC instruction in IntCCtoARMCC, then will that be enough to generate the an instruction like "addvc"?

addvc means "executing the add when overflow clear"? Then yes, that will happen as a result of if conversion if the incoming instruction selection input looks like that.

Evan



Thanks

Regards,
Kapil Anand

On Mon, Jul 14, 2008 at 6:10 PM, Evan Cheng <[hidden email]> wrote:

On Jul 14, 2008, at 12:59 PM, kapil anand wrote:

Hi all,

I am using LLVM compiler and CodeGen  for generating ARM binaries.

I was going through the code for ARM backend. I noticed that the ARM Condition field( Bits 31-28) is generated by converting the conditions used in icmp and branch. For example, if I have following C Code

int a,b,c,d;
c = a+b;

if(c==0)
     d = a + 10;


Then I get ( Assembly Instructions with opcodes only)

add
cmp
addeq


( basically converting branch to the predicate condition field)

I have a few questions regarding the above operation.
1. If I use GCC on above code, then I get following .s output:
   adds
   addeq

I don't  get the intermediate compare instruction, which I got when I used LLVM. So, does LLVM ARM Backend assume that only "cmp" and "test" instructions can set the Status flags and not the usual arithmetic instructions. Is there any way of specifying to Backend that add can also modify status flag through "s" bit.

Right. X86 backend has the same issue. It's not taking advantage of the fact that instructions can set the condition register bits. It's a known codegen deficiency. On x86 it's generally not a *huge* issue but I have no idea what its impact is on various ARM implementations.



2. Also, when I looked at ISelLowering file, I noticed that conditions used in "icmp" instructions are converted to ARM Predicate Condition fields. Icmp has only "10" conditions, which map to corresponding "10" conditions in ARM Condition field but ARM can have fourteen conditions. If we consider the mapping shown in ISelLowering File, then following four conditions are left:
"VS": Overflow Set
"VC" : Overflow Clear
"MI" : Minus
"PL": Plus

So, does this mean that it is not possible to obtain the above conditions are predicate if we use LLVM Compiler framework.

It's not clear to me how those are modeled in the llvm level.

Evan



Thanks

Regards,
Kapil Anand


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Regarding ARM CodeGen

Anton Korobeynikov
In reply to this post by kapil anand-2
Hello,

> Infrastructure, "label" is defined as Primitive type. So, is there any way
> of using a variable of Type Label in some arithmetic operation or in
> "bitcast" instruction.
No.

> llvm-as gave me an error that: "Basic block can't be used in line 3"
> (Bitcast)
Correct, labels can be used only as arguments to branches and switches.

> Is there any other way to use label in arithmetic operations.
No.

> this to represent Program counter in LLVM, since in ARM, we can have various
> instructions which operate on PC , eg.
You should use some sort of intrinsic for this, because change of PC cannot be compatible
with 'normal' CFG structures.

--
WBR, Anton Korobeynikov
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Regarding ARM CodeGen

Gordon Henriksen-3
In reply to this post by kapil anand-2
On 2008-07-15, at 11:35, kapil anand wrote:

> I have one more query regarding the LLVM representations. In LLVM  
> Infrastructure, "label" is defined as Primitive type. So, is there  
> any way of using a variable of Type Label in some arithmetic  
> operation or in "bitcast" instruction.
>
> Is there any other way to use label in arithmetic operations. I am  
> trying this to represent Program counter in LLVM, since in ARM, we  
> can have various instructions which operate on PC , eg.

Hi Kapil,

If this isn't a FAQ, it should be. In LLVM, 'label' values (in C++,  
BasicBlock*'s) can only be used as arguments to flow control  
instructions (br, switch, invoke, and phi, to be specific). The reason  
is that the SSA representation cannot be formed in the presence of  
dynamic flow control—consider how the code generator might implement  
PHI if sources and destinations are not decidable.

What are you attempting to accomplish by reading the PC? The usual  
goal in using an 'address of label' is to implement a jump table by  
hand. In this case, your compiler should assign integers to labels and  
then, when it wants to emit a dynamic 'goto', it should branch into a  
switch statement, which the LLVM optimizer will transform into a jump  
table. If you use mem2reg, LLVM will take care of the phi nodes for you.

-- Gordon


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Regarding ARM CodeGen

kapil anand-2
Hi Gordon,
 
I am trying to represent ARM instruction in LLVM. In ARM ISA, PC is itself a General Purpose Register and we can have following kind of instruction
 
R3 = ADD PC, R2
 
Since label in LLVM corresponds to current position and thus is like a logical Program Counter. I was trying to implement the above instruction by using label as an arguement to LLVM Add instruction, based on the assumption that LLVM CodeGen will finally take care of PC mapping accordingly.
 
label: %tmp3 = add %label,%tmp2
 
But it seems that this kind of operation is not possible and my assumption is not correct. Is there any way to represent this kind of operation in LLVM?
 
Thanks
 
Kapil
 
 
 
 
 


 
On Tue, Jul 15, 2008 at 12:47 PM, Gordon Henriksen <[hidden email]> wrote:
On 2008-07-15, at 11:35, kapil anand wrote:

> I have one more query regarding the LLVM representations. In LLVM
> Infrastructure, "label" is defined as Primitive type. So, is there
> any way of using a variable of Type Label in some arithmetic
> operation or in "bitcast" instruction.
>
> Is there any other way to use label in arithmetic operations. I am
> trying this to represent Program counter in LLVM, since in ARM, we
> can have various instructions which operate on PC , eg.

Hi Kapil,

If this isn't a FAQ, it should be. In LLVM, 'label' values (in C++,
BasicBlock*'s) can only be used as arguments to flow control
instructions (br, switch, invoke, and phi, to be specific). The reason
is that the SSA representation cannot be formed in the presence of
dynamic flow control—consider how the code generator might implement
PHI if sources and destinations are not decidable.

What are you attempting to accomplish by reading the PC? The usual
goal in using an 'address of label' is to implement a jump table by
hand. In this case, your compiler should assign integers to labels and
then, when it wants to emit a dynamic 'goto', it should branch into a
switch statement, which the LLVM optimizer will transform into a jump
table. If you use mem2reg, LLVM will take care of the phi nodes for you.

-- Gordon


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Regarding ARM CodeGen

Gordon Henriksen-3
On 2008-07-15, at 14:55, kapil anand wrote:

> I am trying to represent ARM instruction in LLVM. In ARM ISA, PC is  
> itself a General Purpose Register and we can have following kind of  
> instruction
>
> R3 = ADD PC, R2
>
> But it seems that this kind of operation is not possible and my  
> assumption is not correct. Is there any way to represent this kind  
> of operation in LLVM?

Sure, but what are you attempting to implement with this device?

— Gordon


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Regarding ARM CodeGen

Eli Friedman-2
In reply to this post by kapil anand-2
On Tue, Jul 15, 2008 at 11:55 AM, kapil anand <[hidden email]> wrote:

> Hi Gordon,
>
> I am trying to represent ARM instruction in LLVM. In ARM ISA, PC is itself a
> General Purpose Register and we can have following kind of instruction
>
> R3 = ADD PC, R2
>
> Since label in LLVM corresponds to current position and thus is like a
> logical Program Counter. I was trying to implement the above instruction by
> using label as an arguement to LLVM Add instruction, based on the
> assumption that LLVM CodeGen will finally take care of PC mapping
> accordingly.
>
> label: %tmp3 = add %label,%tmp2
>
> But it seems that this kind of operation is not possible and my assumption
> is not correct. Is there any way to represent this kind of operation in
> LLVM?

You're going about this the wrong way. The question shouldn't be "How
can I represent my instruction in LLVM?", but rather "My architecture
has an interesting instruction X; how can I make LLVM use instruction
X to generate faster code?".  To that end, what sort of high-level
construct are you getting sub-optimal code for?

Off the top of my head, I can think of a few possibilities for this
instruction to speed up switch statements: to shrink jump tables, to
reduce relocations in jump tables, or to allow jump tables in PIC code
to avoid loading the current value of the program counter.  This is
all low-level enough that it belongs in CodeGen, not in the IL.

See http://llvm.org/docs/CodeGenerator.html for documentation on how
code generation works.  And if you haven't already, you might want to
look at some other pages at http://llvm.org/docs/ to get a better feel
for how LLVM works.

-Eli
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev