[LLVMdev] First steps with LLVM and partial evaluation

Martin Apel martin.apel at SIMPACK.de
Wed Jul 6 04:56:14 PDT 2011


Hi all,

I'm rather new to LLVM and intend to dive into partial evaluation with LLVM.
I tried to run the example from http://llvm.org/devmtg/2008-08-23/llvm_partial.pdf, which worked after some adaptations, which were necessary, because
LLVM evolved since
the slides were made. However, I also tried to get the same example running as an optimization pass following the instructions in
http://llvm.org/docs/WritingAnLLVMPass.html.
I am using LLVM 2.9 on Linux.

It seems that opt runs a verification step after each pass, which rejected the modifications my pass made. So here's the code (more or less the
original code with only slight
modififications to get things to compile with LLVM 2.9):

#include "specializeFunc.h"

#include "llvm/Function.h"

#include "llvm/Module.h"

#include "llvm/Constants.h"

#include "llvm/DerivedTypes.h"

#include "llvm/LLVMContext.h"

#include "llvm/ADT/DenseMap.h"

#include "llvm/Transforms/Utils/Cloning.h"

using namespace std;

using namespace llvm;

static Function *cloneFunctionInfo(const Function *F,

                                   ValueToValueMapTy& ValueMap)

{

   vector<const Type*> ArgTypes;

   // The user might be deleting arguments to the function by specifying them in

   // the ValueMap. If so, we need to not add the arguments to the arg ty vector

   //

   for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();

        I != E; ++I)

      if (ValueMap.count(I) == 0) // Haven't mapped the argument to anything yet?

         ArgTypes.push_back(I->getType());

   // Create a new function type...

   FunctionType *FTy = FunctionType::get(F->getFunctionType()->getReturnType(),

                                         ArgTypes, F->getFunctionType()->isVarArg());

   // Create the new function...

   Function *NewF = Function::Create(FTy, F->getLinkage(), F->getName());

   // Loop over the arguments, copying the names of the mapped arguments over...

   Function::arg_iterator DestI = NewF->arg_begin();

   for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();

        I != E; ++I)

      if (ValueMap.count(I) == 0) {

         // Is this argument preserved?

         DestI->setName(I->getName()); // Copy the name over...

         ValueMap[I] = DestI++;

         // Add mapping to ValueMap

      }

   return NewF;

}

//*******************************************************************************

void specializeFunction(Module& m, Function& f, LLVMContext& context)

{

   ValueToValueMapTy valueMap;

   Function *specFunc = cloneFunctionInfo(&f, valueMap);

   specFunc->setName(specFunc->getNameStr() + "_spec");

   for (Function::arg_iterator j = f.arg_begin(); j != f.arg_end(); ++j)

   {

      Argument* arg = j;

      Value* val;

      if (arg->getNameStr() == "n")

      {

         val = ConstantInt::get(Type::getInt32Ty(context), 3);

         valueMap[arg] = val;

      }

   }

   SmallVector<ReturnInst*, 8> returns;

   CloneAndPruneFunctionInto(specFunc, &f, valueMap, false, returns);

   m.getFunctionList().push_back(specFunc);

}

#include "llvm/Pass.h"

#include "llvm/Function.h"

#include "llvm/Module.h"

#include "llvm/LLVMContext.h"

#include "../specFunc/specializeFunc.h"

using namespace std;

using namespace llvm;

namespace {

static LLVMContext context;

struct Hello : public ModulePass {

    

   static char ID;

   Hello() : ModulePass(ID)

   {

   }

   virtual bool runOnModule(Module& m)

   {

      for (Module::iterator i = m.begin(); i != m.end(); ++i)

      {

         string name = i->getNameStr();

         if (!i->isDeclaration() && name.substr(name.length() - 5) != "_spec")

            specializeFunction(m, *i, context);

      }

      return false;

   }

};

char Hello::ID = 0;

static RegisterPass<Hello> X("hello", "Hello World Pass", false, false);

}

------------------------------------------------------------------------------------------------------

The resulting error message from the verification step is:

Stored value type does not match pointer operand type!

  store i32 3, i32* %n_addr

 i32Broken module found, compilation aborted!

Stack dump:

0.      Program arguments: opt --load obj/pass/ce_opt_pass.so -hello power.ir 

1.      Running pass 'Function Pass Manager' on module 'power.ir'.

2.      Running pass 'Module Verifier' on function '@mypower_spec'

I do not understand, what is going wrong here. When calling the exact same function "specializeFunction" from a main program, which simply reads a
bitcode file,
calls "specializeFunction" on the only function definition in it and writing it to another file, everything works fine. The resulting bitcode file can
be disassembled or optimized without
problems. What am I doing wrong?

Any help would be appreciated,

Martin



More information about the llvm-dev mailing list