[llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp IA64ISelLowering.cpp IA64ISelLowering.h IA64InstrInfo.td

Duraid Madina duraid at octopus.com.au
Fri Jan 20 12:24:42 PST 2006



Changes in directory llvm/lib/Target/IA64:

IA64ISelDAGToDAG.cpp updated: 1.27 -> 1.28
IA64ISelLowering.cpp updated: 1.24 -> 1.25
IA64ISelLowering.h updated: 1.4 -> 1.5
IA64InstrInfo.td updated: 1.41 -> 1.42
---
Log message:


remove RET hack, add proper support for rets (watching out for ret voids)



---
Diffs of the changes:  (+89 -56)

 IA64ISelDAGToDAG.cpp |   51 ---------------------------------------
 IA64ISelLowering.cpp |   66 +++++++++++++++++++++++++++++++++++++++++++++++++++
 IA64ISelLowering.h   |   16 ++++++++++--
 IA64InstrInfo.td     |   12 ++++++---
 4 files changed, 89 insertions(+), 56 deletions(-)


Index: llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp
diff -u llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.27 llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.28
--- llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.27	Fri Jan 20 10:10:05 2006
+++ llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp	Fri Jan 20 14:24:31 2006
@@ -585,57 +585,6 @@
                                 getI64Imm(Amt), Select(N->getOperand(0)));
   }
 
-  case ISD::RET: {
-    SDOperand Chain = Select(N->getOperand(0));     // Token chain.
-    SDOperand InFlag;
-
-    switch (N->getNumOperands()) {
-    default:
-      assert(0 && "Unknown return instruction!");
-    case 2: {
-      SDOperand RetVal = Select(N->getOperand(1));
-      switch (RetVal.getValueType()) {
-      default: assert(0 && "I don't know how to return this type! (promote?)");
-               // FIXME: do I need to add support for bools here?
-               // (return '0' or '1' in r8, basically...)
-               //
-               // FIXME: need to round floats - 80 bits is bad, the tester
-               // told me so
-      case MVT::i64:
-        // we mark r8 as live on exit up above in LowerArguments()
-        // BuildMI(BB, IA64::MOV, 1, IA64::r8).addReg(Tmp1);
-        Chain = CurDAG->getCopyToReg(Chain, IA64::r8, RetVal);
-	InFlag = Chain.getValue(1);
-	break;
-      case MVT::f64:
-        // we mark F8 as live on exit up above in LowerArguments()
-        // BuildMI(BB, IA64::FMOV, 1, IA64::F8).addReg(Tmp1);
-        Chain = CurDAG->getCopyToReg(Chain, IA64::F8, RetVal);
-	InFlag = Chain.getValue(1);
-        break;
-      }
-      break;
-      }
-    case 1:
-      break;
-    }
-
-    // we need to copy VirtGPR (the vreg (to become a real reg)) that holds
-    // the output of this function's alloc instruction back into ar.pfs
-    // before we return. this copy must not float up above the last 
-    // outgoing call in this function!!!
-    SDOperand AR_PFSVal = CurDAG->getCopyFromReg(Chain, IA64Lowering.VirtGPR,
-		                                  MVT::i64);
-    Chain = AR_PFSVal.getValue(1);
-    Chain = CurDAG->getCopyToReg(Chain, IA64::AR_PFS, AR_PFSVal);
-
-    // and then just emit a 'ret' instruction
-    // before returning, restore the ar.pfs register (set by the 'alloc' up top)
-    // BuildMI(BB, IA64::MOV, 1).addReg(IA64::AR_PFS).addReg(IA64Lowering.VirtGPR);
-    //
-    return CurDAG->SelectNodeTo(N, IA64::RET, MVT::Other, Chain);
-  }
-  
   case ISD::BR:
 		 // FIXME: we don't need long branches all the time!
     return CurDAG->SelectNodeTo(N, IA64::BRL_NOTCALL, MVT::Other, 


Index: llvm/lib/Target/IA64/IA64ISelLowering.cpp
diff -u llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.24 llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.25
--- llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.24	Fri Jan 20 10:10:05 2006
+++ llvm/lib/Target/IA64/IA64ISelLowering.cpp	Fri Jan 20 14:24:31 2006
@@ -39,6 +39,11 @@
       setOperationAction(ISD::BRTWOWAY_CC      , MVT::Other, Expand);
       setOperationAction(ISD::FP_ROUND_INREG   , MVT::f32  , Expand);
 
+      // We need to handle ISD::RET for void functions ourselves,
+      // so we get a chance to restore ar.pfs before adding a
+      // br.ret insn
+      setOperationAction(ISD::RET, MVT::Other, Custom);
+
       setSetCCResultType(MVT::i1);
       setShiftAmountType(MVT::i64);
 
@@ -101,6 +106,7 @@
   default: return 0;
   case IA64ISD::GETFD:  return "IA64ISD::GETFD";
   case IA64ISD::BRCALL: return "IA64ISD::BRCALL";  
+  case IA64ISD::RET_FLAG: return "IA64ISD::RET_FLAG";
   }
 }
   
@@ -524,6 +530,44 @@
   return std::make_pair(RetVal, Chain);
 }
 
+SDOperand IA64TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
+                                               SelectionDAG &DAG) {
+  SDOperand Copy, InFlag;
+  SDOperand AR_PFSVal = DAG.getCopyFromReg(Chain, this->VirtGPR,
+	                                       MVT::i64);
+  Chain = AR_PFSVal.getValue(1);
+
+  switch (Op.getValueType()) {
+  default: assert(0 && "Unknown type to return! (promote?)");
+  case MVT::i64:
+    Copy = DAG.getCopyToReg(Chain, IA64::r8, Op, InFlag);
+    break;
+  case MVT::f64:
+    Copy = DAG.getCopyToReg(Chain, IA64::F8, Op, InFlag);
+    break;
+  }
+
+  Chain = Copy.getValue(0);
+  InFlag = Copy.getValue(1);
+  // we need to copy VirtGPR (the vreg (to become a real reg)) that holds
+  // the output of this function's alloc instruction back into ar.pfs
+  // before we return. this copy must not float up above the last 
+  // outgoing call in this function - we flag this to the ret instruction
+  Chain = DAG.getCopyToReg(Chain, IA64::AR_PFS, AR_PFSVal, InFlag);
+  InFlag = Chain.getValue(1);
+  
+  // and then just emit a 'ret' instruction
+  std::vector<MVT::ValueType> NodeTys;
+  std::vector<SDOperand> RetOperands;
+  NodeTys.push_back(MVT::Other);
+  NodeTys.push_back(MVT::Flag);
+  RetOperands.push_back(Chain);
+  RetOperands.push_back(InFlag);
+
+  return DAG.getNode(IA64ISD::RET_FLAG, NodeTys, RetOperands);
+//  return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, MVT::Other, Copy, Chain, InFlag);
+}
+
 SDOperand
 IA64TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
                                  Value *VAListV, SelectionDAG &DAG) {
@@ -566,3 +610,25 @@
   abort();
 }
 
+SDOperand IA64TargetLowering::
+LowerOperation(SDOperand Op, SelectionDAG &DAG) {
+  switch (Op.getOpcode()) {
+  default: assert(0 && "Should not custom lower this!");
+  case ISD::RET: { // the DAGgy stuff takes care of
+    // restoring ar.pfs before adding a br.ret for functions
+    // that return something, but we need to take care of stuff
+    // that returns void manually, so here it is:
+    assert(Op.getNumOperands()==1 &&
+      "trying to custom lower a return other than void! (numops!=1)");
+    
+    SDOperand Chain = Op.getOperand(0);
+    SDOperand AR_PFSVal = DAG.getCopyFromReg(Chain, this->VirtGPR,
+		                                  MVT::i64);
+    Chain = AR_PFSVal.getValue(1);
+    Chain = DAG.getCopyToReg(Chain, IA64::AR_PFS, AR_PFSVal);
+
+    // and then just emit a 'ret' instruction
+    return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, Chain);
+  }
+  }
+}


Index: llvm/lib/Target/IA64/IA64ISelLowering.h
diff -u llvm/lib/Target/IA64/IA64ISelLowering.h:1.4 llvm/lib/Target/IA64/IA64ISelLowering.h:1.5
--- llvm/lib/Target/IA64/IA64ISelLowering.h:1.4	Sat Jan 14 16:27:21 2006
+++ llvm/lib/Target/IA64/IA64ISelLowering.h	Fri Jan 20 14:24:31 2006
@@ -30,7 +30,10 @@
       GETFD,
 
       // TODO: explain this hack
-      BRCALL
+      BRCALL,
+      
+      // RET_FLAG - Return with a flag operand
+      RET_FLAG
     };
   }  
   
@@ -64,9 +67,18 @@
                   bool isTailCall, SDOperand Callee, ArgListTy &Args,
                   SelectionDAG &DAG);
     
+    /// LowerReturnTo - This spits out restore-previous-frame-state+br.ret
+    /// instructions
+    virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
+                                    SelectionDAG &DAG);
+    
+    /// LowerOperation - for custom lowering specific ops
+    /// (currently, only "ret void")
+    virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+    
     virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
                                    Value *VAListV, SelectionDAG &DAG);
-    
+
     virtual std::pair<SDOperand,SDOperand>
       LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
                  const Type *ArgTy, SelectionDAG &DAG);


Index: llvm/lib/Target/IA64/IA64InstrInfo.td
diff -u llvm/lib/Target/IA64/IA64InstrInfo.td:1.41 llvm/lib/Target/IA64/IA64InstrInfo.td:1.42
--- llvm/lib/Target/IA64/IA64InstrInfo.td:1.41	Thu Jan 19 21:40:25 2006
+++ llvm/lib/Target/IA64/IA64InstrInfo.td	Fri Jan 20 14:24:31 2006
@@ -21,6 +21,10 @@
 
 def IA64getfd : SDNode<"IA64ISD::GETFD", SDTFPToIntOp, []>;
 
+def SDT_IA64RetFlag : SDTypeProfile<0, 0, []>;
+def retflag         : SDNode<"IA64ISD::RET_FLAG", SDT_IA64RetFlag,
+	                   [SDNPHasChain, SDNPOptInFlag]>;
+
 //===---------
 
 def u2imm : Operand<i8>;
@@ -717,7 +721,9 @@
     "($qp) br.cond.call.sptk $dst;;">;
 }
 
+// Return branch:
 let isTerminator = 1, isReturn = 1, noResults = 1 in
-  def RET : RawForm<0x03, 0xb0, (ops), "br.ret.sptk.many rp;;">; // return
-
-
+  def RET : AForm_DAG<0x03, 0x0b, (ops),
+            "br.ret.sptk.many rp;;",
+            [(retflag)]>; // return
+def : Pat<(ret), (RET)>;






More information about the llvm-commits mailing list