Are global variables candiates for register allocation?

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

Are global variables candiates for register allocation?

Hayden Livingston
I was wondering if global variables can be candidates for register
allocation. My use case is a global variable that is used in every
function in my program.

I'm wondering if it's better to pass it in, or let it stay as a global.

Passing it in will require a bit of work.
_______________________________________________
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: Are global variables candiates for register allocation?

Reid Kleckner-2
This came up in the past for GHC, and we recommended passing it as a parameter everywhere, as it lets the register allocator spill it under high register pressure.

GCC has support for allocating globals in GPRs and removing that GPR from the allocatable set, but LLVM doesn't implement it so far as I know.

On Tue, Jun 30, 2015 at 5:43 PM, Hayden Livingston <[hidden email]> wrote:
I was wondering if global variables can be candidates for register
allocation. My use case is a global variable that is used in every
function in my program.

I'm wondering if it's better to pass it in, or let it stay as a global.

Passing it in will require a bit of work.
_______________________________________________
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: Are global variables candiates for register allocation?

Hayden Livingston
 Thanks, Reid. I'm not an optimization expert, but as a workaround,
can I do the following:

void myFunction()
{
   int local = global;
   .. use local ...
}

?

On Tue, Jun 30, 2015 at 6:53 PM, Reid Kleckner <[hidden email]> wrote:

> This came up in the past for GHC, and we recommended passing it as a
> parameter everywhere, as it lets the register allocator spill it under high
> register pressure.
>
> GCC has support for allocating globals in GPRs and removing that GPR from
> the allocatable set, but LLVM doesn't implement it so far as I know.
>
> On Tue, Jun 30, 2015 at 5:43 PM, Hayden Livingston <[hidden email]>
> wrote:
>>
>> I was wondering if global variables can be candidates for register
>> allocation. My use case is a global variable that is used in every
>> function in my program.
>>
>> I'm wondering if it's better to pass it in, or let it stay as a global.
>>
>> Passing it in will require a bit of work.
>> _______________________________________________
>> 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: Are global variables candiates for register allocation?

mats petersson
From a purely theoretical perspective, the compiler has to deal with here.

1. "Is the variable modified by other functions?"
     If so, the compiler must reload the value of global variables after each call to such a function (or calls that MAY end up in such a function)
2. "is this variable used enough inside the function to warrant it being placed in a local variable?"
     If so, it can be moved to a register (subject to #1 - if it still has to be reloaded umpteen times, it's not necessarily meaningful to do so)

It's entirely plausible to come up with code that uses a global variable and the compiler can allocate a register for it, but also equally possible to come up with something where the compiler CAN'T use a register.

Using the method of

     int local = global;
 
would solve #1 above - as the local value won't change other than within the function.

Making the global(s) into `static` - in other words letting the compiler know "nothing outside this TU can see this variable" can help with #1 as well, as the compiler can then analyze this TU and see what is going on without having to worry that calls outside the TU will modify the variable unknown to its current knowledge.

On 1 July 2015 at 05:57, Hayden Livingston <[hidden email]> wrote:
 Thanks, Reid. I'm not an optimization expert, but as a workaround,
can I do the following:

void myFunction()
{
   int local = global;
   .. use local ...
}

?

On Tue, Jun 30, 2015 at 6:53 PM, Reid Kleckner <[hidden email]> wrote:
> This came up in the past for GHC, and we recommended passing it as a
> parameter everywhere, as it lets the register allocator spill it under high
> register pressure.
>
> GCC has support for allocating globals in GPRs and removing that GPR from
> the allocatable set, but LLVM doesn't implement it so far as I know.
>
> On Tue, Jun 30, 2015 at 5:43 PM, Hayden Livingston <[hidden email]>
> wrote:
>>
>> I was wondering if global variables can be candidates for register
>> allocation. My use case is a global variable that is used in every
>> function in my program.
>>
>> I'm wondering if it's better to pass it in, or let it stay as a global.
>>
>> Passing it in will require a bit of work.
>> _______________________________________________
>> 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: Are global variables candiates for register allocation?

Hayden Livingston
Right, I follow your theory and thought the same.

I have a single TU scenario where the global is just used because we
generate hand assembly at runtime, and want to keep the code written
by hand to be super simple, calls with no parameters. Our scenario is
literally reading a file, which calls this functions hundreds of
thousands of times, and we reset the pointer to the "global" object
every time in the function.

I'll compile and see how it goes.

On Wed, Jul 1, 2015 at 12:40 AM, mats petersson <[hidden email]> wrote:

> From a purely theoretical perspective, the compiler has to deal with here.
>
> 1. "Is the variable modified by other functions?"
>      If so, the compiler must reload the value of global variables after
> each call to such a function (or calls that MAY end up in such a function)
> 2. "is this variable used enough inside the function to warrant it being
> placed in a local variable?"
>      If so, it can be moved to a register (subject to #1 - if it still has
> to be reloaded umpteen times, it's not necessarily meaningful to do so)
>
> It's entirely plausible to come up with code that uses a global variable and
> the compiler can allocate a register for it, but also equally possible to
> come up with something where the compiler CAN'T use a register.
>
> Using the method of
>
>      int local = global;
>
> would solve #1 above - as the local value won't change other than within the
> function.
>
> Making the global(s) into `static` - in other words letting the compiler
> know "nothing outside this TU can see this variable" can help with #1 as
> well, as the compiler can then analyze this TU and see what is going on
> without having to worry that calls outside the TU will modify the variable
> unknown to its current knowledge.
>
> On 1 July 2015 at 05:57, Hayden Livingston <[hidden email]> wrote:
>>
>>  Thanks, Reid. I'm not an optimization expert, but as a workaround,
>> can I do the following:
>>
>> void myFunction()
>> {
>>    int local = global;
>>    .. use local ...
>> }
>>
>> ?
>>
>> On Tue, Jun 30, 2015 at 6:53 PM, Reid Kleckner <[hidden email]> wrote:
>> > This came up in the past for GHC, and we recommended passing it as a
>> > parameter everywhere, as it lets the register allocator spill it under
>> > high
>> > register pressure.
>> >
>> > GCC has support for allocating globals in GPRs and removing that GPR
>> > from
>> > the allocatable set, but LLVM doesn't implement it so far as I know.
>> >
>> > On Tue, Jun 30, 2015 at 5:43 PM, Hayden Livingston
>> > <[hidden email]>
>> > wrote:
>> >>
>> >> I was wondering if global variables can be candidates for register
>> >> allocation. My use case is a global variable that is used in every
>> >> function in my program.
>> >>
>> >> I'm wondering if it's better to pass it in, or let it stay as a global.
>> >>
>> >> Passing it in will require a bit of work.
>> >> _______________________________________________
>> >> 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: Are global variables candiates for register allocation?

Caldarale, Charles R
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Hayden Livingston
> Subject: Re: [LLVMdev] Are global variables candiates for register allocation?

> I have a single TU scenario where the global is just used because we
> generate hand assembly at runtime, and want to keep the code written
> by hand to be super simple, calls with no parameters.

The trick we use for our global register variables (with unique values per thread) is to define additional calling conventions that include the registers of interest, thus avoiding having to change the C++ code (compiled with gcc) that invokes our dynamically generated functions.  We attach the appropriate convention to the functions built by LLVM, and also to calls back into our C++ code made by the generated functions.  Entry and exit IR in each function extracts the values as input arguments and returns them as results; outbound calls to C++ code construct the additional arguments from the original input values.  LLVM then takes care of insuring that the registers are correct at the boundaries, even if they are used for other purposes within the function.  (Note that we don't utilize any exception handling, which would likely complicate this somewhat.)

This involves a small amount of change to X86CallingConv.td and some other auxiliary files, which has been trivial to keep up to date with new LLVM releases.  On our to-do list is figuring out some means of registering our calling conventions dynamically; if we ever get around to that, we would submit it for inclusion in trunk.

 - Chuck

 

_______________________________________________
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: Are global variables candiates for register allocation?

Hayden Livingston
That really would solve my problem ... so I'll look out for your
potential future change.

For now though, it seems like I'll have to get this part of code
compiled with GCC. Sadness ensues.

On Wed, Jul 1, 2015 at 9:29 AM, Caldarale, Charles R
<[hidden email]> wrote:

>> From: [hidden email] [mailto:[hidden email]] On Behalf Of Hayden Livingston
>> Subject: Re: [LLVMdev] Are global variables candiates for register allocation?
>
>> I have a single TU scenario where the global is just used because we
>> generate hand assembly at runtime, and want to keep the code written
>> by hand to be super simple, calls with no parameters.
>
> The trick we use for our global register variables (with unique values per thread) is to define additional calling conventions that include the registers of interest, thus avoiding having to change the C++ code (compiled with gcc) that invokes our dynamically generated functions.  We attach the appropriate convention to the functions built by LLVM, and also to calls back into our C++ code made by the generated functions.  Entry and exit IR in each function extracts the values as input arguments and returns them as results; outbound calls to C++ code construct the additional arguments from the original input values.  LLVM then takes care of insuring that the registers are correct at the boundaries, even if they are used for other purposes within the function.  (Note that we don't utilize any exception handling, which would likely complicate this somewhat.)
>
> This involves a small amount of change to X86CallingConv.td and some other auxiliary files, which has been trivial to keep up to date with new LLVM releases.  On our to-do list is figuring out some means of registering our calling conventions dynamically; if we ever get around to that, we would submit it for inclusion in trunk.
>
>  - Chuck
>
>

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