X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=docs%2FFAQ.html;h=1ba71231093ca406e48b0513ee78a06a4bc64fc2;hb=8255573835970e7130ba93271972172fb335f2ec;hp=3be059891320a23700f34519d7d9c899b6641dda;hpb=290235f8984ad6f60fbb70069fb2e526c6ff38e9;p=oota-llvm.git diff --git a/docs/FAQ.html b/docs/FAQ.html index 3be05989132..1ba71231093 100644 --- a/docs/FAQ.html +++ b/docs/FAQ.html @@ -74,6 +74,9 @@
  • The llvmc program gives me errors/doesn't work.
  • + +
  • When I compile LLVM-GCC with srcdir == objdir, + it fails. Why?
  • Source Languages @@ -121,6 +124,10 @@
  • What is this "undef" thing that shows up in my code?
  • + +
  • Why does instcombine + simplifycfg turn + a call to a function with a mismatched calling convention into "unreachable"? + Why not make the verifier reject it?
  • @@ -412,8 +419,9 @@ Stop. rebuilding.

    -

    -

    The llvmc program gives me errors/doesn't work.

    +
    +

    The llvmc program gives me errors/doesn't + work.

    @@ -421,6 +429,25 @@ Stop. using llvm-gcc instead.

    +
    +

    When I compile LLVM-GCC with srcdir == objdir, it + fails. Why?

    +
    + +
    +

    The GNUmakefile in the top-level directory of LLVM-GCC is a special + Makefile used by Apple to invoke the build_gcc script after + setting up a special environment. This has the unforunate side-effect that + trying to build LLVM-GCC with srcdir == objdir in a "non-Apple way" invokes + the GNUmakefile instead of Makefile. Because the + environment isn't set up correctly to do this, the build fails.

    + +

    People not building LLVM-GCC the "Apple way" need to build LLVM-GCC with + srcdir != objdir, or simply remove the GNUmakefile entirely.

    + +

    We regret the inconvenience.

    +
    +
    Source Languages
    @@ -677,7 +704,7 @@ Stop.

    Another example is sizeof. It's common for sizeof(long) to vary between platforms. In most C front-ends, sizeof is expanded to - a constant immediately, thus hardwaring a platform-specific detail.

    + a constant immediately, thus hard-wiring a platform-specific detail.

    Also, since many platforms define their ABIs in terms of C, and since LLVM is lower-level than C, front-ends currently must emit platform-specific IR in @@ -741,7 +768,7 @@ Stop.

    What is this "undef" thing that shows up in my - code?

    + code?

    @@ -757,6 +784,143 @@ int X() { int i; return i; } value specified for it.

    + + +
    +

    Why does instcombine + simplifycfg turn + a call to a function with a mismatched calling convention into "unreachable"? + Why not make the verifier reject it?

    +
    + +
    +

    This is a common problem run into by authors of front-ends that are using +custom calling conventions: you need to make sure to set the right calling +convention on both the function and on each call to the function. For example, +this code:

    + +
    +define fastcc void @foo() {
    +        ret void
    +}
    +define void @bar() {
    +        call void @foo( )
    +        ret void
    +}
    +
    + +

    Is optimized to:

    + +
    +define fastcc void @foo() {
    +	ret void
    +}
    +define void @bar() {
    +	unreachable
    +}
    +
    + +

    ... with "opt -instcombine -simplifycfg". This often bites people because +"all their code disappears". Setting the calling convention on the caller and +callee is required for indirect calls to work, so people often ask why not make +the verifier reject this sort of thing.

    + +

    The answer is that this code has undefined behavior, but it is not illegal. +If we made it illegal, then every transformation that could potentially create +this would have to ensure that it doesn't, and there is valid code that can +create this sort of construct (in dead code). The sorts of things that can +cause this to happen are fairly contrived, but we still need to accept them. +Here's an example:

    + +
    +define fastcc void @foo() {
    +        ret void
    +}
    +define internal void @bar(void()* %FP, i1 %cond) {
    +        br i1 %cond, label %T, label %F
    +T:  
    +        call void %FP()
    +        ret void
    +F:
    +        call fastcc void %FP()
    +        ret void
    +}
    +define void @test() {
    +        %X = or i1 false, false
    +        call void @bar(void()* @foo, i1 %X)
    +        ret void
    +} 
    +
    + +

    In this example, "test" always passes @foo/false into bar, which ensures that + it is dynamically called with the right calling conv (thus, the code is + perfectly well defined). If you run this through the inliner, you get this + (the explicit "or" is there so that the inliner doesn't dead code eliminate + a bunch of stuff): +

    + +
    +define fastcc void @foo() {
    +	ret void
    +}
    +define void @test() {
    +	%X = or i1 false, false
    +	br i1 %X, label %T.i, label %F.i
    +T.i:
    +	call void @foo()
    +	br label %bar.exit
    +F.i:
    +	call fastcc void @foo()
    +	br label %bar.exit
    +bar.exit:
    +	ret void
    +}
    +
    + +

    Here you can see that the inlining pass made an undefined call to @foo with + the wrong calling convention. We really don't want to make the inliner have + to know about this sort of thing, so it needs to be valid code. In this case, + dead code elimination can trivially remove the undefined code. However, if %X + was an input argument to @test, the inliner would produce this: +

    + +
    +define fastcc void @foo() {
    +	ret void
    +}
    +
    +define void @test(i1 %X) {
    +	br i1 %X, label %T.i, label %F.i
    +T.i:
    +	call void @foo()
    +	br label %bar.exit
    +F.i:
    +	call fastcc void @foo()
    +	br label %bar.exit
    +bar.exit:
    +	ret void
    +}
    +
    + +

    The interesting thing about this is that %X must be false for the +code to be well-defined, but no amount of dead code elimination will be able to +delete the broken call as unreachable. However, since instcombine/simplifycfg +turns the undefined call into unreachable, we end up with a branch on a +condition that goes to unreachable: a branch to unreachable can never happen, so +"-inline -instcombine -simplifycfg" is able to produce:

    + +
    +define fastcc void @foo() {
    +	ret void
    +}
    +define void @test(i1 %X) {
    +F.i:
    +	call fastcc void @foo()
    +	ret void
    +}
    +
    + +
    +