aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h12
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp21
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp4
-rw-r--r--lib/Target/MSP430/MSP430ISelDAGToDAG.cpp13
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.cpp3
-rw-r--r--lib/Target/SystemZ/SystemZISelDAGToDAG.cpp3
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp36
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp10
8 files changed, 63 insertions, 39 deletions
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index b33b21d..ae78c55 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -85,11 +85,13 @@ public:
return true;
}
- /// IsLegalAndProfitableToFold - Returns true if the specific operand node N of
- /// U can be folded during instruction selection that starts at Root and
- /// folding N is profitable.
- virtual
- bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const;
+ /// IsProfitableToFold - Returns true if it's profitable to fold the specific
+ /// operand node N of U during instruction selection that starts at Root.
+ virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const;
+
+ /// IsLegalToFold - Returns true if the specific operand node N of
+ /// U can be folded during instruction selection that starts at Root.
+ virtual bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const;
/// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
/// to use for this target when scheduling the DAG.
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index da2e6e4..eead526 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1341,8 +1341,7 @@ static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,
/// isNonImmUse - Start searching from Root up the DAG to check is Def can
/// be reached. Return true if that's the case. However, ignore direct uses
/// by ImmedUse (which would be U in the example illustrated in
-/// IsLegalAndProfitableToFold) and by Root (which can happen in the store
-/// case).
+/// IsLegalToFold) and by Root (which can happen in the store case).
/// FIXME: to be really generic, we should allow direct use by any node
/// that is being folded. But realisticly since we only fold loads which
/// have one non-chain use, we only need to watch out for load/op/store
@@ -1353,11 +1352,17 @@ static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse) {
return findNonImmUse(Root, Def, ImmedUse, Root, Visited);
}
-/// IsLegalAndProfitableToFold - Returns true if the specific operand node N of
-/// U can be folded during instruction selection that starts at Root and
-/// folding N is profitable.
-bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const {
+/// IsProfitableToFold - Returns true if it's profitable to fold the specific
+/// operand node N of U during instruction selection that starts at Root.
+bool SelectionDAGISel::IsProfitableToFold(SDValue N, SDNode *U,
+ SDNode *Root) const {
+ if (OptLevel == CodeGenOpt::None) return false;
+ return N.hasOneUse();
+}
+
+/// IsLegalToFold - Returns true if the specific operand node N of
+/// U can be folded during instruction selection that starts at Root.
+bool SelectionDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const {
if (OptLevel == CodeGenOpt::None) return false;
// If Root use can somehow reach N through a path that that doesn't contain
@@ -1411,7 +1416,7 @@ bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
VT = Root->getValueType(Root->getNumValues()-1);
}
- return !isNonImmUse(Root, N, U);
+ return !isNonImmUse(Root, N.getNode(), U);
}
SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) {
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index a458269..df4ae70 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -58,6 +58,8 @@ public:
return "ARM Instruction Selection";
}
+ virtual void InstructionSelect();
+
/// getI32Imm - Return a target constant of type i32 with the specified
/// value.
inline SDValue getI32Imm(unsigned Imm) {
@@ -65,7 +67,7 @@ public:
}
SDNode *Select(SDNode *N);
- virtual void InstructionSelect();
+
bool SelectShifterOperandReg(SDNode *Op, SDValue N, SDValue &A,
SDValue &B, SDValue &C);
bool SelectAddrMode2(SDNode *Op, SDValue N, SDValue &Base,
diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
index 4eec757..a8c5e0af 100644
--- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
+++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
@@ -133,8 +133,7 @@ namespace {
bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM);
bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM);
- bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const;
+ bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const;
virtual bool
SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
@@ -336,8 +335,8 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
return false;
}
-bool MSP430DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const {
+bool MSP430DAGToDAGISel::IsLegalToFold(SDValue N, SDNode *U,
+ SDNode *Root) const {
if (OptLevel == CodeGenOpt::None) return false;
/// RMW preprocessing creates the following code:
@@ -364,11 +363,11 @@ bool MSP430DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
/// during preprocessing) to determine whether it's legal to introduce such
/// "cycle" for a moment.
DenseMap<SDNode*, SDNode*>::const_iterator I = RMWStores.find(Root);
- if (I != RMWStores.end() && I->second == N)
+ if (I != RMWStores.end() && I->second == N.getNode())
return true;
// Proceed to 'generic' cycle finder code
- return SelectionDAGISel::IsLegalAndProfitableToFold(N, U, Root);
+ return SelectionDAGISel::IsLegalToFold(N, U, Root);
}
@@ -656,7 +655,7 @@ SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op,
unsigned Opc8, unsigned Opc16) {
if (N1.getOpcode() == ISD::LOAD &&
N1.hasOneUse() &&
- IsLegalAndProfitableToFold(N1.getNode(), Op, Op)) {
+ IsLegalToFold(N1, Op, Op)) {
LoadSDNode *LD = cast<LoadSDNode>(N1);
if (!isValidIndexedLoad(LD))
return NULL;
diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp
index 92b5c7b..d2fc8db 100644
--- a/lib/Target/PIC16/PIC16ISelLowering.cpp
+++ b/lib/Target/PIC16/PIC16ISelLowering.cpp
@@ -1513,8 +1513,7 @@ bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp,
// Direct load operands are folded in binary operations. But before folding
// verify if this folding is legal. Fold only if it is legal otherwise
// convert this direct load to a separate memory operation.
- if(ISel->IsLegalAndProfitableToFold(Op.getOperand(0).getNode(),
- Op.getNode(), Op.getNode()))
+ if(ISel->IsLegalToFold(Op.getOperand(0), Op.getNode(), Op.getNode()))
return false;
else
MemOp = 0;
diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
index f6f632d..7f0d9fb 100644
--- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -594,8 +594,7 @@ bool SystemZDAGToDAGISel::SelectLAAddr(SDNode *Op, SDValue Addr,
bool SystemZDAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Disp, SDValue &Index) {
if (ISD::isNON_EXTLoad(N.getNode()) &&
- N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), P, P))
+ IsLegalToFold(N, P, P))
return SelectAddrRRI20(P, N.getOperand(1), Base, Disp, Index);
return false;
}
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 7bd935d..7b349f6 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -183,8 +183,9 @@ namespace {
virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
- virtual
- bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const;
+ virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const;
+
+ virtual bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const;
// Include the pieces autogenerated from the target description.
#include "X86GenDAGISel.inc"
@@ -303,11 +304,18 @@ namespace {
}
-bool X86DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const {
+bool
+X86DAGToDAGISel::IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const {
if (OptLevel == CodeGenOpt::None) return false;
- if (U == Root)
+ if (!N.hasOneUse())
+ return false;
+
+ if (N.getOpcode() != ISD::LOAD)
+ return true;
+
+ // If N is a load, do additional profitability checks.
+ if (U == Root) {
switch (U->getOpcode()) {
default: break;
case X86ISD::ADD:
@@ -354,9 +362,17 @@ bool X86DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
}
}
}
+ }
+
+ return true;
+}
+
+
+bool X86DAGToDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const {
+ if (OptLevel == CodeGenOpt::None) return false;
// Proceed to 'generic' cycle finder code
- return SelectionDAGISel::IsLegalAndProfitableToFold(N, U, Root);
+ return SelectionDAGISel::IsLegalToFold(N, U, Root);
}
/// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand
@@ -1311,8 +1327,8 @@ bool X86DAGToDAGISel::SelectScalarSSELoad(SDNode *Op, SDValue Pred,
InChain = N.getOperand(0).getValue(1);
if (ISD::isNON_EXTLoad(InChain.getNode()) &&
InChain.getValue(0).hasOneUse() &&
- N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), Pred.getNode(), Op)) {
+ IsProfitableToFold(N, Pred.getNode(), Op) &&
+ IsLegalToFold(N, Pred.getNode(), Op)) {
LoadSDNode *LD = cast<LoadSDNode>(InChain);
if (!SelectAddr(Op, LD->getBasePtr(), Base, Scale, Index, Disp, Segment))
return false;
@@ -1436,8 +1452,8 @@ bool X86DAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N,
SDValue &Index, SDValue &Disp,
SDValue &Segment) {
if (ISD::isNON_EXTLoad(N.getNode()) &&
- N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), P, P))
+ IsProfitableToFold(N, P, P) &&
+ IsLegalToFold(N, P, P))
return SelectAddr(P, N.getOperand(1), Base, Scale, Index, Disp, Segment);
return false;
}
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 0eb06bb..d2e260e 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -566,8 +566,11 @@ void PatternCodeEmitter::EmitMatchCode(TreePatternNode *N, TreePatternNode *P,
if (NodeHasChain)
OpNo = 1;
if (!isRoot) {
- // Multiple uses of actual result?
- emitCheck(getValueName(RootName) + ".hasOneUse()");
+ // Check if it's profitable to fold the node. e.g. Check for multiple uses
+ // of actual result?
+ std::string ParentName(RootName.begin(), RootName.end()-1);
+ emitCheck("IsProfitableToFold(" + getValueName(RootName) +
+ ", " + getNodeName(ParentName) + ", N)");
EmittedUseCheck = true;
if (NodeHasChain) {
// If the immediate use can somehow reach this node through another
@@ -597,8 +600,7 @@ void PatternCodeEmitter::EmitMatchCode(TreePatternNode *N, TreePatternNode *P,
}
if (NeedCheck) {
- std::string ParentName(RootName.begin(), RootName.end()-1);
- emitCheck("IsLegalAndProfitableToFold(" + getNodeName(RootName) +
+ emitCheck("IsLegalToFold(" + getValueName(RootName) +
", " + getNodeName(ParentName) + ", N)");
}
}