llvm/llvm/include/llvm/IR/Operator.h

//===-- llvm/Operator.h - Operator utility subclass -------------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file defines various classes for working with Instructions and
// ConstantExprs.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_IR_OPERATOR_H
#define LLVM_IR_OPERATOR_H

#include "llvm/ADT/MapVector.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/FMF.h"
#include "llvm/IR/GEPNoWrapFlags.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include <cstddef>
#include <optional>

namespace llvm {

/// This is a utility class that provides an abstraction for the common
/// functionality between Instructions and ConstantExprs.
class Operator : public User {};

/// Utility class for integer operators which may exhibit overflow - Add, Sub,
/// Mul, and Shl. It does not include SDiv, despite that operator having the
/// potential for overflow.
class OverflowingBinaryOperator : public Operator {};

template <>
struct OperandTraits<OverflowingBinaryOperator>
    : public FixedNumOperandTraits<OverflowingBinaryOperator, 2> {};

DEFINE_TRANSPARENT_OPERAND_ACCESSORS()

/// A udiv or sdiv instruction, which can be marked as "exact",
/// indicating that no bits are destroyed.
class PossiblyExactOperator : public Operator {};

template <>
struct OperandTraits<PossiblyExactOperator>
    : public FixedNumOperandTraits<PossiblyExactOperator, 2> {};

DEFINE_TRANSPARENT_OPERAND_ACCESSORS()

/// Utility class for floating point operations which can have
/// information about relaxed accuracy requirements attached to them.
class FPMathOperator : public Operator {};

/// A helper template for defining operators for individual opcodes.
template<typename SuperClass, unsigned Opc>
class ConcreteOperator : public SuperClass {};

class AddOperator
  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {};
class SubOperator
  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {};
class MulOperator
  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {};
class ShlOperator
  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {};

class AShrOperator
  : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {};
class LShrOperator
  : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {};

class GEPOperator
    : public ConcreteOperator<Operator, Instruction::GetElementPtr> {};

template <>
struct OperandTraits<GEPOperator>
    : public VariadicOperandTraits<GEPOperator, 1> {};

DEFINE_TRANSPARENT_OPERAND_ACCESSORS()

class PtrToIntOperator
    : public ConcreteOperator<Operator, Instruction::PtrToInt> {};

template <>
struct OperandTraits<PtrToIntOperator>
    : public FixedNumOperandTraits<PtrToIntOperator, 1> {};

DEFINE_TRANSPARENT_OPERAND_ACCESSORS()

class BitCastOperator
    : public ConcreteOperator<Operator, Instruction::BitCast> {};

template <>
struct OperandTraits<BitCastOperator>
    : public FixedNumOperandTraits<BitCastOperator, 1> {};

DEFINE_TRANSPARENT_OPERAND_ACCESSORS()

class AddrSpaceCastOperator
    : public ConcreteOperator<Operator, Instruction::AddrSpaceCast> {};

template <>
struct OperandTraits<AddrSpaceCastOperator>
    : public FixedNumOperandTraits<AddrSpaceCastOperator, 1> {};

DEFINE_TRANSPARENT_OPERAND_ACCESSORS()

} // end namespace llvm

#endif // LLVM_IR_OPERATOR_H