diff options
author | Dan Gohman <gohman@apple.com> | 2008-09-03 23:12:08 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2008-09-03 23:12:08 +0000 |
commit | 3df24e667f04a7003342b534310919abc9c87418 (patch) | |
tree | bcfae226d659d20f4bd6c4b5e8c25e42001a50db /lib | |
parent | 7bbb4339f905345f92fcd60bf8f64bdc29c8cc36 (diff) | |
download | llvm-3df24e667f04a7003342b534310919abc9c87418.tar.gz llvm-3df24e667f04a7003342b534310919abc9c87418.tar.bz2 llvm-3df24e667f04a7003342b534310919abc9c87418.tar.xz |
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')
-rw-r--r-- | lib/CodeGen/SelectionDAG/FastISel.cpp | 279 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 61 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 73 | ||||
-rw-r--r-- | lib/Target/X86/X86FastISel.cpp | 46 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 8 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 9 |
6 files changed, 257 insertions, 219 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()) { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 9df4bbaf73..3bbcdc99b5 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -4757,9 +4757,64 @@ SelectionDAGISel::HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB) { } } SDL->ConstantsOut.clear(); - - // Lower the terminator after the copies are emitted. - SDL->visit(*LLVMBB->getTerminator()); } +/// This is the Fast-ISel version of HandlePHINodesInSuccessorBlocks. It only +/// supports legal types, and it emits MachineInstrs directly instead of +/// creating SelectionDAG nodes. +/// +bool +SelectionDAGISel::HandlePHINodesInSuccessorBlocksFast(BasicBlock *LLVMBB, + FastISel *F) { + TerminatorInst *TI = LLVMBB->getTerminator(); + + SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled; + unsigned OrigNumPHINodesToUpdate = SDL->PHINodesToUpdate.size(); + + // Check successor nodes' PHI nodes that expect a constant to be available + // from this block. + for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) { + BasicBlock *SuccBB = TI->getSuccessor(succ); + if (!isa<PHINode>(SuccBB->begin())) continue; + MachineBasicBlock *SuccMBB = FuncInfo->MBBMap[SuccBB]; + + // If this terminator has multiple identical successors (common for + // switches), only handle each succ once. + if (!SuccsHandled.insert(SuccMBB)) continue; + + MachineBasicBlock::iterator MBBI = SuccMBB->begin(); + PHINode *PN; + // At this point we know that there is a 1-1 correspondence between LLVM PHI + // nodes and Machine PHI nodes, but the incoming operands have not been + // emitted yet. + for (BasicBlock::iterator I = SuccBB->begin(); + (PN = dyn_cast<PHINode>(I)); ++I) { + // Ignore dead phi's. + if (PN->use_empty()) continue; + + // Only handle legal types. Two interesting things to note here. First, + // by bailing out early, we may leave behind some dead instructions, + // since SelectionDAG's HandlePHINodesInSuccessorBlocks will insert its + // own moves. Second, this check is necessary becuase FastISel doesn't + // use CreateRegForValue to create registers, so it always creates + // exactly one register for each non-void instruction. + MVT VT = TLI.getValueType(PN->getType(), /*AllowUnknown=*/true); + if (VT == MVT::Other || !TLI.isTypeLegal(VT)) { + SDL->PHINodesToUpdate.resize(OrigNumPHINodesToUpdate); + return false; + } + + Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB); + + unsigned Reg = F->getRegForValue(PHIOp); + if (Reg == 0) { + SDL->PHINodesToUpdate.resize(OrigNumPHINodesToUpdate); + return false; + } + SDL->PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg)); + } + } + + return true; +} diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index a2cf6a1b56..2b9ba38f20 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -408,8 +408,12 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, } // Handle PHI nodes in successor blocks. - if (End == LLVMBB->end()) + if (End == LLVMBB->end()) { HandlePHINodesInSuccessorBlocks(LLVMBB); + + // Lower the terminator after the copies are emitted. + SDL->visit(*LLVMBB->getTerminator()); + } // Make sure the root of the DAG is up-to-date. CurDAG->setRoot(SDL->getControlRoot()); @@ -606,8 +610,9 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF) { BasicBlock *LLVMBB = &*I; BB = FuncInfo->MBBMap[LLVMBB]; - BasicBlock::iterator Begin = LLVMBB->begin(); - BasicBlock::iterator End = LLVMBB->end(); + BasicBlock::iterator const Begin = LLVMBB->begin(); + BasicBlock::iterator const End = LLVMBB->end(); + BasicBlock::iterator I = Begin; // Lower any arguments needed in this block if this is the entry block. if (LLVMBB == &Fn.getEntryBlock()) @@ -616,7 +621,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF) { // Before doing SelectionDAG ISel, see if FastISel has been requested. // FastISel doesn't support EH landing pads, which require special handling. if (EnableFastISel && !BB->isLandingPad()) { - if (FastISel *F = TLI.createFastISel(*FuncInfo->MF)) { + if (FastISel *F = TLI.createFastISel(*FuncInfo->MF, FuncInfo->ValueMap, + FuncInfo->MBBMap)) { // Emit code for any incoming arguments. This must happen before // beginning FastISel on the entry block. if (LLVMBB == &Fn.getEntryBlock()) { @@ -624,45 +630,51 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF) { CodeGenAndEmitDAG(); SDL->clear(); } + F->setCurrentBlock(BB); // Do FastISel on as many instructions as possible. - while (Begin != End) { - Begin = F->SelectInstructions(Begin, End, FuncInfo->ValueMap, - FuncInfo->MBBMap, BB); + for (; I != End; ++I) { + // Just before the terminator instruction, insert instructions to + // feed PHI nodes in successor blocks. + if (isa<TerminatorInst>(I)) + if (!HandlePHINodesInSuccessorBlocksFast(LLVMBB, F)) { + if (DisableFastISelAbort) + break; +#ifndef NDEBUG + I->dump(); +#endif + assert(0 && "FastISel didn't handle a PHI in a successor"); + } - // If the "fast" selector selected the entire block, we're done. - if (Begin == End) - break; + // First try normal tablegen-generated "fast" selection. + if (F->SelectInstruction(I)) + continue; // Next, try calling the target to attempt to handle the instruction. - if (F->TargetSelectInstruction(Begin, FuncInfo->ValueMap, - FuncInfo->MBBMap, BB)) { - ++Begin; + if (F->TargetSelectInstruction(I)) continue; - } - // Handle certain instructions as single-LLVM-Instruction blocks. - if (isa<CallInst>(Begin) || isa<LoadInst>(Begin) || - isa<StoreInst>(Begin)) { - if (Begin->getType() != Type::VoidTy) { - unsigned &R = FuncInfo->ValueMap[Begin]; + // Then handle certain instructions as single-LLVM-Instruction blocks. + if (isa<CallInst>(I) || isa<LoadInst>(I) || + isa<StoreInst>(I)) { + if (I->getType() != Type::VoidTy) { + unsigned &R = FuncInfo->ValueMap[I]; if (!R) - R = FuncInfo->CreateRegForValue(Begin); + R = FuncInfo->CreateRegForValue(I); } - SelectBasicBlock(LLVMBB, Begin, next(Begin)); - ++Begin; + SelectBasicBlock(LLVMBB, I, next(I)); continue; } if (!DisableFastISelAbort && // For now, don't abort on non-conditional-branch terminators. - (!isa<TerminatorInst>(Begin) || - (isa<BranchInst>(Begin) && - cast<BranchInst>(Begin)->isUnconditional()))) { + (!isa<TerminatorInst>(I) || + (isa<BranchInst>(I) && + cast<BranchInst>(I)->isUnconditional()))) { // The "fast" selector couldn't handle something and bailed. // For the purpose of debugging, just abort. #ifndef NDEBUG - Begin->dump(); + I->dump(); #endif assert(0 && "FastISel didn't select the entire block"); } @@ -674,12 +686,9 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF) { // Run SelectionDAG instruction selection on the remainder of the block // not handled by FastISel. If FastISel is not run, this is the entire - // block. If FastISel is run and happens to handle all of the - // LLVM Instructions in the block, [Begin,End) will be an empty range, - // but we still need to run this so that - // HandlePHINodesInSuccessorBlocks is called and any resulting code - // is emitted. - SelectBasicBlock(LLVMBB, Begin, End); + // block. + if (I != End) + SelectBasicBlock(LLVMBB, I, End); FinishBasicBlock(); } diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 658b65dba7..9b784b4449 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -30,34 +30,27 @@ class X86FastISel : public FastISel { const X86Subtarget *Subtarget; public: - explicit X86FastISel(MachineFunction &mf) : FastISel(mf) { + explicit X86FastISel(MachineFunction &mf, + DenseMap<const Value *, unsigned> &vm, + DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) + : FastISel(mf, vm, bm) { Subtarget = &TM.getSubtarget<X86Subtarget>(); } - virtual bool - TargetSelectInstruction(Instruction *I, - DenseMap<const Value *, unsigned> &ValueMap, - DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap, - MachineBasicBlock *MBB); + virtual bool TargetSelectInstruction(Instruction *I); #include "X86GenFastISel.inc" private: - bool X86SelectConstAddr(Value *V, - DenseMap<const Value *, unsigned> &ValueMap, - MachineBasicBlock *MBB, unsigned &Op0); + bool X86SelectConstAddr(Value *V, unsigned &Op0); - bool X86SelectLoad(Instruction *I, - DenseMap<const Value *, unsigned> &ValueMap, - MachineBasicBlock *MBB); + bool X86SelectLoad(Instruction *I); }; /// X86SelectConstAddr - Select and emit code to materialize constant address. /// bool X86FastISel::X86SelectConstAddr(Value *V, - DenseMap<const Value *, unsigned> &ValueMap, - MachineBasicBlock *MBB, - unsigned &Op0) { + unsigned &Op0) { // FIXME: Only GlobalAddress for now. GlobalValue *GV = dyn_cast<GlobalValue>(V); if (!GV) @@ -84,9 +77,7 @@ bool X86FastISel::X86SelectConstAddr(Value *V, /// X86SelectLoad - Select and emit code to implement load instructions. /// -bool X86FastISel::X86SelectLoad(Instruction *I, - DenseMap<const Value *, unsigned> &ValueMap, - MachineBasicBlock *MBB) { +bool X86FastISel::X86SelectLoad(Instruction *I) { MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true); if (VT == MVT::Other || !VT.isSimple()) // Unhandled type. Halt "fast" selection and bail. @@ -102,10 +93,10 @@ bool X86FastISel::X86SelectLoad(Instruction *I, return false; Value *V = I->getOperand(0); - unsigned Op0 = getRegForValue(V, ValueMap); + unsigned Op0 = getRegForValue(V); if (Op0 == 0) { // Handle constant load address. - if (!isa<Constant>(V) || !X86SelectConstAddr(V, ValueMap, MBB, Op0)) + if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op0)) // Unhandled operand. Halt "fast" selection and bail. return false; } @@ -164,27 +155,26 @@ bool X86FastISel::X86SelectLoad(Instruction *I, else AM.GV = cast<GlobalValue>(V); addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM); - UpdateValueMap(I, ResultReg, ValueMap); + UpdateValueMap(I, ResultReg); return true; } bool -X86FastISel::TargetSelectInstruction(Instruction *I, - DenseMap<const Value *, unsigned> &ValueMap, - DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap, - MachineBasicBlock *MBB) { +X86FastISel::TargetSelectInstruction(Instruction *I) { switch (I->getOpcode()) { default: break; case Instruction::Load: - return X86SelectLoad(I, ValueMap, MBB); + return X86SelectLoad(I); } return false; } namespace llvm { - llvm::FastISel *X86::createFastISel(MachineFunction &mf) { - return new X86FastISel(mf); + llvm::FastISel *X86::createFastISel(MachineFunction &mf, + DenseMap<const Value *, unsigned> &vm, + DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) { + return new X86FastISel(mf, vm, bm); } } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index dceed6fa23..2cdd93c66b 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1879,8 +1879,12 @@ bool X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Call, return false; } -FastISel *X86TargetLowering::createFastISel(MachineFunction &mf) { - return X86::createFastISel(mf); +FastISel * +X86TargetLowering::createFastISel(MachineFunction &mf, + DenseMap<const Value *, unsigned> &vm, + DenseMap<const BasicBlock *, + MachineBasicBlock *> &bm) { + return X86::createFastISel(mf, vm, bm); } diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index c50769c685..e83132d007 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -470,7 +470,10 @@ namespace llvm { /// createFastISel - This method returns a target specific FastISel object, /// or null if the target does not support "fast" ISel. - virtual FastISel *createFastISel(MachineFunction &mf); + virtual FastISel * + createFastISel(MachineFunction &mf, + DenseMap<const Value *, unsigned> &, + DenseMap<const BasicBlock *, MachineBasicBlock *> &); private: /// Subtarget - Keep a pointer to the X86Subtarget around so that we can @@ -598,7 +601,9 @@ namespace llvm { }; namespace X86 { - FastISel *createFastISel(MachineFunction &mf); + FastISel *createFastISel(MachineFunction &mf, + DenseMap<const Value *, unsigned> &, + DenseMap<const BasicBlock *, MachineBasicBlock *> &); } } |