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