llvm/llvm/include/llvm/CodeGen/IndirectThunks.h

//===---- IndirectThunks.h - Indirect thunk insertion helpers ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Contains a base ThunkInserter class that simplifies injection of MI thunks
/// as well as a default implementation of MachineFunctionPass wrapping
/// several `ThunkInserter`s for targets to extend.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_INDIRECTTHUNKS_H
#define LLVM_CODEGEN_INDIRECTTHUNKS_H

#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"

namespace llvm {

/// This class assists in inserting MI thunk functions into the module and
/// rewriting the existing machine functions to call these thunks.
///
/// One of the common cases is implementing security mitigations that involve
/// replacing some machine code patterns with calls to special thunk functions.
///
/// Inserting a module pass late in the codegen pipeline may increase memory
/// usage, as it serializes the transformations and forces preceding passes to
/// produce machine code for all functions before running the module pass.
/// For that reason, ThunkInserter can be driven by a MachineFunctionPass by
/// passing one MachineFunction at a time to its `run(MMI, MF)` method.
/// Then, the derived class should
/// * call createThunkFunction from its insertThunks method exactly once for
///   each of the thunk functions to be inserted
/// * populate the thunk in its populateThunk method
///
/// Note that if some other pass is responsible for rewriting the functions,
/// the insertThunks method may simply create all possible thunks at once,
/// probably postponed until the first occurrence of possibly affected MF.
///
/// Alternatively, insertThunks method can rewrite MF by itself and only insert
/// the thunks being called. In that case InsertedThunks variable can be used
/// to track which thunks were already inserted.
///
/// In any case, the thunk function has to be inserted on behalf of some other
/// function and then populated on its own "iteration" later - this is because
/// MachineFunctionPass will see the newly created functions, but they first
/// have to go through the preceding passes from the same pass manager,
/// possibly even through the instruction selector.
//
// FIXME Maybe implement a documented and less surprising way of modifying
//       the module from a MachineFunctionPass that is restricted to inserting
//       completely new functions to the module.
template <typename Derived, typename InsertedThunksTy = bool>
class ThunkInserter {};

template <typename Derived, typename InsertedThunksTy>
void ThunkInserter<Derived, InsertedThunksTy>::createThunkFunction(
    MachineModuleInfo &MMI, StringRef Name, bool Comdat,
    StringRef TargetAttrs) {}

template <typename Derived, typename InsertedThunksTy>
bool ThunkInserter<Derived, InsertedThunksTy>::run(MachineModuleInfo &MMI,
                                                   MachineFunction &MF) {}

/// Basic implementation of MachineFunctionPass wrapping one or more
/// `ThunkInserter`s passed as type parameters.
template <typename... Inserters>
class ThunkInserterPass : public MachineFunctionPass {};

} // namespace llvm

#endif