- Rename isLegalMemOpType to isSafeMemOpType. "Legal" is a very overloade term.

Also added more comments to explain why it is generally ok to return true.
- Rename getOptimalMemOpType argument IsZeroVal to ZeroOrLdSrc. It's meant to
be true for loaded source (memcpy) or zero constants (memset). The poor name
choice is probably some kind of legacy issue.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169954 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2012-12-12 01:32:07 +00:00
parent 6c645a35cc
commit 7d34267df6
10 changed files with 34 additions and 43 deletions

View File

@ -702,7 +702,7 @@ public:
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it /// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement, /// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If /// probably because the source does not need to be loaded. If
/// 'IsZeroVal' is true, that means it's safe to return a /// 'ZeroOrLdSrc' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded /// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is /// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
/// constant so it does not need to be loaded. /// constant so it does not need to be loaded.
@ -710,19 +710,20 @@ public:
/// target-independent logic. /// target-independent logic.
virtual EVT getOptimalMemOpType(uint64_t /*Size*/, virtual EVT getOptimalMemOpType(uint64_t /*Size*/,
unsigned /*DstAlign*/, unsigned /*SrcAlign*/, unsigned /*DstAlign*/, unsigned /*SrcAlign*/,
bool /*IsZeroVal*/, bool /*ZeroOrLdSrc*/,
bool /*MemcpyStrSrc*/, bool /*MemcpyStrSrc*/,
MachineFunction &/*MF*/) const { MachineFunction &/*MF*/) const {
return MVT::Other; return MVT::Other;
} }
/// isLegalMemOpType - Returns true if it's legal to use load / store of the /// isSafeMemOpType - Returns true if it's safe to use load / store of the
/// specified type to expand memcpy / memset inline. This is mostly true /// specified type to expand memcpy / memset inline. This is mostly true
/// for legal types except for some special cases. For example, on X86 /// for all types except for some special cases. For example, on X86
/// targets without SSE2 f64 load / store are done with fldl / fstpl which /// targets without SSE2 f64 load / store are done with fldl / fstpl which
/// also does type conversion. /// also does type conversion. Note the specified type doesn't have to be
virtual bool isLegalMemOpType(MVT VT) const { /// legal as the hook is used before type legalization.
return VT.isInteger(); virtual bool isSafeMemOpType(MVT VT) const {
return true;
} }
/// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp /// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp

View File

@ -3426,7 +3426,7 @@ static bool isMemSrcFromString(SDValue Src, StringRef &Str) {
static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps, static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
unsigned Limit, uint64_t Size, unsigned Limit, uint64_t Size,
unsigned DstAlign, unsigned SrcAlign, unsigned DstAlign, unsigned SrcAlign,
bool IsZeroVal, bool ZeroOrLdSrc,
bool MemcpyStrSrc, bool MemcpyStrSrc,
bool AllowOverlap, bool AllowOverlap,
SelectionDAG &DAG, SelectionDAG &DAG,
@ -3441,7 +3441,7 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
// 'MemcpyStrSrc' indicates whether the memcpy source is constant so it does // 'MemcpyStrSrc' indicates whether the memcpy source is constant so it does
// not need to be loaded. // not need to be loaded.
EVT VT = TLI.getOptimalMemOpType(Size, DstAlign, SrcAlign, EVT VT = TLI.getOptimalMemOpType(Size, DstAlign, SrcAlign,
IsZeroVal, MemcpyStrSrc, ZeroOrLdSrc, MemcpyStrSrc,
DAG.getMachineFunction()); DAG.getMachineFunction());
if (VT == MVT::Other) { if (VT == MVT::Other) {
@ -3481,11 +3481,11 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
if (VT.isVector() || VT.isFloatingPoint()) { if (VT.isVector() || VT.isFloatingPoint()) {
NewVT = (VT.getSizeInBits() > 64) ? MVT::i64 : MVT::i32; NewVT = (VT.getSizeInBits() > 64) ? MVT::i64 : MVT::i32;
if (TLI.isOperationLegalOrCustom(ISD::STORE, NewVT) && if (TLI.isOperationLegalOrCustom(ISD::STORE, NewVT) &&
TLI.isLegalMemOpType(NewVT.getSimpleVT())) TLI.isSafeMemOpType(NewVT.getSimpleVT()))
Found = true; Found = true;
else if (NewVT == MVT::i64 && else if (NewVT == MVT::i64 &&
TLI.isOperationLegalOrCustom(ISD::STORE, MVT::f64) && TLI.isOperationLegalOrCustom(ISD::STORE, MVT::f64) &&
TLI.isLegalMemOpType(MVT::f64)) { TLI.isSafeMemOpType(MVT::f64)) {
// i64 is usually not legal on 32-bit targets, but f64 may be. // i64 is usually not legal on 32-bit targets, but f64 may be.
NewVT = MVT::f64; NewVT = MVT::f64;
Found = true; Found = true;
@ -3497,7 +3497,7 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
NewVT = (MVT::SimpleValueType)(NewVT.getSimpleVT().SimpleTy - 1); NewVT = (MVT::SimpleValueType)(NewVT.getSimpleVT().SimpleTy - 1);
if (NewVT == MVT::i8) if (NewVT == MVT::i8)
break; break;
} while (!TLI.isLegalMemOpType(NewVT.getSimpleVT())); } while (!TLI.isSafeMemOpType(NewVT.getSimpleVT()));
} }
NewVTSize = NewVT.getSizeInBits() / 8; NewVTSize = NewVT.getSizeInBits() / 8;

View File

@ -9450,13 +9450,13 @@ static bool memOpAlign(unsigned DstAlign, unsigned SrcAlign,
EVT ARMTargetLowering::getOptimalMemOpType(uint64_t Size, EVT ARMTargetLowering::getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign, unsigned DstAlign, unsigned SrcAlign,
bool IsZeroVal, bool ZeroOrLdSrc,
bool MemcpyStrSrc, bool MemcpyStrSrc,
MachineFunction &MF) const { MachineFunction &MF) const {
const Function *F = MF.getFunction(); const Function *F = MF.getFunction();
// See if we can use NEON instructions for this... // See if we can use NEON instructions for this...
if (IsZeroVal && if (ZeroOrLdSrc &&
Subtarget->hasNEON() && Subtarget->hasNEON() &&
!F->getFnAttributes().hasAttribute(Attributes::NoImplicitFloat)) { !F->getFnAttributes().hasAttribute(Attributes::NoImplicitFloat)) {
bool Fast; bool Fast;
@ -9481,10 +9481,6 @@ EVT ARMTargetLowering::getOptimalMemOpType(uint64_t Size,
return MVT::Other; return MVT::Other;
} }
bool ARMTargetLowering::isLegalMemOpType(MVT VT) const {
return VT.isInteger() || VT == MVT::f64 || VT == MVT::v2f64;
}
bool ARMTargetLowering::isZExtFree(SDValue Val, EVT VT2) const { bool ARMTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
if (Val.getOpcode() != ISD::LOAD) if (Val.getOpcode() != ISD::LOAD)
return false; return false;

View File

@ -292,17 +292,10 @@ namespace llvm {
virtual EVT getOptimalMemOpType(uint64_t Size, virtual EVT getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign, unsigned DstAlign, unsigned SrcAlign,
bool IsZeroVal, bool ZeroOrLdSrc,
bool MemcpyStrSrc, bool MemcpyStrSrc,
MachineFunction &MF) const; MachineFunction &MF) const;
/// isLegalMemOpType - Returns true if it's legal to use load / store of the
/// specified type to expand memcpy / memset inline. This is mostly true
/// for legal types except for some special cases. For example, on X86
/// targets without SSE2 f64 load / store are done with fldl / fstpl which
/// also does type conversion.
virtual bool isLegalMemOpType(MVT VT) const;
using TargetLowering::isZExtFree; using TargetLowering::isZExtFree;
virtual bool isZExtFree(SDValue Val, EVT VT2) const; virtual bool isZExtFree(SDValue Val, EVT VT2) const;

View File

@ -3476,7 +3476,7 @@ MipsTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
} }
EVT MipsTargetLowering::getOptimalMemOpType(uint64_t Size, unsigned DstAlign, EVT MipsTargetLowering::getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
unsigned SrcAlign, bool IsZeroVal, unsigned SrcAlign, bool ZeroOrLdSrc,
bool MemcpyStrSrc, bool MemcpyStrSrc,
MachineFunction &MF) const { MachineFunction &MF) const {
if (Subtarget->hasMips64()) if (Subtarget->hasMips64())

View File

@ -362,7 +362,7 @@ namespace llvm {
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
virtual EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, virtual EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
unsigned SrcAlign, bool IsZeroVal, unsigned SrcAlign, bool ZeroOrLdSrc,
bool MemcpyStrSrc, bool MemcpyStrSrc,
MachineFunction &MF) const; MachineFunction &MF) const;

View File

@ -6815,7 +6815,7 @@ PPCTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it /// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement, /// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If /// probably because the source does not need to be loaded. If
/// 'IsZeroVal' is true, that means it's safe to return a /// 'ZeroOrLdSrc' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded /// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is /// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
/// constant so it does not need to be loaded. /// constant so it does not need to be loaded.
@ -6823,7 +6823,7 @@ PPCTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
/// target-independent logic. /// target-independent logic.
EVT PPCTargetLowering::getOptimalMemOpType(uint64_t Size, EVT PPCTargetLowering::getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign, unsigned DstAlign, unsigned SrcAlign,
bool IsZeroVal, bool ZeroOrLdSrc,
bool MemcpyStrSrc, bool MemcpyStrSrc,
MachineFunction &MF) const { MachineFunction &MF) const {
if (this->PPCSubTarget.isPPC64()) { if (this->PPCSubTarget.isPPC64()) {

View File

@ -401,7 +401,7 @@ namespace llvm {
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it /// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement, /// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If /// probably because the source does not need to be loaded. If
/// 'IsZeroVal' is true, that means it's safe to return a /// 'ZeroOrLdSrc' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded /// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is /// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
/// constant so it does not need to be loaded. /// constant so it does not need to be loaded.
@ -409,7 +409,7 @@ namespace llvm {
/// target-independent logic. /// target-independent logic.
virtual EVT virtual EVT
getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign, getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
bool IsZeroVal, bool MemcpyStrSrc, bool ZeroOrLdSrc, bool MemcpyStrSrc,
MachineFunction &MF) const; MachineFunction &MF) const;
/// isFMAFasterThanMulAndAdd - Return true if an FMA operation is faster than /// isFMAFasterThanMulAndAdd - Return true if an FMA operation is faster than

View File

@ -1370,7 +1370,7 @@ unsigned X86TargetLowering::getByValTypeAlignment(Type *Ty) const {
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it /// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement, /// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If /// probably because the source does not need to be loaded. If
/// 'IsZeroVal' is true, that means it's safe to return a /// 'ZeroOrLdSrc' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded /// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is /// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
/// constant so it does not need to be loaded. /// constant so it does not need to be loaded.
@ -1379,11 +1379,11 @@ unsigned X86TargetLowering::getByValTypeAlignment(Type *Ty) const {
EVT EVT
X86TargetLowering::getOptimalMemOpType(uint64_t Size, X86TargetLowering::getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign, unsigned DstAlign, unsigned SrcAlign,
bool IsZeroVal, bool ZeroOrLdSrc,
bool MemcpyStrSrc, bool MemcpyStrSrc,
MachineFunction &MF) const { MachineFunction &MF) const {
const Function *F = MF.getFunction(); const Function *F = MF.getFunction();
if (IsZeroVal && if (ZeroOrLdSrc &&
!F->getFnAttributes().hasAttribute(Attributes::NoImplicitFloat)) { !F->getFnAttributes().hasAttribute(Attributes::NoImplicitFloat)) {
if (Size >= 16 && if (Size >= 16 &&
(Subtarget->isUnalignedMemAccessFast() || (Subtarget->isUnalignedMemAccessFast() ||
@ -1412,12 +1412,12 @@ X86TargetLowering::getOptimalMemOpType(uint64_t Size,
return MVT::i32; return MVT::i32;
} }
bool X86TargetLowering::isLegalMemOpType(MVT VT) const { bool X86TargetLowering::isSafeMemOpType(MVT VT) const {
if (VT == MVT::f32) if (VT == MVT::f32)
return X86ScalarSSEf32; return X86ScalarSSEf32;
else if (VT == MVT::f64) else if (VT == MVT::f64)
return X86ScalarSSEf64; return X86ScalarSSEf64;
return VT.isInteger(); return true;
} }
bool bool

View File

@ -495,7 +495,7 @@ namespace llvm {
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it /// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement, /// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If /// probably because the source does not need to be loaded. If
/// 'IsZeroVal' is true, that means it's safe to return a /// 'ZeroOrLdSrc' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded /// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is /// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
/// constant so it does not need to be loaded. /// constant so it does not need to be loaded.
@ -503,15 +503,16 @@ namespace llvm {
/// target-independent logic. /// target-independent logic.
virtual EVT virtual EVT
getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign, getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
bool IsZeroVal, bool MemcpyStrSrc, bool ZeroOrLdSrc, bool MemcpyStrSrc,
MachineFunction &MF) const; MachineFunction &MF) const;
/// isLegalMemOpType - Returns true if it's legal to use load / store of the /// isSafeMemOpType - Returns true if it's safe to use load / store of the
/// specified type to expand memcpy / memset inline. This is mostly true /// specified type to expand memcpy / memset inline. This is mostly true
/// for legal types except for some special cases. For example, on X86 /// for all types except for some special cases. For example, on X86
/// targets without SSE2 f64 load / store are done with fldl / fstpl which /// targets without SSE2 f64 load / store are done with fldl / fstpl which
/// also does type conversion. /// also does type conversion. Note the specified type doesn't have to be
virtual bool isLegalMemOpType(MVT VT) const; /// legal as the hook is used before type legalization.
virtual bool isSafeMemOpType(MVT VT) const;
/// allowsUnalignedMemoryAccesses - Returns true if the target allows /// allowsUnalignedMemoryAccesses - Returns true if the target allows
/// unaligned memory accesses. of the specified type. Returns whether it /// unaligned memory accesses. of the specified type. Returns whether it