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