#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h"
#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/FunctionLiveVarInfo.h"
+#include "../../Target/SparcV9/LiveVar/FunctionLiveVarInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/BasicBlock.h"
#include "Support/CommandLine.h"
#include <algorithm>
+#include <iostream>
namespace llvm {
clEnumValN(Sched_PrintMachineCode, "y", "print machine code after scheduling"),
clEnumValN(Sched_PrintSchedTrace, "t", "print trace of scheduling actions"),
clEnumValN(Sched_PrintSchedGraphs, "g", "print scheduling graphs"),
- 0));
+ clEnumValEnd));
//************************* Internal Data Types *****************************/
unsigned int slotNum,
cycles_t cycle) {
InstrGroup* igroup = this->getIGroup(cycle);
- assert((*igroup)[slotNum] == NULL && "Slot already filled?");
+ if (!((*igroup)[slotNum] == NULL)) {
+ std::cerr << "Slot already filled?\n";
+ abort();
+ }
igroup->addInstr(node, slotNum);
assert(node->getNodeId() < startTime.size());
startTime[node->getNodeId()] = cycle;
SchedulingManager::SchedulingManager(const TargetMachine& target,
const SchedGraph* graph,
SchedPriorities& _schedPrio)
- : nslots(target.getSchedInfo().getMaxNumIssueTotal()),
- schedInfo(target.getSchedInfo()),
+ : nslots(target.getSchedInfo()->getMaxNumIssueTotal()),
+ schedInfo(*target.getSchedInfo()),
schedPrio(_schedPrio),
isched(nslots, graph->getNumNodes()),
totalInstrCount(graph->getNumNodes() - 2),
nextEarliestIssueTime(0),
choicesForSlot(nslots),
- numInClass(target.getSchedInfo().getNumSchedClasses(), 0), // set all to 0
- nextEarliestStartTime(target.getInstrInfo().getNumRealOpCodes(),
+ numInClass(target.getSchedInfo()->getNumSchedClasses(), 0), // set all to 0
+ nextEarliestStartTime(target.getInstrInfo()->getNumOpcodes(),
(cycles_t) 0) // set all to 0
{
updateTime(0);
{
const TargetInstrInfo& mii = S.schedInfo.getInstrInfo();
-#ifndef NDEBUG
// Lets make sure we didn't lose any instructions, except possibly
// some NOPs from delay slots. Also, PHIs are not included in the schedule.
unsigned numInstr = 0;
for (MachineBasicBlock::iterator I=MBB.begin(); I != MBB.end(); ++I)
- if (! mii.isNop((*I)->getOpcode()) &&
- ! mii.isDummyPhiInstr((*I)->getOpcode()))
+ if (! mii.isNop(I->getOpcode()) &&
+ ! mii.isDummyPhiInstr(I->getOpcode()))
++numInstr;
assert(S.isched.getNumInstructions() >= numInstr &&
"Lost some non-NOP instructions during scheduling!");
-#endif
if (S.isched.getNumInstructions() == 0)
return; // empty basic block!
// First find the dummy instructions at the start of the basic block
MachineBasicBlock::iterator I = MBB.begin();
for ( ; I != MBB.end(); ++I)
- if (! mii.isDummyPhiInstr((*I)->getOpcode()))
+ if (! mii.isDummyPhiInstr(I->getOpcode()))
break;
- // Erase all except the dummy PHI instructions from MBB, and
+ // Remove all except the dummy PHI instructions from MBB, and
// pre-allocate create space for the ones we will put back in.
- MBB.erase(I, MBB.end());
+ while (I != MBB.end())
+ MBB.remove(I++);
InstrSchedule::const_iterator NIend = S.isched.end();
for (InstrSchedule::const_iterator NI = S.isched.begin(); NI != NIend; ++NI)
&& (*EI)->getDepType() == SchedGraphEdge::CtrlDep)
return false;
- // for now, don't put an instruction that does not have operand
- // interlocks in the delay slot of a branch
- if (! S.getInstrInfo().hasOperandInterlock(node->getOpcode()))
- return false;
-
// Finally, if the instruction precedes the branch, we make sure the
// instruction can be reordered relative to the branch. We simply check
// if the instr. has only 1 outgoing edge, viz., a CD edge to the branch.
//
unsigned int firstDelaySlotIdx = node->getOrigIndexInBB() + 1;
MachineBasicBlock& MBB = node->getMachineBasicBlock();
- assert(MBB[firstDelaySlotIdx - 1] == brInstr &&
- "Incorrect instr. index in basic block for brInstr");
+ MachineBasicBlock::iterator MBBI = MBB.begin();
+ std::advance(MBBI, firstDelaySlotIdx - 1);
+ if (!(&*MBBI++ == brInstr)) {
+ std::cerr << "Incorrect instr. index in basic block for brInstr";
+ abort();
+ }
// First find all useful instructions already in the delay slots
// and USE THEM. We'll throw away the unused alternatives below
//
- for (unsigned i=firstDelaySlotIdx; i < firstDelaySlotIdx + ndelays; ++i)
- if (! mii.isNop(MBB[i]->getOpcode()))
+ MachineBasicBlock::iterator Tmp = MBBI;
+ for (unsigned i = 0; i != ndelays; ++i, ++MBBI)
+ if (!mii.isNop(MBBI->getOpcode()))
sdelayNodeVec.insert(sdelayNodeVec.begin(),
- graph->getGraphNodeForInstr(MBB[i]));
-
+ graph->getGraphNodeForInstr(MBBI));
+ MBBI = Tmp;
+
// Then find the NOPs and keep only as many as are needed.
// Put the rest in nopNodeVec to be deleted.
- for (unsigned i=firstDelaySlotIdx; i < firstDelaySlotIdx + ndelays; ++i)
- if (mii.isNop(MBB[i]->getOpcode()))
+ for (unsigned i=firstDelaySlotIdx; i < firstDelaySlotIdx+ndelays; ++i, ++MBBI)
+ if (mii.isNop(MBBI->getOpcode()))
if (sdelayNodeVec.size() < ndelays)
- sdelayNodeVec.push_back(graph->getGraphNodeForInstr(MBB[i]));
+ sdelayNodeVec.push_back(graph->getGraphNodeForInstr(MBBI));
else {
- nopNodeVec.push_back(graph->getGraphNodeForInstr(MBB[i]));
+ nopNodeVec.push_back(graph->getGraphNodeForInstr(MBBI));
//remove the MI from the Machine Code For Instruction
const TerminatorInst *TI = MBB.getBasicBlock()->getTerminator();
for(MachineCodeForInstruction::iterator mciI=llvmMvec.begin(),
mciE=llvmMvec.end(); mciI!=mciE; ++mciI){
- if (*mciI==MBB[i])
+ if (*mciI == MBBI)
llvmMvec.erase(mciI);
}
}
// brInstr will be NULL so this will handle the branch instrs. as well.
//
delayNodeVec.clear();
- for (unsigned i=0; i < MBB.size(); ++i)
- if (MBB[i] != brInstr &&
- mii.getNumDelaySlots(MBB[i]->getOpcode()) > 0)
- {
- SchedGraphNode* node = graph->getGraphNodeForInstr(MBB[i]);
+ for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
+ if (I != brInstr && mii.getNumDelaySlots(I->getOpcode()) > 0) {
+ SchedGraphNode* node = graph->getGraphNodeForInstr(I);
ReplaceNopsWithUsefulInstr(S, node, delayNodeVec, graph);
}
}
const SchedGraphNode* dnode = delayNodeVec[i];
if ( ! S.isScheduled(dnode)
&& S.schedInfo.instrCanUseSlot(dnode->getOpcode(), nextSlot)
- && instrIsFeasible(S, dnode->getOpcode()))
- {
- assert(S.getInstrInfo().hasOperandInterlock(dnode->getOpcode())
- && "Instructions without interlocks not yet supported "
- "when filling branch delay slots");
+ && instrIsFeasible(S, dnode->getOpcode())) {
S.scheduleInstr(dnode, nextSlot, nextTime);
break;
}