slang_backend.h revision 6315f76e3cc6ff2d012d1183a0b030d4ff0dc808
16315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#ifndef _SLANG_COMPILER_BACKEND_H 26315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#define _SLANG_COMPILER_BACKEND_H 3462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 49ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/PassManager.h" 5462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 69ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Target/TargetData.h" 7462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 89ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Support/StandardPasses.h" 99ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Support/FormattedStream.h" 10462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/ASTConsumer.h" 129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Frontend/CodeGenOptions.h" 139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/SourceManager.h" 14462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "libslang.h" 166315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_pragma_recorder.h" 176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace llvm { 196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class LLVMContext; 206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class NamedMDNode; 216315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class raw_ostream; 226315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class Module; 239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 24462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace clang { 266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class ASTConsumer; 276315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class Diagnostic; 286315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class TargetOptions; 296315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class PragmaList; 306315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class CodeGenerator; 316315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class ASTContext; 326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class DeclGroupRef; 336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class TagDecl; 346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr class VarDecl; 359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace slang { 38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclass Backend : public clang::ASTConsumer { 409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao private: 419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::CodeGenOptions &mCodeGenOpts; 429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::TargetOptions &mTargetOpts; 43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::SourceManager &mSourceMgr; 45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Output stream 479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::raw_ostream *mpOS; 489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SlangCompilerOutputTy mOutputType; 496b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart 509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::TargetData *mpTargetData; 51462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // This helps us translate Clang AST using into LLVM IR 539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::CodeGenerator *mGen; 54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Passes 56462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Passes apply on function scope in a translation unit 589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::FunctionPassManager *mPerFunctionPasses; 599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Passes apply on module scope 606315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr llvm::PassManager *mPerModulePasses; 619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Passes for code emission 629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::FunctionPassManager *mCodeGenPasses; 63462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::formatted_raw_ostream FormattedOutStream; 65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool mAllowRSPrefix; 67cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao 689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao inline void CreateFunctionPasses() { 699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!mPerFunctionPasses) { 709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPerFunctionPasses = new llvm::FunctionPassManager(mpModule); 719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPerFunctionPasses->add(new llvm::TargetData(*mpTargetData)); 72462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::createStandardFunctionPasses(mPerFunctionPasses, 749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mCodeGenOpts.OptimizationLevel); 75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao inline void CreateModulePasses() { 809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!mPerModulePasses) { 819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPerModulePasses = new llvm::PassManager(); 829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPerModulePasses->add(new llvm::TargetData(*mpTargetData)); 839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::createStandardModulePasses(mPerModulePasses, 859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mCodeGenOpts.OptimizationLevel, 869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mCodeGenOpts.OptimizeSize, 879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mCodeGenOpts.UnitAtATime, 889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mCodeGenOpts.UnrollLoops, 899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Some libc functions will be replaced 909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // by the LLVM built-in optimized 919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // function (e.g. strcmp) 929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao /* SimplifyLibCalls */true, 939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao /* HaveExceptions */false, 949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao /* InliningPass */NULL); 95462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // llvm::createStandardFunctionPasses and llvm::createStandardModulePasses 989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // insert lots of optimization passes for the code generator. For the 999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // conventional desktop PC which memory resources and computation power is 1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // relatively large, doing lots optimization as possible is reasonible and 1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // feasible. However, on the mobile device or embedded system, this may 1029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // cause some problem due to the hardware resources limitation. So they need 1039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // to be further refined. 1049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool CreateCodeGenPasses(); 1089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao protected: 1109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::LLVMContext &mLLVMContext; 1119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Diagnostic &mDiags; 1129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::Module *mpModule; 1149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const PragmaList &mPragmas; 1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Extra handler for subclass to handle translation unit before emission 1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao virtual void HandleTranslationUnitEx(clang::ASTContext &Ctx) { return; } 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao public: 1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Backend(clang::Diagnostic &Diags, 1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::CodeGenOptions &CodeGenOpts, 1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::TargetOptions &TargetOpts, 1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const PragmaList &Pragmas, 1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::raw_ostream *OS, 1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SlangCompilerOutputTy OutputType, 1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::SourceManager &SourceMgr, 1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool AllowRSPrefix); 1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Initialize - This is called to initialize the consumer, providing the 1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // ASTContext. 1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao virtual void Initialize(clang::ASTContext &Ctx); 1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // HandleTopLevelDecl - Handle the specified top-level declaration. This is 1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // called by the parser to process every top-level Decl*. Note that D can be 1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // the head of a chain of Decls (e.g. for `int a, b` the chain will have two 1379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // elements). Use Decl::getNextDeclarator() to walk the chain. 1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao virtual void HandleTopLevelDecl(clang::DeclGroupRef D); 1399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // HandleTranslationUnit - This method is called when the ASTs for entire 1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // translation unit have been parsed. 1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao virtual void HandleTranslationUnit(clang::ASTContext &Ctx); 1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // HandleTagDeclDefinition - This callback is invoked each time a TagDecl 1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // (e.g. struct, union, enum, class) is completed. This allows the client to 1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // hack on the type, which can occur at any point in the file (because these 1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // can be defined in declspecs). 1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao virtual void HandleTagDeclDefinition(clang::TagDecl *D); 1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // CompleteTentativeDefinition - Callback invoked at the end of a translation 1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // unit to notify the consumer that the given tentative definition should be 1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // completed. 1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao virtual void CompleteTentativeDefinition(clang::VarDecl *D); 1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao virtual ~Backend(); 156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}; 157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} // namespace slang 159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1606315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#endif // _SLANG_COMPILER_BACKEND_H 161