diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index c9eb2474328..f58b60db346 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -59,7 +59,7 @@ namespace { SHUFFLE, SELECT, TRUNC, ZEXT, SEXT, FPTOUI, FPTOSI, UITOFP, SITOFP, FPTRUNC, FPEXT, PTRTOINT, INTTOPTR, BITCAST, GEP, CALL, CONSTANT, - EMPTY, TOMBSTONE }; + EXTRACTVALUE, INSERTVALUE, EMPTY, TOMBSTONE }; ExpressionOpcode opcode; const Type* type; @@ -150,6 +150,8 @@ namespace { Expression create_expression(GetElementPtrInst* G); Expression create_expression(CallInst* C); Expression create_expression(Constant* C); + Expression create_expression(InsertValueInst* I); + Expression create_expression(ExtractValueInst* I); public: ValueTable() : nextValueNumber(1) { } uint32_t lookup_or_add(Value* V); @@ -284,6 +286,40 @@ Expression::ExpressionOpcode ValueTable::getOpcode(CastInst* C) { } } +Expression ValueTable::create_expression(InsertValueInst* I) { + Expression e; + + e.type = I->getType(); + e.firstVN = lookup_or_add(I->getOperand(0)); + e.secondVN = lookup_or_add(I->getOperand(1)); + e.thirdVN = 0; + e.function = 0; + e.opcode = Expression::INSERTVALUE; + + for (InsertValueInst::op_iterator OI = I->op_begin()+2, + OE = I->op_end(); OI != OE; ++OI) + e.varargs.push_back(lookup_or_add(I)); + + return e; +} + +Expression ValueTable::create_expression(ExtractValueInst* I) { + Expression e; + + e.type = I->getType(); + e.firstVN = lookup_or_add(I->getOperand(0)); + e.secondVN = lookup_or_add(I->getOperand(1)); + e.thirdVN = 0; + e.function = 0; + e.opcode = Expression::EXTRACTVALUE; + + for (InsertValueInst::op_iterator OI = I->op_begin()+2, + OE = I->op_end(); OI != OE; ++OI) + e.varargs.push_back(lookup_or_add(I)); + + return e; +} + Expression ValueTable::create_expression(CallInst* C) { Expression e; @@ -539,6 +575,32 @@ uint32_t ValueTable::lookup_or_add(Value* V) { } else { valueNumbering.insert(std::make_pair(V, nextValueNumber)); + return nextValueNumber++; + } + } else if (InsertValueInst* II = dyn_cast(V)) { + Expression e = create_expression(II); + + DenseMap::iterator EI = expressionNumbering.find(e); + if (EI != expressionNumbering.end()) { + valueNumbering.insert(std::make_pair(V, EI->second)); + return EI->second; + } else { + expressionNumbering.insert(std::make_pair(e, nextValueNumber)); + valueNumbering.insert(std::make_pair(V, nextValueNumber)); + + return nextValueNumber++; + } + } else if (ExtractValueInst* E = dyn_cast(V)) { + Expression e = create_expression(E); + + DenseMap::iterator EI = expressionNumbering.find(e); + if (EI != expressionNumbering.end()) { + valueNumbering.insert(std::make_pair(V, EI->second)); + return EI->second; + } else { + expressionNumbering.insert(std::make_pair(e, nextValueNumber)); + valueNumbering.insert(std::make_pair(V, nextValueNumber)); + return nextValueNumber++; } } else if (BinaryOperator* BO = dyn_cast(V)) {