namespace {
cl::opt<RegisterScheduler::FunctionPassCtor, false,
RegisterPassParser<RegisterScheduler> >
- ISHeuristic("sched",
+ ISHeuristic("pre-RA-sched",
cl::init(&createDefaultScheduler),
- cl::desc("Instruction schedulers available:"));
+ cl::desc("Instruction schedulers available (before register allocation):"));
static RegisterScheduler
defaultListDAGScheduler("default", " Best scheduler for the target",
};
}
-/// isFilterOrSelector - Return true if this instruction is a call to the
-/// eh.filter or the eh.selector intrinsic.
-static bool isFilterOrSelector(Instruction *I) {
+/// isSelector - Return true if this instruction is a call to the
+/// eh.selector intrinsic.
+static bool isSelector(Instruction *I) {
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
- return II->getIntrinsicID() == Intrinsic::eh_selector
- || II->getIntrinsicID() == Intrinsic::eh_filter;
+ return II->getIntrinsicID() == Intrinsic::eh_selector;
return false;
}
};
} // end namespace llvm
+
+/// getCopyFromParts - Create a value that contains the
+/// specified legal parts combined into the value they represent.
+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, PartVT, 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);
+ } else {
+ return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
+ }
+ }
+
+ if (MVT::isFloatingPoint(PartVT) &&
+ MVT::isFloatingPoint(ValueVT))
+ return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
+
+ if (MVT::getSizeInBits(PartVT) ==
+ MVT::getSizeInBits(ValueVT))
+ return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
+
+ assert(0 && "Unknown mismatch!");
+ }
+
+ // Handle a multi-element vector.
+ MVT::ValueType IntermediateVT, RegisterVT;
+ unsigned NumIntermediates;
+ unsigned NumRegs =
+ DAG.getTargetLoweringInfo()
+ .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.
+ return DAG.getNode(MVT::isVector(IntermediateVT) ?
+ ISD::CONCAT_VECTORS :
+ ISD::BUILD_VECTOR,
+ ValueVT, &Ops[0], NumIntermediates);
+}
+
+/// getCopyToParts - Create a series of nodes that contain the
+/// specified value split into legal parts.
+static void getCopyToParts(SelectionDAG &DAG,
+ SDOperand Val,
+ SDOperand *Parts,
+ unsigned NumParts,
+ MVT::ValueType PartVT) {
+ TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ MVT::ValueType PtrVT = TLI.getPointerTy();
+ MVT::ValueType ValueVT = Val.getValueType();
+
+ 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);
+ return;
+ }
+
+ // If there is a single part and the types differ, this must be
+ // a promotion.
+ 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::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;
+ }
+
+ // Handle a multi-element vector.
+ MVT::ValueType IntermediateVT, RegisterVT;
+ unsigned NumIntermediates;
+ unsigned NumRegs =
+ DAG.getTargetLoweringInfo()
+ .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
+ RegisterVT);
+ unsigned NumElements = MVT::getVectorNumElements(ValueVT);
+
+ assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
+ assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
+
+ // Split the vector into intermediate operands.
+ SmallVector<SDOperand, 8> Ops(NumIntermediates);
+ for (unsigned i = 0; i != NumIntermediates; ++i)
+ if (MVT::isVector(IntermediateVT))
+ Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR,
+ IntermediateVT, Val,
+ DAG.getConstant(i * (NumElements / NumIntermediates),
+ PtrVT));
+ else
+ Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
+ IntermediateVT, Val,
+ DAG.getConstant(i, PtrVT));
+
+ // Split the intermediate operands into legal parts.
+ if (NumParts == NumIntermediates) {
+ // If the register was not expanded, promote or copy the value,
+ // as appropriate.
+ for (unsigned i = 0; i != NumParts; ++i)
+ getCopyToParts(DAG, Ops[i], &Parts[i], 1, PartVT);
+ } else if (NumParts > 0) {
+ // If the intermediate type was expanded, split each the value into
+ // legal parts.
+ assert(NumParts % NumIntermediates == 0 &&
+ "Must expand into a divisible number of parts!");
+ unsigned Factor = NumParts / NumIntermediates;
+ for (unsigned i = 0; i != NumIntermediates; ++i)
+ getCopyToParts(DAG, Ops[i], &Parts[i * Factor], Factor, PartVT);
+ }
+}
+
+
SDOperand SelectionDAGLowering::getValue(const Value *V) {
SDOperand &N = NodeMap[V];
if (N.Val) return N;
// Now that we know the number and type of the elements, push a
// Constant or ConstantFP node onto the ops list for each element of
- // the packed constant.
+ // the vector constant.
SmallVector<SDOperand, 8> Ops;
if (ConstantVector *CP = dyn_cast<ConstantVector>(C)) {
for (unsigned i = 0; i != NumElements; ++i)
Ops.push_back(getValue(CP->getOperand(i)));
} else {
- assert(isa<ConstantAggregateZero>(C) && "Unknown packed constant!");
+ assert(isa<ConstantAggregateZero>(C) && "Unknown vector constant!");
SDOperand Op;
if (MVT::isFloatingPoint(PVT))
Op = DAG.getConstantFP(0, PVT);
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 LegalizeOp will use ANY_EXTEND rather
- // than sign/zero.
+ // the full width of a register, since getCopyToParts and Legalize will use
+ // ANY_EXTEND rather than sign/zero.
// 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()) &&
if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ZExt))
ExtendKind = ISD::ZERO_EXTEND;
RetOp = DAG.getNode(ExtendKind, TmpVT, RetOp);
+ NewValues.push_back(RetOp);
+ 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));
+ }
}
- NewValues.push_back(RetOp);
- NewValues.push_back(DAG.getConstant(false, MVT::i32));
}
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
&NewValues[0], NewValues.size()));
AllocSize = DAG.getNode(ISD::MUL, IntPtr, AllocSize,
getIntPtrConstant(TySize));
- // Handle alignment. If the requested alignment is less than or equal to the
- // stack alignment, ignore it and round the size of the allocation up to the
- // stack alignment size. If the size is greater than the stack alignment, we
- // note this in the DYNAMIC_STACKALLOC node.
+ // Handle alignment. If the requested alignment is less than or equal to
+ // the stack alignment, ignore it. If the size is greater than or equal to
+ // the stack alignment, we note this in the DYNAMIC_STACKALLOC node.
unsigned StackAlign =
TLI.getTargetMachine().getFrameInfo()->getStackAlignment();
- if (Align <= StackAlign) {
+ if (Align <= StackAlign)
Align = 0;
- // Add SA-1 to the size.
- AllocSize = DAG.getNode(ISD::ADD, AllocSize.getValueType(), AllocSize,
- getIntPtrConstant(StackAlign-1));
- // Mask out the low bits for alignment purposes.
- AllocSize = DAG.getNode(ISD::AND, AllocSize.getValueType(), AllocSize,
- getIntPtrConstant(~(uint64_t)(StackAlign-1)));
- }
+
+ // Round the size of the allocation up to the stack alignment size
+ // by add SA-1 to the size.
+ AllocSize = DAG.getNode(ISD::ADD, AllocSize.getValueType(), AllocSize,
+ getIntPtrConstant(StackAlign-1));
+ // Mask out the low bits for alignment purposes.
+ AllocSize = DAG.getNode(ISD::AND, AllocSize.getValueType(), AllocSize,
+ getIntPtrConstant(~(uint64_t)(StackAlign-1)));
SDOperand Ops[] = { getRoot(), AllocSize, getIntPtrConstant(Align) };
const MVT::ValueType *VTs = DAG.getNodeValueTypes(AllocSize.getValueType(),
}
}
-/// ExtractGlobalVariable - If C is a global variable, or a bitcast of one
-/// (possibly constant folded), return it. Otherwise return NULL.
-static GlobalVariable *ExtractGlobalVariable (Constant *C) {
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
- return GV;
- else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
- if (CE->getOpcode() == Instruction::BitCast)
- return dyn_cast<GlobalVariable>(CE->getOperand(0));
- else if (CE->getOpcode() == Instruction::GetElementPtr) {
- for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
- if (!CE->getOperand(i)->isNullValue())
- return NULL;
- return dyn_cast<GlobalVariable>(CE->getOperand(0));
- }
- }
- return NULL;
+/// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
+static GlobalVariable *ExtractTypeInfo (Value *V) {
+ V = IntrinsicInst::StripPointerCasts(V);
+ GlobalVariable *GV = dyn_cast<GlobalVariable>(V);
+ assert (GV || isa<ConstantPointerNull>(V) &&
+ "TypeInfo must be a global variable or NULL");
+ return GV;
}
/// addCatchInfo - Extract the personality and type infos from an eh.selector
-/// or eh.filter call, and add them to the specified machine basic block.
+/// call, and add them to the specified machine basic block.
static void addCatchInfo(CallInst &I, MachineModuleInfo *MMI,
MachineBasicBlock *MBB) {
// Inform the MachineModuleInfo of the personality for this landing pad.
// Gather all the type infos for this landing pad and pass them along to
// MachineModuleInfo.
std::vector<GlobalVariable *> TyInfo;
- for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) {
- Constant *C = cast<Constant>(I.getOperand(i));
- GlobalVariable *GV = ExtractGlobalVariable(C);
- assert (GV || isa<ConstantPointerNull>(C) &&
- "TypeInfo must be a global variable or NULL");
- TyInfo.push_back(GV);
- }
- if (I.getCalledFunction()->getIntrinsicID() == Intrinsic::eh_filter)
- MMI->addFilterTypeInfo(MBB, TyInfo);
- else
- MMI->addCatchTypeInfo(MBB, TyInfo);
-}
+ unsigned N = I.getNumOperands();
+
+ for (unsigned i = N - 1; i > 2; --i) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(i))) {
+ unsigned FilterLength = CI->getZExtValue();
+ unsigned FirstCatch = i + FilterLength + 1;
+ assert (FirstCatch <= N && "Invalid filter length");
+
+ if (FirstCatch < N) {
+ TyInfo.reserve(N - FirstCatch);
+ for (unsigned j = FirstCatch; j < N; ++j)
+ TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
+ MMI->addCatchTypeInfo(MBB, TyInfo);
+ TyInfo.clear();
+ }
-/// propagateEHRegister - The specified EH register is required in a successor
-/// of the EH landing pad. Propagate it (by adding it to livein) to all the
-/// blocks in the paths between the landing pad and the specified block.
-static void propagateEHRegister(MachineBasicBlock *MBB, unsigned EHReg,
- SmallPtrSet<MachineBasicBlock*, 8> Visited) {
- if (MBB->isLandingPad() || !Visited.insert(MBB))
- return;
+ TyInfo.reserve(FilterLength);
+ for (unsigned j = i + 1; j < FirstCatch; ++j)
+ TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
+ MMI->addFilterTypeInfo(MBB, TyInfo);
+ TyInfo.clear();
- MBB->addLiveIn(EHReg);
- for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
- E = MBB->pred_end(); PI != E; ++PI)
- propagateEHRegister(*PI, EHReg, Visited);
-}
+ N = i;
+ }
+ }
-static void propagateEHRegister(MachineBasicBlock *MBB, unsigned EHReg) {
- SmallPtrSet<MachineBasicBlock*, 8> Visited;
- propagateEHRegister(MBB, EHReg, Visited);
+ if (N > 3) {
+ TyInfo.reserve(N - 3);
+ for (unsigned j = 3; j < N; ++j)
+ TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
+ MMI->addCatchTypeInfo(MBB, TyInfo);
+ }
}
/// visitIntrinsicCall - Lower the call to the specified intrinsic function. If
case Intrinsic::eh_exception: {
if (ExceptionHandling) {
- if (!CurMBB->isLandingPad() && TLI.getExceptionAddressRegister())
- propagateEHRegister(CurMBB, TLI.getExceptionAddressRegister());
-
+ if (!CurMBB->isLandingPad()) {
+ // FIXME: Mark exception register as live in. Hack for PR1508.
+ unsigned Reg = TLI.getExceptionAddressRegister();
+ if (Reg) CurMBB->addLiveIn(Reg);
+ }
// Insert the EXCEPTIONADDR instruction.
SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
SDOperand Ops[1];
return 0;
}
- case Intrinsic::eh_selector:
- case Intrinsic::eh_filter:{
+ case Intrinsic::eh_selector:{
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
if (ExceptionHandling && MMI) {
#ifndef NDEBUG
FuncInfo.CatchInfoLost.insert(&I);
#endif
- if (TLI.getExceptionSelectorRegister())
- propagateEHRegister(CurMBB, TLI.getExceptionSelectorRegister());
+ // FIXME: Mark exception selector register as live in. Hack for PR1508.
+ unsigned Reg = TLI.getExceptionSelectorRegister();
+ if (Reg) CurMBB->addLiveIn(Reg);
}
// Insert the EHSELECTION instruction.
if (MMI) {
// Find the type id for the given typeinfo.
- Constant *C = cast<Constant>(I.getOperand(1));
- GlobalVariable *GV = ExtractGlobalVariable(C);
- assert (GV || isa<ConstantPointerNull>(C) &&
- "TypeInfo must be a global variable or NULL");
+ GlobalVariable *GV = ExtractTypeInfo(I.getOperand(1));
unsigned TypeID = MMI->getTypeIDFor(GV);
setValue(&I, DAG.getConstant(TypeID, MVT::i32));
} else {
- setValue(&I, DAG.getConstant(0, MVT::i32));
+ // Return something different to eh_selector.
+ setValue(&I, DAG.getConstant(1, MVT::i32));
}
return 0;
}
+ case Intrinsic::eh_return: {
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+
+ if (MMI && ExceptionHandling) {
+ MMI->setCallsEHReturn(true);
+ DAG.setRoot(DAG.getNode(ISD::EH_RETURN,
+ MVT::Other,
+ getRoot(),
+ getValue(I.getOperand(1)),
+ getValue(I.getOperand(2))));
+ } else {
+ setValue(&I, DAG.getConstant(0, TLI.getPointerTy()));
+ }
+
+ return 0;
+ }
+
+ case Intrinsic::eh_unwind_init: {
+ if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) {
+ MMI->setCallsUnwindInit(true);
+ }
+
+ return 0;
+ }
+
+ case Intrinsic::eh_dwarf_cfa: {
+ if (ExceptionHandling) {
+ MVT::ValueType VT = getValue(I.getOperand(1)).getValueType();
+ SDOperand Offset = DAG.getNode(ISD::ADD,
+ TLI.getPointerTy(),
+ DAG.getNode(ISD::FRAME_TO_ARGS_OFFSET,
+ VT),
+ getValue(I.getOperand(1)));
+ setValue(&I, DAG.getNode(ISD::ADD,
+ TLI.getPointerTy(),
+ DAG.getNode(ISD::FRAMEADDR,
+ TLI.getPointerTy(),
+ DAG.getConstant(0,
+ TLI.getPointerTy())),
+ Offset));
+ } else {
+ setValue(&I, DAG.getConstant(0, TLI.getPointerTy()));
+ }
+
+ return 0;
+ }
+
case Intrinsic::sqrt_f32:
case Intrinsic::sqrt_f64:
setValue(&I, DAG.getNode(ISD::FSQRT,
SDOperand Arg = getValue(I.getOperand(1));
MVT::ValueType Ty = Arg.getValueType();
SDOperand result = DAG.getNode(ISD::CTTZ, Ty, Arg);
- if (Ty < MVT::i32)
- result = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, result);
- else if (Ty > MVT::i32)
- result = DAG.getNode(ISD::TRUNCATE, MVT::i32, result);
setValue(&I, result);
return 0;
}
SDOperand Arg = getValue(I.getOperand(1));
MVT::ValueType Ty = Arg.getValueType();
SDOperand result = DAG.getNode(ISD::CTLZ, Ty, Arg);
- if (Ty < MVT::i32)
- result = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, result);
- else if (Ty > MVT::i32)
- result = DAG.getNode(ISD::TRUNCATE, MVT::i32, result);
setValue(&I, result);
return 0;
}
SDOperand Arg = getValue(I.getOperand(1));
MVT::ValueType Ty = Arg.getValueType();
SDOperand result = DAG.getNode(ISD::CTPOP, Ty, Arg);
- if (Ty < MVT::i32)
- result = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, result);
- else if (Ty > MVT::i32)
- result = DAG.getNode(ISD::TRUNCATE, MVT::i32, result);
setValue(&I, result);
return 0;
}
case Intrinsic::var_annotation:
// Discard annotate attributes
return 0;
+
+ case Intrinsic::adjust_trampoline: {
+ SDOperand Arg = getValue(I.getOperand(1));
+ setValue(&I, DAG.getNode(ISD::ADJUST_TRAMP, TLI.getPointerTy(), Arg));
+ return 0;
+ }
+
+ case Intrinsic::init_trampoline: {
+ const Function *F =
+ cast<Function>(IntrinsicInst::StripPointerCasts(I.getOperand(2)));
+
+ SDOperand Ops[6];
+ Ops[0] = getRoot();
+ Ops[1] = getValue(I.getOperand(1));
+ Ops[2] = getValue(I.getOperand(2));
+ Ops[3] = getValue(I.getOperand(3));
+ Ops[4] = DAG.getSrcValue(I.getOperand(1));
+ Ops[5] = DAG.getSrcValue(F);
+
+ DAG.setRoot(DAG.getNode(ISD::TRAMPOLINE, MVT::Other, Ops, 6));
+ return 0;
+ }
}
}
Entry.isZExt = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::ZExt);
Entry.isInReg = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::InReg);
Entry.isSRet = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::StructRet);
+ Entry.isNest = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::Nest);
+ Entry.isByVal = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::ByVal);
Args.push_back(Entry);
}
}
-/// getCopyFromParts - Create a value that contains the
-/// specified legal parts combined into the value they represent.
-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];
- 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, PartVT, 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);
- } else {
- return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
- }
- }
-
- if (MVT::isFloatingPoint(PartVT) &&
- MVT::isFloatingPoint(ValueVT))
- return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
-
- if (MVT::getSizeInBits(PartVT) ==
- MVT::getSizeInBits(ValueVT))
- return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
-
- assert(0 && "Unknown mismatch!");
- }
-
- // Handle a multi-element vector.
- MVT::ValueType IntermediateVT, RegisterVT;
- unsigned NumIntermediates;
- unsigned NumRegs =
- DAG.getTargetLoweringInfo()
- .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(NumIntermediates % NumParts == 0 &&
- "Must expand into a divisible number of parts!");
- unsigned Factor = NumIntermediates / NumParts;
- 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.
- return DAG.getNode(MVT::isVector(IntermediateVT) ?
- ISD::CONCAT_VECTORS :
- ISD::BUILD_VECTOR,
- ValueVT, &Ops[0], NumParts);
-}
-
-/// getCopyToParts - Create a series of nodes that contain the
-/// specified value split into legal parts.
-static void getCopyToParts(SelectionDAG &DAG,
- SDOperand Val,
- SDOperand *Parts,
- unsigned NumParts,
- MVT::ValueType PartVT) {
- MVT::ValueType ValueVT = Val.getValueType();
-
- 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, MVT::i32));
- return;
- }
-
- // If there is a single part and the types differ, this must be
- // a promotion.
- 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::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;
- }
-
- // Handle a multi-element vector.
- MVT::ValueType IntermediateVT, RegisterVT;
- unsigned NumIntermediates;
- unsigned NumRegs =
- DAG.getTargetLoweringInfo()
- .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
- RegisterVT);
- unsigned NumElements = MVT::getVectorNumElements(ValueVT);
-
- assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
- assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
-
- // Split the vector into intermediate operands.
- SmallVector<SDOperand, 8> Ops(NumIntermediates);
- for (unsigned i = 0; i != NumIntermediates; ++i)
- if (MVT::isVector(IntermediateVT))
- Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR,
- IntermediateVT, Val,
- DAG.getConstant(i * (NumElements / NumIntermediates),
- MVT::i32));
- else
- Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
- IntermediateVT, Val,
- DAG.getConstant(i, MVT::i32));
-
- // Split the intermediate operands into legal parts.
- if (NumParts == NumIntermediates) {
- // If the register was not expanded, promote or copy the value,
- // as appropriate.
- for (unsigned i = 0; i != NumParts; ++i)
- getCopyToParts(DAG, Ops[i], &Parts[i], 1, PartVT);
- } else if (NumParts > 0) {
- // If the intermediate type was expanded, split each the value into
- // legal parts.
- assert(NumParts % NumIntermediates == 0 &&
- "Must expand into a divisible number of parts!");
- unsigned Factor = NumParts / NumIntermediates;
- for (unsigned i = 0; i != NumIntermediates; ++i)
- getCopyToParts(DAG, Ops[i], &Parts[i * Factor], Factor, PartVT);
- }
-}
-
-
/// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from
/// 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 &Chain, SDOperand *Flag)const{
- // Get the list of registers, in the appropriate order.
- std::vector<unsigned> R(Regs);
- if (!DAG.getTargetLoweringInfo().isLittleEndian())
- std::reverse(R.begin(), R.end());
-
// Copy the legal parts from the registers.
unsigned NumParts = Regs.size();
SmallVector<SDOperand, 8> Parts(NumParts);
/// If the Flag pointer is NULL, no flag is used.
void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
SDOperand &Chain, SDOperand *Flag) const {
- // Get the list of registers, in the appropriate order.
- std::vector<unsigned> R(Regs);
- if (!DAG.getTargetLoweringInfo().isLittleEndian())
- std::reverse(R.begin(), R.end());
-
// Get the list of the values's legal parts.
unsigned NumParts = Regs.size();
SmallVector<SDOperand, 8> Parts(NumParts);
// Copy the parts into the registers.
for (unsigned i = 0; i != NumParts; ++i) {
SDOperand Part = Flag ?
- DAG.getCopyToReg(Chain, R[i], Parts[i], *Flag) :
- DAG.getCopyToReg(Chain, R[i], Parts[i]);
+ DAG.getCopyToReg(Chain, Regs[i], Parts[i], *Flag) :
+ DAG.getCopyToReg(Chain, Regs[i], Parts[i]);
Chain = Part.getValue(0);
if (Flag)
*Flag = Part.getValue(1);
Flags |= ISD::ParamFlags::InReg;
if (Attrs && Attrs->paramHasAttr(j, ParamAttr::StructRet))
Flags |= ISD::ParamFlags::StructReturn;
+ if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ByVal)) {
+ Flags |= ISD::ParamFlags::ByVal;
+ const PointerType *Ty = cast<PointerType>(I->getType());
+ const StructType *STy = cast<StructType>(Ty->getElementType());
+ unsigned StructAlign = Log2_32(getTargetData()->getABITypeAlignment(STy));
+ unsigned StructSize = getTargetData()->getTypeSize(STy);
+ Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
+ Flags |= (StructSize << ISD::ParamFlags::ByValSizeOffs);
+ }
+ if (Attrs && Attrs->paramHasAttr(j, ParamAttr::Nest))
+ Flags |= ISD::ParamFlags::Nest;
Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs);
switch (getTypeAction(VT)) {
Flags |= ISD::ParamFlags::InReg;
if (Args[i].isSRet)
Flags |= ISD::ParamFlags::StructReturn;
+ if (Args[i].isByVal) {
+ Flags |= ISD::ParamFlags::ByVal;
+ const PointerType *Ty = cast<PointerType>(Args[i].Ty);
+ const StructType *STy = cast<StructType>(Ty->getElementType());
+ unsigned StructAlign = Log2_32(getTargetData()->getABITypeAlignment(STy));
+ unsigned StructSize = getTargetData()->getTypeSize(STy);
+ Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
+ Flags |= (StructSize << ISD::ParamFlags::ByValSizeOffs);
+ }
+ if (Args[i].isNest)
+ Flags |= ISD::ParamFlags::Nest;
Flags |= OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs;
switch (getTypeAction(VT)) {
SDOperand Res = DAG.getNode(ISD::CALL,
DAG.getVTList(&RetTys[0], NumRegs + 1),
&Ops[0], Ops.size());
- SDOperand Chain = Res.getValue(NumRegs);
+ Chain = Res.getValue(NumRegs);
// Gather up the call result into a single value.
if (RetTy != Type::VoidTy) {
assert(!FLI.MBBMap[SrcBB]->isLandingPad() &&
"Copying catch info out of a landing pad!");
for (BasicBlock::iterator I = SrcBB->begin(), E = --SrcBB->end(); I != E; ++I)
- if (isFilterOrSelector(I)) {
+ if (isSelector(I)) {
// Apply the catch info to DestBB.
addCatchInfo(cast<CallInst>(*I), MMI, FLI.MBBMap[DestBB]);
#ifndef NDEBUG
// function and list of typeids logically belong to the invoke (or, if you
// like, the basic block containing the invoke), and need to be associated
// with it in the dwarf exception handling tables. Currently however the
- // information is provided by intrinsics (eh.filter and eh.selector) that
- // can be moved to unexpected places by the optimizers: if the unwind edge
- // is critical, then breaking it can result in the intrinsics being in the
- // successor of the landing pad, not the landing pad itself. This results
- // in exceptions not being caught because no typeids are associated with
- // the invoke. This may not be the only way things can go wrong, but it
- // is the only way we try to work around for the moment.
+ // information is provided by an intrinsic (eh.selector) that can be moved
+ // to unexpected places by the optimizers: if the unwind edge is critical,
+ // then breaking it can result in the intrinsics being in the successor of
+ // the landing pad, not the landing pad itself. This results in exceptions
+ // not being caught because no typeids are associated with the invoke.
+ // This may not be the only way things can go wrong, but it is the only way
+ // we try to work around for the moment.
BranchInst *Br = dyn_cast<BranchInst>(LLVMBB->getTerminator());
if (Br && Br->isUnconditional()) { // Critical edge?
BasicBlock::iterator I, E;
for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I)
- if (isFilterOrSelector(I))
+ if (isSelector(I))
break;
if (I == E)
if (TI->getNumSuccessors())
SuccsHandled.resize(BB->getParent()->getNumBlockIDs());
- // Check successor nodes PHI nodes that expect a constant to be available from
- // this block.
+ // Check successor nodes' PHI nodes that expect a constant to be available
+ // from this block.
for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) {
BasicBlock *SuccBB = TI->getSuccessor(succ);
if (!isa<PHINode>(SuccBB->begin())) continue;
/// actual value in the DAG on the RHS of an AND, and DesiredMaskS is the value
/// specified in the .td file (e.g. 255).
bool SelectionDAGISel::CheckAndMask(SDOperand LHS, ConstantSDNode *RHS,
- int64_t DesiredMaskS) {
+ int64_t DesiredMaskS) const {
uint64_t ActualMask = RHS->getValue();
uint64_t DesiredMask =DesiredMaskS & MVT::getIntVTBitMask(LHS.getValueType());
/// actual value in the DAG on the RHS of an OR, and DesiredMaskS is the value
/// specified in the .td file (e.g. 255).
bool SelectionDAGISel::CheckOrMask(SDOperand LHS, ConstantSDNode *RHS,
- int64_t DesiredMaskS) {
+ int64_t DesiredMaskS) const {
uint64_t ActualMask = RHS->getValue();
uint64_t DesiredMask =DesiredMaskS & MVT::getIntVTBitMask(LHS.getValueType());