mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-10 02:25:47 +00:00
Add some statistics, good for understanding how much more powerful
instcombine is compared to instsimplify. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122397 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "instsimplify"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
@@ -28,6 +30,10 @@ using namespace llvm::PatternMatch;
|
||||
|
||||
#define RecursionLimit 3
|
||||
|
||||
STATISTIC(NumExpand, "Number of expansions");
|
||||
STATISTIC(NumFactor , "Number of factorizations");
|
||||
STATISTIC(NumReassoc, "Number of reassociations");
|
||||
|
||||
static Value *SimplifyAndInst(Value *, Value *, const TargetData *,
|
||||
const DominatorTree *, unsigned);
|
||||
static Value *SimplifyBinOp(unsigned, Value *, Value *, const TargetData *,
|
||||
@@ -81,14 +87,19 @@ static Value *ExpandBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
if (Value *R = SimplifyBinOp(Opcode, B, C, TD, DT, MaxRecurse)) {
|
||||
// They do! Return "L op' R" if it simplifies or is already available.
|
||||
// If "L op' R" equals "A op' B" then "L op' R" is just the LHS.
|
||||
if ((L == A && R == B) ||
|
||||
(Instruction::isCommutative(OpcodeToExpand) && L == B && R == A))
|
||||
if ((L == A && R == B) || (Instruction::isCommutative(OpcodeToExpand)
|
||||
&& L == B && R == A)) {
|
||||
++NumExpand;
|
||||
return LHS;
|
||||
}
|
||||
// Otherwise return "L op' R" if it simplifies.
|
||||
if (Value *V = SimplifyBinOp(OpcodeToExpand, L, R, TD, DT,MaxRecurse))
|
||||
if (Value *V = SimplifyBinOp(OpcodeToExpand, L, R, TD, DT,
|
||||
MaxRecurse)) {
|
||||
++NumExpand;
|
||||
return V;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether the expression has the form "A op (B op' C)".
|
||||
if (BinaryOperator *Op1 = dyn_cast<BinaryOperator>(RHS))
|
||||
@@ -100,14 +111,19 @@ static Value *ExpandBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
if (Value *R = SimplifyBinOp(Opcode, A, C, TD, DT, MaxRecurse)) {
|
||||
// They do! Return "L op' R" if it simplifies or is already available.
|
||||
// If "L op' R" equals "B op' C" then "L op' R" is just the RHS.
|
||||
if ((L == B && R == C) ||
|
||||
(Instruction::isCommutative(OpcodeToExpand) && L == C && R == B))
|
||||
if ((L == B && R == C) || (Instruction::isCommutative(OpcodeToExpand)
|
||||
&& L == C && R == B)) {
|
||||
++NumExpand;
|
||||
return RHS;
|
||||
}
|
||||
// Otherwise return "L op' R" if it simplifies.
|
||||
if (Value *V = SimplifyBinOp(OpcodeToExpand, L, R, TD, DT,MaxRecurse))
|
||||
if (Value *V = SimplifyBinOp(OpcodeToExpand, L, R, TD, DT,
|
||||
MaxRecurse)) {
|
||||
++NumExpand;
|
||||
return V;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -144,12 +160,17 @@ static Value *FactorizeBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
if (Value *V = SimplifyBinOp(Opcode, B, DD, TD, DT, MaxRecurse)) {
|
||||
// It does! Return "A op' V" if it simplifies or is already available.
|
||||
// If V equals B then "A op' V" is just the LHS.
|
||||
if (V == B) return LHS;
|
||||
if (V == B) {
|
||||
++NumFactor;
|
||||
return LHS;
|
||||
}
|
||||
// Otherwise return "A op' V" if it simplifies.
|
||||
if (Value *W = SimplifyBinOp(OpcodeToExtract, A, V, TD, DT, MaxRecurse))
|
||||
if (Value *W = SimplifyBinOp(OpcodeToExtract, A, V, TD, DT, MaxRecurse)) {
|
||||
++NumFactor;
|
||||
return W;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use right distributivity, i.e. "(X op Y) op' Z = (X op' Z) op (Y op' Z)".
|
||||
// Does the instruction have the form "(A op' B) op (C op' B)" or, in the
|
||||
@@ -161,12 +182,17 @@ static Value *FactorizeBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
if (Value *V = SimplifyBinOp(Opcode, A, CC, TD, DT, MaxRecurse)) {
|
||||
// It does! Return "V op' B" if it simplifies or is already available.
|
||||
// If V equals A then "V op' B" is just the LHS.
|
||||
if (V == B) return LHS;
|
||||
if (V == B) {
|
||||
++NumFactor;
|
||||
return LHS;
|
||||
}
|
||||
// Otherwise return "V op' B" if it simplifies.
|
||||
if (Value *W = SimplifyBinOp(OpcodeToExtract, V, B, TD, DT, MaxRecurse))
|
||||
if (Value *W = SimplifyBinOp(OpcodeToExtract, V, B, TD, DT, MaxRecurse)) {
|
||||
++NumFactor;
|
||||
return W;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -198,10 +224,12 @@ static Value *SimplifyAssociativeBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
// If V equals B then "A op V" is just the LHS.
|
||||
if (V == B) return LHS;
|
||||
// Otherwise return "A op V" if it simplifies.
|
||||
if (Value *W = SimplifyBinOp(Opcode, A, V, TD, DT, MaxRecurse))
|
||||
if (Value *W = SimplifyBinOp(Opcode, A, V, TD, DT, MaxRecurse)) {
|
||||
++NumReassoc;
|
||||
return W;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transform: "A op (B op C)" ==> "(A op B) op C" if it simplifies completely.
|
||||
if (Op1 && Op1->getOpcode() == Opcode) {
|
||||
@@ -215,10 +243,12 @@ static Value *SimplifyAssociativeBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
// If V equals B then "V op C" is just the RHS.
|
||||
if (V == B) return RHS;
|
||||
// Otherwise return "V op C" if it simplifies.
|
||||
if (Value *W = SimplifyBinOp(Opcode, V, C, TD, DT, MaxRecurse))
|
||||
if (Value *W = SimplifyBinOp(Opcode, V, C, TD, DT, MaxRecurse)) {
|
||||
++NumReassoc;
|
||||
return W;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The remaining transforms require commutativity as well as associativity.
|
||||
if (!Instruction::isCommutative(Opcode))
|
||||
@@ -236,10 +266,12 @@ static Value *SimplifyAssociativeBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
// If V equals A then "V op B" is just the LHS.
|
||||
if (V == A) return LHS;
|
||||
// Otherwise return "V op B" if it simplifies.
|
||||
if (Value *W = SimplifyBinOp(Opcode, V, B, TD, DT, MaxRecurse))
|
||||
if (Value *W = SimplifyBinOp(Opcode, V, B, TD, DT, MaxRecurse)) {
|
||||
++NumReassoc;
|
||||
return W;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transform: "A op (B op C)" ==> "B op (C op A)" if it simplifies completely.
|
||||
if (Op1 && Op1->getOpcode() == Opcode) {
|
||||
@@ -253,10 +285,12 @@ static Value *SimplifyAssociativeBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
// If V equals C then "B op V" is just the RHS.
|
||||
if (V == C) return RHS;
|
||||
// Otherwise return "B op V" if it simplifies.
|
||||
if (Value *W = SimplifyBinOp(Opcode, B, V, TD, DT, MaxRecurse))
|
||||
if (Value *W = SimplifyBinOp(Opcode, B, V, TD, DT, MaxRecurse)) {
|
||||
++NumReassoc;
|
||||
return W;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -58,6 +58,8 @@ STATISTIC(NumCombined , "Number of insts combined");
|
||||
STATISTIC(NumConstProp, "Number of constant folds");
|
||||
STATISTIC(NumDeadInst , "Number of dead inst eliminated");
|
||||
STATISTIC(NumSunkInst , "Number of instructions sunk");
|
||||
STATISTIC(NumFactor , "Number of factorizations");
|
||||
STATISTIC(NumReassoc , "Number of reassociations");
|
||||
|
||||
// Initialization Routines
|
||||
void llvm::initializeInstCombine(PassRegistry &Registry) {
|
||||
@@ -155,6 +157,7 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
|
||||
I.setOperand(0, A);
|
||||
I.setOperand(1, V);
|
||||
Changed = true;
|
||||
++NumReassoc;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -171,6 +174,7 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
|
||||
I.setOperand(0, V);
|
||||
I.setOperand(1, C);
|
||||
Changed = true;
|
||||
++NumReassoc;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -189,6 +193,7 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
|
||||
I.setOperand(0, V);
|
||||
I.setOperand(1, B);
|
||||
Changed = true;
|
||||
++NumReassoc;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -205,6 +210,7 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
|
||||
I.setOperand(0, B);
|
||||
I.setOperand(1, V);
|
||||
Changed = true;
|
||||
++NumReassoc;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -321,9 +327,11 @@ Instruction *InstCombiner::SimplifyByFactorizing(BinaryOperator &I) {
|
||||
// operations "A op' B" and "C op' D" will be zapped since no longer used.
|
||||
if (!RHS && Op0->hasOneUse() && Op1->hasOneUse())
|
||||
RHS = Builder->CreateBinOp(OuterOpcode, B, D, Op1->getName());
|
||||
if (RHS)
|
||||
if (RHS) {
|
||||
++NumFactor;
|
||||
return BinaryOperator::Create(InnerOpcode, A, RHS);
|
||||
}
|
||||
}
|
||||
|
||||
// Does "(X op Y) op' Z" always equal "(X op' Z) op (Y op' Z)"?
|
||||
if (RightDistributesOverLeft(OuterOpcode, InnerOpcode))
|
||||
@@ -339,9 +347,11 @@ Instruction *InstCombiner::SimplifyByFactorizing(BinaryOperator &I) {
|
||||
// operations "A op' B" and "C op' D" will be zapped since no longer used.
|
||||
if (!LHS && Op0->hasOneUse() && Op1->hasOneUse())
|
||||
LHS = Builder->CreateBinOp(OuterOpcode, A, C, Op0->getName());
|
||||
if (LHS)
|
||||
if (LHS) {
|
||||
++NumFactor;
|
||||
return BinaryOperator::Create(InnerOpcode, LHS, B);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user