Printing support for more stuff
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9InstrSelection.cpp
index 35ec8716c5f6a78a686c5850eb211b2e90476ed0..3e2731c002bd985a87aec92568e51bbffa81ab03 100644 (file)
@@ -12,7 +12,7 @@
 #include "llvm/CodeGen/MachineInstrAnnot.h"
 #include "llvm/CodeGen/InstrForest.h"
 #include "llvm/CodeGen/InstrSelection.h"
-#include "llvm/CodeGen/MachineCodeForMethod.h"
+#include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineCodeForInstruction.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/iTerminators.h"
@@ -833,38 +833,65 @@ CreateCodeForVariableSizeAlloca(const TargetMachine& target,
                                 Value* numElementsVal,
                                 vector<MachineInstr*>& getMvec)
 {
+  Value* totalSizeVal;
   MachineInstr* M;
   MachineCodeForInstruction& mcfi = MachineCodeForInstruction::get(result);
+  Function *F = result->getParent()->getParent();
 
-  // Create a Value to hold the (constant) element size
-  Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize);
+  // Enforce the alignment constraints on the stack pointer at
+  // compile time if the total size is a known constant.
+  if (isa<Constant>(numElementsVal))
+    {
+      bool isValid;
+      int64_t numElem = GetConstantValueAsSignedInt(numElementsVal, isValid);
+      assert(isValid && "Unexpectedly large array dimension in alloca!");
+      int64_t total = numElem * tsize;
+      if (int extra= total % target.getFrameInfo().getStackFrameSizeAlignment())
+        total += target.getFrameInfo().getStackFrameSizeAlignment() - extra;
+      totalSizeVal = ConstantSInt::get(Type::IntTy, total);
+    }
+  else
+    {
+      // The size is not a constant.  Generate code to compute it and
+      // code to pad the size for stack alignment.
+      // Create a Value to hold the (constant) element size
+      Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize);
+
+      // Create temporary values to hold the result of MUL, SLL, SRL
+      // THIS CASE IS INCOMPLETE AND WILL BE FIXED SHORTLY.
+      TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal);
+      TmpInstruction* tmpSLL  = new TmpInstruction(numElementsVal, tmpProd);
+      TmpInstruction* tmpSRL  = new TmpInstruction(numElementsVal, tmpSLL);
+      mcfi.addTemp(tmpProd);
+      mcfi.addTemp(tmpSLL);
+      mcfi.addTemp(tmpSRL);
+
+      // Instruction 1: mul numElements, typeSize -> tmpProd
+      // This will optimize the MUL as far as possible.
+      CreateMulInstruction(target, F, numElementsVal, tsizeVal, tmpProd,getMvec,
+                           mcfi, INVALID_MACHINE_OPCODE);
+
+      assert(0 && "Need to insert padding instructions here!");
+
+      totalSizeVal = tmpProd;
+    }
 
   // Get the constant offset from SP for dynamically allocated storage
   // and create a temporary Value to hold it.
-  assert(result && result->getParent() && "Result value is not part of a fn?");
-  Function *F = result->getParent()->getParent();
-  MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(F);
+  MachineFunction& mcInfo = MachineFunction::get(F);
   bool growUp;
   ConstantSInt* dynamicAreaOffset =
     ConstantSInt::get(Type::IntTy,
-                      target.getFrameInfo().getDynamicAreaOffset(mcInfo,growUp));
+                     target.getFrameInfo().getDynamicAreaOffset(mcInfo,growUp));
   assert(! growUp && "Has SPARC v9 stack frame convention changed?");
 
-  // Create a temporary value to hold the result of MUL
-  TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal);
-  mcfi.addTemp(tmpProd);
-  
-  // Instruction 1: mul numElements, typeSize -> tmpProd
-  CreateMulInstruction(target, F, numElementsVal, tsizeVal, tmpProd, getMvec,
-                       mcfi, INVALID_MACHINE_OPCODE);
-        
-  // Instruction 2: sub %sp, tmpProd -> %sp
+  // Instruction 2: sub %sp, totalSizeVal -> %sp
   M = new MachineInstr(SUB);
   M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
-  M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tmpProd);
+  M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, totalSizeVal);
   M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
   getMvec.push_back(M);
-  
+
   // Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
   M = new MachineInstr(ADD);
   M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
@@ -885,7 +912,7 @@ CreateCodeForFixedSizeAlloca(const TargetMachine& target,
   assert(result && result->getParent() &&
          "Result value is not part of a function?");
   Function *F = result->getParent()->getParent();
-  MachineCodeForMethod &mcInfo = MachineCodeForMethod::get(F);
+  MachineFunction &mcInfo = MachineFunction::get(F);
 
   // Check if the offset would small enough to use as an immediate in
   // load/stores (check LDX because all load/stores have the same-size immediate
@@ -938,7 +965,7 @@ CreateCodeForFixedSizeAlloca(const TargetMachine& target,
 
 static void
 SetOperandsForMemInstr(vector<MachineInstr*>& mvec,
-                       const InstructionNode* vmInstrNode,
+                       InstructionNode* vmInstrNode,
                        const TargetMachine& target)
 {
   Instruction* memInst = vmInstrNode->getInstruction();
@@ -1106,7 +1133,7 @@ ForwardOperand(InstructionNode* treeNode,
           for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; ++i)
             {
               const MachineOperand& mop = minstr->getOperand(i);
-              if (mop.getOperandType() == MachineOperand::MO_VirtualRegister &&
+              if (mop.getType() == MachineOperand::MO_VirtualRegister &&
                   mop.getVRegValue() == unusedOp)
                 minstr->SetMachineOperandVal(i,
                                 MachineOperand::MO_VirtualRegister, fwdOp);
@@ -1240,10 +1267,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         MachineCodeForInstruction::get(returnInstr).addTemp(returnReg);
         
         M = new MachineInstr(JMPLRET);
-        M->SetMachineOperandReg(0, MachineOperand::MO_VirtualRegister,
-                                      returnReg);
+        M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+                                returnReg);
         M->SetMachineOperandConst(1,MachineOperand::MO_SignExtendedImmed,
-                                   (int64_t)8);
+                                  (int64_t)8);
         M->SetMachineOperandReg(2, target.getRegInfo().getZeroRegNum());
         
         if (returnInstr->getReturnValue() != NULL)
@@ -1991,11 +2018,12 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         bool isVarArgs = funcType->isVarArg();
         bool noPrototype = isVarArgs && funcType->getNumParams() == 0;
         
-        // Use an annotation to pass information about call arguments
-        // to the register allocator.
+        // Use a descriptor to pass information about call arguments
+        // to the register allocator.  This descriptor will be "owned"
+        // and freed automatically when the MachineCodeForInstruction
+        // object for the callInstr goes away.
         CallArgsDescriptor* argDesc = new CallArgsDescriptor(callInstr,
                                          retAddrReg, isVarArgs, noPrototype);
-        M->addAnnotation(argDesc);
         
         assert(callInstr->getOperand(0) == callee
                && "This is assumed in the loop below!");