[cfe-commits] r105583 - in /cfe/trunk: include/clang/Frontend/CodeGenAction.h include/clang/Frontend/FrontendAction.h lib/Frontend/CodeGenAction.cpp test/Frontend/ir-support-codegen.ll test/Frontend/ir-support-errors.ll tools/driver/CMakeLists.txt tools/driver/Makefile

Daniel Dunbar daniel at zuster.org
Mon Jun 7 16:27:59 PDT 2010


Author: ddunbar
Date: Mon Jun  7 18:27:59 2010
New Revision: 105583

URL: http://llvm.org/viewvc/llvm-project?rev=105583&view=rev
Log:
Frontend: Add CodeGenAction support for handling LLVM IR.
 - This magically enables using 'clang -cc1' as a replacement for most of 'llvm-as', 'llvm-dis', 'llc' and 'opt' functionality.

For example, 'llvm-as' is:
  $ clang -cc1 -emit-llvm-bc FOO.ll -o FOO.bc
and 'llvm-dis' is:
  $ clang -cc1 -emit-llvm    FOO.bc -o -
and 'opt' is, e.g.:
  $ clang -cc1 -emit-llvm -O3 -o FOO.opt.ll FOO.ll
and 'llc' is, e.g.:
  $ clang -cc1 -S -o - FOO.ll

The nice thing about using the backend tools this way is that they are guaranteed to exactly match how the compiler generates code (for example, setting the same backend options).

Added:
    cfe/trunk/test/Frontend/ir-support-codegen.ll
    cfe/trunk/test/Frontend/ir-support-errors.ll
Modified:
    cfe/trunk/include/clang/Frontend/CodeGenAction.h
    cfe/trunk/include/clang/Frontend/FrontendAction.h
    cfe/trunk/lib/Frontend/CodeGenAction.cpp
    cfe/trunk/tools/driver/CMakeLists.txt
    cfe/trunk/tools/driver/Makefile

Modified: cfe/trunk/include/clang/Frontend/CodeGenAction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenAction.h?rev=105583&r1=105582&r2=105583&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CodeGenAction.h (original)
+++ cfe/trunk/include/clang/Frontend/CodeGenAction.h Mon Jun  7 18:27:59 2010
@@ -24,9 +24,13 @@
 protected:
   CodeGenAction(unsigned _Act);
 
+  virtual bool hasIRSupport() const;
+
   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
                                          llvm::StringRef InFile);
 
+  virtual void ExecuteAction();
+
   virtual void EndSourceFileAction();
 
 public:

Modified: cfe/trunk/include/clang/Frontend/FrontendAction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendAction.h?rev=105583&r1=105582&r2=105583&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendAction.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendAction.h Mon Jun  7 18:27:59 2010
@@ -202,6 +202,7 @@
 /// ASTFrontendAction - Abstract base class to use for AST consumer based
 /// frontend actions.
 class ASTFrontendAction : public FrontendAction {
+protected:
   /// ExecuteAction - Implement the ExecuteAction interface by running Sema on
   /// the already initialized AST consumer.
   ///

Modified: cfe/trunk/lib/Frontend/CodeGenAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CodeGenAction.cpp?rev=105583&r1=105582&r2=105583&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CodeGenAction.cpp (original)
+++ cfe/trunk/lib/Frontend/CodeGenAction.cpp Mon Jun  7 18:27:59 2010
@@ -22,6 +22,7 @@
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/IRReader.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/Timer.h"
@@ -220,6 +221,8 @@
 
 CodeGenAction::~CodeGenAction() {}
 
+bool CodeGenAction::hasIRSupport() const { return true; }
+
 void CodeGenAction::EndSourceFileAction() {
   // If the consumer creation failed, do nothing.
   if (!getCompilerInstance().hasASTConsumer())
@@ -236,27 +239,31 @@
   return TheModule.take();
 }
 
-ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI,
-                                              llvm::StringRef InFile) {
-  BackendAction BA = static_cast<BackendAction>(Act);
-  llvm::OwningPtr<llvm::raw_ostream> OS;
-  switch (BA) {
+static raw_ostream *GetOutputStream(CompilerInstance &CI,
+                                    llvm::StringRef InFile,
+                                    BackendAction Action) {
+  switch (Action) {
   case Backend_EmitAssembly:
-    OS.reset(CI.createDefaultOutputFile(false, InFile, "s"));
-    break;
+    return CI.createDefaultOutputFile(false, InFile, "s");
   case Backend_EmitLL:
-    OS.reset(CI.createDefaultOutputFile(false, InFile, "ll"));
-    break;
+    return CI.createDefaultOutputFile(false, InFile, "ll");
   case Backend_EmitBC:
-    OS.reset(CI.createDefaultOutputFile(true, InFile, "bc"));
-    break;
+    return CI.createDefaultOutputFile(true, InFile, "bc");
   case Backend_EmitNothing:
-    break;
+    return 0;
   case Backend_EmitMCNull:
   case Backend_EmitObj:
-    OS.reset(CI.createDefaultOutputFile(true, InFile, "o"));
-    break;
+    return CI.createDefaultOutputFile(true, InFile, "o");
   }
+
+  assert(0 && "Invalid action!");
+  return 0;
+}
+
+ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI,
+                                              llvm::StringRef InFile) {
+  BackendAction BA = static_cast<BackendAction>(Act);
+  llvm::OwningPtr<llvm::raw_ostream> OS(GetOutputStream(CI, InFile, BA));
   if (BA != Backend_EmitNothing && !OS)
     return 0;
 
@@ -266,6 +273,59 @@
                              CI.getLLVMContext());
 }
 
+void CodeGenAction::ExecuteAction() {
+  // If this is an IR file, we have to treat it specially.
+  if (getCurrentFileKind() == IK_LLVM_IR) {
+    BackendAction BA = static_cast<BackendAction>(Act);
+    CompilerInstance &CI = getCompilerInstance();
+    raw_ostream *OS = GetOutputStream(CI, getCurrentFile(), BA);
+    if (BA != Backend_EmitNothing && !OS)
+      return;
+
+    bool Invalid;
+    SourceManager &SM = CI.getSourceManager();
+    const llvm::MemoryBuffer *MainFile = SM.getBuffer(SM.getMainFileID(),
+                                                      &Invalid);
+    if (Invalid)
+      return;
+
+    // FIXME: This is stupid, IRReader shouldn't take ownership.
+    llvm::MemoryBuffer *MainFileCopy =
+      llvm::MemoryBuffer::getMemBufferCopy(MainFile->getBuffer(),
+                                           getCurrentFile().c_str());
+
+    llvm::SMDiagnostic Err;
+    TheModule.reset(ParseIR(MainFileCopy, Err, CI.getLLVMContext()));
+    if (!TheModule) {
+      // Translate from the diagnostic info to the SourceManager location.
+      SourceLocation Loc = SM.getLocation(
+        SM.getFileEntryForID(SM.getMainFileID()), Err.getLineNo(),
+        Err.getColumnNo() + 1);
+
+      // Get a custom diagnostic for the error. We strip off a leading
+      // diagnostic code if there is one.
+      llvm::StringRef Msg = Err.getMessage();
+      if (Msg.startswith("error: "))
+        Msg = Msg.substr(7);
+      unsigned DiagID = CI.getDiagnostics().getCustomDiagID(Diagnostic::Error,
+                                                            Msg);
+
+      CI.getDiagnostics().Report(FullSourceLoc(Loc, SM), DiagID);
+      return;
+    }
+
+    EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(),
+                      CI.getTargetOpts(), TheModule.get(),
+                      BA, OS);
+    return;
+  }
+
+  // Otherwise follow the normal AST path.
+  this->ASTFrontendAction::ExecuteAction();
+}
+
+//
+
 EmitAssemblyAction::EmitAssemblyAction()
   : CodeGenAction(Backend_EmitAssembly) {}
 

Added: cfe/trunk/test/Frontend/ir-support-codegen.ll
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/ir-support-codegen.ll?rev=105583&view=auto
==============================================================================
--- cfe/trunk/test/Frontend/ir-support-codegen.ll (added)
+++ cfe/trunk/test/Frontend/ir-support-codegen.ll Mon Jun  7 18:27:59 2010
@@ -0,0 +1,8 @@
+; RUN: %clang_cc1 -S -o - %s | FileCheck %s
+
+target triple = "x86_64-apple-darwin10"
+
+; CHECK: .globl _f0
+define i32 @f0() nounwind ssp {
+       ret i32 0
+}

Added: cfe/trunk/test/Frontend/ir-support-errors.ll
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/ir-support-errors.ll?rev=105583&view=auto
==============================================================================
--- cfe/trunk/test/Frontend/ir-support-errors.ll (added)
+++ cfe/trunk/test/Frontend/ir-support-errors.ll Mon Jun  7 18:27:59 2010
@@ -0,0 +1,8 @@
+; RUN: %clang_cc1 -S -o - %s 2>&1 | FileCheck %s
+
+target triple = "x86_64-apple-darwin10"
+
+define i32 @f0() nounwind ssp {
+; CHECK: {{.*}}ir-support-errors.ll:7:16: error: expected value token
+       ret i32 x
+}

Modified: cfe/trunk/tools/driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/CMakeLists.txt?rev=105583&r1=105582&r2=105583&view=diff
==============================================================================
--- cfe/trunk/tools/driver/CMakeLists.txt (original)
+++ cfe/trunk/tools/driver/CMakeLists.txt Mon Jun  7 18:27:59 2010
@@ -16,6 +16,7 @@
 
 set( LLVM_LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
+  asmparser
   bitreader
   bitwriter
   codegen

Modified: cfe/trunk/tools/driver/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/Makefile?rev=105583&r1=105582&r2=105583&view=diff
==============================================================================
--- cfe/trunk/tools/driver/Makefile (original)
+++ cfe/trunk/tools/driver/Makefile Mon Jun  7 18:27:59 2010
@@ -26,7 +26,8 @@
 # LINK_COMPONENTS before including Makefile.rules
 include $(LEVEL)/Makefile.config
 
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) bitreader bitwriter codegen ipo selectiondag
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \
+                   ipo selectiondag
 USEDLIBS = clangFrontend.a clangDriver.a clangCodeGen.a clangSema.a \
            clangChecker.a clangAnalysis.a clangRewrite.a  clangAST.a \
            clangParse.a clangLex.a clangBasic.a





More information about the cfe-commits mailing list