diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon')
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp | 52 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h | 5 |
3 files changed, 63 insertions, 1 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index bcd1a5089c7..c2125bec3a5 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -1651,8 +1651,13 @@ bool HexagonInstrInfo::areMemAccessesTriviallyDisjoint( bool HexagonInstrInfo::getIncrementValue(const MachineInstr &MI, int &Value) const { if (isPostIncrement(MI)) { + // For a post-increment, the offset is zero and the increment value is + // determined by the instruction's access size. + int Zero; unsigned AccessSize; - return getBaseAndOffset(MI, Value, AccessSize); + bool RetVal = getBaseAndOffset(MI, Zero, AccessSize); + Value = (int) AccessSize; + return RetVal; } if (MI.getOpcode() == Hexagon::A2_addi) { Value = MI.getOperand(2).getImm(); diff --git a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp index 0f407c2d836..2555b50f91c 100644 --- a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp @@ -496,6 +496,48 @@ void HexagonPacketizerList::useCalleesSP(MachineInstr &MI) { Off.setImm(Off.getImm() + FrameSize + HEXAGON_LRFP_SIZE); } +/// Return true if we can update the offset in MI so that MI and MJ +/// can be packetized together. +bool HexagonPacketizerList::updateOffset(SUnit *SUI, SUnit *SUJ) { + assert(SUI->getInstr() && SUJ->getInstr()); + MachineInstr &MI = *SUI->getInstr(); + MachineInstr &MJ = *SUJ->getInstr(); + + unsigned BPI, OPI; + if (!HII->getBaseAndOffsetPosition(MI, BPI, OPI)) + return false; + unsigned BPJ, OPJ; + if (!HII->getBaseAndOffsetPosition(MJ, BPJ, OPJ)) + return false; + unsigned Reg = MI.getOperand(BPI).getReg(); + if (Reg != MJ.getOperand(BPJ).getReg()) + return false; + // Make sure that the dependences do not restrict adding MI to the packet. + // That is, ignore anti dependences, and make sure the only data dependence + // involves the specific register. + for (const auto &PI : SUI->Preds) + if (PI.getKind() != SDep::Anti && + (PI.getKind() != SDep::Data || PI.getReg() != Reg)) + return false; + int Incr; + if (!HII->getIncrementValue(MJ, Incr)) + return false; + + int64_t Offset = MI.getOperand(OPI).getImm(); + MI.getOperand(OPI).setImm(Offset + Incr); + ChangedOffset = Offset; + return true; +} + +/// Undo the changed offset. This is needed if the instruction cannot be +/// added to the current packet due to a different instruction. +void HexagonPacketizerList::undoChangedOffset(MachineInstr &MI) { + unsigned BP, OP; + if (!HII->getBaseAndOffsetPosition(MI, BP, OP)) + llvm_unreachable("Unable to find base and offset operands."); + MI.getOperand(OP).setImm(ChangedOffset); +} + enum PredicateKind { PK_False, PK_True, @@ -980,6 +1022,7 @@ void HexagonPacketizerList::initPacketizerState() { GlueToNewValueJump = false; GlueAllocframeStore = false; FoundSequentialDependence = false; + ChangedOffset = INT64_MAX; } // Ignore bundling of pseudo instructions. @@ -1567,6 +1610,15 @@ bool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) { useCalleesSP(I); GlueAllocframeStore = false; } + + if (ChangedOffset != INT64_MAX) + undoChangedOffset(I); + else if (updateOffset(SUI, SUJ)) { + FoundSequentialDependence = false; + Dependence = false; + return true; + } + return false; } diff --git a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h index 3a7bdf5101e..cbdd2367429 100644 --- a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h +++ b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h @@ -38,6 +38,9 @@ class HexagonPacketizerList : public VLIWPacketizerList { // Has the feeder instruction been glued to new value jump. bool GlueToNewValueJump; + // This holds the offset value, when pruning the dependences. + int64_t ChangedOffset; + // Check if there is a dependence between some instruction already in this // packet and this instruction. bool Dependence; @@ -117,6 +120,8 @@ protected: bool demoteToDotOld(MachineInstr &MI); bool useCallersSP(MachineInstr &MI); void useCalleesSP(MachineInstr &MI); + bool updateOffset(SUnit *SUI, SUnit *SUJ); + void undoChangedOffset(MachineInstr &MI); bool arePredicatesComplements(MachineInstr &MI1, MachineInstr &MI2); bool restrictingDepExistInPacket(MachineInstr&, unsigned); bool isNewifiable(const MachineInstr &MI, const TargetRegisterClass *NewRC); |

