R600/SI: Don't shrink instructions whose e32 encoding doesn't exist

v2: modify hasVALU32BitEncoding instead
v3: - add pseudoToMCOpcode helper to AMDGPUInstInfo, which is used by both
      hasVALU32BitEncoding and AMDGPUMCInstLower::lower
    - report an error if a pseudo can't be lowered
llvm-svn: 226188
This commit is contained in:
Marek Olsak 2015-01-15 18:42:51 +00:00
parent dc4d202f10
commit a93603d508
8 changed files with 58 additions and 43 deletions

View File

@ -341,8 +341,39 @@ int AMDGPUInstrInfo::getMaskedMIMGOp(uint16_t Opcode, unsigned Channels) const {
// instead.
namespace llvm {
namespace AMDGPU {
int getMCOpcode(uint16_t Opcode, unsigned Gen) {
static int getMCOpcode(uint16_t Opcode, unsigned Gen) {
return getMCOpcodeGen(Opcode, (enum Subtarget)Gen);
}
}
}
// This must be kept in sync with the SISubtarget class in SIInstrInfo.td
enum SISubtarget {
SI = 0,
VI = 1
};
enum SISubtarget AMDGPUSubtargetToSISubtarget(unsigned Gen) {
switch (Gen) {
default:
return SI;
case AMDGPUSubtarget::VOLCANIC_ISLANDS:
return VI;
}
}
int AMDGPUInstrInfo::pseudoToMCOpcode(int Opcode) const {
int MCOp = AMDGPU::getMCOpcode(Opcode,
AMDGPUSubtargetToSISubtarget(RI.ST.getGeneration()));
// -1 means that Opcode is already a native instruction.
if (MCOp == -1)
return Opcode;
// (uint16_t)-1 means that Opcode is a pseudo instruction that has
// no encoding in the given subtarget generation.
if (MCOp == (uint16_t)-1)
return -1;
return MCOp;
}

View File

@ -135,6 +135,11 @@ public:
bool isRegisterStore(const MachineInstr &MI) const;
bool isRegisterLoad(const MachineInstr &MI) const;
/// \brief Return a target-specific opcode if Opcode is a pseudo instruction.
/// Return -1 if the target-specific opcode for the pseudo instruction does
/// not exist. If Opcode is not a pseudo instruction, this is identity.
int pseudoToMCOpcode(int Opcode) const;
//===---------------------------------------------------------------------===//
// Pure virtual funtions to be implemented by sub-classes.
//===---------------------------------------------------------------------===//

View File

@ -22,6 +22,7 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
@ -39,29 +40,17 @@ AMDGPUMCInstLower::AMDGPUMCInstLower(MCContext &ctx, const AMDGPUSubtarget &st):
Ctx(ctx), ST(st)
{ }
enum AMDGPUMCInstLower::SISubtarget
AMDGPUMCInstLower::AMDGPUSubtargetToSISubtarget(unsigned Gen) const {
switch (Gen) {
default:
return AMDGPUMCInstLower::SI;
case AMDGPUSubtarget::VOLCANIC_ISLANDS:
return AMDGPUMCInstLower::VI;
}
}
unsigned AMDGPUMCInstLower::getMCOpcode(unsigned MIOpcode) const {
int MCOpcode = AMDGPU::getMCOpcode(MIOpcode,
AMDGPUSubtargetToSISubtarget(ST.getGeneration()));
if (MCOpcode == -1)
MCOpcode = MIOpcode;
return MCOpcode;
}
void AMDGPUMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
OutMI.setOpcode(getMCOpcode(MI->getOpcode()));
int MCOpcode = ST.getInstrInfo()->pseudoToMCOpcode(MI->getOpcode());
if (MCOpcode == -1) {
LLVMContext &C = MI->getParent()->getParent()->getFunction()->getContext();
C.emitError("AMDGPUMCInstLower::lower - Pseudo instruction doesn't have "
"a target-specific version: " + Twine(MI->getOpcode()));
}
OutMI.setOpcode(MCOpcode);
for (const MachineOperand &MO : MI->explicit_operands()) {
MCOperand MCOp;

View File

@ -19,23 +19,9 @@ class MCContext;
class MCInst;
class AMDGPUMCInstLower {
// This must be kept in sync with the SISubtarget class in SIInstrInfo.td
enum SISubtarget {
SI = 0,
VI = 1
};
MCContext &Ctx;
const AMDGPUSubtarget &ST;
/// Convert a member of the AMDGPUSubtarget::Generation enum to the
/// SISubtarget enum.
enum SISubtarget AMDGPUSubtargetToSISubtarget(unsigned Gen) const;
/// Get the MC opcode for this MachineInstr.
unsigned getMCOpcode(unsigned MIOpcode) const;
public:
AMDGPUMCInstLower(MCContext &ctx, const AMDGPUSubtarget &ST);

View File

@ -1053,7 +1053,11 @@ bool SIInstrInfo::canFoldOffset(unsigned OffsetSize, unsigned AS) const {
}
bool SIInstrInfo::hasVALU32BitEncoding(unsigned Opcode) const {
return AMDGPU::getVOPe32(Opcode) != -1;
int Op32 = AMDGPU::getVOPe32(Opcode);
if (Op32 == -1)
return false;
return pseudoToMCOpcode(Op32) != -1;
}
bool SIInstrInfo::hasModifiers(unsigned Opcode) const {

View File

@ -325,7 +325,6 @@ namespace AMDGPU {
int getVOPe32(uint16_t Opcode);
int getCommuteRev(uint16_t Opcode);
int getCommuteOrig(uint16_t Opcode);
int getMCOpcode(uint16_t Opcode, unsigned Gen);
int getAddr64Inst(uint16_t Opcode);
int getAtomicRetOp(uint16_t Opcode);
int getAtomicNoRetOp(uint16_t Opcode);

View File

@ -57,7 +57,7 @@ class sopk <bits<5> si, bits<5> vi = si> {
}
// Execpt for the NONE field, this must be kept in sync with the SISubtarget enum
// in AMDGPUMCInstLower.h
// in AMDGPUInstrInfo.cpp
def SISubtarget {
int NONE = -1;
int SI = 0;

View File

@ -10,6 +10,7 @@
//
#include "AMDGPU.h"
#include "AMDGPUMCInstLower.h"
#include "AMDGPUSubtarget.h"
#include "SIInstrInfo.h"
#include "llvm/ADT/Statistic.h"
@ -206,13 +207,13 @@ bool SIShrinkInstructions::runOnMachineFunction(MachineFunction &MF) {
continue;
}
int Op32 = AMDGPU::getVOPe32(MI.getOpcode());
// Op32 could be -1 here if we started with an instruction that had a
// getVOPe32 could be -1 here if we started with an instruction that had
// a 32-bit encoding and then commuted it to an instruction that did not.
if (Op32 == -1)
if (!TII->hasVALU32BitEncoding(MI.getOpcode()))
continue;
int Op32 = AMDGPU::getVOPe32(MI.getOpcode());
if (TII->isVOPC(Op32)) {
unsigned DstReg = MI.getOperand(0).getReg();
if (TargetRegisterInfo::isVirtualRegister(DstReg)) {