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