llvm/llvm/lib/CodeGen/TargetLoweringBase.cpp

//===- TargetLoweringBase.cpp - Implement the TargetLoweringBase class ----===//
//
// 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 implements the TargetLoweringBase class.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RuntimeLibcallUtil.h"
#include "llvm/CodeGen/StackMaps.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGenTypes/MachineValueType.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/Transforms/Utils/SizeOpts.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <iterator>
#include <string>
#include <tuple>
#include <utility>

usingnamespacellvm;

static cl::opt<bool> JumpIsExpensiveOverride(
    "jump-is-expensive", cl::init(false),
    cl::desc("Do not create extra branches to split comparison logic."),
    cl::Hidden);

static cl::opt<unsigned> MinimumJumpTableEntries
  ("min-jump-table-entries", cl::init(4), cl::Hidden,
   cl::desc("Set minimum number of entries to use a jump table."));

static cl::opt<unsigned> MaximumJumpTableSize
  ("max-jump-table-size", cl::init(UINT_MAX), cl::Hidden,
   cl::desc("Set maximum size of jump tables."));

/// Minimum jump table density for normal functions.
static cl::opt<unsigned>
    JumpTableDensity("jump-table-density", cl::init(10), cl::Hidden,
                     cl::desc("Minimum density for building a jump table in "
                              "a normal function"));

/// Minimum jump table density for -Os or -Oz functions.
static cl::opt<unsigned> OptsizeJumpTableDensity(
    "optsize-jump-table-density", cl::init(40), cl::Hidden,
    cl::desc("Minimum density for building a jump table in "
             "an optsize function"));

// FIXME: This option is only to test if the strict fp operation processed
// correctly by preventing mutating strict fp operation to normal fp operation
// during development. When the backend supports strict float operation, this
// option will be meaningless.
static cl::opt<bool> DisableStrictNodeMutation("disable-strictnode-mutation",
       cl::desc("Don't mutate strict-float node to a legalize node"),
       cl::init(false), cl::Hidden);

/// GetFPLibCall - Helper to return the right libcall for the given floating
/// point type, or UNKNOWN_LIBCALL if there is none.
RTLIB::Libcall RTLIB::getFPLibCall(EVT VT,
                                   RTLIB::Libcall Call_F32,
                                   RTLIB::Libcall Call_F64,
                                   RTLIB::Libcall Call_F80,
                                   RTLIB::Libcall Call_F128,
                                   RTLIB::Libcall Call_PPCF128) {}

/// getFPEXT - Return the FPEXT_*_* value for the given types, or
/// UNKNOWN_LIBCALL if there is none.
RTLIB::Libcall RTLIB::getFPEXT(EVT OpVT, EVT RetVT) {}

/// getFPROUND - Return the FPROUND_*_* value for the given types, or
/// UNKNOWN_LIBCALL if there is none.
RTLIB::Libcall RTLIB::getFPROUND(EVT OpVT, EVT RetVT) {}

/// getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or
/// UNKNOWN_LIBCALL if there is none.
RTLIB::Libcall RTLIB::getFPTOSINT(EVT OpVT, EVT RetVT) {}

/// getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or
/// UNKNOWN_LIBCALL if there is none.
RTLIB::Libcall RTLIB::getFPTOUINT(EVT OpVT, EVT RetVT) {}

/// getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or
/// UNKNOWN_LIBCALL if there is none.
RTLIB::Libcall RTLIB::getSINTTOFP(EVT OpVT, EVT RetVT) {}

/// getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or
/// UNKNOWN_LIBCALL if there is none.
RTLIB::Libcall RTLIB::getUINTTOFP(EVT OpVT, EVT RetVT) {}

RTLIB::Libcall RTLIB::getPOWI(EVT RetVT) {}

RTLIB::Libcall RTLIB::getLDEXP(EVT RetVT) {}

RTLIB::Libcall RTLIB::getFREXP(EVT RetVT) {}

RTLIB::Libcall RTLIB::getFSINCOS(EVT RetVT) {}

RTLIB::Libcall RTLIB::getOutlineAtomicHelper(const Libcall (&LC)[5][4],
                                             AtomicOrdering Order,
                                             uint64_t MemSize) {}

RTLIB::Libcall RTLIB::getOUTLINE_ATOMIC(unsigned Opc, AtomicOrdering Order,
                                        MVT VT) {}

RTLIB::Libcall RTLIB::getSYNC(unsigned Opc, MVT VT) {}

RTLIB::Libcall RTLIB::getMEMCPY_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize) {}

RTLIB::Libcall RTLIB::getMEMMOVE_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize) {}

RTLIB::Libcall RTLIB::getMEMSET_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize) {}

void RTLIB::initCmpLibcallCCs(ISD::CondCode *CmpLibcallCCs) {}

/// NOTE: The TargetMachine owns TLOF.
TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm)
    :{}

void TargetLoweringBase::initActions() {}

MVT TargetLoweringBase::getScalarShiftAmountTy(const DataLayout &DL,
                                               EVT) const {}

EVT TargetLoweringBase::getShiftAmountTy(EVT LHSTy,
                                         const DataLayout &DL) const {}

bool TargetLoweringBase::canOpTrap(unsigned Op, EVT VT) const {}

bool TargetLoweringBase::isFreeAddrSpaceCast(unsigned SrcAS,
                                             unsigned DestAS) const {}

unsigned TargetLoweringBase::getBitWidthForCttzElements(
    Type *RetTy, ElementCount EC, bool ZeroIsPoison,
    const ConstantRange *VScaleRange) const {}

void TargetLoweringBase::setJumpIsExpensive(bool isExpensive) {}

TargetLoweringBase::LegalizeKind
TargetLoweringBase::getTypeConversion(LLVMContext &Context, EVT VT) const {}

static unsigned getVectorTypeBreakdownMVT(MVT VT, MVT &IntermediateVT,
                                          unsigned &NumIntermediates,
                                          MVT &RegisterVT,
                                          TargetLoweringBase *TLI) {}

/// isLegalRC - Return true if the value types that can be represented by the
/// specified register class are all legal.
bool TargetLoweringBase::isLegalRC(const TargetRegisterInfo &TRI,
                                   const TargetRegisterClass &RC) const {}

/// Replace/modify any TargetFrameIndex operands with a targte-dependent
/// sequence of memory operands that is recognized by PrologEpilogInserter.
MachineBasicBlock *
TargetLoweringBase::emitPatchPoint(MachineInstr &InitialMI,
                                   MachineBasicBlock *MBB) const {}

/// findRepresentativeClass - Return the largest legal super-reg register class
/// of the register class for the specified type and its associated "cost".
// This function is in TargetLowering because it uses RegClassForVT which would
// need to be moved to TargetRegisterInfo and would necessitate moving
// isTypeLegal over as well - a massive change that would just require
// TargetLowering having a TargetRegisterInfo class member that it would use.
std::pair<const TargetRegisterClass *, uint8_t>
TargetLoweringBase::findRepresentativeClass(const TargetRegisterInfo *TRI,
                                            MVT VT) const {}

/// computeRegisterProperties - Once all of the register classes are added,
/// this allows us to compute derived properties we expose.
void TargetLoweringBase::computeRegisterProperties(
    const TargetRegisterInfo *TRI) {}

EVT TargetLoweringBase::getSetCCResultType(const DataLayout &DL, LLVMContext &,
                                           EVT VT) const {}

MVT::SimpleValueType TargetLoweringBase::getCmpLibcallReturnType() const {}

/// getVectorTypeBreakdown - Vector types are broken down into some number of
/// legal first class types.  For example, MVT::v8f32 maps to 2 MVT::v4f32
/// with Altivec or SSE1, or 8 promoted MVT::f64 values with the X86 FP stack.
/// Similarly, MVT::v2i64 turns into 4 MVT::i32 values with both PPC and X86.
///
/// This method returns the number of registers needed, and the VT for each
/// register.  It also returns the VT and quantity of the intermediate values
/// before they are promoted/expanded.
unsigned TargetLoweringBase::getVectorTypeBreakdown(LLVMContext &Context,
                                                    EVT VT, EVT &IntermediateVT,
                                                    unsigned &NumIntermediates,
                                                    MVT &RegisterVT) const {}

bool TargetLoweringBase::isSuitableForJumpTable(const SwitchInst *SI,
                                                uint64_t NumCases,
                                                uint64_t Range,
                                                ProfileSummaryInfo *PSI,
                                                BlockFrequencyInfo *BFI) const {}

MVT TargetLoweringBase::getPreferredSwitchConditionType(LLVMContext &Context,
                                                        EVT ConditionVT) const {}

/// Get the EVTs and ArgFlags collections that represent the legalized return
/// type of the given function.  This does not require a DAG or a return value,
/// and is suitable for use before any DAGs for the function are constructed.
/// TODO: Move this out of TargetLowering.cpp.
void llvm::GetReturnInfo(CallingConv::ID CC, Type *ReturnType,
                         AttributeList attr,
                         SmallVectorImpl<ISD::OutputArg> &Outs,
                         const TargetLowering &TLI, const DataLayout &DL) {}

/// getByValTypeAlignment - Return the desired alignment for ByVal aggregate
/// function arguments in the caller parameter area.  This is the actual
/// alignment, not its logarithm.
uint64_t TargetLoweringBase::getByValTypeAlignment(Type *Ty,
                                                   const DataLayout &DL) const {}

bool TargetLoweringBase::allowsMemoryAccessForAlignment(
    LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace,
    Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const {}

bool TargetLoweringBase::allowsMemoryAccessForAlignment(
    LLVMContext &Context, const DataLayout &DL, EVT VT,
    const MachineMemOperand &MMO, unsigned *Fast) const {}

bool TargetLoweringBase::allowsMemoryAccess(LLVMContext &Context,
                                            const DataLayout &DL, EVT VT,
                                            unsigned AddrSpace, Align Alignment,
                                            MachineMemOperand::Flags Flags,
                                            unsigned *Fast) const {}

bool TargetLoweringBase::allowsMemoryAccess(LLVMContext &Context,
                                            const DataLayout &DL, EVT VT,
                                            const MachineMemOperand &MMO,
                                            unsigned *Fast) const {}

bool TargetLoweringBase::allowsMemoryAccess(LLVMContext &Context,
                                            const DataLayout &DL, LLT Ty,
                                            const MachineMemOperand &MMO,
                                            unsigned *Fast) const {}

//===----------------------------------------------------------------------===//
//  TargetTransformInfo Helpers
//===----------------------------------------------------------------------===//

int TargetLoweringBase::InstructionOpcodeToISD(unsigned Opcode) const {}

Value *
TargetLoweringBase::getDefaultSafeStackPointerLocation(IRBuilderBase &IRB,
                                                       bool UseTLS) const {}

Value *
TargetLoweringBase::getSafeStackPointerLocation(IRBuilderBase &IRB) const {}

//===----------------------------------------------------------------------===//
//  Loop Strength Reduction hooks
//===----------------------------------------------------------------------===//

/// isLegalAddressingMode - Return true if the addressing mode represented
/// by AM is legal for this target, for a load/store of the specified type.
bool TargetLoweringBase::isLegalAddressingMode(const DataLayout &DL,
                                               const AddrMode &AM, Type *Ty,
                                               unsigned AS, Instruction *I) const {}

//===----------------------------------------------------------------------===//
//  Stack Protector
//===----------------------------------------------------------------------===//

// For OpenBSD return its special guard variable. Otherwise return nullptr,
// so that SelectionDAG handle SSP.
Value *TargetLoweringBase::getIRStackGuard(IRBuilderBase &IRB) const {}

// Currently only support "standard" __stack_chk_guard.
// TODO: add LOAD_STACK_GUARD support.
void TargetLoweringBase::insertSSPDeclarations(Module &M) const {}

// Currently only support "standard" __stack_chk_guard.
// TODO: add LOAD_STACK_GUARD support.
Value *TargetLoweringBase::getSDagStackGuard(const Module &M) const {}

Function *TargetLoweringBase::getSSPStackGuardCheck(const Module &M) const {}

unsigned TargetLoweringBase::getMinimumJumpTableEntries() const {}

void TargetLoweringBase::setMinimumJumpTableEntries(unsigned Val) {}

unsigned TargetLoweringBase::getMinimumJumpTableDensity(bool OptForSize) const {}

unsigned TargetLoweringBase::getMaximumJumpTableSize() const {}

void TargetLoweringBase::setMaximumJumpTableSize(unsigned Val) {}

bool TargetLoweringBase::isJumpTableRelative() const {}

Align TargetLoweringBase::getPrefLoopAlignment(MachineLoop *ML) const {}

unsigned TargetLoweringBase::getMaxPermittedBytesForAlignment(
    MachineBasicBlock *MBB) const {}

//===----------------------------------------------------------------------===//
//  Reciprocal Estimates
//===----------------------------------------------------------------------===//

/// Get the reciprocal estimate attribute string for a function that will
/// override the target defaults.
static StringRef getRecipEstimateForFunc(MachineFunction &MF) {}

/// Construct a string for the given reciprocal operation of the given type.
/// This string should match the corresponding option to the front-end's
/// "-mrecip" flag assuming those strings have been passed through in an
/// attribute string. For example, "vec-divf" for a division of a vXf32.
static std::string getReciprocalOpName(bool IsSqrt, EVT VT) {}

/// Return the character position and value (a single numeric character) of a
/// customized refinement operation in the input string if it exists. Return
/// false if there is no customized refinement step count.
static bool parseRefinementStep(StringRef In, size_t &Position,
                                uint8_t &Value) {}

/// For the input attribute string, return one of the ReciprocalEstimate enum
/// status values (enabled, disabled, or not specified) for this operation on
/// the specified data type.
static int getOpEnabled(bool IsSqrt, EVT VT, StringRef Override) {}

/// For the input attribute string, return the customized refinement step count
/// for this operation on the specified data type. If the step count does not
/// exist, return the ReciprocalEstimate enum value for unspecified.
static int getOpRefinementSteps(bool IsSqrt, EVT VT, StringRef Override) {}

int TargetLoweringBase::getRecipEstimateSqrtEnabled(EVT VT,
                                                    MachineFunction &MF) const {}

int TargetLoweringBase::getRecipEstimateDivEnabled(EVT VT,
                                                   MachineFunction &MF) const {}

int TargetLoweringBase::getSqrtRefinementSteps(EVT VT,
                                               MachineFunction &MF) const {}

int TargetLoweringBase::getDivRefinementSteps(EVT VT,
                                              MachineFunction &MF) const {}

bool TargetLoweringBase::isLoadBitCastBeneficial(
    EVT LoadVT, EVT BitcastVT, const SelectionDAG &DAG,
    const MachineMemOperand &MMO) const {}

void TargetLoweringBase::finalizeLowering(MachineFunction &MF) const {}

MachineMemOperand::Flags TargetLoweringBase::getLoadMemOperandFlags(
    const LoadInst &LI, const DataLayout &DL, AssumptionCache *AC,
    const TargetLibraryInfo *LibInfo) const {}

MachineMemOperand::Flags
TargetLoweringBase::getStoreMemOperandFlags(const StoreInst &SI,
                                            const DataLayout &DL) const {}

MachineMemOperand::Flags
TargetLoweringBase::getAtomicMemOperandFlags(const Instruction &AI,
                                             const DataLayout &DL) const {}

Instruction *TargetLoweringBase::emitLeadingFence(IRBuilderBase &Builder,
                                                  Instruction *Inst,
                                                  AtomicOrdering Ord) const {}

Instruction *TargetLoweringBase::emitTrailingFence(IRBuilderBase &Builder,
                                                   Instruction *Inst,
                                                   AtomicOrdering Ord) const {}

//===----------------------------------------------------------------------===//
//  GlobalISel Hooks
//===----------------------------------------------------------------------===//

bool TargetLoweringBase::shouldLocalize(const MachineInstr &MI,
                                        const TargetTransformInfo *TTI) const {}