mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
VMCore support for the insertelement operation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25408 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
956fd7254f
commit
c152f9cd26
@ -734,6 +734,63 @@ Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val,
|
||||||
|
const Constant *Elt,
|
||||||
|
const Constant *Idx) {
|
||||||
|
const ConstantUInt *CIdx = dyn_cast<ConstantUInt>(Idx);
|
||||||
|
if (!CIdx) return 0;
|
||||||
|
unsigned idxVal = CIdx->getValue();
|
||||||
|
if (const UndefValue *UVal = dyn_cast<UndefValue>(Val)) {
|
||||||
|
// Insertion of scalar constant into packed undef
|
||||||
|
// Optimize away insertion of undef
|
||||||
|
if (isa<UndefValue>(Elt))
|
||||||
|
return const_cast<Constant*>(Val);
|
||||||
|
// Otherwise break the aggregate undef into multiple undefs and do
|
||||||
|
// the insertion
|
||||||
|
unsigned numOps =
|
||||||
|
cast<PackedType>(Val->getType())->getNumElements();
|
||||||
|
std::vector<Constant*> Ops;
|
||||||
|
Ops.reserve(numOps);
|
||||||
|
for (unsigned i = 0; i < numOps; ++i) {
|
||||||
|
const Constant *Op =
|
||||||
|
(i == idxVal) ? Elt : UndefValue::get(Elt->getType());
|
||||||
|
Ops.push_back(const_cast<Constant*>(Op));
|
||||||
|
}
|
||||||
|
return ConstantPacked::get(Ops);
|
||||||
|
}
|
||||||
|
if (const ConstantAggregateZero *CVal =
|
||||||
|
dyn_cast<ConstantAggregateZero>(Val)) {
|
||||||
|
// Insertion of scalar constant into packed aggregate zero
|
||||||
|
// Optimize away insertion of zero
|
||||||
|
if (Elt->isNullValue())
|
||||||
|
return const_cast<Constant*>(Val);
|
||||||
|
// Otherwise break the aggregate zero into multiple zeros and do
|
||||||
|
// the insertion
|
||||||
|
unsigned numOps =
|
||||||
|
cast<PackedType>(Val->getType())->getNumElements();
|
||||||
|
std::vector<Constant*> Ops;
|
||||||
|
Ops.reserve(numOps);
|
||||||
|
for (unsigned i = 0; i < numOps; ++i) {
|
||||||
|
const Constant *Op =
|
||||||
|
(i == idxVal) ? Elt : Constant::getNullValue(Elt->getType());
|
||||||
|
Ops.push_back(const_cast<Constant*>(Op));
|
||||||
|
}
|
||||||
|
return ConstantPacked::get(Ops);
|
||||||
|
}
|
||||||
|
if (const ConstantPacked *CVal = dyn_cast<ConstantPacked>(Val)) {
|
||||||
|
// Insertion of scalar constant into packed constant
|
||||||
|
std::vector<Constant*> Ops;
|
||||||
|
Ops.reserve(CVal->getNumOperands());
|
||||||
|
for (unsigned i = 0; i < CVal->getNumOperands(); ++i) {
|
||||||
|
const Constant *Op =
|
||||||
|
(i == idxVal) ? Elt : cast<Constant>(CVal->getOperand(i));
|
||||||
|
Ops.push_back(const_cast<Constant*>(Op));
|
||||||
|
}
|
||||||
|
return ConstantPacked::get(Ops);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// isZeroSizedType - This type is zero sized if its an array or structure of
|
/// isZeroSizedType - This type is zero sized if its an array or structure of
|
||||||
/// zero sized types. The only leaf zero sized type is an empty structure.
|
/// zero sized types. The only leaf zero sized type is an empty structure.
|
||||||
static bool isMaybeZeroSizedType(const Type *Ty) {
|
static bool isMaybeZeroSizedType(const Type *Ty) {
|
||||||
|
@ -33,6 +33,9 @@ namespace llvm {
|
|||||||
const Constant *V2);
|
const Constant *V2);
|
||||||
Constant *ConstantFoldExtractElementInstruction(const Constant *Val,
|
Constant *ConstantFoldExtractElementInstruction(const Constant *Val,
|
||||||
const Constant *Idx);
|
const Constant *Idx);
|
||||||
|
Constant *ConstantFoldInsertElementInstruction(const Constant *Val,
|
||||||
|
const Constant *Elt,
|
||||||
|
const Constant *Idx);
|
||||||
Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
|
Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
|
||||||
const Constant *V2);
|
const Constant *V2);
|
||||||
Constant *ConstantFoldGetElementPtr(const Constant *C,
|
Constant *ConstantFoldGetElementPtr(const Constant *C,
|
||||||
|
@ -33,6 +33,9 @@ namespace llvm {
|
|||||||
const Constant *V2);
|
const Constant *V2);
|
||||||
Constant *ConstantFoldExtractElementInstruction(const Constant *Val,
|
Constant *ConstantFoldExtractElementInstruction(const Constant *Val,
|
||||||
const Constant *Idx);
|
const Constant *Idx);
|
||||||
|
Constant *ConstantFoldInsertElementInstruction(const Constant *Val,
|
||||||
|
const Constant *Elt,
|
||||||
|
const Constant *Idx);
|
||||||
Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
|
Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
|
||||||
const Constant *V2);
|
const Constant *V2);
|
||||||
Constant *ConstantFoldGetElementPtr(const Constant *C,
|
Constant *ConstantFoldGetElementPtr(const Constant *C,
|
||||||
|
@ -347,8 +347,9 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// ExtractElementConstantExpr - This class is private to Constants.cpp, and is used
|
/// ExtractElementConstantExpr - This class is private to
|
||||||
/// behind the scenes to implement extractelement constant exprs.
|
/// Constants.cpp, and is used behind the scenes to implement
|
||||||
|
/// extractelement constant exprs.
|
||||||
class ExtractElementConstantExpr : public ConstantExpr {
|
class ExtractElementConstantExpr : public ConstantExpr {
|
||||||
Use Ops[2];
|
Use Ops[2];
|
||||||
public:
|
public:
|
||||||
@ -360,6 +361,21 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// InsertElementConstantExpr - This class is private to
|
||||||
|
/// Constants.cpp, and is used behind the scenes to implement
|
||||||
|
/// insertelement constant exprs.
|
||||||
|
class InsertElementConstantExpr : public ConstantExpr {
|
||||||
|
Use Ops[3];
|
||||||
|
public:
|
||||||
|
InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
|
||||||
|
: ConstantExpr(C1->getType(), Instruction::InsertElement,
|
||||||
|
Ops, 3) {
|
||||||
|
Ops[0].init(C1, this);
|
||||||
|
Ops[1].init(C2, this);
|
||||||
|
Ops[2].init(C3, this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
|
/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
|
||||||
/// used behind the scenes to implement getelementpr constant exprs.
|
/// used behind the scenes to implement getelementpr constant exprs.
|
||||||
struct GetElementPtrConstantExpr : public ConstantExpr {
|
struct GetElementPtrConstantExpr : public ConstantExpr {
|
||||||
@ -1156,6 +1172,9 @@ namespace llvm {
|
|||||||
return new SelectConstantExpr(V.second[0], V.second[1], V.second[2]);
|
return new SelectConstantExpr(V.second[0], V.second[1], V.second[2]);
|
||||||
if (V.first == Instruction::ExtractElement)
|
if (V.first == Instruction::ExtractElement)
|
||||||
return new ExtractElementConstantExpr(V.second[0], V.second[1]);
|
return new ExtractElementConstantExpr(V.second[0], V.second[1]);
|
||||||
|
if (V.first == Instruction::InsertElement)
|
||||||
|
return new InsertElementConstantExpr(V.second[0], V.second[1],
|
||||||
|
V.second[2]);
|
||||||
|
|
||||||
assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!");
|
assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!");
|
||||||
|
|
||||||
@ -1416,11 +1435,35 @@ Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) {
|
|||||||
assert(isa<PackedType>(Val->getType()) &&
|
assert(isa<PackedType>(Val->getType()) &&
|
||||||
"Tried to create extractelement operation on non-packed type!");
|
"Tried to create extractelement operation on non-packed type!");
|
||||||
assert(Idx->getType() == Type::UIntTy &&
|
assert(Idx->getType() == Type::UIntTy &&
|
||||||
"Index must be uint type!");
|
"Extractelement index must be uint type!");
|
||||||
return getExtractElementTy(cast<PackedType>(Val->getType())->getElementType(),
|
return getExtractElementTy(cast<PackedType>(Val->getType())->getElementType(),
|
||||||
Val, Idx);
|
Val, Idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val,
|
||||||
|
Constant *Elt, Constant *Idx) {
|
||||||
|
if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx))
|
||||||
|
return FC; // Fold a few common cases...
|
||||||
|
// Look up the constant in the table first to ensure uniqueness
|
||||||
|
std::vector<Constant*> ArgVec(1, Val);
|
||||||
|
ArgVec.push_back(Elt);
|
||||||
|
ArgVec.push_back(Idx);
|
||||||
|
const ExprMapKeyType &Key = std::make_pair(Instruction::InsertElement,ArgVec);
|
||||||
|
return ExprConstants.getOrCreate(ReqTy, Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
|
||||||
|
Constant *Idx) {
|
||||||
|
assert(isa<PackedType>(Val->getType()) &&
|
||||||
|
"Tried to create insertelement operation on non-packed type!");
|
||||||
|
assert(Elt->getType() == cast<PackedType>(Val->getType())->getElementType()
|
||||||
|
&& "Insertelement types must match!");
|
||||||
|
assert(Idx->getType() == Type::UIntTy &&
|
||||||
|
"Insertelement index must be uint type!");
|
||||||
|
return getInsertElementTy(cast<PackedType>(Val->getType())->getElementType(),
|
||||||
|
Val, Elt, Idx);
|
||||||
|
}
|
||||||
|
|
||||||
// destroyConstant - Remove the constant from the constant table...
|
// destroyConstant - Remove the constant from the constant table...
|
||||||
//
|
//
|
||||||
void ConstantExpr::destroyConstant() {
|
void ConstantExpr::destroyConstant() {
|
||||||
|
@ -121,6 +121,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
|
|||||||
case Shr: return "shr";
|
case Shr: return "shr";
|
||||||
case VAArg: return "va_arg";
|
case VAArg: return "va_arg";
|
||||||
case ExtractElement: return "extractelement";
|
case ExtractElement: return "extractelement";
|
||||||
|
case InsertElement: return "insertelement";
|
||||||
|
|
||||||
default: return "<Invalid operator> ";
|
default: return "<Invalid operator> ";
|
||||||
}
|
}
|
||||||
|
@ -800,7 +800,7 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
|
ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
|
||||||
const std::string &Name, Instruction *InsertBef)
|
const std::string &Name, Instruction *InsertBef)
|
||||||
: Instruction(cast<PackedType>(Val->getType())->getElementType(),
|
: Instruction(cast<PackedType>(Val->getType())->getElementType(),
|
||||||
ExtractElement, Ops, 2, Name, InsertBef) {
|
ExtractElement, Ops, 2, Name, InsertBef) {
|
||||||
Ops[0].init(Val, this);
|
Ops[0].init(Val, this);
|
||||||
@ -808,13 +808,33 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
|
ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
|
||||||
const std::string &Name, BasicBlock *InsertAE)
|
const std::string &Name, BasicBlock *InsertAE)
|
||||||
: Instruction(cast<PackedType>(Val->getType())->getElementType(),
|
: Instruction(cast<PackedType>(Val->getType())->getElementType(),
|
||||||
ExtractElement, Ops, 2, Name, InsertAE) {
|
ExtractElement, Ops, 2, Name, InsertAE) {
|
||||||
Ops[0].init(Val, this);
|
Ops[0].init(Val, this);
|
||||||
Ops[1].init(Index, this);
|
Ops[1].init(Index, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// InsertElementInst Implementation
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
InsertElementInst::InsertElementInst(Value *Val, Value *Elt, Value *Index,
|
||||||
|
const std::string &Name, Instruction *InsertBef)
|
||||||
|
: Instruction(Val->getType(), InsertElement, Ops, 3, Name, InsertBef) {
|
||||||
|
Ops[0].init(Val, this);
|
||||||
|
Ops[1].init(Elt, this);
|
||||||
|
Ops[2].init(Index, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertElementInst::InsertElementInst(Value *Val, Value *Elt, Value *Index,
|
||||||
|
const std::string &Name, BasicBlock *InsertAE)
|
||||||
|
: Instruction(Val->getType(), InsertElement, Ops, 3, Name, InsertAE) {
|
||||||
|
Ops[0].init(Val, this);
|
||||||
|
Ops[1].init(Elt, this);
|
||||||
|
Ops[2].init(Index, this);
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// BinaryOperator Class
|
// BinaryOperator Class
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -1176,6 +1196,7 @@ ShiftInst *ShiftInst::clone() const { return new ShiftInst(*this); }
|
|||||||
SelectInst *SelectInst::clone() const { return new SelectInst(*this); }
|
SelectInst *SelectInst::clone() const { return new SelectInst(*this); }
|
||||||
VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); }
|
VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); }
|
||||||
ExtractElementInst *ExtractElementInst::clone() const {return new ExtractElementInst(*this); }
|
ExtractElementInst *ExtractElementInst::clone() const {return new ExtractElementInst(*this); }
|
||||||
|
InsertElementInst *InsertElementInst::clone() const {return new InsertElementInst(*this); }
|
||||||
PHINode *PHINode::clone() const { return new PHINode(*this); }
|
PHINode *PHINode::clone() const { return new PHINode(*this); }
|
||||||
ReturnInst *ReturnInst::clone() const { return new ReturnInst(*this); }
|
ReturnInst *ReturnInst::clone() const { return new ReturnInst(*this); }
|
||||||
BranchInst *BranchInst::clone() const { return new BranchInst(*this); }
|
BranchInst *BranchInst::clone() const { return new BranchInst(*this); }
|
||||||
|
@ -140,7 +140,7 @@ namespace { // Anonymous namespace for class
|
|||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.setPreservesAll();
|
AU.setPreservesAll();
|
||||||
if (RealPass)
|
if (RealPass)
|
||||||
AU.addRequired<ETForest>();
|
AU.addRequired<ETForest>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// abortIfBroken - If the module is broken and we are supposed to abort on
|
/// abortIfBroken - If the module is broken and we are supposed to abort on
|
||||||
@ -180,6 +180,7 @@ namespace { // Anonymous namespace for class
|
|||||||
void visitBinaryOperator(BinaryOperator &B);
|
void visitBinaryOperator(BinaryOperator &B);
|
||||||
void visitShiftInst(ShiftInst &SI);
|
void visitShiftInst(ShiftInst &SI);
|
||||||
void visitExtractElementInst(ExtractElementInst &EI);
|
void visitExtractElementInst(ExtractElementInst &EI);
|
||||||
|
void visitInsertElementInst(InsertElementInst &EI);
|
||||||
void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); }
|
void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); }
|
||||||
void visitCallInst(CallInst &CI);
|
void visitCallInst(CallInst &CI);
|
||||||
void visitGetElementPtrInst(GetElementPtrInst &GEP);
|
void visitGetElementPtrInst(GetElementPtrInst &GEP);
|
||||||
@ -540,12 +541,24 @@ void Verifier::visitExtractElementInst(ExtractElementInst &EI) {
|
|||||||
Assert1(EI.getOperand(1)->getType() == Type::UIntTy,
|
Assert1(EI.getOperand(1)->getType() == Type::UIntTy,
|
||||||
"Second operand to extractelement must be uint type!", &EI);
|
"Second operand to extractelement must be uint type!", &EI);
|
||||||
Assert1(EI.getType() ==
|
Assert1(EI.getType() ==
|
||||||
cast<PackedType>(EI.getOperand(0)->getType())->getElementType(),
|
cast<PackedType>(EI.getOperand(0)->getType())->getElementType(),
|
||||||
"Extractelement return type must be same as "
|
"Extractelement return type must match "
|
||||||
"first operand element type!", &EI);
|
"first operand element type!", &EI);
|
||||||
visitInstruction(EI);
|
visitInstruction(EI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Verifier::visitInsertElementInst(InsertElementInst &IE) {
|
||||||
|
Assert1(isa<PackedType>(IE.getOperand(0)->getType()),
|
||||||
|
"First operand to insertelement must be packed type!", &IE);
|
||||||
|
Assert1(IE.getOperand(1)->getType() ==
|
||||||
|
cast<PackedType>(IE.getOperand(0)->getType())->getElementType(),
|
||||||
|
"Second operand to insertelement must match "
|
||||||
|
"first operand element type!", &IE);
|
||||||
|
Assert1(IE.getOperand(2)->getType() == Type::UIntTy,
|
||||||
|
"Third operand to insertelement must be uint type!", &IE);
|
||||||
|
visitInstruction(IE);
|
||||||
|
}
|
||||||
|
|
||||||
void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||||
const Type *ElTy =
|
const Type *ElTy =
|
||||||
GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(),
|
GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(),
|
||||||
|
Loading…
Reference in New Issue
Block a user