aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp')
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp278
1 files changed, 186 insertions, 92 deletions
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp
index 9fd863f6e153..face0f3f64b4 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp
@@ -42,6 +42,11 @@ cl::opt<bool> IsCombinesDisabled("disable-merge-into-combines",
cl::init(false),
cl::desc("Disable merging into combines"));
static
+cl::opt<bool> IsConst64Disabled("disable-const64",
+ cl::Hidden, cl::ZeroOrMore,
+ cl::init(false),
+ cl::desc("Disable generation of const64"));
+static
cl::opt<unsigned>
MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store",
cl::Hidden, cl::init(4),
@@ -62,6 +67,8 @@ class HexagonCopyToCombine : public MachineFunctionPass {
bool ShouldCombineAggressively;
DenseSet<MachineInstr *> PotentiallyNewifiableTFR;
+ SmallVector<MachineInstr *, 8> DbgMItoMove;
+
public:
static char ID;
@@ -79,15 +86,22 @@ public:
bool runOnMachineFunction(MachineFunction &Fn) override;
+ MachineFunctionProperties getRequiredProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::AllVRegsAllocated);
+ }
+
private:
- MachineInstr *findPairable(MachineInstr *I1, bool &DoInsertAtI1);
+ MachineInstr *findPairable(MachineInstr &I1, bool &DoInsertAtI1,
+ bool AllowC64);
void findPotentialNewifiableTFRs(MachineBasicBlock &);
- void combine(MachineInstr *I1, MachineInstr *I2,
- MachineBasicBlock::iterator &MI, bool DoInsertAtI1);
+ void combine(MachineInstr &I1, MachineInstr &I2,
+ MachineBasicBlock::iterator &MI, bool DoInsertAtI1,
+ bool OptForSize);
- bool isSafeToMoveTogether(MachineInstr *I1, MachineInstr *I2,
+ bool isSafeToMoveTogether(MachineInstr &I1, MachineInstr &I2,
unsigned I1DestReg, unsigned I2DestReg,
bool &DoInsertAtI1);
@@ -102,6 +116,9 @@ private:
void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg,
MachineOperand &HiOperand, MachineOperand &LoOperand);
+
+ void emitConst64(MachineBasicBlock::iterator &Before, unsigned DestReg,
+ MachineOperand &HiOperand, MachineOperand &LoOperand);
};
} // End anonymous namespace.
@@ -111,14 +128,13 @@ char HexagonCopyToCombine::ID = 0;
INITIALIZE_PASS(HexagonCopyToCombine, "hexagon-copy-combine",
"Hexagon Copy-To-Combine Pass", false, false)
-static bool isCombinableInstType(MachineInstr *MI,
- const HexagonInstrInfo *TII,
+static bool isCombinableInstType(MachineInstr &MI, const HexagonInstrInfo *TII,
bool ShouldCombineAggressively) {
- switch(MI->getOpcode()) {
+ switch (MI.getOpcode()) {
case Hexagon::A2_tfr: {
// A COPY instruction can be combined if its arguments are IntRegs (32bit).
- const MachineOperand &Op0 = MI->getOperand(0);
- const MachineOperand &Op1 = MI->getOperand(1);
+ const MachineOperand &Op0 = MI.getOperand(0);
+ const MachineOperand &Op1 = MI.getOperand(1);
assert(Op0.isReg() && Op1.isReg());
unsigned DestReg = Op0.getReg();
@@ -130,8 +146,8 @@ static bool isCombinableInstType(MachineInstr *MI,
case Hexagon::A2_tfrsi: {
// A transfer-immediate can be combined if its argument is a signed 8bit
// value.
- const MachineOperand &Op0 = MI->getOperand(0);
- const MachineOperand &Op1 = MI->getOperand(1);
+ const MachineOperand &Op0 = MI.getOperand(0);
+ const MachineOperand &Op1 = MI.getOperand(1);
assert(Op0.isReg());
unsigned DestReg = Op0.getReg();
@@ -154,11 +170,10 @@ static bool isCombinableInstType(MachineInstr *MI,
return false;
}
-template <unsigned N>
-static bool isGreaterThanNBitTFRI(const MachineInstr *I) {
- if (I->getOpcode() == Hexagon::TFRI64_V4 ||
- I->getOpcode() == Hexagon::A2_tfrsi) {
- const MachineOperand &Op = I->getOperand(1);
+template <unsigned N> static bool isGreaterThanNBitTFRI(const MachineInstr &I) {
+ if (I.getOpcode() == Hexagon::TFRI64_V4 ||
+ I.getOpcode() == Hexagon::A2_tfrsi) {
+ const MachineOperand &Op = I.getOperand(1);
return !Op.isImm() || !isInt<N>(Op.getImm());
}
return false;
@@ -167,19 +182,34 @@ static bool isGreaterThanNBitTFRI(const MachineInstr *I) {
/// areCombinableOperations - Returns true if the two instruction can be merge
/// into a combine (ignoring register constraints).
static bool areCombinableOperations(const TargetRegisterInfo *TRI,
- MachineInstr *HighRegInst,
- MachineInstr *LowRegInst) {
- unsigned HiOpc = HighRegInst->getOpcode();
- unsigned LoOpc = LowRegInst->getOpcode();
+ MachineInstr &HighRegInst,
+ MachineInstr &LowRegInst, bool AllowC64) {
+ unsigned HiOpc = HighRegInst.getOpcode();
+ unsigned LoOpc = LowRegInst.getOpcode();
(void)HiOpc; // Fix compiler warning
(void)LoOpc; // Fix compiler warning
assert((HiOpc == Hexagon::A2_tfr || HiOpc == Hexagon::A2_tfrsi) &&
(LoOpc == Hexagon::A2_tfr || LoOpc == Hexagon::A2_tfrsi) &&
"Assume individual instructions are of a combinable type");
- // There is no combine of two constant extended values.
+ if (!AllowC64) {
+ // There is no combine of two constant extended values.
+ if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
+ isGreaterThanNBitTFRI<6>(LowRegInst))
+ return false;
+ }
+
+ // There is a combine of two constant extended values into CONST64,
+ // provided both constants are true immediates.
+ if (isGreaterThanNBitTFRI<16>(HighRegInst) &&
+ isGreaterThanNBitTFRI<16>(LowRegInst))
+ return (HighRegInst.getOperand(1).isImm() &&
+ LowRegInst.getOperand(1).isImm());
+
+ // There is no combine of two constant extended values, unless handled above
+ // Make both 8-bit size checks to allow both combine (#,##) and combine(##,#)
if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
- isGreaterThanNBitTFRI<6>(LowRegInst))
+ isGreaterThanNBitTFRI<8>(LowRegInst))
return false;
return true;
@@ -191,25 +221,23 @@ static bool isEvenReg(unsigned Reg) {
return (Reg - Hexagon::R0) % 2 == 0;
}
-static void removeKillInfo(MachineInstr *MI, unsigned RegNotKilled) {
- for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
- MachineOperand &Op = MI->getOperand(I);
+static void removeKillInfo(MachineInstr &MI, unsigned RegNotKilled) {
+ for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
+ MachineOperand &Op = MI.getOperand(I);
if (!Op.isReg() || Op.getReg() != RegNotKilled || !Op.isKill())
continue;
Op.setIsKill(false);
}
}
-/// isUnsafeToMoveAcross - Returns true if it is unsafe to move a copy
-/// instruction from \p UseReg to \p DestReg over the instruction \p I.
-static bool isUnsafeToMoveAcross(MachineInstr *I, unsigned UseReg,
- unsigned DestReg,
- const TargetRegisterInfo *TRI) {
- return (UseReg && (I->modifiesRegister(UseReg, TRI))) ||
- I->modifiesRegister(DestReg, TRI) ||
- I->readsRegister(DestReg, TRI) ||
- I->hasUnmodeledSideEffects() ||
- I->isInlineAsm() || I->isDebugValue();
+/// Returns true if it is unsafe to move a copy instruction from \p UseReg to
+/// \p DestReg over the instruction \p MI.
+static bool isUnsafeToMoveAcross(MachineInstr &MI, unsigned UseReg,
+ unsigned DestReg,
+ const TargetRegisterInfo *TRI) {
+ return (UseReg && (MI.modifiesRegister(UseReg, TRI))) ||
+ MI.modifiesRegister(DestReg, TRI) || MI.readsRegister(DestReg, TRI) ||
+ MI.hasUnmodeledSideEffects() || MI.isInlineAsm() || MI.isDebugValue();
}
static unsigned UseReg(const MachineOperand& MO) {
@@ -218,16 +246,16 @@ static unsigned UseReg(const MachineOperand& MO) {
/// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such
/// that the two instructions can be paired in a combine.
-bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1,
- MachineInstr *I2,
+bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr &I1,
+ MachineInstr &I2,
unsigned I1DestReg,
unsigned I2DestReg,
bool &DoInsertAtI1) {
- unsigned I2UseReg = UseReg(I2->getOperand(1));
+ unsigned I2UseReg = UseReg(I2.getOperand(1));
// It is not safe to move I1 and I2 into one combine if I2 has a true
// dependence on I1.
- if (I2UseReg && I1->modifiesRegister(I2UseReg, TRI))
+ if (I2UseReg && I1.modifiesRegister(I2UseReg, TRI))
return false;
bool isSafe = true;
@@ -246,7 +274,7 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1,
// uses I2's use reg we need to modify that (first) instruction to now kill
// this reg.
unsigned KilledOperand = 0;
- if (I2->killsRegister(I2UseReg))
+ if (I2.killsRegister(I2UseReg))
KilledOperand = I2UseReg;
MachineInstr *KillingInstr = nullptr;
@@ -257,7 +285,10 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1,
// * reads I2's def reg
// * or has unmodelled side effects
// we can't move I2 across it.
- if (isUnsafeToMoveAcross(&*I, I2UseReg, I2DestReg, TRI)) {
+ if (I->isDebugValue())
+ continue;
+
+ if (isUnsafeToMoveAcross(*I, I2UseReg, I2DestReg, TRI)) {
isSafe = false;
break;
}
@@ -287,7 +318,7 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1,
// At O3 we got better results (dhrystone) by being more conservative here.
if (!ShouldCombineAggressively)
End = std::next(MachineBasicBlock::iterator(I2));
- unsigned I1UseReg = UseReg(I1->getOperand(1));
+ unsigned I1UseReg = UseReg(I1.getOperand(1));
// Track killed operands. If we move across an instruction that kills our
// operand, we need to update the kill information on the moved I1. It kills
// the operand now.
@@ -295,7 +326,8 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1,
unsigned KilledOperand = 0;
while(++I != End) {
- // If the intervening instruction I:
+ MachineInstr &MI = *I;
+ // If the intervening instruction MI:
// * modifies I1's use reg
// * modifies I1's def reg
// * reads I1's def reg
@@ -304,30 +336,36 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1,
// kill flag for a register (a removeRegisterKilled() analogous to
// addRegisterKilled) that handles aliased register correctly.
// * or has a killed aliased register use of I1's use reg
- // %D4<def> = TFRI64 16
- // %R6<def> = TFR %R9
+ // %D4<def> = A2_tfrpi 16
+ // %R6<def> = A2_tfr %R9
// %R8<def> = KILL %R8, %D4<imp-use,kill>
// If we want to move R6 = across the KILL instruction we would have
// to remove the %D4<imp-use,kill> operand. For now, we are
// conservative and disallow the move.
// we can't move I1 across it.
- if (isUnsafeToMoveAcross(I, I1UseReg, I1DestReg, TRI) ||
+ if (MI.isDebugValue()) {
+ if (MI.readsRegister(I1DestReg, TRI)) // Move this instruction after I2.
+ DbgMItoMove.push_back(&MI);
+ continue;
+ }
+
+ if (isUnsafeToMoveAcross(MI, I1UseReg, I1DestReg, TRI) ||
// Check for an aliased register kill. Bail out if we see one.
- (!I->killsRegister(I1UseReg) && I->killsRegister(I1UseReg, TRI)))
+ (!MI.killsRegister(I1UseReg) && MI.killsRegister(I1UseReg, TRI)))
return false;
// Check for an exact kill (registers match).
- if (I1UseReg && I->killsRegister(I1UseReg)) {
+ if (I1UseReg && MI.killsRegister(I1UseReg)) {
assert(!KillingInstr && "Should only see one killing instruction");
KilledOperand = I1UseReg;
- KillingInstr = &*I;
+ KillingInstr = &MI;
}
}
if (KillingInstr) {
- removeKillInfo(KillingInstr, KilledOperand);
+ removeKillInfo(*KillingInstr, KilledOperand);
// Update I1 to set the kill flag. This flag will later be picked up by
// the new COMBINE instruction.
- bool Added = I1->addRegisterKilled(KilledOperand, TRI);
+ bool Added = I1.addRegisterKilled(KilledOperand, TRI);
(void)Added; // suppress compiler warning
assert(Added && "Must successfully update kill flag");
}
@@ -342,14 +380,16 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1,
void
HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {
DenseMap<unsigned, MachineInstr *> LastDef;
- for (MachineBasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
- MachineInstr *MI = I;
+ for (MachineInstr &MI : BB) {
+ if (MI.isDebugValue())
+ continue;
+
// Mark TFRs that feed a potential new value store as such.
- if(TII->mayBeNewStore(MI)) {
+ if (TII->mayBeNewStore(&MI)) {
// Look for uses of TFR instructions.
- for (unsigned OpdIdx = 0, OpdE = MI->getNumOperands(); OpdIdx != OpdE;
+ for (unsigned OpdIdx = 0, OpdE = MI.getNumOperands(); OpdIdx != OpdE;
++OpdIdx) {
- MachineOperand &Op = MI->getOperand(OpdIdx);
+ MachineOperand &Op = MI.getOperand(OpdIdx);
// Skip over anything except register uses.
if (!Op.isReg() || !Op.isUse() || !Op.getReg())
@@ -360,14 +400,18 @@ HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {
MachineInstr *DefInst = LastDef[Reg];
if (!DefInst)
continue;
- if (!isCombinableInstType(DefInst, TII, ShouldCombineAggressively))
+ if (!isCombinableInstType(*DefInst, TII, ShouldCombineAggressively))
continue;
// Only close newifiable stores should influence the decision.
+ // Ignore the debug instructions in between.
MachineBasicBlock::iterator It(DefInst);
unsigned NumInstsToDef = 0;
- while (&*It++ != MI)
- ++NumInstsToDef;
+ while (&*It != &MI) {
+ if (!It->isDebugValue())
+ ++NumInstsToDef;
+ ++It;
+ }
if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR)
continue;
@@ -380,17 +424,17 @@ HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {
// Put instructions that last defined integer or double registers into the
// map.
- for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
- MachineOperand &Op = MI->getOperand(I);
+ for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
+ MachineOperand &Op = MI.getOperand(I);
if (!Op.isReg() || !Op.isDef() || !Op.getReg())
continue;
unsigned Reg = Op.getReg();
if (Hexagon::DoubleRegsRegClass.contains(Reg)) {
for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
- LastDef[*SubRegs] = MI;
+ LastDef[*SubRegs] = &MI;
}
} else if (Hexagon::IntRegsRegClass.contains(Reg))
- LastDef[Reg] = MI;
+ LastDef[Reg] = &MI;
}
}
}
@@ -405,6 +449,9 @@ bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
TRI = MF.getSubtarget().getRegisterInfo();
TII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
+ const Function *F = MF.getFunction();
+ bool OptForSize = F->hasFnAttribute(Attribute::OptimizeForSize);
+
// Combine aggressively (for code size)
ShouldCombineAggressively =
MF.getTarget().getOptLevel() <= CodeGenOpt::Default;
@@ -418,11 +465,15 @@ bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
// Traverse instructions in basic block.
for(MachineBasicBlock::iterator MI = BI->begin(), End = BI->end();
MI != End;) {
- MachineInstr *I1 = MI++;
+ MachineInstr &I1 = *MI++;
+
+ if (I1.isDebugValue())
+ continue;
+
// Don't combine a TFR whose user could be newified (instructions that
// define double registers can not be newified - Programmer's Ref Manual
// 5.4.2 New-value stores).
- if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(I1))
+ if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&I1))
continue;
// Ignore instructions that are not combinable.
@@ -430,12 +481,14 @@ bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
continue;
// Find a second instruction that can be merged into a combine
- // instruction.
+ // instruction. In addition, also find all the debug instructions that
+ // need to be moved along with it.
bool DoInsertAtI1 = false;
- MachineInstr *I2 = findPairable(I1, DoInsertAtI1);
+ DbgMItoMove.clear();
+ MachineInstr *I2 = findPairable(I1, DoInsertAtI1, OptForSize);
if (I2) {
HasChanged = true;
- combine(I1, I2, MI, DoInsertAtI1);
+ combine(I1, *I2, MI, DoInsertAtI1, OptForSize);
}
}
}
@@ -447,23 +500,28 @@ bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
/// COMBINE instruction or 0 if no such instruction can be found. Returns true
/// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1
/// false if the combine must be inserted at the returned instruction.
-MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr *I1,
- bool &DoInsertAtI1) {
+MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr &I1,
+ bool &DoInsertAtI1,
+ bool AllowC64) {
MachineBasicBlock::iterator I2 = std::next(MachineBasicBlock::iterator(I1));
- unsigned I1DestReg = I1->getOperand(0).getReg();
- for (MachineBasicBlock::iterator End = I1->getParent()->end(); I2 != End;
+ while (I2->isDebugValue())
+ ++I2;
+
+ unsigned I1DestReg = I1.getOperand(0).getReg();
+
+ for (MachineBasicBlock::iterator End = I1.getParent()->end(); I2 != End;
++I2) {
// Bail out early if we see a second definition of I1DestReg.
if (I2->modifiesRegister(I1DestReg, TRI))
break;
// Ignore non-combinable instructions.
- if (!isCombinableInstType(I2, TII, ShouldCombineAggressively))
+ if (!isCombinableInstType(*I2, TII, ShouldCombineAggressively))
continue;
// Don't combine a TFR whose user could be newified.
- if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(I2))
+ if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&*I2))
continue;
unsigned I2DestReg = I2->getOperand(0).getReg();
@@ -478,15 +536,14 @@ MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr *I1,
// Check that the two instructions are combinable. V4 allows more
// instructions to be merged into a combine.
- // The order matters because in a TFRI we might can encode a int8 as the
- // hi reg operand but only a uint6 as the low reg operand.
- if ((IsI2LowReg && !areCombinableOperations(TRI, I1, I2)) ||
- (IsI1LowReg && !areCombinableOperations(TRI, I2, I1)))
+ // The order matters because in a A2_tfrsi we might can encode a int8 as
+ // the hi reg operand but only a uint6 as the low reg operand.
+ if ((IsI2LowReg && !areCombinableOperations(TRI, I1, *I2, AllowC64)) ||
+ (IsI1LowReg && !areCombinableOperations(TRI, *I2, I1, AllowC64)))
break;
- if (isSafeToMoveTogether(I1, I2, I1DestReg, I2DestReg,
- DoInsertAtI1))
- return I2;
+ if (isSafeToMoveTogether(I1, *I2, I1DestReg, I2DestReg, DoInsertAtI1))
+ return &*I2;
// Not safe. Stop searching.
break;
@@ -494,16 +551,17 @@ MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr *I1,
return nullptr;
}
-void HexagonCopyToCombine::combine(MachineInstr *I1, MachineInstr *I2,
+void HexagonCopyToCombine::combine(MachineInstr &I1, MachineInstr &I2,
MachineBasicBlock::iterator &MI,
- bool DoInsertAtI1) {
+ bool DoInsertAtI1, bool OptForSize) {
// We are going to delete I2. If MI points to I2 advance it to the next
// instruction.
- if ((MachineInstr *)MI == I2) ++MI;
+ if (MI == I2.getIterator())
+ ++MI;
// Figure out whether I1 or I2 goes into the lowreg part.
- unsigned I1DestReg = I1->getOperand(0).getReg();
- unsigned I2DestReg = I2->getOperand(0).getReg();
+ unsigned I1DestReg = I1.getOperand(0).getReg();
+ unsigned I2DestReg = I2.getOperand(0).getReg();
bool IsI1Loreg = (I2DestReg - I1DestReg) == 1;
unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg;
@@ -515,15 +573,17 @@ void HexagonCopyToCombine::combine(MachineInstr *I1, MachineInstr *I2,
// Setup source operands.
- MachineOperand &LoOperand = IsI1Loreg ? I1->getOperand(1) :
- I2->getOperand(1);
- MachineOperand &HiOperand = IsI1Loreg ? I2->getOperand(1) :
- I1->getOperand(1);
+ MachineOperand &LoOperand = IsI1Loreg ? I1.getOperand(1) : I2.getOperand(1);
+ MachineOperand &HiOperand = IsI1Loreg ? I2.getOperand(1) : I1.getOperand(1);
// Figure out which source is a register and which a constant.
bool IsHiReg = HiOperand.isReg();
bool IsLoReg = LoOperand.isReg();
+ // There is a combine of two constant extended values into CONST64.
+ bool IsC64 = OptForSize && LoOperand.isImm() && HiOperand.isImm() &&
+ isGreaterThanNBitTFRI<16>(I1) && isGreaterThanNBitTFRI<16>(I2);
+
MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2);
// Emit combine.
if (IsHiReg && IsLoReg)
@@ -532,11 +592,45 @@ void HexagonCopyToCombine::combine(MachineInstr *I1, MachineInstr *I2,
emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand);
else if (IsLoReg)
emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
+ else if (IsC64 && !IsConst64Disabled)
+ emitConst64(InsertPt, DoubleRegDest, HiOperand, LoOperand);
else
emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand);
- I1->eraseFromParent();
- I2->eraseFromParent();
+ // Move debug instructions along with I1 if it's being
+ // moved towards I2.
+ if (!DoInsertAtI1 && DbgMItoMove.size() != 0) {
+ // Insert debug instructions at the new location before I2.
+ MachineBasicBlock *BB = InsertPt->getParent();
+ for (auto NewMI : DbgMItoMove) {
+ // If iterator MI is pointing to DEBUG_VAL, make sure
+ // MI now points to next relevant instruction.
+ if (NewMI == (MachineInstr*)MI)
+ ++MI;
+ BB->splice(InsertPt, BB, NewMI);
+ }
+ }
+
+ I1.eraseFromParent();
+ I2.eraseFromParent();
+}
+
+void HexagonCopyToCombine::emitConst64(MachineBasicBlock::iterator &InsertPt,
+ unsigned DoubleDestReg,
+ MachineOperand &HiOperand,
+ MachineOperand &LoOperand) {
+ DEBUG(dbgs() << "Found a CONST64\n");
+
+ DebugLoc DL = InsertPt->getDebugLoc();
+ MachineBasicBlock *BB = InsertPt->getParent();
+ assert(LoOperand.isImm() && HiOperand.isImm() &&
+ "Both operands must be immediate");
+
+ int64_t V = HiOperand.getImm();
+ V = (V << 32) | (0x0ffffffffLL & LoOperand.getImm());
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::CONST64_Int_Real),
+ DoubleDestReg)
+ .addImm(V);
}
void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,