llvm/llvm/include/llvm/SandboxIR/SandboxIR.h

//===- SandboxIR.h ----------------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
// Sandbox IR is a lightweight overlay transactional IR on top of LLVM IR.
// Features:
// - You can save/rollback the state of the IR at any time.
// - Any changes made to Sandbox IR will automatically update the underlying
//   LLVM IR so both IRs are always in sync.
// - Feels like LLVM IR, similar API.
//
// SandboxIR forms a class hierarchy that resembles that of LLVM IR
// but is in the `sandboxir` namespace:
//
// namespace sandboxir {
//
// Value -+- Argument
//        |
//        +- BasicBlock
//        |
//        +- User ------+- Constant ------ Function
//                      |
//                      +- Instruction -+- BinaryOperator
//                                      |
//                                      +- BranchInst
//                                      |
//                                      +- CastInst --------+- AddrSpaceCastInst
//                                      |                   |
//                                      |                   +- BitCastInst
//                                      |                   |
//                                      |                   +- FPExtInst
//                                      |                   |
//                                      |                   +- FPToSIInst
//                                      |                   |
//                                      |                   +- FPToUIInst
//                                      |                   |
//                                      |                   +- FPTruncInst
//                                      |                   |
//                                      |                   +- IntToPtrInst
//                                      |                   |
//                                      |                   +- PtrToIntInst
//                                      |                   |
//                                      |                   +- SExtInst
//                                      |                   |
//                                      |                   +- SIToFPInst
//                                      |                   |
//                                      |                   +- TruncInst
//                                      |                   |
//                                      |                   +- UIToFPInst
//                                      |                   |
//                                      |                   +- ZExtInst
//                                      |
//                                      +- CallBase --------+- CallBrInst
//                                      |                   |
//                                      |                   +- CallInst
//                                      |                   |
//                                      |                   +- InvokeInst
//                                      |
//                                      +- CmpInst ---------+- ICmpInst
//                                      |                   |
//                                      |                   +- FCmpInst
//                                      |
//                                      +- ExtractElementInst
//                                      |
//                                      +- GetElementPtrInst
//                                      |
//                                      +- InsertElementInst
//                                      |
//                                      +- OpaqueInst
//                                      |
//                                      +- PHINode
//                                      |
//                                      +- ReturnInst
//                                      |
//                                      +- SelectInst
//                                      |
//                                      +- ShuffleVectorInst
//                                      |
//                                      +- ExtractValueInst
//                                      |
//                                      +- InsertValueInst
//                                      |
//                                      +- StoreInst
//                                      |
//                                      +- UnaryInstruction -+- LoadInst
//                                      |                    |
//                                      |                    +- CastInst
//                                      |
//                                      +- UnaryOperator
//                                      |
//                                      +- UnreachableInst
//
// Use
//
// } // namespace sandboxir
//

#ifndef LLVM_SANDBOXIR_SANDBOXIR_H
#define LLVM_SANDBOXIR_SANDBOXIR_H

#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/SandboxIR/Tracker.h"
#include "llvm/SandboxIR/Type.h"
#include "llvm/SandboxIR/Use.h"
#include "llvm/Support/raw_ostream.h"
#include <iterator>

namespace llvm {

namespace sandboxir {

class BasicBlock;
class ConstantInt;
class ConstantFP;
class ConstantAggregateZero;
class ConstantPointerNull;
class PoisonValue;
class BlockAddress;
class DSOLocalEquivalent;
class ConstantTokenNone;
class GlobalValue;
class GlobalObject;
class GlobalIFunc;
class Context;
class Function;
class Instruction;
class VAArgInst;
class FreezeInst;
class FenceInst;
class SelectInst;
class ExtractElementInst;
class InsertElementInst;
class ShuffleVectorInst;
class ExtractValueInst;
class InsertValueInst;
class BranchInst;
class UnaryInstruction;
class LoadInst;
class ReturnInst;
class StoreInst;
class User;
class UnreachableInst;
class Value;
class CallBase;
class CallInst;
class InvokeInst;
class CallBrInst;
class LandingPadInst;
class FuncletPadInst;
class CatchPadInst;
class CleanupPadInst;
class CatchReturnInst;
class CleanupReturnInst;
class GetElementPtrInst;
class CastInst;
class PossiblyNonNegInst;
class PtrToIntInst;
class BitCastInst;
class AllocaInst;
class ResumeInst;
class CatchSwitchInst;
class SwitchInst;
class UnaryOperator;
class BinaryOperator;
class PossiblyDisjointInst;
class AtomicRMWInst;
class AtomicCmpXchgInst;
class CmpInst;
class ICmpInst;
class FCmpInst;

/// Iterator for the `Use` edges of a User's operands.
/// \Returns the operand `Use` when dereferenced.
class OperandUseIterator {};

/// Iterator for the `Use` edges of a Value's users.
/// \Returns a `Use` when dereferenced.
class UserUseIterator {};

/// A SandboxIR Value has users. This is the base class.
class Value {};

/// Argument of a sandboxir::Function.
class Argument : public sandboxir::Value {};

/// A sandboxir::User has operands.
class User : public Value {};

class Constant : public sandboxir::User {};

// TODO: This should inherit from ConstantData.
class ConstantInt : public Constant {};

// TODO: This should inherit from ConstantData.
class ConstantFP final : public Constant {};

/// Base class for aggregate constants (with operands).
class ConstantAggregate : public Constant {};

class ConstantArray final : public ConstantAggregate {};

class ConstantStruct final : public ConstantAggregate {};

class ConstantVector final : public ConstantAggregate {};

// TODO: Inherit from ConstantData.
class ConstantAggregateZero final : public Constant {};

// TODO: Inherit from ConstantData.
class ConstantPointerNull final : public Constant {};

// TODO: Inherit from ConstantData.
class UndefValue : public Constant {};

class PoisonValue final : public UndefValue {};

class GlobalValue : public Constant {};

class GlobalObject : public GlobalValue {};

/// Provides API functions, like getIterator() and getReverseIterator() to
/// GlobalIFunc, Function, GlobalVariable and GlobalAlias. In LLVM IR these are
/// provided by ilist_node.
template <typename GlobalT, typename LLVMGlobalT, typename ParentT,
          typename LLVMParentT>
class GlobalWithNodeAPI : public ParentT {};

class GlobalIFunc final
    : public GlobalWithNodeAPI<GlobalIFunc, llvm::GlobalIFunc, GlobalObject,
                               llvm::GlobalObject> {};

class BlockAddress final : public Constant {};

class DSOLocalEquivalent final : public Constant {};

// TODO: This should inherit from ConstantData.
class ConstantTokenNone final : public Constant {};

/// Iterator for `Instruction`s in a `BasicBlock.
/// \Returns an sandboxir::Instruction & when derereferenced.
class BBIterator {};

/// Contains a list of sandboxir::Instruction's.
class BasicBlock : public Value {};

/// A sandboxir::User with operands, opcode and linked with previous/next
/// instructions in an instruction list.
class Instruction : public sandboxir::User {};

/// Instructions that contain a single LLVM Instruction can inherit from this.
template <typename LLVMT> class SingleLLVMInstructionImpl : public Instruction {};

class FenceInst : public SingleLLVMInstructionImpl<llvm::FenceInst> {};

class SelectInst : public SingleLLVMInstructionImpl<llvm::SelectInst> {};

class InsertElementInst final
    : public SingleLLVMInstructionImpl<llvm::InsertElementInst> {};

class ExtractElementInst final
    : public SingleLLVMInstructionImpl<llvm::ExtractElementInst> {};

class ShuffleVectorInst final
    : public SingleLLVMInstructionImpl<llvm::ShuffleVectorInst> {};

class InsertValueInst
    : public SingleLLVMInstructionImpl<llvm::InsertValueInst> {};

class BranchInst : public SingleLLVMInstructionImpl<llvm::BranchInst> {};

/// An abstract class, parent of unary instructions.
class UnaryInstruction
    : public SingleLLVMInstructionImpl<llvm::UnaryInstruction> {};

class ExtractValueInst : public UnaryInstruction {};

class VAArgInst : public UnaryInstruction {};

class FreezeInst : public UnaryInstruction {};

class LoadInst final : public UnaryInstruction {};

class StoreInst final : public SingleLLVMInstructionImpl<llvm::StoreInst> {};

class UnreachableInst final : public Instruction {};

class ReturnInst final : public SingleLLVMInstructionImpl<llvm::ReturnInst> {};

class CallBase : public SingleLLVMInstructionImpl<llvm::CallBase> {};

class CallInst final : public CallBase {};

class InvokeInst final : public CallBase {};

class CallBrInst final : public CallBase {};

class LandingPadInst : public SingleLLVMInstructionImpl<llvm::LandingPadInst> {};

class FuncletPadInst : public SingleLLVMInstructionImpl<llvm::FuncletPadInst> {};

class CatchPadInst : public FuncletPadInst {};

class CleanupPadInst : public FuncletPadInst {};

class CatchReturnInst
    : public SingleLLVMInstructionImpl<llvm::CatchReturnInst> {};

class CleanupReturnInst
    : public SingleLLVMInstructionImpl<llvm::CleanupReturnInst> {};

class GetElementPtrInst final
    : public SingleLLVMInstructionImpl<llvm::GetElementPtrInst> {};

class CatchSwitchInst
    : public SingleLLVMInstructionImpl<llvm::CatchSwitchInst> {};

class ResumeInst : public SingleLLVMInstructionImpl<llvm::ResumeInst> {};

class SwitchInst : public SingleLLVMInstructionImpl<llvm::SwitchInst> {};

class UnaryOperator : public UnaryInstruction {};

class BinaryOperator : public SingleLLVMInstructionImpl<llvm::BinaryOperator> {};

/// An or instruction, which can be marked as "disjoint", indicating that the
/// inputs don't have a 1 in the same bit position. Meaning this instruction
/// can also be treated as an add.
class PossiblyDisjointInst : public BinaryOperator {};

class AtomicRMWInst : public SingleLLVMInstructionImpl<llvm::AtomicRMWInst> {};

class AtomicCmpXchgInst
    : public SingleLLVMInstructionImpl<llvm::AtomicCmpXchgInst> {};

class AllocaInst final : public UnaryInstruction {};

class CastInst : public UnaryInstruction {};

/// Instruction that can have a nneg flag (zext/uitofp).
class PossiblyNonNegInst : public CastInst {};

// Helper class to simplify stamping out CastInst subclasses.
template <Instruction::Opcode Op> class CastInstImpl : public CastInst {};

class TruncInst final : public CastInstImpl<Instruction::Opcode::Trunc> {};
class ZExtInst final : public CastInstImpl<Instruction::Opcode::ZExt> {};
class SExtInst final : public CastInstImpl<Instruction::Opcode::SExt> {};
class FPTruncInst final : public CastInstImpl<Instruction::Opcode::FPTrunc> {};
class FPExtInst final : public CastInstImpl<Instruction::Opcode::FPExt> {};
class UIToFPInst final : public CastInstImpl<Instruction::Opcode::UIToFP> {};
class SIToFPInst final : public CastInstImpl<Instruction::Opcode::SIToFP> {};
class FPToUIInst final : public CastInstImpl<Instruction::Opcode::FPToUI> {};
class FPToSIInst final : public CastInstImpl<Instruction::Opcode::FPToSI> {};
class IntToPtrInst final : public CastInstImpl<Instruction::Opcode::IntToPtr> {};
class PtrToIntInst final : public CastInstImpl<Instruction::Opcode::PtrToInt> {};
class BitCastInst final : public CastInstImpl<Instruction::Opcode::BitCast> {};
class AddrSpaceCastInst final
    : public CastInstImpl<Instruction::Opcode::AddrSpaceCast> {};

class PHINode final : public SingleLLVMInstructionImpl<llvm::PHINode> {};

// Wraps a static function that takes a single Predicate parameter
// LLVMValType should be the type of the wrapped class
#define WRAP_STATIC_PREDICATE
// Wraps a member function that takes no parameters
// LLVMValType should be the type of the wrapped class
#define WRAP_MEMBER
// Wraps both--a common idiom in the CmpInst classes
#define WRAP_BOTH

class CmpInst : public SingleLLVMInstructionImpl<llvm::CmpInst> {};

class ICmpInst : public CmpInst {};

class FCmpInst : public CmpInst {};

#undef WRAP_STATIC_PREDICATE
#undef WRAP_MEMBER
#undef WRAP_BOTH

/// An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to
/// an OpaqueInstr.
class OpaqueInst : public SingleLLVMInstructionImpl<llvm::Instruction> {};

class Context {};

class Function : public GlobalWithNodeAPI<Function, llvm::Function,
                                          GlobalObject, llvm::GlobalObject> {};

} // namespace sandboxir
} // namespace llvm

#endif // LLVM_SANDBOXIR_SANDBOXIR_H