Print "circular" warning message only in debug mode.
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9InstrSelection.cpp
index d9529d21a7c610101e945b70d54091076441adef..5195f4ac29faef839c3603f35fff817e89f62238 100644 (file)
@@ -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);
@@ -841,7 +834,8 @@ CreateCodeForVariableSizeAlloca(const TargetMachine& target,
                                 vector<MachineInstr*>& getMvec)
 {
   MachineInstr* M;
-  
+  MachineCodeForInstruction& mcfi = MachineCodeForInstruction::get(result);
+
   // Create a Value to hold the (constant) element size
   Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize);
 
@@ -858,14 +852,11 @@ CreateCodeForVariableSizeAlloca(const TargetMachine& target,
 
   // Create a temporary value to hold the result of MUL
   TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal);
-  MachineCodeForInstruction::get(result).addTemp(tmpProd);
+  mcfi.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);
+  CreateMulInstruction(target, F, numElementsVal, tsizeVal, tmpProd, getMvec,
+                       mcfi, INVALID_MACHINE_OPCODE);
         
   // Instruction 2: sub %sp, tmpProd -> %sp
   M = new MachineInstr(SUB);
@@ -890,6 +881,7 @@ 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();
@@ -946,7 +938,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 +1001,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
@@ -1925,18 +1915,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 +1936,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,13 +1953,13 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
                                           numElementsVal, mvec);
         break;
       }
-      
+
       case 61: // reg:   Call
-      {         // Generate a direct (CALL) or indirect (JMPL). depending
-                // Mark the return-address register and the indirection
-                // register (if any) as hidden virtual registers.
-                // Also, mark the operands of the Call and return value (if
-                // any) as implicit operands of the CALL machine instruction.
+      {         // Generate a direct (CALL) or indirect (JMPL) call.
+                // Mark the return-address register, the indirection
+                // register (for indirect calls), the operands of the Call,
+                // and the return value (if any) as implicit operands
+                // of the machine instruction.
                 // 
                 // If this is a varargs function, floating point arguments
                 // have to passed in integer registers so insert
@@ -1977,34 +1967,22 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
                 // 
         CallInst *callInstr = cast<CallInst>(subtreeRoot->getInstruction());
         Value *callee = callInstr->getCalledValue();
-        
-        // Create hidden virtual register for return address, with type void*. 
+
+        // Create hidden virtual register for return address with type void*
         TmpInstruction* retAddrReg =
           new TmpInstruction(PointerType::get(Type::VoidTy), callInstr);
         MachineCodeForInstruction::get(callInstr).addTemp(retAddrReg);
-        
+
         // Generate the machine instruction and its operands.
         // Use CALL for direct function calls; this optimistically assumes
         // the PC-relative address fits in the CALL address field (22 bits).
         // Use JMPL for indirect calls.
         // 
-        if (isa<Function>(callee))
-          { // direct function call
-            M = new MachineInstr(CALL);
-            M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp,
-                                    callee);
-          } 
-        else
-          { // indirect function call
-            M = new MachineInstr(JMPLCALL);
-            M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
-                                    callee);
-            M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
-                                      (int64_t) 0);
-            M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
-                                    retAddrReg);
-          }
-        
+        if (isa<Function>(callee))      // direct function call
+          M = Create1OperandInstr_Addr(CALL, callee);
+        else                            // indirect function call
+          M = Create3OperandInstr_SImmed(JMPLCALL, callee,
+                                         (int64_t) 0, retAddrReg);
         mvec.push_back(M);
 
         const FunctionType* funcType =
@@ -2039,7 +2017,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);