1 /* 2 * Copyright (c) 2015 PLUMgrid, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <map> 20 #include <stdio.h> 21 #include <vector> 22 #include <string> 23 #include <set> 24 25 #include "node.h" 26 #include "scope.h" 27 28 namespace llvm { 29 class AllocaInst; 30 class BasicBlock; 31 class BranchInst; 32 class Constant; 33 class Instruction; 34 class IRBuilderBase; 35 class LLVMContext; 36 class Module; 37 class StructType; 38 class SwitchInst; 39 class Type; 40 class Value; 41 class GlobalVariable; 42 } 43 44 namespace ebpf { 45 46 class TableStorage; 47 48 namespace cc { 49 50 class BlockStack; 51 class SwitchStack; 52 53 using std::vector; 54 using std::string; 55 using std::set; 56 57 class CodegenLLVM : public Visitor { 58 friend class BlockStack; 59 friend class SwitchStack; 60 public: 61 CodegenLLVM(llvm::Module *mod, Scopes *scopes, Scopes *proto_scopes); 62 virtual ~CodegenLLVM(); 63 64 #define VISIT(type, func) virtual STATUS_RETURN visit_##func(type* n); 65 EXPAND_NODES(VISIT) 66 #undef VISIT 67 68 STATUS_RETURN visit(Node *n, TableStorage &ts, const std::string &id, 69 const std::string &maps_ns); 70 71 int get_table_fd(const std::string &name) const; 72 73 private: 74 STATUS_RETURN emit_short_circuit_and(BinopExprNode* n); 75 STATUS_RETURN emit_short_circuit_or(BinopExprNode* n); 76 STATUS_RETURN emit_table_lookup(MethodCallExprNode* n); 77 STATUS_RETURN emit_table_update(MethodCallExprNode* n); 78 STATUS_RETURN emit_table_delete(MethodCallExprNode* n); 79 STATUS_RETURN emit_log(MethodCallExprNode* n); 80 STATUS_RETURN emit_packet_rewrite_field(MethodCallExprNode* n); 81 STATUS_RETURN emit_atomic_add(MethodCallExprNode* n); 82 STATUS_RETURN emit_cksum(MethodCallExprNode* n); 83 STATUS_RETURN emit_incr_cksum(MethodCallExprNode* n, size_t sz = 0); 84 STATUS_RETURN emit_lb_hash(MethodCallExprNode* n); 85 STATUS_RETURN emit_sizeof(MethodCallExprNode* n); 86 STATUS_RETURN emit_get_usec_time(MethodCallExprNode* n); 87 STATUS_RETURN emit_forward_to_vnf(MethodCallExprNode* n); 88 STATUS_RETURN emit_forward_to_group(MethodCallExprNode* n); 89 STATUS_RETURN print_header(); 90 91 llvm::LLVMContext & ctx() const; 92 llvm::Constant * const_int(uint64_t val, unsigned bits = 64, bool is_signed = false); 93 llvm::Value * pop_expr(); 94 llvm::BasicBlock * resolve_label(const string &label); 95 llvm::Instruction * resolve_entry_stack(); 96 llvm::AllocaInst *make_alloca(llvm::Instruction *Inst, llvm::Type *Ty, 97 const std::string &name = "", 98 llvm::Value *ArraySize = nullptr); 99 llvm::AllocaInst *make_alloca(llvm::BasicBlock *BB, llvm::Type *Ty, 100 const std::string &name = "", 101 llvm::Value *ArraySize = nullptr); 102 StatusTuple lookup_var(Node *n, const std::string &name, Scopes::VarScope *scope, 103 VariableDeclStmtNode **decl, llvm::Value **mem) const; 104 StatusTuple lookup_struct_type(StructDeclStmtNode *decl, llvm::StructType **stype) const; 105 StatusTuple lookup_struct_type(VariableDeclStmtNode *n, llvm::StructType **stype, 106 StructDeclStmtNode **decl = nullptr) const; 107 108 template <typename... Args> void emit(const char *fmt, Args&&... params); 109 void emit(const char *s); 110 111 FILE* out_; 112 llvm::Module* mod_; 113 llvm::IRBuilderBase *b_; 114 int indent_; 115 int tmp_reg_index_; 116 Scopes *scopes_; 117 Scopes *proto_scopes_; 118 vector<vector<string> > free_instructions_; 119 vector<string> table_inits_; 120 map<string, string> proto_rewrites_; 121 map<TableDeclStmtNode *, llvm::GlobalVariable *> tables_; 122 map<TableDeclStmtNode *, int> table_fds_; 123 map<VariableDeclStmtNode *, llvm::Value *> vars_; 124 map<StructDeclStmtNode *, llvm::StructType *> structs_; 125 map<string, llvm::BasicBlock *> labels_; 126 llvm::SwitchInst *cur_switch_; 127 llvm::Value *expr_; 128 llvm::AllocaInst *retval_; 129 llvm::AllocaInst *errval_; 130 }; 131 132 } // namespace cc 133 } // namespace ebpf 134