aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/FastISel.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-09-03 23:12:08 +0000
committerDan Gohman <gohman@apple.com>2008-09-03 23:12:08 +0000
commit3df24e667f04a7003342b534310919abc9c87418 (patch)
treebcfae226d659d20f4bd6c4b5e8c25e42001a50db /lib/CodeGen/SelectionDAG/FastISel.cpp
parent7bbb4339f905345f92fcd60bf8f64bdc29c8cc36 (diff)
Create HandlePHINodesInSuccessorBlocksFast, a version of
HandlePHINodesInSuccessorBlocks that works FastISel-style. This allows PHI nodes to be updated correctly while using FastISel. This also involves some code reorganization; ValueMap and MBBMap are now members of the FastISel class, so they needn't be passed around explicitly anymore. Also, SelectInstructions is changed to SelectInstruction, and only does one instruction at a time. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55746 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/FastISel.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp279
1 files changed, 127 insertions, 152 deletions
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index 12f12bd22c..c057be5f76 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -25,8 +25,7 @@ using namespace llvm;
// tracking what uses they dominate. Non-constants, however, already
// have the SSA def-doms-use requirement enforced, so we can cache their
// computations.
-unsigned FastISel::getRegForValue(Value *V,
- DenseMap<const Value*, unsigned> &ValueMap) {
+unsigned FastISel::getRegForValue(Value *V) {
if (ValueMap.count(V))
return ValueMap[V];
@@ -78,8 +77,7 @@ unsigned FastISel::getRegForValue(Value *V,
/// NOTE: This is only necessary because we might select a block that uses
/// a value before we select the block that defines the value. It might be
/// possible to fix this by selecting blocks in reverse postorder.
-void FastISel::UpdateValueMap(Instruction* I, unsigned Reg,
- DenseMap<const Value*, unsigned> &ValueMap) {
+void FastISel::UpdateValueMap(Instruction* I, unsigned Reg) {
if (!ValueMap.count(I))
ValueMap[I] = Reg;
else
@@ -90,8 +88,7 @@ void FastISel::UpdateValueMap(Instruction* I, unsigned Reg,
/// 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<const Value*, unsigned> &ValueMap) {
+bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode) {
MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
if (VT == MVT::Other || !VT.isSimple())
// Unhandled type. Halt "fast" selection and bail.
@@ -103,7 +100,7 @@ bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
if (!TLI.isTypeLegal(VT))
return false;
- unsigned Op0 = getRegForValue(I->getOperand(0), ValueMap);
+ unsigned Op0 = getRegForValue(I->getOperand(0));
if (Op0 == 0)
// Unhandled operand. Halt "fast" selection and bail.
return false;
@@ -114,7 +111,7 @@ bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
ISDOpcode, Op0, CI->getZExtValue());
if (ResultReg != 0) {
// We successfully emitted code for the given LLVM Instruction.
- UpdateValueMap(I, ResultReg, ValueMap);
+ UpdateValueMap(I, ResultReg);
return true;
}
}
@@ -125,12 +122,12 @@ bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
ISDOpcode, Op0, CF);
if (ResultReg != 0) {
// We successfully emitted code for the given LLVM Instruction.
- UpdateValueMap(I, ResultReg, ValueMap);
+ UpdateValueMap(I, ResultReg);
return true;
}
}
- unsigned Op1 = getRegForValue(I->getOperand(1), ValueMap);
+ unsigned Op1 = getRegForValue(I->getOperand(1));
if (Op1 == 0)
// Unhandled operand. Halt "fast" selection and bail.
return false;
@@ -144,13 +141,12 @@ bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
return false;
// We successfully emitted code for the given LLVM Instruction.
- UpdateValueMap(I, ResultReg, ValueMap);
+ UpdateValueMap(I, ResultReg);
return true;
}
-bool FastISel::SelectGetElementPtr(Instruction *I,
- DenseMap<const Value*, unsigned> &ValueMap) {
- unsigned N = getRegForValue(I->getOperand(0), ValueMap);
+bool FastISel::SelectGetElementPtr(Instruction *I) {
+ unsigned N = getRegForValue(I->getOperand(0));
if (N == 0)
// Unhandled operand. Halt "fast" selection and bail.
return false;
@@ -190,7 +186,7 @@ bool FastISel::SelectGetElementPtr(Instruction *I,
// N = N + Idx * ElementSize;
uint64_t ElementSize = TD.getABITypeSize(Ty);
- unsigned IdxN = getRegForValue(Idx, ValueMap);
+ unsigned IdxN = getRegForValue(Idx);
if (IdxN == 0)
// Unhandled operand. Halt "fast" selection and bail.
return false;
@@ -220,12 +216,11 @@ bool FastISel::SelectGetElementPtr(Instruction *I,
}
// We successfully emitted code for the given LLVM Instruction.
- UpdateValueMap(I, N, ValueMap);
+ UpdateValueMap(I, N);
return true;
}
-bool FastISel::SelectCast(Instruction *I, ISD::NodeType Opcode,
- DenseMap<const Value*, unsigned> &ValueMap) {
+bool FastISel::SelectCast(Instruction *I, ISD::NodeType Opcode) {
MVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
MVT DstVT = TLI.getValueType(I->getType());
@@ -235,7 +230,7 @@ bool FastISel::SelectCast(Instruction *I, ISD::NodeType Opcode,
// Unhandled type. Halt "fast" selection and bail.
return false;
- unsigned InputReg = getRegForValue(I->getOperand(0), ValueMap);
+ unsigned InputReg = getRegForValue(I->getOperand(0));
if (!InputReg)
// Unhandled operand. Halt "fast" selection and bail.
return false;
@@ -247,18 +242,17 @@ bool FastISel::SelectCast(Instruction *I, ISD::NodeType Opcode,
if (!ResultReg)
return false;
- UpdateValueMap(I, ResultReg, ValueMap);
+ UpdateValueMap(I, ResultReg);
return true;
}
-bool FastISel::SelectBitCast(Instruction *I,
- DenseMap<const Value*, unsigned> &ValueMap) {
+bool FastISel::SelectBitCast(Instruction *I) {
// If the bitcast doesn't change the type, just use the operand value.
if (I->getType() == I->getOperand(0)->getType()) {
- unsigned Reg = getRegForValue(I->getOperand(0), ValueMap);
+ unsigned Reg = getRegForValue(I->getOperand(0));
if (Reg == 0)
return false;
- UpdateValueMap(I, Reg, ValueMap);
+ UpdateValueMap(I, Reg);
return true;
}
@@ -272,7 +266,7 @@ bool FastISel::SelectBitCast(Instruction *I,
// Unhandled type. Halt "fast" selection and bail.
return false;
- unsigned Op0 = getRegForValue(I->getOperand(0), ValueMap);
+ unsigned Op0 = getRegForValue(I->getOperand(0));
if (Op0 == 0)
// Unhandled operand. Halt "fast" selection and bail.
return false;
@@ -298,143 +292,124 @@ bool FastISel::SelectBitCast(Instruction *I,
if (!ResultReg)
return false;
- UpdateValueMap(I, ResultReg, ValueMap);
+ UpdateValueMap(I, ResultReg);
return true;
}
-BasicBlock::iterator
-FastISel::SelectInstructions(BasicBlock::iterator Begin,
- BasicBlock::iterator End,
- DenseMap<const Value*, unsigned> &ValueMap,
- DenseMap<const BasicBlock*,
- MachineBasicBlock *> &MBBMap,
- MachineBasicBlock *mbb) {
- MBB = mbb;
- BasicBlock::iterator I = Begin;
-
- for (; I != End; ++I) {
- switch (I->getOpcode()) {
- case Instruction::Add: {
- ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FADD : ISD::ADD;
- if (!SelectBinaryOp(I, Opc, ValueMap)) return I; break;
- }
- case Instruction::Sub: {
- ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FSUB : ISD::SUB;
- if (!SelectBinaryOp(I, Opc, ValueMap)) return I; break;
- }
- case Instruction::Mul: {
- ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FMUL : ISD::MUL;
- if (!SelectBinaryOp(I, Opc, 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<BranchInst>(I);
-
- if (BI->isUnconditional()) {
- MachineFunction::iterator NextMBB =
- next(MachineFunction::iterator(MBB));
- BasicBlock *LLVMSucc = BI->getSuccessor(0);
- MachineBasicBlock *MSucc = MBBMap[LLVMSucc];
-
- if (NextMBB != MF.end() && MSucc == NextMBB) {
- // The unconditional fall-through case, which needs no instructions.
- } else {
- // The unconditional branch case.
- TII.InsertBranch(*MBB, MSucc, NULL, SmallVector<MachineOperand, 0>());
- }
- MBB->addSuccessor(MSucc);
- break;
- }
-
- // Conditional branches are not handed yet.
- // Halt "fast" selection and bail.
- return I;
- }
-
- case Instruction::PHI:
- // PHI nodes are already emitted.
- break;
-
- case Instruction::BitCast:
- if (!SelectBitCast(I, ValueMap)) return I; break;
-
- case Instruction::FPToSI:
- if (!SelectCast(I, ISD::FP_TO_SINT, ValueMap)) return I;
- break;
- case Instruction::ZExt:
- if (!SelectCast(I, ISD::ZERO_EXTEND, ValueMap)) return I;
- break;
- case Instruction::SExt:
- if (!SelectCast(I, ISD::SIGN_EXTEND, ValueMap)) return I;
- break;
- case Instruction::Trunc:
- if (!SelectCast(I, ISD::TRUNCATE, ValueMap)) return I;
- break;
- case Instruction::SIToFP:
- if (!SelectCast(I, ISD::SINT_TO_FP, ValueMap)) return I;
- break;
-
- case Instruction::IntToPtr: // Deliberate fall-through.
- case Instruction::PtrToInt: {
- MVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
- MVT DstVT = TLI.getValueType(I->getType());
- if (SrcVT.getSimpleVT() == DstVT.getSimpleVT()) {
- if (ValueMap[I->getOperand(0)]) {
- UpdateValueMap(I, ValueMap[I->getOperand(0)], ValueMap);
- break;
- } else
- // Unhandled operand
- return I;
- } else if (DstVT.bitsGT(SrcVT)) {
- if (!SelectCast(I, ISD::ZERO_EXTEND, ValueMap)) return I;
- break;
+bool
+FastISel::SelectInstruction(Instruction *I) {
+ switch (I->getOpcode()) {
+ case Instruction::Add: {
+ ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FADD : ISD::ADD;
+ return SelectBinaryOp(I, Opc);
+ }
+ case Instruction::Sub: {
+ ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FSUB : ISD::SUB;
+ return SelectBinaryOp(I, Opc);
+ }
+ case Instruction::Mul: {
+ ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FMUL : ISD::MUL;
+ return SelectBinaryOp(I, Opc);
+ }
+ case Instruction::SDiv:
+ return SelectBinaryOp(I, ISD::SDIV);
+ case Instruction::UDiv:
+ return SelectBinaryOp(I, ISD::UDIV);
+ case Instruction::FDiv:
+ return SelectBinaryOp(I, ISD::FDIV);
+ case Instruction::SRem:
+ return SelectBinaryOp(I, ISD::SREM);
+ case Instruction::URem:
+ return SelectBinaryOp(I, ISD::UREM);
+ case Instruction::FRem:
+ return SelectBinaryOp(I, ISD::FREM);
+ case Instruction::Shl:
+ return SelectBinaryOp(I, ISD::SHL);
+ case Instruction::LShr:
+ return SelectBinaryOp(I, ISD::SRL);
+ case Instruction::AShr:
+ return SelectBinaryOp(I, ISD::SRA);
+ case Instruction::And:
+ return SelectBinaryOp(I, ISD::AND);
+ case Instruction::Or:
+ return SelectBinaryOp(I, ISD::OR);
+ case Instruction::Xor:
+ return SelectBinaryOp(I, ISD::XOR);
+
+ case Instruction::GetElementPtr:
+ return SelectGetElementPtr(I);
+
+ case Instruction::Br: {
+ BranchInst *BI = cast<BranchInst>(I);
+
+ if (BI->isUnconditional()) {
+ MachineFunction::iterator NextMBB =
+ next(MachineFunction::iterator(MBB));
+ BasicBlock *LLVMSucc = BI->getSuccessor(0);
+ MachineBasicBlock *MSucc = MBBMap[LLVMSucc];
+
+ if (NextMBB != MF.end() && MSucc == NextMBB) {
+ // The unconditional fall-through case, which needs no instructions.
} else {
- // TODO: Handle SrcVT > DstVT, where truncation is needed.
- return I;
+ // The unconditional branch case.
+ TII.InsertBranch(*MBB, MSucc, NULL, SmallVector<MachineOperand, 0>());
}
+ MBB->addSuccessor(MSucc);
+ return true;
}
-
- default:
- // Unhandled instruction. Halt "fast" selection and bail.
- return I;
- }
+
+ // Conditional branches are not handed yet.
+ // Halt "fast" selection and bail.
+ return false;
}
- return I;
+ case Instruction::PHI:
+ // PHI nodes are already emitted.
+ return true;
+
+ case Instruction::BitCast:
+ return SelectBitCast(I);
+
+ case Instruction::FPToSI:
+ return SelectCast(I, ISD::FP_TO_SINT);
+ case Instruction::ZExt:
+ return SelectCast(I, ISD::ZERO_EXTEND);
+ case Instruction::SExt:
+ return SelectCast(I, ISD::SIGN_EXTEND);
+ case Instruction::Trunc:
+ return SelectCast(I, ISD::TRUNCATE);
+ case Instruction::SIToFP:
+ return SelectCast(I, ISD::SINT_TO_FP);
+
+ case Instruction::IntToPtr: // Deliberate fall-through.
+ case Instruction::PtrToInt: {
+ MVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
+ MVT DstVT = TLI.getValueType(I->getType());
+ if (DstVT.bitsGT(SrcVT))
+ return SelectCast(I, ISD::ZERO_EXTEND);
+ if (DstVT.bitsLT(SrcVT))
+ return SelectCast(I, ISD::TRUNCATE);
+ unsigned Reg = getRegForValue(I->getOperand(0));
+ if (Reg == 0) return false;
+ UpdateValueMap(I, Reg);
+ return true;
+ }
+
+ default:
+ // Unhandled instruction. Halt "fast" selection and bail.
+ return false;
+ }
}
-FastISel::FastISel(MachineFunction &mf)
- : MF(mf),
- MRI(mf.getRegInfo()),
- TM(mf.getTarget()),
+FastISel::FastISel(MachineFunction &mf,
+ DenseMap<const Value *, unsigned> &vm,
+ DenseMap<const BasicBlock *, MachineBasicBlock *> &bm)
+ : MBB(0),
+ ValueMap(vm),
+ MBBMap(bm),
+ MF(mf),
+ MRI(MF.getRegInfo()),
+ TM(MF.getTarget()),
TD(*TM.getTargetData()),
TII(*TM.getInstrInfo()),
TLI(*TM.getTargetLowering()) {