[cfe-commits] r58034 - in /cfe/trunk: Driver/ASTConsumers.h Driver/Backend.cpp Driver/clang.cpp include/clang/Driver/CompileOptions.h

Daniel Dunbar daniel at zuster.org
Wed Oct 22 22:50:47 PDT 2008


Author: ddunbar
Date: Thu Oct 23 00:50:47 2008
New Revision: 58034

URL: http://llvm.org/viewvc/llvm-project?rev=58034&view=rev
Log:
Add -O[0-3s] support (following llvm-gcc).
 - Passes match llvm-gcc but many of the switches aren't wired.

Added:
    cfe/trunk/include/clang/Driver/CompileOptions.h
Modified:
    cfe/trunk/Driver/ASTConsumers.h
    cfe/trunk/Driver/Backend.cpp
    cfe/trunk/Driver/clang.cpp

Modified: cfe/trunk/Driver/ASTConsumers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.h?rev=58034&r1=58033&r2=58034&view=diff

==============================================================================
--- cfe/trunk/Driver/ASTConsumers.h (original)
+++ cfe/trunk/Driver/ASTConsumers.h Thu Oct 23 00:50:47 2008
@@ -27,9 +27,10 @@
 class ASTConsumer;
 class Diagnostic;
 class FileManager;
-struct LangOptions;
 class Preprocessor;
 class PreprocessorFactory;
+struct CompileOptions;
+struct LangOptions;
 
 ASTConsumer *CreateASTPrinter(llvm::raw_ostream* OS = NULL);
 
@@ -50,6 +51,7 @@
 ASTConsumer *CreateBackendConsumer(BackendAction Action,
                                    Diagnostic &Diags,
                                    const LangOptions &Features,
+                                   const CompileOptions &CompileOpts,
                                    const std::string& InFile,
                                    const std::string& OutFile,
                                    bool GenerateDebugInfo);

Modified: cfe/trunk/Driver/Backend.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/Backend.cpp?rev=58034&r1=58033&r2=58034&view=diff

==============================================================================
--- cfe/trunk/Driver/Backend.cpp (original)
+++ cfe/trunk/Driver/Backend.cpp Thu Oct 23 00:50:47 2008
@@ -14,11 +14,14 @@
 #include "clang/AST/TranslationUnit.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Driver/CompileOptions.h"
 #include "llvm/Module.h"
 #include "llvm/ModuleProvider.h"
 #include "llvm/PassManager.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Analysis/Verifier.h"
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/CodeGen/RegAllocRegistry.h"
 #include "llvm/CodeGen/SchedulerRegistry.h"
@@ -30,6 +33,8 @@
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetMachineRegistry.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/IPO.h"
 #include <fstream> // FIXME: Remove
 
 using namespace clang;
@@ -38,6 +43,7 @@
 namespace {
   class VISIBILITY_HIDDEN BackendConsumer  : public ASTConsumer {
     BackendAction Action;
+    CompileOptions CompileOpts;
     const std::string &InputFile;
     std::string OutputFile;
     llvm::OwningPtr<CodeGenerator> Gen;
@@ -70,10 +76,11 @@
     
   public:  
     BackendConsumer(BackendAction action, Diagnostic &Diags, 
-                    const LangOptions &Features,
+                    const LangOptions &Features, const CompileOptions &compopts,
                     const std::string& infile, const std::string& outfile,
                     bool GenerateDebugInfo)  :
       Action(action), 
+      CompileOpts(compopts),
       InputFile(infile), 
       OutputFile(outfile), 
       Gen(CreateLLVMCodeGen(Diags, Features, InputFile, GenerateDebugInfo)),
@@ -218,7 +225,88 @@
 }
 
 void BackendConsumer::CreatePasses() {
-  
+  // In -O0 if checking is disabled, we don't even have per-function passes.
+  if (CompileOpts.VerifyModule)
+    getPerFunctionPasses()->add(createVerifierPass());
+
+  if (CompileOpts.OptimizationLevel > 0) {
+    FunctionPassManager *PM = getPerFunctionPasses();
+    PM->add(createCFGSimplificationPass());
+    if (CompileOpts.OptimizationLevel == 1)
+      PM->add(createPromoteMemoryToRegisterPass());
+    else
+      PM->add(createScalarReplAggregatesPass());
+    PM->add(createInstructionCombiningPass());
+  }
+
+  // For now we always create per module passes.
+  PassManager *PM = getPerModulePasses();
+  if (CompileOpts.OptimizationLevel > 0) {
+    if (CompileOpts.UnitAtATime)
+      PM->add(createRaiseAllocationsPass());      // call %malloc -> malloc inst
+    PM->add(createCFGSimplificationPass());       // Clean up disgusting code
+    PM->add(createPromoteMemoryToRegisterPass()); // Kill useless allocas
+    if (CompileOpts.UnitAtATime) {
+      PM->add(createGlobalOptimizerPass());       // Optimize out global vars
+      PM->add(createGlobalDCEPass());             // Remove unused fns and globs
+      PM->add(createIPConstantPropagationPass()); // IP Constant Propagation
+      PM->add(createDeadArgEliminationPass());    // Dead argument elimination
+    }
+    PM->add(createInstructionCombiningPass());    // Clean up after IPCP & DAE
+    PM->add(createCFGSimplificationPass());       // Clean up after IPCP & DAE
+    if (CompileOpts.UnitAtATime) {
+      PM->add(createPruneEHPass());               // Remove dead EH info
+      PM->add(createAddReadAttrsPass());          // Set readonly/readnone attrs
+    }
+    if (CompileOpts.InlineFunctions)
+      PM->add(createFunctionInliningPass());      // Inline small functions
+    else 
+      PM->add(createAlwaysInlinerPass());         // Respect always_inline
+    if (CompileOpts.OptimizationLevel > 2)
+      PM->add(createArgumentPromotionPass());     // Scalarize uninlined fn args
+    if (CompileOpts.SimplifyLibCalls)
+      PM->add(createSimplifyLibCallsPass());      // Library Call Optimizations
+    PM->add(createInstructionCombiningPass());    // Cleanup for scalarrepl.
+    PM->add(createJumpThreadingPass());           // Thread jumps.
+    PM->add(createCFGSimplificationPass());       // Merge & remove BBs
+    PM->add(createScalarReplAggregatesPass());    // Break up aggregate allocas
+    PM->add(createInstructionCombiningPass());    // Combine silly seq's
+    PM->add(createCondPropagationPass());         // Propagate conditionals
+    PM->add(createTailCallEliminationPass());     // Eliminate tail calls
+    PM->add(createCFGSimplificationPass());       // Merge & remove BBs
+    PM->add(createReassociatePass());             // Reassociate expressions
+    PM->add(createLoopRotatePass());              // Rotate Loop
+    PM->add(createLICMPass());                    // Hoist loop invariants
+    PM->add(createLoopUnswitchPass(CompileOpts.OptimizeSize ? true : false));
+    PM->add(createLoopIndexSplitPass());          // Split loop index
+    PM->add(createInstructionCombiningPass());  
+    PM->add(createIndVarSimplifyPass());          // Canonicalize indvars
+    PM->add(createLoopDeletionPass());            // Delete dead loops
+    if (CompileOpts.UnrollLoops)
+      PM->add(createLoopUnrollPass());            // Unroll small loops
+    PM->add(createInstructionCombiningPass());    // Clean up after the unroller
+    PM->add(createGVNPass());                     // Remove redundancies
+    PM->add(createMemCpyOptPass());               // Remove memcpy / form memset
+    PM->add(createSCCPPass());                    // Constant prop with SCCP
+    
+    // Run instcombine after redundancy elimination to exploit opportunities
+    // opened up by them.
+    PM->add(createInstructionCombiningPass());
+    PM->add(createCondPropagationPass());         // Propagate conditionals
+    PM->add(createDeadStoreEliminationPass());    // Delete dead stores
+    PM->add(createAggressiveDCEPass());           // Delete dead instructions
+    PM->add(createCFGSimplificationPass());       // Merge & remove BBs
+
+    if (CompileOpts.UnitAtATime) {
+      PM->add(createStripDeadPrototypesPass());   // Get rid of dead prototypes
+      PM->add(createDeadTypeEliminationPass());   // Eliminate dead types
+    }
+
+    if (CompileOpts.OptimizationLevel > 1 && CompileOpts.UnitAtATime)
+      PM->add(createConstantMergePass());         // Merge dup global constants 
+  } else {
+    PerModulePasses->add(createAlwaysInlinerPass());  
+  }
 }
 
 /// EmitAssembly - Handle interaction with LLVM backend to generate
@@ -275,9 +363,10 @@
 ASTConsumer *clang::CreateBackendConsumer(BackendAction Action,
                                           Diagnostic &Diags,
                                           const LangOptions &Features,
+                                          const CompileOptions &CompileOpts,
                                           const std::string& InFile,
                                           const std::string& OutFile,
                                           bool GenerateDebugInfo) {
-  return new BackendConsumer(Action, Diags, Features, InFile, OutFile,
-                             GenerateDebugInfo);  
+  return new BackendConsumer(Action, Diags, Features, CompileOpts,
+                             InFile, OutFile, GenerateDebugInfo);  
 }

Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=58034&r1=58033&r2=58034&view=diff

==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Thu Oct 23 00:50:47 2008
@@ -24,6 +24,7 @@
 
 #include "clang.h"
 #include "ASTConsumers.h"
+#include "clang/Driver/CompileOptions.h"
 #include "clang/Driver/HTMLDiagnostics.h"
 #include "clang/Driver/InitHeaderSearch.h"
 #include "clang/Driver/TextDiagnosticBuffer.h"
@@ -1084,6 +1085,37 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Code generation options
+//===----------------------------------------------------------------------===//
+
+static llvm::cl::opt<bool>
+OptSize("Os", 
+       llvm::cl::desc("Optimize for size"));
+
+// It might be nice to add bounds to the CommandLine library directly.
+struct OptLevelParser : public llvm::cl::parser<unsigned> {
+  bool parse(llvm::cl::Option &O, const char *ArgName,
+             const std::string &Arg, unsigned &Val) {
+    if (llvm::cl::parser<unsigned>::parse(O, ArgName, Arg, Val))
+      return true;
+    // FIXME: Support -O4.
+    if (Val > 3)
+      return O.error(": '" + Arg + "' invalid optimization level!");
+    return false;
+  }
+};
+static llvm::cl::opt<unsigned, false, OptLevelParser>
+OptLevel("O", llvm::cl::Prefix,
+         llvm::cl::desc("Optimization level"),
+         llvm::cl::init(0));
+
+static void InitializeCompileOptions(CompileOptions &Opts) {
+  Opts.OptimizationLevel = OptLevel;
+  Opts.OptimizeSize = OptSize;
+  // FIXME: Wire other options.
+}
+
+//===----------------------------------------------------------------------===//
 // Main driver
 //===----------------------------------------------------------------------===//
 
@@ -1115,14 +1147,21 @@
       return CreateSerializationTest(Diag, FileMgr);
       
     case EmitAssembly:
-      return CreateBackendConsumer(Backend_EmitAssembly, Diag, LangOpts, 
-                                   InFile, OutputFile, GenerateDebugInfo);
     case EmitLLVM:
-      return CreateBackendConsumer(Backend_EmitLL, Diag, LangOpts, 
-                                   InFile, OutputFile, GenerateDebugInfo);
-    case EmitBC:
-      return CreateBackendConsumer(Backend_EmitBC, Diag, LangOpts, 
+    case EmitBC: {
+      BackendAction Act;
+      if (ProgAction == EmitAssembly) {
+        Act = Backend_EmitAssembly;
+      } else if (ProgAction == EmitLLVM) {
+        Act = Backend_EmitLL;
+      } else {
+        Act = Backend_EmitBC;        
+      }
+      CompileOptions Opts;
+      InitializeCompileOptions(Opts);
+      return CreateBackendConsumer(Act, Diag, LangOpts, Opts, 
                                    InFile, OutputFile, GenerateDebugInfo);
+    }
 
     case SerializeAST:
       // FIXME: Allow user to tailor where the file is written.

Added: cfe/trunk/include/clang/Driver/CompileOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CompileOptions.h?rev=58034&view=auto

==============================================================================
--- cfe/trunk/include/clang/Driver/CompileOptions.h (added)
+++ cfe/trunk/include/clang/Driver/CompileOptions.h Thu Oct 23 00:50:47 2008
@@ -0,0 +1,45 @@
+//===--- CompileOptions.h ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CompileOptions interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_COMPILEOPTIONS_H
+#define LLVM_CLANG_COMPILEOPTIONS_H
+
+namespace clang {
+
+/// CompileOptions - Track various options which control how the code
+/// is optimized and passed to the backend.
+struct CompileOptions {
+  unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
+  unsigned OptimizeSize      : 1; /// If -Os is specified.
+  unsigned UnitAtATime       : 1; /// Unused. For mirroring GCC
+                                  /// optimization selection.
+  unsigned InlineFunctions   : 1; /// Should functions be inlined?
+  unsigned SimplifyLibCalls  : 1; /// Should standard library calls be
+                                  /// treated specially.
+  unsigned UnrollLoops       : 1; /// Control whether loops are unrolled.
+  unsigned VerifyModule      : 1; /// Control whether the module
+                                  /// should be run through the LLVM Verifier.
+
+public:
+  CompileOptions() {
+    OptimizationLevel = 0;
+    OptimizeSize = 0;
+    UnitAtATime = InlineFunctions = SimplifyLibCalls = 1;
+    UnrollLoops = 1;
+    VerifyModule = 1;
+  }
+};
+
+}  // end namespace clang
+
+#endif





More information about the cfe-commits mailing list