From bdeacd17d754e86a0168b89e43a5f8eb03ef8514 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 11 Oct 2017 21:20:43 +0000 Subject: [PATCH] [Hexagon] Make sure that new-value jump is packetized with producer git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315510 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/HexagonVLIWPacketizer.cpp | 24 ++++++++------ .../Hexagon/packetize-nvj-no-prune.mir | 31 +++++++++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 test/CodeGen/Hexagon/packetize-nvj-no-prune.mir diff --git a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp index 2555b50f91c..1bc8d45c3dc 100644 --- a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp @@ -1338,11 +1338,9 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { if (NOp1.isReg() && I.getOperand(0).getReg() == NOp1.getReg()) secondRegMatch = true; - for (auto T : CurrentPacketMIs) { - SUnit *PacketSU = MIToSUnit.find(T)->second; - MachineInstr &PI = *PacketSU->getInstr(); + for (MachineInstr *PI : CurrentPacketMIs) { // NVJ can not be part of the dual jump - Arch Spec: section 7.8. - if (PI.isCall()) { + if (PI->isCall()) { Dependence = true; break; } @@ -1354,22 +1352,22 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { // 3. If the second operand of the nvj is newified, (which means // first operand is also a reg), first reg is not defined in // the same packet. - if (PI.getOpcode() == Hexagon::S2_allocframe || PI.mayStore() || - HII->isLoopN(PI)) { + if (PI->getOpcode() == Hexagon::S2_allocframe || PI->mayStore() || + HII->isLoopN(*PI)) { Dependence = true; break; } // Check #2/#3. const MachineOperand &OpR = secondRegMatch ? NOp0 : NOp1; - if (OpR.isReg() && PI.modifiesRegister(OpR.getReg(), HRI)) { + if (OpR.isReg() && PI->modifiesRegister(OpR.getReg(), HRI)) { Dependence = true; break; } } + GlueToNewValueJump = true; if (Dependence) return false; - GlueToNewValueJump = true; } // There no dependency between a prolog instruction and its successor. @@ -1613,7 +1611,15 @@ bool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) { if (ChangedOffset != INT64_MAX) undoChangedOffset(I); - else if (updateOffset(SUI, SUJ)) { + + if (GlueToNewValueJump) { + // Putting I and J together would prevent the new-value jump from being + // packetized with the producer. In that case I and J must be separated. + GlueToNewValueJump = false; + return false; + } + + if (ChangedOffset == INT64_MAX && updateOffset(SUI, SUJ)) { FoundSequentialDependence = false; Dependence = false; return true; diff --git a/test/CodeGen/Hexagon/packetize-nvj-no-prune.mir b/test/CodeGen/Hexagon/packetize-nvj-no-prune.mir new file mode 100644 index 00000000000..7047968ab6f --- /dev/null +++ b/test/CodeGen/Hexagon/packetize-nvj-no-prune.mir @@ -0,0 +1,31 @@ +# RUN: llc -march=hexagon -run-pass hexagon-packetizer %s -o - | FileCheck %s + +# Make sure that the new-value jump is packetized with the producer. In this +# case, the loads cold be packetized together (with updating the offset in +# the second load), but then the new-value jump would not be possible to +# put in the same packet. + +# CHECK-LABEL: name: fred +# CHECK: BUNDLE +# CHECK-NEXT: %r3 = L2_loadri_io %r1, 0 +# CHECK-NEXT: J4_cmpgtu_f_jumpnv_t internal killed %r3 + + +--- | + define void @fred() { ret void } + @array = external global [256 x i32], align 8 +... + +--- +name: fred +tracksRegLiveness: true +body: | + bb.0: + successors: %bb.1 + %r1 = A2_tfrsi @array + %r2, %r1 = L2_loadri_pi %r1, 4 + %r3 = L2_loadri_io %r1, 0 + J4_cmpgtu_f_jumpnv_t killed %r3, killed %r2, %bb.1, implicit-def %pc + + bb.1: +... -- 2.49.0