slang_backend.h revision 6315f76e3cc6ff2d012d1183a0b030d4ff0dc808
1#ifndef _SLANG_COMPILER_BACKEND_H
2#define _SLANG_COMPILER_BACKEND_H
3
4#include "llvm/PassManager.h"
5
6#include "llvm/Target/TargetData.h"
7
8#include "llvm/Support/StandardPasses.h"
9#include "llvm/Support/FormattedStream.h"
10
11#include "clang/AST/ASTConsumer.h"
12#include "clang/Frontend/CodeGenOptions.h"
13#include "clang/Basic/SourceManager.h"
14
15#include "libslang.h"
16#include "slang_pragma_recorder.h"
17
18namespace llvm {
19  class LLVMContext;
20  class NamedMDNode;
21  class raw_ostream;
22  class Module;
23}
24
25namespace clang {
26  class ASTConsumer;
27  class Diagnostic;
28  class TargetOptions;
29  class PragmaList;
30  class CodeGenerator;
31  class ASTContext;
32  class DeclGroupRef;
33  class TagDecl;
34  class VarDecl;
35}
36
37namespace slang {
38
39class Backend : public clang::ASTConsumer {
40 private:
41  const clang::CodeGenOptions &mCodeGenOpts;
42  const clang::TargetOptions &mTargetOpts;
43
44  clang::SourceManager &mSourceMgr;
45
46  // Output stream
47  llvm::raw_ostream *mpOS;
48  SlangCompilerOutputTy mOutputType;
49
50  llvm::TargetData *mpTargetData;
51
52  // This helps us translate Clang AST using into LLVM IR
53  clang::CodeGenerator *mGen;
54
55  // Passes
56
57  // Passes apply on function scope in a translation unit
58  llvm::FunctionPassManager *mPerFunctionPasses;
59  // Passes apply on module scope
60  llvm::PassManager *mPerModulePasses;
61  // Passes for code emission
62  llvm::FunctionPassManager *mCodeGenPasses;
63
64  llvm::formatted_raw_ostream FormattedOutStream;
65
66  bool mAllowRSPrefix;
67
68  inline void CreateFunctionPasses() {
69    if (!mPerFunctionPasses) {
70      mPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
71      mPerFunctionPasses->add(new llvm::TargetData(*mpTargetData));
72
73      llvm::createStandardFunctionPasses(mPerFunctionPasses,
74                                         mCodeGenOpts.OptimizationLevel);
75    }
76    return;
77  }
78
79  inline void CreateModulePasses() {
80    if (!mPerModulePasses) {
81      mPerModulePasses = new llvm::PassManager();
82      mPerModulePasses->add(new llvm::TargetData(*mpTargetData));
83
84      llvm::createStandardModulePasses(mPerModulePasses,
85                                       mCodeGenOpts.OptimizationLevel,
86                                       mCodeGenOpts.OptimizeSize,
87                                       mCodeGenOpts.UnitAtATime,
88                                       mCodeGenOpts.UnrollLoops,
89                                       // Some libc functions will be replaced
90                                       // by the LLVM built-in optimized
91                                       // function (e.g. strcmp)
92                                       /* SimplifyLibCalls */true,
93                                       /* HaveExceptions */false,
94                                       /* InliningPass */NULL);
95    }
96
97    // llvm::createStandardFunctionPasses and llvm::createStandardModulePasses
98    // insert lots of optimization passes for the code generator. For the
99    // conventional desktop PC which memory resources and computation power is
100    // relatively large, doing lots optimization as possible is reasonible and
101    // feasible. However, on the mobile device or embedded system, this may
102    // cause some problem due to the hardware resources limitation. So they need
103    // to be further refined.
104    return;
105  }
106
107  bool CreateCodeGenPasses();
108
109 protected:
110  llvm::LLVMContext &mLLVMContext;
111  clang::Diagnostic &mDiags;
112
113  llvm::Module *mpModule;
114
115  const PragmaList &mPragmas;
116
117  // Extra handler for subclass to handle translation unit before emission
118  virtual void HandleTranslationUnitEx(clang::ASTContext &Ctx) { return; }
119
120 public:
121  Backend(clang::Diagnostic &Diags,
122          const clang::CodeGenOptions &CodeGenOpts,
123          const clang::TargetOptions &TargetOpts,
124          const PragmaList &Pragmas,
125          llvm::raw_ostream *OS,
126          SlangCompilerOutputTy OutputType,
127          clang::SourceManager &SourceMgr,
128          bool AllowRSPrefix);
129
130  // Initialize - This is called to initialize the consumer, providing the
131  // ASTContext.
132  virtual void Initialize(clang::ASTContext &Ctx);
133
134  // HandleTopLevelDecl - Handle the specified top-level declaration.  This is
135  // called by the parser to process every top-level Decl*. Note that D can be
136  // the head of a chain of Decls (e.g. for `int a, b` the chain will have two
137  // elements). Use Decl::getNextDeclarator() to walk the chain.
138  virtual void HandleTopLevelDecl(clang::DeclGroupRef D);
139
140  // HandleTranslationUnit - This method is called when the ASTs for entire
141  // translation unit have been parsed.
142  virtual void HandleTranslationUnit(clang::ASTContext &Ctx);
143
144  // HandleTagDeclDefinition - This callback is invoked each time a TagDecl
145  // (e.g. struct, union, enum, class) is completed.  This allows the client to
146  // hack on the type, which can occur at any point in the file (because these
147  // can be defined in declspecs).
148  virtual void HandleTagDeclDefinition(clang::TagDecl *D);
149
150  // CompleteTentativeDefinition - Callback invoked at the end of a translation
151  // unit to notify the consumer that the given tentative definition should be
152  // completed.
153  virtual void CompleteTentativeDefinition(clang::VarDecl *D);
154
155  virtual ~Backend();
156};
157
158}   // namespace slang
159
160#endif  // _SLANG_COMPILER_BACKEND_H
161