From cf236b6f9cb788afd1d3cf5a04ce458ca2869c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 2 Mar 2015 16:53:13 +0100 Subject: [PATCH] Mark arithmetic functions with nounwind and readnone attributes --- evmjit/libevmjit/Arith256.cpp | 86 ++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 11 deletions(-) diff --git a/evmjit/libevmjit/Arith256.cpp b/evmjit/libevmjit/Arith256.cpp index b67b157a6..220aa6f05 100644 --- a/evmjit/libevmjit/Arith256.cpp +++ b/evmjit/libevmjit/Arith256.cpp @@ -39,6 +39,8 @@ llvm::Function* Arith256::getMulFunc() { llvm::Type* argTypes[] = {Type::Word, Type::Word}; func = llvm::Function::Create(llvm::FunctionType::get(Type::Word, argTypes, false), llvm::Function::PrivateLinkage, "mul", getModule()); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); auto x = &func->getArgumentList().front(); x->setName("x"); @@ -51,12 +53,64 @@ llvm::Function* Arith256::getMulFunc() auto i64 = Type::Size; auto i128 = m_builder.getIntNTy(128); auto i256 = Type::Word; + auto c64 = Constant::get(64); + auto c128 = Constant::get(128); + auto c192 = Constant::get(192); +// auto mask64 = Constant::get(-1); + +// auto x1 = m_builder.CreateLShr(x, c64); +// auto y2 = m_builder.CreateLShr(y, c64); +// auto x3 = m_builder.CreateLShr(x, c128); +// auto y5 = m_builder.CreateLShr(y, c128); +// auto x4 = m_builder.CreateTrunc(x3, i128); +// auto y6 = m_builder.CreateTrunc(y5, i128); +// auto x9 = m_builder.CreateTrunc(x, i128); +// auto y7 = m_builder.CreateTrunc(y, i128); +// +// auto y8 = m_builder.CreateAnd(y7, mask64); +// auto x10 = m_builder.CreateAnd(x9, mask64); +// auto m11 = m_builder.CreateMul(y8, x10); +// auto y12 = m_builder.CreateTrunc(y2, i128); +// auto y13 = m_builder.CreateAnd(y12, mask64); +// auto m14 = m_builder.CreateMul(y13, x10); +// auto m15 = m_builder.CreateMul(y6, x10); +// auto x16 = m_builder.CreateTrunc(x1, i128); +// auto x17 = m_builder.CreateAnd(x16, mask64); +// auto m18 = m_builder.CreateMul(x17, y8); +// auto m19 = m_builder.CreateMul(y13, x17); +// auto m20 = m_builder.CreateMul(x17, y6); +// auto m21 = m_builder.CreateMul(y8, x4); +// auto m22 = m_builder.CreateMul(y13, x4); +// +// auto n23 = m_builder.CreateZExt(m11, i256); +// auto n24 = m_builder.CreateZExt(m14, i256); +// auto n25 = m_builder.CreateZExt(m15, i256); +// auto n26 = m_builder.CreateZExt(m18, i256); +// auto n27 = m_builder.CreateZExt(m19, i256); +// auto n28 = m_builder.CreateZExt(m20, i256); +// auto n29 = m_builder.CreateZExt(m21, i256); +// auto n30 = m_builder.CreateZExt(m22, i256); +// +// auto p0 = m_builder.CreateNUWAdd(n25, n29); +// auto p1 = m_builder.CreateNUWAdd(p0, n27); +// auto p2 = m_builder.CreateShl(p1, c128); +// auto p3 = m_builder.CreateNUWAdd(n30, n28); +// auto p4 = m_builder.CreateShl(p3, c192); +// auto p5 = m_builder.CreateNUWAdd(n24, n26); +// auto p6 = m_builder.CreateShl(p5, c64); +// +// auto p31 = m_builder.CreateOr(p2, n23); +// auto p32 = m_builder.CreateAdd(p31, p4); +// auto p33 = m_builder.CreateAdd(p32, p6); +// +// m_builder.CreateRet(p33); + auto x_lo = m_builder.CreateTrunc(x, i64, "x.lo"); auto y_lo = m_builder.CreateTrunc(y, i64, "y.lo"); - auto x_mi = m_builder.CreateTrunc(m_builder.CreateLShr(x, Constant::get(64)), i64); - auto y_mi = m_builder.CreateTrunc(m_builder.CreateLShr(y, Constant::get(64)), i64); - auto x_hi = m_builder.CreateTrunc(m_builder.CreateLShr(x, Constant::get(128)), i128); - auto y_hi = m_builder.CreateTrunc(m_builder.CreateLShr(y, Constant::get(128)), i128); + auto x_mi = m_builder.CreateTrunc(m_builder.CreateLShr(x, c64), i64); + auto y_mi = m_builder.CreateTrunc(m_builder.CreateLShr(y, c64), i64); + auto x_hi = m_builder.CreateTrunc(m_builder.CreateLShr(x, c128), i128); + auto y_hi = m_builder.CreateTrunc(m_builder.CreateLShr(y, c128), i128); auto t1 = m_builder.CreateMul(m_builder.CreateZExt(x_lo, i128), m_builder.CreateZExt(y_lo, i128)); auto t2 = m_builder.CreateMul(m_builder.CreateZExt(x_lo, i128), m_builder.CreateZExt(y_mi, i128)); @@ -68,13 +122,13 @@ llvm::Function* Arith256::getMulFunc() auto t8 = m_builder.CreateMul(x_hi, m_builder.CreateZExt(y_mi, i128)); auto p = m_builder.CreateZExt(t1, i256); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t2, i256), Constant::get(64))); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t3, i256), Constant::get(128))); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t4, i256), Constant::get(64))); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t5, i256), Constant::get(128))); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t6, i256), Constant::get(192))); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t7, i256), Constant::get(128))); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t8, i256), Constant::get(192))); + p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t2, i256), c64)); + p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t3, i256), c128)); + p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t4, i256), c64)); + p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t5, i256), c128)); + p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t6, i256), c192)); + p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t7, i256), c128)); + p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t8, i256), c192)); m_builder.CreateRet(p); } return func; @@ -88,6 +142,8 @@ llvm::Function* Arith256::getMul512Func() auto i512 = m_builder.getIntNTy(512); llvm::Type* argTypes[] = {Type::Word, Type::Word}; func = llvm::Function::Create(llvm::FunctionType::get(i512, argTypes, false), llvm::Function::PrivateLinkage, "mul512", getModule()); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); auto x = &func->getArgumentList().front(); x->setName("x"); @@ -131,6 +187,8 @@ llvm::Function* Arith256::getDivFunc(llvm::Type* _type) auto retType = llvm::StructType::get(m_builder.getContext(), llvm::ArrayRef{argTypes}); auto funcName = _type == Type::Word ? "div" : "div512"; func = llvm::Function::Create(llvm::FunctionType::get(retType, argTypes, false), llvm::Function::PrivateLinkage, funcName, getModule()); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); auto zero = llvm::ConstantInt::get(_type, 0); auto one = llvm::ConstantInt::get(_type, 1); @@ -222,6 +280,8 @@ llvm::Function* Arith256::getExpFunc() { llvm::Type* argTypes[] = {Type::Word, Type::Word}; m_exp = llvm::Function::Create(llvm::FunctionType::get(Type::Word, argTypes, false), llvm::Function::PrivateLinkage, "exp", getModule()); + m_exp->setDoesNotThrow(); + m_exp->setDoesNotAccessMemory(); auto base = &m_exp->getArgumentList().front(); base->setName("base"); @@ -290,6 +350,8 @@ llvm::Function* Arith256::getAddModFunc() auto i512Ty = m_builder.getIntNTy(512); llvm::Type* argTypes[] = {Type::Word, Type::Word, Type::Word}; m_addmod = llvm::Function::Create(llvm::FunctionType::get(Type::Word, argTypes, false), llvm::Function::PrivateLinkage, "addmod", getModule()); + m_addmod->setDoesNotThrow(); + m_addmod->setDoesNotAccessMemory(); auto x = &m_addmod->getArgumentList().front(); x->setName("x"); @@ -319,6 +381,8 @@ llvm::Function* Arith256::getMulModFunc() { llvm::Type* argTypes[] = {Type::Word, Type::Word, Type::Word}; m_mulmod = llvm::Function::Create(llvm::FunctionType::get(Type::Word, argTypes, false), llvm::Function::PrivateLinkage, "mulmod", getModule()); + m_mulmod->setDoesNotThrow(); + m_mulmod->setDoesNotAccessMemory(); auto i512Ty = m_builder.getIntNTy(512); auto x = &m_mulmod->getArgumentList().front();