mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +00:00
implement basic support for INSERT_VECTOR_ELT.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26849 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a064d28843
commit
2332b9f16f
@ -729,62 +729,92 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
|
||||
case ISD::BUILD_VECTOR:
|
||||
switch (TLI.getOperationAction(ISD::BUILD_VECTOR, Node->getValueType(0))) {
|
||||
default: assert(0 && "This action is not supported yet!");
|
||||
case TargetLowering::Custom:
|
||||
Tmp3 = TLI.LowerOperation(Result, DAG);
|
||||
if (Tmp3.Val) {
|
||||
Result = Tmp3;
|
||||
break;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
case TargetLowering::Expand: {
|
||||
// We assume that built vectors are not legal, and will be immediately
|
||||
// spilled to memory. If the values are all constants, turn this into a
|
||||
// load from the constant pool.
|
||||
bool isConstant = true;
|
||||
for (SDNode::op_iterator I = Node->op_begin(), E = Node->op_end();
|
||||
I != E; ++I) {
|
||||
if (!isa<ConstantFPSDNode>(I) && !isa<ConstantSDNode>(I) &&
|
||||
I->getOpcode() != ISD::UNDEF) {
|
||||
isConstant = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a ConstantPacked, and put it in the constant pool.
|
||||
if (isConstant) {
|
||||
MVT::ValueType VT = Node->getValueType(0);
|
||||
const Type *OpNTy =
|
||||
MVT::getTypeForValueType(Node->getOperand(0).getValueType());
|
||||
std::vector<Constant*> CV;
|
||||
for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
|
||||
if (ConstantFPSDNode *V =
|
||||
dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) {
|
||||
CV.push_back(ConstantFP::get(OpNTy, V->getValue()));
|
||||
} else if (ConstantSDNode *V =
|
||||
dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
|
||||
CV.push_back(ConstantUInt::get(OpNTy, V->getValue()));
|
||||
} else {
|
||||
assert(Node->getOperand(i).getOpcode() == ISD::UNDEF);
|
||||
CV.push_back(UndefValue::get(OpNTy));
|
||||
}
|
||||
}
|
||||
Constant *CP = ConstantPacked::get(CV);
|
||||
SDOperand CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy());
|
||||
Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
|
||||
DAG.getSrcValue(NULL));
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, this isn't a constant entry. Allocate a sufficiently
|
||||
// aligned object on the stack, store each element into it, then load
|
||||
// the result as a vector.
|
||||
assert(0 && "Cannot lower variable BUILD_VECTOR yet!");
|
||||
abort();
|
||||
default: assert(0 && "This action is not supported yet!");
|
||||
case TargetLowering::Custom:
|
||||
Tmp3 = TLI.LowerOperation(Result, DAG);
|
||||
if (Tmp3.Val) {
|
||||
Result = Tmp3;
|
||||
break;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
case TargetLowering::Expand: {
|
||||
// We assume that built vectors are not legal, and will be immediately
|
||||
// spilled to memory. If the values are all constants, turn this into a
|
||||
// load from the constant pool.
|
||||
bool isConstant = true;
|
||||
for (SDNode::op_iterator I = Node->op_begin(), E = Node->op_end();
|
||||
I != E; ++I) {
|
||||
if (!isa<ConstantFPSDNode>(I) && !isa<ConstantSDNode>(I) &&
|
||||
I->getOpcode() != ISD::UNDEF) {
|
||||
isConstant = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a ConstantPacked, and put it in the constant pool.
|
||||
if (isConstant) {
|
||||
MVT::ValueType VT = Node->getValueType(0);
|
||||
const Type *OpNTy =
|
||||
MVT::getTypeForValueType(Node->getOperand(0).getValueType());
|
||||
std::vector<Constant*> CV;
|
||||
for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
|
||||
if (ConstantFPSDNode *V =
|
||||
dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) {
|
||||
CV.push_back(ConstantFP::get(OpNTy, V->getValue()));
|
||||
} else if (ConstantSDNode *V =
|
||||
dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
|
||||
CV.push_back(ConstantUInt::get(OpNTy, V->getValue()));
|
||||
} else {
|
||||
assert(Node->getOperand(i).getOpcode() == ISD::UNDEF);
|
||||
CV.push_back(UndefValue::get(OpNTy));
|
||||
}
|
||||
}
|
||||
Constant *CP = ConstantPacked::get(CV);
|
||||
SDOperand CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy());
|
||||
Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
|
||||
DAG.getSrcValue(NULL));
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, this isn't a constant entry. Allocate a sufficiently
|
||||
// aligned object on the stack, store each element into it, then load
|
||||
// the result as a vector.
|
||||
assert(0 && "Cannot lower variable BUILD_VECTOR yet!");
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ISD::INSERT_VECTOR_ELT:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // InVec
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // InVal
|
||||
Tmp3 = LegalizeOp(Node->getOperand(2)); // InEltNo
|
||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
|
||||
|
||||
switch (TLI.getOperationAction(ISD::INSERT_VECTOR_ELT,
|
||||
Node->getValueType(0))) {
|
||||
default: assert(0 && "This action is not supported yet!");
|
||||
case TargetLowering::Legal:
|
||||
break;
|
||||
case TargetLowering::Custom:
|
||||
Tmp3 = TLI.LowerOperation(Result, DAG);
|
||||
if (Tmp3.Val) {
|
||||
Result = Tmp3;
|
||||
break;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
case TargetLowering::Expand: {
|
||||
// If the target doesn't support this, we have to spill the input vector
|
||||
// to a temporary stack slot, update the element, then reload it. This is
|
||||
// badness. We could also load the value into a vector register (either
|
||||
// with a "move to register" or "extload into register" instruction, then
|
||||
// permute it into place, if the idx is a constant and if the idx is
|
||||
// supported by the target.
|
||||
assert(0 && "INSERT_VECTOR_ELT expand not supported yet!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ISD::CALLSEQ_START: {
|
||||
SDNode *CallEnd = FindCallEndFromCallStart(Node);
|
||||
|
||||
@ -4104,7 +4134,9 @@ SDOperand SelectionDAGLegalize::PackVectorOp(SDOperand Op,
|
||||
|
||||
SDOperand Result;
|
||||
switch (Node->getOpcode()) {
|
||||
default: assert(0 && "Unknown vector operation!");
|
||||
default:
|
||||
Node->dump(); std::cerr << "\n";
|
||||
assert(0 && "Unknown vector operation in PackVectorOp!");
|
||||
case ISD::VADD:
|
||||
case ISD::VSUB:
|
||||
case ISD::VMUL:
|
||||
@ -4138,6 +4170,16 @@ SDOperand SelectionDAGLegalize::PackVectorOp(SDOperand Op,
|
||||
Result = DAG.getNode(ISD::BUILD_VECTOR, NewVT, Ops);
|
||||
}
|
||||
break;
|
||||
case ISD::VINSERT_VECTOR_ELT:
|
||||
if (!MVT::isVector(NewVT)) {
|
||||
// Returning a scalar? Must be the inserted element.
|
||||
Result = Node->getOperand(1);
|
||||
} else {
|
||||
Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT,
|
||||
PackVectorOp(Node->getOperand(0), NewVT),
|
||||
Node->getOperand(1), Node->getOperand(2));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (TLI.isTypeLegal(NewVT))
|
||||
|
@ -842,33 +842,15 @@ void SelectionDAGLowering::visitCast(User &I) {
|
||||
}
|
||||
|
||||
void SelectionDAGLowering::visitInsertElement(InsertElementInst &I) {
|
||||
const PackedType *Ty = cast<PackedType>(I.getType());
|
||||
unsigned NumElements = Ty->getNumElements();
|
||||
MVT::ValueType PVT = TLI.getValueType(Ty->getElementType());
|
||||
MVT::ValueType TVT = MVT::getVectorType(PVT, NumElements);
|
||||
|
||||
SDOperand InVec = getValue(I.getOperand(0));
|
||||
SDOperand InVal = getValue(I.getOperand(1));
|
||||
SDOperand InIdx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(),
|
||||
getValue(I.getOperand(2)));
|
||||
|
||||
// Immediately scalarize packed types containing only one element, so that
|
||||
// the Legalize pass does not have to deal with them. Similarly, if the
|
||||
// abstract vector is going to turn into one that the target natively
|
||||
// supports, generate that type now so that Legalize doesn't have to deal
|
||||
// with that either. These steps ensure that Legalize only has to handle
|
||||
// vector types in its Expand case.
|
||||
if (NumElements == 1) {
|
||||
setValue(&I, InVal); // Must be insertelt(Vec, InVal, 0) -> InVal
|
||||
} else if (TVT != MVT::Other && TLI.isTypeLegal(TVT) &&
|
||||
TLI.isOperationLegal(ISD::INSERT_VECTOR_ELT, TVT)) {
|
||||
setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT, TVT, InVec, InVal, InIdx));
|
||||
} else {
|
||||
SDOperand Num = DAG.getConstant(NumElements, MVT::i32);
|
||||
SDOperand Typ = DAG.getValueType(PVT);
|
||||
setValue(&I, DAG.getNode(ISD::VINSERT_VECTOR_ELT, MVT::Vector,
|
||||
InVec, InVal, InIdx, Num, Typ));
|
||||
}
|
||||
SDOperand Num = *(InVec.Val->op_end()-2);
|
||||
SDOperand Typ = *(InVec.Val->op_end()-1);
|
||||
setValue(&I, DAG.getNode(ISD::VINSERT_VECTOR_ELT, MVT::Vector,
|
||||
InVec, InVal, InIdx, Num, Typ));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user