Thanks!!! On 7 June 2010 19:27, Daniel Dunbar <[email protected]> wrote: > 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 > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
-- Rafael Ávila de Espíndola _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
