addPassesToEmit(Whole)File changes?

Hi folks,

just installed the new llvm 1.9 build and noticed that my code no longer worked. It seems something has changed with addPassesToEmitFile(). First, the arguments to that method changed so that it no longer takes a PassManager, but only a FunctionPassManager. Instead there is a addPassesToEmitWholeFile() method, but that is marked as optional, and when I change my code to use that there is no output (only an empty file).

I tried changing to code to use a FunctionPassManager, but that then requires the run() call to be changed to individual functions, and I am not convinced I want to do that because what I am outputting are not just functions, but also some global data.

I am currently installing older versions to see if that will work, but of course I will need to get it to work with the newest llvm version at some point.

Any pointers?

Thanks!

Marcel

This is my current code:

-(void)dumpAssemblerToFile:(NSString*)filename
{
  TargetMachine::CodeGenFileType FileType = TargetMachine::AssemblyFile;
  std::string err1;
  Module *M=(Module*)module;
  const TargetMachineRegistry::Entry* entry= TargetMachineRegistry::getClosestStaticTargetForModule( *M, err1 );
  TargetMachine &target=*entry->CtorFn( *M, "" );
  [self generateMethodLists];
  std::ostream *outStream = 0;
  PassManager passes;
  outStream = new std::ofstream( [filename fileSystemRepresentation] );
  TargetData *data =new TargetData( *target.getTargetData());
  passes.add(data);
  target.addPassesToEmitFile(passes, *outStream, FileType, false);
  passes.run(*M);
  delete outStream;
}

just installed the new llvm 1.9 build and noticed that my code no
longer worked. It seems something has changed with
addPassesToEmitFile(). First, the arguments to that method changed so
that it no longer takes a PassManager, but only a
FunctionPassManager. Instead there is a addPassesToEmitWholeFile()
method, but that is marked as optional, and when I change my code to
use that there is no output (only an empty file).

Right, you want to use addPassesToEmitFile if you want the native code generators to work.

I tried changing to code to use a FunctionPassManager, but that then
requires the run() call to be changed to individual functions, and I
am not convinced I want to do that because what I am outputting are
not just functions, but also some global data.

The proper incantations can be found in tools/llc/llc.cpp. You should do something like this:

       // Build up all of the passes that we want to do to the module.
       FunctionPassManager Passes(new ExistingModuleProvider(M.get()));
       Passes.add(new TargetData(*Target.getTargetData()));

       // Ask the target to add backend passes as necessary.
       if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
         std::cerr << argv[0] << ": target does not support generation of this"
                   << " file type!\n";
         if (Out != &std::cout) delete Out;
         // And the Out file is empty and useless, so remove it now.
         sys::Path(OutputFilename).eraseFromDisk();
         return 1;
       }

       Passes.doInitialization();

       // Run our queue of passes all at once now, efficiently.
       for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
         if (!I->isExternal())
           Passes.run(*I);

       Passes.doFinalization();

The doInitialization/doFinalization methods handle the global data.

-Chris

This is my current code:

-(void)dumpAssemblerToFile:(NSString*)filename
{
  TargetMachine::CodeGenFileType FileType = TargetMachine::AssemblyFile;
  std::string err1;
  Module *M=(Module*)module;
  const TargetMachineRegistry::Entry* entry=
TargetMachineRegistry::getClosestStaticTargetForModule( *M, err1 );
  TargetMachine &target=*entry->CtorFn( *M, "" );
  [self generateMethodLists];
  std::ostream *outStream = 0;
  PassManager passes;
  outStream = new std::ofstream( [filename fileSystemRepresentation] );
  TargetData *data =new TargetData( *target.getTargetData());
  passes.add(data);
  target.addPassesToEmitFile(passes, *outStream, FileType, false);
  passes.run(*M);
  delete outStream;
}

_______________________________________________
LLVM Developers mailing list
LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-Chris

[troubles with 1.9 changes]

Right, you want to use addPassesToEmitFile if you want the native code
generators to work.

Ahh...thanks for the quick response! Sad that the nice high-level functionality is gone and I now have to do it manually.

The proper incantations can be found in tools/llc/llc.cpp.

OK, I guess I should look more at the tools. Had been looking mostly at the examples, but those only take you so far.

You should do something like this:

       // Build up all of the passes that we want to do to the module.
       FunctionPassManager Passes(new ExistingModuleProvider(M.get()));
       Passes.add(new TargetData(*Target.getTargetData()));

       // Ask the target to add backend passes as necessary.
       if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
         std::cerr << argv[0] << ": target does not support generation of this"
                   << " file type!\n";
         if (Out != &std::cout) delete Out;
         // And the Out file is empty and useless, so remove it now.
         sys::Path(OutputFilename).eraseFromDisk();
         return 1;
       }

       Passes.doInitialization();

       // Run our queue of passes all at once now, efficiently.
       for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
         if (!I->isExternal())
           Passes.run(*I);

       Passes.doFinalization();

The doInitialization/doFinalization methods handle the global data.

Ahh, OK. Thanks again for the help!

Marcel