Add methods to query about the representation of LLVM quantities (e.g.,

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
This commit is contained in:
Vikram S. Adve 2002-09-16 15:56:01 +00:00
parent 13f1d71c80
commit 4900116ab0
3 changed files with 125 additions and 0 deletions

View 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
//-------------------------------------------------------------------------

View 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
//-------------------------------------------------------------------------

View 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;
}
//