diff options
-rw-r--r-- | include/llvm/CodeGen/SelectionDAGISel.h | 12 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 21 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelDAGToDAG.cpp | 4 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | 13 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16ISelLowering.cpp | 3 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 3 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelDAGToDAG.cpp | 36 | ||||
-rw-r--r-- | utils/TableGen/DAGISelEmitter.cpp | 10 |
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)"); } } |