forked from OSchip/llvm-project
CodeGen: TII: Take MachineInstr& in predicate API, NFC
Change TargetInstrInfo API to take `MachineInstr&` instead of `MachineInstr*` in the functions related to predicated instructions (I'll try to come back later and get some of the rest). All of these functions require non-null parameters already, so references are more clear. As a bonus, this happens to factor away a host of implicit iterator => pointer conversions. No functionality change intended. llvm-svn: 261605
This commit is contained in:
parent
b3613fce19
commit
6307eb5518
|
@ -1010,19 +1010,18 @@ public:
|
||||||
|
|
||||||
|
|
||||||
/// Returns true if the instruction is already predicated.
|
/// Returns true if the instruction is already predicated.
|
||||||
virtual bool isPredicated(const MachineInstr *MI) const {
|
virtual bool isPredicated(const MachineInstr &MI) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the instruction is a
|
/// Returns true if the instruction is a
|
||||||
/// terminator instruction that has not been predicated.
|
/// terminator instruction that has not been predicated.
|
||||||
virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
|
virtual bool isUnpredicatedTerminator(const MachineInstr &MI) const;
|
||||||
|
|
||||||
/// Convert the instruction into a predicated instruction.
|
/// Convert the instruction into a predicated instruction.
|
||||||
/// It returns true if the operation was successful.
|
/// It returns true if the operation was successful.
|
||||||
virtual
|
virtual bool PredicateInstruction(MachineInstr &MI,
|
||||||
bool PredicateInstruction(MachineInstr *MI,
|
ArrayRef<MachineOperand> Pred) const;
|
||||||
ArrayRef<MachineOperand> Pred) const;
|
|
||||||
|
|
||||||
/// Returns true if the first specified predicate
|
/// Returns true if the first specified predicate
|
||||||
/// subsumes the second, e.g. GE subsumes GT.
|
/// subsumes the second, e.g. GE subsumes GT.
|
||||||
|
@ -1035,7 +1034,7 @@ public:
|
||||||
/// If the specified instruction defines any predicate
|
/// If the specified instruction defines any predicate
|
||||||
/// or condition code register(s) used for predication, returns true as well
|
/// or condition code register(s) used for predication, returns true as well
|
||||||
/// as the definition predicate(s) by reference.
|
/// as the definition predicate(s) by reference.
|
||||||
virtual bool DefinesPredicate(MachineInstr *MI,
|
virtual bool DefinesPredicate(MachineInstr &MI,
|
||||||
std::vector<MachineOperand> &Pred) const {
|
std::vector<MachineOperand> &Pred) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1043,8 +1042,8 @@ public:
|
||||||
/// Return true if the specified instruction can be predicated.
|
/// Return true if the specified instruction can be predicated.
|
||||||
/// By default, this returns true for every instruction with a
|
/// By default, this returns true for every instruction with a
|
||||||
/// PredicateOperand.
|
/// PredicateOperand.
|
||||||
virtual bool isPredicable(MachineInstr *MI) const {
|
virtual bool isPredicable(MachineInstr &MI) const {
|
||||||
return MI->getDesc().isPredicable();
|
return MI.getDesc().isPredicable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if it's safe to move a machine
|
/// Return true if it's safe to move a machine
|
||||||
|
@ -1178,7 +1177,7 @@ public:
|
||||||
const MachineInstr *MI,
|
const MachineInstr *MI,
|
||||||
unsigned *PredCost = nullptr) const;
|
unsigned *PredCost = nullptr) const;
|
||||||
|
|
||||||
virtual unsigned getPredicationCost(const MachineInstr *MI) const;
|
virtual unsigned getPredicationCost(const MachineInstr &MI) const;
|
||||||
|
|
||||||
virtual int getInstrLatency(const InstrItineraryData *ItinData,
|
virtual int getInstrLatency(const InstrItineraryData *ItinData,
|
||||||
SDNode *Node) const;
|
SDNode *Node) const;
|
||||||
|
|
|
@ -368,7 +368,7 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI,
|
||||||
// reference either system calls or the register directly. Skip it until we
|
// reference either system calls or the register directly. Skip it until we
|
||||||
// can tell user specified registers from compiler-specified.
|
// can tell user specified registers from compiler-specified.
|
||||||
if (MI->isCall() || MI->hasExtraDefRegAllocReq() ||
|
if (MI->isCall() || MI->hasExtraDefRegAllocReq() ||
|
||||||
TII->isPredicated(MI) || MI->isInlineAsm()) {
|
TII->isPredicated(*MI) || MI->isInlineAsm()) {
|
||||||
DEBUG(if (State->GetGroup(Reg) != 0) dbgs() << "->g0(alloc-req)");
|
DEBUG(if (State->GetGroup(Reg) != 0) dbgs() << "->g0(alloc-req)");
|
||||||
State->UnionGroups(Reg, 0);
|
State->UnionGroups(Reg, 0);
|
||||||
}
|
}
|
||||||
|
@ -444,9 +444,8 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
|
||||||
// instruction which may not be executed. The second R6 def may or may not
|
// instruction which may not be executed. The second R6 def may or may not
|
||||||
// re-define R6 so it's not safe to change it since the last R6 use cannot be
|
// re-define R6 so it's not safe to change it since the last R6 use cannot be
|
||||||
// changed.
|
// changed.
|
||||||
bool Special = MI->isCall() ||
|
bool Special = MI->isCall() || MI->hasExtraSrcRegAllocReq() ||
|
||||||
MI->hasExtraSrcRegAllocReq() ||
|
TII->isPredicated(*MI) || MI->isInlineAsm();
|
||||||
TII->isPredicated(MI) || MI->isInlineAsm();
|
|
||||||
|
|
||||||
// Scan the register uses for this instruction and update
|
// Scan the register uses for this instruction and update
|
||||||
// live-ranges, groups and RegRefs.
|
// live-ranges, groups and RegRefs.
|
||||||
|
|
|
@ -167,7 +167,7 @@ bool BranchFolder::OptimizeImpDefsBlock(MachineBasicBlock *MBB) {
|
||||||
|
|
||||||
MachineBasicBlock::iterator FirstTerm = I;
|
MachineBasicBlock::iterator FirstTerm = I;
|
||||||
while (I != MBB->end()) {
|
while (I != MBB->end()) {
|
||||||
if (!TII->isUnpredicatedTerminator(I))
|
if (!TII->isUnpredicatedTerminator(*I))
|
||||||
return false;
|
return false;
|
||||||
// See if it uses any of the implicitly defined registers.
|
// See if it uses any of the implicitly defined registers.
|
||||||
for (const MachineOperand &MO : I->operands()) {
|
for (const MachineOperand &MO : I->operands()) {
|
||||||
|
@ -1623,7 +1623,7 @@ MachineBasicBlock::iterator findHoistingInsertPosAndDeps(MachineBasicBlock *MBB,
|
||||||
SmallSet<unsigned,4> &Uses,
|
SmallSet<unsigned,4> &Uses,
|
||||||
SmallSet<unsigned,4> &Defs) {
|
SmallSet<unsigned,4> &Defs) {
|
||||||
MachineBasicBlock::iterator Loc = MBB->getFirstTerminator();
|
MachineBasicBlock::iterator Loc = MBB->getFirstTerminator();
|
||||||
if (!TII->isUnpredicatedTerminator(Loc))
|
if (!TII->isUnpredicatedTerminator(*Loc))
|
||||||
return MBB->end();
|
return MBB->end();
|
||||||
|
|
||||||
for (const MachineOperand &MO : Loc->operands()) {
|
for (const MachineOperand &MO : Loc->operands()) {
|
||||||
|
@ -1685,7 +1685,7 @@ MachineBasicBlock::iterator findHoistingInsertPosAndDeps(MachineBasicBlock *MBB,
|
||||||
// Also avoid moving code above predicated instruction since it's hard to
|
// Also avoid moving code above predicated instruction since it's hard to
|
||||||
// reason about register liveness with predicated instruction.
|
// reason about register liveness with predicated instruction.
|
||||||
bool DontMoveAcrossStore = true;
|
bool DontMoveAcrossStore = true;
|
||||||
if (!PI->isSafeToMove(nullptr, DontMoveAcrossStore) || TII->isPredicated(PI))
|
if (!PI->isSafeToMove(nullptr, DontMoveAcrossStore) || TII->isPredicated(*PI))
|
||||||
return MBB->end();
|
return MBB->end();
|
||||||
|
|
||||||
|
|
||||||
|
@ -1765,7 +1765,7 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) {
|
||||||
if (!TIB->isIdenticalTo(FIB, MachineInstr::CheckKillDead))
|
if (!TIB->isIdenticalTo(FIB, MachineInstr::CheckKillDead))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (TII->isPredicated(TIB))
|
if (TII->isPredicated(*TIB))
|
||||||
// Hard to reason about register liveness with predicated instruction.
|
// Hard to reason about register liveness with predicated instruction.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -163,9 +163,8 @@ void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) {
|
||||||
// instruction which may not be executed. The second R6 def may or may not
|
// instruction which may not be executed. The second R6 def may or may not
|
||||||
// re-define R6 so it's not safe to change it since the last R6 use cannot be
|
// re-define R6 so it's not safe to change it since the last R6 use cannot be
|
||||||
// changed.
|
// changed.
|
||||||
bool Special = MI->isCall() ||
|
bool Special =
|
||||||
MI->hasExtraSrcRegAllocReq() ||
|
MI->isCall() || MI->hasExtraSrcRegAllocReq() || TII->isPredicated(*MI);
|
||||||
TII->isPredicated(MI);
|
|
||||||
|
|
||||||
// Scan the register operands for this instruction and update
|
// Scan the register operands for this instruction and update
|
||||||
// Classes and RegRefs.
|
// Classes and RegRefs.
|
||||||
|
@ -241,7 +240,7 @@ void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI,
|
||||||
// instruction are now dead.
|
// instruction are now dead.
|
||||||
assert(!MI->isKill() && "Attempting to scan a kill instruction");
|
assert(!MI->isKill() && "Attempting to scan a kill instruction");
|
||||||
|
|
||||||
if (!TII->isPredicated(MI)) {
|
if (!TII->isPredicated(*MI)) {
|
||||||
// Predicated defs are modeled as read + write, i.e. similar to two
|
// Predicated defs are modeled as read + write, i.e. similar to two
|
||||||
// address updates.
|
// address updates.
|
||||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||||
|
@ -585,7 +584,7 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
|
||||||
// If MI's defs have a special allocation requirement, don't allow
|
// If MI's defs have a special allocation requirement, don't allow
|
||||||
// any def registers to be changed. Also assume all registers
|
// any def registers to be changed. Also assume all registers
|
||||||
// defined in a call must not be changed (ABI).
|
// defined in a call must not be changed (ABI).
|
||||||
if (MI->isCall() || MI->hasExtraDefRegAllocReq() || TII->isPredicated(MI))
|
if (MI->isCall() || MI->hasExtraDefRegAllocReq() || TII->isPredicated(*MI))
|
||||||
// If this instruction's defs have special allocation requirement, don't
|
// If this instruction's defs have special allocation requirement, don't
|
||||||
// break this anti-dependency.
|
// break this anti-dependency.
|
||||||
AntiDepReg = 0;
|
AntiDepReg = 0;
|
||||||
|
|
|
@ -668,16 +668,15 @@ void IfConverter::ScanInstructions(BBInfo &BBI) {
|
||||||
BBI.ExtraCost = 0;
|
BBI.ExtraCost = 0;
|
||||||
BBI.ExtraCost2 = 0;
|
BBI.ExtraCost2 = 0;
|
||||||
BBI.ClobbersPred = false;
|
BBI.ClobbersPred = false;
|
||||||
for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end();
|
for (auto &MI : *BBI.BB) {
|
||||||
I != E; ++I) {
|
if (MI.isDebugValue())
|
||||||
if (I->isDebugValue())
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (I->isNotDuplicable())
|
if (MI.isNotDuplicable())
|
||||||
BBI.CannotBeCopied = true;
|
BBI.CannotBeCopied = true;
|
||||||
|
|
||||||
bool isPredicated = TII->isPredicated(I);
|
bool isPredicated = TII->isPredicated(MI);
|
||||||
bool isCondBr = BBI.IsBrAnalyzable && I->isConditionalBranch();
|
bool isCondBr = BBI.IsBrAnalyzable && MI.isConditionalBranch();
|
||||||
|
|
||||||
// A conditional branch is not predicable, but it may be eliminated.
|
// A conditional branch is not predicable, but it may be eliminated.
|
||||||
if (isCondBr)
|
if (isCondBr)
|
||||||
|
@ -685,8 +684,8 @@ void IfConverter::ScanInstructions(BBInfo &BBI) {
|
||||||
|
|
||||||
if (!isPredicated) {
|
if (!isPredicated) {
|
||||||
BBI.NonPredSize++;
|
BBI.NonPredSize++;
|
||||||
unsigned ExtraPredCost = TII->getPredicationCost(&*I);
|
unsigned ExtraPredCost = TII->getPredicationCost(MI);
|
||||||
unsigned NumCycles = SchedModel.computeInstrLatency(&*I, false);
|
unsigned NumCycles = SchedModel.computeInstrLatency(&MI, false);
|
||||||
if (NumCycles > 1)
|
if (NumCycles > 1)
|
||||||
BBI.ExtraCost += NumCycles-1;
|
BBI.ExtraCost += NumCycles-1;
|
||||||
BBI.ExtraCost2 += ExtraPredCost;
|
BBI.ExtraCost2 += ExtraPredCost;
|
||||||
|
@ -710,10 +709,10 @@ void IfConverter::ScanInstructions(BBInfo &BBI) {
|
||||||
// FIXME: Make use of PredDefs? e.g. ADDC, SUBC sets predicates but are
|
// FIXME: Make use of PredDefs? e.g. ADDC, SUBC sets predicates but are
|
||||||
// still potentially predicable.
|
// still potentially predicable.
|
||||||
std::vector<MachineOperand> PredDefs;
|
std::vector<MachineOperand> PredDefs;
|
||||||
if (TII->DefinesPredicate(I, PredDefs))
|
if (TII->DefinesPredicate(MI, PredDefs))
|
||||||
BBI.ClobbersPred = true;
|
BBI.ClobbersPred = true;
|
||||||
|
|
||||||
if (!TII->isPredicable(I)) {
|
if (!TII->isPredicable(MI)) {
|
||||||
BBI.IsUnpredicable = true;
|
BBI.IsUnpredicable = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1011,9 +1010,9 @@ void IfConverter::RemoveExtraEdges(BBInfo &BBI) {
|
||||||
|
|
||||||
/// Behaves like LiveRegUnits::StepForward() but also adds implicit uses to all
|
/// Behaves like LiveRegUnits::StepForward() but also adds implicit uses to all
|
||||||
/// values defined in MI which are not live/used by MI.
|
/// values defined in MI which are not live/used by MI.
|
||||||
static void UpdatePredRedefs(MachineInstr *MI, LivePhysRegs &Redefs) {
|
static void UpdatePredRedefs(MachineInstr &MI, LivePhysRegs &Redefs) {
|
||||||
SmallVector<std::pair<unsigned, const MachineOperand*>, 4> Clobbers;
|
SmallVector<std::pair<unsigned, const MachineOperand*>, 4> Clobbers;
|
||||||
Redefs.stepForward(*MI, Clobbers);
|
Redefs.stepForward(MI, Clobbers);
|
||||||
|
|
||||||
// Now add the implicit uses for each of the clobbered values.
|
// Now add the implicit uses for each of the clobbered values.
|
||||||
for (auto Reg : Clobbers) {
|
for (auto Reg : Clobbers) {
|
||||||
|
@ -1491,8 +1490,8 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
|
||||||
if (!BBI2->BB->empty() && (DI2 == BBI2->BB->end())) {
|
if (!BBI2->BB->empty() && (DI2 == BBI2->BB->end())) {
|
||||||
MachineBasicBlock::iterator BBI1T = BBI1->BB->getFirstTerminator();
|
MachineBasicBlock::iterator BBI1T = BBI1->BB->getFirstTerminator();
|
||||||
MachineBasicBlock::iterator BBI2T = BBI2->BB->getFirstTerminator();
|
MachineBasicBlock::iterator BBI2T = BBI2->BB->getFirstTerminator();
|
||||||
if ((BBI1T != BBI1->BB->end()) && TII->isPredicated(BBI1T) &&
|
if (BBI1T != BBI1->BB->end() && TII->isPredicated(*BBI1T) &&
|
||||||
((BBI2T != BBI2->BB->end()) && !TII->isPredicated(BBI2T)))
|
BBI2T != BBI2->BB->end() && !TII->isPredicated(*BBI2T))
|
||||||
--DI2;
|
--DI2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1515,7 +1514,7 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
|
||||||
// (e.g. a predicated return). If that is the case, we cannot merge
|
// (e.g. a predicated return). If that is the case, we cannot merge
|
||||||
// it with the tail block.
|
// it with the tail block.
|
||||||
MachineBasicBlock::const_iterator TI = BBI.BB->getFirstTerminator();
|
MachineBasicBlock::const_iterator TI = BBI.BB->getFirstTerminator();
|
||||||
if (TI != BBI.BB->end() && TII->isPredicated(TI))
|
if (TI != BBI.BB->end() && TII->isPredicated(*TI))
|
||||||
CanMergeTail = false;
|
CanMergeTail = false;
|
||||||
// There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
|
// There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
|
||||||
// check if there are any other predecessors besides those.
|
// check if there are any other predecessors besides those.
|
||||||
|
@ -1581,7 +1580,7 @@ void IfConverter::PredicateBlock(BBInfo &BBI,
|
||||||
bool AnyUnpred = false;
|
bool AnyUnpred = false;
|
||||||
bool MaySpec = LaterRedefs != nullptr;
|
bool MaySpec = LaterRedefs != nullptr;
|
||||||
for (MachineBasicBlock::iterator I = BBI.BB->begin(); I != E; ++I) {
|
for (MachineBasicBlock::iterator I = BBI.BB->begin(); I != E; ++I) {
|
||||||
if (I->isDebugValue() || TII->isPredicated(I))
|
if (I->isDebugValue() || TII->isPredicated(*I))
|
||||||
continue;
|
continue;
|
||||||
// It may be possible not to predicate an instruction if it's the 'true'
|
// It may be possible not to predicate an instruction if it's the 'true'
|
||||||
// side of a diamond and the 'false' side may re-define the instruction's
|
// side of a diamond and the 'false' side may re-define the instruction's
|
||||||
|
@ -1593,7 +1592,7 @@ void IfConverter::PredicateBlock(BBInfo &BBI,
|
||||||
// If any instruction is predicated, then every instruction after it must
|
// If any instruction is predicated, then every instruction after it must
|
||||||
// be predicated.
|
// be predicated.
|
||||||
MaySpec = false;
|
MaySpec = false;
|
||||||
if (!TII->PredicateInstruction(I, Cond)) {
|
if (!TII->PredicateInstruction(*I, Cond)) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
dbgs() << "Unable to predicate " << *I << "!\n";
|
dbgs() << "Unable to predicate " << *I << "!\n";
|
||||||
#endif
|
#endif
|
||||||
|
@ -1602,7 +1601,7 @@ void IfConverter::PredicateBlock(BBInfo &BBI,
|
||||||
|
|
||||||
// If the predicated instruction now redefines a register as the result of
|
// If the predicated instruction now redefines a register as the result of
|
||||||
// if-conversion, add an implicit kill.
|
// if-conversion, add an implicit kill.
|
||||||
UpdatePredRedefs(I, Redefs);
|
UpdatePredRedefs(*I, Redefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
BBI.Predicate.append(Cond.begin(), Cond.end());
|
BBI.Predicate.append(Cond.begin(), Cond.end());
|
||||||
|
@ -1622,25 +1621,24 @@ void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
|
||||||
bool IgnoreBr) {
|
bool IgnoreBr) {
|
||||||
MachineFunction &MF = *ToBBI.BB->getParent();
|
MachineFunction &MF = *ToBBI.BB->getParent();
|
||||||
|
|
||||||
for (MachineBasicBlock::iterator I = FromBBI.BB->begin(),
|
for (auto &I : *FromBBI.BB) {
|
||||||
E = FromBBI.BB->end(); I != E; ++I) {
|
|
||||||
// Do not copy the end of the block branches.
|
// Do not copy the end of the block branches.
|
||||||
if (IgnoreBr && I->isBranch())
|
if (IgnoreBr && I.isBranch())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
MachineInstr *MI = MF.CloneMachineInstr(I);
|
MachineInstr *MI = MF.CloneMachineInstr(&I);
|
||||||
ToBBI.BB->insert(ToBBI.BB->end(), MI);
|
ToBBI.BB->insert(ToBBI.BB->end(), MI);
|
||||||
ToBBI.NonPredSize++;
|
ToBBI.NonPredSize++;
|
||||||
unsigned ExtraPredCost = TII->getPredicationCost(&*I);
|
unsigned ExtraPredCost = TII->getPredicationCost(I);
|
||||||
unsigned NumCycles = SchedModel.computeInstrLatency(&*I, false);
|
unsigned NumCycles = SchedModel.computeInstrLatency(&I, false);
|
||||||
if (NumCycles > 1)
|
if (NumCycles > 1)
|
||||||
ToBBI.ExtraCost += NumCycles-1;
|
ToBBI.ExtraCost += NumCycles-1;
|
||||||
ToBBI.ExtraCost2 += ExtraPredCost;
|
ToBBI.ExtraCost2 += ExtraPredCost;
|
||||||
|
|
||||||
if (!TII->isPredicated(I) && !MI->isDebugValue()) {
|
if (!TII->isPredicated(I) && !MI->isDebugValue()) {
|
||||||
if (!TII->PredicateInstruction(MI, Cond)) {
|
if (!TII->PredicateInstruction(*MI, Cond)) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
dbgs() << "Unable to predicate " << *I << "!\n";
|
dbgs() << "Unable to predicate " << I << "!\n";
|
||||||
#endif
|
#endif
|
||||||
llvm_unreachable(nullptr);
|
llvm_unreachable(nullptr);
|
||||||
}
|
}
|
||||||
|
@ -1648,7 +1646,7 @@ void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
|
||||||
|
|
||||||
// If the predicated instruction now redefines a register as the result of
|
// If the predicated instruction now redefines a register as the result of
|
||||||
// if-conversion, add an implicit kill.
|
// if-conversion, add an implicit kill.
|
||||||
UpdatePredRedefs(MI, Redefs);
|
UpdatePredRedefs(*MI, Redefs);
|
||||||
|
|
||||||
// Some kill flags may not be correct anymore.
|
// Some kill flags may not be correct anymore.
|
||||||
if (!DontKill.empty())
|
if (!DontKill.empty())
|
||||||
|
@ -1695,7 +1693,7 @@ void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges) {
|
||||||
ToBBI.BB->splice(ToTI, FromBBI.BB, FromBBI.BB->begin(), FromTI);
|
ToBBI.BB->splice(ToTI, FromBBI.BB, FromBBI.BB->begin(), FromTI);
|
||||||
|
|
||||||
// If FromBB has non-predicated terminator we should copy it at the end.
|
// If FromBB has non-predicated terminator we should copy it at the end.
|
||||||
if ((FromTI != FromBBI.BB->end()) && !TII->isPredicated(FromTI))
|
if (FromTI != FromBBI.BB->end() && !TII->isPredicated(*FromTI))
|
||||||
ToTI = ToBBI.BB->end();
|
ToTI = ToBBI.BB->end();
|
||||||
ToBBI.BB->splice(ToTI, FromBBI.BB, FromTI, FromBBI.BB->end());
|
ToBBI.BB->splice(ToTI, FromBBI.BB, FromTI, FromBBI.BB->end());
|
||||||
|
|
||||||
|
|
|
@ -691,7 +691,7 @@ bool MachineBasicBlock::canFallThrough() {
|
||||||
// is possible. The isPredicated check is needed because this code can be
|
// is possible. The isPredicated check is needed because this code can be
|
||||||
// called during IfConversion, where an instruction which is normally a
|
// called during IfConversion, where an instruction which is normally a
|
||||||
// Barrier is predicated and thus no longer an actual control barrier.
|
// Barrier is predicated and thus no longer an actual control barrier.
|
||||||
return empty() || !back().isBarrier() || TII->isPredicated(&back());
|
return empty() || !back().isBarrier() || TII->isPredicated(back());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is no branch, control always falls through.
|
// If there is no branch, control always falls through.
|
||||||
|
|
|
@ -630,7 +630,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
|
||||||
"differs from its CFG successor!", MBB);
|
"differs from its CFG successor!", MBB);
|
||||||
}
|
}
|
||||||
if (!MBB->empty() && MBB->back().isBarrier() &&
|
if (!MBB->empty() && MBB->back().isBarrier() &&
|
||||||
!TII->isPredicated(&MBB->back())) {
|
!TII->isPredicated(MBB->back())) {
|
||||||
report("MBB exits via unconditional fall-through but ends with a "
|
report("MBB exits via unconditional fall-through but ends with a "
|
||||||
"barrier instruction!", MBB);
|
"barrier instruction!", MBB);
|
||||||
}
|
}
|
||||||
|
@ -772,7 +772,7 @@ void MachineVerifier::visitMachineBundleBefore(const MachineInstr *MI) {
|
||||||
// Ensure non-terminators don't follow terminators.
|
// Ensure non-terminators don't follow terminators.
|
||||||
// Ignore predicated terminators formed by if conversion.
|
// Ignore predicated terminators formed by if conversion.
|
||||||
// FIXME: If conversion shouldn't need to violate this rule.
|
// FIXME: If conversion shouldn't need to violate this rule.
|
||||||
if (MI->isTerminator() && !TII->isPredicated(MI)) {
|
if (MI->isTerminator() && !TII->isPredicated(*MI)) {
|
||||||
if (!FirstTerminator)
|
if (!FirstTerminator)
|
||||||
FirstTerminator = MI;
|
FirstTerminator = MI;
|
||||||
} else if (FirstTerminator) {
|
} else if (FirstTerminator) {
|
||||||
|
|
|
@ -256,32 +256,31 @@ bool TargetInstrInfo::findCommutedOpIndices(MachineInstr *MI,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const {
|
||||||
TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
|
if (!MI.isTerminator()) return false;
|
||||||
if (!MI->isTerminator()) return false;
|
|
||||||
|
|
||||||
// Conditional branch is a special case.
|
// Conditional branch is a special case.
|
||||||
if (MI->isBranch() && !MI->isBarrier())
|
if (MI.isBranch() && !MI.isBarrier())
|
||||||
return true;
|
return true;
|
||||||
if (!MI->isPredicable())
|
if (!MI.isPredicable())
|
||||||
return true;
|
return true;
|
||||||
return !isPredicated(MI);
|
return !isPredicated(MI);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TargetInstrInfo::PredicateInstruction(
|
bool TargetInstrInfo::PredicateInstruction(
|
||||||
MachineInstr *MI, ArrayRef<MachineOperand> Pred) const {
|
MachineInstr &MI, ArrayRef<MachineOperand> Pred) const {
|
||||||
bool MadeChange = false;
|
bool MadeChange = false;
|
||||||
|
|
||||||
assert(!MI->isBundle() &&
|
assert(!MI.isBundle() &&
|
||||||
"TargetInstrInfo::PredicateInstruction() can't handle bundles");
|
"TargetInstrInfo::PredicateInstruction() can't handle bundles");
|
||||||
|
|
||||||
const MCInstrDesc &MCID = MI->getDesc();
|
const MCInstrDesc &MCID = MI.getDesc();
|
||||||
if (!MI->isPredicable())
|
if (!MI.isPredicable())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (unsigned j = 0, i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
for (unsigned j = 0, i = 0, e = MI.getNumOperands(); i != e; ++i) {
|
||||||
if (MCID.OpInfo[i].isPredicate()) {
|
if (MCID.OpInfo[i].isPredicate()) {
|
||||||
MachineOperand &MO = MI->getOperand(i);
|
MachineOperand &MO = MI.getOperand(i);
|
||||||
if (MO.isReg()) {
|
if (MO.isReg()) {
|
||||||
MO.setReg(Pred[j].getReg());
|
MO.setReg(Pred[j].getReg());
|
||||||
MadeChange = true;
|
MadeChange = true;
|
||||||
|
@ -1035,7 +1034,7 @@ unsigned TargetInstrInfo::defaultDefLatency(const MCSchedModel &SchedModel,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned TargetInstrInfo::getPredicationCost(const MachineInstr *) const {
|
unsigned TargetInstrInfo::getPredicationCost(const MachineInstr &) const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -282,7 +282,7 @@ computeOutputLatency(const MachineInstr *DefMI, unsigned DefOperIdx,
|
||||||
unsigned Reg = DefMI->getOperand(DefOperIdx).getReg();
|
unsigned Reg = DefMI->getOperand(DefOperIdx).getReg();
|
||||||
const MachineFunction &MF = *DefMI->getParent()->getParent();
|
const MachineFunction &MF = *DefMI->getParent()->getParent();
|
||||||
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
|
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
|
||||||
if (!DepMI->readsRegister(Reg, TRI) && TII->isPredicated(DepMI))
|
if (!DepMI->readsRegister(Reg, TRI) && TII->isPredicated(*DepMI))
|
||||||
return computeInstrLatency(DefMI);
|
return computeInstrLatency(DefMI);
|
||||||
|
|
||||||
// If we have a per operand scheduling model, check if this def is writing
|
// If we have a per operand scheduling model, check if this def is writing
|
||||||
|
|
|
@ -99,7 +99,7 @@ bool AArch64InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
if (I == MBB.end())
|
if (I == MBB.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!isUnpredicatedTerminator(I))
|
if (!isUnpredicatedTerminator(*I))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Get the last instruction in the block.
|
// Get the last instruction in the block.
|
||||||
|
@ -107,7 +107,7 @@ bool AArch64InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
|
|
||||||
// If there is only one terminator instruction, process it.
|
// If there is only one terminator instruction, process it.
|
||||||
unsigned LastOpc = LastInst->getOpcode();
|
unsigned LastOpc = LastInst->getOpcode();
|
||||||
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
|
if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
|
||||||
if (isUncondBranchOpcode(LastOpc)) {
|
if (isUncondBranchOpcode(LastOpc)) {
|
||||||
TBB = LastInst->getOperand(0).getMBB();
|
TBB = LastInst->getOperand(0).getMBB();
|
||||||
return false;
|
return false;
|
||||||
|
@ -131,7 +131,7 @@ bool AArch64InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
LastInst->eraseFromParent();
|
LastInst->eraseFromParent();
|
||||||
LastInst = SecondLastInst;
|
LastInst = SecondLastInst;
|
||||||
LastOpc = LastInst->getOpcode();
|
LastOpc = LastInst->getOpcode();
|
||||||
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
|
if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
|
||||||
// Return now the only terminator is an unconditional branch.
|
// Return now the only terminator is an unconditional branch.
|
||||||
TBB = LastInst->getOperand(0).getMBB();
|
TBB = LastInst->getOperand(0).getMBB();
|
||||||
return false;
|
return false;
|
||||||
|
@ -143,7 +143,7 @@ bool AArch64InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are three terminators, we don't know what sort of block this is.
|
// If there are three terminators, we don't know what sort of block this is.
|
||||||
if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
|
if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// If the block ends with a B and a Bcc, handle it.
|
// If the block ends with a B and a Bcc, handle it.
|
||||||
|
|
|
@ -876,13 +876,12 @@ R600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool R600InstrInfo::isPredicated(const MachineInstr &MI) const {
|
||||||
R600InstrInfo::isPredicated(const MachineInstr *MI) const {
|
int idx = MI.findFirstPredOperandIdx();
|
||||||
int idx = MI->findFirstPredOperandIdx();
|
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned Reg = MI->getOperand(idx).getReg();
|
unsigned Reg = MI.getOperand(idx).getReg();
|
||||||
switch (Reg) {
|
switch (Reg) {
|
||||||
default: return false;
|
default: return false;
|
||||||
case AMDGPU::PRED_SEL_ONE:
|
case AMDGPU::PRED_SEL_ONE:
|
||||||
|
@ -892,25 +891,24 @@ R600InstrInfo::isPredicated(const MachineInstr *MI) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool R600InstrInfo::isPredicable(MachineInstr &MI) const {
|
||||||
R600InstrInfo::isPredicable(MachineInstr *MI) const {
|
|
||||||
// XXX: KILL* instructions can be predicated, but they must be the last
|
// XXX: KILL* instructions can be predicated, but they must be the last
|
||||||
// instruction in a clause, so this means any instructions after them cannot
|
// instruction in a clause, so this means any instructions after them cannot
|
||||||
// be predicated. Until we have proper support for instruction clauses in the
|
// be predicated. Until we have proper support for instruction clauses in the
|
||||||
// backend, we will mark KILL* instructions as unpredicable.
|
// backend, we will mark KILL* instructions as unpredicable.
|
||||||
|
|
||||||
if (MI->getOpcode() == AMDGPU::KILLGT) {
|
if (MI.getOpcode() == AMDGPU::KILLGT) {
|
||||||
return false;
|
return false;
|
||||||
} else if (MI->getOpcode() == AMDGPU::CF_ALU) {
|
} else if (MI.getOpcode() == AMDGPU::CF_ALU) {
|
||||||
// If the clause start in the middle of MBB then the MBB has more
|
// If the clause start in the middle of MBB then the MBB has more
|
||||||
// than a single clause, unable to predicate several clauses.
|
// than a single clause, unable to predicate several clauses.
|
||||||
if (MI->getParent()->begin() != MachineBasicBlock::iterator(MI))
|
if (MI.getParent()->begin() != MachineBasicBlock::iterator(MI))
|
||||||
return false;
|
return false;
|
||||||
// TODO: We don't support KC merging atm
|
// TODO: We don't support KC merging atm
|
||||||
if (MI->getOperand(3).getImm() != 0 || MI->getOperand(4).getImm() != 0)
|
if (MI.getOperand(3).getImm() != 0 || MI.getOperand(4).getImm() != 0)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
} else if (isVector(*MI)) {
|
} else if (isVector(MI)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return AMDGPUInstrInfo::isPredicable(MI);
|
return AMDGPUInstrInfo::isPredicable(MI);
|
||||||
|
@ -986,10 +984,9 @@ R600InstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) con
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool R600InstrInfo::DefinesPredicate(MachineInstr &MI,
|
||||||
R600InstrInfo::DefinesPredicate(MachineInstr *MI,
|
std::vector<MachineOperand> &Pred) const {
|
||||||
std::vector<MachineOperand> &Pred) const {
|
return isPredicateSetter(MI.getOpcode());
|
||||||
return isPredicateSetter(MI->getOpcode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -999,35 +996,33 @@ R600InstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool R600InstrInfo::PredicateInstruction(MachineInstr &MI,
|
||||||
|
ArrayRef<MachineOperand> Pred) const {
|
||||||
|
int PIdx = MI.findFirstPredOperandIdx();
|
||||||
|
|
||||||
bool
|
if (MI.getOpcode() == AMDGPU::CF_ALU) {
|
||||||
R600InstrInfo::PredicateInstruction(MachineInstr *MI,
|
MI.getOperand(8).setImm(0);
|
||||||
ArrayRef<MachineOperand> Pred) const {
|
|
||||||
int PIdx = MI->findFirstPredOperandIdx();
|
|
||||||
|
|
||||||
if (MI->getOpcode() == AMDGPU::CF_ALU) {
|
|
||||||
MI->getOperand(8).setImm(0);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MI->getOpcode() == AMDGPU::DOT_4) {
|
if (MI.getOpcode() == AMDGPU::DOT_4) {
|
||||||
MI->getOperand(getOperandIdx(*MI, AMDGPU::OpName::pred_sel_X))
|
MI.getOperand(getOperandIdx(MI, AMDGPU::OpName::pred_sel_X))
|
||||||
.setReg(Pred[2].getReg());
|
.setReg(Pred[2].getReg());
|
||||||
MI->getOperand(getOperandIdx(*MI, AMDGPU::OpName::pred_sel_Y))
|
MI.getOperand(getOperandIdx(MI, AMDGPU::OpName::pred_sel_Y))
|
||||||
.setReg(Pred[2].getReg());
|
.setReg(Pred[2].getReg());
|
||||||
MI->getOperand(getOperandIdx(*MI, AMDGPU::OpName::pred_sel_Z))
|
MI.getOperand(getOperandIdx(MI, AMDGPU::OpName::pred_sel_Z))
|
||||||
.setReg(Pred[2].getReg());
|
.setReg(Pred[2].getReg());
|
||||||
MI->getOperand(getOperandIdx(*MI, AMDGPU::OpName::pred_sel_W))
|
MI.getOperand(getOperandIdx(MI, AMDGPU::OpName::pred_sel_W))
|
||||||
.setReg(Pred[2].getReg());
|
.setReg(Pred[2].getReg());
|
||||||
MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI);
|
MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
|
||||||
MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit);
|
MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PIdx != -1) {
|
if (PIdx != -1) {
|
||||||
MachineOperand &PMO = MI->getOperand(PIdx);
|
MachineOperand &PMO = MI.getOperand(PIdx);
|
||||||
PMO.setReg(Pred[2].getReg());
|
PMO.setReg(Pred[2].getReg());
|
||||||
MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI);
|
MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
|
||||||
MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit);
|
MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1035,7 +1030,7 @@ R600InstrInfo::PredicateInstruction(MachineInstr *MI,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int R600InstrInfo::getPredicationCost(const MachineInstr *) const {
|
unsigned int R600InstrInfo::getPredicationCost(const MachineInstr &) const {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,9 +168,9 @@ namespace llvm {
|
||||||
|
|
||||||
unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
|
unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
|
||||||
|
|
||||||
bool isPredicated(const MachineInstr *MI) const override;
|
bool isPredicated(const MachineInstr &MI) const override;
|
||||||
|
|
||||||
bool isPredicable(MachineInstr *MI) const override;
|
bool isPredicable(MachineInstr &MI) const override;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCyles,
|
isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCyles,
|
||||||
|
@ -187,8 +187,8 @@ namespace llvm {
|
||||||
unsigned NumFCycles, unsigned ExtraFCycles,
|
unsigned NumFCycles, unsigned ExtraFCycles,
|
||||||
BranchProbability Probability) const override;
|
BranchProbability Probability) const override;
|
||||||
|
|
||||||
bool DefinesPredicate(MachineInstr *MI,
|
bool DefinesPredicate(MachineInstr &MI,
|
||||||
std::vector<MachineOperand> &Pred) const override;
|
std::vector<MachineOperand> &Pred) const override;
|
||||||
|
|
||||||
bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
|
bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
|
||||||
ArrayRef<MachineOperand> Pred2) const override;
|
ArrayRef<MachineOperand> Pred2) const override;
|
||||||
|
@ -196,10 +196,10 @@ namespace llvm {
|
||||||
bool isProfitableToUnpredicate(MachineBasicBlock &TMBB,
|
bool isProfitableToUnpredicate(MachineBasicBlock &TMBB,
|
||||||
MachineBasicBlock &FMBB) const override;
|
MachineBasicBlock &FMBB) const override;
|
||||||
|
|
||||||
bool PredicateInstruction(MachineInstr *MI,
|
bool PredicateInstruction(MachineInstr &MI,
|
||||||
ArrayRef<MachineOperand> Pred) const override;
|
ArrayRef<MachineOperand> Pred) const override;
|
||||||
|
|
||||||
unsigned int getPredicationCost(const MachineInstr *) const override;
|
unsigned int getPredicationCost(const MachineInstr &) const override;
|
||||||
|
|
||||||
unsigned int getInstrLatency(const InstrItineraryData *ItinData,
|
unsigned int getInstrLatency(const InstrItineraryData *ItinData,
|
||||||
const MachineInstr *MI,
|
const MachineInstr *MI,
|
||||||
|
|
|
@ -85,7 +85,7 @@ private:
|
||||||
if (LastDstChan >= BISlot)
|
if (LastDstChan >= BISlot)
|
||||||
isTrans = true;
|
isTrans = true;
|
||||||
LastDstChan = BISlot;
|
LastDstChan = BISlot;
|
||||||
if (TII->isPredicated(&*BI))
|
if (TII->isPredicated(*BI))
|
||||||
continue;
|
continue;
|
||||||
int OperandIdx = TII->getOperandIdx(BI->getOpcode(), AMDGPU::OpName::write);
|
int OperandIdx = TII->getOperandIdx(BI->getOpcode(), AMDGPU::OpName::write);
|
||||||
if (OperandIdx > -1 && BI->getOperand(OperandIdx).getImm() == 0)
|
if (OperandIdx > -1 && BI->getOperand(OperandIdx).getImm() == 0)
|
||||||
|
|
|
@ -289,7 +289,7 @@ ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||||
|
|
||||||
// Walk backwards from the end of the basic block until the branch is
|
// Walk backwards from the end of the basic block until the branch is
|
||||||
// analyzed or we give up.
|
// analyzed or we give up.
|
||||||
while (isPredicated(I) || I->isTerminator() || I->isDebugValue()) {
|
while (isPredicated(*I) || I->isTerminator() || I->isDebugValue()) {
|
||||||
|
|
||||||
// Flag to be raised on unanalyzeable instructions. This is useful in cases
|
// Flag to be raised on unanalyzeable instructions. This is useful in cases
|
||||||
// where we want to clean up on the end of the basic block before we bail
|
// where we want to clean up on the end of the basic block before we bail
|
||||||
|
@ -322,7 +322,7 @@ ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||||
Cond.push_back(I->getOperand(2));
|
Cond.push_back(I->getOperand(2));
|
||||||
} else if (I->isReturn()) {
|
} else if (I->isReturn()) {
|
||||||
// Returns can't be analyzed, but we should run cleanup.
|
// Returns can't be analyzed, but we should run cleanup.
|
||||||
CantAnalyze = !isPredicated(I);
|
CantAnalyze = !isPredicated(*I);
|
||||||
} else {
|
} else {
|
||||||
// We encountered other unrecognized terminator. Bail out immediately.
|
// We encountered other unrecognized terminator. Bail out immediately.
|
||||||
return true;
|
return true;
|
||||||
|
@ -330,7 +330,7 @@ ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||||
|
|
||||||
// Cleanup code - to be run for unpredicated unconditional branches and
|
// Cleanup code - to be run for unpredicated unconditional branches and
|
||||||
// returns.
|
// returns.
|
||||||
if (!isPredicated(I) &&
|
if (!isPredicated(*I) &&
|
||||||
(isUncondBranchOpcode(I->getOpcode()) ||
|
(isUncondBranchOpcode(I->getOpcode()) ||
|
||||||
isIndirectBranchOpcode(I->getOpcode()) ||
|
isIndirectBranchOpcode(I->getOpcode()) ||
|
||||||
isJumpTableBranchOpcode(I->getOpcode()) ||
|
isJumpTableBranchOpcode(I->getOpcode()) ||
|
||||||
|
@ -438,10 +438,10 @@ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMBaseInstrInfo::isPredicated(const MachineInstr *MI) const {
|
bool ARMBaseInstrInfo::isPredicated(const MachineInstr &MI) const {
|
||||||
if (MI->isBundle()) {
|
if (MI.isBundle()) {
|
||||||
MachineBasicBlock::const_instr_iterator I = MI->getIterator();
|
MachineBasicBlock::const_instr_iterator I = MI.getIterator();
|
||||||
MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
|
MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
|
||||||
while (++I != E && I->isInsideBundle()) {
|
while (++I != E && I->isInsideBundle()) {
|
||||||
int PIdx = I->findFirstPredOperandIdx();
|
int PIdx = I->findFirstPredOperandIdx();
|
||||||
if (PIdx != -1 && I->getOperand(PIdx).getImm() != ARMCC::AL)
|
if (PIdx != -1 && I->getOperand(PIdx).getImm() != ARMCC::AL)
|
||||||
|
@ -450,26 +450,26 @@ bool ARMBaseInstrInfo::isPredicated(const MachineInstr *MI) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PIdx = MI->findFirstPredOperandIdx();
|
int PIdx = MI.findFirstPredOperandIdx();
|
||||||
return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL;
|
return PIdx != -1 && MI.getOperand(PIdx).getImm() != ARMCC::AL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMBaseInstrInfo::
|
bool ARMBaseInstrInfo::PredicateInstruction(
|
||||||
PredicateInstruction(MachineInstr *MI, ArrayRef<MachineOperand> Pred) const {
|
MachineInstr &MI, ArrayRef<MachineOperand> Pred) const {
|
||||||
unsigned Opc = MI->getOpcode();
|
unsigned Opc = MI.getOpcode();
|
||||||
if (isUncondBranchOpcode(Opc)) {
|
if (isUncondBranchOpcode(Opc)) {
|
||||||
MI->setDesc(get(getMatchingCondBranchOpcode(Opc)));
|
MI.setDesc(get(getMatchingCondBranchOpcode(Opc)));
|
||||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
MachineInstrBuilder(*MI.getParent()->getParent(), MI)
|
||||||
.addImm(Pred[0].getImm())
|
.addImm(Pred[0].getImm())
|
||||||
.addReg(Pred[1].getReg());
|
.addReg(Pred[1].getReg());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PIdx = MI->findFirstPredOperandIdx();
|
int PIdx = MI.findFirstPredOperandIdx();
|
||||||
if (PIdx != -1) {
|
if (PIdx != -1) {
|
||||||
MachineOperand &PMO = MI->getOperand(PIdx);
|
MachineOperand &PMO = MI.getOperand(PIdx);
|
||||||
PMO.setImm(Pred[0].getImm());
|
PMO.setImm(Pred[0].getImm());
|
||||||
MI->getOperand(PIdx+1).setReg(Pred[1].getReg());
|
MI.getOperand(PIdx+1).setReg(Pred[1].getReg());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -501,11 +501,11 @@ bool ARMBaseInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI,
|
bool ARMBaseInstrInfo::DefinesPredicate(
|
||||||
std::vector<MachineOperand> &Pred) const {
|
MachineInstr &MI, std::vector<MachineOperand> &Pred) const {
|
||||||
bool Found = false;
|
bool Found = false;
|
||||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
|
||||||
const MachineOperand &MO = MI->getOperand(i);
|
const MachineOperand &MO = MI.getOperand(i);
|
||||||
if ((MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR)) ||
|
if ((MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR)) ||
|
||||||
(MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR)) {
|
(MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR)) {
|
||||||
Pred.push_back(MO);
|
Pred.push_back(MO);
|
||||||
|
@ -555,21 +555,21 @@ static bool isEligibleForITBlock(const MachineInstr *MI) {
|
||||||
/// isPredicable - Return true if the specified instruction can be predicated.
|
/// isPredicable - Return true if the specified instruction can be predicated.
|
||||||
/// By default, this returns true for every instruction with a
|
/// By default, this returns true for every instruction with a
|
||||||
/// PredicateOperand.
|
/// PredicateOperand.
|
||||||
bool ARMBaseInstrInfo::isPredicable(MachineInstr *MI) const {
|
bool ARMBaseInstrInfo::isPredicable(MachineInstr &MI) const {
|
||||||
if (!MI->isPredicable())
|
if (!MI.isPredicable())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!isEligibleForITBlock(MI))
|
if (!isEligibleForITBlock(&MI))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ARMFunctionInfo *AFI =
|
ARMFunctionInfo *AFI =
|
||||||
MI->getParent()->getParent()->getInfo<ARMFunctionInfo>();
|
MI.getParent()->getParent()->getInfo<ARMFunctionInfo>();
|
||||||
|
|
||||||
if (AFI->isThumb2Function()) {
|
if (AFI->isThumb2Function()) {
|
||||||
if (getSubtarget().restrictIT())
|
if (getSubtarget().restrictIT())
|
||||||
return isV8EligibleForIT(MI);
|
return isV8EligibleForIT(&MI);
|
||||||
} else { // non-Thumb
|
} else { // non-Thumb
|
||||||
if ((MI->getDesc().TSFlags & ARMII::DomainMask) == ARMII::DomainNEON)
|
if ((MI.getDesc().TSFlags & ARMII::DomainMask) == ARMII::DomainNEON)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1718,7 +1718,7 @@ isProfitableToIfCvt(MachineBasicBlock &MBB,
|
||||||
CmpMI->getOpcode() == ARM::t2CMPri) {
|
CmpMI->getOpcode() == ARM::t2CMPri) {
|
||||||
unsigned Reg = CmpMI->getOperand(0).getReg();
|
unsigned Reg = CmpMI->getOperand(0).getReg();
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes P = getInstrPredicate(CmpMI, PredReg);
|
ARMCC::CondCodes P = getInstrPredicate(*CmpMI, PredReg);
|
||||||
if (P == ARMCC::AL && CmpMI->getOperand(1).getImm() == 0 &&
|
if (P == ARMCC::AL && CmpMI->getOperand(1).getImm() == 0 &&
|
||||||
isARMLowRegister(Reg))
|
isARMLowRegister(Reg))
|
||||||
return false;
|
return false;
|
||||||
|
@ -1773,16 +1773,16 @@ ARMBaseInstrInfo::isProfitableToUnpredicate(MachineBasicBlock &TMBB,
|
||||||
/// getInstrPredicate - If instruction is predicated, returns its predicate
|
/// getInstrPredicate - If instruction is predicated, returns its predicate
|
||||||
/// condition, otherwise returns AL. It also returns the condition code
|
/// condition, otherwise returns AL. It also returns the condition code
|
||||||
/// register by reference.
|
/// register by reference.
|
||||||
ARMCC::CondCodes
|
ARMCC::CondCodes llvm::getInstrPredicate(const MachineInstr &MI,
|
||||||
llvm::getInstrPredicate(const MachineInstr *MI, unsigned &PredReg) {
|
unsigned &PredReg) {
|
||||||
int PIdx = MI->findFirstPredOperandIdx();
|
int PIdx = MI.findFirstPredOperandIdx();
|
||||||
if (PIdx == -1) {
|
if (PIdx == -1) {
|
||||||
PredReg = 0;
|
PredReg = 0;
|
||||||
return ARMCC::AL;
|
return ARMCC::AL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PredReg = MI->getOperand(PIdx+1).getReg();
|
PredReg = MI.getOperand(PIdx+1).getReg();
|
||||||
return (ARMCC::CondCodes)MI->getOperand(PIdx).getImm();
|
return (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1806,7 +1806,7 @@ MachineInstr *ARMBaseInstrInfo::commuteInstructionImpl(MachineInstr *MI,
|
||||||
case ARM::t2MOVCCr: {
|
case ARM::t2MOVCCr: {
|
||||||
// MOVCC can be commuted by inverting the condition.
|
// MOVCC can be commuted by inverting the condition.
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes CC = getInstrPredicate(MI, PredReg);
|
ARMCC::CondCodes CC = getInstrPredicate(*MI, PredReg);
|
||||||
// MOVCC AL can't be inverted. Shouldn't happen.
|
// MOVCC AL can't be inverted. Shouldn't happen.
|
||||||
if (CC == ARMCC::AL || PredReg != ARM::CPSR)
|
if (CC == ARMCC::AL || PredReg != ARM::CPSR)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -2395,7 +2395,7 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
|
||||||
|
|
||||||
// Masked compares sometimes use the same register as the corresponding 'and'.
|
// Masked compares sometimes use the same register as the corresponding 'and'.
|
||||||
if (CmpMask != ~0) {
|
if (CmpMask != ~0) {
|
||||||
if (!isSuitableForMask(MI, SrcReg, CmpMask, false) || isPredicated(MI)) {
|
if (!isSuitableForMask(MI, SrcReg, CmpMask, false) || isPredicated(*MI)) {
|
||||||
MI = nullptr;
|
MI = nullptr;
|
||||||
for (MachineRegisterInfo::use_instr_iterator
|
for (MachineRegisterInfo::use_instr_iterator
|
||||||
UI = MRI->use_instr_begin(SrcReg), UE = MRI->use_instr_end();
|
UI = MRI->use_instr_begin(SrcReg), UE = MRI->use_instr_end();
|
||||||
|
@ -2403,7 +2403,7 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
|
||||||
if (UI->getParent() != CmpInstr->getParent()) continue;
|
if (UI->getParent() != CmpInstr->getParent()) continue;
|
||||||
MachineInstr *PotentialAND = &*UI;
|
MachineInstr *PotentialAND = &*UI;
|
||||||
if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true) ||
|
if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true) ||
|
||||||
isPredicated(PotentialAND))
|
isPredicated(*PotentialAND))
|
||||||
continue;
|
continue;
|
||||||
MI = PotentialAND;
|
MI = PotentialAND;
|
||||||
break;
|
break;
|
||||||
|
@ -2471,7 +2471,7 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
|
||||||
if (!MI) MI = Sub;
|
if (!MI) MI = Sub;
|
||||||
|
|
||||||
// We can't use a predicated instruction - it doesn't always write the flags.
|
// We can't use a predicated instruction - it doesn't always write the flags.
|
||||||
if (isPredicated(MI))
|
if (isPredicated(*MI))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (MI->getOpcode()) {
|
switch (MI->getOpcode()) {
|
||||||
|
@ -2618,7 +2618,7 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
|
||||||
// Toggle the optional operand to CPSR.
|
// Toggle the optional operand to CPSR.
|
||||||
MI->getOperand(5).setReg(ARM::CPSR);
|
MI->getOperand(5).setReg(ARM::CPSR);
|
||||||
MI->getOperand(5).setIsDef(true);
|
MI->getOperand(5).setIsDef(true);
|
||||||
assert(!isPredicated(MI) && "Can't use flags from predicated instruction");
|
assert(!isPredicated(*MI) && "Can't use flags from predicated instruction");
|
||||||
CmpInstr->eraseFromParent();
|
CmpInstr->eraseFromParent();
|
||||||
|
|
||||||
// Modify the condition code of operands in OperandsToUpdate.
|
// Modify the condition code of operands in OperandsToUpdate.
|
||||||
|
@ -3946,15 +3946,15 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
|
||||||
return Latency;
|
return Latency;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ARMBaseInstrInfo::getPredicationCost(const MachineInstr *MI) const {
|
unsigned ARMBaseInstrInfo::getPredicationCost(const MachineInstr &MI) const {
|
||||||
if (MI->isCopyLike() || MI->isInsertSubreg() ||
|
if (MI.isCopyLike() || MI.isInsertSubreg() || MI.isRegSequence() ||
|
||||||
MI->isRegSequence() || MI->isImplicitDef())
|
MI.isImplicitDef())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (MI->isBundle())
|
if (MI.isBundle())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const MCInstrDesc &MCID = MI->getDesc();
|
const MCInstrDesc &MCID = MI.getDesc();
|
||||||
|
|
||||||
if (MCID.isCall() || MCID.hasImplicitDefOfPhysReg(ARM::CPSR)) {
|
if (MCID.isCall() || MCID.hasImplicitDefOfPhysReg(ARM::CPSR)) {
|
||||||
// When predicated, CPSR is an additional source operand for CPSR updating
|
// When predicated, CPSR is an additional source operand for CPSR updating
|
||||||
|
@ -4152,12 +4152,12 @@ ARMBaseInstrInfo::getExecutionDomain(const MachineInstr *MI) const {
|
||||||
if (Subtarget.hasNEON()) {
|
if (Subtarget.hasNEON()) {
|
||||||
// VMOVD, VMOVRS and VMOVSR are VFP instructions, but can be changed to NEON
|
// VMOVD, VMOVRS and VMOVSR are VFP instructions, but can be changed to NEON
|
||||||
// if they are not predicated.
|
// if they are not predicated.
|
||||||
if (MI->getOpcode() == ARM::VMOVD && !isPredicated(MI))
|
if (MI->getOpcode() == ARM::VMOVD && !isPredicated(*MI))
|
||||||
return std::make_pair(ExeVFP, (1 << ExeVFP) | (1 << ExeNEON));
|
return std::make_pair(ExeVFP, (1 << ExeVFP) | (1 << ExeNEON));
|
||||||
|
|
||||||
// CortexA9 is particularly picky about mixing the two and wants these
|
// CortexA9 is particularly picky about mixing the two and wants these
|
||||||
// converted.
|
// converted.
|
||||||
if (Subtarget.isCortexA9() && !isPredicated(MI) &&
|
if (Subtarget.isCortexA9() && !isPredicated(*MI) &&
|
||||||
(MI->getOpcode() == ARM::VMOVRS || MI->getOpcode() == ARM::VMOVSR ||
|
(MI->getOpcode() == ARM::VMOVRS || MI->getOpcode() == ARM::VMOVSR ||
|
||||||
MI->getOpcode() == ARM::VMOVS))
|
MI->getOpcode() == ARM::VMOVS))
|
||||||
return std::make_pair(ExeVFP, (1 << ExeVFP) | (1 << ExeNEON));
|
return std::make_pair(ExeVFP, (1 << ExeVFP) | (1 << ExeNEON));
|
||||||
|
@ -4252,7 +4252,7 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Zap the predicate operands.
|
// Zap the predicate operands.
|
||||||
assert(!isPredicated(MI) && "Cannot predicate a VORRd");
|
assert(!isPredicated(*MI) && "Cannot predicate a VORRd");
|
||||||
|
|
||||||
// Make sure we've got NEON instructions.
|
// Make sure we've got NEON instructions.
|
||||||
assert(Subtarget.hasNEON() && "VORRd requires NEON");
|
assert(Subtarget.hasNEON() && "VORRd requires NEON");
|
||||||
|
@ -4273,7 +4273,7 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const {
|
||||||
case ARM::VMOVRS:
|
case ARM::VMOVRS:
|
||||||
if (Domain != ExeNEON)
|
if (Domain != ExeNEON)
|
||||||
break;
|
break;
|
||||||
assert(!isPredicated(MI) && "Cannot predicate a VGETLN");
|
assert(!isPredicated(*MI) && "Cannot predicate a VGETLN");
|
||||||
|
|
||||||
// Source instruction is %RDst = VMOVRS %SSrc, 14, %noreg (; implicits)
|
// Source instruction is %RDst = VMOVRS %SSrc, 14, %noreg (; implicits)
|
||||||
DstReg = MI->getOperand(0).getReg();
|
DstReg = MI->getOperand(0).getReg();
|
||||||
|
@ -4299,7 +4299,7 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const {
|
||||||
case ARM::VMOVSR: {
|
case ARM::VMOVSR: {
|
||||||
if (Domain != ExeNEON)
|
if (Domain != ExeNEON)
|
||||||
break;
|
break;
|
||||||
assert(!isPredicated(MI) && "Cannot predicate a VSETLN");
|
assert(!isPredicated(*MI) && "Cannot predicate a VSETLN");
|
||||||
|
|
||||||
// Source instruction is %SDst = VMOVSR %RSrc, 14, %noreg (; implicits)
|
// Source instruction is %SDst = VMOVSR %RSrc, 14, %noreg (; implicits)
|
||||||
DstReg = MI->getOperand(0).getReg();
|
DstReg = MI->getOperand(0).getReg();
|
||||||
|
|
|
@ -135,24 +135,24 @@ public:
|
||||||
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
|
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
|
||||||
|
|
||||||
// Predication support.
|
// Predication support.
|
||||||
bool isPredicated(const MachineInstr *MI) const override;
|
bool isPredicated(const MachineInstr &MI) const override;
|
||||||
|
|
||||||
ARMCC::CondCodes getPredicate(const MachineInstr *MI) const {
|
ARMCC::CondCodes getPredicate(const MachineInstr &MI) const {
|
||||||
int PIdx = MI->findFirstPredOperandIdx();
|
int PIdx = MI.findFirstPredOperandIdx();
|
||||||
return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm()
|
return PIdx != -1 ? (ARMCC::CondCodes)MI.getOperand(PIdx).getImm()
|
||||||
: ARMCC::AL;
|
: ARMCC::AL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PredicateInstruction(MachineInstr *MI,
|
bool PredicateInstruction(MachineInstr &MI,
|
||||||
ArrayRef<MachineOperand> Pred) const override;
|
ArrayRef<MachineOperand> Pred) const override;
|
||||||
|
|
||||||
bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
|
bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
|
||||||
ArrayRef<MachineOperand> Pred2) const override;
|
ArrayRef<MachineOperand> Pred2) const override;
|
||||||
|
|
||||||
bool DefinesPredicate(MachineInstr *MI,
|
bool DefinesPredicate(MachineInstr &MI,
|
||||||
std::vector<MachineOperand> &Pred) const override;
|
std::vector<MachineOperand> &Pred) const override;
|
||||||
|
|
||||||
bool isPredicable(MachineInstr *MI) const override;
|
bool isPredicable(MachineInstr &MI) const override;
|
||||||
|
|
||||||
/// GetInstSize - Returns the size of the specified MachineInstr.
|
/// GetInstSize - Returns the size of the specified MachineInstr.
|
||||||
///
|
///
|
||||||
|
@ -327,7 +327,7 @@ private:
|
||||||
const MCInstrDesc &UseMCID,
|
const MCInstrDesc &UseMCID,
|
||||||
unsigned UseIdx, unsigned UseAlign) const;
|
unsigned UseIdx, unsigned UseAlign) const;
|
||||||
|
|
||||||
unsigned getPredicationCost(const MachineInstr *MI) const override;
|
unsigned getPredicationCost(const MachineInstr &MI) const override;
|
||||||
|
|
||||||
unsigned getInstrLatency(const InstrItineraryData *ItinData,
|
unsigned getInstrLatency(const InstrItineraryData *ItinData,
|
||||||
const MachineInstr *MI,
|
const MachineInstr *MI,
|
||||||
|
@ -447,7 +447,7 @@ static inline bool isPushOpcode(int Opc) {
|
||||||
/// getInstrPredicate - If instruction is predicated, returns its predicate
|
/// getInstrPredicate - If instruction is predicated, returns its predicate
|
||||||
/// condition, otherwise returns AL. It also returns the condition code
|
/// condition, otherwise returns AL. It also returns the condition code
|
||||||
/// register by reference.
|
/// register by reference.
|
||||||
ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg);
|
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, unsigned &PredReg);
|
||||||
|
|
||||||
unsigned getMatchingCondBranchOpcode(unsigned Opc);
|
unsigned getMatchingCondBranchOpcode(unsigned Opc);
|
||||||
|
|
||||||
|
|
|
@ -1463,14 +1463,14 @@ void ARMConstantIslands::createNewWater(unsigned CPUserIndex,
|
||||||
// Avoid splitting an IT block.
|
// Avoid splitting an IT block.
|
||||||
if (LastIT) {
|
if (LastIT) {
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes CC = getITInstrPredicate(MI, PredReg);
|
ARMCC::CondCodes CC = getITInstrPredicate(*MI, PredReg);
|
||||||
if (CC != ARMCC::AL)
|
if (CC != ARMCC::AL)
|
||||||
MI = LastIT;
|
MI = LastIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We really must not split an IT block.
|
// We really must not split an IT block.
|
||||||
DEBUG(unsigned PredReg;
|
DEBUG(unsigned PredReg;
|
||||||
assert(!isThumb || getITInstrPredicate(MI, PredReg) == ARMCC::AL));
|
assert(!isThumb || getITInstrPredicate(*MI, PredReg) == ARMCC::AL));
|
||||||
|
|
||||||
NewMBB = splitBlockBeforeInstr(MI);
|
NewMBB = splitBlockBeforeInstr(MI);
|
||||||
}
|
}
|
||||||
|
@ -1916,7 +1916,7 @@ bool ARMConstantIslands::optimizeThumb2Branches() {
|
||||||
|
|
||||||
NewOpc = 0;
|
NewOpc = 0;
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes Pred = getInstrPredicate(Br.MI, PredReg);
|
ARMCC::CondCodes Pred = getInstrPredicate(*Br.MI, PredReg);
|
||||||
if (Pred == ARMCC::EQ)
|
if (Pred == ARMCC::EQ)
|
||||||
NewOpc = ARM::tCBZ;
|
NewOpc = ARM::tCBZ;
|
||||||
else if (Pred == ARMCC::NE)
|
else if (Pred == ARMCC::NE)
|
||||||
|
@ -1934,7 +1934,7 @@ bool ARMConstantIslands::optimizeThumb2Branches() {
|
||||||
--CmpMI;
|
--CmpMI;
|
||||||
if (CmpMI->getOpcode() == ARM::tCMPi8) {
|
if (CmpMI->getOpcode() == ARM::tCMPi8) {
|
||||||
unsigned Reg = CmpMI->getOperand(0).getReg();
|
unsigned Reg = CmpMI->getOperand(0).getReg();
|
||||||
Pred = getInstrPredicate(CmpMI, PredReg);
|
Pred = getInstrPredicate(*CmpMI, PredReg);
|
||||||
if (Pred == ARMCC::AL &&
|
if (Pred == ARMCC::AL &&
|
||||||
CmpMI->getOperand(1).getImm() == 0 &&
|
CmpMI->getOperand(1).getImm() == 0 &&
|
||||||
isARMLowRegister(Reg)) {
|
isARMLowRegister(Reg)) {
|
||||||
|
|
|
@ -651,7 +651,7 @@ void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
|
||||||
MachineInstr &MI = *MBBI;
|
MachineInstr &MI = *MBBI;
|
||||||
unsigned Opcode = MI.getOpcode();
|
unsigned Opcode = MI.getOpcode();
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes Pred = getInstrPredicate(&MI, PredReg);
|
ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
|
||||||
unsigned DstReg = MI.getOperand(0).getReg();
|
unsigned DstReg = MI.getOperand(0).getReg();
|
||||||
bool DstIsDead = MI.getOperand(0).isDead();
|
bool DstIsDead = MI.getOperand(0).isDead();
|
||||||
bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm;
|
bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm;
|
||||||
|
|
|
@ -840,7 +840,7 @@ MachineInstr *ARMLoadStoreOpt::MergeOpsUpdate(const MergeCandidate &Cand) {
|
||||||
unsigned Base = getLoadStoreBaseOp(*First).getReg();
|
unsigned Base = getLoadStoreBaseOp(*First).getReg();
|
||||||
bool BaseKill = LatestMI->killsRegister(Base);
|
bool BaseKill = LatestMI->killsRegister(Base);
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes Pred = getInstrPredicate(First, PredReg);
|
ARMCC::CondCodes Pred = getInstrPredicate(*First, PredReg);
|
||||||
DebugLoc DL = First->getDebugLoc();
|
DebugLoc DL = First->getDebugLoc();
|
||||||
MachineInstr *Merged = nullptr;
|
MachineInstr *Merged = nullptr;
|
||||||
if (Cand.CanMergeToLSDouble)
|
if (Cand.CanMergeToLSDouble)
|
||||||
|
@ -1102,7 +1102,7 @@ static int isIncrementOrDecrement(const MachineInstr &MI, unsigned Reg,
|
||||||
unsigned MIPredReg;
|
unsigned MIPredReg;
|
||||||
if (MI.getOperand(0).getReg() != Reg ||
|
if (MI.getOperand(0).getReg() != Reg ||
|
||||||
MI.getOperand(1).getReg() != Reg ||
|
MI.getOperand(1).getReg() != Reg ||
|
||||||
getInstrPredicate(&MI, MIPredReg) != Pred ||
|
getInstrPredicate(MI, MIPredReg) != Pred ||
|
||||||
MIPredReg != PredReg)
|
MIPredReg != PredReg)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1169,7 +1169,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineInstr *MI) {
|
||||||
unsigned Base = BaseOP.getReg();
|
unsigned Base = BaseOP.getReg();
|
||||||
bool BaseKill = BaseOP.isKill();
|
bool BaseKill = BaseOP.isKill();
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
|
ARMCC::CondCodes Pred = getInstrPredicate(*MI, PredReg);
|
||||||
unsigned Opcode = MI->getOpcode();
|
unsigned Opcode = MI->getOpcode();
|
||||||
DebugLoc DL = MI->getDebugLoc();
|
DebugLoc DL = MI->getDebugLoc();
|
||||||
|
|
||||||
|
@ -1291,7 +1291,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineInstr *MI) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
|
ARMCC::CondCodes Pred = getInstrPredicate(*MI, PredReg);
|
||||||
int Bytes = getLSMultipleTransferSize(MI);
|
int Bytes = getLSMultipleTransferSize(MI);
|
||||||
MachineBasicBlock &MBB = *MI->getParent();
|
MachineBasicBlock &MBB = *MI->getParent();
|
||||||
MachineBasicBlock::iterator MBBI(MI);
|
MachineBasicBlock::iterator MBBI(MI);
|
||||||
|
@ -1388,7 +1388,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSDouble(MachineInstr &MI) const {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned PredReg;
|
unsigned PredReg;
|
||||||
ARMCC::CondCodes Pred = getInstrPredicate(&MI, PredReg);
|
ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
|
||||||
MachineBasicBlock::iterator MBBI(MI);
|
MachineBasicBlock::iterator MBBI(MI);
|
||||||
MachineBasicBlock &MBB = *MI.getParent();
|
MachineBasicBlock &MBB = *MI.getParent();
|
||||||
int Offset;
|
int Offset;
|
||||||
|
@ -1549,7 +1549,7 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
|
||||||
bool OffUndef = isT2 ? false : MI->getOperand(3).isUndef();
|
bool OffUndef = isT2 ? false : MI->getOperand(3).isUndef();
|
||||||
int OffImm = getMemoryOpOffset(MI);
|
int OffImm = getMemoryOpOffset(MI);
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
|
ARMCC::CondCodes Pred = getInstrPredicate(*MI, PredReg);
|
||||||
|
|
||||||
if (OddRegNum > EvenRegNum && OffImm == 0) {
|
if (OddRegNum > EvenRegNum && OffImm == 0) {
|
||||||
// Ascending register numbers and no offset. It's safe to change it to a
|
// Ascending register numbers and no offset. It's safe to change it to a
|
||||||
|
@ -1655,7 +1655,7 @@ bool ARMLoadStoreOpt::LoadStoreMultipleOpti(MachineBasicBlock &MBB) {
|
||||||
unsigned Reg = MO.getReg();
|
unsigned Reg = MO.getReg();
|
||||||
unsigned Base = getLoadStoreBaseOp(*MBBI).getReg();
|
unsigned Base = getLoadStoreBaseOp(*MBBI).getReg();
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes Pred = getInstrPredicate(MBBI, PredReg);
|
ARMCC::CondCodes Pred = getInstrPredicate(*MBBI, PredReg);
|
||||||
int Offset = getMemoryOpOffset(MBBI);
|
int Offset = getMemoryOpOffset(MBBI);
|
||||||
if (CurrBase == 0) {
|
if (CurrBase == 0) {
|
||||||
// Start of a new chain.
|
// Start of a new chain.
|
||||||
|
@ -2056,7 +2056,7 @@ ARMPreAllocLoadStoreOpt::CanFormLdStDWord(MachineInstr *Op0, MachineInstr *Op1,
|
||||||
if (FirstReg == SecondReg)
|
if (FirstReg == SecondReg)
|
||||||
return false;
|
return false;
|
||||||
BaseReg = Op0->getOperand(1).getReg();
|
BaseReg = Op0->getOperand(1).getReg();
|
||||||
Pred = getInstrPredicate(Op0, PredReg);
|
Pred = getInstrPredicate(*Op0, PredReg);
|
||||||
dl = Op0->getDebugLoc();
|
dl = Op0->getDebugLoc();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2250,7 +2250,7 @@ ARMPreAllocLoadStoreOpt::RescheduleLoadStoreInstrs(MachineBasicBlock *MBB) {
|
||||||
if (!isMemoryOp(*MI))
|
if (!isMemoryOp(*MI))
|
||||||
continue;
|
continue;
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
if (getInstrPredicate(MI, PredReg) != ARMCC::AL)
|
if (getInstrPredicate(*MI, PredReg) != ARMCC::AL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int Opc = MI->getOpcode();
|
int Opc = MI->getOpcode();
|
||||||
|
|
|
@ -94,7 +94,7 @@ def : PredicateProlog<[{
|
||||||
(void)TII;
|
(void)TII;
|
||||||
}]>;
|
}]>;
|
||||||
|
|
||||||
def IsPredicatedPred : SchedPredicate<[{TII->isPredicated(MI)}]>;
|
def IsPredicatedPred : SchedPredicate<[{TII->isPredicated(*MI)}]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Instruction Itinerary classes used for ARM
|
// Instruction Itinerary classes used for ARM
|
||||||
|
|
|
@ -165,7 +165,7 @@ Thumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI,
|
||||||
++I;
|
++I;
|
||||||
if (I != E) {
|
if (I != E) {
|
||||||
unsigned NPredReg = 0;
|
unsigned NPredReg = 0;
|
||||||
ARMCC::CondCodes NCC = getITInstrPredicate(I, NPredReg);
|
ARMCC::CondCodes NCC = getITInstrPredicate(*I, NPredReg);
|
||||||
if (NCC == CC || NCC == OCC)
|
if (NCC == CC || NCC == OCC)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ bool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) {
|
||||||
MachineInstr *MI = &*MBBI;
|
MachineInstr *MI = &*MBBI;
|
||||||
DebugLoc dl = MI->getDebugLoc();
|
DebugLoc dl = MI->getDebugLoc();
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes CC = getITInstrPredicate(MI, PredReg);
|
ARMCC::CondCodes CC = getITInstrPredicate(*MI, PredReg);
|
||||||
if (CC == ARMCC::AL) {
|
if (CC == ARMCC::AL) {
|
||||||
++MBBI;
|
++MBBI;
|
||||||
continue;
|
continue;
|
||||||
|
@ -222,7 +222,7 @@ bool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) {
|
||||||
MI = NMI;
|
MI = NMI;
|
||||||
|
|
||||||
unsigned NPredReg = 0;
|
unsigned NPredReg = 0;
|
||||||
ARMCC::CondCodes NCC = getITInstrPredicate(NMI, NPredReg);
|
ARMCC::CondCodes NCC = getITInstrPredicate(*NMI, NPredReg);
|
||||||
if (NCC == CC || NCC == OCC) {
|
if (NCC == CC || NCC == OCC) {
|
||||||
Mask |= (NCC & 1) << Pos;
|
Mask |= (NCC & 1) << Pos;
|
||||||
// Add implicit use of ITSTATE.
|
// Add implicit use of ITSTATE.
|
||||||
|
|
|
@ -58,7 +58,7 @@ Thumb2InstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
|
||||||
// If the first instruction of Tail is predicated, we may have to update
|
// If the first instruction of Tail is predicated, we may have to update
|
||||||
// the IT instruction.
|
// the IT instruction.
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes CC = getInstrPredicate(Tail, PredReg);
|
ARMCC::CondCodes CC = getInstrPredicate(*Tail, PredReg);
|
||||||
MachineBasicBlock::iterator MBBI = Tail;
|
MachineBasicBlock::iterator MBBI = Tail;
|
||||||
if (CC != ARMCC::AL)
|
if (CC != ARMCC::AL)
|
||||||
// Expecting at least the t2IT instruction before it.
|
// Expecting at least the t2IT instruction before it.
|
||||||
|
@ -106,7 +106,7 @@ Thumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
return getITInstrPredicate(MBBI, PredReg) == ARMCC::AL;
|
return getITInstrPredicate(*MBBI, PredReg) == ARMCC::AL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||||
|
@ -459,7 +459,7 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
|
||||||
Offset += MI.getOperand(FrameRegIdx+1).getImm();
|
Offset += MI.getOperand(FrameRegIdx+1).getImm();
|
||||||
|
|
||||||
unsigned PredReg;
|
unsigned PredReg;
|
||||||
if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
|
if (Offset == 0 && getInstrPredicate(MI, PredReg) == ARMCC::AL) {
|
||||||
// Turn it into a move.
|
// Turn it into a move.
|
||||||
MI.setDesc(TII.get(ARM::tMOVr));
|
MI.setDesc(TII.get(ARM::tMOVr));
|
||||||
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
|
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
|
||||||
|
@ -627,9 +627,9 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
|
||||||
return Offset == 0;
|
return Offset == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ARMCC::CondCodes
|
ARMCC::CondCodes llvm::getITInstrPredicate(const MachineInstr &MI,
|
||||||
llvm::getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg) {
|
unsigned &PredReg) {
|
||||||
unsigned Opc = MI->getOpcode();
|
unsigned Opc = MI.getOpcode();
|
||||||
if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
|
if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
|
||||||
return ARMCC::AL;
|
return ARMCC::AL;
|
||||||
return getInstrPredicate(MI, PredReg);
|
return getInstrPredicate(MI, PredReg);
|
||||||
|
|
|
@ -70,9 +70,7 @@ private:
|
||||||
/// getITInstrPredicate - Valid only in Thumb2 mode. This function is identical
|
/// getITInstrPredicate - Valid only in Thumb2 mode. This function is identical
|
||||||
/// to llvm::getInstrPredicate except it returns AL for conditional branch
|
/// to llvm::getInstrPredicate except it returns AL for conditional branch
|
||||||
/// instructions which are "predicated", but are not in IT blocks.
|
/// instructions which are "predicated", but are not in IT blocks.
|
||||||
ARMCC::CondCodes getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg);
|
ARMCC::CondCodes getITInstrPredicate(const MachineInstr &MI, unsigned &PredReg);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -597,7 +597,7 @@ Thumb2SizeReduce::ReduceSpecial(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||||
case ARM::t2ADDSri:
|
case ARM::t2ADDSri:
|
||||||
case ARM::t2ADDSrr: {
|
case ARM::t2ADDSrr: {
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
if (getInstrPredicate(MI, PredReg) == ARMCC::AL) {
|
if (getInstrPredicate(*MI, PredReg) == ARMCC::AL) {
|
||||||
switch (Opc) {
|
switch (Opc) {
|
||||||
default: break;
|
default: break;
|
||||||
case ARM::t2ADDSri: {
|
case ARM::t2ADDSri: {
|
||||||
|
@ -702,7 +702,7 @@ Thumb2SizeReduce::ReduceTo2Addr(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||||
// Check if it's possible / necessary to transfer the predicate.
|
// Check if it's possible / necessary to transfer the predicate.
|
||||||
const MCInstrDesc &NewMCID = TII->get(Entry.NarrowOpc2);
|
const MCInstrDesc &NewMCID = TII->get(Entry.NarrowOpc2);
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
|
ARMCC::CondCodes Pred = getInstrPredicate(*MI, PredReg);
|
||||||
bool SkipPred = false;
|
bool SkipPred = false;
|
||||||
if (Pred != ARMCC::AL) {
|
if (Pred != ARMCC::AL) {
|
||||||
if (!NewMCID.isPredicable())
|
if (!NewMCID.isPredicable())
|
||||||
|
@ -798,7 +798,7 @@ Thumb2SizeReduce::ReduceToNarrow(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||||
// Check if it's possible / necessary to transfer the predicate.
|
// Check if it's possible / necessary to transfer the predicate.
|
||||||
const MCInstrDesc &NewMCID = TII->get(Entry.NarrowOpc1);
|
const MCInstrDesc &NewMCID = TII->get(Entry.NarrowOpc1);
|
||||||
unsigned PredReg = 0;
|
unsigned PredReg = 0;
|
||||||
ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
|
ARMCC::CondCodes Pred = getInstrPredicate(*MI, PredReg);
|
||||||
bool SkipPred = false;
|
bool SkipPred = false;
|
||||||
if (Pred != ARMCC::AL) {
|
if (Pred != ARMCC::AL) {
|
||||||
if (!NewMCID.isPredicable())
|
if (!NewMCID.isPredicable())
|
||||||
|
|
|
@ -90,7 +90,7 @@ bool BPFInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
|
|
||||||
// Working from the bottom, when we see a non-terminator
|
// Working from the bottom, when we see a non-terminator
|
||||||
// instruction, we're done.
|
// instruction, we're done.
|
||||||
if (!isUnpredicatedTerminator(I))
|
if (!isUnpredicatedTerminator(*I))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// A terminator that isn't a branch can't easily be handled
|
// A terminator that isn't a branch can't easily be handled
|
||||||
|
|
|
@ -937,7 +937,7 @@ bool HexagonEvaluator::evaluate(const MachineInstr *BI,
|
||||||
|
|
||||||
bool HexagonEvaluator::evaluateLoad(const MachineInstr *MI,
|
bool HexagonEvaluator::evaluateLoad(const MachineInstr *MI,
|
||||||
const CellMapType &Inputs, CellMapType &Outputs) const {
|
const CellMapType &Inputs, CellMapType &Outputs) const {
|
||||||
if (TII.isPredicated(MI))
|
if (TII.isPredicated(*MI))
|
||||||
return false;
|
return false;
|
||||||
assert(MI->mayLoad() && "A load that mayn't?");
|
assert(MI->mayLoad() && "A load that mayn't?");
|
||||||
unsigned Opc = MI->getOpcode();
|
unsigned Opc = MI->getOpcode();
|
||||||
|
|
|
@ -445,7 +445,7 @@ unsigned HexagonEarlyIfConversion::computePhiCost(MachineBasicBlock *B) const {
|
||||||
}
|
}
|
||||||
MachineInstr *Def1 = MRI->getVRegDef(RO1.getReg());
|
MachineInstr *Def1 = MRI->getVRegDef(RO1.getReg());
|
||||||
MachineInstr *Def3 = MRI->getVRegDef(RO3.getReg());
|
MachineInstr *Def3 = MRI->getVRegDef(RO3.getReg());
|
||||||
if (!TII->isPredicable(Def1) || !TII->isPredicable(Def3))
|
if (!TII->isPredicable(*Def1) || !TII->isPredicable(*Def3))
|
||||||
Cost++;
|
Cost++;
|
||||||
}
|
}
|
||||||
return Cost;
|
return Cost;
|
||||||
|
|
|
@ -421,7 +421,7 @@ void HexagonExpandCondsets::addInstrToLiveness(MachineInstr *MI) {
|
||||||
DEBUG(dbgs() << "adding liveness info for instr\n " << MX << " " << *MI);
|
DEBUG(dbgs() << "adding liveness info for instr\n " << MX << " " << *MI);
|
||||||
|
|
||||||
MX = MX.getRegSlot();
|
MX = MX.getRegSlot();
|
||||||
bool Predicated = HII->isPredicated(MI);
|
bool Predicated = HII->isPredicated(*MI);
|
||||||
MachineBasicBlock *MB = MI->getParent();
|
MachineBasicBlock *MB = MI->getParent();
|
||||||
|
|
||||||
// Strip all implicit uses from predicated instructions. They will be
|
// Strip all implicit uses from predicated instructions. They will be
|
||||||
|
@ -748,7 +748,7 @@ bool HexagonExpandCondsets::splitInBlock(MachineBasicBlock &B) {
|
||||||
|
|
||||||
|
|
||||||
bool HexagonExpandCondsets::isPredicable(MachineInstr *MI) {
|
bool HexagonExpandCondsets::isPredicable(MachineInstr *MI) {
|
||||||
if (HII->isPredicated(MI) || !HII->isPredicable(MI))
|
if (HII->isPredicated(*MI) || !HII->isPredicable(*MI))
|
||||||
return false;
|
return false;
|
||||||
if (MI->hasUnmodeledSideEffects() || MI->mayStore())
|
if (MI->hasUnmodeledSideEffects() || MI->mayStore())
|
||||||
return false;
|
return false;
|
||||||
|
@ -784,8 +784,8 @@ MachineInstr *HexagonExpandCondsets::getReachingDefForPred(RegisterRef RD,
|
||||||
MachineInstr *MI = &*I;
|
MachineInstr *MI = &*I;
|
||||||
// Check if this instruction can be ignored, i.e. if it is predicated
|
// Check if this instruction can be ignored, i.e. if it is predicated
|
||||||
// on the complementary condition.
|
// on the complementary condition.
|
||||||
if (PredValid && HII->isPredicated(MI)) {
|
if (PredValid && HII->isPredicated(*MI)) {
|
||||||
if (MI->readsRegister(PredR) && (Cond != HII->isPredicatedTrue(MI)))
|
if (MI->readsRegister(PredR) && (Cond != HII->isPredicatedTrue(*MI)))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -945,9 +945,9 @@ void HexagonExpandCondsets::renameInRange(RegisterRef RO, RegisterRef RN,
|
||||||
MachineInstr *MI = &*I;
|
MachineInstr *MI = &*I;
|
||||||
// Do not touch instructions that are not predicated, or are predicated
|
// Do not touch instructions that are not predicated, or are predicated
|
||||||
// on the opposite condition.
|
// on the opposite condition.
|
||||||
if (!HII->isPredicated(MI))
|
if (!HII->isPredicated(*MI))
|
||||||
continue;
|
continue;
|
||||||
if (!MI->readsRegister(PredR) || (Cond != HII->isPredicatedTrue(MI)))
|
if (!MI->readsRegister(PredR) || (Cond != HII->isPredicatedTrue(*MI)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (auto &Op : MI->operands()) {
|
for (auto &Op : MI->operands()) {
|
||||||
|
@ -1014,8 +1014,8 @@ bool HexagonExpandCondsets::predicate(MachineInstr *TfrI, bool Cond) {
|
||||||
// By default assume that the instruction executes on the same condition
|
// By default assume that the instruction executes on the same condition
|
||||||
// as TfrI (Exec_Then), and also on the opposite one (Exec_Else).
|
// as TfrI (Exec_Then), and also on the opposite one (Exec_Else).
|
||||||
unsigned Exec = Exec_Then | Exec_Else;
|
unsigned Exec = Exec_Then | Exec_Else;
|
||||||
if (PredValid && HII->isPredicated(MI) && MI->readsRegister(PredR))
|
if (PredValid && HII->isPredicated(*MI) && MI->readsRegister(PredR))
|
||||||
Exec = (Cond == HII->isPredicatedTrue(MI)) ? Exec_Then : Exec_Else;
|
Exec = (Cond == HII->isPredicatedTrue(*MI)) ? Exec_Then : Exec_Else;
|
||||||
|
|
||||||
for (auto &Op : MI->operands()) {
|
for (auto &Op : MI->operands()) {
|
||||||
if (!Op.isReg())
|
if (!Op.isReg())
|
||||||
|
@ -1119,11 +1119,9 @@ void HexagonExpandCondsets::removeImplicitUses(MachineInstr *MI) {
|
||||||
|
|
||||||
|
|
||||||
void HexagonExpandCondsets::removeImplicitUses(MachineBasicBlock &B) {
|
void HexagonExpandCondsets::removeImplicitUses(MachineBasicBlock &B) {
|
||||||
for (MachineBasicBlock::iterator I = B.begin(), E = B.end(); I != E; ++I) {
|
for (MachineInstr &MI : B)
|
||||||
MachineInstr *MI = &*I;
|
|
||||||
if (HII->isPredicated(MI))
|
if (HII->isPredicated(MI))
|
||||||
removeImplicitUses(MI);
|
removeImplicitUses(&MI);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1290,13 +1288,13 @@ bool HexagonExpandCondsets::coalesceSegments(MachineFunction &MF) {
|
||||||
if (S1.isReg()) {
|
if (S1.isReg()) {
|
||||||
RegisterRef RS = S1;
|
RegisterRef RS = S1;
|
||||||
MachineInstr *RDef = getReachingDefForPred(RS, CI, RP.Reg, true);
|
MachineInstr *RDef = getReachingDefForPred(RS, CI, RP.Reg, true);
|
||||||
if (!RDef || !HII->isPredicable(RDef))
|
if (!RDef || !HII->isPredicable(*RDef))
|
||||||
Done = coalesceRegisters(RD, RegisterRef(S1));
|
Done = coalesceRegisters(RD, RegisterRef(S1));
|
||||||
}
|
}
|
||||||
if (!Done && S2.isReg()) {
|
if (!Done && S2.isReg()) {
|
||||||
RegisterRef RS = S2;
|
RegisterRef RS = S2;
|
||||||
MachineInstr *RDef = getReachingDefForPred(RS, CI, RP.Reg, false);
|
MachineInstr *RDef = getReachingDefForPred(RS, CI, RP.Reg, false);
|
||||||
if (!RDef || !HII->isPredicable(RDef))
|
if (!RDef || !HII->isPredicable(*RDef))
|
||||||
Done = coalesceRegisters(RD, RegisterRef(S2));
|
Done = coalesceRegisters(RD, RegisterRef(S2));
|
||||||
}
|
}
|
||||||
Changed |= Done;
|
Changed |= Done;
|
||||||
|
|
|
@ -1772,8 +1772,8 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
|
||||||
|
|
||||||
for (auto &In : B) {
|
for (auto &In : B) {
|
||||||
int LFI, SFI;
|
int LFI, SFI;
|
||||||
bool Load = HII.isLoadFromStackSlot(&In, LFI) && !HII.isPredicated(&In);
|
bool Load = HII.isLoadFromStackSlot(&In, LFI) && !HII.isPredicated(In);
|
||||||
bool Store = HII.isStoreToStackSlot(&In, SFI) && !HII.isPredicated(&In);
|
bool Store = HII.isStoreToStackSlot(&In, SFI) && !HII.isPredicated(In);
|
||||||
if (Load && Store) {
|
if (Load && Store) {
|
||||||
// If it's both a load and a store, then we won't handle it.
|
// If it's both a load and a store, then we won't handle it.
|
||||||
BadFIs.insert(LFI);
|
BadFIs.insert(LFI);
|
||||||
|
|
|
@ -424,7 +424,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
return false;
|
return false;
|
||||||
--I;
|
--I;
|
||||||
}
|
}
|
||||||
if (!isUnpredicatedTerminator(&*I))
|
if (!isUnpredicatedTerminator(*I))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Get the last instruction in the block.
|
// Get the last instruction in the block.
|
||||||
|
@ -432,7 +432,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
MachineInstr *SecondLastInst = nullptr;
|
MachineInstr *SecondLastInst = nullptr;
|
||||||
// Find one more terminator if present.
|
// Find one more terminator if present.
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(&*I)) {
|
if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
|
||||||
if (!SecondLastInst)
|
if (!SecondLastInst)
|
||||||
SecondLastInst = &*I;
|
SecondLastInst = &*I;
|
||||||
else
|
else
|
||||||
|
@ -585,7 +585,7 @@ unsigned HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock *NewTBB, *NewFBB;
|
MachineBasicBlock *NewTBB, *NewFBB;
|
||||||
SmallVector<MachineOperand, 4> Cond;
|
SmallVector<MachineOperand, 4> Cond;
|
||||||
MachineInstr *Term = MBB.getFirstTerminator();
|
MachineInstr *Term = MBB.getFirstTerminator();
|
||||||
if (Term != MBB.end() && isPredicated(Term) &&
|
if (Term != MBB.end() && isPredicated(*Term) &&
|
||||||
!AnalyzeBranch(MBB, NewTBB, NewFBB, Cond, false)) {
|
!AnalyzeBranch(MBB, NewTBB, NewFBB, Cond, false)) {
|
||||||
MachineBasicBlock *NextBB = &*++MBB.getIterator();
|
MachineBasicBlock *NextBB = &*++MBB.getIterator();
|
||||||
if (NewTBB == NextBB) {
|
if (NewTBB == NextBB) {
|
||||||
|
@ -1211,20 +1211,19 @@ void HexagonInstrInfo::insertNoop(MachineBasicBlock &MBB,
|
||||||
// if (!p0.new) R1 = add(R2, R3)
|
// if (!p0.new) R1 = add(R2, R3)
|
||||||
// Note: New-value stores are not included here as in the current
|
// Note: New-value stores are not included here as in the current
|
||||||
// implementation, we don't need to check their predicate sense.
|
// implementation, we don't need to check their predicate sense.
|
||||||
bool HexagonInstrInfo::isPredicated(const MachineInstr *MI) const {
|
bool HexagonInstrInfo::isPredicated(const MachineInstr &MI) const {
|
||||||
const uint64_t F = MI->getDesc().TSFlags;
|
const uint64_t F = MI.getDesc().TSFlags;
|
||||||
return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;
|
return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HexagonInstrInfo::PredicateInstruction(
|
||||||
bool HexagonInstrInfo::PredicateInstruction(MachineInstr *MI,
|
MachineInstr &MI, ArrayRef<MachineOperand> Cond) const {
|
||||||
ArrayRef<MachineOperand> Cond) const {
|
|
||||||
if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||
|
if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||
|
||||||
isEndLoopN(Cond[0].getImm())) {
|
isEndLoopN(Cond[0].getImm())) {
|
||||||
DEBUG(dbgs() << "\nCannot predicate:"; MI->dump(););
|
DEBUG(dbgs() << "\nCannot predicate:"; MI.dump(););
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int Opc = MI->getOpcode();
|
int Opc = MI.getOpcode();
|
||||||
assert (isPredicable(MI) && "Expected predicable instruction");
|
assert (isPredicable(MI) && "Expected predicable instruction");
|
||||||
bool invertJump = predOpcodeHasNot(Cond);
|
bool invertJump = predOpcodeHasNot(Cond);
|
||||||
|
|
||||||
|
@ -1233,13 +1232,13 @@ bool HexagonInstrInfo::PredicateInstruction(MachineInstr *MI,
|
||||||
// plicated manipulations with the operands (handling tied operands,
|
// plicated manipulations with the operands (handling tied operands,
|
||||||
// etc.), build a new temporary instruction, then overwrite MI with it.
|
// etc.), build a new temporary instruction, then overwrite MI with it.
|
||||||
|
|
||||||
MachineBasicBlock &B = *MI->getParent();
|
MachineBasicBlock &B = *MI.getParent();
|
||||||
DebugLoc DL = MI->getDebugLoc();
|
DebugLoc DL = MI.getDebugLoc();
|
||||||
unsigned PredOpc = getCondOpcode(Opc, invertJump);
|
unsigned PredOpc = getCondOpcode(Opc, invertJump);
|
||||||
MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));
|
MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));
|
||||||
unsigned NOp = 0, NumOps = MI->getNumOperands();
|
unsigned NOp = 0, NumOps = MI.getNumOperands();
|
||||||
while (NOp < NumOps) {
|
while (NOp < NumOps) {
|
||||||
MachineOperand &Op = MI->getOperand(NOp);
|
MachineOperand &Op = MI.getOperand(NOp);
|
||||||
if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
|
if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
|
||||||
break;
|
break;
|
||||||
T.addOperand(Op);
|
T.addOperand(Op);
|
||||||
|
@ -1252,13 +1251,13 @@ bool HexagonInstrInfo::PredicateInstruction(MachineInstr *MI,
|
||||||
assert(GotPredReg);
|
assert(GotPredReg);
|
||||||
T.addReg(PredReg, PredRegFlags);
|
T.addReg(PredReg, PredRegFlags);
|
||||||
while (NOp < NumOps)
|
while (NOp < NumOps)
|
||||||
T.addOperand(MI->getOperand(NOp++));
|
T.addOperand(MI.getOperand(NOp++));
|
||||||
|
|
||||||
MI->setDesc(get(PredOpc));
|
MI.setDesc(get(PredOpc));
|
||||||
while (unsigned n = MI->getNumOperands())
|
while (unsigned n = MI.getNumOperands())
|
||||||
MI->RemoveOperand(n-1);
|
MI.RemoveOperand(n-1);
|
||||||
for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)
|
for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)
|
||||||
MI->addOperand(T->getOperand(i));
|
MI.addOperand(T->getOperand(i));
|
||||||
|
|
||||||
MachineBasicBlock::instr_iterator TI = T->getIterator();
|
MachineBasicBlock::instr_iterator TI = T->getIterator();
|
||||||
B.erase(TI);
|
B.erase(TI);
|
||||||
|
@ -1275,12 +1274,11 @@ bool HexagonInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HexagonInstrInfo::DefinesPredicate(
|
||||||
bool HexagonInstrInfo::DefinesPredicate(MachineInstr *MI,
|
MachineInstr &MI, std::vector<MachineOperand> &Pred) const {
|
||||||
std::vector<MachineOperand> &Pred) const {
|
|
||||||
auto &HRI = getRegisterInfo();
|
auto &HRI = getRegisterInfo();
|
||||||
for (unsigned oper = 0; oper < MI->getNumOperands(); ++oper) {
|
for (unsigned oper = 0; oper < MI.getNumOperands(); ++oper) {
|
||||||
MachineOperand MO = MI->getOperand(oper);
|
MachineOperand MO = MI.getOperand(oper);
|
||||||
if (MO.isReg() && MO.isDef()) {
|
if (MO.isReg() && MO.isDef()) {
|
||||||
const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());
|
const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());
|
||||||
if (RC == &Hexagon::PredRegsRegClass) {
|
if (RC == &Hexagon::PredRegsRegClass) {
|
||||||
|
@ -1292,14 +1290,14 @@ bool HexagonInstrInfo::DefinesPredicate(MachineInstr *MI,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const {
|
bool HexagonInstrInfo::isPredicable(MachineInstr &MI) const {
|
||||||
bool isPred = MI->getDesc().isPredicable();
|
bool isPred = MI.getDesc().isPredicable();
|
||||||
|
|
||||||
if (!isPred)
|
if (!isPred)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const int Opc = MI->getOpcode();
|
const int Opc = MI.getOpcode();
|
||||||
int NumOperands = MI->getNumOperands();
|
int NumOperands = MI.getNumOperands();
|
||||||
|
|
||||||
// Keep a flag for upto 4 operands in the instructions, to indicate if
|
// Keep a flag for upto 4 operands in the instructions, to indicate if
|
||||||
// that operand has been constant extended.
|
// that operand has been constant extended.
|
||||||
|
@ -1308,64 +1306,64 @@ bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const {
|
||||||
NumOperands = 4;
|
NumOperands = 4;
|
||||||
|
|
||||||
for (int i = 0; i < NumOperands; i++)
|
for (int i = 0; i < NumOperands; i++)
|
||||||
OpCExtended[i] = (isOperandExtended(MI, i) && isConstExtended(MI));
|
OpCExtended[i] = (isOperandExtended(&MI, i) && isConstExtended(&MI));
|
||||||
|
|
||||||
switch(Opc) {
|
switch(Opc) {
|
||||||
case Hexagon::A2_tfrsi:
|
case Hexagon::A2_tfrsi:
|
||||||
return (isOperandExtended(MI, 1) && isConstExtended(MI)) ||
|
return (isOperandExtended(&MI, 1) && isConstExtended(&MI)) ||
|
||||||
isInt<12>(MI->getOperand(1).getImm());
|
isInt<12>(MI.getOperand(1).getImm());
|
||||||
|
|
||||||
case Hexagon::S2_storerd_io:
|
case Hexagon::S2_storerd_io:
|
||||||
return isShiftedUInt<6,3>(MI->getOperand(1).getImm());
|
return isShiftedUInt<6,3>(MI.getOperand(1).getImm());
|
||||||
|
|
||||||
case Hexagon::S2_storeri_io:
|
case Hexagon::S2_storeri_io:
|
||||||
case Hexagon::S2_storerinew_io:
|
case Hexagon::S2_storerinew_io:
|
||||||
return isShiftedUInt<6,2>(MI->getOperand(1).getImm());
|
return isShiftedUInt<6,2>(MI.getOperand(1).getImm());
|
||||||
|
|
||||||
case Hexagon::S2_storerh_io:
|
case Hexagon::S2_storerh_io:
|
||||||
case Hexagon::S2_storerhnew_io:
|
case Hexagon::S2_storerhnew_io:
|
||||||
return isShiftedUInt<6,1>(MI->getOperand(1).getImm());
|
return isShiftedUInt<6,1>(MI.getOperand(1).getImm());
|
||||||
|
|
||||||
case Hexagon::S2_storerb_io:
|
case Hexagon::S2_storerb_io:
|
||||||
case Hexagon::S2_storerbnew_io:
|
case Hexagon::S2_storerbnew_io:
|
||||||
return isUInt<6>(MI->getOperand(1).getImm());
|
return isUInt<6>(MI.getOperand(1).getImm());
|
||||||
|
|
||||||
case Hexagon::L2_loadrd_io:
|
case Hexagon::L2_loadrd_io:
|
||||||
return isShiftedUInt<6,3>(MI->getOperand(2).getImm());
|
return isShiftedUInt<6,3>(MI.getOperand(2).getImm());
|
||||||
|
|
||||||
case Hexagon::L2_loadri_io:
|
case Hexagon::L2_loadri_io:
|
||||||
return isShiftedUInt<6,2>(MI->getOperand(2).getImm());
|
return isShiftedUInt<6,2>(MI.getOperand(2).getImm());
|
||||||
|
|
||||||
case Hexagon::L2_loadrh_io:
|
case Hexagon::L2_loadrh_io:
|
||||||
case Hexagon::L2_loadruh_io:
|
case Hexagon::L2_loadruh_io:
|
||||||
return isShiftedUInt<6,1>(MI->getOperand(2).getImm());
|
return isShiftedUInt<6,1>(MI.getOperand(2).getImm());
|
||||||
|
|
||||||
case Hexagon::L2_loadrb_io:
|
case Hexagon::L2_loadrb_io:
|
||||||
case Hexagon::L2_loadrub_io:
|
case Hexagon::L2_loadrub_io:
|
||||||
return isUInt<6>(MI->getOperand(2).getImm());
|
return isUInt<6>(MI.getOperand(2).getImm());
|
||||||
|
|
||||||
case Hexagon::L2_loadrd_pi:
|
case Hexagon::L2_loadrd_pi:
|
||||||
return isShiftedInt<4,3>(MI->getOperand(3).getImm());
|
return isShiftedInt<4,3>(MI.getOperand(3).getImm());
|
||||||
|
|
||||||
case Hexagon::L2_loadri_pi:
|
case Hexagon::L2_loadri_pi:
|
||||||
return isShiftedInt<4,2>(MI->getOperand(3).getImm());
|
return isShiftedInt<4,2>(MI.getOperand(3).getImm());
|
||||||
|
|
||||||
case Hexagon::L2_loadrh_pi:
|
case Hexagon::L2_loadrh_pi:
|
||||||
case Hexagon::L2_loadruh_pi:
|
case Hexagon::L2_loadruh_pi:
|
||||||
return isShiftedInt<4,1>(MI->getOperand(3).getImm());
|
return isShiftedInt<4,1>(MI.getOperand(3).getImm());
|
||||||
|
|
||||||
case Hexagon::L2_loadrb_pi:
|
case Hexagon::L2_loadrb_pi:
|
||||||
case Hexagon::L2_loadrub_pi:
|
case Hexagon::L2_loadrub_pi:
|
||||||
return isInt<4>(MI->getOperand(3).getImm());
|
return isInt<4>(MI.getOperand(3).getImm());
|
||||||
|
|
||||||
case Hexagon::S4_storeirb_io:
|
case Hexagon::S4_storeirb_io:
|
||||||
case Hexagon::S4_storeirh_io:
|
case Hexagon::S4_storeirh_io:
|
||||||
case Hexagon::S4_storeiri_io:
|
case Hexagon::S4_storeiri_io:
|
||||||
return (OpCExtended[1] || isUInt<6>(MI->getOperand(1).getImm())) &&
|
return (OpCExtended[1] || isUInt<6>(MI.getOperand(1).getImm())) &&
|
||||||
(OpCExtended[2] || isInt<6>(MI->getOperand(2).getImm()));
|
(OpCExtended[2] || isInt<6>(MI.getOperand(2).getImm()));
|
||||||
|
|
||||||
case Hexagon::A2_addi:
|
case Hexagon::A2_addi:
|
||||||
return isInt<8>(MI->getOperand(2).getImm());
|
return isInt<8>(MI.getOperand(2).getImm());
|
||||||
|
|
||||||
case Hexagon::A2_aslh:
|
case Hexagon::A2_aslh:
|
||||||
case Hexagon::A2_asrh:
|
case Hexagon::A2_asrh:
|
||||||
|
@ -1662,13 +1660,13 @@ bool HexagonInstrInfo::isCompoundBranchInstr(const MachineInstr *MI) const {
|
||||||
|
|
||||||
|
|
||||||
bool HexagonInstrInfo::isCondInst(const MachineInstr *MI) const {
|
bool HexagonInstrInfo::isCondInst(const MachineInstr *MI) const {
|
||||||
return (MI->isBranch() && isPredicated(MI)) ||
|
return (MI->isBranch() && isPredicated(*MI)) ||
|
||||||
isConditionalTransfer(MI) ||
|
isConditionalTransfer(MI) ||
|
||||||
isConditionalALU32(MI) ||
|
isConditionalALU32(MI) ||
|
||||||
isConditionalLoad(MI) ||
|
isConditionalLoad(MI) ||
|
||||||
// Predicated stores which don't have a .new on any operands.
|
// Predicated stores which don't have a .new on any operands.
|
||||||
(MI->mayStore() && isPredicated(MI) && !isNewValueStore(MI) &&
|
(MI->mayStore() && isPredicated(*MI) && !isNewValueStore(MI) &&
|
||||||
!isPredicatedNew(MI));
|
!isPredicatedNew(*MI));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1733,7 +1731,7 @@ bool HexagonInstrInfo::isConditionalALU32(const MachineInstr* MI) const {
|
||||||
// FIXME - Function name and it's functionality don't match.
|
// FIXME - Function name and it's functionality don't match.
|
||||||
// It should be renamed to hasPredNewOpcode()
|
// It should be renamed to hasPredNewOpcode()
|
||||||
bool HexagonInstrInfo::isConditionalLoad(const MachineInstr* MI) const {
|
bool HexagonInstrInfo::isConditionalLoad(const MachineInstr* MI) const {
|
||||||
if (!MI->getDesc().mayLoad() || !isPredicated(MI))
|
if (!MI->getDesc().mayLoad() || !isPredicated(*MI))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int PNewOpcode = Hexagon::getPredNewOpcode(MI->getOpcode());
|
int PNewOpcode = Hexagon::getPredNewOpcode(MI->getOpcode());
|
||||||
|
@ -1939,8 +1937,7 @@ bool HexagonInstrInfo::isDotCurInst(const MachineInstr* MI) const {
|
||||||
// Returns true, if any one of the operands is a dot new
|
// Returns true, if any one of the operands is a dot new
|
||||||
// insn, whether it is predicated dot new or register dot new.
|
// insn, whether it is predicated dot new or register dot new.
|
||||||
bool HexagonInstrInfo::isDotNewInst(const MachineInstr* MI) const {
|
bool HexagonInstrInfo::isDotNewInst(const MachineInstr* MI) const {
|
||||||
if (isNewValueInst(MI) ||
|
if (isNewValueInst(MI) || (isPredicated(*MI) && isPredicatedNew(*MI)))
|
||||||
(isPredicated(MI) && isPredicatedNew(MI)))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -2305,8 +2302,8 @@ bool HexagonInstrInfo::isPostIncrement(const MachineInstr* MI) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool HexagonInstrInfo::isPredicatedNew(const MachineInstr *MI) const {
|
bool HexagonInstrInfo::isPredicatedNew(const MachineInstr &MI) const {
|
||||||
const uint64_t F = MI->getDesc().TSFlags;
|
const uint64_t F = MI.getDesc().TSFlags;
|
||||||
assert(isPredicated(MI));
|
assert(isPredicated(MI));
|
||||||
return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;
|
return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;
|
||||||
}
|
}
|
||||||
|
@ -2319,8 +2316,8 @@ bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool HexagonInstrInfo::isPredicatedTrue(const MachineInstr *MI) const {
|
bool HexagonInstrInfo::isPredicatedTrue(const MachineInstr &MI) const {
|
||||||
const uint64_t F = MI->getDesc().TSFlags;
|
const uint64_t F = MI.getDesc().TSFlags;
|
||||||
return !((F >> HexagonII::PredicatedFalsePos) &
|
return !((F >> HexagonII::PredicatedFalsePos) &
|
||||||
HexagonII::PredicatedFalseMask);
|
HexagonII::PredicatedFalseMask);
|
||||||
}
|
}
|
||||||
|
@ -3084,7 +3081,7 @@ bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr *MI,
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (isPredicated(MI)) {
|
if (isPredicated(*MI)) {
|
||||||
BasePos++;
|
BasePos++;
|
||||||
OffsetPos++;
|
OffsetPos++;
|
||||||
}
|
}
|
||||||
|
@ -3138,7 +3135,7 @@ SmallVector<MachineInstr*, 2> HexagonInstrInfo::getBranchingInstrs(
|
||||||
return Jumpers;
|
return Jumpers;
|
||||||
--I;
|
--I;
|
||||||
}
|
}
|
||||||
if (!isUnpredicatedTerminator(&*I))
|
if (!isUnpredicatedTerminator(*I))
|
||||||
return Jumpers;
|
return Jumpers;
|
||||||
|
|
||||||
// Get the last instruction in the block.
|
// Get the last instruction in the block.
|
||||||
|
@ -3147,7 +3144,7 @@ SmallVector<MachineInstr*, 2> HexagonInstrInfo::getBranchingInstrs(
|
||||||
MachineInstr *SecondLastInst = nullptr;
|
MachineInstr *SecondLastInst = nullptr;
|
||||||
// Find one more terminator if present.
|
// Find one more terminator if present.
|
||||||
do {
|
do {
|
||||||
if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(&*I)) {
|
if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
|
||||||
if (!SecondLastInst) {
|
if (!SecondLastInst) {
|
||||||
SecondLastInst = &*I;
|
SecondLastInst = &*I;
|
||||||
Jumpers.push_back(SecondLastInst);
|
Jumpers.push_back(SecondLastInst);
|
||||||
|
@ -4106,7 +4103,7 @@ bool HexagonInstrInfo::invertAndChangeJumpTarget(
|
||||||
--TargetPos;
|
--TargetPos;
|
||||||
assert((TargetPos >= 0) && MI->getOperand(TargetPos).isMBB());
|
assert((TargetPos >= 0) && MI->getOperand(TargetPos).isMBB());
|
||||||
MI->getOperand(TargetPos).setMBB(NewTarget);
|
MI->getOperand(TargetPos).setMBB(NewTarget);
|
||||||
if (EnableBranchPrediction && isPredicatedNew(MI)) {
|
if (EnableBranchPrediction && isPredicatedNew(*MI)) {
|
||||||
NewOpcode = reversePrediction(NewOpcode);
|
NewOpcode = reversePrediction(NewOpcode);
|
||||||
}
|
}
|
||||||
MI->setDesc(get(NewOpcode));
|
MI->setDesc(get(NewOpcode));
|
||||||
|
|
|
@ -183,11 +183,11 @@ public:
|
||||||
MachineBasicBlock::iterator MI) const override;
|
MachineBasicBlock::iterator MI) const override;
|
||||||
|
|
||||||
/// Returns true if the instruction is already predicated.
|
/// Returns true if the instruction is already predicated.
|
||||||
bool isPredicated(const MachineInstr *MI) const override;
|
bool isPredicated(const MachineInstr &MI) const override;
|
||||||
|
|
||||||
/// Convert the instruction into a predicated instruction.
|
/// Convert the instruction into a predicated instruction.
|
||||||
/// It returns true if the operation was successful.
|
/// It returns true if the operation was successful.
|
||||||
bool PredicateInstruction(MachineInstr *MI,
|
bool PredicateInstruction(MachineInstr &MI,
|
||||||
ArrayRef<MachineOperand> Cond) const override;
|
ArrayRef<MachineOperand> Cond) const override;
|
||||||
|
|
||||||
/// Returns true if the first specified predicate
|
/// Returns true if the first specified predicate
|
||||||
|
@ -198,13 +198,13 @@ public:
|
||||||
/// If the specified instruction defines any predicate
|
/// If the specified instruction defines any predicate
|
||||||
/// or condition code register(s) used for predication, returns true as well
|
/// or condition code register(s) used for predication, returns true as well
|
||||||
/// as the definition predicate(s) by reference.
|
/// as the definition predicate(s) by reference.
|
||||||
bool DefinesPredicate(MachineInstr *MI,
|
bool DefinesPredicate(MachineInstr &MI,
|
||||||
std::vector<MachineOperand> &Pred) const override;
|
std::vector<MachineOperand> &Pred) const override;
|
||||||
|
|
||||||
/// Return true if the specified instruction can be predicated.
|
/// Return true if the specified instruction can be predicated.
|
||||||
/// By default, this returns true for every instruction with a
|
/// By default, this returns true for every instruction with a
|
||||||
/// PredicateOperand.
|
/// PredicateOperand.
|
||||||
bool isPredicable(MachineInstr *MI) const override;
|
bool isPredicable(MachineInstr &MI) const override;
|
||||||
|
|
||||||
/// Test if the given instruction should be considered a scheduling boundary.
|
/// Test if the given instruction should be considered a scheduling boundary.
|
||||||
/// This primarily includes labels and terminators.
|
/// This primarily includes labels and terminators.
|
||||||
|
@ -301,9 +301,9 @@ public:
|
||||||
bool isNewValueStore(unsigned Opcode) const;
|
bool isNewValueStore(unsigned Opcode) const;
|
||||||
bool isOperandExtended(const MachineInstr *MI, unsigned OperandNum) const;
|
bool isOperandExtended(const MachineInstr *MI, unsigned OperandNum) const;
|
||||||
bool isPostIncrement(const MachineInstr* MI) const;
|
bool isPostIncrement(const MachineInstr* MI) const;
|
||||||
bool isPredicatedNew(const MachineInstr *MI) const;
|
bool isPredicatedNew(const MachineInstr &MI) const;
|
||||||
bool isPredicatedNew(unsigned Opcode) const;
|
bool isPredicatedNew(unsigned Opcode) const;
|
||||||
bool isPredicatedTrue(const MachineInstr *MI) const;
|
bool isPredicatedTrue(const MachineInstr &MI) const;
|
||||||
bool isPredicatedTrue(unsigned Opcode) const;
|
bool isPredicatedTrue(unsigned Opcode) const;
|
||||||
bool isPredicated(unsigned Opcode) const;
|
bool isPredicated(unsigned Opcode) const;
|
||||||
bool isPredicateLate(unsigned Opcode) const;
|
bool isPredicateLate(unsigned Opcode) const;
|
||||||
|
|
|
@ -116,7 +116,7 @@ static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
|
||||||
MachineFunction &MF) {
|
MachineFunction &MF) {
|
||||||
|
|
||||||
// Predicated instruction can not be feeder to NVJ.
|
// Predicated instruction can not be feeder to NVJ.
|
||||||
if (QII->isPredicated(II))
|
if (QII->isPredicated(*II))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Bail out if feederReg is a paired register (double regs in
|
// Bail out if feederReg is a paired register (double regs in
|
||||||
|
|
|
@ -243,7 +243,7 @@ bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
|
||||||
// Look for Predicated instructions.
|
// Look for Predicated instructions.
|
||||||
if (!DisablePNotP) {
|
if (!DisablePNotP) {
|
||||||
bool Done = false;
|
bool Done = false;
|
||||||
if (QII->isPredicated(MI)) {
|
if (QII->isPredicated(*MI)) {
|
||||||
MachineOperand &Op0 = MI->getOperand(0);
|
MachineOperand &Op0 = MI->getOperand(0);
|
||||||
unsigned Reg0 = Op0.getReg();
|
unsigned Reg0 = Op0.getReg();
|
||||||
const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0);
|
const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0);
|
||||||
|
|
|
@ -436,7 +436,7 @@ enum PredicateKind {
|
||||||
|
|
||||||
/// Returns true if an instruction is predicated on p0 and false if it's
|
/// Returns true if an instruction is predicated on p0 and false if it's
|
||||||
/// predicated on !p0.
|
/// predicated on !p0.
|
||||||
static PredicateKind getPredicateSense(const MachineInstr *MI,
|
static PredicateKind getPredicateSense(const MachineInstr &MI,
|
||||||
const HexagonInstrInfo *HII) {
|
const HexagonInstrInfo *HII) {
|
||||||
if (!HII->isPredicated(MI))
|
if (!HII->isPredicated(MI))
|
||||||
return PK_Unknown;
|
return PK_Unknown;
|
||||||
|
@ -570,8 +570,8 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||||
|
|
||||||
// If the source that feeds the store is predicated, new value store must
|
// If the source that feeds the store is predicated, new value store must
|
||||||
// also be predicated.
|
// also be predicated.
|
||||||
if (HII->isPredicated(PacketMI)) {
|
if (HII->isPredicated(*PacketMI)) {
|
||||||
if (!HII->isPredicated(MI))
|
if (!HII->isPredicated(*MI))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check to make sure that they both will have their predicates
|
// Check to make sure that they both will have their predicates
|
||||||
|
@ -613,8 +613,8 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||||
// 3) Both new-value register producer and user should have same predicate
|
// 3) Both new-value register producer and user should have same predicate
|
||||||
// sense, i.e, either both should be negated or both should be non-negated.
|
// sense, i.e, either both should be negated or both should be non-negated.
|
||||||
if (predRegNumDst != predRegNumSrc ||
|
if (predRegNumDst != predRegNumSrc ||
|
||||||
HII->isDotNewInst(PacketMI) != HII->isDotNewInst(MI) ||
|
HII->isDotNewInst(PacketMI) != HII->isDotNewInst(MI) ||
|
||||||
getPredicateSense(MI, HII) != getPredicateSense(PacketMI, HII))
|
getPredicateSense(*MI, HII) != getPredicateSense(*PacketMI, HII))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,7 +793,7 @@ bool HexagonPacketizerList::restrictingDepExistInPacket(MachineInstr* MI,
|
||||||
|
|
||||||
for (auto I : CurrentPacketMIs) {
|
for (auto I : CurrentPacketMIs) {
|
||||||
// We only care for dependencies to predicated instructions
|
// We only care for dependencies to predicated instructions
|
||||||
if (!HII->isPredicated(I))
|
if (!HII->isPredicated(*I))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Scheduling Unit for current insn in the packet
|
// Scheduling Unit for current insn in the packet
|
||||||
|
@ -817,13 +817,13 @@ bool HexagonPacketizerList::restrictingDepExistInPacket(MachineInstr* MI,
|
||||||
|
|
||||||
|
|
||||||
/// Gets the predicate register of a predicated instruction.
|
/// Gets the predicate register of a predicated instruction.
|
||||||
static unsigned getPredicatedRegister(MachineInstr *MI,
|
static unsigned getPredicatedRegister(MachineInstr &MI,
|
||||||
const HexagonInstrInfo *QII) {
|
const HexagonInstrInfo *QII) {
|
||||||
/// We use the following rule: The first predicate register that is a use is
|
/// We use the following rule: The first predicate register that is a use is
|
||||||
/// the predicate register of a predicated instruction.
|
/// the predicate register of a predicated instruction.
|
||||||
assert(QII->isPredicated(MI) && "Must be predicated instruction");
|
assert(QII->isPredicated(MI) && "Must be predicated instruction");
|
||||||
|
|
||||||
for (auto &Op : MI->operands()) {
|
for (auto &Op : MI.operands()) {
|
||||||
if (Op.isReg() && Op.getReg() && Op.isUse() &&
|
if (Op.isReg() && Op.getReg() && Op.isUse() &&
|
||||||
Hexagon::PredRegsRegClass.contains(Op.getReg()))
|
Hexagon::PredRegsRegClass.contains(Op.getReg()))
|
||||||
return Op.getReg();
|
return Op.getReg();
|
||||||
|
@ -835,8 +835,8 @@ static unsigned getPredicatedRegister(MachineInstr *MI,
|
||||||
|
|
||||||
// Given two predicated instructions, this function detects whether
|
// Given two predicated instructions, this function detects whether
|
||||||
// the predicates are complements.
|
// the predicates are complements.
|
||||||
bool HexagonPacketizerList::arePredicatesComplements(MachineInstr *MI1,
|
bool HexagonPacketizerList::arePredicatesComplements(MachineInstr &MI1,
|
||||||
MachineInstr *MI2) {
|
MachineInstr &MI2) {
|
||||||
// If we don't know the predicate sense of the instructions bail out early, we
|
// If we don't know the predicate sense of the instructions bail out early, we
|
||||||
// need it later.
|
// need it later.
|
||||||
if (getPredicateSense(MI1, HII) == PK_Unknown ||
|
if (getPredicateSense(MI1, HII) == PK_Unknown ||
|
||||||
|
@ -844,7 +844,7 @@ bool HexagonPacketizerList::arePredicatesComplements(MachineInstr *MI1,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Scheduling unit for candidate.
|
// Scheduling unit for candidate.
|
||||||
SUnit *SU = MIToSUnit[MI1];
|
SUnit *SU = MIToSUnit[&MI1];
|
||||||
|
|
||||||
// One corner case deals with the following scenario:
|
// One corner case deals with the following scenario:
|
||||||
// Trying to add
|
// Trying to add
|
||||||
|
@ -898,7 +898,7 @@ bool HexagonPacketizerList::arePredicatesComplements(MachineInstr *MI1,
|
||||||
Hexagon::PredRegsRegClass.contains(PReg1) &&
|
Hexagon::PredRegsRegClass.contains(PReg1) &&
|
||||||
Hexagon::PredRegsRegClass.contains(PReg2) &&
|
Hexagon::PredRegsRegClass.contains(PReg2) &&
|
||||||
getPredicateSense(MI1, HII) != getPredicateSense(MI2, HII) &&
|
getPredicateSense(MI1, HII) != getPredicateSense(MI2, HII) &&
|
||||||
HII->isDotNewInst(MI1) == HII->isDotNewInst(MI2);
|
HII->isDotNewInst(&MI1) == HII->isDotNewInst(&MI2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize packetizer flags.
|
// Initialize packetizer flags.
|
||||||
|
@ -1045,7 +1045,7 @@ bool HexagonPacketizerList::hasDeadDependence(const MachineInstr *I,
|
||||||
// defining the same (dead) register.
|
// defining the same (dead) register.
|
||||||
if (I->isCall() || J->isCall())
|
if (I->isCall() || J->isCall())
|
||||||
return false;
|
return false;
|
||||||
if (HII->isPredicated(I) || HII->isPredicated(J))
|
if (HII->isPredicated(*I) || HII->isPredicated(*J))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
BitVector DeadDefs(Hexagon::NUM_TARGET_REGS);
|
BitVector DeadDefs(Hexagon::NUM_TARGET_REGS);
|
||||||
|
@ -1085,7 +1085,7 @@ bool HexagonPacketizerList::hasControlDependence(const MachineInstr *I,
|
||||||
auto isBadForLoopN = [this] (const MachineInstr *MI) -> bool {
|
auto isBadForLoopN = [this] (const MachineInstr *MI) -> bool {
|
||||||
if (MI->isCall() || HII->isDeallocRet(MI) || HII->isNewValueJump(MI))
|
if (MI->isCall() || HII->isDeallocRet(MI) || HII->isNewValueJump(MI))
|
||||||
return true;
|
return true;
|
||||||
if (HII->isPredicated(MI) && HII->isPredicatedNew(MI) && HII->isJumpR(MI))
|
if (HII->isPredicated(*MI) && HII->isPredicatedNew(*MI) && HII->isJumpR(MI))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -1275,8 +1275,8 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||||
|
|
||||||
// For predicated instructions, if the predicates are complements then
|
// For predicated instructions, if the predicates are complements then
|
||||||
// there can be no dependence.
|
// there can be no dependence.
|
||||||
if (HII->isPredicated(I) && HII->isPredicated(J) &&
|
if (HII->isPredicated(*I) && HII->isPredicated(*J) &&
|
||||||
arePredicatesComplements(I, J)) {
|
arePredicatesComplements(*I, *J)) {
|
||||||
// Not always safe to do this translation.
|
// Not always safe to do this translation.
|
||||||
// DAG Builder attempts to reduce dependence edges using transitive
|
// DAG Builder attempts to reduce dependence edges using transitive
|
||||||
// nature of dependencies. Here is an example:
|
// nature of dependencies. Here is an example:
|
||||||
|
|
|
@ -93,7 +93,7 @@ protected:
|
||||||
bool canPromoteToNewValueStore(const MachineInstr* MI,
|
bool canPromoteToNewValueStore(const MachineInstr* MI,
|
||||||
const MachineInstr* PacketMI, unsigned DepReg);
|
const MachineInstr* PacketMI, unsigned DepReg);
|
||||||
bool demoteToDotOld(MachineInstr* MI);
|
bool demoteToDotOld(MachineInstr* MI);
|
||||||
bool arePredicatesComplements(MachineInstr* MI1, MachineInstr* MI2);
|
bool arePredicatesComplements(MachineInstr &MI1, MachineInstr &MI2);
|
||||||
bool restrictingDepExistInPacket(MachineInstr*, unsigned);
|
bool restrictingDepExistInPacket(MachineInstr*, unsigned);
|
||||||
bool isNewifiable(const MachineInstr *MI);
|
bool isNewifiable(const MachineInstr *MI);
|
||||||
bool isCurifiable(MachineInstr* MI);
|
bool isCurifiable(MachineInstr* MI);
|
||||||
|
|
|
@ -674,7 +674,7 @@ bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB) const {
|
||||||
// unchanged across this def.
|
// unchanged across this def.
|
||||||
bool TargetOperandInfo::isPreserving(const MachineInstr &In, unsigned OpNum)
|
bool TargetOperandInfo::isPreserving(const MachineInstr &In, unsigned OpNum)
|
||||||
const {
|
const {
|
||||||
return TII.isPredicated(&In);
|
return TII.isPredicated(In);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the definition of RR produces an unspecified value.
|
// Check if the definition of RR produces an unspecified value.
|
||||||
|
@ -1179,7 +1179,7 @@ void DataFlowGraph::buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In) {
|
||||||
ImpUses.insert({R, 0});
|
ImpUses.insert({R, 0});
|
||||||
|
|
||||||
bool IsCall = In.isCall(), IsReturn = In.isReturn();
|
bool IsCall = In.isCall(), IsReturn = In.isReturn();
|
||||||
bool IsPredicated = TII.isPredicated(&In);
|
bool IsPredicated = TII.isPredicated(In);
|
||||||
unsigned NumOps = In.getNumOperands();
|
unsigned NumOps = In.getNumOperands();
|
||||||
|
|
||||||
// Avoid duplicate implicit defs. This will not detect cases of implicit
|
// Avoid duplicate implicit defs. This will not detect cases of implicit
|
||||||
|
|
|
@ -156,13 +156,14 @@ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MSP430InstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
|
bool MSP430InstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const {
|
||||||
if (!MI->isTerminator()) return false;
|
if (!MI.isTerminator())
|
||||||
|
return false;
|
||||||
|
|
||||||
// Conditional branch is a special case.
|
// Conditional branch is a special case.
|
||||||
if (MI->isBranch() && !MI->isBarrier())
|
if (MI.isBranch() && !MI.isBarrier())
|
||||||
return true;
|
return true;
|
||||||
if (!MI->isPredicable())
|
if (!MI.isPredicable())
|
||||||
return true;
|
return true;
|
||||||
return !isPredicated(MI);
|
return !isPredicated(MI);
|
||||||
}
|
}
|
||||||
|
@ -182,7 +183,7 @@ bool MSP430InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
|
|
||||||
// Working from the bottom, when we see a non-terminator
|
// Working from the bottom, when we see a non-terminator
|
||||||
// instruction, we're done.
|
// instruction, we're done.
|
||||||
if (!isUnpredicatedTerminator(I))
|
if (!isUnpredicatedTerminator(*I))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// A terminator that isn't a branch can't easily be handled
|
// A terminator that isn't a branch can't easily be handled
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
// Branch folding goodness
|
// Branch folding goodness
|
||||||
bool
|
bool
|
||||||
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
|
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
|
||||||
bool isUnpredicatedTerminator(const MachineInstr *MI) const override;
|
bool isUnpredicatedTerminator(const MachineInstr &MI) const override;
|
||||||
bool AnalyzeBranch(MachineBasicBlock &MBB,
|
bool AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock *&TBB, MachineBasicBlock *&FBB,
|
MachineBasicBlock *&TBB, MachineBasicBlock *&FBB,
|
||||||
SmallVectorImpl<MachineOperand> &Cond,
|
SmallVectorImpl<MachineOperand> &Cond,
|
||||||
|
|
|
@ -184,7 +184,7 @@ MipsInstrInfo::BranchType MipsInstrInfo::AnalyzeBranch(
|
||||||
while (I != REnd && I->isDebugValue())
|
while (I != REnd && I->isDebugValue())
|
||||||
++I;
|
++I;
|
||||||
|
|
||||||
if (I == REnd || !isUnpredicatedTerminator(&*I)) {
|
if (I == REnd || !isUnpredicatedTerminator(*I)) {
|
||||||
// This block ends with no branches (it just falls through to its succ).
|
// This block ends with no branches (it just falls through to its succ).
|
||||||
// Leave TBB/FBB null.
|
// Leave TBB/FBB null.
|
||||||
TBB = FBB = nullptr;
|
TBB = FBB = nullptr;
|
||||||
|
@ -208,7 +208,7 @@ MipsInstrInfo::BranchType MipsInstrInfo::AnalyzeBranch(
|
||||||
SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode());
|
SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode());
|
||||||
|
|
||||||
// Not an analyzable branch (must be an indirect jump).
|
// Not an analyzable branch (must be an indirect jump).
|
||||||
if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc)
|
if (isUnpredicatedTerminator(*SecondLastInst) && !SecondLastOpc)
|
||||||
return BT_None;
|
return BT_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ MipsInstrInfo::BranchType MipsInstrInfo::AnalyzeBranch(
|
||||||
|
|
||||||
// If we reached here, there are two branches.
|
// If we reached here, there are two branches.
|
||||||
// If there are three terminators, we don't know what sort of block this is.
|
// If there are three terminators, we don't know what sort of block this is.
|
||||||
if (++I != REnd && isUnpredicatedTerminator(&*I))
|
if (++I != REnd && isUnpredicatedTerminator(*I))
|
||||||
return BT_None;
|
return BT_None;
|
||||||
|
|
||||||
BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst);
|
BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst);
|
||||||
|
|
|
@ -150,14 +150,14 @@ bool NVPTXInstrInfo::AnalyzeBranch(
|
||||||
SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) const {
|
SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) const {
|
||||||
// If the block has no terminators, it just falls into the block after it.
|
// If the block has no terminators, it just falls into the block after it.
|
||||||
MachineBasicBlock::iterator I = MBB.end();
|
MachineBasicBlock::iterator I = MBB.end();
|
||||||
if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
|
if (I == MBB.begin() || !isUnpredicatedTerminator(*--I))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Get the last instruction in the block.
|
// Get the last instruction in the block.
|
||||||
MachineInstr *LastInst = I;
|
MachineInstr *LastInst = I;
|
||||||
|
|
||||||
// If there is only one terminator instruction, process it.
|
// If there is only one terminator instruction, process it.
|
||||||
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
|
if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
|
||||||
if (LastInst->getOpcode() == NVPTX::GOTO) {
|
if (LastInst->getOpcode() == NVPTX::GOTO) {
|
||||||
TBB = LastInst->getOperand(0).getMBB();
|
TBB = LastInst->getOperand(0).getMBB();
|
||||||
return false;
|
return false;
|
||||||
|
@ -175,7 +175,7 @@ bool NVPTXInstrInfo::AnalyzeBranch(
|
||||||
MachineInstr *SecondLastInst = I;
|
MachineInstr *SecondLastInst = I;
|
||||||
|
|
||||||
// If there are three terminators, we don't know what sort of block this is.
|
// If there are three terminators, we don't know what sort of block this is.
|
||||||
if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
|
if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.
|
// If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.
|
||||||
|
|
|
@ -453,14 +453,14 @@ bool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||||
if (I == MBB.end())
|
if (I == MBB.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!isUnpredicatedTerminator(I))
|
if (!isUnpredicatedTerminator(*I))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Get the last instruction in the block.
|
// Get the last instruction in the block.
|
||||||
MachineInstr *LastInst = I;
|
MachineInstr *LastInst = I;
|
||||||
|
|
||||||
// If there is only one terminator instruction, process it.
|
// If there is only one terminator instruction, process it.
|
||||||
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
|
if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
|
||||||
if (LastInst->getOpcode() == PPC::B) {
|
if (LastInst->getOpcode() == PPC::B) {
|
||||||
if (!LastInst->getOperand(0).isMBB())
|
if (!LastInst->getOperand(0).isMBB())
|
||||||
return true;
|
return true;
|
||||||
|
@ -522,8 +522,7 @@ bool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||||
MachineInstr *SecondLastInst = I;
|
MachineInstr *SecondLastInst = I;
|
||||||
|
|
||||||
// If there are three terminators, we don't know what sort of block this is.
|
// If there are three terminators, we don't know what sort of block this is.
|
||||||
if (SecondLastInst && I != MBB.begin() &&
|
if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))
|
||||||
isUnpredicatedTerminator(--I))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// If the block ends with PPC::B and PPC:BCC, handle it.
|
// If the block ends with PPC::B and PPC:BCC, handle it.
|
||||||
|
@ -1299,7 +1298,7 @@ bool PPCInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PPCInstrInfo::isPredicated(const MachineInstr *MI) const {
|
bool PPCInstrInfo::isPredicated(const MachineInstr &MI) const {
|
||||||
// The predicated branches are identified by their type, not really by the
|
// The predicated branches are identified by their type, not really by the
|
||||||
// explicit presence of a predicate. Furthermore, some of them can be
|
// explicit presence of a predicate. Furthermore, some of them can be
|
||||||
// predicated more than once. Because if conversion won't try to predicate
|
// predicated more than once. Because if conversion won't try to predicate
|
||||||
|
@ -1310,73 +1309,71 @@ bool PPCInstrInfo::isPredicated(const MachineInstr *MI) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
|
bool PPCInstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const {
|
||||||
if (!MI->isTerminator())
|
if (!MI.isTerminator())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Conditional branch is a special case.
|
// Conditional branch is a special case.
|
||||||
if (MI->isBranch() && !MI->isBarrier())
|
if (MI.isBranch() && !MI.isBarrier())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return !isPredicated(MI);
|
return !isPredicated(MI);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCInstrInfo::PredicateInstruction(MachineInstr *MI,
|
bool PPCInstrInfo::PredicateInstruction(MachineInstr &MI,
|
||||||
ArrayRef<MachineOperand> Pred) const {
|
ArrayRef<MachineOperand> Pred) const {
|
||||||
unsigned OpC = MI->getOpcode();
|
unsigned OpC = MI.getOpcode();
|
||||||
if (OpC == PPC::BLR || OpC == PPC::BLR8) {
|
if (OpC == PPC::BLR || OpC == PPC::BLR8) {
|
||||||
if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
|
if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
|
||||||
bool isPPC64 = Subtarget.isPPC64();
|
bool isPPC64 = Subtarget.isPPC64();
|
||||||
MI->setDesc(get(Pred[0].getImm() ?
|
MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)
|
||||||
(isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR) :
|
: (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
|
||||||
(isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
|
|
||||||
} else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
|
} else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
|
||||||
MI->setDesc(get(PPC::BCLR));
|
MI.setDesc(get(PPC::BCLR));
|
||||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
MachineInstrBuilder(*MI.getParent()->getParent(), MI)
|
||||||
.addReg(Pred[1].getReg());
|
.addReg(Pred[1].getReg());
|
||||||
} else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
|
} else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
|
||||||
MI->setDesc(get(PPC::BCLRn));
|
MI.setDesc(get(PPC::BCLRn));
|
||||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
MachineInstrBuilder(*MI.getParent()->getParent(), MI)
|
||||||
.addReg(Pred[1].getReg());
|
.addReg(Pred[1].getReg());
|
||||||
} else {
|
} else {
|
||||||
MI->setDesc(get(PPC::BCCLR));
|
MI.setDesc(get(PPC::BCCLR));
|
||||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
MachineInstrBuilder(*MI.getParent()->getParent(), MI)
|
||||||
.addImm(Pred[0].getImm())
|
.addImm(Pred[0].getImm())
|
||||||
.addReg(Pred[1].getReg());
|
.addReg(Pred[1].getReg());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (OpC == PPC::B) {
|
} else if (OpC == PPC::B) {
|
||||||
if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
|
if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
|
||||||
bool isPPC64 = Subtarget.isPPC64();
|
bool isPPC64 = Subtarget.isPPC64();
|
||||||
MI->setDesc(get(Pred[0].getImm() ?
|
MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
|
||||||
(isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
|
: (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
|
||||||
(isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
|
|
||||||
} else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
|
} else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
|
||||||
MachineBasicBlock *MBB = MI->getOperand(0).getMBB();
|
MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
|
||||||
MI->RemoveOperand(0);
|
MI.RemoveOperand(0);
|
||||||
|
|
||||||
MI->setDesc(get(PPC::BC));
|
MI.setDesc(get(PPC::BC));
|
||||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
MachineInstrBuilder(*MI.getParent()->getParent(), MI)
|
||||||
.addReg(Pred[1].getReg())
|
.addReg(Pred[1].getReg())
|
||||||
.addMBB(MBB);
|
.addMBB(MBB);
|
||||||
} else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
|
} else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
|
||||||
MachineBasicBlock *MBB = MI->getOperand(0).getMBB();
|
MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
|
||||||
MI->RemoveOperand(0);
|
MI.RemoveOperand(0);
|
||||||
|
|
||||||
MI->setDesc(get(PPC::BCn));
|
MI.setDesc(get(PPC::BCn));
|
||||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
MachineInstrBuilder(*MI.getParent()->getParent(), MI)
|
||||||
.addReg(Pred[1].getReg())
|
.addReg(Pred[1].getReg())
|
||||||
.addMBB(MBB);
|
.addMBB(MBB);
|
||||||
} else {
|
} else {
|
||||||
MachineBasicBlock *MBB = MI->getOperand(0).getMBB();
|
MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
|
||||||
MI->RemoveOperand(0);
|
MI.RemoveOperand(0);
|
||||||
|
|
||||||
MI->setDesc(get(PPC::BCC));
|
MI.setDesc(get(PPC::BCC));
|
||||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
MachineInstrBuilder(*MI.getParent()->getParent(), MI)
|
||||||
.addImm(Pred[0].getImm())
|
.addImm(Pred[0].getImm())
|
||||||
.addReg(Pred[1].getReg())
|
.addReg(Pred[1].getReg())
|
||||||
.addMBB(MBB);
|
.addMBB(MBB);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1389,24 +1386,24 @@ bool PPCInstrInfo::PredicateInstruction(MachineInstr *MI,
|
||||||
bool isPPC64 = Subtarget.isPPC64();
|
bool isPPC64 = Subtarget.isPPC64();
|
||||||
|
|
||||||
if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
|
if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
|
||||||
MI->setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8) :
|
MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8)
|
||||||
(setLR ? PPC::BCCTRL : PPC::BCCTR)));
|
: (setLR ? PPC::BCCTRL : PPC::BCCTR)));
|
||||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
MachineInstrBuilder(*MI.getParent()->getParent(), MI)
|
||||||
.addReg(Pred[1].getReg());
|
.addReg(Pred[1].getReg());
|
||||||
return true;
|
return true;
|
||||||
} else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
|
} else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
|
||||||
MI->setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n) :
|
MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)
|
||||||
(setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
|
: (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
|
||||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
MachineInstrBuilder(*MI.getParent()->getParent(), MI)
|
||||||
.addReg(Pred[1].getReg());
|
.addReg(Pred[1].getReg());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MI->setDesc(get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8) :
|
MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
|
||||||
(setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
|
: (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
|
||||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
MachineInstrBuilder(*MI.getParent()->getParent(), MI)
|
||||||
.addImm(Pred[0].getImm())
|
.addImm(Pred[0].getImm())
|
||||||
.addReg(Pred[1].getReg());
|
.addReg(Pred[1].getReg());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1444,7 +1441,7 @@ bool PPCInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCInstrInfo::DefinesPredicate(MachineInstr *MI,
|
bool PPCInstrInfo::DefinesPredicate(MachineInstr &MI,
|
||||||
std::vector<MachineOperand> &Pred) const {
|
std::vector<MachineOperand> &Pred) const {
|
||||||
// Note: At the present time, the contents of Pred from this function is
|
// Note: At the present time, the contents of Pred from this function is
|
||||||
// unused by IfConversion. This implementation follows ARM by pushing the
|
// unused by IfConversion. This implementation follows ARM by pushing the
|
||||||
|
@ -1457,8 +1454,8 @@ bool PPCInstrInfo::DefinesPredicate(MachineInstr *MI,
|
||||||
&PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };
|
&PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };
|
||||||
|
|
||||||
bool Found = false;
|
bool Found = false;
|
||||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
|
||||||
const MachineOperand &MO = MI->getOperand(i);
|
const MachineOperand &MO = MI.getOperand(i);
|
||||||
for (unsigned c = 0; c < array_lengthof(RCs) && !Found; ++c) {
|
for (unsigned c = 0; c < array_lengthof(RCs) && !Found; ++c) {
|
||||||
const TargetRegisterClass *RC = RCs[c];
|
const TargetRegisterClass *RC = RCs[c];
|
||||||
if (MO.isReg()) {
|
if (MO.isReg()) {
|
||||||
|
@ -1480,8 +1477,8 @@ bool PPCInstrInfo::DefinesPredicate(MachineInstr *MI,
|
||||||
return Found;
|
return Found;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCInstrInfo::isPredicable(MachineInstr *MI) const {
|
bool PPCInstrInfo::isPredicable(MachineInstr &MI) const {
|
||||||
unsigned OpC = MI->getOpcode();
|
unsigned OpC = MI.getOpcode();
|
||||||
switch (OpC) {
|
switch (OpC) {
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -230,20 +230,20 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Predication support.
|
// Predication support.
|
||||||
bool isPredicated(const MachineInstr *MI) const override;
|
bool isPredicated(const MachineInstr &MI) const override;
|
||||||
|
|
||||||
bool isUnpredicatedTerminator(const MachineInstr *MI) const override;
|
bool isUnpredicatedTerminator(const MachineInstr &MI) const override;
|
||||||
|
|
||||||
bool PredicateInstruction(MachineInstr *MI,
|
bool PredicateInstruction(MachineInstr &MI,
|
||||||
ArrayRef<MachineOperand> Pred) const override;
|
ArrayRef<MachineOperand> Pred) const override;
|
||||||
|
|
||||||
bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
|
bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
|
||||||
ArrayRef<MachineOperand> Pred2) const override;
|
ArrayRef<MachineOperand> Pred2) const override;
|
||||||
|
|
||||||
bool DefinesPredicate(MachineInstr *MI,
|
bool DefinesPredicate(MachineInstr &MI,
|
||||||
std::vector<MachineOperand> &Pred) const override;
|
std::vector<MachineOperand> &Pred) const override;
|
||||||
|
|
||||||
bool isPredicable(MachineInstr *MI) const override;
|
bool isPredicable(MachineInstr &MI) const override;
|
||||||
|
|
||||||
// Comparison optimization.
|
// Comparison optimization.
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
if (I == MBB.end())
|
if (I == MBB.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!isUnpredicatedTerminator(I))
|
if (!isUnpredicatedTerminator(*I))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Get the last instruction in the block.
|
// Get the last instruction in the block.
|
||||||
|
@ -156,7 +156,7 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
unsigned LastOpc = LastInst->getOpcode();
|
unsigned LastOpc = LastInst->getOpcode();
|
||||||
|
|
||||||
// If there is only one terminator instruction, process it.
|
// If there is only one terminator instruction, process it.
|
||||||
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
|
if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
|
||||||
if (isUncondBranchOpcode(LastOpc)) {
|
if (isUncondBranchOpcode(LastOpc)) {
|
||||||
TBB = LastInst->getOperand(0).getMBB();
|
TBB = LastInst->getOperand(0).getMBB();
|
||||||
return false;
|
return false;
|
||||||
|
@ -180,7 +180,7 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
LastInst->eraseFromParent();
|
LastInst->eraseFromParent();
|
||||||
LastInst = SecondLastInst;
|
LastInst = SecondLastInst;
|
||||||
LastOpc = LastInst->getOpcode();
|
LastOpc = LastInst->getOpcode();
|
||||||
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
|
if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
|
||||||
// Return now the only terminator is an unconditional branch.
|
// Return now the only terminator is an unconditional branch.
|
||||||
TBB = LastInst->getOperand(0).getMBB();
|
TBB = LastInst->getOperand(0).getMBB();
|
||||||
return false;
|
return false;
|
||||||
|
@ -192,7 +192,7 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are three terminators, we don't know what sort of block this is.
|
// If there are three terminators, we don't know what sort of block this is.
|
||||||
if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
|
if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// If the block ends with a B and a Bcc, handle it.
|
// If the block ends with a B and a Bcc, handle it.
|
||||||
|
|
|
@ -261,7 +261,7 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
|
|
||||||
// Working from the bottom, when we see a non-terminator instruction, we're
|
// Working from the bottom, when we see a non-terminator instruction, we're
|
||||||
// done.
|
// done.
|
||||||
if (!isUnpredicatedTerminator(I))
|
if (!isUnpredicatedTerminator(*I))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// A terminator that isn't a branch can't easily be handled by this
|
// A terminator that isn't a branch can't easily be handled by this
|
||||||
|
@ -506,8 +506,8 @@ static unsigned getConditionalMove(unsigned Opcode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SystemZInstrInfo::isPredicable(MachineInstr *MI) const {
|
bool SystemZInstrInfo::isPredicable(MachineInstr &MI) const {
|
||||||
unsigned Opcode = MI->getOpcode();
|
unsigned Opcode = MI.getOpcode();
|
||||||
return STI.hasLoadStoreOnCond() && getConditionalMove(Opcode);
|
return STI.hasLoadStoreOnCond() && getConditionalMove(Opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,19 +529,20 @@ isProfitableToIfCvt(MachineBasicBlock &TMBB,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SystemZInstrInfo::
|
bool SystemZInstrInfo::PredicateInstruction(
|
||||||
PredicateInstruction(MachineInstr *MI, ArrayRef<MachineOperand> Pred) const {
|
MachineInstr &MI, ArrayRef<MachineOperand> Pred) const {
|
||||||
assert(Pred.size() == 2 && "Invalid condition");
|
assert(Pred.size() == 2 && "Invalid condition");
|
||||||
unsigned CCValid = Pred[0].getImm();
|
unsigned CCValid = Pred[0].getImm();
|
||||||
unsigned CCMask = Pred[1].getImm();
|
unsigned CCMask = Pred[1].getImm();
|
||||||
assert(CCMask > 0 && CCMask < 15 && "Invalid predicate");
|
assert(CCMask > 0 && CCMask < 15 && "Invalid predicate");
|
||||||
unsigned Opcode = MI->getOpcode();
|
unsigned Opcode = MI.getOpcode();
|
||||||
if (STI.hasLoadStoreOnCond()) {
|
if (STI.hasLoadStoreOnCond()) {
|
||||||
if (unsigned CondOpcode = getConditionalMove(Opcode)) {
|
if (unsigned CondOpcode = getConditionalMove(Opcode)) {
|
||||||
MI->setDesc(get(CondOpcode));
|
MI.setDesc(get(CondOpcode));
|
||||||
MachineInstrBuilder(*MI->getParent()->getParent(), MI)
|
MachineInstrBuilder(*MI.getParent()->getParent(), MI)
|
||||||
.addImm(CCValid).addImm(CCMask)
|
.addImm(CCValid)
|
||||||
.addReg(SystemZ::CC, RegState::Implicit);
|
.addImm(CCMask)
|
||||||
|
.addReg(SystemZ::CC, RegState::Implicit);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,7 @@ public:
|
||||||
bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
|
bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
|
||||||
unsigned SrcReg2, int Mask, int Value,
|
unsigned SrcReg2, int Mask, int Value,
|
||||||
const MachineRegisterInfo *MRI) const override;
|
const MachineRegisterInfo *MRI) const override;
|
||||||
bool isPredicable(MachineInstr *MI) const override;
|
bool isPredicable(MachineInstr &MI) const override;
|
||||||
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
|
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
|
||||||
unsigned ExtraPredCycles,
|
unsigned ExtraPredCycles,
|
||||||
BranchProbability Probability) const override;
|
BranchProbability Probability) const override;
|
||||||
|
@ -165,7 +165,7 @@ public:
|
||||||
MachineBasicBlock &FMBB,
|
MachineBasicBlock &FMBB,
|
||||||
unsigned NumCyclesF, unsigned ExtraPredCyclesF,
|
unsigned NumCyclesF, unsigned ExtraPredCyclesF,
|
||||||
BranchProbability Probability) const override;
|
BranchProbability Probability) const override;
|
||||||
bool PredicateInstruction(MachineInstr *MI,
|
bool PredicateInstruction(MachineInstr &MI,
|
||||||
ArrayRef<MachineOperand> Pred) const override;
|
ArrayRef<MachineOperand> Pred) const override;
|
||||||
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
|
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
|
||||||
DebugLoc DL, unsigned DestReg, unsigned SrcReg,
|
DebugLoc DL, unsigned DestReg, unsigned SrcReg,
|
||||||
|
|
|
@ -3903,13 +3903,13 @@ unsigned X86::getCMovFromCond(CondCode CC, unsigned RegBytes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool X86InstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
|
bool X86InstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const {
|
||||||
if (!MI->isTerminator()) return false;
|
if (!MI.isTerminator()) return false;
|
||||||
|
|
||||||
// Conditional branch is a special case.
|
// Conditional branch is a special case.
|
||||||
if (MI->isBranch() && !MI->isBarrier())
|
if (MI.isBranch() && !MI.isBarrier())
|
||||||
return true;
|
return true;
|
||||||
if (!MI->isPredicable())
|
if (!MI.isPredicable())
|
||||||
return true;
|
return true;
|
||||||
return !isPredicated(MI);
|
return !isPredicated(MI);
|
||||||
}
|
}
|
||||||
|
@ -3930,7 +3930,7 @@ bool X86InstrInfo::AnalyzeBranchImpl(
|
||||||
|
|
||||||
// Working from the bottom, when we see a non-terminator instruction, we're
|
// Working from the bottom, when we see a non-terminator instruction, we're
|
||||||
// done.
|
// done.
|
||||||
if (!isUnpredicatedTerminator(I))
|
if (!isUnpredicatedTerminator(*I))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// A terminator that isn't a branch can't easily be handled by this
|
// A terminator that isn't a branch can't easily be handled by this
|
||||||
|
|
|
@ -305,7 +305,7 @@ public:
|
||||||
unsigned SrcOpIdx2) const;
|
unsigned SrcOpIdx2) const;
|
||||||
|
|
||||||
// Branch analysis.
|
// Branch analysis.
|
||||||
bool isUnpredicatedTerminator(const MachineInstr* MI) const override;
|
bool isUnpredicatedTerminator(const MachineInstr &MI) const override;
|
||||||
bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
|
bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
|
||||||
MachineBasicBlock *&FBB,
|
MachineBasicBlock *&FBB,
|
||||||
SmallVectorImpl<MachineOperand> &Cond,
|
SmallVectorImpl<MachineOperand> &Cond,
|
||||||
|
|
|
@ -200,14 +200,14 @@ XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
|
||||||
if (I == MBB.end())
|
if (I == MBB.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!isUnpredicatedTerminator(I))
|
if (!isUnpredicatedTerminator(*I))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Get the last instruction in the block.
|
// Get the last instruction in the block.
|
||||||
MachineInstr *LastInst = I;
|
MachineInstr *LastInst = I;
|
||||||
|
|
||||||
// If there is only one terminator instruction, process it.
|
// If there is only one terminator instruction, process it.
|
||||||
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
|
if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
|
||||||
if (IsBRU(LastInst->getOpcode())) {
|
if (IsBRU(LastInst->getOpcode())) {
|
||||||
TBB = LastInst->getOperand(0).getMBB();
|
TBB = LastInst->getOperand(0).getMBB();
|
||||||
return false;
|
return false;
|
||||||
|
@ -230,8 +230,7 @@ XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
|
||||||
MachineInstr *SecondLastInst = I;
|
MachineInstr *SecondLastInst = I;
|
||||||
|
|
||||||
// If there are three terminators, we don't know what sort of block this is.
|
// If there are three terminators, we don't know what sort of block this is.
|
||||||
if (SecondLastInst && I != MBB.begin() &&
|
if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))
|
||||||
isUnpredicatedTerminator(--I))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
unsigned SecondLastOpc = SecondLastInst->getOpcode();
|
unsigned SecondLastOpc = SecondLastInst->getOpcode();
|
||||||
|
|
Loading…
Reference in New Issue