diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2009-05-03 13:12:23 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2009-05-03 13:12:23 +0000 |
commit | 8b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9 (patch) | |
tree | 152e3fb01cadc9e040298fffba1ec792278ddb08 /lib/Target | |
parent | ed1a51af376b9027db60ff060e0a2572493df07b (diff) | |
download | external_llvm-8b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9.zip external_llvm-8b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9.tar.gz external_llvm-8b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9.tar.bz2 |
Lower select with custom inserted and make condjumps generic
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70744 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/MSP430/MSP430AsmPrinter.cpp | 28 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430ISelLowering.cpp | 118 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430ISelLowering.h | 9 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430InstrInfo.h | 3 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430InstrInfo.td | 46 |
5 files changed, 168 insertions, 36 deletions
diff --git a/lib/Target/MSP430/MSP430AsmPrinter.cpp b/lib/Target/MSP430/MSP430AsmPrinter.cpp index 8fc5de6..039ccce 100644 --- a/lib/Target/MSP430/MSP430AsmPrinter.cpp +++ b/lib/Target/MSP430/MSP430AsmPrinter.cpp @@ -51,6 +51,7 @@ namespace { const char* Modifier = 0); void printSrcMemOperand(const MachineInstr *MI, int OpNum, const char* Modifier = 0); + void printCCOperand(const MachineInstr *MI, int OpNum); bool printInstruction(const MachineInstr *MI); // autogenerated. void printMachineInstruction(const MachineInstr * MI); bool runOnMachineFunction(MachineFunction &F); @@ -182,3 +183,30 @@ void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum, assert(0 && "Unsupported memory operand"); } +void MSP430AsmPrinter::printCCOperand(const MachineInstr *MI, int OpNum) { + unsigned CC = MI->getOperand(OpNum).getImm(); + + switch (CC) { + default: + assert(0 && "Unsupported CC code"); + break; + case MSP430::COND_E: + O << 'e'; + break; + case MSP430::COND_NE: + O << "ne"; + break; + case MSP430::COND_HS: + O << "hs"; + break; + case MSP430::COND_LO: + O << "lo"; + break; + case MSP430::COND_GE: + O << "ge"; + break; + case MSP430::COND_L: + O << 'l'; + break; + } +} diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp index 2354c83..5e67265 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -58,7 +58,7 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : setBooleanContents(ZeroOrOneBooleanContent); setSchedulingPreference(SchedulingForLatency); - setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); + setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); @@ -67,13 +67,16 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : // We don't have any truncstores setTruncStoreAction(MVT::i16, MVT::i8, Expand); - setOperationAction(ISD::SRA, MVT::i16, Custom); - setOperationAction(ISD::RET, MVT::Other, Custom); - setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); - setOperationAction(ISD::BR_CC, MVT::Other, Expand); - setOperationAction(ISD::BRCOND, MVT::Other, Custom); - setOperationAction(ISD::SETCC, MVT::i8 , Custom); - setOperationAction(ISD::SETCC, MVT::i16 , Custom); + setOperationAction(ISD::SRA, MVT::i16, Custom); + setOperationAction(ISD::RET, MVT::Other, Custom); + setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); + setOperationAction(ISD::BR_CC, MVT::Other, Expand); + setOperationAction(ISD::BRCOND, MVT::Other, Custom); + setOperationAction(ISD::SETCC, MVT::i8, Custom); + setOperationAction(ISD::SETCC, MVT::i16, Custom); + setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); + setOperationAction(ISD::SELECT, MVT::i8, Custom); + setOperationAction(ISD::SELECT, MVT::i16, Custom); } SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { @@ -85,6 +88,7 @@ SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::SETCC: return LowerSETCC(Op, DAG); case ISD::BRCOND: return LowerBRCOND(Op, DAG); + case ISD::SELECT: return LowerSELECT(Op, DAG); default: assert(0 && "unimplemented operand"); return SDValue(); @@ -517,6 +521,40 @@ SDValue MSP430TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) { Chain, Dest, CC, Cond); } +SDValue MSP430TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) { + SDValue Cond = Op.getOperand(0); + SDValue TrueV = Op.getOperand(1); + SDValue FalseV = Op.getOperand(2); + DebugLoc dl = Op.getDebugLoc(); + SDValue CC; + + // Lower condition if not lowered yet + if (Cond.getOpcode() == ISD::SETCC) + Cond = LowerSETCC(Cond, DAG); + + // If condition flag is set by a MSP430ISD::CMP, then use it as the condition + // setting operand in place of the MSP430ISD::SETCC. + if (Cond.getOpcode() == MSP430ISD::SETCC) { + CC = Cond.getOperand(0); + Cond = Cond.getOperand(1); + TrueV = Cond.getOperand(0); + FalseV = Cond.getOperand(1); + } else { + CC = DAG.getConstant(MSP430::COND_NE, MVT::i16); + Cond = DAG.getNode(MSP430ISD::CMP, dl, MVT::i16, + Cond, DAG.getConstant(0, MVT::i16)); + } + + SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); + SmallVector<SDValue, 4> Ops; + Ops.push_back(TrueV); + Ops.push_back(FalseV); + Ops.push_back(CC); + Ops.push_back(Cond); + + return DAG.getNode(MSP430ISD::SELECT, dl, VTs, &Ops[0], Ops.size()); +} + const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { default: return NULL; @@ -527,5 +565,69 @@ const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { case MSP430ISD::BRCOND: return "MSP430ISD::BRCOND"; case MSP430ISD::CMP: return "MSP430ISD::CMP"; case MSP430ISD::SETCC: return "MSP430ISD::SETCC"; + case MSP430ISD::SELECT: return "MSP430ISD::SELECT"; } } + +//===----------------------------------------------------------------------===// +// Other Lowering Code +//===----------------------------------------------------------------------===// + +MachineBasicBlock* +MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, + MachineBasicBlock *BB) const { + const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + assert((MI->getOpcode() == MSP430::Select16) && + "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); + BuildMI(BB, dl, TII.get(MSP430::JCC)) + .addMBB(copy1MBB) + .addImm(MI->getOperand(3).getImm()); + 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(MSP430::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/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h index c0ababd..f14af1d 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.h +++ b/lib/Target/MSP430/MSP430ISelLowering.h @@ -49,7 +49,11 @@ namespace llvm { /// is the block to branch if condition is true, operand 2 is the /// condition code, and operand 3 is the flag operand produced by a CMP /// instruction. - BRCOND + BRCOND, + + /// SELECT. Operand 0 and operand 1 are selection variable, operand 3 is + /// condition code and operand 4 is flag operand. + SELECT }; } @@ -77,6 +81,7 @@ namespace llvm { SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG); SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG); + SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG); SDValue LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC); @@ -84,6 +89,8 @@ namespace llvm { CallSDNode *TheCall, unsigned CallingConv, SelectionDAG &DAG); + MachineBasicBlock* EmitInstrWithCustomInserter(MachineInstr *MI, + MachineBasicBlock *BB) const; private: const MSP430Subtarget &Subtarget; diff --git a/lib/Target/MSP430/MSP430InstrInfo.h b/lib/Target/MSP430/MSP430InstrInfo.h index 0803e2d..59133d9 100644 --- a/lib/Target/MSP430/MSP430InstrInfo.h +++ b/lib/Target/MSP430/MSP430InstrInfo.h @@ -22,8 +22,7 @@ namespace llvm { class MSP430TargetMachine; namespace MSP430 { - // MSP430 specific condition code. These correspond to MSP430_*_COND in - // MSP430InstrInfo.td. They must be kept in synch. + // MSP430 specific condition code. enum CondCode { COND_E = 0, // aka COND_Z COND_NE = 1, // aka COND_NZ diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td index 83a236e..5799121 100644 --- a/lib/Target/MSP430/MSP430InstrInfo.td +++ b/lib/Target/MSP430/MSP430InstrInfo.td @@ -31,6 +31,8 @@ def SDT_MSP430SetCC : SDTypeProfile<1, 2, [SDTCisVT<0, i8>, def SDT_MSP430Cmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; def SDT_MSP430BrCond : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i8>, SDTCisVT<2, i16>]>; +def SDT_MSP430Select : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, + SDTCisVT<3, i8>, SDTCisVT<4, i16>]>; //===----------------------------------------------------------------------===// // MSP430 Specific Node Definitions. @@ -52,6 +54,7 @@ def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>; def MSP430setcc : SDNode<"MSP430ISD::SETCC", SDT_MSP430SetCC>; def MSP430cmp : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp>; def MSP430brcond : SDNode<"MSP430ISD::BRCOND", SDT_MSP430BrCond, [SDNPHasChain]>; +def MSP430select : SDNode<"MSP430ISD::SELECT", SDT_MSP430Select>; //===----------------------------------------------------------------------===// // MSP430 Operand Definitions. @@ -71,6 +74,11 @@ def memdst : Operand<i16> { // Branch targets have OtherVT type. def brtarget : Operand<OtherVT>; +// Operand for printing out a condition code. +def cc : Operand<i8> { + let PrintMethod = "printCCOperand"; +} + //===----------------------------------------------------------------------===// // MSP430 Complex Pattern Definitions. //===----------------------------------------------------------------------===// @@ -82,15 +90,6 @@ def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>; def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>; def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>; -// MSP430 specific condition code. These correspond to CondCode in -// MSP430InstrInfo.h. They must be kept in synch. -def MSP430_COND_E : PatLeaf<(i8 0)>; // aka COND_Z -def MSP430_COND_NE : PatLeaf<(i8 1)>; // aka COND_NZ -def MSP430_COND_HS : PatLeaf<(i8 2)>; // aka COND_C -def MSP430_COND_LO : PatLeaf<(i8 3)>; // aka COND_NC -def MSP430_COND_GE : PatLeaf<(i8 4)>; -def MSP430_COND_L : PatLeaf<(i8 5)>; - //===----------------------------------------------------------------------===// // Instruction list.. @@ -108,6 +107,12 @@ def ADJCALLSTACKUP : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2), [(MSP430callseq_end timm:$amt1, timm:$amt2)]>; } +let usesCustomDAGSchedInserter = 1 in { + def Select16 : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2, i8imm:$cc), + "# Select16 PSEUDO", + [(set GR16:$dst, + (MSP430select GR16:$src1, GR16:$src2, imm:$cc, SRW))]>; +} let neverHasSideEffects = 1 in def NOP : Pseudo<(outs), (ins), "nop", []>; @@ -123,18 +128,9 @@ let isReturn = 1, isTerminator = 1 in { // Conditional branches let isBranch = 1, isTerminator = 1, Uses = [SRW] in { -def JE : Pseudo<(outs), (ins brtarget:$dst), "je\t$dst", - [(MSP430brcond bb:$dst, MSP430_COND_E, SRW)]>; -def JNE : Pseudo<(outs), (ins brtarget:$dst), "jne\t$dst", - [(MSP430brcond bb:$dst, MSP430_COND_NE, SRW)]>; -def JHS : Pseudo<(outs), (ins brtarget:$dst), "jhs\t$dst", - [(MSP430brcond bb:$dst, MSP430_COND_HS, SRW)]>; -def JLO : Pseudo<(outs), (ins brtarget:$dst), "jlo\t$dst", - [(MSP430brcond bb:$dst, MSP430_COND_LO, SRW)]>; -def JGE : Pseudo<(outs), (ins brtarget:$dst), "jge\t$dst", - [(MSP430brcond bb:$dst, MSP430_COND_GE, SRW)]>; -def JL : Pseudo<(outs), (ins brtarget:$dst), "jl\t$dst", - [(MSP430brcond bb:$dst, MSP430_COND_L, SRW)]>; +def JCC : Pseudo<(outs), (ins brtarget:$dst, cc:$cc), + "j$cc $dst", + [(MSP430brcond bb:$dst, imm:$cc, SRW)]>; } // Uses = [SRW] //===----------------------------------------------------------------------===// @@ -656,17 +652,17 @@ def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), // Integer comparisons let Defs = [SRW] in { def CMP8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2), - "cmp.b\t{$src2, $src1|$src1, $src2}", + "cmp.b\t{$src1, $src2}", [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>; def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2), - "cmp.w\t{$src2, $src1|$src1, $src2}", + "cmp.w\t{$src1, $src2}", [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>; def CMP8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2), - "cmp.b\t{$src2, $src1|$src1, $src2}", + "cmp.b\t{$src1, $src2}", [(MSP430cmp GR8:$src1, imm:$src2), (implicit SRW)]>; def CMP16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2), - "cmp.w\t{$src2, $src1|$src1, $src2}", + "cmp.w\t{$src1, $src2}", [(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>; def CMP8rm : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2), |