forked from OSchip/llvm-project
Return Expand from getOperationAction for all extended
types. This is needed for SIGN_EXTEND_INREG at least. It is not clear if this is correct for other operations. On the other hand, for the various load/store actions it seems to correct to return the type action, as is currently done. Also, it seems that SelectionDAG::getValueType can be called for extended value types; introduce a map for holding these, since we don't really want to extend the vector to be 2^32 pointers long! Generalize DAGTypeLegalizer::PromoteResult_TRUNCATE and DAGTypeLegalizer::PromoteResult_INT_EXTEND to handle the various funky possibilities that apints introduce, for example that you can promote to a type that needs to be expanded. llvm-svn: 43071
This commit is contained in:
parent
91ff13edcc
commit
d42c812f4a
|
@ -541,6 +541,7 @@ private:
|
|||
std::vector<CondCodeSDNode*> CondCodeNodes;
|
||||
|
||||
std::vector<SDNode*> ValueTypeNodes;
|
||||
std::map<MVT::ValueType, SDNode*> ExtendedValueTypeNodes;
|
||||
std::map<std::string, SDNode*> ExternalSymbols;
|
||||
std::map<std::string, SDNode*> TargetExternalSymbols;
|
||||
std::map<std::string, StringSDNode*> StringNodes;
|
||||
|
|
|
@ -273,7 +273,7 @@ public:
|
|||
/// expanded to some other code sequence, or the target has a custom expander
|
||||
/// for it.
|
||||
LegalizeAction getOperationAction(unsigned Op, MVT::ValueType VT) const {
|
||||
if (MVT::isExtendedVT(VT)) return getTypeAction(VT);
|
||||
if (MVT::isExtendedVT(VT)) return Expand;
|
||||
return (LegalizeAction)((OpActions[Op] >> (2*VT)) & 3);
|
||||
}
|
||||
|
||||
|
|
|
@ -1762,8 +1762,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||
Result = DAG.getExtLoad(ExtType, Node->getValueType(0), Tmp1, Tmp2,
|
||||
LD->getSrcValue(), LD->getSrcValueOffset(),
|
||||
MVT::i8, LD->isVolatile(), LD->getAlignment());
|
||||
Tmp1 = Result.getValue(0);
|
||||
Tmp2 = Result.getValue(1);
|
||||
Tmp1 = Result.getValue(0);
|
||||
Tmp2 = Result.getValue(1);
|
||||
break;
|
||||
case TargetLowering::Custom:
|
||||
isCustom = true;
|
||||
|
|
|
@ -390,7 +390,6 @@ void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) {
|
|||
OpEntry = Result;
|
||||
}
|
||||
|
||||
|
||||
void DAGTypeLegalizer::GetExpandedOp(SDOperand Op, SDOperand &Lo,
|
||||
SDOperand &Hi) {
|
||||
std::pair<SDOperand, SDOperand> &Entry = ExpandedNodes[Op];
|
||||
|
@ -479,46 +478,53 @@ SDOperand DAGTypeLegalizer::PromoteResult_Constant(SDNode *N) {
|
|||
}
|
||||
|
||||
SDOperand DAGTypeLegalizer::PromoteResult_TRUNCATE(SDNode *N) {
|
||||
MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
|
||||
SDOperand Res;
|
||||
|
||||
switch (getTypeAction(N->getOperand(0).getValueType())) {
|
||||
default: assert(0 && "Unknown type action!");
|
||||
case Legal: {
|
||||
SDOperand Res = N->getOperand(0);
|
||||
assert(Res.getValueType() >= NVT && "Truncation doesn't make sense!");
|
||||
if (Res.getValueType() > NVT) // Truncate to NVT instead of VT
|
||||
return DAG.getNode(ISD::TRUNCATE, NVT, Res);
|
||||
return Res;
|
||||
}
|
||||
case Promote:
|
||||
// The truncation is not required, because we don't guarantee anything
|
||||
// about high bits anyway.
|
||||
return GetPromotedOp(N->getOperand(0));
|
||||
case Legal:
|
||||
case Expand:
|
||||
// Truncate the low part of the expanded value to the result type
|
||||
SDOperand Lo, Hi;
|
||||
GetExpandedOp(N->getOperand(0), Lo, Hi);
|
||||
return DAG.getNode(ISD::TRUNCATE, NVT, Lo);
|
||||
Res = N->getOperand(0);
|
||||
break;
|
||||
case Promote:
|
||||
Res = GetPromotedOp(N->getOperand(0));
|
||||
break;
|
||||
}
|
||||
|
||||
MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
|
||||
assert(MVT::getSizeInBits(Res.getValueType()) >= MVT::getSizeInBits(NVT) &&
|
||||
"Truncation doesn't make sense!");
|
||||
if (Res.getValueType() == NVT)
|
||||
return Res;
|
||||
|
||||
// Truncate to NVT instead of VT
|
||||
return DAG.getNode(ISD::TRUNCATE, NVT, Res);
|
||||
}
|
||||
|
||||
SDOperand DAGTypeLegalizer::PromoteResult_INT_EXTEND(SDNode *N) {
|
||||
MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
|
||||
switch (getTypeAction(N->getOperand(0).getValueType())) {
|
||||
default: assert(0 && "BUG: Smaller reg should have been promoted!");
|
||||
case Legal:
|
||||
// Input is legal? Just do extend all the way to the larger type.
|
||||
return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0));
|
||||
case Promote:
|
||||
// Get promoted operand if it is smaller.
|
||||
|
||||
if (getTypeAction(N->getOperand(0).getValueType()) == Promote) {
|
||||
SDOperand Res = GetPromotedOp(N->getOperand(0));
|
||||
// The high bits are not guaranteed to be anything. Insert an extend.
|
||||
if (N->getOpcode() == ISD::SIGN_EXTEND)
|
||||
return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
|
||||
DAG.getValueType(N->getOperand(0).getValueType()));
|
||||
if (N->getOpcode() == ISD::ZERO_EXTEND)
|
||||
return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType());
|
||||
assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
|
||||
return Res;
|
||||
assert(MVT::getSizeInBits(Res.getValueType()) <= MVT::getSizeInBits(NVT) &&
|
||||
"Extension doesn't make sense!");
|
||||
|
||||
// If the result and operand types are the same after promotion, simplify
|
||||
// to an in-register extension.
|
||||
if (NVT == Res.getValueType()) {
|
||||
// The high bits are not guaranteed to be anything. Insert an extend.
|
||||
if (N->getOpcode() == ISD::SIGN_EXTEND)
|
||||
return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
|
||||
DAG.getValueType(N->getOperand(0).getValueType()));
|
||||
if (N->getOpcode() == ISD::ZERO_EXTEND)
|
||||
return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType());
|
||||
assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
|
||||
return Res;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, just extend the original operand all the way to the larger type.
|
||||
return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0));
|
||||
}
|
||||
|
||||
SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) {
|
||||
|
@ -527,7 +533,6 @@ SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) {
|
|||
N->getOperand(0), DAG.getValueType(N->getValueType(0)));
|
||||
}
|
||||
|
||||
|
||||
SDOperand DAGTypeLegalizer::PromoteResult_SETCC(SDNode *N) {
|
||||
assert(isTypeLegal(TLI.getSetCCResultTy()) && "SetCC type is not legal??");
|
||||
return DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), N->getOperand(0),
|
||||
|
@ -1198,6 +1203,7 @@ SDOperand DAGTypeLegalizer::PromoteOperand_ZERO_EXTEND(SDNode *N) {
|
|||
Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
|
||||
return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType());
|
||||
}
|
||||
|
||||
SDOperand DAGTypeLegalizer::PromoteOperand_SIGN_EXTEND(SDNode *N) {
|
||||
SDOperand Op = GetPromotedOp(N->getOperand(0));
|
||||
Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
|
||||
|
|
|
@ -527,10 +527,16 @@ void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
|
|||
Erased =
|
||||
TargetExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol());
|
||||
break;
|
||||
case ISD::VALUETYPE:
|
||||
Erased = ValueTypeNodes[cast<VTSDNode>(N)->getVT()] != 0;
|
||||
ValueTypeNodes[cast<VTSDNode>(N)->getVT()] = 0;
|
||||
case ISD::VALUETYPE: {
|
||||
MVT::ValueType VT = cast<VTSDNode>(N)->getVT();
|
||||
if (MVT::isExtendedVT(VT)) {
|
||||
Erased = ExtendedValueTypeNodes.erase(VT);
|
||||
} else {
|
||||
Erased = ValueTypeNodes[VT] != 0;
|
||||
ValueTypeNodes[VT] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Remove it from the CSE Map.
|
||||
Erased = CSEMap.RemoveNode(N);
|
||||
|
@ -847,15 +853,16 @@ SDOperand SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {
|
|||
}
|
||||
|
||||
SDOperand SelectionDAG::getValueType(MVT::ValueType VT) {
|
||||
assert(!MVT::isExtendedVT(VT) && "Expecting a simple value type!");
|
||||
if ((unsigned)VT >= ValueTypeNodes.size())
|
||||
if (!MVT::isExtendedVT(VT) && (unsigned)VT >= ValueTypeNodes.size())
|
||||
ValueTypeNodes.resize(VT+1);
|
||||
if (ValueTypeNodes[VT] == 0) {
|
||||
ValueTypeNodes[VT] = new VTSDNode(VT);
|
||||
AllNodes.push_back(ValueTypeNodes[VT]);
|
||||
}
|
||||
|
||||
return SDOperand(ValueTypeNodes[VT], 0);
|
||||
SDNode *&N = MVT::isExtendedVT(VT) ?
|
||||
ExtendedValueTypeNodes[VT] : ValueTypeNodes[VT];
|
||||
|
||||
if (N) return SDOperand(N, 0);
|
||||
N = new VTSDNode(VT);
|
||||
AllNodes.push_back(N);
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getExternalSymbol(const char *Sym, MVT::ValueType VT) {
|
||||
|
|
Loading…
Reference in New Issue