1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

SELECT_CC lowering

llvm-svn: 75948
This commit is contained in:
Anton Korobeynikov 2009-07-16 13:52:51 +00:00
parent 769a8c2312
commit e26fb377c5
5 changed files with 155 additions and 1 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
};
}

View File

@ -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...