[llvm-commits] [llvm] r55746 - in /llvm/trunk: include/llvm/CodeGen/FastISel.h include/llvm/CodeGen/SelectionDAGISel.h include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/FastISel.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/X86/X86FastISel.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h
Dan Gohman
gohman at apple.com
Wed Sep 3 16:12:08 PDT 2008
Author: djg
Date: Wed Sep 3 18:12:08 2008
New Revision: 55746
URL: http://llvm.org/viewvc/llvm-project?rev=55746&view=rev
Log:
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.
Modified:
llvm/trunk/include/llvm/CodeGen/FastISel.h
llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h
llvm/trunk/include/llvm/Target/TargetLowering.h
llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
llvm/trunk/lib/Target/X86/X86FastISel.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.h
Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=55746&r1=55745&r2=55746&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/FastISel.h Wed Sep 3 18:12:08 2008
@@ -36,6 +36,8 @@
class FastISel {
protected:
MachineBasicBlock *MBB;
+ DenseMap<const Value *, unsigned> &ValueMap;
+ DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap;
MachineFunction &MF;
MachineRegisterInfo &MRI;
const TargetMachine &TM;
@@ -44,17 +46,18 @@
const TargetLowering &TLI;
public:
- /// SelectInstructions - Do "fast" instruction selection over the
- /// LLVM IR instructions in the range [Begin, N) where N is either
- /// End or the first unsupported instruction. Return N.
- /// ValueMap is filled in with a mapping of LLVM IR Values to
- /// virtual register numbers. MBB is a block to which to append
- /// the generated MachineInstrs.
- BasicBlock::iterator
- SelectInstructions(BasicBlock::iterator Begin, BasicBlock::iterator End,
- DenseMap<const Value *, unsigned> &ValueMap,
- DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap,
- MachineBasicBlock *MBB);
+ /// setCurrentBlock - Set the current block, to which generated
+ /// machine instructions will be appended.
+ ///
+ void setCurrentBlock(MachineBasicBlock *mbb) {
+ MBB = mbb;
+ }
+
+ /// SelectInstruction - Do "fast" instruction selection for the given
+ /// LLVM IR instruction, and append generated machine instructions to
+ /// the current block. Return true if selection was successful.
+ ///
+ bool SelectInstruction(Instruction *I);
/// TargetSelectInstruction - This method is called by target-independent
/// code when the normal FastISel process fails to select an instruction.
@@ -62,15 +65,18 @@
/// fit into FastISel's framework. It returns true if it was successful.
///
virtual bool
- TargetSelectInstruction(Instruction *I,
- DenseMap<const Value *, unsigned> &ValueMap,
- DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap,
- MachineBasicBlock *MBB) = 0;
+ TargetSelectInstruction(Instruction *I) = 0;
+
+ /// getRegForValue - Create a virtual register and arrange for it to
+ /// be assigned the value for the given LLVM value.
+ unsigned getRegForValue(Value *V);
virtual ~FastISel();
protected:
- explicit FastISel(MachineFunction &mf);
+ FastISel(MachineFunction &mf,
+ DenseMap<const Value *, unsigned> &vm,
+ DenseMap<const BasicBlock *, MachineBasicBlock *> &bm);
/// FastEmit_r - This method is called by target-independent code
/// to request that an instruction with the given type and opcode
@@ -208,26 +214,18 @@
/// from a specified index of a superregister.
unsigned FastEmitInst_extractsubreg(unsigned Op0, uint32_t Idx);
- unsigned getRegForValue(Value *V,
- DenseMap<const Value*, unsigned> &ValueMap);
-
- void UpdateValueMap(Instruction* I, unsigned Reg,
- DenseMap<const Value*, unsigned> &ValueMap);
+ void UpdateValueMap(Instruction* I, unsigned Reg);
unsigned createResultReg(const TargetRegisterClass *RC);
private:
- bool SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
- DenseMap<const Value*, unsigned> &ValueMap);
+ bool SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode);
- bool SelectGetElementPtr(Instruction *I,
- DenseMap<const Value*, unsigned> &ValueMap);
+ bool SelectGetElementPtr(Instruction *I);
- bool SelectBitCast(Instruction *I,
- DenseMap<const Value*, unsigned> &ValueMap);
+ bool SelectBitCast(Instruction *I);
- bool SelectCast(Instruction *I, ISD::NodeType Opcode,
- DenseMap<const Value*, unsigned> &ValueMap);
+ bool SelectCast(Instruction *I, ISD::NodeType Opcode);
};
}
Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h?rev=55746&r1=55745&r2=55746&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Wed Sep 3 18:12:08 2008
@@ -21,6 +21,7 @@
#include "llvm/CodeGen/SelectionDAG.h"
namespace llvm {
+ class FastISel;
class SelectionDAGLowering;
class SDValue;
class MachineRegisterInfo;
@@ -118,6 +119,8 @@
void HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB);
+ bool HandlePHINodesInSuccessorBlocksFast(BasicBlock *LLVMBB, FastISel *F);
+
/// Pick a safe ordering for instructions for each target node in the
/// graph.
ScheduleDAG *Schedule();
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=55746&r1=55745&r2=55746&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Wed Sep 3 18:12:08 2008
@@ -27,6 +27,7 @@
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include <map>
#include <vector>
@@ -1116,7 +1117,12 @@
/// createFastISel - This method returns a target specific FastISel object,
/// or null if the target does not support "fast" ISel.
- virtual FastISel *createFastISel(MachineFunction &) { return 0; }
+ virtual FastISel *
+ createFastISel(MachineFunction &,
+ DenseMap<const Value *, unsigned> &,
+ DenseMap<const BasicBlock *, MachineBasicBlock *> &) {
+ return 0;
+ }
//===--------------------------------------------------------------------===//
// Inline Asm Support hooks
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=55746&r1=55745&r2=55746&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Wed Sep 3 18:12:08 2008
@@ -25,8 +25,7 @@
// 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 @@
/// 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 @@
/// 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
}
// 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 @@
// 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 @@
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 @@
// 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 @@
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;
+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];
- 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;
+ 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()) {
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=55746&r1=55745&r2=55746&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Wed Sep 3 18:12:08 2008
@@ -4757,9 +4757,64 @@
}
}
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;
+}
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=55746&r1=55745&r2=55746&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Sep 3 18:12:08 2008
@@ -408,8 +408,12 @@
}
// 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 @@
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 @@
// 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 @@
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 @@
// 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();
}
Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=55746&r1=55745&r2=55746&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Wed Sep 3 18:12:08 2008
@@ -30,34 +30,27 @@
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 X86SelectLoad(Instruction *I,
- DenseMap<const Value *, unsigned> &ValueMap,
- MachineBasicBlock *MBB);
+ bool X86SelectConstAddr(Value *V, unsigned &Op0);
+
+ 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 @@
/// 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 @@
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 @@
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);
}
}
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=55746&r1=55745&r2=55746&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Sep 3 18:12:08 2008
@@ -1879,8 +1879,12 @@
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);
}
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=55746&r1=55745&r2=55746&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Wed Sep 3 18:12:08 2008
@@ -470,7 +470,10 @@
/// 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 X86 {
- FastISel *createFastISel(MachineFunction &mf);
+ FastISel *createFastISel(MachineFunction &mf,
+ DenseMap<const Value *, unsigned> &,
+ DenseMap<const BasicBlock *, MachineBasicBlock *> &);
}
}
More information about the llvm-commits
mailing list