-// $Id$
-//***************************************************************************
-// File:
-// InstrScheduling.cpp
-//
-// Purpose:
-//
-// History:
-// 7/23/01 - Vikram Adve - Created
-//**************************************************************************/
-
+//===- InstrScheduling.cpp - Generic Instruction Scheduling support -------===//
+//
+// This file implements the llvm/CodeGen/InstrScheduling.h interface, along with
+// generic support routines for instruction scheduling.
+//
+//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/InstrScheduling.h"
-#include "llvm/Analysis/LiveVar/BBLiveVar.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h"
#include "llvm/CodeGen/MachineCodeForMethod.h"
+#include "llvm/Analysis/LiveVar/FunctionLiveVarInfo.h" // FIXME: Remove when modularized better
#include "llvm/Target/TargetMachine.h"
-#include "Support/CommandLine.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Instruction.h"
#include "SchedPriorities.h"
#include <ext/hash_set>
#include <algorithm>
cl::Enum<enum SchedDebugLevel_t> SchedDebugLevel("dsched", cl::NoFlags,
"enable instruction scheduling debugging information",
clEnumValN(Sched_NoDebugInfo, "n", "disable debug output"),
+ clEnumValN(Sched_Disable, "off", "disable instruction scheduling"),
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);
class InstrSchedule;
class SchedulingManager;
-class DelaySlotInfo;
//----------------------------------------------------------------------
}
inline InstrGroup* getIGroup (cycles_t c) {
- if (c >= groups.size())
+ if ((unsigned)c >= groups.size())
groups.resize(c+1);
if (groups[c] == NULL)
groups[c] = new InstrGroup(nslots);
}
inline const InstrGroup* getIGroup (cycles_t c) const {
- assert(c < groups.size());
+ assert((unsigned)c < groups.size());
return groups[c];
}
// indexed by branch node ptr
public:
- /*ctor*/ SchedulingManager (const TargetMachine& _target,
- const SchedGraph* graph,
- SchedPriorities& schedPrio);
- /*dtor*/ ~SchedulingManager () {}
+ SchedulingManager(const TargetMachine& _target, const SchedGraph* graph,
+ SchedPriorities& schedPrio);
+ ~SchedulingManager() {
+ for (std::hash_map<const SchedGraphNode*,
+ DelaySlotInfo*>::iterator I = delaySlotInfoForBranches.begin(),
+ E = delaySlotInfoForBranches.end(); I != E; ++I)
+ delete I->second;
+ }
//----------------------------------------------------------------------
// Simplify access to the machine instruction info
inline DelaySlotInfo* getDelaySlotInfoForInstr(const SchedGraphNode* bn,
bool createIfMissing=false)
{
- DelaySlotInfo* dinfo;
- std::hash_map<const SchedGraphNode*, DelaySlotInfo* >::const_iterator
+ std::hash_map<const SchedGraphNode*, DelaySlotInfo*>::const_iterator
I = delaySlotInfoForBranches.find(bn);
- if (I == delaySlotInfoForBranches.end())
- {
- if (createIfMissing)
- {
- dinfo = new DelaySlotInfo(bn,
- getInstrInfo().getNumDelaySlots(bn->getOpCode()));
- delaySlotInfoForBranches[bn] = dinfo;
- }
- else
- dinfo = NULL;
- }
- else
- dinfo = (*I).second;
-
- return dinfo;
+ if (I != delaySlotInfoForBranches.end())
+ return I->second;
+
+ if (!createIfMissing) return 0;
+
+ DelaySlotInfo *dinfo =
+ new DelaySlotInfo(bn, getInstrInfo().getNumDelaySlots(bn->getOpCode()));
+ return delaySlotInfoForBranches[bn] = dinfo;
}
private:
- /*ctor*/ SchedulingManager (); // Disable: DO NOT IMPLEMENT.
- void updateEarliestStartTimes(const SchedGraphNode* node,
- cycles_t schedTime);
+ SchedulingManager(); // DISABLED: DO NOT IMPLEMENT
+ void updateEarliestStartTimes(const SchedGraphNode* node, cycles_t schedTime);
};
// Erase all except the dummy PHI instructions from mvec, and
// pre-allocate create space for the ones we will put back in.
mvec.erase(I, mvec.end());
- mvec.reserve(mvec.size() + S.isched.getNumInstructions());
InstrSchedule::const_iterator NIend = S.isched.end();
for (InstrSchedule::const_iterator NI = S.isched.begin(); NI != NIend; ++NI)
SchedGraph *graph)
{
const MachineInstrInfo& mii = S.getInstrInfo();
- const TerminatorInst *termInstr = bb->getTerminator();
+ const Instruction *termInstr = (Instruction*)bb->getTerminator();
MachineCodeForInstruction &termMvec=MachineCodeForInstruction::get(termInstr);
vector<SchedGraphNode*> delayNodeVec;
const MachineInstr* brInstr = NULL;
- assert(termInstr->getOpcode() != Instruction::Call
- && "Call used as terminator?");
-
if (termInstr->getOpcode() != Instruction::Ret)
{
// To find instructions that need delay slots without searching the full
// are still in SSA form.
//---------------------------------------------------------------------------
+namespace {
+ class InstructionSchedulingWithSSA : public FunctionPass {
+ const TargetMachine ⌖
+ public:
+ inline InstructionSchedulingWithSSA(const TargetMachine &T) : target(T) {}
+
+ const char *getPassName() const { return "Instruction Scheduling"; }
+
+ // getAnalysisUsage - We use LiveVarInfo...
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired(FunctionLiveVarInfo::ID);
+ }
+
+ bool runOnFunction(Function *F);
+ };
+} // end anonymous namespace
+
+
bool
-ScheduleInstructionsWithSSA(Method* method,
- const TargetMachine &target)
+InstructionSchedulingWithSSA::runOnFunction(Function *M)
{
- SchedGraphSet graphSet(method, target);
+ if (SchedDebugLevel == Sched_Disable)
+ return false;
+
+ SchedGraphSet graphSet(M, target);
if (SchedDebugLevel >= Sched_PrintSchedGraphs)
{
graphSet.dump();
}
- for (SchedGraphSet::const_iterator GI=graphSet.begin();
- GI != graphSet.end(); ++GI)
+ for (SchedGraphSet::const_iterator GI=graphSet.begin(), GE=graphSet.end();
+ GI != GE; ++GI)
{
- SchedGraph* graph = GI->second;
- const vector<const BasicBlock*>& bbvec = graph->getBasicBlocks();
+ SchedGraph* graph = (*GI);
+ const vector<const BasicBlock*> &bbvec = graph->getBasicBlocks();
assert(bbvec.size() == 1 && "Cannot schedule multiple basic blocks");
const BasicBlock* bb = bbvec[0];
if (SchedDebugLevel >= Sched_PrintSchedTrace)
- cerr << "\n*** TRACE OF INSTRUCTION SCHEDULING OPERATIONS\n\n";
+ cerr << "\n*** TRACE OF INSTRUCTION SCHEDULING OPERATIONS\n\n";
- SchedPriorities schedPrio(method, graph); // expensive!
+ // expensive!
+ SchedPriorities schedPrio(M, graph,getAnalysis<FunctionLiveVarInfo>());
SchedulingManager S(target, graph, schedPrio);
-
+
ChooseInstructionsForDelaySlots(S, bb, graph); // modifies graph
- ForwardListSchedule(S); // computes schedule in S
+ ForwardListSchedule(S); // computes schedule in S
- RecordSchedule(GI->first, S); // records schedule in BB
+ RecordSchedule(bb, S); // records schedule in BB
}
if (SchedDebugLevel >= Sched_PrintMachineCode)
{
cerr << "\n*** Machine instructions after INSTRUCTION SCHEDULING\n";
- MachineCodeForMethod::get(method).dump();
+ MachineCodeForMethod::get(M).dump();
}
- return false; // no reason to fail yet
+ return false;
}
+Pass *createInstructionSchedulingWithSSAPass(const TargetMachine &tgt) {
+ return new InstructionSchedulingWithSSA(tgt);
+}