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