Proteus
Programmable JIT compilation and optimization for C/C++ using LLVM
Loading...
Searching...
No Matches
Func.hpp
Go to the documentation of this file.
1#ifndef PROTEUS_FRONTEND_FUNC_HPP
2#define PROTEUS_FRONTEND_FUNC_HPP
3
4#include <deque>
5
6#include <llvm/IR/IRBuilder.h>
7#include <llvm/IR/Module.h>
8
9#include "proteus/Error.h"
13#include "proteus/Hashing.hpp"
14
15namespace proteus {
16
17struct Var;
18class JitModule;
19
20using namespace llvm;
21
22class FuncBase {
23protected:
25 FunctionCallee FC;
26 IRBuilder<> IRB;
27 IRBuilderBase::InsertPoint IP;
28 std::deque<Var> Arguments;
29 std::deque<Var> Variables;
30 std::deque<Var> RuntimeConstants;
31 std::string Name;
32
33 enum class ScopeKind { FUNCTION, IF, FOR };
34 struct Scope {
35 std::string File;
36 int Line;
38 IRBuilderBase::InsertPoint ContIP;
39
40 explicit Scope(const char *File, int Line, ScopeKind Kind,
41 IRBuilderBase::InsertPoint ContIP)
43 };
44 std::vector<Scope> Scopes;
45
46 std::string toString(ScopeKind Kind) {
47 switch (Kind) {
49 return "FUNCTION";
50 case ScopeKind::IF:
51 return "IF";
52 case ScopeKind::FOR:
53 return "FOR";
54 default:
55 PROTEUS_FATAL_ERROR("Unsupported Kind " +
56 std::to_string(static_cast<int>(Kind)));
57 }
58 }
59
60public:
61 FuncBase(JitModule &J, FunctionCallee FC);
62
63 Function *getFunction();
64
65 AllocaInst *emitAlloca(Type *Ty, StringRef Name);
66
67 IRBuilderBase &getIRBuilder();
68
69 Var &declVarInternal(StringRef Name, Type *Ty,
70 Type *PointerElemType = nullptr);
71
72 template <typename T> Var &declVar(StringRef Name = "var") {
73 Function *F = getFunction();
74 auto *Alloca = emitAlloca(TypeMap<T>::get(F->getContext()), Name);
75
76 return Variables.emplace_back(
77 Alloca, *this, TypeMap<T>::getPointerElemType(F->getContext()));
78 }
79
80 template <typename T> Var &defVar(T Val, StringRef Name = "var") {
81 Function *F = getFunction();
82 auto *Alloca = emitAlloca(TypeMap<T>::get(F->getContext()), Name);
83
84 Var &VarRef = Variables.emplace_back(
85 Alloca, *this, TypeMap<T>::getPointerElemType(F->getContext()));
86
87 VarRef = Val;
88
89 return VarRef;
90 }
91
92 template <typename T>
93 Var &defRuntimeConst(T Val, StringRef Name = "run.const.var") {
94 Function *F = getFunction();
95 auto *Alloca = emitAlloca(TypeMap<T>::get(F->getContext()), Name);
96
97 Var &VarRef = RuntimeConstants.emplace_back(
98 Alloca, *this, TypeMap<T>::getPointerElemType(F->getContext()));
99
100 VarRef = Val;
101
102 return VarRef;
103 }
104
105 template <typename... ArgT> auto defRuntimeConsts(ArgT &&...Args) {
106 return std::tie(defRuntimeConst(std::forward<ArgT>(Args))...);
107 }
108
109 template <typename... Ts> void declArgs() {
110 Function *F = getFunction();
111 auto &EntryBB = F->getEntryBlock();
112 IP = IRBuilderBase::InsertPoint(&EntryBB, EntryBB.end());
113 IRB.restoreIP(IP);
114
115 (
116 [&]() {
117 auto *Alloca = emitAlloca(TypeMap<Ts>::get(F->getContext()),
118 "arg." + std::to_string(Arguments.size()));
119
120 auto *Arg = F->getArg(Arguments.size());
121 IRB.CreateStore(Arg, Alloca);
122
123 Arguments.emplace_back(
124 Alloca, *this, TypeMap<Ts>::getPointerElemType(F->getContext()));
125 }(),
126 ...);
127 IRB.ClearInsertionPoint();
128 }
129
130 Var &getArg(unsigned int ArgNo);
131
132 void beginFunction(const char *File = __builtin_FILE(),
133 int Line = __builtin_LINE());
134 void endFunction();
135
136 void beginIf(Var &CondVar, const char *File = __builtin_FILE(),
137 int Line = __builtin_LINE());
138 void endIf();
139
140 void beginFor(Var &IterVar, Var &InitVar, Var &UpperBound, Var &IncVar,
141 const char *File = __builtin_FILE(),
142 int Line = __builtin_LINE());
143 void endFor();
144
145 template <typename RetT, typename... ArgT>
146 std::enable_if_t<!std::is_void_v<RetT>, Var &> call(StringRef Name);
147 template <typename RetT, typename... ArgT>
148 std::enable_if_t<std::is_void_v<RetT>, void> call(StringRef Name);
149
150 Var &callBuiltin(function_ref<Var &(FuncBase &)> Lower) {
151 return Lower(*this);
152 }
153
154 void ret(std::optional<std::reference_wrapper<Var>> OptRet = std::nullopt);
155
156 StringRef getName() const { return Name; }
157
158 void setName(StringRef NewName) {
159 Name = NewName.str();
160 Function *F = getFunction();
161 F->setName(Name);
162 }
163};
164
165template <typename RetT, typename... ArgT> class Func final : public FuncBase {
166private:
167 Dispatcher &Dispatch;
168 RetT (*CompiledFunc)(ArgT...) = nullptr;
169
170private:
171 template <std::size_t... Is> auto getArgsImpl(std::index_sequence<Is...>) {
172 return std::tie(getArg(Is)...);
173 }
174
175public:
176 Func(JitModule &J, FunctionCallee FC, Dispatcher &Dispatch)
177 : FuncBase(J, FC), Dispatch(Dispatch) {}
178
179 RetT operator()(ArgT... Args);
180
181 auto getArgs() { return getArgsImpl(std::index_sequence_for<ArgT...>{}); }
182
183 auto getCompiledFunc() const { return CompiledFunc; }
184
185 void setCompiledFunc(RetT (*CompiledFuncIn)(ArgT...)) {
186 CompiledFunc = CompiledFuncIn;
187 }
188};
189
190} // namespace proteus
191
192#endif // PROTEUS_FRONTEND_FUNC_HPP
char int void ** Args
Definition CompilerInterfaceHost.cpp:21
#define PROTEUS_FATAL_ERROR(x)
Definition Error.h:7
Definition Dispatcher.hpp:46
Definition Func.hpp:22
void declArgs()
Definition Func.hpp:109
std::enable_if_t<!std::is_void_v< RetT >, Var & > call(StringRef Name)
Definition JitFrontend.hpp:224
std::vector< Scope > Scopes
Definition Func.hpp:44
void setName(StringRef NewName)
Definition Func.hpp:158
Var & declVarInternal(StringRef Name, Type *Ty, Type *PointerElemType=nullptr)
Definition Func.cpp:18
void beginIf(Var &CondVar, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.cpp:98
Var & defVar(T Val, StringRef Name="var")
Definition Func.hpp:80
auto defRuntimeConsts(ArgT &&...Args)
Definition Func.hpp:105
void endFunction()
Definition Func.cpp:47
void beginFunction(const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.cpp:24
IRBuilder IRB
Definition Func.hpp:26
Var & defRuntimeConst(T Val, StringRef Name="run.const.var")
Definition Func.hpp:93
Function * getFunction()
Definition Func.cpp:60
ScopeKind
Definition Func.hpp:33
std::deque< Var > Arguments
Definition Func.hpp:28
void endIf()
Definition Func.cpp:132
Var & getArg(unsigned int ArgNo)
Definition Func.cpp:67
std::string Name
Definition Func.hpp:31
FunctionCallee FC
Definition Func.hpp:25
std::deque< Var > RuntimeConstants
Definition Func.hpp:30
IRBuilderBase::InsertPoint IP
Definition Func.hpp:27
JitModule & J
Definition Func.hpp:24
void ret(std::optional< std::reference_wrapper< Var > > OptRet=std::nullopt)
Definition Func.cpp:81
std::deque< Var > Variables
Definition Func.hpp:29
StringRef getName() const
Definition Func.hpp:156
void beginFor(Var &IterVar, Var &InitVar, Var &UpperBound, Var &IncVar, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.cpp:148
AllocaInst * emitAlloca(Type *Ty, StringRef Name)
Definition Func.cpp:69
void endFor()
Definition Func.cpp:206
Var & callBuiltin(function_ref< Var &(FuncBase &)> Lower)
Definition Func.hpp:150
std::string toString(ScopeKind Kind)
Definition Func.hpp:46
IRBuilderBase & getIRBuilder()
Definition Func.cpp:12
Var & declVar(StringRef Name="var")
Definition Func.hpp:72
Definition Func.hpp:165
Func(JitModule &J, FunctionCallee FC, Dispatcher &Dispatch)
Definition Func.hpp:176
auto getCompiledFunc() const
Definition Func.hpp:183
auto getArgs()
Definition Func.hpp:181
void setCompiledFunc(RetT(*CompiledFuncIn)(ArgT...))
Definition Func.hpp:185
RetT operator()(ArgT... Args)
Definition JitFrontend.hpp:248
Definition JitFrontend.hpp:26
Definition Helpers.h:76
Definition CppJitModule.cpp:21
Definition Func.hpp:34
Scope(const char *File, int Line, ScopeKind Kind, IRBuilderBase::InsertPoint ContIP)
Definition Func.hpp:40
int Line
Definition Func.hpp:36
ScopeKind Kind
Definition Func.hpp:37
std::string File
Definition Func.hpp:35
IRBuilderBase::InsertPoint ContIP
Definition Func.hpp:38
Definition TypeMap.hpp:13
Definition Var.hpp:15