mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-16 11:30:51 +00:00
Allow targets to legalize operations (with illegal operands) that produces multiple values. For example, a load with an illegal operand (a load produces two values, a value and chain).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62663 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
aaf414c92c
commit
bb326bbe88
@ -1131,6 +1131,23 @@ public:
|
|||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// LowerOperationWrapper - This callback is invoked by the type legalizer
|
||||||
|
/// to legalize operation with illegal operand types but legal result types;
|
||||||
|
/// It replaces the LowerOperation callback in the type Legalizer.
|
||||||
|
/// The reason we can not do away with LowerOperation entirely is that
|
||||||
|
/// LegalizeDAG isn't yet ready to use this callback.
|
||||||
|
|
||||||
|
/// The target places new result values for the node in Results (their number
|
||||||
|
/// and types must exactly match those of the original return values of
|
||||||
|
/// the node), or leaves Results empty, which indicates that the node is not
|
||||||
|
/// to be custom lowered after all.
|
||||||
|
/// In its default implementation it calls the LowerOperation.
|
||||||
|
|
||||||
|
virtual void LowerOperationWrapper(SDValue Op,
|
||||||
|
SmallVectorImpl<SDValue> &Results,
|
||||||
|
SelectionDAG &DAG);
|
||||||
|
|
||||||
|
|
||||||
/// LowerOperation - This callback is invoked for operations that are
|
/// LowerOperation - This callback is invoked for operations that are
|
||||||
/// unsupported by the target, which are registered to use 'custom' lowering,
|
/// unsupported by the target, which are registered to use 'custom' lowering,
|
||||||
/// and whose defined values are all legal.
|
/// and whose defined values are all legal.
|
||||||
|
@ -722,7 +722,7 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
|
|||||||
Lo = Hi = SDValue();
|
Lo = Hi = SDValue();
|
||||||
|
|
||||||
// See if the target wants to custom expand this node.
|
// See if the target wants to custom expand this node.
|
||||||
if (CustomLowerResults(N, ResNo))
|
if (CustomLowerResults(N, ResNo, true))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (N->getOpcode()) {
|
switch (N->getOpcode()) {
|
||||||
|
@ -34,7 +34,7 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
|
|||||||
SDValue Result = SDValue();
|
SDValue Result = SDValue();
|
||||||
|
|
||||||
// See if the target wants to custom expand this node.
|
// See if the target wants to custom expand this node.
|
||||||
if (CustomLowerResults(N, ResNo))
|
if (CustomLowerResults(N, ResNo, true))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (N->getOpcode()) {
|
switch (N->getOpcode()) {
|
||||||
@ -623,45 +623,42 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
|
|||||||
DEBUG(cerr << "Promote integer operand: "; N->dump(&DAG); cerr << "\n");
|
DEBUG(cerr << "Promote integer operand: "; N->dump(&DAG); cerr << "\n");
|
||||||
SDValue Res = SDValue();
|
SDValue Res = SDValue();
|
||||||
|
|
||||||
if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
|
if (CustomLowerResults(N, OpNo, false))
|
||||||
== TargetLowering::Custom)
|
return false;
|
||||||
Res = TLI.LowerOperation(SDValue(N, 0), DAG);
|
|
||||||
|
|
||||||
if (Res.getNode() == 0) {
|
switch (N->getOpcode()) {
|
||||||
switch (N->getOpcode()) {
|
default:
|
||||||
default:
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
cerr << "PromoteIntegerOperand Op #" << OpNo << ": ";
|
cerr << "PromoteIntegerOperand Op #" << OpNo << ": ";
|
||||||
N->dump(&DAG); cerr << "\n";
|
N->dump(&DAG); cerr << "\n";
|
||||||
#endif
|
#endif
|
||||||
assert(0 && "Do not know how to promote this operator's operand!");
|
assert(0 && "Do not know how to promote this operator's operand!");
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break;
|
case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break;
|
||||||
case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break;
|
case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break;
|
||||||
case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break;
|
case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break;
|
||||||
case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break;
|
case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break;
|
||||||
case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break;
|
case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break;
|
||||||
case ISD::CONVERT_RNDSAT:
|
case ISD::CONVERT_RNDSAT:
|
||||||
Res = PromoteIntOp_CONVERT_RNDSAT(N); break;
|
Res = PromoteIntOp_CONVERT_RNDSAT(N); break;
|
||||||
case ISD::INSERT_VECTOR_ELT:
|
case ISD::INSERT_VECTOR_ELT:
|
||||||
Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break;
|
Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break;
|
||||||
case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break;
|
case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break;
|
||||||
case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break;
|
case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break;
|
||||||
case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break;
|
case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break;
|
||||||
case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break;
|
case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break;
|
||||||
case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break;
|
case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break;
|
||||||
case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break;
|
case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break;
|
||||||
case ISD::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
|
case ISD::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
|
||||||
OpNo); break;
|
OpNo); break;
|
||||||
case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break;
|
case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break;
|
||||||
case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break;
|
case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break;
|
||||||
case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break;
|
case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the result is null, the sub-method took care of registering results etc.
|
// If the result is null, the sub-method took care of registering results etc.
|
||||||
if (!Res.getNode()) return false;
|
if (! Res.getNode()) return false;
|
||||||
|
|
||||||
// If the result is N, the sub-method updated N in place. Tell the legalizer
|
// If the result is N, the sub-method updated N in place. Tell the legalizer
|
||||||
// core about this.
|
// core about this.
|
||||||
@ -921,7 +918,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
|
|||||||
Lo = Hi = SDValue();
|
Lo = Hi = SDValue();
|
||||||
|
|
||||||
// See if the target wants to custom expand this node.
|
// See if the target wants to custom expand this node.
|
||||||
if (CustomLowerResults(N, ResNo))
|
if (CustomLowerResults(N, ResNo, true))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (N->getOpcode()) {
|
switch (N->getOpcode()) {
|
||||||
@ -1851,35 +1848,32 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
|
|||||||
DEBUG(cerr << "Expand integer operand: "; N->dump(&DAG); cerr << "\n");
|
DEBUG(cerr << "Expand integer operand: "; N->dump(&DAG); cerr << "\n");
|
||||||
SDValue Res = SDValue();
|
SDValue Res = SDValue();
|
||||||
|
|
||||||
if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
|
if (CustomLowerResults(N, OpNo, false))
|
||||||
== TargetLowering::Custom)
|
return false;
|
||||||
Res = TLI.LowerOperation(SDValue(N, 0), DAG);
|
|
||||||
|
|
||||||
if (Res.getNode() == 0) {
|
switch (N->getOpcode()) {
|
||||||
switch (N->getOpcode()) {
|
default:
|
||||||
default:
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
cerr << "ExpandIntegerOperand Op #" << OpNo << ": ";
|
cerr << "ExpandIntegerOperand Op #" << OpNo << ": ";
|
||||||
N->dump(&DAG); cerr << "\n";
|
N->dump(&DAG); cerr << "\n";
|
||||||
#endif
|
#endif
|
||||||
assert(0 && "Do not know how to expand this operator's operand!");
|
assert(0 && "Do not know how to expand this operator's operand!");
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
|
case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
|
||||||
case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break;
|
case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break;
|
||||||
case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
|
case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
|
||||||
case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
|
case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
|
||||||
case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
|
case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
|
||||||
|
|
||||||
case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
|
case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
|
||||||
case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
|
case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
|
||||||
case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
|
case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
|
||||||
case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break;
|
case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break;
|
||||||
case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo);
|
case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo);
|
||||||
break;
|
break;
|
||||||
case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
|
case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
|
||||||
case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break;
|
case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the result is null, the sub-method took care of registering results etc.
|
// If the result is null, the sub-method took care of registering results etc.
|
||||||
|
@ -848,14 +848,28 @@ SDValue DAGTypeLegalizer::CreateStackStoreLoad(SDValue Op,
|
|||||||
|
|
||||||
/// CustomLowerResults - Replace the node's results with custom code provided
|
/// CustomLowerResults - Replace the node's results with custom code provided
|
||||||
/// by the target and return "true", or do nothing and return "false".
|
/// by the target and return "true", or do nothing and return "false".
|
||||||
bool DAGTypeLegalizer::CustomLowerResults(SDNode *N, unsigned ResNo) {
|
/// The last parameter is FALSE if we are dealing with a node with legal
|
||||||
|
/// result types and illegal operand. The second parameter denotes the illegal
|
||||||
|
/// OperandNo in that case.
|
||||||
|
/// The last parameter being TRUE means we are dealing with a
|
||||||
|
/// node with illegal result types. The second parameter denotes the illegal
|
||||||
|
/// ResNo in that case.
|
||||||
|
bool DAGTypeLegalizer::CustomLowerResults(SDNode *N, unsigned Num,
|
||||||
|
bool LegalizeResult) {
|
||||||
|
// Get the type of illegal Result or Operand.
|
||||||
|
MVT ValueTy = (LegalizeResult) ? N->getValueType(Num)
|
||||||
|
: N->getOperand(Num).getValueType();
|
||||||
|
|
||||||
// See if the target wants to custom lower this node.
|
// See if the target wants to custom lower this node.
|
||||||
if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) !=
|
if (TLI.getOperationAction(N->getOpcode(), ValueTy) != TargetLowering::Custom)
|
||||||
TargetLowering::Custom)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SmallVector<SDValue, 8> Results;
|
SmallVector<SDValue, 8> Results;
|
||||||
TLI.ReplaceNodeResults(N, Results, DAG);
|
if (LegalizeResult)
|
||||||
|
TLI.ReplaceNodeResults(N, Results, DAG);
|
||||||
|
else
|
||||||
|
TLI.LowerOperationWrapper(SDValue(N, 0), Results, DAG);
|
||||||
|
|
||||||
if (Results.empty())
|
if (Results.empty())
|
||||||
// The target didn't want to custom lower it after all.
|
// The target didn't want to custom lower it after all.
|
||||||
return false;
|
return false;
|
||||||
|
@ -191,7 +191,7 @@ private:
|
|||||||
// Common routines.
|
// Common routines.
|
||||||
SDValue BitConvertToInteger(SDValue Op);
|
SDValue BitConvertToInteger(SDValue Op);
|
||||||
SDValue CreateStackStoreLoad(SDValue Op, MVT DestVT);
|
SDValue CreateStackStoreLoad(SDValue Op, MVT DestVT);
|
||||||
bool CustomLowerResults(SDNode *N, unsigned ResNo);
|
bool CustomLowerResults(SDNode *N, unsigned ResNo, bool LegalizeResult);
|
||||||
SDValue GetVectorElementPointer(SDValue VecPtr, MVT EltVT, SDValue Index);
|
SDValue GetVectorElementPointer(SDValue VecPtr, MVT EltVT, SDValue Index);
|
||||||
SDValue JoinIntegers(SDValue Lo, SDValue Hi);
|
SDValue JoinIntegers(SDValue Lo, SDValue Hi);
|
||||||
SDValue LibCallify(RTLIB::Libcall LC, SDNode *N, bool isSigned);
|
SDValue LibCallify(RTLIB::Libcall LC, SDNode *N, bool isSigned);
|
||||||
|
@ -5568,6 +5568,15 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
|
|||||||
return std::make_pair(Res, Chain);
|
return std::make_pair(Res, Chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TargetLowering::LowerOperationWrapper(SDValue Op,
|
||||||
|
SmallVectorImpl<SDValue> &Results,
|
||||||
|
SelectionDAG &DAG) {
|
||||||
|
SDValue Res;
|
||||||
|
Res = LowerOperation(Op, DAG);
|
||||||
|
if (Res.getNode())
|
||||||
|
Results.push_back(Res);
|
||||||
|
}
|
||||||
|
|
||||||
SDValue TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
SDValue TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
||||||
assert(0 && "LowerOperation not implemented for this target!");
|
assert(0 && "LowerOperation not implemented for this target!");
|
||||||
abort();
|
abort();
|
||||||
|
Loading…
Reference in New Issue
Block a user