blob: b2a2a9c9b8c59390a3e6106bedd2fd70dcbed7bf [file] [log] [blame]
//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Evan Cheng and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the ScheduleDAG class, which is used as the common
// base class for SelectionDAG-based instruction scheduler.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
#define LLVM_CODEGEN_SCHEDULEDAG_H
#include "llvm/CodeGen/SelectionDAG.h"
namespace llvm {
struct InstrStage;
class MachineConstantPool;
class MachineDebugInfo;
class MachineInstr;
class MRegisterInfo;
class SelectionDAG;
class SSARegMap;
class TargetInstrInfo;
class TargetInstrDescriptor;
class TargetMachine;
/// HazardRecognizer - This determines whether or not an instruction can be
/// issued this cycle, and whether or not a noop needs to be inserted to handle
/// the hazard.
class HazardRecognizer {
public:
virtual ~HazardRecognizer();
enum HazardType {
NoHazard, // This instruction can be emitted at this cycle.
Hazard, // This instruction can't be emitted at this cycle.
NoopHazard, // This instruction can't be emitted, and needs noops.
};
/// getHazardType - Return the hazard type of emitting this node. There are
/// three possible results. Either:
/// * NoHazard: it is legal to issue this instruction on this cycle.
/// * Hazard: issuing this instruction would stall the machine. If some
/// other instruction is available, issue it first.
/// * NoopHazard: issuing this instruction would break the program. If
/// some other instruction can be issued, do so, otherwise issue a noop.
virtual HazardType getHazardType(SDNode *Node) {
return NoHazard;
}
/// EmitInstruction - This callback is invoked when an instruction is
/// emitted, to advance the hazard state.
virtual void EmitInstruction(SDNode *Node) {
}
/// AdvanceCycle - This callback is invoked when no instructions can be
/// issued on this cycle without a hazard. This should increment the
/// internal state of the hazard recognizer so that previously "Hazard"
/// instructions will now not be hazards.
virtual void AdvanceCycle() {
}
/// EmitNoop - This callback is invoked when a noop was added to the
/// instruction stream.
virtual void EmitNoop() {
}
};
class ScheduleDAG {
public:
SelectionDAG &DAG; // DAG of the current basic block
MachineBasicBlock *BB; // Current basic block
const TargetMachine &TM; // Target processor
const TargetInstrInfo *TII; // Target instruction information
const MRegisterInfo *MRI; // Target processor register info
SSARegMap *RegMap; // Virtual/real register map
MachineConstantPool *ConstPool; // Target constant pool
ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb,
const TargetMachine &tm)
: DAG(dag), BB(bb), TM(tm) {}
virtual ~ScheduleDAG() {}
/// Run - perform scheduling.
///
MachineBasicBlock *Run();
/// isPassiveNode - Return true if the node is a non-scheduled leaf.
///
static bool isPassiveNode(SDNode *Node) {
if (isa<ConstantSDNode>(Node)) return true;
if (isa<RegisterSDNode>(Node)) return true;
if (isa<GlobalAddressSDNode>(Node)) return true;
if (isa<BasicBlockSDNode>(Node)) return true;
if (isa<FrameIndexSDNode>(Node)) return true;
if (isa<ConstantPoolSDNode>(Node)) return true;
if (isa<ExternalSymbolSDNode>(Node)) return true;
return false;
}
/// EmitNode - Generate machine code for an node and needed dependencies.
/// VRBaseMap contains, for each already emitted node, the first virtual
/// register number for the results of the node.
///
void EmitNode(SDNode *Node, std::map<SDNode*, unsigned> &VRBaseMap);
/// EmitNoop - Emit a noop instruction.
///
void EmitNoop();
/// Schedule - Order nodes according to selected style.
///
virtual void Schedule() {}
private:
void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
const TargetInstrDescriptor *II,
std::map<SDNode*, unsigned> &VRBaseMap);
};
ScheduleDAG *createBFS_DAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB);
/// createSimpleDAGScheduler - This creates a simple two pass instruction
/// scheduler.
ScheduleDAG* createSimpleDAGScheduler(bool NoItins, SelectionDAG &DAG,
MachineBasicBlock *BB);
/// createBURRListDAGScheduler - This creates a bottom up register usage
/// reduction list scheduler.
ScheduleDAG* createBURRListDAGScheduler(SelectionDAG &DAG,
MachineBasicBlock *BB);
/// createTDListDAGScheduler - This creates a top-down list scheduler with
/// the specified hazard recognizer. This takes ownership of the hazard
/// recognizer and deletes it when done.
ScheduleDAG* createTDListDAGScheduler(SelectionDAG &DAG,
MachineBasicBlock *BB,
HazardRecognizer *HR);
}
#endif