mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
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:
parent
13f1d71c80
commit
4900116ab0
@ -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
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user