mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-29 23:12:55 +01:00
0a64d261e0
llvm-svn: 26693
149 lines
5.5 KiB
C++
149 lines
5.5 KiB
C++
//===------- 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
|