1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

Move BaseIndexOffset in DAGCombiner.cpp so it will be available for the upcoming user

llvm-svn: 289537
This commit is contained in:
Artur Pilipenko 2016-12-13 14:16:02 +00:00
parent d5a20f83a2
commit c5f2a9227a

View File

@ -4236,6 +4236,110 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL) {
return nullptr;
}
namespace {
/// Helper struct to parse and store a memory address as base + index + offset.
/// We ignore sign extensions when it is safe to do so.
/// The following two expressions are not equivalent. To differentiate we need
/// to store whether there was a sign extension involved in the index
/// computation.
/// (load (i64 add (i64 copyfromreg %c)
/// (i64 signextend (add (i8 load %index)
/// (i8 1))))
/// vs
///
/// (load (i64 add (i64 copyfromreg %c)
/// (i64 signextend (i32 add (i32 signextend (i8 load %index))
/// (i32 1)))))
struct BaseIndexOffset {
SDValue Base;
SDValue Index;
int64_t Offset;
bool IsIndexSignExt;
BaseIndexOffset() : Offset(0), IsIndexSignExt(false) {}
BaseIndexOffset(SDValue Base, SDValue Index, int64_t Offset,
bool IsIndexSignExt) :
Base(Base), Index(Index), Offset(Offset), IsIndexSignExt(IsIndexSignExt) {}
bool equalBaseIndex(const BaseIndexOffset &Other) {
return Other.Base == Base && Other.Index == Index &&
Other.IsIndexSignExt == IsIndexSignExt;
}
/// Parses tree in Ptr for base, index, offset addresses.
static BaseIndexOffset match(SDValue Ptr, SelectionDAG &DAG) {
bool IsIndexSignExt = false;
// Split up a folded GlobalAddress+Offset into its component parts.
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Ptr))
if (GA->getOpcode() == ISD::GlobalAddress && GA->getOffset() != 0) {
return BaseIndexOffset(DAG.getGlobalAddress(GA->getGlobal(),
SDLoc(GA),
GA->getValueType(0),
/*Offset=*/0,
/*isTargetGA=*/false,
GA->getTargetFlags()),
SDValue(),
GA->getOffset(),
IsIndexSignExt);
}
// We only can pattern match BASE + INDEX + OFFSET. If Ptr is not an ADD
// instruction, then it could be just the BASE or everything else we don't
// know how to handle. Just use Ptr as BASE and give up.
if (Ptr->getOpcode() != ISD::ADD)
return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
// We know that we have at least an ADD instruction. Try to pattern match
// the simple case of BASE + OFFSET.
if (isa<ConstantSDNode>(Ptr->getOperand(1))) {
int64_t Offset = cast<ConstantSDNode>(Ptr->getOperand(1))->getSExtValue();
return BaseIndexOffset(Ptr->getOperand(0), SDValue(), Offset,
IsIndexSignExt);
}
// Inside a loop the current BASE pointer is calculated using an ADD and a
// MUL instruction. In this case Ptr is the actual BASE pointer.
// (i64 add (i64 %array_ptr)
// (i64 mul (i64 %induction_var)
// (i64 %element_size)))
if (Ptr->getOperand(1)->getOpcode() == ISD::MUL)
return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
// Look at Base + Index + Offset cases.
SDValue Base = Ptr->getOperand(0);
SDValue IndexOffset = Ptr->getOperand(1);
// Skip signextends.
if (IndexOffset->getOpcode() == ISD::SIGN_EXTEND) {
IndexOffset = IndexOffset->getOperand(0);
IsIndexSignExt = true;
}
// Either the case of Base + Index (no offset) or something else.
if (IndexOffset->getOpcode() != ISD::ADD)
return BaseIndexOffset(Base, IndexOffset, 0, IsIndexSignExt);
// Now we have the case of Base + Index + offset.
SDValue Index = IndexOffset->getOperand(0);
SDValue Offset = IndexOffset->getOperand(1);
if (!isa<ConstantSDNode>(Offset))
return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
// Ignore signextends.
if (Index->getOpcode() == ISD::SIGN_EXTEND) {
Index = Index->getOperand(0);
IsIndexSignExt = true;
} else IsIndexSignExt = false;
int64_t Off = cast<ConstantSDNode>(Offset)->getSExtValue();
return BaseIndexOffset(Base, Index, Off, IsIndexSignExt);
}
};
} // namespace
SDValue DAGCombiner::visitXOR(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
@ -11217,110 +11321,6 @@ SDValue DAGCombiner::TransformFPLoadStorePair(SDNode *N) {
return SDValue();
}
namespace {
/// Helper struct to parse and store a memory address as base + index + offset.
/// We ignore sign extensions when it is safe to do so.
/// The following two expressions are not equivalent. To differentiate we need
/// to store whether there was a sign extension involved in the index
/// computation.
/// (load (i64 add (i64 copyfromreg %c)
/// (i64 signextend (add (i8 load %index)
/// (i8 1))))
/// vs
///
/// (load (i64 add (i64 copyfromreg %c)
/// (i64 signextend (i32 add (i32 signextend (i8 load %index))
/// (i32 1)))))
struct BaseIndexOffset {
SDValue Base;
SDValue Index;
int64_t Offset;
bool IsIndexSignExt;
BaseIndexOffset() : Offset(0), IsIndexSignExt(false) {}
BaseIndexOffset(SDValue Base, SDValue Index, int64_t Offset,
bool IsIndexSignExt) :
Base(Base), Index(Index), Offset(Offset), IsIndexSignExt(IsIndexSignExt) {}
bool equalBaseIndex(const BaseIndexOffset &Other) {
return Other.Base == Base && Other.Index == Index &&
Other.IsIndexSignExt == IsIndexSignExt;
}
/// Parses tree in Ptr for base, index, offset addresses.
static BaseIndexOffset match(SDValue Ptr, SelectionDAG &DAG) {
bool IsIndexSignExt = false;
// Split up a folded GlobalAddress+Offset into its component parts.
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Ptr))
if (GA->getOpcode() == ISD::GlobalAddress && GA->getOffset() != 0) {
return BaseIndexOffset(DAG.getGlobalAddress(GA->getGlobal(),
SDLoc(GA),
GA->getValueType(0),
/*Offset=*/0,
/*isTargetGA=*/false,
GA->getTargetFlags()),
SDValue(),
GA->getOffset(),
IsIndexSignExt);
}
// We only can pattern match BASE + INDEX + OFFSET. If Ptr is not an ADD
// instruction, then it could be just the BASE or everything else we don't
// know how to handle. Just use Ptr as BASE and give up.
if (Ptr->getOpcode() != ISD::ADD)
return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
// We know that we have at least an ADD instruction. Try to pattern match
// the simple case of BASE + OFFSET.
if (isa<ConstantSDNode>(Ptr->getOperand(1))) {
int64_t Offset = cast<ConstantSDNode>(Ptr->getOperand(1))->getSExtValue();
return BaseIndexOffset(Ptr->getOperand(0), SDValue(), Offset,
IsIndexSignExt);
}
// Inside a loop the current BASE pointer is calculated using an ADD and a
// MUL instruction. In this case Ptr is the actual BASE pointer.
// (i64 add (i64 %array_ptr)
// (i64 mul (i64 %induction_var)
// (i64 %element_size)))
if (Ptr->getOperand(1)->getOpcode() == ISD::MUL)
return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
// Look at Base + Index + Offset cases.
SDValue Base = Ptr->getOperand(0);
SDValue IndexOffset = Ptr->getOperand(1);
// Skip signextends.
if (IndexOffset->getOpcode() == ISD::SIGN_EXTEND) {
IndexOffset = IndexOffset->getOperand(0);
IsIndexSignExt = true;
}
// Either the case of Base + Index (no offset) or something else.
if (IndexOffset->getOpcode() != ISD::ADD)
return BaseIndexOffset(Base, IndexOffset, 0, IsIndexSignExt);
// Now we have the case of Base + Index + offset.
SDValue Index = IndexOffset->getOperand(0);
SDValue Offset = IndexOffset->getOperand(1);
if (!isa<ConstantSDNode>(Offset))
return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
// Ignore signextends.
if (Index->getOpcode() == ISD::SIGN_EXTEND) {
Index = Index->getOperand(0);
IsIndexSignExt = true;
} else IsIndexSignExt = false;
int64_t Off = cast<ConstantSDNode>(Offset)->getSExtValue();
return BaseIndexOffset(Base, Index, Off, IsIndexSignExt);
}
};
} // namespace
// This is a helper function for visitMUL to check the profitability
// of folding (mul (add x, c1), c2) -> (add (mul x, c2), c1*c2).
// MulNode is the original multiply, AddNode is (add x, c1),