Now that Reassociate's LinearizeExprTree can look through arbitrary expression

topologies, it is quite possible for a leaf node to have huge multiplicity, for
example: x0 = x*x, x1 = x0*x0, x2 = x1*x1, ... rapidly gives a value which is x
raised to a vast power (the multiplicity, or weight, of x).  This patch fixes
the computation of weights by correctly computing them no matter how big they
are, rather than just overflowing and getting a wrong value.  It turns out that
the weight for a value never needs more bits to represent than the value itself,
so it is enough to represent weights as APInts of the same bitwidth and do the
right overflow-avoiding dance steps when computing weights.  As a side-effect it
reduces the number of multiplies needed in some cases of large powers.  While
there, in view of external uses (eg by the vectorizer) I made LinearizeExprTree
static, pushing the rank computation out into users.  This is progress towards
fixing PR13021.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158358 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan Sands
2012-06-12 14:33:56 +00:00
parent 3f696e568b
commit c038a78335
6 changed files with 525 additions and 25 deletions

View File

@@ -917,6 +917,11 @@ public:
return getLShr(C1, C2, true);
}
/// getBinOpIdentity - Return the identity for the given binary operation,
/// i.e. a constant C such that X op C = X and C op X = X for every X. It
/// is an error to call this for an operation that doesn't have an identity.
static Constant *getBinOpIdentity(unsigned Opcode, Type *Ty);
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);

View File

@@ -215,6 +215,27 @@ public:
bool isCommutative() const { return isCommutative(getOpcode()); }
static bool isCommutative(unsigned op);
/// isIdempotent - Return true if the instruction is idempotent:
///
/// Idempotent operators satisfy: x op x === x
///
/// In LLVM, the And and Or operators are idempotent.
///
bool isIdempotent() const { return isIdempotent(getOpcode()); }
static bool isIdempotent(unsigned op);
/// isNilpotent - Return true if the instruction is nilpotent:
///
/// Nilpotent operators satisfy: x op x === Id,
///
/// where Id is the identity for the operator, i.e. a constant such that
/// x op Id === x and Id op x === x for all x.
///
/// In LLVM, the Xor operator is nilpotent.
///
bool isNilpotent() const { return isNilpotent(getOpcode()); }
static bool isNilpotent(unsigned op);
/// mayWriteToMemory - Return true if this instruction may modify memory.
///
bool mayWriteToMemory() const;