From ce636764de5ad5b829462497344644a649f98624 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 20 Aug 2008 00:11:48 +0000 Subject: [PATCH] Add FastISel support for several more binary operators. llvm-svn: 55020 --- include/llvm/CodeGen/FastISel.h | 31 +++++++++++ lib/CodeGen/SelectionDAG/FastISel.cpp | 78 +++++++++++++++++++++------ test/CodeGen/X86/fast-isel.ll | 10 +++- 3 files changed, 101 insertions(+), 18 deletions(-) diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 577e35ddc81..b395e9710f1 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -50,22 +50,53 @@ protected: virtual ~FastISel(); + /// FastEmit_r - This method is called by target-independent code + /// to request that an instruction with the given type and opcode + /// be emitted. virtual unsigned FastEmit_(MVT::SimpleValueType VT, ISD::NodeType Opcode); + + /// FastEmit_r - This method is called by target-independent code + /// to request that an instruction with the given type, opcode, and + /// register operand be emitted. + /// virtual unsigned FastEmit_r(MVT::SimpleValueType VT, ISD::NodeType Opcode, unsigned Op0); + + /// FastEmit_rr - This method is called by target-independent code + /// to request that an instruction with the given type, opcode, and + /// register operands be emitted. + /// virtual unsigned FastEmit_rr(MVT::SimpleValueType VT, ISD::NodeType Opcode, unsigned Op0, unsigned Op1); + /// FastEmitInst_ - Emit a MachineInstr with no operands and a + /// result register in the given register class. + /// unsigned FastEmitInst_(unsigned MachineInstOpcode, const TargetRegisterClass *RC); + + /// FastEmitInst_ - Emit a MachineInstr with one register operand + /// and a result register in the given register class. + /// unsigned FastEmitInst_r(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0); + + /// FastEmitInst_ - Emit a MachineInstr with two register operands + /// and a result register in the given register class. + /// unsigned FastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, unsigned Op1); + +private: + bool SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode, + DenseMap &ValueMap); + + bool SelectGetElementPtr(Instruction *I, + DenseMap &ValueMap); }; } diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index ab6c80e1827..f3fcaec28c3 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -18,6 +18,34 @@ #include "llvm/Target/TargetInstrInfo.h" using namespace llvm; +/// SelectBinaryOp - Select and emit code for a binary operator instruction, +/// which has an opcode which directly corresponds to the given ISD opcode. +/// +bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode, + DenseMap &ValueMap) { + unsigned Op0 = ValueMap[I->getOperand(0)]; + unsigned Op1 = ValueMap[I->getOperand(1)]; + MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true); + if (VT == MVT::Other || !VT.isSimple()) + // Unhandled type. Halt "fast" selection and bail. + return false; + + unsigned ResultReg = FastEmit_rr(VT.getSimpleVT(), ISDOpcode, Op0, Op1); + if (ResultReg == 0) + // Target-specific code wasn't able to find a machine opcode for + // the given ISD opcode and type. Halt "fast" selection and bail. + return false; + + ValueMap[I] = ResultReg; + return true; +} + +bool FastISel::SelectGetElementPtr(Instruction *I, + DenseMap &ValueMap) { + // TODO: implement me + return false; +} + BasicBlock::iterator FastISel::SelectInstructions(BasicBlock::iterator Begin, BasicBlock::iterator End, DenseMap &ValueMap) { @@ -25,23 +53,41 @@ FastISel::SelectInstructions(BasicBlock::iterator Begin, BasicBlock::iterator En for (; I != End; ++I) { switch (I->getOpcode()) { - case Instruction::Add: { - unsigned Op0 = ValueMap[I->getOperand(0)]; - unsigned Op1 = ValueMap[I->getOperand(1)]; - MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true); - if (VT == MVT::Other || !VT.isSimple()) { - // Unhandled type. Halt "fast" selection and bail. - return I; - } - unsigned ResultReg = FastEmit_rr(VT.getSimpleVT(), ISD::ADD, Op0, Op1); - if (ResultReg == 0) { - // Target-specific code wasn't able to find a machine opcode for - // the given ISD opcode and type. Halt "fast" selection and bail. - return I; - } - ValueMap[I] = ResultReg; + case Instruction::Add: + if (!SelectBinaryOp(I, ISD::ADD, ValueMap)) return I; break; + case Instruction::Sub: + if (!SelectBinaryOp(I, ISD::SUB, ValueMap)) return I; break; + case Instruction::Mul: + if (!SelectBinaryOp(I, ISD::MUL, ValueMap)) return I; break; + case Instruction::SDiv: + if (!SelectBinaryOp(I, ISD::SDIV, ValueMap)) return I; break; + case Instruction::UDiv: + if (!SelectBinaryOp(I, ISD::UDIV, ValueMap)) return I; break; + case Instruction::FDiv: + if (!SelectBinaryOp(I, ISD::FDIV, ValueMap)) return I; break; + case Instruction::SRem: + if (!SelectBinaryOp(I, ISD::SREM, ValueMap)) return I; break; + case Instruction::URem: + if (!SelectBinaryOp(I, ISD::UREM, ValueMap)) return I; break; + case Instruction::FRem: + if (!SelectBinaryOp(I, ISD::FREM, ValueMap)) return I; break; + case Instruction::Shl: + if (!SelectBinaryOp(I, ISD::SHL, ValueMap)) return I; break; + case Instruction::LShr: + if (!SelectBinaryOp(I, ISD::SRL, ValueMap)) return I; break; + case Instruction::AShr: + if (!SelectBinaryOp(I, ISD::SRA, ValueMap)) return I; break; + case Instruction::And: + if (!SelectBinaryOp(I, ISD::AND, ValueMap)) return I; break; + case Instruction::Or: + if (!SelectBinaryOp(I, ISD::OR, ValueMap)) return I; break; + case Instruction::Xor: + if (!SelectBinaryOp(I, ISD::XOR, ValueMap)) return I; break; + + case Instruction::GetElementPtr: + if (!SelectGetElementPtr(I, ValueMap)) return I; break; - } + case Instruction::Br: { BranchInst *BI = cast(I); diff --git a/test/CodeGen/X86/fast-isel.ll b/test/CodeGen/X86/fast-isel.ll index 36c5a2dca3b..1b0d5b2f8f6 100644 --- a/test/CodeGen/X86/fast-isel.ll +++ b/test/CodeGen/X86/fast-isel.ll @@ -9,9 +9,15 @@ entry: br label %fast fast: - %t = add i32 %r, %s + %t0 = add i32 %r, %s + %t1 = mul i32 %t0, %s + %t2 = sub i32 %t1, %s + %t3 = and i32 %t2, %s + %t4 = or i32 %t3, %s + %t5 = xor i32 %t4, %s br label %exit exit: - ret i32 %t + ret i32 %t5 } +