mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
Add shufflevector support, todo, implement better constant folding.
llvm-svn: 27510
This commit is contained in:
parent
4bd21d8de2
commit
14b19acd56
@ -1237,7 +1237,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
|
|||||||
|
|
||||||
// Shift Left & Right print both types even for Ubyte LHS, and select prints
|
// Shift Left & Right print both types even for Ubyte LHS, and select prints
|
||||||
// types even if all operands are bools.
|
// types even if all operands are bools.
|
||||||
if (isa<ShiftInst>(I) || isa<SelectInst>(I) || isa<StoreInst>(I)) {
|
if (isa<ShiftInst>(I) || isa<SelectInst>(I) || isa<StoreInst>(I) ||
|
||||||
|
isa<ShuffleVectorInst>(I)) {
|
||||||
PrintAllTypes = true;
|
PrintAllTypes = true;
|
||||||
} else {
|
} else {
|
||||||
for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) {
|
for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) {
|
||||||
|
@ -908,6 +908,14 @@ Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1,
|
||||||
|
const Constant *V2,
|
||||||
|
const Constant *Mask) {
|
||||||
|
// TODO:
|
||||||
|
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) {
|
||||||
|
@ -36,6 +36,9 @@ namespace llvm {
|
|||||||
Constant *ConstantFoldInsertElementInstruction(const Constant *Val,
|
Constant *ConstantFoldInsertElementInstruction(const Constant *Val,
|
||||||
const Constant *Elt,
|
const Constant *Elt,
|
||||||
const Constant *Idx);
|
const Constant *Idx);
|
||||||
|
Constant *ConstantFoldShuffleVectorInstruction(const Constant *V1,
|
||||||
|
const Constant *V2,
|
||||||
|
const Constant *Mask);
|
||||||
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,
|
||||||
|
@ -376,6 +376,21 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// ShuffleVectorConstantExpr - This class is private to
|
||||||
|
/// Constants.cpp, and is used behind the scenes to implement
|
||||||
|
/// shufflevector constant exprs.
|
||||||
|
class ShuffleVectorConstantExpr : public ConstantExpr {
|
||||||
|
Use Ops[3];
|
||||||
|
public:
|
||||||
|
ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
|
||||||
|
: ConstantExpr(C1->getType(), Instruction::ShuffleVector,
|
||||||
|
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 {
|
||||||
@ -1175,7 +1190,10 @@ namespace llvm {
|
|||||||
if (V.first == Instruction::InsertElement)
|
if (V.first == Instruction::InsertElement)
|
||||||
return new InsertElementConstantExpr(V.second[0], V.second[1],
|
return new InsertElementConstantExpr(V.second[0], V.second[1],
|
||||||
V.second[2]);
|
V.second[2]);
|
||||||
|
if (V.first == Instruction::ShuffleVector)
|
||||||
|
return new ShuffleVectorConstantExpr(V.second[0], V.second[1],
|
||||||
|
V.second[2]);
|
||||||
|
|
||||||
assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!");
|
assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!");
|
||||||
|
|
||||||
std::vector<Constant*> IdxList(V.second.begin()+1, V.second.end());
|
std::vector<Constant*> IdxList(V.second.begin()+1, V.second.end());
|
||||||
@ -1464,6 +1482,26 @@ Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
|
|||||||
Val, Elt, Idx);
|
Val, Elt, Idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1,
|
||||||
|
Constant *V2, Constant *Mask) {
|
||||||
|
if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask))
|
||||||
|
return FC; // Fold a few common cases...
|
||||||
|
// Look up the constant in the table first to ensure uniqueness
|
||||||
|
std::vector<Constant*> ArgVec(1, V1);
|
||||||
|
ArgVec.push_back(V2);
|
||||||
|
ArgVec.push_back(Mask);
|
||||||
|
const ExprMapKeyType &Key = std::make_pair(Instruction::ShuffleVector,ArgVec);
|
||||||
|
return ExprConstants.getOrCreate(ReqTy, Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
|
||||||
|
Constant *Mask) {
|
||||||
|
assert(ShuffleVectorInst::isValidOperands(V1, V2, Mask) &&
|
||||||
|
"Invalid shuffle vector constant expr operands!");
|
||||||
|
return getShuffleVectorTy(V1->getType(), V1, V2, Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// destroyConstant - Remove the constant from the constant table...
|
// destroyConstant - Remove the constant from the constant table...
|
||||||
//
|
//
|
||||||
void ConstantExpr::destroyConstant() {
|
void ConstantExpr::destroyConstant() {
|
||||||
|
@ -122,6 +122,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
|
|||||||
case VAArg: return "va_arg";
|
case VAArg: return "va_arg";
|
||||||
case ExtractElement: return "extractelement";
|
case ExtractElement: return "extractelement";
|
||||||
case InsertElement: return "insertelement";
|
case InsertElement: return "insertelement";
|
||||||
|
case ShuffleVector: return "shufflevector";
|
||||||
|
|
||||||
default: return "<Invalid operator> ";
|
default: return "<Invalid operator> ";
|
||||||
}
|
}
|
||||||
|
@ -800,7 +800,8 @@ 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,7 +809,8 @@ 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);
|
||||||
@ -820,7 +822,8 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
InsertElementInst::InsertElementInst(Value *Val, Value *Elt, Value *Index,
|
InsertElementInst::InsertElementInst(Value *Val, Value *Elt, Value *Index,
|
||||||
const std::string &Name, Instruction *InsertBef)
|
const std::string &Name,
|
||||||
|
Instruction *InsertBef)
|
||||||
: Instruction(Val->getType(), InsertElement, Ops, 3, Name, InsertBef) {
|
: Instruction(Val->getType(), InsertElement, Ops, 3, Name, InsertBef) {
|
||||||
Ops[0].init(Val, this);
|
Ops[0].init(Val, this);
|
||||||
Ops[1].init(Elt, this);
|
Ops[1].init(Elt, this);
|
||||||
@ -828,13 +831,54 @@ InsertElementInst::InsertElementInst(Value *Val, Value *Elt, Value *Index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
InsertElementInst::InsertElementInst(Value *Val, Value *Elt, Value *Index,
|
InsertElementInst::InsertElementInst(Value *Val, Value *Elt, Value *Index,
|
||||||
const std::string &Name, BasicBlock *InsertAE)
|
const std::string &Name,
|
||||||
|
BasicBlock *InsertAE)
|
||||||
: Instruction(Val->getType(), InsertElement, Ops, 3, Name, InsertAE) {
|
: Instruction(Val->getType(), InsertElement, Ops, 3, Name, InsertAE) {
|
||||||
Ops[0].init(Val, this);
|
Ops[0].init(Val, this);
|
||||||
Ops[1].init(Elt, this);
|
Ops[1].init(Elt, this);
|
||||||
Ops[2].init(Index, this);
|
Ops[2].init(Index, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// ShuffleVectorInst Implementation
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
|
||||||
|
const std::string &Name,
|
||||||
|
Instruction *InsertBefore)
|
||||||
|
: Instruction(V1->getType(), ShuffleVector, Ops, 3, Name, InsertBefore) {
|
||||||
|
assert(isValidOperands(V1, V2, Mask) &&
|
||||||
|
"Invalid shuffle vector instruction operands!");
|
||||||
|
Ops[0].init(V1, this);
|
||||||
|
Ops[1].init(V2, this);
|
||||||
|
Ops[2].init(Mask, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
|
||||||
|
const std::string &Name,
|
||||||
|
BasicBlock *InsertAtEnd)
|
||||||
|
: Instruction(V1->getType(), ShuffleVector, Ops, 3, Name, InsertAtEnd) {
|
||||||
|
assert(isValidOperands(V1, V2, Mask) &&
|
||||||
|
"Invalid shuffle vector instruction operands!");
|
||||||
|
|
||||||
|
Ops[0].init(V1, this);
|
||||||
|
Ops[1].init(V2, this);
|
||||||
|
Ops[2].init(Mask, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
|
||||||
|
const Value *Mask) {
|
||||||
|
if (!isa<PackedType>(V1->getType())) return false;
|
||||||
|
if (V1->getType() != V2->getType()) return false;
|
||||||
|
if (!isa<PackedType>(Mask->getType()) ||
|
||||||
|
cast<PackedType>(Mask->getType())->getElementType() != Type::UIntTy ||
|
||||||
|
cast<PackedType>(Mask->getType())->getNumElements() !=
|
||||||
|
cast<PackedType>(V1->getType())->getNumElements())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// BinaryOperator Class
|
// BinaryOperator Class
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -1202,8 +1246,15 @@ CallInst *CallInst::clone() const { return new CallInst(*this); }
|
|||||||
ShiftInst *ShiftInst::clone() const { return new ShiftInst(*this); }
|
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 {
|
||||||
InsertElementInst *InsertElementInst::clone() const {return new InsertElementInst(*this); }
|
return new ExtractElementInst(*this);
|
||||||
|
}
|
||||||
|
InsertElementInst *InsertElementInst::clone() const {
|
||||||
|
return new InsertElementInst(*this);
|
||||||
|
}
|
||||||
|
ShuffleVectorInst *ShuffleVectorInst::clone() const {
|
||||||
|
return new ShuffleVectorInst(*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); }
|
||||||
|
@ -184,6 +184,7 @@ namespace { // Anonymous namespace for class
|
|||||||
void visitShiftInst(ShiftInst &SI);
|
void visitShiftInst(ShiftInst &SI);
|
||||||
void visitExtractElementInst(ExtractElementInst &EI);
|
void visitExtractElementInst(ExtractElementInst &EI);
|
||||||
void visitInsertElementInst(InsertElementInst &EI);
|
void visitInsertElementInst(InsertElementInst &EI);
|
||||||
|
void visitShuffleVectorInst(ShuffleVectorInst &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);
|
||||||
@ -562,6 +563,29 @@ void Verifier::visitInsertElementInst(InsertElementInst &IE) {
|
|||||||
visitInstruction(IE);
|
visitInstruction(IE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Verifier::visitShuffleVectorInst(ShuffleVectorInst &SV) {
|
||||||
|
Assert1(ShuffleVectorInst::isValidOperands(SV.getOperand(0), SV.getOperand(1),
|
||||||
|
SV.getOperand(2)),
|
||||||
|
"Invalid shufflevector operands!", &SV);
|
||||||
|
Assert1(SV.getType() == SV.getOperand(0)->getType(),
|
||||||
|
"Result of shufflevector must match first operand type!", &SV);
|
||||||
|
|
||||||
|
// Check to see if Mask is valid.
|
||||||
|
if (const ConstantPacked *MV = dyn_cast<ConstantPacked>(SV.getOperand(2))) {
|
||||||
|
for (unsigned i = 0, e = MV->getNumOperands(); i != e; ++i) {
|
||||||
|
Assert1(isa<ConstantUInt>(MV->getOperand(i)) ||
|
||||||
|
isa<UndefValue>(MV->getOperand(i)),
|
||||||
|
"Invalid shufflevector shuffle mask!", &SV);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Assert1(isa<UndefValue>(SV.getOperand(2)) ||
|
||||||
|
isa<ConstantAggregateZero>(SV.getOperand(2)),
|
||||||
|
"Invalid shufflevector shuffle mask!", &SV);
|
||||||
|
}
|
||||||
|
|
||||||
|
visitInstruction(SV);
|
||||||
|
}
|
||||||
|
|
||||||
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