[LLVMdev] Precompiled templates

Eichner, Andreas - SID-NLKM Andreas.Eichner at sid.sachsen.de
Fri May 27 03:14:13 PDT 2011


Hi Duncan,

thanks for your response. Meanwhile I got a quick and dirty version
working.
> It is.  For example you can declare a new global constant P2 with the
> appropriate initial value (0 or 1), then do: 
> P->replaceAllUsesWith(P2).
> At that you can erase (i.e. delete) P.
I'm currently using a global variable, set it's initializer to a freshly
created constant value, declare the variable as itself being constant
and set it's linkage to internal.

> Running the instcombine pass on
> the module should then propagate the information into all functions;
> following that by a run of the simplifycfg pass will get rid of dead
> basic blocks.
I used a complete set of standard optimizations copy-pasted from some
tutorials. I was surprised that's all I had to do. Pretty cool and fast
:)
So everything ends up in something like:

  bc  = MemoryBuffer::getFile ("test.bc");
  mod = ParseBitcodeFile (bc, Context);

  GlobalVariable *val;
  ConstantInt    *const_val;

  val       = mod->getNamedGlobal ("P");
  const_val = ConstantInt::get (Context, APInt (32, 1234));
  val->setInitializer (const_val);
  val->setConstant (true);
  val->setLinkage (GlobalValue::InternalLinkage);

  FunctionPassManager fpm (mod);
  fpm.add (createInstructionCombiningPass());
  fpm.add (createCFGSimplificationPass ());
  fpm.doInitialization ();
  Function *f = mod->getFunction ("t");
  fpm.run (*f);

This allows me to write in C:
  int P;

  float t (float a, float b) {
    if (P == 0)
      return a - b;
    else
      return b - a;
  }

compiling this with: clang -O3 -x c test.c -emit-llvm -c -o test.bc
results in:
  @P = common global i32 0, align 4                 ; <i32*> [#uses=1]

  define float @t(float %a, float %b) nounwind readonly {
    %1 = load i32* @P                               ; <i32> [#uses=1]
    %2 = icmp eq i32 %1, 0                          ; <i1> [#uses=1]
    br i1 %2, label %3, label %5

  ; <label>:3                                       ; preds = %0
    %4 = fsub float %a, %b                          ; <float> [#uses=1]
    ret float %4

  ; <label>:5                                       ; preds = %0
    %6 = fsub float %b, %a                          ; <float> [#uses=1]
    ret float %6
  }

and after replacing the global with a constant and run the optimizations
I get a simple:
  define float @t(float %a, float %b) nounwind readnone {
    %1 = fsub float %a, %b                          ; <float> [#uses=1]
    ret float %1
  }

That is what I wanted. LLVM is really pretty cool stuff...




More information about the llvm-dev mailing list