#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/LoadValueNumbering.h"
#include "llvm/CodeGen/FileWriters.h"
+#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
*mergedModule, errMsg);
if ( march == NULL )
return true;
- std::string features;
- _target = march->CtorFn(*mergedModule, features);
+
+ // construct LTModule, hand over ownership of module and target
+ std::string FeatureStr =
+ getFeatureString(_linker.getModule()->getTargetTriple().c_str());
+ _target = march->CtorFn(*mergedModule, FeatureStr.c_str());
}
return false;
}
}
}
-
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::generateAssemblyCode(std::ostream& out, std::string& errMsg)
{
// Add an appropriate TargetData instance for this module...
passes.add(new TargetData(*_target->getTargetData()));
+ // Propagate constants at call sites into the functions they call. This
+ // opens opportunities for globalopt (and inlining) by substituting function
+ // pointers passed as arguments to direct uses of functions.
+ passes.add(createIPSCCPPass());
+
// Now that we internalized some globals, see if we can hack on them!
passes.add(createGlobalOptimizerPass());
// keep one copy of each constant...
passes.add(createConstantMergePass());
- // If the -s command line option was specified, strip the symbols out of the
- // resulting program to make it smaller. -s is a GLD option that we are
- // supporting.
- passes.add(createStripSymbolsPass());
-
- // Propagate constants at call sites into the functions they call.
- passes.add(createIPConstantPropagationPass());
-
// Remove unused arguments from functions...
passes.add(createDeadArgEliminationPass());
- passes.add(createFunctionInliningPass()); // Inline small functions
-
- passes.add(createPruneEHPass()); // Remove dead EH info
-
- passes.add(createGlobalDCEPass()); // Remove dead functions
+ // Reduce the code after globalopt and ipsccp. Both can open up significant
+ // simplification opportunities, and both can propagate functions through
+ // function pointers. When this happens, we often have to resolve varargs
+ // calls, etc, so let instcombine do this.
+ passes.add(createInstructionCombiningPass());
+ passes.add(createFunctionInliningPass()); // Inline small functions
+ passes.add(createPruneEHPass()); // Remove dead EH info
+ passes.add(createGlobalDCEPass()); // Remove dead functions
// If we didn't decide to inline a function, check to see if we can
// transform it to pass arguments by value instead of by reference.
passes.add(createScalarReplAggregatesPass()); // Break up allocas
// Run a few AA driven optimizations here and now, to cleanup the code.
- passes.add(createGlobalsModRefPass()); // IP alias analysis
-
- passes.add(createLICMPass()); // Hoist loop invariants
- passes.add(createGVNPass()); // Remove common subexprs
+ passes.add(createGlobalsModRefPass()); // IP alias analysis
+ passes.add(createLICMPass()); // Hoist loop invariants
+ passes.add(createGVNPass()); // Remove common subexprs
+ passes.add(createMemCpyOptPass()); // Remove dead memcpy's
passes.add(createDeadStoreEliminationPass()); // Nuke dead stores
// Cleanup and simplify the code after the scalar optimizations.
passes.add(createInstructionCombiningPass());
-
passes.add(createJumpThreadingPass()); // Thread jumps.
// Delete basic blocks, which optimization passes may have killed...
// Run the code generator, and write assembly file
codeGenPasses->doInitialization();
- for (Module::iterator it = mergedModule->begin(),
- e = mergedModule->end(); it != e; ++it) {
- if (!it->isDeclaration())
- codeGenPasses->run(*it);
- }
- codeGenPasses->doFinalization();
+ for (Module::iterator
+ it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
+ if (!it->isDeclaration())
+ codeGenPasses->run(*it);
+
+ codeGenPasses->doFinalization();
return false; // success
}