+++ /dev/null
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
- *
- * Copyright (c) 2006-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __LLVM_READER_H__
-#define __LLVM_READER_H__
-
-#include <stdlib.h>
-#include <vector>
-#include "MachOFileAbstraction.hpp"
-#include "Architectures.hpp"
-#include "ObjectFile.h"
-#include "llvm/LinkTimeOptimizer.h"
-
-#define LLVMLinkTimeOptimizer "LLVMlto.dylib"
-
-class LLVMReader;
-
-//
-// LLVMReference handles LLVMAtom references. These references facilitate
-// symbol resolution.
-//
-
-class LLVMReference : public ObjectFile::Reference
-{
-public:
- LLVMReference (const char *n) : fName(n), fAtom(0), fFromAtom(0) { }
-
- bool isTargetUnbound() const { return fAtom == 0; }
- bool isFromTargetUnbound() const { return true; }
- uint8_t getKind() const { return 0; }
- uint64_t getFixUpOffset() const { return 0; }
- const char * getTargetName() const { return fName; }
- ObjectFile::Atom& getTarget() const { return *fAtom; }
- uint64_t getTargetOffset() const { return 0; }
- bool hasFromTarget() const { return false; }
- ObjectFile::Atom& getFromTarget() const { return *fFromAtom; }
- const char * getFromTargetName() const { return NULL; }
- uint64_t getFromTargetOffset() const { return 0; }
- TargetBinding getTargetBinding() const;
- TargetBinding getFromTargetBinding() const { return kDontBind; }
- void setTarget (ObjectFile::Atom &a, uint64_t offset)
- { fAtom = &a; }
- void setFromTarget(ObjectFile::Atom &a) { }
- const char * getDescription() const { return NULL; }
-
-private:
- const char * fName;
- ObjectFile::Atom * fAtom;
- ObjectFile::Atom * fFromAtom;
-};
-
-ObjectFile::Reference::TargetBinding LLVMReference::getTargetBinding() const
-{
- if (strncmp (fName, "__ld64.llvm", 11) == 0)
- return kDontBind;
- else return kUnboundByName;
-}
-
-//
-// LLVMAtom acts as a proxy Atom for the symbols that are exported by LLVM bytecode file. Initially,
-// LLVMReader creates LLVMAtoms to allow linker proceed with usual symbol resolution phase. After
-// optimization is performed, real Atoms are created for these symobls. However these real Atoms
-// are not inserted into global symbol table. LLVMAtom holds real Atom and forwards appropriate
-// methods to real atom.
-//
-
-class LLVMAtom : public ObjectFile::Atom
-{
-public:
- ObjectFile::Reader * getFile() const { return fOwner; }
- bool getTranslationUnitSource (const char **dir, const char **name) const
- { return fRealAtom->getTranslationUnitSource (dir, name); }
- const char * getName () const { return fAtomName; }
- const char * getDisplayName() const { return this->getName(); }
- Scope getScope() const { return fScope; }
- DefinitionKind getDefinitionKind() const;
- SymbolTableInclusion getSymbolTableInclusion() const
- { return fRealAtom->getSymbolTableInclusion(); }
- bool dontDeadStrip() const { return false; }
- bool isZeroFill() const { return fRealAtom->isZeroFill(); }
- uint64_t getSize() const { return fRealAtom->getSize(); }
- std::vector<ObjectFile::Reference*>& getReferences() const
- { return (fRealAtom ? fRealAtom->getReferences() : (std::vector<ObjectFile::Reference*>&)fReferences); }
- bool mustRemainInSection() const { return fRealAtom->mustRemainInSection(); }
- const char * getSectionName() const { return (fRealAtom ? fRealAtom->getSectionName() : NULL); }
- // Linker::optimize() sets section for this atom, not fRealAtom. Use this Atom's fSection.
- class ObjectFile::Section * getSection() const { return fSection; }
- ObjectFile::Segment& getSegment() const { return fRealAtom->getSegment(); }
- uint32_t getOrdinal() const { return (fRealAtom ? fRealAtom->getOrdinal() : 0); }
- ObjectFile::Atom& getFollowOnAtom() const { return fRealAtom->getFollowOnAtom(); }
- std::vector<ObjectFile::LineInfo>* getLineInfo() const { return fRealAtom->getLineInfo(); }
- ObjectFile::Alignment getAlignment() const;
- void copyRawContent(uint8_t buffer[]) const
- { fRealAtom->copyRawContent(buffer); }
- void setScope(Scope s) { if (fRealAtom) fRealAtom->setScope(s); }
-
- LLVMAtom(ObjectFile::Reader *owner, const char *n, llvm::LLVMSymbol *ls);
-
- void setRealAtom (ObjectFile::Atom *atom)
- { fRealAtom = atom; }
- void addReference(ObjectFile::Reference *ref)
- { fReferences.push_back(ref); }
-
- void setSectionOffset(uint64_t offset) { fSectionOffset = offset; if (fRealAtom) fRealAtom->setSectionOffset(offset); }
- void setSection(class ObjectFile::Section* sect) { fSection = sect; if (fRealAtom) fRealAtom->setSection(sect); }
-
-private:
- ObjectFile::Reader * fOwner;
- const char * fAtomName;
- llvm::LLVMSymbol * fLLVMSymbol;
- ObjectFile::Atom * fRealAtom;
- std::vector<ObjectFile::Reference*> fReferences;
- ObjectFile::Atom::Scope fScope;
- ObjectFile::Atom::DefinitionKind fDefKind;
-};
-
-ObjectFile::Atom::DefinitionKind LLVMAtom::getDefinitionKind() const
-{
- if (fRealAtom)
- return fRealAtom->getDefinitionKind();
- else
- return fDefKind;
-}
-
-LLVMAtom::LLVMAtom(ObjectFile::Reader *owner, const char *n, llvm::LLVMSymbol *ls) : fOwner(owner), fAtomName(n), fLLVMSymbol(ls), fRealAtom(0)
-{
-
- if (!ls) return;
-
- switch (ls->getLinkage()) {
- case llvm::LTOExternalLinkage:
- fScope = scopeGlobal;
- fDefKind = kRegularDefinition;
- break;
- case llvm::LTOLinkOnceLinkage:
- case llvm::LTOWeakLinkage:
- // ??? How to differentiate between this two linkage types ?
- fScope = scopeGlobal;
- fDefKind = kWeakDefinition;
- break;
- default:
- throw "Unexpected LLVM Symbol Linkage info\n";
- break;
- }
-}
-
-ObjectFile::Alignment LLVMAtom::getAlignment() const
-{
- if (fRealAtom)
- return fRealAtom->getAlignment();
- else {
- ObjectFile::Alignment alignment(fLLVMSymbol->getAlignment());
- return alignment;
- }
-}
-
-//
-// LLVMReader does not expose internal symbols defined and used inside bytecode file. However,
-// these symbols may refere other external symbols. IntercessorAtom facilitate by acting as a
-// orignator of such references during pre-optimization symbol resoultion phase. These atoms
-// are immediately removed after optimization.
-//
-
-class IntercessorAtom : public ObjectFile::Atom
-{
-public:
- ObjectFile::Reader * getFile() const { return fOwner; }
- bool getTranslationUnitSource (const char **dir, const char **name) const
- { return false; }
- const char * getName () const { return fAtomName; }
- const char * getDisplayName() const { return this->getName(); }
- Scope getScope() const { return scopeGlobal; }
- DefinitionKind getDefinitionKind() const { return kRegularDefinition; }
- SymbolTableInclusion getSymbolTableInclusion() const
- { return kSymbolTableNotIn; }
- bool dontDeadStrip() const { return false; }
- bool isZeroFill() const { return false; }
- uint64_t getSize() const { return 0; }
- std::vector<ObjectFile::Reference*>& getReferences() const { return (std::vector<ObjectFile::Reference*>&)fReferences; }
- bool mustRemainInSection() const { return false; }
- const char * getSectionName() const { return NULL; }
- class ObjectFile::Section * getSection() const { return NULL; }
- ObjectFile::Segment& getSegment() const { return this->getSegment(); }
- uint32_t getOrdinal() const { return 0; }
- ObjectFile::Atom& getFollowOnAtom() const { return this->getFollowOnAtom(); }
- std::vector<ObjectFile::LineInfo>* getLineInfo() const { return NULL; }
- ObjectFile::Alignment getAlignment() const { ObjectFile::Alignment a(0); return a; }
- void copyRawContent(uint8_t buffer[]) const
- { }
- void setScope(Scope s) { }
-
-
- IntercessorAtom(ObjectFile::Reader *owner, std::set<std::string> &references);
-
- void addReference(ObjectFile::Reference *ref)
- { fReferences.push_back(ref); }
- void addReferences(std::set<std::string> &references);
-private:
- ObjectFile::Reader * fOwner;
- char * fAtomName;
- std::vector<ObjectFile::Reference*> fReferences;
- ObjectFile::Atom::Scope fScope;
- ObjectFile::Atom::DefinitionKind fDefKind;
-};
-
-IntercessorAtom::IntercessorAtom(ObjectFile::Reader *owner, std::set<std::string> &references)
-{
- static int sCount = 0;
- fOwner = owner;
- fAtomName = (char *) malloc (sizeof(char)*20);
- sprintf (fAtomName,"__ld64.llvm%d__",sCount++);
-
- for (std::set<std::string>::iterator it = references.begin(); it != references.end(); it++) {
- std::string r = *it;
- this->addReference(new LLVMReference(r.c_str()));
- }
-}
-
-void IntercessorAtom::addReferences(std::set<std::string> &references)
-{
- for (std::set<std::string>::iterator it = references.begin(); it != references.end(); it++) {
- std::string r = *it;
- this->addReference(new LLVMReference(r.c_str()));
- }
-}
-
-class InIntercessorSet
-{
-public:
- InIntercessorSet(std::set<ObjectFile::Atom*>& iAtoms) : fIntercessorAtoms(iAtoms) {}
-
- bool operator()(ObjectFile::Atom*& atom) const {
- return ( fIntercessorAtoms.count(atom) != 0 );
- }
-
-private:
- std::set<ObjectFile::Atom*>& fIntercessorAtoms;
-};
-
-//
-// LLVMOptimizer class is responsible for communicating with LLVM LTO library.
-// One LLVMOptimizer object is created per Linker invocation. All LLVMReaders share this
-// one single optimizer object.
-//
-
-class LLVMOptimizer
-{
-public:
- LLVMOptimizer(Options &opt);
- ~LLVMOptimizer() { if (fLLVMHandle) dlclose(fLLVMHandle); }
-
-
- void optimize(std::vector<ObjectFile::Atom *>&, std::vector<ObjectFile::Atom*>&, uint32_t);
- void read(ObjectFile::Reader *, const char *, std::set<std::string>&, std::vector<ObjectFile::Atom*>&, const char *);
- void reconcileOptimizedAtoms(std::vector<class ObjectFile::Atom*>&, std::vector<class ObjectFile::Atom*>&);
- void addIntercessor(IntercessorAtom * atom) { fIntercessorAtoms.insert(atom); }
- void addReader(ObjectFile::Reader *reader) { fLLVMReaders[reader->getPath()] = reader; }
- cpu_type_t getCpuType(std::string &targetTriple);
- bool validArchitecture(const char *path, cpu_type_t architecture);
- class LCStringEquals
- {
- public:
- bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
- };
- typedef hash_map<const char*, LLVMAtom*, hash<const char*>, LCStringEquals> LLVMAtomToNameMapper;
- typedef hash_map<const char*, ObjectFile::Reader*, hash<const char*>, LCStringEquals> ReaderToPathMapper;
-
- typedef llvm::LinkTimeOptimizer * (*createLLVMOptimizer_func_t) ();
-private:
- bool fOptimized;
- llvm::LinkTimeOptimizer *fOptimizer;
- void *fLLVMHandle;
- LLVMAtomToNameMapper fLLVMSymbols;
- Options& fOptions;
- std::set<ObjectFile::Atom*> fIntercessorAtoms;
- ReaderToPathMapper fLLVMReaders;
-};
-
-LLVMOptimizer::LLVMOptimizer(Options &opts) : fOptions(opts)
-{
- fLLVMHandle = (llvm::LinkTimeOptimizer *) dlopen (LLVMLinkTimeOptimizer, RTLD_LAZY);
- if (!fLLVMHandle)
- throwf("Unable to load LLVM library: \n", dlerror());
-
- createLLVMOptimizer_func_t createLLVMOptimizer_fp = (createLLVMOptimizer_func_t)dlsym(fLLVMHandle, "createLLVMOptimizer");
- if (createLLVMOptimizer_fp == NULL)
- throwf("couldn't find \"createLLVMOptimizer\" ", dlerror());
- fOptimizer = createLLVMOptimizer_fp();
- fOptimized = false;
-}
-
-cpu_type_t LLVMOptimizer::getCpuType(std::string &targetTriple)
-{
- if ( strncmp (targetTriple.c_str(), "powerpc-", 8) == 0)
- return CPU_TYPE_POWERPC;
- else if ( strncmp (targetTriple.c_str(), "powerpc64-", 10))
- return CPU_TYPE_POWERPC64;
- // match "i[3-9]86-*".
- else if ( targetTriple.size() >= 5 && targetTriple[0] == 'i' && targetTriple[2] == '8' && targetTriple[3] == '6' && targetTriple[4] == '-' && targetTriple[1] - '3' < 6 )
- return CPU_TYPE_I386;
- else
- return CPU_TYPE_ANY;
-}
-
-bool LLVMOptimizer::validArchitecture(const char *path, cpu_type_t architecture)
-{
- std::string targetTriple;
- fOptimizer->getTargetTriple(path, targetTriple);
- if (architecture != getCpuType(targetTriple)) {
- fOptimizer->removeModule(path);
- return false;
- }
-
- return true;
-}
-
-void LLVMOptimizer::optimize(std::vector<ObjectFile::Atom*> &allAtoms, std::vector<ObjectFile::Atom*> &newAtoms, uint32_t nextInputOrdinal)
-{
- if (fOptimized)
- return;
-
- char * tmp = "/tmp/ld64XXXXXXXX";
- char * bigOfile = (char *) malloc (strlen (tmp) + 3);
- if (!bigOfile)
- throw "Unable to create temp file name";
- strcpy (bigOfile, tmp);
- mktemp (bigOfile);
- strcat (bigOfile, ".o");
-
- std::vector <const char *> exportList;
- for (std::vector<ObjectFile::Atom*>::iterator it = allAtoms.begin(); it != allAtoms.end(); ++it) {
- ObjectFile::Atom *atom = *it;
- if (atom->getName()) {
- ReaderToPathMapper::iterator pos = fLLVMReaders.find(atom->getFile()->getPath());
- if (pos != fLLVMReaders.end())
- exportList.push_back(atom->getName());
- }
-
- }
-
- std::string targetTriple;
- llvm::LTOStatus status = fOptimizer->optimizeModules(bigOfile, exportList, targetTriple, fOptions.saveTempFiles(), fOptions.getOutputFilePath());
- if (status != llvm::LTO_OPT_SUCCESS) {
- if (status == llvm::LTO_WRITE_FAILURE)
- throw "Unable to write optimized output file";
- if (status == llvm::LTO_ASM_FAILURE)
- throw "Unable to assemble optimized output file";
- if (status == llvm::LTO_MODULE_MERGE_FAILURE)
- throw "Unable to merge bytecode files";
- if (status == llvm::LTO_NO_TARGET)
- throw "Unable to load target optimizer";
- }
- fOptimized = true;
-
- Options::FileInfo info = fOptions.findFile (bigOfile);
- ObjectFile::Reader* nr = NULL;
- int fd = ::open(info.path, O_RDONLY, 0);
- if ( fd == -1 )
- throwf("can't open file, errno=%d", errno);
- if ( info.fileLen < 20 )
- throw "file too small";
-
- uint8_t* p = (uint8_t*)::mmap(NULL, info.fileLen, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
- if ( p == (uint8_t*)(-1) )
- throwf("can't map file, errno=%d", errno);
-
- cpu_type_t cpt = getCpuType(targetTriple);
- switch (cpt) {
- case CPU_TYPE_POWERPC:
- if ( mach_o::relocatable::Reader<ppc>::validFile(p) )
- nr = new mach_o::relocatable::Reader<ppc>(p, info.path, info.modTime, fOptions.readerOptions(), nextInputOrdinal);
- break;
- case CPU_TYPE_POWERPC64:
- if ( mach_o::relocatable::Reader<ppc64>::validFile(p) )
- nr = new mach_o::relocatable::Reader<ppc64>(p, info.path, info.modTime, fOptions.readerOptions(), nextInputOrdinal);
- break;
- case CPU_TYPE_I386:
- if ( mach_o::relocatable::Reader<x86>::validFile(p) )
- nr = new mach_o::relocatable::Reader<x86>(p, info.path, info.modTime, fOptions.readerOptions(), nextInputOrdinal);
- break;
- default:
- throw "file is not of required architecture";
- break;
- }
-
- std::vector<class ObjectFile::Atom*> optimizedAtoms;
- optimizedAtoms = nr->getAtoms();
- reconcileOptimizedAtoms(optimizedAtoms, newAtoms);
-
- allAtoms.erase(std::remove_if(allAtoms.begin(), allAtoms.end(), InIntercessorSet(fIntercessorAtoms)), allAtoms.end());
- unlink(bigOfile);
- free(bigOfile);
-}
-
-void LLVMOptimizer::read(ObjectFile::Reader *reader, const char *path, std::set<std::string> &references, std::vector<ObjectFile::Atom*> &atoms, const char *intercessorName)
-{
- llvm::LinkTimeOptimizer::NameToSymbolMap symbols;
- llvm::LTOStatus status = fOptimizer->readLLVMObjectFile (path, symbols, references);
- if (status != llvm::LTO_READ_SUCCESS)
- throw "Unable to read LLVM bytecode file";
-
- for (llvm::LinkTimeOptimizer::NameToSymbolMap::iterator itr = symbols.begin();
- itr != symbols.end(); itr++) {
- const char *name = itr->first;
- llvm::LLVMSymbol *ls = itr->second;
- LLVMAtom *a = new LLVMAtom(reader, name, ls);
-
- LLVMAtomToNameMapper::iterator pos = fLLVMSymbols.find(name);
- bool insertNewAtom = true;
- if (pos != fLLVMSymbols.end()) {
- LLVMAtom *existingAtom = pos->second;
- ObjectFile::Atom::DefinitionKind newDefKind = a->getDefinitionKind();
- ObjectFile::Atom::DefinitionKind existingDefKind = existingAtom->getDefinitionKind();
- if (newDefKind == ObjectFile::Atom::kRegularDefinition
- && existingDefKind == ObjectFile::Atom::kRegularDefinition)
- throwf ("duplicate symbol %s in %s and %s\n", name, a->getFile()->getPath(), existingAtom->getFile()->getPath());
- else if (newDefKind == ObjectFile::Atom::kWeakDefinition
- && existingDefKind == ObjectFile::Atom::kRegularDefinition)
- insertNewAtom = false;
- else if (newDefKind == ObjectFile::Atom::kWeakDefinition
- && existingDefKind == ObjectFile::Atom::kWeakDefinition)
- // pick one
- insertNewAtom = false;
- else if (newDefKind == ObjectFile::Atom::kRegularDefinition
- && existingDefKind == ObjectFile::Atom::kWeakDefinition)
- insertNewAtom = true;
- }
- if (insertNewAtom) {
- atoms.push_back(a);
- fLLVMSymbols[name] = a;
- a->addReference(new LLVMReference (intercessorName));
- }
- }
-}
-
-void LLVMOptimizer::reconcileOptimizedAtoms(std::vector<class ObjectFile::Atom*>& optimizedAtoms,
- std::vector<class ObjectFile::Atom*>& newAtoms)
-{
- for (std::vector<ObjectFile::Atom *>::iterator itr = optimizedAtoms.begin();
- itr != optimizedAtoms.end(); ++itr) {
-
- ObjectFile::Atom* atom = *itr;
- if (!atom->getName()) {
- newAtoms.push_back(atom);
- continue;
- }
-
- LLVMAtomToNameMapper::iterator pos = fLLVMSymbols.find(atom->getName());
- if ( pos != fLLVMSymbols.end() ) {
-
- LLVMAtom *la = fLLVMSymbols[atom->getName()];
- la->setRealAtom(atom);
-
- }
- else
- newAtoms.push_back(atom);
- }
-}
-
-//
-// LLVM bytecode file reader
-//
-
-class LLVMReader : public ObjectFile::Reader
-{
-public:
- static bool validFile(const uint8_t* fileContent, const char *path, cpu_type_t architecture, Options &opts);
- static LLVMReader* make(const uint8_t* fileContent, const char* path, time_t modTime, Options& options)
- { return new LLVMReader(fileContent, path, modTime, options); }
- virtual ~LLVMReader();
- virtual std::vector<class ObjectFile::Atom*>& getAtoms() { return (std::vector<class ObjectFile::Atom*>&)(fAtoms); }
- virtual std::vector<class ObjectFile::Atom*>* getJustInTimeAtomsFor(const char* name) { return NULL; }
- virtual const char* getPath() { return fPath; }
- virtual time_t getModificationTime() { return fModTime; }
- virtual ObjectFile::Reader::DebugInfoKind getDebugInfoKind() { return kDebugInfoNone; }
- virtual std::vector<Stab>* getStabs() { return NULL; }
-
- ObjectFile::Atom * retriveIntercessorAtom() { fAtoms.pop_back();return fIntercessorAtom; }
- ObjectFile::Atom * getIntercessorAtom() { return fIntercessorAtom; }
-
-private:
-
- LLVMReader(const uint8_t* fileContent, const char* path, time_t modTime, Options& options);
- void optimize(std::vector<ObjectFile::Atom*>& allAtoms, std::vector<ObjectFile::Atom*> &newAtoms, uint32_t);
-
- const char* fPath;
- time_t fModTime;
- std::vector<ObjectFile::Atom*> fAtoms;
- IntercessorAtom * fIntercessorAtom;
- static LLVMOptimizer *fOptimizer;
- std::set<std::string> fLLVMReferences;
-};
-
-LLVMOptimizer *LLVMReader::fOptimizer = NULL;
-
-LLVMReader::~LLVMReader()
-{
- if (fOptimizer)
- delete fOptimizer;
-}
-
-LLVMReader::LLVMReader (const uint8_t* fileContent, const char *path, time_t modTime, Options& options)
-{
-
- fPath = path;
- fModTime = modTime;
- fIntercessorAtom = new IntercessorAtom(this, fLLVMReferences);
- fOptimizer->read(this, path, fLLVMReferences, fAtoms, fIntercessorAtom->getName());
- fIntercessorAtom->addReferences(fLLVMReferences);
- fAtoms.push_back(fIntercessorAtom);
- fOptimizer->addIntercessor(fIntercessorAtom);
- fOptimizer->addReader(this);
-}
-
-bool LLVMReader::validFile(const uint8_t* fileContent, const char *path, cpu_type_t architecture, Options &opts)
-{
- if (fileContent[0] == 'l'
- && fileContent[1] == 'l'
- && fileContent[2] == 'v'
- && (fileContent[3] == 'c' || fileContent[3] == 'm')) {
-
- // create optimizer
- if (!fOptimizer)
- fOptimizer = new LLVMOptimizer(opts);
-
- if (fOptimizer->validArchitecture(path, architecture))
- return true;
- }
-
- return false;
-}
-
-void LLVMReader::optimize(std::vector<ObjectFile::Atom *> &allAtoms, std::vector<ObjectFile::Atom*> &newAtoms, uint32_t nextInputOrdinal)
-{
- if (fOptimizer)
- fOptimizer->optimize(allAtoms, newAtoms, nextInputOrdinal);
-}
-
-#endif
-