Printing support for more stuff
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9InstrSelection.cpp
index 2cde093bb250a2d91be2c1fa5adb3111755dad58..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"
@@ -20,6 +20,7 @@
 #include "llvm/iOther.h"
 #include "llvm/Function.h"
 #include "llvm/Constants.h"
+#include "llvm/ConstantHandling.h"
 #include "Support/MathExtras.h"
 #include <math.h>
 using std::vector;
@@ -664,18 +665,10 @@ CreateCheapestMulConstInstruction(const TargetMachine &target,
 {
   Value* constOp;
   if (isa<Constant>(lval) && isa<Constant>(rval))
-    { // both operands are constant: try both orders!
-      vector<MachineInstr*> mvec1, mvec2;
-      unsigned int lcost = CreateMulConstInstruction(target, F, lval, rval,
-                                                     destVal, mvec1, mcfi);
-      unsigned int rcost = CreateMulConstInstruction(target, F, rval, lval,
-                                                     destVal, mvec2, mcfi);
-      vector<MachineInstr*>& mincostMvec =  (lcost <= rcost)? mvec1 : mvec2;
-      vector<MachineInstr*>& maxcostMvec =  (lcost <= rcost)? mvec2 : mvec1;
-      mvec.insert(mvec.end(), mincostMvec.begin(), mincostMvec.end()); 
-
-      for (unsigned int i=0; i < maxcostMvec.size(); ++i)
-        delete maxcostMvec[i];
+    { // both operands are constant: evaluate and "set" in dest
+      Constant* P = ConstantFoldBinaryInstruction(Instruction::Mul,
+                                  cast<Constant>(lval), cast<Constant>(rval));
+      target.getInstrInfo().CreateCodeToLoadConst(target,F,P,destVal,mvec,mcfi);
     }
   else if (isa<Constant>(rval))         // rval is constant, but not lval
     CreateMulConstInstruction(target, F, lval, rval, destVal, mvec, mcfi);
@@ -840,40 +833,65 @@ CreateCodeForVariableSizeAlloca(const TargetMachine& target,
                                 Value* numElementsVal,
                                 vector<MachineInstr*>& getMvec)
 {
+  Value* totalSizeVal;
   MachineInstr* M;
-  
-  // Create a Value to hold the (constant) element size
-  Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize);
+  MachineCodeForInstruction& mcfi = MachineCodeForInstruction::get(result);
+  Function *F = result->getParent()->getParent();
+
+  // 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);
-  MachineCodeForInstruction::get(result).addTemp(tmpProd);
-  
-  // Instruction 1: mul numElements, typeSize -> tmpProd
-  M = new MachineInstr(MULX);
-  M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, numElementsVal);
-  M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tsizeVal);
-  M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, tmpProd);
-  getMvec.push_back(M);
-        
-  // 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());
@@ -890,10 +908,11 @@ CreateCodeForFixedSizeAlloca(const TargetMachine& target,
                              unsigned int numElements,
                              vector<MachineInstr*>& getMvec)
 {
+  assert(tsize > 0 && "Illegal (zero) type size for alloca");
   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
@@ -946,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();
@@ -1009,13 +1028,11 @@ SetOperandsForMemInstr(vector<MachineInstr*>& mvec,
                                        target.DataLayout.getTypeSize(eltType));
 
           // CreateMulInstruction() folds constants intelligently enough.
-          CreateMulInstruction(target,
-                               memInst->getParent()->getParent(),
+          CreateMulInstruction(target, memInst->getParent()->getParent(),
                                idxVal,         /* lval, not likely to be const*/
                                eltSizeVal,     /* rval, likely to be constant */
                                addr,           /* result */
-                               mulVec,
-                               MachineCodeForInstruction::get(memInst),
+                               mulVec, MachineCodeForInstruction::get(memInst),
                                INVALID_MACHINE_OPCODE);
 
           // Insert mulVec[] before *mvecI in mvec[] and update mvecI
@@ -1116,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);
@@ -1250,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)
@@ -1925,18 +1942,18 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         mvec.push_back(new MachineInstr(ADD));
         SetOperandsForMemInstr(mvec, subtreeRoot, target);
         break;
-        
+
       case 57: // reg:  Alloca: Implement as 1 instruction:
       {         //         add %fp, offsetFromFP -> result
         AllocationInst* instr =
           cast<AllocationInst>(subtreeRoot->getInstruction());
         unsigned int tsize =
-          target.findOptimalStorageSize(instr->getAllocatedType());
+          target.DataLayout.getTypeSize(instr->getAllocatedType());
         assert(tsize != 0);
         CreateCodeForFixedSizeAlloca(target, instr, tsize, 1, mvec);
         break;
       }
-      
+
       case 58: // reg:   Alloca(reg): Implement as 3 instructions:
                 //     mul num, typeSz -> tmp
                 //     sub %sp, tmp    -> %sp
@@ -1946,7 +1963,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         const Type* eltType = instr->getAllocatedType();
         
         // If #elements is constant, use simpler code for fixed-size allocas
-        int tsize = (int) target.findOptimalStorageSize(eltType);
+        int tsize = (int) target.DataLayout.getTypeSize(eltType);
         Value* numElementsVal = NULL;
         bool isArray = instr->isArrayAllocation();
         
@@ -1963,7 +1980,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
                                           numElementsVal, mvec);
         break;
       }
-      
+
       case 61: // reg:   Call
       {         // Generate a direct (CALL) or indirect (JMPL) call.
                 // Mark the return-address register, the indirection
@@ -2001,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!");
@@ -2027,7 +2045,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
                 
                 // If this arg. is in the first $K$ regs, add a copy
                 // float-to-int instruction to pass the value as an integer.
-                if (i < target.getRegInfo().GetNumOfIntArgRegs())
+                if (i <= target.getRegInfo().GetNumOfIntArgRegs())
                   {
                     MachineCodeForInstruction &destMCFI = 
                       MachineCodeForInstruction::get(callInstr);