//===------- 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(Node)) return true; if (isa(Node)) return true; if (isa(Node)) return true; if (isa(Node)) return true; if (isa(Node)) return true; if (isa(Node)) return true; if (isa(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 &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 &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