mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[Hexagon] Adding functionality for searching for compound instruction pairs. Compound instructions reduce slot resource requirements freeing those packet slots up for more instructions.
llvm-svn: 239307
This commit is contained in:
parent
4434fd1d6b
commit
e930f8c3f6
@ -200,11 +200,17 @@ void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
HexagonLowerToMC(MI, MCB, *this);
|
||||
HexagonMCInstrInfo::padEndloop(MCB);
|
||||
}
|
||||
// Examine the packet and try to find instructions that can be converted
|
||||
// to compounds.
|
||||
HexagonMCInstrInfo::tryCompound(*Subtarget->getInstrInfo(),
|
||||
OutStreamer->getContext(), MCB);
|
||||
// Examine the packet and convert pairs of instructions to duplex
|
||||
// instructions when possible.
|
||||
SmallVector<DuplexCandidate, 8> possibleDuplexes;
|
||||
possibleDuplexes = HexagonMCInstrInfo::getDuplexPossibilties(*Subtarget->getInstrInfo(), MCB);
|
||||
HexagonMCShuffle(*Subtarget->getInstrInfo(), *Subtarget, OutStreamer->getContext(), MCB, possibleDuplexes);
|
||||
possibleDuplexes = HexagonMCInstrInfo::getDuplexPossibilties(
|
||||
*Subtarget->getInstrInfo(), MCB);
|
||||
HexagonMCShuffle(*Subtarget->getInstrInfo(), *Subtarget,
|
||||
OutStreamer->getContext(), MCB, possibleDuplexes);
|
||||
EmitToStreamer(*OutStreamer, MCB);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ add_llvm_library(LLVMHexagonDesc
|
||||
HexagonInstPrinter.cpp
|
||||
HexagonMCAsmInfo.cpp
|
||||
HexagonMCCodeEmitter.cpp
|
||||
HexagonMCCompound.cpp
|
||||
HexagonMCDuplexInfo.cpp
|
||||
HexagonMCInstrInfo.cpp
|
||||
HexagonMCShuffler.cpp
|
||||
|
@ -202,6 +202,14 @@ namespace HexagonII {
|
||||
HSIG_Compound
|
||||
};
|
||||
|
||||
// Hexagon Compound classes.
|
||||
enum CompoundGroup {
|
||||
HCG_None = 0,
|
||||
HCG_A,
|
||||
HCG_B,
|
||||
HCG_C
|
||||
};
|
||||
|
||||
enum InstParseBits {
|
||||
INST_PARSE_MASK = 0x0000c000,
|
||||
INST_PARSE_PACKET_END = 0x0000c000,
|
||||
|
420
lib/Target/Hexagon/MCTargetDesc/HexagonMCCompound.cpp
Normal file
420
lib/Target/Hexagon/MCTargetDesc/HexagonMCCompound.cpp
Normal file
@ -0,0 +1,420 @@
|
||||
|
||||
//=== HexagonMCCompound.cpp - Hexagon Compound checker -------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is looks at a packet and tries to form compound insns
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "Hexagon.h"
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCShuffler.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/MC/MCAssembler.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace Hexagon;
|
||||
|
||||
#define DEBUG_TYPE "hexagon-mccompound"
|
||||
|
||||
enum OpcodeIndex {
|
||||
fp0_jump_nt = 0,
|
||||
fp0_jump_t,
|
||||
fp1_jump_nt,
|
||||
fp1_jump_t,
|
||||
tp0_jump_nt,
|
||||
tp0_jump_t,
|
||||
tp1_jump_nt,
|
||||
tp1_jump_t
|
||||
};
|
||||
|
||||
unsigned tstBitOpcode[8] = {J4_tstbit0_fp0_jump_nt, J4_tstbit0_fp0_jump_t,
|
||||
J4_tstbit0_fp1_jump_nt, J4_tstbit0_fp1_jump_t,
|
||||
J4_tstbit0_tp0_jump_nt, J4_tstbit0_tp0_jump_t,
|
||||
J4_tstbit0_tp1_jump_nt, J4_tstbit0_tp1_jump_t};
|
||||
unsigned cmpeqBitOpcode[8] = {J4_cmpeq_fp0_jump_nt, J4_cmpeq_fp0_jump_t,
|
||||
J4_cmpeq_fp1_jump_nt, J4_cmpeq_fp1_jump_t,
|
||||
J4_cmpeq_tp0_jump_nt, J4_cmpeq_tp0_jump_t,
|
||||
J4_cmpeq_tp1_jump_nt, J4_cmpeq_tp1_jump_t};
|
||||
unsigned cmpgtBitOpcode[8] = {J4_cmpgt_fp0_jump_nt, J4_cmpgt_fp0_jump_t,
|
||||
J4_cmpgt_fp1_jump_nt, J4_cmpgt_fp1_jump_t,
|
||||
J4_cmpgt_tp0_jump_nt, J4_cmpgt_tp0_jump_t,
|
||||
J4_cmpgt_tp1_jump_nt, J4_cmpgt_tp1_jump_t};
|
||||
unsigned cmpgtuBitOpcode[8] = {J4_cmpgtu_fp0_jump_nt, J4_cmpgtu_fp0_jump_t,
|
||||
J4_cmpgtu_fp1_jump_nt, J4_cmpgtu_fp1_jump_t,
|
||||
J4_cmpgtu_tp0_jump_nt, J4_cmpgtu_tp0_jump_t,
|
||||
J4_cmpgtu_tp1_jump_nt, J4_cmpgtu_tp1_jump_t};
|
||||
unsigned cmpeqiBitOpcode[8] = {J4_cmpeqi_fp0_jump_nt, J4_cmpeqi_fp0_jump_t,
|
||||
J4_cmpeqi_fp1_jump_nt, J4_cmpeqi_fp1_jump_t,
|
||||
J4_cmpeqi_tp0_jump_nt, J4_cmpeqi_tp0_jump_t,
|
||||
J4_cmpeqi_tp1_jump_nt, J4_cmpeqi_tp1_jump_t};
|
||||
unsigned cmpgtiBitOpcode[8] = {J4_cmpgti_fp0_jump_nt, J4_cmpgti_fp0_jump_t,
|
||||
J4_cmpgti_fp1_jump_nt, J4_cmpgti_fp1_jump_t,
|
||||
J4_cmpgti_tp0_jump_nt, J4_cmpgti_tp0_jump_t,
|
||||
J4_cmpgti_tp1_jump_nt, J4_cmpgti_tp1_jump_t};
|
||||
unsigned cmpgtuiBitOpcode[8] = {J4_cmpgtui_fp0_jump_nt, J4_cmpgtui_fp0_jump_t,
|
||||
J4_cmpgtui_fp1_jump_nt, J4_cmpgtui_fp1_jump_t,
|
||||
J4_cmpgtui_tp0_jump_nt, J4_cmpgtui_tp0_jump_t,
|
||||
J4_cmpgtui_tp1_jump_nt, J4_cmpgtui_tp1_jump_t};
|
||||
unsigned cmpeqn1BitOpcode[8] = {J4_cmpeqn1_fp0_jump_nt, J4_cmpeqn1_fp0_jump_t,
|
||||
J4_cmpeqn1_fp1_jump_nt, J4_cmpeqn1_fp1_jump_t,
|
||||
J4_cmpeqn1_tp0_jump_nt, J4_cmpeqn1_tp0_jump_t,
|
||||
J4_cmpeqn1_tp1_jump_nt, J4_cmpeqn1_tp1_jump_t};
|
||||
unsigned cmpgtn1BitOpcode[8] = {
|
||||
J4_cmpgtn1_fp0_jump_nt, J4_cmpgtn1_fp0_jump_t, J4_cmpgtn1_fp1_jump_nt,
|
||||
J4_cmpgtn1_fp1_jump_t, J4_cmpgtn1_tp0_jump_nt, J4_cmpgtn1_tp0_jump_t,
|
||||
J4_cmpgtn1_tp1_jump_nt, J4_cmpgtn1_tp1_jump_t,
|
||||
};
|
||||
|
||||
// enum HexagonII::CompoundGroup
|
||||
namespace {
|
||||
unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
|
||||
unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
default:
|
||||
return HexagonII::HCG_None;
|
||||
//
|
||||
// Compound pairs.
|
||||
// "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
|
||||
// "Rd16=#U6 ; jump #r9:2"
|
||||
// "Rd16=Rs16 ; jump #r9:2"
|
||||
//
|
||||
case Hexagon::C2_cmpeq:
|
||||
case Hexagon::C2_cmpgt:
|
||||
case Hexagon::C2_cmpgtu:
|
||||
if (IsExtended)
|
||||
return false;
|
||||
DstReg = MI.getOperand(0).getReg();
|
||||
Src1Reg = MI.getOperand(1).getReg();
|
||||
Src2Reg = MI.getOperand(2).getReg();
|
||||
if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg))
|
||||
return HexagonII::HCG_A;
|
||||
break;
|
||||
case Hexagon::C2_cmpeqi:
|
||||
case Hexagon::C2_cmpgti:
|
||||
case Hexagon::C2_cmpgtui:
|
||||
if (IsExtended)
|
||||
return false;
|
||||
// P0 = cmp.eq(Rs,#u2)
|
||||
DstReg = MI.getOperand(0).getReg();
|
||||
SrcReg = MI.getOperand(1).getReg();
|
||||
if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
|
||||
MI.getOperand(2).isImm() && ((isUInt<5>(MI.getOperand(2).getImm())) ||
|
||||
(MI.getOperand(2).getImm() == -1)))
|
||||
return HexagonII::HCG_A;
|
||||
break;
|
||||
case Hexagon::A2_tfr:
|
||||
if (IsExtended)
|
||||
return false;
|
||||
// Rd = Rs
|
||||
DstReg = MI.getOperand(0).getReg();
|
||||
SrcReg = MI.getOperand(1).getReg();
|
||||
if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(SrcReg))
|
||||
return HexagonII::HCG_A;
|
||||
break;
|
||||
case Hexagon::A2_tfrsi:
|
||||
if (IsExtended)
|
||||
return false;
|
||||
// Rd = #u6
|
||||
DstReg = MI.getOperand(0).getReg();
|
||||
if (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() <= 63 &&
|
||||
MI.getOperand(1).getImm() >= 0 &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(DstReg))
|
||||
return HexagonII::HCG_A;
|
||||
break;
|
||||
case Hexagon::S2_tstbit_i:
|
||||
if (IsExtended)
|
||||
return false;
|
||||
DstReg = MI.getOperand(0).getReg();
|
||||
Src1Reg = MI.getOperand(1).getReg();
|
||||
if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
|
||||
MI.getOperand(2).isImm() &&
|
||||
HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
|
||||
(MI.getOperand(2).getImm() == 0))
|
||||
return HexagonII::HCG_A;
|
||||
break;
|
||||
// The fact that .new form is used pretty much guarantees
|
||||
// that predicate register will match. Nevertheless,
|
||||
// there could be some false positives without additional
|
||||
// checking.
|
||||
case Hexagon::J2_jumptnew:
|
||||
case Hexagon::J2_jumpfnew:
|
||||
case Hexagon::J2_jumptnewpt:
|
||||
case Hexagon::J2_jumpfnewpt:
|
||||
Src1Reg = MI.getOperand(0).getReg();
|
||||
if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg)
|
||||
return HexagonII::HCG_B;
|
||||
break;
|
||||
// Transfer and jump:
|
||||
// Rd=#U6 ; jump #r9:2
|
||||
// Rd=Rs ; jump #r9:2
|
||||
// Do not test for jump range here.
|
||||
case Hexagon::J2_jump:
|
||||
case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
|
||||
return HexagonII::HCG_C;
|
||||
break;
|
||||
}
|
||||
|
||||
return HexagonII::HCG_None;
|
||||
}
|
||||
}
|
||||
|
||||
/// getCompoundOp - Return the index from 0-7 into the above opcode lists.
|
||||
namespace {
|
||||
unsigned getCompoundOp(MCInst const &HMCI) {
|
||||
const MCOperand &Predicate = HMCI.getOperand(0);
|
||||
unsigned PredReg = Predicate.getReg();
|
||||
|
||||
assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) ||
|
||||
(PredReg == Hexagon::P2) || (PredReg == Hexagon::P3));
|
||||
|
||||
switch (HMCI.getOpcode()) {
|
||||
default:
|
||||
llvm_unreachable("Expected match not found.\n");
|
||||
break;
|
||||
case Hexagon::J2_jumpfnew:
|
||||
return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt;
|
||||
case Hexagon::J2_jumpfnewpt:
|
||||
return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t;
|
||||
case Hexagon::J2_jumptnew:
|
||||
return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt;
|
||||
case Hexagon::J2_jumptnewpt:
|
||||
return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
MCInst *getCompoundInsn(MCContext &Context, MCInst const &L, MCInst const &R) {
|
||||
MCInst *CompoundInsn = 0;
|
||||
unsigned compoundOpcode;
|
||||
MCOperand Rs, Rt;
|
||||
|
||||
switch (L.getOpcode()) {
|
||||
default:
|
||||
DEBUG(dbgs() << "Possible compound ignored\n");
|
||||
return CompoundInsn;
|
||||
|
||||
case Hexagon::A2_tfrsi:
|
||||
Rt = L.getOperand(0);
|
||||
compoundOpcode = J4_jumpseti;
|
||||
CompoundInsn = new (Context) MCInst;
|
||||
CompoundInsn->setOpcode(compoundOpcode);
|
||||
|
||||
CompoundInsn->addOperand(Rt);
|
||||
CompoundInsn->addOperand(L.getOperand(1)); // Immediate
|
||||
CompoundInsn->addOperand(R.getOperand(0)); // Jump target
|
||||
break;
|
||||
|
||||
case Hexagon::A2_tfr:
|
||||
Rt = L.getOperand(0);
|
||||
Rs = L.getOperand(1);
|
||||
|
||||
compoundOpcode = J4_jumpsetr;
|
||||
CompoundInsn = new (Context) MCInst;
|
||||
CompoundInsn->setOpcode(compoundOpcode);
|
||||
CompoundInsn->addOperand(Rt);
|
||||
CompoundInsn->addOperand(Rs);
|
||||
CompoundInsn->addOperand(R.getOperand(0)); // Jump target.
|
||||
|
||||
break;
|
||||
|
||||
case Hexagon::C2_cmpeq:
|
||||
DEBUG(dbgs() << "CX: C2_cmpeq\n");
|
||||
Rs = L.getOperand(1);
|
||||
Rt = L.getOperand(2);
|
||||
|
||||
compoundOpcode = cmpeqBitOpcode[getCompoundOp(R)];
|
||||
CompoundInsn = new (Context) MCInst;
|
||||
CompoundInsn->setOpcode(compoundOpcode);
|
||||
CompoundInsn->addOperand(Rs);
|
||||
CompoundInsn->addOperand(Rt);
|
||||
CompoundInsn->addOperand(R.getOperand(1));
|
||||
break;
|
||||
|
||||
case Hexagon::C2_cmpgt:
|
||||
DEBUG(dbgs() << "CX: C2_cmpgt\n");
|
||||
Rs = L.getOperand(1);
|
||||
Rt = L.getOperand(2);
|
||||
|
||||
compoundOpcode = cmpgtBitOpcode[getCompoundOp(R)];
|
||||
CompoundInsn = new (Context) MCInst;
|
||||
CompoundInsn->setOpcode(compoundOpcode);
|
||||
CompoundInsn->addOperand(Rs);
|
||||
CompoundInsn->addOperand(Rt);
|
||||
CompoundInsn->addOperand(R.getOperand(1));
|
||||
break;
|
||||
|
||||
case Hexagon::C2_cmpgtu:
|
||||
DEBUG(dbgs() << "CX: C2_cmpgtu\n");
|
||||
Rs = L.getOperand(1);
|
||||
Rt = L.getOperand(2);
|
||||
|
||||
compoundOpcode = cmpgtuBitOpcode[getCompoundOp(R)];
|
||||
CompoundInsn = new (Context) MCInst;
|
||||
CompoundInsn->setOpcode(compoundOpcode);
|
||||
CompoundInsn->addOperand(Rs);
|
||||
CompoundInsn->addOperand(Rt);
|
||||
CompoundInsn->addOperand(R.getOperand(1));
|
||||
break;
|
||||
|
||||
case Hexagon::C2_cmpeqi:
|
||||
DEBUG(dbgs() << "CX: C2_cmpeqi\n");
|
||||
if (L.getOperand(2).getImm() == -1)
|
||||
compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)];
|
||||
else
|
||||
compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)];
|
||||
|
||||
Rs = L.getOperand(1);
|
||||
CompoundInsn = new (Context) MCInst;
|
||||
CompoundInsn->setOpcode(compoundOpcode);
|
||||
CompoundInsn->addOperand(Rs);
|
||||
if (L.getOperand(2).getImm() != -1)
|
||||
CompoundInsn->addOperand(L.getOperand(2));
|
||||
CompoundInsn->addOperand(R.getOperand(1));
|
||||
break;
|
||||
|
||||
case Hexagon::C2_cmpgti:
|
||||
DEBUG(dbgs() << "CX: C2_cmpgti\n");
|
||||
if (L.getOperand(2).getImm() == -1)
|
||||
compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
|
||||
else
|
||||
compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];
|
||||
|
||||
Rs = L.getOperand(1);
|
||||
CompoundInsn = new (Context) MCInst;
|
||||
CompoundInsn->setOpcode(compoundOpcode);
|
||||
CompoundInsn->addOperand(Rs);
|
||||
if (L.getOperand(2).getImm() != -1)
|
||||
CompoundInsn->addOperand(L.getOperand(2));
|
||||
CompoundInsn->addOperand(R.getOperand(1));
|
||||
break;
|
||||
|
||||
case Hexagon::C2_cmpgtui:
|
||||
DEBUG(dbgs() << "CX: C2_cmpgtui\n");
|
||||
Rs = L.getOperand(1);
|
||||
compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(R)];
|
||||
CompoundInsn = new (Context) MCInst;
|
||||
CompoundInsn->setOpcode(compoundOpcode);
|
||||
CompoundInsn->addOperand(Rs);
|
||||
CompoundInsn->addOperand(L.getOperand(2));
|
||||
CompoundInsn->addOperand(R.getOperand(1));
|
||||
break;
|
||||
|
||||
case Hexagon::S2_tstbit_i:
|
||||
DEBUG(dbgs() << "CX: S2_tstbit_i\n");
|
||||
Rs = L.getOperand(1);
|
||||
compoundOpcode = tstBitOpcode[getCompoundOp(R)];
|
||||
CompoundInsn = new (Context) MCInst;
|
||||
CompoundInsn->setOpcode(compoundOpcode);
|
||||
CompoundInsn->addOperand(Rs);
|
||||
CompoundInsn->addOperand(R.getOperand(1));
|
||||
break;
|
||||
}
|
||||
|
||||
return CompoundInsn;
|
||||
}
|
||||
}
|
||||
|
||||
/// Non-Symmetrical. See if these two instructions are fit for compound pair.
|
||||
namespace {
|
||||
bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
|
||||
MCInst const &MIb, bool IsExtendedB) {
|
||||
unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
|
||||
unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
|
||||
// We have two candidates - check that this is the same register
|
||||
// we are talking about.
|
||||
unsigned Opca = MIa.getOpcode();
|
||||
if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C &&
|
||||
(Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
|
||||
return true;
|
||||
return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
|
||||
(MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI) {
|
||||
assert(HexagonMCInstrInfo::isBundle(MCI));
|
||||
bool JExtended = false;
|
||||
for (MCInst::iterator J =
|
||||
MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
|
||||
J != MCI.end(); ++J) {
|
||||
MCInst const *JumpInst = J->getInst();
|
||||
if (HexagonMCInstrInfo::isImmext(*JumpInst)) {
|
||||
JExtended = true;
|
||||
continue;
|
||||
}
|
||||
if (llvm::HexagonMCInstrInfo::getType(MCII, *JumpInst) ==
|
||||
HexagonII::TypeJ) {
|
||||
// Try to pair with another insn (B)undled with jump.
|
||||
bool BExtended = false;
|
||||
for (MCInst::iterator B =
|
||||
MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
|
||||
B != MCI.end(); ++B) {
|
||||
MCInst const *Inst = B->getInst();
|
||||
if (JumpInst == Inst)
|
||||
continue;
|
||||
if (HexagonMCInstrInfo::isImmext(*Inst)) {
|
||||
BExtended = true;
|
||||
continue;
|
||||
}
|
||||
DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << ","
|
||||
<< Inst->getOpcode() << "\n");
|
||||
if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) {
|
||||
MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst);
|
||||
if (CompoundInsn) {
|
||||
DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
|
||||
<< JumpInst->getOpcode() << " Compounds to "
|
||||
<< CompoundInsn->getOpcode() << "\n");
|
||||
J->setInst(CompoundInsn);
|
||||
MCI.erase(B);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
BExtended = false;
|
||||
}
|
||||
}
|
||||
JExtended = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// tryCompound - Given a bundle check for compound insns when one
|
||||
/// is found update the contents fo the bundle with the compound insn.
|
||||
/// If a compound instruction is found then the bundle will have one
|
||||
/// additional slot.
|
||||
void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII,
|
||||
MCContext &Context, MCInst &MCI) {
|
||||
assert(MCI.getOpcode() == Hexagon::BUNDLE &&
|
||||
"Non-Bundle where Bundle expected");
|
||||
|
||||
// By definition a compound must have 2 insn.
|
||||
if (MCI.size() < 2)
|
||||
return;
|
||||
|
||||
// Look for compounds until none are found, only update the bundle when
|
||||
// a compound is found.
|
||||
while (lookForCompound(MCII, Context, MCI))
|
||||
;
|
||||
|
||||
return;
|
||||
}
|
@ -223,6 +223,9 @@ void setOuterLoop(MCInst &MCI);
|
||||
|
||||
// Would duplexing this instruction create a requirement to extend
|
||||
bool subInstWouldBeExtended(MCInst const &potentialDuplex);
|
||||
|
||||
// Attempt to find and replace compound pairs
|
||||
void tryCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI);
|
||||
}
|
||||
}
|
||||
|
||||
|
17
test/CodeGen/Hexagon/compound.ll
Normal file
17
test/CodeGen/Hexagon/compound.ll
Normal file
@ -0,0 +1,17 @@
|
||||
; RUN: llc -march=hexagon -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
|
||||
|
||||
; CHECK: p0 = cmp.gt(r0,#-1); if (!p0.new) jump:nt
|
||||
|
||||
declare void @a()
|
||||
declare void @b()
|
||||
|
||||
define void @foo(i32 %a) {
|
||||
%b = icmp sgt i32 %a, -1
|
||||
br i1 %b, label %x, label %y
|
||||
x:
|
||||
call void @a()
|
||||
ret void
|
||||
y:
|
||||
call void @b()
|
||||
ret void
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user