mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-10 20:33:15 +00:00
Move HandlePHINodesInSuccessorBlocks functions out of SelectionDAGISel
and into SelectionDAGBuilder and FastISel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102123 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f720a4edb0
commit
f81eca0ab9
@ -28,6 +28,7 @@ class Instruction;
|
||||
class MachineBasicBlock;
|
||||
class MachineConstantPool;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
class MachineFrameInfo;
|
||||
class MachineRegisterInfo;
|
||||
class TargetData;
|
||||
@ -46,6 +47,7 @@ protected:
|
||||
DenseMap<const Value *, unsigned> &ValueMap;
|
||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap;
|
||||
DenseMap<const AllocaInst *, int> &StaticAllocaMap;
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate;
|
||||
#ifndef NDEBUG
|
||||
SmallSet<const Instruction *, 8> &CatchInfoLost;
|
||||
#endif
|
||||
@ -105,13 +107,22 @@ public:
|
||||
/// index value.
|
||||
unsigned getRegForGEPIndex(const Value *V);
|
||||
|
||||
/// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks.
|
||||
/// Emit code to ensure constants are copied into registers when needed.
|
||||
/// Remember the virtual registers that need to be added to the Machine PHI
|
||||
/// nodes as input. We cannot just directly add them, because expansion
|
||||
/// might result in multiple MBB's for one BB. As such, the start of the
|
||||
/// BB might correspond to a different MBB than the end.
|
||||
bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
|
||||
|
||||
virtual ~FastISel();
|
||||
|
||||
protected:
|
||||
FastISel(MachineFunction &mf,
|
||||
DenseMap<const Value *, unsigned> &vm,
|
||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
|
||||
DenseMap<const AllocaInst *, int> &am
|
||||
DenseMap<const AllocaInst *, int> &am,
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate
|
||||
#ifndef NDEBUG
|
||||
, SmallSet<const Instruction *, 8> &cil
|
||||
#endif
|
||||
|
@ -295,11 +295,6 @@ private:
|
||||
void ShrinkDemandedOps();
|
||||
void ComputeLiveOutVRegInfo();
|
||||
|
||||
void HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
|
||||
|
||||
bool HandlePHINodesInSuccessorBlocksFast(const BasicBlock *LLVMBB,
|
||||
FastISel *F);
|
||||
|
||||
/// Create the scheduler. If a specific scheduler was specified
|
||||
/// via the SchedulerRegistry, use it, otherwise select the
|
||||
/// one preferred by the target.
|
||||
|
@ -1302,7 +1302,8 @@ public:
|
||||
createFastISel(MachineFunction &,
|
||||
DenseMap<const Value *, unsigned> &,
|
||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &,
|
||||
DenseMap<const AllocaInst *, int> &
|
||||
DenseMap<const AllocaInst *, int> &,
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > &
|
||||
#ifndef NDEBUG
|
||||
, SmallSet<const Instruction *, 8> &CatchInfoLost
|
||||
#endif
|
||||
|
@ -744,7 +744,8 @@ FastISel::SelectOperator(const User *I, unsigned Opcode) {
|
||||
FastISel::FastISel(MachineFunction &mf,
|
||||
DenseMap<const Value *, unsigned> &vm,
|
||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
|
||||
DenseMap<const AllocaInst *, int> &am
|
||||
DenseMap<const AllocaInst *, int> &am,
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > &pn
|
||||
#ifndef NDEBUG
|
||||
, SmallSet<const Instruction *, 8> &cil
|
||||
#endif
|
||||
@ -753,6 +754,7 @@ FastISel::FastISel(MachineFunction &mf,
|
||||
ValueMap(vm),
|
||||
MBBMap(bm),
|
||||
StaticAllocaMap(am),
|
||||
PHINodesToUpdate(pn),
|
||||
#ifndef NDEBUG
|
||||
CatchInfoLost(cil),
|
||||
#endif
|
||||
@ -1020,3 +1022,67 @@ unsigned FastISel::FastEmitInst_extractsubreg(MVT RetVT,
|
||||
unsigned FastISel::FastEmitZExtFromI1(MVT VT, unsigned Op) {
|
||||
return FastEmit_ri(VT, VT, ISD::AND, Op, 1);
|
||||
}
|
||||
|
||||
/// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks.
|
||||
/// Emit code to ensure constants are copied into registers when needed.
|
||||
/// Remember the virtual registers that need to be added to the Machine PHI
|
||||
/// nodes as input. We cannot just directly add them, because expansion
|
||||
/// might result in multiple MBB's for one BB. As such, the start of the
|
||||
/// BB might correspond to a different MBB than the end.
|
||||
bool FastISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
|
||||
const TerminatorInst *TI = LLVMBB->getTerminator();
|
||||
|
||||
SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled;
|
||||
unsigned OrigNumPHINodesToUpdate = 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) {
|
||||
const BasicBlock *SuccBB = TI->getSuccessor(succ);
|
||||
if (!isa<PHINode>(SuccBB->begin())) continue;
|
||||
MachineBasicBlock *SuccMBB = 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();
|
||||
|
||||
// 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::const_iterator I = SuccBB->begin();
|
||||
const PHINode *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.
|
||||
EVT VT = TLI.getValueType(PN->getType(), /*AllowUnknown=*/true);
|
||||
if (VT == MVT::Other || !TLI.isTypeLegal(VT)) {
|
||||
// Promote MVT::i1.
|
||||
if (VT == MVT::i1)
|
||||
VT = TLI.getTypeToTransformTo(LLVMBB->getContext(), VT);
|
||||
else {
|
||||
PHINodesToUpdate.resize(OrigNumPHINodesToUpdate);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB);
|
||||
|
||||
unsigned Reg = getRegForValue(PHIOp);
|
||||
if (Reg == 0) {
|
||||
PHINodesToUpdate.resize(OrigNumPHINodesToUpdate);
|
||||
return false;
|
||||
}
|
||||
PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -5801,7 +5801,7 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) {
|
||||
// or one register.
|
||||
ISD::ArgFlagsTy Flags;
|
||||
Flags.setSRet();
|
||||
EVT RegisterVT = TLI.getRegisterType(*CurDAG->getContext(), ValueVTs[0]);
|
||||
EVT RegisterVT = TLI.getRegisterType(*DAG.getContext(), ValueVTs[0]);
|
||||
ISD::InputArg RetArg(Flags, RegisterVT, true);
|
||||
Ins.push_back(RetArg);
|
||||
}
|
||||
@ -5964,7 +5964,7 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) {
|
||||
/// the end.
|
||||
///
|
||||
void
|
||||
SelectionDAGISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
|
||||
SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
|
||||
const TerminatorInst *TI = LLVMBB->getTerminator();
|
||||
|
||||
SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled;
|
||||
@ -5974,7 +5974,7 @@ SelectionDAGISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
|
||||
for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) {
|
||||
const BasicBlock *SuccBB = TI->getSuccessor(succ);
|
||||
if (!isa<PHINode>(SuccBB->begin())) continue;
|
||||
MachineBasicBlock *SuccMBB = FuncInfo->MBBMap[SuccBB];
|
||||
MachineBasicBlock *SuccMBB = FuncInfo.MBBMap[SuccBB];
|
||||
|
||||
// If this terminator has multiple identical successors (common for
|
||||
// switches), only handle each succ once.
|
||||
@ -5994,20 +5994,20 @@ SelectionDAGISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
|
||||
const Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB);
|
||||
|
||||
if (const Constant *C = dyn_cast<Constant>(PHIOp)) {
|
||||
unsigned &RegOut = SDB->ConstantsOut[C];
|
||||
unsigned &RegOut = ConstantsOut[C];
|
||||
if (RegOut == 0) {
|
||||
RegOut = FuncInfo->CreateRegForValue(C);
|
||||
SDB->CopyValueToVirtualRegister(C, RegOut);
|
||||
RegOut = FuncInfo.CreateRegForValue(C);
|
||||
CopyValueToVirtualRegister(C, RegOut);
|
||||
}
|
||||
Reg = RegOut;
|
||||
} else {
|
||||
Reg = FuncInfo->ValueMap[PHIOp];
|
||||
Reg = FuncInfo.ValueMap[PHIOp];
|
||||
if (Reg == 0) {
|
||||
assert(isa<AllocaInst>(PHIOp) &&
|
||||
FuncInfo->StaticAllocaMap.count(cast<AllocaInst>(PHIOp)) &&
|
||||
FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(PHIOp)) &&
|
||||
"Didn't codegen value into a register!??");
|
||||
Reg = FuncInfo->CreateRegForValue(PHIOp);
|
||||
SDB->CopyValueToVirtualRegister(PHIOp, Reg);
|
||||
Reg = FuncInfo.CreateRegForValue(PHIOp);
|
||||
CopyValueToVirtualRegister(PHIOp, Reg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6017,76 +6017,12 @@ SelectionDAGISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
|
||||
ComputeValueVTs(TLI, PN->getType(), ValueVTs);
|
||||
for (unsigned vti = 0, vte = ValueVTs.size(); vti != vte; ++vti) {
|
||||
EVT VT = ValueVTs[vti];
|
||||
unsigned NumRegisters = TLI.getNumRegisters(*CurDAG->getContext(), VT);
|
||||
unsigned NumRegisters = TLI.getNumRegisters(*DAG.getContext(), VT);
|
||||
for (unsigned i = 0, e = NumRegisters; i != e; ++i)
|
||||
FuncInfo->PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg+i));
|
||||
FuncInfo.PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg+i));
|
||||
Reg += NumRegisters;
|
||||
}
|
||||
}
|
||||
}
|
||||
SDB->ConstantsOut.clear();
|
||||
}
|
||||
|
||||
/// 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(const BasicBlock *LLVMBB,
|
||||
FastISel *F) {
|
||||
const TerminatorInst *TI = LLVMBB->getTerminator();
|
||||
|
||||
SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled;
|
||||
unsigned OrigNumPHINodesToUpdate = FuncInfo->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) {
|
||||
const 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();
|
||||
|
||||
// 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::const_iterator I = SuccBB->begin();
|
||||
const PHINode *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.
|
||||
EVT VT = TLI.getValueType(PN->getType(), /*AllowUnknown=*/true);
|
||||
if (VT == MVT::Other || !TLI.isTypeLegal(VT)) {
|
||||
// Promote MVT::i1.
|
||||
if (VT == MVT::i1)
|
||||
VT = TLI.getTypeToTransformTo(*CurDAG->getContext(), VT);
|
||||
else {
|
||||
FuncInfo->PHINodesToUpdate.resize(OrigNumPHINodesToUpdate);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB);
|
||||
|
||||
unsigned Reg = F->getRegForValue(PHIOp);
|
||||
if (Reg == 0) {
|
||||
FuncInfo->PHINodesToUpdate.resize(OrigNumPHINodesToUpdate);
|
||||
return false;
|
||||
}
|
||||
FuncInfo->PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
ConstantsOut.clear();
|
||||
}
|
||||
|
@ -369,6 +369,8 @@ public:
|
||||
void LowerCallTo(ImmutableCallSite CS, SDValue Callee, bool IsTailCall,
|
||||
MachineBasicBlock *LandingPad = NULL);
|
||||
|
||||
void HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
|
||||
|
||||
private:
|
||||
// Terminator instructions.
|
||||
void visitRet(const ReturnInst &I);
|
||||
|
@ -241,7 +241,7 @@ SelectionDAGISel::SelectBasicBlock(MachineBasicBlock *BB,
|
||||
if (!SDB->HasTailCall) {
|
||||
// Handle PHI nodes in successor blocks.
|
||||
if (End == LLVMBB->end()) {
|
||||
HandlePHINodesInSuccessorBlocks(LLVMBB);
|
||||
SDB->HandlePHINodesInSuccessorBlocks(LLVMBB);
|
||||
|
||||
// Lower the terminator after the copies are emitted.
|
||||
SDB->visit(*LLVMBB->getTerminator());
|
||||
@ -711,7 +711,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
|
||||
FastISel *FastIS = 0;
|
||||
if (EnableFastISel)
|
||||
FastIS = TLI.createFastISel(*MF, FuncInfo->ValueMap, FuncInfo->MBBMap,
|
||||
FuncInfo->StaticAllocaMap
|
||||
FuncInfo->StaticAllocaMap,
|
||||
FuncInfo->PHINodesToUpdate
|
||||
#ifndef NDEBUG
|
||||
, FuncInfo->CatchInfoLost
|
||||
#endif
|
||||
@ -765,7 +766,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
|
||||
// Just before the terminator instruction, insert instructions to
|
||||
// feed PHI nodes in successor blocks.
|
||||
if (isa<TerminatorInst>(BI))
|
||||
if (!HandlePHINodesInSuccessorBlocksFast(LLVMBB, FastIS)) {
|
||||
if (!FastIS->HandlePHINodesInSuccessorBlocks(LLVMBB)) {
|
||||
++NumFastIselFailures;
|
||||
if (EnableFastISelVerbose || EnableFastISelAbort) {
|
||||
dbgs() << "FastISel miss: ";
|
||||
|
@ -55,12 +55,13 @@ public:
|
||||
explicit X86FastISel(MachineFunction &mf,
|
||||
DenseMap<const Value *, unsigned> &vm,
|
||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
|
||||
DenseMap<const AllocaInst *, int> &am
|
||||
DenseMap<const AllocaInst *, int> &am,
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > &pn
|
||||
#ifndef NDEBUG
|
||||
, SmallSet<const Instruction *, 8> &cil
|
||||
#endif
|
||||
)
|
||||
: FastISel(mf, vm, bm, am
|
||||
: FastISel(mf, vm, bm, am, pn
|
||||
#ifndef NDEBUG
|
||||
, cil
|
||||
#endif
|
||||
@ -1754,12 +1755,13 @@ namespace llvm {
|
||||
llvm::FastISel *X86::createFastISel(MachineFunction &mf,
|
||||
DenseMap<const Value *, unsigned> &vm,
|
||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
|
||||
DenseMap<const AllocaInst *, int> &am
|
||||
DenseMap<const AllocaInst *, int> &am,
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > &pn
|
||||
#ifndef NDEBUG
|
||||
, SmallSet<const Instruction *, 8> &cil
|
||||
#endif
|
||||
) {
|
||||
return new X86FastISel(mf, vm, bm, am
|
||||
return new X86FastISel(mf, vm, bm, am, pn
|
||||
#ifndef NDEBUG
|
||||
, cil
|
||||
#endif
|
||||
|
@ -2419,12 +2419,13 @@ FastISel *
|
||||
X86TargetLowering::createFastISel(MachineFunction &mf,
|
||||
DenseMap<const Value *, unsigned> &vm,
|
||||
DenseMap<const BasicBlock*, MachineBasicBlock*> &bm,
|
||||
DenseMap<const AllocaInst *, int> &am
|
||||
DenseMap<const AllocaInst *, int> &am,
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > &pn
|
||||
#ifndef NDEBUG
|
||||
, SmallSet<const Instruction *, 8> &cil
|
||||
#endif
|
||||
) const {
|
||||
return X86::createFastISel(mf, vm, bm, am
|
||||
return X86::createFastISel(mf, vm, bm, am, pn
|
||||
#ifndef NDEBUG
|
||||
, cil
|
||||
#endif
|
||||
|
@ -580,7 +580,8 @@ namespace llvm {
|
||||
createFastISel(MachineFunction &mf,
|
||||
DenseMap<const Value *, unsigned> &,
|
||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &,
|
||||
DenseMap<const AllocaInst *, int> &
|
||||
DenseMap<const AllocaInst *, int> &,
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > &
|
||||
#ifndef NDEBUG
|
||||
, SmallSet<const Instruction *, 8> &
|
||||
#endif
|
||||
@ -826,7 +827,8 @@ namespace llvm {
|
||||
FastISel *createFastISel(MachineFunction &mf,
|
||||
DenseMap<const Value *, unsigned> &,
|
||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &,
|
||||
DenseMap<const AllocaInst *, int> &
|
||||
DenseMap<const AllocaInst *, int> &,
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > &
|
||||
#ifndef NDEBUG
|
||||
, SmallSet<const Instruction*, 8> &
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user