[GHC] #8855: LLVM backend needs to use `-globalopt` explicitly
GHC
ghc-devs at haskell.org
Fri Mar 7 15:31:47 UTC 2014
#8855: LLVM backend needs to use `-globalopt` explicitly
-------------------------------------+------------------------------------
Reporter: bgamari | Owner:
Type: bug | Status: patch
Priority: normal | Milestone: 7.8.1
Component: Compiler | Version: 7.8.1-rc1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture: Unknown/Multiple
Type of failure: None/Unknown | Difficulty: Unknown
Test Case: | Blocked By:
Blocking: | Related Tickets:
-------------------------------------+------------------------------------
Comment (by scpmw):
The issue here is that GHC code somewhat randomly refuses to compile with
LLVM 3.4, with an error along the lines of:
{{{
LLVM ERROR: .LnewCAF$alias: Target doesn't support aliases to
declarations
}}}
These `$alias` definitions are forward references used by the LLVM backend
where it can not derive the exact type of a symbol yet due to it either
being a global symbol. That can happen because either the symbol is
external, or because it is part of another `CmmGroup` (which we can't see
due to streaming).
In either case we rely on these aliases getting eliminated by the
`-globalopt` optimisation pass, much in the same way we are relying on
`-mem2reg` to remove `alloca`s. This is the reason we already pass
`-globalopt` explicitly for `-O0`. For `-O1` and `-O2` the `-globalopt`
pass is always active, so we don't run it twice.
What seems to happen here that in spite of the `-globalopt` pass getting
run, a few `$alias$` definitions survive:
{{{
$ llvm-3.4-build/bin/opt bgamari/History.ll -O1 -S -o - | grep \$alias
@"base_GHCziChar_chr2_info$alias" = alias private i8*
@base_GHCziChar_chr2_info
}}}
Especially note that we only find a definition, but no usage site. So it
might simply be dead code detection not doing its job to completion.
Notably, this behaviour doesn't happen for any of the previous LLVM
versions:
{{{
$ llvm-3.3-build/bin/opt bgamari/History.ll -O1 -S -o - | grep \$alias
$ llvm-3.2-build/bin/opt bgamari/History.ll -O1 -S -o - | grep \$alias
$ llvm-3.1-build/bin/opt bgamari/History.ll -O1 -S -o - | grep \$alias
$ llvm-3.0-build/bin/opt bgamari/History.ll -O1 -S -o - | grep \$alias
$ llvm-2.9-build/bin/opt bgamari/History.ll -O1 -S -o - | grep \$alias
$ llvm-2.8-build/bin/opt bgamari/History.ll -O1 -S -o - | grep \$alias
$ llvm-2.7-build/bin/opt bgamari/History.ll -O1 -S -o - | grep \$alias
}}}
And it vanishes for both `-O1 -globalopt` as well as `-O2` for LLVM 3.4:
{{{
$ llvm-3.4-build/bin/opt bgamari/History.ll -O1 -globalopt -S -o - | grep
\$alias
$ llvm-3.4-build/bin/opt bgamari/History.ll -O2 -S -o - | grep \$alias
}}}
Bottom line is that `-O1 -globalopt` is positively needed for LLVM 3.4. On
the other hand, it's up for discussion whether we want it
1. for `-O2`. I would vote no, it probably does multiple passes already,
at which point we should *really* except all remainders to be gone.
2. for other LLVM versions. Unsure about that one. It only started
happening very recently, and that a lone definition survives with `-O1`
smells like a bug. On the other hand, without having any numbers I would
estimate that `-globalopt` is one of the cheaper optimization passes.
In the end, I would favour doing:
{{{
llvmOpts = ["-mem2reg -globalopt"
, if ver >= 34 then "-O1 -globalopt" else "-O1"
-- LLVM 3.4 -O1 doesn't eliminate aliases reliably
, "-O2"]
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8855#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list