From 91eadc6d697647f426d05cab66aae2a19112343e Mon Sep 17 00:00:00 2001 From: Jyotsna Verma Date: Tue, 14 May 2013 16:36:34 +0000 Subject: 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 --- lib/Target/Hexagon/HexagonVLIWPacketizer.cpp | 36 ++++++++++++++++++++++++---- test/CodeGen/Hexagon/packetize_cond_inst.ll | 32 +++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/Hexagon/packetize_cond_inst.ll 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 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 + +;