llvm.org GIT mirror llvm / b4997ae
Add code to check at SelectionDAGISel::LowerArguments time to see if return values can be lowered to registers. Coming soon, code to perform sret-demotion if return values cannot be lowered to registers git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86324 91177308-0d34-0410-b5e6-96231b3b80d8 Kenneth Uildriks 10 years ago
6 changed file(s) with 111 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
182182 void AnalyzeReturn(const SmallVectorImpl &Outs,
183183 CCAssignFn Fn);
184184
185 /// CheckReturn - Analyze the return values of a function, returning
186 /// true if the return can be performed without sret-demotion, and
187 /// false otherwise.
188 bool CheckReturn(const SmallVectorImpl &OutTys,
189 const SmallVectorImpl &ArgsFlags,
190 CCAssignFn Fn);
191
185192 /// AnalyzeCallOperands - Analyze the outgoing arguments to a call,
186193 /// incorporating info about the passed values into this state.
187194 void AnalyzeCallOperands(const SmallVectorImpl &Outs,
11661166 return SDValue(); // this is here to silence compiler errors
11671167 }
11681168
1169 /// CanLowerReturn - This hook should be implemented to check whether the
1170 /// return values described by the Outs array can fit into the return
1171 /// registers. If false is returned, an sret-demotion is performed.
1172 ///
1173 virtual bool CanLowerReturn(CallingConv::ID CallConv, bool isVarArg,
1174 const SmallVectorImpl &OutTys,
1175 const SmallVectorImpl &ArgsFlags,
1176 SelectionDAG &DAG)
1177 {
1178 // Return true by default to get preexisting behavior.
1179 return true;
1180 }
11691181 /// LowerReturn - This hook must be implemented to lower outgoing
11701182 /// return values, described by the Outs array, into the specified
11711183 /// DAG. The implementation should return the resulting token chain
7474 llvm_unreachable(0);
7575 }
7676 }
77 }
78
79 /// CheckReturn - Analyze the return values of a function, returning true if
80 /// the return can be performed without sret-demotion, and false otherwise.
81 bool CCState::CheckReturn(const SmallVectorImpl &OutTys,
82 const SmallVectorImpl &ArgsFlags,
83 CCAssignFn Fn) {
84 // Determine which register each value should be copied into.
85 for (unsigned i = 0, e = OutTys.size(); i != e; ++i) {
86 EVT VT = OutTys[i];
87 ISD::ArgFlagsTy ArgFlags = ArgsFlags[i];
88 if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this))
89 return false;
90 }
91 return true;
7792 }
7893
7994 /// AnalyzeReturn - Analyze the returned values of a return,
946946 return RFV.getCopyFromRegs(DAG, getCurDebugLoc(), Chain, NULL);
947947 }
948948
949 /// Get the EVTs and ArgFlags collections that represent the return type
950 /// of the given function. This does not require a DAG or a return value, and
951 /// is suitable for use before any DAGs for the function are constructed.
952 static void getReturnInfo(const Function* F, SmallVectorImpl &OutVTs,
953 SmallVectorImpl &OutFlags,
954 TargetLowering &TLI) {
955 const Type* ReturnType = F->getReturnType();
956
957 SmallVector ValueVTs;
958 ComputeValueVTs(TLI, ReturnType, ValueVTs);
959 unsigned NumValues = ValueVTs.size();
960 if ( NumValues == 0 ) return;
961
962 for (unsigned j = 0, f = NumValues; j != f; ++j) {
963 EVT VT = ValueVTs[j];
964 ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
965
966 if (F->paramHasAttr(0, Attribute::SExt))
967 ExtendKind = ISD::SIGN_EXTEND;
968 else if (F->paramHasAttr(0, Attribute::ZExt))
969 ExtendKind = ISD::ZERO_EXTEND;
970
971 // FIXME: C calling convention requires the return type to be promoted to
972 // at least 32-bit. But this is not necessary for non-C calling
973 // conventions. The frontend should mark functions whose return values
974 // require promoting with signext or zeroext attributes.
975 if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) {
976 EVT MinVT = TLI.getRegisterType(F->getContext(), MVT::i32);
977 if (VT.bitsLT(MinVT))
978 VT = MinVT;
979 }
980
981 unsigned NumParts = TLI.getNumRegisters(F->getContext(), VT);
982 EVT PartVT = TLI.getRegisterType(F->getContext(), VT);
983 // 'inreg' on function refers to return value
984 ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
985 if (F->paramHasAttr(0, Attribute::InReg))
986 Flags.setInReg();
987
988 // Propagate extension type if any
989 if (F->paramHasAttr(0, Attribute::SExt))
990 Flags.setSExt();
991 else if (F->paramHasAttr(0, Attribute::ZExt))
992 Flags.setZExt();
993
994 for (unsigned i = 0; i < NumParts; ++i)
995 {
996 OutVTs.push_back(PartVT);
997 OutFlags.push_back(Flags);
998 }
999 }
1000 }
9491001
9501002 void SelectionDAGLowering::visitRet(ReturnInst &I) {
9511003 SDValue Chain = getControlRoot();
57575809 DebugLoc dl = SDL->getCurDebugLoc();
57585810 const TargetData *TD = TLI.getTargetData();
57595811
5812 // Check whether the function can return without sret-demotion.
5813 SmallVector OutVTs;
5814 SmallVector OutsFlags;
5815 getReturnInfo(&F, OutVTs, OutsFlags, TLI);
5816 // For now, assert and bail out if it can't.
5817 assert(TLI.CanLowerReturn(F.getCallingConv(), F.isVarArg(), OutVTs, OutsFlags,
5818 DAG) && "Cannot fit return value in registers!");
5819
57605820 // Set up the incoming argument description vector.
57615821 SmallVector Ins;
57625822 unsigned Idx = 1;
10851085 //===----------------------------------------------------------------------===//
10861086
10871087 #include "X86GenCallingConv.inc"
1088
1089 bool
1090 X86TargetLowering::CanLowerReturn(CallingConv::ID CallConv, bool isVarArg,
1091 const SmallVectorImpl &OutTys,
1092 const SmallVectorImpl &ArgsFlags,
1093 SelectionDAG &DAG) {
1094 SmallVector RVLocs;
1095 CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
1096 RVLocs, *DAG.getContext());
1097 return CCInfo.CheckReturn(OutTys, ArgsFlags, RetCC_X86);
1098 }
10881099
10891100 SDValue
10901101 X86TargetLowering::LowerReturn(SDValue Chain,
698698 const SmallVectorImpl &Outs,
699699 DebugLoc dl, SelectionDAG &DAG);
700700
701 virtual bool
702 CanLowerReturn(CallingConv::ID CallConv, bool isVarArg,
703 const SmallVectorImpl &OutTys,
704 const SmallVectorImpl &ArgsFlags,
705 SelectionDAG &DAG);
706
701707 void ReplaceATOMIC_BINARY_64(SDNode *N, SmallVectorImpl &Results,
702708 SelectionDAG &DAG, unsigned NewOp);
703709