diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-02-06 14:54:34 -0500 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-02-06 14:54:34 -0500 |
commit | e1931fe7a1fdb2555c24a30652d0b78b1d723fff (patch) | |
tree | 05cc339fa7fa196c58dc1f2954b7170276947020 | |
parent | cc26dd73794182e7f4ac0d1143789630ba305426 (diff) |
optimize memcpy loops
-rw-r--r-- | lib/Target/JSBackend/CallHandlers.h | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/lib/Target/JSBackend/CallHandlers.h b/lib/Target/JSBackend/CallHandlers.h index 0568d98db0..04e3b23ff0 100644 --- a/lib/Target/JSBackend/CallHandlers.h +++ b/lib/Target/JSBackend/CallHandlers.h @@ -236,6 +236,7 @@ DEF_CALL_HANDLER(llvm_memcpy_p0i8_p0i8_i32, { ConstantInt *LenInt = dyn_cast<ConstantInt>(CI->getOperand(2)); if (LenInt) { unsigned Len = LenInt->getZExtValue(); + if (Len == 0) return ""; // after here, we can assume Len>1 unsigned Align = AlignInt->getZExtValue(); while (Align > 0 && Len % Align != 0) Align /= 2; // a very unaligned small number of bytes can still be unrolled in some cases if (Align > 4) Align = 4; @@ -256,7 +257,7 @@ DEF_CALL_HANDLER(llvm_memcpy_p0i8_p0i8_i32, { } else if (Len <= WRITE_LOOP_MAX) { // emit a loop UsedVars["dest"] = UsedVars["src"] = UsedVars["stop"] = Type::getInt32Ty(TheModule->getContext())->getTypeID(); - return "for (dest=" + Dest + ", src=" + Src + ", stop=(" + Dest + "+" + utostr(Len) + ")|0; (dest|0) < (stop|0); dest=(dest+" + utostr(Align) + ")|0, src=(src+" + utostr(Align) + ")|0) { " + getHeapAccess("dest", Align) + "=" + getHeapAccess("src", Align) + "|0; }"; + return "dest=" + Dest + "; src=" + Src + "; stop=" + Dest + "+" + utostr(Len) + "|0; do { " + getHeapAccess("dest", Align) + "=" + getHeapAccess("src", Align) + "|0; dest=dest+" + utostr(Align) + "|0; src=src+" + utostr(Align) + "|0; } while ((dest|0) < (stop|0));"; } } } |