| //===------- 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 |