aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/LowerPacked.cpp31
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp12
2 files changed, 43 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/LowerPacked.cpp b/lib/Transforms/Scalar/LowerPacked.cpp
index 45ed8b43fd..e8338bb96f 100644
--- a/lib/Transforms/Scalar/LowerPacked.cpp
+++ b/lib/Transforms/Scalar/LowerPacked.cpp
@@ -59,6 +59,10 @@ public:
/// @param SELI the select operator to convert
void visitSelectInst(SelectInst& SELI);
+ /// @brief Lowers packed extractelement instructions.
+ /// @param EI the extractelement operator to convert
+ void visitExtractElementInst(ExtractElementInst& EI);
+
/// This function asserts if the instruction is a PackedType but
/// is handled by another function.
///
@@ -332,6 +336,33 @@ void LowerPacked::visitSelectInst(SelectInst& SELI)
}
}
+void LowerPacked::visitExtractElementInst(ExtractElementInst& EI)
+{
+ std::vector<Value*>& op0Vals = getValues(EI.getOperand(0));
+ const PackedType *PTy = cast<PackedType>(EI.getOperand(0)->getType());
+ Value *op1 = EI.getOperand(1);
+
+ if (ConstantUInt *C = dyn_cast<ConstantUInt>(op1)) {
+ EI.replaceAllUsesWith(op0Vals[C->getValue()]);
+ } else {
+ AllocaInst *alloca = new AllocaInst(PTy->getElementType(),
+ ConstantUInt::get(Type::UIntTy, PTy->getNumElements()),
+ EI.getName() + ".alloca", &(EI.getParent()->getParent()->getEntryBlock().front()));
+ for (unsigned i = 0; i < PTy->getNumElements(); ++i) {
+ GetElementPtrInst *GEP = new GetElementPtrInst(alloca, ConstantUInt::get(Type::UIntTy, i),
+ "store.ge", &EI);
+ new StoreInst(op0Vals[i], GEP, &EI);
+ }
+ GetElementPtrInst *GEP = new GetElementPtrInst(alloca, op1,
+ EI.getName() + ".ge", &EI);
+ LoadInst *load = new LoadInst(GEP, EI.getName() + ".load", &EI);
+ EI.replaceAllUsesWith(load);
+ }
+
+ Changed = true;
+ instrsToRemove.push_back(&EI);
+}
+
bool LowerPacked::runOnFunction(Function& F)
{
// initialize
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp
index 491ca73fa3..1a76eb5e5e 100644
--- a/lib/Transforms/Scalar/SCCP.cpp
+++ b/lib/Transforms/Scalar/SCCP.cpp
@@ -322,6 +322,7 @@ private:
void visitSelectInst(SelectInst &I);
void visitBinaryOperator(Instruction &I);
void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); }
+ void visitExtractElementInst(ExtractElementInst &I);
// Instructions that cannot be folded away...
void visitStoreInst (Instruction &I);
@@ -728,6 +729,17 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) {
}
}
+void SCCPSolver::visitExtractElementInst(ExtractElementInst &I) {
+ LatticeVal &ValState = getValueState(I.getOperand(0));
+ LatticeVal &IdxState = getValueState(I.getOperand(1));
+
+ if (ValState.isOverdefined() || IdxState.isOverdefined())
+ markOverdefined(&I);
+ else if(ValState.isConstant() && IdxState.isConstant())
+ markConstant(&I, ConstantExpr::getExtractElement(ValState.getConstant(),
+ IdxState.getConstant()));
+}
+
// Handle getelementptr instructions... if all operands are constants then we
// can turn this into a getelementptr ConstantExpr.
//