Implement a bunch more TargetSelectionDAGInfo infrastructure.

Move EmitTargetCodeForMemcpy, EmitTargetCodeForMemset, and
EmitTargetCodeForMemmove out of TargetLowering and into
SelectionDAGInfo to exercise this.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103481 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2010-05-11 17:31:57 +00:00
parent 651804c3d6
commit ff7a562751
61 changed files with 626 additions and 463 deletions

View File

@ -36,6 +36,7 @@ class MDNode;
class SDNodeOrdering;
class SDDbgValue;
class TargetLowering;
class TargetSelectionDAGInfo;
template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
private:
@ -131,6 +132,7 @@ void checkForCycles(const SelectionDAG *DAG);
class SelectionDAG {
const TargetMachine &TM;
const TargetLowering &TLI;
const TargetSelectionDAGInfo &TSI;
MachineFunction *MF;
FunctionLoweringInfo &FLI;
LLVMContext *Context;
@ -201,6 +203,7 @@ public:
MachineFunction &getMachineFunction() const { return *MF; }
const TargetMachine &getTarget() const { return TM; }
const TargetLowering &getTargetLoweringInfo() const { return TLI; }
const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; }
FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; }
LLVMContext *getContext() const {return Context; }

View File

@ -1194,61 +1194,6 @@ public:
return SDValue(); // this is here to silence compiler errors
}
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
/// memcpy. This can be used by targets to provide code sequences for cases
/// that don't fit the target's parameters for simple loads/stores and can be
/// more efficient than using a library call. This function can return a null
/// SDValue if the target declines to use custom code and a different
/// lowering strategy should be used.
///
/// If AlwaysInline is true, the size is constant and the target should not
/// emit any calls and is strongly encouraged to attempt to emit inline code
/// even if it is beyond the usual threshold because this intrinsic is being
/// expanded in a place where calls are not feasible (e.g. within the prologue
/// for another call). If the target chooses to decline an AlwaysInline
/// request here, legalize will resort to using simple loads and stores.
virtual SDValue
EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Op1, SDValue Op2,
SDValue Op3, unsigned Align, bool isVolatile,
bool AlwaysInline,
const Value *DstSV, uint64_t DstOff,
const Value *SrcSV, uint64_t SrcOff) const {
return SDValue();
}
/// EmitTargetCodeForMemmove - Emit target-specific code that performs a
/// memmove. This can be used by targets to provide code sequences for cases
/// that don't fit the target's parameters for simple loads/stores and can be
/// more efficient than using a library call. This function can return a null
/// SDValue if the target declines to use custom code and a different
/// lowering strategy should be used.
virtual SDValue
EmitTargetCodeForMemmove(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Op1, SDValue Op2,
SDValue Op3, unsigned Align, bool isVolatile,
const Value *DstSV, uint64_t DstOff,
const Value *SrcSV, uint64_t SrcOff) const {
return SDValue();
}
/// EmitTargetCodeForMemset - Emit target-specific code that performs a
/// memset. This can be used by targets to provide code sequences for cases
/// that don't fit the target's parameters for simple stores and can be more
/// efficient than using a library call. This function can return a null
/// SDValue if the target declines to use custom code and a different
/// lowering strategy should be used.
virtual SDValue
EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Op1, SDValue Op2,
SDValue Op3, unsigned Align, bool isVolatile,
const Value *DstSV, uint64_t DstOff) const {
return SDValue();
}
/// LowerOperationWrapper - This callback is invoked by the type legalizer
/// to legalize nodes with an illegal operand type but legal result types.
/// It replaces the LowerOperation callback in the type Legalizer.

View File

@ -16,8 +16,13 @@
#ifndef LLVM_TARGET_TARGETSELECTIONDAGINFO_H
#define LLVM_TARGET_TARGETSELECTIONDAGINFO_H
#include "llvm/CodeGen/SelectionDAGNodes.h"
namespace llvm {
class TargetData;
class TargetMachine;
//===----------------------------------------------------------------------===//
/// TargetSelectionDAGLowering - Targets can subclass this to parameterize the
/// SelectionDAG lowering and instruction selection process.
@ -26,9 +31,69 @@ class TargetSelectionDAGInfo {
TargetSelectionDAGInfo(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT
void operator=(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT
const TargetData *TD;
protected:
const TargetData *getTargetData() const { return TD; }
public:
TargetSelectionDAGInfo();
explicit TargetSelectionDAGInfo(const TargetMachine &TM);
virtual ~TargetSelectionDAGInfo();
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
/// memcpy. This can be used by targets to provide code sequences for cases
/// that don't fit the target's parameters for simple loads/stores and can be
/// more efficient than using a library call. This function can return a null
/// SDValue if the target declines to use custom code and a different
/// lowering strategy should be used.
///
/// If AlwaysInline is true, the size is constant and the target should not
/// emit any calls and is strongly encouraged to attempt to emit inline code
/// even if it is beyond the usual threshold because this intrinsic is being
/// expanded in a place where calls are not feasible (e.g. within the prologue
/// for another call). If the target chooses to decline an AlwaysInline
/// request here, legalize will resort to using simple loads and stores.
virtual SDValue
EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Op1, SDValue Op2,
SDValue Op3, unsigned Align, bool isVolatile,
bool AlwaysInline,
const Value *DstSV, uint64_t DstOff,
const Value *SrcSV, uint64_t SrcOff) const {
return SDValue();
}
/// EmitTargetCodeForMemmove - Emit target-specific code that performs a
/// memmove. This can be used by targets to provide code sequences for cases
/// that don't fit the target's parameters for simple loads/stores and can be
/// more efficient than using a library call. This function can return a null
/// SDValue if the target declines to use custom code and a different
/// lowering strategy should be used.
virtual SDValue
EmitTargetCodeForMemmove(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Op1, SDValue Op2,
SDValue Op3, unsigned Align, bool isVolatile,
const Value *DstSV, uint64_t DstOff,
const Value *SrcSV, uint64_t SrcOff) const {
return SDValue();
}
/// EmitTargetCodeForMemset - Emit target-specific code that performs a
/// memset. This can be used by targets to provide code sequences for cases
/// that don't fit the target's parameters for simple stores and can be more
/// efficient than using a library call. This function can return a null
/// SDValue if the target declines to use custom code and a different
/// lowering strategy should be used.
virtual SDValue
EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Op1, SDValue Op2,
SDValue Op3, unsigned Align, bool isVolatile,
const Value *DstSV, uint64_t DstOff) const {
return SDValue();
}
};
} // end llvm namespace

View File

@ -33,6 +33,7 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetSelectionDAGInfo.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetIntrinsicInfo.h"
@ -790,7 +791,8 @@ unsigned SelectionDAG::getEVTAlignment(EVT VT) const {
// EntryNode could meaningfully have debug info if we can find it...
SelectionDAG::SelectionDAG(const TargetMachine &tm, FunctionLoweringInfo &fli)
: TM(tm), TLI(*tm.getTargetLowering()), FLI(fli),
: TM(tm), TLI(*tm.getTargetLowering()), TSI(*tm.getSelectionDAGInfo()),
FLI(fli),
EntryNode(ISD::EntryToken, DebugLoc(), getVTList(MVT::Other)),
Root(getEntryNode()), Ordering(0) {
AllNodes.push_back(&EntryNode);
@ -3536,7 +3538,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
// Then check to see if we should lower the memcpy with target-specific
// code. If the target chooses to do this, this is the next best.
SDValue Result =
TLI.EmitTargetCodeForMemcpy(*this, dl, Chain, Dst, Src, Size, Align,
TSI.EmitTargetCodeForMemcpy(*this, dl, Chain, Dst, Src, Size, Align,
isVol, AlwaysInline,
DstSV, DstSVOff, SrcSV, SrcSVOff);
if (Result.getNode())
@ -3601,7 +3603,7 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
// Then check to see if we should lower the memmove with target-specific
// code. If the target chooses to do this, this is the next best.
SDValue Result =
TLI.EmitTargetCodeForMemmove(*this, dl, Chain, Dst, Src, Size, Align, isVol,
TSI.EmitTargetCodeForMemmove(*this, dl, Chain, Dst, Src, Size, Align, isVol,
DstSV, DstSVOff, SrcSV, SrcSVOff);
if (Result.getNode())
return Result;
@ -3652,7 +3654,7 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
// Then check to see if we should lower the memset with target-specific
// code. If the target chooses to do this, this is the next best.
SDValue Result =
TLI.EmitTargetCodeForMemset(*this, dl, Chain, Dst, Src, Size, Align, isVol,
TSI.EmitTargetCodeForMemset(*this, dl, Chain, Dst, Src, Size, Align, isVol,
DstSV, DstSVOff);
if (Result.getNode())
return Result;

View File

@ -12,9 +12,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/Target/TargetSelectionDAGInfo.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
TargetSelectionDAGInfo::TargetSelectionDAGInfo() {
TargetSelectionDAGInfo::TargetSelectionDAGInfo(const TargetMachine &TM)
: TD(TM.getTargetData()) {
}
TargetSelectionDAGInfo::~TargetSelectionDAGInfo() {

View File

@ -2124,116 +2124,6 @@ SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
return FrameAddr;
}
SDValue
ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile, bool AlwaysInline,
const Value *DstSV,
uint64_t DstSVOff,
const Value *SrcSV,
uint64_t SrcSVOff) const {
// Do repeated 4-byte loads and stores. To be improved.
// This requires 4-byte alignment.
if ((Align & 3) != 0)
return SDValue();
// This requires the copy size to be a constant, preferrably
// within a subtarget-specific limit.
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
if (!ConstantSize)
return SDValue();
uint64_t SizeVal = ConstantSize->getZExtValue();
if (!AlwaysInline && SizeVal > getSubtarget()->getMaxInlineSizeThreshold())
return SDValue();
unsigned BytesLeft = SizeVal & 3;
unsigned NumMemOps = SizeVal >> 2;
unsigned EmittedNumMemOps = 0;
EVT VT = MVT::i32;
unsigned VTSize = 4;
unsigned i = 0;
const unsigned MAX_LOADS_IN_LDM = 6;
SDValue TFOps[MAX_LOADS_IN_LDM];
SDValue Loads[MAX_LOADS_IN_LDM];
uint64_t SrcOff = 0, DstOff = 0;
// Emit up to MAX_LOADS_IN_LDM loads, then a TokenFactor barrier, then the
// same number of stores. The loads and stores will get combined into
// ldm/stm later on.
while (EmittedNumMemOps < NumMemOps) {
for (i = 0;
i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
Loads[i] = DAG.getLoad(VT, dl, Chain,
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
DAG.getConstant(SrcOff, MVT::i32)),
SrcSV, SrcSVOff + SrcOff, isVolatile, false, 0);
TFOps[i] = Loads[i].getValue(1);
SrcOff += VTSize;
}
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
for (i = 0;
i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
DAG.getConstant(DstOff, MVT::i32)),
DstSV, DstSVOff + DstOff, isVolatile, false, 0);
DstOff += VTSize;
}
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
EmittedNumMemOps += i;
}
if (BytesLeft == 0)
return Chain;
// Issue loads / stores for the trailing (1 - 3) bytes.
unsigned BytesLeftSave = BytesLeft;
i = 0;
while (BytesLeft) {
if (BytesLeft >= 2) {
VT = MVT::i16;
VTSize = 2;
} else {
VT = MVT::i8;
VTSize = 1;
}
Loads[i] = DAG.getLoad(VT, dl, Chain,
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
DAG.getConstant(SrcOff, MVT::i32)),
SrcSV, SrcSVOff + SrcOff, false, false, 0);
TFOps[i] = Loads[i].getValue(1);
++i;
SrcOff += VTSize;
BytesLeft -= VTSize;
}
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
i = 0;
BytesLeft = BytesLeftSave;
while (BytesLeft) {
if (BytesLeft >= 2) {
VT = MVT::i16;
VTSize = 2;
} else {
VT = MVT::i8;
VTSize = 1;
}
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
DAG.getConstant(DstOff, MVT::i32)),
DstSV, DstSVOff + DstOff, false, false, 0);
++i;
DstOff += VTSize;
BytesLeft -= VTSize;
}
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
}
/// ExpandBIT_CONVERT - If the target supports VFP, this function is called to
/// expand a bit convert where either the source or destination type is i64 to
/// use a VMOVDRR or VMOVRRD node. This should not be done when the non-i64

View File

@ -301,15 +301,6 @@ namespace llvm {
SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile, bool AlwaysInline,
const Value *DstSV,
uint64_t DstSVOff,
const Value *SrcSV,
uint64_t SrcSVOff) const;
SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,

View File

@ -12,11 +12,123 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "arm-selectiondag-info"
#include "ARMSelectionDAGInfo.h"
#include "ARMTargetMachine.h"
using namespace llvm;
ARMSelectionDAGInfo::ARMSelectionDAGInfo() {
ARMSelectionDAGInfo::ARMSelectionDAGInfo(const TargetMachine &TM)
: TargetSelectionDAGInfo(TM),
Subtarget(&TM.getSubtarget<ARMSubtarget>()) {
}
ARMSelectionDAGInfo::~ARMSelectionDAGInfo() {
}
SDValue
ARMSelectionDAGInfo::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile, bool AlwaysInline,
const Value *DstSV,
uint64_t DstSVOff,
const Value *SrcSV,
uint64_t SrcSVOff) const {
// Do repeated 4-byte loads and stores. To be improved.
// This requires 4-byte alignment.
if ((Align & 3) != 0)
return SDValue();
// This requires the copy size to be a constant, preferrably
// within a subtarget-specific limit.
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
if (!ConstantSize)
return SDValue();
uint64_t SizeVal = ConstantSize->getZExtValue();
if (!AlwaysInline && SizeVal > Subtarget->getMaxInlineSizeThreshold())
return SDValue();
unsigned BytesLeft = SizeVal & 3;
unsigned NumMemOps = SizeVal >> 2;
unsigned EmittedNumMemOps = 0;
EVT VT = MVT::i32;
unsigned VTSize = 4;
unsigned i = 0;
const unsigned MAX_LOADS_IN_LDM = 6;
SDValue TFOps[MAX_LOADS_IN_LDM];
SDValue Loads[MAX_LOADS_IN_LDM];
uint64_t SrcOff = 0, DstOff = 0;
// Emit up to MAX_LOADS_IN_LDM loads, then a TokenFactor barrier, then the
// same number of stores. The loads and stores will get combined into
// ldm/stm later on.
while (EmittedNumMemOps < NumMemOps) {
for (i = 0;
i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
Loads[i] = DAG.getLoad(VT, dl, Chain,
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
DAG.getConstant(SrcOff, MVT::i32)),
SrcSV, SrcSVOff + SrcOff, isVolatile, false, 0);
TFOps[i] = Loads[i].getValue(1);
SrcOff += VTSize;
}
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
for (i = 0;
i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
DAG.getConstant(DstOff, MVT::i32)),
DstSV, DstSVOff + DstOff, isVolatile, false, 0);
DstOff += VTSize;
}
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
EmittedNumMemOps += i;
}
if (BytesLeft == 0)
return Chain;
// Issue loads / stores for the trailing (1 - 3) bytes.
unsigned BytesLeftSave = BytesLeft;
i = 0;
while (BytesLeft) {
if (BytesLeft >= 2) {
VT = MVT::i16;
VTSize = 2;
} else {
VT = MVT::i8;
VTSize = 1;
}
Loads[i] = DAG.getLoad(VT, dl, Chain,
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
DAG.getConstant(SrcOff, MVT::i32)),
SrcSV, SrcSVOff + SrcOff, false, false, 0);
TFOps[i] = Loads[i].getValue(1);
++i;
SrcOff += VTSize;
BytesLeft -= VTSize;
}
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
i = 0;
BytesLeft = BytesLeftSave;
while (BytesLeft) {
if (BytesLeft >= 2) {
VT = MVT::i16;
VTSize = 2;
} else {
VT = MVT::i8;
VTSize = 1;
}
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
DAG.getConstant(DstOff, MVT::i32)),
DstSV, DstSVOff + DstOff, false, false, 0);
++i;
DstOff += VTSize;
BytesLeft -= VTSize;
}
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
}

View File

@ -19,9 +19,24 @@
namespace llvm {
class ARMSelectionDAGInfo : public TargetSelectionDAGInfo {
/// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
/// make the right decision when generating code for different targets.
const ARMSubtarget *Subtarget;
public:
ARMSelectionDAGInfo();
explicit ARMSelectionDAGInfo(const TargetMachine &TM);
~ARMSelectionDAGInfo();
virtual
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile, bool AlwaysInline,
const Value *DstSV,
uint64_t DstSVOff,
const Value *SrcSV,
uint64_t SrcSVOff) const;
};
}

View File

@ -62,7 +62,8 @@ ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT,
DataLayout(Subtarget.isAPCS_ABI() ?
std::string("e-p:32:32-f64:32:32-i64:32:32-n32") :
std::string("e-p:32:32-f64:64:64-i64:64:64-n32")),
TLInfo(*this) {
TLInfo(*this),
TSInfo(*this) {
}
ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT,
@ -76,7 +77,8 @@ ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT,
"i16:16:32-i8:8:32-i1:8:32-a:0:32-n32") :
std::string("e-p:32:32-f64:64:64-i64:64:64-"
"i16:16:32-i8:8:32-i1:8:32-a:0:32-n32")),
TLInfo(*this) {
TLInfo(*this),
TSInfo(*this) {
}

View File

@ -21,6 +21,7 @@
#include "ARMJITInfo.h"
#include "ARMSubtarget.h"
#include "ARMISelLowering.h"
#include "ARMSelectionDAGInfo.h"
#include "Thumb1InstrInfo.h"
#include "Thumb2InstrInfo.h"
#include "llvm/ADT/OwningPtr.h"
@ -63,6 +64,7 @@ class ARMTargetMachine : public ARMBaseTargetMachine {
ARMInstrInfo InstrInfo;
const TargetData DataLayout; // Calculates type size & alignment
ARMTargetLowering TLInfo;
ARMSelectionDAGInfo TSInfo;
public:
ARMTargetMachine(const Target &T, const std::string &TT,
const std::string &FS);
@ -75,6 +77,10 @@ public:
return &TLInfo;
}
virtual const ARMSelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
virtual const ARMInstrInfo *getInstrInfo() const { return &InstrInfo; }
virtual const TargetData *getTargetData() const { return &DataLayout; }
};
@ -88,6 +94,7 @@ class ThumbTargetMachine : public ARMBaseTargetMachine {
OwningPtr<ARMBaseInstrInfo> InstrInfo;
const TargetData DataLayout; // Calculates type size & alignment
ARMTargetLowering TLInfo;
ARMSelectionDAGInfo TSInfo;
public:
ThumbTargetMachine(const Target &T, const std::string &TT,
const std::string &FS);
@ -101,6 +108,10 @@ public:
return &TLInfo;
}
virtual const ARMSelectionDAGInfo *getSelectionDAGInfo() const {
return &TSInfo;
}
/// returns either Thumb1InstrInfo or Thumb2InstrInfo
virtual const ARMBaseInstrInfo *getInstrInfo() const {
return InstrInfo.get();

View File

@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "alpha-selectiondag-info"
#include "AlphaSelectionDAGInfo.h"
#include "AlphaTargetMachine.h"
using namespace llvm;
AlphaSelectionDAGInfo::AlphaSelectionDAGInfo() {
AlphaSelectionDAGInfo::AlphaSelectionDAGInfo(const AlphaTargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
AlphaSelectionDAGInfo::~AlphaSelectionDAGInfo() {

View File

@ -18,9 +18,11 @@
namespace llvm {
class AlphaTargetMachine;
class AlphaSelectionDAGInfo : public TargetSelectionDAGInfo {
public:
AlphaSelectionDAGInfo();
explicit AlphaSelectionDAGInfo(const AlphaTargetMachine &TM);
~AlphaSelectionDAGInfo();
};

View File

@ -32,7 +32,8 @@ AlphaTargetMachine::AlphaTargetMachine(const Target &T, const std::string &TT,
FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
JITInfo(*this),
Subtarget(TT, FS),
TLInfo(*this) {
TLInfo(*this),
TSInfo(*this) {
setRelocationModel(Reloc::PIC_);
}

View File

@ -20,6 +20,7 @@
#include "AlphaInstrInfo.h"
#include "AlphaJITInfo.h"
#include "AlphaISelLowering.h"
#include "AlphaSelectionDAGInfo.h"
#include "AlphaSubtarget.h"
namespace llvm {
@ -33,6 +34,7 @@ class AlphaTargetMachine : public LLVMTargetMachine {
AlphaJITInfo JITInfo;
AlphaSubtarget Subtarget;
AlphaTargetLowering TLInfo;
AlphaSelectionDAGInfo TSInfo;
public:
AlphaTargetMachine(const Target &T, const std::string &TT,
@ -47,6 +49,9 @@ public:
virtual const AlphaTargetLowering* getTargetLowering() const {
return &TLInfo;
}
virtual const AlphaSelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
virtual const TargetData *getTargetData() const { return &DataLayout; }
virtual AlphaJITInfo* getJITInfo() {
return &JITInfo;

View File

@ -12,10 +12,12 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "blackfin-selectiondag-info"
#include "BlackfinSelectionDAGInfo.h"
#include "BlackfinTargetMachine.h"
using namespace llvm;
BlackfinSelectionDAGInfo::BlackfinSelectionDAGInfo() {
BlackfinSelectionDAGInfo::BlackfinSelectionDAGInfo(
const BlackfinTargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
BlackfinSelectionDAGInfo::~BlackfinSelectionDAGInfo() {

View File

@ -18,9 +18,11 @@
namespace llvm {
class BlackfinTargetMachine;
class BlackfinSelectionDAGInfo : public TargetSelectionDAGInfo {
public:
BlackfinSelectionDAGInfo();
explicit BlackfinSelectionDAGInfo(const BlackfinTargetMachine &TM);
~BlackfinSelectionDAGInfo();
};

View File

@ -31,6 +31,7 @@ BlackfinTargetMachine::BlackfinTargetMachine(const Target &T,
DataLayout("e-p:32:32-i64:32-f64:32-n32"),
Subtarget(TT, FS),
TLInfo(*this),
TSInfo(*this),
InstrInfo(Subtarget),
FrameInfo(TargetFrameInfo::StackGrowsDown, 4, 0) {
}

View File

@ -20,6 +20,7 @@
#include "BlackfinInstrInfo.h"
#include "BlackfinSubtarget.h"
#include "BlackfinISelLowering.h"
#include "BlackfinSelectionDAGInfo.h"
#include "BlackfinIntrinsicInfo.h"
namespace llvm {
@ -28,6 +29,7 @@ namespace llvm {
const TargetData DataLayout;
BlackfinSubtarget Subtarget;
BlackfinTargetLowering TLInfo;
BlackfinSelectionDAGInfo TSInfo;
BlackfinInstrInfo InstrInfo;
TargetFrameInfo FrameInfo;
BlackfinIntrinsicInfo IntrinsicInfo;
@ -46,6 +48,9 @@ namespace llvm {
virtual const BlackfinTargetLowering* getTargetLowering() const {
return &TLInfo;
}
virtual const BlackfinSelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
virtual const TargetData *getTargetData() const { return &DataLayout; }
virtual bool addInstSelector(PassManagerBase &PM,
CodeGenOpt::Level OptLevel);

View File

@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "cellspu-selectiondag-info"
#include "SPUSelectionDAGInfo.h"
#include "SPUTargetMachine.h"
using namespace llvm;
SPUSelectionDAGInfo::SPUSelectionDAGInfo() {
SPUSelectionDAGInfo::SPUSelectionDAGInfo(const SPUTargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
SPUSelectionDAGInfo::~SPUSelectionDAGInfo() {

View File

@ -18,9 +18,11 @@
namespace llvm {
class SPUTargetMachine;
class SPUSelectionDAGInfo : public TargetSelectionDAGInfo {
public:
SPUSelectionDAGInfo();
explicit SPUSelectionDAGInfo(const SPUTargetMachine &TM);
~SPUSelectionDAGInfo();
};

View File

@ -42,6 +42,7 @@ SPUTargetMachine::SPUTargetMachine(const Target &T, const std::string &TT,
InstrInfo(*this),
FrameInfo(*this),
TLInfo(*this),
TSInfo(*this),
InstrItins(Subtarget.getInstrItineraryData()) {
// For the time being, use static relocations, since there's really no
// support for PIC yet.

View File

@ -17,6 +17,7 @@
#include "SPUSubtarget.h"
#include "SPUInstrInfo.h"
#include "SPUISelLowering.h"
#include "SPUSelectionDAGInfo.h"
#include "SPUFrameInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
@ -34,6 +35,7 @@ class SPUTargetMachine : public LLVMTargetMachine {
SPUInstrInfo InstrInfo;
SPUFrameInfo FrameInfo;
SPUTargetLowering TLInfo;
SPUSelectionDAGInfo TSInfo;
InstrItineraryData InstrItins;
public:
SPUTargetMachine(const Target &T, const std::string &TT,
@ -61,6 +63,10 @@ public:
return &TLInfo;
}
virtual const SPUSelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
virtual const SPURegisterInfo *getRegisterInfo() const {
return &InstrInfo.getRegisterInfo();
}

View File

@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mblaze-selectiondag-info"
#include "MBlazeSelectionDAGInfo.h"
#include "MBlazeTargetMachine.h"
using namespace llvm;
MBlazeSelectionDAGInfo::MBlazeSelectionDAGInfo() {
MBlazeSelectionDAGInfo::MBlazeSelectionDAGInfo(const MBlazeTargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
MBlazeSelectionDAGInfo::~MBlazeSelectionDAGInfo() {

View File

@ -18,9 +18,11 @@
namespace llvm {
class MBlazeTargetMachine;
class MBlazeSelectionDAGInfo : public TargetSelectionDAGInfo {
public:
MBlazeSelectionDAGInfo();
explicit MBlazeSelectionDAGInfo(const MBlazeTargetMachine &TM);
~MBlazeSelectionDAGInfo();
};

View File

@ -39,7 +39,7 @@ MBlazeTargetMachine(const Target &T, const std::string &TT,
"f64:32:32-v64:32:32-v128:32:32-n32"),
InstrInfo(*this),
FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0),
TLInfo(*this) {
TLInfo(*this), TSInfo(*this) {
if (getRelocationModel() == Reloc::Default) {
setRelocationModel(Reloc::Static);
}

View File

@ -17,6 +17,7 @@
#include "MBlazeSubtarget.h"
#include "MBlazeInstrInfo.h"
#include "MBlazeISelLowering.h"
#include "MBlazeSelectionDAGInfo.h"
#include "MBlazeIntrinsicInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
@ -31,6 +32,7 @@ namespace llvm {
MBlazeInstrInfo InstrInfo;
TargetFrameInfo FrameInfo;
MBlazeTargetLowering TLInfo;
MBlazeSelectionDAGInfo TSInfo;
MBlazeIntrinsicInfo IntrinsicInfo;
public:
MBlazeTargetMachine(const Target &T, const std::string &TT,
@ -54,6 +56,9 @@ namespace llvm {
virtual const MBlazeTargetLowering *getTargetLowering() const
{ return &TLInfo; }
virtual const MBlazeSelectionDAGInfo* getSelectionDAGInfo() const
{ return &TSInfo; }
const TargetIntrinsicInfo *getIntrinsicInfo() const
{ return &IntrinsicInfo; }

View File

@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "msp430-selectiondag-info"
#include "MSP430SelectionDAGInfo.h"
#include "MSP430TargetMachine.h"
using namespace llvm;
MSP430SelectionDAGInfo::MSP430SelectionDAGInfo() {
MSP430SelectionDAGInfo::MSP430SelectionDAGInfo(const MSP430TargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
MSP430SelectionDAGInfo::~MSP430SelectionDAGInfo() {

View File

@ -18,9 +18,11 @@
namespace llvm {
class MSP430TargetMachine;
class MSP430SelectionDAGInfo : public TargetSelectionDAGInfo {
public:
MSP430SelectionDAGInfo();
explicit MSP430SelectionDAGInfo(const MSP430TargetMachine &TM);
~MSP430SelectionDAGInfo();
};

View File

@ -33,7 +33,7 @@ MSP430TargetMachine::MSP430TargetMachine(const Target &T,
Subtarget(TT, FS),
// FIXME: Check TargetData string.
DataLayout("e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"),
InstrInfo(*this), TLInfo(*this),
InstrInfo(*this), TLInfo(*this), TSInfo(*this),
FrameInfo(TargetFrameInfo::StackGrowsDown, 2, -2) { }

View File

@ -17,6 +17,7 @@
#include "MSP430InstrInfo.h"
#include "MSP430ISelLowering.h"
#include "MSP430SelectionDAGInfo.h"
#include "MSP430RegisterInfo.h"
#include "MSP430Subtarget.h"
#include "llvm/Target/TargetData.h"
@ -32,6 +33,7 @@ class MSP430TargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
MSP430InstrInfo InstrInfo;
MSP430TargetLowering TLInfo;
MSP430SelectionDAGInfo TSInfo;
// MSP430 does not have any call stack frame, therefore not having
// any MSP430 specific FrameInfo class.
@ -54,6 +56,10 @@ public:
return &TLInfo;
}
virtual const MSP430SelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
}; // MSP430TargetMachine.

View File

@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mips-selectiondag-info"
#include "MipsSelectionDAGInfo.h"
#include "MipsTargetMachine.h"
using namespace llvm;
MipsSelectionDAGInfo::MipsSelectionDAGInfo() {
MipsSelectionDAGInfo::MipsSelectionDAGInfo(const MipsTargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
MipsSelectionDAGInfo::~MipsSelectionDAGInfo() {

View File

@ -18,9 +18,11 @@
namespace llvm {
class MipsTargetMachine;
class MipsSelectionDAGInfo : public TargetSelectionDAGInfo {
public:
MipsSelectionDAGInfo();
explicit MipsSelectionDAGInfo(const MipsTargetMachine &TM);
~MipsSelectionDAGInfo();
};

View File

@ -42,7 +42,7 @@ MipsTargetMachine(const Target &T, const std::string &TT, const std::string &FS,
std::string("E-p:32:32:32-i8:8:32-i16:16:32-n32")),
InstrInfo(*this),
FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0),
TLInfo(*this) {
TLInfo(*this), TSInfo(*this) {
// Abicall enables PIC by default
if (getRelocationModel() == Reloc::Default) {
if (Subtarget.isABI_O32())

View File

@ -17,6 +17,7 @@
#include "MipsSubtarget.h"
#include "MipsInstrInfo.h"
#include "MipsISelLowering.h"
#include "MipsSelectionDAGInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
@ -30,6 +31,7 @@ namespace llvm {
MipsInstrInfo InstrInfo;
TargetFrameInfo FrameInfo;
MipsTargetLowering TLInfo;
MipsSelectionDAGInfo TSInfo;
public:
MipsTargetMachine(const Target &T, const std::string &TT,
const std::string &FS, bool isLittle);
@ -51,6 +53,10 @@ namespace llvm {
return &TLInfo;
}
virtual const MipsSelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
// Pass Pipeline Configuration
virtual bool addInstSelector(PassManagerBase &PM,
CodeGenOpt::Level OptLevel);

View File

@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "pic16-selectiondag-info"
#include "PIC16SelectionDAGInfo.h"
#include "PIC16TargetMachine.h"
using namespace llvm;
PIC16SelectionDAGInfo::PIC16SelectionDAGInfo() {
PIC16SelectionDAGInfo::PIC16SelectionDAGInfo(const PIC16TargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
PIC16SelectionDAGInfo::~PIC16SelectionDAGInfo() {

View File

@ -18,9 +18,11 @@
namespace llvm {
class PIC16TargetMachine;
class PIC16SelectionDAGInfo : public TargetSelectionDAGInfo {
public:
PIC16SelectionDAGInfo();
explicit PIC16SelectionDAGInfo(const PIC16TargetMachine &TM);
~PIC16SelectionDAGInfo();
};

View File

@ -35,7 +35,7 @@ PIC16TargetMachine::PIC16TargetMachine(const Target &T, const std::string &TT,
: LLVMTargetMachine(T, TT),
Subtarget(TT, FS, Trad),
DataLayout("e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-n8"),
InstrInfo(*this), TLInfo(*this),
InstrInfo(*this), TLInfo(*this), TSInfo(*this),
FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0) { }

View File

@ -17,6 +17,7 @@
#include "PIC16InstrInfo.h"
#include "PIC16ISelLowering.h"
#include "PIC16SelectionDAGInfo.h"
#include "PIC16RegisterInfo.h"
#include "PIC16Subtarget.h"
#include "llvm/Target/TargetData.h"
@ -32,6 +33,7 @@ class PIC16TargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
PIC16InstrInfo InstrInfo;
PIC16TargetLowering TLInfo;
PIC16SelectionDAGInfo TSInfo;
// PIC16 does not have any call stack frame, therefore not having
// any PIC16 specific FrameInfo class.
@ -54,6 +56,10 @@ public:
return &TLInfo;
}
virtual const PIC16SelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
virtual bool addInstSelector(PassManagerBase &PM,
CodeGenOpt::Level OptLevel);
virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);

View File

@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "powerpc-selectiondag-info"
#include "PPCSelectionDAGInfo.h"
#include "PPCTargetMachine.h"
using namespace llvm;
PPCSelectionDAGInfo::PPCSelectionDAGInfo() {
PPCSelectionDAGInfo::PPCSelectionDAGInfo(const PPCTargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
PPCSelectionDAGInfo::~PPCSelectionDAGInfo() {

View File

@ -18,9 +18,11 @@
namespace llvm {
class PPCTargetMachine;
class PPCSelectionDAGInfo : public TargetSelectionDAGInfo {
public:
PPCSelectionDAGInfo();
explicit PPCSelectionDAGInfo(const PPCTargetMachine &TM);
~PPCSelectionDAGInfo();
};

View File

@ -44,7 +44,8 @@ PPCTargetMachine::PPCTargetMachine(const Target &T, const std::string &TT,
: LLVMTargetMachine(T, TT),
Subtarget(TT, FS, is64Bit),
DataLayout(Subtarget.getTargetDataString()), InstrInfo(*this),
FrameInfo(*this, is64Bit), JITInfo(*this, is64Bit), TLInfo(*this),
FrameInfo(*this, is64Bit), JITInfo(*this, is64Bit),
TLInfo(*this), TSInfo(*this),
InstrItins(Subtarget.getInstrItineraryData()) {
if (getRelocationModel() == Reloc::Default) {

View File

@ -19,6 +19,7 @@
#include "PPCJITInfo.h"
#include "PPCInstrInfo.h"
#include "PPCISelLowering.h"
#include "PPCSelectionDAGInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
@ -35,6 +36,7 @@ class PPCTargetMachine : public LLVMTargetMachine {
PPCFrameInfo FrameInfo;
PPCJITInfo JITInfo;
PPCTargetLowering TLInfo;
PPCSelectionDAGInfo TSInfo;
InstrItineraryData InstrItins;
public:
@ -47,6 +49,9 @@ public:
virtual const PPCTargetLowering *getTargetLowering() const {
return &TLInfo;
}
virtual const PPCSelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
virtual const PPCRegisterInfo *getRegisterInfo() const {
return &InstrInfo.getRegisterInfo();
}

View File

@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "sparc-selectiondag-info"
#include "SparcSelectionDAGInfo.h"
#include "SparcTargetMachine.h"
using namespace llvm;
SparcSelectionDAGInfo::SparcSelectionDAGInfo() {
SparcSelectionDAGInfo::SparcSelectionDAGInfo(const SparcTargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
SparcSelectionDAGInfo::~SparcSelectionDAGInfo() {

View File

@ -18,9 +18,11 @@
namespace llvm {
class SparcTargetMachine;
class SparcSelectionDAGInfo : public TargetSelectionDAGInfo {
public:
SparcSelectionDAGInfo();
explicit SparcSelectionDAGInfo(const SparcTargetMachine &TM);
~SparcSelectionDAGInfo();
};

View File

@ -34,7 +34,7 @@ SparcTargetMachine::SparcTargetMachine(const Target &T, const std::string &TT,
: LLVMTargetMachine(T, TT),
Subtarget(TT, FS, is64bit),
DataLayout(Subtarget.getDataLayout()),
TLInfo(*this), InstrInfo(Subtarget),
TLInfo(*this), TSInfo(*this), InstrInfo(Subtarget),
FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) {
}

View File

@ -20,6 +20,7 @@
#include "SparcInstrInfo.h"
#include "SparcSubtarget.h"
#include "SparcISelLowering.h"
#include "SparcSelectionDAGInfo.h"
namespace llvm {
@ -27,6 +28,7 @@ class SparcTargetMachine : public LLVMTargetMachine {
SparcSubtarget Subtarget;
const TargetData DataLayout; // Calculates type size & alignment
SparcTargetLowering TLInfo;
SparcSelectionDAGInfo TSInfo;
SparcInstrInfo InstrInfo;
TargetFrameInfo FrameInfo;
public:
@ -42,6 +44,9 @@ public:
virtual const SparcTargetLowering* getTargetLowering() const {
return &TLInfo;
}
virtual const SparcSelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
virtual const TargetData *getTargetData() const { return &DataLayout; }
// Pass Pipeline Configuration

View File

@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "systemz-selectiondag-info"
#include "SystemZSelectionDAGInfo.h"
#include "SystemZTargetMachine.h"
using namespace llvm;
SystemZSelectionDAGInfo::SystemZSelectionDAGInfo() {
SystemZSelectionDAGInfo::SystemZSelectionDAGInfo(const SystemZTargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
SystemZSelectionDAGInfo::~SystemZSelectionDAGInfo() {

View File

@ -18,9 +18,11 @@
namespace llvm {
class SystemZTargetMachine;
class SystemZSelectionDAGInfo : public TargetSelectionDAGInfo {
public:
SystemZSelectionDAGInfo();
explicit SystemZSelectionDAGInfo(const SystemZTargetMachine &TM);
~SystemZSelectionDAGInfo();
};

View File

@ -29,7 +29,7 @@ SystemZTargetMachine::SystemZTargetMachine(const Target &T,
Subtarget(TT, FS),
DataLayout("E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32"
"-f64:64:64-f128:128:128-a0:16:16-n32:64"),
InstrInfo(*this), TLInfo(*this),
InstrInfo(*this), TLInfo(*this), TSInfo(*this),
FrameInfo(TargetFrameInfo::StackGrowsDown, 8, -160) {
if (getRelocationModel() == Reloc::Default)

View File

@ -17,6 +17,7 @@
#include "SystemZInstrInfo.h"
#include "SystemZISelLowering.h"
#include "SystemZSelectionDAGInfo.h"
#include "SystemZRegisterInfo.h"
#include "SystemZSubtarget.h"
#include "llvm/Target/TargetData.h"
@ -32,6 +33,7 @@ class SystemZTargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
SystemZInstrInfo InstrInfo;
SystemZTargetLowering TLInfo;
SystemZSelectionDAGInfo TSInfo;
// SystemZ does not have any call stack frame, therefore not having
// any SystemZ specific FrameInfo class.
@ -53,6 +55,10 @@ public:
return &TLInfo;
}
virtual const SystemZSelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
}; // SystemZTargetMachine.

View File

@ -6593,221 +6593,6 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
return DAG.getMergeValues(Ops1, 2, dl);
}
SDValue
X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile,
const Value *DstSV,
uint64_t DstSVOff) const {
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
// If not DWORD aligned or size is more than the threshold, call the library.
// The libc version is likely to be faster for these cases. It can use the
// address value and run time information about the CPU.
if ((Align & 3) != 0 ||
!ConstantSize ||
ConstantSize->getZExtValue() >
getSubtarget()->getMaxInlineSizeThreshold()) {
SDValue InFlag(0, 0);
// Check to see if there is a specialized entry-point for memory zeroing.
ConstantSDNode *V = dyn_cast<ConstantSDNode>(Src);
if (const char *bzeroEntry = V &&
V->isNullValue() ? Subtarget->getBZeroEntry() : 0) {
EVT IntPtr = getPointerTy();
const Type *IntPtrTy = TD->getIntPtrType(*DAG.getContext());
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
Entry.Node = Dst;
Entry.Ty = IntPtrTy;
Args.push_back(Entry);
Entry.Node = Size;
Args.push_back(Entry);
std::pair<SDValue,SDValue> CallResult =
LowerCallTo(Chain, Type::getVoidTy(*DAG.getContext()),
false, false, false, false,
0, CallingConv::C, false, /*isReturnValueUsed=*/false,
DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG, dl);
return CallResult.second;
}
// Otherwise have the target-independent code call memset.
return SDValue();
}
uint64_t SizeVal = ConstantSize->getZExtValue();
SDValue InFlag(0, 0);
EVT AVT;
SDValue Count;
ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Src);
unsigned BytesLeft = 0;
bool TwoRepStos = false;
if (ValC) {
unsigned ValReg;
uint64_t Val = ValC->getZExtValue() & 255;
// If the value is a constant, then we can potentially use larger sets.
switch (Align & 3) {
case 2: // WORD aligned
AVT = MVT::i16;
ValReg = X86::AX;
Val = (Val << 8) | Val;
break;
case 0: // DWORD aligned
AVT = MVT::i32;
ValReg = X86::EAX;
Val = (Val << 8) | Val;
Val = (Val << 16) | Val;
if (Subtarget->is64Bit() && ((Align & 0x7) == 0)) { // QWORD aligned
AVT = MVT::i64;
ValReg = X86::RAX;
Val = (Val << 32) | Val;
}
break;
default: // Byte aligned
AVT = MVT::i8;
ValReg = X86::AL;
Count = DAG.getIntPtrConstant(SizeVal);
break;
}
if (AVT.bitsGT(MVT::i8)) {
unsigned UBytes = AVT.getSizeInBits() / 8;
Count = DAG.getIntPtrConstant(SizeVal / UBytes);
BytesLeft = SizeVal % UBytes;
}
Chain = DAG.getCopyToReg(Chain, dl, ValReg, DAG.getConstant(Val, AVT),
InFlag);
InFlag = Chain.getValue(1);
} else {
AVT = MVT::i8;
Count = DAG.getIntPtrConstant(SizeVal);
Chain = DAG.getCopyToReg(Chain, dl, X86::AL, Src, InFlag);
InFlag = Chain.getValue(1);
}
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RCX :
X86::ECX,
Count, InFlag);
InFlag = Chain.getValue(1);
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RDI :
X86::EDI,
Dst, InFlag);
InFlag = Chain.getValue(1);
SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(Ops));
if (TwoRepStos) {
InFlag = Chain.getValue(1);
Count = Size;
EVT CVT = Count.getValueType();
SDValue Left = DAG.getNode(ISD::AND, dl, CVT, Count,
DAG.getConstant((AVT == MVT::i64) ? 7 : 3, CVT));
Chain = DAG.getCopyToReg(Chain, dl, (CVT == MVT::i64) ? X86::RCX :
X86::ECX,
Left, InFlag);
InFlag = Chain.getValue(1);
Tys = DAG.getVTList(MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain, DAG.getValueType(MVT::i8), InFlag };
Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(Ops));
} else if (BytesLeft) {
// Handle the last 1 - 7 bytes.
unsigned Offset = SizeVal - BytesLeft;
EVT AddrVT = Dst.getValueType();
EVT SizeVT = Size.getValueType();
Chain = DAG.getMemset(Chain, dl,
DAG.getNode(ISD::ADD, dl, AddrVT, Dst,
DAG.getConstant(Offset, AddrVT)),
Src,
DAG.getConstant(BytesLeft, SizeVT),
Align, isVolatile, DstSV, DstSVOff + Offset);
}
// TODO: Use a Tokenfactor, as in memcpy, instead of a single chain.
return Chain;
}
SDValue
X86TargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain, SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile, bool AlwaysInline,
const Value *DstSV,
uint64_t DstSVOff,
const Value *SrcSV,
uint64_t SrcSVOff) const {
// This requires the copy size to be a constant, preferrably
// within a subtarget-specific limit.
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
if (!ConstantSize)
return SDValue();
uint64_t SizeVal = ConstantSize->getZExtValue();
if (!AlwaysInline && SizeVal > getSubtarget()->getMaxInlineSizeThreshold())
return SDValue();
/// If not DWORD aligned, call the library.
if ((Align & 3) != 0)
return SDValue();
// DWORD aligned
EVT AVT = MVT::i32;
if (Subtarget->is64Bit() && ((Align & 0x7) == 0)) // QWORD aligned
AVT = MVT::i64;
unsigned UBytes = AVT.getSizeInBits() / 8;
unsigned CountVal = SizeVal / UBytes;
SDValue Count = DAG.getIntPtrConstant(CountVal);
unsigned BytesLeft = SizeVal % UBytes;
SDValue InFlag(0, 0);
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RCX :
X86::ECX,
Count, InFlag);
InFlag = Chain.getValue(1);
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RDI :
X86::EDI,
Dst, InFlag);
InFlag = Chain.getValue(1);
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RSI :
X86::ESI,
Src, InFlag);
InFlag = Chain.getValue(1);
SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
SDValue RepMovs = DAG.getNode(X86ISD::REP_MOVS, dl, Tys, Ops,
array_lengthof(Ops));
SmallVector<SDValue, 4> Results;
Results.push_back(RepMovs);
if (BytesLeft) {
// Handle the last 1 - 7 bytes.
unsigned Offset = SizeVal - BytesLeft;
EVT DstVT = Dst.getValueType();
EVT SrcVT = Src.getValueType();
EVT SizeVT = Size.getValueType();
Results.push_back(DAG.getMemcpy(Chain, dl,
DAG.getNode(ISD::ADD, dl, DstVT, Dst,
DAG.getConstant(Offset, DstVT)),
DAG.getNode(ISD::ADD, dl, SrcVT, Src,
DAG.getConstant(Offset, SrcVT)),
DAG.getConstant(BytesLeft, SizeVT),
Align, isVolatile, AlwaysInline,
DstSV, DstSVOff + Offset,
SrcSV, SrcSVOff + Offset));
}
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
&Results[0], Results.size());
}
SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();

View File

@ -743,23 +743,6 @@ namespace llvm {
void ReplaceATOMIC_BINARY_64(SDNode *N, SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG, unsigned NewOp) const;
SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile,
const Value *DstSV,
uint64_t DstSVOff) const;
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile, bool AlwaysInline,
const Value *DstSV,
uint64_t DstSVOff,
const Value *SrcSV,
uint64_t SrcSVOff) const;
/// Utility function to emit string processing sse4.2 instructions
/// that return in xmm0.
/// This takes the instruction to expand, the associated machine basic

View File

@ -12,11 +12,232 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "x86-selectiondag-info"
#include "X86SelectionDAGInfo.h"
#include "X86TargetMachine.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/SelectionDAG.h"
using namespace llvm;
X86SelectionDAGInfo::X86SelectionDAGInfo() {
X86SelectionDAGInfo::X86SelectionDAGInfo(const X86TargetMachine &TM) :
TargetSelectionDAGInfo(TM),
Subtarget(&TM.getSubtarget<X86Subtarget>()),
TLI(*TM.getTargetLowering()) {
}
X86SelectionDAGInfo::~X86SelectionDAGInfo() {
}
SDValue
X86SelectionDAGInfo::EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile,
const Value *DstSV,
uint64_t DstSVOff) const {
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
// If not DWORD aligned or size is more than the threshold, call the library.
// The libc version is likely to be faster for these cases. It can use the
// address value and run time information about the CPU.
if ((Align & 3) != 0 ||
!ConstantSize ||
ConstantSize->getZExtValue() >
Subtarget->getMaxInlineSizeThreshold()) {
SDValue InFlag(0, 0);
// Check to see if there is a specialized entry-point for memory zeroing.
ConstantSDNode *V = dyn_cast<ConstantSDNode>(Src);
if (const char *bzeroEntry = V &&
V->isNullValue() ? Subtarget->getBZeroEntry() : 0) {
EVT IntPtr = TLI.getPointerTy();
const Type *IntPtrTy = getTargetData()->getIntPtrType(*DAG.getContext());
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
Entry.Node = Dst;
Entry.Ty = IntPtrTy;
Args.push_back(Entry);
Entry.Node = Size;
Args.push_back(Entry);
std::pair<SDValue,SDValue> CallResult =
TLI.LowerCallTo(Chain, Type::getVoidTy(*DAG.getContext()),
false, false, false, false,
0, CallingConv::C, false, /*isReturnValueUsed=*/false,
DAG.getExternalSymbol(bzeroEntry, IntPtr), Args,
DAG, dl);
return CallResult.second;
}
// Otherwise have the target-independent code call memset.
return SDValue();
}
uint64_t SizeVal = ConstantSize->getZExtValue();
SDValue InFlag(0, 0);
EVT AVT;
SDValue Count;
ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Src);
unsigned BytesLeft = 0;
bool TwoRepStos = false;
if (ValC) {
unsigned ValReg;
uint64_t Val = ValC->getZExtValue() & 255;
// If the value is a constant, then we can potentially use larger sets.
switch (Align & 3) {
case 2: // WORD aligned
AVT = MVT::i16;
ValReg = X86::AX;
Val = (Val << 8) | Val;
break;
case 0: // DWORD aligned
AVT = MVT::i32;
ValReg = X86::EAX;
Val = (Val << 8) | Val;
Val = (Val << 16) | Val;
if (Subtarget->is64Bit() && ((Align & 0x7) == 0)) { // QWORD aligned
AVT = MVT::i64;
ValReg = X86::RAX;
Val = (Val << 32) | Val;
}
break;
default: // Byte aligned
AVT = MVT::i8;
ValReg = X86::AL;
Count = DAG.getIntPtrConstant(SizeVal);
break;
}
if (AVT.bitsGT(MVT::i8)) {
unsigned UBytes = AVT.getSizeInBits() / 8;
Count = DAG.getIntPtrConstant(SizeVal / UBytes);
BytesLeft = SizeVal % UBytes;
}
Chain = DAG.getCopyToReg(Chain, dl, ValReg, DAG.getConstant(Val, AVT),
InFlag);
InFlag = Chain.getValue(1);
} else {
AVT = MVT::i8;
Count = DAG.getIntPtrConstant(SizeVal);
Chain = DAG.getCopyToReg(Chain, dl, X86::AL, Src, InFlag);
InFlag = Chain.getValue(1);
}
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RCX :
X86::ECX,
Count, InFlag);
InFlag = Chain.getValue(1);
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RDI :
X86::EDI,
Dst, InFlag);
InFlag = Chain.getValue(1);
SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(Ops));
if (TwoRepStos) {
InFlag = Chain.getValue(1);
Count = Size;
EVT CVT = Count.getValueType();
SDValue Left = DAG.getNode(ISD::AND, dl, CVT, Count,
DAG.getConstant((AVT == MVT::i64) ? 7 : 3, CVT));
Chain = DAG.getCopyToReg(Chain, dl, (CVT == MVT::i64) ? X86::RCX :
X86::ECX,
Left, InFlag);
InFlag = Chain.getValue(1);
Tys = DAG.getVTList(MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain, DAG.getValueType(MVT::i8), InFlag };
Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(Ops));
} else if (BytesLeft) {
// Handle the last 1 - 7 bytes.
unsigned Offset = SizeVal - BytesLeft;
EVT AddrVT = Dst.getValueType();
EVT SizeVT = Size.getValueType();
Chain = DAG.getMemset(Chain, dl,
DAG.getNode(ISD::ADD, dl, AddrVT, Dst,
DAG.getConstant(Offset, AddrVT)),
Src,
DAG.getConstant(BytesLeft, SizeVT),
Align, isVolatile, DstSV, DstSVOff + Offset);
}
// TODO: Use a Tokenfactor, as in memcpy, instead of a single chain.
return Chain;
}
SDValue
X86SelectionDAGInfo::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain, SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile, bool AlwaysInline,
const Value *DstSV,
uint64_t DstSVOff,
const Value *SrcSV,
uint64_t SrcSVOff) const {
// This requires the copy size to be a constant, preferrably
// within a subtarget-specific limit.
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
if (!ConstantSize)
return SDValue();
uint64_t SizeVal = ConstantSize->getZExtValue();
if (!AlwaysInline && SizeVal > Subtarget->getMaxInlineSizeThreshold())
return SDValue();
/// If not DWORD aligned, call the library.
if ((Align & 3) != 0)
return SDValue();
// DWORD aligned
EVT AVT = MVT::i32;
if (Subtarget->is64Bit() && ((Align & 0x7) == 0)) // QWORD aligned
AVT = MVT::i64;
unsigned UBytes = AVT.getSizeInBits() / 8;
unsigned CountVal = SizeVal / UBytes;
SDValue Count = DAG.getIntPtrConstant(CountVal);
unsigned BytesLeft = SizeVal % UBytes;
SDValue InFlag(0, 0);
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RCX :
X86::ECX,
Count, InFlag);
InFlag = Chain.getValue(1);
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RDI :
X86::EDI,
Dst, InFlag);
InFlag = Chain.getValue(1);
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RSI :
X86::ESI,
Src, InFlag);
InFlag = Chain.getValue(1);
SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
SDValue RepMovs = DAG.getNode(X86ISD::REP_MOVS, dl, Tys, Ops,
array_lengthof(Ops));
SmallVector<SDValue, 4> Results;
Results.push_back(RepMovs);
if (BytesLeft) {
// Handle the last 1 - 7 bytes.
unsigned Offset = SizeVal - BytesLeft;
EVT DstVT = Dst.getValueType();
EVT SrcVT = Src.getValueType();
EVT SizeVT = Size.getValueType();
Results.push_back(DAG.getMemcpy(Chain, dl,
DAG.getNode(ISD::ADD, dl, DstVT, Dst,
DAG.getConstant(Offset, DstVT)),
DAG.getNode(ISD::ADD, dl, SrcVT, Src,
DAG.getConstant(Offset, SrcVT)),
DAG.getConstant(BytesLeft, SizeVT),
Align, isVolatile, AlwaysInline,
DstSV, DstSVOff + Offset,
SrcSV, SrcSVOff + Offset));
}
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
&Results[0], Results.size());
}

View File

@ -18,10 +18,40 @@
namespace llvm {
class X86TargetLowering;
class X86TargetMachine;
class X86Subtarget;
class X86SelectionDAGInfo : public TargetSelectionDAGInfo {
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
/// make the right decision when generating code for different targets.
const X86Subtarget *Subtarget;
const X86TargetLowering &TLI;
public:
X86SelectionDAGInfo();
explicit X86SelectionDAGInfo(const X86TargetMachine &TM);
~X86SelectionDAGInfo();
virtual
SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile,
const Value *DstSV,
uint64_t DstSVOff) const;
virtual
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile, bool AlwaysInline,
const Value *DstSV,
uint64_t DstSVOff,
const Value *SrcSV,
uint64_t SrcSVOff) const;
};
}

View File

@ -82,7 +82,8 @@ X86TargetMachine::X86TargetMachine(const Target &T, const std::string &TT,
Subtarget.getStackAlignment(),
(Subtarget.isTargetWin64() ? -40 :
(Subtarget.is64Bit() ? -8 : -4))),
InstrInfo(*this), JITInfo(*this), TLInfo(*this), ELFWriterInfo(*this) {
InstrInfo(*this), JITInfo(*this), TLInfo(*this), TSInfo(*this),
ELFWriterInfo(*this) {
DefRelocModel = getRelocationModel();
// If no relocation model was picked, default as appropriate for the target.

View File

@ -23,6 +23,7 @@
#include "X86JITInfo.h"
#include "X86Subtarget.h"
#include "X86ISelLowering.h"
#include "X86SelectionDAGInfo.h"
namespace llvm {
@ -35,6 +36,7 @@ class X86TargetMachine : public LLVMTargetMachine {
X86InstrInfo InstrInfo;
X86JITInfo JITInfo;
X86TargetLowering TLInfo;
X86SelectionDAGInfo TSInfo;
X86ELFWriterInfo ELFWriterInfo;
Reloc::Model DefRelocModel; // Reloc model before it's overridden.
@ -54,6 +56,9 @@ public:
virtual const X86TargetLowering *getTargetLowering() const {
return &TLInfo;
}
virtual const X86SelectionDAGInfo *getSelectionDAGInfo() const {
return &TSInfo;
}
virtual const X86RegisterInfo *getRegisterInfo() const {
return &InstrInfo.getRegisterInfo();
}

View File

@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "xcore-selectiondag-info"
#include "XCoreSelectionDAGInfo.h"
#include "XCoreTargetMachine.h"
using namespace llvm;
XCoreSelectionDAGInfo::XCoreSelectionDAGInfo() {
XCoreSelectionDAGInfo::XCoreSelectionDAGInfo(const XCoreTargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
XCoreSelectionDAGInfo::~XCoreSelectionDAGInfo() {

View File

@ -18,9 +18,11 @@
namespace llvm {
class XCoreTargetMachine;
class XCoreSelectionDAGInfo : public TargetSelectionDAGInfo {
public:
XCoreSelectionDAGInfo();
explicit XCoreSelectionDAGInfo(const XCoreTargetMachine &TM);
~XCoreSelectionDAGInfo();
};

View File

@ -28,7 +28,8 @@ XCoreTargetMachine::XCoreTargetMachine(const Target &T, const std::string &TT,
"i16:16:32-i32:32:32-i64:32:32-n32"),
InstrInfo(),
FrameInfo(*this),
TLInfo(*this) {
TLInfo(*this),
TSInfo(*this) {
}
bool XCoreTargetMachine::addInstSelector(PassManagerBase &PM,

View File

@ -20,6 +20,7 @@
#include "XCoreSubtarget.h"
#include "XCoreInstrInfo.h"
#include "XCoreISelLowering.h"
#include "XCoreSelectionDAGInfo.h"
namespace llvm {
@ -29,6 +30,7 @@ class XCoreTargetMachine : public LLVMTargetMachine {
XCoreInstrInfo InstrInfo;
XCoreFrameInfo FrameInfo;
XCoreTargetLowering TLInfo;
XCoreSelectionDAGInfo TSInfo;
public:
XCoreTargetMachine(const Target &T, const std::string &TT,
const std::string &FS);
@ -40,6 +42,10 @@ public:
return &TLInfo;
}
virtual const XCoreSelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
virtual const TargetRegisterInfo *getRegisterInfo() const {
return &InstrInfo.getRegisterInfo();
}