Add methods to query about the representation of LLVM quantities (e.g.,
authorVikram S. Adve <vadve@cs.uiuc.edu>
Mon, 16 Sep 2002 15:56:01 +0000 (15:56 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Mon, 16 Sep 2002 15:56:01 +0000 (15:56 +0000)
constants).  Useful for target-dependent LLVM transformations like
Preselection.

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

include/llvm/Target/MachineInstrInfo.h
include/llvm/Target/TargetInstrInfo.h
lib/Target/SparcV9/SparcV9InstrInfo.cpp

index 855840caf7f84ecf48dd84b92ad4b25c8adbc0d8..24d13634531f3f6cb44976147f2bd0dff83cc594 100644 (file)
@@ -9,6 +9,8 @@
 
 #include "Support/NonCopyable.h"
 #include "Support/DataTypes.h"
+#include "llvm/Constant.h"
+#include "llvm/DerivedTypes.h"
 #include <string>
 #include <vector>
 
@@ -239,6 +241,27 @@ public:
     return getDescriptor(opCode).maxImmedConst;
   }
 
+  //-------------------------------------------------------------------------
+  // Queries about representation of LLVM quantities (e.g., constants)
+  //-------------------------------------------------------------------------
+
+  // Test if this type of constant must be loaded from memory into
+  // a register, i.e., cannot be set bitwise in register and cannot
+  // use immediate fields of instructions.  Note that this only makes
+  // sense for primitive types.
+  virtual bool ConstantTypeMustBeLoaded(const Constant* CV) const {
+    assert(CV->getType()->isPrimitiveType() || isa<PointerType>(CV->getType()));
+    return !(CV->getType()->isIntegral() || isa<PointerType>(CV->getType()));
+  }
+
+  // Test if this constant may not fit in the immediate field of the
+  // machine instructions (probably) generated for this instruction.
+  // 
+  virtual bool ConstantMayNotFitInImmedField(const Constant* CV,
+                                             const Instruction* I) const {
+    return true;                        // safe but very conservative
+  }
+
   //-------------------------------------------------------------------------
   // Code generation support for creating individual machine instructions
   //-------------------------------------------------------------------------
index 855840caf7f84ecf48dd84b92ad4b25c8adbc0d8..24d13634531f3f6cb44976147f2bd0dff83cc594 100644 (file)
@@ -9,6 +9,8 @@
 
 #include "Support/NonCopyable.h"
 #include "Support/DataTypes.h"
+#include "llvm/Constant.h"
+#include "llvm/DerivedTypes.h"
 #include <string>
 #include <vector>
 
@@ -239,6 +241,27 @@ public:
     return getDescriptor(opCode).maxImmedConst;
   }
 
+  //-------------------------------------------------------------------------
+  // Queries about representation of LLVM quantities (e.g., constants)
+  //-------------------------------------------------------------------------
+
+  // Test if this type of constant must be loaded from memory into
+  // a register, i.e., cannot be set bitwise in register and cannot
+  // use immediate fields of instructions.  Note that this only makes
+  // sense for primitive types.
+  virtual bool ConstantTypeMustBeLoaded(const Constant* CV) const {
+    assert(CV->getType()->isPrimitiveType() || isa<PointerType>(CV->getType()));
+    return !(CV->getType()->isIntegral() || isa<PointerType>(CV->getType()));
+  }
+
+  // Test if this constant may not fit in the immediate field of the
+  // machine instructions (probably) generated for this instruction.
+  // 
+  virtual bool ConstantMayNotFitInImmedField(const Constant* CV,
+                                             const Instruction* I) const {
+    return true;                        // safe but very conservative
+  }
+
   //-------------------------------------------------------------------------
   // Code generation support for creating individual machine instructions
   //-------------------------------------------------------------------------
index ffec82445dce15f4038f0934099be25c16b1d806..6a1373174e0698c0c54c9781e3250c658b6eef5b 100644 (file)
@@ -11,6 +11,7 @@
 #include "llvm/Function.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
+#include <stdlib.h>
 using std::vector;
 
 static const uint32_t MAXLO   = (1 << 10) - 1; // set bits set by %lo(*)
@@ -257,6 +258,61 @@ CreateIntSetInstruction(const TargetMachine& target,
 }
 
 
+//---------------------------------------------------------------------------
+// Create a table of LLVM opcode -> max. immediate constant likely to
+// be usable for that operation.
+//---------------------------------------------------------------------------
+
+// Entry == 0 ==> no immediate constant field exists at all.
+// Entry >  0 ==> abs(immediate constant) <= Entry
+// 
+vector<unsigned int> MaxConstantsTable(Instruction::NumOtherOps);
+
+static int
+MaxConstantForInstr(unsigned llvmOpCode)
+{
+  int modelOpCode = -1;
+
+  if (llvmOpCode >= Instruction::FirstBinaryOp &&
+      llvmOpCode <  Instruction::NumBinaryOps)
+    modelOpCode = ADD;
+  else
+    switch(llvmOpCode) {
+    case Instruction::Ret:   modelOpCode = JMPLCALL; break;
+
+    case Instruction::Malloc:         
+    case Instruction::Alloca:         
+    case Instruction::GetElementPtr:  
+    case Instruction::PHINode:       
+    case Instruction::Cast:
+    case Instruction::Call:  modelOpCode = ADD; break;
+
+    case Instruction::Shl:
+    case Instruction::Shr:   modelOpCode = SLLX; break;
+
+    default: break;
+    };
+
+  return (modelOpCode < 0)? 0: SparcMachineInstrDesc[modelOpCode].maxImmedConst;
+}
+
+static void
+InitializeMaxConstantsTable()
+{
+  unsigned op;
+  assert(MaxConstantsTable.size() == Instruction::NumOtherOps &&
+         "assignments below will be illegal!");
+  for (op = Instruction::FirstTermOp; op < Instruction::NumTermOps; ++op)
+    MaxConstantsTable[op] = MaxConstantForInstr(op);
+  for (op = Instruction::FirstBinaryOp; op < Instruction::NumBinaryOps; ++op)
+    MaxConstantsTable[op] = MaxConstantForInstr(op);
+  for (op = Instruction::FirstMemoryOp; op < Instruction::NumMemoryOps; ++op)
+    MaxConstantsTable[op] = MaxConstantForInstr(op);
+  for (op = Instruction::FirstOtherOp; op < Instruction::NumOtherOps; ++op)
+    MaxConstantsTable[op] = MaxConstantForInstr(op);
+}
+
+
 //---------------------------------------------------------------------------
 // class UltraSparcInstrInfo 
 // 
@@ -273,6 +329,29 @@ UltraSparcInstrInfo::UltraSparcInstrInfo(const TargetMachine& tgt)
                     /*descSize = */ NUM_TOTAL_OPCODES,
                     /*numRealOpCodes = */ NUM_REAL_OPCODES)
 {
+  InitializeMaxConstantsTable();
+}
+
+bool
+UltraSparcInstrInfo::ConstantMayNotFitInImmedField(const Constant* CV,
+                                                   const Instruction* I) const
+{
+  if (I->getOpcode() >= MaxConstantsTable.size()) // user-defined op (or bug!)
+    return true;
+
+  if (isa<ConstantPointerNull>(CV))               // can always use %g0
+    return false;
+
+  if (const ConstantUInt* U = dyn_cast<ConstantUInt>(CV))
+    return (U->getValue() > MaxConstantsTable[I->getOpcode()]);
+
+  if (const ConstantSInt* S = dyn_cast<ConstantSInt>(CV))
+    return (labs(S->getValue()) > (int) MaxConstantsTable[I->getOpcode()]);
+
+  if (isa<ConstantBool>(CV))
+    return (1U > MaxConstantsTable[I->getOpcode()]);
+
+  return true;
 }
 
 //