#include "llvm/IntrinsicInst.h"
#include "llvm/ParameterAttributes.h"
#include "llvm/CodeGen/Collector.h"
-#include "llvm/CodeGen/MachineDebugInfoDesc.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
using namespace llvm;
static cl::opt<bool>
-EnableValueProp("enable-value-prop", cl::Hidden, cl::init(false));
+EnableValueProp("enable-value-prop", cl::Hidden);
+static cl::opt<bool>
+EnableLegalizeTypes("enable-legalize-types", cl::Hidden);
#ifndef NDEBUG
/// for the target.
ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG,
- MachineBasicBlock *BB) {
+ MachineBasicBlock *BB,
+ bool Fast) {
TargetLowering &TLI = IS->getTargetLowering();
if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency) {
- return createTDListDAGScheduler(IS, DAG, BB);
+ return createTDListDAGScheduler(IS, DAG, BB, Fast);
} else {
assert(TLI.getSchedulingPreference() ==
TargetLowering::SchedulingForRegPressure && "Unknown sched type!");
- return createBURRListDAGScheduler(IS, DAG, BB);
+ return createBURRListDAGScheduler(IS, DAG, BB, Fast);
}
}
// also creates the initial PHI MachineInstrs, though none of the input
// operands are populated.
for (BB = Fn.begin(), EB = Fn.end(); BB != EB; ++BB) {
- MachineBasicBlock *MBB = new MachineBasicBlock(BB);
+ MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(BB);
MBBMap[BB] = MBB;
- MF.getBasicBlockList().push_back(MBB);
+ MF.push_back(MBB);
// Create Machine PHI nodes for LLVM PHI nodes, lowering them as
// appropriate.
if (isa<ConstantStruct>(C) || isa<ConstantArray>(C)) {
SmallVector<SDOperand, 4> Constants;
- SmallVector<MVT, 4> ValueVTs;
for (User::const_op_iterator OI = C->op_begin(), OE = C->op_end();
OI != OE; ++OI) {
SDNode *Val = getValue(*OI).Val;
- for (unsigned i = 0, e = Val->getNumValues(); i != e; ++i) {
+ for (unsigned i = 0, e = Val->getNumValues(); i != e; ++i)
Constants.push_back(SDOperand(Val, i));
- ValueVTs.push_back(Val->getValueType(i));
- }
}
- return DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
- &Constants[0], Constants.size());
+ return DAG.getMergeValues(&Constants[0], Constants.size());
}
if (const ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) {
return SDOperand(); // empty array
MVT EltVT = TLI.getValueType(ATy->getElementType());
SmallVector<SDOperand, 4> Constants(NumElts);
- SmallVector<MVT, 4> ValueVTs(NumElts, EltVT);
for (unsigned i = 0, e = NumElts; i != e; ++i) {
if (isa<UndefValue>(C))
Constants[i] = DAG.getNode(ISD::UNDEF, EltVT);
else
Constants[i] = DAG.getConstant(0, EltVT);
}
- return DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
- &Constants[0], Constants.size());
+ return DAG.getMergeValues(&Constants[0], Constants.size());
}
if (const StructType *STy = dyn_cast<StructType>(C->getType())) {
if (NumElts == 0)
return SDOperand(); // empty struct
SmallVector<SDOperand, 4> Constants(NumElts);
- SmallVector<MVT, 4> ValueVTs(NumElts);
for (unsigned i = 0, e = NumElts; i != e; ++i) {
MVT EltVT = TLI.getValueType(STy->getElementType(i));
- ValueVTs[i] = EltVT;
if (isa<UndefValue>(C))
Constants[i] = DAG.getNode(ISD::UNDEF, EltVT);
else if (EltVT.isFloatingPoint())
else
Constants[i] = DAG.getConstant(0, EltVT);
}
- return DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
- &Constants[0], Constants.size());
+ return DAG.getMergeValues(&Constants[0], Constants.size());
}
const VectorType *VecTy = cast<VectorType>(V->getType());
// Create TmpBB after CurBB.
MachineFunction::iterator BBI = CurBB;
- MachineBasicBlock *TmpBB = new MachineBasicBlock(CurBB->getBasicBlock());
- CurBB->getParent()->getBasicBlockList().insert(++BBI, TmpBB);
+ MachineFunction &MF = DAG.getMachineFunction();
+ MachineBasicBlock *TmpBB = MF.CreateMachineBasicBlock(CurBB->getBasicBlock());
+ CurBB->getParent()->insert(++BBI, TmpBB);
if (Opc == Instruction::Or) {
// Codegen X | Y as:
// Okay, we decided not to do this, remove any inserted MBB's and clear
// SwitchCases.
for (unsigned i = 1, e = SwitchCases.size(); i != e; ++i)
- CurMBB->getParent()->getBasicBlockList().erase(SwitchCases[i].ThisBB);
+ CurMBB->getParent()->erase(SwitchCases[i].ThisBB);
SwitchCases.clear();
}
for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++I) {
MachineBasicBlock *FallThrough;
if (I != E-1) {
- FallThrough = new MachineBasicBlock(CurBlock->getBasicBlock());
- CurMF->getBasicBlockList().insert(BBI, FallThrough);
+ FallThrough = CurMF->CreateMachineBasicBlock(CurBlock->getBasicBlock());
+ CurMF->insert(BBI, FallThrough);
} else {
// If the last case doesn't match, go to the default block.
FallThrough = Default;
// of the jump table, and jumping to it. Update successor information;
// we will either branch to the default case for the switch, or the jump
// table.
- MachineBasicBlock *JumpTableBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, JumpTableBB);
+ MachineBasicBlock *JumpTableBB = CurMF->CreateMachineBasicBlock(LLVMBB);
+ CurMF->insert(BBI, JumpTableBB);
CR.CaseBB->addSuccessor(Default);
CR.CaseBB->addSuccessor(JumpTableBB);
(cast<ConstantInt>(CR.GE)->getSExtValue() + 1LL)) {
TrueBB = LHSR.first->BB;
} else {
- TrueBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, TrueBB);
+ TrueBB = CurMF->CreateMachineBasicBlock(LLVMBB);
+ CurMF->insert(BBI, TrueBB);
WorkList.push_back(CaseRec(TrueBB, C, CR.GE, LHSR));
}
(cast<ConstantInt>(CR.LT)->getSExtValue() - 1LL)) {
FalseBB = RHSR.first->BB;
} else {
- FalseBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, FalseBB);
+ FalseBB = CurMF->CreateMachineBasicBlock(LLVMBB);
+ CurMF->insert(BBI, FalseBB);
WorkList.push_back(CaseRec(FalseBB,CR.LT,C,RHSR));
}
DOUT << "Mask: " << CasesBits[i].Mask << ", Bits: " << CasesBits[i].Bits
<< ", BB: " << CasesBits[i].BB << "\n";
- MachineBasicBlock *CaseBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, CaseBB);
+ MachineBasicBlock *CaseBB = CurMF->CreateMachineBasicBlock(LLVMBB);
+ CurMF->insert(BBI, CaseBB);
BTC.push_back(SelectionDAGISel::BitTestCase(CasesBits[i].Mask,
CaseBB,
CasesBits[i].BB));
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
DbgStopPointInst &SPI = cast<DbgStopPointInst>(I);
if (MMI && SPI.getContext() && MMI->Verify(SPI.getContext())) {
- SDOperand Ops[5];
-
- Ops[0] = getRoot();
- Ops[1] = getValue(SPI.getLineValue());
- Ops[2] = getValue(SPI.getColumnValue());
-
DebugInfoDesc *DD = MMI->getDescFor(SPI.getContext());
assert(DD && "Not a debug information descriptor");
- CompileUnitDesc *CompileUnit = cast<CompileUnitDesc>(DD);
-
- Ops[3] = DAG.getString(CompileUnit->getFileName());
- Ops[4] = DAG.getString(CompileUnit->getDirectory());
-
- DAG.setRoot(DAG.getNode(ISD::LOCATION, MVT::Other, Ops, 5));
+ DAG.setRoot(DAG.getDbgStopPoint(getRoot(),
+ SPI.getLine(),
+ SPI.getColumn(),
+ cast<CompileUnitDesc>(DD)));
}
return 0;
DbgRegionStartInst &RSI = cast<DbgRegionStartInst>(I);
if (MMI && RSI.getContext() && MMI->Verify(RSI.getContext())) {
unsigned LabelID = MMI->RecordRegionStart(RSI.getContext());
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
- DAG.getConstant(LabelID, MVT::i32),
- DAG.getConstant(0, MVT::i32)));
+ DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID));
}
return 0;
DbgRegionEndInst &REI = cast<DbgRegionEndInst>(I);
if (MMI && REI.getContext() && MMI->Verify(REI.getContext())) {
unsigned LabelID = MMI->RecordRegionEnd(REI.getContext());
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
- DAG.getConstant(LabelID, MVT::i32),
- DAG.getConstant(0, MVT::i32)));
+ DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID));
}
return 0;
assert(DD && "Not a debug information descriptor");
SubprogramDesc *Subprogram = cast<SubprogramDesc>(DD);
const CompileUnitDesc *CompileUnit = Subprogram->getFile();
- unsigned SrcFile = MMI->RecordSource(CompileUnit->getDirectory(),
- CompileUnit->getFileName());
+ unsigned SrcFile = MMI->RecordSource(CompileUnit);
// Record the source line but does create a label. It will be emitted
// at asm emission time.
MMI->RecordSourceLine(Subprogram->getLine(), 0, SrcFile);
// Both PendingLoads and PendingExports must be flushed here;
// this call might not return.
(void)getRoot();
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getControlRoot(),
- DAG.getConstant(BeginLabel, MVT::i32),
- DAG.getConstant(1, MVT::i32)));
+ DAG.setRoot(DAG.getLabel(ISD::EH_LABEL, getControlRoot(), BeginLabel));
}
std::pair<SDOperand,SDOperand> Result =
// Insert a label at the end of the invoke call to mark the try range. This
// can be used to detect deletion of the invoke via the MachineModuleInfo.
EndLabel = MMI->NextLabelID();
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
- DAG.getConstant(EndLabel, MVT::i32),
- DAG.getConstant(1, MVT::i32)));
+ DAG.setRoot(DAG.getLabel(ISD::EH_LABEL, getRoot(), EndLabel));
// Inform MachineModuleInfo of range.
MMI->addInvoke(LandingPad, BeginLabel, EndLabel);
ValueVT);
Part += NumRegs;
}
-
- if (ValueVTs.size() == 1)
- return Values[0];
-
+
return DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
&Values[0], ValueVTs.size());
}
return SDOperand();
}
-SDOperand TargetLowering::CustomPromoteOperation(SDOperand Op,
- SelectionDAG &DAG) {
- assert(0 && "CustomPromoteOperation not implemented for this target!");
- abort();
- return SDOperand();
-}
//===----------------------------------------------------------------------===//
// SelectionDAGISel code
// Mark landing pad.
FuncInfo.MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
- for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
- SelectBasicBlock(I, MF, FuncInfo);
+ SelectAllBasicBlocks(Fn, MF, FuncInfo);
// Add function live-ins to entry block live-in set.
BasicBlock *EntryBB = &Fn.getEntryBlock();
ComputeValueVTs(TLI, AI->getType(), ValueVTs);
unsigned NumValues = ValueVTs.size();
if (!AI->use_empty()) {
- SmallVector<MVT, 4> LegalValueVTs(NumValues);
- for (unsigned VI = 0; VI != NumValues; ++VI)
- LegalValueVTs[VI] = Args[a + VI].getValueType();
- SDL.setValue(AI,
- SDL.DAG.getMergeValues(SDL.DAG.getVTList(&LegalValueVTs[0],
- NumValues),
- &Args[a], NumValues));
+ SDL.setValue(AI, SDL.DAG.getMergeValues(&Args[a], NumValues));
// If this argument is live outside of the entry block, insert a copy from
// whereever we got it to the vreg that other BB's will reference it as.
DenseMap<const Value*, unsigned>::iterator VMI=FuncInfo.ValueMap.find(AI);
// Fix tail call attribute of CALL nodes.
for (SelectionDAG::allnodes_iterator BE = DAG.allnodes_begin(),
- BI = prior(DAG.allnodes_end()); BI != BE; --BI) {
+ BI = DAG.allnodes_end(); BI != BE; ) {
+ --BI;
if (BI->getOpcode() == ISD::CALL) {
SDOperand OpRet(Ret, 0);
- SDOperand OpCall(static_cast<SDNode*>(BI), 0);
+ SDOperand OpCall(BI, 0);
bool isMarkedTailCall =
cast<ConstantSDNode>(OpCall.getOperand(3))->getValue() != 0;
// If CALL node has tail call attribute set to true and the call is not
// Add a label to mark the beginning of the landing pad. Deletion of the
// landing pad can thus be detected via the MachineModuleInfo.
unsigned LabelID = MMI->addLandingPad(BB);
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
- DAG.getConstant(LabelID, MVT::i32),
- DAG.getConstant(1, MVT::i32)));
+ DAG.setRoot(DAG.getLabel(ISD::EH_LABEL, DAG.getEntryNode(), LabelID));
// Mark exception register as live in.
unsigned Reg = TLI.getExceptionAddressRegister();
void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) {
DOUT << "Lowered selection DAG:\n";
DEBUG(DAG.dump());
+ std::string GroupName = "Instruction Selection and Scheduling";
// Run the DAG combiner in pre-legalize mode.
- DAG.Combine(false, *AA);
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("DAG Combining 1", GroupName);
+ DAG.Combine(false, *AA);
+ } else {
+ DAG.Combine(false, *AA);
+ }
DOUT << "Optimized lowered selection DAG:\n";
DEBUG(DAG.dump());
// Second step, hack on the DAG until it only uses operations and types that
// the target supports.
-#if 0 // Enable this some day.
- DAG.LegalizeTypes();
- // Someday even later, enable a dag combine pass here.
-#endif
- DAG.Legalize();
+ if (EnableLegalizeTypes) {// Enable this some day.
+ DAG.LegalizeTypes();
+ // TODO: enable a dag combine pass here.
+ }
+
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("DAG Legalization", GroupName);
+ DAG.Legalize();
+ } else {
+ DAG.Legalize();
+ }
DOUT << "Legalized selection DAG:\n";
DEBUG(DAG.dump());
// Run the DAG combiner in post-legalize mode.
- DAG.Combine(true, *AA);
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("DAG Combining 2", GroupName);
+ DAG.Combine(true, *AA);
+ } else {
+ DAG.Combine(true, *AA);
+ }
DOUT << "Optimized legalized selection DAG:\n";
DEBUG(DAG.dump());
if (ViewISelDAGs) DAG.viewGraph();
- if (EnableValueProp) // FIXME: Only do this if !fast.
+ if (!FastISel && EnableValueProp)
ComputeLiveOutVRegInfo(DAG);
// Third, instruction select all of the operations to machine code, adding the
// code to the MachineBasicBlock.
- InstructionSelect(DAG);
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Selection", GroupName);
+ InstructionSelect(DAG);
+ } else {
+ InstructionSelect(DAG);
+ }
+
+ // Schedule machine code.
+ ScheduleDAG *Scheduler;
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Scheduling", GroupName);
+ Scheduler = Schedule(DAG);
+ } else {
+ Scheduler = Schedule(DAG);
+ }
// Emit machine code to BB. This can change 'BB' to the last block being
// inserted into.
- ScheduleAndEmitDAG(DAG);
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Creation", GroupName);
+ BB = Scheduler->EmitSchedule();
+ } else {
+ BB = Scheduler->EmitSchedule();
+ }
+
+ // Free the scheduler state.
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Scheduling Cleanup", GroupName);
+ delete Scheduler;
+ } else {
+ delete Scheduler;
+ }
// Perform target specific isel post processing.
- InstructionSelectPostProcessing(DAG);
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Selection Post Processing", GroupName);
+ InstructionSelectPostProcessing(DAG);
+ } else {
+ InstructionSelectPostProcessing(DAG);
+ }
DOUT << "Selected machine code:\n";
DEBUG(BB->dump());
}
+void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
+ FunctionLoweringInfo &FuncInfo) {
+ // Define AllNodes here so that memory allocation is reused for
+ // each basic block.
+ alist<SDNode, LargestSDNode> AllNodes;
+
+ for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
+ SelectBasicBlock(I, MF, FuncInfo, AllNodes);
+ AllNodes.clear();
+ }
+}
+
void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
- FunctionLoweringInfo &FuncInfo) {
+ FunctionLoweringInfo &FuncInfo,
+ alist<SDNode, LargestSDNode> &AllNodes) {
std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
{
SelectionDAG DAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
+ getAnalysisToUpdate<MachineModuleInfo>(),
+ AllNodes);
CurDAG = &DAG;
// First step, lower LLVM code to some DAG. This DAG may use operations and
// Lower header first, if it wasn't already lowered
if (!BitTestCases[i].Emitted) {
SelectionDAG HSDAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
+ getAnalysisToUpdate<MachineModuleInfo>(),
+ AllNodes);
CurDAG = &HSDAG;
SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
// Set the current basic block to the mbb we wish to insert the code into
for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) {
SelectionDAG BSDAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
+ getAnalysisToUpdate<MachineModuleInfo>(),
+ AllNodes);
CurDAG = &BSDAG;
SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo, GCI);
// Set the current basic block to the mbb we wish to insert the code into
// Lower header first, if it wasn't already lowered
if (!JTCases[i].first.Emitted) {
SelectionDAG HSDAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
+ getAnalysisToUpdate<MachineModuleInfo>(),
+ AllNodes);
CurDAG = &HSDAG;
SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
// Set the current basic block to the mbb we wish to insert the code into
}
SelectionDAG JSDAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
+ getAnalysisToUpdate<MachineModuleInfo>(),
+ AllNodes);
CurDAG = &JSDAG;
SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo, GCI);
// Set the current basic block to the mbb we wish to insert the code into
// additional DAGs necessary.
for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) {
SelectionDAG SDAG(TLI, MF, FuncInfo,
- getAnalysisToUpdate<MachineModuleInfo>());
+ getAnalysisToUpdate<MachineModuleInfo>(),
+ AllNodes);
CurDAG = &SDAG;
SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo, GCI);
}
-//===----------------------------------------------------------------------===//
-/// ScheduleAndEmitDAG - Pick a safe ordering and emit instructions for each
+/// Schedule - Pick a safe ordering for instructions for each
/// target node in the graph.
-void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) {
+///
+ScheduleDAG *SelectionDAGISel::Schedule(SelectionDAG &DAG) {
if (ViewSchedDAGs) DAG.viewGraph();
RegisterScheduler::FunctionPassCtor Ctor = RegisterScheduler::getDefault();
RegisterScheduler::setDefault(Ctor);
}
- ScheduleDAG *SL = Ctor(this, &DAG, BB);
- BB = SL->Run();
-
- if (ViewSUnitDAGs) SL->viewGraph();
+ ScheduleDAG *Scheduler = Ctor(this, &DAG, BB, FastISel);
+ Scheduler->Run();
- delete SL;
+ if (ViewSUnitDAGs) Scheduler->viewGraph();
+ return Scheduler;
}