diff options
| author | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-09-16 15:56:01 +0000 |
|---|---|---|
| committer | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-09-16 15:56:01 +0000 |
| commit | fff5ffde275d675cd505a81dfad75490c723ff67 (patch) | |
| tree | 7d8210e5e1556efd7c6767936305429a119e6fa7 /llvm/lib/Target | |
| parent | 8cbdbd8e2ed3bc9f0ac1ed1096553364698ce1f6 (diff) | |
| download | bcm5719-llvm-fff5ffde275d675cd505a81dfad75490c723ff67.tar.gz bcm5719-llvm-fff5ffde275d675cd505a81dfad75490c723ff67.zip | |
Add methods to query about the representation of LLVM quantities (e.g.,
constants). Useful for target-dependent LLVM transformations like
Preselection.
llvm-svn: 3743
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcInstrInfo.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.cpp b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp index ffec82445dc..6a1373174e0 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.cpp +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp @@ -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(*) @@ -258,6 +259,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 // // Purpose: @@ -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; } // |

