[llvm-commits] [llvm] r131942 - /llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp

Akira Hatanaka ahatanak at gmail.com
Mon May 23 17:23:52 PDT 2011


Author: ahatanak
Date: Mon May 23 19:23:52 2011
New Revision: 131942

URL: http://llvm.org/viewvc/llvm-project?rev=131942&view=rev
Log:
Simplify offset calculation of stack frame objects for $gp restore location and
variable arguments in LowerCall and LowerFormalArguments. This should also fix
the bug in which handling of variable arguments is incorrect when the front-end
optimizes away unused fixed arguments.

Modified:
    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=131942&r1=131941&r2=131942&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon May 23 19:23:52 2011
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "mips-lower"
+//#include <algorithm>
 #include "MipsISelLowering.h"
 #include "MipsMachineFunction.h"
 #include "MipsTargetMachine.h"
@@ -1064,7 +1065,6 @@
   // With EABI is it possible to have 16 args on registers.
   SmallVector<std::pair<unsigned, SDValue>, 16> RegsToPass;
   SmallVector<SDValue, 8> MemOpChains;
-  unsigned NextStackOffset = (Subtarget->isABI_EABI() ? 0 : 16);
 
   MipsFI->setHasCall();
 
@@ -1125,11 +1125,8 @@
     // This guarantees that when allocating Local Area the firsts
     // 16 bytes which are alwayes reserved won't be overwritten
     // if O32 ABI is used. For EABI the first address is zero.
-    unsigned ArgSize = VA.getValVT().getSizeInBits()/8;
-    NextStackOffset = VA.getLocMemOffset();
-    LastFI = MFI->CreateFixedObject(ArgSize, NextStackOffset, true);
-    NextStackOffset += ArgSize;
-
+    LastFI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8, 
+                                    VA.getLocMemOffset(), true);
     SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy());
 
     // emit ISD::STORE whichs stores the
@@ -1236,6 +1233,12 @@
     // Function can have an arbitrary number of calls, so
     // hold the LastArgStackLoc with the biggest offset.
     int MaxCallFrameSize = MipsFI->getMaxCallFrameSize();
+    unsigned NextStackOffset = CCInfo.getNextStackOffset();
+
+    // For O32, a minimum of four words (16 bytes) of argument space is
+    // allocated.
+    if (Subtarget->isABI_O32())
+      NextStackOffset = std::max(NextStackOffset, (unsigned)16);
 
     if (MaxCallFrameSize < (int)NextStackOffset) {
       MipsFI->setMaxCallFrameSize(NextStackOffset);
@@ -1318,9 +1321,6 @@
   // Used with vargs to acumulate store chains.
   std::vector<SDValue> OutChains;
 
-  // Keep track of the last register used for arguments
-  unsigned ArgRegEnd = 0;
-
   // Assign locations to all of the incoming arguments.
   SmallVector<CCValAssign, 16> ArgLocs;
   CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
@@ -1331,8 +1331,6 @@
   else
     CCInfo.AnalyzeFormalArguments(Ins, CC_Mips);
 
-  unsigned NextStackOffset = (Subtarget->isABI_EABI() ? 0 : 16);
-  EVT LastRegArgValVT;
   int LastFI = 0;// MipsFI->LastInArgFI is 0 at the entry of this function.
 
   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
@@ -1341,8 +1339,7 @@
     // Arguments stored on registers
     if (VA.isRegLoc()) {
       EVT RegVT = VA.getLocVT();
-      ArgRegEnd = VA.getLocReg();
-      LastRegArgValVT = VA.getValVT();
+      unsigned ArgReg = VA.getLocReg();
       TargetRegisterClass *RC = 0;
 
       if (RegVT == MVT::i32)
@@ -1357,7 +1354,7 @@
 
       // Transform the arguments stored on
       // physical registers into virtual ones
-      unsigned Reg = AddLiveIn(DAG.getMachineFunction(), ArgRegEnd, RC);
+      unsigned Reg = AddLiveIn(DAG.getMachineFunction(), ArgReg, RC);
       SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
 
       // If this is an 8 or 16-bit value, it has been passed promoted
@@ -1396,9 +1393,6 @@
       // sanity check
       assert(VA.isMemLoc());
 
-      // The last argument is not a register anymore
-      ArgRegEnd = 0;
-
       // The stack pointer offset is relative to the caller stack frame.
       // Since the real stack size is unknown here, a negative SPOffset
       // is used so there's a way to adjust these offsets when the stack
@@ -1406,10 +1400,8 @@
       // used instead of a direct negative address (which is recorded to
       // be used on emitPrologue) to avoid mis-calc of the first stack
       // offset on PEI::calculateFrameObjectOffsets.
-      unsigned ArgSize = VA.getValVT().getSizeInBits()/8;
-      NextStackOffset = VA.getLocMemOffset();
-      LastFI = MFI->CreateFixedObject(ArgSize, NextStackOffset, true);
-      NextStackOffset += ArgSize;
+      LastFI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8,
+                                      VA.getLocMemOffset(), true);
 
       // Create load nodes to retrieve arguments from the stack
       SDValue FIN = DAG.getFrameIndex(LastFI, getPointerTy());
@@ -1436,44 +1428,27 @@
   // must have their values written to the caller stack frame. If the last
   // argument was placed in the stack, there's no need to save any register.
   if (isVarArg && Subtarget->isABI_O32()) {
-    if (ArgRegEnd) {
-      // Last named formal argument is passed in register.
+    // Record the frame index of the first variable argument
+    // which is a value necessary to VASTART.    
+    unsigned NextStackOffset = CCInfo.getNextStackOffset();
+    LastFI = MFI->CreateFixedObject(4, NextStackOffset, true);
+    MipsFI->setVarArgsFrameIndex(LastFI);
+    
+    const unsigned O32IntRegs[] = {
+      Mips::A0, Mips::A1, Mips::A2, Mips::A3
+    };
 
-      // The last register argument that must be saved is Mips::A3
+    // Copy variable arguments passed in registers to stack.
+    for (; NextStackOffset < 16; NextStackOffset += 4) {
       TargetRegisterClass *RC = Mips::CPURegsRegisterClass;
-      if (LastRegArgValVT == MVT::f64)
-        ArgRegEnd++;
-
-      if (ArgRegEnd < Mips::A3) {
-        // Both the last named formal argument and the first variable
-        // argument are passed in registers.
-        for (++ArgRegEnd; ArgRegEnd <= Mips::A3; ++ArgRegEnd) {
-          unsigned Reg = AddLiveIn(DAG.getMachineFunction(), ArgRegEnd, RC);
-          SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, MVT::i32);
-
-          LastFI = MFI->CreateFixedObject(4, (ArgRegEnd-Mips::A0)*4, true);
-          SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy());
-          OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff,
-                                           MachinePointerInfo(),
-                                           false, false, 0));
-
-          // Record the frame index of the first variable argument
-          // which is a value necessary to VASTART.
-          if (!MipsFI->getVarArgsFrameIndex())
-            MipsFI->setVarArgsFrameIndex(LastFI);
-        }
-      } else {
-        // Last named formal argument is in register Mips::A3, and the first
-        // variable argument is on stack. Record the frame index of the first
-        // variable argument.
-        LastFI = MFI->CreateFixedObject(4, 16, true);
-        MipsFI->setVarArgsFrameIndex(LastFI);
-      }
-    } else {
-      // Last named formal argument and all the variable arguments are passed
-      // on stack. Record the frame index of the first variable argument.
+      unsigned Idx = NextStackOffset / 4;
+      unsigned Reg = AddLiveIn(DAG.getMachineFunction(), O32IntRegs[Idx], RC);
+      SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, MVT::i32);
       LastFI = MFI->CreateFixedObject(4, NextStackOffset, true);
-      MipsFI->setVarArgsFrameIndex(LastFI);
+      SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy());
+      OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff,
+                                       MachinePointerInfo(),
+                                       false, false, 0));
     }
   }
 





More information about the llvm-commits mailing list