diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2009-07-16 13:52:51 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2009-07-16 13:52:51 +0000 |
commit | 0b608cbf1f0ce3b03ac5f995f08649842531facc (patch) | |
tree | 8eef8154248e2d460c25a9c784e113e9d863126e /lib | |
parent | 9ad3dd5ab1d5efd39b8c0a25296e78ed2554e540 (diff) | |
download | external_llvm-0b608cbf1f0ce3b03ac5f995f08649842531facc.zip external_llvm-0b608cbf1f0ce3b03ac5f995f08649842531facc.tar.gz external_llvm-0b608cbf1f0ce3b03ac5f995f08649842531facc.tar.bz2 |
SELECT_CC lowering
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75948 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/SystemZ/SystemZISelLowering.cpp | 93 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZISelLowering.h | 16 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.cpp | 29 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.h | 2 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.td | 16 |
5 files changed, 155 insertions, 1 deletions
diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index 448f521..6860420 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -61,6 +61,14 @@ SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) : setOperationAction(ISD::BRCOND, MVT::Other, Expand); setOperationAction(ISD::BR_CC, MVT::i32, Custom); setOperationAction(ISD::BR_CC, MVT::i64, Custom); + + // FIXME: Can we lower these 2 efficiently? + setOperationAction(ISD::SETCC, MVT::i32, Expand); + setOperationAction(ISD::SETCC, MVT::i64, Expand); + setOperationAction(ISD::SELECT, MVT::i32, Expand); + setOperationAction(ISD::SELECT, MVT::i64, Expand); + setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); + setOperationAction(ISD::SELECT_CC, MVT::i64, Custom); } SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { @@ -69,6 +77,7 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::RET: return LowerRET(Op, DAG); case ISD::CALL: return LowerCALL(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); + case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); default: assert(0 && "unimplemented operand"); return SDValue(); @@ -472,6 +481,27 @@ SDValue SystemZTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) { Chain, Dest, SystemZCC, Flag); } +SDValue SystemZTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) { + SDValue LHS = Op.getOperand(0); + SDValue RHS = Op.getOperand(1); + SDValue TrueV = Op.getOperand(2); + SDValue FalseV = Op.getOperand(3); + ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); + DebugLoc dl = Op.getDebugLoc(); + + SDValue SystemZCC; + SDValue Flag = EmitCmp(LHS, RHS, CC, SystemZCC, DAG); + + SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); + SmallVector<SDValue, 4> Ops; + Ops.push_back(TrueV); + Ops.push_back(FalseV); + Ops.push_back(SystemZCC); + Ops.push_back(Flag); + + return DAG.getNode(SystemZISD::SELECT, dl, VTs, &Ops[0], Ops.size()); +} + const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { @@ -480,7 +510,70 @@ const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const { case SystemZISD::BRCOND: return "SystemZISD::BRCOND"; case SystemZISD::CMP: return "SystemZISD::CMP"; case SystemZISD::UCMP: return "SystemZISD::UCMP"; + case SystemZISD::SELECT: return "SystemZISD::SELECT"; default: return NULL; } } +//===----------------------------------------------------------------------===// +// Other Lowering Code +//===----------------------------------------------------------------------===// + +MachineBasicBlock* +SystemZTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, + MachineBasicBlock *BB) const { + const SystemZInstrInfo &TII = *TM.getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + assert((MI->getOpcode() == SystemZ::Select32 || + MI->getOpcode() == SystemZ::Select64) && + "Unexpected instr type to insert"); + + // To "insert" a SELECT instruction, we actually have to insert the diamond + // control-flow pattern. The incoming instruction knows the destination vreg + // to set, the condition code register to branch on, the true/false values to + // select between, and a branch opcode to use. + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction::iterator I = BB; + ++I; + + // thisMBB: + // ... + // TrueVal = ... + // cmpTY ccX, r1, r2 + // jCC copy1MBB + // fallthrough --> copy0MBB + MachineBasicBlock *thisMBB = BB; + MachineFunction *F = BB->getParent(); + MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); + SystemZCC::CondCodes CC = (SystemZCC::CondCodes)MI->getOperand(3).getImm(); + BuildMI(BB, dl, TII.getBrCond(CC)).addMBB(copy1MBB); + F->insert(I, copy0MBB); + F->insert(I, copy1MBB); + // Update machine-CFG edges by transferring all successors of the current + // block to the new block which will contain the Phi node for the select. + copy1MBB->transferSuccessors(BB); + // Next, add the true and fallthrough blocks as its successors. + BB->addSuccessor(copy0MBB); + BB->addSuccessor(copy1MBB); + + // copy0MBB: + // %FalseValue = ... + // # fallthrough to copy1MBB + BB = copy0MBB; + + // Update machine-CFG edges + BB->addSuccessor(copy1MBB); + + // copy1MBB: + // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] + // ... + BB = copy1MBB; + BuildMI(BB, dl, TII.get(SystemZ::PHI), + MI->getOperand(0).getReg()) + .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) + .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); + + F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. + return BB; +} diff --git a/lib/Target/SystemZ/SystemZISelLowering.h b/lib/Target/SystemZ/SystemZISelLowering.h index 0f432bb..51c3321 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.h +++ b/lib/Target/SystemZ/SystemZISelLowering.h @@ -32,9 +32,18 @@ namespace llvm { /// instruction, which includes a bunch of information. CALL, + /// CMP, UCMP - Compare instruction CMP, UCMP, - BRCOND + + /// BRCOND - Conditional branch. Operand 0 is chain operand, operand 1 is + /// the block to branch if condition is true, operand 2 is condition code + /// and operand 3 is the flag operand produced by a CMP instruction. + BRCOND, + + /// SELECT - Operands 0 and 1 are selection variables, operand 2 is + /// condition code and operand 3 is the flag operand. + SELECT }; } @@ -56,6 +65,7 @@ namespace llvm { SDValue LowerRET(SDValue Op, SelectionDAG &DAG); SDValue LowerCALL(SDValue Op, SelectionDAG &DAG); SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG); + SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG); SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG); SDValue LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC); @@ -67,6 +77,10 @@ namespace llvm { ISD::CondCode CC, SDValue &SystemZCC, SelectionDAG &DAG); + + MachineBasicBlock* EmitInstrWithCustomInserter(MachineInstr *MI, + MachineBasicBlock *BB) const; + private: const SystemZSubtarget &Subtarget; const SystemZTargetMachine &TM; diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index 335d460..9734709 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -239,3 +239,32 @@ SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, return 0; } + +const TargetInstrDesc& +SystemZInstrInfo::getBrCond(SystemZCC::CondCodes CC) const { + unsigned Opc; + switch (CC) { + default: + assert(0 && "Unknown condition code!"); + case SystemZCC::E: + Opc = SystemZ::JE; + break; + case SystemZCC::NE: + Opc = SystemZ::JNE; + break; + case SystemZCC::H: + Opc = SystemZ::JH; + break; + case SystemZCC::L: + Opc = SystemZ::JL; + break; + case SystemZCC::HE: + Opc = SystemZ::JHE; + break; + case SystemZCC::LE: + Opc = SystemZ::JLE; + break; + } + + return get(Opc); +} diff --git a/lib/Target/SystemZ/SystemZInstrInfo.h b/lib/Target/SystemZ/SystemZInstrInfo.h index 6bc9f37..2359014 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/lib/Target/SystemZ/SystemZInstrInfo.h @@ -14,6 +14,7 @@ #ifndef LLVM_TARGET_SYSTEMZINSTRINFO_H #define LLVM_TARGET_SYSTEMZINSTRINFO_H +#include "SystemZ.h" #include "SystemZRegisterInfo.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/Target/TargetInstrInfo.h" @@ -65,6 +66,7 @@ public: MachineBasicBlock *FBB, const SmallVectorImpl<MachineOperand> &Cond) const; + const TargetInstrDesc& getBrCond(SystemZCC::CondCodes CC) const; }; } diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index fb1a070..87c5344 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -31,6 +31,10 @@ def SDT_CmpTest : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; def SDT_BrCond : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisI8<1>]>; +def SDT_SelectCC : SDTypeProfile<1, 3, + [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, + SDTCisI8<3>]>; + //===----------------------------------------------------------------------===// // SystemZ Specific Node Definitions. @@ -49,6 +53,7 @@ def SystemZcmp : SDNode<"SystemZISD::CMP", SDT_CmpTest, [SDNPOutFlag]>; def SystemZucmp : SDNode<"SystemZISD::UCMP", SDT_CmpTest, [SDNPOutFlag]>; def SystemZbrcond : SDNode<"SystemZISD::BRCOND", SDT_BrCond, [SDNPHasChain, SDNPInFlag]>; +def SystemZselect : SDNode<"SystemZISD::SELECT", SDT_SelectCC, [SDNPInFlag]>; //===----------------------------------------------------------------------===// // Instruction Pattern Stuff. @@ -236,6 +241,17 @@ def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2), "#ADJCALLSTACKUP", [(SystemZcallseq_end timm:$amt1, timm:$amt2)]>; +let usesCustomDAGSchedInserter = 1 in { + def Select32 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2, i8imm:$cc), + "# Select32 PSEUDO", + [(set GR32:$dst, + (SystemZselect GR32:$src1, GR32:$src2, imm:$cc))]>; + def Select64 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$cc), + "# Select64 PSEUDO", + [(set GR64:$dst, + (SystemZselect GR64:$src1, GR64:$src2, imm:$cc))]>; +} + //===----------------------------------------------------------------------===// // Control Flow Instructions... |