#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Timer.h"
#include <algorithm>
using namespace llvm;
+static cl::opt<bool>
+EnableValueProp("enable-value-prop", cl::Hidden);
+static cl::opt<bool>
+EnableLegalizeTypes("enable-legalize-types", cl::Hidden);
+
+
#ifndef NDEBUG
static cl::opt<bool>
ViewISelDAGs("view-isel-dags", cl::Hidden,
const unsigned *IndicesEnd,
unsigned CurIndex = 0) {
// Base case: We're done.
- if (Indices == IndicesEnd)
+ if (Indices && Indices == IndicesEnd)
return CurIndex;
- // Otherwise we need to recurse. A non-negative value is used to
- // indicate the final result value; a negative value carries the
- // complemented position to continue the search.
- CurIndex = ~CurIndex;
-
// Given a struct type, recursively traverse the elements.
if (const StructType *STy = dyn_cast<StructType>(Ty)) {
- for (StructType::element_iterator EI = STy->element_begin(),
+ for (StructType::element_iterator EB = STy->element_begin(),
+ EI = EB,
EE = STy->element_end();
EI != EE; ++EI) {
- CurIndex = ComputeLinearIndex(TLI, *EI, Indices+1, IndicesEnd,
- ~CurIndex);
- if ((int)CurIndex >= 0)
- return CurIndex;
+ if (Indices && *Indices == unsigned(EI - EB))
+ return ComputeLinearIndex(TLI, *EI, Indices+1, IndicesEnd, CurIndex);
+ CurIndex = ComputeLinearIndex(TLI, *EI, 0, 0, CurIndex);
}
}
// Given an array type, recursively traverse the elements.
else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
const Type *EltTy = ATy->getElementType();
for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) {
- CurIndex = ComputeLinearIndex(TLI, EltTy, Indices+1, IndicesEnd,
- ~CurIndex);
- if ((int)CurIndex >= 0)
- return CurIndex;
+ if (Indices && *Indices == i)
+ return ComputeLinearIndex(TLI, EltTy, Indices+1, IndicesEnd, CurIndex);
+ CurIndex = ComputeLinearIndex(TLI, EltTy, 0, 0, CurIndex);
}
}
// We haven't found the type we're looking for, so keep searching.
- return CurIndex;
+ return CurIndex + 1;
}
/// ComputeValueVTs - Given an LLVM IR type, compute a sequence of
/// 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);
}
}
assert(R == 0 && "Already initialized this value register!");
return R = CreateRegForValue(V);
}
+
+ struct LiveOutInfo {
+ unsigned NumSignBits;
+ APInt KnownOne, KnownZero;
+ LiveOutInfo() : NumSignBits(0) {}
+ };
+
+ /// LiveOutRegInfo - Information about live out vregs, indexed by their
+ /// register number offset by 'FirstVirtualRegister'.
+ std::vector<LiveOutInfo> LiveOutRegInfo;
};
}
// 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.
/// them up and then emit token factor nodes when possible. This allows us to
/// get simple disambiguation between loads without worrying about alias
/// analysis.
- std::vector<SDOperand> PendingLoads;
+ SmallVector<SDOperand, 8> PendingLoads;
/// PendingExports - CopyToReg nodes that copy values to virtual registers
/// for export to other blocks need to be emitted before any terminator
void setCurrentBasicBlock(MachineBasicBlock *MBB) { CurMBB = MBB; }
- SDOperand getLoadFrom(const Type *Ty, SDOperand Ptr,
- const Value *SV, SDOperand Root,
- bool isVolatile, unsigned Alignment);
-
SDOperand getValue(const Value *V);
void setValue(const Value *V, SDOperand NewN) {
if (PartVT.isInteger() &&
ValueVT.isInteger()) {
- if (ValueVT.getSizeInBits() < PartVT.getSizeInBits()) {
+ if (ValueVT.bitsLT(PartVT)) {
// For a truncate, see if we have any information to
// indicate whether the truncated bits will always be
// zero or sign-extension.
}
if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) {
- if (ValueVT < Val.getValueType())
+ if (ValueVT.bitsLT(Val.getValueType()))
// FP_ROUND's are always exact here.
return DAG.getNode(ISD::FP_ROUND, ValueVT, Val,
DAG.getIntPtrConstant(1));
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.getNode(ISD::MERGE_VALUES,
- 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())) {
assert((isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) &&
"Unknown array constant!");
unsigned NumElts = ATy->getNumElements();
+ if (NumElts == 0)
+ 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.getNode(ISD::MERGE_VALUES,
- 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())) {
assert((isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) &&
"Unknown struct constant!");
unsigned NumElts = STy->getNumElements();
+ 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.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
- &Constants[0], Constants.size());
+ return DAG.getMergeValues(&Constants[0], Constants.size());
}
const VectorType *VecTy = cast<VectorType>(V->getType());
NewValues.push_back(getControlRoot());
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
SDOperand RetOp = getValue(I.getOperand(i));
- MVT VT = RetOp.getValueType();
-
- // FIXME: C calling convention requires the return type to be promoted to
- // at least 32-bit. But this is not necessary for non-C calling conventions.
- if (VT.isInteger()) {
- MVT MinVT = TLI.getRegisterType(MVT::i32);
- if (VT.getSizeInBits() < MinVT.getSizeInBits())
- VT = MinVT;
- }
- unsigned NumParts = TLI.getNumRegisters(VT);
- MVT PartVT = TLI.getRegisterType(VT);
- SmallVector<SDOperand, 4> Parts(NumParts);
- ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
-
- const Function *F = I.getParent()->getParent();
- if (F->paramHasAttr(0, ParamAttr::SExt))
- ExtendKind = ISD::SIGN_EXTEND;
- else if (F->paramHasAttr(0, ParamAttr::ZExt))
- ExtendKind = ISD::ZERO_EXTEND;
-
- getCopyToParts(DAG, RetOp, &Parts[0], NumParts, PartVT, ExtendKind);
+ SmallVector<MVT, 4> ValueVTs;
+ ComputeValueVTs(TLI, I.getOperand(i)->getType(), ValueVTs);
+ for (unsigned j = 0, f = ValueVTs.size(); j != f; ++j) {
+ MVT VT = ValueVTs[j];
+
+ // FIXME: C calling convention requires the return type to be promoted to
+ // at least 32-bit. But this is not necessary for non-C calling conventions.
+ if (VT.isInteger()) {
+ MVT MinVT = TLI.getRegisterType(MVT::i32);
+ if (VT.bitsLT(MinVT))
+ VT = MinVT;
+ }
- for (unsigned i = 0; i < NumParts; ++i) {
- NewValues.push_back(Parts[i]);
- NewValues.push_back(DAG.getArgFlags(ISD::ArgFlagsTy()));
+ unsigned NumParts = TLI.getNumRegisters(VT);
+ MVT PartVT = TLI.getRegisterType(VT);
+ SmallVector<SDOperand, 4> Parts(NumParts);
+ ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
+
+ const Function *F = I.getParent()->getParent();
+ if (F->paramHasAttr(0, ParamAttr::SExt))
+ ExtendKind = ISD::SIGN_EXTEND;
+ else if (F->paramHasAttr(0, ParamAttr::ZExt))
+ ExtendKind = ISD::ZERO_EXTEND;
+
+ getCopyToParts(DAG, SDOperand(RetOp.Val, RetOp.ResNo + j),
+ &Parts[0], NumParts, PartVT, ExtendKind);
+
+ for (unsigned i = 0; i < NumParts; ++i) {
+ NewValues.push_back(Parts[i]);
+ NewValues.push_back(DAG.getArgFlags(ISD::ArgFlagsTy()));
+ }
}
}
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
// 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();
}
// register so it can be used as an index into the jump table in a
// subsequent basic block. This value may be smaller or larger than the
// target's pointer type, and therefore require extension or truncating.
- if (VT.getSizeInBits() > TLI.getPointerTy().getSizeInBits())
+ if (VT.bitsGT(TLI.getPointerTy()))
SwitchOp = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), SUB);
else
SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), SUB);
ISD::SETUGT);
SDOperand ShiftOp;
- if (VT.getSizeInBits() > TLI.getShiftAmountTy().getSizeInBits())
+ if (VT.bitsGT(TLI.getShiftAmountTy()))
ShiftOp = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), SUB);
else
ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), SUB);
unsigned Reg,
SelectionDAGISel::BitTestCase &B) {
// Emit bit tests and jumps
- SDOperand SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg, TLI.getPointerTy());
+ SDOperand SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg,
+ TLI.getPointerTy());
- SDOperand AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(),
- SwitchVal,
- DAG.getConstant(B.Mask,
- TLI.getPointerTy()));
+ SDOperand AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(), SwitchVal,
+ DAG.getConstant(B.Mask, TLI.getPointerTy()));
SDOperand AndCmp = DAG.getSetCC(TLI.getSetCCResultType(AndOp), AndOp,
DAG.getConstant(0, TLI.getPointerTy()),
ISD::SETNE);
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));
SDOperand Op1 = getValue(I.getOperand(0));
SDOperand Op2 = getValue(I.getOperand(1));
- if (TLI.getShiftAmountTy().getSizeInBits() <
- Op2.getValueType().getSizeInBits())
+ if (TLI.getShiftAmountTy().bitsLT(Op2.getValueType()))
Op2 = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), Op2);
- else if (TLI.getShiftAmountTy() > Op2.getValueType())
+ else if (TLI.getShiftAmountTy().bitsGT(Op2.getValueType()))
Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2);
setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2));
MVT SrcVT = N.getValueType();
MVT DestVT = TLI.getValueType(I.getType());
SDOperand Result;
- if (DestVT.getSizeInBits() < SrcVT.getSizeInBits())
+ if (DestVT.bitsLT(SrcVT))
Result = DAG.getNode(ISD::TRUNCATE, DestVT, N);
else
// Note: ZERO_EXTEND can handle cases where the sizes are equal too
SDOperand N = getValue(I.getOperand(0));
MVT SrcVT = N.getValueType();
MVT DestVT = TLI.getValueType(I.getType());
- if (DestVT.getSizeInBits() < SrcVT.getSizeInBits())
+ if (DestVT.bitsLT(SrcVT))
setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N));
else
// Note: ZERO_EXTEND can handle cases where the sizes are equal too
Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
SDOperand(Agg.Val, Agg.ResNo + i);
- setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&AggValueVTs[0], NumAggValues),
- &Values[0], NumAggValues));
+ setValue(&I, DAG.getMergeValues(DAG.getVTList(&AggValueVTs[0], NumAggValues),
+ &Values[0], NumAggValues));
}
void SelectionDAGLowering::visitExtractValue(ExtractValueInst &I) {
// Copy out the selected value(s).
for (unsigned i = LinearIndex; i != LinearIndex + NumValValues; ++i)
Values[i - LinearIndex] =
- OutOfUndef ? DAG.getNode(ISD::UNDEF, Agg.Val->getValueType(i)) :
- SDOperand(Agg.Val, Agg.ResNo + i - LinearIndex);
+ OutOfUndef ? DAG.getNode(ISD::UNDEF, Agg.Val->getValueType(Agg.ResNo + i)) :
+ SDOperand(Agg.Val, Agg.ResNo + i);
- setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&ValValueVTs[0], NumValValues),
- &Values[0], NumValValues));
+ setValue(&I, DAG.getMergeValues(DAG.getVTList(&ValValueVTs[0], NumValValues),
+ &Values[0], NumValValues));
}
// If the index is smaller or larger than intptr_t, truncate or extend
// it.
- if (IdxN.getValueType() < N.getValueType()) {
+ if (IdxN.getValueType().bitsLT(N.getValueType())) {
IdxN = DAG.getNode(ISD::SIGN_EXTEND, N.getValueType(), IdxN);
- } else if (IdxN.getValueType() > N.getValueType())
+ } else if (IdxN.getValueType().bitsGT(N.getValueType()))
IdxN = DAG.getNode(ISD::TRUNCATE, N.getValueType(), IdxN);
// If this is a multiply by a power of two, turn it into a shl
SDOperand AllocSize = getValue(I.getArraySize());
MVT IntPtr = TLI.getPointerTy();
- if (IntPtr < AllocSize.getValueType())
+ if (IntPtr.bitsLT(AllocSize.getValueType()))
AllocSize = DAG.getNode(ISD::TRUNCATE, IntPtr, AllocSize);
- else if (IntPtr > AllocSize.getValueType())
+ else if (IntPtr.bitsGT(AllocSize.getValueType()))
AllocSize = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, AllocSize);
AllocSize = DAG.getNode(ISD::MUL, IntPtr, AllocSize,
}
void SelectionDAGLowering::visitLoad(LoadInst &I) {
- SDOperand Ptr = getValue(I.getOperand(0));
+ const Value *SV = I.getOperand(0);
+ SDOperand Ptr = getValue(SV);
+
+ const Type *Ty = I.getType();
+ bool isVolatile = I.isVolatile();
+ unsigned Alignment = I.getAlignment();
+
+ SmallVector<MVT, 4> ValueVTs;
+ SmallVector<uint64_t, 4> Offsets;
+ ComputeValueVTs(TLI, Ty, ValueVTs, &Offsets);
+ unsigned NumValues = ValueVTs.size();
+ if (NumValues == 0)
+ return;
SDOperand Root;
if (I.isVolatile())
Root = DAG.getRoot();
}
- setValue(&I, getLoadFrom(I.getType(), Ptr, I.getOperand(0),
- Root, I.isVolatile(), I.getAlignment()));
-}
-
-SDOperand SelectionDAGLowering::getLoadFrom(const Type *Ty, SDOperand Ptr,
- const Value *SV, SDOperand Root,
- bool isVolatile,
- unsigned Alignment) {
- SmallVector<MVT, 4> ValueVTs;
- SmallVector<uint64_t, 4> Offsets;
- ComputeValueVTs(TLI, Ty, ValueVTs, &Offsets);
- unsigned NumValues = ValueVTs.size();
-
SmallVector<SDOperand, 4> Values(NumValues);
SmallVector<SDOperand, 4> Chains(NumValues);
MVT PtrVT = Ptr.getValueType();
else
PendingLoads.push_back(Chain);
- return DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&ValueVTs[0], NumValues),
- &Values[0], NumValues);
+ setValue(&I, DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], NumValues),
+ &Values[0], NumValues));
}
SmallVector<uint64_t, 4> Offsets;
ComputeValueVTs(TLI, SrcV->getType(), ValueVTs, &Offsets);
unsigned NumValues = ValueVTs.size();
+ if (NumValues == 0)
+ return;
SDOperand Root = getRoot();
SmallVector<SDOperand, 4> Chains(NumValues);
const char *
SelectionDAGLowering::implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op) {
SDOperand Root = getRoot();
- SDOperand O2 = getValue(I.getOperand(2));
SDOperand L = DAG.getAtomic(Op, Root,
getValue(I.getOperand(1)),
- O2, O2.getValueType());
+ getValue(I.getOperand(2)),
+ I.getOperand(1));
setValue(&I, L);
DAG.setRoot(L.getValue(1));
return 0;
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);
case Intrinsic::eh_dwarf_cfa: {
MVT VT = getValue(I.getOperand(1)).getValueType();
SDOperand CfaArg;
- if (VT.getSizeInBits() > TLI.getPointerTy().getSizeInBits())
+ if (VT.bitsGT(TLI.getPointerTy()))
CfaArg = DAG.getNode(ISD::TRUNCATE,
TLI.getPointerTy(), getValue(I.getOperand(1)));
else
DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, MVT::Other, &Ops[0], 6));
return 0;
}
- case Intrinsic::atomic_lcs: {
+ case Intrinsic::atomic_cmp_swap: {
SDOperand Root = getRoot();
- SDOperand O3 = getValue(I.getOperand(3));
- SDOperand L = DAG.getAtomic(ISD::ATOMIC_LCS, Root,
+ SDOperand L = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, Root,
getValue(I.getOperand(1)),
getValue(I.getOperand(2)),
- O3, O3.getValueType());
+ getValue(I.getOperand(3)),
+ I.getOperand(1));
setValue(&I, L);
DAG.setRoot(L.getValue(1));
return 0;
}
- case Intrinsic::atomic_las:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LAS);
- case Intrinsic::atomic_lss:
- return implVisitBinaryAtomic(I, ISD::ATOMIC_LSS);
+ case Intrinsic::atomic_load_add:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_ADD);
+ case Intrinsic::atomic_load_sub:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_SUB);
case Intrinsic::atomic_load_and:
return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_AND);
case Intrinsic::atomic_load_or:
return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_OR);
case Intrinsic::atomic_load_xor:
return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_XOR);
+ case Intrinsic::atomic_load_nand:
+ return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_NAND);
case Intrinsic::atomic_load_min:
return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MIN);
case Intrinsic::atomic_load_max:
// 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);
/// this value and returns the result as a ValueVT value. This uses
/// Chain/Flag as the input and updates them for the output Chain/Flag.
/// If the Flag pointer is NULL, no flag is used.
-SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
+SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
SDOperand &Chain,
SDOperand *Flag) const {
// Assemble the legal parts into the final values.
*Flag = P.getValue(2);
}
Chain = P.getValue(1);
+
+ // If the source register was virtual and if we know something about it,
+ // add an assert node.
+ if (TargetRegisterInfo::isVirtualRegister(Regs[Part+i]) &&
+ RegisterVT.isInteger() && !RegisterVT.isVector()) {
+ unsigned SlotNo = Regs[Part+i]-TargetRegisterInfo::FirstVirtualRegister;
+ FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo();
+ if (FLI.LiveOutRegInfo.size() > SlotNo) {
+ FunctionLoweringInfo::LiveOutInfo &LOI = FLI.LiveOutRegInfo[SlotNo];
+
+ unsigned RegSize = RegisterVT.getSizeInBits();
+ unsigned NumSignBits = LOI.NumSignBits;
+ unsigned NumZeroBits = LOI.KnownZero.countLeadingOnes();
+
+ // FIXME: We capture more information than the dag can represent. For
+ // now, just use the tightest assertzext/assertsext possible.
+ bool isSExt = true;
+ MVT FromVT(MVT::Other);
+ if (NumSignBits == RegSize)
+ isSExt = true, FromVT = MVT::i1; // ASSERT SEXT 1
+ else if (NumZeroBits >= RegSize-1)
+ isSExt = false, FromVT = MVT::i1; // ASSERT ZEXT 1
+ else if (NumSignBits > RegSize-8)
+ isSExt = true, FromVT = MVT::i8; // ASSERT SEXT 8
+ else if (NumZeroBits >= RegSize-9)
+ isSExt = false, FromVT = MVT::i8; // ASSERT ZEXT 8
+ else if (NumSignBits > RegSize-16)
+ isSExt = true, FromVT = MVT::i16; // ASSERT SEXT 16
+ else if (NumZeroBits >= RegSize-17)
+ isSExt = false, FromVT = MVT::i16; // ASSERT ZEXT 16
+ else if (NumSignBits > RegSize-32)
+ isSExt = true, FromVT = MVT::i32; // ASSERT SEXT 32
+ else if (NumZeroBits >= RegSize-33)
+ isSExt = false, FromVT = MVT::i32; // ASSERT ZEXT 32
+
+ if (FromVT != MVT::Other) {
+ P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext,
+ RegisterVT, P, DAG.getValueType(FromVT));
+
+ }
+ }
+ }
+
Parts[Part+i] = P;
}
ValueVT);
Part += NumRegs;
}
-
- if (ValueVTs.size() == 1)
- return Values[0];
-
- return DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
- &Values[0], ValueVTs.size());
+
+ return DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
+ &Values[0], ValueVTs.size());
}
/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
// If we have already found this register in a different register class,
// choose the one with the largest VT specified. For example, on
// PowerPC, we favor f64 register classes over f32.
- if (FoundVT == MVT::Other ||
- FoundVT.getSizeInBits() < (*I).getSizeInBits()) {
+ if (FoundVT == MVT::Other || FoundVT.bitsLT(*I)) {
ThisVT = *I;
break;
}
// Copy the output from the appropriate register. Find a register that
// we can use.
if (OpInfo.AssignedRegs.Regs.empty()) {
- cerr << "Couldn't allocate output reg for contraint '"
+ cerr << "Couldn't allocate output reg for constraint '"
<< OpInfo.ConstraintCode << "'!\n";
exit(1);
}
MVT IntPtr = TLI.getPointerTy();
- if (IntPtr < Src.getValueType())
+ if (IntPtr.bitsLT(Src.getValueType()))
Src = DAG.getNode(ISD::TRUNCATE, IntPtr, Src);
- else if (IntPtr > Src.getValueType())
+ else if (IntPtr.bitsGT(Src.getValueType()))
Src = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, Src);
// Scale the source by the type size.
/// implementation, which just inserts a FORMAL_ARGUMENTS node. FIXME: When all
/// targets are migrated to using FORMAL_ARGUMENTS, this hook should be
/// integrated into SDISel.
-std::vector<SDOperand>
-TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
+void TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
+ SmallVectorImpl<SDOperand> &ArgValues) {
// Add CC# and isVararg as operands to the FORMAL_ARGUMENTS node.
- std::vector<SDOperand> Ops;
+ SmallVector<SDOperand, 3+16> Ops;
Ops.push_back(DAG.getRoot());
Ops.push_back(DAG.getConstant(F.getCallingConv(), getPointerTy()));
Ops.push_back(DAG.getConstant(F.isVarArg(), getPointerTy()));
// Add one result value for each formal argument.
- std::vector<MVT> RetVals;
+ SmallVector<MVT, 16> RetVals;
unsigned j = 1;
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
I != E; ++I, ++j) {
- MVT VT = getValueType(I->getType());
- ISD::ArgFlagsTy Flags;
- unsigned OriginalAlignment =
- getTargetData()->getABITypeAlignment(I->getType());
-
- if (F.paramHasAttr(j, ParamAttr::ZExt))
- Flags.setZExt();
- if (F.paramHasAttr(j, ParamAttr::SExt))
- Flags.setSExt();
- if (F.paramHasAttr(j, ParamAttr::InReg))
- Flags.setInReg();
- if (F.paramHasAttr(j, ParamAttr::StructRet))
- Flags.setSRet();
- if (F.paramHasAttr(j, ParamAttr::ByVal)) {
- Flags.setByVal();
- const PointerType *Ty = cast<PointerType>(I->getType());
- const Type *ElementTy = Ty->getElementType();
- unsigned FrameAlign = getByValTypeAlignment(ElementTy);
- unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
- // For ByVal, alignment should be passed from FE. BE will guess if
- // this info is not there but there are cases it cannot get right.
- if (F.getParamAlignment(j))
- FrameAlign = F.getParamAlignment(j);
- Flags.setByValAlign(FrameAlign);
- Flags.setByValSize(FrameSize);
- }
- if (F.paramHasAttr(j, ParamAttr::Nest))
- Flags.setNest();
- Flags.setOrigAlign(OriginalAlignment);
+ SmallVector<MVT, 4> ValueVTs;
+ ComputeValueVTs(*this, I->getType(), ValueVTs);
+ for (unsigned Value = 0, NumValues = ValueVTs.size();
+ Value != NumValues; ++Value) {
+ MVT VT = ValueVTs[Value];
+ const Type *ArgTy = VT.getTypeForMVT();
+ ISD::ArgFlagsTy Flags;
+ unsigned OriginalAlignment =
+ getTargetData()->getABITypeAlignment(ArgTy);
+
+ if (F.paramHasAttr(j, ParamAttr::ZExt))
+ Flags.setZExt();
+ if (F.paramHasAttr(j, ParamAttr::SExt))
+ Flags.setSExt();
+ if (F.paramHasAttr(j, ParamAttr::InReg))
+ Flags.setInReg();
+ if (F.paramHasAttr(j, ParamAttr::StructRet))
+ Flags.setSRet();
+ if (F.paramHasAttr(j, ParamAttr::ByVal)) {
+ Flags.setByVal();
+ const PointerType *Ty = cast<PointerType>(I->getType());
+ const Type *ElementTy = Ty->getElementType();
+ unsigned FrameAlign = getByValTypeAlignment(ElementTy);
+ unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
+ // For ByVal, alignment should be passed from FE. BE will guess if
+ // this info is not there but there are cases it cannot get right.
+ if (F.getParamAlignment(j))
+ FrameAlign = F.getParamAlignment(j);
+ Flags.setByValAlign(FrameAlign);
+ Flags.setByValSize(FrameSize);
+ }
+ if (F.paramHasAttr(j, ParamAttr::Nest))
+ Flags.setNest();
+ Flags.setOrigAlign(OriginalAlignment);
- MVT RegisterVT = getRegisterType(VT);
- unsigned NumRegs = getNumRegisters(VT);
- for (unsigned i = 0; i != NumRegs; ++i) {
- RetVals.push_back(RegisterVT);
- ISD::ArgFlagsTy MyFlags = Flags;
- if (NumRegs > 1 && i == 0)
- MyFlags.setSplit();
- // if it isn't first piece, alignment must be 1
- else if (i > 0)
- MyFlags.setOrigAlign(1);
- Ops.push_back(DAG.getArgFlags(MyFlags));
+ MVT RegisterVT = getRegisterType(VT);
+ unsigned NumRegs = getNumRegisters(VT);
+ for (unsigned i = 0; i != NumRegs; ++i) {
+ RetVals.push_back(RegisterVT);
+ ISD::ArgFlagsTy MyFlags = Flags;
+ if (NumRegs > 1 && i == 0)
+ MyFlags.setSplit();
+ // if it isn't first piece, alignment must be 1
+ else if (i > 0)
+ MyFlags.setOrigAlign(1);
+ Ops.push_back(DAG.getArgFlags(MyFlags));
+ }
}
}
DAG.setRoot(SDOperand(Result, NumArgRegs));
// Set up the return result vector.
- Ops.clear();
unsigned i = 0;
unsigned Idx = 1;
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E;
++I, ++Idx) {
- MVT VT = getValueType(I->getType());
- MVT PartVT = getRegisterType(VT);
-
- unsigned NumParts = getNumRegisters(VT);
- SmallVector<SDOperand, 4> Parts(NumParts);
- for (unsigned j = 0; j != NumParts; ++j)
- Parts[j] = SDOperand(Result, i++);
-
- ISD::NodeType AssertOp = ISD::DELETED_NODE;
- if (F.paramHasAttr(Idx, ParamAttr::SExt))
- AssertOp = ISD::AssertSext;
- else if (F.paramHasAttr(Idx, ParamAttr::ZExt))
- AssertOp = ISD::AssertZext;
-
- Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT,
- AssertOp));
+ SmallVector<MVT, 4> ValueVTs;
+ ComputeValueVTs(*this, I->getType(), ValueVTs);
+ for (unsigned Value = 0, NumValues = ValueVTs.size();
+ Value != NumValues; ++Value) {
+ MVT VT = ValueVTs[Value];
+ MVT PartVT = getRegisterType(VT);
+
+ unsigned NumParts = getNumRegisters(VT);
+ SmallVector<SDOperand, 4> Parts(NumParts);
+ for (unsigned j = 0; j != NumParts; ++j)
+ Parts[j] = SDOperand(Result, i++);
+
+ ISD::NodeType AssertOp = ISD::DELETED_NODE;
+ if (F.paramHasAttr(Idx, ParamAttr::SExt))
+ AssertOp = ISD::AssertSext;
+ else if (F.paramHasAttr(Idx, ParamAttr::ZExt))
+ AssertOp = ISD::AssertZext;
+
+ ArgValues.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT,
+ AssertOp));
+ }
}
assert(i == NumArgRegs && "Argument register count mismatch!");
- return Ops;
}
// Handle all of the outgoing arguments.
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
- MVT VT = getValueType(Args[i].Ty);
- SDOperand Op = Args[i].Node;
- ISD::ArgFlagsTy Flags;
- unsigned OriginalAlignment =
- getTargetData()->getABITypeAlignment(Args[i].Ty);
-
- if (Args[i].isZExt)
- Flags.setZExt();
- if (Args[i].isSExt)
- Flags.setSExt();
- if (Args[i].isInReg)
- Flags.setInReg();
- if (Args[i].isSRet)
- Flags.setSRet();
- if (Args[i].isByVal) {
- Flags.setByVal();
- const PointerType *Ty = cast<PointerType>(Args[i].Ty);
- const Type *ElementTy = Ty->getElementType();
- unsigned FrameAlign = getByValTypeAlignment(ElementTy);
- unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
- // For ByVal, alignment should come from FE. BE will guess if this
- // info is not there but there are cases it cannot get right.
- if (Args[i].Alignment)
- FrameAlign = Args[i].Alignment;
- Flags.setByValAlign(FrameAlign);
- Flags.setByValSize(FrameSize);
- }
- if (Args[i].isNest)
- Flags.setNest();
- Flags.setOrigAlign(OriginalAlignment);
-
- MVT PartVT = getRegisterType(VT);
- unsigned NumParts = getNumRegisters(VT);
- SmallVector<SDOperand, 4> Parts(NumParts);
- ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
-
- if (Args[i].isSExt)
- ExtendKind = ISD::SIGN_EXTEND;
- else if (Args[i].isZExt)
- ExtendKind = ISD::ZERO_EXTEND;
-
- getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT, ExtendKind);
-
- for (unsigned i = 0; i != NumParts; ++i) {
- // if it isn't first piece, alignment must be 1
- ISD::ArgFlagsTy MyFlags = Flags;
- if (NumParts > 1 && i == 0)
- MyFlags.setSplit();
- else if (i != 0)
- MyFlags.setOrigAlign(1);
-
- Ops.push_back(Parts[i]);
- Ops.push_back(DAG.getArgFlags(MyFlags));
+ SmallVector<MVT, 4> ValueVTs;
+ ComputeValueVTs(*this, Args[i].Ty, ValueVTs);
+ for (unsigned Value = 0, NumValues = ValueVTs.size();
+ Value != NumValues; ++Value) {
+ MVT VT = ValueVTs[Value];
+ const Type *ArgTy = VT.getTypeForMVT();
+ SDOperand Op = SDOperand(Args[i].Node.Val, Args[i].Node.ResNo + Value);
+ ISD::ArgFlagsTy Flags;
+ unsigned OriginalAlignment =
+ getTargetData()->getABITypeAlignment(ArgTy);
+
+ if (Args[i].isZExt)
+ Flags.setZExt();
+ if (Args[i].isSExt)
+ Flags.setSExt();
+ if (Args[i].isInReg)
+ Flags.setInReg();
+ if (Args[i].isSRet)
+ Flags.setSRet();
+ if (Args[i].isByVal) {
+ Flags.setByVal();
+ const PointerType *Ty = cast<PointerType>(Args[i].Ty);
+ const Type *ElementTy = Ty->getElementType();
+ unsigned FrameAlign = getByValTypeAlignment(ElementTy);
+ unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
+ // For ByVal, alignment should come from FE. BE will guess if this
+ // info is not there but there are cases it cannot get right.
+ if (Args[i].Alignment)
+ FrameAlign = Args[i].Alignment;
+ Flags.setByValAlign(FrameAlign);
+ Flags.setByValSize(FrameSize);
+ }
+ if (Args[i].isNest)
+ Flags.setNest();
+ Flags.setOrigAlign(OriginalAlignment);
+
+ MVT PartVT = getRegisterType(VT);
+ unsigned NumParts = getNumRegisters(VT);
+ SmallVector<SDOperand, 4> Parts(NumParts);
+ ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
+
+ if (Args[i].isSExt)
+ ExtendKind = ISD::SIGN_EXTEND;
+ else if (Args[i].isZExt)
+ ExtendKind = ISD::ZERO_EXTEND;
+
+ getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT, ExtendKind);
+
+ for (unsigned i = 0; i != NumParts; ++i) {
+ // if it isn't first piece, alignment must be 1
+ ISD::ArgFlagsTy MyFlags = Flags;
+ if (NumParts > 1 && i == 0)
+ MyFlags.setSplit();
+ else if (i != 0)
+ MyFlags.setOrigAlign(1);
+
+ Ops.push_back(Parts[i]);
+ Ops.push_back(DAG.getArgFlags(MyFlags));
+ }
}
}
AssertOp);
ReturnValues.push_back(ReturnValue);
}
- Res = ReturnValues.size() == 1 ? ReturnValues.front() :
- DAG.getNode(ISD::MERGE_VALUES,
- DAG.getVTList(&RetTys[0], RetTys.size()),
- &ReturnValues[0], ReturnValues.size());
+ Res = DAG.getMergeValues(DAG.getVTList(&RetTys[0], RetTys.size()),
+ &ReturnValues[0], ReturnValues.size());
}
return std::make_pair(Res, Chain);
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();
Function &F = *LLVMBB->getParent();
FunctionLoweringInfo &FuncInfo = SDL.FuncInfo;
SDOperand OldRoot = SDL.DAG.getRoot();
- std::vector<SDOperand> Args = TLI.LowerArguments(F, SDL.DAG);
+ SmallVector<SDOperand, 16> Args;
+ TLI.LowerArguments(F, SDL.DAG, Args);
unsigned a = 0;
for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
- AI != E; ++AI, ++a)
+ AI != E; ++AI) {
+ SmallVector<MVT, 4> ValueVTs;
+ ComputeValueVTs(TLI, AI->getType(), ValueVTs);
+ unsigned NumValues = ValueVTs.size();
if (!AI->use_empty()) {
- SDL.setValue(AI, Args[a]);
-
+ 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);
SDL.CopyValueToVirtualRegister(AI, VMI->second);
}
}
+ a += NumValues;
+ }
// Finally, if the target has anything special to do, allow it to do so.
// FIXME: this should insert code into the DAG!
// 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();
CheckDAGForTailCallsAndFixThem(DAG, TLI);
}
+void SelectionDAGISel::ComputeLiveOutVRegInfo(SelectionDAG &DAG) {
+ SmallPtrSet<SDNode*, 128> VisitedNodes;
+ SmallVector<SDNode*, 128> Worklist;
+
+ Worklist.push_back(DAG.getRoot().Val);
+
+ APInt Mask;
+ APInt KnownZero;
+ APInt KnownOne;
+
+ while (!Worklist.empty()) {
+ SDNode *N = Worklist.back();
+ Worklist.pop_back();
+
+ // If we've already seen this node, ignore it.
+ if (!VisitedNodes.insert(N))
+ continue;
+
+ // Otherwise, add all chain operands to the worklist.
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+ if (N->getOperand(i).getValueType() == MVT::Other)
+ Worklist.push_back(N->getOperand(i).Val);
+
+ // If this is a CopyToReg with a vreg dest, process it.
+ if (N->getOpcode() != ISD::CopyToReg)
+ continue;
+
+ unsigned DestReg = cast<RegisterSDNode>(N->getOperand(1))->getReg();
+ if (!TargetRegisterInfo::isVirtualRegister(DestReg))
+ continue;
+
+ // Ignore non-scalar or non-integer values.
+ SDOperand Src = N->getOperand(2);
+ MVT SrcVT = Src.getValueType();
+ if (!SrcVT.isInteger() || SrcVT.isVector())
+ continue;
+
+ unsigned NumSignBits = DAG.ComputeNumSignBits(Src);
+ Mask = APInt::getAllOnesValue(SrcVT.getSizeInBits());
+ DAG.ComputeMaskedBits(Src, Mask, KnownZero, KnownOne);
+
+ // Only install this information if it tells us something.
+ if (NumSignBits != 1 || KnownZero != 0 || KnownOne != 0) {
+ DestReg -= TargetRegisterInfo::FirstVirtualRegister;
+ FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo();
+ if (DestReg >= FLI.LiveOutRegInfo.size())
+ FLI.LiveOutRegInfo.resize(DestReg+1);
+ FunctionLoweringInfo::LiveOutInfo &LOI = FLI.LiveOutRegInfo[DestReg];
+ LOI.NumSignBits = NumSignBits;
+ LOI.KnownOne = NumSignBits;
+ LOI.KnownZero = NumSignBits;
+ }
+ }
+}
+
void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) {
DOUT << "Lowered selection DAG:\n";
DEBUG(DAG.dump());
// Run the DAG combiner in pre-legalize mode.
- DAG.Combine(false, *AA);
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("DAG Combining 1");
+ 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");
+ 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");
+ DAG.Combine(true, *AA);
+ } else {
+ DAG.Combine(true, *AA);
+ }
DOUT << "Optimized legalized selection DAG:\n";
DEBUG(DAG.dump());
if (ViewISelDAGs) DAG.viewGraph();
+
+ if (!FastISel && EnableValueProp)
+ ComputeLiveOutVRegInfo(DAG);
// Third, instruction select all of the operations to machine code, adding the
// code to the MachineBasicBlock.
- InstructionSelectBasicBlock(DAG);
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Selection");
+ InstructionSelect(DAG);
+ } else {
+ InstructionSelect(DAG);
+ }
+
+ // Emit machine code to BB. This can change 'BB' to the last block being
+ // inserted into.
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Scheduling");
+ ScheduleAndEmitDAG(DAG);
+ } else {
+ ScheduleAndEmitDAG(DAG);
+ }
+
+ // Perform target specific isel post processing.
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Selection Post Processing");
+ 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, getAnalysisToUpdate<MachineModuleInfo>());
+ SelectionDAG DAG(TLI, MF, FuncInfo,
+ getAnalysisToUpdate<MachineModuleInfo>(),
+ AllNodes);
CurDAG = &DAG;
// First step, lower LLVM code to some DAG. This DAG may use operations and
for (unsigned i = 0, e = BitTestCases.size(); i != e; ++i) {
// Lower header first, if it wasn't already lowered
if (!BitTestCases[i].Emitted) {
- SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+ SelectionDAG HSDAG(TLI, MF, FuncInfo,
+ 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, getAnalysisToUpdate<MachineModuleInfo>());
+ SelectionDAG BSDAG(TLI, MF, FuncInfo,
+ 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
for (unsigned i = 0, e = JTCases.size(); i != e; ++i) {
// Lower header first, if it wasn't already lowered
if (!JTCases[i].first.Emitted) {
- SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+ SelectionDAG HSDAG(TLI, MF, FuncInfo,
+ 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
CodeGenAndEmitDAG(HSDAG);
}
- SelectionDAG JSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+ SelectionDAG JSDAG(TLI, MF, FuncInfo,
+ 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
// If we generated any switch lowering information, build and codegen any
// additional DAGs necessary.
for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) {
- SelectionDAG SDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+ SelectionDAG SDAG(TLI, MF, FuncInfo,
+ getAnalysisToUpdate<MachineModuleInfo>(),
+ AllNodes);
CurDAG = &SDAG;
SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo, GCI);
RegisterScheduler::setDefault(Ctor);
}
- ScheduleDAG *SL = Ctor(this, &DAG, BB);
+ ScheduleDAG *SL = Ctor(this, &DAG, BB, FastISel);
BB = SL->Run();
if (ViewSUnitDAGs) SL->viewGraph();