diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2017-10-11 15:51:44 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2017-10-11 15:51:44 +0000 |
commit | 8f174dde92540a2cfedef73a489d4f3296ca22fd (patch) | |
tree | 0d7b06ad344f6fe0cfc33c57e35f10a552b514df /llvm/lib/Target/Hexagon | |
parent | 7b6010cddebfebec3699860293751e29ed0d4b04 (diff) | |
download | bcm5719-llvm-8f174dde92540a2cfedef73a489d4f3296ca22fd.tar.gz bcm5719-llvm-8f174dde92540a2cfedef73a489d4f3296ca22fd.zip |
[Pipeliner] Improve serialization order for post-increments
The pipeliner is generating a serial sequence that causes poor
register allocation when a post-increment instruction appears
prior to the use of the post-increment register. This occurs when
there is a circular set of dependences involved with a sequence
of instructions in the same cycle. In this case, there is no
serialization of the parallel semantics that will not cause an
additional register to be allocated.
This patch fixes the problem by changing the instructions so that
the post-increment instruction is used by the subsequent
instruction, which enables the register allocator to make a
better decision and not require another register.
Patch by Brendon Cahoon.
llvm-svn: 315466
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); |