[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCISelLowering.h

Chris Lattner lattner at cs.uiuc.edu
Tue May 16 11:19:02 PDT 2006



Changes in directory llvm/lib/Target/PowerPC:

PPCISelLowering.cpp updated: 1.171 -> 1.172
PPCISelLowering.h updated: 1.47 -> 1.48
---
Log message:

Switch the PPC backend over to using FORMAL_ARGUMENTS for formal argument
handling.  This makes the lower argument code significantly simpler (we
only need to handle legal argument types).

Incidentally, this also implements support for vector argument registers,
so long as they are not on the stack.


---
Diffs of the changes:  (+157 -172)

 PPCISelLowering.cpp |  325 +++++++++++++++++++++++++---------------------------
 PPCISelLowering.h   |    4 
 2 files changed, 157 insertions(+), 172 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.171 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.172
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.171	Mon May 15 23:20:24 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp	Tue May 16 13:18:50 2006
@@ -727,6 +727,161 @@
                      Op.getOperand(1), Op.getOperand(2));
 }
 
+static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
+                                       int &VarArgsFrameIndex) {
+  // TODO: add description of PPC stack frame format, or at least some docs.
+  //
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+  SSARegMap *RegMap = MF.getSSARegMap();
+  std::vector<SDOperand> ArgValues;
+  SDOperand Root = Op.getOperand(0);
+  
+  unsigned ArgOffset = 24;
+  unsigned GPR_remaining = 8;
+  unsigned FPR_remaining = 13;
+  unsigned VR_remaining  = 12;
+  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
+  };
+  
+  // Add DAG nodes to load the arguments or copy them out of registers.  On
+  // entry to a function on PPC, the arguments start at offset 24, although the
+  // first ones are often in registers.
+  for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
+    SDOperand ArgVal;
+    bool needsLoad = false;
+    bool ArgLive = !Op.Val->hasNUsesOfValue(0, ArgNo);
+    MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
+    unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
+
+    switch (ObjectVT) {
+    default: assert(0 && "Unhandled argument type!");
+    case MVT::i32:
+      if (!ArgLive) break;
+      if (GPR_remaining > 0) {
+        unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
+        MF.addLiveIn(GPR[GPR_idx], VReg);
+        ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
+      } else {
+        needsLoad = true;
+      }
+      break;
+    case MVT::f32:
+    case MVT::f64:
+      if (!ArgLive) {
+        if (FPR_remaining > 0) {
+          --FPR_remaining;
+          ++FPR_idx;
+        }        
+        break;
+      }
+      if (FPR_remaining > 0) {
+        unsigned VReg;
+        if (ObjectVT == MVT::f32)
+          VReg = RegMap->createVirtualRegister(&PPC::F4RCRegClass);
+        else
+          VReg = RegMap->createVirtualRegister(&PPC::F8RCRegClass);
+        MF.addLiveIn(FPR[FPR_idx], VReg);
+        ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
+        --FPR_remaining;
+        ++FPR_idx;
+      } else {
+        needsLoad = true;
+      }
+      break;
+    case MVT::v4f32:
+    case MVT::v4i32:
+    case MVT::v8i16:
+    case MVT::v16i8:
+      if (!ArgLive) {
+        if (VR_remaining > 0) {
+          --VR_remaining;
+          ++VR_idx;
+        }
+        break;
+      }
+      if (VR_remaining > 0) {
+        unsigned VReg = RegMap->createVirtualRegister(&PPC::VRRCRegClass);
+        MF.addLiveIn(VR[VR_idx], VReg);
+        ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
+        --VR_remaining;
+        ++VR_idx;
+      } else {
+        // This should be simple, but requires getting 16-byte aligned stack
+        // values.
+        assert(0 && "Loading VR argument not implemented yet!");
+        needsLoad = true;
+      }
+      break;
+    }
+    
+    // We need to load the argument to a virtual register if we determined above
+    // that we ran out of physical registers of the appropriate type
+    if (needsLoad) {
+      int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
+      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
+      ArgVal = DAG.getLoad(ObjectVT, Root, FIN,
+                           DAG.getSrcValue(NULL));
+    }
+    
+    // Every 4 bytes of argument space consumes one of the GPRs available for
+    // argument passing.
+    if (GPR_remaining > 0) {
+      unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1;
+      GPR_remaining -= delta;
+      GPR_idx += delta;
+    }
+    ArgOffset += ObjSize;
+    
+    if (ArgVal.Val == 0)
+      ArgVal = DAG.getNode(ISD::UNDEF, ObjectVT);
+    ArgValues.push_back(ArgVal);
+  }
+  
+  // If the function takes variable number of arguments, make a frame index for
+  // the start of the first vararg value... for expansion of llvm.va_start.
+  bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
+  if (isVarArg) {
+    VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset);
+    SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
+    // If this function is vararg, store any remaining integer argument regs
+    // to their spots on the stack so that they may be loaded by deferencing the
+    // result of va_next.
+    std::vector<SDOperand> MemOps;
+    for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
+      unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
+      MF.addLiveIn(GPR[GPR_idx], VReg);
+      SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::i32);
+      SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
+                                    Val, FIN, DAG.getSrcValue(NULL));
+      MemOps.push_back(Store);
+      // Increment the address by four for the next argument to store
+      SDOperand PtrOff = DAG.getConstant(4, MVT::i32);
+      FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff);
+    }
+    if (!MemOps.empty())
+      Root = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps);
+  }
+  
+  ArgValues.push_back(Root);
+ 
+  // Return the new list of results.
+  std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
+                                    Op.Val->value_end());
+  return DAG.getNode(ISD::MERGE_VALUES, RetVT, ArgValues);
+}
+
 static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
   SDOperand Copy;
   switch(Op.getNumOperands()) {
@@ -1690,6 +1845,8 @@
   case ISD::JumpTable:          return LowerJumpTable(Op, DAG);
   case ISD::SETCC:              return LowerSETCC(Op, DAG);
   case ISD::VASTART:            return LowerVASTART(Op, DAG, VarArgsFrameIndex);
+  case ISD::FORMAL_ARGUMENTS:   return LowerFORMAL_ARGUMENTS(Op, DAG,
+                                                             VarArgsFrameIndex);
   case ISD::RET:                return LowerRET(Op, DAG);
     
   case ISD::SELECT_CC:          return LowerSELECT_CC(Op, DAG);
@@ -1715,174 +1872,6 @@
 //  Other Lowering Code
 //===----------------------------------------------------------------------===//
 
-std::vector<SDOperand>
-PPCTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
-  //
-  // add beautiful description of PPC stack frame format, or at least some docs
-  //
-  MachineFunction &MF = DAG.getMachineFunction();
-  MachineFrameInfo *MFI = MF.getFrameInfo();
-  SSARegMap *RegMap = MF.getSSARegMap();
-  std::vector<SDOperand> ArgValues;
-  
-  unsigned ArgOffset = 24;
-  unsigned GPR_remaining = 8;
-  unsigned FPR_remaining = 13;
-  unsigned GPR_idx = 0, FPR_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
-  };
-  
-  // Add DAG nodes to load the arguments...  On entry to a function on PPC,
-  // the arguments start at offset 24, although they are likely to be passed
-  // in registers.
-  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
-    SDOperand newroot, argt;
-    unsigned ObjSize;
-    bool needsLoad = false;
-    bool ArgLive = !I->use_empty();
-    MVT::ValueType ObjectVT = getValueType(I->getType());
-    
-    switch (ObjectVT) {
-    default: assert(0 && "Unhandled argument type!");
-    case MVT::i1:
-    case MVT::i8:
-    case MVT::i16:
-    case MVT::i32:
-      ObjSize = 4;
-      if (!ArgLive) break;
-      if (GPR_remaining > 0) {
-        unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
-        MF.addLiveIn(GPR[GPR_idx], VReg);
-        argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
-        if (ObjectVT != MVT::i32) {
-          unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext 
-                                                       : ISD::AssertZext;
-          argt = DAG.getNode(AssertOp, MVT::i32, argt, 
-                             DAG.getValueType(ObjectVT));
-          argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, argt);
-        }
-      } else {
-        needsLoad = true;
-      }
-      break;
-    case MVT::i64:
-      ObjSize = 8;
-      if (!ArgLive) break;
-      if (GPR_remaining > 0) {
-        SDOperand argHi, argLo;
-        unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
-        MF.addLiveIn(GPR[GPR_idx], VReg);
-        argHi = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
-        // If we have two or more remaining argument registers, then both halves
-        // of the i64 can be sourced from there.  Otherwise, the lower half will
-        // have to come off the stack.  This can happen when an i64 is preceded
-        // by 28 bytes of arguments.
-        if (GPR_remaining > 1) {
-          unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
-          MF.addLiveIn(GPR[GPR_idx+1], VReg);
-          argLo = DAG.getCopyFromReg(argHi, VReg, MVT::i32);
-        } else {
-          int FI = MFI->CreateFixedObject(4, ArgOffset+4);
-          SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
-          argLo = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN,
-                              DAG.getSrcValue(NULL));
-        }
-        // Build the outgoing arg thingy
-        argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi);
-        newroot = argLo;
-      } else {
-        needsLoad = true;
-      }
-      break;
-    case MVT::f32:
-    case MVT::f64:
-      ObjSize = (ObjectVT == MVT::f64) ? 8 : 4;
-      if (!ArgLive) {
-        if (FPR_remaining > 0) {
-          --FPR_remaining;
-          ++FPR_idx;
-        }        
-        break;
-      }
-      if (FPR_remaining > 0) {
-        unsigned VReg;
-        if (ObjectVT == MVT::f32)
-          VReg = RegMap->createVirtualRegister(&PPC::F4RCRegClass);
-        else
-          VReg = RegMap->createVirtualRegister(&PPC::F8RCRegClass);
-        MF.addLiveIn(FPR[FPR_idx], VReg);
-        argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, ObjectVT);
-        --FPR_remaining;
-        ++FPR_idx;
-      } else {
-        needsLoad = true;
-      }
-      break;
-    }
-    
-    // We need to load the argument to a virtual register if we determined above
-    // that we ran out of physical registers of the appropriate type
-    if (needsLoad) {
-      unsigned SubregOffset = 0;
-      if (ObjectVT == MVT::i8 || ObjectVT == MVT::i1) SubregOffset = 3;
-      if (ObjectVT == MVT::i16) SubregOffset = 2;
-      int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
-      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
-      FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN,
-                        DAG.getConstant(SubregOffset, MVT::i32));
-      argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
-                                   DAG.getSrcValue(NULL));
-    }
-    
-    // Every 4 bytes of argument space consumes one of the GPRs available for
-    // argument passing.
-    if (GPR_remaining > 0) {
-      unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1;
-      GPR_remaining -= delta;
-      GPR_idx += delta;
-    }
-    ArgOffset += ObjSize;
-    if (newroot.Val)
-      DAG.setRoot(newroot.getValue(1));
-    
-    ArgValues.push_back(argt);
-  }
-  
-  // If the function takes variable number of arguments, make a frame index for
-  // the start of the first vararg value... for expansion of llvm.va_start.
-  if (F.isVarArg()) {
-    VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset);
-    SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
-    // If this function is vararg, store any remaining integer argument regs
-    // to their spots on the stack so that they may be loaded by deferencing the
-    // result of va_next.
-    std::vector<SDOperand> MemOps;
-    for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
-      unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
-      MF.addLiveIn(GPR[GPR_idx], VReg);
-      SDOperand Val = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
-      SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
-                                    Val, FIN, DAG.getSrcValue(NULL));
-      MemOps.push_back(Store);
-      // Increment the address by four for the next argument to store
-      SDOperand PtrOff = DAG.getConstant(4, getPointerTy());
-      FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff);
-    }
-    if (!MemOps.empty()) {
-      MemOps.push_back(DAG.getRoot());
-      DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps));
-    }
-  }
-  
-  return ArgValues;
-}
-
 std::pair<SDOperand, SDOperand>
 PPCTargetLowering::LowerCallTo(SDOperand Chain,
                                const Type *RetTy, bool isVarArg,


Index: llvm/lib/Target/PowerPC/PPCISelLowering.h
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.47 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.48
--- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.47	Tue Apr 18 12:59:36 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.h	Tue May 16 13:18:50 2006
@@ -166,10 +166,6 @@
                                                 uint64_t &KnownZero, 
                                                 uint64_t &KnownOne,
                                                 unsigned Depth = 0) const;
-    /// LowerArguments - This hook must be implemented to indicate how we should
-    /// lower the arguments for the specified function, into the specified DAG.
-    virtual std::vector<SDOperand>
-      LowerArguments(Function &F, SelectionDAG &DAG);
     
     /// LowerCallTo - This hook lowers an abstract call to a function into an
     /// actual call.






More information about the llvm-commits mailing list