diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2013-06-10 20:36:52 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2013-06-10 20:36:52 +0000 | 
| commit | 59d6cff90eecf31cb3dd860c4e786674cfdd42eb (patch) | |
| tree | 909310b2e05119d1d6efda049977042abbb58bb1 /lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | |
| parent | 4a16efa3e43e35f0cc9efe3a67f620f0017c3d36 (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
| -rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 102 | 
1 files changed, 68 insertions, 34 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index ce40cd6a0c9c..67db211ec427 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -314,7 +314,7 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL,      } else {        Ctx.emitError(ErrMsg);      } -    report_fatal_error("Cannot handle scalar-to-vector conversion!"); +    return DAG.getUNDEF(ValueVT);    }    if (ValueVT.getVectorNumElements() == 1 && @@ -5034,6 +5034,11 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {      setValue(&I, Res);      return 0;    } +  case Intrinsic::annotation: +  case Intrinsic::ptr_annotation: +    // Drop the intrinsic, but forward the value +    setValue(&I, getValue(I.getOperand(0))); +    return 0;    case Intrinsic::var_annotation:      // Discard annotate attributes      return 0; @@ -5232,6 +5237,7 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,      Entry.isSRet = true;      Entry.isNest = false;      Entry.isByVal = false; +    Entry.isReturned = false;      Entry.Alignment = Align;      Args.push_back(Entry);      RetTy = Type::getVoidTy(FTy->getContext()); @@ -5249,13 +5255,14 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,      Entry.Node = ArgNode; Entry.Ty = V->getType();      unsigned attrInd = i - CS.arg_begin() + 1; -    Entry.isSExt  = CS.paramHasAttr(attrInd, Attribute::SExt); -    Entry.isZExt  = CS.paramHasAttr(attrInd, Attribute::ZExt); -    Entry.isInReg = CS.paramHasAttr(attrInd, Attribute::InReg); -    Entry.isSRet  = CS.paramHasAttr(attrInd, Attribute::StructRet); -    Entry.isNest  = CS.paramHasAttr(attrInd, Attribute::Nest); -    Entry.isByVal = CS.paramHasAttr(attrInd, Attribute::ByVal); -    Entry.Alignment = CS.getParamAlignment(attrInd); +    Entry.isSExt     = CS.paramHasAttr(attrInd, Attribute::SExt); +    Entry.isZExt     = CS.paramHasAttr(attrInd, Attribute::ZExt); +    Entry.isInReg    = CS.paramHasAttr(attrInd, Attribute::InReg); +    Entry.isSRet     = CS.paramHasAttr(attrInd, Attribute::StructRet); +    Entry.isNest     = CS.paramHasAttr(attrInd, Attribute::Nest); +    Entry.isByVal    = CS.paramHasAttr(attrInd, Attribute::ByVal); +    Entry.isReturned = CS.paramHasAttr(attrInd, Attribute::Returned); +    Entry.Alignment  = CS.getParamAlignment(attrInd);      Args.push_back(Entry);    } @@ -6169,10 +6176,17 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {            MatchedRegs.RegVTs.push_back(RegVT);            MachineRegisterInfo &RegInfo = DAG.getMachineFunction().getRegInfo();            for (unsigned i = 0, e = InlineAsm::getNumOperandRegisters(OpFlag); -               i != e; ++i) -            MatchedRegs.Regs.push_back -              (RegInfo.createVirtualRegister(TLI.getRegClassFor(RegVT))); - +               i != e; ++i) { +            if (const TargetRegisterClass *RC = TLI.getRegClassFor(RegVT)) +              MatchedRegs.Regs.push_back(RegInfo.createVirtualRegister(RC)); +            else { +              LLVMContext &Ctx = *DAG.getContext(); +              Ctx.emitError(CS.getInstruction(), "inline asm error: This value" +                            " type register class is not natively supported!"); +              report_fatal_error("inline asm error: This value type register " +                                 "class is not natively supported!"); +            } +          }            // Use the produced MatchedRegs object to            MatchedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),                                      Chain, &Flag, CS.getInstruction()); @@ -6389,6 +6403,28 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) {  /// migrated to using LowerCall, this hook should be integrated into SDISel.  std::pair<SDValue, SDValue>  TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const { +  // Handle the incoming return values from the call. +  CLI.Ins.clear(); +  SmallVector<EVT, 4> RetTys; +  ComputeValueVTs(*this, CLI.RetTy, RetTys); +  for (unsigned I = 0, E = RetTys.size(); I != E; ++I) { +    EVT VT = RetTys[I]; +    MVT RegisterVT = getRegisterType(CLI.RetTy->getContext(), VT); +    unsigned NumRegs = getNumRegisters(CLI.RetTy->getContext(), VT); +    for (unsigned i = 0; i != NumRegs; ++i) { +      ISD::InputArg MyFlags; +      MyFlags.VT = RegisterVT; +      MyFlags.Used = CLI.IsReturnValueUsed; +      if (CLI.RetSExt) +        MyFlags.Flags.setSExt(); +      if (CLI.RetZExt) +        MyFlags.Flags.setZExt(); +      if (CLI.IsInReg) +        MyFlags.Flags.setInReg(); +      CLI.Ins.push_back(MyFlags); +    } +  } +    // Handle all of the outgoing arguments.    CLI.Outs.clear();    CLI.OutVals.clear(); @@ -6442,6 +6478,26 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {        else if (Args[i].isZExt)          ExtendKind = ISD::ZERO_EXTEND; +      // Conservatively only handle 'returned' on non-vectors for now +      if (Args[i].isReturned && !Op.getValueType().isVector()) { +        assert(CLI.RetTy == Args[i].Ty && RetTys.size() == NumValues && +               "unexpected use of 'returned'"); +        // Before passing 'returned' to the target lowering code, ensure that +        // either the register MVT and the actual EVT are the same size or that +        // the return value and argument are extended in the same way; in these +        // cases it's safe to pass the argument register value unchanged as the +        // return register value (although it's at the target's option whether +        // to do so) +        // TODO: allow code generation to take advantage of partially preserved +        // registers rather than clobbering the entire register when the +        // parameter extension method is not compatible with the return +        // extension method +        if ((NumParts * PartVT.getSizeInBits() == VT.getSizeInBits()) || +            (ExtendKind != ISD::ANY_EXTEND && +             CLI.RetSExt == Args[i].isSExt && CLI.RetZExt == Args[i].isZExt)) +        Flags.setReturned(); +      } +        getCopyToParts(CLI.DAG, CLI.DL, Op, &Parts[0], NumParts,                       PartVT, CLI.CS ? CLI.CS->getInstruction() : 0, ExtendKind); @@ -6461,28 +6517,6 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {      }    } -  // Handle the incoming return values from the call. -  CLI.Ins.clear(); -  SmallVector<EVT, 4> RetTys; -  ComputeValueVTs(*this, CLI.RetTy, RetTys); -  for (unsigned I = 0, E = RetTys.size(); I != E; ++I) { -    EVT VT = RetTys[I]; -    MVT RegisterVT = getRegisterType(CLI.RetTy->getContext(), VT); -    unsigned NumRegs = getNumRegisters(CLI.RetTy->getContext(), VT); -    for (unsigned i = 0; i != NumRegs; ++i) { -      ISD::InputArg MyFlags; -      MyFlags.VT = RegisterVT; -      MyFlags.Used = CLI.IsReturnValueUsed; -      if (CLI.RetSExt) -        MyFlags.Flags.setSExt(); -      if (CLI.RetZExt) -        MyFlags.Flags.setZExt(); -      if (CLI.IsInReg) -        MyFlags.Flags.setInReg(); -      CLI.Ins.push_back(MyFlags); -    } -  } -    SmallVector<SDValue, 4> InVals;    CLI.Chain = LowerCall(CLI, InVals);  | 
