diff options
author | Duncan Sands <baldrick@free.fr> | 2012-06-13 09:42:13 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2012-06-13 09:42:13 +0000 |
commit | 318a89ddacd6f4c9044b2e85bdab42bda4dac2cd (patch) | |
tree | ff7bf034f563992c895f4e70a8bea14612fef8b2 /llvm/lib/VMCore/Constants.cpp | |
parent | 71dc02d6590b76604fb2df0f59ab4c5e6dd121c7 (diff) | |
download | bcm5719-llvm-318a89ddacd6f4c9044b2e85bdab42bda4dac2cd.tar.gz bcm5719-llvm-318a89ddacd6f4c9044b2e85bdab42bda4dac2cd.zip |
When linearizing a multiplication, return at once if we see a factor of zero,
since then the entire expression must equal zero (similarly for other operations
with an absorbing element). With this in place a bunch of reassociate code for
handling constants is dead since it is all taken care of when linearizing. No
intended functionality change.
llvm-svn: 158398
Diffstat (limited to 'llvm/lib/VMCore/Constants.cpp')
-rw-r--r-- | llvm/lib/VMCore/Constants.cpp | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/llvm/lib/VMCore/Constants.cpp b/llvm/lib/VMCore/Constants.cpp index 17bad97e6f8..400b2741cdf 100644 --- a/llvm/lib/VMCore/Constants.cpp +++ b/llvm/lib/VMCore/Constants.cpp @@ -2009,11 +2009,13 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) { /// 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. +/// returns null if the operator doesn't have an identity. Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) { switch (Opcode) { default: - llvm_unreachable("Not a binary operation with identity"); + // Doesn't have an identity. + return 0; + case Instruction::Add: case Instruction::Or: case Instruction::Xor: @@ -2027,6 +2029,25 @@ Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) { } } +/// getBinOpAbsorber - Return the absorbing element for the given binary +/// operation, i.e. a constant C such that X op C = C and C op X = C for +/// every X. For example, this returns zero for integer multiplication. +/// It returns null if the operator doesn't have an absorbing element. +Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) { + switch (Opcode) { + default: + // Doesn't have an absorber. + return 0; + + case Instruction::Or: + return Constant::getAllOnesValue(Ty); + + case Instruction::And: + case Instruction::Mul: + return Constant::getNullValue(Ty); + } +} + // destroyConstant - Remove the constant from the constant table... // void ConstantExpr::destroyConstant() { |