LLVM API Documentation

SPUISelLowering.cpp File Reference

#include "SPURegisterNames.h"
#include "SPUISelLowering.h"
#include "SPUTargetMachine.h"
#include "SPUFrameInfo.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/CallingConv.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Intrinsics.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetOptions.h"
#include <map>
#include "SPUGenCallingConv.inc"

Include dependency graph for SPUISelLowering.cpp:

Go to the source code of this file.

Functions

const valtype_map_s * getValueTypeMapEntry (MVT VT)
SDValue ExpandLibCall (RTLIB::Libcall LC, SDValue Op, SelectionDAG &DAG, bool isSigned, SDValue &Hi, SPUTargetLowering &TLI)
 Expand a library call into an actual call DAG node.
static SDValue LowerLOAD (SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST)
 Custom lower loads for CellSPU.
static SDValue LowerSTORE (SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST)
 Custom lower stores for CellSPU.
SDValue LowerConstantPool (SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST)
 Generate the address of a constant pool entry.
static SDValue LowerJumpTable (SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST)
static SDValue LowerGlobalAddress (SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST)
static SDValue LowerConstantFP (SDValue Op, SelectionDAG &DAG)
 Custom lower double precision floating point constants.
static SDValue LowerFORMAL_ARGUMENTS (SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
static SDNode * isLSAAddress (SDValue Op, SelectionDAG &DAG)
static SDValue LowerCALL (SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST)
static SDValue LowerRET (SDValue Op, SelectionDAG &DAG, TargetMachine &TM)
static ConstantSDNode * getVecImm (SDNode *N)
static bool GetConstantBuildVectorBits (SDNode *BV, uint64_t VectorBits[2], uint64_t UndefBits[2])
static bool isConstantSplat (const uint64_t Bits128[2], const uint64_t Undef128[2], int MinSplatBits, uint64_t &SplatBits, uint64_t &SplatUndef, int &SplatSize)
SDValue LowerBUILD_VECTOR (SDValue Op, SelectionDAG &DAG)
 Lower a BUILD_VECTOR instruction creatively:.
static SDValue LowerVECTOR_SHUFFLE (SDValue Op, SelectionDAG &DAG)
static SDValue LowerSCALAR_TO_VECTOR (SDValue Op, SelectionDAG &DAG)
static SDValue LowerEXTRACT_VECTOR_ELT (SDValue Op, SelectionDAG &DAG)
static SDValue LowerINSERT_VECTOR_ELT (SDValue Op, SelectionDAG &DAG)
static SDValue LowerI8Math (SDValue Op, SelectionDAG &DAG, unsigned Opc, const TargetLowering &TLI)
static SDValue LowerByteImmed (SDValue Op, SelectionDAG &DAG)
 Lower byte immediate operations for v16i8 vectors:.
static SDValue LowerCTPOP (SDValue Op, SelectionDAG &DAG)
 Custom lowering for CTPOP (count population).
static SDValue LowerFP_TO_INT (SDValue Op, SelectionDAG &DAG, SPUTargetLowering &TLI)
 Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32.
static SDValue LowerINT_TO_FP (SDValue Op, SelectionDAG &DAG, SPUTargetLowering &TLI)
 Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32.
static SDValue LowerSETCC (SDValue Op, SelectionDAG &DAG, const TargetLowering &TLI)
 Lower ISD::SETCC.
static SDValue LowerSELECT_CC (SDValue Op, SelectionDAG &DAG, const TargetLowering &TLI)
 Lower ISD::SELECT_CC.
static SDValue LowerTRUNCATE (SDValue Op, SelectionDAG &DAG)
 Custom lower ISD::TRUNCATE.

Variables

std::map< unsigned, const char * > node_names
const valtype_map_s valtype_map []
const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0])


Function Documentation

SDValue @785::ExpandLibCall ( RTLIB::Libcall  LC,
SDValue  Op,
SelectionDAG &  DAG,
bool  isSigned,
SDValue &  Hi,
SPUTargetLowering &  TLI 
) [static]

static bool GetConstantBuildVectorBits ( SDNode *  BV,
uint64_t  VectorBits[2],
uint64_t  UndefBits[2] 
) [static]

const valtype_map_s* @785::getValueTypeMapEntry ( MVT  VT  )  [static]

Definition at line 61 of file SPUISelLowering.cpp.

References llvm::cerr(), llvm::MVT::getMVTString(), and valtype.

static ConstantSDNode* getVecImm ( SDNode *  N  )  [static]

static bool isConstantSplat ( const uint64_t  Bits128[2],
const uint64_t  Undef128[2],
int  MinSplatBits,
uint64_t &  SplatBits,
uint64_t &  SplatUndef,
int &  SplatSize 
) [static]

If this is a splat (repetition) of a value across the whole vector, return the smallest size that splats it. For example, "0x01010101010101..." is a splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and SplatSize = 1 byte.

Definition at line 1509 of file SPUISelLowering.cpp.

Referenced by LowerBUILD_VECTOR(), and LowerByteImmed().

static SDNode* isLSAAddress ( SDValue  Op,
SelectionDAG &  DAG 
) [static]

isLSAAddress - Return the immediate to use if the specified value is representable as a LSA address.

Definition at line 1038 of file SPUISelLowering.cpp.

References llvm::CallingConv::C, llvm::dyn_cast(), llvm::SelectionDAG::getConstant(), llvm::ConstantSDNode::getZExtValue(), and llvm::MVT::i32.

Referenced by LowerCALL().

SDValue LowerBUILD_VECTOR ( SDValue  Op,
SelectionDAG &  DAG 
)

static SDValue LowerByteImmed ( SDValue  Op,
SelectionDAG &  DAG 
) [static]

static SDValue LowerCALL ( SDValue  Op,
SelectionDAG &  DAG,
const SPUSubtarget *  ST 
) [static]

Definition at line 1051 of file SPUISelLowering.cpp.

References llvm::ISD::ADD, llvm::SPUISD::AFormAddr, Arg, llvm::SPUISD::CALL, Dest, llvm::SmallVectorImpl< T >::empty(), llvm::MVT::f32, llvm::MVT::f64, first, llvm::MVT::Flag, G, llvm::CallSDNode::getArg(), llvm::SPURegisterInfo::getArgRegs(), llvm::CallSDNode::getCallee(), llvm::SelectionDAG::getCALLSEQ_END(), llvm::SelectionDAG::getCALLSEQ_START(), llvm::CallSDNode::getChain(), llvm::SelectionDAG::getConstant(), llvm::SelectionDAG::getCopyFromReg(), llvm::SelectionDAG::getCopyToReg(), llvm::SelectionDAG::getIntPtrConstant(), llvm::SelectionDAG::getMergeValues(), llvm::SelectionDAG::getNode(), llvm::SDValue::getNode(), llvm::SPURegisterInfo::getNumArgRegs(), llvm::CallSDNode::getNumArgs(), llvm::TargetLowering::getPointerTy(), llvm::SelectionDAG::getRegister(), llvm::SDValue::getResNo(), llvm::MVT::getSimpleVT(), llvm::SelectionDAG::getStore(), llvm::SelectionDAG::getTargetExternalSymbol(), llvm::SelectionDAG::getTargetGlobalAddress(), llvm::SelectionDAG::getTargetLoweringInfo(), llvm::SDValue::getValue(), llvm::SDNode::getValueType(), llvm::SDValue::getValueType(), llvm::SelectionDAG::getVTList(), GV, llvm::MVT::i128, llvm::MVT::i16, llvm::MVT::i32, llvm::MVT::i64, llvm::MVT::i8, llvm::SPUISD::IndirectAddr, llvm::GlobalValue::isDeclaration(), isLSAAddress(), llvm::SPUFrameInfo::minStackSize(), llvm::MVT::Other, llvm::SPUISD::PCRelAddr, llvm::SmallVectorImpl< T >::push_back(), second, llvm::SmallVectorImpl< T >::size(), llvm::SPUFrameInfo::stackSlotSize(), llvm::ISD::TokenFactor, llvm::SPUSubtarget::usingLargeMem(), llvm::MVT::v16i8, llvm::MVT::v2f64, llvm::MVT::v2i64, llvm::MVT::v4f32, llvm::MVT::v4i32, and llvm::MVT::v8i16.

Referenced by llvm::SPUTargetLowering::LowerOperation(), and llvm::SparcTargetLowering::LowerOperation().

static SDValue LowerConstantFP ( SDValue  Op,
SelectionDAG &  DAG 
) [static]

SDValue LowerConstantPool ( SDValue  Op,
SelectionDAG &  DAG,
const SPUSubtarget *  ST 
)

static SDValue LowerCTPOP ( SDValue  Op,
SelectionDAG &  DAG 
) [static]

static SDValue LowerEXTRACT_VECTOR_ELT ( SDValue  Op,
SelectionDAG &  DAG 
) [static]

static SDValue LowerFORMAL_ARGUMENTS ( SDValue  Op,
SelectionDAG &  DAG,
int &  VarArgsFrameIndex 
) [static]

static SDValue LowerFP_TO_INT ( SDValue  Op,
SelectionDAG &  DAG,
SPUTargetLowering &  TLI 
) [static]

Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32.

f32->i32 passes through unchanged, whereas f64->i32 expands to a libcall. All conversions to i64 are expanded to a libcall.

Definition at line 2404 of file SPUISelLowering.cpp.

References llvm::PIC16ISD::Dummy, ExpandLibCall(), llvm::MVT::f64, llvm::ISD::FP_TO_SINT, llvm::RTLIB::getFPTOSINT(), llvm::RTLIB::getFPTOUINT(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::SDValue::getValueType(), llvm::MVT::i32, llvm::MVT::i64, and llvm::RTLIB::UNKNOWN_LIBCALL.

static SDValue LowerGlobalAddress ( SDValue  Op,
SelectionDAG &  DAG,
const SPUSubtarget *  ST 
) [static]

static SDValue LowerI8Math ( SDValue  Op,
SelectionDAG &  DAG,
unsigned  Opc,
const TargetLowering &  TLI 
) [static]

static SDValue LowerINSERT_VECTOR_ELT ( SDValue  Op,
SelectionDAG &  DAG 
) [static]

static SDValue LowerINT_TO_FP ( SDValue  Op,
SelectionDAG &  DAG,
SPUTargetLowering &  TLI 
) [static]

Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32.

i32->f32 passes through unchanged, whereas i32->f64 is expanded to a libcall. All conversions from i64 are expanded to a libcall.

Definition at line 2430 of file SPUISelLowering.cpp.

References llvm::PIC16ISD::Dummy, ExpandLibCall(), llvm::MVT::f64, llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::RTLIB::getSINTTOFP(), llvm::RTLIB::getUINTTOFP(), llvm::SDValue::getValueType(), llvm::MVT::i32, llvm::MVT::i64, llvm::ISD::SINT_TO_FP, and llvm::RTLIB::UNKNOWN_LIBCALL.

static SDValue LowerJumpTable ( SDValue  Op,
SelectionDAG &  DAG,
const SPUSubtarget *  ST 
) [static]

static SDValue LowerLOAD ( SDValue  Op,
SelectionDAG &  DAG,
const SPUSubtarget *  ST 
) [static]

Custom lower loads for CellSPU.

All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements within a 16-byte block, we have to rotate to extract the requested element.

For extending loads, we also want to ensure that the following sequence is emitted, e.g. for MVT::f32 extending load to MVT::f64:

%1  v16i8,ch = load
%2  v16i8,ch = rotate %1
%3  v4f8, ch = bitconvert %2
%4  f32      = vec2perfslot %3
%5  f64      = fp_extend %4

Definition at line 501 of file SPUISelLowering.cpp.

References llvm::ISD::ADD, llvm::SPUISD::AFormAddr, llvm::ISD::ANY_EXTEND, llvm::ISD::BIT_CONVERT, llvm::cerr(), llvm::MachineRegisterInfo::createVirtualRegister(), llvm::dyn_cast(), llvm::ISD::EXTLOAD, llvm::ISD::FP_EXTEND, llvm::LSBaseSDNode::getAddressingMode(), llvm::MemSDNode::getAlignment(), llvm::LoadSDNode::getBasePtr(), llvm::MemSDNode::getChain(), llvm::SelectionDAG::getConstant(), llvm::SelectionDAG::getCopyFromReg(), llvm::SelectionDAG::getCopyToReg(), llvm::LoadSDNode::getExtensionType(), llvm::SelectionDAG::getLoad(), llvm::SelectionDAG::getMachineFunction(), llvm::MemSDNode::getMemoryVT(), llvm::SelectionDAG::getNode(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::TargetLowering::getPointerTy(), llvm::MachineFunction::getRegInfo(), llvm::MVT::getSizeInBits(), llvm::MemSDNode::getSrcValue(), llvm::MemSDNode::getSrcValueOffset(), llvm::SelectionDAG::getTargetLoweringInfo(), llvm::SDValue::getValue(), llvm::SDValue::getValueType(), getValueTypeMapEntry(), llvm::MVT::getVectorVT(), llvm::SelectionDAG::getVTList(), llvm::SPUISD::Hi, llvm::MVT::i16, llvm::SPUISD::IndirectAddr, llvm::MVT::isFloatingPoint(), llvm::MemSDNode::isVolatile(), llvm::ISD::LAST_INDEXED_MODE, llvm::SPUISD::LDRESULT, llvm::SPUISD::Lo, MF, offset, llvm::MVT::Other, llvm::ISD::POST_DEC, llvm::ISD::POST_INC, llvm::ISD::PRE_DEC, llvm::ISD::PRE_INC, RegInfo, llvm::SPUISD::ROTBYTES_LEFT, llvm::ISD::SEXTLOAD, llvm::ISD::SIGN_EXTEND, llvm::ISD::UNINDEXED, llvm::MVT::v16i8, llvm::SPUISD::VEC2PREFSLOT, llvm::ISD::ZERO_EXTEND, and llvm::ISD::ZEXTLOAD.

Referenced by llvm::SPUTargetLowering::LowerOperation().

static SDValue LowerRET ( SDValue  Op,
SelectionDAG &  DAG,
TargetMachine &  TM 
) [static]

static SDValue LowerSCALAR_TO_VECTOR ( SDValue  Op,
SelectionDAG &  DAG 
) [static]

static SDValue LowerSELECT_CC ( SDValue  Op,
SelectionDAG &  DAG,
const TargetLowering &  TLI 
) [static]

Lower ISD::SELECT_CC.

ISD::SELECT_CC can (generally) be implemented directly on the SPU using the SELB instruction.

Note:
Need to revisit this in the future: if the code path through the true and false value computations is longer than the latency of a branch (6 cycles), then it would be more advantageous to branch and insert a new basic block and branch on the condition. However, this code does not make that assumption, given the simplisitc uses so far.

Definition at line 2587 of file SPUISelLowering.cpp.

References compare(), llvm::SelectionDAG::getNode(), llvm::SDValue::getOperand(), llvm::TargetLowering::getSetCCResultType(), llvm::SDValue::getValueType(), llvm::SPUISD::SELB, llvm::ISD::SETCC, and VT.

static SDValue LowerSETCC ( SDValue  Op,
SelectionDAG &  DAG,
const TargetLowering &  TLI 
) [static]

static SDValue LowerSTORE ( SDValue  Op,
SelectionDAG &  DAG,
const SPUSubtarget *  ST 
) [static]

Custom lower stores for CellSPU.

All CellSPU stores are aligned to 16-byte boundaries, so for elements within a 16-byte block, we have to generate a shuffle to insert the requested element into its place, then store the resulting block.

Definition at line 660 of file SPUISelLowering.cpp.

References llvm::ISD::ADD, llvm::ISD::AssertSext, llvm::ISD::AssertZext, llvm::ISD::BIT_CONVERT, llvm::cerr(), llvm::MachineRegisterInfo::createVirtualRegister(), DEBUG_TYPE, llvm::DebugFlag, llvm::SelectionDAG::dump(), llvm::SDNode::dump(), llvm::dyn_cast(), llvm::LSBaseSDNode::getAddressingMode(), llvm::MemSDNode::getAlignment(), llvm::StoreSDNode::getBasePtr(), llvm::MemSDNode::getChain(), llvm::SelectionDAG::getConstant(), llvm::SelectionDAG::getCopyFromReg(), llvm::SelectionDAG::getCopyToReg(), llvm::SelectionDAG::getLoad(), llvm::SelectionDAG::getMachineFunction(), llvm::MemSDNode::getMemoryVT(), llvm::SDValue::getNode(), llvm::SelectionDAG::getNode(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::TargetLowering::getPointerTy(), llvm::MachineFunction::getRegInfo(), llvm::SelectionDAG::getRoot(), llvm::MVT::getSizeInBits(), llvm::MemSDNode::getSrcValue(), llvm::MemSDNode::getSrcValueOffset(), llvm::SelectionDAG::getStore(), llvm::SelectionDAG::getTargetLoweringInfo(), llvm::SDValue::getValue(), llvm::StoreSDNode::getValue(), llvm::MVT::getVectorVT(), llvm::SPUISD::IndirectAddr, llvm::isCurrentDebugType(), llvm::StoreSDNode::isTruncatingStore(), llvm::MemSDNode::isVolatile(), llvm::ISD::LAST_INDEXED_MODE, MF, offset, llvm::ISD::POST_DEC, llvm::ISD::POST_INC, llvm::ISD::PRE_DEC, llvm::ISD::PRE_INC, RegInfo, llvm::ISD::SCALAR_TO_VECTOR, llvm::SelectionDAG::setRoot(), llvm::SPUISD::SHUFB, llvm::SPUISD::SHUFFLE_MASK, llvm::ISD::UNINDEXED, llvm::MVT::v16i8, llvm::MVT::v4i32, and VT.

Referenced by llvm::SPUTargetLowering::LowerOperation().

static SDValue LowerTRUNCATE ( SDValue  Op,
SelectionDAG &  DAG 
) [static]

static SDValue LowerVECTOR_SHUFFLE ( SDValue  Op,
SelectionDAG &  DAG 
) [static]

LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on which the Cell can operate. The code inspects V3 to ascertain whether the permutation vector, V3, is monotonically increasing with one "exception" element, e.g., (0, 1, _, 3). If this is the case, then generate a SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool. In either case, the net result is going to eventually invoke SHUFB to permute/shuffle the bytes from V1 and V2.

Note:
SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate control word for byte/halfword/word insertion. This takes care of a single element move from V2 into V1.

SPUISD::SHUFB is eventually selected as Cell's shufb instructions.

Definition at line 1754 of file SPUISelLowering.cpp.

References llvm::ISD::BUILD_VECTOR, llvm::MachineRegisterInfo::createVirtualRegister(), llvm::MVT::f32, llvm::MVT::f64, llvm::SelectionDAG::getConstant(), llvm::SelectionDAG::getCopyFromReg(), llvm::SelectionDAG::getCopyToReg(), llvm::SelectionDAG::getEntryNode(), llvm::SelectionDAG::getMachineFunction(), llvm::SelectionDAG::getNode(), llvm::SDValue::getNumOperands(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::TargetLowering::getPointerTy(), llvm::MachineFunction::getRegInfo(), llvm::MVT::getSizeInBits(), llvm::SelectionDAG::getTargetConstant(), llvm::SelectionDAG::getTargetLoweringInfo(), llvm::SDValue::getValueType(), llvm::MVT::getVectorElementType(), llvm::MVT::getVectorNumElements(), llvm::MVT::i16, llvm::MVT::i32, llvm::MVT::i64, llvm::MVT::i8, MF, llvm::SmallVectorImpl< T >::push_back(), RegInfo, llvm::SPUISD::ROTBYTES_LEFT, llvm::SPUISD::SHUFB, llvm::SPUISD::SHUFFLE_MASK, llvm::SmallVectorImpl< T >::size(), llvm::ISD::UNDEF, V1, llvm::MVT::v16i8, and llvm::MVT::v4i32.

Referenced by llvm::SPUTargetLowering::LowerOperation().


Variable Documentation

const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]) [static]

Definition at line 59 of file SPUISelLowering.cpp.

std::map<unsigned, const char *> node_names [static]

Definition at line 40 of file SPUISelLowering.cpp.

const int prefslot_byte

Definition at line 45 of file SPUISelLowering.cpp.

const MVT valtype

Definition at line 44 of file SPUISelLowering.cpp.

Referenced by getValueTypeMapEntry().

const valtype_map_s valtype_map[] [static]

Initial value:

 {
    { MVT::i1,   3 },
    { MVT::i8,   3 },
    { MVT::i16,  2 },
    { MVT::i32,  0 },
    { MVT::f32,  0 },
    { MVT::i64,  0 },
    { MVT::f64,  0 },
    { MVT::i128, 0 }
  }

Definition at line 48 of file SPUISelLowering.cpp.