C Backend's future

I'm wondering what the longer term plans are for the C Backend. I understand it's not actively developed, even deprecated. What I'm not clear about is whether it's something that is viewed as non-vital and should just as well go away, or if it's just a low priority. Basically: it's not improving, but is it likely to disappear?

Thanks,
Kirk

I don't know of anyone actively working on it, and that means it isn't likely to improve anytime soon.

That said, a saving grace of the C backend is that it is very isolated from the rest of the compiler. That means that there is little reason to rip it out. However, as new features are added to LLVM IR, the C backend *is* likely to get more and more out of date and less and less useful.

In short, I don't see a compelling reason to rip it out anytime soon. If it ends up being completely broken for simple programs, it might make sense to remove in the future.

-Chris

Chris Lattner <clattner@apple.com> writes:

I'm wondering what the longer term plans are for the C Backend. I
understand it's not actively developed, even deprecated. What I'm not
clear about is whether it's something that is viewed as non-vital and
should just as well go away, or if it's just a low
priority. Basically: it's not improving, but is it likely to
disappear?

I don't know of anyone actively working on it, and that means it isn't likely to improve anytime soon.

I have quite a few patches for it queued up. Vector code is a problem
since the C backend currently generates aligned vector loads of
unaligned data.

In short, I don't see a compelling reason to rip it out anytime soon.
If it ends up being completely broken for simple programs, it might
make sense to remove in the future.

There's a big reason to keep it. It's a godsend when trying to bugpoint
something where no working llc is available. I've used it quite a lot
during AVX development, for example. It's useful for developing any
new target.

                             -Dave

Hi Dave,

I'm wondering what the longer term plans are for the C Backend. I
understand it's not actively developed, even deprecated. What I'm not
clear about is whether it's something that is viewed as non-vital and
should just as well go away, or if it's just a low
priority. Basically: it's not improving, but is it likely to
disappear?

I don't know of anyone actively working on it, and that means it isn't likely to improve anytime soon.

I have quite a few patches for it queued up. Vector code is a problem
since the C backend currently generates aligned vector loads of
unaligned data.

In short, I don't see a compelling reason to rip it out anytime soon.
If it ends up being completely broken for simple programs, it might
make sense to remove in the future.

There's a big reason to keep it. It's a godsend when trying to bugpoint
something where no working llc is available. I've used it quite a lot
during AVX development, for example. It's useful for developing any
new target.

an alternative is to make the interpreter more powerful and have bugpoint
use it rather than the C backend.

Ciao,

Duncan.

In http://llvm.org/docs/tutorial/LangImpl4.html#jit there's an example that optimizes calls to functions without side effects. Specifically,

extern sin(x);
extern cos(x);
def foo(x) sin(x)*sin(x) + cos(x)*cos(x);

Read function definition:
define double @foo(double %x) {
entry:
        %calltmp = call double @sin(double %x)
        %multmp = fmul double %calltmp, %calltmp
        %calltmp2 = call double @cos(double %x)
        %multmp4 = fmul double %calltmp2, %calltmp2
        %addtmp = fadd double %multmp, %multmp4
        ret double %addtmp
}

I find that when I run the code, the calls to sin and cos aren't optimized and, instead, I end up with:

define double @foo(double %x) {
entry:
  %calltmp = call double @sin(double %x)
  %calltmp1 = call double @sin(double %x)
  %multmp = fmul double %calltmp, %calltmp1
  %calltmp2 = call double @cos(double %x)
  %calltmp3 = call double @cos(double %x)
  %multmp4 = fmul double %calltmp2, %calltmp3
  %addtmp = fadd double %multmp, %multmp4
  ret double %addtmp
}

How do you tell LLVM if a function has side effects or not?

Cheers!

- Rob

Hi Rob,

You need to set attribute ReadOnly on the sin / cos functions, using Function::addFnAttr(Attribute) for example.

Best regards,

Hi,

You need to set attribute ReadOnly on the sin / cos functions, using Function::addFnAttr(Attribute) for example.

the readnone attribute means that the function doesn't dereference any pointers,
doesn't read any global variables etc; while readonly means that while the
function can dereference pointers, it only reads memory and doesn't write it.
Declaring something readnone is stronger than declaring it readonly.
If sin and cos do not write to errno (or you want to ignore that they write to
errno) then you can declare them readonly. If they also don't depend on the
floating point rounding mode (which is modelled as a global variable in LLVM)
or you don't care about rounding modes, then you can declare them readnone.

Ciao,

Duncan.

You need to set attribute ReadOnly on the sin / cos functions, using
Function::addFnAttr(Attribute) for example.

Hmm ... I tried setting that right after Function::Create but I still get the same result (though flagged with "readonly")

declare double @sin(double) readonly

declare double @cos(double) readonly

define double @foo(double %x) readonly {
entry:
  %calltmp = call double @sin(double %x)
  %calltmp1 = call double @sin(double %x)
  %multmp = fmul double %calltmp, %calltmp1
  %calltmp2 = call double @cos(double %x)
  %calltmp3 = call double @cos(double %x)
  %multmp4 = fmul double %calltmp2, %calltmp3
  %addtmp = fadd double %multmp, %multmp4
  ret double %addtmp
}

Hi Rob,

Hmm ... I tried setting that right after Function::Create but I still get the same result (though flagged with "readonly")

did you run the gvn pass (preceded by basic-aa)?

Ciao,

Duncan.

I'm using the gvn pass, not sure about basic-aa.

I've copied the code as-is from http://llvm.org/docs/tutorial/LangImpl4.html#code and added "F->addFnAttr( Attribute::ReadOnly )" after "Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule)".

The passes it sets up are:

  // Set up the optimizer pipeline. Start with registering info about how the
  // target lays out data structures.
  OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData()));
  // Do simple "peephole" optimizations and bit-twiddling optzns.
  OurFPM.add(createInstructionCombiningPass());
  // Reassociate expressions.
  OurFPM.add(createReassociatePass());
  // Eliminate Common SubExpressions.
  OurFPM.add(createGVNPass());
  // Simplify the control flow graph (deleting unreachable blocks, etc).
  OurFPM.add(createCFGSimplificationPass());

It does simplify _some_ things. For example:

def simplifyThis(x) (x*2)+(2*x);

Read function definition:
define double @simplifyThis(double %x) readonly {
entry:
  %multmp = fmul double %x, 2.000000e+00
  %addtmp = fadd double %multmp, %multmp
  ret double %addtmp
}

Rob,

I can reproduce the behaviour you observe using llvm top-of-tree.

I will try to look into it.

Best regards,

Thanks! I'm brand-new to LLVM, so it's probably something pretty basic that I haven't learned yet :slight_smile:

Hi Rob,

I'm using the gvn pass, not sure about basic-aa.

if you are using LLVM from svn then you need to specify the basic-aa analysis,
otherwise gvn won't unify calls to readonly/readnone functions. This is new
behaviour introduced by Dan; probably the tutorial should be updated.

Ciao,

Duncan.

Still no luck after switching to:

  theFPM->add( new llvm::TargetData( *theExecutionEngine->getTargetData() ) );
  theFPM->add( llvm::createBasicAliasAnalysisPass() );
  theFPM->add( llvm::createInstructionCombiningPass() );
  theFPM->add( llvm::createReassociatePass() );
  theFPM->add( llvm::createGVNPass() );
  theFPM->add( llvm::createCFGSimplificationPass() );

Based on output from "llvm-ld -version" and "clang -v" I'm using:

  llvm version 2.9svn
  clang version 2.9 (trunk 118171)

SUCCESS!

Sorry, I had removed the addFnAttr() call by accident. Using the basicAA pass and ReadOnly, as you suggested, works like a charm!

:slight_smile:

Here is the needed patch.

Beside the basic-aa pass, it is also needed to set the attributes on the extern declaration.

Kaleidoscope-Ch4.patch (1.36 KB)

Duncan Sands <baldrick@free.fr> writes:

There's a big reason to keep it. It's a godsend when trying to bugpoint
something where no working llc is available. I've used it quite a lot
during AVX development, for example. It's useful for developing any
new target.

an alternative is to make the interpreter more powerful and have bugpoint
use it rather than the C backend.

That would actually be better. I've never tried the interpreter. Do
you have a sense of what's needed to make it more powerful?

                                      -Dave

Duncan Sands<baldrick@free.fr> writes:

There's a big reason to keep it. It's a godsend when trying to bugpoint
something where no working llc is available. I've used it quite a lot
during AVX development, for example. It's useful for developing any
new target.

an alternative is to make the interpreter more powerful and have bugpoint
use it rather than the C backend.

That would actually be better. I've never tried the interpreter. Do
you have a sense of what's needed to make it more powerful?

Are you sure that this is a good idea? The interpreter (if it is made to work) will probably be much, much slower than the C backend.

Since both the interpreter and the CBE need some love and care to work again, it may be better to exert effort on the CBE.

-- John T.

If anyone was really interested in this, I'd strongly suggest a complete rewrite of the C backend: make use the existing target independent code generator code (for legalization etc) and then just put out a weird ".s file" at the end.

-Chris

IMHO, we should keep the C backend. It still has value, in particular
someone may come along and fix it up. I agree with Chris' earlier
point that there is little value in ripping it out, aside from users
being confused when it doesn't work.

Of course, a rewrite would be nice too...

- Daniel