#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
cl::desc("Pop up a window to show sched dags as they are processed"));
static cl::opt<bool>
ViewSUnitDAGs("view-sunit-dags", cl::Hidden,
- cl::desc("Pop up a window to show SUnit dags after they are processed"));
+ cl::desc("Pop up a window to show SUnit dags after they are processed"));
#else
static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0, ViewSUnitDAGs = 0;
#endif
RegisterPassParser<RegisterScheduler> >
ISHeuristic("pre-RA-sched",
cl::init(&createDefaultScheduler),
- cl::desc("Instruction schedulers available (before register allocation):"));
+ cl::desc("Instruction schedulers available (before register"
+ " allocation):"));
static RegisterScheduler
defaultListDAGScheduler("default", " Best scheduler for the target",
void visitMemIntrinsic(CallInst &I, unsigned Op);
+ void visitGetResult(GetResultInst &I) {
+ // FIXME
+ }
+
void visitUserOp1(Instruction &I) {
assert(0 && "UserOp1 should not exist at instruction selection time!");
abort();
} // end namespace llvm
-/// getCopyFromParts - Create a value that contains the
-/// specified legal parts combined into the value they represent.
+/// getCopyFromParts - Create a value that contains the specified legal parts
+/// combined into the value they represent. If the parts combine to a type
+/// larger then ValueVT then AssertOp can be used to specify whether the extra
+/// bits are known to be zero (ISD::AssertZext) or sign extended from ValueVT
+/// (ISD::AssertSext). Likewise TruncExact is used for floating point types to
+/// indicate that the extra bits can be discarded without losing precision.
static SDOperand getCopyFromParts(SelectionDAG &DAG,
const SDOperand *Parts,
unsigned NumParts,
MVT::ValueType PartVT,
MVT::ValueType ValueVT,
- ISD::NodeType AssertOp = ISD::DELETED_NODE) {
- if (!MVT::isVector(ValueVT) || NumParts == 1) {
- SDOperand Val = Parts[0];
-
- // If the value was expanded, copy from the top part.
- if (NumParts > 1) {
- assert(NumParts == 2 &&
- "Cannot expand to more than 2 elts yet!");
- SDOperand Hi = Parts[1];
- if (!DAG.getTargetLoweringInfo().isLittleEndian())
- std::swap(Val, Hi);
- return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi);
- }
-
- // Otherwise, if the value was promoted or extended, truncate it to the
- // appropriate type.
- if (PartVT == ValueVT)
- return Val;
-
- if (MVT::isVector(PartVT)) {
- assert(MVT::isVector(ValueVT) && "Unknown vector conversion!");
- return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
- }
-
- if (MVT::isVector(ValueVT)) {
- assert(NumParts == 1 &&
- MVT::getVectorElementType(ValueVT) == PartVT &&
- MVT::getVectorNumElements(ValueVT) == 1 &&
- "Only trivial scalar-to-vector conversions should get here!");
- return DAG.getNode(ISD::BUILD_VECTOR, ValueVT, Val);
- }
-
- if (MVT::isInteger(PartVT) &&
- MVT::isInteger(ValueVT)) {
- if (ValueVT < PartVT) {
- // For a truncate, see if we have any information to
- // indicate whether the truncated bits will always be
- // zero or sign-extension.
- if (AssertOp != ISD::DELETED_NODE)
- Val = DAG.getNode(AssertOp, PartVT, Val,
- DAG.getValueType(ValueVT));
- return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+ ISD::NodeType AssertOp = ISD::DELETED_NODE,
+ bool TruncExact = false) {
+ assert(NumParts > 0 && "No parts to assemble!");
+ TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ SDOperand Val = Parts[0];
+
+ if (NumParts > 1) {
+ // Assemble the value from multiple parts.
+ if (!MVT::isVector(ValueVT)) {
+ unsigned PartBits = MVT::getSizeInBits(PartVT);
+ unsigned ValueBits = MVT::getSizeInBits(ValueVT);
+
+ // Assemble the power of 2 part.
+ unsigned RoundParts = NumParts & (NumParts - 1) ?
+ 1 << Log2_32(NumParts) : NumParts;
+ unsigned RoundBits = PartBits * RoundParts;
+ MVT::ValueType RoundVT = RoundBits == ValueBits ?
+ ValueVT : MVT::getIntegerType(RoundBits);
+ SDOperand Lo, Hi;
+
+ if (RoundParts > 2) {
+ MVT::ValueType HalfVT = MVT::getIntegerType(RoundBits/2);
+ Lo = getCopyFromParts(DAG, Parts, RoundParts/2, PartVT, HalfVT);
+ Hi = getCopyFromParts(DAG, Parts+RoundParts/2, RoundParts/2,
+ PartVT, HalfVT);
} else {
- return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
+ Lo = Parts[0];
+ Hi = Parts[1];
}
+ if (TLI.isBigEndian())
+ std::swap(Lo, Hi);
+ Val = DAG.getNode(ISD::BUILD_PAIR, RoundVT, Lo, Hi);
+
+ if (RoundParts < NumParts) {
+ // Assemble the trailing non-power-of-2 part.
+ unsigned OddParts = NumParts - RoundParts;
+ MVT::ValueType OddVT = MVT::getIntegerType(OddParts * PartBits);
+ Hi = getCopyFromParts(DAG, Parts+RoundParts, OddParts, PartVT, OddVT);
+
+ // Combine the round and odd parts.
+ Lo = Val;
+ if (TLI.isBigEndian())
+ std::swap(Lo, Hi);
+ MVT::ValueType TotalVT = MVT::getIntegerType(NumParts * PartBits);
+ Hi = DAG.getNode(ISD::ANY_EXTEND, TotalVT, Hi);
+ Hi = DAG.getNode(ISD::SHL, TotalVT, Hi,
+ DAG.getConstant(MVT::getSizeInBits(Lo.getValueType()),
+ TLI.getShiftAmountTy()));
+ Lo = DAG.getNode(ISD::ZERO_EXTEND, TotalVT, Lo);
+ Val = DAG.getNode(ISD::OR, TotalVT, Lo, Hi);
+ }
+ } else {
+ // Handle a multi-element vector.
+ MVT::ValueType IntermediateVT, RegisterVT;
+ unsigned NumIntermediates;
+ unsigned NumRegs =
+ TLI.getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
+ RegisterVT);
+
+ assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
+ assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
+ assert(RegisterVT == Parts[0].getValueType() &&
+ "Part type doesn't match part!");
+
+ // Assemble the parts into intermediate operands.
+ SmallVector<SDOperand, 8> Ops(NumIntermediates);
+ if (NumIntermediates == NumParts) {
+ // If the register was not expanded, truncate or copy the value,
+ // as appropriate.
+ for (unsigned i = 0; i != NumParts; ++i)
+ Ops[i] = getCopyFromParts(DAG, &Parts[i], 1,
+ PartVT, IntermediateVT);
+ } else if (NumParts > 0) {
+ // If the intermediate type was expanded, build the intermediate operands
+ // from the parts.
+ assert(NumParts % NumIntermediates == 0 &&
+ "Must expand into a divisible number of parts!");
+ unsigned Factor = NumParts / NumIntermediates;
+ for (unsigned i = 0; i != NumIntermediates; ++i)
+ Ops[i] = getCopyFromParts(DAG, &Parts[i * Factor], Factor,
+ PartVT, IntermediateVT);
+ }
+
+ // Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the intermediate
+ // operands.
+ Val = DAG.getNode(MVT::isVector(IntermediateVT) ?
+ ISD::CONCAT_VECTORS : ISD::BUILD_VECTOR,
+ ValueVT, &Ops[0], NumIntermediates);
}
-
- if (MVT::isFloatingPoint(PartVT) && MVT::isFloatingPoint(ValueVT))
- return DAG.getNode(ISD::FP_ROUND, ValueVT, Val, DAG.getIntPtrConstant(0));
+ }
- if (MVT::getSizeInBits(PartVT) == MVT::getSizeInBits(ValueVT))
- return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
+ // There is now one part, held in Val. Correct it to match ValueVT.
+ PartVT = Val.getValueType();
- assert(0 && "Unknown mismatch!");
- }
+ if (PartVT == ValueVT)
+ return Val;
- // Handle a multi-element vector.
- MVT::ValueType IntermediateVT, RegisterVT;
- unsigned NumIntermediates;
- unsigned NumRegs =
- DAG.getTargetLoweringInfo()
- .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
- RegisterVT);
+ if (MVT::isVector(PartVT)) {
+ assert(MVT::isVector(ValueVT) && "Unknown vector conversion!");
+ return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
+ }
- assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
- assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
- assert(RegisterVT == Parts[0].getValueType() &&
- "Part type doesn't match part!");
+ if (MVT::isVector(ValueVT)) {
+ assert(MVT::getVectorElementType(ValueVT) == PartVT &&
+ MVT::getVectorNumElements(ValueVT) == 1 &&
+ "Only trivial scalar-to-vector conversions should get here!");
+ return DAG.getNode(ISD::BUILD_VECTOR, ValueVT, Val);
+ }
- // Assemble the parts into intermediate operands.
- SmallVector<SDOperand, 8> Ops(NumIntermediates);
- if (NumIntermediates == NumParts) {
- // If the register was not expanded, truncate or copy the value,
- // as appropriate.
- for (unsigned i = 0; i != NumParts; ++i)
- Ops[i] = getCopyFromParts(DAG, &Parts[i], 1,
- PartVT, IntermediateVT);
- } else if (NumParts > 0) {
- // If the intermediate type was expanded, build the intermediate operands
- // from the parts.
- assert(NumParts % NumIntermediates == 0 &&
- "Must expand into a divisible number of parts!");
- unsigned Factor = NumParts / NumIntermediates;
- for (unsigned i = 0; i != NumIntermediates; ++i)
- Ops[i] = getCopyFromParts(DAG, &Parts[i * Factor], Factor,
- PartVT, IntermediateVT);
+ if (MVT::isInteger(PartVT) &&
+ MVT::isInteger(ValueVT)) {
+ if (MVT::getSizeInBits(ValueVT) < MVT::getSizeInBits(PartVT)) {
+ // For a truncate, see if we have any information to
+ // indicate whether the truncated bits will always be
+ // zero or sign-extension.
+ if (AssertOp != ISD::DELETED_NODE)
+ Val = DAG.getNode(AssertOp, PartVT, Val,
+ DAG.getValueType(ValueVT));
+ return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+ } else {
+ return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
+ }
}
-
- // Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the intermediate
- // operands.
- return DAG.getNode(MVT::isVector(IntermediateVT) ?
- ISD::CONCAT_VECTORS :
- ISD::BUILD_VECTOR,
- ValueVT, &Ops[0], NumIntermediates);
+
+ if (MVT::isFloatingPoint(PartVT) && MVT::isFloatingPoint(ValueVT))
+ return DAG.getNode(ISD::FP_ROUND, ValueVT, Val,
+ DAG.getIntPtrConstant(TruncExact));
+
+ if (MVT::getSizeInBits(PartVT) == MVT::getSizeInBits(ValueVT))
+ return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
+
+ assert(0 && "Unknown mismatch!");
}
-/// getCopyToParts - Create a series of nodes that contain the
-/// specified value split into legal parts.
+/// getCopyToParts - Create a series of nodes that contain the specified value
+/// split into legal parts. If the parts contain more bits than Val, then, for
+/// integers, ExtendKind can be used to specify how to generate the extra bits.
static void getCopyToParts(SelectionDAG &DAG,
SDOperand Val,
SDOperand *Parts,
unsigned NumParts,
- MVT::ValueType PartVT) {
+ MVT::ValueType PartVT,
+ ISD::NodeType ExtendKind = ISD::ANY_EXTEND) {
TargetLowering &TLI = DAG.getTargetLoweringInfo();
MVT::ValueType PtrVT = TLI.getPointerTy();
MVT::ValueType ValueVT = Val.getValueType();
+ unsigned PartBits = MVT::getSizeInBits(PartVT);
+ assert(TLI.isTypeLegal(PartVT) && "Copying to an illegal type!");
+
+ if (!NumParts)
+ return;
- if (!MVT::isVector(ValueVT) || NumParts == 1) {
- // If the value was expanded, copy from the parts.
- if (NumParts > 1) {
- for (unsigned i = 0; i != NumParts; ++i)
- Parts[i] = DAG.getNode(ISD::EXTRACT_ELEMENT, PartVT, Val,
- DAG.getConstant(i, PtrVT));
- if (!DAG.getTargetLoweringInfo().isLittleEndian())
- std::reverse(Parts, Parts + NumParts);
+ if (!MVT::isVector(ValueVT)) {
+ if (PartVT == ValueVT) {
+ assert(NumParts == 1 && "No-op copy with multiple parts!");
+ Parts[0] = Val;
return;
}
- // If there is a single part and the types differ, this must be
- // a promotion.
+ if (NumParts * PartBits > MVT::getSizeInBits(ValueVT)) {
+ // If the parts cover more bits than the value has, promote the value.
+ if (MVT::isFloatingPoint(PartVT) && MVT::isFloatingPoint(ValueVT)) {
+ assert(NumParts == 1 && "Do not know what to promote to!");
+ Val = DAG.getNode(ISD::FP_EXTEND, PartVT, Val);
+ } else if (MVT::isInteger(PartVT) && MVT::isInteger(ValueVT)) {
+ ValueVT = MVT::getIntegerType(NumParts * PartBits);
+ Val = DAG.getNode(ExtendKind, ValueVT, Val);
+ } else {
+ assert(0 && "Unknown mismatch!");
+ }
+ } else if (PartBits == MVT::getSizeInBits(ValueVT)) {
+ // Different types of the same size.
+ assert(NumParts == 1 && PartVT != ValueVT);
+ Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+ } else if (NumParts * PartBits < MVT::getSizeInBits(ValueVT)) {
+ // If the parts cover less bits than value has, truncate the value.
+ if (MVT::isInteger(PartVT) && MVT::isInteger(ValueVT)) {
+ ValueVT = MVT::getIntegerType(NumParts * PartBits);
+ Val = DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+ } else {
+ assert(0 && "Unknown mismatch!");
+ }
+ }
+
+ // The value may have changed - recompute ValueVT.
+ ValueVT = Val.getValueType();
+ assert(NumParts * PartBits == MVT::getSizeInBits(ValueVT) &&
+ "Failed to tile the value with PartVT!");
+
+ if (NumParts == 1) {
+ assert(PartVT == ValueVT && "Type conversion failed!");
+ Parts[0] = Val;
+ return;
+ }
+
+ // Expand the value into multiple parts.
+ if (NumParts & (NumParts - 1)) {
+ // The number of parts is not a power of 2. Split off and copy the tail.
+ assert(MVT::isInteger(PartVT) && MVT::isInteger(ValueVT) &&
+ "Do not know what to expand to!");
+ unsigned RoundParts = 1 << Log2_32(NumParts);
+ unsigned RoundBits = RoundParts * PartBits;
+ unsigned OddParts = NumParts - RoundParts;
+ SDOperand OddVal = DAG.getNode(ISD::SRL, ValueVT, Val,
+ DAG.getConstant(RoundBits,
+ TLI.getShiftAmountTy()));
+ getCopyToParts(DAG, OddVal, Parts + RoundParts, OddParts, PartVT);
+ if (TLI.isBigEndian())
+ // The odd parts were reversed by getCopyToParts - unreverse them.
+ std::reverse(Parts + RoundParts, Parts + NumParts);
+ NumParts = RoundParts;
+ ValueVT = MVT::getIntegerType(NumParts * PartBits);
+ Val = DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+ }
+
+ // The number of parts is a power of 2. Repeatedly bisect the value using
+ // EXTRACT_ELEMENT.
+ Parts[0] = Val;
+ for (unsigned StepSize = NumParts; StepSize > 1; StepSize /= 2) {
+ for (unsigned i = 0; i < NumParts; i += StepSize) {
+ unsigned ThisBits = StepSize * PartBits / 2;
+ MVT::ValueType ThisVT =
+ ThisBits == PartBits ? PartVT : MVT::getIntegerType (ThisBits);
+
+ Parts[i+StepSize/2] =
+ DAG.getNode(ISD::EXTRACT_ELEMENT, ThisVT, Parts[i],
+ DAG.getConstant(1, PtrVT));
+ Parts[i] =
+ DAG.getNode(ISD::EXTRACT_ELEMENT, ThisVT, Parts[i],
+ DAG.getConstant(0, PtrVT));
+ }
+ }
+
+ if (TLI.isBigEndian())
+ std::reverse(Parts, Parts + NumParts);
+
+ return;
+ }
+
+ // Vector ValueVT.
+ if (NumParts == 1) {
if (PartVT != ValueVT) {
if (MVT::isVector(PartVT)) {
- assert(MVT::isVector(ValueVT) &&
- "Not a vector-vector cast?");
Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
- } else if (MVT::isVector(ValueVT)) {
- assert(NumParts == 1 &&
- MVT::getVectorElementType(ValueVT) == PartVT &&
+ } else {
+ assert(MVT::getVectorElementType(ValueVT) == PartVT &&
MVT::getVectorNumElements(ValueVT) == 1 &&
"Only trivial vector-to-scalar conversions should get here!");
Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, PartVT, Val,
DAG.getConstant(0, PtrVT));
- } else if (MVT::isInteger(PartVT) && MVT::isInteger(ValueVT)) {
- if (PartVT < ValueVT)
- Val = DAG.getNode(ISD::TRUNCATE, PartVT, Val);
- else
- Val = DAG.getNode(ISD::ANY_EXTEND, PartVT, Val);
- } else if (MVT::isFloatingPoint(PartVT) &&
- MVT::isFloatingPoint(ValueVT)) {
- Val = DAG.getNode(ISD::FP_EXTEND, PartVT, Val);
- } else if (MVT::getSizeInBits(PartVT) ==
- MVT::getSizeInBits(ValueVT)) {
- Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
- } else {
- assert(0 && "Unknown mismatch!");
}
}
+
Parts[0] = Val;
return;
}
NewValues.push_back(getRoot());
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
SDOperand RetOp = getValue(I.getOperand(i));
-
- // If this is an integer return value, we need to promote it ourselves to
- // the full width of a register, since getCopyToParts and Legalize will use
- // ANY_EXTEND rather than sign/zero.
+ MVT::ValueType 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 (MVT::isInteger(RetOp.getValueType()) &&
- RetOp.getValueType() < MVT::i64) {
- MVT::ValueType TmpVT;
- if (TLI.getTypeAction(MVT::i32) == TargetLowering::Promote)
- TmpVT = TLI.getTypeToTransformTo(MVT::i32);
- else
- TmpVT = MVT::i32;
- const Function *F = I.getParent()->getParent();
- ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
- if (F->paramHasAttr(0, ParamAttr::SExt))
- ExtendKind = ISD::SIGN_EXTEND;
- if (F->paramHasAttr(0, ParamAttr::ZExt))
- ExtendKind = ISD::ZERO_EXTEND;
- RetOp = DAG.getNode(ExtendKind, TmpVT, RetOp);
- NewValues.push_back(RetOp);
+ if (MVT::isInteger(VT)) {
+ MVT::ValueType MinVT = TLI.getRegisterType(MVT::i32);
+ if (MVT::getSizeInBits(VT) < MVT::getSizeInBits(MinVT))
+ VT = MinVT;
+ }
+
+ unsigned NumParts = TLI.getNumRegisters(VT);
+ MVT::ValueType 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);
+
+ for (unsigned i = 0; i < NumParts; ++i) {
+ NewValues.push_back(Parts[i]);
NewValues.push_back(DAG.getConstant(false, MVT::i32));
- } else {
- MVT::ValueType VT = RetOp.getValueType();
- unsigned NumParts = TLI.getNumRegisters(VT);
- MVT::ValueType PartVT = TLI.getRegisterType(VT);
- SmallVector<SDOperand, 4> Parts(NumParts);
- getCopyToParts(DAG, RetOp, &Parts[0], NumParts, PartVT);
- for (unsigned i = 0; i < NumParts; ++i) {
- NewValues.push_back(Parts[i]);
- NewValues.push_back(DAG.getConstant(false, MVT::i32));
- }
}
}
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
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(LabelID, MVT::i32),
+ DAG.getConstant(0, MVT::i32)));
}
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.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
+ DAG.getConstant(LabelID, MVT::i32),
+ DAG.getConstant(0, MVT::i32)));
}
return 0;
}
case Intrinsic::dbg_func_start: {
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ if (!MMI) return 0;
DbgFuncStartInst &FSI = cast<DbgFuncStartInst>(I);
- if (MMI && FSI.getSubprogram() &&
- MMI->Verify(FSI.getSubprogram())) {
- unsigned LabelID = MMI->RecordRegionStart(FSI.getSubprogram());
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other,
- getRoot(), DAG.getConstant(LabelID, MVT::i32)));
+ Value *SP = FSI.getSubprogram();
+ if (SP && MMI->Verify(SP)) {
+ // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is
+ // what (most?) gdb expects.
+ DebugInfoDesc *DD = MMI->getDescFor(SP);
+ 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());
+ // Record the source line but does create a label. It will be emitted
+ // at asm emission time.
+ MMI->RecordSourceLine(Subprogram->getLine(), 0, SrcFile);
}
return 0;
case Intrinsic::dbg_declare: {
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
- if (MMI && DI.getVariable() && MMI->Verify(DI.getVariable())) {
- SDOperand AddressOp = getValue(DI.getAddress());
- if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(AddressOp))
- MMI->RecordVariable(DI.getVariable(), FI->getIndex());
- }
-
+ Value *Variable = DI.getVariable();
+ if (MMI && Variable && MMI->Verify(Variable))
+ DAG.setRoot(DAG.getNode(ISD::DECLARE, MVT::Other, getRoot(),
+ getValue(DI.getAddress()), getValue(Variable)));
return 0;
}
return 0;
case Intrinsic::flt_rounds: {
- setValue(&I, DAG.getNode(ISD::FLT_ROUNDS, MVT::i32));
+ setValue(&I, DAG.getNode(ISD::FLT_ROUNDS_, MVT::i32));
return 0;
}
DAG.setRoot(DAG.getNode(ISD::TRAP, MVT::Other, getRoot()));
return 0;
}
+ case Intrinsic::memory_barrier: {
+ SDOperand Ops[6];
+ Ops[0] = getRoot();
+ for (int x = 1; x < 6; ++x)
+ Ops[x] = getValue(I.getOperand(x));
+
+ DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, MVT::Other, &Ops[0], 6));
+ return 0;
+ }
}
}
// used to detect deletion of the invoke via the MachineModuleInfo.
BeginLabel = MMI->NextLabelID();
DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
- DAG.getConstant(BeginLabel, MVT::i32)));
+ DAG.getConstant(BeginLabel, MVT::i32),
+ DAG.getConstant(1, MVT::i32)));
}
std::pair<SDOperand,SDOperand> Result =
TLI.LowerCallTo(getRoot(), CS.getType(),
CS.paramHasAttr(0, ParamAttr::SExt),
+ CS.paramHasAttr(0, ParamAttr::ZExt),
FTy->isVarArg(), CS.getCallingConv(), IsTailCall,
Callee, Args, DAG);
if (CS.getType() != Type::VoidTy)
// 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(EndLabel, MVT::i32),
+ DAG.getConstant(1, MVT::i32)));
// Inform MachineModuleInfo of range.
MMI->addInvoke(LandingPad, BeginLabel, EndLabel);
/// register class for the register. Otherwise, return null.
static const TargetRegisterClass *
isAllocatableRegister(unsigned Reg, MachineFunction &MF,
- const TargetLowering &TLI, const MRegisterInfo *MRI) {
+ const TargetLowering &TLI,
+ const TargetRegisterInfo *TRI) {
MVT::ValueType FoundVT = MVT::Other;
const TargetRegisterClass *FoundRC = 0;
- for (MRegisterInfo::regclass_iterator RCI = MRI->regclass_begin(),
- E = MRI->regclass_end(); RCI != E; ++RCI) {
+ for (TargetRegisterInfo::regclass_iterator RCI = TRI->regclass_begin(),
+ E = TRI->regclass_end(); RCI != E; ++RCI) {
MVT::ValueType ThisVT = MVT::Other;
const TargetRegisterClass *RC = *RCI;
if (Codes.size() == 1) { // Single-letter constraints ('r') are very common.
ConstraintCode = *Current;
ConstraintType = CurType;
- return;
+ } else {
+ unsigned CurGenerality = getConstraintGenerality(CurType);
+
+ // If we have multiple constraints, try to pick the most general one ahead
+ // of time. This isn't a wonderful solution, but handles common cases.
+ for (unsigned j = 1, e = Codes.size(); j != e; ++j) {
+ TargetLowering::ConstraintType ThisType = TLI.getConstraintType(Codes[j]);
+ unsigned ThisGenerality = getConstraintGenerality(ThisType);
+ if (ThisGenerality > CurGenerality) {
+ // This constraint letter is more general than the previous one,
+ // use it.
+ CurType = ThisType;
+ Current = &Codes[j];
+ CurGenerality = ThisGenerality;
+ }
+ }
+
+ ConstraintCode = *Current;
+ ConstraintType = CurType;
}
-
- unsigned CurGenerality = getConstraintGenerality(CurType);
-
- // If we have multiple constraints, try to pick the most general one ahead
- // of time. This isn't a wonderful solution, but handles common cases.
- for (unsigned j = 1, e = Codes.size(); j != e; ++j) {
- TargetLowering::ConstraintType ThisType = TLI.getConstraintType(Codes[j]);
- unsigned ThisGenerality = getConstraintGenerality(ThisType);
- if (ThisGenerality > CurGenerality) {
- // This constraint letter is more general than the previous one,
- // use it.
- CurType = ThisType;
- Current = &Codes[j];
- CurGenerality = ThisGenerality;
+
+ if (ConstraintCode == "X") {
+ if (isa<BasicBlock>(CallOperandVal) || isa<ConstantInt>(CallOperandVal))
+ return;
+ // This matches anything. Labels and constants we handle elsewhere
+ // ('X' is the only thing that matches labels). Otherwise, try to
+ // resolve it to something we know about by looking at the actual
+ // operand type.
+ std::string s = "";
+ TLI.lowerXConstraint(ConstraintVT, s);
+ if (s!="") {
+ ConstraintCode = s;
+ ConstraintType = TLI.getConstraintType(ConstraintCode);
}
}
-
- ConstraintCode = *Current;
- ConstraintType = CurType;
}
OpInfo.ConstraintVT);
}
- const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo();
+ const TargetRegisterInfo *TRI = DAG.getTarget().getRegisterInfo();
unsigned NumAllocated = 0;
for (unsigned i = 0, e = RegClassRegs.size(); i != e; ++i) {
unsigned Reg = RegClassRegs[i];
// Check to see if this register is allocatable (i.e. don't give out the
// stack pointer).
if (RC == 0) {
- RC = isAllocatableRegister(Reg, MF, TLI, MRI);
+ RC = isAllocatableRegister(Reg, MF, TLI, TRI);
if (!RC) { // Couldn't allocate this register.
// Reset NumAllocated to make sure we return consecutive registers.
NumAllocated = 0;
if (OpInfo.CallOperandVal) {
if (isa<BasicBlock>(OpInfo.CallOperandVal))
OpInfo.CallOperand =
- DAG.getBasicBlock(FuncInfo.MBBMap[cast<BasicBlock>(OpInfo.CallOperandVal)]);
+ DAG.getBasicBlock(FuncInfo.MBBMap[cast<BasicBlock>(
+ OpInfo.CallOperandVal)]);
else {
OpInfo.CallOperand = getValue(OpInfo.CallOperandVal);
const Type *OpTy = OpInfo.CallOperandVal->getType();
Args.push_back(Entry);
std::pair<SDOperand,SDOperand> Result =
- TLI.LowerCallTo(getRoot(), I.getType(), false, false, CallingConv::C, true,
- DAG.getExternalSymbol("malloc", IntPtr),
- Args, DAG);
+ TLI.LowerCallTo(getRoot(), I.getType(), false, false, false, CallingConv::C,
+ true, DAG.getExternalSymbol("malloc", IntPtr), Args, DAG);
setValue(&I, Result.first); // Pointers always fit in registers
DAG.setRoot(Result.second);
}
Args.push_back(Entry);
MVT::ValueType IntPtr = TLI.getPointerTy();
std::pair<SDOperand,SDOperand> Result =
- TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, CallingConv::C, true,
+ TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, false,
+ CallingConv::C, true,
DAG.getExternalSymbol("free", IntPtr), Args, DAG);
DAG.setRoot(Result.second);
}
-// InsertAtEndOfBasicBlock - This method should be implemented by targets that
-// mark instructions with the 'usesCustomDAGSchedInserter' flag. These
+// EmitInstrWithCustomInserter - This method should be implemented by targets
+// that mark instructions with the 'usesCustomDAGSchedInserter' flag. These
// instructions are special in various ways, which require special support to
// 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::InsertAtEndOfBasicBlock(MachineInstr *MI,
+MachineBasicBlock *TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *MBB) {
cerr << "If a target marks an instruction with "
<< "'usesCustomDAGSchedInserter', it must implement "
- << "TargetLowering::InsertAtEndOfBasicBlock!\n";
+ << "TargetLowering::EmitInstrWithCustomInserter!\n";
abort();
return 0;
}
if (F.paramHasAttr(j, ParamAttr::Nest))
Flags |= ISD::ParamFlags::Nest;
Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs);
-
- switch (getTypeAction(VT)) {
- default: assert(0 && "Unknown type action!");
- case Legal:
- RetVals.push_back(VT);
- Ops.push_back(DAG.getConstant(Flags, MVT::i32));
- break;
- case Promote:
- RetVals.push_back(getTypeToTransformTo(VT));
+
+ MVT::ValueType RegisterVT = getRegisterType(VT);
+ unsigned NumRegs = getNumRegisters(VT);
+ for (unsigned i = 0; i != NumRegs; ++i) {
+ RetVals.push_back(RegisterVT);
+ // if it isn't first piece, alignment must be 1
+ if (i > 0)
+ Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
+ (1 << ISD::ParamFlags::OrigAlignmentOffs);
Ops.push_back(DAG.getConstant(Flags, MVT::i32));
- break;
- case Expand: {
- // If this is an illegal type, it needs to be broken up to fit into
- // registers.
- MVT::ValueType RegisterVT = getRegisterType(VT);
- unsigned NumRegs = getNumRegisters(VT);
- for (unsigned i = 0; i != NumRegs; ++i) {
- RetVals.push_back(RegisterVT);
- // if it isn't first piece, alignment must be 1
- if (i > 0)
- Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
- (1 << ISD::ParamFlags::OrigAlignmentOffs);
- Ops.push_back(DAG.getConstant(Flags, MVT::i32));
- }
- break;
- }
}
}
// Create the node.
SDNode *Result = DAG.getNode(ISD::FORMAL_ARGUMENTS,
- DAG.getNodeValueTypes(RetVals), RetVals.size(),
+ DAG.getVTList(&RetVals[0], RetVals.size()),
&Ops[0], Ops.size()).Val;
+
+ // Prelower FORMAL_ARGUMENTS. This isn't required for functionality, but
+ // allows exposing the loads that may be part of the argument access to the
+ // first DAGCombiner pass.
+ SDOperand TmpRes = LowerOperation(SDOperand(Result, 0), DAG);
+
+ // The number of results should match up, except that the lowered one may have
+ // an extra flag result.
+ assert((Result->getNumValues() == TmpRes.Val->getNumValues() ||
+ (Result->getNumValues()+1 == TmpRes.Val->getNumValues() &&
+ TmpRes.getValue(Result->getNumValues()).getValueType() == MVT::Flag))
+ && "Lowering produced unexpected number of results!");
+ Result = TmpRes.Val;
+
unsigned NumArgRegs = Result->getNumValues() - 1;
DAG.setRoot(SDOperand(Result, NumArgRegs));
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E;
++I, ++Idx) {
MVT::ValueType VT = getValueType(I->getType());
-
- switch (getTypeAction(VT)) {
- default: assert(0 && "Unknown type action!");
- case Legal:
- Ops.push_back(SDOperand(Result, i++));
- break;
- case Promote: {
- SDOperand Op(Result, i++);
- if (MVT::isInteger(VT)) {
- if (F.paramHasAttr(Idx, ParamAttr::SExt))
- Op = DAG.getNode(ISD::AssertSext, Op.getValueType(), Op,
- DAG.getValueType(VT));
- else if (F.paramHasAttr(Idx, ParamAttr::ZExt))
- Op = DAG.getNode(ISD::AssertZext, Op.getValueType(), Op,
- DAG.getValueType(VT));
- Op = DAG.getNode(ISD::TRUNCATE, VT, Op);
- } else {
- assert(MVT::isFloatingPoint(VT) && "Not int or FP?");
- Op = DAG.getNode(ISD::FP_ROUND, VT, Op, DAG.getIntPtrConstant(1));
- }
- Ops.push_back(Op);
- break;
- }
- case Expand: {
- MVT::ValueType PartVT = getRegisterType(VT);
- unsigned NumParts = getNumRegisters(VT);
- SmallVector<SDOperand, 4> Parts(NumParts);
- for (unsigned j = 0; j != NumParts; ++j)
- Parts[j] = SDOperand(Result, i++);
- Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT));
- break;
- }
- }
+ MVT::ValueType 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, true));
}
assert(i == NumArgRegs && "Argument register count mismatch!");
return Ops;
/// lowered by the target to something concrete. FIXME: When all targets are
/// migrated to using ISD::CALL, this hook should be integrated into SDISel.
std::pair<SDOperand, SDOperand>
-TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
- bool RetTyIsSigned, bool isVarArg,
- unsigned CallingConv, bool isTailCall,
+TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
+ bool RetSExt, bool RetZExt, bool isVarArg,
+ unsigned CallingConv, bool isTailCall,
SDOperand Callee,
ArgListTy &Args, SelectionDAG &DAG) {
SmallVector<SDOperand, 32> Ops;
if (Args[i].isNest)
Flags |= ISD::ParamFlags::Nest;
Flags |= OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs;
-
- switch (getTypeAction(VT)) {
- default: assert(0 && "Unknown type action!");
- case Legal:
- Ops.push_back(Op);
- Ops.push_back(DAG.getConstant(Flags, MVT::i32));
- break;
- case Promote:
- if (MVT::isInteger(VT)) {
- unsigned ExtOp;
- if (Args[i].isSExt)
- ExtOp = ISD::SIGN_EXTEND;
- else if (Args[i].isZExt)
- ExtOp = ISD::ZERO_EXTEND;
- else
- ExtOp = ISD::ANY_EXTEND;
- Op = DAG.getNode(ExtOp, getTypeToTransformTo(VT), Op);
- } else {
- assert(MVT::isFloatingPoint(VT) && "Not int or FP?");
- Op = DAG.getNode(ISD::FP_EXTEND, getTypeToTransformTo(VT), Op);
- }
- Ops.push_back(Op);
- Ops.push_back(DAG.getConstant(Flags, MVT::i32));
- break;
- case Expand: {
- MVT::ValueType PartVT = getRegisterType(VT);
- unsigned NumParts = getNumRegisters(VT);
- SmallVector<SDOperand, 4> Parts(NumParts);
- getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT);
- for (unsigned i = 0; i != NumParts; ++i) {
- // if it isn't first piece, alignment must be 1
- unsigned MyFlags = Flags;
- if (i != 0)
- MyFlags = (MyFlags & (~ISD::ParamFlags::OrigAlignment)) |
- (1 << ISD::ParamFlags::OrigAlignmentOffs);
-
- Ops.push_back(Parts[i]);
- Ops.push_back(DAG.getConstant(MyFlags, MVT::i32));
- }
- break;
- }
+
+ MVT::ValueType 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
+ unsigned MyFlags = Flags;
+ if (i != 0)
+ MyFlags = (MyFlags & (~ISD::ParamFlags::OrigAlignment)) |
+ (1 << ISD::ParamFlags::OrigAlignmentOffs);
+
+ Ops.push_back(Parts[i]);
+ Ops.push_back(DAG.getConstant(MyFlags, MVT::i32));
}
}
// Gather up the call result into a single value.
if (RetTy != Type::VoidTy) {
- ISD::NodeType AssertOp = ISD::AssertSext;
- if (!RetTyIsSigned)
+ ISD::NodeType AssertOp = ISD::DELETED_NODE;
+
+ if (RetSExt)
+ AssertOp = ISD::AssertSext;
+ else if (RetZExt)
AssertOp = ISD::AssertZext;
+
SmallVector<SDOperand, 4> Results(NumRegs);
for (unsigned i = 0; i != NumRegs; ++i)
Results[i] = Res.getValue(i);
- Res = getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT, AssertOp);
+ Res = getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT,
+ AssertOp, true);
}
return std::make_pair(Res, Chain);
// 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(LabelID, MVT::i32),
+ DAG.getConstant(1, MVT::i32)));
// Mark exception register as live in.
unsigned Reg = TLI.getExceptionAddressRegister();