Add intitial support for promoting some operators.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19565 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-01-15 05:21:40 +00:00
parent 59615f0f85
commit 03c8546ec5

View File

@ -81,6 +81,11 @@ class SelectionDAGLegalize {
/// allows us to avoid legalizing the same thing more than once.
std::map<SDOperand, SDOperand> LegalizedNodes;
/// PromotedNodes - For nodes that are below legal width, and that have more
/// than one use, this map indicates what promoted value to use. This allows
/// us to avoid promoting the same thing more than once.
std::map<SDOperand, SDOperand> PromotedNodes;
/// ExpandedNodes - For nodes that need to be expanded, and which have more
/// than one use, this map indicates which which operands are the expanded
/// version of the input. This allows us to avoid expanding the same node
@ -91,6 +96,10 @@ class SelectionDAGLegalize {
bool isNew = LegalizedNodes.insert(std::make_pair(From, To)).second;
assert(isNew && "Got into the map somehow?");
}
void AddPromotedOperand(SDOperand From, SDOperand To) {
bool isNew = PromotedNodes.insert(std::make_pair(From, To)).second;
assert(isNew && "Got into the map somehow?");
}
/// setValueTypeAction - Set the action for a particular value type. This
/// assumes an action has not already been set for this value type.
@ -157,6 +166,7 @@ private:
SDOperand LegalizeOp(SDOperand O);
void ExpandOp(SDOperand O, SDOperand &Lo, SDOperand &Hi);
SDOperand PromoteOp(SDOperand O);
SDOperand getIntPtrConstant(uint64_t Val) {
return DAG.getConstant(Val, TLI.getPointerTy());
@ -217,8 +227,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
return LegalizedNodes[Op];
}
case Promote:
// FIXME: Implement promotion!
assert(0 && "Promotion not implemented at all yet!");
PromoteOp(Op.getValue(i));
assert(LegalizedNodes.count(Op) &&
"Expansion didn't add legal operands!");
return LegalizedNodes[Op];
}
}
@ -478,8 +490,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
Tmp2 = LegalizeOp(Node->getOperand(2)); // Legalize the pointer.
// Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr'
if (ConstantFPSDNode *CFP =
dyn_cast<ConstantFPSDNode>(Node->getOperand(1))) {
if (ConstantFPSDNode *CFP =dyn_cast<ConstantFPSDNode>(Node->getOperand(1))){
if (CFP->getValueType(0) == MVT::f32) {
union {
unsigned I;
@ -511,7 +522,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
break;
}
case Promote:
assert(0 && "FIXME: promote for stores not implemented!");
// Truncate the value and store the result.
Tmp3 = PromoteOp(Node->getOperand(1));
Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp3, Tmp2,
Node->getOperand(1).getValueType());
break;
case Expand:
SDOperand Lo, Hi;
ExpandOp(Node->getOperand(1), Lo, Hi);
@ -696,8 +712,28 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
Result = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0), Tmp1);
break;
default:
assert(0 && "Do not know how to promote this yet!");
case Promote:
switch (Node->getOpcode()) {
case ISD::ZERO_EXTEND: {
// Mask out the high bits.
uint64_t MaskCst =
1ULL << (MVT::getSizeInBits(Node->getOperand(0).getValueType()))-1;
Tmp1 = PromoteOp(Node->getOperand(0));
Result = DAG.getNode(ISD::AND, Node->getValueType(0), Tmp1,
DAG.getConstant(MaskCst, Node->getValueType(0)));
break;
}
case ISD::SIGN_EXTEND:
case ISD::TRUNCATE:
case ISD::FP_EXTEND:
case ISD::FP_ROUND:
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT:
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP:
Node->dump();
assert(0 && "Do not know how to promote this yet!");
}
}
break;
}
@ -708,6 +744,82 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
return Result;
}
SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
MVT::ValueType VT = Op.getValueType();
MVT::ValueType NVT = TransformToType[VT];
assert(getTypeAction(VT) == Promote &&
"Caller should expand or legalize operands that are not promotable!");
assert(NVT > VT && MVT::isInteger(NVT) == MVT::isInteger(VT) &&
"Cannot promote to smaller type!");
std::map<SDOperand, SDOperand>::iterator I = PromotedNodes.find(Op);
if (I != PromotedNodes.end()) return I->second;
SDOperand Tmp1, Tmp2, Tmp3;
SDOperand Result;
SDNode *Node = Op.Val;
switch (Node->getOpcode()) {
default:
std::cerr << "NODE: "; Node->dump(); std::cerr << "\n";
assert(0 && "Do not know how to promote this operator!");
abort();
case ISD::Constant:
Result = DAG.getNode(ISD::ZERO_EXTEND, NVT, Op);
assert(isa<ConstantSDNode>(Result) && "Didn't constant fold zext?");
break;
case ISD::ConstantFP:
Result = DAG.getNode(ISD::FP_EXTEND, NVT, Op);
assert(isa<ConstantFPSDNode>(Result) && "Didn't constant fold fp_extend?");
break;
case ISD::TRUNCATE:
switch (getTypeAction(Node->getOperand(0).getValueType())) {
case Legal:
Result = LegalizeOp(Node->getOperand(0));
assert(Result.getValueType() >= NVT &&
"This truncation doesn't make sense!");
if (Result.getValueType() > NVT) // Truncate to NVT instead of VT
Result = DAG.getNode(ISD::TRUNCATE, NVT, Result);
break;
case Expand:
assert(0 && "Cannot handle expand yet");
case Promote:
assert(0 && "Cannot handle promote-promote yet");
}
break;
case ISD::AND:
case ISD::OR:
case ISD::XOR:
// The logical ops can just execute, they don't care what the top bits
// coming in are.
Tmp1 = PromoteOp(Node->getOperand(0));
Tmp2 = PromoteOp(Node->getOperand(1));
assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT);
Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
break;
case ISD::LOAD:
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
Result = DAG.getNode(ISD::EXTLOAD, NVT, Tmp1, Tmp2, VT);
// Remember that we legalized the chain.
AddLegalizedOperand(Op.getValue(1), Result.getValue(1));
break;
case ISD::SELECT:
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the condition
Tmp2 = PromoteOp(Node->getOperand(1)); // Legalize the op0
Tmp3 = PromoteOp(Node->getOperand(2)); // Legalize the op1
Result = DAG.getNode(ISD::SELECT, NVT, Tmp1, Tmp2, Tmp3);
break;
}
assert(Result.Val && "Didn't set a result!");
AddPromotedOperand(Op, Result);
return Result;
}
/// ExpandOp - Expand the specified SDOperand into its two component pieces
/// Lo&Hi. Note that the Op MUST be an expanded type. As a result of this, the