[llvm-dev] trouble hoisting GlobalValues

Steve King via llvm-dev llvm-dev at lists.llvm.org
Mon Jan 4 11:42:41 PST 2016

Hi Guys,

TL;DR: Perhaps we need ISD::OPAQUE instead of more abuse of ISD::BITCAST.

For global values, none of the suggested solutions work well.  The
root of the matter is that we overload ISD::BITCAST with the implicit
role of "ISD::OPAQUE".  However, existing code doesn't treat
ISD::BITCAST as an generally opaque value, since bitcasts and opacity
are two different semantics with sometimes opposite behavior.

Some specific problems:
1) In more than one well buried code path, the compiler
opportunistically removes ISD::BITCAST.  This makes perfect sense for
a BITCAST, but is the opposite of what we want for opaque value.
2) A special exception was coded for a bitcast of a ConstantInt that
prevents premature removal of the BITCAST.  The overall behavior is
non-obvious since it fooled us all into thinking that bitcasts create
more general opaque values.
3) Instruction definition solutions like Zia's work only in the scope
of a basic block (correct?).  This approach also requires targets to
code exceptions for every instruction that *might* use an opaque
value, rather that just one instruction to handle an opaque value.
Long term, my feeling is that this approach requires too much
4) In my specific case, I had a very frustrating time trying to add
global values into the opaque-ifying code paths used by ConstantInt.
Many of the code paths were new to me, but I bumped into subtle
problems trying to sneak global values through in this manner
sometimes due to (1) above.

What do you all think of a first class ISD::OPAQUE operation?  The
basic concept embodied is that optimizations, mostly folding, should
not look through OPAQUE.  ISD::OPAQUE would not imply any casting or

Some positives:
1) We avoid an ever increasing number of exceptions being added to
BITCAST handling to create opaque values.
2) ISD::OPAQUE could at least be used in a global and constant
hoisting passes, maybe elsewhere.
3) Specical case BITCAST handling for ConstantInt special case moves
to ISD::OPAQUE where it's semantically more accurate.  Target
independent code resolves ISD::OPAQUE as a constant load as we do for
BITCAST today.  Targets never see it.
4) Targets that enable a hypothetical global hoisting would lower
ISD::OPAQUE as an immediate-to-register operation.  No need to
duplicate the rest of their instruction definitions that might touch
an opaque value.

Some negatives:
1) Yet another IR instruction
2) Usage is somewhat niche, suited mostly to minimal code size optimizations.

Does any of this sound sensible?


On Mon, Dec 14, 2015 at 9:55 AM, Ansari, Zia via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
> +1
> As Hal mentioned, ConstantHoisting.cpp should be able to do this fine for global values. You just need to be careful because I found that the CG needs a little work to make sure that the extra global register pressure doesn't cause any issues.
> For local values, if you don't have it, check out my patch : http://reviews.llvm.org/D11363
> This will run at ISEL/DAG with the intent of being more precise in the cases that it targets/catches, and to run at a point where more opportunities are exposed. It was worth a fair bit of code size (over 1% on spec2000), and can be extended to catch more cases, if need be.
> Thanks,
> Zia.
> |-----Original Message-----
> |From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of Hal
> |Finkel via llvm-dev
> |Sent: Friday, December 11, 2015 2:33 PM
> |To: Rafael EspĂ­ndola
> |Cc: llvm-dev
> |Subject: Re: [llvm-dev] trouble hoisting GlobalValues
> |
> |----- Original Message -----
> |> From: "Rafael EspĂ­ndola via llvm-dev" <llvm-dev at lists.llvm.org>
> |> To: "Steve King" <steve at metrokings.com>
> |> Cc: "llvm-dev" <llvm-dev at lists.llvm.org>
> |> Sent: Friday, December 11, 2015 4:28:33 PM
> |> Subject: Re: [llvm-dev] trouble hoisting GlobalValues
> |>
> |> On 11 December 2015 at 16:53, Steve King via llvm-dev
> |> <llvm-dev at lists.llvm.org> wrote:
> |> > Hello LLVM,
> |> > To reduce the code-size cost of relocations, I'm trying to hoist
> |> > GlobalValues that are used many times.  A new pass hides each
> |> > hoisted GV behind a BITCAST in the dominating BB.  The pass then
> |> > updates users with the output of the BITCAST.  This pass works
> |> > properly AFAICT.
> |> >
> |> > The problems come in instruction selection.
> |> > SelectionDAGBuilder::visitBitCast() treats the BITCAST as a no-op
> |> > and eventually users of the GV fold the relocation as if hoisting
> |> > never happened.  Experiments turning the BITCAST into a copytoreg
> |> > failed and anyway I feel like I'm just shooting in the dark.
> |> >
> |> > Can anyone can suggest a strategy for lowering a hoisted GV?  The
> |> > end result should be that the GV materializes as a simple
> |> > move-immediate to register.
> |
> |Also, something similar-sounding to this is done in
> |lib/Transforms/Scalar/ConstantHoisting.cpp
> |
> | -Hal
> |
> |>
> |> Nothing simple. One possibility would be to make constants explicitly
> |> materialized. Something like:
> |>
> |> https://github.com/apple/swift/blob/master/docs/SIL.rst#global-addr
> |>
> |> Which would also be useful for architectures where some constants are
> |> expensive to place in a register.
> |>
> |> Cheers,
> |> Rafael
> |> _______________________________________________
> |> LLVM Developers mailing list
> |> llvm-dev at lists.llvm.org
> |> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> |>
> |
> |--
> |Hal Finkel
> |Assistant Computational Scientist
> |Leadership Computing Facility
> |Argonne National Laboratory
> |_______________________________________________
> |LLVM Developers mailing list
> |llvm-dev at lists.llvm.org
> |http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

More information about the llvm-dev mailing list