diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-12-21 13:52:26 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-12-21 13:56:49 -0800 |
commit | c2b3ea05aa367e7e1957b30a154b86458d61605f (patch) | |
tree | 257b5d867488a795ac5d6ae22401f0ebd4f92353 /lib/Target/CppBackend/CPPBackend.cpp | |
parent | 30716ce07e1014fc22481cfd4ecd7d0eda338415 (diff) |
optimize integer multiply with a constant
Diffstat (limited to 'lib/Target/CppBackend/CPPBackend.cpp')
-rw-r--r-- | lib/Target/CppBackend/CPPBackend.cpp | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index db5c4f8817..747459e9a7 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -405,8 +405,29 @@ std::string JSWriter::getDoubleToInt(const StringRef &s) { } std::string JSWriter::getIMul(const Value *V1, const Value *V2) { - // TODO: if small enough, emit direct multiply - return "Math_imul(" + getValueAsStr(V1) + ", " + getValueAsStr(V2) + ")|0"; + const ConstantInt *CI = NULL; + const Value *Other = NULL; + if ((CI = dyn_cast<ConstantInt>(V1))) { + Other = V2; + } else if ((CI = dyn_cast<ConstantInt>(V2))) { + Other = V1; + } + // we ignore optimizing the case of multiplying two constants - optimizer would have removed those + if (CI) { + std::string OtherStr = getValueAsStr(Other); + unsigned C = CI->getZExtValue(); + if (C == 0) return "0"; + if (C == 1) return OtherStr; + unsigned Orig = C, Shifts = 0; + while (C) { + if ((C & 1) && (C != 1)) break; // not power of 2 + C >>= 1; + Shifts++; + if (C == 0) return OtherStr + "<<" + utostr(Shifts-1); // power of 2, emit shift + } + if (Orig < (1<<20)) return "(" + OtherStr + "*" + utostr(Orig) + ")|0"; // small enough, avoid imul + } + return "Math_imul(" + getValueAsStr(V1) + ", " + getValueAsStr(V2) + ")|0"; // unknown or too large, emit imul } std::string JSWriter::getLoad(std::string Assign, const Value *P, const Type *T, unsigned Alignment, char sep) { |