mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-16 12:24:03 +00:00
misched preparation: modularize schedule emission.
ScheduleDAG has nothing to do with how the instructions are scheduled. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152206 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -522,11 +522,6 @@ namespace llvm {
|
|||||||
void viewGraph(const Twine &Name, const Twine &Title);
|
void viewGraph(const Twine &Name, const Twine &Title);
|
||||||
void viewGraph();
|
void viewGraph();
|
||||||
|
|
||||||
/// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock
|
|
||||||
/// according to the order specified in Sequence.
|
|
||||||
///
|
|
||||||
virtual MachineBasicBlock *EmitSchedule() = 0;
|
|
||||||
|
|
||||||
virtual void dumpNode(const SUnit *SU) const = 0;
|
virtual void dumpNode(const SUnit *SU) const = 0;
|
||||||
|
|
||||||
/// getGraphNodeLabel - Return a label for an SUnit node in a visualization
|
/// getGraphNodeLabel - Return a label for an SUnit node in a visualization
|
||||||
@ -571,12 +566,6 @@ namespace llvm {
|
|||||||
/// override this as needed.
|
/// override this as needed.
|
||||||
virtual bool ForceUnitLatencies() const { return false; }
|
virtual bool ForceUnitLatencies() const { return false; }
|
||||||
|
|
||||||
/// EmitNoop - Emit a noop instruction.
|
|
||||||
///
|
|
||||||
void EmitNoop();
|
|
||||||
|
|
||||||
void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Return the MCInstrDesc of this SDNode or NULL.
|
// Return the MCInstrDesc of this SDNode or NULL.
|
||||||
const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
|
const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
|
||||||
|
@ -145,6 +145,8 @@ namespace {
|
|||||||
///
|
///
|
||||||
void Schedule();
|
void Schedule();
|
||||||
|
|
||||||
|
void EmitSchedule();
|
||||||
|
|
||||||
/// Observe - Update liveness information to account for the current
|
/// Observe - Update liveness information to account for the current
|
||||||
/// instruction, which will not be scheduled.
|
/// instruction, which will not be scheduled.
|
||||||
///
|
///
|
||||||
@ -730,3 +732,37 @@ void SchedulePostRATDList::ListScheduleTopDown() {
|
|||||||
"The number of nodes scheduled doesn't match the expected number!");
|
"The number of nodes scheduled doesn't match the expected number!");
|
||||||
#endif // NDEBUG
|
#endif // NDEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EmitSchedule - Emit the machine code in scheduled order.
|
||||||
|
void SchedulePostRATDList::EmitSchedule() {
|
||||||
|
Begin = InsertPos;
|
||||||
|
|
||||||
|
// If first instruction was a DBG_VALUE then put it back.
|
||||||
|
if (FirstDbgValue)
|
||||||
|
BB->splice(InsertPos, BB, FirstDbgValue);
|
||||||
|
|
||||||
|
// Then re-insert them according to the given schedule.
|
||||||
|
for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
|
||||||
|
if (SUnit *SU = Sequence[i])
|
||||||
|
BB->splice(InsertPos, BB, SU->getInstr());
|
||||||
|
else
|
||||||
|
// Null SUnit* is a noop.
|
||||||
|
TII->insertNoop(*BB, InsertPos);
|
||||||
|
|
||||||
|
// Update the Begin iterator, as the first instruction in the block
|
||||||
|
// may have been scheduled later.
|
||||||
|
if (i == 0)
|
||||||
|
Begin = prior(InsertPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reinsert any remaining debug_values.
|
||||||
|
for (std::vector<std::pair<MachineInstr *, MachineInstr *> >::iterator
|
||||||
|
DI = DbgValues.end(), DE = DbgValues.begin(); DI != DE; --DI) {
|
||||||
|
std::pair<MachineInstr *, MachineInstr *> P = *prior(DI);
|
||||||
|
MachineInstr *DbgValue = P.first;
|
||||||
|
MachineBasicBlock::iterator OrigPrivMI = P.second;
|
||||||
|
BB->splice(++OrigPrivMI, BB, DbgValue);
|
||||||
|
}
|
||||||
|
DbgValues.clear();
|
||||||
|
FirstDbgValue = NULL;
|
||||||
|
}
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
//===---- ScheduleDAGEmit.cpp - Emit routines for the ScheduleDAG class ---===//
|
|
||||||
//
|
|
||||||
// The LLVM Compiler Infrastructure
|
|
||||||
//
|
|
||||||
// This file is distributed under the University of Illinois Open Source
|
|
||||||
// License. See LICENSE.TXT for details.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// This implements the Emit routines for the ScheduleDAG class, which creates
|
|
||||||
// MachineInstrs according to the computed schedule.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#define DEBUG_TYPE "pre-RA-sched"
|
|
||||||
#include "llvm/CodeGen/ScheduleDAG.h"
|
|
||||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
||||||
#include "llvm/Target/TargetData.h"
|
|
||||||
#include "llvm/Target/TargetMachine.h"
|
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
|
||||||
#include "llvm/Target/TargetLowering.h"
|
|
||||||
#include "llvm/ADT/Statistic.h"
|
|
||||||
#include "llvm/Support/CommandLine.h"
|
|
||||||
#include "llvm/Support/Debug.h"
|
|
||||||
#include "llvm/Support/MathExtras.h"
|
|
||||||
using namespace llvm;
|
|
||||||
|
|
||||||
void ScheduleDAG::EmitNoop() {
|
|
||||||
TII->insertNoop(*BB, InsertPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScheduleDAG::EmitPhysRegCopy(SUnit *SU,
|
|
||||||
DenseMap<SUnit*, unsigned> &VRBaseMap) {
|
|
||||||
for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
|
|
||||||
I != E; ++I) {
|
|
||||||
if (I->isCtrl()) continue; // ignore chain preds
|
|
||||||
if (I->getSUnit()->CopyDstRC) {
|
|
||||||
// Copy to physical register.
|
|
||||||
DenseMap<SUnit*, unsigned>::iterator VRI = VRBaseMap.find(I->getSUnit());
|
|
||||||
assert(VRI != VRBaseMap.end() && "Node emitted out of order - late");
|
|
||||||
// Find the destination physical register.
|
|
||||||
unsigned Reg = 0;
|
|
||||||
for (SUnit::const_succ_iterator II = SU->Succs.begin(),
|
|
||||||
EE = SU->Succs.end(); II != EE; ++II) {
|
|
||||||
if (II->isCtrl()) continue; // ignore chain preds
|
|
||||||
if (II->getReg()) {
|
|
||||||
Reg = II->getReg();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BuildMI(*BB, InsertPos, DebugLoc(), TII->get(TargetOpcode::COPY), Reg)
|
|
||||||
.addReg(VRI->second);
|
|
||||||
} else {
|
|
||||||
// Copy from physical register.
|
|
||||||
assert(I->getReg() && "Unknown physical register!");
|
|
||||||
unsigned VRBase = MRI.createVirtualRegister(SU->CopyDstRC);
|
|
||||||
bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second;
|
|
||||||
(void)isNew; // Silence compiler warning.
|
|
||||||
assert(isNew && "Node emitted out of order - early");
|
|
||||||
BuildMI(*BB, InsertPos, DebugLoc(), TII->get(TargetOpcode::COPY), VRBase)
|
|
||||||
.addReg(I->getReg());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
@ -813,38 +813,3 @@ std::string ScheduleDAGInstrs::getGraphNodeLabel(const SUnit *SU) const {
|
|||||||
std::string ScheduleDAGInstrs::getDAGName() const {
|
std::string ScheduleDAGInstrs::getDAGName() const {
|
||||||
return "dag." + BB->getFullName();
|
return "dag." + BB->getFullName();
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmitSchedule - Emit the machine code in scheduled order.
|
|
||||||
MachineBasicBlock *ScheduleDAGInstrs::EmitSchedule() {
|
|
||||||
Begin = InsertPos;
|
|
||||||
|
|
||||||
// If first instruction was a DBG_VALUE then put it back.
|
|
||||||
if (FirstDbgValue)
|
|
||||||
BB->splice(InsertPos, BB, FirstDbgValue);
|
|
||||||
|
|
||||||
// Then re-insert them according to the given schedule.
|
|
||||||
for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
|
|
||||||
if (SUnit *SU = Sequence[i])
|
|
||||||
BB->splice(InsertPos, BB, SU->getInstr());
|
|
||||||
else
|
|
||||||
// Null SUnit* is a noop.
|
|
||||||
EmitNoop();
|
|
||||||
|
|
||||||
// Update the Begin iterator, as the first instruction in the block
|
|
||||||
// may have been scheduled later.
|
|
||||||
if (i == 0)
|
|
||||||
Begin = prior(InsertPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reinsert any remaining debug_values.
|
|
||||||
for (std::vector<std::pair<MachineInstr *, MachineInstr *> >::iterator
|
|
||||||
DI = DbgValues.end(), DE = DbgValues.begin(); DI != DE; --DI) {
|
|
||||||
std::pair<MachineInstr *, MachineInstr *> P = *prior(DI);
|
|
||||||
MachineInstr *DbgValue = P.first;
|
|
||||||
MachineBasicBlock::iterator OrigPrivMI = P.second;
|
|
||||||
BB->splice(++OrigPrivMI, BB, DbgValue);
|
|
||||||
}
|
|
||||||
DbgValues.clear();
|
|
||||||
FirstDbgValue = NULL;
|
|
||||||
return BB;
|
|
||||||
}
|
|
||||||
|
@ -266,8 +266,6 @@ namespace llvm {
|
|||||||
virtual void ComputeOperandLatency(SUnit *Def, SUnit *Use,
|
virtual void ComputeOperandLatency(SUnit *Def, SUnit *Use,
|
||||||
SDep& dep) const;
|
SDep& dep) const;
|
||||||
|
|
||||||
virtual MachineBasicBlock *EmitSchedule();
|
|
||||||
|
|
||||||
/// StartBlock - Prepare to perform scheduling in the given block.
|
/// StartBlock - Prepare to perform scheduling in the given block.
|
||||||
///
|
///
|
||||||
virtual void StartBlock(MachineBasicBlock *BB);
|
virtual void StartBlock(MachineBasicBlock *BB);
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
#include "ScheduleDAGSDNodes.h"
|
#include "ScheduleDAGSDNodes.h"
|
||||||
#include "InstrEmitter.h"
|
#include "InstrEmitter.h"
|
||||||
#include "llvm/CodeGen/SelectionDAG.h"
|
#include "llvm/CodeGen/SelectionDAG.h"
|
||||||
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/MC/MCInstrItineraries.h"
|
#include "llvm/MC/MCInstrItineraries.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
@ -710,8 +712,46 @@ static void ProcessSourceNode(SDNode *N, SelectionDAG *DAG,
|
|||||||
ProcessSDDbgValues(N, DAG, Emitter, Orders, VRBaseMap, Order);
|
ProcessSDDbgValues(N, DAG, Emitter, Orders, VRBaseMap, Order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScheduleDAGSDNodes::
|
||||||
|
EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap,
|
||||||
|
MachineBasicBlock::iterator InsertPos) {
|
||||||
|
for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
|
||||||
|
I != E; ++I) {
|
||||||
|
if (I->isCtrl()) continue; // ignore chain preds
|
||||||
|
if (I->getSUnit()->CopyDstRC) {
|
||||||
|
// Copy to physical register.
|
||||||
|
DenseMap<SUnit*, unsigned>::iterator VRI = VRBaseMap.find(I->getSUnit());
|
||||||
|
assert(VRI != VRBaseMap.end() && "Node emitted out of order - late");
|
||||||
|
// Find the destination physical register.
|
||||||
|
unsigned Reg = 0;
|
||||||
|
for (SUnit::const_succ_iterator II = SU->Succs.begin(),
|
||||||
|
EE = SU->Succs.end(); II != EE; ++II) {
|
||||||
|
if (II->isCtrl()) continue; // ignore chain preds
|
||||||
|
if (II->getReg()) {
|
||||||
|
Reg = II->getReg();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BuildMI(*BB, InsertPos, DebugLoc(), TII->get(TargetOpcode::COPY), Reg)
|
||||||
|
.addReg(VRI->second);
|
||||||
|
} else {
|
||||||
|
// Copy from physical register.
|
||||||
|
assert(I->getReg() && "Unknown physical register!");
|
||||||
|
unsigned VRBase = MRI.createVirtualRegister(SU->CopyDstRC);
|
||||||
|
bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second;
|
||||||
|
(void)isNew; // Silence compiler warning.
|
||||||
|
assert(isNew && "Node emitted out of order - early");
|
||||||
|
BuildMI(*BB, InsertPos, DebugLoc(), TII->get(TargetOpcode::COPY), VRBase)
|
||||||
|
.addReg(I->getReg());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// EmitSchedule - Emit the machine code in scheduled order.
|
/// EmitSchedule - Emit the machine code in scheduled order. Return the new
|
||||||
|
/// InsertPos and MachineBasicBlock that contains this insertion
|
||||||
|
/// point. ScheduleDAGSDNodes holds a BB pointer for convenience, but this does
|
||||||
|
/// not necessarily refer to returned BB. The emitter may split blocks.
|
||||||
MachineBasicBlock *ScheduleDAGSDNodes::EmitSchedule() {
|
MachineBasicBlock *ScheduleDAGSDNodes::EmitSchedule() {
|
||||||
InstrEmitter Emitter(BB, InsertPos);
|
InstrEmitter Emitter(BB, InsertPos);
|
||||||
DenseMap<SDValue, unsigned> VRBaseMap;
|
DenseMap<SDValue, unsigned> VRBaseMap;
|
||||||
@ -735,7 +775,7 @@ MachineBasicBlock *ScheduleDAGSDNodes::EmitSchedule() {
|
|||||||
SUnit *SU = Sequence[i];
|
SUnit *SU = Sequence[i];
|
||||||
if (!SU) {
|
if (!SU) {
|
||||||
// Null SUnit* is a noop.
|
// Null SUnit* is a noop.
|
||||||
EmitNoop();
|
TII->insertNoop(*Emitter.getBlock(), InsertPos);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,7 +783,7 @@ MachineBasicBlock *ScheduleDAGSDNodes::EmitSchedule() {
|
|||||||
// SDNode and any glued SDNodes and append them to the block.
|
// SDNode and any glued SDNodes and append them to the block.
|
||||||
if (!SU->getNode()) {
|
if (!SU->getNode()) {
|
||||||
// Emit a copy.
|
// Emit a copy.
|
||||||
EmitPhysRegCopy(SU, CopyVRBaseMap);
|
EmitPhysRegCopy(SU, CopyVRBaseMap, InsertPos);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,11 @@ namespace llvm {
|
|||||||
/// consistent with the Sequence of scheduled instructions.
|
/// consistent with the Sequence of scheduled instructions.
|
||||||
void VerifyScheduledSequence(bool isBottomUp);
|
void VerifyScheduledSequence(bool isBottomUp);
|
||||||
|
|
||||||
|
/// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock
|
||||||
|
/// according to the order specified in Sequence.
|
||||||
|
///
|
||||||
|
MachineBasicBlock *EmitSchedule(MachineBasicBlock::iterator &InsertPos);
|
||||||
|
|
||||||
virtual void dumpNode(const SUnit *SU) const;
|
virtual void dumpNode(const SUnit *SU) const;
|
||||||
|
|
||||||
void dumpSchedule() const;
|
void dumpSchedule() const;
|
||||||
@ -168,6 +173,9 @@ namespace llvm {
|
|||||||
/// BuildSchedUnits, AddSchedEdges - Helper functions for BuildSchedGraph.
|
/// BuildSchedUnits, AddSchedEdges - Helper functions for BuildSchedGraph.
|
||||||
void BuildSchedUnits();
|
void BuildSchedUnits();
|
||||||
void AddSchedEdges();
|
void AddSchedEdges();
|
||||||
|
|
||||||
|
void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap,
|
||||||
|
MachineBasicBlock::iterator InsertPos);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user