Skip to content
This repository was archived by the owner on Sep 27, 2019. It is now read-only.

Commit 9b29a4c

Browse files
committed
Merge branch 'master' of https://github.com/cmu-db/peloton into txnctx/readonly
2 parents 0fa4b3d + a045cfc commit 9b29a4c

40 files changed

+6000
-355
lines changed

cmake/Dependencies.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ llvm_map_components_to_libnames(LLVM_LIBRARIES core mcjit nativecodegen native)
8686
include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
8787
list(APPEND Peloton_LINKER_LIBS ${LLVM_LIBRARIES})
8888

89+
# --[ FFI
90+
find_package(Libffi)
91+
include_directories(SYSTEM ${LIBFFI_INCLUDE_DIRS})
92+
list(APPEND Peloton_LINKER_LIBS ${LIBFFI_LIBRARIES})
93+
8994
# --[ IWYU
9095

9196
# Generate clang compilation database

cmake/Modules/FindLibffi.cmake

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# - Try to find Libffi
2+
#
3+
# A Portable Foreign Function Interface Library (https://sourceware.org/libffi)
4+
#
5+
# Usage:
6+
# LIBFFI_INCLUDE_DIRS, location of header files
7+
# LIBFFI_LIBRARIES, location of library
8+
# LIBFFI_FOUND, indicates if libffi was found
9+
10+
# Look for the header file.
11+
execute_process(COMMAND brew --prefix libffi OUTPUT_VARIABLE LIBFFI_BREW_PREFIX)
12+
13+
find_library(LIBFFI_LIBRARY NAMES ffi libffi
14+
PATHS /usr /usr/local /opt/local
15+
PATH_SUFFIXES lib lib64 x86_64-linux-gnu lib/x86_64-linux-gnu
16+
)
17+
18+
find_path(LIBFFI_INCLUDE_DIR ffi.h
19+
PATHS /usr /usr/local /opt/local /usr/include/ffi
20+
PATH_SUFFIXES include include/ffi include/x86_64-linux-gnu x86_64-linux-gnu
21+
HINT LIBFFI_BREW_PREFIX
22+
)
23+
24+
include(FindPackageHandleStandardArgs)
25+
find_package_handle_standard_args(LIBFFI DEFAULT_MSG LIBFFI_LIBRARY LIBFFI_INCLUDE_DIR)
26+
27+
28+
# Copy the results to the output variables.
29+
IF(LIBFFI_FOUND)
30+
SET(LIBFFI_LIBRARIES ${LIBFFI_LIBRARY})
31+
SET(LIBFFI_INCLUDE_DIRS ${LIBFFI_INCLUDE_DIR})
32+
ELSE(LIBFFI_FOUND)
33+
SET(LIBFFI_LIBRARIES)
34+
SET(LIBFFI_INCLUDE_DIRS)
35+
ENDIF(LIBFFI_FOUND)
36+
37+
MARK_AS_ADVANCED(LIBFFI_INCLUDE_DIRS LIBFFI_LIBRARIES)
38+
39+
message(STATUS "Found Libffi (include: ${LIBFFI_INCLUDE_DIRS}, library: ${LIBFFI_LIBRARIES})")

script/installation/packages.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ if [ "$DISTRO" = "UBUNTU" ]; then
176176
libedit-dev \
177177
libssl-dev \
178178
postgresql-client \
179+
libffi6 \
180+
libffi-dev \
179181
libtbb-dev \
180182
python3-pip \
181183
curl \
@@ -219,6 +221,7 @@ elif [ "$DISTRO" = "DARWIN" ]; then
219221
brew install libedit
220222
brew install [email protected]
221223
brew install postgresql
224+
brew install libffi
222225
brew install tbb
223226
brew install curl
224227
brew install wget

src/codegen/code_context.cpp

Lines changed: 67 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ namespace {
4444
class PelotonMemoryManager : public llvm::SectionMemoryManager {
4545
public:
4646
explicit PelotonMemoryManager(
47-
const std::unordered_map<std::string, CodeContext::FuncPtr> &symbols)
48-
: symbols_(symbols) {}
47+
const std::unordered_map<std::string,
48+
std::pair<llvm::Function *, CodeContext::FuncPtr>> &builtins)
49+
: builtins_(builtins) {}
4950

5051
#if LLVM_VERSION_GE(4, 0)
5152
#define RET_TYPE llvm::JITSymbol
@@ -56,8 +57,6 @@ class PelotonMemoryManager : public llvm::SectionMemoryManager {
5657
#define BUILD_RET_TYPE(addr) \
5758
(RET_TYPE{(uint64_t)addr, llvm::JITSymbolFlags::Exported})
5859
#endif
59-
60-
/// Find the address of the function with the given name
6160
RET_TYPE findSymbol(const std::string &name) override {
6261
LOG_TRACE("Looking up symbol '%s' ...", name.c_str());
6362
if (auto *builtin = LookupSymbol(name)) {
@@ -68,23 +67,22 @@ class PelotonMemoryManager : public llvm::SectionMemoryManager {
6867
LOG_TRACE("--> Not builtin, use fallback resolution ...");
6968
return llvm::SectionMemoryManager::findSymbol(name);
7069
}
71-
7270
#undef RET_TYPE
7371
#undef BUILD_RET_TYPE
7472

7573
private:
7674
void *LookupSymbol(const std::string &name) const {
7775
// Check for a builtin with the exact name
78-
auto symbol_iter = symbols_.find(name);
79-
if (symbol_iter != symbols_.end()) {
80-
return symbol_iter->second;
76+
auto symbol_iter = builtins_.find(name);
77+
if (symbol_iter != builtins_.end()) {
78+
return symbol_iter->second.second;
8179
}
8280

8381
// Check for a builtin with the leading '_' removed
8482
if (!name.empty() && name[0] == '_') {
85-
symbol_iter = symbols_.find(name.substr(1));
86-
if (symbol_iter != symbols_.end()) {
87-
return symbol_iter->second;
83+
symbol_iter = builtins_.find(name.substr(1));
84+
if (symbol_iter != builtins_.end()) {
85+
return symbol_iter->second.second;
8886
}
8987
}
9088

@@ -94,7 +92,9 @@ class PelotonMemoryManager : public llvm::SectionMemoryManager {
9492

9593
private:
9694
// The code context
97-
const std::unordered_map<std::string, CodeContext::FuncPtr> &symbols_;
95+
const std::unordered_map<std::string,
96+
std::pair<llvm::Function *, CodeContext::FuncPtr>>
97+
&builtins_;
9898
};
9999

100100
////////////////////////////////////////////////////////////////////////////////
@@ -177,7 +177,8 @@ CodeContext::CodeContext()
177177
func_(nullptr),
178178
udf_func_ptr_(nullptr),
179179
pass_manager_(nullptr),
180-
engine_(nullptr) {
180+
engine_(nullptr),
181+
is_verified_(false) {
181182
// Initialize JIT stuff
182183
llvm::InitializeNativeTarget();
183184
llvm::InitializeNativeTargetAsmPrinter();
@@ -200,8 +201,7 @@ CodeContext::CodeContext()
200201
engine_.reset(
201202
llvm::EngineBuilder(std::move(m))
202203
.setEngineKind(llvm::EngineKind::JIT)
203-
.setMCJITMemoryManager(
204-
llvm::make_unique<PelotonMemoryManager>(function_symbols_))
204+
.setMCJITMemoryManager(llvm::make_unique<PelotonMemoryManager>(builtins_))
205205
.setMCPU(llvm::sys::getHostCPUName())
206206
.setErrorStr(&err_str_)
207207
.create());
@@ -223,6 +223,7 @@ CodeContext::CodeContext()
223223
int32_type_ = llvm::Type::getInt32Ty(*context_);
224224
int64_type_ = llvm::Type::getInt64Ty(*context_);
225225
double_type_ = llvm::Type::getDoubleTy(*context_);
226+
float_type_ = llvm::Type::getFloatTy(*context_);
226227
void_type_ = llvm::Type::getVoidTy(*context_);
227228
void_ptr_type_ = llvm::Type::getInt8PtrTy(*context_);
228229
char_ptr_type_ = llvm::Type::getInt8PtrTy(*context_);
@@ -251,14 +252,13 @@ void CodeContext::RegisterExternalFunction(llvm::Function *func_decl,
251252
PELOTON_ASSERT(func_impl != nullptr && "The function pointer cannot be NULL");
252253
functions_.emplace_back(func_decl, func_impl);
253254

254-
// Register the builtin symbol by name
255-
function_symbols_[func_decl->getName()] = func_impl;
255+
builtins_[func_decl->getName()] = std::make_pair(func_decl, func_impl);
256256
}
257257

258258
void CodeContext::RegisterBuiltin(llvm::Function *func_decl,
259259
CodeContext::FuncPtr func_impl) {
260260
const auto name = func_decl->getName();
261-
if (LookupBuiltin(name) != nullptr) {
261+
if (LookupBuiltin(name).first != nullptr) {
262262
LOG_DEBUG("Builtin '%s' already registered, skipping ...", name.data());
263263
return;
264264
}
@@ -268,44 +268,58 @@ void CodeContext::RegisterBuiltin(llvm::Function *func_decl,
268268
func_decl->isDeclaration() &&
269269
"You cannot provide a function definition for a builtin function");
270270

271-
// Register the builtin function
272-
builtins_[name] = func_decl;
273-
274-
// Register the builtin symbol by name
275-
function_symbols_[name] = func_impl;
271+
// Register the builtin function with type and implementation
272+
builtins_[name] = std::make_pair(func_decl, func_impl);
276273
}
277274

278-
llvm::Function *CodeContext::LookupBuiltin(const std::string &name) const {
275+
std::pair<llvm::Function *, CodeContext::FuncPtr> CodeContext::LookupBuiltin(const std::string &name) const {
279276
auto iter = builtins_.find(name);
280-
return (iter == builtins_.end() ? nullptr : iter->second);
277+
return (iter == builtins_.end() ? std::make_pair<llvm::Function *, CodeContext::FuncPtr>(nullptr, nullptr) : iter->second);
281278
}
282279

283-
/// Optimize and JIT compile all the functions that were created in this context
284-
bool CodeContext::Compile() {
280+
/// Verify all the functions that were created in this context
281+
void CodeContext::Verify() {
285282
// Verify the module is okay
286283
llvm::raw_ostream &errors = llvm::errs();
287284
if (llvm::verifyModule(*module_, &errors)) {
288-
// There is an error in the module that failed compilation.
285+
// There is an error in the module.
289286
// Dump the crappy IR to the log ...
290287
LOG_ERROR("ERROR IN MODULE:\n%s\n", GetIR().c_str());
291-
return false;
288+
289+
throw Exception("The generated LLVM code contains errors. ");
292290
}
293291

292+
// All is well
293+
is_verified_ = true;
294+
}
295+
296+
/// Optimize all the functions that were created in this context
297+
void CodeContext::Optimize() {
298+
// make sure the code is verified
299+
if (!is_verified_) Verify();
300+
294301
// Run the optimization passes over each function in this module
295302
pass_manager_->doInitialization();
296303
for (auto &func_iter : functions_) {
297304
pass_manager_->run(*func_iter.first);
298305
}
299306
pass_manager_->doFinalization();
307+
}
308+
309+
/// JIT compile all the functions that were created in this context
310+
void CodeContext::Compile() {
311+
// make sure the code is verified
312+
if (!is_verified_) Verify();
300313

314+
// Print some IR stats
301315
if (settings::SettingsManager::GetBool(settings::SettingId::print_ir_stats)) {
302316
char name[] = "inst count";
303317
InstructionCounts inst_count(*name);
304318
inst_count.runOnModule(GetModule());
305319
inst_count.DumpStats();
306320
}
307321

308-
// Functions and module have been optimized, now JIT compile the module
322+
// JIT compile the module
309323
engine_->finalizeObject();
310324

311325
// Pull out the compiled function implementations
@@ -314,14 +328,34 @@ bool CodeContext::Compile() {
314328
}
315329

316330
// Log the module
331+
LOG_TRACE("%s\n", GetIR().c_str());
317332
if (settings::SettingsManager::GetBool(settings::SettingId::dump_ir)) {
318333
LOG_DEBUG("%s\n", GetIR().c_str());
319334
}
335+
}
320336

321-
// All is well
322-
return true;
337+
size_t CodeContext::GetTypeSize(llvm::Type *type) const {
338+
auto size = GetDataLayout().getTypeSizeInBits(type) / 8;
339+
return size != 0 ? size : 1;
340+
}
341+
342+
size_t CodeContext::GetTypeSizeInBits(llvm::Type *type) const {
343+
return GetDataLayout().getTypeSizeInBits(type);
344+
}
345+
346+
size_t CodeContext::GetTypeAllocSize(llvm::Type *type) const {
347+
return GetDataLayout().getTypeAllocSize(type);
348+
}
349+
350+
size_t CodeContext::GetTypeAllocSizeInBits(llvm::Type *type) const {
351+
return GetDataLayout().getTypeAllocSizeInBits(type);
352+
}
353+
354+
size_t CodeContext::GetStructElementOffset(llvm::StructType *type, size_t index) const {
355+
return GetDataLayout().getStructLayout(type)->getElementOffset(index);
323356
}
324357

358+
// TODO(marcel) same as LookupBuiltin?
325359
CodeContext::FuncPtr CodeContext::GetRawFunctionPointer(
326360
llvm::Function *fn) const {
327361
for (const auto &iter : functions_) {
@@ -334,6 +368,7 @@ CodeContext::FuncPtr CodeContext::GetRawFunctionPointer(
334368
return nullptr;
335369
}
336370

371+
/// Get the module's layout
337372
const llvm::DataLayout &CodeContext::GetDataLayout() const {
338373
return module_->getDataLayout();
339374
}

src/codegen/codegen.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ llvm::Value *CodeGen::CallFunc(llvm::Value *fn,
150150

151151
llvm::Value *CodeGen::Printf(const std::string &format,
152152
const std::vector<llvm::Value *> &args) {
153-
auto *printf_fn = LookupBuiltin("printf");
153+
auto *printf_fn = LookupBuiltin("printf").first;
154154
if (printf_fn == nullptr) {
155155
#if GCC_AT_LEAST_6
156156
// In newer GCC versions (i.e., GCC 6+), function attributes are part of the
@@ -183,7 +183,7 @@ llvm::Value *CodeGen::Printf(const std::string &format,
183183
llvm::Value *CodeGen::Memcmp(llvm::Value *ptr1, llvm::Value *ptr2,
184184
llvm::Value *len) {
185185
static constexpr char kMemcmpFnName[] = "memcmp";
186-
auto *memcmp_fn = LookupBuiltin(kMemcmpFnName);
186+
auto *memcmp_fn = LookupBuiltin(kMemcmpFnName).first;
187187
if (memcmp_fn == nullptr) {
188188
#if GCC_AT_LEAST_6
189189
// In newer GCC versions (i.e., GCC 6+), function attributes are part of the
@@ -311,7 +311,7 @@ llvm::Function *CodeGen::RegisterBuiltin(const std::string &fn_name,
311311
llvm::FunctionType *fn_type,
312312
void *func_impl) {
313313
// Check if this is already registered as a built in, quit if to
314-
auto *builtin = LookupBuiltin(fn_name);
314+
auto *builtin = LookupBuiltin(fn_name).first;
315315
if (builtin != nullptr) {
316316
return builtin;
317317
}
@@ -332,6 +332,10 @@ llvm::Type *CodeGen::LookupType(const std::string &name) const {
332332
return GetModule().getTypeByName(name);
333333
}
334334

335+
std::pair<llvm::Function *, CodeContext::FuncPtr> CodeGen::LookupBuiltin(const std::string &name) const {
336+
return code_context_.LookupBuiltin(name);
337+
};
338+
335339
llvm::Value *CodeGen::GetState() const {
336340
auto *func_builder = code_context_.GetCurrentFunction();
337341
PELOTON_ASSERT(func_builder != nullptr);
@@ -346,6 +350,20 @@ uint64_t CodeGen::SizeOf(llvm::Type *type) const {
346350
return size != 0 ? size : 1;
347351
}
348352

353+
std::string CodeGen::Dump(const llvm::Value *value) {
354+
std::string string;
355+
llvm::raw_string_ostream llvm_stream(string);
356+
llvm_stream << *value;
357+
return llvm_stream.str();
358+
}
359+
360+
std::string CodeGen::Dump(llvm::Type *type) {
361+
std::string string;
362+
llvm::raw_string_ostream llvm_stream(string);
363+
llvm_stream << *type;
364+
return llvm_stream.str();
365+
}
366+
349367
uint64_t CodeGen::ElementOffset(llvm::Type *type, uint32_t element_idx) const {
350368
PELOTON_ASSERT(llvm::isa<llvm::StructType>(type));
351369
auto &data_layout = code_context_.GetDataLayout();

src/codegen/compilation_context.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,17 +97,13 @@ void CompilationContext::GeneratePlan(Query &query,
9797
}
9898

9999
// Next, we prepare the query statement with the functions we've generated
100-
Query::QueryFunctions funcs = {
101-
.init_func = init, .plan_func = plan, .tear_down_func = tear_down};
102-
bool prepared = query.Prepare(funcs);
103-
if (!prepared) {
104-
throw Exception{"There was an error preparing the compiled query"};
105-
}
100+
Query::LLVMFunctions funcs = {init, plan, tear_down};
101+
query.Prepare(funcs);
106102

107103
// We're done
108104
if (stats != nullptr) {
109105
timer.Stop();
110-
stats->jit_ms = timer.GetDuration();
106+
stats->optimize_ms = timer.GetDuration();
111107
}
112108
}
113109

0 commit comments

Comments
 (0)