cecko
ckir.hpp
Go to the documentation of this file.
1 
9 #ifndef ckir_hpp_
10 #define ckir_hpp_
11 
12 #include "llvm/ADT/APInt.h"
13 #include "llvm/IR/Verifier.h"
14 #include "llvm/ExecutionEngine/ExecutionEngine.h"
15 #include "llvm/ExecutionEngine/GenericValue.h"
16 #include "llvm/ExecutionEngine/MCJIT.h"
17 #include "llvm/IR/Argument.h"
18 #include "llvm/IR/BasicBlock.h"
19 #include "llvm/IR/Constants.h"
20 #include "llvm/IR/DerivedTypes.h"
21 #include "llvm/IR/Function.h"
22 #include "llvm/IR/InstrTypes.h"
23 #include "llvm/IR/Instructions.h"
24 #include "llvm/IR/LLVMContext.h"
25 #include "llvm/IR/Module.h"
26 #include "llvm/IR/Type.h"
27 #include "llvm/IR/IRBuilder.h"
28 #include "llvm/Support/Casting.h"
29 #include "llvm/Support/TargetSelect.h"
30 #include "llvm/Support/raw_ostream.h"
31 #include "llvm/Bitcode/BitcodeWriter.h"
32 #include "llvm/Support/raw_os_ostream.h"
33 
34 #include <ostream>
35 #include <cstdio>
36 
37 namespace cecko {
38 
40  template< typename E>
41  struct safe_default
42  {
43  E operator()() const { return E(); }
44  };
46 
53  template< typename E, typename DF = safe_default<E>>
54  class safe_ptr
55  {
56  public:
57  safe_ptr() : p_(nullptr) {}
58  safe_ptr(std::nullptr_t) : p_(nullptr) {}
59  template<typename E2, typename DF2, std::enable_if_t<std::is_convertible_v<E2*,E*>,bool> = true>
60  safe_ptr(const safe_ptr<E2, DF2>& b) : p_(b.p_) {}
61  explicit safe_ptr(E* p) : p_(p) {}
62  operator E* () const { return p_; }
63  operator bool() const { return !!p_; }
64  E& operator*() const { return p_ ? *p_ : dummy(); }
65  E* operator->() const { return p_ ? p_ : &dummy(); }
66  friend bool operator==(const safe_ptr& a, const safe_ptr& b) { return a.p_ == b.p_; }
67  friend bool operator!=(const safe_ptr& a, const safe_ptr& b) { return a.p_ != b.p_; }
68  private:
69  E* p_;
70  static E& dummy() { static decltype(DF()()) d = DF()(); return d; }
71  template<typename E2, typename DF2>
72  friend class safe_ptr;
73  };
74 
75  // numbers
76  using CKIRAPInt = llvm::APInt;
77  // context
78  using CKIRContextRef = llvm::LLVMContext&;
79  // types
80  using CKIRTypeObs = llvm::Type*;
81  using CKIRStructTypeObs = llvm::StructType*;
82  using CKIRFunctionTypeObs = llvm::FunctionType*;
83  using CKIRTypeObsArray = std::vector<llvm::Type*>;
84  using CKIRTypeObsArrayRef = llvm::ArrayRef<llvm::Type*>;
85  // values
86  using CKIRValueObs = llvm::Value*;
87  using CKIRValueObsArray = std::vector<llvm::Value*>;
88  using CKIRValueObsArrayRef = llvm::ArrayRef<llvm::Value*>;
89  // constant values
90  using CKIRConstantObs = llvm::Constant*;
91  using CKIRConstantIntObs = llvm::ConstantInt*;
92  // module
93  using CKIRModuleObs = llvm::Module*;
94  // function
95  using CKIRFunctionObs = llvm::Function*;
96  // basic block
97  using CKIRBasicBlockObs = llvm::BasicBlock*;
98  // instructions
99  using CKIRAllocaInstObs = llvm::AllocaInst*;
100  // builder
101  using CKIRBuilder = llvm::IRBuilder<>;
104 
105  // string
106  using CKIRName = llvm::Twine;
107 
109 
110  inline std::size_t CKHashValue(const CKIRAPInt& Arg)
111  {
112  return llvm::hash_value(Arg);
113  }
114 
115  inline CKIRTypeObs CKGetVoidType(CKIRContextRef Context)
116  {
117  return llvm::Type::getVoidTy(Context);
118  }
119 
120  inline CKIRTypeObs CKGetInt1Type(CKIRContextRef Context)
121  {
122  return llvm::Type::getInt1Ty(Context);
123  }
124 
125  inline CKIRTypeObs CKGetInt8Type(CKIRContextRef Context)
126  {
127  return llvm::Type::getInt8Ty(Context);
128  }
129 
130  inline CKIRTypeObs CKGetInt32Type(CKIRContextRef Context)
131  {
132  return llvm::Type::getInt32Ty(Context);
133  }
134 
135  inline CKIRTypeObs CKGetInt8PtrType(CKIRContextRef Context)
136  {
137  return llvm::Type::getInt8PtrTy(Context);
138  }
139 
140  CKIRTypeObs CKGetPtrType(CKIRContextRef irc);
141 
142  CKIRTypeObs CKGetArrayType(CKIRTypeObs element, CKIRConstantIntObs size);
143 
144  inline CKIRStructTypeObs CKCreateStructType(CKIRContextRef Context, const std::string& name)
145  {
146  return llvm::StructType::create(Context, name);
147  }
148 
149  inline CKIRFunctionTypeObs CKGetFunctionType(CKIRTypeObs rettype, CKIRTypeObsArrayRef argtypes, bool variadic = false)
150  {
151  return llvm::FunctionType::get(rettype, argtypes, variadic);
152  }
153 
154  inline CKIRConstantIntObs CKGetInt1Constant(CKIRContextRef Context, bool V)
155  {
156  return llvm::ConstantInt::get(llvm::Type::getInt1Ty(Context), V);
157  }
158 
159  inline CKIRConstantIntObs CKGetInt8Constant(CKIRContextRef Context, std::int_fast8_t V)
160  {
161  return llvm::ConstantInt::get(llvm::Type::getInt8Ty(Context), V);
162  }
163 
164  inline CKIRConstantIntObs CKGetInt32Constant(CKIRContextRef Context, std::int_fast32_t V)
165  {
166  return llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), V);
167  }
168 
169  inline CKIRFunctionObs CKCreateFunction(CKIRFunctionTypeObs FT, const std::string& name, CKIRModuleObs M)
170  {
171  return llvm::Function::Create(FT, llvm::Function::ExternalLinkage, name, M);
172  }
173 
175  inline CKIRBasicBlockObs CKCreateBasicBlock(const std::string& name, CKIRFunctionObs F)
176  {
177  if (!F)
178  return nullptr;
179  return llvm::BasicBlock::Create(F->getContext(), name, F);
180  }
182 
185  {
186  if (!v)
187  return nullptr;
188  if (!llvm::isa< llvm::ConstantInt>(v))
189  return nullptr;
190  return llvm::cast<llvm::ConstantInt>(v);
191  }
192 
195  {
196  return llvm::Constant::getNullValue(t);
197  }
198 
200  CKIRConstantObs CKCreateGlobalVariable(CKIRTypeObs irtp, const std::string& name, CKIRModuleObs M);
201 
202  CKIRConstantObs CKCreateExternVariable(CKIRTypeObs irtp, const std::string& name, CKIRModuleObs M);
203 
204  using CKIRDataLayoutObs = const llvm::DataLayout*;
205 
206  inline std::int_fast64_t CKGetTypeSize(CKIRDataLayoutObs DataLayout, CKIRTypeObs Ty)
207  {
208  auto ts = DataLayout->getTypeAllocSize(Ty);
209  return ts;
210  }
211 
212  class CKIREnvironment {
213  public:
214  CKIREnvironment();
215 
216  void dump_module(std::ostream& os, CKIRModuleObs module) const;
217 
218  std::error_code write_bitcode_module(const std::string& fname, CKIRModuleObs module) const;
219 
220  int run_main(CKIRFunctionObs fnc, int argc, char** argv, std::ostream& os);
221 
222  CKIRContextRef context()
223  {
224  return *ckircontextptr_;
225  }
226 
227  CKIRModuleObs module()
228  {
229  return ckirmoduleobs_;
230  }
231 
232  CKIRDataLayoutObs data_layout() const
233  {
234  return &*ckirdatalayoutptr_;
235  }
236 
237  private:
238  std::unique_ptr< llvm::LLVMContext> ckircontextptr_;
239  std::unique_ptr< llvm::Module> ckirmoduleptr_;
240  CKIRModuleObs ckirmoduleobs_;
241  std::unique_ptr< llvm::DataLayout> ckirdatalayoutptr_;
242  };
243 
244  using CKIREnvironmentObs = CKIREnvironment*;
246 };
247 
248 #endif
llvm::BasicBlock * CKIRBasicBlockObs
Definition: ckir.hpp:97
std::vector< llvm::Value * > CKIRValueObsArray
Definition: ckir.hpp:87
llvm::Type * CKIRTypeObs
Definition: ckir.hpp:80
llvm::ConstantInt * CKIRConstantIntObs
Definition: ckir.hpp:91
llvm::IRBuilder<> CKIRBuilder
Definition: ckir.hpp:101
llvm::ArrayRef< llvm::Type * > CKIRTypeObsArrayRef
Definition: ckir.hpp:84
llvm::AllocaInst * CKIRAllocaInstObs
Definition: ckir.hpp:99
llvm::Module * CKIRModuleObs
Definition: ckir.hpp:93
llvm::Twine CKIRName
Definition: ckir.hpp:106
llvm::LLVMContext & CKIRContextRef
Definition: ckir.hpp:78
llvm::Function * CKIRFunctionObs
Definition: ckir.hpp:95
CKIRConstantObs CKIRNullValue(CKIRTypeObs t)
Get null value for a llvm::Type.
Definition: ckir.hpp:194
llvm::Constant * CKIRConstantObs
Definition: ckir.hpp:90
llvm::FunctionType * CKIRFunctionTypeObs
Definition: ckir.hpp:82
std::vector< llvm::Type * > CKIRTypeObsArray
Definition: ckir.hpp:83
llvm::APInt CKIRAPInt
Definition: ckir.hpp:76
CKIRConstantIntObs CKTryGetConstantInt(CKIRValueObs v)
Get integral constant from a llvm::Value.
Definition: ckir.hpp:184
CKIRBuilder * CKIRBuilderObs
Definition: ckir.hpp:103
llvm::ArrayRef< llvm::Value * > CKIRValueObsArrayRef
Definition: ckir.hpp:88
llvm::StructType * CKIRStructTypeObs
Definition: ckir.hpp:81
llvm::Value * CKIRValueObs
Definition: ckir.hpp:86
CKIRBuilder & CKIRBuilderRef
Definition: ckir.hpp:102
Safe pointer to E.
Definition: ckir.hpp:55