slang_backend.h revision 6b22674f4ef0a6c689c589830f1c44f443520785
1462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#ifndef _SLANG_COMPILER_BACKEND_HPP 2462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao# define _SLANG_COMPILER_BACKEND_HPP 3462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "libslang.h" 5462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_pragma_recorder.hpp" 6462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/PassManager.h" /* for class llvm::PassManager and llvm::FunctionPassManager */ 8462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Target/TargetData.h" /* for class llvm::TargetData */ 10462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Support/StandardPasses.h" /* for function llvm::createStandardFunctionPasses() and llvm::createStandardModulePasses() */ 12462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Support/FormattedStream.h" /* for class llvm::formatted_raw_ostream */ 13462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/AST/ASTConsumer.h" /* for class clang::ASTConsumer */ 15462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/CodeGen/CodeGenOptions.h" /* for class clang::CodeGenOptions */ 166b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart#include "clang/Basic/SourceManager.h" /* for class clang::SourceManager */ 17462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace llvm { 19462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 20462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass LLVMContext; 21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass NamedMDNode; 22462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass raw_ostream; 23462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass Module; 24462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} /* namespace llvm */ 26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace clang { 28462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass ASTConsumer; 30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass Diagnostic; 31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass TargetOptions; 32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass PragmaList; 33462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass CodeGenerator; 34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass ASTContext; 35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass DeclGroupRef; 36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass TagDecl; 37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass VarDecl; 38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} /* namespace clang */ 40462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace slang { 42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaousing namespace clang; 44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass Backend : public ASTConsumer { 46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoprivate: 47462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const CodeGenOptions& mCodeGenOpts; 48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const TargetOptions& mTargetOpts; 49462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 506b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart SourceManager& mSourceMgr; 516b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart 52462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Output stream */ 53462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::raw_ostream* mpOS; 54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao SlangCompilerOutputTy mOutputType; 55462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 56462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::TargetData* mpTargetData; 57462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 58462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* The @Gen here help us to translate AST using in Clang to LLVM IR */ 59462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao CodeGenerator* mGen; 60462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 61462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Passes */ 62462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::FunctionPassManager* mPerFunctionPasses; /* passes apply on function scope in a translation unit */ 63462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::PassManager* mPerModulePasses; /* passes apply on module scope */ 64462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::FunctionPassManager* mCodeGenPasses; /* passes for code emission */ 65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 66462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::formatted_raw_ostream FormattedOutStream; 67462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 68462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao inline void CreateFunctionPasses() { 69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!mPerFunctionPasses) { 70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerFunctionPasses = new llvm::FunctionPassManager(mpModule); 71462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerFunctionPasses->add(new llvm::TargetData(*mpTargetData)); 72462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::createStandardFunctionPasses(mPerFunctionPasses, mCodeGenOpts.OptimizationLevel); 74462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 76462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 78462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao inline void CreateModulePasses() { 79462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!mPerModulePasses) { 80462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* inline passes */ 81462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerModulePasses = new llvm::PassManager(); 82462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerModulePasses->add(new llvm::TargetData(*mpTargetData)); 83462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 84462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::createStandardModulePasses(mPerModulePasses, 85462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenOpts.OptimizationLevel, 86462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenOpts.OptimizeSize, 87462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenOpts.UnitAtATime, 88462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenOpts.UnrollLoops, 89462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* SimplifyLibCalls */true, /* Some libc functions will be replaced 90462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * by the LLVM built-in optimized function (e.g. strcmp) 91462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 92462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* HaveExceptions */false, 93462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* InliningPass */NULL); 94462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 95462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* 97462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * llvm::createStandardFunctionPasses and llvm::createStandardModulePasses insert lots of optimization passes for 98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * the code generator. For the conventional desktop PC which memory resources and computation power is relative 99462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * large, doing lots optimization as possible is reasonible and feasible. However, on the mobile device or embedded 100462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * system, this may cause some problem due to the hardware resources limitation. So they need further refine. 101462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 105462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao bool CreateCodeGenPasses(); 106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 107462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoprotected: 108462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::Module* mpModule; 109462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 110462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::LLVMContext& mLLVMContext; 111462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const PragmaList& mPragmas; 112462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Diagnostic &mDiags; 113462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 114462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Extra handler for subclass to handle translation unit before emission */ 115462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao virtual void HandleTranslationUnitEx(ASTContext& Ctx) { return; } 116462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 117462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaopublic: 118462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Backend(Diagnostic &Diags, 119462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const CodeGenOptions& CodeGenOpts, 120462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const TargetOptions& TargetOpts, 121462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const PragmaList& Pragmas, 122462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::raw_ostream* OS, 1236b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart SlangCompilerOutputTy OutputType, 1246b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart SourceManager& SourceMgr); 125462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* 127462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * Initialize - This is called to initialize the consumer, providing the 128462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * ASTContext. 129462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 130462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao virtual void Initialize(ASTContext &Ctx); 131462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 132462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* 133462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * HandleTopLevelDecl - Handle the specified top-level declaration. This is 134462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * called by the parser to process every top-level Decl*. Note that D can be 135462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * the head of a chain of Decls (e.g. for `int a, b` the chain will have two 136462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * elements). Use Decl::getNextDeclarator() to walk the chain. 137462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 138462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao virtual void HandleTopLevelDecl(DeclGroupRef D); 139462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 140462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* 141462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * HandleTranslationUnit - This method is called when the ASTs for entire 142462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * translation unit have been parsed. 143462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 144462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao virtual void HandleTranslationUnit(ASTContext& Ctx); 145462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 146462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* 147462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * HandleTagDeclDefinition - This callback is invoked each time a TagDecl 148462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * (e.g. struct, union, enum, class) is completed. This allows the client to 149462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * hack on the type, which can occur at any point in the file (because these 150462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * can be defined in declspecs). 151462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 152462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao virtual void HandleTagDeclDefinition(TagDecl* D); 153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* 155462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * CompleteTentativeDefinition - Callback invoked at the end of a translation 156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * unit to notify the consumer that the given tentative definition should be 157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * completed. 158462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao virtual void CompleteTentativeDefinition(VarDecl* D); 160462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 161462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao virtual ~Backend(); 162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}; 163462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} /* namespace slang */ 165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#endif /* _SLANG_COMPILER_BACKEND_HPP */ 167