Params are not being generated as static globals now. The caller passes them onto...
authorSanjiv Gupta <sanjiv.gupta@microchip.com>
Thu, 2 Apr 2009 17:42:00 +0000 (17:42 +0000)
committerSanjiv Gupta <sanjiv.gupta@microchip.com>
Thu, 2 Apr 2009 17:42:00 +0000 (17:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68327 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PIC16/PIC16AsmPrinter.cpp
lib/Target/PIC16/PIC16AsmPrinter.h
lib/Target/PIC16/PIC16ISelLowering.cpp
lib/Target/PIC16/PIC16ISelLowering.h
lib/Target/PIC16/PIC16InstrInfo.td

index 3696d5afeb5b05e42927bcc58d8ea356e0e43dcd..6a5c2e03718994eab2398bec24d16d5f1dd40357 100644 (file)
@@ -335,6 +335,7 @@ bool PIC16AsmPrinter::doFinalization(Module &M) {
 void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
   const Function *F = MF.getFunction();
   std::string FuncName = Mang->getValueName(F);
+  MachineFrameInfo *MFI= MF.getFrameInfo();
   Module *M = const_cast<Module *>(F->getParent());
   const TargetData *TD = TM.getTargetData();
   unsigned FrameSize = 0;
@@ -346,15 +347,30 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
                                                SectionFlags::Writeable);
   SwitchToSection(fDataSection);
   
-  //Emit function return value.
-  O << CurrentFnName << ".retval:\n";
+
+  // Emit function frame label
+  O << CurrentFnName << ".frame:\n";
+
   const Type *RetType = F->getReturnType();
   unsigned RetSize = 0; 
   if (RetType->getTypeID() != Type::VoidTyID) 
     RetSize = TD->getTypePaddedSize(RetType);
   
-  // Emit function arguments.
-  O << CurrentFnName << ".args:\n";
+  //Emit function return value space
+  if(RetSize > 0)
+     O << CurrentFnName << ".retval    RES  " << RetSize << "\n";
+  else
+     O << CurrentFnName << ".retval:\n";
+   
+  // Emit variable to hold the space for function arguments 
+  unsigned ArgSize = 0;
+  for (Function::const_arg_iterator argi = F->arg_begin(),
+           arge = F->arg_end(); argi != arge ; ++argi) {
+    const Type *Ty = argi->getType();
+    ArgSize += TD->getTypePaddedSize(Ty);
+   }
+  O << CurrentFnName << ".args      RES  " << ArgSize << "\n";
+
   // Emit the function variables. 
    
   // In PIC16 all the function arguments and local variables are global.
@@ -382,34 +398,15 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
     O << VarName << "  RES  " << Size << "\n";
   }
 
-  // Return value can not overlap with temp data, becasue a temp slot
-  // may be read/written after a return value is calculated and saved 
-  // within the function.
-  if (RetSize > FrameSize)
-    O << CurrentFnName << ".dummy" << " RES " << (RetSize - FrameSize) << "\n";
-
-  emitFunctionTempData(MF, FrameSize);
-}
 
-void PIC16AsmPrinter::emitFunctionTempData(MachineFunction &MF,
-                                           unsigned &FrameSize) {
-  // Emit temporary variables.
-  MachineFrameInfo *FrameInfo = MF.getFrameInfo();
-  if (FrameInfo->hasStackObjects()) {
-    int indexBegin = FrameInfo->getObjectIndexBegin();
-    int indexEnd = FrameInfo->getObjectIndexEnd();
-
-    if (indexBegin < indexEnd) { 
-      FrameSize += indexEnd - indexBegin; 
-      O << CurrentFnName << ".tmp RES"<< " " 
-        <<indexEnd - indexBegin <<"\n";
-    } 
-    /*
-    while (indexBegin < indexEnd) {
-        O << CurrentFnName << "_tmp_" << indexBegin << " " << "RES"<< " " 
-          << 1 << "\n" ;
-        indexBegin++;
+  // Emit the variable to hold the space for temporary locations
+  // in function frame.
+  if (MFI->hasStackObjects()) {
+    int indexBegin = MFI->getObjectIndexBegin();
+    int indexEnd = MFI->getObjectIndexEnd();
+    if (indexBegin < indexEnd) {
+      int TempSize = indexEnd - indexBegin; 
+      O << CurrentFnName << ".tmp       RES  " << TempSize <<"\n";
     }
-    */
   }
 }
index 5479717a455f2a1b077245c5a3d5bba94d60006c..5286dd2e7a38616b9257baa933051ea769f93516 100644 (file)
@@ -45,7 +45,6 @@ namespace llvm {
     void EmitUnInitData (Module &M);
     void EmitRomData (Module &M);
     void emitFunctionData(MachineFunction &MF);
-    void emitFunctionTempData(MachineFunction &MF, unsigned &FrameSize);
 
     protected:
     bool doInitialization(Module &M);
index 3ace4821d8d8a8dd61530f2f847f71afac3e492b..cbe3a9dc1ea00540fa4bd7e50bbe256b4fabd94b 100644 (file)
@@ -244,6 +244,7 @@ const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const {
   case PIC16ISD::MTHI:             return "PIC16ISD::MTHI";
   case PIC16ISD::Banksel:          return "PIC16ISD::Banksel";
   case PIC16ISD::PIC16Load:        return "PIC16ISD::PIC16Load";
+  case PIC16ISD::PIC16LdArg:       return "PIC16ISD::PIC16LdArg";
   case PIC16ISD::PIC16LdWF:        return "PIC16ISD::PIC16LdWF";
   case PIC16ISD::PIC16Store:       return "PIC16ISD::PIC16Store";
   case PIC16ISD::PIC16StWF:        return "PIC16ISD::PIC16StWF";
@@ -503,13 +504,24 @@ PIC16TargetLowering::LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG,
 
   MachineFunction &MF = DAG.getMachineFunction();
   const Function *Func = MF.getFunction();
+  MachineFrameInfo *MFI = MF.getFrameInfo();
   const std::string Name = Func->getName();
 
   char *tmpName = new char [strlen(Name.c_str()) +  8];
-  sprintf(tmpName, "%s.args", Name.c_str());
+  sprintf(tmpName, "%s.frame", Name.c_str());
   ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
   FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(Op);
-  Offset = FR->getIndex();
+
+  // FrameIndices are not stack offsets. But they represent the request
+  // for space on stack. That space requested may be more than one byte. 
+  // Therefore, to calculate the stack offset that a FrameIndex aligns
+  // with, we need to traverse all the FrameIndices available earlier in 
+  // the list and add their requested size.
+  unsigned FIndex = FR->getIndex();
+  Offset = 0;
+  for (unsigned i=0; i<FIndex ; ++i) {
+    Offset += MFI->getObjectSize(i);
+  }
 
   return;
 }
@@ -810,7 +822,7 @@ SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
   const Function *Func = MF.getFunction();
   const std::string FuncName = Func->getName();
 
-  char *tmpName = new char [strlen(FuncName.c_str()) +  6];
+  char *tmpName = new char [strlen(FuncName.c_str()) +  8];
 
   // Put the value on stack.
   // Get a stack slot index and convert to es.
@@ -938,11 +950,41 @@ PIC16TargetLowering::LowerCallReturn(SDValue Op, SDValue Chain,
 }
 
 SDValue PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
- //int NumOps = Op.getNode()->getNumOperands();
+  SDValue Chain = Op.getOperand(0);
+  DebugLoc dl = Op.getDebugLoc();
+
+  if (Op.getNumOperands() == 1)   // return void
+    return Op;
+
+  // return should have odd number of operands
+  if ((Op.getNumOperands() % 2) == 0 ) {
+    assert(0 && "Do not know how to return this many arguments!");
+    abort();
+  }
+  
+  // Number of values to return 
+  unsigned NumRet = (Op.getNumOperands() / 2);
+
+  // Function returns value always on stack with the offset starting
+  // from 0 
+  MachineFunction &MF = DAG.getMachineFunction();
+  const Function *F = MF.getFunction();
+  std::string FuncName = F->getName();
 
- // For default cases LLVM returns the value on the function frame 
- // So let LLVM do this for all the cases other than character
- return Op; 
+  char *tmpName = new char [strlen(FuncName.c_str()) +  8];
+  sprintf(tmpName, "%s.frame", FuncName.c_str());
+  SDVTList VTs  = DAG.getVTList (MVT::i8, MVT::Other);
+  SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
+  SDValue BS = DAG.getConstant(1, MVT::i8);
+  SDValue RetVal;
+  for(unsigned i=0;i<NumRet; ++i) {
+    RetVal = Op.getNode()->getOperand(2*i + 1);
+    Chain =  DAG.getNode (PIC16ISD::PIC16Store, dl, MVT::Other, Chain, RetVal,
+                        ES, BS,
+                        DAG.getConstant (i, MVT::i8));
+      
+  }
+  return DAG.getNode(ISD::RET, dl, MVT::Other, Chain);
 }
 
 SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
@@ -1164,13 +1206,26 @@ SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) {
 SDValue PIC16TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, 
                                                     SelectionDAG &DAG) {
   SmallVector<SDValue, 8> ArgValues;
-  unsigned NumArgs = Op.getNumOperands() - 3;
+  unsigned NumArgs = Op.getNode()->getNumValues()-1;
   DebugLoc dl = Op.getDebugLoc();
+  SDValue Chain = Op.getOperand(0);    // Formal arguments' chain
 
-  // Creating UNDEF nodes to meet the requirement of MERGE_VALUES node.
-  for(unsigned i = 0 ; i<NumArgs ; i++) {
-    SDValue TempNode = DAG.getUNDEF(Op.getNode()->getValueType(i));
-    ArgValues.push_back(TempNode);
+  MachineFunction &MF = DAG.getMachineFunction();
+  //const TargetData *TD = getTargetData();
+  const Function *F = MF.getFunction();
+  std::string FuncName = F->getName();
+
+  char *tmpName = new char [strlen(FuncName.c_str()) +  6];
+  sprintf(tmpName, "%s.args", FuncName.c_str());
+  SDVTList VTs  = DAG.getVTList (MVT::i8, MVT::Other);
+  SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
+  SDValue BS = DAG.getConstant(1, MVT::i8);
+  for (unsigned i=0; i<NumArgs ; ++i) {
+    SDValue Offset = DAG.getConstant(i, MVT::i8);
+    SDValue PICLoad = DAG.getNode(PIC16ISD::PIC16LdArg, dl, VTs, Chain, ES, BS,
+                                     Offset);
+    Chain = getChain(PICLoad);
+    ArgValues.push_back(PICLoad);
   }
 
   ArgValues.push_back(Op.getOperand(0));
@@ -1191,11 +1246,34 @@ PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const {
   return SDValue();
 }
 
+// For all the functions with arguments some STORE nodes are generated 
+// that store the argument on the frameindex. However in PIC16 the arguments
+// are passed on stack only. Therefore these STORE nodes are redundant. 
+// To remove these STORE nodes will be removed in PerformStoreCombine 
+//
+// Currently this function is doint nothing and will be updated for removing
+// unwanted store operations
+SDValue PIC16TargetLowering::
+PerformStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const {
+  SelectionDAG &DAG = DCI.DAG;
+  SDValue Chain;
+  return SDValue(N, 0);
+  /*
+  // Storing an undef value is of no use, so remove it
+  if (isStoringUndef(N, Chain, DAG)) {
+    return Chain; // remove the store and return the chain
+  }
+  //else everything is ok.
+  return SDValue(N, 0);
+  */
+}
 
 SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N, 
                                                DAGCombinerInfo &DCI) const {
   switch (N->getOpcode()) {
-  case PIC16ISD::PIC16Load:
+  case ISD::STORE:   
+   return PerformStoreCombine(N, DCI); 
+  case PIC16ISD::PIC16Load:   
     return PerformPIC16LoadCombine(N, DCI);
   }
   return SDValue();
index 75e824a0a6b9c4c9535bde8468aad5bfd4eca36c..b2a89db3ea83821948cfb510d48e6e586e542812 100644 (file)
@@ -29,6 +29,10 @@ namespace llvm {
       Lo,            // Low 8-bits of GlobalAddress.
       Hi,            // High 8-bits of GlobalAddress.
       PIC16Load,
+      PIC16LdArg,   // This is replica of PIC16Load but used to load function 
+                    // arguments and is being used for facilitating for some 
+                    // store removal optimizations. 
+
       PIC16LdWF,
       PIC16Store,
       PIC16StWF,
@@ -103,17 +107,17 @@ namespace llvm {
 
     SDValue ExpandStore(SDNode *N, SelectionDAG &DAG);
     SDValue ExpandLoad(SDNode *N, SelectionDAG &DAG);
-    //SDValue ExpandAdd(SDNode *N, SelectionDAG &DAG);
     SDValue ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG);
     SDValue ExpandExternalSymbol(SDNode *N, SelectionDAG &DAG);
     SDValue ExpandFrameIndex(SDNode *N, SelectionDAG &DAG);
 
     SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; 
     SDValue PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const; 
+    SDValue PerformStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const; 
 
   private:
-    // If the Node is a BUILD_PAIR representing representing an Address
-    // then this function will return true
+    // If the Node is a BUILD_PAIR representing a direct Address,
+    // then this function will return true.
     bool isDirectAddress(const SDValue &Op);
 
     // If the Node is a DirectAddress in ROM_SPACE then this 
@@ -149,14 +153,14 @@ namespace llvm {
 
 
     // Extending the LIB Call framework of LLVM
-    // To hold the names of PIC16Libcalls
+    // to hold the names of PIC16Libcalls.
     const char *PIC16LibcallNames[PIC16ISD::PIC16UnknownCall]; 
 
-    // To set and retrieve the lib call names
+    // To set and retrieve the lib call names.
     void setPIC16LibcallName(PIC16ISD::PIC16Libcall Call, const char *Name);
     const char *getPIC16LibcallName(PIC16ISD::PIC16Libcall Call);
 
-    // Make PIC16 Libcall
+    // Make PIC16 Libcall.
     SDValue MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, MVT RetVT, 
                              const SDValue *Ops, unsigned NumOps, bool isSigned,
                              SelectionDAG &DAG, DebugLoc dl);
index 40119d0a89dbb62ad5f9384022566f72b00bb82c..471180fa491647f4f4de00a4065267a4d0a65651 100644 (file)
@@ -88,8 +88,9 @@ def PIC16StWF : SDNode<"PIC16ISD::PIC16StWF", SDT_PIC16Store,
                        [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
 
 // Node to match a direct load operation.
-def PIC16Load : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>;
-def PIC16LdWF : SDNode<"PIC16ISD::PIC16LdWF", SDT_PIC16Load, 
+def PIC16Load  : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>;
+def PIC16LdArg  : SDNode<"PIC16ISD::PIC16LdArg", SDT_PIC16Load, [SDNPHasChain]>;
+def PIC16LdWF  : SDNode<"PIC16ISD::PIC16LdWF", SDT_PIC16Load, 
                        [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
 
 // Node to match PIC16 call
@@ -267,6 +268,7 @@ def movf : MOVF_INSN<0, tglobaladdr, PIC16Load>;
 
 // Load from an ES.
 def movf_1 : MOVF_INSN<0, texternalsym, PIC16Load>;
+def movf_1_1 : MOVF_INSN<0, texternalsym, PIC16LdArg>;
 
 // Load with InFlag and OutFlag
 // This is same as movf_1 but has a flag. A flag is required to