diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon')
41 files changed, 1639 insertions, 2836 deletions
diff --git a/contrib/llvm/lib/Target/Hexagon/Hexagon.h b/contrib/llvm/lib/Target/Hexagon/Hexagon.h index a9b00a2..5467ee3 100644 --- a/contrib/llvm/lib/Target/Hexagon/Hexagon.h +++ b/contrib/llvm/lib/Target/Hexagon/Hexagon.h @@ -29,7 +29,7 @@ namespace llvm { class HexagonTargetMachine; class raw_ostream; - FunctionPass *createHexagonISelDag(const HexagonTargetMachine &TM, + FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, CodeGenOpt::Level OptLevel); FunctionPass *createHexagonDelaySlotFillerPass(const TargetMachine &TM); FunctionPass *createHexagonFPMoverPass(const TargetMachine &TM); @@ -37,11 +37,15 @@ namespace llvm { FunctionPass *createHexagonCFGOptimizer(const HexagonTargetMachine &TM); FunctionPass *createHexagonSplitTFRCondSets(const HexagonTargetMachine &TM); + FunctionPass *createHexagonSplitConst32AndConst64( + const HexagonTargetMachine &TM); FunctionPass *createHexagonExpandPredSpillCode( const HexagonTargetMachine &TM); FunctionPass *createHexagonHardwareLoops(); FunctionPass *createHexagonPeephole(); FunctionPass *createHexagonFixupHwLoops(); + FunctionPass *createHexagonNewValueJump(); + FunctionPass *createHexagonCopyToCombine(); FunctionPass *createHexagonPacketizer(); FunctionPass *createHexagonNewValueJump(); diff --git a/contrib/llvm/lib/Target/Hexagon/Hexagon.td b/contrib/llvm/lib/Target/Hexagon/Hexagon.td index 9b3a643..568798c 100644 --- a/contrib/llvm/lib/Target/Hexagon/Hexagon.td +++ b/contrib/llvm/lib/Target/Hexagon/Hexagon.td @@ -120,15 +120,39 @@ def getPredNewOpcode : InstrMapping { } //===----------------------------------------------------------------------===// +// Generate mapping table to relate .new predicated instructions with their old +// format. +// +def getPredOldOpcode : InstrMapping { + let FilterClass = "PredNewRel"; + let RowFields = ["BaseOpcode", "PredSense", "isNVStore"]; + let ColFields = ["PNewValue"]; + let KeyCol = ["new"]; + let ValueCols = [[""]]; +} + +//===----------------------------------------------------------------------===// // Generate mapping table to relate store instructions with their new-value // format. // def getNewValueOpcode : InstrMapping { let FilterClass = "NewValueRel"; let RowFields = ["BaseOpcode", "PredSense", "PNewValue"]; - let ColFields = ["isNVStore"]; - let KeyCol = ["0"]; - let ValueCols = [["1"]]; + let ColFields = ["NValueST"]; + let KeyCol = ["false"]; + let ValueCols = [["true"]]; +} + +//===----------------------------------------------------------------------===// +// Generate mapping table to relate new-value store instructions with their old +// format. +// +def getNonNVStore : InstrMapping { + let FilterClass = "NewValueRel"; + let RowFields = ["BaseOpcode", "PredSense", "PNewValue"]; + let ColFields = ["NValueST"]; + let KeyCol = ["true"]; + let ValueCols = [["false"]]; } def getBasedWithImmOffset : InstrMapping { diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp index 88cd3fb..a2e04ba 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -99,7 +99,7 @@ void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, return; case MachineOperand::MO_GlobalAddress: // Computing the address of a global symbol, not calling it. - O << *Mang->getSymbol(MO.getGlobal()); + O << *getSymbol(MO.getGlobal()); printOffset(MO.getOffset(), O); return; } @@ -267,7 +267,7 @@ void HexagonAsmPrinter::printGlobalOperand(const MachineInstr *MI, int OpNo, assert( (MO.getType() == MachineOperand::MO_GlobalAddress) && "Expecting global address"); - O << *Mang->getSymbol(MO.getGlobal()); + O << *getSymbol(MO.getGlobal()); if (MO.getOffset() != 0) { O << " + "; O << MO.getOffset(); diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonCallingConvLower.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonCallingConvLower.cpp index 2c93d04..f5f958c 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonCallingConvLower.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonCallingConvLower.cpp @@ -25,14 +25,13 @@ using namespace llvm; Hexagon_CCState::Hexagon_CCState(CallingConv::ID CC, bool isVarArg, const TargetMachine &tm, - SmallVector<CCValAssign, 16> &locs, + SmallVectorImpl<CCValAssign> &locs, LLVMContext &c) - : CallingConv(CC), IsVarArg(isVarArg), TM(tm), - TRI(*TM.getRegisterInfo()), Locs(locs), Context(c) { + : CallingConv(CC), IsVarArg(isVarArg), TM(tm), Locs(locs), Context(c) { // No stack is used. StackOffset = 0; - UsedRegs.resize((TRI.getNumRegs()+31)/32); + UsedRegs.resize((TM.getRegisterInfo()->getNumRegs()+31)/32); } // HandleByVal - Allocate a stack slot large enough to pass an argument by @@ -56,6 +55,7 @@ void Hexagon_CCState::HandleByVal(unsigned ValNo, EVT ValVT, /// MarkAllocated - Mark a register and all of its aliases as allocated. void Hexagon_CCState::MarkAllocated(unsigned Reg) { + const TargetRegisterInfo &TRI = *TM.getRegisterInfo(); for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) UsedRegs[*AI/32] |= 1 << (*AI&31); } diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonCallingConvLower.h b/contrib/llvm/lib/Target/Hexagon/HexagonCallingConvLower.h index 489b3a3..33c8306 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonCallingConvLower.h +++ b/contrib/llvm/lib/Target/Hexagon/HexagonCallingConvLower.h @@ -48,15 +48,14 @@ class Hexagon_CCState { CallingConv::ID CallingConv; bool IsVarArg; const TargetMachine &TM; - const TargetRegisterInfo &TRI; - SmallVector<CCValAssign, 16> &Locs; + SmallVectorImpl<CCValAssign> &Locs; LLVMContext &Context; unsigned StackOffset; SmallVector<uint32_t, 16> UsedRegs; public: Hexagon_CCState(CallingConv::ID CC, bool isVarArg, const TargetMachine &TM, - SmallVector<CCValAssign, 16> &locs, LLVMContext &c); + SmallVectorImpl<CCValAssign> &locs, LLVMContext &c); void addLoc(const CCValAssign &V) { Locs.push_back(V); diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp new file mode 100644 index 0000000..dc440cb --- /dev/null +++ b/contrib/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp @@ -0,0 +1,677 @@ +//===------- HexagonCopyToCombine.cpp - Hexagon Copy-To-Combine Pass ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This pass replaces transfer instructions by combine instructions. +// We walk along a basic block and look for two combinable instructions and try +// 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/ADT/DenseSet.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/CodeGen/Passes.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/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" + +using namespace llvm; + +static +cl::opt<bool> IsCombinesDisabled("disable-merge-into-combines", + cl::Hidden, cl::ZeroOrMore, + cl::init(false), + cl::desc("Disable merging into combines")); +static +cl::opt<unsigned> +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<MachineInstr *> PotentiallyNewifiableTFR; +public: + static char ID; + + HexagonCopyToCombine() : MachineFunctionPass(ID) { + initializeHexagonCopyToCombinePass(*PassRegistry::getPassRegistry()); + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + MachineFunctionPass::getAnalysisUsage(AU); + } + + const char *getPassName() const { + return "Hexagon Copy-To-Combine Pass"; + } + + virtual bool runOnMachineFunction(MachineFunction &Fn); + +private: + MachineInstr *findPairable(MachineInstr *I1, bool &DoInsertAtI1); + + void findPotentialNewifiableTFRs(MachineBasicBlock &); + + void combine(MachineInstr *I1, MachineInstr *I2, + MachineBasicBlock::iterator &MI, bool DoInsertAtI1); + + bool isSafeToMoveTogether(MachineInstr *I1, MachineInstr *I2, + unsigned I1DestReg, unsigned I2DestReg, + bool &DoInsertAtI1); + + void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg, + MachineOperand &HiOperand, MachineOperand &LoOperand); + + void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg, + MachineOperand &HiOperand, MachineOperand &LoOperand); + + void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg, + MachineOperand &HiOperand, MachineOperand &LoOperand); + + void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg, + MachineOperand &HiOperand, MachineOperand &LoOperand); +}; + +} // End anonymous namespace. + +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, + bool ShouldCombineAggressively) { + switch(MI->getOpcode()) { + case Hexagon::TFR: { + // A COPY instruction can be combined if its arguments are IntRegs (32bit). + assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg()); + + unsigned DestReg = MI->getOperand(0).getReg(); + unsigned SrcReg = MI->getOperand(1).getReg(); + return Hexagon::IntRegsRegClass.contains(DestReg) && + Hexagon::IntRegsRegClass.contains(SrcReg); + } + + case Hexagon::TFRI: { + // 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) && + (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; + } + + return false; +} + +static bool isGreaterThan8BitTFRI(MachineInstr *I) { + return I->getOpcode() == Hexagon::TFRI && + !isInt<8>(I->getOperand(1).getImm()); +} +static bool isGreaterThan6BitTFRI(MachineInstr *I) { + return I->getOpcode() == Hexagon::TFRI && + !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 *HighRegInst, + MachineInstr *LowRegInst) { + assert((HighRegInst->getOpcode() == Hexagon::TFR || + HighRegInst->getOpcode() == Hexagon::TFRI || + HighRegInst->getOpcode() == Hexagon::TFRI_V4) && + (LowRegInst->getOpcode() == Hexagon::TFR || + LowRegInst->getOpcode() == Hexagon::TFRI || + LowRegInst->getOpcode() == Hexagon::TFRI_V4) && + "Assume individual instructions are of a combinable type"); + + const HexagonRegisterInfo *QRI = + static_cast<const HexagonRegisterInfo *>(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. 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; +} + +static bool isEvenReg(unsigned Reg) { + assert(TargetRegisterInfo::isPhysicalRegister(Reg) && + Hexagon::IntRegsRegClass.contains(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); + 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(); +} + +/// 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, + 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 (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); + // 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; + + for (; I != End; ++I) { + // If the intervening instruction I: + // * modifies I2's use reg + // * modifies I2's def reg + // * reads I2's def reg + // * or has unmodelled side effects + // we can't move I2 across it. + if (isUnsafeToMoveAcross(&*I, I2UseReg, I2DestReg, TRI)) { + isSafe = false; + break; + } + + // Update first use of the killed operand. + if (!KillingInstr && KilledOperand && + I->readsRegister(KilledOperand, TRI)) + KillingInstr = &*I; + } + if (isSafe) { + // Update the intermediate instruction to with the kill flag. + if (KillingInstr) { + bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true); + (void)Added; // supress compiler warning + assert(Added && "Must successfully update kill flag"); + removeKillInfo(I2, KilledOperand); + } + DoInsertAtI1 = true; + return true; + } + } + + // Try to move I1 towards I2. + { + // 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 = llvm::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 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; + unsigned KilledOperand = 0; + + while(++I != End) { + // If the intervening instruction I: + // * modifies I1's use reg + // * modifies I1's def reg + // * reads I1's def reg + // * or has unmodelled side effects + // We introduce this special case because llvm has no api to remove a + // 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 + // %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) || + // 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"); + KilledOperand = I1UseReg; + KillingInstr = &*I; + } + } + if (KillingInstr) { + 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); + (void)Added; // supress compiler warning + assert(Added && "Must successfully update kill flag"); + } + DoInsertAtI1 = false; + } + + 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<unsigned, MachineInstr *> 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; + + bool HasChanged = false; + + // Get target info. + TRI = MF.getTarget().getRegisterInfo(); + TII = static_cast<const HexagonInstrInfo *>(MF.getTarget().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, ShouldCombineAggressively)) + continue; + + // Find a second instruction that can be merged into a combine + // instruction. + bool DoInsertAtI1 = false; + MachineInstr *I2 = findPairable(I1, DoInsertAtI1); + if (I2) { + HasChanged = true; + combine(I1, I2, MI, DoInsertAtI1); + } + } + } + + return HasChanged; +} + +/// findPairable - Returns an instruction that can be merged with \p I1 into a +/// 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) { + MachineBasicBlock::iterator I2 = llvm::next(MachineBasicBlock::iterator(I1)); + 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)) + 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 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. + // 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, + DoInsertAtI1)) + return I2; + + // Not safe. Stop searching. + break; + } + return 0; +} + +void HexagonCopyToCombine::combine(MachineInstr *I1, MachineInstr *I2, + MachineBasicBlock::iterator &MI, + bool DoInsertAtI1) { + // We are going to delete I2. If MI points to I2 advance it to the next + // instruction. + if ((MachineInstr *)MI == I2) ++MI; + + // Figure out whether I1 or I2 goes into the lowreg part. + unsigned I1DestReg = I1->getOperand(0).getReg(); + unsigned I2DestReg = I2->getOperand(0).getReg(); + bool IsI1Loreg = (I2DestReg - I1DestReg) == 1; + unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg; + + // Get the double word register. + unsigned DoubleRegDest = + TRI->getMatchingSuperReg(LoRegDef, Hexagon::subreg_loreg, + &Hexagon::DoubleRegsRegClass); + assert(DoubleRegDest != 0 && "Expect a valid register"); + + + // Setup source operands. + 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(); + + MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2); + // Emit combine. + if (IsHiReg && IsLoReg) + emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand); + else if (IsHiReg) + emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand); + else if (IsLoReg) + emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand); + else + emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand); + + I1->eraseFromParent(); + I2->eraseFromParent(); +} + +void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt, + unsigned DoubleDestReg, + MachineOperand &HiOperand, + MachineOperand &LoOperand) { + DebugLoc DL = InsertPt->getDebugLoc(); + MachineBasicBlock *BB = InsertPt->getParent(); + + // Handle globals. + if (HiOperand.isGlobal()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg) + .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), + HiOperand.getTargetFlags()) + .addImm(LoOperand.getImm()); + return; + } + if (LoOperand.isGlobal()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_iI_V4), 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::COMBINE_Ii), 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::COMBINE_iI_V4), 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) + .addImm(HiOperand.getImm()) + .addImm(LoOperand.getImm()); +} + +void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt, + unsigned DoubleDestReg, + MachineOperand &HiOperand, + MachineOperand &LoOperand) { + unsigned LoReg = LoOperand.getReg(); + unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill()); + + DebugLoc DL = InsertPt->getDebugLoc(); + MachineBasicBlock *BB = InsertPt->getParent(); + + // Handle global. + if (HiOperand.isGlobal()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ir_V4), 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) + .addImm(HiOperand.getImm()) + .addReg(LoReg, LoRegKillFlag); +} + +void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt, + unsigned DoubleDestReg, + MachineOperand &HiOperand, + MachineOperand &LoOperand) { + unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill()); + unsigned HiReg = HiOperand.getReg(); + + DebugLoc DL = InsertPt->getDebugLoc(); + MachineBasicBlock *BB = InsertPt->getParent(); + + // Handle global. + if (LoOperand.isGlobal()) { + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rI_V4), 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) + .addReg(HiReg, HiRegKillFlag) + .addImm(LoOperand.getImm()); +} + +void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt, + unsigned DoubleDestReg, + MachineOperand &HiOperand, + MachineOperand &LoOperand) { + unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill()); + unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill()); + unsigned LoReg = LoOperand.getReg(); + unsigned HiReg = HiOperand.getReg(); + + DebugLoc DL = InsertPt->getDebugLoc(); + MachineBasicBlock *BB = InsertPt->getParent(); + + // Insert new combine instruction. + // DoubleRegDest = combine HiReg, LoReg + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rr), DoubleDestReg) + .addReg(HiReg, HiRegKillFlag) + .addReg(LoReg, LoRegKillFlag); +} + +FunctionPass *llvm::createHexagonCopyToCombine() { + return new HexagonCopyToCombine(); +} diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index de993ee..2b04f25 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -76,17 +76,12 @@ void HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const { void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineModuleInfo &MMI = MF.getMMI(); MachineBasicBlock::iterator MBBI = MBB.begin(); const HexagonRegisterInfo *QRI = static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo()); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); determineFrameLayout(MF); - // Check if frame moves are needed for EH. - bool needsFrameMoves = MMI.hasDebugInfo() || - !MF.getFunction()->needsUnwindTableEntry(); - // Get the number of bytes to allocate from the FrameInfo. int NumBytes = (int) MFI->getStackSize(); @@ -113,28 +108,6 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { MO.setImm(MFI->getMaxCallFrameSize()); } - std::vector<MachineMove> &Moves = MMI.getFrameMoves(); - - if (needsFrameMoves) { - // Advance CFA. DW_CFA_def_cfa - unsigned FPReg = QRI->getFrameRegister(); - unsigned RAReg = QRI->getRARegister(); - - MachineLocation Dst(MachineLocation::VirtualFP); - MachineLocation Src(FPReg, -8); - Moves.push_back(MachineMove(0, Dst, Src)); - - // R31 = (R31 - #4) - MachineLocation LRDst(RAReg, -4); - MachineLocation LRSrc(RAReg); - Moves.push_back(MachineMove(0, LRDst, LRSrc)); - - // R30 = (R30 - #8) - MachineLocation SPDst(FPReg, -8); - MachineLocation SPSrc(FPReg); - Moves.push_back(MachineMove(0, SPDst, SPSrc)); - } - // // Only insert ALLOCFRAME if we need to. // @@ -174,30 +147,55 @@ void HexagonFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock::iterator MBBI = prior(MBB.end()); DebugLoc dl = MBBI->getDebugLoc(); // - // Only insert deallocframe if we need to. + // Only insert deallocframe if we need to. Also at -O0. See comment + // in emitPrologue above. // - if (hasFP(MF)) { + if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) { MachineBasicBlock::iterator MBBI = prior(MBB.end()); MachineBasicBlock::iterator MBBI_end = MBB.end(); - // - // For Hexagon, we don't need the frame size. - // - MachineFrameInfo *MFI = MF.getFrameInfo(); - int NumBytes = (int) MFI->getStackSize(); const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); - + // Handle EH_RETURN. + if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) { + assert(MBBI->getOperand(0).isReg() && "Offset should be in register!"); + BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)); + BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr), + Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28); + return; + } // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher // versions. if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPret && !DisableDeallocRet) { - // Remove jumpr node. - MBB.erase(MBBI); + // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC + // instruction if we encounter it. + MachineBasicBlock::iterator BeforeJMPR = + MBB.begin() == MBBI ? MBBI : prior(MBBI); + if (BeforeJMPR != MBBI && + BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) { + // Remove the JMPR node. + MBB.erase(MBBI); + return; + } + // Add dealloc_return. - BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4)) - .addImm(NumBytes); - } else { // Add deallocframe for V2 and V3. - BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)).addImm(NumBytes); + MachineInstrBuilder MIB = + BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4)); + // Transfer the function live-out registers. + MIB->copyImplicitOps(*MBB.getParent(), &*MBBI); + // Remove the JUMPR node. + MBB.erase(MBBI); + } else { // Add deallocframe for V2 and V3, and V4 tail calls. + // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra + // DEALLOCFRAME instruction after it. + MachineBasicBlock::iterator Term = MBB.getFirstTerminator(); + MachineBasicBlock::iterator I = + Term == MBB.begin() ? MBB.end() : prior(Term); + if (I != MBB.end() && + I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4) + return; + + BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)); } } } diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp index d002788..52d5ab2 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -134,7 +134,7 @@ namespace { /// has a computable trip count and, if so, return a value that represents /// the trip count expression. CountValue *getLoopTripCount(MachineLoop *L, - SmallVector<MachineInstr*, 2> &OldInsts); + SmallVectorImpl<MachineInstr *> &OldInsts); /// \brief Return the expression that represents the number of times /// a loop iterates. The function takes the operands that represent the @@ -164,7 +164,7 @@ namespace { /// \brief Return true if the instruction is now dead. bool isDead(const MachineInstr *MI, - SmallVector<MachineInstr*, 1> &DeadPhis) const; + SmallVectorImpl<MachineInstr *> &DeadPhis) const; /// \brief Remove the instruction if it is now dead. void removeIfDead(MachineInstr *MI); @@ -428,7 +428,7 @@ bool HexagonHardwareLoops::findInductionRegister(MachineLoop *L, /// induction variable patterns that are used in the calculation for /// the number of time the loop is executed. CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L, - SmallVector<MachineInstr*, 2> &OldInsts) { + SmallVectorImpl<MachineInstr *> &OldInsts) { MachineBasicBlock *TopMBB = L->getTopBlock(); MachineBasicBlock::pred_iterator PI = TopMBB->pred_begin(); assert(PI != TopMBB->pred_end() && @@ -871,7 +871,7 @@ bool HexagonHardwareLoops::isInvalidLoopOperation( /// \brief - Return true if the loop contains an instruction that inhibits /// the use of the hardware loop function. bool HexagonHardwareLoops::containsInvalidInstruction(MachineLoop *L) const { - const std::vector<MachineBasicBlock*> Blocks = L->getBlocks(); + const std::vector<MachineBasicBlock *> &Blocks = L->getBlocks(); for (unsigned i = 0, e = Blocks.size(); i != e; ++i) { MachineBasicBlock *MBB = Blocks[i]; for (MachineBasicBlock::iterator @@ -890,7 +890,7 @@ bool HexagonHardwareLoops::containsInvalidInstruction(MachineLoop *L) const { /// for inline asm, physical registers and instructions with side effects /// removed. bool HexagonHardwareLoops::isDead(const MachineInstr *MI, - SmallVector<MachineInstr*, 1> &DeadPhis) const { + SmallVectorImpl<MachineInstr *> &DeadPhis) const { // Examine each operand. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index 491ccc4..5ae93284 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -50,15 +50,13 @@ class HexagonDAGToDAGISel : public SelectionDAGISel { // Keep a reference to HexagonTargetMachine. const HexagonTargetMachine& TM; - const HexagonInstrInfo *TII; DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap; public: - explicit HexagonDAGToDAGISel(const HexagonTargetMachine &targetmachine, + explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine, CodeGenOpt::Level OptLevel) : SelectionDAGISel(targetmachine, OptLevel), Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()), - TM(targetmachine), - TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) { + TM(targetmachine) { initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry()); } bool hasNumUsesBelowThresGA(SDNode *N) const; @@ -92,14 +90,14 @@ public: bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset); SDNode *SelectLoad(SDNode *N); - SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl); - SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl); + SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl); + SDNode *SelectIndexedLoad(LoadSDNode *LD, SDLoc dl); SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode, - DebugLoc dl); + SDLoc dl); SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode, - DebugLoc dl); - SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl); - SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl); + SDLoc dl); + SDNode *SelectBaseOffsetStore(StoreSDNode *ST, SDLoc dl); + SDNode *SelectIndexedStore(StoreSDNode *ST, SDLoc dl); SDNode *SelectStore(SDNode *N); SDNode *SelectSHL(SDNode *N); SDNode *SelectSelect(SDNode *N); @@ -180,7 +178,7 @@ inline SDValue XformUToUM1Imm(unsigned Imm) { /// createHexagonISelDag - This pass converts a legalized DAG into a /// Hexagon-specific DAG, ready for instruction scheduling. /// -FunctionPass *llvm::createHexagonISelDag(const HexagonTargetMachine &TM, +FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM, CodeGenOpt::Level OptLevel) { return new HexagonDAGToDAGISel(TM, OptLevel); } @@ -385,7 +383,7 @@ static bool OffsetFitsS11(EVT MemType, int64_t Offset) { // lowering for GlobalAddress nodes has already turned it into a // CONST32. // -SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) { +SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl) { SDValue Chain = LD->getChain(); SDNode* Const32 = LD->getBasePtr().getNode(); unsigned Opcode = 0; @@ -396,7 +394,7 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) { EVT LoadedVT = LD->getMemoryVT(); int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset(); if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) { - MVT PointerTy = TLI.getPointerTy(); + MVT PointerTy = getTargetLowering()->getPointerTy(); const GlobalValue* GV = cast<GlobalAddressSDNode>(Base)->getGlobal(); SDValue TargAddr = @@ -433,7 +431,7 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) { SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode, - DebugLoc dl) + SDLoc dl) { SDValue Chain = LD->getChain(); EVT LoadedVT = LD->getMemoryVT(); @@ -444,8 +442,11 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD, SDValue N1 = LD->getOperand(1); SDValue CPTmpN1_0; SDValue CPTmpN1_1; + if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) && N1.getNode()->getValueType(0) == MVT::i32) { + const HexagonInstrInfo *TII = + static_cast<const HexagonInstrInfo*>(TM.getInstrInfo()); if (TII->isValidAutoIncImm(LoadedVT, Val)) { SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32); SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32, @@ -497,7 +498,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD, SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode, - DebugLoc dl) + SDLoc dl) { SDValue Chain = LD->getChain(); EVT LoadedVT = LD->getMemoryVT(); @@ -508,8 +509,11 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD, SDValue N1 = LD->getOperand(1); SDValue CPTmpN1_0; SDValue CPTmpN1_1; + if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) && N1.getNode()->getValueType(0) == MVT::i32) { + const HexagonInstrInfo *TII = + static_cast<const HexagonInstrInfo*>(TM.getInstrInfo()); if (TII->isValidAutoIncImm(LoadedVT, Val)) { SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); @@ -572,7 +576,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD, } -SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) { +SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) { SDValue Chain = LD->getChain(); SDValue Base = LD->getBasePtr(); SDValue Offset = LD->getOffset(); @@ -586,6 +590,8 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) { bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD); // Figure out the opcode. + const HexagonInstrInfo *TII = + static_cast<const HexagonInstrInfo*>(TM.getInstrInfo()); if (LoadedVT == MVT::i64) { if (TII->isValidAutoIncImm(LoadedVT, Val)) Opcode = Hexagon::POST_LDrid; @@ -667,7 +673,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) { SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) { SDNode *result; - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); LoadSDNode *LD = cast<LoadSDNode>(N); ISD::MemIndexedMode AM = LD->getAddressingMode(); @@ -682,7 +688,7 @@ SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) { } -SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) { +SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) { SDValue Chain = ST->getChain(); SDValue Base = ST->getBasePtr(); SDValue Offset = ST->getOffset(); @@ -694,6 +700,8 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) { // Offset value must be within representable range // and must have correct alignment properties. + const HexagonInstrInfo *TII = + static_cast<const HexagonInstrInfo*>(TM.getInstrInfo()); if (TII->isValidAutoIncImm(StoredVT, Val)) { SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value, Chain}; @@ -751,7 +759,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) { SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST, - DebugLoc dl) { + SDLoc dl) { SDValue Chain = ST->getChain(); SDNode* Const32 = ST->getBasePtr().getNode(); SDValue Value = ST->getValue(); @@ -769,7 +777,7 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST, EVT StoredVT = ST->getMemoryVT(); int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset(); if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) { - MVT PointerTy = TLI.getPointerTy(); + MVT PointerTy = getTargetLowering()->getPointerTy(); const GlobalValue* GV = cast<GlobalAddressSDNode>(Base)->getGlobal(); SDValue TargAddr = @@ -805,7 +813,7 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST, SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); StoreSDNode *ST = cast<StoreSDNode>(N); ISD::MemIndexedMode AM = ST->getAddressingMode(); @@ -818,7 +826,7 @@ SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) { } SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); // // %conv.i = sext i32 %tmp1 to i64 @@ -902,7 +910,7 @@ SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) { SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); SDValue N0 = N->getOperand(0); if (N0.getOpcode() == ISD::SETCC) { SDValue N00 = N0.getOperand(0); @@ -969,7 +977,7 @@ SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) { SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); SDValue Shift = N->getOperand(0); // @@ -1082,7 +1090,7 @@ SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) { SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); if (N->getValueType(0) == MVT::i32) { SDValue Shl_0 = N->getOperand(0); SDValue Shl_1 = N->getOperand(1); @@ -1158,7 +1166,7 @@ SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) { // We want to preserve all the lower 8-bits and, not just 1 LSB bit. // SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); SDNode *IsIntrinsic = N->getOperand(0).getNode(); if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) { unsigned ID = @@ -1201,7 +1209,7 @@ SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) { // and lowering to the actual intrinsic. // SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID); @@ -1209,6 +1217,8 @@ SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) { // as at least one of the operands. if (IntrinsicWithPred) { SmallVector<SDValue, 8> Ops; + const HexagonInstrInfo *TII = + static_cast<const HexagonInstrInfo*>(TM.getInstrInfo()); const MCInstrDesc &MCID = TII->get(IntrinsicWithPred); const TargetRegisterInfo *TRI = TM.getRegisterInfo(); @@ -1251,7 +1261,7 @@ SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) { // Map floating point constant values. // SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N); APFloat APF = CN->getValueAPF(); if (N->getValueType(0) == MVT::f32) { @@ -1271,7 +1281,7 @@ SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) { // Map predicate true (encoded as -1 in LLVM) to a XOR. // SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); if (N->getValueType(0) == MVT::i1) { SDNode* Result; int32_t Val = cast<ConstantSDNode>(N)->getSExtValue(); @@ -1310,7 +1320,7 @@ SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) { // Map add followed by a asr -> asr +=. // SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); if (N->getValueType(0) != MVT::i32) { return SelectCode(N); } @@ -1662,7 +1672,7 @@ bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R, !hasNumUsesBelowThresGA(GA)) return false; R = CurDAG->getTargetGlobalAddress(GA->getGlobal(), - Const->getDebugLoc(), + SDLoc(Const), N.getValueType(), GA->getOffset() + (uint64_t)Const->getSExtValue()); diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index 0e5b8dc..1374179 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -39,13 +39,24 @@ using namespace llvm; -const unsigned Hexagon_MAX_RET_SIZE = 64; - static cl::opt<bool> EmitJumpTables("hexagon-emit-jump-tables", cl::init(true), cl::Hidden, cl::desc("Control jump table emission on Hexagon target")); -int NumNamedVarArgParams = -1; +namespace { +class HexagonCCState : public CCState { + int NumNamedVarArgParams; + +public: + HexagonCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, + const TargetMachine &TM, SmallVectorImpl<CCValAssign> &locs, + LLVMContext &C, int NumNamedVarArgParams) + : CCState(CC, isVarArg, MF, TM, locs, C), + NumNamedVarArgParams(NumNamedVarArgParams) {} + + int getNumNamedVarArgParams() const { return NumNamedVarArgParams; } +}; +} // Implement calling convention for Hexagon. static bool @@ -82,12 +93,13 @@ static bool CC_Hexagon_VarArg (unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State) { + HexagonCCState &HState = static_cast<HexagonCCState &>(State); // NumNamedVarArgParams can not be zero for a VarArg function. - assert ( (NumNamedVarArgParams > 0) && - "NumNamedVarArgParams is not bigger than zero."); + assert((HState.getNumNamedVarArgParams() > 0) && + "NumNamedVarArgParams is not bigger than zero."); - if ( (int)ValNo < NumNamedVarArgParams ) { + if ((int)ValNo < HState.getNumNamedVarArgParams()) { // Deal with named arguments. return CC_Hexagon(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State); } @@ -285,7 +297,7 @@ const { static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, - DebugLoc dl) { + SDLoc dl) { SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i32); return DAG.getMemcpy(Chain, dl, Dst, Src, SizeNode, Flags.getByValAlign(), @@ -302,7 +314,7 @@ HexagonTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, - DebugLoc dl, SelectionDAG &DAG) const { + SDLoc dl, SelectionDAG &DAG) const { // CCValAssign - represent the assignment of the return value to locations. SmallVector<CCValAssign, 16> RVLocs; @@ -351,7 +363,7 @@ HexagonTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, const SmallVectorImpl<SDValue> &OutVals, SDValue Callee) const { @@ -382,10 +394,10 @@ SDValue HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const { SelectionDAG &DAG = CLI.DAG; - DebugLoc &dl = CLI.DL; - SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs; - SmallVector<SDValue, 32> &OutVals = CLI.OutVals; - SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins; + SDLoc &dl = CLI.DL; + SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; + SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; + SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; SDValue Chain = CLI.Chain; SDValue Callee = CLI.Callee; bool &isTailCall = CLI.IsTailCall; @@ -394,13 +406,8 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, bool IsStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet(); - // Analyze operands of the call, assigning locations to each operand. - SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), - getTargetMachine(), ArgLocs, *DAG.getContext()); - // Check for varargs. - NumNamedVarArgParams = -1; + int NumNamedVarArgParams = -1; if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Callee)) { const Function* CalleeFn = NULL; @@ -417,6 +424,12 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, } } + // Analyze operands of the call, assigning locations to each operand. + SmallVector<CCValAssign, 16> ArgLocs; + HexagonCCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), + getTargetMachine(), ArgLocs, *DAG.getContext(), + NumNamedVarArgParams); + if (NumNamedVarArgParams > 0) CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon_VarArg); else @@ -513,7 +526,8 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, if (!isTailCall) Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumBytes, - getPointerTy(), true)); + getPointerTy(), true), + dl); // Build a sequence of copy-to-reg nodes chained together with token // chain and flag operands which copy the outgoing args into registers. @@ -588,7 +602,7 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // Create the CALLSEQ_END node. Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), - DAG.getIntPtrConstant(0, true), InFlag); + DAG.getIntPtrConstant(0, true), InFlag, dl); InFlag = Chain.getValue(1); // Handle result values, copying them out of physregs into vregs that we @@ -730,7 +744,7 @@ LowerBR_JT(SDValue Op, SelectionDAG &DAG) const SDValue Chain = Op.getOperand(0); SDValue Table = Op.getOperand(1); SDValue Index = Op.getOperand(2); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); JumpTableSDNode *JT = cast<JumpTableSDNode>(Table); unsigned JTI = JT->getIndex(); MachineFunction &MF = DAG.getMachineFunction(); @@ -766,7 +780,7 @@ HexagonTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); SDValue Size = Op.getOperand(1); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); unsigned SPReg = getStackPointerRegisterToSaveRestore(); @@ -812,7 +826,7 @@ HexagonTargetLowering::LowerFormalArguments(SDValue Chain, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { @@ -925,7 +939,7 @@ HexagonTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { HexagonMachineFunctionInfo *QFI = MF.getInfo<HexagonMachineFunctionInfo>(); SDValue Addr = DAG.getFrameIndex(QFI->getVarArgsFrameIndex(), MVT::i32); const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); - return DAG.getStore(Op.getOperand(0), Op.getDebugLoc(), Addr, + return DAG.getStore(Op.getOperand(0), SDLoc(Op), Addr, Op.getOperand(1), MachinePointerInfo(SV), false, false, 0); } @@ -937,7 +951,7 @@ HexagonTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { SDValue CC = Op.getOperand(4); SDValue TrueVal = Op.getOperand(2); SDValue FalseVal = Op.getOperand(3); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); SDNode* OpNode = Op.getNode(); EVT SVT = OpNode->getValueType(0); @@ -948,8 +962,7 @@ HexagonTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { SDValue HexagonTargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) const { EVT ValTy = Op.getValueType(); - - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); SDValue Res; if (CP->isMachineConstantPoolEntry()) @@ -969,7 +982,7 @@ HexagonTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const { MFI->setReturnAddressIsTaken(true); EVT VT = Op.getValueType(); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); if (Depth) { SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); @@ -991,7 +1004,7 @@ HexagonTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { MFI->setFrameAddressIsTaken(true); EVT VT = Op.getValueType(); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, TRI->getFrameRegister(), VT); @@ -1004,7 +1017,7 @@ HexagonTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { SDValue HexagonTargetLowering::LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const { - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); return DAG.getNode(HexagonISD::BARRIER, dl, MVT::Other, Op.getOperand(0)); } @@ -1014,7 +1027,7 @@ SDValue HexagonTargetLowering::LowerGLOBALADDRESS(SDValue Op, SDValue Result; const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); Result = DAG.getTargetGlobalAddress(GV, dl, getPointerTy(), Offset); const HexagonTargetObjectFile &TLOF = @@ -1030,7 +1043,7 @@ SDValue HexagonTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const { const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); SDValue BA_SD = DAG.getTargetBlockAddress(BA, MVT::i32); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); return DAG.getNode(HexagonISD::CONST32_GP, dl, getPointerTy(), BA_SD); } @@ -1361,7 +1374,6 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine // Increase jump tables cutover to 5, was 4. setMinimumJumpTableEntries(5); - setOperationAction(ISD::BR_CC, MVT::Other, Expand); setOperationAction(ISD::BR_CC, MVT::f32, Expand); setOperationAction(ISD::BR_CC, MVT::f64, Expand); setOperationAction(ISD::BR_CC, MVT::i1, Expand); @@ -1429,11 +1441,6 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); - setOperationAction(ISD::EXCEPTIONADDR, MVT::i64, Expand); - setOperationAction(ISD::EHSELECTION, MVT::i64, Expand); - setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand); - setOperationAction(ISD::EHSELECTION, MVT::i32, Expand); - setOperationAction(ISD::EH_RETURN, MVT::Other, Custom); if (TM.getSubtargetImpl()->isSubtargetV2()) { @@ -1510,12 +1517,25 @@ bool HexagonTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const { return ((VT1.getSimpleVT() == MVT::i64) && (VT2.getSimpleVT() == MVT::i32)); } +bool +HexagonTargetLowering::allowTruncateForTailCall(Type *Ty1, Type *Ty2) const { + // Assuming the caller does not have either a signext or zeroext modifier, and + // only one value is accepted, any reasonable truncation is allowed. + if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy()) + return false; + + // FIXME: in principle up to 64-bit could be made safe, but it would be very + // fragile at the moment: any support for multiple value returns would be + // liable to disallow tail calls involving i64 -> iN truncation in many cases. + return Ty1->getPrimitiveSizeInBits() <= 32; +} + SDValue HexagonTargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); SDValue Offset = Op.getOperand(1); SDValue Handler = Op.getOperand(2); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); // Mark function as containing a call to EH_RETURN. HexagonMachineFunctionInfo *FuncInfo = @@ -1591,11 +1611,11 @@ const { std::pair<unsigned, const TargetRegisterClass*> HexagonTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, - EVT VT) const { + MVT VT) const { if (Constraint.size() == 1) { switch (Constraint[0]) { case 'r': // R0-R31 - switch (VT.getSimpleVT().SimpleTy) { + switch (VT.SimpleTy) { default: llvm_unreachable("getRegForInlineAsmConstraint Unhandled data type"); case MVT::i32: diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.h index bb1acc1..73da226 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.h +++ b/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.h @@ -95,6 +95,8 @@ namespace llvm { virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const; virtual bool isTruncateFree(EVT VT1, EVT VT2) const; + virtual bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const; + virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; virtual const char *getTargetNodeName(unsigned Opcode) const; @@ -106,7 +108,7 @@ namespace llvm { SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const; SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; @@ -117,7 +119,7 @@ namespace llvm { SDValue LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, const SmallVectorImpl<SDValue> &OutVals, SDValue Callee) const; @@ -131,7 +133,7 @@ namespace llvm { CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, - DebugLoc dl, SelectionDAG &DAG) const; + SDLoc dl, SelectionDAG &DAG) const; virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, @@ -139,8 +141,11 @@ namespace llvm { SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; - virtual EVT getSetCCResultType(EVT VT) const { - return MVT::i1; + virtual EVT getSetCCResultType(LLVMContext &C, EVT VT) const { + if (!VT.isVector()) + return MVT::i1; + else + return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements()); } virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, @@ -150,7 +155,7 @@ namespace llvm { std::pair<unsigned, const TargetRegisterClass*> getRegForInlineAsmConstraint(const std::string &Constraint, - EVT VT) const; + MVT VT) const; // Intrinsics virtual SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormats.td b/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormats.td index 587fa7d..d25bfa8 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormats.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrFormats.td @@ -54,6 +54,7 @@ def AbsoluteSet : AddrModeType<2>; // Absolute set addressing mode def BaseImmOffset : AddrModeType<3>; // Indirect with offset def BaseLongOffset : AddrModeType<4>; // Indirect with long offset def BaseRegOffset : AddrModeType<5>; // Indirect with register offset +def PostInc : AddrModeType<6>; // Post increment addressing mode class MemAccessSize<bits<3> value> { bits<3> Value = value; @@ -62,7 +63,7 @@ class MemAccessSize<bits<3> value> { def NoMemAccess : MemAccessSize<0>;// Not a memory acces instruction. def ByteAccess : MemAccessSize<1>;// Byte access instruction (memb). def HalfWordAccess : MemAccessSize<2>;// Half word access instruction (memh). -def WordAccess : MemAccessSize<3>;// Word access instrution (memw). +def WordAccess : MemAccessSize<3>;// Word access instruction (memw). def DoubleWordAccess : MemAccessSize<4>;// Double word access instruction (memd) @@ -157,6 +158,7 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern, string CextOpcode = ""; string PredSense = ""; string PNewValue = ""; + string NValueST = ""; // Set to "true" for new-value stores. string InputType = ""; // Input is "imm" or "reg" type. string isMEMri = "false"; // Set to "true" for load/store with MEMri operand. string isFloat = "false"; // Set to "true" for the floating-point load/store. @@ -165,6 +167,7 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern, let PredSense = !if(isPredicated, !if(isPredicatedFalse, "false", "true"), ""); let PNewValue = !if(isPredicatedNew, "new", ""); + let NValueST = !if(isNVStore, "true", "false"); // *** Must match MCTargetDesc/HexagonBaseInfo.h *** } diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index f114170..6b97609 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -26,7 +26,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" -#define GET_INSTRINFO_CTOR +#define GET_INSTRINFO_CTOR_DTOR #define GET_INSTRMAP_INFO #include "HexagonGenInstrInfo.inc" #include "HexagonGenDFAPacketizer.inc" @@ -55,10 +55,12 @@ const int Hexagon_MEMH_AUTOINC_MIN = -16; const int Hexagon_MEMB_AUTOINC_MAX = 7; const int Hexagon_MEMB_AUTOINC_MIN = -8; +// Pin the vtable to this file. +void HexagonInstrInfo::anchor() {} HexagonInstrInfo::HexagonInstrInfo(HexagonSubtarget &ST) : HexagonGenInstrInfo(Hexagon::ADJCALLSTACKDOWN, Hexagon::ADJCALLSTACKUP), - RI(ST, *this), Subtarget(ST) { + RI(ST), Subtarget(ST) { } @@ -558,16 +560,6 @@ MachineInstr *HexagonInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, return(0); } -MachineInstr* -HexagonInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, - int FrameIx, uint64_t Offset, - const MDNode *MDPtr, - DebugLoc DL) const { - MachineInstrBuilder MIB = BuildMI(MF, DL, get(Hexagon::DBG_VALUE)) - .addImm(0).addImm(Offset).addMetadata(MDPtr); - return &*MIB; -} - unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const { MachineRegisterInfo &RegInfo = MF->getRegInfo(); @@ -630,188 +622,6 @@ bool HexagonInstrInfo::isBranch (const MachineInstr *MI) const { return MI->getDesc().isBranch(); } -bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const { - switch (MI->getOpcode()) { - default: return false; - // Store Byte - case Hexagon::STrib_nv_V4: - case Hexagon::STrib_indexed_nv_V4: - case Hexagon::STrib_indexed_shl_nv_V4: - case Hexagon::STrib_shl_nv_V4: - case Hexagon::STb_GP_nv_V4: - case Hexagon::POST_STbri_nv_V4: - case Hexagon::STrib_cPt_nv_V4: - case Hexagon::STrib_cdnPt_nv_V4: - case Hexagon::STrib_cNotPt_nv_V4: - case Hexagon::STrib_cdnNotPt_nv_V4: - case Hexagon::STrib_indexed_cPt_nv_V4: - case Hexagon::STrib_indexed_cdnPt_nv_V4: - case Hexagon::STrib_indexed_cNotPt_nv_V4: - case Hexagon::STrib_indexed_cdnNotPt_nv_V4: - case Hexagon::STrib_indexed_shl_cPt_nv_V4: - case Hexagon::STrib_indexed_shl_cdnPt_nv_V4: - case Hexagon::STrib_indexed_shl_cNotPt_nv_V4: - case Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4: - case Hexagon::POST_STbri_cPt_nv_V4: - case Hexagon::POST_STbri_cdnPt_nv_V4: - case Hexagon::POST_STbri_cNotPt_nv_V4: - case Hexagon::POST_STbri_cdnNotPt_nv_V4: - case Hexagon::STb_GP_cPt_nv_V4: - case Hexagon::STb_GP_cNotPt_nv_V4: - case Hexagon::STb_GP_cdnPt_nv_V4: - case Hexagon::STb_GP_cdnNotPt_nv_V4: - case Hexagon::STrib_abs_nv_V4: - case Hexagon::STrib_abs_cPt_nv_V4: - case Hexagon::STrib_abs_cdnPt_nv_V4: - case Hexagon::STrib_abs_cNotPt_nv_V4: - case Hexagon::STrib_abs_cdnNotPt_nv_V4: - - // Store Halfword - case Hexagon::STrih_nv_V4: - case Hexagon::STrih_indexed_nv_V4: - case Hexagon::STrih_indexed_shl_nv_V4: - case Hexagon::STrih_shl_nv_V4: - case Hexagon::STh_GP_nv_V4: - case Hexagon::POST_SThri_nv_V4: - case Hexagon::STrih_cPt_nv_V4: - case Hexagon::STrih_cdnPt_nv_V4: - case Hexagon::STrih_cNotPt_nv_V4: - case Hexagon::STrih_cdnNotPt_nv_V4: - case Hexagon::STrih_indexed_cPt_nv_V4: - case Hexagon::STrih_indexed_cdnPt_nv_V4: - case Hexagon::STrih_indexed_cNotPt_nv_V4: - case Hexagon::STrih_indexed_cdnNotPt_nv_V4: - case Hexagon::STrih_indexed_shl_cPt_nv_V4: - case Hexagon::STrih_indexed_shl_cdnPt_nv_V4: - case Hexagon::STrih_indexed_shl_cNotPt_nv_V4: - case Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4: - case Hexagon::POST_SThri_cPt_nv_V4: - case Hexagon::POST_SThri_cdnPt_nv_V4: - case Hexagon::POST_SThri_cNotPt_nv_V4: - case Hexagon::POST_SThri_cdnNotPt_nv_V4: - case Hexagon::STh_GP_cPt_nv_V4: - case Hexagon::STh_GP_cNotPt_nv_V4: - case Hexagon::STh_GP_cdnPt_nv_V4: - case Hexagon::STh_GP_cdnNotPt_nv_V4: - case Hexagon::STrih_abs_nv_V4: - case Hexagon::STrih_abs_cPt_nv_V4: - case Hexagon::STrih_abs_cdnPt_nv_V4: - case Hexagon::STrih_abs_cNotPt_nv_V4: - case Hexagon::STrih_abs_cdnNotPt_nv_V4: - - // Store Word - case Hexagon::STriw_nv_V4: - case Hexagon::STriw_indexed_nv_V4: - case Hexagon::STriw_indexed_shl_nv_V4: - case Hexagon::STriw_shl_nv_V4: - case Hexagon::STw_GP_nv_V4: - case Hexagon::POST_STwri_nv_V4: - case Hexagon::STriw_cPt_nv_V4: - case Hexagon::STriw_cdnPt_nv_V4: - case Hexagon::STriw_cNotPt_nv_V4: - case Hexagon::STriw_cdnNotPt_nv_V4: - case Hexagon::STriw_indexed_cPt_nv_V4: - case Hexagon::STriw_indexed_cdnPt_nv_V4: - case Hexagon::STriw_indexed_cNotPt_nv_V4: - case Hexagon::STriw_indexed_cdnNotPt_nv_V4: - case Hexagon::STriw_indexed_shl_cPt_nv_V4: - case Hexagon::STriw_indexed_shl_cdnPt_nv_V4: - case Hexagon::STriw_indexed_shl_cNotPt_nv_V4: - case Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4: - case Hexagon::POST_STwri_cPt_nv_V4: - case Hexagon::POST_STwri_cdnPt_nv_V4: - case Hexagon::POST_STwri_cNotPt_nv_V4: - case Hexagon::POST_STwri_cdnNotPt_nv_V4: - case Hexagon::STw_GP_cPt_nv_V4: - case Hexagon::STw_GP_cNotPt_nv_V4: - case Hexagon::STw_GP_cdnPt_nv_V4: - case Hexagon::STw_GP_cdnNotPt_nv_V4: - case Hexagon::STriw_abs_nv_V4: - case Hexagon::STriw_abs_cPt_nv_V4: - case Hexagon::STriw_abs_cdnPt_nv_V4: - case Hexagon::STriw_abs_cNotPt_nv_V4: - case Hexagon::STriw_abs_cdnNotPt_nv_V4: - return true; - } -} - -bool HexagonInstrInfo::isPostIncrement (const MachineInstr* MI) const { - switch (MI->getOpcode()) - { - default: return false; - // Load Byte - case Hexagon::POST_LDrib: - case Hexagon::POST_LDrib_cPt: - case Hexagon::POST_LDrib_cNotPt: - case Hexagon::POST_LDrib_cdnPt_V4: - case Hexagon::POST_LDrib_cdnNotPt_V4: - - // Load unsigned byte - case Hexagon::POST_LDriub: - case Hexagon::POST_LDriub_cPt: - case Hexagon::POST_LDriub_cNotPt: - case Hexagon::POST_LDriub_cdnPt_V4: - case Hexagon::POST_LDriub_cdnNotPt_V4: - - // Load halfword - case Hexagon::POST_LDrih: - case Hexagon::POST_LDrih_cPt: - case Hexagon::POST_LDrih_cNotPt: - case Hexagon::POST_LDrih_cdnPt_V4: - case Hexagon::POST_LDrih_cdnNotPt_V4: - - // Load unsigned halfword - case Hexagon::POST_LDriuh: - case Hexagon::POST_LDriuh_cPt: - case Hexagon::POST_LDriuh_cNotPt: - case Hexagon::POST_LDriuh_cdnPt_V4: - case Hexagon::POST_LDriuh_cdnNotPt_V4: - - // Load word - case Hexagon::POST_LDriw: - case Hexagon::POST_LDriw_cPt: - case Hexagon::POST_LDriw_cNotPt: - case Hexagon::POST_LDriw_cdnPt_V4: - case Hexagon::POST_LDriw_cdnNotPt_V4: - - // Load double word - case Hexagon::POST_LDrid: - case Hexagon::POST_LDrid_cPt: - case Hexagon::POST_LDrid_cNotPt: - case Hexagon::POST_LDrid_cdnPt_V4: - case Hexagon::POST_LDrid_cdnNotPt_V4: - - // Store byte - case Hexagon::POST_STbri: - case Hexagon::POST_STbri_cPt: - case Hexagon::POST_STbri_cNotPt: - case Hexagon::POST_STbri_cdnPt_V4: - case Hexagon::POST_STbri_cdnNotPt_V4: - - // Store halfword - case Hexagon::POST_SThri: - case Hexagon::POST_SThri_cPt: - case Hexagon::POST_SThri_cNotPt: - case Hexagon::POST_SThri_cdnPt_V4: - case Hexagon::POST_SThri_cdnNotPt_V4: - - // Store word - case Hexagon::POST_STwri: - case Hexagon::POST_STwri_cPt: - case Hexagon::POST_STwri_cNotPt: - case Hexagon::POST_STwri_cdnPt_V4: - case Hexagon::POST_STwri_cdnNotPt_V4: - - // Store double word - case Hexagon::POST_STdri: - case Hexagon::POST_STdri_cPt: - case Hexagon::POST_STdri_cNotPt: - case Hexagon::POST_STdri_cdnPt_V4: - case Hexagon::POST_STdri_cdnNotPt_V4: - return true; - } -} - bool HexagonInstrInfo::isNewValueInst(const MachineInstr *MI) const { if (isNewValueJump(MI)) return true; @@ -917,19 +727,6 @@ bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const { // cPt ---> cNotPt // cNotPt ---> cPt // -// however, these inversiones are NOT included: -// -// cdnPt -X-> cdnNotPt -// cdnNotPt -X-> cdnPt -// cPt_nv -X-> cNotPt_nv (new value stores) -// cNotPt_nv -X-> cPt_nv (new value stores) -// -// because only the following transformations are allowed: -// -// cNotPt ---> cdnNotPt -// cPt ---> cdnPt -// cNotPt ---> cNotPt_nv -// cPt ---> cPt_nv unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const { int InvPredOpcode; InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc) @@ -939,332 +736,12 @@ unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const { switch(Opc) { default: llvm_unreachable("Unexpected predicated instruction"); - case Hexagon::TFR_cPt: - return Hexagon::TFR_cNotPt; - case Hexagon::TFR_cNotPt: - return Hexagon::TFR_cPt; - - case Hexagon::TFRI_cPt: - return Hexagon::TFRI_cNotPt; - case Hexagon::TFRI_cNotPt: - return Hexagon::TFRI_cPt; - - case Hexagon::JMP_t: - return Hexagon::JMP_f; - case Hexagon::JMP_f: - return Hexagon::JMP_t; - - case Hexagon::ADD_ri_cPt: - return Hexagon::ADD_ri_cNotPt; - case Hexagon::ADD_ri_cNotPt: - return Hexagon::ADD_ri_cPt; - - case Hexagon::ADD_rr_cPt: - return Hexagon::ADD_rr_cNotPt; - case Hexagon::ADD_rr_cNotPt: - return Hexagon::ADD_rr_cPt; - - case Hexagon::XOR_rr_cPt: - return Hexagon::XOR_rr_cNotPt; - case Hexagon::XOR_rr_cNotPt: - return Hexagon::XOR_rr_cPt; - - case Hexagon::AND_rr_cPt: - return Hexagon::AND_rr_cNotPt; - case Hexagon::AND_rr_cNotPt: - return Hexagon::AND_rr_cPt; - - case Hexagon::OR_rr_cPt: - return Hexagon::OR_rr_cNotPt; - case Hexagon::OR_rr_cNotPt: - return Hexagon::OR_rr_cPt; - - case Hexagon::SUB_rr_cPt: - return Hexagon::SUB_rr_cNotPt; - case Hexagon::SUB_rr_cNotPt: - return Hexagon::SUB_rr_cPt; - case Hexagon::COMBINE_rr_cPt: return Hexagon::COMBINE_rr_cNotPt; case Hexagon::COMBINE_rr_cNotPt: return Hexagon::COMBINE_rr_cPt; - case Hexagon::ASLH_cPt_V4: - return Hexagon::ASLH_cNotPt_V4; - case Hexagon::ASLH_cNotPt_V4: - return Hexagon::ASLH_cPt_V4; - - case Hexagon::ASRH_cPt_V4: - return Hexagon::ASRH_cNotPt_V4; - case Hexagon::ASRH_cNotPt_V4: - return Hexagon::ASRH_cPt_V4; - - case Hexagon::SXTB_cPt_V4: - return Hexagon::SXTB_cNotPt_V4; - case Hexagon::SXTB_cNotPt_V4: - return Hexagon::SXTB_cPt_V4; - - case Hexagon::SXTH_cPt_V4: - return Hexagon::SXTH_cNotPt_V4; - case Hexagon::SXTH_cNotPt_V4: - return Hexagon::SXTH_cPt_V4; - - case Hexagon::ZXTB_cPt_V4: - return Hexagon::ZXTB_cNotPt_V4; - case Hexagon::ZXTB_cNotPt_V4: - return Hexagon::ZXTB_cPt_V4; - - case Hexagon::ZXTH_cPt_V4: - return Hexagon::ZXTH_cNotPt_V4; - case Hexagon::ZXTH_cNotPt_V4: - return Hexagon::ZXTH_cPt_V4; - - - case Hexagon::JMPR_t: - return Hexagon::JMPR_f; - case Hexagon::JMPR_f: - return Hexagon::JMPR_t; - - // V4 indexed+scaled load. - case Hexagon::LDrid_indexed_shl_cPt_V4: - return Hexagon::LDrid_indexed_shl_cNotPt_V4; - case Hexagon::LDrid_indexed_shl_cNotPt_V4: - return Hexagon::LDrid_indexed_shl_cPt_V4; - - case Hexagon::LDrib_indexed_shl_cPt_V4: - return Hexagon::LDrib_indexed_shl_cNotPt_V4; - case Hexagon::LDrib_indexed_shl_cNotPt_V4: - return Hexagon::LDrib_indexed_shl_cPt_V4; - - case Hexagon::LDriub_indexed_shl_cPt_V4: - return Hexagon::LDriub_indexed_shl_cNotPt_V4; - case Hexagon::LDriub_indexed_shl_cNotPt_V4: - return Hexagon::LDriub_indexed_shl_cPt_V4; - - case Hexagon::LDrih_indexed_shl_cPt_V4: - return Hexagon::LDrih_indexed_shl_cNotPt_V4; - case Hexagon::LDrih_indexed_shl_cNotPt_V4: - return Hexagon::LDrih_indexed_shl_cPt_V4; - - case Hexagon::LDriuh_indexed_shl_cPt_V4: - return Hexagon::LDriuh_indexed_shl_cNotPt_V4; - case Hexagon::LDriuh_indexed_shl_cNotPt_V4: - return Hexagon::LDriuh_indexed_shl_cPt_V4; - - case Hexagon::LDriw_indexed_shl_cPt_V4: - return Hexagon::LDriw_indexed_shl_cNotPt_V4; - case Hexagon::LDriw_indexed_shl_cNotPt_V4: - return Hexagon::LDriw_indexed_shl_cPt_V4; - - // Byte. - case Hexagon::POST_STbri_cPt: - return Hexagon::POST_STbri_cNotPt; - case Hexagon::POST_STbri_cNotPt: - return Hexagon::POST_STbri_cPt; - - case Hexagon::STrib_cPt: - return Hexagon::STrib_cNotPt; - case Hexagon::STrib_cNotPt: - return Hexagon::STrib_cPt; - - case Hexagon::STrib_indexed_cPt: - return Hexagon::STrib_indexed_cNotPt; - case Hexagon::STrib_indexed_cNotPt: - return Hexagon::STrib_indexed_cPt; - - case Hexagon::STrib_imm_cPt_V4: - return Hexagon::STrib_imm_cNotPt_V4; - case Hexagon::STrib_imm_cNotPt_V4: - return Hexagon::STrib_imm_cPt_V4; - - case Hexagon::STrib_indexed_shl_cPt_V4: - return Hexagon::STrib_indexed_shl_cNotPt_V4; - case Hexagon::STrib_indexed_shl_cNotPt_V4: - return Hexagon::STrib_indexed_shl_cPt_V4; - - // Halfword. - case Hexagon::POST_SThri_cPt: - return Hexagon::POST_SThri_cNotPt; - case Hexagon::POST_SThri_cNotPt: - return Hexagon::POST_SThri_cPt; - - case Hexagon::STrih_cPt: - return Hexagon::STrih_cNotPt; - case Hexagon::STrih_cNotPt: - return Hexagon::STrih_cPt; - - case Hexagon::STrih_indexed_cPt: - return Hexagon::STrih_indexed_cNotPt; - case Hexagon::STrih_indexed_cNotPt: - return Hexagon::STrih_indexed_cPt; - - case Hexagon::STrih_imm_cPt_V4: - return Hexagon::STrih_imm_cNotPt_V4; - case Hexagon::STrih_imm_cNotPt_V4: - return Hexagon::STrih_imm_cPt_V4; - - case Hexagon::STrih_indexed_shl_cPt_V4: - return Hexagon::STrih_indexed_shl_cNotPt_V4; - case Hexagon::STrih_indexed_shl_cNotPt_V4: - return Hexagon::STrih_indexed_shl_cPt_V4; - - // Word. - case Hexagon::POST_STwri_cPt: - return Hexagon::POST_STwri_cNotPt; - case Hexagon::POST_STwri_cNotPt: - return Hexagon::POST_STwri_cPt; - - case Hexagon::STriw_cPt: - return Hexagon::STriw_cNotPt; - case Hexagon::STriw_cNotPt: - return Hexagon::STriw_cPt; - - case Hexagon::STriw_indexed_cPt: - return Hexagon::STriw_indexed_cNotPt; - case Hexagon::STriw_indexed_cNotPt: - return Hexagon::STriw_indexed_cPt; - - case Hexagon::STriw_indexed_shl_cPt_V4: - return Hexagon::STriw_indexed_shl_cNotPt_V4; - case Hexagon::STriw_indexed_shl_cNotPt_V4: - return Hexagon::STriw_indexed_shl_cPt_V4; - - case Hexagon::STriw_imm_cPt_V4: - return Hexagon::STriw_imm_cNotPt_V4; - case Hexagon::STriw_imm_cNotPt_V4: - return Hexagon::STriw_imm_cPt_V4; - - // Double word. - case Hexagon::POST_STdri_cPt: - return Hexagon::POST_STdri_cNotPt; - case Hexagon::POST_STdri_cNotPt: - return Hexagon::POST_STdri_cPt; - - case Hexagon::STrid_cPt: - return Hexagon::STrid_cNotPt; - case Hexagon::STrid_cNotPt: - return Hexagon::STrid_cPt; - - case Hexagon::STrid_indexed_cPt: - return Hexagon::STrid_indexed_cNotPt; - case Hexagon::STrid_indexed_cNotPt: - return Hexagon::STrid_indexed_cPt; - - case Hexagon::STrid_indexed_shl_cPt_V4: - return Hexagon::STrid_indexed_shl_cNotPt_V4; - case Hexagon::STrid_indexed_shl_cNotPt_V4: - return Hexagon::STrid_indexed_shl_cPt_V4; - - // V4 Store to global address. - case Hexagon::STd_GP_cPt_V4: - return Hexagon::STd_GP_cNotPt_V4; - case Hexagon::STd_GP_cNotPt_V4: - return Hexagon::STd_GP_cPt_V4; - - case Hexagon::STb_GP_cPt_V4: - return Hexagon::STb_GP_cNotPt_V4; - case Hexagon::STb_GP_cNotPt_V4: - return Hexagon::STb_GP_cPt_V4; - - case Hexagon::STh_GP_cPt_V4: - return Hexagon::STh_GP_cNotPt_V4; - case Hexagon::STh_GP_cNotPt_V4: - return Hexagon::STh_GP_cPt_V4; - - case Hexagon::STw_GP_cPt_V4: - return Hexagon::STw_GP_cNotPt_V4; - case Hexagon::STw_GP_cNotPt_V4: - return Hexagon::STw_GP_cPt_V4; - - // Load. - case Hexagon::LDrid_cPt: - return Hexagon::LDrid_cNotPt; - case Hexagon::LDrid_cNotPt: - return Hexagon::LDrid_cPt; - - case Hexagon::LDriw_cPt: - return Hexagon::LDriw_cNotPt; - case Hexagon::LDriw_cNotPt: - return Hexagon::LDriw_cPt; - - case Hexagon::LDrih_cPt: - return Hexagon::LDrih_cNotPt; - case Hexagon::LDrih_cNotPt: - return Hexagon::LDrih_cPt; - - case Hexagon::LDriuh_cPt: - return Hexagon::LDriuh_cNotPt; - case Hexagon::LDriuh_cNotPt: - return Hexagon::LDriuh_cPt; - - case Hexagon::LDrib_cPt: - return Hexagon::LDrib_cNotPt; - case Hexagon::LDrib_cNotPt: - return Hexagon::LDrib_cPt; - - case Hexagon::LDriub_cPt: - return Hexagon::LDriub_cNotPt; - case Hexagon::LDriub_cNotPt: - return Hexagon::LDriub_cPt; - - // Load Indexed. - case Hexagon::LDrid_indexed_cPt: - return Hexagon::LDrid_indexed_cNotPt; - case Hexagon::LDrid_indexed_cNotPt: - return Hexagon::LDrid_indexed_cPt; - - case Hexagon::LDriw_indexed_cPt: - return Hexagon::LDriw_indexed_cNotPt; - case Hexagon::LDriw_indexed_cNotPt: - return Hexagon::LDriw_indexed_cPt; - - case Hexagon::LDrih_indexed_cPt: - return Hexagon::LDrih_indexed_cNotPt; - case Hexagon::LDrih_indexed_cNotPt: - return Hexagon::LDrih_indexed_cPt; - - case Hexagon::LDriuh_indexed_cPt: - return Hexagon::LDriuh_indexed_cNotPt; - case Hexagon::LDriuh_indexed_cNotPt: - return Hexagon::LDriuh_indexed_cPt; - - case Hexagon::LDrib_indexed_cPt: - return Hexagon::LDrib_indexed_cNotPt; - case Hexagon::LDrib_indexed_cNotPt: - return Hexagon::LDrib_indexed_cPt; - - case Hexagon::LDriub_indexed_cPt: - return Hexagon::LDriub_indexed_cNotPt; - case Hexagon::LDriub_indexed_cNotPt: - return Hexagon::LDriub_indexed_cPt; - - // Post Inc Load. - case Hexagon::POST_LDrid_cPt: - return Hexagon::POST_LDrid_cNotPt; - case Hexagon::POST_LDriw_cNotPt: - return Hexagon::POST_LDriw_cPt; - - case Hexagon::POST_LDrih_cPt: - return Hexagon::POST_LDrih_cNotPt; - case Hexagon::POST_LDrih_cNotPt: - return Hexagon::POST_LDrih_cPt; - - case Hexagon::POST_LDriuh_cPt: - return Hexagon::POST_LDriuh_cNotPt; - case Hexagon::POST_LDriuh_cNotPt: - return Hexagon::POST_LDriuh_cPt; - - case Hexagon::POST_LDrib_cPt: - return Hexagon::POST_LDrib_cNotPt; - case Hexagon::POST_LDrib_cNotPt: - return Hexagon::POST_LDrib_cPt; - - case Hexagon::POST_LDriub_cPt: - return Hexagon::POST_LDriub_cNotPt; - case Hexagon::POST_LDriub_cNotPt: - return Hexagon::POST_LDriub_cPt; - - // Dealloc_return. + // Dealloc_return. case Hexagon::DEALLOC_RET_cPt_V4: return Hexagon::DEALLOC_RET_cNotPt_V4; case Hexagon::DEALLOC_RET_cNotPt_V4: @@ -1272,6 +749,18 @@ unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const { } } +// New Value Store instructions. +bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const { + const uint64_t F = MI->getDesc().TSFlags; + + return ((F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask); +} + +bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const { + const uint64_t F = get(Opcode).TSFlags; + + return ((F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask); +} int HexagonInstrInfo:: getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const { @@ -1285,218 +774,21 @@ getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const { // This switch case will be removed once all the instructions have been // modified to use relation maps. switch(Opc) { - case Hexagon::TFR: - return !invertPredicate ? Hexagon::TFR_cPt : - Hexagon::TFR_cNotPt; case Hexagon::TFRI_f: return !invertPredicate ? Hexagon::TFRI_cPt_f : Hexagon::TFRI_cNotPt_f; - case Hexagon::TFRI: - return !invertPredicate ? Hexagon::TFRI_cPt : - Hexagon::TFRI_cNotPt; - case Hexagon::JMP: - return !invertPredicate ? Hexagon::JMP_t : - Hexagon::JMP_f; - case Hexagon::COMBINE_rr: return !invertPredicate ? Hexagon::COMBINE_rr_cPt : Hexagon::COMBINE_rr_cNotPt; - case Hexagon::ASLH: - return !invertPredicate ? Hexagon::ASLH_cPt_V4 : - Hexagon::ASLH_cNotPt_V4; - case Hexagon::ASRH: - return !invertPredicate ? Hexagon::ASRH_cPt_V4 : - Hexagon::ASRH_cNotPt_V4; - case Hexagon::SXTB: - return !invertPredicate ? Hexagon::SXTB_cPt_V4 : - Hexagon::SXTB_cNotPt_V4; - case Hexagon::SXTH: - return !invertPredicate ? Hexagon::SXTH_cPt_V4 : - Hexagon::SXTH_cNotPt_V4; - case Hexagon::ZXTB: - return !invertPredicate ? Hexagon::ZXTB_cPt_V4 : - Hexagon::ZXTB_cNotPt_V4; - case Hexagon::ZXTH: - return !invertPredicate ? Hexagon::ZXTH_cPt_V4 : - Hexagon::ZXTH_cNotPt_V4; - - case Hexagon::JMPR: - return !invertPredicate ? Hexagon::JMPR_t : - Hexagon::JMPR_f; - - // V4 indexed+scaled load. - case Hexagon::LDrid_indexed_shl_V4: - return !invertPredicate ? Hexagon::LDrid_indexed_shl_cPt_V4 : - Hexagon::LDrid_indexed_shl_cNotPt_V4; - case Hexagon::LDrib_indexed_shl_V4: - return !invertPredicate ? Hexagon::LDrib_indexed_shl_cPt_V4 : - Hexagon::LDrib_indexed_shl_cNotPt_V4; - case Hexagon::LDriub_indexed_shl_V4: - return !invertPredicate ? Hexagon::LDriub_indexed_shl_cPt_V4 : - Hexagon::LDriub_indexed_shl_cNotPt_V4; - case Hexagon::LDrih_indexed_shl_V4: - return !invertPredicate ? Hexagon::LDrih_indexed_shl_cPt_V4 : - Hexagon::LDrih_indexed_shl_cNotPt_V4; - case Hexagon::LDriuh_indexed_shl_V4: - return !invertPredicate ? Hexagon::LDriuh_indexed_shl_cPt_V4 : - Hexagon::LDriuh_indexed_shl_cNotPt_V4; - case Hexagon::LDriw_indexed_shl_V4: - return !invertPredicate ? Hexagon::LDriw_indexed_shl_cPt_V4 : - Hexagon::LDriw_indexed_shl_cNotPt_V4; - - // V4 Load from global address - case Hexagon::LDd_GP_V4: - return !invertPredicate ? Hexagon::LDd_GP_cPt_V4 : - Hexagon::LDd_GP_cNotPt_V4; - case Hexagon::LDb_GP_V4: - return !invertPredicate ? Hexagon::LDb_GP_cPt_V4 : - Hexagon::LDb_GP_cNotPt_V4; - case Hexagon::LDub_GP_V4: - return !invertPredicate ? Hexagon::LDub_GP_cPt_V4 : - Hexagon::LDub_GP_cNotPt_V4; - case Hexagon::LDh_GP_V4: - return !invertPredicate ? Hexagon::LDh_GP_cPt_V4 : - Hexagon::LDh_GP_cNotPt_V4; - case Hexagon::LDuh_GP_V4: - return !invertPredicate ? Hexagon::LDuh_GP_cPt_V4 : - Hexagon::LDuh_GP_cNotPt_V4; - case Hexagon::LDw_GP_V4: - return !invertPredicate ? Hexagon::LDw_GP_cPt_V4 : - Hexagon::LDw_GP_cNotPt_V4; - - // Byte. - case Hexagon::POST_STbri: - return !invertPredicate ? Hexagon::POST_STbri_cPt : - Hexagon::POST_STbri_cNotPt; - case Hexagon::STrib: - return !invertPredicate ? Hexagon::STrib_cPt : - Hexagon::STrib_cNotPt; - case Hexagon::STrib_indexed: - return !invertPredicate ? Hexagon::STrib_indexed_cPt : - Hexagon::STrib_indexed_cNotPt; - case Hexagon::STrib_imm_V4: - return !invertPredicate ? Hexagon::STrib_imm_cPt_V4 : - Hexagon::STrib_imm_cNotPt_V4; - case Hexagon::STrib_indexed_shl_V4: - return !invertPredicate ? Hexagon::STrib_indexed_shl_cPt_V4 : - Hexagon::STrib_indexed_shl_cNotPt_V4; - // Halfword. - case Hexagon::POST_SThri: - return !invertPredicate ? Hexagon::POST_SThri_cPt : - Hexagon::POST_SThri_cNotPt; - case Hexagon::STrih: - return !invertPredicate ? Hexagon::STrih_cPt : - Hexagon::STrih_cNotPt; - case Hexagon::STrih_indexed: - return !invertPredicate ? Hexagon::STrih_indexed_cPt : - Hexagon::STrih_indexed_cNotPt; - case Hexagon::STrih_imm_V4: - return !invertPredicate ? Hexagon::STrih_imm_cPt_V4 : - Hexagon::STrih_imm_cNotPt_V4; - case Hexagon::STrih_indexed_shl_V4: - return !invertPredicate ? Hexagon::STrih_indexed_shl_cPt_V4 : - Hexagon::STrih_indexed_shl_cNotPt_V4; + // Word. - case Hexagon::POST_STwri: - return !invertPredicate ? Hexagon::POST_STwri_cPt : - Hexagon::POST_STwri_cNotPt; - case Hexagon::STriw: + case Hexagon::STriw_f: return !invertPredicate ? Hexagon::STriw_cPt : Hexagon::STriw_cNotPt; - case Hexagon::STriw_indexed: + case Hexagon::STriw_indexed_f: return !invertPredicate ? Hexagon::STriw_indexed_cPt : Hexagon::STriw_indexed_cNotPt; - case Hexagon::STriw_indexed_shl_V4: - return !invertPredicate ? Hexagon::STriw_indexed_shl_cPt_V4 : - Hexagon::STriw_indexed_shl_cNotPt_V4; - case Hexagon::STriw_imm_V4: - return !invertPredicate ? Hexagon::STriw_imm_cPt_V4 : - Hexagon::STriw_imm_cNotPt_V4; - // Double word. - case Hexagon::POST_STdri: - return !invertPredicate ? Hexagon::POST_STdri_cPt : - Hexagon::POST_STdri_cNotPt; - case Hexagon::STrid: - return !invertPredicate ? Hexagon::STrid_cPt : - Hexagon::STrid_cNotPt; - case Hexagon::STrid_indexed: - return !invertPredicate ? Hexagon::STrid_indexed_cPt : - Hexagon::STrid_indexed_cNotPt; - case Hexagon::STrid_indexed_shl_V4: - return !invertPredicate ? Hexagon::STrid_indexed_shl_cPt_V4 : - Hexagon::STrid_indexed_shl_cNotPt_V4; - - // V4 Store to global address - case Hexagon::STd_GP_V4: - return !invertPredicate ? Hexagon::STd_GP_cPt_V4 : - Hexagon::STd_GP_cNotPt_V4; - case Hexagon::STb_GP_V4: - return !invertPredicate ? Hexagon::STb_GP_cPt_V4 : - Hexagon::STb_GP_cNotPt_V4; - case Hexagon::STh_GP_V4: - return !invertPredicate ? Hexagon::STh_GP_cPt_V4 : - Hexagon::STh_GP_cNotPt_V4; - case Hexagon::STw_GP_V4: - return !invertPredicate ? Hexagon::STw_GP_cPt_V4 : - Hexagon::STw_GP_cNotPt_V4; - - // Load. - case Hexagon::LDrid: - return !invertPredicate ? Hexagon::LDrid_cPt : - Hexagon::LDrid_cNotPt; - case Hexagon::LDriw: - return !invertPredicate ? Hexagon::LDriw_cPt : - Hexagon::LDriw_cNotPt; - case Hexagon::LDrih: - return !invertPredicate ? Hexagon::LDrih_cPt : - Hexagon::LDrih_cNotPt; - case Hexagon::LDriuh: - return !invertPredicate ? Hexagon::LDriuh_cPt : - Hexagon::LDriuh_cNotPt; - case Hexagon::LDrib: - return !invertPredicate ? Hexagon::LDrib_cPt : - Hexagon::LDrib_cNotPt; - case Hexagon::LDriub: - return !invertPredicate ? Hexagon::LDriub_cPt : - Hexagon::LDriub_cNotPt; - // Load Indexed. - case Hexagon::LDrid_indexed: - return !invertPredicate ? Hexagon::LDrid_indexed_cPt : - Hexagon::LDrid_indexed_cNotPt; - case Hexagon::LDriw_indexed: - return !invertPredicate ? Hexagon::LDriw_indexed_cPt : - Hexagon::LDriw_indexed_cNotPt; - case Hexagon::LDrih_indexed: - return !invertPredicate ? Hexagon::LDrih_indexed_cPt : - Hexagon::LDrih_indexed_cNotPt; - case Hexagon::LDriuh_indexed: - return !invertPredicate ? Hexagon::LDriuh_indexed_cPt : - Hexagon::LDriuh_indexed_cNotPt; - case Hexagon::LDrib_indexed: - return !invertPredicate ? Hexagon::LDrib_indexed_cPt : - Hexagon::LDrib_indexed_cNotPt; - case Hexagon::LDriub_indexed: - return !invertPredicate ? Hexagon::LDriub_indexed_cPt : - Hexagon::LDriub_indexed_cNotPt; - // Post Increment Load. - case Hexagon::POST_LDrid: - return !invertPredicate ? Hexagon::POST_LDrid_cPt : - Hexagon::POST_LDrid_cNotPt; - case Hexagon::POST_LDriw: - return !invertPredicate ? Hexagon::POST_LDriw_cPt : - Hexagon::POST_LDriw_cNotPt; - case Hexagon::POST_LDrih: - return !invertPredicate ? Hexagon::POST_LDrih_cPt : - Hexagon::POST_LDrih_cNotPt; - case Hexagon::POST_LDriuh: - return !invertPredicate ? Hexagon::POST_LDriuh_cPt : - Hexagon::POST_LDriuh_cNotPt; - case Hexagon::POST_LDrib: - return !invertPredicate ? Hexagon::POST_LDrib_cPt : - Hexagon::POST_LDrib_cNotPt; - case Hexagon::POST_LDriub: - return !invertPredicate ? Hexagon::POST_LDriub_cPt : - Hexagon::POST_LDriub_cNotPt; + // DEALLOC_RETURN. case Hexagon::DEALLOC_RET_V4: return !invertPredicate ? Hexagon::DEALLOC_RET_cPt_V4 : @@ -1727,6 +1019,16 @@ bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const { return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask); } +// Returns true, if a ST insn can be promoted to a new-value store. +bool HexagonInstrInfo::mayBeNewStore(const MachineInstr *MI) const { + const HexagonRegisterInfo& QRI = getRegisterInfo(); + const uint64_t F = MI->getDesc().TSFlags; + + return ((F >> HexagonII::mayNVStorePos) & + HexagonII::mayNVStoreMask & + QRI.Subtarget.hasV4TOps()); +} + bool HexagonInstrInfo::DefinesPredicate(MachineInstr *MI, std::vector<MachineOperand> &Pred) const { @@ -1911,6 +1213,8 @@ isValidAutoIncImm(const EVT VT, const int Offset) const { bool HexagonInstrInfo:: isMemOp(const MachineInstr *MI) const { +// return MI->getDesc().mayLoad() && MI->getDesc().mayStore(); + switch (MI->getOpcode()) { default: return false; @@ -2202,6 +1506,10 @@ bool HexagonInstrInfo::isNewValueJump(const MachineInstr *MI) const { return false; } +bool HexagonInstrInfo::isPostIncrement (const MachineInstr* MI) const { + return (getAddrMode(MI) == HexagonII::PostInc); +} + bool HexagonInstrInfo::isNewValue(const MachineInstr* MI) const { const uint64_t F = MI->getDesc().TSFlags; return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask); @@ -2214,6 +1522,97 @@ bool HexagonInstrInfo::isDotNewInst (const MachineInstr* MI) const { (isPredicated(MI) && isPredicatedNew(MI))); } +// Returns the most basic instruction for the .new predicated instructions and +// new-value stores. +// For example, all of the following instructions will be converted back to the +// same instruction: +// 1) if (p0.new) memw(R0+#0) = R1.new ---> +// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1 +// 3) if (p0.new) memw(R0+#0) = R1 ---> +// + +int HexagonInstrInfo::GetDotOldOp(const int opc) const { + int NewOp = opc; + if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form + NewOp = Hexagon::getPredOldOpcode(NewOp); + if (NewOp < 0) + assert(0 && "Couldn't change predicate new instruction to its old form."); + } + + if (isNewValueStore(NewOp)) { // Convert into non new-value format + NewOp = Hexagon::getNonNVStore(NewOp); + if (NewOp < 0) + assert(0 && "Couldn't change new-value store to its old form."); + } + return NewOp; +} + +// Return the new value instruction for a given store. +int HexagonInstrInfo::GetDotNewOp(const MachineInstr* MI) const { + int NVOpcode = Hexagon::getNewValueOpcode(MI->getOpcode()); + if (NVOpcode >= 0) // Valid new-value store instruction. + return NVOpcode; + + switch (MI->getOpcode()) { + default: llvm_unreachable("Unknown .new type"); + // store new value byte + case Hexagon::STrib_shl_V4: + return Hexagon::STrib_shl_nv_V4; + + case Hexagon::STrih_shl_V4: + return Hexagon::STrih_shl_nv_V4; + + case Hexagon::STriw_f: + return Hexagon::STriw_nv_V4; + + case Hexagon::STriw_indexed_f: + return Hexagon::STriw_indexed_nv_V4; + + case Hexagon::STriw_shl_V4: + return Hexagon::STriw_shl_nv_V4; + + } + return 0; +} + +// Return .new predicate version for an instruction. +int HexagonInstrInfo::GetDotNewPredOp(MachineInstr *MI, + const MachineBranchProbabilityInfo + *MBPI) const { + + int NewOpcode = Hexagon::getPredNewOpcode(MI->getOpcode()); + if (NewOpcode >= 0) // Valid predicate new instruction + return NewOpcode; + + switch (MI->getOpcode()) { + default: llvm_unreachable("Unknown .new type"); + // Condtional Jumps + case Hexagon::JMP_t: + case Hexagon::JMP_f: + return getDotNewPredJumpOp(MI, MBPI); + + case Hexagon::JMPR_t: + return Hexagon::JMPR_tnew_tV3; + + case Hexagon::JMPR_f: + return Hexagon::JMPR_fnew_tV3; + + case Hexagon::JMPret_t: + return Hexagon::JMPret_tnew_tV3; + + case Hexagon::JMPret_f: + return Hexagon::JMPret_fnew_tV3; + + + // Conditional combine + case Hexagon::COMBINE_rr_cPt : + return Hexagon::COMBINE_rr_cdnPt; + case Hexagon::COMBINE_rr_cNotPt : + return Hexagon::COMBINE_rr_cdnNotPt; + } +} + + unsigned HexagonInstrInfo::getAddrMode(const MachineInstr* MI) const { const uint64_t F = MI->getDesc().TSFlags; diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h index b721da4..3f45b8b 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h @@ -26,8 +26,9 @@ namespace llvm { class HexagonInstrInfo : public HexagonGenInstrInfo { + virtual void anchor(); const HexagonRegisterInfo RI; - const HexagonSubtarget& Subtarget; + const HexagonSubtarget &Subtarget; typedef unsigned Opcode_t; public: @@ -148,11 +149,6 @@ public: isProfitableToDupForIfCvt(MachineBasicBlock &MBB,unsigned NumCycles, const BranchProbability &Probability) const; - virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, - int FrameIx, - uint64_t Offset, - const MDNode *MDPtr, - DebugLoc DL) const; virtual DFAPacketizer* CreateTargetScheduleState(const TargetMachine *TM, const ScheduleDAG *DAG) const; @@ -185,12 +181,19 @@ public: bool isNewValueInst(const MachineInstr* MI) const; bool isNewValue(const MachineInstr* MI) const; bool isDotNewInst(const MachineInstr* MI) const; + int GetDotOldOp(const int opc) const; + int GetDotNewOp(const MachineInstr* MI) const; + int GetDotNewPredOp(MachineInstr *MI, + const MachineBranchProbabilityInfo + *MBPI) const; + bool mayBeNewStore(const MachineInstr* MI) const; bool isDeallocRet(const MachineInstr *MI) const; unsigned getInvertedPredicatedOpcode(const int Opc) const; bool isExtendable(const MachineInstr* MI) const; bool isExtended(const MachineInstr* MI) const; bool isPostIncrement(const MachineInstr* MI) const; bool isNewValueStore(const MachineInstr* MI) const; + bool isNewValueStore(unsigned Opcode) const; bool isNewValueJump(const MachineInstr* MI) const; bool isNewValueJumpCandidate(const MachineInstr *MI) const; diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.td b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.td index 2a4b17b..c96aaca 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.td @@ -384,6 +384,12 @@ def TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1), // ALU32/PERM + //===----------------------------------------------------------------------===// +let neverHasSideEffects = 1 in +def COMBINE_ii : ALU32_ii<(outs DoubleRegs:$dst), + (ins s8Imm:$src1, s8Imm:$src2), + "$dst = combine(#$src1, #$src2)", + []>; + // Mux. def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, DoubleRegs:$src2, @@ -932,12 +938,21 @@ multiclass LD_MEMri<string mnemonic, string CextOp, RegisterClass RC, } let addrMode = BaseImmOffset, isMEMri = "true" in { - defm LDrib: LD_MEMri < "memb", "LDrib", IntRegs, 11, 6>, AddrModeRel; - defm LDriub: LD_MEMri < "memub" , "LDriub", IntRegs, 11, 6>, AddrModeRel; - defm LDrih: LD_MEMri < "memh", "LDrih", IntRegs, 12, 7>, AddrModeRel; - defm LDriuh: LD_MEMri < "memuh", "LDriuh", IntRegs, 12, 7>, AddrModeRel; - defm LDriw: LD_MEMri < "memw", "LDriw", IntRegs, 13, 8>, AddrModeRel; - defm LDrid: LD_MEMri < "memd", "LDrid", DoubleRegs, 14, 9>, AddrModeRel; + let accessSize = ByteAccess in { + defm LDrib: LD_MEMri < "memb", "LDrib", IntRegs, 11, 6>, AddrModeRel; + defm LDriub: LD_MEMri < "memub" , "LDriub", IntRegs, 11, 6>, AddrModeRel; + } + + let accessSize = HalfWordAccess in { + defm LDrih: LD_MEMri < "memh", "LDrih", IntRegs, 12, 7>, AddrModeRel; + defm LDriuh: LD_MEMri < "memuh", "LDriuh", IntRegs, 12, 7>, AddrModeRel; + } + + let accessSize = WordAccess in + defm LDriw: LD_MEMri < "memw", "LDriw", IntRegs, 13, 8>, AddrModeRel; + + let accessSize = DoubleWordAccess in + defm LDrid: LD_MEMri < "memd", "LDrid", DoubleRegs, 14, 9>, AddrModeRel; } def : Pat < (i32 (sextloadi8 ADDRriS11_0:$addr)), @@ -1000,18 +1015,25 @@ multiclass LD_Idxd<string mnemonic, string CextOp, RegisterClass RC, } let addrMode = BaseImmOffset in { - defm LDrib_indexed: LD_Idxd <"memb", "LDrib", IntRegs, s11_0Ext, u6_0Ext, - 11, 6>, AddrModeRel; - defm LDriub_indexed: LD_Idxd <"memub" , "LDriub", IntRegs, s11_0Ext, u6_0Ext, - 11, 6>, AddrModeRel; - defm LDrih_indexed: LD_Idxd <"memh", "LDrih", IntRegs, s11_1Ext, u6_1Ext, - 12, 7>, AddrModeRel; - defm LDriuh_indexed: LD_Idxd <"memuh", "LDriuh", IntRegs, s11_1Ext, u6_1Ext, - 12, 7>, AddrModeRel; - defm LDriw_indexed: LD_Idxd <"memw", "LDriw", IntRegs, s11_2Ext, u6_2Ext, - 13, 8>, AddrModeRel; - defm LDrid_indexed: LD_Idxd <"memd", "LDrid", DoubleRegs, s11_3Ext, u6_3Ext, - 14, 9>, AddrModeRel; + let accessSize = ByteAccess in { + defm LDrib_indexed: LD_Idxd <"memb", "LDrib", IntRegs, s11_0Ext, u6_0Ext, + 11, 6>, AddrModeRel; + defm LDriub_indexed: LD_Idxd <"memub" , "LDriub", IntRegs, s11_0Ext, u6_0Ext, + 11, 6>, AddrModeRel; + } + let accessSize = HalfWordAccess in { + defm LDrih_indexed: LD_Idxd <"memh", "LDrih", IntRegs, s11_1Ext, u6_1Ext, + 12, 7>, AddrModeRel; + defm LDriuh_indexed: LD_Idxd <"memuh", "LDriuh", IntRegs, s11_1Ext, u6_1Ext, + 12, 7>, AddrModeRel; + } + let accessSize = WordAccess in + defm LDriw_indexed: LD_Idxd <"memw", "LDriw", IntRegs, s11_2Ext, u6_2Ext, + 13, 8>, AddrModeRel; + + let accessSize = DoubleWordAccess in + defm LDrid_indexed: LD_Idxd <"memd", "LDrid", DoubleRegs, s11_3Ext, u6_3Ext, + 14, 9>, AddrModeRel; } let AddedComplexity = 20 in { @@ -1036,8 +1058,6 @@ def : Pat < (i64 (load (add IntRegs:$src1, s11_3ExtPred:$offset))), //===----------------------------------------------------------------------===// // Post increment load -// Make sure that in post increment load, the first operand is always the post -// increment operand. //===----------------------------------------------------------------------===// multiclass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp, @@ -1079,7 +1099,7 @@ multiclass LD_PostInc<string mnemonic, string BaseOp, RegisterClass RC, } } -let hasCtrlDep = 1, neverHasSideEffects = 1 in { +let hasCtrlDep = 1, neverHasSideEffects = 1, addrMode = PostInc in { defm POST_LDrib : LD_PostInc<"memb", "LDrib", IntRegs, s4_0Imm>, PredNewRel; defm POST_LDriub : LD_PostInc<"memub", "LDriub", IntRegs, s4_0Imm>, @@ -1382,7 +1402,7 @@ multiclass ST_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp, multiclass ST_PostInc_Pred<string mnemonic, RegisterClass RC, Operand ImmOp, bit PredNot> { let isPredicatedFalse = PredNot in { - defm _c#NAME# : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>; + defm _c#NAME : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>; // Predicate new let Predicates = [HasV4T], validSubTargets = HasV4SubT in defm _cdn#NAME#_V4 : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>; @@ -1397,7 +1417,7 @@ multiclass ST_PostInc<string mnemonic, string BaseOp, RegisterClass RC, let isPredicable = 1 in def NAME : STInst2PI<(outs IntRegs:$dst), (ins IntRegs:$src1, ImmOp:$offset, RC:$src2), - #mnemonic#"($src1++#$offset) = $src2", + mnemonic#"($src1++#$offset) = $src2", [], "$src1 = $dst">; @@ -1474,12 +1494,17 @@ multiclass ST_MEMri<string mnemonic, string CextOp, RegisterClass RC, } let addrMode = BaseImmOffset, isMEMri = "true" in { - defm STrib: ST_MEMri < "memb", "STrib", IntRegs, 11, 6>, AddrModeRel; - defm STrih: ST_MEMri < "memh", "STrih", IntRegs, 12, 7>, AddrModeRel; - defm STriw: ST_MEMri < "memw", "STriw", IntRegs, 13, 8>, AddrModeRel; + let accessSize = ByteAccess in + defm STrib: ST_MEMri < "memb", "STrib", IntRegs, 11, 6>, AddrModeRel; + + let accessSize = HalfWordAccess in + defm STrih: ST_MEMri < "memh", "STrih", IntRegs, 12, 7>, AddrModeRel; - let isNVStorable = 0 in - defm STrid: ST_MEMri < "memd", "STrid", DoubleRegs, 14, 9>, AddrModeRel; + let accessSize = WordAccess in + defm STriw: ST_MEMri < "memw", "STriw", IntRegs, 13, 8>, AddrModeRel; + + let accessSize = DoubleWordAccess, isNVStorable = 0 in + defm STrid: ST_MEMri < "memd", "STrid", DoubleRegs, 14, 9>, AddrModeRel; } def : Pat<(truncstorei8 (i32 IntRegs:$src1), ADDRriS11_0:$addr), @@ -1541,15 +1566,21 @@ multiclass ST_Idxd<string mnemonic, string CextOp, RegisterClass RC, } let addrMode = BaseImmOffset, InputType = "reg" in { - defm STrib_indexed: ST_Idxd < "memb", "STrib", IntRegs, s11_0Ext, - u6_0Ext, 11, 6>, AddrModeRel, ImmRegRel; - defm STrih_indexed: ST_Idxd < "memh", "STrih", IntRegs, s11_1Ext, - u6_1Ext, 12, 7>, AddrModeRel, ImmRegRel; - defm STriw_indexed: ST_Idxd < "memw", "STriw", IntRegs, s11_2Ext, - u6_2Ext, 13, 8>, AddrModeRel, ImmRegRel; - let isNVStorable = 0 in - defm STrid_indexed: ST_Idxd < "memd", "STrid", DoubleRegs, s11_3Ext, - u6_3Ext, 14, 9>, AddrModeRel; + let accessSize = ByteAccess in + defm STrib_indexed: ST_Idxd < "memb", "STrib", IntRegs, s11_0Ext, + u6_0Ext, 11, 6>, AddrModeRel, ImmRegRel; + + let accessSize = HalfWordAccess in + defm STrih_indexed: ST_Idxd < "memh", "STrih", IntRegs, s11_1Ext, + u6_1Ext, 12, 7>, AddrModeRel, ImmRegRel; + + let accessSize = WordAccess in + defm STriw_indexed: ST_Idxd < "memw", "STriw", IntRegs, s11_2Ext, + u6_2Ext, 13, 8>, AddrModeRel, ImmRegRel; + + let accessSize = DoubleWordAccess, isNVStorable = 0 in + defm STrid_indexed: ST_Idxd < "memd", "STrid", DoubleRegs, s11_3Ext, + u6_3Ext, 14, 9>, AddrModeRel; } let AddedComplexity = 10 in { diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td index 933239d..475c23d 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td @@ -213,7 +213,7 @@ def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst), // Template class for load instructions with Absolute set addressing mode. //===----------------------------------------------------------------------===// let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1, -validSubTargets = HasV4SubT in +validSubTargets = HasV4SubT, addrMode = AbsoluteSet in class T_LD_abs_set<string mnemonic, RegisterClass RC>: LDInst2<(outs RC:$dst1, IntRegs:$dst2), (ins u0AlwaysExt:$addr), @@ -266,12 +266,23 @@ multiclass ld_idxd_shl<string mnemonic, string CextOp, RegisterClass RC> { } let addrMode = BaseRegOffset in { - defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>, AddrModeRel; - defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>, AddrModeRel; - defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel; - defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>, AddrModeRel; - defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel; - defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>, AddrModeRel; + let accessSize = ByteAccess in { + defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>, + AddrModeRel; + defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>, + AddrModeRel; + } + let accessSize = HalfWordAccess in { + defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel; + defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>, + AddrModeRel; + } + let accessSize = WordAccess in + defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel; + + let accessSize = DoubleWordAccess in + defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>, + AddrModeRel; } // 'def pats' for load instructions with base + register offset and non-zero @@ -456,7 +467,8 @@ def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))), //===----------------------------------------------------------------------===// // Template class for store instructions with Absolute set addressing mode. //===----------------------------------------------------------------------===// -let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in +let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT, +addrMode = AbsoluteSet in class T_ST_abs_set<string mnemonic, RegisterClass RC>: STInst2<(outs IntRegs:$dst1), (ins RC:$src1, u0AlwaysExt:$src2), @@ -551,17 +563,20 @@ multiclass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> { let addrMode = BaseRegOffset, neverHasSideEffects = 1, validSubTargets = HasV4SubT in { - defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>, - ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel; + let accessSize = ByteAccess in + defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>, + ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel; - defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>, - ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel; + let accessSize = HalfWordAccess in + defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>, + ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel; - defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>, - ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel; + let accessSize = WordAccess in + defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>, + ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel; - let isNVStorable = 0 in - defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel; + let isNVStorable = 0, accessSize = DoubleWordAccess in + defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel; } let Predicates = [HasV4T], AddedComplexity = 10 in { @@ -695,10 +710,15 @@ multiclass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> { } let addrMode = BaseImmOffset, InputType = "imm", - validSubTargets = HasV4SubT in { - defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel; - defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel; - defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel; +validSubTargets = HasV4SubT in { + let accessSize = ByteAccess in + defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel; + + let accessSize = HalfWordAccess in + defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel; + + let accessSize = WordAccess in + defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel; } let Predicates = [HasV4T], AddedComplexity = 10 in { @@ -834,12 +854,17 @@ multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC, } let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in { - defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext, - u6_0Ext, 11, 6>, AddrModeRel; - defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext, - u6_1Ext, 12, 7>, AddrModeRel; - defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext, - u6_2Ext, 13, 8>, AddrModeRel; + let accessSize = ByteAccess in + defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext, + u6_0Ext, 11, 6>, AddrModeRel; + + let accessSize = HalfWordAccess in + defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext, + u6_1Ext, 12, 7>, AddrModeRel; + + let accessSize = WordAccess in + defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext, + u6_2Ext, 13, 8>, AddrModeRel; } // multiclass for new-value store instructions with base + immediate offset. @@ -887,9 +912,14 @@ multiclass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC, let addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT, mayStore = 1 in { - defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel; - defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel; - defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel; + let accessSize = ByteAccess in + defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel; + + let accessSize = HalfWordAccess in + defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel; + + let accessSize = WordAccess in + defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel; } //===----------------------------------------------------------------------===// @@ -939,7 +969,7 @@ multiclass ST_PostInc_nv<string mnemonic, string BaseOp, RegisterClass RC, } } -let validSubTargets = HasV4SubT in { +let addrMode = PostInc, validSubTargets = HasV4SubT in { defm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel; defm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel; defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel; @@ -2534,8 +2564,9 @@ def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), //Deallocate frame and return. // dealloc_return let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in { - def DEALLOC_RET_V4 : NVInst_V4<(outs), (ins i32imm:$amt1), + Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1 in { +let validSubTargets = HasV4SubT in + def DEALLOC_RET_V4 : LD0Inst<(outs), (ins), "dealloc_return", []>, Requires<[HasV4T]>; @@ -2544,9 +2575,10 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1, // Restore registers and dealloc return function call. let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1, Defs = [R29, R30, R31, PC] in { +let validSubTargets = HasV4SubT in def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs), (ins calltarget:$dst), - "jump $dst // Restore_and_dealloc_return", + "jump $dst", []>, Requires<[HasV4T]>; } @@ -2554,9 +2586,10 @@ let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1, // Restore registers and dealloc frame before a tail call. let isCall = 1, isBarrier = 1, Defs = [R29, R30, R31, PC] in { +let validSubTargets = HasV4SubT in def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs), (ins calltarget:$dst), - "call $dst // Restore_and_dealloc_before_tailcall", + "call $dst", []>, Requires<[HasV4T]>; } @@ -2573,10 +2606,11 @@ let isCall = 1, isBarrier = 1, // if (Ps) dealloc_return let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, + Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, isPredicated = 1 in { - def DEALLOC_RET_cPt_V4 : NVInst_V4<(outs), - (ins PredRegs:$src1, i32imm:$amt1), +let validSubTargets = HasV4SubT in + def DEALLOC_RET_cPt_V4 : LD0Inst<(outs), + (ins PredRegs:$src1), "if ($src1) dealloc_return", []>, Requires<[HasV4T]>; @@ -2584,10 +2618,10 @@ let isReturn = 1, isTerminator = 1, // if (!Ps) dealloc_return let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, - isPredicated = 1 in { - def DEALLOC_RET_cNotPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, - i32imm:$amt1), + Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, + isPredicated = 1, isPredicatedFalse = 1 in { +let validSubTargets = HasV4SubT in + def DEALLOC_RET_cNotPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), "if (!$src1) dealloc_return", []>, Requires<[HasV4T]>; @@ -2595,10 +2629,10 @@ let isReturn = 1, isTerminator = 1, // if (Ps.new) dealloc_return:nt let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, + Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, isPredicated = 1 in { - def DEALLOC_RET_cdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, - i32imm:$amt1), +let validSubTargets = HasV4SubT in + def DEALLOC_RET_cdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), "if ($src1.new) dealloc_return:nt", []>, Requires<[HasV4T]>; @@ -2606,10 +2640,10 @@ let isReturn = 1, isTerminator = 1, // if (!Ps.new) dealloc_return:nt let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, - isPredicated = 1 in { - def DEALLOC_RET_cNotdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, - i32imm:$amt1), + Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, + isPredicated = 1, isPredicatedFalse = 1 in { +let validSubTargets = HasV4SubT in + def DEALLOC_RET_cNotdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), "if (!$src1.new) dealloc_return:nt", []>, Requires<[HasV4T]>; @@ -2617,21 +2651,21 @@ let isReturn = 1, isTerminator = 1, // if (Ps.new) dealloc_return:t let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, + Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, isPredicated = 1 in { - def DEALLOC_RET_cdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, - i32imm:$amt1), +let validSubTargets = HasV4SubT in + def DEALLOC_RET_cdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), "if ($src1.new) dealloc_return:t", []>, Requires<[HasV4T]>; } -// if (!Ps.new) dealloc_return:nt +// if (!Ps.new) dealloc_return:nt let isReturn = 1, isTerminator = 1, - Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1, - isPredicated = 1 in { - def DEALLOC_RET_cNotdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1, - i32imm:$amt1), + Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, + isPredicated = 1, isPredicatedFalse = 1 in { +let validSubTargets = HasV4SubT in + def DEALLOC_RET_cNotdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), "if (!$src1.new) dealloc_return:t", []>, Requires<[HasV4T]>; @@ -3033,37 +3067,42 @@ def : Pat<(HexagonCONST32_GP tblockaddress:$src1), (TFRI_V4 tblockaddress:$src1)>, Requires<[HasV4T]>; -let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in +let isExtended = 1, opExtendable = 2, AddedComplexity=50, +neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$src2), - "if($src1) $dst = ##$src2", + (ins PredRegs:$src1, s16Ext:$src2), + "if($src1) $dst = #$src2", []>, Requires<[HasV4T]>; -let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in +let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1, +neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$src2), - "if(!$src1) $dst = ##$src2", + (ins PredRegs:$src1, s16Ext:$src2), + "if(!$src1) $dst = #$src2", []>, Requires<[HasV4T]>; -let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in +let isExtended = 1, opExtendable = 2, AddedComplexity=50, +neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$src2), - "if($src1.new) $dst = ##$src2", + (ins PredRegs:$src1, s16Ext:$src2), + "if($src1.new) $dst = #$src2", []>, Requires<[HasV4T]>; -let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in +let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1, +neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, globaladdress:$src2), - "if(!$src1.new) $dst = ##$src2", + (ins PredRegs:$src1, s16Ext:$src2), + "if(!$src1.new) $dst = #$src2", []>, Requires<[HasV4T]>; let AddedComplexity = 50, Predicates = [HasV4T] in def : Pat<(HexagonCONST32_GP tglobaladdr:$src1), - (TFRI_V4 tglobaladdr:$src1)>; + (TFRI_V4 tglobaladdr:$src1)>, + Requires<[HasV4T]>; // Load - Indirect with long offset: These instructions take global address @@ -3149,6 +3188,93 @@ def STriw_offset_ext_V4 : STInst<(outs), (add IntRegs:$src1, u6_2ImmPred:$src2))]>, Requires<[HasV4T]>; +def : Pat<(i64 (ctlz (i64 DoubleRegs:$src1))), + (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>, + Requires<[HasV4T]>; + +def : Pat<(i64 (cttz (i64 DoubleRegs:$src1))), + (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTTZ64_rr DoubleRegs:$src1))))>, + Requires<[HasV4T]>; + + +// i8 -> i64 loads +// We need a complexity of 120 here to overide preceeding handling of +// zextloadi8. +let Predicates = [HasV4T], AddedComplexity = 120 in { +def: Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), + (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 tglobaladdr:$addr)))>; + +def: Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), + (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 tglobaladdr:$addr)))>; + +def: Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), + (i64 (SXTW (LDrib_abs_V4 tglobaladdr:$addr)))>; + +def: Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)), + (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 FoldGlobalAddr:$addr)))>; + +def: Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)), + (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 FoldGlobalAddr:$addr)))>; + +def: Pat <(i64 (sextloadi8 FoldGlobalAddr:$addr)), + (i64 (SXTW (LDrib_abs_V4 FoldGlobalAddr:$addr)))>; +} +// i16 -> i64 loads +// We need a complexity of 120 here to overide preceeding handling of +// zextloadi16. +let AddedComplexity = 120 in { +def: Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), + (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 tglobaladdr:$addr)))>, + Requires<[HasV4T]>; + +def: Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), + (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 tglobaladdr:$addr)))>, + Requires<[HasV4T]>; + +def: Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), + (i64 (SXTW (LDrih_abs_V4 tglobaladdr:$addr)))>, + Requires<[HasV4T]>; + +def: Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)), + (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 FoldGlobalAddr:$addr)))>, + Requires<[HasV4T]>; + +def: Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)), + (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 FoldGlobalAddr:$addr)))>, + Requires<[HasV4T]>; + +def: Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)), + (i64 (SXTW (LDrih_abs_V4 FoldGlobalAddr:$addr)))>, + Requires<[HasV4T]>; +} +// i32->i64 loads +// We need a complexity of 120 here to overide preceeding handling of +// zextloadi32. +let AddedComplexity = 120 in { +def: Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), + (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>, + Requires<[HasV4T]>; + +def: Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), + (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>, + Requires<[HasV4T]>; + +def: Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), + (i64 (SXTW (LDriw_abs_V4 tglobaladdr:$addr)))>, + Requires<[HasV4T]>; + +def: Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)), + (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>, + Requires<[HasV4T]>; + +def: Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)), + (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>, + Requires<[HasV4T]>; + +def: Pat <(i64 (sextloadi32 FoldGlobalAddr:$addr)), + (i64 (SXTW (LDriw_abs_V4 FoldGlobalAddr:$addr)))>, + Requires<[HasV4T]>; +} // Indexed store double word - global address. // memw(Rs+#u6:2)=#S8 @@ -3264,4 +3390,3 @@ def : Pat<(i32 (load FoldGlobalAddrGP:$addr)), def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr), (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>, Requires<[HasV4T]>; - diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV5.td b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV5.td index 92d098c..9da6074 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV5.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfoV5.td @@ -26,22 +26,29 @@ def CONST32_Float_Real : LDInst<(outs IntRegs:$dst), (ins f32imm:$src1), // Only works with single precision fp value. // For double precision, use CONST64_float_real, as 64bit transfer // can only hold 40-bit values - 32 from const ext + 8 bit immediate. -let isMoveImm = 1, isReMaterializable = 1, isPredicable = 1 in -def TFRI_f : ALU32_ri<(outs IntRegs:$dst), (ins f32imm:$src1), - "$dst = ##$src1", +// Make sure that complexity is more than the CONST32 pattern in +// HexagonInstrInfo.td patterns. +let isExtended = 1, opExtendable = 1, isMoveImm = 1, isReMaterializable = 1, +isPredicable = 1, AddedComplexity = 30, validSubTargets = HasV5SubT, +isCodeGenOnly = 1 in +def TFRI_f : ALU32_ri<(outs IntRegs:$dst), (ins f32Ext:$src1), + "$dst = #$src1", [(set IntRegs:$dst, fpimm:$src1)]>, Requires<[HasV5T]>; +let isExtended = 1, opExtendable = 2, isPredicated = 1, +neverHasSideEffects = 1, validSubTargets = HasV5SubT in def TFRI_cPt_f : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, f32imm:$src2), - "if ($src1) $dst = ##$src2", + (ins PredRegs:$src1, f32Ext:$src2), + "if ($src1) $dst = #$src2", []>, Requires<[HasV5T]>; -let isPredicated = 1 in +let isExtended = 1, opExtendable = 2, isPredicated = 1, isPredicatedFalse = 1, +neverHasSideEffects = 1, validSubTargets = HasV5SubT in def TFRI_cNotPt_f : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, f32imm:$src2), - "if (!$src1) $dst = ##$src2", + (ins PredRegs:$src1, f32Ext:$src2), + "if (!$src1) $dst =#$src2", []>, Requires<[HasV5T]>; diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonMCInstLower.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonMCInstLower.cpp index f011d51..bbb2fa4 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonMCInstLower.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonMCInstLower.cpp @@ -73,7 +73,7 @@ void llvm::HexagonLowerToMC(const MachineInstr* MI, HexagonMCInst& MCI, AP.OutContext)); break; case MachineOperand::MO_GlobalAddress: - MCO = GetSymbolRef(MO, AP.Mang->getSymbol(MO.getGlobal()), AP); + MCO = GetSymbolRef(MO, AP.getSymbol(MO.getGlobal()), AP); break; case MachineOperand::MO_ExternalSymbol: MCO = GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.cpp new file mode 100644 index 0000000..9579c8b --- /dev/null +++ b/contrib/llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.cpp @@ -0,0 +1,16 @@ +//= HexagonMachineFunctionInfo.cpp - Hexagon machine function info *- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "HexagonMachineFunctionInfo.h" + +using namespace llvm; + +// pin vtable to this file +void HexagonMachineFunctionInfo::anchor() {} + diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.h b/contrib/llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.h index bd7b26a..a59c8c9 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.h +++ b/contrib/llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.h @@ -1,4 +1,4 @@ -//=- HexagonMachineFuctionInfo.h - Hexagon machine function info --*- C++ -*-=// +//=- HexagonMachineFunctionInfo.h - Hexagon machine function info -*- C++ -*-=// // // The LLVM Compiler Infrastructure // @@ -10,6 +10,7 @@ #ifndef HexagonMACHINEFUNCTIONINFO_H #define HexagonMACHINEFUNCTIONINFO_H +#include <map> #include "llvm/CodeGen/MachineFunction.h" namespace llvm { @@ -30,9 +31,8 @@ class HexagonMachineFunctionInfo : public MachineFunctionInfo { int VarArgsFrameIndex; bool HasClobberLR; bool HasEHReturn; - std::map<const MachineInstr*, unsigned> PacketInfo; - + virtual void anchor(); public: HexagonMachineFunctionInfo() : SRetReturnReg(0), HasClobberLR(0), diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonMachineScheduler.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonMachineScheduler.cpp index 1388ad4..c94f081 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonMachineScheduler.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonMachineScheduler.cpp @@ -195,7 +195,6 @@ void VLIWMachineScheduler::schedule() { void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) { DAG = static_cast<VLIWMachineScheduler*>(dag); SchedModel = DAG->getSchedModel(); - TRI = DAG->TRI; Top.init(DAG, SchedModel); Bot.init(DAG, SchedModel); @@ -209,6 +208,8 @@ void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) { Top.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG); Bot.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG); + delete Top.ResourceModel; + delete Bot.ResourceModel; Top.ResourceModel = new VLIWResourceModel(TM, DAG->getSchedModel()); Bot.ResourceModel = new VLIWResourceModel(TM, DAG->getSchedModel()); @@ -223,7 +224,7 @@ void ConvergingVLIWScheduler::releaseTopNode(SUnit *SU) { for (SUnit::succ_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { unsigned PredReadyCycle = I->getSUnit()->TopReadyCycle; - unsigned MinLatency = I->getMinLatency(); + unsigned MinLatency = I->getLatency(); #ifndef NDEBUG Top.MaxMinLatency = std::max(MinLatency, Top.MaxMinLatency); #endif @@ -242,7 +243,7 @@ void ConvergingVLIWScheduler::releaseBottomNode(SUnit *SU) { for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { unsigned SuccReadyCycle = I->getSUnit()->BotReadyCycle; - unsigned MinLatency = I->getMinLatency(); + unsigned MinLatency = I->getLatency(); #ifndef NDEBUG Bot.MaxMinLatency = std::max(MinLatency, Bot.MaxMinLatency); #endif @@ -406,11 +407,11 @@ SUnit *ConvergingVLIWScheduler::SchedBoundary::pickOnlyChoice() { #ifndef NDEBUG void ConvergingVLIWScheduler::traceCandidate(const char *Label, const ReadyQueue &Q, - SUnit *SU, PressureElement P) { + SUnit *SU, PressureChange P) { dbgs() << Label << " " << Q.getName() << " "; if (P.isValid()) - dbgs() << TRI->getRegPressureSetName(P.PSetID) << ":" << P.UnitIncrease - << " "; + dbgs() << DAG->TRI->getRegPressureSetName(P.getPSet()) << ":" + << P.getUnitInc() << " "; else dbgs() << " "; SU->dump(DAG); @@ -456,9 +457,7 @@ static SUnit *getSingleUnscheduledSucc(SUnit *SU) { // Constants used to denote relative importance of // heuristic components for cost computation. static const unsigned PriorityOne = 200; -static const unsigned PriorityTwo = 100; -static const unsigned PriorityThree = 50; -static const unsigned PriorityFour = 20; +static const unsigned PriorityTwo = 50; static const unsigned ScaleTwo = 10; static const unsigned FactorOne = 2; @@ -516,8 +515,8 @@ int ConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU, ResCount += (NumNodesBlocking * ScaleTwo); // Factor in reg pressure as a heuristic. - ResCount -= (Delta.Excess.UnitIncrease*PriorityThree); - ResCount -= (Delta.CriticalMax.UnitIncrease*PriorityThree); + ResCount -= (Delta.Excess.getUnitInc()*PriorityTwo); + ResCount -= (Delta.CriticalMax.getUnitInc()*PriorityTwo); DEBUG(if (verbose) dbgs() << " Total(" << ResCount << ")"); diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonMachineScheduler.h b/contrib/llvm/lib/Target/Hexagon/HexagonMachineScheduler.h index f68dadf..8ac333f 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonMachineScheduler.h +++ b/contrib/llvm/lib/Target/Hexagon/HexagonMachineScheduler.h @@ -190,7 +190,6 @@ class ConvergingVLIWScheduler : public MachineSchedStrategy { VLIWMachineScheduler *DAG; const TargetSchedModel *SchedModel; - const TargetRegisterInfo *TRI; // State of the top and bottom scheduled instruction boundaries. SchedBoundary Top; @@ -205,7 +204,7 @@ public: }; ConvergingVLIWScheduler(): - DAG(0), SchedModel(0), TRI(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {} + DAG(0), SchedModel(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {} virtual void initialize(ScheduleDAGMI *dag); @@ -234,7 +233,7 @@ protected: SchedCandidate &Candidate); #ifndef NDEBUG void traceCandidate(const char *Label, const ReadyQueue &Q, SUnit *SU, - PressureElement P = PressureElement()); + PressureChange P = PressureChange()); #endif }; diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp index 05e6968..f7c4513 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp @@ -631,6 +631,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) { .addMBB(jmpTarget); assert(NewMI && "New Value Jump Instruction Not created!"); + (void)NewMI; if (cmpInstr->getOperand(0).isReg() && cmpInstr->getOperand(0).isKill()) cmpInstr->getOperand(0).setIsKill(false); diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonPeephole.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonPeephole.cpp index 89e3406..5490ecd 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonPeephole.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonPeephole.cpp @@ -29,7 +29,7 @@ // // Note: The peephole pass makes the instrucstions like // %vreg170<def> = SXTW %vreg166 or %vreg16<def> = NOT_p %vreg15<kill> -// redundant and relies on some form of dead removal instrucions, like +// redundant and relies on some form of dead removal instructions, like // DCE or DIE to actually eliminate them. diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp index d8b4e2f..1786e9d 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp @@ -38,11 +38,9 @@ using namespace llvm; -HexagonRegisterInfo::HexagonRegisterInfo(HexagonSubtarget &st, - const HexagonInstrInfo &tii) +HexagonRegisterInfo::HexagonRegisterInfo(HexagonSubtarget &st) : HexagonGenRegisterInfo(Hexagon::R31), - Subtarget(st), - TII(tii) { + Subtarget(st) { } const uint16_t* HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction @@ -130,6 +128,8 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, // Addressable stack objects are accessed using neg. offsets from %fp. MachineFunction &MF = *MI.getParent()->getParent(); + const HexagonInstrInfo &TII = + *static_cast<const HexagonInstrInfo*>(MF.getTarget().getInstrInfo()); int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); MachineFrameInfo &MFI = *MF.getFrameInfo(); @@ -295,23 +295,5 @@ unsigned HexagonRegisterInfo::getStackRegister() const { return Hexagon::R29; } -void HexagonRegisterInfo::getInitialFrameState(std::vector<MachineMove> - &Moves) const -{ - // VirtualFP = (R30 + #0). - unsigned FPReg = getFrameRegister(); - MachineLocation Dst(MachineLocation::VirtualFP); - MachineLocation Src(FPReg, 0); - Moves.push_back(MachineMove(0, Dst, Src)); -} - -unsigned HexagonRegisterInfo::getEHExceptionRegister() const { - llvm_unreachable("What is the exception register"); -} - -unsigned HexagonRegisterInfo::getEHHandlerRegister() const { - llvm_unreachable("What is the exception handler register"); -} - #define GET_REGINFO_TARGET_DESC #include "HexagonGenRegisterInfo.inc" diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h b/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h index 8a3f94a..89af7c3 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h +++ b/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h @@ -44,9 +44,8 @@ class Type; struct HexagonRegisterInfo : public HexagonGenRegisterInfo { HexagonSubtarget &Subtarget; - const HexagonInstrInfo &TII; - HexagonRegisterInfo(HexagonSubtarget &st, const HexagonInstrInfo &tii); + HexagonRegisterInfo(HexagonSubtarget &st); /// Code Generation virtual methods... const uint16_t *getCalleeSavedRegs(const MachineFunction *MF = 0) const; @@ -78,12 +77,7 @@ struct HexagonRegisterInfo : public HexagonGenRegisterInfo { unsigned getRARegister() const; unsigned getFrameRegister(const MachineFunction &MF) const; unsigned getFrameRegister() const; - void getInitialFrameState(std::vector<MachineMove> &Moves) const; unsigned getStackRegister() const; - - // Exception handling queries. - unsigned getEHExceptionRegister() const; - unsigned getEHHandlerRegister() const; }; } // end namespace llvm diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td b/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td index fe41fc3..8ea1b7e 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td +++ b/contrib/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td @@ -57,8 +57,8 @@ let Namespace = "Hexagon" in { let Aliases = [R]; } - def subreg_loreg : SubRegIndex; - def subreg_hireg : SubRegIndex; + def subreg_loreg : SubRegIndex<32>; + def subreg_hireg : SubRegIndex<32, 32>; // Integer registers. def R0 : Ri< 0, "r0">, DwarfRegNum<[0]>; diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp index a52c604..c37bf9f 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp @@ -27,7 +27,7 @@ HexagonSelectionDAGInfo::~HexagonSelectionDAGInfo() { SDValue HexagonSelectionDAGInfo:: -EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl, SDValue Chain, +EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVolatile, bool AlwaysInline, MachinePointerInfo DstPtrInfo, diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h b/contrib/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h index 0673e4d..31f278a 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h +++ b/contrib/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h @@ -26,7 +26,7 @@ public: ~HexagonSelectionDAGInfo(); virtual - SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl, + SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp new file mode 100644 index 0000000..5166f8e --- /dev/null +++ b/contrib/llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp @@ -0,0 +1,174 @@ +//=== HexagonSplitConst32AndConst64.cpp - split CONST32/Const64 into HI/LO ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// When the compiler is invoked with no small data, for instance, with the -G0 +// command line option, then all CONST32_* opcodes should be broken down into +// appropriate LO and HI instructions. This splitting is done by this pass. +// The only reason this is not done in the DAG lowering itself is that there +// is no simple way of getting the register allocator to allot the same hard +// register to the result of LO and HI instructions. This pass is always +// scheduled after register allocation. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "xfer" + +#include "HexagonTargetMachine.h" +#include "HexagonSubtarget.h" +#include "HexagonMachineFunctionInfo.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/LatencyPriorityQueue.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/ScheduleDAGInstrs.h" +#include "llvm/CodeGen/ScheduleHazardRecognizer.h" +#include "llvm/CodeGen/SchedulerRegistry.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/MathExtras.h" +#include <map> + +using namespace llvm; + +namespace { + +class HexagonSplitConst32AndConst64 : public MachineFunctionPass { + const HexagonTargetMachine& QTM; + const HexagonSubtarget &QST; + + public: + static char ID; + HexagonSplitConst32AndConst64(const HexagonTargetMachine& TM) + : MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {} + + const char *getPassName() const { + return "Hexagon Split Const32s and Const64s"; + } + bool runOnMachineFunction(MachineFunction &Fn); +}; + + +char HexagonSplitConst32AndConst64::ID = 0; + + +bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) { + + const TargetInstrInfo *TII = QTM.getInstrInfo(); + + // Loop over all of the basic blocks + for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); + MBBb != MBBe; ++MBBb) { + MachineBasicBlock* MBB = MBBb; + // Traverse the basic block + MachineBasicBlock::iterator MII = MBB->begin(); + MachineBasicBlock::iterator MIE = MBB->end (); + while (MII != MIE) { + MachineInstr *MI = MII; + int Opc = MI->getOpcode(); + if (Opc == Hexagon::CONST32_set) { + int DestReg = MI->getOperand(0).getReg(); + MachineOperand &Symbol = MI->getOperand (1); + + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::LO), DestReg).addOperand(Symbol); + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::HI), DestReg).addOperand(Symbol); + // MBB->erase returns the iterator to the next instruction, which is the + // one we want to process next + MII = MBB->erase (MI); + continue; + } + else if (Opc == Hexagon::CONST32_set_jt) { + int DestReg = MI->getOperand(0).getReg(); + MachineOperand &Symbol = MI->getOperand (1); + + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::LO_jt), DestReg).addOperand(Symbol); + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::HI_jt), DestReg).addOperand(Symbol); + // MBB->erase returns the iterator to the next instruction, which is the + // one we want to process next + MII = MBB->erase (MI); + continue; + } + else if (Opc == Hexagon::CONST32_Label) { + int DestReg = MI->getOperand(0).getReg(); + MachineOperand &Symbol = MI->getOperand (1); + + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::LO_label), DestReg).addOperand(Symbol); + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::HI_label), DestReg).addOperand(Symbol); + // MBB->erase returns the iterator to the next instruction, which is the + // one we want to process next + MII = MBB->erase (MI); + continue; + } + else if (Opc == Hexagon::CONST32_Int_Real) { + int DestReg = MI->getOperand(0).getReg(); + int64_t ImmValue = MI->getOperand(1).getImm (); + + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::LOi), DestReg).addImm(ImmValue); + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::HIi), DestReg).addImm(ImmValue); + MII = MBB->erase (MI); + continue; + } + else if (Opc == Hexagon::CONST64_Int_Real) { + int DestReg = MI->getOperand(0).getReg(); + int64_t ImmValue = MI->getOperand(1).getImm (); + unsigned DestLo = + QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_loreg); + unsigned DestHi = + QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_hireg); + + int32_t LowWord = (ImmValue & 0xFFFFFFFF); + int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF; + + // Lower Registers Lower Half + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::LOi), DestLo).addImm(LowWord); + // Lower Registers Higher Half + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::HIi), DestLo).addImm(LowWord); + // Higher Registers Lower Half + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::LOi), DestHi).addImm(HighWord); + // Higher Registers Higher Half. + BuildMI (*MBB, MII, MI->getDebugLoc(), + TII->get(Hexagon::HIi), DestHi).addImm(HighWord); + MII = MBB->erase (MI); + continue; + } + ++MII; + } + } + + return true; +} + +} + +//===----------------------------------------------------------------------===// +// Public Constructor Functions +//===----------------------------------------------------------------------===// + +FunctionPass * +llvm::createHexagonSplitConst32AndConst64(const HexagonTargetMachine &TM) { + return new HexagonSplitConst32AndConst64(TM); +} diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp index 07d5ce1..fca6707 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp @@ -86,3 +86,5 @@ HexagonSubtarget::HexagonSubtarget(StringRef TT, StringRef CPU, StringRef FS): ModeIEEERndNear = false; } +// Pin the vtable to this file. +void HexagonSubtarget::anchor() {} diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonSubtarget.h b/contrib/llvm/lib/Target/Hexagon/HexagonSubtarget.h index 76a8fba..690bef0 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonSubtarget.h +++ b/contrib/llvm/lib/Target/Hexagon/HexagonSubtarget.h @@ -27,7 +27,7 @@ namespace llvm { class HexagonSubtarget : public HexagonGenSubtargetInfo { - + virtual void anchor(); bool UseMemOps; bool ModeIEEERndNear; diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp index caa1ba4..bb950a0 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -15,6 +15,7 @@ #include "Hexagon.h" #include "HexagonISelLowering.h" #include "HexagonMachineScheduler.h" +#include "HexagonTargetObjectFile.h" #include "llvm/CodeGen/Passes.h" #include "llvm/IR/Module.h" #include "llvm/PassManager.h" @@ -78,6 +79,7 @@ HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT, FrameLowering(Subtarget), InstrItins(&Subtarget.getInstrItineraryData()) { setMCUseCFI(false); + initAsmInfo(); } // addPassesForOptimizations - Allow the backend (target) to add Target @@ -100,17 +102,25 @@ class HexagonPassConfig : public TargetPassConfig { public: HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM) : TargetPassConfig(TM, PM) { - // Enable MI scheduler. - if (!DisableHexagonMISched) { + // FIXME: Rather than calling enablePass(&MachineSchedulerID) below, define + // HexagonSubtarget::enableMachineScheduler() { return true; }. + // That will bypass the SelectionDAG VLIW scheduler, which is probably just + // hurting compile time and will be removed eventually anyway. + if (DisableHexagonMISched) + disablePass(&MachineSchedulerID); + else enablePass(&MachineSchedulerID); - MachineSchedRegistry::setDefault(createVLIWMachineSched); - } } HexagonTargetMachine &getHexagonTargetMachine() const { return getTM<HexagonTargetMachine>(); } + virtual ScheduleDAGInstrs * + createMachineScheduler(MachineSchedContext *C) const { + return createVLIWMachineSched(C); + } + virtual bool addInstSelector(); virtual bool addPreRegAlloc(); virtual bool addPostRegAlloc(); @@ -124,7 +134,7 @@ TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { } bool HexagonPassConfig::addInstSelector() { - const HexagonTargetMachine &TM = getHexagonTargetMachine(); + HexagonTargetMachine &TM = getHexagonTargetMachine(); bool NoOpt = (getOptLevel() == CodeGenOpt::None); if (!NoOpt) @@ -156,9 +166,18 @@ bool HexagonPassConfig::addPostRegAlloc() { } bool HexagonPassConfig::addPreSched2() { + const HexagonTargetMachine &TM = getHexagonTargetMachine(); + const HexagonTargetObjectFile &TLOF = + (const HexagonTargetObjectFile &)getTargetLowering()->getObjFileLowering(); + + addPass(createHexagonCopyToCombine()); if (getOptLevel() != CodeGenOpt::None) addPass(&IfConverterID); - return false; + if (!TLOF.IsSmallDataEnabled()) { + addPass(createHexagonSplitConst32AndConst64(TM)); + printAndVerify("After hexagon split const32/64 pass"); + } + return true; } bool HexagonPassConfig::addPreEmitPass() { diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp index 993fcfa..7773cff 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp @@ -25,7 +25,8 @@ using namespace llvm; static cl::opt<int> SmallDataThreshold("hexagon-small-data-threshold", - cl::init(8), cl::Hidden); + cl::init(8), cl::Hidden, + cl::desc("The maximum size of an object in the sdata section")); void HexagonTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { @@ -46,6 +47,11 @@ void HexagonTargetObjectFile::Initialize(MCContext &Ctx, static bool IsInSmallSection(uint64_t Size) { return Size > 0 && Size <= (uint64_t)SmallDataThreshold; } + +bool HexagonTargetObjectFile::IsSmallDataEnabled () const { + return SmallDataThreshold > 0; +} + /// IsGlobalInSmallSection - Return true if this global value should be /// placed into small data/bss section. bool HexagonTargetObjectFile::IsGlobalInSmallSection(const GlobalValue *GV, diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.h b/contrib/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.h index 6933450..41f6792 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.h +++ b/contrib/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.h @@ -29,6 +29,7 @@ namespace llvm { bool IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM) const; + bool IsSmallDataEnabled () const; const MCSection* SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp index 39995e1..41e382d 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp @@ -164,7 +164,6 @@ namespace { unsigned, std::map <MachineInstr*, SUnit*>); bool isNewifiable(MachineInstr* MI); bool isCondInst(MachineInstr* MI); - bool IsNewifyStore (MachineInstr* MI); bool tryAllocateResourcesForConstExt(MachineInstr* MI); bool canReserveResourcesForConstExt(MachineInstr *MI); void reserveResourcesForConstExt(MachineInstr* MI); @@ -383,104 +382,6 @@ static bool IsControlFlow(MachineInstr* MI) { return (MI->getDesc().isTerminator() || MI->getDesc().isCall()); } -// Function returns true if an instruction can be promoted to the new-value -// store. It will always return false for v2 and v3. -// It lists all the conditional and unconditional stores that can be promoted -// to the new-value stores. - -bool HexagonPacketizerList::IsNewifyStore (MachineInstr* MI) { - const HexagonRegisterInfo* QRI = - (const HexagonRegisterInfo *) TM.getRegisterInfo(); - switch (MI->getOpcode()) - { - // store byte - case Hexagon::STrib: - case Hexagon::STrib_indexed: - case Hexagon::STrib_indexed_shl_V4: - case Hexagon::STrib_shl_V4: - case Hexagon::STb_GP_V4: - case Hexagon::POST_STbri: - case Hexagon::STrib_cPt: - case Hexagon::STrib_cdnPt_V4: - case Hexagon::STrib_cNotPt: - case Hexagon::STrib_cdnNotPt_V4: - case Hexagon::STrib_indexed_cPt: - case Hexagon::STrib_indexed_cdnPt_V4: - case Hexagon::STrib_indexed_cNotPt: - case Hexagon::STrib_indexed_cdnNotPt_V4: - case Hexagon::STrib_indexed_shl_cPt_V4: - case Hexagon::STrib_indexed_shl_cdnPt_V4: - case Hexagon::STrib_indexed_shl_cNotPt_V4: - case Hexagon::STrib_indexed_shl_cdnNotPt_V4: - case Hexagon::POST_STbri_cPt: - case Hexagon::POST_STbri_cdnPt_V4: - case Hexagon::POST_STbri_cNotPt: - case Hexagon::POST_STbri_cdnNotPt_V4: - case Hexagon::STb_GP_cPt_V4: - case Hexagon::STb_GP_cNotPt_V4: - case Hexagon::STb_GP_cdnPt_V4: - case Hexagon::STb_GP_cdnNotPt_V4: - - // store halfword - case Hexagon::STrih: - case Hexagon::STrih_indexed: - case Hexagon::STrih_indexed_shl_V4: - case Hexagon::STrih_shl_V4: - case Hexagon::STh_GP_V4: - case Hexagon::POST_SThri: - case Hexagon::STrih_cPt: - case Hexagon::STrih_cdnPt_V4: - case Hexagon::STrih_cNotPt: - case Hexagon::STrih_cdnNotPt_V4: - case Hexagon::STrih_indexed_cPt: - case Hexagon::STrih_indexed_cdnPt_V4: - case Hexagon::STrih_indexed_cNotPt: - case Hexagon::STrih_indexed_cdnNotPt_V4: - case Hexagon::STrih_indexed_shl_cPt_V4: - case Hexagon::STrih_indexed_shl_cdnPt_V4: - case Hexagon::STrih_indexed_shl_cNotPt_V4: - case Hexagon::STrih_indexed_shl_cdnNotPt_V4: - case Hexagon::POST_SThri_cPt: - case Hexagon::POST_SThri_cdnPt_V4: - case Hexagon::POST_SThri_cNotPt: - case Hexagon::POST_SThri_cdnNotPt_V4: - case Hexagon::STh_GP_cPt_V4: - case Hexagon::STh_GP_cNotPt_V4: - case Hexagon::STh_GP_cdnPt_V4: - case Hexagon::STh_GP_cdnNotPt_V4: - - // store word - case Hexagon::STriw: - case Hexagon::STriw_indexed: - case Hexagon::STriw_indexed_shl_V4: - case Hexagon::STriw_shl_V4: - case Hexagon::STw_GP_V4: - case Hexagon::POST_STwri: - case Hexagon::STriw_cPt: - case Hexagon::STriw_cdnPt_V4: - case Hexagon::STriw_cNotPt: - case Hexagon::STriw_cdnNotPt_V4: - case Hexagon::STriw_indexed_cPt: - case Hexagon::STriw_indexed_cdnPt_V4: - case Hexagon::STriw_indexed_cNotPt: - case Hexagon::STriw_indexed_cdnNotPt_V4: - case Hexagon::STriw_indexed_shl_cPt_V4: - case Hexagon::STriw_indexed_shl_cdnPt_V4: - case Hexagon::STriw_indexed_shl_cNotPt_V4: - case Hexagon::STriw_indexed_shl_cdnNotPt_V4: - case Hexagon::POST_STwri_cPt: - case Hexagon::POST_STwri_cdnPt_V4: - case Hexagon::POST_STwri_cNotPt: - case Hexagon::POST_STwri_cdnNotPt_V4: - case Hexagon::STw_GP_cPt_V4: - case Hexagon::STw_GP_cNotPt_V4: - case Hexagon::STw_GP_cdnPt_V4: - case Hexagon::STw_GP_cdnNotPt_V4: - return QRI->Subtarget.hasV4TOps(); - } - return false; -} - static bool IsLoopN(MachineInstr *MI) { return (MI->getOpcode() == Hexagon::LOOP0_i || MI->getOpcode() == Hexagon::LOOP0_r); @@ -498,769 +399,11 @@ static bool DoesModifyCalleeSavedReg(MachineInstr *MI, return false; } -// Return the new value instruction for a given store. -static int GetDotNewOp(const int opc) { - switch (opc) { - default: llvm_unreachable("Unknown .new type"); - // store new value byte - case Hexagon::STrib: - return Hexagon::STrib_nv_V4; - - case Hexagon::STrib_indexed: - return Hexagon::STrib_indexed_nv_V4; - - case Hexagon::STrib_indexed_shl_V4: - return Hexagon::STrib_indexed_shl_nv_V4; - - case Hexagon::STrib_shl_V4: - return Hexagon::STrib_shl_nv_V4; - - case Hexagon::STb_GP_V4: - return Hexagon::STb_GP_nv_V4; - - case Hexagon::POST_STbri: - return Hexagon::POST_STbri_nv_V4; - - case Hexagon::STrib_cPt: - return Hexagon::STrib_cPt_nv_V4; - - case Hexagon::STrib_cdnPt_V4: - return Hexagon::STrib_cdnPt_nv_V4; - - case Hexagon::STrib_cNotPt: - return Hexagon::STrib_cNotPt_nv_V4; - - case Hexagon::STrib_cdnNotPt_V4: - return Hexagon::STrib_cdnNotPt_nv_V4; - - case Hexagon::STrib_indexed_cPt: - return Hexagon::STrib_indexed_cPt_nv_V4; - - case Hexagon::STrib_indexed_cdnPt_V4: - return Hexagon::STrib_indexed_cdnPt_nv_V4; - - case Hexagon::STrib_indexed_cNotPt: - return Hexagon::STrib_indexed_cNotPt_nv_V4; - - case Hexagon::STrib_indexed_cdnNotPt_V4: - return Hexagon::STrib_indexed_cdnNotPt_nv_V4; - - case Hexagon::STrib_indexed_shl_cPt_V4: - return Hexagon::STrib_indexed_shl_cPt_nv_V4; - - case Hexagon::STrib_indexed_shl_cdnPt_V4: - return Hexagon::STrib_indexed_shl_cdnPt_nv_V4; - - case Hexagon::STrib_indexed_shl_cNotPt_V4: - return Hexagon::STrib_indexed_shl_cNotPt_nv_V4; - - case Hexagon::STrib_indexed_shl_cdnNotPt_V4: - return Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_STbri_cPt: - return Hexagon::POST_STbri_cPt_nv_V4; - - case Hexagon::POST_STbri_cdnPt_V4: - return Hexagon::POST_STbri_cdnPt_nv_V4; - - case Hexagon::POST_STbri_cNotPt: - return Hexagon::POST_STbri_cNotPt_nv_V4; - - case Hexagon::POST_STbri_cdnNotPt_V4: - return Hexagon::POST_STbri_cdnNotPt_nv_V4; - - case Hexagon::STb_GP_cPt_V4: - return Hexagon::STb_GP_cPt_nv_V4; - - case Hexagon::STb_GP_cNotPt_V4: - return Hexagon::STb_GP_cNotPt_nv_V4; - - case Hexagon::STb_GP_cdnPt_V4: - return Hexagon::STb_GP_cdnPt_nv_V4; - - case Hexagon::STb_GP_cdnNotPt_V4: - return Hexagon::STb_GP_cdnNotPt_nv_V4; - - // store new value halfword - case Hexagon::STrih: - return Hexagon::STrih_nv_V4; - - case Hexagon::STrih_indexed: - return Hexagon::STrih_indexed_nv_V4; - - case Hexagon::STrih_indexed_shl_V4: - return Hexagon::STrih_indexed_shl_nv_V4; - - case Hexagon::STrih_shl_V4: - return Hexagon::STrih_shl_nv_V4; - - case Hexagon::STh_GP_V4: - return Hexagon::STh_GP_nv_V4; - - case Hexagon::POST_SThri: - return Hexagon::POST_SThri_nv_V4; - - case Hexagon::STrih_cPt: - return Hexagon::STrih_cPt_nv_V4; - - case Hexagon::STrih_cdnPt_V4: - return Hexagon::STrih_cdnPt_nv_V4; - - case Hexagon::STrih_cNotPt: - return Hexagon::STrih_cNotPt_nv_V4; - - case Hexagon::STrih_cdnNotPt_V4: - return Hexagon::STrih_cdnNotPt_nv_V4; - - case Hexagon::STrih_indexed_cPt: - return Hexagon::STrih_indexed_cPt_nv_V4; - - case Hexagon::STrih_indexed_cdnPt_V4: - return Hexagon::STrih_indexed_cdnPt_nv_V4; - - case Hexagon::STrih_indexed_cNotPt: - return Hexagon::STrih_indexed_cNotPt_nv_V4; - - case Hexagon::STrih_indexed_cdnNotPt_V4: - return Hexagon::STrih_indexed_cdnNotPt_nv_V4; - - case Hexagon::STrih_indexed_shl_cPt_V4: - return Hexagon::STrih_indexed_shl_cPt_nv_V4; - - case Hexagon::STrih_indexed_shl_cdnPt_V4: - return Hexagon::STrih_indexed_shl_cdnPt_nv_V4; - - case Hexagon::STrih_indexed_shl_cNotPt_V4: - return Hexagon::STrih_indexed_shl_cNotPt_nv_V4; - - case Hexagon::STrih_indexed_shl_cdnNotPt_V4: - return Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_SThri_cPt: - return Hexagon::POST_SThri_cPt_nv_V4; - - case Hexagon::POST_SThri_cdnPt_V4: - return Hexagon::POST_SThri_cdnPt_nv_V4; - - case Hexagon::POST_SThri_cNotPt: - return Hexagon::POST_SThri_cNotPt_nv_V4; - - case Hexagon::POST_SThri_cdnNotPt_V4: - return Hexagon::POST_SThri_cdnNotPt_nv_V4; - - case Hexagon::STh_GP_cPt_V4: - return Hexagon::STh_GP_cPt_nv_V4; - - case Hexagon::STh_GP_cNotPt_V4: - return Hexagon::STh_GP_cNotPt_nv_V4; - - case Hexagon::STh_GP_cdnPt_V4: - return Hexagon::STh_GP_cdnPt_nv_V4; - - case Hexagon::STh_GP_cdnNotPt_V4: - return Hexagon::STh_GP_cdnNotPt_nv_V4; - - // store new value word - case Hexagon::STriw: - return Hexagon::STriw_nv_V4; - - case Hexagon::STriw_indexed: - return Hexagon::STriw_indexed_nv_V4; - - case Hexagon::STriw_indexed_shl_V4: - return Hexagon::STriw_indexed_shl_nv_V4; - - case Hexagon::STriw_shl_V4: - return Hexagon::STriw_shl_nv_V4; - - case Hexagon::STw_GP_V4: - return Hexagon::STw_GP_nv_V4; - - case Hexagon::POST_STwri: - return Hexagon::POST_STwri_nv_V4; - - case Hexagon::STriw_cPt: - return Hexagon::STriw_cPt_nv_V4; - - case Hexagon::STriw_cdnPt_V4: - return Hexagon::STriw_cdnPt_nv_V4; - - case Hexagon::STriw_cNotPt: - return Hexagon::STriw_cNotPt_nv_V4; - - case Hexagon::STriw_cdnNotPt_V4: - return Hexagon::STriw_cdnNotPt_nv_V4; - - case Hexagon::STriw_indexed_cPt: - return Hexagon::STriw_indexed_cPt_nv_V4; - - case Hexagon::STriw_indexed_cdnPt_V4: - return Hexagon::STriw_indexed_cdnPt_nv_V4; - - case Hexagon::STriw_indexed_cNotPt: - return Hexagon::STriw_indexed_cNotPt_nv_V4; - - case Hexagon::STriw_indexed_cdnNotPt_V4: - return Hexagon::STriw_indexed_cdnNotPt_nv_V4; - - case Hexagon::STriw_indexed_shl_cPt_V4: - return Hexagon::STriw_indexed_shl_cPt_nv_V4; - - case Hexagon::STriw_indexed_shl_cdnPt_V4: - return Hexagon::STriw_indexed_shl_cdnPt_nv_V4; - - case Hexagon::STriw_indexed_shl_cNotPt_V4: - return Hexagon::STriw_indexed_shl_cNotPt_nv_V4; - - case Hexagon::STriw_indexed_shl_cdnNotPt_V4: - return Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_STwri_cPt: - return Hexagon::POST_STwri_cPt_nv_V4; - - case Hexagon::POST_STwri_cdnPt_V4: - return Hexagon::POST_STwri_cdnPt_nv_V4; - - case Hexagon::POST_STwri_cNotPt: - return Hexagon::POST_STwri_cNotPt_nv_V4; - - case Hexagon::POST_STwri_cdnNotPt_V4: - return Hexagon::POST_STwri_cdnNotPt_nv_V4; - - case Hexagon::STw_GP_cPt_V4: - return Hexagon::STw_GP_cPt_nv_V4; - - case Hexagon::STw_GP_cNotPt_V4: - return Hexagon::STw_GP_cNotPt_nv_V4; - - case Hexagon::STw_GP_cdnPt_V4: - return Hexagon::STw_GP_cdnPt_nv_V4; - - case Hexagon::STw_GP_cdnNotPt_V4: - return Hexagon::STw_GP_cdnNotPt_nv_V4; - - } -} - -// Return .new predicate version for an instruction -static int GetDotNewPredOp(MachineInstr *MI, - const MachineBranchProbabilityInfo *MBPI, - const HexagonInstrInfo *QII) { - switch (MI->getOpcode()) { - default: llvm_unreachable("Unknown .new type"); - // Conditional stores - // Store byte conditionally - case Hexagon::STrib_cPt : - return Hexagon::STrib_cdnPt_V4; - - case Hexagon::STrib_cNotPt : - return Hexagon::STrib_cdnNotPt_V4; - - case Hexagon::STrib_indexed_cPt : - return Hexagon::STrib_indexed_cdnPt_V4; - - case Hexagon::STrib_indexed_cNotPt : - return Hexagon::STrib_indexed_cdnNotPt_V4; - - case Hexagon::STrib_imm_cPt_V4 : - return Hexagon::STrib_imm_cdnPt_V4; - - case Hexagon::STrib_imm_cNotPt_V4 : - return Hexagon::STrib_imm_cdnNotPt_V4; - - case Hexagon::POST_STbri_cPt : - return Hexagon::POST_STbri_cdnPt_V4; - - case Hexagon::POST_STbri_cNotPt : - return Hexagon::POST_STbri_cdnNotPt_V4; - - case Hexagon::STrib_indexed_shl_cPt_V4 : - return Hexagon::STrib_indexed_shl_cdnPt_V4; - - case Hexagon::STrib_indexed_shl_cNotPt_V4 : - return Hexagon::STrib_indexed_shl_cdnNotPt_V4; - - case Hexagon::STb_GP_cPt_V4 : - return Hexagon::STb_GP_cdnPt_V4; - - case Hexagon::STb_GP_cNotPt_V4 : - return Hexagon::STb_GP_cdnNotPt_V4; - - // Store doubleword conditionally - case Hexagon::STrid_cPt : - return Hexagon::STrid_cdnPt_V4; - - case Hexagon::STrid_cNotPt : - return Hexagon::STrid_cdnNotPt_V4; - - case Hexagon::STrid_indexed_cPt : - return Hexagon::STrid_indexed_cdnPt_V4; - - case Hexagon::STrid_indexed_cNotPt : - return Hexagon::STrid_indexed_cdnNotPt_V4; - - case Hexagon::STrid_indexed_shl_cPt_V4 : - return Hexagon::STrid_indexed_shl_cdnPt_V4; - - case Hexagon::STrid_indexed_shl_cNotPt_V4 : - return Hexagon::STrid_indexed_shl_cdnNotPt_V4; - - case Hexagon::POST_STdri_cPt : - return Hexagon::POST_STdri_cdnPt_V4; - - case Hexagon::POST_STdri_cNotPt : - return Hexagon::POST_STdri_cdnNotPt_V4; - - case Hexagon::STd_GP_cPt_V4 : - return Hexagon::STd_GP_cdnPt_V4; - - case Hexagon::STd_GP_cNotPt_V4 : - return Hexagon::STd_GP_cdnNotPt_V4; - - // Store halfword conditionally - case Hexagon::STrih_cPt : - return Hexagon::STrih_cdnPt_V4; - - case Hexagon::STrih_cNotPt : - return Hexagon::STrih_cdnNotPt_V4; - - case Hexagon::STrih_indexed_cPt : - return Hexagon::STrih_indexed_cdnPt_V4; - - case Hexagon::STrih_indexed_cNotPt : - return Hexagon::STrih_indexed_cdnNotPt_V4; - - case Hexagon::STrih_imm_cPt_V4 : - return Hexagon::STrih_imm_cdnPt_V4; - - case Hexagon::STrih_imm_cNotPt_V4 : - return Hexagon::STrih_imm_cdnNotPt_V4; - - case Hexagon::STrih_indexed_shl_cPt_V4 : - return Hexagon::STrih_indexed_shl_cdnPt_V4; - - case Hexagon::STrih_indexed_shl_cNotPt_V4 : - return Hexagon::STrih_indexed_shl_cdnNotPt_V4; - - case Hexagon::POST_SThri_cPt : - return Hexagon::POST_SThri_cdnPt_V4; - - case Hexagon::POST_SThri_cNotPt : - return Hexagon::POST_SThri_cdnNotPt_V4; - - case Hexagon::STh_GP_cPt_V4 : - return Hexagon::STh_GP_cdnPt_V4; - - case Hexagon::STh_GP_cNotPt_V4 : - return Hexagon::STh_GP_cdnNotPt_V4; - - // Store word conditionally - case Hexagon::STriw_cPt : - return Hexagon::STriw_cdnPt_V4; - - case Hexagon::STriw_cNotPt : - return Hexagon::STriw_cdnNotPt_V4; - - case Hexagon::STriw_indexed_cPt : - return Hexagon::STriw_indexed_cdnPt_V4; - - case Hexagon::STriw_indexed_cNotPt : - return Hexagon::STriw_indexed_cdnNotPt_V4; - - case Hexagon::STriw_imm_cPt_V4 : - return Hexagon::STriw_imm_cdnPt_V4; - - case Hexagon::STriw_imm_cNotPt_V4 : - return Hexagon::STriw_imm_cdnNotPt_V4; - - case Hexagon::STriw_indexed_shl_cPt_V4 : - return Hexagon::STriw_indexed_shl_cdnPt_V4; - - case Hexagon::STriw_indexed_shl_cNotPt_V4 : - return Hexagon::STriw_indexed_shl_cdnNotPt_V4; - - case Hexagon::POST_STwri_cPt : - return Hexagon::POST_STwri_cdnPt_V4; - - case Hexagon::POST_STwri_cNotPt : - return Hexagon::POST_STwri_cdnNotPt_V4; - - case Hexagon::STw_GP_cPt_V4 : - return Hexagon::STw_GP_cdnPt_V4; - - case Hexagon::STw_GP_cNotPt_V4 : - return Hexagon::STw_GP_cdnNotPt_V4; - - // Condtional Jumps - case Hexagon::JMP_t: - case Hexagon::JMP_f: - return QII->getDotNewPredJumpOp(MI, MBPI); - - case Hexagon::JMPR_t: - return Hexagon::JMPR_tnew_tV3; - - case Hexagon::JMPR_f: - return Hexagon::JMPR_fnew_tV3; - - // Conditional Transfers - case Hexagon::TFR_cPt: - return Hexagon::TFR_cdnPt; - - case Hexagon::TFR_cNotPt: - return Hexagon::TFR_cdnNotPt; - - case Hexagon::TFRI_cPt: - return Hexagon::TFRI_cdnPt; - - case Hexagon::TFRI_cNotPt: - return Hexagon::TFRI_cdnNotPt; - - // Load double word - case Hexagon::LDrid_cPt : - return Hexagon::LDrid_cdnPt; - - case Hexagon::LDrid_cNotPt : - return Hexagon::LDrid_cdnNotPt; - - case Hexagon::LDrid_indexed_cPt : - return Hexagon::LDrid_indexed_cdnPt; - - case Hexagon::LDrid_indexed_cNotPt : - return Hexagon::LDrid_indexed_cdnNotPt; - - case Hexagon::POST_LDrid_cPt : - return Hexagon::POST_LDrid_cdnPt_V4; - - case Hexagon::POST_LDrid_cNotPt : - return Hexagon::POST_LDrid_cdnNotPt_V4; - - // Load word - case Hexagon::LDriw_cPt : - return Hexagon::LDriw_cdnPt; - - case Hexagon::LDriw_cNotPt : - return Hexagon::LDriw_cdnNotPt; - - case Hexagon::LDriw_indexed_cPt : - return Hexagon::LDriw_indexed_cdnPt; - - case Hexagon::LDriw_indexed_cNotPt : - return Hexagon::LDriw_indexed_cdnNotPt; - - case Hexagon::POST_LDriw_cPt : - return Hexagon::POST_LDriw_cdnPt_V4; - - case Hexagon::POST_LDriw_cNotPt : - return Hexagon::POST_LDriw_cdnNotPt_V4; - - // Load halfword - case Hexagon::LDrih_cPt : - return Hexagon::LDrih_cdnPt; - - case Hexagon::LDrih_cNotPt : - return Hexagon::LDrih_cdnNotPt; - - case Hexagon::LDrih_indexed_cPt : - return Hexagon::LDrih_indexed_cdnPt; - - case Hexagon::LDrih_indexed_cNotPt : - return Hexagon::LDrih_indexed_cdnNotPt; - - case Hexagon::POST_LDrih_cPt : - return Hexagon::POST_LDrih_cdnPt_V4; - - case Hexagon::POST_LDrih_cNotPt : - return Hexagon::POST_LDrih_cdnNotPt_V4; - - // Load byte - case Hexagon::LDrib_cPt : - return Hexagon::LDrib_cdnPt; - - case Hexagon::LDrib_cNotPt : - return Hexagon::LDrib_cdnNotPt; - - case Hexagon::LDrib_indexed_cPt : - return Hexagon::LDrib_indexed_cdnPt; - - case Hexagon::LDrib_indexed_cNotPt : - return Hexagon::LDrib_indexed_cdnNotPt; - - case Hexagon::POST_LDrib_cPt : - return Hexagon::POST_LDrib_cdnPt_V4; - - case Hexagon::POST_LDrib_cNotPt : - return Hexagon::POST_LDrib_cdnNotPt_V4; - - // Load unsigned halfword - case Hexagon::LDriuh_cPt : - return Hexagon::LDriuh_cdnPt; - - case Hexagon::LDriuh_cNotPt : - return Hexagon::LDriuh_cdnNotPt; - - case Hexagon::LDriuh_indexed_cPt : - return Hexagon::LDriuh_indexed_cdnPt; - - case Hexagon::LDriuh_indexed_cNotPt : - return Hexagon::LDriuh_indexed_cdnNotPt; - - case Hexagon::POST_LDriuh_cPt : - return Hexagon::POST_LDriuh_cdnPt_V4; - - case Hexagon::POST_LDriuh_cNotPt : - return Hexagon::POST_LDriuh_cdnNotPt_V4; - - // Load unsigned byte - case Hexagon::LDriub_cPt : - return Hexagon::LDriub_cdnPt; - - case Hexagon::LDriub_cNotPt : - return Hexagon::LDriub_cdnNotPt; - - case Hexagon::LDriub_indexed_cPt : - return Hexagon::LDriub_indexed_cdnPt; - - case Hexagon::LDriub_indexed_cNotPt : - return Hexagon::LDriub_indexed_cdnNotPt; - - case Hexagon::POST_LDriub_cPt : - return Hexagon::POST_LDriub_cdnPt_V4; - - case Hexagon::POST_LDriub_cNotPt : - return Hexagon::POST_LDriub_cdnNotPt_V4; - - // V4 indexed+scaled load - - case Hexagon::LDrid_indexed_shl_cPt_V4 : - return Hexagon::LDrid_indexed_shl_cdnPt_V4; - - case Hexagon::LDrid_indexed_shl_cNotPt_V4 : - return Hexagon::LDrid_indexed_shl_cdnNotPt_V4; - - case Hexagon::LDrib_indexed_shl_cPt_V4 : - return Hexagon::LDrib_indexed_shl_cdnPt_V4; - - case Hexagon::LDrib_indexed_shl_cNotPt_V4 : - return Hexagon::LDrib_indexed_shl_cdnNotPt_V4; - - case Hexagon::LDriub_indexed_shl_cPt_V4 : - return Hexagon::LDriub_indexed_shl_cdnPt_V4; - - case Hexagon::LDriub_indexed_shl_cNotPt_V4 : - return Hexagon::LDriub_indexed_shl_cdnNotPt_V4; - - case Hexagon::LDrih_indexed_shl_cPt_V4 : - return Hexagon::LDrih_indexed_shl_cdnPt_V4; - - case Hexagon::LDrih_indexed_shl_cNotPt_V4 : - return Hexagon::LDrih_indexed_shl_cdnNotPt_V4; - - case Hexagon::LDriuh_indexed_shl_cPt_V4 : - return Hexagon::LDriuh_indexed_shl_cdnPt_V4; - - case Hexagon::LDriuh_indexed_shl_cNotPt_V4 : - return Hexagon::LDriuh_indexed_shl_cdnNotPt_V4; - - case Hexagon::LDriw_indexed_shl_cPt_V4 : - return Hexagon::LDriw_indexed_shl_cdnPt_V4; - - case Hexagon::LDriw_indexed_shl_cNotPt_V4 : - return Hexagon::LDriw_indexed_shl_cdnNotPt_V4; - - // V4 global address load - - case Hexagon::LDd_GP_cPt_V4: - return Hexagon::LDd_GP_cdnPt_V4; - - case Hexagon::LDd_GP_cNotPt_V4: - return Hexagon::LDd_GP_cdnNotPt_V4; - - case Hexagon::LDb_GP_cPt_V4: - return Hexagon::LDb_GP_cdnPt_V4; - - case Hexagon::LDb_GP_cNotPt_V4: - return Hexagon::LDb_GP_cdnNotPt_V4; - - case Hexagon::LDub_GP_cPt_V4: - return Hexagon::LDub_GP_cdnPt_V4; - - case Hexagon::LDub_GP_cNotPt_V4: - return Hexagon::LDub_GP_cdnNotPt_V4; - - case Hexagon::LDh_GP_cPt_V4: - return Hexagon::LDh_GP_cdnPt_V4; - - case Hexagon::LDh_GP_cNotPt_V4: - return Hexagon::LDh_GP_cdnNotPt_V4; - - case Hexagon::LDuh_GP_cPt_V4: - return Hexagon::LDuh_GP_cdnPt_V4; - - case Hexagon::LDuh_GP_cNotPt_V4: - return Hexagon::LDuh_GP_cdnNotPt_V4; - - case Hexagon::LDw_GP_cPt_V4: - return Hexagon::LDw_GP_cdnPt_V4; - - case Hexagon::LDw_GP_cNotPt_V4: - return Hexagon::LDw_GP_cdnNotPt_V4; - - // Conditional store new-value byte - case Hexagon::STrib_cPt_nv_V4 : - return Hexagon::STrib_cdnPt_nv_V4; - case Hexagon::STrib_cNotPt_nv_V4 : - return Hexagon::STrib_cdnNotPt_nv_V4; - - case Hexagon::STrib_indexed_cPt_nv_V4 : - return Hexagon::STrib_indexed_cdnPt_nv_V4; - case Hexagon::STrib_indexed_cNotPt_nv_V4 : - return Hexagon::STrib_indexed_cdnNotPt_nv_V4; - - case Hexagon::STrib_indexed_shl_cPt_nv_V4 : - return Hexagon::STrib_indexed_shl_cdnPt_nv_V4; - case Hexagon::STrib_indexed_shl_cNotPt_nv_V4 : - return Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_STbri_cPt_nv_V4 : - return Hexagon::POST_STbri_cdnPt_nv_V4; - case Hexagon::POST_STbri_cNotPt_nv_V4 : - return Hexagon::POST_STbri_cdnNotPt_nv_V4; - - case Hexagon::STb_GP_cPt_nv_V4 : - return Hexagon::STb_GP_cdnPt_nv_V4; - - case Hexagon::STb_GP_cNotPt_nv_V4 : - return Hexagon::STb_GP_cdnNotPt_nv_V4; - - // Conditional store new-value halfword - case Hexagon::STrih_cPt_nv_V4 : - return Hexagon::STrih_cdnPt_nv_V4; - case Hexagon::STrih_cNotPt_nv_V4 : - return Hexagon::STrih_cdnNotPt_nv_V4; - - case Hexagon::STrih_indexed_cPt_nv_V4 : - return Hexagon::STrih_indexed_cdnPt_nv_V4; - case Hexagon::STrih_indexed_cNotPt_nv_V4 : - return Hexagon::STrih_indexed_cdnNotPt_nv_V4; - - case Hexagon::STrih_indexed_shl_cPt_nv_V4 : - return Hexagon::STrih_indexed_shl_cdnPt_nv_V4; - case Hexagon::STrih_indexed_shl_cNotPt_nv_V4 : - return Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_SThri_cPt_nv_V4 : - return Hexagon::POST_SThri_cdnPt_nv_V4; - case Hexagon::POST_SThri_cNotPt_nv_V4 : - return Hexagon::POST_SThri_cdnNotPt_nv_V4; - - case Hexagon::STh_GP_cPt_nv_V4 : - return Hexagon::STh_GP_cdnPt_nv_V4; - - case Hexagon::STh_GP_cNotPt_nv_V4 : - return Hexagon::STh_GP_cdnNotPt_nv_V4; - - // Conditional store new-value word - case Hexagon::STriw_cPt_nv_V4 : - return Hexagon::STriw_cdnPt_nv_V4; - case Hexagon::STriw_cNotPt_nv_V4 : - return Hexagon::STriw_cdnNotPt_nv_V4; - - case Hexagon::STriw_indexed_cPt_nv_V4 : - return Hexagon::STriw_indexed_cdnPt_nv_V4; - case Hexagon::STriw_indexed_cNotPt_nv_V4 : - return Hexagon::STriw_indexed_cdnNotPt_nv_V4; - - case Hexagon::STriw_indexed_shl_cPt_nv_V4 : - return Hexagon::STriw_indexed_shl_cdnPt_nv_V4; - case Hexagon::STriw_indexed_shl_cNotPt_nv_V4 : - return Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4; - - case Hexagon::POST_STwri_cPt_nv_V4 : - return Hexagon::POST_STwri_cdnPt_nv_V4; - case Hexagon::POST_STwri_cNotPt_nv_V4: - return Hexagon::POST_STwri_cdnNotPt_nv_V4; - - case Hexagon::STw_GP_cPt_nv_V4 : - return Hexagon::STw_GP_cdnPt_nv_V4; - - case Hexagon::STw_GP_cNotPt_nv_V4 : - return Hexagon::STw_GP_cdnNotPt_nv_V4; - - // Conditional add - case Hexagon::ADD_ri_cPt : - return Hexagon::ADD_ri_cdnPt; - case Hexagon::ADD_ri_cNotPt : - return Hexagon::ADD_ri_cdnNotPt; - - case Hexagon::ADD_rr_cPt : - return Hexagon::ADD_rr_cdnPt; - case Hexagon::ADD_rr_cNotPt : - return Hexagon::ADD_rr_cdnNotPt; - - // Conditional logical Operations - case Hexagon::XOR_rr_cPt : - return Hexagon::XOR_rr_cdnPt; - case Hexagon::XOR_rr_cNotPt : - return Hexagon::XOR_rr_cdnNotPt; - - case Hexagon::AND_rr_cPt : - return Hexagon::AND_rr_cdnPt; - case Hexagon::AND_rr_cNotPt : - return Hexagon::AND_rr_cdnNotPt; - - case Hexagon::OR_rr_cPt : - return Hexagon::OR_rr_cdnPt; - case Hexagon::OR_rr_cNotPt : - return Hexagon::OR_rr_cdnNotPt; - - // Conditional Subtract - case Hexagon::SUB_rr_cPt : - return Hexagon::SUB_rr_cdnPt; - case Hexagon::SUB_rr_cNotPt : - return Hexagon::SUB_rr_cdnNotPt; - - // Conditional combine - case Hexagon::COMBINE_rr_cPt : - return Hexagon::COMBINE_rr_cdnPt; - case Hexagon::COMBINE_rr_cNotPt : - return Hexagon::COMBINE_rr_cdnNotPt; - - case Hexagon::ASLH_cPt_V4 : - return Hexagon::ASLH_cdnPt_V4; - case Hexagon::ASLH_cNotPt_V4 : - return Hexagon::ASLH_cdnNotPt_V4; - - case Hexagon::ASRH_cPt_V4 : - return Hexagon::ASRH_cdnPt_V4; - case Hexagon::ASRH_cNotPt_V4 : - return Hexagon::ASRH_cdnNotPt_V4; - - case Hexagon::SXTB_cPt_V4 : - return Hexagon::SXTB_cdnPt_V4; - case Hexagon::SXTB_cNotPt_V4 : - return Hexagon::SXTB_cdnNotPt_V4; - - case Hexagon::SXTH_cPt_V4 : - return Hexagon::SXTH_cdnPt_V4; - case Hexagon::SXTH_cNotPt_V4 : - return Hexagon::SXTH_cdnNotPt_V4; - - case Hexagon::ZXTB_cPt_V4 : - return Hexagon::ZXTB_cdnPt_V4; - case Hexagon::ZXTB_cNotPt_V4 : - return Hexagon::ZXTB_cdnNotPt_V4; - - case Hexagon::ZXTH_cPt_V4 : - return Hexagon::ZXTH_cdnPt_V4; - case Hexagon::ZXTH_cNotPt_V4 : - return Hexagon::ZXTH_cdnNotPt_V4; - } -} - // Returns true if an instruction can be promoted to .new predicate // or new-value store. bool HexagonPacketizerList::isNewifiable(MachineInstr* MI) { - if ( isCondInst(MI) || IsNewifyStore(MI)) + const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; + if ( isCondInst(MI) || QII->mayBeNewStore(MI)) return true; else return false; @@ -1294,896 +437,38 @@ bool HexagonPacketizerList::PromoteToDotNew(MachineInstr* MI, int NewOpcode; if (RC == &Hexagon::PredRegsRegClass) - NewOpcode = GetDotNewPredOp(MI, MBPI, QII); + NewOpcode = QII->GetDotNewPredOp(MI, MBPI); else - NewOpcode = GetDotNewOp(MI->getOpcode()); + NewOpcode = QII->GetDotNewOp(MI); MI->setDesc(QII->get(NewOpcode)); return true; } -// Returns the most basic instruction for the .new predicated instructions and -// new-value stores. -// For example, all of the following instructions will be converted back to the -// same instruction: -// 1) if (p0.new) memw(R0+#0) = R1.new ---> -// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1 -// 3) if (p0.new) memw(R0+#0) = R1 ---> -// -// To understand the translation of instruction 1 to its original form, consider -// a packet with 3 instructions. -// { p0 = cmp.eq(R0,R1) -// if (p0.new) R2 = add(R3, R4) -// R5 = add (R3, R1) -// } -// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet -// -// This instruction can be part of the previous packet only if both p0 and R2 -// are promoted to .new values. This promotion happens in steps, first -// predicate register is promoted to .new and in the next iteration R2 is -// promoted. Therefore, in case of dependence check failure (due to R5) during -// next iteration, it should be converted back to its most basic form. - -static int GetDotOldOp(const int opc) { - switch (opc) { - default: llvm_unreachable("Unknown .old type"); - case Hexagon::TFR_cdnPt: - return Hexagon::TFR_cPt; - - case Hexagon::TFR_cdnNotPt: - return Hexagon::TFR_cNotPt; - - case Hexagon::TFRI_cdnPt: - return Hexagon::TFRI_cPt; - - case Hexagon::TFRI_cdnNotPt: - return Hexagon::TFRI_cNotPt; - - case Hexagon::JMP_tnew_t: - return Hexagon::JMP_t; - - case Hexagon::JMP_fnew_t: - return Hexagon::JMP_f; - - case Hexagon::JMPR_tnew_tV3: - return Hexagon::JMPR_t; - - case Hexagon::JMPR_fnew_tV3: - return Hexagon::JMPR_f; - - // Load double word - - case Hexagon::LDrid_cdnPt : - return Hexagon::LDrid_cPt; - - case Hexagon::LDrid_cdnNotPt : - return Hexagon::LDrid_cNotPt; - - case Hexagon::LDrid_indexed_cdnPt : - return Hexagon::LDrid_indexed_cPt; - - case Hexagon::LDrid_indexed_cdnNotPt : - return Hexagon::LDrid_indexed_cNotPt; - - case Hexagon::POST_LDrid_cdnPt_V4 : - return Hexagon::POST_LDrid_cPt; - - case Hexagon::POST_LDrid_cdnNotPt_V4 : - return Hexagon::POST_LDrid_cNotPt; - - // Load word - - case Hexagon::LDriw_cdnPt : - return Hexagon::LDriw_cPt; - - case Hexagon::LDriw_cdnNotPt : - return Hexagon::LDriw_cNotPt; - - case Hexagon::LDriw_indexed_cdnPt : - return Hexagon::LDriw_indexed_cPt; - - case Hexagon::LDriw_indexed_cdnNotPt : - return Hexagon::LDriw_indexed_cNotPt; - - case Hexagon::POST_LDriw_cdnPt_V4 : - return Hexagon::POST_LDriw_cPt; - - case Hexagon::POST_LDriw_cdnNotPt_V4 : - return Hexagon::POST_LDriw_cNotPt; - - // Load half - - case Hexagon::LDrih_cdnPt : - return Hexagon::LDrih_cPt; - - case Hexagon::LDrih_cdnNotPt : - return Hexagon::LDrih_cNotPt; - - case Hexagon::LDrih_indexed_cdnPt : - return Hexagon::LDrih_indexed_cPt; - - case Hexagon::LDrih_indexed_cdnNotPt : - return Hexagon::LDrih_indexed_cNotPt; - - case Hexagon::POST_LDrih_cdnPt_V4 : - return Hexagon::POST_LDrih_cPt; - - case Hexagon::POST_LDrih_cdnNotPt_V4 : - return Hexagon::POST_LDrih_cNotPt; - - // Load byte - - case Hexagon::LDrib_cdnPt : - return Hexagon::LDrib_cPt; - - case Hexagon::LDrib_cdnNotPt : - return Hexagon::LDrib_cNotPt; - - case Hexagon::LDrib_indexed_cdnPt : - return Hexagon::LDrib_indexed_cPt; - - case Hexagon::LDrib_indexed_cdnNotPt : - return Hexagon::LDrib_indexed_cNotPt; - - case Hexagon::POST_LDrib_cdnPt_V4 : - return Hexagon::POST_LDrib_cPt; - - case Hexagon::POST_LDrib_cdnNotPt_V4 : - return Hexagon::POST_LDrib_cNotPt; - - // Load unsigned half - - case Hexagon::LDriuh_cdnPt : - return Hexagon::LDriuh_cPt; - - case Hexagon::LDriuh_cdnNotPt : - return Hexagon::LDriuh_cNotPt; - - case Hexagon::LDriuh_indexed_cdnPt : - return Hexagon::LDriuh_indexed_cPt; - - case Hexagon::LDriuh_indexed_cdnNotPt : - return Hexagon::LDriuh_indexed_cNotPt; - - case Hexagon::POST_LDriuh_cdnPt_V4 : - return Hexagon::POST_LDriuh_cPt; - - case Hexagon::POST_LDriuh_cdnNotPt_V4 : - return Hexagon::POST_LDriuh_cNotPt; - - // Load unsigned byte - case Hexagon::LDriub_cdnPt : - return Hexagon::LDriub_cPt; - - case Hexagon::LDriub_cdnNotPt : - return Hexagon::LDriub_cNotPt; - - case Hexagon::LDriub_indexed_cdnPt : - return Hexagon::LDriub_indexed_cPt; - - case Hexagon::LDriub_indexed_cdnNotPt : - return Hexagon::LDriub_indexed_cNotPt; - - case Hexagon::POST_LDriub_cdnPt_V4 : - return Hexagon::POST_LDriub_cPt; - - case Hexagon::POST_LDriub_cdnNotPt_V4 : - return Hexagon::POST_LDriub_cNotPt; - - // V4 indexed+scaled Load - - case Hexagon::LDrid_indexed_shl_cdnPt_V4 : - return Hexagon::LDrid_indexed_shl_cPt_V4; - - case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDrid_indexed_shl_cNotPt_V4; - - case Hexagon::LDrib_indexed_shl_cdnPt_V4 : - return Hexagon::LDrib_indexed_shl_cPt_V4; - - case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDrib_indexed_shl_cNotPt_V4; - - case Hexagon::LDriub_indexed_shl_cdnPt_V4 : - return Hexagon::LDriub_indexed_shl_cPt_V4; - - case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDriub_indexed_shl_cNotPt_V4; - - case Hexagon::LDrih_indexed_shl_cdnPt_V4 : - return Hexagon::LDrih_indexed_shl_cPt_V4; - - case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDrih_indexed_shl_cNotPt_V4; - - case Hexagon::LDriuh_indexed_shl_cdnPt_V4 : - return Hexagon::LDriuh_indexed_shl_cPt_V4; - - case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDriuh_indexed_shl_cNotPt_V4; - - case Hexagon::LDriw_indexed_shl_cdnPt_V4 : - return Hexagon::LDriw_indexed_shl_cPt_V4; - - case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 : - return Hexagon::LDriw_indexed_shl_cNotPt_V4; - - // V4 global address load - - case Hexagon::LDd_GP_cdnPt_V4: - return Hexagon::LDd_GP_cPt_V4; - - case Hexagon::LDd_GP_cdnNotPt_V4: - return Hexagon::LDd_GP_cNotPt_V4; - - case Hexagon::LDb_GP_cdnPt_V4: - return Hexagon::LDb_GP_cPt_V4; - - case Hexagon::LDb_GP_cdnNotPt_V4: - return Hexagon::LDb_GP_cNotPt_V4; - - case Hexagon::LDub_GP_cdnPt_V4: - return Hexagon::LDub_GP_cPt_V4; - - case Hexagon::LDub_GP_cdnNotPt_V4: - return Hexagon::LDub_GP_cNotPt_V4; - - case Hexagon::LDh_GP_cdnPt_V4: - return Hexagon::LDh_GP_cPt_V4; - - case Hexagon::LDh_GP_cdnNotPt_V4: - return Hexagon::LDh_GP_cNotPt_V4; - - case Hexagon::LDuh_GP_cdnPt_V4: - return Hexagon::LDuh_GP_cPt_V4; - - case Hexagon::LDuh_GP_cdnNotPt_V4: - return Hexagon::LDuh_GP_cNotPt_V4; - - case Hexagon::LDw_GP_cdnPt_V4: - return Hexagon::LDw_GP_cPt_V4; - - case Hexagon::LDw_GP_cdnNotPt_V4: - return Hexagon::LDw_GP_cNotPt_V4; - - // Conditional add - - case Hexagon::ADD_ri_cdnPt : - return Hexagon::ADD_ri_cPt; - case Hexagon::ADD_ri_cdnNotPt : - return Hexagon::ADD_ri_cNotPt; - - case Hexagon::ADD_rr_cdnPt : - return Hexagon::ADD_rr_cPt; - case Hexagon::ADD_rr_cdnNotPt: - return Hexagon::ADD_rr_cNotPt; - - // Conditional logical Operations - - case Hexagon::XOR_rr_cdnPt : - return Hexagon::XOR_rr_cPt; - case Hexagon::XOR_rr_cdnNotPt : - return Hexagon::XOR_rr_cNotPt; - - case Hexagon::AND_rr_cdnPt : - return Hexagon::AND_rr_cPt; - case Hexagon::AND_rr_cdnNotPt : - return Hexagon::AND_rr_cNotPt; - - case Hexagon::OR_rr_cdnPt : - return Hexagon::OR_rr_cPt; - case Hexagon::OR_rr_cdnNotPt : - return Hexagon::OR_rr_cNotPt; - - // Conditional Subtract - - case Hexagon::SUB_rr_cdnPt : - return Hexagon::SUB_rr_cPt; - case Hexagon::SUB_rr_cdnNotPt : - return Hexagon::SUB_rr_cNotPt; - - // Conditional combine - - case Hexagon::COMBINE_rr_cdnPt : - return Hexagon::COMBINE_rr_cPt; - case Hexagon::COMBINE_rr_cdnNotPt : - return Hexagon::COMBINE_rr_cNotPt; - -// Conditional shift operations - - case Hexagon::ASLH_cdnPt_V4 : - return Hexagon::ASLH_cPt_V4; - case Hexagon::ASLH_cdnNotPt_V4 : - return Hexagon::ASLH_cNotPt_V4; - - case Hexagon::ASRH_cdnPt_V4 : - return Hexagon::ASRH_cPt_V4; - case Hexagon::ASRH_cdnNotPt_V4 : - return Hexagon::ASRH_cNotPt_V4; - - case Hexagon::SXTB_cdnPt_V4 : - return Hexagon::SXTB_cPt_V4; - case Hexagon::SXTB_cdnNotPt_V4 : - return Hexagon::SXTB_cNotPt_V4; - - case Hexagon::SXTH_cdnPt_V4 : - return Hexagon::SXTH_cPt_V4; - case Hexagon::SXTH_cdnNotPt_V4 : - return Hexagon::SXTH_cNotPt_V4; - - case Hexagon::ZXTB_cdnPt_V4 : - return Hexagon::ZXTB_cPt_V4; - case Hexagon::ZXTB_cdnNotPt_V4 : - return Hexagon::ZXTB_cNotPt_V4; - - case Hexagon::ZXTH_cdnPt_V4 : - return Hexagon::ZXTH_cPt_V4; - case Hexagon::ZXTH_cdnNotPt_V4 : - return Hexagon::ZXTH_cNotPt_V4; - - // Store byte - - case Hexagon::STrib_imm_cdnPt_V4 : - return Hexagon::STrib_imm_cPt_V4; - - case Hexagon::STrib_imm_cdnNotPt_V4 : - return Hexagon::STrib_imm_cNotPt_V4; - - case Hexagon::STrib_cdnPt_nv_V4 : - case Hexagon::STrib_cPt_nv_V4 : - case Hexagon::STrib_cdnPt_V4 : - return Hexagon::STrib_cPt; - - case Hexagon::STrib_cdnNotPt_nv_V4 : - case Hexagon::STrib_cNotPt_nv_V4 : - case Hexagon::STrib_cdnNotPt_V4 : - return Hexagon::STrib_cNotPt; - - case Hexagon::STrib_indexed_cdnPt_V4 : - case Hexagon::STrib_indexed_cPt_nv_V4 : - case Hexagon::STrib_indexed_cdnPt_nv_V4 : - return Hexagon::STrib_indexed_cPt; - - case Hexagon::STrib_indexed_cdnNotPt_V4 : - case Hexagon::STrib_indexed_cNotPt_nv_V4 : - case Hexagon::STrib_indexed_cdnNotPt_nv_V4 : - return Hexagon::STrib_indexed_cNotPt; - - case Hexagon::STrib_indexed_shl_cdnPt_nv_V4: - case Hexagon::STrib_indexed_shl_cPt_nv_V4 : - case Hexagon::STrib_indexed_shl_cdnPt_V4 : - return Hexagon::STrib_indexed_shl_cPt_V4; - - case Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4: - case Hexagon::STrib_indexed_shl_cNotPt_nv_V4 : - case Hexagon::STrib_indexed_shl_cdnNotPt_V4 : - return Hexagon::STrib_indexed_shl_cNotPt_V4; - - case Hexagon::POST_STbri_cdnPt_nv_V4 : - case Hexagon::POST_STbri_cPt_nv_V4 : - case Hexagon::POST_STbri_cdnPt_V4 : - return Hexagon::POST_STbri_cPt; - - case Hexagon::POST_STbri_cdnNotPt_nv_V4 : - case Hexagon::POST_STbri_cNotPt_nv_V4: - case Hexagon::POST_STbri_cdnNotPt_V4 : - return Hexagon::POST_STbri_cNotPt; - - case Hexagon::STb_GP_cdnPt_nv_V4: - case Hexagon::STb_GP_cdnPt_V4: - case Hexagon::STb_GP_cPt_nv_V4: - return Hexagon::STb_GP_cPt_V4; - - case Hexagon::STb_GP_cdnNotPt_nv_V4: - case Hexagon::STb_GP_cdnNotPt_V4: - case Hexagon::STb_GP_cNotPt_nv_V4: - return Hexagon::STb_GP_cNotPt_V4; - - // Store new-value byte - unconditional - case Hexagon::STrib_nv_V4: - return Hexagon::STrib; - - case Hexagon::STrib_indexed_nv_V4: - return Hexagon::STrib_indexed; - - case Hexagon::STrib_indexed_shl_nv_V4: - return Hexagon::STrib_indexed_shl_V4; - - case Hexagon::STrib_shl_nv_V4: - return Hexagon::STrib_shl_V4; - - case Hexagon::STb_GP_nv_V4: - return Hexagon::STb_GP_V4; - - case Hexagon::POST_STbri_nv_V4: - return Hexagon::POST_STbri; - - // Store halfword - case Hexagon::STrih_imm_cdnPt_V4 : - return Hexagon::STrih_imm_cPt_V4; - - case Hexagon::STrih_imm_cdnNotPt_V4 : - return Hexagon::STrih_imm_cNotPt_V4; - - case Hexagon::STrih_cdnPt_nv_V4 : - case Hexagon::STrih_cPt_nv_V4 : - case Hexagon::STrih_cdnPt_V4 : - return Hexagon::STrih_cPt; - - case Hexagon::STrih_cdnNotPt_nv_V4 : - case Hexagon::STrih_cNotPt_nv_V4 : - case Hexagon::STrih_cdnNotPt_V4 : - return Hexagon::STrih_cNotPt; - - case Hexagon::STrih_indexed_cdnPt_nv_V4: - case Hexagon::STrih_indexed_cPt_nv_V4 : - case Hexagon::STrih_indexed_cdnPt_V4 : - return Hexagon::STrih_indexed_cPt; - - case Hexagon::STrih_indexed_cdnNotPt_nv_V4: - case Hexagon::STrih_indexed_cNotPt_nv_V4 : - case Hexagon::STrih_indexed_cdnNotPt_V4 : - return Hexagon::STrih_indexed_cNotPt; - - case Hexagon::STrih_indexed_shl_cdnPt_nv_V4 : - case Hexagon::STrih_indexed_shl_cPt_nv_V4 : - case Hexagon::STrih_indexed_shl_cdnPt_V4 : - return Hexagon::STrih_indexed_shl_cPt_V4; - - case Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4 : - case Hexagon::STrih_indexed_shl_cNotPt_nv_V4 : - case Hexagon::STrih_indexed_shl_cdnNotPt_V4 : - return Hexagon::STrih_indexed_shl_cNotPt_V4; - - case Hexagon::POST_SThri_cdnPt_nv_V4 : - case Hexagon::POST_SThri_cPt_nv_V4 : - case Hexagon::POST_SThri_cdnPt_V4 : - return Hexagon::POST_SThri_cPt; - - case Hexagon::POST_SThri_cdnNotPt_nv_V4 : - case Hexagon::POST_SThri_cNotPt_nv_V4 : - case Hexagon::POST_SThri_cdnNotPt_V4 : - return Hexagon::POST_SThri_cNotPt; - - case Hexagon::STh_GP_cdnPt_nv_V4: - case Hexagon::STh_GP_cdnPt_V4: - case Hexagon::STh_GP_cPt_nv_V4: - return Hexagon::STh_GP_cPt_V4; - - case Hexagon::STh_GP_cdnNotPt_nv_V4: - case Hexagon::STh_GP_cdnNotPt_V4: - case Hexagon::STh_GP_cNotPt_nv_V4: - return Hexagon::STh_GP_cNotPt_V4; - - // Store new-value halfword - unconditional - - case Hexagon::STrih_nv_V4: - return Hexagon::STrih; - - case Hexagon::STrih_indexed_nv_V4: - return Hexagon::STrih_indexed; - - case Hexagon::STrih_indexed_shl_nv_V4: - return Hexagon::STrih_indexed_shl_V4; - - case Hexagon::STrih_shl_nv_V4: - return Hexagon::STrih_shl_V4; - - case Hexagon::STh_GP_nv_V4: - return Hexagon::STh_GP_V4; - - case Hexagon::POST_SThri_nv_V4: - return Hexagon::POST_SThri; - - // Store word - - case Hexagon::STriw_imm_cdnPt_V4 : - return Hexagon::STriw_imm_cPt_V4; - - case Hexagon::STriw_imm_cdnNotPt_V4 : - return Hexagon::STriw_imm_cNotPt_V4; - - case Hexagon::STriw_cdnPt_nv_V4 : - case Hexagon::STriw_cPt_nv_V4 : - case Hexagon::STriw_cdnPt_V4 : - return Hexagon::STriw_cPt; - - case Hexagon::STriw_cdnNotPt_nv_V4 : - case Hexagon::STriw_cNotPt_nv_V4 : - case Hexagon::STriw_cdnNotPt_V4 : - return Hexagon::STriw_cNotPt; - - case Hexagon::STriw_indexed_cdnPt_nv_V4 : - case Hexagon::STriw_indexed_cPt_nv_V4 : - case Hexagon::STriw_indexed_cdnPt_V4 : - return Hexagon::STriw_indexed_cPt; - - case Hexagon::STriw_indexed_cdnNotPt_nv_V4 : - case Hexagon::STriw_indexed_cNotPt_nv_V4 : - case Hexagon::STriw_indexed_cdnNotPt_V4 : - return Hexagon::STriw_indexed_cNotPt; - - case Hexagon::STriw_indexed_shl_cdnPt_nv_V4 : - case Hexagon::STriw_indexed_shl_cPt_nv_V4 : - case Hexagon::STriw_indexed_shl_cdnPt_V4 : - return Hexagon::STriw_indexed_shl_cPt_V4; - - case Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4 : - case Hexagon::STriw_indexed_shl_cNotPt_nv_V4 : - case Hexagon::STriw_indexed_shl_cdnNotPt_V4 : - return Hexagon::STriw_indexed_shl_cNotPt_V4; - - case Hexagon::POST_STwri_cdnPt_nv_V4 : - case Hexagon::POST_STwri_cPt_nv_V4 : - case Hexagon::POST_STwri_cdnPt_V4 : - return Hexagon::POST_STwri_cPt; - - case Hexagon::POST_STwri_cdnNotPt_nv_V4 : - case Hexagon::POST_STwri_cNotPt_nv_V4 : - case Hexagon::POST_STwri_cdnNotPt_V4 : - return Hexagon::POST_STwri_cNotPt; - - case Hexagon::STw_GP_cdnPt_nv_V4: - case Hexagon::STw_GP_cdnPt_V4: - case Hexagon::STw_GP_cPt_nv_V4: - return Hexagon::STw_GP_cPt_V4; - - case Hexagon::STw_GP_cdnNotPt_nv_V4: - case Hexagon::STw_GP_cdnNotPt_V4: - case Hexagon::STw_GP_cNotPt_nv_V4: - return Hexagon::STw_GP_cNotPt_V4; - - // Store new-value word - unconditional - - case Hexagon::STriw_nv_V4: - return Hexagon::STriw; - - case Hexagon::STriw_indexed_nv_V4: - return Hexagon::STriw_indexed; - - case Hexagon::STriw_indexed_shl_nv_V4: - return Hexagon::STriw_indexed_shl_V4; - - case Hexagon::STriw_shl_nv_V4: - return Hexagon::STriw_shl_V4; - - case Hexagon::STw_GP_nv_V4: - return Hexagon::STw_GP_V4; - - case Hexagon::POST_STwri_nv_V4: - return Hexagon::POST_STwri; - - // Store doubleword - - case Hexagon::STrid_cdnPt_V4 : - return Hexagon::STrid_cPt; - - case Hexagon::STrid_cdnNotPt_V4 : - return Hexagon::STrid_cNotPt; - - case Hexagon::STrid_indexed_cdnPt_V4 : - return Hexagon::STrid_indexed_cPt; - - case Hexagon::STrid_indexed_cdnNotPt_V4 : - return Hexagon::STrid_indexed_cNotPt; - - case Hexagon::STrid_indexed_shl_cdnPt_V4 : - return Hexagon::STrid_indexed_shl_cPt_V4; - - case Hexagon::STrid_indexed_shl_cdnNotPt_V4 : - return Hexagon::STrid_indexed_shl_cNotPt_V4; - - case Hexagon::POST_STdri_cdnPt_V4 : - return Hexagon::POST_STdri_cPt; - - case Hexagon::POST_STdri_cdnNotPt_V4 : - return Hexagon::POST_STdri_cNotPt; - - case Hexagon::STd_GP_cdnPt_V4 : - return Hexagon::STd_GP_cPt_V4; - - case Hexagon::STd_GP_cdnNotPt_V4 : - return Hexagon::STd_GP_cNotPt_V4; - - } -} - bool HexagonPacketizerList::DemoteToDotOld(MachineInstr* MI) { const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - int NewOpcode = GetDotOldOp(MI->getOpcode()); + int NewOpcode = QII->GetDotOldOp(MI->getOpcode()); MI->setDesc(QII->get(NewOpcode)); return true; } -// Returns true if an instruction is predicated on p0 and false if it's -// predicated on !p0. +enum PredicateKind { + PK_False, + PK_True, + PK_Unknown +}; -static bool GetPredicateSense(MachineInstr* MI, - const HexagonInstrInfo *QII) { +/// Returns true if an instruction is predicated on p0 and false if it's +/// predicated on !p0. +static PredicateKind getPredicateSense(MachineInstr* MI, + const HexagonInstrInfo *QII) { + if (!QII->isPredicated(MI)) + return PK_Unknown; - switch (MI->getOpcode()) { - default: llvm_unreachable("Unknown predicate sense of the instruction"); - case Hexagon::TFR_cPt: - case Hexagon::TFR_cdnPt: - case Hexagon::TFRI_cPt: - case Hexagon::TFRI_cdnPt: - case Hexagon::STrib_cPt : - case Hexagon::STrib_cdnPt_V4 : - case Hexagon::STrib_indexed_cPt : - case Hexagon::STrib_indexed_cdnPt_V4 : - case Hexagon::STrib_indexed_shl_cPt_V4 : - case Hexagon::STrib_indexed_shl_cdnPt_V4 : - case Hexagon::POST_STbri_cPt : - case Hexagon::POST_STbri_cdnPt_V4 : - case Hexagon::STrih_cPt : - case Hexagon::STrih_cdnPt_V4 : - case Hexagon::STrih_indexed_cPt : - case Hexagon::STrih_indexed_cdnPt_V4 : - case Hexagon::STrih_indexed_shl_cPt_V4 : - case Hexagon::STrih_indexed_shl_cdnPt_V4 : - case Hexagon::POST_SThri_cPt : - case Hexagon::POST_SThri_cdnPt_V4 : - case Hexagon::STriw_cPt : - case Hexagon::STriw_cdnPt_V4 : - case Hexagon::STriw_indexed_cPt : - case Hexagon::STriw_indexed_cdnPt_V4 : - case Hexagon::STriw_indexed_shl_cPt_V4 : - case Hexagon::STriw_indexed_shl_cdnPt_V4 : - case Hexagon::POST_STwri_cPt : - case Hexagon::POST_STwri_cdnPt_V4 : - case Hexagon::STrib_imm_cPt_V4 : - case Hexagon::STrib_imm_cdnPt_V4 : - case Hexagon::STrid_cPt : - case Hexagon::STrid_cdnPt_V4 : - case Hexagon::STrid_indexed_cPt : - case Hexagon::STrid_indexed_cdnPt_V4 : - case Hexagon::STrid_indexed_shl_cPt_V4 : - case Hexagon::STrid_indexed_shl_cdnPt_V4 : - case Hexagon::POST_STdri_cPt : - case Hexagon::POST_STdri_cdnPt_V4 : - case Hexagon::STrih_imm_cPt_V4 : - case Hexagon::STrih_imm_cdnPt_V4 : - case Hexagon::STriw_imm_cPt_V4 : - case Hexagon::STriw_imm_cdnPt_V4 : - case Hexagon::JMP_tnew_t : - case Hexagon::LDrid_cPt : - case Hexagon::LDrid_cdnPt : - case Hexagon::LDrid_indexed_cPt : - case Hexagon::LDrid_indexed_cdnPt : - case Hexagon::POST_LDrid_cPt : - case Hexagon::POST_LDrid_cdnPt_V4 : - case Hexagon::LDriw_cPt : - case Hexagon::LDriw_cdnPt : - case Hexagon::LDriw_indexed_cPt : - case Hexagon::LDriw_indexed_cdnPt : - case Hexagon::POST_LDriw_cPt : - case Hexagon::POST_LDriw_cdnPt_V4 : - case Hexagon::LDrih_cPt : - case Hexagon::LDrih_cdnPt : - case Hexagon::LDrih_indexed_cPt : - case Hexagon::LDrih_indexed_cdnPt : - case Hexagon::POST_LDrih_cPt : - case Hexagon::POST_LDrih_cdnPt_V4 : - case Hexagon::LDrib_cPt : - case Hexagon::LDrib_cdnPt : - case Hexagon::LDrib_indexed_cPt : - case Hexagon::LDrib_indexed_cdnPt : - case Hexagon::POST_LDrib_cPt : - case Hexagon::POST_LDrib_cdnPt_V4 : - case Hexagon::LDriuh_cPt : - case Hexagon::LDriuh_cdnPt : - case Hexagon::LDriuh_indexed_cPt : - case Hexagon::LDriuh_indexed_cdnPt : - case Hexagon::POST_LDriuh_cPt : - case Hexagon::POST_LDriuh_cdnPt_V4 : - case Hexagon::LDriub_cPt : - case Hexagon::LDriub_cdnPt : - case Hexagon::LDriub_indexed_cPt : - case Hexagon::LDriub_indexed_cdnPt : - case Hexagon::POST_LDriub_cPt : - case Hexagon::POST_LDriub_cdnPt_V4 : - case Hexagon::LDrid_indexed_shl_cPt_V4 : - case Hexagon::LDrid_indexed_shl_cdnPt_V4 : - case Hexagon::LDrib_indexed_shl_cPt_V4 : - case Hexagon::LDrib_indexed_shl_cdnPt_V4 : - case Hexagon::LDriub_indexed_shl_cPt_V4 : - case Hexagon::LDriub_indexed_shl_cdnPt_V4 : - case Hexagon::LDrih_indexed_shl_cPt_V4 : - case Hexagon::LDrih_indexed_shl_cdnPt_V4 : - case Hexagon::LDriuh_indexed_shl_cPt_V4 : - case Hexagon::LDriuh_indexed_shl_cdnPt_V4 : - case Hexagon::LDriw_indexed_shl_cPt_V4 : - case Hexagon::LDriw_indexed_shl_cdnPt_V4 : - case Hexagon::ADD_ri_cPt : - case Hexagon::ADD_ri_cdnPt : - case Hexagon::ADD_rr_cPt : - case Hexagon::ADD_rr_cdnPt : - case Hexagon::XOR_rr_cPt : - case Hexagon::XOR_rr_cdnPt : - case Hexagon::AND_rr_cPt : - case Hexagon::AND_rr_cdnPt : - case Hexagon::OR_rr_cPt : - case Hexagon::OR_rr_cdnPt : - case Hexagon::SUB_rr_cPt : - case Hexagon::SUB_rr_cdnPt : - case Hexagon::COMBINE_rr_cPt : - case Hexagon::COMBINE_rr_cdnPt : - case Hexagon::ASLH_cPt_V4 : - case Hexagon::ASLH_cdnPt_V4 : - case Hexagon::ASRH_cPt_V4 : - case Hexagon::ASRH_cdnPt_V4 : - case Hexagon::SXTB_cPt_V4 : - case Hexagon::SXTB_cdnPt_V4 : - case Hexagon::SXTH_cPt_V4 : - case Hexagon::SXTH_cdnPt_V4 : - case Hexagon::ZXTB_cPt_V4 : - case Hexagon::ZXTB_cdnPt_V4 : - case Hexagon::ZXTH_cPt_V4 : - case Hexagon::ZXTH_cdnPt_V4 : - case Hexagon::LDd_GP_cPt_V4 : - case Hexagon::LDb_GP_cPt_V4 : - case Hexagon::LDub_GP_cPt_V4 : - case Hexagon::LDh_GP_cPt_V4 : - case Hexagon::LDuh_GP_cPt_V4 : - case Hexagon::LDw_GP_cPt_V4 : - case Hexagon::STd_GP_cPt_V4 : - case Hexagon::STb_GP_cPt_V4 : - case Hexagon::STh_GP_cPt_V4 : - case Hexagon::STw_GP_cPt_V4 : - case Hexagon::LDd_GP_cdnPt_V4 : - case Hexagon::LDb_GP_cdnPt_V4 : - case Hexagon::LDub_GP_cdnPt_V4 : - case Hexagon::LDh_GP_cdnPt_V4 : - case Hexagon::LDuh_GP_cdnPt_V4 : - case Hexagon::LDw_GP_cdnPt_V4 : - case Hexagon::STd_GP_cdnPt_V4 : - case Hexagon::STb_GP_cdnPt_V4 : - case Hexagon::STh_GP_cdnPt_V4 : - case Hexagon::STw_GP_cdnPt_V4 : - return true; + if (QII->isPredicatedTrue(MI)) + return PK_True; - case Hexagon::TFR_cNotPt: - case Hexagon::TFR_cdnNotPt: - case Hexagon::TFRI_cNotPt: - case Hexagon::TFRI_cdnNotPt: - case Hexagon::STrib_cNotPt : - case Hexagon::STrib_cdnNotPt_V4 : - case Hexagon::STrib_indexed_cNotPt : - case Hexagon::STrib_indexed_cdnNotPt_V4 : - case Hexagon::STrib_indexed_shl_cNotPt_V4 : - case Hexagon::STrib_indexed_shl_cdnNotPt_V4 : - case Hexagon::POST_STbri_cNotPt : - case Hexagon::POST_STbri_cdnNotPt_V4 : - case Hexagon::STrih_cNotPt : - case Hexagon::STrih_cdnNotPt_V4 : - case Hexagon::STrih_indexed_cNotPt : - case Hexagon::STrih_indexed_cdnNotPt_V4 : - case Hexagon::STrih_indexed_shl_cNotPt_V4 : - case Hexagon::STrih_indexed_shl_cdnNotPt_V4 : - case Hexagon::POST_SThri_cNotPt : - case Hexagon::POST_SThri_cdnNotPt_V4 : - case Hexagon::STriw_cNotPt : - case Hexagon::STriw_cdnNotPt_V4 : - case Hexagon::STriw_indexed_cNotPt : - case Hexagon::STriw_indexed_cdnNotPt_V4 : - case Hexagon::STriw_indexed_shl_cNotPt_V4 : - case Hexagon::STriw_indexed_shl_cdnNotPt_V4 : - case Hexagon::POST_STwri_cNotPt : - case Hexagon::POST_STwri_cdnNotPt_V4 : - case Hexagon::STrib_imm_cNotPt_V4 : - case Hexagon::STrib_imm_cdnNotPt_V4 : - case Hexagon::STrid_cNotPt : - case Hexagon::STrid_cdnNotPt_V4 : - case Hexagon::STrid_indexed_cdnNotPt_V4 : - case Hexagon::STrid_indexed_cNotPt : - case Hexagon::STrid_indexed_shl_cNotPt_V4 : - case Hexagon::STrid_indexed_shl_cdnNotPt_V4 : - case Hexagon::POST_STdri_cNotPt : - case Hexagon::POST_STdri_cdnNotPt_V4 : - case Hexagon::STrih_imm_cNotPt_V4 : - case Hexagon::STrih_imm_cdnNotPt_V4 : - case Hexagon::STriw_imm_cNotPt_V4 : - case Hexagon::STriw_imm_cdnNotPt_V4 : - case Hexagon::JMP_fnew_t : - case Hexagon::LDrid_cNotPt : - case Hexagon::LDrid_cdnNotPt : - case Hexagon::LDrid_indexed_cNotPt : - case Hexagon::LDrid_indexed_cdnNotPt : - case Hexagon::POST_LDrid_cNotPt : - case Hexagon::POST_LDrid_cdnNotPt_V4 : - case Hexagon::LDriw_cNotPt : - case Hexagon::LDriw_cdnNotPt : - case Hexagon::LDriw_indexed_cNotPt : - case Hexagon::LDriw_indexed_cdnNotPt : - case Hexagon::POST_LDriw_cNotPt : - case Hexagon::POST_LDriw_cdnNotPt_V4 : - case Hexagon::LDrih_cNotPt : - case Hexagon::LDrih_cdnNotPt : - case Hexagon::LDrih_indexed_cNotPt : - case Hexagon::LDrih_indexed_cdnNotPt : - case Hexagon::POST_LDrih_cNotPt : - case Hexagon::POST_LDrih_cdnNotPt_V4 : - case Hexagon::LDrib_cNotPt : - case Hexagon::LDrib_cdnNotPt : - case Hexagon::LDrib_indexed_cNotPt : - case Hexagon::LDrib_indexed_cdnNotPt : - case Hexagon::POST_LDrib_cNotPt : - case Hexagon::POST_LDrib_cdnNotPt_V4 : - case Hexagon::LDriuh_cNotPt : - case Hexagon::LDriuh_cdnNotPt : - case Hexagon::LDriuh_indexed_cNotPt : - case Hexagon::LDriuh_indexed_cdnNotPt : - case Hexagon::POST_LDriuh_cNotPt : - case Hexagon::POST_LDriuh_cdnNotPt_V4 : - case Hexagon::LDriub_cNotPt : - case Hexagon::LDriub_cdnNotPt : - case Hexagon::LDriub_indexed_cNotPt : - case Hexagon::LDriub_indexed_cdnNotPt : - case Hexagon::POST_LDriub_cNotPt : - case Hexagon::POST_LDriub_cdnNotPt_V4 : - case Hexagon::LDrid_indexed_shl_cNotPt_V4 : - case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDrib_indexed_shl_cNotPt_V4 : - case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriub_indexed_shl_cNotPt_V4 : - case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDrih_indexed_shl_cNotPt_V4 : - case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriuh_indexed_shl_cNotPt_V4 : - case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriw_indexed_shl_cNotPt_V4 : - case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 : - case Hexagon::ADD_ri_cNotPt : - case Hexagon::ADD_ri_cdnNotPt : - case Hexagon::ADD_rr_cNotPt : - case Hexagon::ADD_rr_cdnNotPt : - case Hexagon::XOR_rr_cNotPt : - case Hexagon::XOR_rr_cdnNotPt : - case Hexagon::AND_rr_cNotPt : - case Hexagon::AND_rr_cdnNotPt : - case Hexagon::OR_rr_cNotPt : - case Hexagon::OR_rr_cdnNotPt : - case Hexagon::SUB_rr_cNotPt : - case Hexagon::SUB_rr_cdnNotPt : - case Hexagon::COMBINE_rr_cNotPt : - case Hexagon::COMBINE_rr_cdnNotPt : - case Hexagon::ASLH_cNotPt_V4 : - case Hexagon::ASLH_cdnNotPt_V4 : - case Hexagon::ASRH_cNotPt_V4 : - case Hexagon::ASRH_cdnNotPt_V4 : - case Hexagon::SXTB_cNotPt_V4 : - case Hexagon::SXTB_cdnNotPt_V4 : - case Hexagon::SXTH_cNotPt_V4 : - case Hexagon::SXTH_cdnNotPt_V4 : - case Hexagon::ZXTB_cNotPt_V4 : - case Hexagon::ZXTB_cdnNotPt_V4 : - case Hexagon::ZXTH_cNotPt_V4 : - case Hexagon::ZXTH_cdnNotPt_V4 : - - case Hexagon::LDd_GP_cNotPt_V4 : - case Hexagon::LDb_GP_cNotPt_V4 : - case Hexagon::LDub_GP_cNotPt_V4 : - case Hexagon::LDh_GP_cNotPt_V4 : - case Hexagon::LDuh_GP_cNotPt_V4 : - case Hexagon::LDw_GP_cNotPt_V4 : - case Hexagon::STd_GP_cNotPt_V4 : - case Hexagon::STb_GP_cNotPt_V4 : - case Hexagon::STh_GP_cNotPt_V4 : - case Hexagon::STw_GP_cNotPt_V4 : - case Hexagon::LDd_GP_cdnNotPt_V4 : - case Hexagon::LDb_GP_cdnNotPt_V4 : - case Hexagon::LDub_GP_cdnNotPt_V4 : - case Hexagon::LDh_GP_cdnNotPt_V4 : - case Hexagon::LDuh_GP_cdnNotPt_V4 : - case Hexagon::LDw_GP_cdnNotPt_V4 : - case Hexagon::STd_GP_cdnNotPt_V4 : - case Hexagon::STb_GP_cdnNotPt_V4 : - case Hexagon::STh_GP_cdnNotPt_V4 : - case Hexagon::STw_GP_cdnNotPt_V4 : - return false; - } - // return *some value* to avoid compiler warning - return false; + return PK_False; } static MachineOperand& GetPostIncrementOperand(MachineInstr *MI, @@ -2252,10 +537,10 @@ static MachineOperand& GetStoreValueOperand(MachineInstr *MI) { // Arch Spec: 3.4.4.2 bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI, MachineInstr *PacketMI, unsigned DepReg, - std::map <MachineInstr*, SUnit*> MIToSUnit) -{ - // Make sure we are looking at the store - if (!IsNewifyStore(MI)) + std::map <MachineInstr*, SUnit*> MIToSUnit) { + const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; + // Make sure we are looking at the store, that can be promoted. + if (!QII->mayBeNewStore(MI)) return false; // Make sure there is dependency and can be new value'ed @@ -2263,12 +548,11 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI, GetStoreValueOperand(MI).getReg() != DepReg) return false; - const HexagonRegisterInfo* QRI = + const HexagonRegisterInfo* QRI = (const HexagonRegisterInfo *) TM.getRegisterInfo(); const MCInstrDesc& MCID = PacketMI->getDesc(); // first operand is always the result - const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; const TargetRegisterClass* PacketRC = QII->getRegClass(MCID, 0, QRI, MF); // if there is already an store in the packet, no can do new value store @@ -2311,7 +595,7 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI, } // If the source that feeds the store is predicated, new value store must - // also be also predicated. + // also be predicated. if (QII->isPredicated(PacketMI)) { if (!QII->isPredicated(MI)) return false; @@ -2357,7 +641,7 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI, if (( predRegNumDst != predRegNumSrc) || QII->isDotNewInst(PacketMI) != QII->isDotNewInst(MI) || - GetPredicateSense(MI, QII) != GetPredicateSense(PacketMI, QII)) { + getPredicateSense(MI, QII) != getPredicateSense(PacketMI, QII)) { return false; } } @@ -2438,10 +722,11 @@ bool HexagonPacketizerList::CanPromoteToNewValue( MachineInstr *MI, MachineBasicBlock::iterator &MII) { + const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; const HexagonRegisterInfo* QRI = (const HexagonRegisterInfo *) TM.getRegisterInfo(); if (!QRI->Subtarget.hasV4TOps() || - !IsNewifyStore(MI)) + !QII->mayBeNewStore(MI)) return false; MachineInstr *PacketMI = PacketSU->getInstr(); @@ -2468,7 +753,7 @@ bool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI, { const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; // Already a dot new instruction. - if (QII->isDotNewInst(MI) && !IsNewifyStore(MI)) + if (QII->isDotNewInst(MI) && !QII->mayBeNewStore(MI)) return false; if (!isNewifiable(MI)) @@ -2478,12 +763,12 @@ bool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI, if (RC == &Hexagon::PredRegsRegClass && isCondInst(MI)) return true; else if (RC != &Hexagon::PredRegsRegClass && - !IsNewifyStore(MI)) // MI is not a new-value store + !QII->mayBeNewStore(MI)) // MI is not a new-value store return false; else { // Create a dot new machine instruction to see if resources can be // allocated. If not, bail out now. - int NewOpcode = GetDotNewOp(MI->getOpcode()); + int NewOpcode = QII->GetDotNewOp(MI); const MCInstrDesc &desc = QII->get(NewOpcode); DebugLoc dl; MachineInstr *NewMI = @@ -2552,16 +837,39 @@ bool HexagonPacketizerList::RestrictingDepExistInPacket (MachineInstr* MI, } +/// Gets the predicate register of a predicated instruction. +static unsigned getPredicatedRegister(MachineInstr *MI, + const HexagonInstrInfo *QII) { + /// We use the following rule: The first predicate register that is a use is + /// the predicate register of a predicated instruction. + + assert(QII->isPredicated(MI) && "Must be predicated instruction"); + + for (MachineInstr::mop_iterator OI = MI->operands_begin(), + OE = MI->operands_end(); OI != OE; ++OI) { + MachineOperand &Op = *OI; + if (Op.isReg() && Op.getReg() && Op.isUse() && + Hexagon::PredRegsRegClass.contains(Op.getReg())) + return Op.getReg(); + } + + llvm_unreachable("Unknown instruction operand layout"); + + return 0; +} + // Given two predicated instructions, this function detects whether // the predicates are complements bool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1, MachineInstr* MI2, std::map <MachineInstr*, SUnit*> MIToSUnit) { const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; - // Currently can only reason about conditional transfers - if (!QII->isConditionalTransfer(MI1) || !QII->isConditionalTransfer(MI2)) { + + // If we don't know the predicate sense of the instructions bail out early, we + // need it later. + if (getPredicateSense(MI1, QII) == PK_Unknown || + getPredicateSense(MI2, QII) == PK_Unknown) return false; - } // Scheduling unit for candidate SUnit* SU = MIToSUnit[MI1]; @@ -2600,9 +908,9 @@ bool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1, // there already exist anti dep on the same pred in // the packet. if (PacketSU->Succs[i].getSUnit() == SU && + PacketSU->Succs[i].getKind() == SDep::Data && Hexagon::PredRegsRegClass.contains( PacketSU->Succs[i].getReg()) && - PacketSU->Succs[i].getKind() == SDep::Data && // Here I know that *VIN is predicate setting instruction // with true data dep to candidate on the register // we care about - c) in the above example. @@ -2623,8 +931,12 @@ bool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1, // that the predicate sense is different // We also need to differentiate .old vs. .new: // !p0 is not complimentary to p0.new - return ((MI1->getOperand(1).getReg() == MI2->getOperand(1).getReg()) && - (GetPredicateSense(MI1, QII) != GetPredicateSense(MI2, QII)) && + unsigned PReg1 = getPredicatedRegister(MI1, QII); + unsigned PReg2 = getPredicatedRegister(MI2, QII); + return ((PReg1 == PReg2) && + Hexagon::PredRegsRegClass.contains(PReg1) && + Hexagon::PredRegsRegClass.contains(PReg2) && + (getPredicateSense(MI1, QII) != getPredicateSense(MI2, QII)) && (QII->isDotNewInst(MI1) == QII->isDotNewInst(MI2))); } @@ -2722,24 +1034,21 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { } // A LoopN instruction cannot appear in the same packet as a jump or call. - if (IsLoopN(I) && ( IsDirectJump(J) - || MCIDJ.isCall() - || QII->isDeallocRet(J))) { + if (IsLoopN(I) && + (IsDirectJump(J) || MCIDJ.isCall() || QII->isDeallocRet(J))) { Dependence = true; return false; } - if (IsLoopN(J) && ( IsDirectJump(I) - || MCIDI.isCall() - || QII->isDeallocRet(I))) { + if (IsLoopN(J) && + (IsDirectJump(I) || MCIDI.isCall() || QII->isDeallocRet(I))) { Dependence = true; return false; } // dealloc_return cannot appear in the same packet as a conditional or // unconditional jump. - if (QII->isDeallocRet(I) && ( MCIDJ.isBranch() - || MCIDJ.isCall() - || MCIDJ.isBarrier())) { + if (QII->isDeallocRet(I) && + (MCIDJ.isBranch() || MCIDJ.isCall() || MCIDJ.isBarrier())) { Dependence = true; return false; } @@ -2764,7 +1073,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { } //if dealloc_return - if (MCIDJ.mayStore() && QII->isDeallocRet(I)){ + if (MCIDJ.mayStore() && QII->isDeallocRet(I)) { Dependence = true; return false; } diff --git a/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp b/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp index 36da6df..7c41507 100644 --- a/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp +++ b/contrib/llvm/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp @@ -21,7 +21,6 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" #include "llvm/Support/raw_ostream.h" -#include <cstdio> using namespace llvm; @@ -179,7 +178,7 @@ void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const { // Branches can take an immediate operand. This is used by the branch // selection pass to print $+8, an eight byte displacement from the PC. - assert("Unknown branch operand."); + llvm_unreachable("Unknown branch operand."); } void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo, @@ -196,15 +195,9 @@ void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool hi) const { - const MCOperand& MO = MI->getOperand(OpNo); + assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand"); - O << '#' << (hi? "HI": "LO") << '('; - if (MO.isImm()) { - O << '#'; - printOperand(MI, OpNo, O); - } else { - assert("Unknown symbol operand"); - printOperand(MI, OpNo, O); - } + O << '#' << (hi ? "HI" : "LO") << "(#"; + printOperand(MI, OpNo, O); O << ')'; } diff --git a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h index d4a93b5..8519cf3 100644 --- a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h +++ b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h @@ -65,14 +65,15 @@ namespace HexagonII { AbsoluteSet = 2, // Absolute set addressing mode BaseImmOffset = 3, // Indirect with offset BaseLongOffset = 4, // Indirect with long offset - BaseRegOffset = 5 // Indirect with register offset + BaseRegOffset = 5, // Indirect with register offset + PostInc = 6 // Post increment addressing mode }; enum MemAccessSize { NoMemAccess = 0, // Not a memory acces instruction. ByteAccess = 1, // Byte access instruction (memb). HalfWordAccess = 2, // Half word access instruction (memh). - WordAccess = 3, // Word access instrution (memw). + WordAccess = 3, // Word access instruction (memw). DoubleWordAccess = 4 // Double word access instruction (memd) }; diff --git a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp index 3deb8d1..3f9415b 100644 --- a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp +++ b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp @@ -15,7 +15,10 @@ using namespace llvm; -HexagonMCAsmInfo::HexagonMCAsmInfo(const Target &T, StringRef TT) { +// Pin the vtable to this file. +void HexagonMCAsmInfo::anchor() {} + +HexagonMCAsmInfo::HexagonMCAsmInfo(StringRef TT) { Data16bitsDirective = "\t.half\t"; Data32bitsDirective = "\t.word\t"; Data64bitsDirective = 0; // .xword is only supported by V9. @@ -29,7 +32,6 @@ HexagonMCAsmInfo::HexagonMCAsmInfo(const Target &T, StringRef TT) { InlineAsmEnd = "# InlineAsm End"; ZeroDirective = "\t.space\t"; AscizDirective = "\t.string\t"; - WeakRefDirective = "\t.weak\t"; SupportsDebugInformation = true; UsesELFSectionDirectiveForBSS = true; diff --git a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h index d336cd5..bd8cb76 100644 --- a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h +++ b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h @@ -15,14 +15,13 @@ #define HexagonMCASMINFO_H #include "llvm/ADT/StringRef.h" -#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCAsmInfoELF.h" namespace llvm { - class Target; - - class HexagonMCAsmInfo : public MCAsmInfo { + class HexagonMCAsmInfo : public MCAsmInfoELF { + virtual void anchor(); public: - explicit HexagonMCAsmInfo(const Target &T, StringRef TT); + explicit HexagonMCAsmInfo(StringRef TT); }; } // namespace llvm diff --git a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index 6b1d2d1..2f93a52 100644 --- a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -54,13 +54,14 @@ static MCSubtargetInfo *createHexagonMCSubtargetInfo(StringRef TT, return X; } -static MCAsmInfo *createHexagonMCAsmInfo(const Target &T, StringRef TT) { - MCAsmInfo *MAI = new HexagonMCAsmInfo(T, TT); +static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI, + StringRef TT) { + MCAsmInfo *MAI = new HexagonMCAsmInfo(TT); // VirtualFP = (R30 + #0). - MachineLocation Dst(MachineLocation::VirtualFP); - MachineLocation Src(Hexagon::R30, 0); - MAI->addInitialFrameState(0, Dst, Src); + MCCFIInstruction Inst = MCCFIInstruction::createDefCfa( + 0, Hexagon::R30, 0); + MAI->addInitialFrameState(Inst); return MAI; } |