Skip to content

Commit

Permalink
codegen: Initial framework changes to emit hl-mlir and llvm ir
Browse files Browse the repository at this point in the history
  • Loading branch information
kumarak committed Jan 26, 2025
1 parent 496874b commit d9ffbc3
Show file tree
Hide file tree
Showing 29 changed files with 1,190 additions and 441 deletions.
4 changes: 3 additions & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ Checks: "*,\
-google-build-using-namespace, \
-cppcoreguidelines-owning-memory, \
-readability-identifier-length, \
-readability-function-cognitive-complexity "
-readability-function-cognitive-complexity, \
-cppcoreguidelines-pro-type-const-cast, \
-clang-tidycppcoreguidelines-avoid-const-or-ref-data-members "
WarningsAsErrors: ''
CheckOptions:
- key: 'bugprone-argument-comment.StrictMode'
Expand Down
19 changes: 9 additions & 10 deletions include/patchestry/AST/ASTConsumer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#pragma once

#include "patchestry/Util/Options.hpp"
#include <functional>
#include <memory>
#include <unordered_map>
Expand All @@ -23,7 +24,6 @@
#include <clang/Sema/Sema.h>
#include <llvm/Support/raw_ostream.h>

#include <patchestry/AST/Codegen.hpp>
#include <patchestry/AST/TypeBuilder.hpp>
#include <patchestry/Ghidra/JsonDeserialize.hpp>
#include <patchestry/Ghidra/PcodeOperations.hpp>
Expand All @@ -38,16 +38,16 @@ namespace patchestry::ast {
{
public:
explicit PcodeASTConsumer(
clang::CompilerInstance &ci, Program &prog, std::string &outfile
clang::CompilerInstance &ci, Program &prog, patchestry::Options &opts
)
: program(prog)
, ci(ci)
, outfile(outfile)
, codegen(std::make_unique< CodeGenerator >(ci))
, type_builder(std::make_unique< TypeBuilder >(ci.getASTContext())) {}
: options(opts), program(prog), ci(ci), type_builder(nullptr) {}

void HandleTranslationUnit(clang::ASTContext &ctx) override;

const std::unordered_map< void *, std::string > &locations(void) const {
return location_map;
}

private:
void set_sema_context(clang::DeclContext *dc);

Expand All @@ -63,11 +63,10 @@ namespace patchestry::ast {

clang::Sema &sema(void) const { return ci.get().getSema(); }

const patchestry::Options &options;

std::reference_wrapper< Program > program;
std::reference_wrapper< clang::CompilerInstance > ci;

std::string outfile;
std::unique_ptr< CodeGenerator > codegen;
std::unique_ptr< TypeBuilder > type_builder;

std::unordered_map< std::string, clang::FunctionDecl * > function_declarations;
Expand Down
46 changes: 0 additions & 46 deletions include/patchestry/AST/Codegen.hpp

This file was deleted.

3 changes: 2 additions & 1 deletion include/patchestry/AST/OperationBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ namespace patchestry::ast {
* occurs.
*/
clang::Expr *perform_explicit_cast(
clang::ASTContext &ctx, clang::Expr *expr, clang::QualType to_type
clang::ASTContext &ctx, clang::Expr *expr, clang::QualType to_type,
const std::string &location_key
);

clang::Stmt *create_varnode(
Expand Down
14 changes: 13 additions & 1 deletion include/patchestry/AST/TypeBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ namespace patchestry::ast {
static constexpr uint32_t num_bits_in_byte = 8U;
static constexpr uint32_t num_bits_uint = 32U;

explicit TypeBuilder(clang::ASTContext &ctx) : context(ctx), serialized_types({}) {}
explicit TypeBuilder(
clang::ASTContext &ctx, std::unordered_map< void *, std::string > &locations
)
: location_map(locations), context(ctx), serialized_types({}) {}

TypeBuilder &operator=(const TypeBuilder &) = delete;
TypeBuilder(const TypeBuilder &) = delete;
Expand All @@ -34,6 +37,13 @@ namespace patchestry::ast {

virtual ~TypeBuilder() = default;

template< typename T >
void set_location_key(T *pointer, const std::string &key) {
if (!location_map.get().contains(pointer)) {
location_map.get().emplace(pointer, key);
}
}

/**
* @brief Provides access to the serialized type map.
*
Expand Down Expand Up @@ -199,6 +209,8 @@ namespace patchestry::ast {

std::unordered_map< std::string, clang::Decl * > missing_type_definition;

std::reference_wrapper< std::unordered_map< void *, std::string > > location_map;

std::reference_wrapper< clang::ASTContext > context;
SerializedTypeMap serialized_types;
};
Expand Down
110 changes: 110 additions & 0 deletions include/patchestry/Codegen/Codegen.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2024, Trail of Bits, Inc.
*
* This source code is licensed in accordance with the terms specified in
* the LICENSE file found in the root directory of this source tree.
*/

#pragma once

#include "patchestry/Util/Options.hpp"
#include <mlir/IR/MLIRContext.h>
#include <unordered_map>

#include <clang/AST/ASTContext.h>
#include <clang/Frontend/CompilerInstance.h>
#include <mlir/Pass/PassRegistry.h>

#include <vast/Frontend/FrontendAction.hpp>
#include <vast/Frontend/Options.hpp>
#include <vast/Frontend/Targets.hpp>

namespace llvm {
class raw_fd_ostream;
} // namespace llvm

namespace patchestry::codegen {

using LocationMap = std::unordered_map< void *, std::string >;

class MLIRRegistryInitializer
{
public:
explicit MLIRRegistryInitializer(mlir::DialectRegistry &registry);
};

class CodegenInitializer
{
public:
// Delete copy and move constructors and assignment operators
CodegenInitializer(const CodegenInitializer &) = delete;
CodegenInitializer &operator=(const CodegenInitializer &) = delete;
CodegenInitializer(CodegenInitializer &&) noexcept = delete;
CodegenInitializer &operator=(CodegenInitializer &&) noexcept = delete;

// Public static method to access the singleton instance
static CodegenInitializer &getInstance() {
static CodegenInitializer instance(0);
return instance;
}

inline mlir::MLIRContext &context() const noexcept { return ctx; }

~CodegenInitializer();

private:
explicit CodegenInitializer(int /*unused*/);

// Members
mlir::DialectRegistry registry;
MLIRRegistryInitializer registry_initializer;
mutable mlir::MLIRContext ctx;
};

class CodeGenerator

{
public:
explicit CodeGenerator(clang::CompilerInstance &ci) : opts(vast::cc::options(ci)) {}

CodeGenerator(const CodeGenerator &) = delete;
CodeGenerator &operator=(const CodeGenerator &) = delete;
CodeGenerator(CodeGenerator &&) noexcept = delete;
CodeGenerator &operator=(CodeGenerator &&) noexcept = delete;

virtual ~CodeGenerator() = default;

void emit_tower(
clang::ASTContext &actx, const LocationMap &locations,
const patchestry::Options &options
);

void emit_source_ir(
clang::ASTContext &actx, const LocationMap &locations,
const patchestry::Options &options
);

private:
void process_mlir_module(
clang::ASTContext &actx, vast::cc::target_dialect target, vast::mlir_module mod
);

void emit_mlir_after_pipeline(
clang::ASTContext &actx, vast::mlir_module mod, const patchestry::Options &options
);

void emit_llvmir(
clang::ASTContext &actx, vast::mlir_module mod, const patchestry::Options &options
);

void emit_asm(
clang::ASTContext &actx, vast::mlir_module mod, const patchestry::Options &options
);

std::optional< vast::owning_mlir_module_ref >
emit_mlir(clang::ASTContext &ctx, const LocationMap &locations);

vast::cc::action_options opts;
};

} // namespace patchestry::codegen
47 changes: 47 additions & 0 deletions include/patchestry/Codegen/MetaGenerator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2024, Trail of Bits, Inc.
*
* This source code is licensed in accordance with the terms specified in
* the LICENSE file found in the root directory of this source tree.
*/

#pragma once

#include <clang/AST/ASTContext.h>
#include <mlir/IR/MLIRContext.h>

#define GAP_ENABLE_COROUTINES
#include <vast/CodeGen/CodeGenMetaGenerator.hpp>

#include <patchestry/Codegen/Codegen.hpp>

namespace patchestry::codegen {

struct MetaGen final : vast::cg::meta_generator
{
MetaGen(clang::ASTContext *actx, mlir::MLIRContext *mctx, const LocationMap &locs);

void *raw_pointer(const clang::Decl *decl) const;

void *raw_pointer(const clang::Stmt *stmt) const;

void *raw_pointer(const clang::Expr *expr) const;

mlir::Location location(const clang::Decl *decl) const override;

mlir::Location location(const clang::Stmt *stmt) const override;

mlir::Location location(const clang::Expr *expr) const override;

private:
uint64_t address_from_location(const std::string &str, char delimiter) const;

mlir::Location location(void *data, const clang::SourceLocation &loc) const;

clang::ASTContext *actx;

mlir::MLIRContext *mctx;
const LocationMap &locations;
};

} // namespace patchestry::codegen
31 changes: 31 additions & 0 deletions include/patchestry/Codegen/PassInstrumentation.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2024, Trail of Bits, Inc.
*
* This source code is licensed in accordance with the terms specified in
* the LICENSE file found in the root directory of this source tree.
*/

#pragma once

#include <mlir/InitAllPasses.h>
#include <mlir/Pass/Pass.h>
#include <mlir/Pass/PassManager.h>
#include <mlir/Pass/PassRegistry.h>

namespace patchestry::codegen {

class PassInstrumentation : public mlir::PassInstrumentation
{
public:
explicit PassInstrumentation(bool enable_location_transform = false)
: location_transform(enable_location_transform) {}

void runAfterPass(mlir::Pass *pass, mlir::Operation *op) override;

void runBeforePass(mlir::Pass *pass, mlir::Operation *op) override;

private:
bool location_transform;
};

} // namespace patchestry::codegen
Loading

0 comments on commit d9ffbc3

Please sign in to comment.