slang_backend.h revision 6315f76e3cc6ff2d012d1183a0b030d4ff0dc808
1#ifndef _SLANG_COMPILER_BACKEND_H 2#define _SLANG_COMPILER_BACKEND_H 3 4#include "llvm/PassManager.h" 5 6#include "llvm/Target/TargetData.h" 7 8#include "llvm/Support/StandardPasses.h" 9#include "llvm/Support/FormattedStream.h" 10 11#include "clang/AST/ASTConsumer.h" 12#include "clang/Frontend/CodeGenOptions.h" 13#include "clang/Basic/SourceManager.h" 14 15#include "libslang.h" 16#include "slang_pragma_recorder.h" 17 18namespace llvm { 19 class LLVMContext; 20 class NamedMDNode; 21 class raw_ostream; 22 class Module; 23} 24 25namespace clang { 26 class ASTConsumer; 27 class Diagnostic; 28 class TargetOptions; 29 class PragmaList; 30 class CodeGenerator; 31 class ASTContext; 32 class DeclGroupRef; 33 class TagDecl; 34 class VarDecl; 35} 36 37namespace slang { 38 39class Backend : public clang::ASTConsumer { 40 private: 41 const clang::CodeGenOptions &mCodeGenOpts; 42 const clang::TargetOptions &mTargetOpts; 43 44 clang::SourceManager &mSourceMgr; 45 46 // Output stream 47 llvm::raw_ostream *mpOS; 48 SlangCompilerOutputTy mOutputType; 49 50 llvm::TargetData *mpTargetData; 51 52 // This helps us translate Clang AST using into LLVM IR 53 clang::CodeGenerator *mGen; 54 55 // Passes 56 57 // Passes apply on function scope in a translation unit 58 llvm::FunctionPassManager *mPerFunctionPasses; 59 // Passes apply on module scope 60 llvm::PassManager *mPerModulePasses; 61 // Passes for code emission 62 llvm::FunctionPassManager *mCodeGenPasses; 63 64 llvm::formatted_raw_ostream FormattedOutStream; 65 66 bool mAllowRSPrefix; 67 68 inline void CreateFunctionPasses() { 69 if (!mPerFunctionPasses) { 70 mPerFunctionPasses = new llvm::FunctionPassManager(mpModule); 71 mPerFunctionPasses->add(new llvm::TargetData(*mpTargetData)); 72 73 llvm::createStandardFunctionPasses(mPerFunctionPasses, 74 mCodeGenOpts.OptimizationLevel); 75 } 76 return; 77 } 78 79 inline void CreateModulePasses() { 80 if (!mPerModulePasses) { 81 mPerModulePasses = new llvm::PassManager(); 82 mPerModulePasses->add(new llvm::TargetData(*mpTargetData)); 83 84 llvm::createStandardModulePasses(mPerModulePasses, 85 mCodeGenOpts.OptimizationLevel, 86 mCodeGenOpts.OptimizeSize, 87 mCodeGenOpts.UnitAtATime, 88 mCodeGenOpts.UnrollLoops, 89 // Some libc functions will be replaced 90 // by the LLVM built-in optimized 91 // function (e.g. strcmp) 92 /* SimplifyLibCalls */true, 93 /* HaveExceptions */false, 94 /* InliningPass */NULL); 95 } 96 97 // llvm::createStandardFunctionPasses and llvm::createStandardModulePasses 98 // insert lots of optimization passes for the code generator. For the 99 // conventional desktop PC which memory resources and computation power is 100 // relatively large, doing lots optimization as possible is reasonible and 101 // feasible. However, on the mobile device or embedded system, this may 102 // cause some problem due to the hardware resources limitation. So they need 103 // to be further refined. 104 return; 105 } 106 107 bool CreateCodeGenPasses(); 108 109 protected: 110 llvm::LLVMContext &mLLVMContext; 111 clang::Diagnostic &mDiags; 112 113 llvm::Module *mpModule; 114 115 const PragmaList &mPragmas; 116 117 // Extra handler for subclass to handle translation unit before emission 118 virtual void HandleTranslationUnitEx(clang::ASTContext &Ctx) { return; } 119 120 public: 121 Backend(clang::Diagnostic &Diags, 122 const clang::CodeGenOptions &CodeGenOpts, 123 const clang::TargetOptions &TargetOpts, 124 const PragmaList &Pragmas, 125 llvm::raw_ostream *OS, 126 SlangCompilerOutputTy OutputType, 127 clang::SourceManager &SourceMgr, 128 bool AllowRSPrefix); 129 130 // Initialize - This is called to initialize the consumer, providing the 131 // ASTContext. 132 virtual void Initialize(clang::ASTContext &Ctx); 133 134 // HandleTopLevelDecl - Handle the specified top-level declaration. This is 135 // called by the parser to process every top-level Decl*. Note that D can be 136 // the head of a chain of Decls (e.g. for `int a, b` the chain will have two 137 // elements). Use Decl::getNextDeclarator() to walk the chain. 138 virtual void HandleTopLevelDecl(clang::DeclGroupRef D); 139 140 // HandleTranslationUnit - This method is called when the ASTs for entire 141 // translation unit have been parsed. 142 virtual void HandleTranslationUnit(clang::ASTContext &Ctx); 143 144 // HandleTagDeclDefinition - This callback is invoked each time a TagDecl 145 // (e.g. struct, union, enum, class) is completed. This allows the client to 146 // hack on the type, which can occur at any point in the file (because these 147 // can be defined in declspecs). 148 virtual void HandleTagDeclDefinition(clang::TagDecl *D); 149 150 // CompleteTentativeDefinition - Callback invoked at the end of a translation 151 // unit to notify the consumer that the given tentative definition should be 152 // completed. 153 virtual void CompleteTentativeDefinition(clang::VarDecl *D); 154 155 virtual ~Backend(); 156}; 157 158} // namespace slang 159 160#endif // _SLANG_COMPILER_BACKEND_H 161