blob: f57eed60d689446c41c73952bf5292923e45d58c [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 */
15#include "clang/CodeGen/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
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, mCodeGenOpts.OptimizationLevel);
74 }
75 return;
76 }
77
78 inline void CreateModulePasses() {
79 if(!mPerModulePasses) {
80 /* inline passes */
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 /* SimplifyLibCalls */true, /* Some libc functions will be replaced
90 * by the LLVM built-in optimized function (e.g. strcmp)
91 */
92 /* HaveExceptions */false,
93 /* InliningPass */NULL);
94 }
95
96 /*
97 * llvm::createStandardFunctionPasses and llvm::createStandardModulePasses insert lots of optimization passes for
98 * the code generator. For the conventional desktop PC which memory resources and computation power is relative
99 * large, doing lots optimization as possible is reasonible and feasible. However, on the mobile device or embedded
100 * system, this may cause some problem due to the hardware resources limitation. So they need further refine.
101 */
102 return;
103 }
104
105 bool CreateCodeGenPasses();
106
107protected:
108 llvm::Module* mpModule;
109
110 llvm::LLVMContext& mLLVMContext;
111 const PragmaList& mPragmas;
112 Diagnostic &mDiags;
113
114 /* Extra handler for subclass to handle translation unit before emission */
115 virtual void HandleTranslationUnitEx(ASTContext& Ctx) { return; }
116
117public:
118 Backend(Diagnostic &Diags,
119 const CodeGenOptions& CodeGenOpts,
120 const TargetOptions& TargetOpts,
121 const PragmaList& Pragmas,
122 llvm::raw_ostream* OS,
Kirk Stewart6b226742010-06-11 10:51:12 -0700123 SlangCompilerOutputTy OutputType,
124 SourceManager& SourceMgr);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700125
126 /*
127 * Initialize - This is called to initialize the consumer, providing the
128 * ASTContext.
129 */
130 virtual void Initialize(ASTContext &Ctx);
131
132 /*
133 * HandleTopLevelDecl - Handle the specified top-level declaration. This is
134 * called by the parser to process every top-level Decl*. Note that D can be
135 * the head of a chain of Decls (e.g. for `int a, b` the chain will have two
136 * elements). Use Decl::getNextDeclarator() to walk the chain.
137 */
138 virtual void HandleTopLevelDecl(DeclGroupRef D);
139
140 /*
141 * HandleTranslationUnit - This method is called when the ASTs for entire
142 * translation unit have been parsed.
143 */
144 virtual void HandleTranslationUnit(ASTContext& Ctx);
145
146 /*
147 * HandleTagDeclDefinition - This callback is invoked each time a TagDecl
148 * (e.g. struct, union, enum, class) is completed. This allows the client to
149 * hack on the type, which can occur at any point in the file (because these
150 * can be defined in declspecs).
151 */
152 virtual void HandleTagDeclDefinition(TagDecl* D);
153
154 /*
155 * CompleteTentativeDefinition - Callback invoked at the end of a translation
156 * unit to notify the consumer that the given tentative definition should be
157 * completed.
158 */
159 virtual void CompleteTentativeDefinition(VarDecl* D);
160
161 virtual ~Backend();
162};
163
164} /* namespace slang */
165
166#endif /* _SLANG_COMPILER_BACKEND_HPP */