Index: lib/Analysis/InlineCost.cpp =================================================================== --- lib/Analysis/InlineCost.cpp +++ lib/Analysis/InlineCost.cpp @@ -208,6 +208,12 @@ bool visitCleanupReturnInst(CleanupReturnInst &RI); bool visitCatchReturnInst(CatchReturnInst &RI); bool visitUnreachableInst(UnreachableInst &I); + /// Simplify \p I if its operands are constants and update SimplifiedValues. + /// Evaluate is a lambda specific to instruction type that evaluates the + /// instruction when all the operands are constants. + bool + simplifyInstruction(Instruction &I, + function_ref)> Evaluate); public: CallAnalyzer(const TargetTransformInfo &TTI, @@ -452,16 +458,32 @@ return isGEPFree(I); } +bool CallAnalyzer::simplifyInstruction( + Instruction &I, function_ref)> Evaluate) { + Constant *COps[2]; + int N = 0; + for (Value *Op : I.operands()) { + Constant *COp = dyn_cast(Op); + if (!COp) + COp = SimplifiedValues.lookup(Op); + if (!COp) + return false; + COps[N++] = COp; + } + if (auto *C = Evaluate(COps)) { + SimplifiedValues[&I] = C; + return true; + } + return false; +} + bool CallAnalyzer::visitBitCast(BitCastInst &I) { // Propagate constants through bitcasts. - Constant *COp = dyn_cast(I.getOperand(0)); - if (!COp) - COp = SimplifiedValues.lookup(I.getOperand(0)); - if (COp) - if (Constant *C = ConstantExpr::getBitCast(COp, I.getType())) { - SimplifiedValues[&I] = C; - return true; - } + auto Evaluate = [&](ArrayRef COps) -> Constant * { + return ConstantExpr::getBitCast(COps[0], I.getType()); + }; + if (simplifyInstruction(I, Evaluate)) + return true; // Track base/offsets through casts std::pair BaseAndOffset = @@ -482,14 +504,11 @@ bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) { // Propagate constants through ptrtoint. - Constant *COp = dyn_cast(I.getOperand(0)); - if (!COp) - COp = SimplifiedValues.lookup(I.getOperand(0)); - if (COp) - if (Constant *C = ConstantExpr::getPtrToInt(COp, I.getType())) { - SimplifiedValues[&I] = C; - return true; - } + auto Evaluate = [&](ArrayRef COps) -> Constant * { + return ConstantExpr::getPtrToInt(COps[0], I.getType()); + }; + if (simplifyInstruction(I, Evaluate)) + return true; // Track base/offset pairs when converted to a plain integer provided the // integer is large enough to represent the pointer. @@ -519,14 +538,11 @@ bool CallAnalyzer::visitIntToPtr(IntToPtrInst &I) { // Propagate constants through ptrtoint. - Constant *COp = dyn_cast(I.getOperand(0)); - if (!COp) - COp = SimplifiedValues.lookup(I.getOperand(0)); - if (COp) - if (Constant *C = ConstantExpr::getIntToPtr(COp, I.getType())) { - SimplifiedValues[&I] = C; - return true; - } + auto Evaluate = [&](ArrayRef COps) -> Constant * { + return ConstantExpr::getIntToPtr(COps[0], I.getType()); + }; + if (simplifyInstruction(I, Evaluate)) + return true; // Track base/offset pairs when round-tripped through a pointer without // modifications provided the integer is not too large. @@ -550,14 +566,11 @@ bool CallAnalyzer::visitCastInst(CastInst &I) { // Propagate constants through ptrtoint. - Constant *COp = dyn_cast(I.getOperand(0)); - if (!COp) - COp = SimplifiedValues.lookup(I.getOperand(0)); - if (COp) - if (Constant *C = ConstantExpr::getCast(I.getOpcode(), COp, I.getType())) { - SimplifiedValues[&I] = C; - return true; - } + auto Evaluate = [&](ArrayRef COps) -> Constant * { + return ConstantExpr::getCast(I.getOpcode(), COps[0], I.getType()); + }; + if (simplifyInstruction(I, Evaluate)) + return true; // Disable SROA in the face of arbitrary casts we don't whitelist elsewhere. disableSROA(I.getOperand(0)); @@ -567,16 +580,12 @@ bool CallAnalyzer::visitUnaryInstruction(UnaryInstruction &I) { Value *Operand = I.getOperand(0); - Constant *COp = dyn_cast(Operand); - if (!COp) - COp = SimplifiedValues.lookup(Operand); - if (COp) { + auto Evaluate = [&](ArrayRef COps) -> Constant * { const DataLayout &DL = F.getParent()->getDataLayout(); - if (Constant *C = ConstantFoldInstOperands(&I, COp, DL)) { - SimplifiedValues[&I] = C; - return true; - } - } + return ConstantFoldInstOperands(&I, COps[0], DL); + }; + if (simplifyInstruction(I, Evaluate)) + return true; // Disable any SROA on the argument to arbitrary unary operators. disableSROA(Operand); @@ -697,20 +706,11 @@ bool CallAnalyzer::visitCmpInst(CmpInst &I) { Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); // First try to handle simplified comparisons. - if (!isa(LHS)) - if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS)) - LHS = SimpleLHS; - if (!isa(RHS)) - if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS)) - RHS = SimpleRHS; - if (Constant *CLHS = dyn_cast(LHS)) { - if (Constant *CRHS = dyn_cast(RHS)) - if (Constant *C = - ConstantExpr::getCompare(I.getPredicate(), CLHS, CRHS)) { - SimplifiedValues[&I] = C; - return true; - } - } + auto Evaluate = [&](ArrayRef COps) -> Constant * { + return ConstantExpr::getCompare(I.getPredicate(), COps[0], COps[1]); + }; + if (simplifyInstruction(I, Evaluate)) + return true; if (I.getOpcode() == Instruction::FCmp) return false; @@ -788,24 +788,19 @@ bool CallAnalyzer::visitBinaryOperator(BinaryOperator &I) { Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); - const DataLayout &DL = F.getParent()->getDataLayout(); - if (!isa(LHS)) - if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS)) - LHS = SimpleLHS; - if (!isa(RHS)) - if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS)) - RHS = SimpleRHS; - Value *SimpleV = nullptr; - if (auto FI = dyn_cast(&I)) - SimpleV = - SimplifyFPBinOp(I.getOpcode(), LHS, RHS, FI->getFastMathFlags(), DL); - else - SimpleV = SimplifyBinOp(I.getOpcode(), LHS, RHS, DL); + auto Evaluate = [&](ArrayRef COps) -> Constant * { + Value *SimpleV = nullptr; + const DataLayout &DL = F.getParent()->getDataLayout(); + if (auto FI = dyn_cast(&I)) + SimpleV = SimplifyFPBinOp(I.getOpcode(), COps[0], COps[1], + FI->getFastMathFlags(), DL); + else + SimpleV = SimplifyBinOp(I.getOpcode(), COps[0], COps[1], DL); + return dyn_cast_or_null(SimpleV); + }; - if (Constant *C = dyn_cast_or_null(SimpleV)) { - SimplifiedValues[&I] = C; + if (simplifyInstruction(I, Evaluate)) return true; - } // Disable any SROA on arguments to arbitrary, unsimplified binary operators. disableSROA(LHS); @@ -846,13 +841,11 @@ bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) { // Constant folding for extract value is trivial. - Constant *C = dyn_cast(I.getAggregateOperand()); - if (!C) - C = SimplifiedValues.lookup(I.getAggregateOperand()); - if (C) { - SimplifiedValues[&I] = ConstantExpr::getExtractValue(C, I.getIndices()); + auto Evaluate = [&](ArrayRef COps) -> Constant * { + return ConstantExpr::getExtractValue(COps[0], I.getIndices()); + }; + if (simplifyInstruction(I, Evaluate)) return true; - } // SROA can look through these but give them a cost. return false; @@ -860,17 +853,13 @@ bool CallAnalyzer::visitInsertValue(InsertValueInst &I) { // Constant folding for insert value is trivial. - Constant *AggC = dyn_cast(I.getAggregateOperand()); - if (!AggC) - AggC = SimplifiedValues.lookup(I.getAggregateOperand()); - Constant *InsertedC = dyn_cast(I.getInsertedValueOperand()); - if (!InsertedC) - InsertedC = SimplifiedValues.lookup(I.getInsertedValueOperand()); - if (AggC && InsertedC) { - SimplifiedValues[&I] = - ConstantExpr::getInsertValue(AggC, InsertedC, I.getIndices()); + auto Evaluate = [&](ArrayRef COps) -> Constant * { + return ConstantExpr::getInsertValue(/*AggregateOperand*/ COps[0], + /*InsertedValueOperand*/ COps[1], + I.getIndices()); + }; + if (simplifyInstruction(I, Evaluate)) return true; - } // SROA can look through these but give them a cost. return false;