X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FHexagon%2FHexagonCopyToCombine.cpp;h=1883ad8f2e51499ec3fb6234b7fabfe46c561aa1;hb=aa4172e1d8045101f030d95061a8608def9626a0;hp=e93d278c820d111a53c05d83e382072b8fff4ac8;hpb=8a81df1b7fe2e8c3386c24ef6a4e9cf48cb5f2f1;p=oota-llvm.git diff --git a/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/lib/Target/Hexagon/HexagonCopyToCombine.cpp index e93d278c820..1883ad8f2e5 100644 --- a/lib/Target/Hexagon/HexagonCopyToCombine.cpp +++ b/lib/Target/Hexagon/HexagonCopyToCombine.cpp @@ -11,58 +11,78 @@ // to move them together. If we can move them next to each other we do so and // replace them with a combine instruction. //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "hexagon-copy-combine" - #include "llvm/PassSupport.h" -#include "llvm/CodeGen/Passes.h" +#include "Hexagon.h" +#include "HexagonInstrInfo.h" +#include "HexagonMachineFunctionInfo.h" +#include "HexagonRegisterInfo.h" +#include "HexagonSubtarget.h" +#include "HexagonTargetMachine.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" - -#include "Hexagon.h" -#include "HexagonInstrInfo.h" -#include "HexagonRegisterInfo.h" -#include "HexagonSubtarget.h" -#include "HexagonTargetMachine.h" -#include "HexagonMachineFunctionInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; +#define DEBUG_TYPE "hexagon-copy-combine" + static cl::opt IsCombinesDisabled("disable-merge-into-combines", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable merging into combines")); +static +cl::opt +MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store", + cl::Hidden, cl::init(4), + cl::desc("Maximum distance between a tfr feeding a store we " + "consider the store still to be newifiable")); + +namespace llvm { + void initializeHexagonCopyToCombinePass(PassRegistry&); +} + namespace { class HexagonCopyToCombine : public MachineFunctionPass { const HexagonInstrInfo *TII; const TargetRegisterInfo *TRI; + bool ShouldCombineAggressively; + + DenseSet PotentiallyNewifiableTFR; public: static char ID; - HexagonCopyToCombine() : MachineFunctionPass(ID) { } + HexagonCopyToCombine() : MachineFunctionPass(ID) { + initializeHexagonCopyToCombinePass(*PassRegistry::getPassRegistry()); + } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { MachineFunctionPass::getAnalysisUsage(AU); } - const char *getPassName() const { + const char *getPassName() const override { return "Hexagon Copy-To-Combine Pass"; } - virtual bool runOnMachineFunction(MachineFunction &Fn); + bool runOnMachineFunction(MachineFunction &Fn) override; private: MachineInstr *findPairable(MachineInstr *I1, bool &DoInsertAtI1); + void findPotentialNewifiableTFRs(MachineBasicBlock &); + void combine(MachineInstr *I1, MachineInstr *I2, MachineBasicBlock::iterator &MI, bool DoInsertAtI1); @@ -87,10 +107,14 @@ private: 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) { + const HexagonInstrInfo *TII, + bool ShouldCombineAggressively) { switch(MI->getOpcode()) { - case Hexagon::TFR: { + case Hexagon::A2_tfr: { // A COPY instruction can be combined if its arguments are IntRegs (32bit). assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg()); @@ -100,14 +124,32 @@ static bool isCombinableInstType(MachineInstr *MI, Hexagon::IntRegsRegClass.contains(SrcReg); } - case Hexagon::TFRI: { + case Hexagon::A2_tfrsi: { // A transfer-immediate can be combined if its argument is a signed 8bit // value. assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); unsigned DestReg = MI->getOperand(0).getReg(); + + // Only combine constant extended TFRI if we are in aggressive mode. return Hexagon::IntRegsRegClass.contains(DestReg) && - isInt<8>(MI->getOperand(1).getImm()); + (ShouldCombineAggressively || isInt<8>(MI->getOperand(1).getImm())); + } + + case Hexagon::TFRI_V4: { + if (!ShouldCombineAggressively) + return false; + assert(MI->getOperand(0).isReg() && MI->getOperand(1).isGlobal()); + + // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a + // workaround for an ABI bug that prevents GOT relocations on combine + // instructions + if (MI->getOperand(1).getTargetFlags() != HexagonII::MO_NO_FLAG) + return false; + + unsigned DestReg = MI->getOperand(0).getReg(); + return Hexagon::IntRegsRegClass.contains(DestReg); } + default: break; } @@ -115,15 +157,26 @@ static bool isCombinableInstType(MachineInstr *MI, return false; } +static bool isGreaterThan8BitTFRI(MachineInstr *I) { + return I->getOpcode() == Hexagon::A2_tfrsi && + !isInt<8>(I->getOperand(1).getImm()); +} +static bool isGreaterThan6BitTFRI(MachineInstr *I) { + return I->getOpcode() == Hexagon::A2_tfrsi && + !isUInt<6>(I->getOperand(1).getImm()); +} /// areCombinableOperations - Returns true if the two instruction can be merge /// into a combine (ignoring register constraints). static bool areCombinableOperations(const TargetRegisterInfo *TRI, - MachineInstr *I1, MachineInstr *I2) { - assert((I1->getOpcode() == Hexagon::TFR || - I1->getOpcode() == Hexagon::TFRI) && - (I2->getOpcode() == Hexagon::TFR || - I2->getOpcode() == Hexagon::TFRI) && + MachineInstr *HighRegInst, + MachineInstr *LowRegInst) { + assert((HighRegInst->getOpcode() == Hexagon::A2_tfr || + HighRegInst->getOpcode() == Hexagon::A2_tfrsi || + HighRegInst->getOpcode() == Hexagon::TFRI_V4) && + (LowRegInst->getOpcode() == Hexagon::A2_tfr || + LowRegInst->getOpcode() == Hexagon::A2_tfrsi || + LowRegInst->getOpcode() == Hexagon::TFRI_V4) && "Assume individual instructions are of a combinable type"); const HexagonRegisterInfo *QRI = @@ -131,9 +184,19 @@ static bool areCombinableOperations(const TargetRegisterInfo *TRI, // V4 added some combine variations (mixed immediate and register source // operands), if we are on < V4 we can only combine 2 register-to-register - // moves and 2 immediate-to-register moves. - if (QRI->Subtarget.getHexagonArchVersion() < HexagonSubtarget::V4) - return I1->getOpcode() == I2->getOpcode(); + // moves and 2 immediate-to-register moves. We also don't have + // constant-extenders. + if (!QRI->Subtarget.hasV4TOps()) + return HighRegInst->getOpcode() == LowRegInst->getOpcode() && + !isGreaterThan8BitTFRI(HighRegInst) && + !isGreaterThan6BitTFRI(LowRegInst); + + // There is no combine of two constant extended values. + if ((HighRegInst->getOpcode() == Hexagon::TFRI_V4 || + isGreaterThan8BitTFRI(HighRegInst)) && + (LowRegInst->getOpcode() == Hexagon::TFRI_V4 || + isGreaterThan6BitTFRI(LowRegInst))) + return false; return true; } @@ -153,10 +216,11 @@ static void removeKillInfo(MachineInstr *MI, unsigned RegNotKilled) { } } -/// isUnsafeToMoveAccross - Returns true if it is unsafe to move a copy +/// isUnsafeToMoveAcross - Returns true if it is unsafe to move a copy /// instruction from \p UseReg to \p DestReg over the instruction \p I. -bool isUnsafeToMoveAccross(MachineInstr *I, unsigned UseReg, unsigned DestReg, - const TargetRegisterInfo *TRI) { +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) || @@ -171,25 +235,34 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, unsigned I1DestReg, unsigned I2DestReg, bool &DoInsertAtI1) { + + bool IsImmUseReg = I2->getOperand(1).isImm() || I2->getOperand(1).isGlobal(); + unsigned I2UseReg = IsImmUseReg ? 0 : I2->getOperand(1).getReg(); + + // 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)) + return false; + bool isSafe = true; // First try to move I2 towards I1. { // A reverse_iterator instantiated like below starts before I2, and I1 // respectively. - // Look at instructions I in between I2 and (including) I1. + // Look at instructions I in between I2 and (excluding) I1. MachineBasicBlock::reverse_iterator I(I2), + End = --(MachineBasicBlock::reverse_iterator(I1)); + // At 03 we got better results (dhrystone!) by being more conservative. + if (!ShouldCombineAggressively) End = MachineBasicBlock::reverse_iterator(I1); - bool IsImmUseReg = I2->getOperand(1).isImm(); - unsigned I2UseReg = IsImmUseReg ? 0 : I2->getOperand(1).getReg(); - // If I2 kills its operand and we move I2 over an instruction that also // uses I2's use reg we need to modify that (first) instruction to now kill // this reg. unsigned KilledOperand = 0; if (I2->killsRegister(I2UseReg)) KilledOperand = I2UseReg; - MachineInstr *KillingInstr = 0; + MachineInstr *KillingInstr = nullptr; for (; I != End; ++I) { // If the intervening instruction I: @@ -198,7 +271,7 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, // * reads I2's def reg // * or has unmodelled side effects // we can't move I2 across it. - if (isUnsafeToMoveAccross(&*I, I2UseReg, I2DestReg, TRI)) { + if (isUnsafeToMoveAcross(&*I, I2UseReg, I2DestReg, TRI)) { isSafe = false; break; } @@ -212,8 +285,8 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, // Update the intermediate instruction to with the kill flag. if (KillingInstr) { bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true); + (void)Added; // suppress compiler warning assert(Added && "Must successfully update kill flag"); - (void)Added; removeKillInfo(I2, KilledOperand); } DoInsertAtI1 = true; @@ -223,15 +296,17 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, // Try to move I1 towards I2. { - // Look at instructions I in between I1 and (including) I2. - MachineBasicBlock::iterator I(I1), - End(llvm::next(MachineBasicBlock::iterator(I2))); - bool IsImmUseReg = I1->getOperand(1).isImm(); + // Look at instructions I in between I1 and (excluding) I2. + MachineBasicBlock::iterator I(I1), End(I2); + // At O3 we got better results (dhrystone) by being more conservative here. + if (!ShouldCombineAggressively) + End = std::next(MachineBasicBlock::iterator(I2)); + IsImmUseReg = I1->getOperand(1).isImm() || I1->getOperand(1).isGlobal(); unsigned I1UseReg = IsImmUseReg ? 0 : I1->getOperand(1).getReg(); - // Track killed operands. If we move accross an instruction that kills our + // 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. - MachineInstr *KillingInstr = 0; + MachineInstr *KillingInstr = nullptr; unsigned KilledOperand = 0; while(++I != End) { @@ -251,14 +326,14 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, // to remove the %D4 operand. For now, we are // conservative and disallow the move. // we can't move I1 across it. - if (isUnsafeToMoveAccross(I, I1UseReg, I1DestReg, TRI) || + if (isUnsafeToMoveAcross(I, I1UseReg, I1DestReg, TRI) || // Check for an aliased register kill. Bail out if we see one. (!I->killsRegister(I1UseReg) && I->killsRegister(I1UseReg, TRI))) return false; // Check for an exact kill (registers match). if (I1UseReg && I->killsRegister(I1UseReg)) { - assert(KillingInstr == 0 && "Should only see one killing instruction"); + assert(!KillingInstr && "Should only see one killing instruction"); KilledOperand = I1UseReg; KillingInstr = &*I; } @@ -268,8 +343,8 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, // 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); + (void)Added; // suppress compiler warning assert(Added && "Must successfully update kill flag"); - (void)Added; } DoInsertAtI1 = false; } @@ -277,6 +352,64 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, return true; } +/// findPotentialNewifiableTFRs - Finds tranfers that feed stores that could be +/// newified. (A use of a 64 bit register define can not be newified) +void +HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) { + DenseMap LastDef; + for (MachineBasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) { + MachineInstr *MI = I; + // Mark TFRs that feed a potential new value store as such. + if(TII->mayBeNewStore(MI)) { + // Look for uses of TFR instructions. + for (unsigned OpdIdx = 0, OpdE = MI->getNumOperands(); OpdIdx != OpdE; + ++OpdIdx) { + MachineOperand &Op = MI->getOperand(OpdIdx); + + // Skip over anything except register uses. + if (!Op.isReg() || !Op.isUse() || !Op.getReg()) + continue; + + // Look for the defining instruction. + unsigned Reg = Op.getReg(); + MachineInstr *DefInst = LastDef[Reg]; + if (!DefInst) + continue; + if (!isCombinableInstType(DefInst, TII, ShouldCombineAggressively)) + continue; + + // Only close newifiable stores should influence the decision. + MachineBasicBlock::iterator It(DefInst); + unsigned NumInstsToDef = 0; + while (&*It++ != MI) + ++NumInstsToDef; + + if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR) + continue; + + PotentiallyNewifiableTFR.insert(DefInst); + } + // Skip to next instruction. + continue; + } + + // 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); + 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; + } + } else if (Hexagon::IntRegsRegClass.contains(Reg)) + LastDef[Reg] = MI; + } + } +} + bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) { if (IsCombinesDisabled) return false; @@ -284,19 +417,31 @@ bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) { bool HasChanged = false; // Get target info. - TRI = MF.getTarget().getRegisterInfo(); - TII = static_cast(MF.getTarget().getInstrInfo()); + TRI = MF.getSubtarget().getRegisterInfo(); + TII = static_cast(MF.getSubtarget().getInstrInfo()); + + // Combine aggressively (for code size) + ShouldCombineAggressively = + MF.getTarget().getOptLevel() <= CodeGenOpt::Default; // Traverse basic blocks. for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); BI != BE; ++BI) { + PotentiallyNewifiableTFR.clear(); + findPotentialNewifiableTFRs(*BI); + // Traverse instructions in basic block. for(MachineBasicBlock::iterator MI = BI->begin(), End = BI->end(); MI != End;) { MachineInstr *I1 = MI++; + // 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)) + continue; // Ignore instructions that are not combinable. - if (!isCombinableInstType(I1, TII)) + if (!isCombinableInstType(I1, TII, ShouldCombineAggressively)) continue; // Find a second instruction that can be merged into a combine @@ -319,7 +464,7 @@ bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) { /// false if the combine must be inserted at the returned instruction. MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr *I1, bool &DoInsertAtI1) { - MachineBasicBlock::iterator I2 = llvm::next(MachineBasicBlock::iterator(I1)); + MachineBasicBlock::iterator I2 = std::next(MachineBasicBlock::iterator(I1)); unsigned I1DestReg = I1->getOperand(0).getReg(); for (MachineBasicBlock::iterator End = I1->getParent()->end(); I2 != End; @@ -329,22 +474,29 @@ MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr *I1, break; // Ignore non-combinable instructions. - if (!isCombinableInstType(I2, TII)) + if (!isCombinableInstType(I2, TII, ShouldCombineAggressively)) + continue; + + // Don't combine a TFR whose user could be newified. + if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(I2)) continue; unsigned I2DestReg = I2->getOperand(0).getReg(); // Check that registers are adjacent and that the first destination register // is even. - bool IsI1BeforeI2 = (I2DestReg - I1DestReg) == 1; - bool IsI2BeforeI1 = (I1DestReg - I2DestReg) == 1; - unsigned FirstRegIndex = IsI1BeforeI2 ? I1DestReg : I2DestReg; - if ((!IsI1BeforeI2 && !IsI2BeforeI1) || !isEvenReg(FirstRegIndex)) + bool IsI1LowReg = (I2DestReg - I1DestReg) == 1; + bool IsI2LowReg = (I1DestReg - I2DestReg) == 1; + unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg; + if ((!IsI1LowReg && !IsI2LowReg) || !isEvenReg(FirstRegIndex)) continue; // Check that the two instructions are combinable. V4 allows more // instructions to be merged into a combine. - if (!areCombinableOperations(TRI, I1, I2)) + // 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))) break; if (isSafeToMoveTogether(I1, I2, I1DestReg, I2DestReg, @@ -354,7 +506,7 @@ MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr *I1, // Not safe. Stop searching. break; } - return 0; + return nullptr; } void HexagonCopyToCombine::combine(MachineInstr *I1, MachineInstr *I2, @@ -373,7 +525,7 @@ void HexagonCopyToCombine::combine(MachineInstr *I1, MachineInstr *I2, // Get the double word register. unsigned DoubleRegDest = TRI->getMatchingSuperReg(LoRegDef, Hexagon::subreg_loreg, - Hexagon::DoubleRegsRegisterClass); + &Hexagon::DoubleRegsRegClass); assert(DoubleRegDest != 0 && "Expect a valid register"); @@ -409,9 +561,42 @@ void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt, DebugLoc DL = InsertPt->getDebugLoc(); MachineBasicBlock *BB = InsertPt->getParent(); + // Handle globals. + if (HiOperand.isGlobal()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) + .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), + HiOperand.getTargetFlags()) + .addImm(LoOperand.getImm()); + return; + } + if (LoOperand.isGlobal()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) + .addImm(HiOperand.getImm()) + .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(), + LoOperand.getTargetFlags()); + return; + } + + // Handle constant extended immediates. + if (!isInt<8>(HiOperand.getImm())) { + assert(isInt<8>(LoOperand.getImm())); + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) + .addImm(HiOperand.getImm()) + .addImm(LoOperand.getImm()); + return; + } + + if (!isUInt<6>(LoOperand.getImm())) { + assert(isInt<8>(HiOperand.getImm())); + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) + .addImm(HiOperand.getImm()) + .addImm(LoOperand.getImm()); + return; + } + // Insert new combine instruction. // DoubleRegDest = combine #HiImm, #LoImm - BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_ii), DoubleDestReg) + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) .addImm(HiOperand.getImm()) .addImm(LoOperand.getImm()); } @@ -426,9 +611,17 @@ void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt, DebugLoc DL = InsertPt->getDebugLoc(); MachineBasicBlock *BB = InsertPt->getParent(); + // Handle global. + if (HiOperand.isGlobal()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) + .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), + HiOperand.getTargetFlags()) + .addReg(LoReg, LoRegKillFlag); + return; + } // Insert new combine instruction. // DoubleRegDest = combine #HiImm, LoReg - BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_ir_V4), DoubleDestReg) + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) .addImm(HiOperand.getImm()) .addReg(LoReg, LoRegKillFlag); } @@ -443,9 +636,18 @@ void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt, DebugLoc DL = InsertPt->getDebugLoc(); MachineBasicBlock *BB = InsertPt->getParent(); + // Handle global. + if (LoOperand.isGlobal()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) + .addReg(HiReg, HiRegKillFlag) + .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(), + LoOperand.getTargetFlags()); + return; + } + // Insert new combine instruction. // DoubleRegDest = combine HiReg, #LoImm - BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_ri_V4), DoubleDestReg) + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) .addReg(HiReg, HiRegKillFlag) .addImm(LoOperand.getImm()); } @@ -464,7 +666,7 @@ void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt, // Insert new combine instruction. // DoubleRegDest = combine HiReg, LoReg - BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rr), DoubleDestReg) + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combinew), DoubleDestReg) .addReg(HiReg, HiRegKillFlag) .addReg(LoReg, LoRegKillFlag); } @@ -472,4 +674,3 @@ void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt, FunctionPass *llvm::createHexagonCopyToCombine() { return new HexagonCopyToCombine(); } -