//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "isel"
-#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "ScheduleDAGSDNodes.h"
#include "SelectionDAGBuild.h"
-#include "llvm/ADT/BitVector.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Constants.h"
#include "llvm/CallingConv.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
+#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include <algorithm>
using namespace llvm;
-static cl::opt<bool>
-EnableValueProp("enable-value-prop", cl::Hidden);
static cl::opt<bool>
DisableLegalizeTypes("disable-legalize-types", cl::Hidden);
#ifndef NDEBUG
//===--------------------------------------------------------------------===//
/// createDefaultScheduler - This creates an instruction scheduler appropriate
/// for the target.
- ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
- SelectionDAG *DAG,
- const TargetMachine *TM,
- MachineBasicBlock *BB,
- bool Fast) {
- TargetLowering &TLI = IS->getTargetLowering();
-
+ ScheduleDAGSDNodes* createDefaultScheduler(SelectionDAGISel *IS,
+ bool Fast) {
+ const TargetLowering &TLI = IS->getTargetLowering();
+
if (Fast)
- return createFastDAGScheduler(IS, DAG, TM, BB, Fast);
+ return createFastDAGScheduler(IS, Fast);
if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency)
- return createTDListDAGScheduler(IS, DAG, TM, BB, Fast);
+ return createTDListDAGScheduler(IS, Fast);
assert(TLI.getSchedulingPreference() ==
TargetLowering::SchedulingForRegPressure && "Unknown sched type!");
- return createBURRListDAGScheduler(IS, DAG, TM, BB, Fast);
+ return createBURRListDAGScheduler(IS, Fast);
}
}
// insert. The specified MachineInstr is created but not inserted into any
// basic blocks, and the scheduler passes ownership of it to this method.
MachineBasicBlock *TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
- MachineBasicBlock *MBB) {
+ MachineBasicBlock *MBB) const {
cerr << "If a target marks an instruction with "
<< "'usesCustomDAGSchedInserter', it must implement "
<< "TargetLowering::EmitInstrWithCustomInserter!\n";
// don't coalesce. Also, only coalesce away a virtual register to virtual
// register copy.
bool Coalesced = false;
- unsigned SrcReg, DstReg;
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (NumUses == 1 &&
- TII.isMoveInstr(*UseMI, SrcReg, DstReg) &&
+ TII.isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
TargetRegisterInfo::isVirtualRegister(DstReg)) {
VirtReg = DstReg;
Coalesced = true;
// SelectionDAGISel code
//===----------------------------------------------------------------------===//
-SelectionDAGISel::SelectionDAGISel(TargetLowering &tli, bool fast) :
- FunctionPass(&ID), TLI(tli),
+SelectionDAGISel::SelectionDAGISel(TargetMachine &tm, bool fast) :
+ FunctionPass(&ID), TM(tm), TLI(*tm.getTargetLowering()),
FuncInfo(new FunctionLoweringInfo(TLI)),
CurDAG(new SelectionDAG(TLI, *FuncInfo)),
- SDL(new SelectionDAGLowering(*CurDAG, TLI, *FuncInfo)),
+ SDL(new SelectionDAGLowering(*CurDAG, TLI, *FuncInfo, fast)),
GFI(),
Fast(fast),
DAGSize(0)
void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AliasAnalysis>();
AU.addRequired<GCModuleInfo>();
+ AU.addRequired<DwarfWriter>();
AU.setPreservesAll();
}
AA = &getAnalysis<AliasAnalysis>();
TargetMachine &TM = TLI.getTargetMachine();
- MachineFunction &MF = MachineFunction::construct(&Fn, TM);
- const MachineRegisterInfo &MRI = MF.getRegInfo();
+ MF = &MachineFunction::construct(&Fn, TM);
const TargetInstrInfo &TII = *TM.getInstrInfo();
const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
- if (MF.getFunction()->hasGC())
- GFI = &getAnalysis<GCModuleInfo>().getFunctionInfo(*MF.getFunction());
+ if (MF->getFunction()->hasGC())
+ GFI = &getAnalysis<GCModuleInfo>().getFunctionInfo(*MF->getFunction());
else
GFI = 0;
- RegInfo = &MF.getRegInfo();
+ RegInfo = &MF->getRegInfo();
DOUT << "\n\n\n=== " << Fn.getName() << "\n";
- FuncInfo->set(Fn, MF, EnableFastISel);
- MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();
- CurDAG->init(MF, MMI);
+ MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
+ DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
+ CurDAG->init(*MF, MMI, DW);
+ FuncInfo->set(Fn, *MF, *CurDAG, EnableFastISel);
SDL->init(GFI, *AA);
for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
// Mark landing pad.
FuncInfo->MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
- SelectAllBasicBlocks(Fn, MF, MMI, TII);
+ SelectAllBasicBlocks(Fn, *MF, MMI, DW, TII);
// If the first basic block in the function has live ins that need to be
// copied into vregs, emit the copies into the top of the block before
// emitting the code for the block.
- EmitLiveInCopies(MF.begin(), MRI, TRI, TII);
+ EmitLiveInCopies(MF->begin(), *RegInfo, TRI, TII);
// Add function live-ins to entry block live-in set.
for (MachineRegisterInfo::livein_iterator I = RegInfo->livein_begin(),
E = RegInfo->livein_end(); I != E; ++I)
- MF.begin()->addLiveIn(I->first);
+ MF->begin()->addLiveIn(I->first);
#ifndef NDEBUG
assert(FuncInfo->CatchInfoFound.size() == FuncInfo->CatchInfoLost.size() &&
/// IsFixedFrameObjectWithPosOffset - Check if object is a fixed frame object and
/// whether object offset >= 0.
static bool
-IsFixedFrameObjectWithPosOffset(MachineFrameInfo * MFI, SDValue Op) {
+IsFixedFrameObjectWithPosOffset(MachineFrameInfo *MFI, SDValue Op) {
if (!isa<FrameIndexSDNode>(Op)) return false;
FrameIndexSDNode * FrameIdxNode = dyn_cast<FrameIndexSDNode>(Op);
/// assumes all arguments sourcing from FORMAL_ARGUMENTS or a CopyFromReg with
/// virtual registers would be overwritten by direct lowering.
static bool IsPossiblyOverwrittenArgumentOfTailCall(SDValue Op,
- MachineFrameInfo * MFI) {
+ MachineFrameInfo *MFI) {
RegisterSDNode * OpReg = NULL;
if (Op.getOpcode() == ISD::FORMAL_ARGUMENTS ||
(Op.getOpcode()== ISD::CopyFromReg &&
/// CheckDAGForTailCallsAndFixThem - This Function looks for CALL nodes in the
/// DAG and fixes their tailcall attribute operand.
static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG,
- TargetLowering& TLI) {
+ const TargetLowering& TLI) {
SDNode * Ret = NULL;
SDValue Terminator = DAG.getRoot();
MVT VT = Arg.getValueType();
unsigned VReg = MF.getRegInfo().
createVirtualRegister(TLI.getRegClassFor(VT));
- Chain = DAG.getCopyToReg(Chain, VReg, Arg, InFlag);
+ Chain = DAG.getCopyToReg(Chain, Arg.getDebugLoc(),
+ VReg, Arg, InFlag);
InFlag = Chain.getValue(1);
- Arg = DAG.getCopyFromReg(Chain, VReg, VT, InFlag);
+ Arg = DAG.getCopyFromReg(Chain, Arg.getDebugLoc(),
+ VReg, VT, InFlag);
Chain = Arg.getValue(1);
InFlag = Arg.getValue(2);
}
if (TimePassesIsEnabled) {
NamedRegionTimer T("DAG Legalization", GroupName);
- CurDAG->Legalize(DisableLegalizeTypes);
+ CurDAG->Legalize(DisableLegalizeTypes, Fast);
} else {
- CurDAG->Legalize(DisableLegalizeTypes);
+ CurDAG->Legalize(DisableLegalizeTypes, Fast);
}
DOUT << "Legalized selection DAG:\n";
if (ViewISelDAGs) CurDAG->viewGraph("isel input for " + BlockName);
- if (!Fast && EnableValueProp)
+ if (!Fast)
ComputeLiveOutVRegInfo();
// Third, instruction select all of the operations to machine code, adding the
if (ViewSchedDAGs) CurDAG->viewGraph("scheduler input for " + BlockName);
// Schedule machine code.
- ScheduleDAG *Scheduler;
+ ScheduleDAGSDNodes *Scheduler = CreateScheduler();
if (TimePassesIsEnabled) {
NamedRegionTimer T("Instruction Scheduling", GroupName);
- Scheduler = Schedule();
+ Scheduler->Run(CurDAG, BB, BB->end());
} else {
- Scheduler = Schedule();
+ Scheduler->Run(CurDAG, BB, BB->end());
}
if (ViewSUnitDAGs) Scheduler->viewGraph();
DEBUG(BB->dump());
}
-void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
+void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
+ MachineFunction &MF,
MachineModuleInfo *MMI,
+ DwarfWriter *DW,
const TargetInstrInfo &TII) {
// Initialize the Fast-ISel state, if needed.
FastISel *FastIS = 0;
if (EnableFastISel)
- FastIS = TLI.createFastISel(*FuncInfo->MF, MMI,
+ FastIS = TLI.createFastISel(MF, MMI, DW,
FuncInfo->ValueMap,
FuncInfo->MBBMap,
FuncInfo->StaticAllocaMap
unsigned LabelID = MMI->addLandingPad(BB);
const TargetInstrDesc &II = TII.get(TargetInstrInfo::EH_LABEL);
- BuildMI(BB, II).addImm(LabelID);
+ BuildMI(BB, SDL->getCurDebugLoc(), II).addImm(LabelID);
// Mark exception register as live in.
unsigned Reg = TLI.getExceptionAddressRegister();
}
-/// Schedule - Pick a safe ordering for instructions for each
-/// target node in the graph.
+/// Create the scheduler. If a specific scheduler was specified
+/// via the SchedulerRegistry, use it, otherwise select the
+/// one preferred by the target.
///
-ScheduleDAG *SelectionDAGISel::Schedule() {
+ScheduleDAGSDNodes *SelectionDAGISel::CreateScheduler() {
RegisterScheduler::FunctionPassCtor Ctor = RegisterScheduler::getDefault();
if (!Ctor) {
RegisterScheduler::setDefault(Ctor);
}
- TargetMachine &TM = getTargetLowering().getTargetMachine();
- ScheduleDAG *Scheduler = Ctor(this, CurDAG, &TM, BB, Fast);
- Scheduler->Run();
-
- return Scheduler;
+ return Ctor(this, Fast);
}
-
-HazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() {
- return new HazardRecognizer();
+ScheduleHazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() {
+ return new ScheduleHazardRecognizer();
}
//===----------------------------------------------------------------------===//
unsigned Flags = cast<ConstantSDNode>(InOps[i])->getZExtValue();
if ((Flags & 7) != 4 /*MEM*/) {
// Just skip over this operand, copying the operands verbatim.
- Ops.insert(Ops.end(), InOps.begin()+i, InOps.begin()+i+(Flags >> 3) + 1);
- i += (Flags >> 3) + 1;
+ Ops.insert(Ops.end(), InOps.begin()+i,
+ InOps.begin()+i+InlineAsm::getNumOperandRegisters(Flags) + 1);
+ i += InlineAsm::getNumOperandRegisters(Flags) + 1;
} else {
- assert((Flags >> 3) == 1 && "Memory operand with multiple values?");
+ assert(InlineAsm::getNumOperandRegisters(Flags) == 1 &&
+ "Memory operand with multiple values?");
// Otherwise, this is a memory operand. Ask the target to select it.
std::vector<SDValue> SelOps;
if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps)) {