[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp PPCISelLowering.cpp PPCInstrInfo.td

Chris Lattner lattner at cs.uiuc.edu
Tue May 16 23:01:45 PDT 2006



Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.185 -> 1.186
PPCISelLowering.cpp updated: 1.178 -> 1.179
PPCInstrInfo.td updated: 1.218 -> 1.219
---
Log message:

Switch PPC over to a call-selection model where the lowering code creates
the copyto/fromregs instead of making the PPCISD::CALL selection code create
them.  This vastly simplifies the selection code, and moves the ABI handling
parts into one place.


---
Diffs of the changes:  (+136 -155)

 PPCISelDAGToDAG.cpp |  124 ++++++++---------------------------------
 PPCISelLowering.cpp |  157 ++++++++++++++++++++++++++++++++++------------------
 PPCInstrInfo.td     |   10 ++-
 3 files changed, 136 insertions(+), 155 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.185 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.186
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.185	Tue May 16 18:54:25 2006
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp	Wed May 17 01:01:33 2006
@@ -874,129 +874,55 @@
 
 SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
   SDNode *N = Op.Val;
-  SDOperand Chain;
+  SDOperand Chain, Flag;
   Select(Chain, N->getOperand(0));
+  if (N->getNumOperands() == 3) // input flag
+    Select(Flag, N->getOperand(2));
   
   unsigned CallOpcode;
-  std::vector<SDOperand> CallOperands;
-  
+
+  std::vector<SDOperand> CallArgs;
   if (GlobalAddressSDNode *GASD =
       dyn_cast<GlobalAddressSDNode>(N->getOperand(1))) {
     CallOpcode = PPC::BL;
-    CallOperands.push_back(N->getOperand(1));
+    CallArgs.push_back(N->getOperand(1));
   } else if (ExternalSymbolSDNode *ESSDN =
              dyn_cast<ExternalSymbolSDNode>(N->getOperand(1))) {
     CallOpcode = PPC::BL;
-    CallOperands.push_back(N->getOperand(1));
+    CallArgs.push_back(N->getOperand(1));
   } else if (isa<ConstantSDNode>(N->getOperand(1)) &&
              isCallCompatibleAddress(cast<ConstantSDNode>(N->getOperand(1)))) {
     ConstantSDNode *C = cast<ConstantSDNode>(N->getOperand(1));
     CallOpcode = PPC::BLA;
-    CallOperands.push_back(getI32Imm((int)C->getValue() >> 2));
+    CallArgs.push_back(getI32Imm((int)C->getValue() >> 2));
   } else {
     // Copy the callee address into the CTR register.
     SDOperand Callee;
     Select(Callee, N->getOperand(1));
-    Chain = SDOperand(CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, Callee,
-                                            Chain), 0);
+    if (Flag.Val)
+      Chain = SDOperand(CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, MVT::Flag,
+                                              Callee, Chain, Flag), 0);
+    else
+      Chain = SDOperand(CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, MVT::Flag,
+                                              Callee, Chain), 0);
+    Flag = Chain.getValue(1);
     
     // Copy the callee address into R12 on darwin.
-    SDOperand R12 = CurDAG->getRegister(PPC::R12, MVT::i32);
-    Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R12, Callee);
+    Chain = CurDAG->getCopyToReg(Chain, PPC::R12, Callee, Flag);
+    Flag = Chain.getValue(1);
 
-    CallOperands.push_back(R12);
     CallOpcode = PPC::BCTRL;
   }
   
-  unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
-  static const unsigned GPR[] = {
-    PPC::R3, PPC::R4, PPC::R5, PPC::R6,
-    PPC::R7, PPC::R8, PPC::R9, PPC::R10,
-  };
-  static const unsigned FPR[] = {
-    PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
-    PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
-  };
-  static const unsigned VR[] = {
-    PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
-    PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
-  };
-  
-  SDOperand InFlag;  // Null incoming flag value.
-  
-  for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) {
-    unsigned DestReg = 0;
-    MVT::ValueType RegTy = N->getOperand(i).getValueType();
-    if (RegTy == MVT::i32) {
-      assert(GPR_idx < 8 && "Too many int args");
-      DestReg = GPR[GPR_idx++];
-    } else if (MVT::isFloatingPoint(N->getOperand(i).getValueType())) {
-      assert(FPR_idx < 13 && "Too many fp args");
-      DestReg = FPR[FPR_idx++];
-    } else {
-      assert(MVT::isVector(N->getOperand(i).getValueType()) && "unknown arg!");
-      assert(VR_idx < 12 && "Too many vector args");
-      DestReg = VR[VR_idx++];
-    }
-    
-    if (N->getOperand(i).getOpcode() != ISD::UNDEF) {
-      SDOperand Val;
-      Select(Val, N->getOperand(i));
-      Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag);
-      InFlag = Chain.getValue(1);
-      CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy));
-    }
-  }
-  
-  // Finally, once everything is in registers to pass to the call, emit the
-  // call itself.
-  if (InFlag.Val)
-    CallOperands.push_back(InFlag);   // Strong dep on register copies.
-  else
-    CallOperands.push_back(Chain);    // Weak dep on whatever occurs before
+  // Emit the call itself.
+  CallArgs.push_back(Chain);
+  if (Flag.Val)
+    CallArgs.push_back(Flag);
   Chain = SDOperand(CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag,
-                                          CallOperands), 0);
-  
-  std::vector<SDOperand> CallResults;
-  
-  // If the call has results, copy the values out of the ret val registers.
-  switch (N->getValueType(0)) {
-  default: assert(0 && "Unexpected ret value!");
-  case MVT::Other: break;
-  case MVT::i32:
-    if (N->getValueType(1) == MVT::i32) {
-      Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32, 
-                                     Chain.getValue(1)).getValue(1);
-      CallResults.push_back(Chain.getValue(0));
-      Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32,
-                                     Chain.getValue(2)).getValue(1);
-      CallResults.push_back(Chain.getValue(0));
-    } else {
-      Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32,
-                                     Chain.getValue(1)).getValue(1);
-      CallResults.push_back(Chain.getValue(0));
-    }
-    break;
-  case MVT::f32:
-  case MVT::f64:
-    Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0),
-                                   Chain.getValue(1)).getValue(1);
-    CallResults.push_back(Chain.getValue(0));
-    break;
-  case MVT::v4f32:
-  case MVT::v4i32:
-  case MVT::v8i16:
-  case MVT::v16i8:
-    Chain = CurDAG->getCopyFromReg(Chain, PPC::V2, N->getValueType(0),
-                                   Chain.getValue(1)).getValue(1);
-    CallResults.push_back(Chain.getValue(0));
-    break;
-  }
-  
-  CallResults.push_back(Chain);
-  for (unsigned i = 0, e = CallResults.size(); i != e; ++i)
-    CodeGenMap[Op.getValue(i)] = CallResults[i];
-  return CallResults[Op.ResNo];
+                                          CallArgs), 0);
+  CodeGenMap[Op.getValue(0)] = Chain;
+  CodeGenMap[Op.getValue(1)] = Chain.getValue(1);
+  return Chain.getValue(Op.ResNo);
 }
 
 // Select - Convert the specified operand from a target-independent to a


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.178 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.179
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.178	Tue May 16 19:15:40 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp	Wed May 17 01:01:33 2006
@@ -925,11 +925,25 @@
   // must be stored to our stack, and loaded into integer regs as well, if
   // any integer regs are available for argument passing.
   unsigned ArgOffset = 24;
-  unsigned GPR_remaining = 8;
-  unsigned FPR_remaining = 13;
-  unsigned VR_remaining  = 12;
-
-  std::vector<SDOperand> MemOps;
+  unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
+  static const unsigned GPR[] = {
+    PPC::R3, PPC::R4, PPC::R5, PPC::R6,
+    PPC::R7, PPC::R8, PPC::R9, PPC::R10,
+  };
+  static const unsigned FPR[] = {
+    PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
+    PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
+  };
+  static const unsigned VR[] = {
+    PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
+    PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
+  };
+  const unsigned NumGPRs = sizeof(GPR)/sizeof(GPR[0]);
+  const unsigned NumFPRs = sizeof(FPR)/sizeof(FPR[0]);
+  const unsigned NumVRs  = sizeof( VR)/sizeof( VR[0]);
+  
+  std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
+  std::vector<SDOperand> MemOpChains;
   for (unsigned i = 5, e = Op.getNumOperands(); i != e; ++i) {
     SDOperand Arg = Op.getOperand(i);
     
@@ -940,58 +954,52 @@
     switch (Arg.getValueType()) {
     default: assert(0 && "Unexpected ValueType for argument!");
     case MVT::i32:
-      if (GPR_remaining > 0) {
-        args_to_use.push_back(Arg);
-        --GPR_remaining;
+      if (GPR_idx != NumGPRs) {
+        RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Arg));
       } else {
-        MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                     Arg, PtrOff, DAG.getSrcValue(NULL)));
+        MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                          Arg, PtrOff, DAG.getSrcValue(NULL)));
       }
       ArgOffset += 4;
       break;
     case MVT::f32:
     case MVT::f64:
-      if (FPR_remaining > 0) {
-        args_to_use.push_back(Arg);
-        --FPR_remaining;
+      if (FPR_idx != NumFPRs) {
+        RegsToPass.push_back(std::make_pair(FPR[FPR_idx++], Arg));
+
         if (isVarArg) {
           SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain,
                                         Arg, PtrOff,
                                         DAG.getSrcValue(NULL));
-          MemOps.push_back(Store);
+          MemOpChains.push_back(Store);
+
           // Float varargs are always shadowed in available integer registers
-          if (GPR_remaining > 0) {
+          if (GPR_idx != NumGPRs) {
             SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff,
                                          DAG.getSrcValue(NULL));
-            MemOps.push_back(Load.getValue(1));
-            args_to_use.push_back(Load);
-            --GPR_remaining;
+            MemOpChains.push_back(Load.getValue(1));
+            RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
           }
-          if (GPR_remaining > 0 && Arg.getValueType() == MVT::f64) {
+          if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64) {
             SDOperand ConstFour = DAG.getConstant(4, PtrOff.getValueType());
             PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
             SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff,
                                          DAG.getSrcValue(NULL));
-            MemOps.push_back(Load.getValue(1));
-            args_to_use.push_back(Load);
-            --GPR_remaining;
+            MemOpChains.push_back(Load.getValue(1));
+            RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
           }
         } else {
           // If we have any FPRs remaining, we may also have GPRs remaining.
           // Args passed in FPRs consume either 1 (f32) or 2 (f64) available
           // GPRs.
-          if (GPR_remaining > 0) {
-            args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32));
-            --GPR_remaining;
-          }
-          if (GPR_remaining > 0 && Arg.getValueType() == MVT::f64) {
-            args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32));
-            --GPR_remaining;
-          }
+          if (GPR_idx != NumGPRs)
+            ++GPR_idx;
+          if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64)
+            ++GPR_idx;
         }
       } else {
-        MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                     Arg, PtrOff, DAG.getSrcValue(NULL)));
+        MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                          Arg, PtrOff, DAG.getSrcValue(NULL)));
       }
       ArgOffset += (Arg.getValueType() == MVT::f32) ? 4 : 8;
       break;
@@ -1000,43 +1008,86 @@
     case MVT::v8i16:
     case MVT::v16i8:
       assert(!isVarArg && "Don't support passing vectors to varargs yet!");
-      assert(VR_remaining &&
+      assert(VR_idx != NumVRs &&
              "Don't support passing more than 12 vector args yet!");
-      args_to_use.push_back(Arg);
-      --VR_remaining;
+      RegsToPass.push_back(std::make_pair(VR[VR_idx++], Arg));
       break;
     }
   }
-  if (!MemOps.empty())
-    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps);
+  if (!MemOpChains.empty())
+    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOpChains);
   
-  std::vector<MVT::ValueType> RetVals(Op.Val->value_begin(), 
-                                      Op.Val->value_end());
+  // Build a sequence of copy-to-reg nodes chained together with token chain
+  // and flag operands which copy the outgoing args into the appropriate regs.
+  SDOperand InFlag;
+  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
+    Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
+                             InFlag);
+    InFlag = Chain.getValue(1);
+  }
   
   // If the callee is a GlobalAddress node (quite common, every direct call is)
   // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
-    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i32);
-  
+    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), Callee.getValueType());
+
+  // Create the PPCISD::CALL node itself.
+  std::vector<MVT::ValueType> NodeTys;
+  NodeTys.push_back(MVT::Other);   // Returns a chain
+  NodeTys.push_back(MVT::Flag);    // Returns a flag for retval copy to use.
   std::vector<SDOperand> Ops;
   Ops.push_back(Chain);
   Ops.push_back(Callee);
-  Ops.insert(Ops.end(), args_to_use.begin(), args_to_use.end());
-  SDOperand TheCall = DAG.getNode(PPCISD::CALL, RetVals, Ops);
+  if (InFlag.Val)
+    Ops.push_back(InFlag);
+  Chain = DAG.getNode(PPCISD::CALL, NodeTys, Ops);
+  InFlag = Chain.getValue(1);
+  
+  std::vector<SDOperand> ResultVals;
+  NodeTys.clear();
+  
+  // If the call has results, copy the values out of the ret val registers.
+  switch (Op.Val->getValueType(0)) {
+  default: assert(0 && "Unexpected ret value!");
+  case MVT::Other: break;
+  case MVT::i32:
+    if (Op.Val->getValueType(1) == MVT::i32) {
+      Chain = DAG.getCopyFromReg(Chain, PPC::R4, MVT::i32, InFlag).getValue(1);
+      ResultVals.push_back(Chain.getValue(0));
+      Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32,
+                                 Chain.getValue(2)).getValue(1);
+      ResultVals.push_back(Chain.getValue(0));
+      NodeTys.push_back(MVT::i32);
+    } else {
+      Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, InFlag).getValue(1);
+      ResultVals.push_back(Chain.getValue(0));
+    }
+    NodeTys.push_back(MVT::i32);
+    break;
+  case MVT::f32:
+  case MVT::f64:
+    Chain = DAG.getCopyFromReg(Chain, PPC::F1, Op.Val->getValueType(0),
+                               InFlag).getValue(1);
+    ResultVals.push_back(Chain.getValue(0));
+    NodeTys.push_back(Op.Val->getValueType(0));
+    break;
+  case MVT::v4f32:
+  case MVT::v4i32:
+  case MVT::v8i16:
+  case MVT::v16i8:
+    Chain = DAG.getCopyFromReg(Chain, PPC::V2, Op.Val->getValueType(0),
+                                   InFlag).getValue(1);
+    ResultVals.push_back(Chain.getValue(0));
+    NodeTys.push_back(Op.Val->getValueType(0));
+    break;
+  }
   
-  Chain = TheCall.getValue(TheCall.Val->getNumValues()-1);
   Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
                       DAG.getConstant(NumBytes, MVT::i32));
+  NodeTys.push_back(MVT::Other);
   
-  std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
-                                    Op.Val->value_end());
-  Ops.clear();
-  
-  for (unsigned i = 0, e = TheCall.Val->getNumValues()-1; i != e; ++i)
-    Ops.push_back(SDOperand(TheCall.Val, i));
-  Ops.push_back(Chain);
-  SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, RetVT, Ops);
-  
+  ResultVals.push_back(Chain);
+  SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, ResultVals);
   return Res.getValue(Op.ResNo);
 }
 


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.218 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.219
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.218	Sat Apr 22 13:53:45 2006
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td	Wed May 17 01:01:33 2006
@@ -72,6 +72,10 @@
 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeq,[SDNPHasChain]>;
 def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_PPCCallSeq,[SDNPHasChain]>;
 
+def SDT_PPCCall   : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
+def call          : SDNode<"PPCISD::CALL", SDT_PPCCall,
+                           [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
+
 def retflag       : SDNode<"PPCISD::RET_FLAG", SDT_PPCRetFlag,
 	                   [SDNPHasChain, SDNPOptInFlag]>;
 
@@ -303,11 +307,11 @@
           LR,CTR,
           CR0,CR1,CR5,CR6,CR7] in {
   // Convenient aliases for call instructions
-  def BL  : IForm<18, 0, 1, (ops calltarget:$func, variable_ops), 
+  def BL  : IForm<18, 0, 1, (ops calltarget:$func), 
                             "bl $func", BrB, []>;
-  def BLA : IForm<18, 1, 1, (ops aaddr:$func, variable_ops),
+  def BLA : IForm<18, 1, 1, (ops aaddr:$func),
                             "bla $func", BrB, []>;
-  def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops variable_ops), "bctrl", BrB,
+  def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops), "bctrl", BrB,
                            []>;
 }
 






More information about the llvm-commits mailing list