Skip to content

Commit

Permalink
Fuse NamedExpr and IndexExpr into VariableExpr
Browse files Browse the repository at this point in the history
This changes removes the distinction between both. Callers will only be
exposed with named bitmaps (variables). Language now support
EmptyBitmapExpr and FullBitmapExpr via the `$0` and `$1` literals.
  • Loading branch information
fsaintjacques committed Dec 14, 2019
1 parent b7e8021 commit 8be6bbf
Show file tree
Hide file tree
Showing 18 changed files with 199 additions and 234 deletions.
7 changes: 6 additions & 1 deletion include/jitmap/query/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
namespace jitmap {
namespace query {

class CompilerException : public util::Exception {
public:
using Exception::Exception;
};

std::string Compile(Query& query);
}
} // namespace query
} // namespace jitmap
47 changes: 11 additions & 36 deletions include/jitmap/query/expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include <memory>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

Expand All @@ -15,8 +14,7 @@ class Expr {
// Literals
EMPTY_LITERAL = 0,
FULL_LITERAL,
NAMED_REF_LITERAL,
INDEX_REF_LITERAL,
VARIABLE,

// Operators
NOT_OPERATOR,
Expand All @@ -28,7 +26,7 @@ class Expr {
Type type() const { return type_; }

bool IsLiteral() const;
bool IsConstant() const;
bool IsVariable() const;
bool IsOperator() const;
bool IsUnaryOperator() const;
bool IsBinaryOperator() const;
Expand All @@ -43,7 +41,7 @@ class Expr {
std::string ToString() const;

// Return all Reference expressions.
std::unordered_set<std::string> CollectReferences() const;
std::vector<std::string> Variables() const;

virtual ~Expr() {}

Expand All @@ -63,8 +61,6 @@ class BaseExpr : public Expr {
};

class LiteralExpr {};
class ConstantExpr : public LiteralExpr {};
class ReferenceExpr : public LiteralExpr {};
class OpExpr {};

class UnaryOpExpr : public OpExpr {
Expand Down Expand Up @@ -92,36 +88,22 @@ class BinaryOpExpr : public OpExpr {
// Literal Expressions

// Represents an empty bitmap (all bits cleared)
class EmptyBitmapExpr final : public BaseExpr<Expr::EMPTY_LITERAL>,
public ConstantExpr {};
class EmptyBitmapExpr final : public BaseExpr<Expr::EMPTY_LITERAL>, public LiteralExpr {};

// Represents a full bitmap (all bits set)
class FullBitmapExpr final : public BaseExpr<Expr::FULL_LITERAL>, public ConstantExpr {};
class FullBitmapExpr final : public BaseExpr<Expr::FULL_LITERAL>, public LiteralExpr {};

// References a Bitmap by name
class NamedRefExpr final : public BaseExpr<Expr::NAMED_REF_LITERAL>,
public ReferenceExpr {
class VariableExpr final : public BaseExpr<Expr::VARIABLE> {
public:
NamedRefExpr(std::string name) : name_(std::move(name)) {}
VariableExpr(std::string name) : name_(std::move(name)) {}

const std::string& value() const { return name_; }

private:
std::string name_;
};

// References a Bitmap by index
class IndexRefExpr final : public BaseExpr<Expr::INDEX_REF_LITERAL>,
public ReferenceExpr {
public:
IndexRefExpr(size_t index) : index_(index) {}

size_t value() const { return index_; }

private:
size_t index_;
};

// Operators

class NotOpExpr final : public BaseExpr<Expr::NOT_OPERATOR>, public UnaryOpExpr {
Expand Down Expand Up @@ -156,13 +138,8 @@ class ExprBuilder {
return &full;
}

Expr* NamedRef(std::string name) { return Build<NamedRefExpr>(name); }
Expr* NamedRef(std::string_view name) { return Build<NamedRefExpr>(std::string(name)); }

Expr* IndexRef(size_t index) { return Build<IndexRefExpr>(index); }
Expr* IndexRef(std::string_view index) {
return Build<IndexRefExpr>(std::stoull(index.data()));
}
Expr* Var(std::string name) { return Build<VariableExpr>(name); }
Expr* Var(std::string_view name) { return Build<VariableExpr>(std::string(name)); }

Expr* Not(Expr* expr) { return Build<NotOpExpr>(expr); }

Expand Down Expand Up @@ -190,10 +167,8 @@ auto Expr::Visit(Visitor&& v) const {
return v(static_cast<const EmptyBitmapExpr&>(*this));
case FULL_LITERAL:
return v(static_cast<const FullBitmapExpr&>(*this));
case NAMED_REF_LITERAL:
return v(static_cast<const NamedRefExpr&>(*this));
case INDEX_REF_LITERAL:
return v(static_cast<const IndexRefExpr&>(*this));
case VARIABLE:
return v(static_cast<const VariableExpr&>(*this));
case NOT_OPERATOR:
return v(static_cast<const NotOpExpr&>(*this));
case AND_OPERATOR:
Expand Down
15 changes: 9 additions & 6 deletions include/jitmap/query/parser_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ namespace query {
class Token {
public:
enum Type {
INDEX_LITERAL,
NAMED_LITERAL,
EMPTY_LITERAL,
FULL_LITERAL,
VARIABLE,
LEFT_PARENTHESIS,
RIGHT_PARENTHESIS,
NOT_OPERATOR,
AND_OPERATOR,
OR_OPERATOR,
XOR_OPERATOR,
END_OF_STREAM,
LAST_TOKEN = END_OF_STREAM,
};

Token(Type type, std::string_view token) : type_(type), string_(std::move(token)) {}
Expand All @@ -38,8 +40,9 @@ class Token {
}

// Friendly builder methods
static Token IndexLit(std::string_view);
static Token NamedLit(std::string_view);
static Token Empty(std::string_view = "");
static Token Full(std::string_view = "");
static Token Var(std::string_view);
static Token LeftParen(std::string_view = "");
static Token RightParen(std::string_view = "");
static Token NotOp(std::string_view = "");
Expand Down Expand Up @@ -67,8 +70,8 @@ class Lexer {
char Consume();
char Consume(char expected);

Token ConsumeIndexRef();
Token ConsumeNamedRef();
Token ConsumeLiteral();
Token ConsumeVariable();
Token ConsumeOperator();

size_t position_;
Expand Down
4 changes: 2 additions & 2 deletions include/jitmap/query/query.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class Query : public std::enable_shared_from_this<Query> {
void Optimize();
void Compile();

const std::unordered_set<std::string>& parameters() const { return parameters_; }
const std::vector<std::string>& parameters() const { return parameters_; }
const std::string& name() const { return name_; }
const Expr& expr() const { return *query_; }

Expand All @@ -39,7 +39,7 @@ class Query : public std::enable_shared_from_this<Query> {
std::optional<Expr*> optimized_query_;
Expr* query_;

std::unordered_set<std::string> parameters_;
std::vector<std::string> parameters_;

Query(std::string name, Expr* expr);
};
Expand Down
6 changes: 1 addition & 5 deletions include/jitmap/query/type_fwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,10 @@ namespace query {
class Expr;

class LiteralExpr;

class ConstantExpr;
class EmptyBitmapExpr;
class FullBitmapExpr;

class ReferenceExpr;
class NamedRefExpr;
class IndexRefExpr;
class VariableExpr;

class OpExpr;

Expand Down
22 changes: 2 additions & 20 deletions include/jitmap/query/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,10 @@ template <typename E, typename R = void>
using enable_if_literal = std::enable_if_t<is_literal<E>::value, R>;

template <typename E>
using is_constant = std::is_base_of<ConstantExpr, E>;
using is_variable = std::is_base_of<VariableExpr, E>;

template <typename E, typename R = void>
using enable_if_constant = std::enable_if_t<is_constant<E>::value, R>;

template <typename E>
using is_reference = std::is_base_of<ReferenceExpr, E>;

template <typename E, typename R = void>
using enable_if_reference = std::enable_if_t<is_reference<E>::value, R>;

template <typename E>
using is_named_ref = std::is_base_of<NamedRefExpr, E>;

template <typename E, typename R = void>
using enable_if_named_ref = std::enable_if_t<is_named_ref<E>::value, R>;

template <typename E>
using is_index_ref = std::is_base_of<IndexRefExpr, E>;

template <typename E, typename R = void>
using enable_if_index_ref = std::enable_if_t<is_index_ref<E>::value, R>;
using enable_if_variable = std::enable_if_t<is_variable<E>::value, R>;

template <typename E>
using is_op = std::is_base_of<OpExpr, E>;
Expand Down
33 changes: 26 additions & 7 deletions src/jitmap/query/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <llvm/IR/Type.h>
#include <llvm/Support/raw_ostream.h>

#include "jitmap/query/compiler.h"
#include "jitmap/query/query.h"
#include "jitmap/query/type_traits.h"

Expand All @@ -24,15 +25,20 @@ InputsOutputArguments PartitionFunctionArguments(llvm::Function* fn);
struct CompilerOptions {
uint64_t word_size() const { return kBitsPerContainer / scalar_width_; }

uint8_t vector_width_ = 4;
uint8_t vector_width_ = 1;
uint8_t scalar_width_ = 64;
};

struct ExprCodeGenVisitor {
llvm::Value* operator()(const IndexRefExpr& e) { return bitmaps[e.value()]; }
llvm::Value* operator()(const NamedRefExpr& e) { return nullptr; }
llvm::Value* operator()(const EmptyBitmapExpr& e) { return nullptr; }
llvm::Value* operator()(const FullBitmapExpr& e) { return nullptr; }
llvm::Value* operator()(const VariableExpr& e) { return FindBitmapByName(e.value()); }

llvm::Value* operator()(const EmptyBitmapExpr& e) {
return llvm::ConstantInt::get(vector_type, 0UL);
}

llvm::Value* operator()(const FullBitmapExpr& e) {
return llvm::ConstantInt::get(vector_type, UINT64_MAX);
}

llvm::Value* operator()(const NotOpExpr& e) {
auto operand = e.operand()->Visit(*this);
Expand All @@ -58,8 +64,16 @@ struct ExprCodeGenVisitor {
return builder.CreateXor(lhs, rhs);
}

std::vector<llvm::Value*>& bitmaps;
llvm::Value* FindBitmapByName(const std::string& name) {
auto result = bitmaps.find(name);
if (result == bitmaps.end())
throw CompilerException("Referenced bitmap '", name, "' not found.");
return result->second;
}

std::unordered_map<std::string, llvm::Value*>& bitmaps;
llvm::IRBuilder<>& builder;
llvm::Type* vector_type;
};

class QueryCompiler {
Expand Down Expand Up @@ -148,7 +162,12 @@ class QueryCompiler {
}

llvm::Value* ExprCodeGen(std::vector<llvm::Value*>& bitmaps) {
return query_.expr().Visit(ExprCodeGenVisitor{bitmaps, builder_});
std::unordered_map<std::string, llvm::Value*> keyed_bitmaps;
const auto& parameters = query_.parameters();
for (size_t i = 0; i < bitmaps.size(); i++) {
keyed_bitmaps.emplace(parameters[i], bitmaps[i]);
}
return query_.expr().Visit(ExprCodeGenVisitor{keyed_bitmaps, builder_, VectorType()});
}

llvm::FunctionType* FunctionTypeForArguments(size_t n_arguments) {
Expand Down
Loading

0 comments on commit 8be6bbf

Please sign in to comment.