summaryrefslogtreecommitdiff
path: root/lib/VMCore/Constants.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2012-06-12 14:33:56 +0000
committerDuncan Sands <baldrick@free.fr>2012-06-12 14:33:56 +0000
commitc038a7833565ecf92a699371d448135a097c9e2f (patch)
tree3df170cfa4feeaad9409335ee997d76551bcf483 /lib/VMCore/Constants.cpp
parent3f696e568bae8afa5986e7af48156c2bac041ba7 (diff)
downloadllvm-c038a7833565ecf92a699371d448135a097c9e2f.tar.gz
llvm-c038a7833565ecf92a699371d448135a097c9e2f.tar.bz2
llvm-c038a7833565ecf92a699371d448135a097c9e2f.tar.xz
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
Diffstat (limited to 'lib/VMCore/Constants.cpp')
-rw-r--r--lib/VMCore/Constants.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 6dbc1449f2..17bad97e6f 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -2007,6 +2007,26 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) {
isExact ? PossiblyExactOperator::IsExact : 0);
}
+/// 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.
+Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) {
+ switch (Opcode) {
+ default:
+ llvm_unreachable("Not a binary operation with identity");
+ case Instruction::Add:
+ case Instruction::Or:
+ case Instruction::Xor:
+ return Constant::getNullValue(Ty);
+
+ case Instruction::Mul:
+ return ConstantInt::get(Ty, 1);
+
+ case Instruction::And:
+ return Constant::getAllOnesValue(Ty);
+ }
+}
+
// destroyConstant - Remove the constant from the constant table...
//
void ConstantExpr::destroyConstant() {