summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-10-11 15:51:44 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-10-11 15:51:44 +0000
commit8f174dde92540a2cfedef73a489d4f3296ca22fd (patch)
tree0d7b06ad344f6fe0cfc33c57e35f10a552b514df /llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
parent7b6010cddebfebec3699860293751e29ed0d4b04 (diff)
downloadbcm5719-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/HexagonVLIWPacketizer.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp52
1 files changed, 52 insertions, 0 deletions
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;
}
OpenPOWER on IntegriCloud