From 09a5899adca65a82d876a13199ea13d31b0aa2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 10 Oct 2014 14:56:06 +0200 Subject: [PATCH] Fix stack swap or dup not generating PHI nodes --- evmcc/BasicBlock.cpp | 29 ++++++++++++++++++++--------- evmcc/BasicBlock.h | 2 +- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/evmcc/BasicBlock.cpp b/evmcc/BasicBlock.cpp index 5271c984f..3a2c1c548 100644 --- a/evmcc/BasicBlock.cpp +++ b/evmcc/BasicBlock.cpp @@ -33,17 +33,27 @@ void BasicBlock::Stack::push(llvm::Value* _value) llvm::Value* BasicBlock::Stack::pop() { - if (m_backend.empty()) + auto top = get(0); + m_backend.pop_back(); + return top; +} + +llvm::Value* BasicBlock::Stack::get(size_t _index) +{ + if (_index >= m_backend.size()) { - // Create PHI node - if (m_llvmBB->empty()) - return llvm::PHINode::Create(Type::i256, 0, {}, m_llvmBB); - return llvm::PHINode::Create(Type::i256, 0, {}, m_llvmBB->getFirstNonPHI()); + // Create PHI node for missing values + auto nMissingVals = _index - m_backend.size() + 1; + m_backend.insert(m_backend.begin(), nMissingVals, nullptr); + for (decltype(nMissingVals) i = 0; i < nMissingVals; ++i) + { + m_backend[i] = m_llvmBB->empty() ? + llvm::PHINode::Create(Type::i256, 0, {}, m_llvmBB) : + llvm::PHINode::Create(Type::i256, 0, {}, m_llvmBB->getFirstNonPHI()); + } } - auto top = m_backend.back(); - m_backend.pop_back(); - return top; + return *(m_backend.rbegin() + _index); } void BasicBlock::Stack::dup(size_t _index) @@ -54,7 +64,8 @@ void BasicBlock::Stack::dup(size_t _index) void BasicBlock::Stack::swap(size_t _index) { assert(_index != 0); - std::swap(get(0), get(_index)); + get(_index); // Create PHI nodes + std::swap(*m_backend.rbegin(), *(m_backend.rbegin() + _index)); } } diff --git a/evmcc/BasicBlock.h b/evmcc/BasicBlock.h index 3c47db328..598ab731c 100644 --- a/evmcc/BasicBlock.h +++ b/evmcc/BasicBlock.h @@ -21,7 +21,7 @@ public: llvm::Value* pop(); /// Gets _index'th value from top (counting from 0) - llvm::Value*& get(size_t _index) { return *(m_backend.rbegin() + _index); } + llvm::Value* get(size_t _index); /// Duplicates _index'th value on stack. void dup(size_t _index);