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