Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
fsaintjacques committed Jan 22, 2020
1 parent a70a591 commit 63c3c1f
Show file tree
Hide file tree
Showing 21 changed files with 678 additions and 709 deletions.
2 changes: 1 addition & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Checks: 'bugprone-*,cert-*,clang-analyzer-*,cppcoreguidelines-*,google-*,modernize-*performance-*,readability-*'
Checks: 'bugprone-*,cert-*,clang-analyzer-*,cppcoreguidelines-*,-cppcoreguidelines-special-member-functions,google-*,modernize-*performance-*,readability-*,-readability-convert-member-functions-to-static'
CheckOptions:
- key: readability-braces-around-statements.ShortStatementLines
value: '1'
Expand Down
81 changes: 48 additions & 33 deletions include/jitmap/query/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <jitmap/size.h>
#include <jitmap/util/exception.h>
#include <jitmap/util/pimpl.h>

namespace llvm {
class LLVMContext;
Expand All @@ -34,6 +35,9 @@ class CompilerException : public Exception {
using Exception::Exception;
};

// Signature of generated functions
typedef void (*DenseEvalFn)(const BitsetWordType**, BitsetWordType*);

struct CompilerOptions {
// Controls LLVM optimization level (-O0, -O1, -O2, -O3). Anything above 3
// will be clamped to 3.
Expand All @@ -50,53 +54,64 @@ struct CompilerOptions {
std::string cpu = "";
};

class Query;
class Expr;

// The QueryIRCodeGen class generates LLVM IR for query expression on dense
// bitmaps. The QueryIRCodeGen is backed by a single llvm::Module where each
// Query object is represented by a single llvm::Function.
class QueryIRCodeGen {
class JitEngineImpl;
// The JitEngine class transforms IR queries into executable functions.
class JitEngine : util::Pimpl<JitEngineImpl> {
public:
QueryIRCodeGen(const std::string& module_name);
QueryIRCodeGen(QueryIRCodeGen&&);
~QueryIRCodeGen();
// Create a JitEngine.
//
// \param[in] options, see `CompilerOptions` documentation.
//
// \return a JitEngine
static std::shared_ptr<JitEngine> Make(CompilerOptions options = {});

// Compile a query expression into the module.
//
// - The query's name must be unique within the QueryIRCodeGen object.
// - The generated function is not executable as-is, it is only the LLVM IR
// representation.
// Takes an expression, lowers it to LLVM's IR. Pass the IR module to the
// internal jit engine which compiles it into assembly. Inject an executable
// function symbol in the current process. See `Lookup` in order to retrieve
// a function pointer to this symbol.
//
// \param[in] query, the query to compile into LLVM IR.
// \param[in] name, the query name, will be used in the generated symbol name.
// The name must be unique with regards to previously
// compiled queries.
// \param[in] expr, the query expression.
//
// \throws CompilerException if any errors is encountered.
void Compile(const Query& query);
void Compile(const std::string& name, const Expr& expression);

// Compile a query expression into the module.
template <typename Ptr>
void Compile(const Ptr& query) {
JITMAP_PRE_NE(query, nullptr);
Compile(*query);
}

// Finalize and consume as a module and context.
// Lower a query expression to LLVM's IR representation.
//
// This method is used for debugging. An executable symbol is _not_ generated
// with this function, see `Compile`.
//
// The QueryIRCodeGen must be moved to invoke this function, e.g.
// \param[in] name, the query name, will be used in the generated symbol name.
// \param[in] expr, the query expression.
//
// auto [mod_, ctx_] = std::move(query_compiler).Finish();
// \return the IR of the compiled function.
//
// The move is required because the module and context ownership are
// transferred to the caller. Instead of resetting the internal state, the
// caller must create a new QueryIRCodeGen.
using ModuleAndContext =
std::pair<std::unique_ptr<llvm::Module>, std::unique_ptr<llvm::LLVMContext>>;
ModuleAndContext Finish() &&;
// \throws CompilerException if any errors is encountered.
std::string CompileIR(const std::string& name, const Expr& expression);

private:
class Impl;
std::unique_ptr<Impl> impl_;
// Lookup a query
DenseEvalFn LookupUserQuery(const std::string& query_name);

// Return the LLVM name for the host CPU.
//
// This is the string given to `-march/-mtune/-mcpu`. See
// http:https://llvm.org/doxygen/Host_8h_source.html for more information.
std::string GetTargetCPU() const;

QueryIRCodeGen(const QueryIRCodeGen&) = delete;
// Return the LLVM target triple for the host.
//
// The format is ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT. See
// http:https://llvm.org/doxygen/Triple_8h_source.html for more information.
std::string GetTargetTriple() const;

private:
explicit JitEngine(CompilerOptions options);
};

} // namespace query
Expand Down
41 changes: 21 additions & 20 deletions include/jitmap/query/expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ class Expr {
virtual ~Expr() {}

protected:
Expr(Type type) : type_(type) {}
Type type_;
explicit Expr(Type type) : type_(type) {}

private:
Type type_;

// Use Copy()
Expr(const Expr&) = delete;
};
Expand All @@ -87,12 +88,12 @@ class OpExpr {};

class UnaryOpExpr : public OpExpr {
public:
UnaryOpExpr(Expr* expr) : operand_(expr) {}
explicit UnaryOpExpr(Expr* expr) : operand_(expr) {}

Expr* operand() const { return operand_; }
void SetOperand(Expr* expr) { operand_ = expr; }

protected:
private:
Expr* operand_;
};

Expand All @@ -106,7 +107,7 @@ class BinaryOpExpr : public OpExpr {
Expr* right_operand() const { return right_operand_; }
void SetRightOperand(Expr* right) { right_operand_ = right; }

protected:
private:
Expr* left_operand_;
Expr* right_operand_;
};
Expand All @@ -122,7 +123,7 @@ class FullBitmapExpr final : public BaseExpr<Expr::FULL_LITERAL>, public Literal
// References a Bitmap by name
class VariableExpr final : public BaseExpr<Expr::VARIABLE> {
public:
VariableExpr(std::string name) : name_(std::move(name)) {}
explicit VariableExpr(std::string name) : name_(std::move(name)) {}

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

Expand Down Expand Up @@ -190,39 +191,39 @@ template <typename Visitor>
auto Expr::Visit(Visitor&& v) const {
switch (type()) {
case EMPTY_LITERAL:
return v(static_cast<const EmptyBitmapExpr*>(this));
return v(dynamic_cast<const EmptyBitmapExpr*>(this));
case FULL_LITERAL:
return v(static_cast<const FullBitmapExpr*>(this));
return v(dynamic_cast<const FullBitmapExpr*>(this));
case VARIABLE:
return v(static_cast<const VariableExpr*>(this));
return v(dynamic_cast<const VariableExpr*>(this));
case NOT_OPERATOR:
return v(static_cast<const NotOpExpr*>(this));
return v(dynamic_cast<const NotOpExpr*>(this));
case AND_OPERATOR:
return v(static_cast<const AndOpExpr*>(this));
return v(dynamic_cast<const AndOpExpr*>(this));
case OR_OPERATOR:
return v(static_cast<const OrOpExpr*>(this));
return v(dynamic_cast<const OrOpExpr*>(this));
case XOR_OPERATOR:
return v(static_cast<const XorOpExpr*>(this));
return v(dynamic_cast<const XorOpExpr*>(this));
}
}

template <typename Visitor>
auto Expr::Visit(Visitor&& v) {
switch (type()) {
case EMPTY_LITERAL:
return v(static_cast<EmptyBitmapExpr*>(this));
return v(dynamic_cast<EmptyBitmapExpr*>(this));
case FULL_LITERAL:
return v(static_cast<FullBitmapExpr*>(this));
return v(dynamic_cast<FullBitmapExpr*>(this));
case VARIABLE:
return v(static_cast<VariableExpr*>(this));
return v(dynamic_cast<VariableExpr*>(this));
case NOT_OPERATOR:
return v(static_cast<NotOpExpr*>(this));
return v(dynamic_cast<NotOpExpr*>(this));
case AND_OPERATOR:
return v(static_cast<AndOpExpr*>(this));
return v(dynamic_cast<AndOpExpr*>(this));
case OR_OPERATOR:
return v(static_cast<OrOpExpr*>(this));
return v(dynamic_cast<OrOpExpr*>(this));
case XOR_OPERATOR:
return v(static_cast<XorOpExpr*>(this));
return v(dynamic_cast<XorOpExpr*>(this));
}
}

Expand Down
67 changes: 0 additions & 67 deletions include/jitmap/query/jit.h

This file was deleted.

13 changes: 6 additions & 7 deletions include/jitmap/query/matcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,12 @@
namespace jitmap {
namespace query {

// An expression matcher
// The Matcher interface is used to recognize patterns in expressions.
class Matcher {
public:
virtual bool Match(const Expr& expr) const = 0;
bool Match(Expr* expr) const {
if (!expr) return false;
return Match(*expr);
return (expr != nullptr) && Match(*expr);
}

bool operator()(const Expr& expr) const { return Match(expr); }
Expand All @@ -44,9 +43,9 @@ class TypeMatcher final : public Matcher {
using Type = Expr::Type;

// Construct a TypeMatcher matching a single type.
TypeMatcher(Type type);
explicit TypeMatcher(Type type);
// Construct a TypeMatcher matching a set of types.
TypeMatcher(const std::vector<Expr::Type>& types);
explicit TypeMatcher(const std::vector<Expr::Type>& types);
TypeMatcher(const std::initializer_list<Expr::Type>& types);

bool Match(const Expr& expr) const override;
Expand All @@ -68,7 +67,7 @@ class OperandMatcher final : public Matcher {
ALL,
};

OperandMatcher(Matcher* operand_matcher, Mode mode = ANY);
explicit OperandMatcher(Matcher* operand_matcher, Mode mode = ANY);

bool Match(const Expr& expr) const override;

Expand All @@ -89,7 +88,7 @@ class ChainMatcher final : public Matcher {
ALL,
};

ChainMatcher(const std::vector<Matcher*>& matchers, Mode mode = ALL);
explicit ChainMatcher(const std::vector<Matcher*>& matchers, Mode mode = ALL);
ChainMatcher(const std::initializer_list<Matcher*>& matchers, Mode mode = ALL);

bool Match(const Expr& expr) const override;
Expand Down
16 changes: 8 additions & 8 deletions include/jitmap/query/optimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,27 +74,27 @@ class OptimizationPass {
// Xor(1, e) -> Not(e)
class ConstantFolding final : public OptimizationPass {
public:
ConstantFolding(ExprBuilder* builder);
explicit ConstantFolding(ExprBuilder* builder);

Expr* Rewrite(const Expr& expr);
Expr* Rewrite(const Expr& expr) override;
};

// And(e, e) -> e
// Or(e, e) -> e
// Xor(e, e) -> 0
class SameOperandFolding final : public OptimizationPass {
public:
SameOperandFolding(ExprBuilder* builder);
explicit SameOperandFolding(ExprBuilder* builder);

Expr* Rewrite(const Expr& expr);
Expr* Rewrite(const Expr& expr) override;
};

// Not(Not(Not...(e)...))) -> e or Not(e) depending on occurence
class NotChainFolding final : public OptimizationPass {
public:
NotChainFolding(ExprBuilder* builder);
explicit NotChainFolding(ExprBuilder* builder);

Expr* Rewrite(const Expr& expr);
Expr* Rewrite(const Expr& expr) override;
};

struct OptimizerOptions {
Expand All @@ -105,7 +105,7 @@ struct OptimizerOptions {
};

bool HasOptimization(enum EnabledOptimizations optimization) {
return enabled_optimizations & optimization;
return (enabled_optimizations & optimization) != 0;
}

static constexpr uint64_t kDefaultOptimizations =
Expand All @@ -116,7 +116,7 @@ struct OptimizerOptions {

class Optimizer {
public:
Optimizer(ExprBuilder* builder, OptimizerOptions options = {});
explicit Optimizer(ExprBuilder* builder, OptimizerOptions options = {});

const OptimizerOptions& options() const { return options_; }

Expand Down
Loading

0 comments on commit 63c3c1f

Please sign in to comment.