Added functions to generate prolog and epilog code.
authorVikram S. Adve <vadve@cs.uiuc.edu>
Mon, 22 Oct 2001 13:36:31 +0000 (13:36 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Mon, 22 Oct 2001 13:36:31 +0000 (13:36 +0000)
Use JMPLRET instead of RETURN for method returns so that

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@939 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SparcV9/SparcV9InstrSelection.cpp

index 8841cc8ed81c245016ae359e8974c10b71aba41d..dc8ab1b761f7c103365057888a0f0f6d7032a59d 100644 (file)
 
 //******************** Internal Data Declarations ************************/
 
-// to be used later
-struct BranchPattern {
-  bool          flipCondition; // should the sense of the test be reversed
-  BasicBlock*   targetBB;      // which basic block to branch to
-  MachineInstr* extraBranch;   // if neither branch is fall-through, then this
-                               // BA must be inserted after the cond'l one
-};
 
 //************************* Forward Declarations ***************************/
 
@@ -50,46 +43,6 @@ static void SetMemOperands_Internal     (MachineInstr* minstr,
 //************************ Internal Functions ******************************/
 
 
-//------------------------------------------------------------------------ 
-// External Function: ThisIsAChainRule
-//
-// Purpose:
-//   Check if a given BURG rule is a chain rule.
-//------------------------------------------------------------------------ 
-
-extern bool
-ThisIsAChainRule(int eruleno)
-{
-  switch(eruleno)
-    {
-    case 111:  // stmt:  reg
-    case 113:  // stmt:  bool
-    case 123:
-    case 124:
-    case 125:
-    case 126:
-    case 127:
-    case 128:
-    case 129:
-    case 130:
-    case 131:
-    case 132:
-    case 133:
-    case 155:
-    case 221:
-    case 222:
-    case 241:
-    case 242:
-    case 243:
-    case 244:
-      return true; break;
-      
-    default:
-      return false; break;
-    }
-}
-
-
 static inline MachineOpCode 
 ChooseBprInstruction(const InstructionNode* instrNode)
 {
@@ -1026,28 +979,99 @@ CreateCopyInstructionsByType(const TargetMachine& target,
 }
 
 
-// This function is currently unused and incomplete but will be 
-// used if we have a linear layout of basic blocks in LLVM code.
-// It decides which branch should fall-through, and whether an
-// extra unconditional branch is needed (when neither falls through).
-// 
-void
-ChooseBranchPattern(Instruction* vmInstr, BranchPattern& brPattern)
+//******************* Externally Visible Functions *************************/
+
+
+//------------------------------------------------------------------------ 
+// External Function: GetInstructionsForProlog
+// External Function: GetInstructionsForEpilog
+//
+// Purpose:
+//   Create prolog and epilog code for procedure entry and exit
+//------------------------------------------------------------------------ 
+
+extern unsigned
+GetInstructionsForProlog(BasicBlock* entryBB,
+                         TargetMachine &target,
+                         MachineInstr** mvec)
 {
-  BranchInst* brInstr = (BranchInst*) vmInstr;
-  
-  brPattern.flipCondition = false;
-  brPattern.targetBB      = brInstr->getSuccessor(0);
-  brPattern.extraBranch   = NULL;
+  int64_t s0=0;                // used to avoid overloading ambiguity below
+  
+  // The second operand is the stack size. If it does not fit in the
+  // immediate field, we either have to find an unused register in the
+  // caller's window or move some elements to the dynamically allocated
+  // area of the stack frame (just above save area and method args).
+  Method* method = entryBB->getParent();
+  MachineCodeForMethod& mcodeInfo = method->getMachineCode();
+  unsigned int staticStackSize = mcodeInfo.getStaticStackSize();
+  
+  assert(target.getInstrInfo().constantFitsInImmedField(SAVE, staticStackSize)
+         && "Stack size too large for immediate field of SAVE instruction. Need additional work as described in the comment above");
+  
+  mvec[0] = new MachineInstr(SAVE);
+  mvec[0]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
+  mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
+                                staticStackSize);
+  mvec[0]->SetMachineOperand(2, target.getRegInfo().getStackPointer());
+  
+  return 1;
+}
+
+
+extern unsigned
+GetInstructionsForEpilog(BasicBlock* anExitBB,
+                         TargetMachine &target,
+                         MachineInstr** mvec)
+{
+  int64_t s0=0;                // used to avoid overloading ambiguity below
   
-  assert(brInstr->getNumSuccessors() > 1 &&
-         "Unnecessary analysis for unconditional branch");
+  mvec[0] = new MachineInstr(RESTORE);
+  mvec[0]->SetMachineOperand(0, target.getRegInfo().getZeroRegNum());
+  mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed, s0);
+  mvec[0]->SetMachineOperand(2, target.getRegInfo().getZeroRegNum());
   
-  assert(0 && "Fold branches in peephole optimization");
+  return 1;
 }
 
 
-//******************* Externally Visible Functions *************************/
+//------------------------------------------------------------------------ 
+// External Function: ThisIsAChainRule
+//
+// Purpose:
+//   Check if a given BURG rule is a chain rule.
+//------------------------------------------------------------------------ 
+
+extern bool
+ThisIsAChainRule(int eruleno)
+{
+  switch(eruleno)
+    {
+    case 111:  // stmt:  reg
+    case 113:  // stmt:  bool
+    case 123:
+    case 124:
+    case 125:
+    case 126:
+    case 127:
+    case 128:
+    case 129:
+    case 130:
+    case 131:
+    case 132:
+    case 133:
+    case 155:
+    case 221:
+    case 222:
+    case 241:
+    case 242:
+    case 243:
+    case 244:
+      return true; break;
+      
+    default:
+      return false; break;
+    }
+}
 
 
 //------------------------------------------------------------------------ 
@@ -1062,7 +1086,7 @@ unsigned
 GetInstructionsByRule(InstructionNode* subtreeRoot,
                       int ruleForNode,
                       short* nts,
-                      TargetMachine &target,
+                      TargetMachine &tgt,
                       MachineInstr** mvec)
 {
   int numInstr = 1;                    // initialize for common case
@@ -1074,7 +1098,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
   int64_t s0=0, s8=8;                  // variables holding constants to avoid
   uint64_t u0=0;                       // overloading ambiguities below
   
-  mvec[0] = mvec[1] = mvec[2] = mvec[3] = NULL;        // just for safety
+  UltraSparc& target = (UltraSparc&) tgt;
+  
+  for (unsigned i=0; i < MAX_INSTR_PER_VMINSTR; i++)
+    mvec[i] = NULL;
   
   // 
   // Let's check for chain rules outside the switch so that we don't have
@@ -1101,25 +1128,27 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
                 // Mark the return-address register as a hidden virtual reg.
                 // Mark the return value   register as an implicit ref of
                 // the machine instruction.
-        {              
+        {      // Finally put a NOP in the delay slot.
         ReturnInst* returnInstr = (ReturnInst*) subtreeRoot->getInstruction();
         assert(returnInstr->getOpcode() == Instruction::Ret);
+        Method* method = returnInstr->getParent()->getParent();
         
         Instruction* returnReg = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
                                                     returnInstr, NULL);
         returnInstr->getMachineInstrVec().addTempValue(returnReg);
-
-        mvec[0] = new MachineInstr(RETURN);
+        
+        mvec[0] = new MachineInstr(JMPLRET);
         mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
                                       returnReg);
         mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,s8);
+        mvec[0]->SetMachineOperand(2, target.getRegInfo().getZeroRegNum());
         
         if (returnInstr->getReturnValue() != NULL)
           mvec[0]->addImplicitRef(returnInstr->getReturnValue());
         
-        // returnReg->addMachineInstruction(mvec[0]);
+        unsigned n = numInstr++; // delay slot
+        mvec[n] = new MachineInstr(NOP);
         
-        mvec[numInstr++] = new MachineInstr(NOP); // delay slot
         break;
         }  
         
@@ -1605,9 +1634,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
         break;
 
-      case 57: // reg:   Alloca: Implement as 2 instructions:
-                    // sub %sp, tmp -> %sp
-        {              //      add %sp, 0   -> result
+      case 57: // reg:   Alloca: Implement as 1 instruction:
+        {      //      add %fp, offsetFromFP -> result
         Instruction* instr = subtreeRoot->getInstruction();
         const PointerType* instrType = (const PointerType*) instr->getType();
         assert(instrType->isPointerType());
@@ -1615,25 +1643,24 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
           target.findOptimalStorageSize(instrType->getValueType());
         assert(tsize != 0 && "Just to check when this can happen");
         
-        // Create a temporary Value to hold the constant type-size
-        ConstPoolSInt* valueForTSize = ConstPoolSInt::get(Type::IntTy, tsize);
-
-        // Instruction 1: sub %sp, tsize -> %sp
-        // tsize is always constant, but it may have to be put into a
-        // register if it doesn't fit in the immediate field.
-        // 
-        mvec[0] = new MachineInstr(SUB);
-        mvec[0]->SetMachineOperand(0, /*regNum %sp=o6=r[14]*/(unsigned int)14);
+        Method* method = instr->getParent()->getParent();
+        MachineCodeForMethod& mcode = method->getMachineCode();
+        int offsetFromFP =
+          target.getFrameInfo().getFirstAutomaticVarOffsetFromFP(method)
+          - (tsize + mcode.getAutomaticVarsSize());
+        
+        mcode.putLocalVarAtOffsetFromFP(instr, offsetFromFP, tsize);
+        
+        // Create a temporary Value to hold the constant offset.
+        // This is needed because it may not fit in the immediate field.
+        ConstPoolSInt* offsetVal=ConstPoolSInt::get(Type::IntTy, offsetFromFP);
+        
+        // Instruction 1: add %fp, offsetFromFP -> result
+        mvec[0] = new MachineInstr(ADD);
+        mvec[0]->SetMachineOperand(0, target.getRegInfo().getFramePointer());
         mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
-                                      valueForTSize);
-        mvec[0]->SetMachineOperand(2, /*regNum %sp=o6=r[14]*/(unsigned int)14);
-
-        // Instruction 2: add %sp, 0 -> result
-        numInstr++;
-        mvec[1] = new MachineInstr(ADD);
-        mvec[1]->SetMachineOperand(0, /*regNum %sp=o6=r[14]*/(unsigned int)14);
-        mvec[1]->SetMachineOperand(1, target.getRegInfo().getZeroRegNum());
-        mvec[1]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
+                                      offsetVal); 
+        mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
                                       instr);
         break;
         }
@@ -1641,7 +1668,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
       case 58: // reg:   Alloca(reg): Implement as 3 instructions:
                 //     mul num, typeSz -> tmp
                 //     sub %sp, tmp    -> %sp
-        {      //      add %sp, 0      -> result
+        {      //      add %sp, frameSizeBelowDynamicArea -> result
         Instruction* instr = subtreeRoot->getInstruction();
         const PointerType* instrType = (const PointerType*) instr->getType();
         assert(instrType->isPointerType() &&
@@ -1649,18 +1676,26 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         const Type* eltType =
           ((ArrayType*) instrType->getValueType())->getElementType();
         int tsize = (int) target.findOptimalStorageSize(eltType);
-
+        
         assert(tsize != 0 && "Just to check when this can happen");
-        // if (tsize == 0)
-          // {
-            // numInstr = 0;
-            // break;
-          // }
-        //else go on to create the instructions needed...
-
+        
         // Create a temporary Value to hold the constant type-size
-        ConstPoolSInt* valueForTSize = ConstPoolSInt::get(Type::IntTy, tsize);
-
+        ConstPoolSInt* tsizeVal = ConstPoolSInt::get(Type::IntTy, tsize);
+        
+        // Create a temporary Value to hold the constant offset from SP
+        Method* method = instr->getParent()->getParent();
+        MachineCodeForMethod& mcode = method->getMachineCode();
+        int frameSizeBelowDynamicArea =
+          target.getFrameInfo().getFrameSizeBelowDynamicArea(method);
+        ConstPoolSInt* lowerAreaSizeVal = ConstPoolSInt::get(Type::IntTy,
+                                                  frameSizeBelowDynamicArea);
+        cerr << "***" << endl
+             << "*** Variable-size ALLOCA operation needs more work:" << endl
+             << "*** We have to precompute the size of "
+             << " optional arguments in the stack frame" << endl
+             << "***" << endl; 
+        assert(0 && "SEE MESSAGE ABOVE");
+        
         // Create a temporary value to hold `tmp'
         Instruction* tmpInstr = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
                                           subtreeRoot->leftChild()->getValue(),
@@ -1670,34 +1705,32 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         // Instruction 1: mul numElements, typeSize -> tmp
         mvec[0] = new MachineInstr(MULX);
         mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
-                                    subtreeRoot->leftChild()->getValue());
+                                      subtreeRoot->leftChild()->getValue());
         mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
-                                      valueForTSize);
+                                      tsizeVal);
         mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
                                       tmpInstr);
-
-        // tmpInstr->addMachineInstruction(mvec[0]);
-
+        
         // Instruction 2: sub %sp, tmp -> %sp
         numInstr++;
         mvec[1] = new MachineInstr(SUB);
-        mvec[1]->SetMachineOperand(0, /*regNum %sp=o6=r[14]*/(unsigned int)14);
+        mvec[1]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
         mvec[1]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
                                       tmpInstr);
-        mvec[1]->SetMachineOperand(2, /*regNum %sp=o6=r[14]*/(unsigned int)14);
+        mvec[1]->SetMachineOperand(2, target.getRegInfo().getStackPointer());
         
-        // Instruction 3: add %sp, 0 -> result
+        // Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
         numInstr++;
         mvec[2] = new MachineInstr(ADD);
-        mvec[2]->SetMachineOperand(0, /*regNum %sp=o6=r[14]*/(unsigned int)14);
-        mvec[2]->SetMachineOperand(1, target.getRegInfo().getZeroRegNum());
-        mvec[2]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
-                                      instr);
+        mvec[2]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
+        mvec[2]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
+                                      lowerAreaSizeVal);
+        mvec[2]->SetMachineOperand(2,MachineOperand::MO_VirtualRegister,instr);
         break;
         }
 
       case 61: // reg:   Call
-                // Generate a call-indirect (i.e., JMPL) for now to expose
+                // Generate a call-indirect (i.e., jmpl) for now to expose
                 // the potential need for registers.  If an absolute address
                 // is available, replace this with a CALL instruction.
                 // Mark both the indirection register and the return-address
@@ -1733,7 +1766,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
           } 
         else
           { // indirect function call
-            mvec[0] = new MachineInstr(JMPL);
+            mvec[0] = new MachineInstr(JMPLCALL);
             mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
                                           callee);
             mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,