Avoid creating a redundant zero APInt.
[oota-llvm.git] / tools / lto2 / LTOCodeGenerator.cpp
index 429d6c4f59d4a1bbd27e4f3c23feaf8ef93cf732..5b7a067b4c389cf4400cac14e12f5eedbc8f9781 100644 (file)
@@ -32,6 +32,7 @@
 #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"
@@ -261,8 +262,11 @@ bool LTOCodeGenerator::determineTarget(std::string& errMsg)
                                                        *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;
 }
@@ -302,7 +306,6 @@ void LTOCodeGenerator::applyScopeRestrictions()
     }
 }
 
-
 /// Optimize merged modules using various IPO passes
 bool LTOCodeGenerator::generateAssemblyCode(std::ostream& out, std::string& errMsg)
 {
@@ -340,6 +343,11 @@ bool LTOCodeGenerator::generateAssemblyCode(std::ostream& out, std::string& errM
     // 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());
 
@@ -347,26 +355,17 @@ bool LTOCodeGenerator::generateAssemblyCode(std::ostream& out, std::string& errM
     // 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.
-    if( !llvm::ExceptionHandling ) {
-        // FIXME : This causes multiple nameless _.eh symbols on 
-        // darwin when EH is ON.
-        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.
@@ -374,19 +373,19 @@ bool LTOCodeGenerator::generateAssemblyCode(std::ostream& out, std::string& errM
 
     // The IPO passes may leave cruft around.  Clean up after them.
     passes.add(createInstructionCombiningPass());
-
+    passes.add(createJumpThreadingPass());        // Thread jumps.
     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(createLoadValueNumberingPass()); // GVN for load instrs
-    passes.add(createGCSEPass());               // 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...
     passes.add(createCFGSimplificationPass());
@@ -430,13 +429,13 @@ bool LTOCodeGenerator::generateAssemblyCode(std::ostream& out, std::string& errM
 
     // 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
 }