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; }
On Sun, 21 Jan 2007, Marcel Weiher wrote:> 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 at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-Chris -- http://nondot.org/sabre/ http://llvm.org/
On Jan 21, 2007, at 20:41 , Chris Lattner wrote:> On Sun, 21 Jan 2007, Marcel Weiher wrote: >> [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