Change how FP immediates are handled.
authorNate Begeman <natebegeman@mac.com>
Thu, 14 Feb 2008 08:57:00 +0000 (08:57 +0000)
committerNate Begeman <natebegeman@mac.com>
Thu, 14 Feb 2008 08:57:00 +0000 (08:57 +0000)
1) ConstantFP is now expand by default
2) ConstantFP is not turned into TargetConstantFP during Legalize
   if it is legal.

This allows ConstantFP to be handled like Constant, allowing for
targets that can encode FP immediates as MachineOperands.

As a bonus, fix up Itanium FP constants, which now correctly match,
and match more constants!  Hooray.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47121 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/llvm/CodeGen/ScheduleDAG.h
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
lib/CodeGen/SelectionDAG/TargetLowering.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/Alpha/AlphaISelLowering.cpp
lib/Target/IA64/IA64ISelLowering.cpp
lib/Target/IA64/IA64InstrInfo.td
lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/Sparc/SparcISelDAGToDAG.cpp
lib/Target/TargetSelectionDAG.td
lib/Target/X86/X86ISelLowering.cpp
utils/TableGen/DAGISelEmitter.cpp

index 9c24f17e5fe58d974569affe649a2789a4da4170..78eb7a55d9e093d394a0263e8e905f5c49f81a76 100644 (file)
@@ -272,6 +272,7 @@ namespace llvm {
     ///
     static bool isPassiveNode(SDNode *Node) {
       if (isa<ConstantSDNode>(Node))       return true;
+      if (isa<ConstantFPSDNode>(Node))     return true;
       if (isa<RegisterSDNode>(Node))       return true;
       if (isa<GlobalAddressSDNode>(Node))  return true;
       if (isa<BasicBlockSDNode>(Node))     return true;
index 2b8d47bf25733b08987b230372ba9c5c8e20938f..f0f3d1ca7b9291360d33636eb87d6cf20740be4d 100644 (file)
@@ -1155,24 +1155,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     // leave these constants as ConstantFP nodes for the target to deal with.
     ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Node);
 
-    // Check to see if this FP immediate is already legal.
-    bool isLegal = false;
-    for (TargetLowering::legal_fpimm_iterator I = TLI.legal_fpimm_begin(),
-           E = TLI.legal_fpimm_end(); I != E; ++I)
-      if (CFP->isExactlyValue(*I)) {
-        isLegal = true;
-        break;
-      }
-
-    // If this is a legal constant, turn it into a TargetConstantFP node.
-    if (isLegal) {
-      Result = DAG.getTargetConstantFP(CFP->getValueAPF(), 
-                                       CFP->getValueType(0));
-      break;
-    }
-
     switch (TLI.getOperationAction(ISD::ConstantFP, CFP->getValueType(0))) {
     default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal:
+      break;
     case TargetLowering::Custom:
       Tmp3 = TLI.LowerOperation(Result, DAG);
       if (Tmp3.Val) {
@@ -1180,9 +1166,22 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         break;
       }
       // FALLTHROUGH
-    case TargetLowering::Expand:
+    case TargetLowering::Expand: {
+      // Check to see if this FP immediate is already legal.
+      bool isLegal = false;
+      for (TargetLowering::legal_fpimm_iterator I = TLI.legal_fpimm_begin(),
+             E = TLI.legal_fpimm_end(); I != E; ++I) {
+        if (CFP->isExactlyValue(*I)) {
+          isLegal = true;
+          break;
+        }
+      }
+      // If this is a legal constant, turn it into a TargetConstantFP node.
+      if (isLegal)
+        break;
       Result = ExpandConstantFP(CFP, true, DAG, TLI);
     }
+    }
     break;
   }
   case ISD::TokenFactor:
index 44886e76df824d861f87c76d40b8f86136a2b2d6..e7980156905ac2577202f57ef71b6b245034184e 100644 (file)
@@ -14,6 +14,7 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "pre-RA-sched"
+#include "llvm/Constants.h"
 #include "llvm/Type.h"
 #include "llvm/CodeGen/ScheduleDAG.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
@@ -478,6 +479,10 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
     }
   } else if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
     MI->addOperand(MachineOperand::CreateImm(C->getValue()));
+  } else if (ConstantFPSDNode *F = dyn_cast<ConstantFPSDNode>(Op)) {
+    const Type *FType = MVT::getTypeForValueType(Op.getValueType());
+    ConstantFP *CFP = ConstantFP::get(FType, F->getValueAPF());
+    MI->addOperand(MachineOperand::CreateFPImm(CFP));
   } else if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op)) {
     MI->addOperand(MachineOperand::CreateReg(R->getReg(), false));
   } else if (GlobalAddressSDNode *TGA = dyn_cast<GlobalAddressSDNode>(Op)) {
index f74ea5c29b29646d8ec909531d7af831d3ebb9e5..e58c2f76ff1fd45eeaec1f2fb3dd928cdd0de782 100644 (file)
@@ -174,6 +174,13 @@ TargetLowering::TargetLowering(TargetMachine &tm)
     // These operations default to expand.
     setOperationAction(ISD::FGETSIGN, (MVT::ValueType)VT, Expand);
   }
+  
+  // ConstantFP nodes default to expand.  Targets can either change this to 
+  // Legal, in which case all fp constants are legal, or use addLegalFPImmediate
+  // to optimize expansions for certain constants.
+  setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
+  setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
+  setOperationAction(ISD::ConstantFP, MVT::f80, Expand);
 
   // Default ISD::TRAP to expand (which turns it into abort).
   setOperationAction(ISD::TRAP, MVT::Other, Expand);
index a4ab39381218e9172360d98882415c8556050966..066d8e3ede2b1159b5f34b228b417f43914f26b3 100644 (file)
@@ -240,10 +240,6 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::BR_CC    , MVT::f64,   Custom);
   setOperationAction(ISD::BR_JT    , MVT::Other, Custom);
 
-  // FP Constants can't be immediates.
-  setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
-  setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
-
   // We don't support sin/cos/fmod/copysign/pow
   setOperationAction(ISD::FSIN     , MVT::f64, Expand);
   setOperationAction(ISD::FSIN     , MVT::f32, Expand);
index cf646efcda546c5f06d24a05e5d8fd86d3f4b98c..774dad3e44a05eb34e18e85f8e1d608e1fe2ee9d 100644 (file)
@@ -139,8 +139,6 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
 
   setStackPointerRegisterToSaveRestore(Alpha::R30);
 
-  setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
-  setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
   addLegalFPImmediate(APFloat(+0.0)); //F31
   addLegalFPImmediate(APFloat(+0.0f)); //F31
   addLegalFPImmediate(APFloat(-0.0)); //-F31
index ef772749ed3a6dba27bb4066c1daa102522764a5..9d74ee16d12b6b760ba5a6762b5df515ffb6b4d7 100644 (file)
@@ -120,11 +120,10 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM)
       
       computeRegisterProperties();
 
-      setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
       addLegalFPImmediate(APFloat(+0.0));
-      addLegalFPImmediate(APFloat(+0.0f));
+      addLegalFPImmediate(APFloat(-0.0));
       addLegalFPImmediate(APFloat(+1.0));
-      addLegalFPImmediate(APFloat(+1.0f));
+      addLegalFPImmediate(APFloat(-1.0));
 }
 
 const char *IA64TargetLowering::getTargetNodeName(unsigned Opcode) const {
index 5ab898b20e8978f69e14a5fb283c4cf900b24333..c8cdf2e7ab1f73716fa231419022d6cbb08559df 100644 (file)
@@ -688,6 +688,23 @@ def FP_TO_SINT : Pat<(i64 (fp_to_sint FP:$src)),
 def FP_TO_UINT : Pat<(i64 (fp_to_uint FP:$src)),
   (GETFSIG (FCVTFXUTRUNC FP:$src))>;
 
+def fpimm0 : PatLeaf<(fpimm), [{
+  return N->isExactlyValue(+0.0);
+}]>;
+def fpimm1 : PatLeaf<(fpimm), [{
+  return N->isExactlyValue(+1.0);
+}]>;
+def fpimmn0 : PatLeaf<(fpimm), [{
+  return N->isExactlyValue(-0.0);
+}]>;
+def fpimmn1 : PatLeaf<(fpimm), [{
+  return N->isExactlyValue(-1.0);
+}]>;
+
+def : Pat<(f64 fpimm0), (FMOV F0)>;
+def : Pat<(f64 fpimm1), (FMOV F1)>;
+def : Pat<(f64 fpimmn0), (FNEG F0)>;
+def : Pat<(f64 fpimmn1), (FNEG F1)>;
 
 let isTerminator = 1, isBranch = 1 in {
   def BRL_NOTCALL : RawForm<0x03, 0xb0, (outs), (ins i64imm:$dst),
index 53be370f0a1f3314c786c7d45f9f66e09fcf36f8..5ebc4c0c4259cb3fb03699bea28a64217989dc39 100644 (file)
@@ -70,9 +70,6 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
   setIndexedStoreAction(ISD::PRE_INC, MVT::i32, Legal);
   setIndexedStoreAction(ISD::PRE_INC, MVT::i64, Legal);
 
-  setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
-  setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
-
   // Shortening conversions involving ppcf128 get expanded (2 regs -> 1 reg)
   setConvertAction(MVT::ppcf128, MVT::f64, Expand);
   setConvertAction(MVT::ppcf128, MVT::f32, Expand);
index 29fe6a41602d880cd63e05eb684301997501a3e8..e8943621d3c743c1b2bd2a7483130196fffdb80b 100644 (file)
@@ -236,9 +236,6 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::STACKRESTORE      , MVT::Other, Expand);
   setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Custom);
 
-  setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
-  setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
-  
   setStackPointerRegisterToSaveRestore(SP::O6);
 
   if (TM.getSubtarget<SparcSubtarget>().isV9()) {
index dc9a9931f65fb7eedd6bc8e9228145f7d6863fce..21bdb5c04fbe33decb8dc6f823068f101d817abe 100644 (file)
@@ -224,8 +224,7 @@ def node;
 def srcvalue;
 
 def imm        : SDNode<"ISD::Constant"  , SDTIntLeaf , [], "ConstantSDNode">;
-def fpimm      : SDNode<"ISD::TargetConstantFP",
-                         SDTFPLeaf, [], "ConstantFPSDNode">;
+def fpimm      : SDNode<"ISD::ConstantFP", SDTFPLeaf  , [], "ConstantFPSDNode">;
 def vt         : SDNode<"ISD::VALUETYPE" , SDTOther   , [], "VTSDNode">;
 def bb         : SDNode<"ISD::BasicBlock", SDTOther   , [], "BasicBlockSDNode">;
 def cond       : SDNode<"ISD::CONDCODE"  , SDTOther   , [], "CondCodeSDNode">;
index 7bfb30278811a2e78a01d10b00145ddbdc72c8d2..e2c3ae0ff9b21a34e453ec42d8bcfe988e6c447b 100644 (file)
@@ -353,8 +353,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
 
     // Expand FP immediates into loads from the stack, except for the special
     // cases we handle.
-    setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
-    setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
     addLegalFPImmediate(APFloat(+0.0)); // xorpd
     addLegalFPImmediate(APFloat(+0.0f)); // xorps
 
@@ -390,10 +388,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::FCOS , MVT::f32, Expand);
     setOperationAction(ISD::FREM , MVT::f32, Expand);
 
-    // Expand FP immediates into loads from the stack, except for the special
-    // cases we handle.
-    setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
-    setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
+    // Special cases we handle for FP constants.
     addLegalFPImmediate(APFloat(+0.0f)); // xorps
     addLegalFPImmediate(APFloat(+0.0)); // FLD0
     addLegalFPImmediate(APFloat(+1.0)); // FLD1
@@ -440,9 +435,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
       setOperationAction(ISD::FSIN           , MVT::f64  , Expand);
       setOperationAction(ISD::FCOS           , MVT::f64  , Expand);
     }
-
-    setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
-    setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
     addLegalFPImmediate(APFloat(+0.0)); // FLD0
     addLegalFPImmediate(APFloat(+1.0)); // FLD1
     addLegalFPImmediate(APFloat(-0.0)); // FLD0/FCHS
@@ -458,7 +450,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::UNDEF,     MVT::f80, Expand);
   setOperationAction(ISD::FCOPYSIGN, MVT::f80, Expand);
   {
-    setOperationAction(ISD::ConstantFP, MVT::f80, Expand);
     APFloat TmpFlt(+0.0);
     TmpFlt.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven);
     addLegalFPImmediate(TmpFlt);  // FLD0
index f74b9970107a8ad5fb770c0b2dcbddc8d04d3ed2..472edbccbe0fd6149a7cdd03cf889b49adad176a 100644 (file)
@@ -764,6 +764,18 @@ public:
         Val = TmpVar;
         ModifiedVal = true;
         NodeOps.push_back(Val);
+      } else if (!N->isLeaf() && N->getOperator()->getName() == "fpimm") {
+        assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
+        std::string TmpVar =  "Tmp" + utostr(ResNo);
+        emitCode("SDOperand " + TmpVar + 
+                 " = CurDAG->getTargetConstantFP(cast<ConstantFPSDNode>(" + 
+                 Val + ")->getValueAPF(), cast<ConstantFPSDNode>(" + Val +
+                 ")->getValueType(0));");
+        // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
+        // value if used multiple times by this pattern result.
+        Val = TmpVar;
+        ModifiedVal = true;
+        NodeOps.push_back(Val);
       } else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym"){
         Record *Op = OperatorMap[N->getName()];
         // Transform ExternalSymbol to TargetExternalSymbol
@@ -1889,6 +1901,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
      << "  case ISD::Register:\n"
      << "  case ISD::HANDLENODE:\n"
      << "  case ISD::TargetConstant:\n"
+     << "  case ISD::TargetConstantFP:\n"
      << "  case ISD::TargetConstantPool:\n"
      << "  case ISD::TargetFrameIndex:\n"
      << "  case ISD::TargetExternalSymbol:\n"