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