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