Browse Source

Remove some LLVM 3.5 bugs workarounds

cl-refactor
Paweł Bylica 10 years ago
parent
commit
56c3d18582
  1. 11
      evmjit/libevmjit/Arith256.cpp
  2. 8
      evmjit/libevmjit/Compiler.cpp
  3. 5
      evmjit/libevmjit/Endianness.cpp
  4. 15
      evmjit/libevmjit/ExecutionEngine.cpp
  5. 22
      evmjit/libevmjit/GasMeter.cpp
  6. 4
      evmjit/libevmjit/Optimizer.cpp
  7. 4
      evmjit/libevmjit/preprocessor/llvm_includes_end.h
  8. 8
      evmjit/libevmjit/preprocessor/llvm_includes_start.h

11
evmjit/libevmjit/Arith256.cpp

@ -170,18 +170,7 @@ llvm::Function* Arith256::getDivFunc(llvm::Type* _type)
auto yLz = m_builder.CreateCall2(ctlzIntr, yArg, m_builder.getInt1(true), "y.lz");
auto rLz = m_builder.CreateCall2(ctlzIntr, r0, m_builder.getInt1(true), "r.lz");
auto i0 = m_builder.CreateNUWSub(yLz, rLz, "i0");
auto shlBy0 = m_builder.CreateICmpEQ(i0, zero);
auto y0 = m_builder.CreateShl(yArg, i0);
if (_type == m_builder.getIntNTy(512)) // Workaround for shl bug for long shifts
{
const auto treshold = m_builder.getIntN(512, 128);
auto highShift = m_builder.CreateICmpUGT(i0, treshold);
auto s = m_builder.CreateNUWSub(i0, treshold);
auto yhs = m_builder.CreateShl(yArg, treshold);
yhs = m_builder.CreateShl(yhs, s);
y0 = m_builder.CreateSelect(highShift, yhs, y0);
}
y0 = m_builder.CreateSelect(shlBy0, yArg, y0, "y0"); // Workaround for LLVM bug: shl by 0 produces wrong result
m_builder.CreateBr(loopBB);
m_builder.SetInsertPoint(loopBB);

8
evmjit/libevmjit/Compiler.cpp

@ -464,12 +464,8 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti
// test for word >> (k * 8 + 7)
auto bitpos = m_builder.CreateAdd(k32x8, m_builder.getInt64(7), "bitpos");
auto bitposEx = m_builder.CreateZExt(bitpos, Type::Word);
auto bittester = m_builder.CreateShl(Constant::get(1), bitposEx);
auto bitresult = m_builder.CreateAnd(word, bittester);
auto bittest = m_builder.CreateICmpUGT(bitresult, Constant::get(0));
// FIXME: The following does not work - LLVM bug, report!
//auto bitval = m_builder.CreateLShr(word, bitpos, "bitval");
//auto bittest = m_builder.CreateTrunc(bitval, Type::Bool, "bittest");
auto bitval = m_builder.CreateLShr(word, bitposEx, "bitval");
auto bittest = m_builder.CreateTrunc(bitval, Type::Bool, "bittest");
auto mask_ = m_builder.CreateShl(Constant::get(1), bitposEx);
auto mask = m_builder.CreateSub(mask_, Constant::get(1), "mask");

5
evmjit/libevmjit/Endianness.cpp

@ -18,9 +18,8 @@ llvm::Value* Endianness::bswapIfLE(llvm::IRBuilder<>& _builder, llvm::Value* _wo
{
if (llvm::sys::IsLittleEndianHost)
{
// FIXME: Disabled because of problems with BYTE
//if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(_word))
// return _builder.getInt(constant->getValue().byteSwap());
if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(_word))
return _builder.getInt(constant->getValue().byteSwap());
// OPT: Cache func declaration?
auto bswapFunc = llvm::Intrinsic::getDeclaration(_builder.GetInsertBlock()->getParent()->getParent(), llvm::Intrinsic::bswap, Type::Word);

15
evmjit/libevmjit/ExecutionEngine.cpp

@ -85,20 +85,7 @@ void parseOptions()
{
static llvm::llvm_shutdown_obj shutdownObj{};
cl::AddExtraVersionPrinter(printVersion);
//cl::ParseEnvironmentOptions("evmjit", "EVMJIT", "Ethereum EVM JIT Compiler");
// FIXME: LLVM workaround:
// Manually select instruction scheduler. Confirmed bad schedulers: source, list-burr, list-hybrid.
// "source" scheduler has a bug: http://llvm.org/bugs/show_bug.cgi?id=22304
auto envLine = std::getenv("EVMJIT");
auto commandLine = std::string{"evmjit "} + (envLine ? envLine : "") + " -pre-RA-sched=list-ilp\0";
static const auto c_maxArgs = 20;
char const* argv[c_maxArgs] = {nullptr, };
auto arg = std::strtok(&*commandLine.begin(), " ");
auto i = 0;
for (; i < c_maxArgs && arg; ++i, arg = std::strtok(nullptr, " "))
argv[i] = arg;
cl::ParseCommandLineOptions(i, argv, "Ethereum EVM JIT Compiler");
cl::ParseEnvironmentOptions("evmjit", "EVMJIT", "Ethereum EVM JIT Compiler");
}
}

22
evmjit/libevmjit/GasMeter.cpp

@ -216,22 +216,12 @@ void GasMeter::countExp(llvm::Value* _exponent)
// cost = ((256 - lz) + 7) / 8
// OPT: Can gas update be done in exp algorithm?
auto t = llvm::APInt{256, 1};
auto c = m_builder.CreateSelect(m_builder.CreateICmpUGE(_exponent, Constant::get(t)), m_builder.getInt64(1), m_builder.getInt64(0));
for (auto i = 2; i <= 32; ++i)
{
t <<= 8;
c = m_builder.CreateSelect(m_builder.CreateICmpUGE(_exponent, Constant::get(t)), m_builder.getInt64(i), c);
}
// FIXME: Does not work because of LLVM bug: https://llvm.org/bugs/show_bug.cgi?id=22304
// auto ctlz = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::ctlz, Type::Word);
// auto lz256 = m_builder.CreateCall2(ctlz, _exponent, m_builder.getInt1(false));
// auto lz = m_builder.CreateTrunc(lz256, Type::Gas, "lz");
// auto sigBits = m_builder.CreateSub(m_builder.getInt64(256), lz, "sigBits");
// auto sigBytes = m_builder.CreateUDiv(m_builder.CreateAdd(sigBits, m_builder.getInt64(7)), m_builder.getInt64(8));
count(m_builder.CreateNUWMul(c, m_builder.getInt64(c_expByteGas)));
auto ctlz = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::ctlz, Type::Word);
auto lz256 = m_builder.CreateCall2(ctlz, _exponent, m_builder.getInt1(false));
auto lz = m_builder.CreateTrunc(lz256, Type::Gas, "lz");
auto sigBits = m_builder.CreateSub(m_builder.getInt64(256), lz, "sigBits");
auto sigBytes = m_builder.CreateUDiv(m_builder.CreateAdd(sigBits, m_builder.getInt64(7)), m_builder.getInt64(8));
count(m_builder.CreateNUWMul(sigBytes, m_builder.getInt64(c_expByteGas)));
}
void GasMeter::countSStore(Ext& _ext, llvm::Value* _index, llvm::Value* _newValue)

4
evmjit/libevmjit/Optimizer.cpp

@ -16,9 +16,9 @@ namespace jit
bool optimize(llvm::Module& _module)
{
auto pm = llvm::legacy::PassManager{};
//pm.add(llvm::createFunctionInliningPass(2, 2)); // Produces invalid IR
//pm.add(llvm::createFunctionInliningPass(2, 2)); // Problem with APInt value bigger than 64bit
pm.add(llvm::createCFGSimplificationPass());
//pm.add(llvm::createInstructionCombiningPass()); // Produces invalid runtime results
pm.add(llvm::createInstructionCombiningPass());
pm.add(llvm::createAggressiveDCEPass());
pm.add(llvm::createLowerSwitchPass());
return pm.run(_module);

4
evmjit/libevmjit/preprocessor/llvm_includes_end.h

@ -1,7 +1,3 @@
#if defined(_MSC_VER)
#pragma warning(pop)
#elif defined(__clang__)
#pragma clang diagnostic pop
#else
#pragma GCC diagnostic pop
#endif

8
evmjit/libevmjit/preprocessor/llvm_includes_start.h

@ -1,12 +1,4 @@
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable: 4267 4244 4800)
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma clang diagnostic ignored "-Wconversion"
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wconversion"
#endif

Loading…
Cancel
Save