1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 #if !defined(BOOST_SPIRIT_CONJURE_COMPILER_HPP)
8 #define BOOST_SPIRIT_CONJURE_COMPILER_HPP
9 
10 #include "ast.hpp"
11 #include "error_handler.hpp"
12 #include "vm.hpp"
13 #include <map>
14 
15 #include <boost/function.hpp>
16 #include <boost/shared_ptr.hpp>
17 #include <boost/spirit/include/phoenix_core.hpp>
18 #include <boost/spirit/include/phoenix_function.hpp>
19 #include <boost/spirit/include/phoenix_operator.hpp>
20 #include <boost/iterator/transform_iterator.hpp>
21 
22 #include <llvm/DerivedTypes.h>
23 #include <llvm/Constants.h>
24 #include <llvm/LLVMContext.h>
25 #include <llvm/Module.h>
26 #include <llvm/PassManager.h>
27 #include <llvm/Analysis/Verifier.h>
28 #include <llvm/Analysis/Passes.h>
29 #include <llvm/Transforms/Scalar.h>
30 #include <llvm/Support/IRBuilder.h>
31 
32 namespace client { namespace code_gen
33 {
34     unsigned const int_size = 32;
35     struct compiler;
36     struct llvm_compiler;
37 
38     ///////////////////////////////////////////////////////////////////////////
39     //  The Value (light abstraction of an LLVM::Value)
40     ///////////////////////////////////////////////////////////////////////////
41     struct value
42     {
43         value();
44         value(value const& rhs);
45 
46         value& operator=(value const& rhs);
47         bool is_lvalue() const;
48         bool is_valid() const;
49         operator bool() const;
50 
51         value& assign(value const& rhs);
52 
53         void name(char const* id);
54         void name(std::string const& id);
55 
56         friend value operator-(value a);
57         friend value operator!(value a);
58         friend value operator+(value a, value b);
59         friend value operator-(value a, value b);
60         friend value operator*(value a, value b);
61         friend value operator/(value a, value b);
62         friend value operator%(value a, value b);
63 
64         friend value operator&(value a, value b);
65         friend value operator|(value a, value b);
66         friend value operator^(value a, value b);
67         friend value operator<<(value a, value b);
68         friend value operator>>(value a, value b);
69 
70         friend value operator==(value a, value b);
71         friend value operator!=(value a, value b);
72         friend value operator<(value a, value b);
73         friend value operator<=(value a, value b);
74         friend value operator>(value a, value b);
75         friend value operator>=(value a, value b);
76 
77     private:
78 
79         struct to_llvm_value;
80         friend struct to_llvm_value;
81         friend struct llvm_compiler;
82 
83         value(
84             llvm::Value* v,
85             bool is_lvalue_,
86             llvm::IRBuilder<>* builder);
87 
contextclient::code_gen::value88         llvm::LLVMContext& context() const
89         { return llvm::getGlobalContext(); }
90 
91         operator llvm::Value*() const;
92 
93         llvm::Value* v;
94         bool is_lvalue_;
95         llvm::IRBuilder<>* builder;
96     };
97 
98     ///////////////////////////////////////////////////////////////////////////
99     //  The Basic Block (light abstraction of an LLVM::BasicBlock)
100     ///////////////////////////////////////////////////////////////////////////
101     struct function;
102 
103     struct basic_block
104     {
basic_blockclient::code_gen::basic_block105         basic_block()
106           : b(0) {}
107 
108         bool has_terminator() const;
109         bool is_valid() const;
110 
111     private:
112 
basic_blockclient::code_gen::basic_block113         basic_block(llvm::BasicBlock* b)
114           : b(b) {}
115 
operator llvm::BasicBlock*client::code_gen::basic_block116         operator llvm::BasicBlock*() const
117         { return b; }
118 
119         friend struct llvm_compiler;
120         friend struct function;
121         llvm::BasicBlock* b;
122     };
123 
124     ///////////////////////////////////////////////////////////////////////////
125     //  The Function (light abstraction of an LLVM::Function)
126     ///////////////////////////////////////////////////////////////////////////
127     struct llvm_compiler;
128 
129     struct function
130     {
131     private:
132 
133         struct to_value;
134         typedef llvm::Function::arg_iterator arg_iterator;
135         typedef boost::transform_iterator<
136             to_value, arg_iterator>
137         arg_val_iterator;
138 
139     public:
140 
141         typedef boost::iterator_range<arg_val_iterator> arg_range;
142 
functionclient::code_gen::function143         function()
144           : f(0), c(c) {}
145 
146         std::string name() const;
147 
148         std::size_t arg_size() const;
149         arg_range args() const;
150 
151         void add(basic_block const& b);
152         void erase_from_parent();
153         basic_block last_block();
154         bool empty() const;
155 
156         bool is_valid() const;
157         void verify() const;
158 
159     private:
160 
functionclient::code_gen::function161         function(llvm::Function* f, llvm_compiler* c)
162           : f(f), c(c) {}
163 
164         operator llvm::Function*() const;
165 
166         friend struct llvm_compiler;
167         llvm::Function* f;
168         llvm_compiler* c;
169     };
170 
171     ///////////////////////////////////////////////////////////////////////////
172     //  The LLVM Compiler. Lower level compiler (does not deal with ASTs)
173     ///////////////////////////////////////////////////////////////////////////
174     struct llvm_compiler
175     {
llvm_compilerclient::code_gen::llvm_compiler176         llvm_compiler(vmachine& vm)
177           : llvm_builder(context())
178           , vm(vm)
179           , fpm(vm.module())
180         { init_fpm(); }
181 
valclient::code_gen::llvm_compiler182         value val() { return value(); }
183         value val(unsigned int x);
184         value val(int x);
185         value val(bool x);
186 
187         value var(char const* name);
188         value var(std::string const& name);
189 
190         template <typename Container>
191         value call(function callee, Container const& args);
192 
193         function get_function(char const* name);
194         function get_function(std::string const& name);
195         function get_current_function();
196 
197         function declare_function(
198             bool void_return
199           , std::string const& name
200           , std::size_t nargs);
201 
202         basic_block make_basic_block(
203             char const* name
204           , function parent = function()
205           , basic_block before = basic_block());
206 
207         basic_block get_insert_block();
208         void set_insert_point(basic_block b);
209 
210         void conditional_branch(
211             value cond, basic_block true_br, basic_block false_br);
212         void branch(basic_block b);
213 
214         void return_();
215         void return_(value v);
216 
217         void optimize_function(function f);
218 
219     protected:
220 
contextclient::code_gen::llvm_compiler221         llvm::LLVMContext& context() const
222         { return llvm::getGlobalContext(); }
223 
builderclient::code_gen::llvm_compiler224         llvm::IRBuilder<>& builder()
225         { return llvm_builder; }
226 
227     private:
228 
229         friend struct function::to_value;
230 
231         value val(llvm::Value* v);
232 
233         template <typename C>
234         llvm::Value* call_impl(
235             function callee,
236             C const& args);
237 
238         void init_fpm();
239         llvm::IRBuilder<> llvm_builder;
240         vmachine& vm;
241         llvm::FunctionPassManager fpm;
242     };
243 
244     ///////////////////////////////////////////////////////////////////////////
245     //  The main compiler. Generates code from our AST.
246     ///////////////////////////////////////////////////////////////////////////
247     struct compiler : llvm_compiler
248     {
249         typedef value result_type;
250 
251         template <typename ErrorHandler>
compilerclient::code_gen::compiler252         compiler(vmachine& vm, ErrorHandler& error_handler_)
253           : llvm_compiler(vm)
254         {
255             using namespace boost::phoenix::arg_names;
256             namespace phx = boost::phoenix;
257             using boost::phoenix::function;
258 
259             error_handler = function<ErrorHandler>(error_handler_)(
260                 "Error! ", _2, phx::cref(error_handler_.iters)[_1]);
261         }
262 
operator ()client::code_gen::compiler263         value operator()(ast::nil) { BOOST_ASSERT(0); return val(); }
264         value operator()(unsigned int x);
265         value operator()(bool x);
266         value operator()(ast::primary_expr const& x);
267         value operator()(ast::identifier const& x);
268         value operator()(ast::unary_expr const& x);
269         value operator()(ast::function_call const& x);
270         value operator()(ast::expression const& x);
271         value operator()(ast::assignment const& x);
272 
273         bool operator()(ast::variable_declaration const& x);
274         bool operator()(ast::statement_list const& x);
275         bool operator()(ast::statement const& x);
276         bool operator()(ast::if_statement const& x);
277         bool operator()(ast::while_statement const& x);
278         bool operator()(ast::return_statement const& x);
279         bool operator()(ast::function const& x);
280         bool operator()(ast::function_list const& x);
281 
282     private:
283 
284         value compile_binary_expression(
285             value lhs, value rhs, token_ids::type op);
286 
287         value compile_expression(
288             int min_precedence,
289             value lhs,
290             std::list<ast::operation>::const_iterator& rest_begin,
291             std::list<ast::operation>::const_iterator rest_end);
292 
293         struct statement_compiler;
294         statement_compiler& as_statement();
295 
296         function function_decl(ast::function const& x);
297         void function_allocas(ast::function const& x, function function);
298 
299         boost::function<
300             void(int tag, std::string const& what)>
301         error_handler;
302 
303         bool void_return;
304         std::string current_function_name;
305         std::map<std::string, value> locals;
306         basic_block return_block;
307         value return_var;
308     };
309 }}
310 
311 #endif
312