mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
Hexagon: Honor __builtin_expect by using branch probabilities.
* lib/Target/Hexagon/HexagonInstrInfo.cpp (GetDotNewPredOp): Given a jump opcode return the right pred.new jump opcode with a taken vs not-taken hint based on branch probabilities provided by the target independent module. * lib/Target/Hexagon/HexagonVLIWPacketizer.cpp: Use the above function. * lib/Target/Hexagon/HexagonNewValueJump.cpp(getNewvalueJumpOpcode): Enhance existing function use branch probabilities like HexagonInstrInfo::GetDotNewPredOp but for New Value (GPR) Jumps. llvm-svn: 180923
This commit is contained in:
parent
6f9f86852b
commit
c909ae62a5
@ -2472,6 +2472,34 @@ bool HexagonInstrInfo::isConstExtended(MachineInstr *MI) const {
|
||||
return (ImmValue < MinValue || ImmValue > MaxValue);
|
||||
}
|
||||
|
||||
// Returns the opcode to use when converting MI, which is a conditional jump,
|
||||
// into a conditional instruction which uses the .new value of the predicate.
|
||||
// We also use branch probabilities to add a hint to the jump.
|
||||
int
|
||||
HexagonInstrInfo::getDotNewPredJumpOp(MachineInstr *MI,
|
||||
const
|
||||
MachineBranchProbabilityInfo *MBPI) const {
|
||||
|
||||
// We assume that block can have at most two successors.
|
||||
bool taken = false;
|
||||
MachineBasicBlock *Src = MI->getParent();
|
||||
MachineOperand *BrTarget = &MI->getOperand(1);
|
||||
MachineBasicBlock *Dst = BrTarget->getMBB();
|
||||
|
||||
const BranchProbability Prediction = MBPI->getEdgeProbability(Src, Dst);
|
||||
if (Prediction >= BranchProbability(1,2))
|
||||
taken = true;
|
||||
|
||||
switch (MI->getOpcode()) {
|
||||
case Hexagon::JMP_t:
|
||||
return taken ? Hexagon::JMP_tnew_t : Hexagon::JMP_tnew_nt;
|
||||
case Hexagon::JMP_f:
|
||||
return taken ? Hexagon::JMP_fnew_t : Hexagon::JMP_fnew_nt;
|
||||
|
||||
default:
|
||||
llvm_unreachable("Unexpected jump instruction.");
|
||||
}
|
||||
}
|
||||
// Returns true if a particular operand is extendable for an instruction.
|
||||
bool HexagonInstrInfo::isOperandExtended(const MachineInstr *MI,
|
||||
unsigned short OperandNum) const {
|
||||
|
@ -18,8 +18,7 @@
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
|
||||
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
|
||||
|
||||
#define GET_INSTRINFO_HEADER
|
||||
#include "HexagonGenInstrInfo.inc"
|
||||
@ -192,6 +191,8 @@ public:
|
||||
|
||||
void immediateExtend(MachineInstr *MI) const;
|
||||
bool isConstExtended(MachineInstr *MI) const;
|
||||
int getDotNewPredJumpOp(MachineInstr *MI,
|
||||
const MachineBranchProbabilityInfo *MBPI) const;
|
||||
unsigned getAddrMode(const MachineInstr* MI) const;
|
||||
bool isOperandExtended(const MachineInstr *MI,
|
||||
unsigned short OperandNum) const;
|
||||
|
@ -68,6 +68,7 @@ namespace {
|
||||
HexagonNewValueJump() : MachineFunctionPass(ID) { }
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<MachineBranchProbabilityInfo>();
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
@ -78,6 +79,8 @@ namespace {
|
||||
virtual bool runOnMachineFunction(MachineFunction &Fn);
|
||||
|
||||
private:
|
||||
/// \brief A handle to the branch probability pass.
|
||||
const MachineBranchProbabilityInfo *MBPI;
|
||||
|
||||
};
|
||||
|
||||
@ -267,42 +270,58 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
|
||||
// Given a compare operator, return a matching New Value Jump
|
||||
// compare operator. Make sure that MI here is included in
|
||||
// HexagonInstrInfo.cpp::isNewValueJumpCandidate
|
||||
static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg,
|
||||
bool secondRegNewified) {
|
||||
static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
|
||||
bool secondRegNewified,
|
||||
MachineBasicBlock *jmpTarget,
|
||||
const MachineBranchProbabilityInfo
|
||||
*MBPI) {
|
||||
bool taken = false;
|
||||
MachineBasicBlock *Src = MI->getParent();
|
||||
const BranchProbability Prediction =
|
||||
MBPI->getEdgeProbability(Src, jmpTarget);
|
||||
|
||||
if (Prediction >= BranchProbability(1,2))
|
||||
taken = true;
|
||||
|
||||
switch (MI->getOpcode()) {
|
||||
case Hexagon::CMPEQrr:
|
||||
return Hexagon::JMP_EQrrPt_nv_V4;
|
||||
return taken ? Hexagon::JMP_EQrrPt_nv_V4 : Hexagon::JMP_EQrrPnt_nv_V4;
|
||||
|
||||
case Hexagon::CMPEQri: {
|
||||
if (reg >= 0)
|
||||
return Hexagon::JMP_EQriPt_nv_V4;
|
||||
return taken ? Hexagon::JMP_EQriPt_nv_V4 : Hexagon::JMP_EQriPnt_nv_V4;
|
||||
else
|
||||
return Hexagon::JMP_EQriPtneg_nv_V4;
|
||||
return taken ? Hexagon::JMP_EQriPtneg_nv_V4
|
||||
: Hexagon::JMP_EQriPntneg_nv_V4;
|
||||
}
|
||||
|
||||
case Hexagon::CMPGTrr: {
|
||||
if (secondRegNewified)
|
||||
return Hexagon::JMP_GTrrdnPt_nv_V4;
|
||||
return taken ? Hexagon::JMP_GTrrdnPt_nv_V4
|
||||
: Hexagon::JMP_GTrrdnPnt_nv_V4;
|
||||
else
|
||||
return Hexagon::JMP_GTrrPt_nv_V4;
|
||||
return taken ? Hexagon::JMP_GTrrPt_nv_V4
|
||||
: Hexagon::JMP_GTrrPnt_nv_V4;
|
||||
}
|
||||
|
||||
case Hexagon::CMPGTri: {
|
||||
if (reg >= 0)
|
||||
return Hexagon::JMP_GTriPt_nv_V4;
|
||||
return taken ? Hexagon::JMP_GTriPt_nv_V4 : Hexagon::JMP_GTriPnt_nv_V4;
|
||||
else
|
||||
return Hexagon::JMP_GTriPtneg_nv_V4;
|
||||
return taken ? Hexagon::JMP_GTriPtneg_nv_V4
|
||||
: Hexagon::JMP_GTriPntneg_nv_V4;
|
||||
}
|
||||
|
||||
case Hexagon::CMPGTUrr: {
|
||||
if (secondRegNewified)
|
||||
return Hexagon::JMP_GTUrrdnPt_nv_V4;
|
||||
return taken ? Hexagon::JMP_GTUrrdnPt_nv_V4
|
||||
: Hexagon::JMP_GTUrrdnPnt_nv_V4;
|
||||
else
|
||||
return Hexagon::JMP_GTUrrPt_nv_V4;
|
||||
return taken ? Hexagon::JMP_GTUrrPt_nv_V4 : Hexagon::JMP_GTUrrPnt_nv_V4;
|
||||
}
|
||||
|
||||
case Hexagon::CMPGTUri:
|
||||
return Hexagon::JMP_GTUriPt_nv_V4;
|
||||
return taken ? Hexagon::JMP_GTUriPt_nv_V4 : Hexagon::JMP_GTUriPnt_nv_V4;
|
||||
|
||||
default:
|
||||
llvm_unreachable("Could not find matching New Value Jump instruction.");
|
||||
@ -326,6 +345,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
|
||||
QII = static_cast<const HexagonInstrInfo *>(MF.getTarget().getInstrInfo());
|
||||
QRI =
|
||||
static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
|
||||
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
|
||||
|
||||
if (!QRI->Subtarget.hasV4TOps() ||
|
||||
DisableNewValueJumps) {
|
||||
@ -560,7 +580,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
|
||||
assert((QII->isNewValueJumpCandidate(cmpInstr)) &&
|
||||
"This compare is not a New Value Jump candidate.");
|
||||
unsigned opc = getNewValueJumpOpcode(cmpInstr, cmpOp2,
|
||||
isSecondOpNewified);
|
||||
isSecondOpNewified,
|
||||
jmpTarget, MBPI);
|
||||
if (invertPredicate)
|
||||
opc = QII->getInvertedPredicatedOpcode(opc);
|
||||
|
||||
|
@ -48,19 +48,35 @@
|
||||
#include "HexagonMachineFunctionInfo.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<bool> PacketizeVolatiles("hexagon-packetize-volatiles",
|
||||
cl::ZeroOrMore, cl::Hidden, cl::init(true),
|
||||
cl::desc("Allow non-solo packetization of volatile memory references"));
|
||||
|
||||
extern cl::opt<bool> ScheduleInlineAsm;
|
||||
extern cl::opt<bool> CountDeadOutput;
|
||||
|
||||
namespace llvm {
|
||||
void initializeHexagonPacketizerPass(PassRegistry&);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
class HexagonPacketizer : public MachineFunctionPass {
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
HexagonPacketizer() : MachineFunctionPass(ID) {}
|
||||
HexagonPacketizer() : MachineFunctionPass(ID) {
|
||||
initializeHexagonPacketizerPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<MachineDominatorTree>();
|
||||
AU.addRequired<MachineBranchProbabilityInfo>();
|
||||
AU.addPreserved<MachineDominatorTree>();
|
||||
AU.addRequired<MachineLoopInfo>();
|
||||
AU.addPreserved<MachineLoopInfo>();
|
||||
@ -96,10 +112,17 @@ namespace {
|
||||
// schedule this instruction.
|
||||
bool FoundSequentialDependence;
|
||||
|
||||
/// \brief A handle to the branch probability pass.
|
||||
const MachineBranchProbabilityInfo *MBPI;
|
||||
|
||||
// Track MIs with ignored dependece.
|
||||
std::vector<MachineInstr*> IgnoreDepMIs;
|
||||
|
||||
public:
|
||||
// Ctor.
|
||||
HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI,
|
||||
MachineDominatorTree &MDT);
|
||||
MachineDominatorTree &MDT,
|
||||
const MachineBranchProbabilityInfo *MBPI);
|
||||
|
||||
// initPacketizerState - initialize some internal flags.
|
||||
void initPacketizerState();
|
||||
@ -123,20 +146,20 @@ namespace {
|
||||
private:
|
||||
bool IsCallDependent(MachineInstr* MI, SDep::Kind DepType, unsigned DepReg);
|
||||
bool PromoteToDotNew(MachineInstr* MI, SDep::Kind DepType,
|
||||
MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC);
|
||||
MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC);
|
||||
bool CanPromoteToDotNew(MachineInstr* MI, SUnit* PacketSU,
|
||||
unsigned DepReg,
|
||||
std::map <MachineInstr*, SUnit*> MIToSUnit,
|
||||
MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC);
|
||||
unsigned DepReg,
|
||||
std::map <MachineInstr*, SUnit*> MIToSUnit,
|
||||
MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC);
|
||||
bool CanPromoteToNewValue(MachineInstr* MI, SUnit* PacketSU,
|
||||
unsigned DepReg,
|
||||
std::map <MachineInstr*, SUnit*> MIToSUnit,
|
||||
MachineBasicBlock::iterator &MII);
|
||||
unsigned DepReg,
|
||||
std::map <MachineInstr*, SUnit*> MIToSUnit,
|
||||
MachineBasicBlock::iterator &MII);
|
||||
bool CanPromoteToNewValueStore(MachineInstr* MI, MachineInstr* PacketMI,
|
||||
unsigned DepReg,
|
||||
std::map <MachineInstr*, SUnit*> MIToSUnit);
|
||||
unsigned DepReg,
|
||||
std::map <MachineInstr*, SUnit*> MIToSUnit);
|
||||
bool DemoteToDotOld(MachineInstr* MI);
|
||||
bool ArePredicatesComplements(MachineInstr* MI1, MachineInstr* MI2,
|
||||
std::map <MachineInstr*, SUnit*> MIToSUnit);
|
||||
@ -152,19 +175,31 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(HexagonPacketizer, "packets", "Hexagon Packetizer",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
|
||||
INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
|
||||
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
|
||||
INITIALIZE_PASS_END(HexagonPacketizer, "packets", "Hexagon Packetizer",
|
||||
false, false)
|
||||
|
||||
|
||||
// HexagonPacketizerList Ctor.
|
||||
HexagonPacketizerList::HexagonPacketizerList(
|
||||
MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT)
|
||||
MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT,
|
||||
const MachineBranchProbabilityInfo *MBPI)
|
||||
: VLIWPacketizerList(MF, MLI, MDT, true){
|
||||
this->MBPI = MBPI;
|
||||
}
|
||||
|
||||
bool HexagonPacketizer::runOnMachineFunction(MachineFunction &Fn) {
|
||||
const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo();
|
||||
MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
|
||||
MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>();
|
||||
|
||||
const MachineBranchProbabilityInfo *MBPI =
|
||||
&getAnalysis<MachineBranchProbabilityInfo>();
|
||||
// Instantiate the packetizer.
|
||||
HexagonPacketizerList Packetizer(Fn, MLI, MDT);
|
||||
HexagonPacketizerList Packetizer(Fn, MLI, MDT, MBPI);
|
||||
|
||||
// DFA state table should not be empty.
|
||||
assert(Packetizer.getResourceTracker() && "Empty DFA table!");
|
||||
@ -710,8 +745,10 @@ static int GetDotNewOp(const int opc) {
|
||||
}
|
||||
|
||||
// Return .new predicate version for an instruction
|
||||
static int GetDotNewPredOp(const int opc) {
|
||||
switch (opc) {
|
||||
static int GetDotNewPredOp(MachineInstr *MI,
|
||||
const MachineBranchProbabilityInfo *MBPI,
|
||||
const HexagonInstrInfo *QII) {
|
||||
switch (MI->getOpcode()) {
|
||||
default: llvm_unreachable("Unknown .new type");
|
||||
// Conditional stores
|
||||
// Store byte conditionally
|
||||
@ -858,10 +895,8 @@ static int GetDotNewPredOp(const int opc) {
|
||||
|
||||
// Condtional Jumps
|
||||
case Hexagon::JMP_t:
|
||||
return Hexagon::JMP_f;
|
||||
|
||||
case Hexagon::JMP_f:
|
||||
return Hexagon::JMP_fnew_t;
|
||||
return QII->getDotNewPredJumpOp(MI, MBPI);
|
||||
|
||||
case Hexagon::JMPR_t:
|
||||
return Hexagon::JMPR_tnew_tV3;
|
||||
@ -1261,7 +1296,7 @@ bool HexagonPacketizerList::PromoteToDotNew(MachineInstr* MI,
|
||||
|
||||
int NewOpcode;
|
||||
if (RC == &Hexagon::PredRegsRegClass)
|
||||
NewOpcode = GetDotNewPredOp(MI->getOpcode());
|
||||
NewOpcode = GetDotNewPredOp(MI, MBPI, QII);
|
||||
else
|
||||
NewOpcode = GetDotNewOp(MI->getOpcode());
|
||||
MI->setDesc(QII->get(NewOpcode));
|
||||
|
Loading…
Reference in New Issue
Block a user