Adding support for dag combiner to promote operations for profit. This requires target specific queries. For example, x86 should promote i16 to i32 when it does not impact load folding.

x86 support is off by default. It can be enabled with -promote-16bit.

Work in progress.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101448 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-04-16 06:14:10 +00:00
parent 47b7b9f228
commit 64b7bf71e8
4 changed files with 97 additions and 6 deletions

View File

@ -880,6 +880,13 @@ public:
/// more complex transformations.
///
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
/// PerformDAGCombinePromotion - This method query the target whether it is
/// beneficial for dag combiner to promote the specified node. If true, it
/// should return the desired promotion type by reference.
virtual bool PerformDAGCombinePromotion(SDValue Op, EVT &PVT) const {
return false;
}
//===--------------------------------------------------------------------===//
// TargetLowering Configuration Methods - These methods should be invoked by

View File

@ -129,6 +129,7 @@ namespace {
bool CombineToPreIndexedLoadStore(SDNode *N);
bool CombineToPostIndexedLoadStore(SDNode *N);
SDValue PromoteIntBinOp(SDValue Op);
/// combine - call the node-specific routine that knows how to fold each
/// particular type of node. If that doesn't do anything, try the
@ -633,6 +634,46 @@ bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) {
return true;
}
static SDValue PromoteOperand(SDValue Op, EVT PVT, SelectionDAG &DAG) {
unsigned Opc = ISD::ZERO_EXTEND;
if (Op.getOpcode() == ISD::Constant) {
// Zero extend things like i1, sign extend everything else. It shouldn't
// matter in theory which one we pick, but this tends to give better code?
// See DAGTypeLegalizer::PromoteIntRes_Constant.
if (Op.getValueType().isByteSized())
Opc = ISD::SIGN_EXTEND;
}
return DAG.getNode(Opc, Op.getDebugLoc(), PVT, Op);
}
/// PromoteIntBinOp - Promote the specified integer binary operation if the
/// target indicates it is beneficial. e.g. On x86, it's usually better to
/// promote i16 operations to i32 since i16 instructions are longer.
SDValue DAGCombiner::PromoteIntBinOp(SDValue Op) {
if (!LegalOperations)
return SDValue();
EVT VT = Op.getValueType();
if (VT.isVector() || !VT.isInteger())
return SDValue();
EVT PVT = VT;
if (TLI.PerformDAGCombinePromotion(Op, PVT)) {
assert(PVT != VT && "Don't know what type to promote to!");
SDValue N0 = PromoteOperand(Op.getOperand(0), PVT, DAG);
AddToWorkList(N0.getNode());
SDValue N1 = PromoteOperand(Op.getOperand(1), PVT, DAG);
AddToWorkList(N1.getNode());
DebugLoc dl = Op.getDebugLoc();
return DAG.getNode(ISD::TRUNCATE, dl, VT,
DAG.getNode(Op.getOpcode(), dl, PVT, N0, N1));
}
return SDValue();
}
//===----------------------------------------------------------------------===//
// Main DAG Combiner implementation
//===----------------------------------------------------------------------===//
@ -1112,7 +1153,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
N0.getOperand(0).getOperand(1),
N0.getOperand(1)));
return SDValue();
return PromoteIntBinOp(SDValue(N, 0));
}
SDValue DAGCombiner::visitADDC(SDNode *N) {
@ -1250,7 +1291,7 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
VT);
}
return SDValue();
return PromoteIntBinOp(SDValue(N, 0));
}
SDValue DAGCombiner::visitMUL(SDNode *N) {
@ -1343,7 +1384,7 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
if (RMUL.getNode() != 0)
return RMUL;
return SDValue();
return PromoteIntBinOp(SDValue(N, 0));
}
SDValue DAGCombiner::visitSDIV(SDNode *N) {
@ -1987,7 +2028,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
}
}
return SDValue();
return PromoteIntBinOp(SDValue(N, 0));
}
SDValue DAGCombiner::visitOR(SDNode *N) {
@ -2113,7 +2154,7 @@ SDValue DAGCombiner::visitOR(SDNode *N) {
if (SDNode *Rot = MatchRotate(N0, N1, N->getDebugLoc()))
return SDValue(Rot, 0);
return SDValue();
return PromoteIntBinOp(SDValue(N, 0));
}
/// MatchRotateHalf - Match "(X shl/srl V1) & V2" where V2 may not be present.
@ -2422,7 +2463,7 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
SimplifyDemandedBits(SDValue(N, 0)))
return SDValue(N, 0);
return SDValue();
return PromoteIntBinOp(SDValue(N, 0));
}
/// visitShiftByConstant - Handle transforms common to the three shifts, when

View File

@ -64,6 +64,9 @@ DisableMMX("disable-mmx", cl::Hidden, cl::desc("Disable use of MMX"));
static cl::opt<bool>
Disable16Bit("disable-16bit", cl::Hidden,
cl::desc("Disable use of 16-bit instructions"));
static cl::opt<bool>
Promote16Bit("promote-16bit", cl::Hidden,
cl::desc("Promote 16-bit instructions"));
// Forward declarations.
static SDValue getMOVL(SelectionDAG &DAG, DebugLoc dl, EVT VT, SDValue V1,
@ -9906,6 +9909,44 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
return SDValue();
}
/// PerformDAGCombinePromotion - This method query the target whether it is
/// beneficial for dag combiner to promote the specified node. If true, it
/// should return the desired promotion type by reference.
bool X86TargetLowering::PerformDAGCombinePromotion(SDValue Op, EVT &PVT) const {
if (!Promote16Bit)
return false;
EVT VT = Op.getValueType();
if (VT != MVT::i16)
return false;
bool Commute = true;
switch (Op.getOpcode()) {
default: return false;
case ISD::SUB:
Commute = false;
// fallthrough
case ISD::ADD:
case ISD::MUL:
case ISD::AND:
case ISD::OR:
case ISD::XOR: {
SDValue N0 = Op.getOperand(0);
SDValue N1 = Op.getOperand(1);
if (!Commute && isa<LoadSDNode>(N1))
return false;
// Avoid disabling potential load folding opportunities.
if ((isa<LoadSDNode>(N0) && N0.hasOneUse()) && !isa<ConstantSDNode>(N1))
return false;
if ((isa<LoadSDNode>(N1) && N1.hasOneUse()) && !isa<ConstantSDNode>(N0))
return false;
}
}
PVT = MVT::i32;
return true;
}
//===----------------------------------------------------------------------===//
// X86 Inline Assembly Support
//===----------------------------------------------------------------------===//

View File

@ -452,6 +452,8 @@ namespace llvm {
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
virtual bool PerformDAGCombinePromotion(SDValue Op, EVT &PVT) const;
virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *MBB,
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const;