summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJyotsna Verma <jverma@codeaurora.org>2013-05-14 16:36:34 +0000
committerJyotsna Verma <jverma@codeaurora.org>2013-05-14 16:36:34 +0000
commit91eadc6d697647f426d05cab66aae2a19112343e (patch)
tree5547f8b3d6a86bd5a3da1dc64dda2e4ed6e9df8a
parente4642bc096984c12c1ef129137e17fad61201118 (diff)
downloadllvm-91eadc6d697647f426d05cab66aae2a19112343e.tar.gz
llvm-91eadc6d697647f426d05cab66aae2a19112343e.tar.bz2
llvm-91eadc6d697647f426d05cab66aae2a19112343e.tar.xz
Hexagon: ArePredicatesComplement should not restrict itself to TFRs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181803 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/Hexagon/HexagonVLIWPacketizer.cpp36
-rw-r--r--test/CodeGen/Hexagon/packetize_cond_inst.ll32
2 files changed, 63 insertions, 5 deletions
diff --git a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
index c508d124b3..59b4fabe01 100644
--- a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
+++ b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
@@ -837,16 +837,38 @@ bool HexagonPacketizerList::RestrictingDepExistInPacket (MachineInstr* MI,
}
+/// Gets the predicate register of a predicated instruction.
+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];
@@ -885,9 +907,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.
@@ -908,7 +930,11 @@ 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()) &&
+ 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)));
}
diff --git a/test/CodeGen/Hexagon/packetize_cond_inst.ll b/test/CodeGen/Hexagon/packetize_cond_inst.ll
new file mode 100644
index 0000000000..a48a9f62ec
--- /dev/null
+++ b/test/CodeGen/Hexagon/packetize_cond_inst.ll
@@ -0,0 +1,32 @@
+; RUN: llc -mcpu=hexagonv4 -tail-dup-size=1 < %s | FileCheck %s
+
+target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-v64:64:64-v32:32:32-a0:0-n16:32"
+target triple = "hexagon-unknown--elf"
+
+; Make sure we put the two conditionally executed adds in a packet.
+; ifcnv_add:
+; {
+; p0 = cmp.gt(r2, r1)
+; if (!p0.new) r0 = add(r2, r1)
+; if (p0.new) r0 = add(r0, #10)
+; }
+; CHECK: cmp
+; CHECK-NEXT: add
+; CHECH-NEXT: add
+define i32 @ifcnv_add(i32, i32, i32) nounwind readnone {
+ %4 = icmp sgt i32 %2, %1
+ br i1 %4, label %5, label %7
+
+; <label>:5 ; preds = %3
+ %6 = add nsw i32 %0, 10
+ br label %9
+
+; <label>:7 ; preds = %3
+ %8 = add nsw i32 %2, %1
+ br label %9
+
+; <label>:9 ; preds = %7, %5
+ %10 = phi i32 [ %6, %5 ], [ %8, %7 ]
+ %11 = add nsw i32 %10, 1
+ ret i32 %11
+}